1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114
|
SML/NJ 106.4 Function Calling Convention
(12/1/94, Zhong Shao)
I. CLASSIFICATION OF FUNCTIONS
------------------------------
Let's divide all the functions into the following three categories:
(1) Escaping User Functions (EUF) ---
These are normal escaping functions (in the source program),
exception handler continuations, or callcc continuations.
All functions in this category must take a return continuation
as one of its argument. The CPS conversion rewrites each exception
handler continuation (and callcc continuation) "k" into a user
function that takes a dummy continuation (never called) as the
default return continuation argument.
(2) Known Functions (KF) ---
These are all functions whose call sites are all known at compile time.
They MAY or MAY NOT take a return continuation as its argument.
(3) Return Continuation Functions (RCF) ---
These must be "well-behaved" continuation functions. They DO NOT
take any continuation argument.
II. ASSUMPTION ON REGISTERS (see cps/generic.sml)
-------------------------------------------------
GPR 0 --- standard link
GPR 1 --- standard closure
GPR 3 --- standard cont
GPR 2,4,5,6,..,N and FPR 1,2,3,...,M --- standard arg and misc regs
Given a strandard "n"-argument function (either EUF or RCF), suppose
among these "n" arguments, p of them are non-floating-point type,
i.e., a_1,...,a_p, and n-p of them are floating-point type, i.e,
b_1,...,b_n-p. Assume there are "k" general-purpose callee-save
registers (these will be GPR 3,...k+2, see Below for details)
and "j" floating-point callee-save registers (these will be FPR 1,
..., j). Then, standard arguments
a_1,...,a_p will be assigned GPR 2,k+4,5,...,k+p+2;
b_1,...,b_n-p will be assigned FPR j,j+1,3,...,j+n-p-1.
Right now, the number of floating-point callee-save registers
is usually 0 (see !CG.fpcalleesaves).
III. CASE A (no callee-save register, i.e., !CG.calleesaves = 0)
----------------------------------------------------------------
(* This case applies to platform such as M68 and X86. Because of
* severe lack of registers, we use 0 GPR calleesave registers and
* 0 FPR calleesave registers. EUF and RCF functions always use
* GPR 2 to pass its standard argument. KF might use multiple registers
* to pass arguments. Anyway, representation analysis is turned off
* by default.
*)
(1) If f is a EUF, and f's arguments are (x1, x2, x3, x4)
x1 ------ GPR 0 --- the link register, i.e, f's code pointer
x2 ------ GPR 1 --- a pointer to f's closure
x3 ------ GPR 3 --- a pointer to f's return continuation closure
x4 ------ GPR 2 --- standard argument
(2) If f is a KF, and f's arguments are (x1, x2, ..., xN)
No standard conventions, x1-xN can be anything. But the order
of each x1-xN is strictly first the closure for f's return
continuation (if there is any), then f's standard arguments,
and then f's environment (free variables).
(3) If f is a RCF, and f's arguments are (x1, x2, x3}
x1 ------ GPR 0 --- the link register, i.e, f's code pointer
x2 ------ GPR 1 --- a pointer to f's closure
x3 ------ GPR 2 --- standard arguments
IV. CASE B (with k callee-save register, i.e., !CG.calleesaves = k)
-------------------------------------------------------------------
(* This case applies to platform such as SPARC, MIPS, RS6000 and Alpha32.
* Normally, we use 3 GPR calleesave registers and 0 FPR calleesave
* registers.
*
* NOTE: Alpha32 currently does not use floating point registers to
* pass arguments or return results at function applications. This will
* be supported in the future.
*)
By Default, k callee-save registers are always [GPR 4, GPR 5, ..., GPR 3+k].
(1) If f is a EUF, and f's arguments are (x1, x2, x3, x4, ..., xN)
x1 ------ GPR 0 --- the link register, i.e, f's code pointer
x2 ------ GPR 1 --- a pointer to f's closure
x3 ------ GPR 3 --- a pointer to f's return continuation code pointer
x4-x(k+3) --- GPR [4,...,k+3] --- calleesave registers for x3
x(k+3)-xN --- GPR [2,k+4,...] and FPR [...] --- standard arguments
(2) If f is a KF, and f's arguments are (x1, x2, ..., xN)
No standard conventions, x1-xN can be anything. But the order
of each x1-xN is strictly first f's return continuation and its
callee-save registers (if there is any), and then f's standard
arguments, and then f's environment (free variables).
(3) If f is a RCF, and f's arguments are (x1, x2, x3, ..., xN)
x1 ------ GPR 3 --- a pointer to f's code pointer (link register)
x2-x(k+1) --- GPR [4,...,k+3] --- calleesave registers for f
x(k+2)-xN --- GPR [2,k+4,...] and FPR [...] --- standard arguments
|