Next: Blackfin Built-in Functions, Previous: ARM NEON Intrinsics, Up: Target Builtins

#### 6.55.4 AVR Built-in Functions

For each built-in function for AVR, there is an equally named, uppercase built-in macro defined. That way users can easily query if or if not a specific built-in is implemented or not. For example, if `__builtin_avr_nop` is available the macro `__BUILTIN_AVR_NOP` is defined to `1` and undefined otherwise.

The following built-in functions map to the respective machine instruction, i.e. `nop`, `sei`, `cli`, `sleep`, `wdr`, `swap`, `fmul`, `fmuls` resp. `fmulsu`. The three `fmul*` built-ins are implemented as library call if no hardware multiplier is available.

         void __builtin_avr_nop (void)
         void __builtin_avr_sei (void)
         void __builtin_avr_cli (void)
         void __builtin_avr_sleep (void)
         void __builtin_avr_wdr (void)
         unsigned char __builtin_avr_swap (unsigned char)
         unsigned int __builtin_avr_fmul (unsigned char, unsigned char)
         int __builtin_avr_fmuls (char, char)
         int __builtin_avr_fmulsu (char, unsigned char)

In order to delay execution for a specific number of cycles, GCC implements

         void __builtin_avr_delay_cycles (unsigned long ticks)

`ticks` is the number of ticks to delay execution. Note that this built-in does not take into account the effect of interrupts which might increase delay time. `ticks` must be a compile time integer constant; delays with a variable number of cycles are not supported.

         char __builtin_avr_flash_segment (const __memx void*)

This built-in takes a byte address to the 24-bit address space `__memx` and returns the number of the flash segment (the 64 KiB chunk) where the address points to. Counting starts at `0`. If the address does not point to flash memory, return `-1`.

         unsigned char __builtin_avr_insert_bits (unsigned long map, unsigned char bits, unsigned char val)

Insert bits from bits into val and return the resulting value. The nibbles of map determine how the insertion is performed: Let X be the n-th nibble of map

1. If X is `0xf`, then the n-th bit of val is returned unaltered.
2. If X is in the range 0...7, then the n-th result bit is set to the X-th bit of bits
3. If X is in the range 8...`0xe`, then the n-th result bit is undefined.

One typical use case for this built-in is adjusting input and output values to non-contiguous port layouts. Some examples:

         // same as val, bits is unused
         __builtin_avr_insert_bits (0xffffffff, bits, val)

         // same as bits, val is unused
         __builtin_avr_insert_bits (0x76543210, bits, val)

         // same as rotating bits by 4
         __builtin_avr_insert_bits (0x32107654, bits, 0)

         // high-nibble of result is the high-nibble of val
         // low-nibble of result is the low-nibble of bits
         __builtin_avr_insert_bits (0xffff3210, bits, val)

         // reverse the bit order of bits
         __builtin_avr_insert_bits (0x01234567, bits, 0)