comparison dyncall/dyncall_call_sparc64.S @ 0:3e629dc19168

initial from svn dyncall-1745
author Daniel Adler
date Thu, 19 Mar 2015 22:24:28 +0100
parents
children
comparison
equal deleted inserted replaced
-1:000000000000 0:3e629dc19168
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