File: CALLING

package info (click to toggle)
sml-nj 110-4
  • links: PTS
  • area: main
  • in suites: potato, slink
  • size: 23,248 kB
  • ctags: 35,601
  • sloc: ansic: 22,557; asm: 4,998; makefile: 1,421; sh: 1,173; pascal: 256; yacc: 190; perl: 181; lisp: 25
file content (114 lines) | stat: -rw-r--r-- 4,936 bytes parent folder | download
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