111
|
1 /* -----------------------------------------------------------------------
|
|
2
|
|
3 sysv.S - Copyright (c) 2012 Alan Hourihane
|
|
4 Copyright (c) 1998, 2012 Andreas Schwab
|
|
5 Copyright (c) 2008 Red Hat, Inc.
|
|
6 Copyright (c) 2012 Thorsten Glaser
|
|
7
|
|
8 m68k Foreign Function Interface
|
|
9
|
|
10 Permission is hereby granted, free of charge, to any person obtaining
|
|
11 a copy of this software and associated documentation files (the
|
|
12 ``Software''), to deal in the Software without restriction, including
|
|
13 without limitation the rights to use, copy, modify, merge, publish,
|
|
14 distribute, sublicense, and/or sell copies of the Software, and to
|
|
15 permit persons to whom the Software is furnished to do so, subject to
|
|
16 the following conditions:
|
|
17
|
|
18 The above copyright notice and this permission notice shall be included
|
|
19 in all copies or substantial portions of the Software.
|
|
20
|
|
21 THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,
|
|
22 EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
23 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
|
24 NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
|
25 HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
|
26 WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
27 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
|
28 DEALINGS IN THE SOFTWARE.
|
|
29 ----------------------------------------------------------------------- */
|
|
30
|
|
31 #define LIBFFI_ASM
|
|
32 #include <fficonfig.h>
|
|
33 #include <ffi.h>
|
|
34
|
|
35 #ifdef HAVE_AS_CFI_PSEUDO_OP
|
|
36 #define CFI_STARTPROC() .cfi_startproc
|
|
37 #define CFI_OFFSET(reg,off) .cfi_offset reg,off
|
|
38 #define CFI_DEF_CFA(reg,off) .cfi_def_cfa reg,off
|
|
39 #define CFI_ENDPROC() .cfi_endproc
|
|
40 #else
|
|
41 #define CFI_STARTPROC()
|
|
42 #define CFI_OFFSET(reg,off)
|
|
43 #define CFI_DEF_CFA(reg,off)
|
|
44 #define CFI_ENDPROC()
|
|
45 #endif
|
|
46
|
|
47 #ifdef __MINT__
|
|
48 #define CALLFUNC(funcname) _ ## funcname
|
|
49 #else
|
|
50 #define CALLFUNC(funcname) funcname
|
|
51 #endif
|
|
52
|
|
53 .text
|
|
54
|
|
55 .globl CALLFUNC(ffi_call_SYSV)
|
|
56 .type CALLFUNC(ffi_call_SYSV),@function
|
|
57 .align 4
|
|
58
|
|
59 CALLFUNC(ffi_call_SYSV):
|
|
60 CFI_STARTPROC()
|
|
61 link %fp,#0
|
|
62 CFI_OFFSET(14,-8)
|
|
63 CFI_DEF_CFA(14,8)
|
|
64 move.l %d2,-(%sp)
|
|
65 CFI_OFFSET(2,-12)
|
|
66
|
|
67 | Make room for all of the new args.
|
|
68 sub.l 12(%fp),%sp
|
|
69
|
|
70 | Call ffi_prep_args
|
|
71 move.l 8(%fp),-(%sp)
|
|
72 pea 4(%sp)
|
|
73 #if !defined __PIC__
|
|
74 jsr CALLFUNC(ffi_prep_args)
|
|
75 #else
|
|
76 bsr.l CALLFUNC(ffi_prep_args@PLTPC)
|
|
77 #endif
|
|
78 addq.l #8,%sp
|
|
79
|
|
80 | Pass pointer to struct value, if any
|
|
81 #ifdef __MINT__
|
|
82 move.l %d0,%a1
|
|
83 #else
|
|
84 move.l %a0,%a1
|
|
85 #endif
|
|
86
|
|
87 | Call the function
|
|
88 move.l 24(%fp),%a0
|
|
89 jsr (%a0)
|
|
90
|
|
91 | Remove the space we pushed for the args
|
|
92 add.l 12(%fp),%sp
|
|
93
|
|
94 | Load the pointer to storage for the return value
|
|
95 move.l 20(%fp),%a1
|
|
96
|
|
97 | Load the return type code
|
|
98 move.l 16(%fp),%d2
|
|
99
|
|
100 | If the return value pointer is NULL, assume no return value.
|
|
101 | NOTE: On the mc68000, tst on an address register is not supported.
|
|
102 #if !defined(__mc68020__) && !defined(__mc68030__) && !defined(__mc68040__) && !defined(__mc68060__) && !defined(__mcoldfire__)
|
|
103 cmp.w #0, %a1
|
|
104 #else
|
|
105 tst.l %a1
|
|
106 #endif
|
|
107 jbeq noretval
|
|
108
|
|
109 btst #0,%d2
|
|
110 jbeq retlongint
|
|
111 move.l %d0,(%a1)
|
|
112 jbra epilogue
|
|
113
|
|
114 retlongint:
|
|
115 btst #1,%d2
|
|
116 jbeq retfloat
|
|
117 move.l %d0,(%a1)
|
|
118 move.l %d1,4(%a1)
|
|
119 jbra epilogue
|
|
120
|
|
121 retfloat:
|
|
122 btst #2,%d2
|
|
123 jbeq retdouble
|
|
124 #if defined(__MC68881__) || defined(__HAVE_68881__)
|
|
125 fmove.s %fp0,(%a1)
|
|
126 #else
|
|
127 move.l %d0,(%a1)
|
|
128 #endif
|
|
129 jbra epilogue
|
|
130
|
|
131 retdouble:
|
|
132 btst #3,%d2
|
|
133 jbeq retlongdouble
|
|
134 #if defined(__MC68881__) || defined(__HAVE_68881__)
|
|
135 fmove.d %fp0,(%a1)
|
|
136 #else
|
|
137 move.l %d0,(%a1)+
|
|
138 move.l %d1,(%a1)
|
|
139 #endif
|
|
140 jbra epilogue
|
|
141
|
|
142 retlongdouble:
|
|
143 btst #4,%d2
|
|
144 jbeq retpointer
|
|
145 #if defined(__MC68881__) || defined(__HAVE_68881__)
|
|
146 fmove.x %fp0,(%a1)
|
|
147 #else
|
|
148 move.l %d0,(%a1)+
|
|
149 move.l %d1,(%a1)+
|
|
150 move.l %d2,(%a1)
|
|
151 #endif
|
|
152 jbra epilogue
|
|
153
|
|
154 retpointer:
|
|
155 btst #5,%d2
|
|
156 jbeq retstruct1
|
|
157 #ifdef __MINT__
|
|
158 move.l %d0,(%a1)
|
|
159 #else
|
|
160 move.l %a0,(%a1)
|
|
161 #endif
|
|
162 jbra epilogue
|
|
163
|
|
164 retstruct1:
|
|
165 btst #6,%d2
|
|
166 jbeq retstruct2
|
|
167 move.b %d0,(%a1)
|
|
168 jbra epilogue
|
|
169
|
|
170 retstruct2:
|
|
171 btst #7,%d2
|
|
172 jbeq retsint8
|
|
173 move.w %d0,(%a1)
|
|
174 jbra epilogue
|
|
175
|
|
176 retsint8:
|
|
177 btst #8,%d2
|
|
178 jbeq retsint16
|
|
179 | NOTE: On the mc68000, extb is not supported. 8->16, then 16->32.
|
|
180 #if !defined(__mc68020__) && !defined(__mc68030__) && !defined(__mc68040__) && !defined(__mc68060__) && !defined(__mcoldfire__)
|
|
181 ext.w %d0
|
|
182 ext.l %d0
|
|
183 #else
|
|
184 extb.l %d0
|
|
185 #endif
|
|
186 move.l %d0,(%a1)
|
|
187 jbra epilogue
|
|
188
|
|
189 retsint16:
|
|
190 btst #9,%d2
|
|
191 jbeq noretval
|
|
192 ext.l %d0
|
|
193 move.l %d0,(%a1)
|
|
194
|
|
195 noretval:
|
|
196 epilogue:
|
|
197 move.l (%sp)+,%d2
|
|
198 unlk %fp
|
|
199 rts
|
|
200 CFI_ENDPROC()
|
|
201 .size CALLFUNC(ffi_call_SYSV),.-CALLFUNC(ffi_call_SYSV)
|
|
202
|
|
203 .globl CALLFUNC(ffi_closure_SYSV)
|
|
204 .type CALLFUNC(ffi_closure_SYSV), @function
|
|
205 .align 4
|
|
206
|
|
207 CALLFUNC(ffi_closure_SYSV):
|
|
208 CFI_STARTPROC()
|
|
209 link %fp,#-12
|
|
210 CFI_OFFSET(14,-8)
|
|
211 CFI_DEF_CFA(14,8)
|
|
212 move.l %sp,-12(%fp)
|
|
213 pea 8(%fp)
|
|
214 pea -12(%fp)
|
|
215 move.l %a0,-(%sp)
|
|
216 #if !defined __PIC__
|
|
217 jsr CALLFUNC(ffi_closure_SYSV_inner)
|
|
218 #else
|
|
219 bsr.l CALLFUNC(ffi_closure_SYSV_inner@PLTPC)
|
|
220 #endif
|
|
221
|
|
222 lsr.l #1,%d0
|
|
223 jne 1f
|
|
224 jcc .Lcls_epilogue
|
|
225 | CIF_FLAGS_INT
|
|
226 move.l -12(%fp),%d0
|
|
227 .Lcls_epilogue:
|
|
228 | no CIF_FLAGS_*
|
|
229 unlk %fp
|
|
230 rts
|
|
231 1:
|
|
232 lea -12(%fp),%a0
|
|
233 lsr.l #2,%d0
|
|
234 jne 1f
|
|
235 jcs .Lcls_ret_float
|
|
236 | CIF_FLAGS_DINT
|
|
237 move.l (%a0)+,%d0
|
|
238 move.l (%a0),%d1
|
|
239 jra .Lcls_epilogue
|
|
240 .Lcls_ret_float:
|
|
241 #if defined(__MC68881__) || defined(__HAVE_68881__)
|
|
242 fmove.s (%a0),%fp0
|
|
243 #else
|
|
244 move.l (%a0),%d0
|
|
245 #endif
|
|
246 jra .Lcls_epilogue
|
|
247 1:
|
|
248 lsr.l #2,%d0
|
|
249 jne 1f
|
|
250 jcs .Lcls_ret_ldouble
|
|
251 | CIF_FLAGS_DOUBLE
|
|
252 #if defined(__MC68881__) || defined(__HAVE_68881__)
|
|
253 fmove.d (%a0),%fp0
|
|
254 #else
|
|
255 move.l (%a0)+,%d0
|
|
256 move.l (%a0),%d1
|
|
257 #endif
|
|
258 jra .Lcls_epilogue
|
|
259 .Lcls_ret_ldouble:
|
|
260 #if defined(__MC68881__) || defined(__HAVE_68881__)
|
|
261 fmove.x (%a0),%fp0
|
|
262 #else
|
|
263 move.l (%a0)+,%d0
|
|
264 move.l (%a0)+,%d1
|
|
265 move.l (%a0),%d2
|
|
266 #endif
|
|
267 jra .Lcls_epilogue
|
|
268 1:
|
|
269 lsr.l #2,%d0
|
|
270 jne 1f
|
|
271 jcs .Lcls_ret_struct1
|
|
272 | CIF_FLAGS_POINTER
|
|
273 move.l (%a0),%a0
|
|
274 move.l %a0,%d0
|
|
275 jra .Lcls_epilogue
|
|
276 .Lcls_ret_struct1:
|
|
277 move.b (%a0),%d0
|
|
278 jra .Lcls_epilogue
|
|
279 1:
|
|
280 lsr.l #2,%d0
|
|
281 jne 1f
|
|
282 jcs .Lcls_ret_sint8
|
|
283 | CIF_FLAGS_STRUCT2
|
|
284 move.w (%a0),%d0
|
|
285 jra .Lcls_epilogue
|
|
286 .Lcls_ret_sint8:
|
|
287 move.l (%a0),%d0
|
|
288 | NOTE: On the mc68000, extb is not supported. 8->16, then 16->32.
|
|
289 #if !defined(__mc68020__) && !defined(__mc68030__) && !defined(__mc68040__) && !defined(__mc68060__) && !defined(__mcoldfire__)
|
|
290 ext.w %d0
|
|
291 ext.l %d0
|
|
292 #else
|
|
293 extb.l %d0
|
|
294 #endif
|
|
295 jra .Lcls_epilogue
|
|
296 1:
|
|
297 | CIF_FLAGS_SINT16
|
|
298 move.l (%a0),%d0
|
|
299 ext.l %d0
|
|
300 jra .Lcls_epilogue
|
|
301 CFI_ENDPROC()
|
|
302
|
|
303 .size CALLFUNC(ffi_closure_SYSV),.-CALLFUNC(ffi_closure_SYSV)
|
|
304
|
|
305 .globl CALLFUNC(ffi_closure_struct_SYSV)
|
|
306 .type CALLFUNC(ffi_closure_struct_SYSV), @function
|
|
307 .align 4
|
|
308
|
|
309 CALLFUNC(ffi_closure_struct_SYSV):
|
|
310 CFI_STARTPROC()
|
|
311 link %fp,#0
|
|
312 CFI_OFFSET(14,-8)
|
|
313 CFI_DEF_CFA(14,8)
|
|
314 move.l %sp,-12(%fp)
|
|
315 pea 8(%fp)
|
|
316 move.l %a1,-(%sp)
|
|
317 move.l %a0,-(%sp)
|
|
318 #if !defined __PIC__
|
|
319 jsr CALLFUNC(ffi_closure_SYSV_inner)
|
|
320 #else
|
|
321 bsr.l CALLFUNC(ffi_closure_SYSV_inner@PLTPC)
|
|
322 #endif
|
|
323 unlk %fp
|
|
324 rts
|
|
325 CFI_ENDPROC()
|
|
326 .size CALLFUNC(ffi_closure_struct_SYSV),.-CALLFUNC(ffi_closure_struct_SYSV)
|
|
327
|
|
328 #if defined __ELF__ && defined __linux__
|
|
329 .section .note.GNU-stack,"",@progbits
|
|
330 #endif
|