1 /* ----------------------------------------------------------------------- 2 sysv.S - Copyright (c) 1998 Andreas Schwab 3 Copyright (c) 2008 Red Hat, Inc. 4 5 m68k Foreign Function Interface 6 7 Permission is hereby granted, free of charge, to any person obtaining 8 a copy of this software and associated documentation files (the 9 ``Software''), to deal in the Software without restriction, including 10 without limitation the rights to use, copy, modify, merge, publish, 11 distribute, sublicense, and/or sell copies of the Software, and to 12 permit persons to whom the Software is furnished to do so, subject to 13 the following conditions: 14 15 The above copyright notice and this permission notice shall be included 16 in all copies or substantial portions of the Software. 17 18 THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, 19 EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 20 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 21 NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 22 HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 23 WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 24 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 25 DEALINGS IN THE SOFTWARE. 26 ----------------------------------------------------------------------- */ 27 28 #define LIBFFI_ASM 29 #include <fficonfig.h> 30 #include <ffi.h> 31 32 #ifdef HAVE_AS_CFI_PSEUDO_OP 33 #define CFI_STARTPROC() .cfi_startproc 34 #define CFI_OFFSET(reg,off) .cfi_offset reg,off 35 #define CFI_DEF_CFA(reg,off) .cfi_def_cfa reg,off 36 #define CFI_ENDPROC() .cfi_endproc 37 #else 38 #define CFI_STARTPROC() 39 #define CFI_OFFSET(reg,off) 40 #define CFI_DEF_CFA(reg,off) 41 #define CFI_ENDPROC() 42 #endif 43 44 .text 45 46 .globl ffi_call_SYSV 47 .type ffi_call_SYSV,@function 48 .align 4 49 50 ffi_call_SYSV: 51 CFI_STARTPROC() 52 link %fp,#0 53 CFI_OFFSET(14,-8) 54 CFI_DEF_CFA(14,8) 55 move.l %d2,-(%sp) 56 CFI_OFFSET(2,-12) 57 58 | Make room for all of the new args. 59 sub.l 12(%fp),%sp 60 61 | Call ffi_prep_args 62 move.l 8(%fp),-(%sp) 63 pea 4(%sp) 64 #if !defined __PIC__ 65 jsr ffi_prep_args 66 #else 67 bsr.l ffi_prep_args@PLTPC 68 #endif 69 addq.l #8,%sp 70 71 | Pass pointer to struct value, if any 72 move.l %a0,%a1 73 74 | Call the function 75 move.l 24(%fp),%a0 76 jsr (%a0) 77 78 | Remove the space we pushed for the args 79 add.l 12(%fp),%sp 80 81 | Load the pointer to storage for the return value 82 move.l 20(%fp),%a1 83 84 | Load the return type code 85 move.l 16(%fp),%d2 86 87 | If the return value pointer is NULL, assume no return value. 88 tst.l %a1 89 jbeq noretval 90 91 btst #0,%d2 92 jbeq retlongint 93 move.l %d0,(%a1) 94 jbra epilogue 95 96 retlongint: 97 btst #1,%d2 98 jbeq retfloat 99 move.l %d0,(%a1) 100 move.l %d1,4(%a1) 101 jbra epilogue 102 103 retfloat: 104 btst #2,%d2 105 jbeq retdouble 106 fmove.s %fp0,(%a1) 107 jbra epilogue 108 109 retdouble: 110 btst #3,%d2 111 jbeq retlongdouble 112 fmove.d %fp0,(%a1) 113 jbra epilogue 114 115 retlongdouble: 116 btst #4,%d2 117 jbeq retpointer 118 fmove.x %fp0,(%a1) 119 jbra epilogue 120 121 retpointer: 122 btst #5,%d2 123 jbeq retstruct1 124 move.l %a0,(%a1) 125 jbra epilogue 126 127 retstruct1: 128 btst #6,%d2 129 jbeq retstruct2 130 move.b %d0,(%a1) 131 jbra epilogue 132 133 retstruct2: 134 btst #7,%d2 135 jbeq noretval 136 move.w %d0,(%a1) 137 138 noretval: 139 epilogue: 140 move.l (%sp)+,%d2 141 unlk %fp 142 rts 143 CFI_ENDPROC() 144 .size ffi_call_SYSV,.-ffi_call_SYSV 145 146 .globl ffi_closure_SYSV 147 .type ffi_closure_SYSV, @function 148 .align 4 149 150 ffi_closure_SYSV: 151 CFI_STARTPROC() 152 link %fp,#-12 153 CFI_OFFSET(14,-8) 154 CFI_DEF_CFA(14,8) 155 move.l %sp,-12(%fp) 156 pea 8(%fp) 157 pea -12(%fp) 158 move.l %a0,-(%sp) 159 #if !defined __PIC__ 160 jsr ffi_closure_SYSV_inner 161 #else 162 bsr.l ffi_closure_SYSV_inner@PLTPC 163 #endif 164 165 lsr.l #1,%d0 166 jne 1f 167 jcc .Lcls_epilogue 168 move.l -12(%fp),%d0 169 .Lcls_epilogue: 170 unlk %fp 171 rts 172 1: 173 lea -12(%fp),%a0 174 lsr.l #2,%d0 175 jne 1f 176 jcs .Lcls_ret_float 177 move.l (%a0)+,%d0 178 move.l (%a0),%d1 179 jra .Lcls_epilogue 180 .Lcls_ret_float: 181 fmove.s (%a0),%fp0 182 jra .Lcls_epilogue 183 1: 184 lsr.l #2,%d0 185 jne 1f 186 jcs .Lcls_ret_ldouble 187 fmove.d (%a0),%fp0 188 jra .Lcls_epilogue 189 .Lcls_ret_ldouble: 190 fmove.x (%a0),%fp0 191 jra .Lcls_epilogue 192 1: 193 lsr.l #2,%d0 194 jne .Lcls_ret_struct2 195 jcs .Lcls_ret_struct1 196 move.l (%a0),%a0 197 move.l %a0,%d0 198 jra .Lcls_epilogue 199 .Lcls_ret_struct1: 200 move.b (%a0),%d0 201 jra .Lcls_epilogue 202 .Lcls_ret_struct2: 203 move.w (%a0),%d0 204 jra .Lcls_epilogue 205 CFI_ENDPROC() 206 207 .size ffi_closure_SYSV,.-ffi_closure_SYSV 208 209 .globl ffi_closure_struct_SYSV 210 .type ffi_closure_struct_SYSV, @function 211 .align 4 212 213 ffi_closure_struct_SYSV: 214 CFI_STARTPROC() 215 link %fp,#0 216 CFI_OFFSET(14,-8) 217 CFI_DEF_CFA(14,8) 218 move.l %sp,-12(%fp) 219 pea 8(%fp) 220 move.l %a1,-(%sp) 221 move.l %a0,-(%sp) 222 #if !defined __PIC__ 223 jsr ffi_closure_SYSV_inner 224 #else 225 bsr.l ffi_closure_SYSV_inner@PLTPC 226 #endif 227 unlk %fp 228 rts 229 CFI_ENDPROC() 230 .size ffi_closure_struct_SYSV,.-ffi_closure_struct_SYSV 231 232 #if defined __ELF__ && defined __linux__ 233 .section .note.GNU-stack,"",@progbits 234 #endif 235