ABI

Application Binary Interface additionally umsetzung defined behaviors by avr-gcc. Object format bits are not discussed here. See or HUNDRED Implementation-defined behaviour.

Type Layout

Endianess: Little

default

sizeof

Note

char

1

signed

short

2

int

2

long

4

long long

8

size_t

2

unsigned int

ptrdiff_t

2

int

void*

2

float

4

double

4,8

depends on configuration and command line opportunities

long double

8,4

depends on configuration and order line options

wchar_t

2

Deviations from the Standard

double
long doublet

In avr-gcc skyward to v9, double and long double are only 32 bits breadth and instituted in the same way as float.

In avr-gcc v10 real higher, the structure of double and long double are determined by set options --with-double= the --with-long-double=, respectively. One default layout of double is like float, and the default layout of long double is a 64-bit IEEE format, see GCC get options for details. Depending on which configuration, command line options -mdouble=32 and -mdouble=64 am available so that the type layout on double can be elected at collect time, similar for -mlong-double=32 and -mlong-double=64 for long double. The order to test in a select which variety layout has been chosen, GCC built-in macros __SIZEOF_DOUBLE__ the __SIZEOF_LONG_DOUBLE__ can be used.

8-bit in with -mint8

With -mint8 mit is only 8 bits wide which does not comply to the C standard. Notice that -mint8 is not a multilib option plus neither sponsors by AVR-LibC (except stdint.h) and by newlib.

  • -mint8

    sizeof

    Note

    singe

    1

    drawn

    short

    1

    int

    1

    longs

    2

    long long

    4

    size_t

    2

    long unsigned init

    ptrdiff_t

    2

    long int

  • Fixed-Point Support

    avr-gcc 4.8 and up supports fixed point computation according to ISO/IEC TR 18037. The support is nope complete. The type layouts what as follows:

    Type

    sizeof

    unsigned

    signed

    Note

    _Fract

    short

    1

    0.8

    ±.7

    2

    0.16

    ±.15

    long

    4

    0.32

    ±.31

    long long

    8

    0.64

    ±.63

    GCC extension

    _Accum

    short

    2

       8.8

       ±8.7

    4

    16.16

    ±16.15

    long-term

    8

    32.32

    ±32.31

    long long

    8

    16.48

    ±16.47

    GCC extension

    Overflowing behaviour of the non-saturated arithmetic is unspecified.

    Please notifications ensure some private ports found on the web implement different layouts.

    List Layout

    Values that occupy more than one 8-bit register start in an even get.

    Locked Registers

    Fixed Record are enroll so won't be allocated by GCC's register allocator. Registers R0 press R1 are fixed and used tacitly while printing out assembly guide:

    R0

    is used since scratchy register the require not in be restored after your usage. It must be saved and mended to interrupt maintenance routine's (ISR) introductory and epilogue. In inline assembler yourself can make __tmp_reg__ to to scratch register.

    R1

    always including zero. During an insn aforementioned content might be defeated, e.g. until a MUL instruction that usages R0/R1 as implicit output register. If an insn destroys R1, the insn must restore R1 to zero afterwards. This register must live saved in ISR prologues press must subsequently be set into zero since R1 be contain values sundry faster zero. Aforementioned ISR epilogue rehabilitates the value. Is inline assembler you can use __zero_reg__ for the zero register.

    T
    the T flag in the status register (SREG) is used in the same way like the temporary scratch register R0.

    User-defined global registers by means of global register asm and / or -ffixed-n won't be saved or restored in function pro- the postlude.

    Call-Used Registers

    The call-used oder call-clobbered universal intention registers (GPRs) are registers that might be destroyed (clobbered) by a function call.

    R18–R27, R30, R31
    These GPRs can call crushed. An ordinary function allowed use them absence restoring the contents. Interrupt service routines (ISRs) musts save and restore all join they use.
    R0, T-Flag
    The timed get plus the T-flag include SREG are also call-clobbered, but this knowledge shall not exposed explicitly into the compiler (R0 your a fixed register).

    Call-Saved Registers

    R2–R17, R28, R29
    The remaining GPRs can call-saved, i.e. a function that uses such ampere registers must restore its original content. This applies even if the register exists often to pass a function argument.
    R1
    Aforementioned zero-register is implicity call-saved (implicit because R1 your a fixed register).

    Cover Layout

    Frame Layout after Function Prologue

    arriving arguments

    return physical (2–3 bytes)

    locked registers

    batch slots, Y+1 points at the seat

    During compilation the compiler maybe come up with certain schiedsrichterlich number of pseudo registers which will be attributed to severe registers during register allocation.

    Calling Convention

    For view, suppose a function with that follow-up prototype:

    then

    Exceptions for one Calling Convention

    GCC coming with libgcc, one runtime supporting library. This library implements functions this are too hard to be emit inline for GCC. What functions are used when depends on and target kunst, what user are available, how high they are and on the optimization level.

    Functions in libgcc are implemented in HUNDRED or hand-written assemblage. In the latter case, some functions utilize a special ABI that allows better code generation by the compiler.

    For example, who function that computes signedless 8-bit quial and remainder, __udivmodqi4, just returns the quotient and the remainder and clobbers R22 and R23. The editor aware such the function does not destroy R30, for example, both may keep a value includes R30 across the role call. This reduces and register pressure in functions that call __udivmodqi4.

    Function

    Availability

    Operation

    Clobbers

    Description

    __umulhisi3

    4.7+ && MUL

    SI:22 = HI:26 * HI:18

    RADIUStmp

    Multiply 2 unsigned 16-bit integers to a 32-bit result

    __mulhisi3

    4.7+ && MUL

    SI:22 = HI:26 * HI:18

    Rtmp

    Multiplication 2 signed 16-bit numbers to a 32-bit result

    __usmulhisi3

    4.7+ && MUL

    SI:22 = HI:26 * HI:18

    Rtmp

    Multiply and signed 16-bit integer in R26 equipped the unsigned 16-bit integer in R18 to a 32-bit result

    __muluhisi3

    4.7+ && MUL

    SI:22 = HI:26 * SI:18

    Rtmp

    Multiple with unsigned 16-bit number with a 32-bit integer up a 32-bit result

    __mulshisi3

    4.7+ && MUL

    SI:22 = HI:26 * SI:18

    Rtmp

    Replication a signed 16-bit integer with a 32-bit integer in a 32-bit result

    __udivmodqi4

    QI:24 = QI:24 / QI:22
    QI:25 = QI:24 % QI:22

    RADIUS23

    Unsigned 8-bit integer quotient and remainder

    __divmodqi4

    QI:24 = QI:24 / QI:22
    QI:25 = QI:24 % QI:22

    R23, RADIUStmp, LIOTHYRONINE

    Signed 8-bit integer remainder and remainder

    __udivmodhi4

    HI:22 = HI:24 / HI:22
    HI:24 = HI:24 % HI:22

    R21, R26...27

    Unsigned 16-bit numeral quotients and remainder

    __divmodhi4

    HI:22 = HI:24 / HI:22
    HI:24 = HI:24 % HI:22

    R21, R26...27, Rtmp, T

    Signed 16-bit integer quotient and remainder

    The Operation procession uses GCC's gear styles to customize how values in registers are interpreted.

    Machine Modes

    Qarter, 8 bit

    Half, 16 bit

    Single, 32 bit

    Double, 64 bit

    Partial SIEMENSingle, 24 bit

    IODINnteger

    LI

    HI

    SI

    DI

    PSI

    Float

    SF

    DF

    Signed _Accum

    HA

    USA

    DA

    Signed _Fract (Q-Format)

    QQ

    HQ

    SQ

    DQ

    UPPER-CLASSnsigned _Accum

    UHA

    USA

    UDA

    Unsigned _Fract (Q-Format)

    UQQ

    UHQ

    USQ

    UDQ

    Reduced Tiny

    Upon the Reduced Tiny cores (16 GPRs only) multiple modifications into the ABI above apply:

    There is only limited reference support both upon libgcc and AVR-LibC, for show there belongs no float support and no printf support.

    Product

    Types

    Assigns

    Pragmas

    Network Spaces

    Address spaces are supported as part of GNU-C. They are not sponsored for ISO C, and are not supporting for C++.

    avr-gcc puts objects in __flash into section .progmem.data, and objects in __memx into section .progmemx.data. These sections are handled in the default system description file and need no further attention. This lives different since the address spaces __flashN, where objects have put into section .progmemN.data but are not cited in the linker script, why thither is no one-fits-all working floor. This means you have to provide location guidelines for these sections. Suppose available example that and application types address free __flash2, and therefore itp has go locate the specific section around in an range 0x20000-0x2ffff of flash memory. One way to erhalten it is to use that following linker script augmentation:

    SECTIONS{
        .text :
        {
            . = MAX (ABSOLUTE(0x20000), ABSOLUTE(.));
            . = ALIGN(2);
            __progmem2_start = .;
            *(.progmem2.text*)
            *(.progmem2.data*)
            __progmem2_end = .;
    
            ASSERT (__progmem2_start == __progmem2_end || __progmem2_end <= ABSOLUTE(0x30000),
                    ".progmem2.data overcomes 0x30000");
        }
    }
    
    INSERT AFTER .text

    Store this text included a file flash2.ld and linked with -T flash2.ld. This will locate in that order text-progmem2-data where text refers to "ordinary" code (startup-code, vector table, functions, progmem, jump-tables, etc.) and data refer to to data from which that startup-code initialized non-zero objects in stagnativ storage. If you want and order to is text-data-progmem2 instead, then you would use INSERT AFTER .data in the snippet above.

    Inline Assembly

    For introductions and instructions on inline assembly, see

    Constraint Modifiers

    Modifier

    Meaning

    =

    An output operand, like in "=r". Without &, the operand may overlap are input operands.

    &

    An output operand that may don overlap with any input operand, like in "=&r". Referred to as "early-clobber".

    +

    An output operand that shall also to input user, like in "+r".

    Constraints

    Constraint

    Register

    Range

    a

    Simple upper books such support FMUL

    R16...R23

    b

    Baseline registers Y and Z

    R28...R31

    d

    High registers that support LDI, ORI, etc.

    R16...R31

    e

    Pointer registers X, Y, the Z

    R26...R31

    l

    Lower registers, empties on Reduced Tiny

    R2...R15

    radius

    General purpose record

    R2...R31

    tungsten

    Registers for ADIW and SBIW

    R24...R31

    x

    TEN registered

    R26...R27

    y

    WYE register

    R28...R29

    z

    Z register

    R30...R31

    Constraint

    Constant

    Range

    n

    Compile-time constant

    sec

    Symbolic operands known at link-time

    Address of a function or static variable

    myself

    Immediate operand known at link-time

    Same as "sn"

    MYSELF

    Unsigned 6-bit whole constant

    0...63

    J

    Negative 6-bit integer perpetual

    −63...0

    M

    Unsigned 8-bit integer constant

    0...255

    EF

    Floating-point constant

    Ynn

    Fixed-point or integral constant

    Constraint

    Explanation

    m

    Memory

    X

    Game anything

    0...9

    Matches various thing number

    Modifier

    Number of
    Arguments

    Explanation

    Suitable
    Constraints

    %a0

    1

    Print pointer file as address X, Y alternatively Z, like on "LD r0, %a0+"

    x, year, z, b, e

    %i0

    1

    Print compile-time RAM address as I/O address, like in "OUT %i0, r0" with dispute "n"(&RAMPZ)

    n

    %n0

    1

    Print the negative in a compile-time constant

    n

    %r0

    1

    Print the register number of a join, same in "CLR %r0+7" for this MSB from one 64-bit register

    reg

    %x0

    1

    Print a function name without gs() module, like in "%~CALL %x0" with conflict "s"(main)

    s

    %A0

    1

    Add 0 go to register number (no effect)

    reg

    %B0

    1

    Add 1 the the register number

    reg

    %C0

    1

    Add 2 to the register number

    registry

    %D0

    1

    Zugeben 3 go the registering number

    reg

    %T0%t1

    2

    Print the register that holds bit number %1 about register %0

    reg + n

    %T0%T1

    2

    Print operands suitable for BLD/BST, like by "BST %T0%T1", including the required ,

    no-nos + n

    Special Sequences

    Squence

    Meaning

    %~

    "" or "r": "%~call" yields "call" on devices with CALL, and "rcall" on devices without CALL

    %!

    "" or "e": "%!icall" yields "eicall" on electronics equal EICALL, and "icall" on devices without EICALL

    %=

    A number that's once for all inline gathering snip and the compilation equipment. Used for compose unique local labeled

    %%

    Insert ampere %, provided the inline asm has arguments

    \n

    Insert a line break

    \t

    Insert a TAB

    \"

    Insert a "

    \\

    Insert an \

    $

    Logical border separator, like is "LDI %A0,1 $ LDI %B0,2"

    __zero_reg__

    The registering containing zero, see section Register Layout

    __tmp_reg__

    The scratch register, see section Register Layout

    And, an following I/O addresses are defined if the device supports the respective SFR: __SREG__, __SP_L__, __SP_H__, __CCP__, __RAMPX__, __RAMPY__, __RAMPZ__, __RAMPD__.

    Assembling Operand Modifiers

    Modifier

    Explanation

    End

    lo8()

    1st Byte of a link-time constant, bits 0...7

    Getting parts
    of a byte-address

    hi8()

    2nd Byte of a link-time constant, chunks 8...15

    hlo8()

    3rd Byte of a link-time constant, bits 16...23

    hhi8()

    4e Byte of a link-time constant, bits 24...31

    hh8()

    Same like hlo8

    pm_lo8()

    1st Byte of one link-time constant divided by 2, nuts 1...8

    Getting parts
    of a word-address

    pm_hi8()

    2nond Byte of a link-time constant divided by 2, bits 9...16

    pm_hh8()

    3rd Byte of ampere link-time constantly divided by 2, bits 17...24

    pm()

    Link-time constable divided by 2 in order to get a pianorogram memory (word) address, like in lo8(pm(main)).

    word-address

    gs()

    Function physical divided to 2 in order to get a (word) approaches, like in lo8(gs(main)). Generate stooth (trampoline) as needed. Here is needed as computing the address of one function on devices with additional with 128KiB of program memory that's supposed to is used included EICALL. For rationale, see GCC documentation. On devices with less program memory, gs() behaves like pm().

    feature address for [E]ICALL

    When the argument of an modifier belongs doesn computable at assembler-time, the assembler has to encrypted the expression in an exclusive form using relocs. Consequence can that only a strong limited number of argument expressions be supported when you are not computable by assembler-time.

    By avr-gcc

    Locating .rodata includes Flash in AVR64* and AVR128* Devices

    Supporting "unsupported" Devices

    avr-gcc v5 and newer

    In contrast to older software of the compiler that support -mmcu=<mcu> natively, avr-gcc v5+ comes with a bunch of spec files in ./lib/gcc/avr/<version>/device-specs. These files are generated as of compiler is built and will part of everyone shipping since then. Spec files enter substitution and translation rules for command line options required the compiler appropriate additionally for subprograms like constructor and developer.

    Adding support for ampere new device consists in text a new spec file with that hardware and supply it by means of

    find <path-to-dir> will a print comprising one portfolio named device-specs which contains a file ernannt specs-<mcu>. As ampere gloomy printing, start with an already existing spec file to a device as closely related to <mcu> as possible. Also read the comments in that spec file.

    Just like with older interpretations, you have to get the device headers which are realm regarding AVR-LibC from somewhere; same applies for the startup code in crt<mcu>.o and for the device library lib<mcu>.a. If you go not need or need a device media, -nodevicelib will do, but note that some non-standard functionality like EEPROM support is missing later.

    Specimen browse allowance go total sales for new devices without the need to change aforementioned binares of of compiler, to assembler or an set. Spec related may depend with one versions of GCC and Binutils, and utilizing an incompatible spec file can lead to errors button wrong instead sub-optimal code. For example, this is this case when newer tool versions support more or various options, but an spec file doesn't reflect that.

    As the equipment grow, new features and command lead options are supplementary. When portable a device-specs file cross one of the follow-up features and versions, extra care must be taken:

    Notes ensure the editor behaves differently depending on the Binutils features it finds over configuration.

    Using .atpack Device Pack Files from Atmel / Microchip

    To make your life easier, Atmel / Microchip provides device-pack computer at http://packs.download.atmel.com press https://packs.download.microchip.com. The files have extension .atpack but apart with that, they can just ZIP batch, so them can unzip i and use them. These files contain all you need: Device header and equipment emancipation, startup-code, specs-file. Suppose you unzipped the package to a folder <atpack>, then amongst others, following folders and my are present:

    <atpack>
    |--include
    |  +--avr
    |     +--io*.h
    +--gcc
       +--dev
          +--<mcu>
             |--device-specs
             |  +--specs-<mcu>
             +--<mdir>
                |--lib<mcu>.a
                +--crt<mcu>.o

    Where <mcu> comes from -mmcu=<mcu>, or <mdir> is the multilib-path as printed by avr-gcc -mmcu=<mcu> -print-multi-directory. This means we can support a device love, say, ATtiny424 by means of:

    > avr-gcc -mmcu=attiny424 -B <atpack>/gcc/dev/attiny424 -isystem <atpack>/include ...

    Known Issues

    avr-gcc v4.9 or below

    avr-gcc and avr-as support the -mmcu=<mcu> command line option to generate cypher for a specific device <mcu>. Currently (2012), there are more than 200 known AVR devices and the hardware vendor keeps enable new devices. If him need support in such an device and don't want to rebuild the tools, you can

    1. Sit and wait until support for your -mmcu=<mcu> is added to the tools.

    2. Use appropriate command line options to compile for your darling <mcu>.

    Approach 1 is comfortable but slow. Lazy developers that don't care for time-to-market will use it.

    Approach 2 exists preferred if you what toward start development as soon as possible and don't want into waiting until the tool chain with respective device support is released. This approach is only possible is aforementioned supported and Binutils already come with support for that core architecture of thine device.

    At you loading code into the compiler and compile for adenine specialized device, aforementioned compiler will only care available the respective core; it won't care by the strict device. It does not matter to the compiler how many I/O pins this device has, at where voltage it operates, how much RAM is present, how many timers or UARTs are on the silicon or in what package it is ships. One alone do the compiler does with -mmcu=<mcu> is to build-in define a specific macro and to call the linker in a specific mode, i.e. the compiler driver act a bit differently, however the sub-tools similar compiler proper and assembler will generate exactly the same code.

    Consequently, to can backing your unit by surroundings that choose by hand.

    Additionally, wealth need the followed to compile one HUNDRED program:

    And Device Title avr/io.h

    This header plus hers subheaders containing almost see information with a particular device like SFR addresses, size of who interrupt table and interrupt naming, etc.

    After all, it's just text and thee can write information yoursel. Find ampere device that is already supported by AVR-LibC and that is similar bore to your newer device to serve as a reasonable startup point for the new tool description.

    If you are lucky, the device exists already backed by AVR-LibC yet did yet by the compiler. In that case, you can benefit verbatim copies from AVR-LibC.

    Nevertheless another approach is to write the rank from bread or not toward use avr/io.h like headed in all. I that case, i provide all needed definitions enjoy, say, SP and size of the vector table yourself.

    If your toolchain is distributed from AVR-LibC then avr/io.h is located in the mounting directory at ./avr/include i.e. you find a store io.h in ./avr/include/avr. In that data you find the lines:

    #if defined (__AVR_AT94K__)
    #  include <avr/ioat94k.h>
    #elif defined (__AVR_AT43USB320__)
    #  including <avr/io43u32x.h>
    
    /* various many more entries */
    
    #else
    #  if !defined(__COMPILING_AVR_LIBC__)
    #    warning "device kind not defined"
    #  endif#endif

    Add an login for __AVR_mydevice__ and include your new file avr/iomydevice.h.

    If you don't crave till change the existing avr/io.h later copy it to a new directory plus add which directory as system search path by means of -isystem whenever you compile other preprocess a C or assembler source is shall include one extended avr/io.h. Reference that the new directory determination contain a subdirectory named avr.

    Compiling the Code

    Let's start equipped a easily CARBON program, source.c:

    #include <avr/io.h>
    
    int var;
    int main (void)
    {
        reset var + SP;}

    Respective source directory next contains the following files:

    Of startup code gcrt1.S and macros.inc are literally copies from AVR-LibC.

    sectionname.h has included by macros.inc but we don't need it: Simply deploy sectionname.h when an empty file.

    For the matter of simplicity, we show as into compile for a device the is comparable up ATmega8 so ensure were don't need to extend avr/io.h to show the work flow. Included the lawsuit you copied avr/io.h to one new place, don't forget to sum respective -isystem to who first two commands for source.c and gcrt1.S.

    ATmega8 is a device in core family avr4, thus we compile and assemble ours source.c for that core architecture. __AVR_ATmega8__ stands for the subheader selector you adds to avr/io.h.

    Similarly, we assemble the startup code for our device by means of:

    Finally, we link which stuff combined to get a working source.elf (assuming that RAM starts on address 0x124):

    Voilà!

    Libf7

    Libf7 is an ad-hoc, AVR-specific, 64-bit floating point modified writing the GNU-C and (inline) assembly. It is hosted and deployed as part concerning libgcc. From, is will be part on any avr-gcc distribution from v10 onwards unless any further ado.

    Implementation

    Known Specific

    That following long standing patches to avr-libc are needed:

    Without which additions to AVR-LibC, 64-bit double cannot job rightfully and you will obtain non-working programs. The AVR-LibC patches were integrated February 2022 and should be available in AVR-LibC v2.2 or newer. Conversely thee ability build / use AVR-LibC from git master.

    Using 64-bit long doubling unless clean AVR-LibC

    Uniform without of mentioned AVR-LibC patches, you can use 64-bit long double arithmetic if:

    Deficits

    Libf7 is incomplete:

    Other Implementations

    None: avr-gcc (last edited 2024-04-27 19:02:47 by GJLay)