#### 3.17.3 AVR Options

These options are defined for AVR implementations:

`-mmcu=`mcu
  Specify ATMEL AVR instruction set or MCU type.

  Instruction set avr1 is for the minimal AVR core, not supported by the C compiler, only for assembler programs (MCU types: at90s1200, attiny10, attiny11, attiny12, attiny15, attiny28).

  Instruction set avr2 (default) is for the classic AVR core with up to 8K program memory space (MCU types: at90s2313, at90s2323, attiny22, at90s2333, at90s2343, at90s4414, at90s4433, at90s4434, at90s8515, at90c8534, at90s8535).

  Instruction set avr3 is for the classic AVR core with up to 128K program memory space (MCU types: atmega103, atmega603, at43usb320, at76c711).

  Instruction set avr4 is for the enhanced AVR core with up to 8K program memory space (MCU types: atmega8, atmega83, atmega85).

  Instruction set avr5 is for the enhanced AVR core with up to 128K program memory space (MCU types: atmega16, atmega161, atmega163, atmega32, atmega323, atmega64, atmega128, at43usb355, at94k).

`-mno-interrupts`
  Generated code is not compatible with hardware interrupts. Code size will be smaller.
`-mcall-prologues`
  Functions prologues/epilogues expanded as call to appropriate subroutines. Code size will be smaller.
`-mtiny-stack`
  Change only the low 8 bits of the stack pointer.
`-mint8`
  Assume int to be 8 bit integer. This affects the sizes of all types: A char will be 1 byte, an int will be 1 byte, a long will be 2 bytes and long long will be 4 bytes. Please note that this option does not comply to the C standards, but it will provide you with smaller code size.

##### 3.17.3.1 `EIND` and Devices with more than 128k 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 address any code address in the range of 64k words.

In order to faciliate indirect jump on devices with more than 128k 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 and are subject to some limitations:

- The compiler never sets `EIND`.
- 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.
- The compiler uses `EIND` implicitely in `EICALL`/`EIJMP` instructions or might read `EIND` directly.
- The compiler assumes that `EIND` never changes during the startup code or run of the application. In particular, `EIND` is not saved/restored in function or interrupt service routine prologue/epilogue.
- It is legitimate for user-specific startup code to set up `EIND` early, for example by means of initialization code located in section `.init3`, and thus prior to general startup code that initializes RAM and calls constructors.
- For indirect calls to functions and computed goto, the linker will generate stubs. Stubs are jump pads sometimes also called trampolines. Thus, the indirect call/jump will jump to such a stub. The stub contains a direct jump to the desired address.
- Stubs will be 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 will emit 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.
- 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.
- 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:

                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.