AVR Options (Using the GNU Compiler Collection (GCC))

#### 3.20.6 AVR Options ¶

These options are defined for AVR implementations:

`-mmcu=mcu` ¶

  Specify the AVR instruction set architecture (ISA) or device type. The default for this option is `avr2`.

  The following AVR devices and ISAs are supported. Note: A complete device support consists of startup code `crtmcu.o`, a device header `avr/io*.h`, a device library `libmcu.a` and a device-specs file `specs-mcu`. Only the latter is provided by the compiler according to the supported `mcu`s below. The rest is supported by AVR-LibC, or by means of `atpack` files from the hardware manufacturer.

  `avr2`

    “Classic” devices with up to 8 KiB of program memory.
    mcu = `attiny22`, `attiny26`, `at90s2313`, `at90s2323`, `at90s2333`, `at90s2343`, `at90s4414`, `at90s4433`, `at90s4434`, `at90c8534`, `at90s8515`, `at90s8535`.

  `avr25`

    “Classic” devices with up to 8 KiB of program memory and with the `MOVW` instruction.
    mcu = `attiny13`, `attiny13a`, `attiny24`, `attiny24a`, `attiny25`, `attiny261`, `attiny261a`, `attiny2313`, `attiny2313a`, `attiny43u`, `attiny44`, `attiny44a`, `attiny45`, `attiny48`, `attiny441`, `attiny461`, `attiny461a`, `attiny4313`, `attiny84`, `attiny84a`, `attiny85`, `attiny87`, `attiny88`, `attiny828`, `attiny841`, `attiny861`, `attiny861a`, `ata5272`, `ata6616c`, `at86rf401`.

  `avr3`

    “Classic” devices with 16 KiB up to 64 KiB of program memory.
    mcu = `at76c711`, `at43usb355`.

  `avr31`

    “Classic” devices with 128 KiB of program memory.
    mcu = `atmega103`, `at43usb320`.

  `avr35`

    “Classic” devices with 16 KiB up to 64 KiB of program memory and with the `MOVW` instruction.
    mcu = `attiny167`, `attiny1634`, `atmega8u2`, `atmega16u2`, `atmega32u2`, `ata5505`, `ata6617c`, `ata664251`, `at90usb82`, `at90usb162`.

  `avr4`

    “Enhanced” devices with up to 8 KiB of program memory.
    mcu = `atmega48`, `atmega48a`, `atmega48p`, `atmega48pa`, `atmega48pb`, `atmega8`, `atmega8a`, `atmega8hva`, `atmega88`, `atmega88a`, `atmega88p`, `atmega88pa`, `atmega88pb`, `atmega8515`, `atmega8535`, `ata5795`, `ata6285`, `ata6286`, `ata6289`, `ata6612c`, `at90pwm1`, `at90pwm2`, `at90pwm2b`, `at90pwm3`, `at90pwm3b`, `at90pwm81`.

  `avr5`

    “Enhanced” devices with 16 KiB up to 64 KiB of program memory.
    mcu = `atmega16`, `atmega16a`, `atmega16hva`, `atmega16hva2`, `atmega16hvb`, `atmega16hvbrevb`, `atmega16m1`, `atmega16u4`, `atmega161`, `atmega162`, `atmega163`, `atmega164a`, `atmega164p`, `atmega164pa`, `atmega165`, `atmega165a`, `atmega165p`, `atmega165pa`, `atmega168`, `atmega168a`, `atmega168p`, `atmega168pa`, `atmega168pb`, `atmega169`, `atmega169a`, `atmega169p`, `atmega169pa`, `atmega32`, `atmega32a`, `atmega32c1`, `atmega32hvb`, `atmega32hvbrevb`, `atmega32m1`, `atmega32u4`, `atmega32u6`, `atmega323`, `atmega324a`, `atmega324p`, `atmega324pa`, `atmega324pb`, `atmega325`, `atmega325a`, `atmega325p`, `atmega325pa`, `atmega328`, `atmega328p`, `atmega328pb`, `atmega329`, `atmega329a`, `atmega329p`, `atmega329pa`, `atmega3250`, `atmega3250a`, `atmega3250p`, `atmega3250pa`, `atmega3290`, `atmega3290a`, `atmega3290p`, `atmega3290pa`, `atmega406`, `atmega64`, `atmega64a`, `atmega64c1`, `atmega64hve`, `atmega64hve2`, `atmega64m1`, `atmega64rfr2`, `atmega640`, `atmega644`, `atmega644a`, `atmega644p`, `atmega644pa`, `atmega644rfr2`, `atmega645`, `atmega645a`, `atmega645p`, `atmega649`, `atmega649a`, `atmega649p`, `atmega6450`, `atmega6450a`, `atmega6450p`, `atmega6490`, `atmega6490a`, `atmega6490p`, `ata5790`, `ata5790n`, `ata5791`, `ata6613c`, `ata6614q`, `ata5782`, `ata5831`, `ata8210`, `ata8510`, `ata5787`, `ata5835`, `ata5700m322`, `ata5702m322`, `at90pwm161`, `at90pwm216`, `at90pwm316`, `at90can32`, `at90can64`, `at90scr100`, `at90usb646`, `at90usb647`, `at94k`, `m3000`.

  `avr51`

    “Enhanced” devices with 128 KiB of program memory.
    mcu = `atmega128`, `atmega128a`, `atmega128rfa1`, `atmega128rfr2`, `atmega1280`, `atmega1281`, `atmega1284`, `atmega1284p`, `atmega1284rfr2`, `at90can128`, `at90usb1286`, `at90usb1287`.

  `avr6`

    “Enhanced” devices with 3-byte PC, i.e. with more than 128 KiB of program memory.
    mcu = `atmega256rfr2`, `atmega2560`, `atmega2561`, `atmega2564rfr2`.

  `avrxmega2`

    “XMEGA” devices with more than 8 KiB and up to 64 KiB of program memory.
    mcu = `atxmega8e5`, `atxmega16a4`, `atxmega16a4u`, `atxmega16c4`, `atxmega16d4`, `atxmega16e5`, `atxmega32a4`, `atxmega32a4u`, `atxmega32c3`, `atxmega32c4`, `atxmega32d3`, `atxmega32d4`, `atxmega32e5`, `avr64da28`, `avr64da28s`, `avr64da32`, `avr64da32s`, `avr64da48`, `avr64da48s`, `avr64da64`, `avr64da64s`, `avr64db28`, `avr64db32`, `avr64db48`, `avr64db64`, `avr64dd14`, `avr64dd20`, `avr64dd28`, `avr64dd32`, `avr64du28`, `avr64du32`, `avr64ea28`, `avr64ea32`, `avr64ea48`, `avr64sd28`, `avr64sd32`, `avr64sd48`.

  `avrxmega3`

    “XMEGA” devices with up to 64 KiB of combined program memory and RAM, and with program memory visible in the RAM address space.
    mcu = `attiny202`, `attiny204`, `attiny212`, `attiny214`, `attiny402`, `attiny404`, `attiny406`, `attiny412`, `attiny414`, `attiny416`, `attiny416auto`, `attiny417`, `attiny424`, `attiny426`, `attiny427`, `attiny804`, `attiny806`, `attiny807`, `attiny814`, `attiny816`, `attiny817`, `attiny824`, `attiny826`, `attiny827`, `attiny1604`, `attiny1606`, `attiny1607`, `attiny1614`, `attiny1616`, `attiny1617`, `attiny1624`, `attiny1626`, `attiny1627`, `attiny3214`, `attiny3216`, `attiny3217`, `attiny3224`, `attiny3226`, `attiny3227`, `atmega808`, `atmega809`, `atmega1608`, `atmega1609`, `atmega3208`, `atmega3209`, `atmega4808`, `atmega4809`, `avr16dd14`, `avr16dd20`, `avr16dd28`, `avr16dd32`, `avr16du14`, `avr16du20`, `avr16du28`, `avr16du32`, `avr16ea28`, `avr16ea32`, `avr16ea48`, `avr16eb14`, `avr16eb20`, `avr16eb28`, `avr16eb32`, `avr16la14`, `avr16la20`, `avr16la28`, `avr16la32`, `avr32da28`, `avr32da28s`, `avr32da32`, `avr32da32s`, `avr32da48`, `avr32da48s`, `avr32db28`, `avr32db32`, `avr32db48`, `avr32dd14`, `avr32dd20`, `avr32dd28`, `avr32dd32`, `avr32du14`, `avr32du20`, `avr32du28`, `avr32du32`, `avr32ea28`, `avr32ea32`, `avr32ea48`, `avr32eb14`, `avr32eb20`, `avr32eb28`, `avr32eb32`, `avr32la14`, `avr32la20`, `avr32la28`, `avr32la32`, `avr32sd20`, `avr32sd28`, `avr32sd32`.

  `avrxmega4`

    “XMEGA” devices with more than 64 KiB and up to 128 KiB of program memory.
    mcu = `atxmega64a3`, `atxmega64a3u`, `atxmega64a4u`, `atxmega64b1`, `atxmega64b3`, `atxmega64c3`, `atxmega64d3`, `atxmega64d4`, `avr128da28`, `avr128da28s`, `avr128da32`, `avr128da32s`, `avr128da48`, `avr128da48s`, `avr128da64`, `avr128da64s`, `avr128db28`, `avr128db32`, `avr128db48`, `avr128db64`.

  `avrxmega5`

    “XMEGA” devices with more than 64 KiB and up to 128 KiB of program memory and more than 64 KiB of RAM.
    mcu = `atxmega64a1`, `atxmega64a1u`.

  `avrxmega6`

    “XMEGA” devices with more than 128 KiB of program memory.
    mcu = `atxmega128a3`, `atxmega128a3u`, `atxmega128b1`, `atxmega128b3`, `atxmega128c3`, `atxmega128d3`, `atxmega128d4`, `atxmega192a3`, `atxmega192a3u`, `atxmega192c3`, `atxmega192d3`, `atxmega256a3`, `atxmega256a3b`, `atxmega256a3bu`, `atxmega256a3u`, `atxmega256c3`, `atxmega256d3`, `atxmega384c3`, `atxmega384d3`.

  `avrxmega7`

    “XMEGA” devices with more than 128 KiB of program memory and more than 64 KiB of RAM.
    mcu = `atxmega128a1`, `atxmega128a1u`, `atxmega128a4u`.

  `avrtiny`

    “Reduced Tiny” Tiny core devices with only 16 general purpose registers and 512 B up to 4 KiB of program memory.
    mcu = `attiny4`, `attiny5`, `attiny9`, `attiny10`, `attiny102`, `attiny104`, `attiny20`, `attiny40`.

  `avr1`

    This ISA is implemented by the minimal AVR core and supported for assembler only.
    mcu = `attiny11`, `attiny12`, `attiny15`, `attiny28`, `at90s1200`.

