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