-*- text -*- Proposed application binary interface for PDP-10 code generated by GCC. Register numbers in octal notation. Register usage: Register 17 is used as the stack pointer. Register 16 may be used as a frame pointer, or as a general- purpose register. A frame pointer simplifies debugging, but is usually not necessary to generate functional code. ?? Register 15 may be used as an auxiliary register for position-independent code, if PIC would ever be needed. Register preservation: A function may use registers 0 through 4 without preserving their contents. Registers 5 through 17 must be preserved. Argument passing: Registers 1 through 4 are used to pass arguments. An argument at most one word in size is passed in one register. Arguments larger than one word may span several contigous registers, and are stored as in memory. Arguments may be passed part in registers, part on stack (FIXME: which part in registers, which part on stack?). The first argument is passed starting from register 1. The following arguments are passed in higher-numbered registers if possible, or else on stack if all argument-passing registers are occupied. The last argument is pushed to stack first. The stack grows upwards in memory, as is natural for the PUSH instruction. Return address: The return address is pushed to stack after the arguments. Return value passing: Values at most one word in size are returned in register 1. Values at most two words in size are returned in registers 1 and 2, and are stored as in memory. Values larger than two words are returned in a memory block. The address to this memory block is passed as the first argument to the function. This argument is invisible in high- level languages. Stack layout: A function caller stores argument words 1 through 4 in the corresponding registers. The rest of the arguments words are stored in the stack space which is reserved for outgoing arguments. Then the caller pushes the return address and jumps to the callee. The stack as seen by the callee is thus: [ ... ] [ arg word 6 ] [ arg word 5 ] sp -> [ return address ] In a callee which takes a variable number of arguments, some arguments stored in registers 1 through 4 may have to be stored in the stack. Of the register arguments, the last fixed and all variable arguments are pushed. The return address will then have to be moved away to the top of the stack. For example, if the callee has only one fixed argument, the stack looks like this: [ ... ] [ arg word 6 ] [ arg word 5 ] [ arg word 4 ] <- Old return address location. [ arg word 3 ] [ arg word 2 ] [ arg word 1 ] sp -> [ return address ] The function prologe proceeds by pushing all callee-saved registers that is clobbered by the callee to stack. In this example, all registers are saved: [ ... ] [ arg word 6 ] [ arg word 5 ] [ arg word 4 ] [ arg word 3 ] [ arg word 2 ] [ arg word 1 ] [ return address ] [ saved reg 5 ] [ saved reg 6 ] [ saved reg 7 ] [ saved reg 10 ] [ saved reg 11 ] [ saved reg 12 ] [ saved reg 13 ] [ saved reg 14 ] [ saved reg 15 ] sp -> [ saved reg 16 ] Finally, space is reserved for local variables and outgoing arguments, and optionally, a frame pointer is set up to point to the location which contains the return address: [ ... ] [ arg word 6 ] [ arg word 5 ] [ arg word 4 ] [ arg word 3 ] [ arg word 2 ] [ arg word 1 ] fp -> [ return address ] [ saved reg 5 ] [ saved reg 6 ] [ saved reg 7 ] [ saved reg 10 ] [ saved reg 11 ] [ saved reg 12 ] [ saved reg 13 ] [ saved reg 14 ] [ saved reg 15 ] [ saved reg 16 ] [local variable 1] [local variable 2] [local variable 3] [ ... ] [ outgoing arg 6 ] [ outgoing arg 5 ] sp -> [ outgoing arg 4 ] Before returning, the callee must restore the stack to the way it looked before the function prologue started to modify it. This means that the stack pointer and the location originally containing the return address must be restored.