`-mabsdata` ¶

  Assume that all data in static storage can be accessed by LDS / STS instructions. This option has only an effect on reduced Tiny devices like ATtiny40. See also the `absdata` variable attribute.

`-masm-len-notes` ¶
`-mno-asm-len-notes`

  Recognize resp. ignore `[[len=spec]]` notes that are placed in (comments in) inline assembly code templates. They allow to specify the exact size of `asm` constructs. This option is on per default.

`-mcvt` ¶

  Use a compact vector table. Some devices support a CVT with only four entries: 0=Reset, 1=NMI, 2=Prio1 IRQ, 3=Prio0 IRQs. This option will link startup code from `crtmcu-cvt.o` instead of the usual `crtmcu.o`. Apart from providing a compact vector table, the startup code will set bit `CPUINT_CTRLA.CPUINT_CVT` which enables the CVT on the device.

  When you do not want the startup code to set `CPUINT_CTRLA.CPUINT_CVT`, then you can satisfy symbol `__init_cvt` so that the respective code is no more pulled in from `libmcu.a`. For example, you can link with `-Wl,--defsym,__init_cvt=0`.

  The CVT startup code is available since AVR-LibC v2.3.

`-mdouble=bits` ¶
`-mlong-double=bits`

  Set the size (in bits) of the `double` or `long double` type, respectively. Possible values for bits are 32 and 64. Whether or not a specific value for bits is allowed depends on the `--with-double=` and `--with-long-double=` configure options, and the same applies for the default values of the options.

