Calling Convention

AVR

The Caller

The Caller pushes the Arguments on the Stack in Order.

The Callee

The Callee then must pop them into registers in reverse Order. That happens before anything else in the Callee.

Example - IR

TAC_CONST_VALUE t1 = 19
TAC_PARAM t1
TAC_CONST_VALUE t2 = 24
TAC_PARAM t2
TAC_CALL myfunction
TAC_RETURN t2
----------------
TAC_CONST_VALUE t0 = 0
TAC_RETURN t0

Example - AVR Assembler

main:
ldi r16, 19
push r16
ldi r16, 24
push r16
call myfunction
mov r0, r16
ret

myfunction:
pop r17
pop r18
ret

x86-64 Backend

For the x86-64 backend, espl is using the System V AMD64 ABI. Basically what gcc is doing on Linux.
So there is nothing special here. This is to make it easier to call C code.

integer / pointer arguments

Usage Storage
return value rax
arg 0 rdi
arg 1 rsi
arg 2 rdx
arg 3 rcx
arg 4 r8
arg 5 r9
arg > 5 stored on stack

caller/callee saved registers

Example (x86-64)

Example to see the stack usage for local variables. This is implementation detail (not part of calling convention).

Example Code
fn f1 (int8 arg0, int8 arg1) ~> int {
	int16 x = 0; // local var 0, 2 bytes
	int8 y = 0;  // local var 1, 1 byte
	x += 1;
	return x
}
	
Example Stack Fragments
...                   |
return address byte 1 |
return address byte 0 | <- rsp
                      | ...
                      | 0x0

...                   |
return address byte 1 |
return address byte 0 |
... callee saved regs | <- rsp (callee saved registers have been pushed)
                      | ...
                      | 0x0


...                   |
return address byte 1 |
return address byte 0 |
... callee saved regs | <- rbp, rsp (rbp has been set)
                      | ...
                      | 0x0

...                   |
return address byte 0 |
... callee saved regs | <- rbp
                      | ...
                      | <- rsp  (has been decremented by 5 bytes to make space for local vars and args)
                      | ...
                      | 0x0

...                   |
return address byte 0 |
... callee saved regs | <- rbp
local var 0, byte 1   |
local var 0, byte 0   |
local var 1, byte 0   |
arg 0, byte 0         |
arg 1, byte 0         | <- rsp
                      | ...
                      | 0x0

...                   |
return address byte 0 |
... callee saved regs |<- rbp, rsp (rsp has been reset before return)
                      | ...
                      | 0x0

...                   |
return address byte 0 | <- rbp, rsp (callee saved regs have been restored)
                      | ...
                      | 0x0
	

References for x86-64 Calling Conventions