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 mcus 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.
avr1This 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-notesRecognize 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=bitsSet 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.
-mfract-convert-truncate ¶Allow to use truncation instead of rounding towards zero for fractional fixed-point types.
-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.
-mpmem-wrap-around ¶Enable program counter wrap-around in linker relaxation.
-mrodata-in-ram ¶-mno-rodata-in-ramLocate 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.
-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 assembly code generated by the compiler is the same, but the instructions in the executable may differ from instructions in the assembly code.
Relaxing can be used to remove unused linker stubs, see the
section on EIND and linker stubs below.
-mprune-vectab ¶Remove unused entries in the AVR-LibC interrupt vector table during relaxing.
An entry is unused when it targets __bad_interrupt and all following
entries are also unused.
Setting -mprune-vectab just adds the --prune-vectab option to the linker’s command line, provided the required GNU Binutils support (PR34679) is available. Otherwise, or when relaxing is not enabled, the option has no effect. This option makes it harder to find rogue IRQs that lack an interrupt service routine (ISR) and whose IRQ vector is located beyond the last used one.
What is not supported are jumps like
JMP 0x18
that target a vector table entry that is not the reset vector. Use code like
JMP __vectors + 0x18
instead.
-mstrict-addr-space-subsets ¶Impose strict named address space subset relations. Without this option, every address space is considered to be a subset of all the other spaces, which allows to write code like
char read_char (const char *addr, bool in_flash)
{
return in_flash
? *(const __flash char*) addr // Read from program memory.
: *addr; // Read from RAM.
}
When the option is on, such code is rejected since address space
__flash is not a subset of the generic space, and hence the
cast in the above code is prohibited.
-mtiny-stack ¶Only change the lower 8 bits of the stack pointer.
-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.
EIND and Devices with More Than 128 Ki Bytes of FlashRAMPD, RAMPX, RAMPY and RAMPZ Special Function RegistersThe following options are pure optimization options. Options -mgas-isr-prologues, -mmain-is-OS_task, -mno-call-main, -mrelax and -mprune-vectab 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.
-mdemote-switch ¶Without this option, the compiler will treat switch variables
as 32-bit values at least. When this option is on, an AVR-specific
pass will try to demote such switch variables to the widths
as actually used in the program. This option is on per default when
optimization is on.
-mfuse-add ¶-mno-fuse-add-mfuse-add=levelOptimize 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-ifelse ¶Optimize compare-branch-compare-branch sequences to compare-branch-branch, which typically occurs in if-else trees generated from dense switch statements. This option is enabled per default if optimization is on.
-mfuse-move ¶-mno-fuse-move-mfuse-move=levelRun 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.
-mno-optimize ¶-moptimizeDisable / enable AVR-specific optimization passes, all documented in this paragraph: -mdemote-switch, -mfuse-add, -mfuse-ifelse, -mfuse-move, -mfuse-move2, -msplit-ldst, -msplit-bit-shift, -muse-nonzero-bits. Usually, you don’t need to specify this option because the respective passes are activated by default when optimization is on.
-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.
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:
EIND.
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.
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.
EICALL/EIJMP jumps to such a
stub, which contains a direct JMP to the desired address.
.trampolines section contains unused stubs that target
locations in the same 128 KiB block like the trampolines.
Linker relaxation can be turned on to remove such unused stubs, see
the compiler option -mrelax and the linker option --relax.
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.
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.
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.
gs modifier
(short for generate stubs) like so:
LDI r24, lo8(gs(func)) LDI r25, hi8(gs(func))
gs modifier behaves
like pm, i.e. it evaluates to the word address of the symbol
without generating a stub.
gs modifiers for code labels in the
following situations:
gs() modifier explained above.
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.
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.
RAMP special function
registers with zero.
__flash is used, then RAMPZ is set
as needed before the operation.
RAMPZ to accomplish an operation, RAMPZ
is reset to zero after the operation.
RAMP register, the ISR
prologue/epilogue saves/restores that SFR and initializes it with
zero in case the ISR code might (implicitly) use it.
RAMP registers,
you must reset it to zero after the access.