`-mgas-isr-prologues` ¶

  Interrupt service routines (ISRs) may use the `__gcc_isr` pseudo instruction supported by GNU Binutils. If this option is on, the feature can still be disabled for individual ISRs by means of the `no_gccisr` function attribute. This feature is activated per default if optimization is on (but not with `-Og`, see Options That Control Optimization), and if GNU Binutils support PR21683.

`-mint8` ¶

  Assume `int` to be 8-bit integer. This affects the sizes of all types: a `char` is 1 byte, an `int` is 1 byte, a `long` is 2 bytes, and `long long` is 4 bytes. Please note that this option does not conform to the C standards, but it results in smaller code size.

`-mmain-is-OS_task` ¶

  Do not save registers in `main`. The effect is the same like attaching attribute `OS_task` to `main`. It is activated per default if optimization is on.

`-mno-call-main` ¶

  Don’t run `main` by means of

      XCALL  main
      XJMP   exit

  Instead, put `main` in section `.init9` so that no call is required. By setting this option the user asserts that `main` will not return.

  This option can be used for devices with very limited resources in order to save a few bytes of code and stack space. It will work as expected since AVR-LibC v2.3. With older versions, there will be no performance gain.

`-mno-interrupts` ¶

  Generated code is not compatible with hardware interrupts. Code size is smaller.

