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 59CALLFUNC(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 114retlongint: 115 btst #1,%d2 116 jbeq retfloat 117 move.l %d0,(%a1) 118 move.l %d1,4(%a1) 119 jbra epilogue 120 121retfloat: 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 131retdouble: 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 142retlongdouble: 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 154retpointer: 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 164retstruct1: 165 btst #6,%d2 166 jbeq retstruct2 167 move.b %d0,(%a1) 168 jbra epilogue 169 170retstruct2: 171 btst #7,%d2 172 jbeq retsint8 173 move.w %d0,(%a1) 174 jbra epilogue 175 176retsint8: 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 189retsint16: 190 btst #9,%d2 191 jbeq noretval 192 ext.l %d0 193 move.l %d0,(%a1) 194 195noretval: 196epilogue: 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 207CALLFUNC(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 2311: 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 2471: 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 2681: 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 2791: 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 2961: 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 309CALLFUNC(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 331