1*1fd5a2e1SPrashanth Swaminathan/* ----------------------------------------------------------------------- 2*1fd5a2e1SPrashanth Swaminathan sysv.S - Copyright (c) 2009 Bradley Smith <[email protected]> 3*1fd5a2e1SPrashanth Swaminathan 4*1fd5a2e1SPrashanth Swaminathan AVR32 Foreign Function Interface 5*1fd5a2e1SPrashanth Swaminathan 6*1fd5a2e1SPrashanth Swaminathan Permission is hereby granted, free of charge, to any person obtaining 7*1fd5a2e1SPrashanth Swaminathan a copy of this software and associated documentation files (the 8*1fd5a2e1SPrashanth Swaminathan ``Software''), to deal in the Software without restriction, including 9*1fd5a2e1SPrashanth Swaminathan without limitation the rights to use, copy, modify, merge, publish, 10*1fd5a2e1SPrashanth Swaminathan distribute, sublicense, and/or sell copies of the Software, and to 11*1fd5a2e1SPrashanth Swaminathan permit persons to whom the Software is furnished to do so, subject to 12*1fd5a2e1SPrashanth Swaminathan the following conditions: 13*1fd5a2e1SPrashanth Swaminathan 14*1fd5a2e1SPrashanth Swaminathan The above copyright notice and this permission notice shall be included 15*1fd5a2e1SPrashanth Swaminathan in all copies or substantial portions of the Software. 16*1fd5a2e1SPrashanth Swaminathan 17*1fd5a2e1SPrashanth Swaminathan THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, 18*1fd5a2e1SPrashanth Swaminathan EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 19*1fd5a2e1SPrashanth Swaminathan MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 20*1fd5a2e1SPrashanth Swaminathan IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 21*1fd5a2e1SPrashanth Swaminathan CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 22*1fd5a2e1SPrashanth Swaminathan TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 23*1fd5a2e1SPrashanth Swaminathan SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 24*1fd5a2e1SPrashanth Swaminathan --------------------------------------------------------------------- */ 25*1fd5a2e1SPrashanth Swaminathan 26*1fd5a2e1SPrashanth Swaminathan#define LIBFFI_ASM 27*1fd5a2e1SPrashanth Swaminathan#include <fficonfig.h> 28*1fd5a2e1SPrashanth Swaminathan#include <ffi.h> 29*1fd5a2e1SPrashanth Swaminathan 30*1fd5a2e1SPrashanth Swaminathan /* r12: ffi_prep_args 31*1fd5a2e1SPrashanth Swaminathan * r11: &ecif 32*1fd5a2e1SPrashanth Swaminathan * r10: size 33*1fd5a2e1SPrashanth Swaminathan * r9: cif->flags 34*1fd5a2e1SPrashanth Swaminathan * r8: ecif.rvalue 35*1fd5a2e1SPrashanth Swaminathan * sp+0: cif->rstruct_flag 36*1fd5a2e1SPrashanth Swaminathan * sp+4: fn */ 37*1fd5a2e1SPrashanth Swaminathan 38*1fd5a2e1SPrashanth Swaminathan .text 39*1fd5a2e1SPrashanth Swaminathan .align 1 40*1fd5a2e1SPrashanth Swaminathan .globl ffi_call_SYSV 41*1fd5a2e1SPrashanth Swaminathan .type ffi_call_SYSV, @function 42*1fd5a2e1SPrashanth Swaminathanffi_call_SYSV: 43*1fd5a2e1SPrashanth Swaminathan stm --sp, r0,r1,lr 44*1fd5a2e1SPrashanth Swaminathan stm --sp, r8-r12 45*1fd5a2e1SPrashanth Swaminathan mov r0, sp 46*1fd5a2e1SPrashanth Swaminathan 47*1fd5a2e1SPrashanth Swaminathan /* Make room for all of the new args. */ 48*1fd5a2e1SPrashanth Swaminathan sub sp, r10 49*1fd5a2e1SPrashanth Swaminathan /* Pad to make way for potential skipped registers */ 50*1fd5a2e1SPrashanth Swaminathan sub sp, 20 51*1fd5a2e1SPrashanth Swaminathan 52*1fd5a2e1SPrashanth Swaminathan /* Call ffi_prep_args(stack, &ecif). */ 53*1fd5a2e1SPrashanth Swaminathan /* r11 already set */ 54*1fd5a2e1SPrashanth Swaminathan mov r1, r12 55*1fd5a2e1SPrashanth Swaminathan mov r12, sp 56*1fd5a2e1SPrashanth Swaminathan icall r1 57*1fd5a2e1SPrashanth Swaminathan 58*1fd5a2e1SPrashanth Swaminathan /* Save new argument size */ 59*1fd5a2e1SPrashanth Swaminathan mov r1, r12 60*1fd5a2e1SPrashanth Swaminathan 61*1fd5a2e1SPrashanth Swaminathan /* Move first 5 parameters in registers. */ 62*1fd5a2e1SPrashanth Swaminathan ldm sp++, r8-r12 63*1fd5a2e1SPrashanth Swaminathan 64*1fd5a2e1SPrashanth Swaminathan /* call (fn) (...). */ 65*1fd5a2e1SPrashanth Swaminathan ld.w r1, r0[36] 66*1fd5a2e1SPrashanth Swaminathan icall r1 67*1fd5a2e1SPrashanth Swaminathan 68*1fd5a2e1SPrashanth Swaminathan /* Remove the space we pushed for the args. */ 69*1fd5a2e1SPrashanth Swaminathan mov sp, r0 70*1fd5a2e1SPrashanth Swaminathan 71*1fd5a2e1SPrashanth Swaminathan /* Load r1 with the rstruct flag. */ 72*1fd5a2e1SPrashanth Swaminathan ld.w r1, sp[32] 73*1fd5a2e1SPrashanth Swaminathan 74*1fd5a2e1SPrashanth Swaminathan /* Load r9 with the return type code. */ 75*1fd5a2e1SPrashanth Swaminathan ld.w r9, sp[12] 76*1fd5a2e1SPrashanth Swaminathan 77*1fd5a2e1SPrashanth Swaminathan /* Load r8 with the return value pointer. */ 78*1fd5a2e1SPrashanth Swaminathan ld.w r8, sp[16] 79*1fd5a2e1SPrashanth Swaminathan 80*1fd5a2e1SPrashanth Swaminathan /* If the return value pointer is NULL, assume no return value. */ 81*1fd5a2e1SPrashanth Swaminathan cp.w r8, 0 82*1fd5a2e1SPrashanth Swaminathan breq .Lend 83*1fd5a2e1SPrashanth Swaminathan 84*1fd5a2e1SPrashanth Swaminathan /* Check if return type is actually a struct */ 85*1fd5a2e1SPrashanth Swaminathan cp.w r1, 0 86*1fd5a2e1SPrashanth Swaminathan breq 1f 87*1fd5a2e1SPrashanth Swaminathan 88*1fd5a2e1SPrashanth Swaminathan /* Return 8bit */ 89*1fd5a2e1SPrashanth Swaminathan cp.w r9, FFI_TYPE_UINT8 90*1fd5a2e1SPrashanth Swaminathan breq .Lstore8 91*1fd5a2e1SPrashanth Swaminathan 92*1fd5a2e1SPrashanth Swaminathan /* Return 16bit */ 93*1fd5a2e1SPrashanth Swaminathan cp.w r9, FFI_TYPE_UINT16 94*1fd5a2e1SPrashanth Swaminathan breq .Lstore16 95*1fd5a2e1SPrashanth Swaminathan 96*1fd5a2e1SPrashanth Swaminathan1: 97*1fd5a2e1SPrashanth Swaminathan /* Return 32bit */ 98*1fd5a2e1SPrashanth Swaminathan cp.w r9, FFI_TYPE_UINT32 99*1fd5a2e1SPrashanth Swaminathan breq .Lstore32 100*1fd5a2e1SPrashanth Swaminathan cp.w r9, FFI_TYPE_UINT16 101*1fd5a2e1SPrashanth Swaminathan breq .Lstore32 102*1fd5a2e1SPrashanth Swaminathan cp.w r9, FFI_TYPE_UINT8 103*1fd5a2e1SPrashanth Swaminathan breq .Lstore32 104*1fd5a2e1SPrashanth Swaminathan 105*1fd5a2e1SPrashanth Swaminathan /* Return 64bit */ 106*1fd5a2e1SPrashanth Swaminathan cp.w r9, FFI_TYPE_UINT64 107*1fd5a2e1SPrashanth Swaminathan breq .Lstore64 108*1fd5a2e1SPrashanth Swaminathan 109*1fd5a2e1SPrashanth Swaminathan /* Didn't match anything */ 110*1fd5a2e1SPrashanth Swaminathan bral .Lend 111*1fd5a2e1SPrashanth Swaminathan 112*1fd5a2e1SPrashanth Swaminathan.Lstore64: 113*1fd5a2e1SPrashanth Swaminathan st.w r8[0], r11 114*1fd5a2e1SPrashanth Swaminathan st.w r8[4], r10 115*1fd5a2e1SPrashanth Swaminathan bral .Lend 116*1fd5a2e1SPrashanth Swaminathan 117*1fd5a2e1SPrashanth Swaminathan.Lstore32: 118*1fd5a2e1SPrashanth Swaminathan st.w r8[0], r12 119*1fd5a2e1SPrashanth Swaminathan bral .Lend 120*1fd5a2e1SPrashanth Swaminathan 121*1fd5a2e1SPrashanth Swaminathan.Lstore16: 122*1fd5a2e1SPrashanth Swaminathan st.h r8[0], r12 123*1fd5a2e1SPrashanth Swaminathan bral .Lend 124*1fd5a2e1SPrashanth Swaminathan 125*1fd5a2e1SPrashanth Swaminathan.Lstore8: 126*1fd5a2e1SPrashanth Swaminathan st.b r8[0], r12 127*1fd5a2e1SPrashanth Swaminathan bral .Lend 128*1fd5a2e1SPrashanth Swaminathan 129*1fd5a2e1SPrashanth Swaminathan.Lend: 130*1fd5a2e1SPrashanth Swaminathan sub sp, -20 131*1fd5a2e1SPrashanth Swaminathan ldm sp++, r0,r1,pc 132*1fd5a2e1SPrashanth Swaminathan 133*1fd5a2e1SPrashanth Swaminathan .size ffi_call_SYSV, . - ffi_call_SYSV 134*1fd5a2e1SPrashanth Swaminathan 135*1fd5a2e1SPrashanth Swaminathan 136*1fd5a2e1SPrashanth Swaminathan /* r12: __ctx 137*1fd5a2e1SPrashanth Swaminathan * r11: __rstruct_flag 138*1fd5a2e1SPrashanth Swaminathan * r10: __inner */ 139*1fd5a2e1SPrashanth Swaminathan 140*1fd5a2e1SPrashanth Swaminathan .align 1 141*1fd5a2e1SPrashanth Swaminathan .globl ffi_closure_SYSV 142*1fd5a2e1SPrashanth Swaminathan .type ffi_closure_SYSV, @function 143*1fd5a2e1SPrashanth Swaminathanffi_closure_SYSV: 144*1fd5a2e1SPrashanth Swaminathan stm --sp, r0,lr 145*1fd5a2e1SPrashanth Swaminathan mov r0, r11 146*1fd5a2e1SPrashanth Swaminathan mov r8, r10 147*1fd5a2e1SPrashanth Swaminathan sub r10, sp, -8 148*1fd5a2e1SPrashanth Swaminathan sub sp, 12 149*1fd5a2e1SPrashanth Swaminathan st.w sp[8], sp 150*1fd5a2e1SPrashanth Swaminathan sub r11, sp, -8 151*1fd5a2e1SPrashanth Swaminathan icall r8 152*1fd5a2e1SPrashanth Swaminathan 153*1fd5a2e1SPrashanth Swaminathan /* Check if return type is actually a struct */ 154*1fd5a2e1SPrashanth Swaminathan cp.w r0, 0 155*1fd5a2e1SPrashanth Swaminathan breq 1f 156*1fd5a2e1SPrashanth Swaminathan 157*1fd5a2e1SPrashanth Swaminathan /* Return 8bit */ 158*1fd5a2e1SPrashanth Swaminathan cp.w r12, FFI_TYPE_UINT8 159*1fd5a2e1SPrashanth Swaminathan breq .Lget8 160*1fd5a2e1SPrashanth Swaminathan 161*1fd5a2e1SPrashanth Swaminathan /* Return 16bit */ 162*1fd5a2e1SPrashanth Swaminathan cp.w r12, FFI_TYPE_UINT16 163*1fd5a2e1SPrashanth Swaminathan breq .Lget16 164*1fd5a2e1SPrashanth Swaminathan 165*1fd5a2e1SPrashanth Swaminathan1: 166*1fd5a2e1SPrashanth Swaminathan /* Return 32bit */ 167*1fd5a2e1SPrashanth Swaminathan cp.w r12, FFI_TYPE_UINT32 168*1fd5a2e1SPrashanth Swaminathan breq .Lget32 169*1fd5a2e1SPrashanth Swaminathan cp.w r12, FFI_TYPE_UINT16 170*1fd5a2e1SPrashanth Swaminathan breq .Lget32 171*1fd5a2e1SPrashanth Swaminathan cp.w r12, FFI_TYPE_UINT8 172*1fd5a2e1SPrashanth Swaminathan breq .Lget32 173*1fd5a2e1SPrashanth Swaminathan 174*1fd5a2e1SPrashanth Swaminathan /* Return 64bit */ 175*1fd5a2e1SPrashanth Swaminathan cp.w r12, FFI_TYPE_UINT64 176*1fd5a2e1SPrashanth Swaminathan breq .Lget64 177*1fd5a2e1SPrashanth Swaminathan 178*1fd5a2e1SPrashanth Swaminathan /* Didn't match anything */ 179*1fd5a2e1SPrashanth Swaminathan bral .Lclend 180*1fd5a2e1SPrashanth Swaminathan 181*1fd5a2e1SPrashanth Swaminathan.Lget64: 182*1fd5a2e1SPrashanth Swaminathan ld.w r11, sp[0] 183*1fd5a2e1SPrashanth Swaminathan ld.w r10, sp[4] 184*1fd5a2e1SPrashanth Swaminathan bral .Lclend 185*1fd5a2e1SPrashanth Swaminathan 186*1fd5a2e1SPrashanth Swaminathan.Lget32: 187*1fd5a2e1SPrashanth Swaminathan ld.w r12, sp[0] 188*1fd5a2e1SPrashanth Swaminathan bral .Lclend 189*1fd5a2e1SPrashanth Swaminathan 190*1fd5a2e1SPrashanth Swaminathan.Lget16: 191*1fd5a2e1SPrashanth Swaminathan ld.uh r12, sp[0] 192*1fd5a2e1SPrashanth Swaminathan bral .Lclend 193*1fd5a2e1SPrashanth Swaminathan 194*1fd5a2e1SPrashanth Swaminathan.Lget8: 195*1fd5a2e1SPrashanth Swaminathan ld.ub r12, sp[0] 196*1fd5a2e1SPrashanth Swaminathan bral .Lclend 197*1fd5a2e1SPrashanth Swaminathan 198*1fd5a2e1SPrashanth Swaminathan.Lclend: 199*1fd5a2e1SPrashanth Swaminathan sub sp, -12 200*1fd5a2e1SPrashanth Swaminathan ldm sp++, r0,lr 201*1fd5a2e1SPrashanth Swaminathan sub sp, -20 202*1fd5a2e1SPrashanth Swaminathan mov pc, lr 203*1fd5a2e1SPrashanth Swaminathan 204*1fd5a2e1SPrashanth Swaminathan .size ffi_closure_SYSV, . - ffi_closure_SYSV 205*1fd5a2e1SPrashanth Swaminathan 206*1fd5a2e1SPrashanth Swaminathan#if defined __ELF__ && defined __linux__ 207*1fd5a2e1SPrashanth Swaminathan .section .note.GNU-stack,"",@progbits 208*1fd5a2e1SPrashanth Swaminathan#endif 209