`-mrelax` ¶

  Try to replace `CALL` resp. `JMP` instruction by the shorter `RCALL` resp. `RJMP` instruction if applicable. Setting `-mrelax` just adds the `--mlink-relax` option to the assembler’s command line and the `--relax` option to the linker’s command line.

  Jump relaxing is performed by the linker because jump offsets are not known before code is located. Therefore, the assembler code generated by the compiler is the same, but the instructions in the executable may differ from instructions in the assembler code.

  Relaxing must be turned on if linker stubs are needed, see the section on `EIND` and linker stubs below.

`-mpmem-wrap-around` ¶

  Enable program counter wrap-around in linker relaxation.

`-mrodata-in-ram` ¶
`-mno-rodata-in-ram`

  Locate the `.rodata` sections for read-only data in RAM resp. in program memory. For most devices, there is no choice and this option acts rather like an assertion.

  Since v14 and for the AVR64* and AVR128* devices, `.rodata` is located in flash memory per default, provided the required GNU Binutils support (PR31124) is available. In that case, `-mrodata-in-ram` can be used to return to the old layout with `.rodata` in RAM.

`-mtiny-stack` ¶

  Only change the lower 8 bits of the stack pointer.

`-mfract-convert-truncate` ¶

  Allow to use truncation instead of rounding towards zero for fractional fixed-point types.

`-nodevicelib` ¶

  Don’t link against AVR-LibC’s device specific library `libmcu.a`.

  Notice that since AVR-LibC v2.3, that library contains code that is essential for the correct functioning of a program. In particular, it contains parts of the startup code like: `__init_sp` to initialize the stack pointer with symbol `__stack`, `__init_cvt` to set up the hardware to use a compact vector table with `-mcvt`, `__call_main` to call `main` and `exit`, and `__do_flmap_init` to set up FLMAP according to symbol `__flmap`.

`-nodevicespecs` ¶

  Don’t add `-specs=device-specs/specs-mcu` to the compiler driver’s command line. The user takes responsibility for supplying the sub-processes like compiler proper, assembler and linker with appropriate command-line options. This means that the user has to supply her private device specs file by means of `-specs=path-to-specs-file`. There is no more need for option `-mmcu=mcu`.

  This option can also serve as a replacement for the older way of specifying custom device-specs files that needed `-B some-path` to point to a directory which contains a folder named `device-specs` which contains a specs file named `specs-mcu`, where mcu was specified by `-mmcu=mcu`.

`-Waddr-space-convert` ¶

  Warn about conversions between address spaces in the case where the resulting address space is not contained in the incoming address space.

`-Wasm-len-notes` ¶

  Warn about unrecognized `[[len=spec]]` length annotations in inline assembly code templates. This warning is on per default. Notice that in LTO mode, the code must be compiled with option `-ffat-lto-objects` in order for these diagnoses to appear.

`-Wmisspelled-isr` ¶

  Warn if the ISR is misspelled, i.e. without __vector prefix. Enabled by default.

#### 3.20.6.1 AVR Optimization Options ¶

The following options are pure optimization options. Options `-mgas-isr-prologues`, `-mmain-is-OS_task`, `-mno-call-main` and `-mrelax` from above are only almost optimization options, since there are rare occasions where their different code generation matters.

