annotate libffi/src/m68k/sysv.S @ 158:494b0b89df80 default tip

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