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


7.13.9 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.

Built-in Function: void __builtin_avr_nop (void)

Built-in Function: void __builtin_avr_sei (void)

Built-in Function: void __builtin_avr_cli (void)

Built-in Function: void __builtin_avr_sleep (void)

Built-in Function: void __builtin_avr_wdr (void)

Built-in Function: uint8_t __builtin_avr_swap (uint8_t)

Built-in Function: uint16_t __builtin_avr_fmul (uint8_t, uint8_t)

Built-in Function: int16_t __builtin_avr_fmuls (int8_t, int8_t)

Built-in Function: int16_t __builtin_avr_fmulsu (int8_t, uint8_t)

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

Built-in Function: void __builtin_avr_delay_cycles (uint32_t 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.

Built-in Function: 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);

Built-in Function: uint8_t __builtin_avr_mask1 (uint8_t mask, uint8_t offs)

Rotate the 8-bit constant value mask by an offset of offs, where mask is in { 0x01, 0xfe, 0x7f, 0x80 }. This built-in can be used as an alternative to 8-bit expressions like1 << offs when their computation consumes too much time, and offs is known to be in the range 0…7.

__builtin_avr_mask1 (1, offs) // same like 1 << offs __builtin_avr_mask1 (1, offs) // same like ~(1 << offs) __builtin_avr_mask1 (0x80, offs) // same like 0x80 >> offs __builtin_avr_mask1 (0x80, offs) // same like ~(0x80 >> offs)

The open coded C versions take at least 5 + 4 * offs cycles (and 5 instructions), whereas the built-in takes 7 cycles and instructions (8 cycles and instructions in the case of mask = 0x7f).

Built-in Function: void __builtin_avr_nops (uint16_t count)

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

All of the following built-in functions are only available for GNU-C

Built-in Function: int8_t __builtin_avr_flash_segment (const __memx void*)

This built-in takes a byte address to the 24-bitnamed 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.

Built-in Function: size_t __builtin_avr_strlen_flash (const __flash char*)

Built-in Function: size_t __builtin_avr_strlen_flashx (const __flashx char*)

Built-in Function: size_t __builtin_avr_strlen_memx (const __memx char*)

These built-ins return the length of a string located in named address-space __flash, __flashx or __memx, respectively. They are used to support functions like strlen_F fromAVR-LibC’s header avr/flash.h.

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); }