`-maccumulate-args` ¶

  Accumulate outgoing function arguments and acquire/release the needed stack space for outgoing function arguments once in function prologue/epilogue. Without this option, outgoing arguments are pushed before calling a function and popped afterwards. See also the `-fdefer-pop` optimization option.

  Popping the arguments after the function call can be expensive on AVR so that accumulating the stack space might lead to smaller executables because arguments need not be removed from the stack after such a function call.

  This option can lead to reduced code size for functions that perform several calls to functions that get their arguments on the stack like calls to printf-like functions.

`-mbranch-cost=cost` ¶

  Set the branch costs for conditional branch instructions to cost. Reasonable values for cost are small, non-negative integers. The default branch cost is 0.

`-mcall-prologues` ¶

  Functions prologues/epilogues are expanded as calls to appropriate subroutines. Code size is smaller.

`-mfuse-add` ¶
`-mno-fuse-add`
`-mfuse-add=level`

  Optimize indirect memory accesses on reduced Tiny devices. The default uses `level=1` for optimizations `-Og` and `-O1`, and `level=2` for higher optimizations. Valid values for level are `0`, `1` and `2`.

`-mfuse-move` ¶
`-mno-fuse-move`
`-mfuse-move=level`

  Run a post reload optimization pass that tries to fuse move instructions and to split multi-byte instructions into 8-bit operations. The default uses `level=3` for optimization `-O1`, and `level=23` for higher optimizations. Valid values for level are in the range `0` … `23` which is a 3:2:2:2 mixed radix value. Each digit controls some aspect of the optimization.

`-mfuse-move2` ¶

  Run a post combine optimization pass that tries to fuse move instructions.

`-mstrict-X` ¶

  Use address register `X` in a way proposed by the hardware. This means that `X` is only used in indirect, post-increment or pre-decrement addressing.

  Without this option, the `X` register may be used in the same way as `Y` or `Z` which then is emulated by additional instructions. For example, loading a value with `X+const` addressing with a small non-negative `const < 64` to a register Rn is performed as

      adiw r26, const   ; X += const
      ld   Rn, X        ; Rn = *X
      sbiw r26, const   ; X -= const

`-msplit-bit-shift` ¶

  Split multi-byte shifts with a constant offset into a shift with a byte offset and a residual shift with a non-byte offset. This optimization is turned on per default for `-O2` and higher, including `-Os` but excluding `-Oz`. Splitting of shifts with a constant offset that is a multiple of 8 is controlled by `-mfuse-move`.

`-msplit-ldst` ¶

  Split multi-byte loads and stores into several byte loads and stores. This optimization is turned on per default for `-O2` and higher.

`-muse-nonzero-bits` ¶

  Enable optimizations that are only possible when some bits in a register are always zero. This optimization is turned on per default for `-O2` and higher.

#### 3.20.6.2 `EIND` and Devices with More Than 128 Ki Bytes of Flash ¶

Pointers in the implementation are 16 bits wide. The address of a function or label is represented as word address so that indirect jumps and calls can target any code address in the range of 64 Ki words.

In order to facilitate indirect jump on devices with more than 128 Ki bytes of program memory space, there is a special function register called `EIND` that serves as most significant part of the target address when `EICALL` or `EIJMP` instructions are used.

Indirect jumps and calls on these devices are handled as follows by the compiler and are subject to some limitations:

