comparison dyncall/dyncall_call_sparc_v9.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_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