Using the GNU Compiler Collection (GCC): AVR Built-in Functions

Next: Blackfin Built-in Functions, Previous: ARM ARMv8-M Security Extensions, Up: Target Builtins [Contents][Index]

#### 6.60.10 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.

`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)`

  These 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_delay_cycles (unsigned long ticks)`

  Delay execution for ticks cycles. Note that this built-in does not take into account the effect of interrupts that 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`.

`uint8_t __builtin_avr_insert_bits (uint32_t map, uint8_t bits, uint8_t 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);

`void __builtin_avr_nops (unsigned count)`

  Insert count `NOP` instructions. The number of instructions must be a compile-time integer constant.

There are many more AVR-specific built-in functions that are used to implement the ISO/IEC TR 18037 “Embedded C” fixed-point functions of section 7.18a.6. You don’t need to use these built-ins directly. Instead, use the declarations as supplied by the `stdfix.h` header with GNU-C99:

    #include <stdfix.h>

    // Re-interpret the bit representation of unsigned 16-bit
    // integer uval as Q-format 0.16 value.
    unsigned fract get_bits (uint_ur_t uval)
    {
        return urbits (uval);
    }

Next: Blackfin Built-in Functions, Previous: ARM ARMv8-M Security Extensions, Up: Target Builtins [Contents][Index]