- The compiler never sets `EIND`.
- The compiler uses `EIND` implicitly in `EICALL`/`EIJMP` instructions or might read `EIND` directly in order to emulate an indirect call/jump by means of a `RET` instruction.
- The compiler assumes that `EIND` never changes during the startup code or during the application. In particular, `EIND` is not saved/restored in function or interrupt service routine prologue/epilogue.
- For indirect calls to functions and computed goto, the linker generates stubs. Stubs are jump pads sometimes also called trampolines. Thus, the indirect call/jump jumps to such a stub. The stub contains a direct jump to the desired address.
- Linker relaxation must be turned on so that the linker generates the stubs correctly in all situations. See the compiler option `-mrelax` and the linker option `--relax`. There are corner cases where the linker is supposed to generate stubs but aborts without relaxation and without a helpful error message.
- The default linker script is arranged for code with `EIND = 0`. If code is supposed to work for a setup with `EIND != 0`, a custom linker script has to be used in order to place the sections whose name start with `.trampolines` into the segment where `EIND` points to.
- The startup code from libgcc never sets `EIND`. Notice that startup code is a blend of code from libgcc and AVR-LibC. For the impact of AVR-LibC on `EIND`, see the AVR-LibC user manual.
- It is legitimate for user-specific startup code to set up `EIND` early, for example by means of initialization code located in section `.init3`. Such code runs prior to general startup code that initializes RAM and calls constructors, but after the bit of startup code from AVR-LibC that sets `EIND` to the segment where the vector table is located.

      #include <avr/io.h>

      static void
      __attribute__((section(".init3"),naked,used,no_instrument_function))
      init3_set_eind (void)
      {
        __asm volatile ("ldi r24,pm_hh8(__trampolines_start)\n\t"
                        "out %i0,r24" :: "n" (&EIND) : "r24","memory");
      }

  The `__trampolines_start` symbol is defined in the linker script.

- Stubs are generated automatically by the linker if the following two conditions are met:
  - The address of a label is taken by means of the `gs` modifier (short for generate stubs) like so:

        LDI r24, lo8(gs(func))
        LDI r25, hi8(gs(func))

  - The final location of that label is in a code segment outside the segment where the stubs are located.
- The compiler emits such `gs` modifiers for code labels in the following situations:
  - Taking address of a function or code label.
  - Computed goto.
  - If prologue-save function is used, see `-mcall-prologues` command-line option.
  - Switch/case dispatch tables. If you do not want such dispatch tables you can specify the `-fno-jump-tables` command-line option.
  - C and C++ constructors/destructors called during startup/shutdown.
  - If the tools hit a `gs()` modifier explained above.
- Jumping to non-symbolic addresses like so is not supported:

      int main (void)
      {
          /* Call function at word address 0x2 */
          return ((int(*)(void)) 0x2)();
      }

  Instead, a stub has to be set up, i.e. the function has to be called through a symbol (`func_4` in the example):

      int main (void)
      {
          extern int func_4 (void);

          /* Call function at byte address 0x4 */
          return func_4();
      }

  and the application be linked with `-Wl,--defsym,func_4=0x4`. Alternatively, `func_4` can be defined in the linker script.

#### 3.20.6.3 Handling of the `RAMPD`, `RAMPX`, `RAMPY` and `RAMPZ` Special Function Registers ¶

Some AVR devices support memories larger than the 64 KiB range that can be accessed with 16-bit pointers. To access memory locations outside this 64 KiB range, the content of a `RAMP` register is used as high part of the address: The `X`, `Y`, `Z` address register is concatenated with the `RAMPX`, `RAMPY`, `RAMPZ` special function register, respectively, to get a wide address. Similarly, `RAMPD` is used together with direct addressing.

- The startup code initializes the `RAMP` special function registers with zero.
- If a named address space other than generic or `__flash` is used, then `RAMPZ` is set as needed before the operation.
- If the device supports RAM larger than 64 KiB and the compiler needs to change `RAMPZ` to accomplish an operation, `RAMPZ` is reset to zero after the operation.
- If the device comes with a specific `RAMP` register, the ISR prologue/epilogue saves/restores that SFR and initializes it with zero in case the ISR code might (implicitly) use it.
- RAM larger than 64 KiB is not supported by GCC for AVR targets. If you use inline assembler to read from locations outside the 16-bit address range and change one of the `RAMP` registers, you must reset it to zero after the access.

#### 3.20.6.4 AVR Built-in Macros ¶

GCC defines several built-in macros so that the user code can test for the presence or absence of features. Almost any of the following built-in macros are deduced from device capabilities and thus triggered by the `-mmcu=` command-line option.

For even more AVR-specific built-in macros see AVR Named Address Spaces and AVR Built-in Functions.

`__AVR_ARCH__`

  Build-in macro that resolves to a decimal number that identifies the architecture and depends on the `-mmcu=mcu` option. Possible values are:

  `2`, `25`, `3`, `31`, `35`, `4`, `5`, `51`, `6`

  for mcu=`avr2`, `avr25`, `avr3`, `avr31`, `avr35`, `avr4`, `avr5`, `avr51`, `avr6`,

  respectively and

  `100`, `102`, `103`, `104`, `105`, `106`, `107`

  for mcu=`avrtiny`, `avrxmega2`, `avrxmega3`, `avrxmega4`, `avrxmega5`, `avrxmega6`, `avrxmega7`, respectively. If mcu specifies a device, this built-in macro is set accordingly. For example, with `-mmcu=atmega8` the macro is defined to `4`.

