0

Sory for bad English, please.

I need write a time-critical piece of code (a strict part of software protocol implementation via bit-bang) that uses delays. C preprocessor at the compile time can compute the number of clock cycles (with F_CPU macro) for a delay, so I need to implement a assembler delay code for unknown number of cycles.

But GCC provide very useful function __builtin_avr_delay_cycles(unsigned long cycles) that make delay exactly cycles clock cycles for defined F_CPU frequency.

Question. Is there way to use __builtin_avr_delay_cycles within inline-assembler code?

Note. Bypass way is like this:

__asm__ (...);
__builtin_avr_delay_cycles(...);
__asm__ (...);

but the compiler can make some code around __asm__ pieces. It is bad for me, I need to control each clock cycle.

2 Answers2

2
__asm__ (...);
__builtin_avr_delay_cycles(...);
__asm__ (...);

Compile the code like this and then look at what the compiler emitted for the builtin.

It will be a sequence very similar to the following:

   ldi R2,lo8(N)
   ldi R3,hi8(N)
   ldi R4,hlo8(N)
1: subi R2,1
   sbci R3,0
   sbci R4,0
   brne 1b"

There may be a 2-3 such sequences, sometimes ending with nopv insn, sometimes there will be 1 or 2 or 3 ldi and sbci insns, you get the pattern (it depends on the cycles count).

Turn these insns into inline assembly, N is the cycles count, Rn are registers.

The drawback is that generated code depends on the cycle count and if it changes, you'll have to repeat the process. However, you're safe if the change is within one of the following ranges: [83886082, 0xFFFFFFFF], [262145, 83886081], [768, 262144], [6, 767].

chill
  • 16,470
  • 2
  • 40
  • 44
0

No, compiler built-ins are not real functions and cannot be called from assembler, nor will the compiler recognise them within assembler.

ams
  • 24,923
  • 4
  • 54
  • 75