123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150 |
- =========================
- MN10300 FUNCTION CALL ABI
- =========================
- =======
- GENERAL
- =======
- The MN10300/AM33 kernel runs in little-endian mode; big-endian mode is not
- supported.
- The stack grows downwards, and should always be 32-bit aligned. There are
- separate stack pointer registers for userspace and the kernel.
- ================
- ARGUMENT PASSING
- ================
- The first two arguments (assuming up to 32-bits per argument) to a function are
- passed in the D0 and D1 registers respectively; all other arguments are passed
- on the stack.
- If 64-bit arguments are being passed, then they are never split between
- registers and the stack. If the first argument is a 64-bit value, it will be
- passed in D0:D1. If the first argument is not a 64-bit value, but the second
- is, the second will be passed entirely on the stack and D1 will be unused.
- Arguments smaller than 32-bits are not coalesced within a register or a stack
- word. For example, two byte-sized arguments will always be passed in separate
- registers or word-sized stack slots.
- =================
- CALLING FUNCTIONS
- =================
- The caller must allocate twelve bytes on the stack for the callee's use before
- it inserts a CALL instruction. The CALL instruction will write into the TOS
- word, but won't actually modify the stack pointer; similarly, the RET
- instruction reads from the TOS word of the stack, but doesn't move the stack
- pointer beyond it.
- Stack:
- | |
- | |
- |---------------| SP+20
- | 4th Arg |
- |---------------| SP+16
- | 3rd Arg |
- |---------------| SP+12
- | D1 Save Slot |
- |---------------| SP+8
- | D0 Save Slot |
- |---------------| SP+4
- | Return Addr |
- |---------------| SP
- | |
- | |
- The caller must leave space on the stack (hence an allocation of twelve bytes)
- in which the callee may store the first two arguments.
- ============
- RETURN VALUE
- ============
- The return value is passed in D0 for an integer (or D0:D1 for a 64-bit value),
- or A0 for a pointer.
- If the return value is a value larger than 64-bits, or is a structure or an
- array, then a hidden first argument will be passed to the callee by the caller:
- this will point to a piece of memory large enough to hold the result of the
- function. In this case, the callee will return the value in that piece of
- memory, and no value will be returned in D0 or A0.
- ===================
- REGISTER CLOBBERING
- ===================
- The values in certain registers may be clobbered by the callee, and other
- values must be saved:
- Clobber: D0-D1, A0-A1, E0-E3
- Save: D2-D3, A2-A3, E4-E7, SP
- All other non-supervisor-only registers are clobberable (such as MDR, MCRL,
- MCRH).
- =================
- SPECIAL REGISTERS
- =================
- Certain ordinary registers may carry special usage for the compiler:
- A3: Frame pointer
- E2: TLS pointer
- ==========
- KERNEL ABI
- ==========
- The kernel may use a slightly different ABI internally.
- (*) E2
- If CONFIG_MN10300_CURRENT_IN_E2 is defined, then the current task pointer
- will be kept in the E2 register, and that register will be marked
- unavailable for the compiler to use as a scratch register.
- Normally the kernel uses something like:
- MOV SP,An
- AND 0xFFFFE000,An
- MOV (An),Rm // Rm holds current
- MOV (yyy,Rm) // Access current->yyy
- To find the address of current; but since this option permits current to
- be carried globally in an register, it can use:
- MOV (yyy,E2) // Access current->yyy
- instead.
- ===============
- SYSTEM CALL ABI
- ===============
- System calls are called with the following convention:
- REGISTER ENTRY EXIT
- =============== ======================= =======================
- D0 Syscall number Return value
- A0 1st syscall argument Saved
- D1 2nd syscall argument Saved
- A3 3rd syscall argument Saved
- A2 4th syscall argument Saved
- D3 5th syscall argument Saved
- D2 6th syscall argument Saved
- All other registers are saved. The layout is a consequence of the way the MOVM
- instruction stores registers onto the stack.
|