`__AVR_Device__`

  Setting `-mmcu=device` defines this built-in macro which reflects the device’s name. For example, `-mmcu=atmega8` defines the built-in macro `__AVR_ATmega8__`, `-mmcu=attiny261a` defines `__AVR_ATtiny261A__`, etc.

  The built-in macros’ names follow the scheme `__AVR_Device__` where Device is the device name as from the AVR user manual. The difference between Device in the built-in macro and device in `-mmcu=device` is that the latter is always lowercase.

  If device is not a device but only a core architecture like ‘`avr51`’, this macro is not defined.

`__AVR_DEVICE_NAME__`

  Setting `-mmcu=device` defines this built-in macro to the device’s name. For example, with `-mmcu=atmega8` the macro is defined to `atmega8`.

  If device is not a device but only a core architecture like ‘`avr51`’, this macro is not defined.

`__AVR_CVT__`

  The code is being compiled with option `-mcvt` to use a compact vector table.

`__AVR_XMEGA__`

  The device / architecture belongs to the XMEGA family of devices.

`__AVR_HAVE_ADIW__`

  The device has the `ADIW` and `SBIW` instructions.

`__AVR_HAVE_ELPM__`

  The device has the `ELPM` instruction.

`__AVR_HAVE_ELPMX__`

  The device has the `ELPM Rn,Z` and `ELPM Rn,Z+` instructions.

`__AVR_HAVE_LPMX__`

  The device has the `LPM Rn,Z` and `LPM Rn,Z+` instructions.

`__AVR_HAVE_MOVW__`

  The device has the `MOVW` instruction to perform 16-bit register-register moves.

`__AVR_HAVE_MUL__`

  The device has a hardware multiplier.

`__AVR_HAVE_JMP_CALL__`

  The device has the `JMP` and `CALL` instructions. This is the case for devices with more than 8 KiB of program memory.

`__AVR_HAVE_EIJMP_EICALL__`
`__AVR_3_BYTE_PC__`

  The device has the `EIJMP` and `EICALL` instructions. This is the case for devices with more than 128 KiB of program memory. This also means that the program counter (PC) is 3 bytes wide.

`__AVR_2_BYTE_PC__`

  The program counter (PC) is 2 bytes wide. This is the case for devices with up to 128 KiB of program memory.

`__AVR_HAVE_8BIT_SP__`
`__AVR_HAVE_16BIT_SP__`

  The stack pointer (SP) register is treated as 8-bit respectively 16-bit register by the compiler. The definition of these macros is affected by `-mtiny-stack`.

`__AVR_HAVE_SPH__`
`__AVR_SP8__`

  The device has the SPH (high part of stack pointer) special function register or has an 8-bit stack pointer, respectively. The definition of these macros is affected by `-mmcu=` and in the cases of `-mmcu=avr2` and `-mmcu=avr25` also by `-msp8`.

`__AVR_HAVE_RAMPD__`
`__AVR_HAVE_RAMPX__`
`__AVR_HAVE_RAMPY__`
`__AVR_HAVE_RAMPZ__`

  The device has the `RAMPD`, `RAMPX`, `RAMPY`, `RAMPZ` special function register, respectively.

`__NO_INTERRUPTS__`

  This macro reflects the `-mno-interrupts` command-line option.

`__AVR_ERRATA_SKIP__`
`__AVR_ERRATA_SKIP_JMP_CALL__`

  Some AVR devices (AT90S8515, ATmega103) must not skip 32-bit instructions because of a hardware erratum. Skip instructions are `SBRS`, `SBRC`, `SBIS`, `SBIC` and `CPSE`. The second macro is only defined if `__AVR_HAVE_JMP_CALL__` is also set.

`__AVR_ISA_RMW__`

  The device has Read-Modify-Write instructions (XCH, LAC, LAS and LAT).

