0
|
1 /*
|
|
2
|
|
3 Package: dyncall
|
|
4 Library: dyncall
|
|
5 File: dyncall/dyncall_call_sparc_v9.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 #define BIAS 2047
|
|
27 .global dcCall_v9
|
|
28 /* dcCall_sparc64( DCCallVM* , void * target ) */
|
|
29 /* o0 o1 */
|
|
30 dcCall_v9:
|
|
31 or %o0, %g0, %o3 /* o3: callvm */
|
|
32 or %o1, %g0, %o0 /* o0: target */
|
|
33 ldx [%o3+24], %o1 /* o1: mVecSize */
|
|
34 add %o3, 32, %o2 /* o2: stack */
|
|
35 /* Compute a matching stack size (approximate): o3 = align(o1+136,16) */
|
|
36
|
|
37 add %o1, (16+1+6)*8+15, %o3
|
|
38 and %o3, -16, %o3
|
|
39 neg %o3 /* o3: -stacksize */
|
|
40 save %sp, %o3, %sp
|
|
41
|
|
42 ldd [%i2+8*0 ],%f0 /* Load double-precision float registers. */
|
|
43 ldd [%i2+8*1 ],%f2
|
|
44 ldd [%i2+8*2 ],%f4
|
|
45 ldd [%i2+8*3 ],%f6
|
|
46 ldd [%i2+8*4 ],%f8
|
|
47 ldd [%i2+8*5 ],%f10
|
|
48 ldd [%i2+8*6 ],%f12
|
|
49 ldd [%i2+8*7 ],%f14
|
|
50 ldd [%i2+8*8 ],%f16
|
|
51 ldd [%i2+8*9 ],%f18
|
|
52 ldd [%i2+8*10],%f20
|
|
53 ldd [%i2+8*11],%f22
|
|
54 ldd [%i2+8*12],%f24
|
|
55 ldd [%i2+8*13],%f26
|
|
56 ldd [%i2+8*14],%f28
|
|
57 ldd [%i2+8*15],%f30
|
|
58 ldx [%i2+8*0],%o0 /* Load output registers. */
|
|
59 ldx [%i2+8*1],%o1
|
|
60 ldx [%i2+8*2],%o2
|
|
61 ldx [%i2+8*3],%o3
|
|
62 ldx [%i2+8*4],%o4
|
|
63 ldx [%i2+8*5],%o5
|
|
64 sub %i1, 48, %i1
|
|
65 cmp %i1, 0
|
|
66 ble .do_call
|
|
67 nop
|
|
68 /* Copy loop: */
|
|
69 add %i2, 48, %i2 /* skip homing area */
|
|
70 or %g0, %g0, %l0 /* l0 = offset initialized to 0. */
|
|
71 add %sp, BIAS+((16+6)*8), %l2 /* l2 = argument area on stack space (7th word). (64+4+6*4 = byte offset 92). */
|
|
72 .next:
|
|
73 ldx [%i2+%l0],%l1 /* Read from arg buffer(%i2) to %l1. */
|
|
74 stx %l1, [%l2+%l0] /* Write %l1 to stack space(%l2). */
|
|
75 add %l0, 8, %l0 /* Increment offset. */
|
|
76 sub %i1, 8, %i1 /* Decrement copy size. */
|
|
77 cmp %i1, 0
|
|
78 bgt .next
|
|
79 nop
|
|
80 .do_call:
|
|
81 call %i0 /* Call target. */
|
|
82 nop
|
|
83 or %o0, %g0, %i0
|
|
84 jmpl %i7 + 8, %g0
|
|
85 restore
|
|
86
|
|
87 /*
|
|
88 or %o0, %g0, %i0
|
|
89 or %o1, %g0, %i1
|
|
90 or %o2, %g0, %i2
|
|
91 or %o3, %g0, %i3
|
|
92 return %i7 + 8
|
|
93 nop
|
|
94
|
|
95 Changes from v8:
|
|
96 - fundamental data types
|
|
97 - (un)signed int: 8,16,32,64
|
|
98 - float: 32,64,128
|
|
99 - float: IEEE 754 compilant
|
|
100 32 32-bit float registers f0,f1,..,f31
|
|
101 32 64-bit float registers f0,f2,..,f62
|
|
102 16 128-bit float registers f0,f4,..,f60
|
|
103
|
|
104 Description:
|
|
105 We need to raise up a dynamic stack frame.
|
|
106 Therefore we need to compute the stack size. We do this first,
|
|
107 in the context of the caller as a leaf function (using o3 as scratch for addition).
|
|
108 Then we raise the frame, ending up in o0-o3 is then i0-i3.
|
|
109
|
|
110
|
|
111 Stack Layout:
|
|
112 BIAS = 2047
|
|
113
|
|
114 BIAS+XX: should be 16 byte aligned.
|
|
115 ...
|
|
116 136: argument overflow area
|
|
117 128: 1 extended word for struct/union poiner return value
|
|
118 BIAS+ 0: 16 extended words for registers (in/local) save area [register window]
|
|
119
|
|
120
|
|
121 Function Argument Passing:
|
|
122 - integer %o0..%o5 (caller view).
|
|
123 - floating-point %f0 .. %f15
|
|
124 - continuous memory starting at %sp+BIAS+136 (caller view).
|
|
125
|
|
126 Register Usage:
|
|
127 %fp0..%fp31 : floating-point arguments.
|
|
128 %sp or %o6 : stack pointer, always 8 (or 16?)-byte aligned.
|
|
129 %fp or %i6 : frame pointer.
|
|
130 %i0 and %o0 : integer and pointer return values.
|
|
131 %i7 and %o7 : return address. (caller puts return address to %o7, callee uses %i7)
|
|
132 %fp0 and %fp1: return value (float).
|
|
133 %i0..%i5 : input argument registers
|
|
134 %o0..%o5 : output argument registers
|
|
135 %g0 : always zero, writes to it have no effect.
|
|
136
|
|
137 Register Mappings:
|
|
138 r0-7 -> globals
|
|
139 r8-15 -> outs
|
|
140 r16-r23 -> locals
|
|
141 r24-r31 -> ins
|
|
142
|
|
143 Integer Register Overview Table:
|
|
144 ID Class Name Description
|
|
145 ------------------------------------------------------------------------------
|
|
146 0 globals g0 always zero, writes to it have no effect
|
|
147 1 g1
|
|
148 2 g2
|
|
149 3 g3
|
|
150 4 g4
|
|
151 5 g5
|
|
152 6 g6
|
|
153 7 g7
|
|
154 8 out o0 [int/ptr] arg 0 and return
|
|
155 9 o1 arg 1
|
|
156 10 o2 arg 2
|
|
157 11 o3 arg 3
|
|
158 12 o4 arg 4
|
|
159 13 o5 arg 5
|
|
160 14 o6 stack pointer
|
|
161 15 o7
|
|
162 16 local l0 scratch
|
|
163 17 l1
|
|
164 18 l2
|
|
165 19 l3
|
|
166 20 l4
|
|
167 21 l5
|
|
168 22 l6
|
|
169 23 l7
|
|
170 24 in i0 [int/pt] arg 0 and return
|
|
171 25 i1
|
|
172 26 i2
|
|
173 27 i3
|
|
174 28 i4
|
|
175 29 i5
|
|
176 30 i6 frame pointer
|
|
177 31 i7
|
|
178 */
|
|
179
|
|
180 /* ---------------------------------------------------------------------------
|
|
181
|
|
182 call kernel for sparc64 v9 abi
|
|
183 tested on sparc64/linux/debian [gcc54.fsffrance.org - thanx to the farm!]
|
|
184
|
|
185 new C Interface:
|
|
186 void dcCall_sparc (DCCallVM* callvm, DCpointer target);
|
|
187 %i0 %1
|
|
188
|
|
189 see dyncall_call_sparc.S for details.
|
|
190
|
|
191 old C Interface:
|
|
192 void dcCall_sparc (DCpointer target, DCsize size, DCpointer data);
|
|
193 %i0 , %i1 , %i2
|
|
194 Input:
|
|
195 i0 target
|
|
196 i1 size
|
|
197 i2 data
|
|
198
|
|
199 */
|
|
200
|
|
201 #if 0
|
|
202
|
|
203
|
|
204 #define REGSIZE 8
|
|
205
|
|
206
|
|
207
|
|
208 #define SHEAD ((16+6)*8)
|
|
209 #define ALIGN 16
|
|
210 #define IREGS 6
|
|
211 #define FREGS 16
|
|
212 #define SREGS 16
|
|
213 #define IBASE 0
|
|
214 #define FBASE (IREGS*8)
|
|
215
|
|
216 // #define DHEAD ((IREGS+FREGS)*8)+SREGS*4
|
|
217
|
|
218 CALLVM_regdata = 72
|
|
219 CALLVM_size = 208
|
|
220 CALLVM_buffer = 216
|
|
221
|
|
222 #endif
|