201 lines | 5423 chars
1 | /*********************************************************************/ |
2 | /* */ |
3 | /* OCaml */ |
4 | /* */ |
5 | /* Xavier Leroy, projet Cristal, INRIA Rocquencourt */ |
6 | /* */ |
7 | /* Copyright 1996 Institut National de Recherche en Informatique et */ |
8 | /* en Automatique. All rights reserved. This file is distributed */ |
9 | /* under the terms of the Q Public License version 1.0. */ |
10 | /* */ |
11 | /*********************************************************************/ |
12 | |
13 | #if defined(MODEL_ppc64) || defined(MODEL_ppc64le) |
14 | #define EITHER(a,b) b |
15 | #else |
16 | #define EITHER(a,b) a |
17 | #endif |
18 | |
19 | #define WORD EITHER(4,8) |
20 | #define lg EITHER(lwz,ld) |
21 | #define lgu EITHER(lwzu,ldu) |
22 | #define stg EITHER(stw,std) |
23 | #define stgu EITHER(stwu,stdu) |
24 | |
25 | #if defined(MODEL_ppc) |
26 | #define RESERVED_STACK 16 |
27 | #define LR_SAVE_AREA 4 |
28 | #endif |
29 | #if defined(MODEL_ppc64) |
30 | #define RESERVED_STACK 48 |
31 | #define LR_SAVE_AREA 16 |
32 | #endif |
33 | #if defined(MODEL_ppc64le) |
34 | #define RESERVED_STACK 32 |
35 | #define LR_SAVE_AREA 16 |
36 | #endif |
37 | |
38 | /* Function definitions */ |
39 | |
40 | #if defined(MODEL_ppc) |
41 | #define FUNCTION(name) \ |
42 | .section ".text"; \ |
43 | .globl name; \ |
44 | .type name, @function; \ |
45 | .align 2; \ |
46 | name: |
47 | #endif |
48 | |
49 | #if defined(MODEL_ppc64) |
50 | #define FUNCTION(name) \ |
51 | .section ".opd","aw"; \ |
52 | .align 3; \ |
53 | .globl name; \ |
54 | .type name, @function; \ |
55 | name: .quad .L.name,.TOC.@tocbase; \ |
56 | .text; \ |
57 | .align 2; \ |
58 | .L.name: |
59 | #endif |
60 | |
61 | #if defined(MODEL_ppc64le) |
62 | #define FUNCTION(name) \ |
63 | .section ".text"; \ |
64 | .globl name; \ |
65 | .type name, @function; \ |
66 | .align 2; \ |
67 | name: ; \ |
68 | 0: addis 2, 12, (.TOC. - 0b)@ha; \ |
69 | addi 2, 2, (.TOC. - 0b)@l; \ |
70 | .localentry name, . - 0b |
71 | #endif |
72 | |
73 | FUNCTION(call_gen_code) |
74 | /* Allocate and link stack frame */ |
75 | stgu 1, -(WORD*18 + 8*18 + RESERVED_STACK)(1) |
76 | /* 18 saved GPRs, 18 saved FPRs */ |
77 | /* Save return address */ |
78 | mflr 0 |
79 | stg 0, (WORD*18 + 8*18 + RESERVED_STACK + LR_SAVE_AREA)(1) |
80 | /* Save all callee-save registers, starting at RESERVED_STACK */ |
81 | addi 11, 1, RESERVED_STACK - WORD |
82 | stgu 14, WORD(11) |
83 | stgu 15, WORD(11) |
84 | stgu 16, WORD(11) |
85 | stgu 17, WORD(11) |
86 | stgu 18, WORD(11) |
87 | stgu 19, WORD(11) |
88 | stgu 20, WORD(11) |
89 | stgu 21, WORD(11) |
90 | stgu 22, WORD(11) |
91 | stgu 23, WORD(11) |
92 | stgu 24, WORD(11) |
93 | stgu 25, WORD(11) |
94 | stgu 26, WORD(11) |
95 | stgu 27, WORD(11) |
96 | stgu 28, WORD(11) |
97 | stgu 29, WORD(11) |
98 | stgu 30, WORD(11) |
99 | stgu 31, WORD(11) |
100 | stfdu 14, 8(11) |
101 | stfdu 15, 8(11) |
102 | stfdu 16, 8(11) |
103 | stfdu 17, 8(11) |
104 | stfdu 18, 8(11) |
105 | stfdu 19, 8(11) |
106 | stfdu 20, 8(11) |
107 | stfdu 21, 8(11) |
108 | stfdu 22, 8(11) |
109 | stfdu 23, 8(11) |
110 | stfdu 24, 8(11) |
111 | stfdu 25, 8(11) |
112 | stfdu 26, 8(11) |
113 | stfdu 27, 8(11) |
114 | stfdu 28, 8(11) |
115 | stfdu 29, 8(11) |
116 | stfdu 30, 8(11) |
117 | stfdu 31, 8(11) |
118 | /* Get function pointer in CTR */ |
119 | #if defined(MODEL_ppc) |
120 | mtctr 3 |
121 | #elif defined(MODEL_ppc64) |
122 | ld 0, 0(3) |
123 | mtctr 0 |
124 | ld 2, 8(3) |
125 | #elif defined(MODEL_ppc64le) |
126 | mtctr 3 |
127 | mr 12, 3 |
128 | #else |
129 | #error "wrong MODEL" |
130 | #endif |
131 | /* Shuffle arguments */ |
132 | mr 3, 4 |
133 | mr 4, 5 |
134 | mr 5, 6 |
135 | mr 6, 7 |
136 | /* Call the function */ |
137 | bctrl |
138 | /* Restore callee-save registers */ |
139 | addi 11, 1, RESERVED_STACK - WORD |
140 | lgu 14, WORD(11) |
141 | lgu 15, WORD(11) |
142 | lgu 16, WORD(11) |
143 | lgu 17, WORD(11) |
144 | lgu 18, WORD(11) |
145 | lgu 19, WORD(11) |
146 | lgu 20, WORD(11) |
147 | lgu 21, WORD(11) |
148 | lgu 22, WORD(11) |
149 | lgu 23, WORD(11) |
150 | lgu 24, WORD(11) |
151 | lgu 25, WORD(11) |
152 | lgu 26, WORD(11) |
153 | lgu 27, WORD(11) |
154 | lgu 28, WORD(11) |
155 | lgu 29, WORD(11) |
156 | lgu 30, WORD(11) |
157 | lgu 31, WORD(11) |
158 | lfdu 14, 8(11) |
159 | lfdu 15, 8(11) |
160 | lfdu 16, 8(11) |
161 | lfdu 17, 8(11) |
162 | lfdu 18, 8(11) |
163 | lfdu 19, 8(11) |
164 | lfdu 20, 8(11) |
165 | lfdu 21, 8(11) |
166 | lfdu 22, 8(11) |
167 | lfdu 23, 8(11) |
168 | lfdu 24, 8(11) |
169 | lfdu 25, 8(11) |
170 | lfdu 26, 8(11) |
171 | lfdu 27, 8(11) |
172 | lfdu 28, 8(11) |
173 | lfdu 29, 8(11) |
174 | lfdu 30, 8(11) |
175 | lfdu 31, 8(11) |
176 | /* Reload return address */ |
177 | lg 0, (WORD*18 + 8*18 + RESERVED_STACK + LR_SAVE_AREA)(1) |
178 | mtlr 0 |
179 | /* Return */ |
180 | addi 1, 1, (WORD*18 + 8*18 + RESERVED_STACK) |
181 | blr |
182 | |
183 | FUNCTION(caml_c_call) |
184 | /* Jump to C function (address in r28) */ |
185 | #if defined(MODEL_ppc) |
186 | mtctr 28 |
187 | #elif defined(MODEL_ppc64) |
188 | ld 0, 0(28) |
189 | mtctr 0 |
190 | ld 2, 8(28) |
191 | #elif defined(MODEL_ppc64le) |
192 | mtctr 28 |
193 | mr 12, 28 |
194 | #else |
195 | #error "wrong MODEL" |
196 | #endif |
197 | bctr |
198 | |
199 | /* Mark stack as non-executable */ |
200 | .section .note.GNU-stack,"",%progbits |
201 |