`__AVR_SFR_OFFSET__=offset`

  Instructions that can address I/O special function registers directly like `IN`, `OUT`, `SBI`, etc. may use a different address as if addressed by an instruction to access RAM like `LD` or `STS`. This offset depends on the device architecture and has to be subtracted from the RAM address in order to get the respective I/O address.

`__AVR_SHORT_CALLS__`

  The `-mshort-calls` command-line option is set.

`__AVR_PM_BASE_ADDRESS__=addr`

  Some devices support reading from flash memory by means of `LD*` instructions. The flash memory is seen in the data address space at an offset of `__AVR_PM_BASE_ADDRESS__`. If this macro is not defined, this feature is not available. If defined, the address space is linear and there is no need to put `.rodata` into RAM. This is handled by the default linker description file, and is currently available for `avrtiny` and `avrxmega3`. Even more convenient, there is no need to use address spaces like `__flash` or features like attribute `progmem` and `pgm_read_*`.

`__AVR_HAVE_FLMAP__`

  This macro is defined provided the following conditions are met:

  - The device has the `NVMCTRL_CTRLB.FLMAP` bitfield. This applies to the AVR64* and AVR128* devices.
  - It’s not known at assembler-time which emulation will be used.

  This implies the compiler was configured with GNU Binutils that implement PR31124.

`__AVR_RODATA_IN_RAM__`

  This macro is undefined when the code is compiled for a core architecture.

  When the code is compiled for a device, the macro is defined to 1 when the `.rodata` sections for read-only data is located in RAM; and defined to 0, otherwise.

`__WITH_AVRLIBC__`

  The compiler is configured to be used together with AVR-LibC. See the `--with-avrlibc` configure option.

`__HAVE_SIGNAL_N__`

  The compiler supports the `signal(num)` and `interrupt(num)` function attributes with an argument num that specifies the number of the interrupt service routine.

`__HAVE_DOUBLE_MULTILIB__`

  Defined if `-mdouble=` acts as a multilib option.

`__HAVE_DOUBLE32__`
`__HAVE_DOUBLE64__`

  Defined if the compiler supports 32-bit double resp. 64-bit double. The actual layout is specified by option `-mdouble=`.

`__DEFAULT_DOUBLE__`

  The size in bits of `double` if `-mdouble=` is not set. To test the layout of `double` in a program, use the built-in macro `__SIZEOF_DOUBLE__`.

`__HAVE_LONG_DOUBLE32__`
`__HAVE_LONG_DOUBLE64__`
`__HAVE_LONG_DOUBLE_MULTILIB__`
`__DEFAULT_LONG_DOUBLE__`

  Same as above, but for `long double` instead of `double`.

`__WITH_DOUBLE_COMPARISON__`

  Reflects the `--with-double-comparison={tristate|bool|libf7}` configure option and is defined to `2` or `3`.

`__WITH_LIBF7_LIBGCC__`
`__WITH_LIBF7_MATH__`
`__WITH_LIBF7_MATH_SYMBOLS__`

  Reflects the `--with-libf7={libgcc|math|math-symbols}` configure option.

#### 3.20.6.5 AVR Internal Options ¶

The following options are used internally by the compiler and to communicate between device specs files and the compiler proper. You don’t need to set these options by hand, in particular they are not optimization options. Using these options in the wrong way may lead to sub-optimal or wrong code. They are documented for completeness, and in order to get a better understanding of device specs files.

`-mn-flash=num` ¶

  Assume that the flash memory has a size of num times 64 KiB. This determines which `__flashN` address spaces are available.

`-mflmap` ¶

  The device has the `FLMAP` bit field located in special function register `NVMCTRL_CTRLB`.

`-mrmw` ¶

  Assume that the device supports the Read-Modify-Write instructions `XCH`, `LAC`, `LAS` and `LAT`.

`-mshort-calls` ¶

  Assume that `RJMP` and `RCALL` can target the whole program memory. This option is used for multilib generation and selection for the devices from architecture `avrxmega3`.

`-mskip-bug` ¶

  Generate code without skips (`CPSE`, `SBRS`, `SBRC`, `SBIS`, `SBIC`) over 32-bit instructions.

`-msp8` ¶

  Treat the stack pointer register as an 8-bit register, i.e. assume the high byte of the stack pointer is zero. This option is used by the compiler to select and build multilibs for architectures `avr2` and `avr25`. These architectures mix devices with and without `SPH`.