0
|
1 /*
|
|
2
|
|
3 Package: dyncall
|
|
4 Library: dyncall
|
|
5 File: dyncall/dyncall_call_sparc64.S
|
|
6 Description: Call kernel for sparc64 v9 ABI.
|
|
7 License:
|
|
8
|
|
9 Copyright (c) 2011-2015 Daniel Adler <dadler@uni-goettingen.de>
|
|
10
|
|
11 Permission to use, copy, modify, and distribute this software for any
|
|
12 purpose with or without fee is hereby granted, provided that the above
|
|
13 copyright notice and this permission notice appear in all copies.
|
|
14
|
|
15 THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
|
16 WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
|
17 MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
|
18 ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
|
19 WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
|
20 ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
|
21 OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
|
22
|
|
23 */
|
|
24
|
|
25
|
|
26
|
|
27
|
|
28 /* ---------------------------------------------------------------------------
|
|
29
|
|
30 call kernel for sparc64 v9 abi
|
|
31 tested on sparc64/linux/debian [gcc54.fsffrance.org - thanx to the farm!]
|
|
32
|
|
33 new C Interface:
|
|
34 void dcCall_sparc (DCCallVM* callvm, DCpointer target);
|
|
35 %i0 %1
|
|
36
|
|
37 see dyncall_call_sparc.S for details.
|
|
38
|
|
39 old C Interface:
|
|
40 void dcCall_sparc (DCpointer target, DCsize size, DCpointer data);
|
|
41 %i0 , %i1 , %i2
|
|
42 Input:
|
|
43 i0 target
|
|
44 i1 size
|
|
45 i2 data
|
|
46
|
|
47 */
|
|
48
|
|
49 #define REGSIZE 8
|
|
50
|
|
51 #define BIAS 2047
|
|
52
|
|
53 #define ALIGN 16
|
|
54
|
|
55 #define IREGS 6
|
|
56 #define FREGS 16
|
|
57 #define SREGS 16
|
|
58 #define IBASE 0
|
|
59 #define FBASE (IREGS*8)
|
|
60
|
|
61 #define SHEAD ((16+6)*8)
|
|
62 #define DHEAD ((IREGS+FREGS)*8)+SREGS*4
|
|
63
|
|
64 CALLVM_singleUseFlags = 24
|
|
65 CALLVM_size = 40
|
|
66 CALLVM_dataoff = 48
|
|
67
|
|
68
|
|
69 .global dcCall_sparc64
|
|
70 dcCall_sparc64:
|
|
71
|
|
72 /* Basic Prolog: supports up to 6 arguments. */
|
|
73
|
|
74 /* new C interface */
|
|
75 /* o0-1: callvm,target */
|
|
76
|
|
77 or %o0, %g0, %o3 /* %o3: callvm */
|
|
78 or %o1, %g0, %o0 /* %o0: target */
|
|
79 ldx [%o3+CALLVM_size], %o1 /* %o1: size */
|
|
80 add %o3, CALLVM_dataoff, %o2 /* %o2: data */
|
|
81 ld [%o3+CALLVM_singleUseFlags], %o4 /* %o4: flags */
|
|
82 /*leaf functions: may use the first six output registers.*/
|
|
83 /*o0-2:target,size,data*/
|
|
84 /*o3-5:free to use */
|
|
85
|
|
86 /* Arguments: */
|
|
87 /* %o0 = ptr to target. */
|
|
88 /* %o1 = size of data. */
|
|
89 /* %o2 = data pointer. */
|
|
90 /* %o4 = use flags. */
|
|
91
|
|
92 /* Compute a matching stack size (approximate): o3 = align(o1+136,16) */
|
|
93
|
|
94 add %o1, SHEAD+ALIGN-1, %o3
|
|
95 and %o3, -ALIGN, %o3
|
|
96 neg %o3
|
|
97
|
|
98 /* Prolog. */
|
|
99 save %sp, %o3, %sp
|
|
100
|
|
101 /* Arguments: */
|
|
102 /* %i0 = ptr to target. */
|
|
103 /* %i1 = size of data. */
|
|
104 /* %i2 = data pointer. */
|
|
105 /* %i3 = stack size. */
|
|
106
|
|
107 /* Load output registers. */
|
|
108
|
|
109 ldx [%i2+IBASE+REGSIZE*0 ],%o0
|
|
110 ldx [%i2+IBASE+REGSIZE*1 ],%o1
|
|
111 ldx [%i2+IBASE+REGSIZE*2 ],%o2
|
|
112 ldx [%i2+IBASE+REGSIZE*3 ],%o3
|
|
113 ldx [%i2+IBASE+REGSIZE*4 ],%o4
|
|
114 ldx [%i2+IBASE+REGSIZE*5 ],%o5
|
|
115
|
|
116 /* Load double-precision float registers. */
|
|
117
|
|
118 ldd [%i2+FBASE+REGSIZE*0 ],%f0
|
|
119 ldd [%i2+FBASE+REGSIZE*1 ],%f2
|
|
120 ldd [%i2+FBASE+REGSIZE*2 ],%f4
|
|
121 ldd [%i2+FBASE+REGSIZE*3 ],%f6
|
|
122 ldd [%i2+FBASE+REGSIZE*4 ],%f8
|
|
123 ldd [%i2+FBASE+REGSIZE*5 ],%f10
|
|
124 ldd [%i2+FBASE+REGSIZE*6 ],%f12
|
|
125 ldd [%i2+FBASE+REGSIZE*7 ],%f14
|
|
126 ldd [%i2+FBASE+REGSIZE*8 ],%f16
|
|
127 ldd [%i2+FBASE+REGSIZE*9 ],%f18
|
|
128 ldd [%i2+FBASE+REGSIZE*10],%f20
|
|
129 ldd [%i2+FBASE+REGSIZE*11],%f22
|
|
130 ldd [%i2+FBASE+REGSIZE*12],%f24
|
|
131 ldd [%i2+FBASE+REGSIZE*13],%f26
|
|
132 ldd [%i2+FBASE+REGSIZE*14],%f28
|
|
133 ldd [%i2+FBASE+REGSIZE*15],%f30
|
|
134
|
|
135 /* load single-precision float registers */
|
|
136
|
|
137 or %g0, 1, %l0
|
|
138 .f0:
|
|
139 andcc %i4, %l0, %g0
|
|
140 beq .f1
|
|
141 nop
|
|
142 ld [%i2+FBASE+REGSIZE*16+4*0 ], %f1
|
|
143 .f1:
|
|
144 sll %l0, 1, %l0
|
|
145 andcc %i4, %l0, %g0
|
|
146 beq .f2
|
|
147 nop
|
|
148 ld [%i2+FBASE+REGSIZE*16+4*1 ], %f3
|
|
149 .f2:
|
|
150 sll %l0, 1, %l0
|
|
151 andcc %i4, %l0, %g0
|
|
152 beq .f3
|
|
153 nop
|
|
154 ld [%i2+FBASE+REGSIZE*16+4*2 ], %f5
|
|
155 .f3:
|
|
156 sll %l0, 1, %l0
|
|
157 andcc %i4, %l0, %g0
|
|
158 beq .f4
|
|
159 nop
|
|
160 ld [%i2+FBASE+REGSIZE*16+4*3 ], %f7
|
|
161 .f4:
|
|
162 sll %l0, 1, %l0
|
|
163 andcc %i4, %l0, %g0
|
|
164 beq .f5
|
|
165 nop
|
|
166 ld [%i2+FBASE+REGSIZE*16+4*4 ], %f9
|
|
167 .f5:
|
|
168 sll %l0, 1, %l0
|
|
169 andcc %i4, %l0, %g0
|
|
170 beq .f6
|
|
171 nop
|
|
172 ld [%i2+FBASE+REGSIZE*16+4*5 ], %f11
|
|
173 .f6:
|
|
174 sll %l0, 1, %l0
|
|
175 andcc %i4, %l0, %g0
|
|
176 beq .f7
|
|
177 nop
|
|
178 ld [%i2+FBASE+REGSIZE*16+4*6 ], %f13
|
|
179 .f7:
|
|
180 sll %l0, 1, %l0
|
|
181 andcc %i4, %l0, %g0
|
|
182 beq .f8
|
|
183 nop
|
|
184 ld [%i2+FBASE+REGSIZE*16+4*7 ], %f15
|
|
185 .f8:
|
|
186 sll %l0, 1, %l0
|
|
187 andcc %i4, %l0, %g0
|
|
188 beq .f9
|
|
189 nop
|
|
190 ld [%i2+FBASE+REGSIZE*16+4*8 ], %f17
|
|
191 .f9:
|
|
192 sll %l0, 1, %l0
|
|
193 andcc %i4, %l0, %g0
|
|
194 beq .f10
|
|
195 nop
|
|
196 ld [%i2+FBASE+REGSIZE*16+4*9 ], %f19
|
|
197 .f10:
|
|
198 sll %l0, 1, %l0
|
|
199 andcc %i4, %l0, %g0
|
|
200 beq .f11
|
|
201 nop
|
|
202 ld [%i2+FBASE+REGSIZE*16+4*10], %f21
|
|
203 .f11:
|
|
204 sll %l0, 1, %l0
|
|
205 andcc %i4, %l0, %g0
|
|
206 beq .f12
|
|
207 nop
|
|
208 ld [%i2+FBASE+REGSIZE*16+4*11], %f23
|
|
209 .f12:
|
|
210 sll %l0, 1, %l0
|
|
211 andcc %i4, %l0, %g0
|
|
212 beq .f13
|
|
213 nop
|
|
214 ld [%i2+FBASE+REGSIZE*16+4*12], %f25
|
|
215 .f13:
|
|
216 sll %l0, 1, %l0
|
|
217 andcc %i4, %l0, %g0
|
|
218 beq .f14
|
|
219 nop
|
|
220 ld [%i2+FBASE+REGSIZE*16+4*13], %f27
|
|
221 .f14:
|
|
222 sll %l0, 1, %l0
|
|
223 andcc %i4, %l0, %g0
|
|
224 beq .f15
|
|
225 nop
|
|
226 ld [%i2+FBASE+REGSIZE*16+4*14], %f29
|
|
227 .f15:
|
|
228 sll %l0, 1, %l0
|
|
229 andcc %i4, %l0, %g0
|
|
230 beq .f_end
|
|
231 nop
|
|
232 ld [%i2+FBASE+REGSIZE*16+4*15], %f31
|
|
233 .f_end:
|
|
234 /* Skip Register Data, do we nee to copy on stack at all? */
|
|
235 sub %i1, DHEAD, %i1 /* skip data header. */
|
|
236 cmp %i1, 0
|
|
237 ble .do_call
|
|
238 nop
|
|
239
|
|
240 /* Copy loop: */
|
|
241 add %i2, DHEAD, %i2 /* i2 = skip data header. */
|
|
242 or %g0, %g0, %l0 /* l0 = offset initialized to 0. */
|
|
243 add %sp, BIAS+SHEAD, %l2 /* l2 = argument area on stack space (7th word). (64+4+6*4 = byte offset 92). */
|
|
244
|
|
245 .next:
|
|
246 ldx [%i2+%l0],%l1 /* Read from arg buffer(%i2) to %l1. */
|
|
247 stx %l1, [%l2+%l0] /* Write %l1 to stack space(%l2). */
|
|
248 add %l0, REGSIZE, %l0 /* Increment offset. */
|
|
249 sub %i1, REGSIZE, %i1 /* Decrement copy size. */
|
|
250 cmp %i1, 0
|
|
251 bgt .next
|
|
252 nop
|
|
253 .do_call:
|
|
254 call %i0 /* Call target. */
|
|
255 nop
|
|
256 or %o0, %g0, %i0
|
|
257 jmpl %i7 + 8, %g0
|
|
258 restore
|
|
259 /*
|
|
260 return %i7 + 8
|
|
261 jmpl %i7 + 8, %g0
|
|
262 nop
|
|
263
|
|
264 jmpl %i7 + 8, %g0
|
|
265 nop
|
|
266 restore
|
|
267 ret
|
|
268 */
|
|
269
|
|
270 /*
|
|
271 or %o0, %g0, %i0
|
|
272 or %o1, %g0, %i1
|
|
273 or %o2, %g0, %i2
|
|
274 or %o3, %g0, %i3
|
|
275 return %i7 + 8
|
|
276 nop
|
|
277
|
|
278 Changes from v8:
|
|
279 - fundamental data types
|
|
280 - (un)signed int: 8,16,32,64
|
|
281 - float: 32,64,128
|
|
282 - float: IEEE 754 compilant
|
|
283 32 32-bit float registers f0,f1,..,f31
|
|
284 32 64-bit float registers f0,f2,..,f62
|
|
285 16 128-bit float registers f0,f4,..,f60
|
|
286
|
|
287 Description:
|
|
288 We need to raise up a dynamic stack frame.
|
|
289 Therefore we need to compute the stack size. We do this first,
|
|
290 in the context of the caller as a leaf function (using o3 as scratch for addition).
|
|
291 Then we raise the frame, ending up in o0-o3 is then i0-i3.
|
|
292
|
|
293
|
|
294 Stack Layout:
|
|
295 BIAS = 2047
|
|
296
|
|
297 BIAS+XX: should be 16 byte aligned.
|
|
298 ...
|
|
299 136: argument overflow area
|
|
300 128: 1 extended word for struct/union poiner return value
|
|
301 BIAS+ 0: 16 extended words for registers (in/local) save area [register window]
|
|
302
|
|
303
|
|
304 Function Argument Passing:
|
|
305 - integer %o0..%o5 (caller view).
|
|
306 - floating-point %f0 .. %f15
|
|
307 - continuous memory starting at %sp+BIAS+136 (caller view).
|
|
308
|
|
309 Register Usage:
|
|
310 %fp0..%fp31 : floating-point arguments.
|
|
311 %sp or %o6 : stack pointer, always 8 (or 16?)-byte aligned.
|
|
312 %fp or %i6 : frame pointer.
|
|
313 %i0 and %o0 : integer and pointer return values.
|
|
314 %i7 and %o7 : return address. (caller puts return address to %o7, callee uses %i7)
|
|
315 %fp0 and %fp1: return value (float).
|
|
316 %i0..%i5 : input argument registers
|
|
317 %o0..%o5 : output argument registers
|
|
318 %g0 : always zero, writes to it have no effect.
|
|
319
|
|
320 Register Mappings:
|
|
321 r0-7 -> globals
|
|
322 r8-15 -> outs
|
|
323 r16-r23 -> locals
|
|
324 r24-r31 -> ins
|
|
325
|
|
326 Integer Register Overview Table:
|
|
327 ID Class Name Description
|
|
328 ------------------------------------------------------------------------------
|
|
329 0 globals g0 always zero, writes to it have no effect
|
|
330 1 g1
|
|
331 2 g2
|
|
332 3 g3
|
|
333 4 g4
|
|
334 5 g5
|
|
335 6 g6
|
|
336 7 g7
|
|
337 8 out o0 [int/ptr] arg 0 and return
|
|
338 9 o1 arg 1
|
|
339 10 o2 arg 2
|
|
340 11 o3 arg 3
|
|
341 12 o4 arg 4
|
|
342 13 o5 arg 5
|
|
343 14 o6 stack pointer
|
|
344 15 o7
|
|
345 16 local l0 scratch
|
|
346 17 l1
|
|
347 18 l2
|
|
348 19 l3
|
|
349 20 l4
|
|
350 21 l5
|
|
351 22 l6
|
|
352 23 l7
|
|
353 24 in i0 [int/pt] arg 0 and return
|
|
354 25 i1
|
|
355 26 i2
|
|
356 27 i3
|
|
357 28 i4
|
|
358 29 i5
|
|
359 30 i6 frame pointer
|
|
360 31 i7
|
|
361 */
|
|
362
|