111
|
1 /* -----------------------------------------------------------------------
|
|
2 osf.S - Copyright (c) 1998, 2001, 2007, 2008, 2011, 2014 Red Hat
|
|
3
|
|
4 Alpha/OSF Foreign Function Interface
|
|
5
|
|
6 Permission is hereby granted, free of charge, to any person obtaining
|
|
7 a copy of this software and associated documentation files (the
|
|
8 ``Software''), to deal in the Software without restriction, including
|
|
9 without limitation the rights to use, copy, modify, merge, publish,
|
|
10 distribute, sublicense, and/or sell copies of the Software, and to
|
|
11 permit persons to whom the Software is furnished to do so, subject to
|
|
12 the following conditions:
|
|
13
|
|
14 The above copyright notice and this permission notice shall be included
|
|
15 in all copies or substantial portions of the Software.
|
|
16
|
|
17 THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,
|
|
18 EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
19 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
|
20 NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
|
21 HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
|
22 WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
23 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
|
24 DEALINGS IN THE SOFTWARE.
|
|
25 ----------------------------------------------------------------------- */
|
|
26
|
|
27 #define LIBFFI_ASM
|
|
28 #include <fficonfig.h>
|
|
29 #include <ffi.h>
|
|
30 #include <ffi_cfi.h>
|
|
31 #include "internal.h"
|
|
32
|
|
33 .arch ev6
|
|
34 .text
|
|
35
|
|
36 /* Aid in building a direct addressed jump table, 4 insns per entry. */
|
|
37 .macro E index
|
|
38 .align 4
|
|
39 .org 99b + \index * 16
|
|
40 .endm
|
|
41
|
|
42 /* ffi_call_osf (void *stack, void *frame, unsigned flags,
|
|
43 void *raddr, void (*fnaddr)(void), void *closure)
|
|
44
|
|
45 Bit o trickiness here -- FRAME is the base of the stack frame
|
|
46 for this function. This has been allocated by ffi_call. We also
|
|
47 deallocate some of the stack that has been alloca'd. */
|
|
48
|
|
49 .align 4
|
|
50 .globl ffi_call_osf
|
|
51 .ent ffi_call_osf
|
|
52 FFI_HIDDEN(ffi_call_osf)
|
|
53
|
|
54 ffi_call_osf:
|
|
55 cfi_startproc
|
|
56 cfi_def_cfa($17, 32)
|
|
57 mov $16, $30
|
|
58 stq $26, 0($17)
|
|
59 stq $15, 8($17)
|
|
60 mov $17, $15
|
|
61 .prologue 0
|
|
62 cfi_def_cfa_register($15)
|
|
63 cfi_rel_offset($26, 0)
|
|
64 cfi_rel_offset($15, 8)
|
|
65
|
|
66 stq $18, 16($17) # save flags into frame
|
|
67 stq $19, 24($17) # save rvalue into frame
|
|
68 mov $20, $27 # fn into place for call
|
|
69 mov $21, $1 # closure into static chain
|
|
70
|
|
71 # Load up all of the (potential) argument registers.
|
|
72 ldq $16, 0($30)
|
|
73 ldt $f16, 0($30)
|
|
74 ldt $f17, 8($30)
|
|
75 ldq $17, 8($30)
|
|
76 ldt $f18, 16($30)
|
|
77 ldq $18, 16($30)
|
|
78 ldt $f19, 24($30)
|
|
79 ldq $19, 24($30)
|
|
80 ldt $f20, 32($30)
|
|
81 ldq $20, 32($30)
|
|
82 ldt $f21, 40($30)
|
|
83 ldq $21, 40($30)
|
|
84
|
|
85 # Deallocate the register argument area.
|
|
86 lda $30, 48($30)
|
|
87
|
|
88 jsr $26, ($27), 0
|
|
89 0:
|
|
90 ldah $29, 0($26) !gpdisp!1
|
|
91 ldq $2, 24($15) # reload rvalue
|
|
92 lda $29, 0($29) !gpdisp!1
|
|
93 ldq $3, 16($15) # reload flags
|
|
94 lda $1, 99f-0b($26)
|
|
95 ldq $26, 0($15)
|
|
96 ldq $15, 8($15)
|
|
97 cfi_restore($26)
|
|
98 cfi_restore($15)
|
|
99 cfi_def_cfa($sp, 0)
|
|
100 cmoveq $2, ALPHA_ST_VOID, $3 # mash null rvalue to void
|
|
101 addq $3, $3, $3
|
|
102 s8addq $3, $1, $1 # 99f + stcode * 16
|
|
103 jmp $31, ($1), $st_int
|
|
104
|
|
105 .align 4
|
|
106 99:
|
|
107 E ALPHA_ST_VOID
|
|
108 ret
|
|
109 E ALPHA_ST_INT
|
|
110 $st_int:
|
|
111 stq $0, 0($2)
|
|
112 ret
|
|
113 E ALPHA_ST_FLOAT
|
|
114 sts $f0, 0($2)
|
|
115 ret
|
|
116 E ALPHA_ST_DOUBLE
|
|
117 stt $f0, 0($2)
|
|
118 ret
|
|
119 E ALPHA_ST_CPLXF
|
|
120 sts $f0, 0($2)
|
|
121 sts $f1, 4($2)
|
|
122 ret
|
|
123 E ALPHA_ST_CPLXD
|
|
124 stt $f0, 0($2)
|
|
125 stt $f1, 8($2)
|
|
126 ret
|
|
127
|
|
128 cfi_endproc
|
|
129 .end ffi_call_osf
|
|
130
|
|
131 /* ffi_closure_osf(...)
|
|
132
|
|
133 Receives the closure argument in $1. */
|
|
134
|
|
135 #define CLOSURE_FS (16*8)
|
|
136
|
|
137 .align 4
|
|
138 .globl ffi_go_closure_osf
|
|
139 .ent ffi_go_closure_osf
|
|
140 FFI_HIDDEN(ffi_go_closure_osf)
|
|
141
|
|
142 ffi_go_closure_osf:
|
|
143 cfi_startproc
|
|
144 ldgp $29, 0($27)
|
|
145 subq $30, CLOSURE_FS, $30
|
|
146 cfi_adjust_cfa_offset(CLOSURE_FS)
|
|
147 stq $26, 0($30)
|
|
148 .prologue 1
|
|
149 cfi_rel_offset($26, 0)
|
|
150
|
|
151 stq $16, 10*8($30)
|
|
152 stq $17, 11*8($30)
|
|
153 stq $18, 12*8($30)
|
|
154
|
|
155 ldq $16, 8($1) # load cif
|
|
156 ldq $17, 16($1) # load fun
|
|
157 mov $1, $18 # closure is user_data
|
|
158 br $do_closure
|
|
159
|
|
160 cfi_endproc
|
|
161 .end ffi_go_closure_osf
|
|
162
|
|
163 .align 4
|
|
164 .globl ffi_closure_osf
|
|
165 .ent ffi_closure_osf
|
|
166 FFI_HIDDEN(ffi_closure_osf)
|
|
167
|
|
168 ffi_closure_osf:
|
|
169 cfi_startproc
|
|
170 ldgp $29, 0($27)
|
|
171 subq $30, CLOSURE_FS, $30
|
|
172 cfi_adjust_cfa_offset(CLOSURE_FS)
|
|
173 stq $26, 0($30)
|
|
174 .prologue 1
|
|
175 cfi_rel_offset($26, 0)
|
|
176
|
|
177 # Store all of the potential argument registers in va_list format.
|
|
178 stq $16, 10*8($30)
|
|
179 stq $17, 11*8($30)
|
|
180 stq $18, 12*8($30)
|
|
181
|
|
182 ldq $16, 24($1) # load cif
|
|
183 ldq $17, 32($1) # load fun
|
|
184 ldq $18, 40($1) # load user_data
|
|
185
|
|
186 $do_closure:
|
|
187 stq $19, 13*8($30)
|
|
188 stq $20, 14*8($30)
|
|
189 stq $21, 15*8($30)
|
|
190 stt $f16, 4*8($30)
|
|
191 stt $f17, 5*8($30)
|
|
192 stt $f18, 6*8($30)
|
|
193 stt $f19, 7*8($30)
|
|
194 stt $f20, 8*8($30)
|
|
195 stt $f21, 9*8($30)
|
|
196
|
|
197 # Call ffi_closure_osf_inner to do the bulk of the work.
|
|
198 lda $19, 2*8($30)
|
|
199 lda $20, 10*8($30)
|
|
200 jsr $26, ffi_closure_osf_inner
|
|
201 0:
|
|
202 ldah $29, 0($26) !gpdisp!2
|
|
203 lda $2, 99f-0b($26)
|
|
204 s4addq $0, 0, $1 # ldcode * 4
|
|
205 ldq $0, 16($30) # preload return value
|
|
206 s4addq $1, $2, $1 # 99f + ldcode * 16
|
|
207 lda $29, 0($29) !gpdisp!2
|
|
208 ldq $26, 0($30)
|
|
209 cfi_restore($26)
|
|
210 jmp $31, ($1), $load_32
|
|
211
|
|
212 .macro epilogue
|
|
213 addq $30, CLOSURE_FS, $30
|
|
214 cfi_adjust_cfa_offset(-CLOSURE_FS)
|
|
215 ret
|
|
216 .align 4
|
|
217 cfi_adjust_cfa_offset(CLOSURE_FS)
|
|
218 .endm
|
|
219
|
|
220 .align 4
|
|
221 99:
|
|
222 E ALPHA_LD_VOID
|
|
223 epilogue
|
|
224
|
|
225 E ALPHA_LD_INT64
|
|
226 epilogue
|
|
227
|
|
228 E ALPHA_LD_INT32
|
|
229 $load_32:
|
|
230 sextl $0, $0
|
|
231 epilogue
|
|
232
|
|
233 E ALPHA_LD_UINT16
|
|
234 zapnot $0, 3, $0
|
|
235 epilogue
|
|
236
|
|
237 E ALPHA_LD_SINT16
|
|
238 #ifdef __alpha_bwx__
|
|
239 sextw $0, $0
|
|
240 #else
|
|
241 sll $0, 48, $0
|
|
242 sra $0, 48, $0
|
|
243 #endif
|
|
244 epilogue
|
|
245
|
|
246 E ALPHA_LD_UINT8
|
|
247 and $0, 0xff, $0
|
|
248 epilogue
|
|
249
|
|
250 E ALPHA_LD_SINT8
|
|
251 #ifdef __alpha_bwx__
|
|
252 sextb $0, $0
|
|
253 #else
|
|
254 sll $0, 56, $0
|
|
255 sra $0, 56, $0
|
|
256 #endif
|
|
257 epilogue
|
|
258
|
|
259 E ALPHA_LD_FLOAT
|
|
260 lds $f0, 16($sp)
|
|
261 epilogue
|
|
262
|
|
263 E ALPHA_LD_DOUBLE
|
|
264 ldt $f0, 16($sp)
|
|
265 epilogue
|
|
266
|
|
267 E ALPHA_LD_CPLXF
|
|
268 lds $f0, 16($sp)
|
|
269 lds $f1, 20($sp)
|
|
270 epilogue
|
|
271
|
|
272 E ALPHA_LD_CPLXD
|
|
273 ldt $f0, 16($sp)
|
|
274 ldt $f1, 24($sp)
|
|
275 epilogue
|
|
276
|
|
277 cfi_endproc
|
|
278 .end ffi_closure_osf
|
|
279
|
|
280 #if defined __ELF__ && defined __linux__
|
|
281 .section .note.GNU-stack,"",@progbits
|
|
282 #endif
|