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
, fmuls
resp. 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
- If X is
0xf
, then the n-th bit of val is returned unaltered. - If X is in the range 0…7, then the n-th result bit is set to the X-th bit of bits
- 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); }