1*1fd5a2e1SPrashanth Swaminathan/* ----------------------------------------------------------------------- 2*1fd5a2e1SPrashanth Swaminathan sysv.S - Copyright (c) 2004 Simon Posnjak 3*1fd5a2e1SPrashanth Swaminathan Copyright (c) 2005 Axis Communications AB 4*1fd5a2e1SPrashanth Swaminathan 5*1fd5a2e1SPrashanth Swaminathan CRIS Foreign Function Interface 6*1fd5a2e1SPrashanth Swaminathan 7*1fd5a2e1SPrashanth Swaminathan Permission is hereby granted, free of charge, to any person obtaining 8*1fd5a2e1SPrashanth Swaminathan a copy of this software and associated documentation files (the 9*1fd5a2e1SPrashanth Swaminathan ``Software''), to deal in the Software without restriction, including 10*1fd5a2e1SPrashanth Swaminathan without limitation the rights to use, copy, modify, merge, publish, 11*1fd5a2e1SPrashanth Swaminathan distribute, sublicense, and/or sell copies of the Software, and to 12*1fd5a2e1SPrashanth Swaminathan permit persons to whom the Software is furnished to do so, subject to 13*1fd5a2e1SPrashanth Swaminathan the following conditions: 14*1fd5a2e1SPrashanth Swaminathan 15*1fd5a2e1SPrashanth Swaminathan The above copyright notice and this permission notice shall be included 16*1fd5a2e1SPrashanth Swaminathan in all copies or substantial portions of the Software. 17*1fd5a2e1SPrashanth Swaminathan 18*1fd5a2e1SPrashanth Swaminathan THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS 19*1fd5a2e1SPrashanth Swaminathan OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 20*1fd5a2e1SPrashanth Swaminathan MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 21*1fd5a2e1SPrashanth Swaminathan IN NO EVENT SHALL SIMON POSNJAK BE LIABLE FOR ANY CLAIM, DAMAGES OR 22*1fd5a2e1SPrashanth Swaminathan OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 23*1fd5a2e1SPrashanth Swaminathan ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 24*1fd5a2e1SPrashanth Swaminathan OTHER DEALINGS IN THE SOFTWARE. 25*1fd5a2e1SPrashanth Swaminathan ----------------------------------------------------------------------- */ 26*1fd5a2e1SPrashanth Swaminathan 27*1fd5a2e1SPrashanth Swaminathan#define LIBFFI_ASM 28*1fd5a2e1SPrashanth Swaminathan#include <ffi.h> 29*1fd5a2e1SPrashanth Swaminathan#define CONCAT(x,y) x ## y 30*1fd5a2e1SPrashanth Swaminathan#define XCONCAT(x,y) CONCAT (x, y) 31*1fd5a2e1SPrashanth Swaminathan#define L(x) XCONCAT (__USER_LABEL_PREFIX__, x) 32*1fd5a2e1SPrashanth Swaminathan 33*1fd5a2e1SPrashanth Swaminathan .text 34*1fd5a2e1SPrashanth Swaminathan 35*1fd5a2e1SPrashanth Swaminathan ;; OK, when we get called we should have this (according to 36*1fd5a2e1SPrashanth Swaminathan ;; AXIS ETRAX 100LX Programmer's Manual chapter 6.3). 37*1fd5a2e1SPrashanth Swaminathan ;; 38*1fd5a2e1SPrashanth Swaminathan ;; R10: ffi_prep_args (func. pointer) 39*1fd5a2e1SPrashanth Swaminathan ;; R11: &ecif 40*1fd5a2e1SPrashanth Swaminathan ;; R12: cif->bytes 41*1fd5a2e1SPrashanth Swaminathan ;; R13: fig->flags 42*1fd5a2e1SPrashanth Swaminathan ;; sp+0: ecif.rvalue 43*1fd5a2e1SPrashanth Swaminathan ;; sp+4: fn (function pointer to the function that we need to call) 44*1fd5a2e1SPrashanth Swaminathan 45*1fd5a2e1SPrashanth Swaminathan .globl L(ffi_call_SYSV) 46*1fd5a2e1SPrashanth Swaminathan .type L(ffi_call_SYSV),@function 47*1fd5a2e1SPrashanth Swaminathan .hidden L(ffi_call_SYSV) 48*1fd5a2e1SPrashanth Swaminathan 49*1fd5a2e1SPrashanth SwaminathanL(ffi_call_SYSV): 50*1fd5a2e1SPrashanth Swaminathan ;; Save the regs to the stack. 51*1fd5a2e1SPrashanth Swaminathan push $srp 52*1fd5a2e1SPrashanth Swaminathan ;; Used for stack pointer saving. 53*1fd5a2e1SPrashanth Swaminathan push $r6 54*1fd5a2e1SPrashanth Swaminathan ;; Used for function address pointer. 55*1fd5a2e1SPrashanth Swaminathan push $r7 56*1fd5a2e1SPrashanth Swaminathan ;; Used for stack pointer saving. 57*1fd5a2e1SPrashanth Swaminathan push $r8 58*1fd5a2e1SPrashanth Swaminathan ;; We save fig->flags to stack we will need them after we 59*1fd5a2e1SPrashanth Swaminathan ;; call The Function. 60*1fd5a2e1SPrashanth Swaminathan push $r13 61*1fd5a2e1SPrashanth Swaminathan 62*1fd5a2e1SPrashanth Swaminathan ;; Saving current stack pointer. 63*1fd5a2e1SPrashanth Swaminathan move.d $sp,$r8 64*1fd5a2e1SPrashanth Swaminathan move.d $sp,$r6 65*1fd5a2e1SPrashanth Swaminathan 66*1fd5a2e1SPrashanth Swaminathan ;; Move address of ffi_prep_args to r13. 67*1fd5a2e1SPrashanth Swaminathan move.d $r10,$r13 68*1fd5a2e1SPrashanth Swaminathan 69*1fd5a2e1SPrashanth Swaminathan ;; Make room on the stack for the args of fn. 70*1fd5a2e1SPrashanth Swaminathan sub.d $r12,$sp 71*1fd5a2e1SPrashanth Swaminathan 72*1fd5a2e1SPrashanth Swaminathan ;; Function void ffi_prep_args(char *stack, extended_cif *ecif) parameters are: 73*1fd5a2e1SPrashanth Swaminathan ;; r10 <-- stack pointer 74*1fd5a2e1SPrashanth Swaminathan ;; r11 <-- &ecif (already there) 75*1fd5a2e1SPrashanth Swaminathan move.d $sp,$r10 76*1fd5a2e1SPrashanth Swaminathan 77*1fd5a2e1SPrashanth Swaminathan ;; Call the function. 78*1fd5a2e1SPrashanth Swaminathan jsr $r13 79*1fd5a2e1SPrashanth Swaminathan 80*1fd5a2e1SPrashanth Swaminathan ;; Save the size of the structures which are passed on stack. 81*1fd5a2e1SPrashanth Swaminathan move.d $r10,$r7 82*1fd5a2e1SPrashanth Swaminathan 83*1fd5a2e1SPrashanth Swaminathan ;; Move first four args in to r10..r13. 84*1fd5a2e1SPrashanth Swaminathan move.d [$sp+0],$r10 85*1fd5a2e1SPrashanth Swaminathan move.d [$sp+4],$r11 86*1fd5a2e1SPrashanth Swaminathan move.d [$sp+8],$r12 87*1fd5a2e1SPrashanth Swaminathan move.d [$sp+12],$r13 88*1fd5a2e1SPrashanth Swaminathan 89*1fd5a2e1SPrashanth Swaminathan ;; Adjust the stack and check if any parameters are given on stack. 90*1fd5a2e1SPrashanth Swaminathan addq 16,$sp 91*1fd5a2e1SPrashanth Swaminathan sub.d $r7,$r6 92*1fd5a2e1SPrashanth Swaminathan cmp.d $sp,$r6 93*1fd5a2e1SPrashanth Swaminathan 94*1fd5a2e1SPrashanth Swaminathan bpl go_on 95*1fd5a2e1SPrashanth Swaminathan nop 96*1fd5a2e1SPrashanth Swaminathan 97*1fd5a2e1SPrashanth Swaminathango_on_no_params_on_stack: 98*1fd5a2e1SPrashanth Swaminathan move.d $r6,$sp 99*1fd5a2e1SPrashanth Swaminathan 100*1fd5a2e1SPrashanth Swaminathango_on: 101*1fd5a2e1SPrashanth Swaminathan ;; Discover if we need to put rval address in to r9. 102*1fd5a2e1SPrashanth Swaminathan move.d [$r8+0],$r7 103*1fd5a2e1SPrashanth Swaminathan cmpq FFI_TYPE_STRUCT,$r7 104*1fd5a2e1SPrashanth Swaminathan bne call_now 105*1fd5a2e1SPrashanth Swaminathan nop 106*1fd5a2e1SPrashanth Swaminathan 107*1fd5a2e1SPrashanth Swaminathan ;; Move rval address to $r9. 108*1fd5a2e1SPrashanth Swaminathan move.d [$r8+20],$r9 109*1fd5a2e1SPrashanth Swaminathan 110*1fd5a2e1SPrashanth Swaminathancall_now: 111*1fd5a2e1SPrashanth Swaminathan ;; Move address of The Function in to r7. 112*1fd5a2e1SPrashanth Swaminathan move.d [$r8+24],$r7 113*1fd5a2e1SPrashanth Swaminathan 114*1fd5a2e1SPrashanth Swaminathan ;; Call The Function. 115*1fd5a2e1SPrashanth Swaminathan jsr $r7 116*1fd5a2e1SPrashanth Swaminathan 117*1fd5a2e1SPrashanth Swaminathan ;; Reset stack. 118*1fd5a2e1SPrashanth Swaminathan move.d $r8,$sp 119*1fd5a2e1SPrashanth Swaminathan 120*1fd5a2e1SPrashanth Swaminathan ;; Load rval type (fig->flags) in to r13. 121*1fd5a2e1SPrashanth Swaminathan pop $r13 122*1fd5a2e1SPrashanth Swaminathan 123*1fd5a2e1SPrashanth Swaminathan ;; Detect rval type. 124*1fd5a2e1SPrashanth Swaminathan cmpq FFI_TYPE_VOID,$r13 125*1fd5a2e1SPrashanth Swaminathan beq epilogue 126*1fd5a2e1SPrashanth Swaminathan 127*1fd5a2e1SPrashanth Swaminathan cmpq FFI_TYPE_STRUCT,$r13 128*1fd5a2e1SPrashanth Swaminathan beq epilogue 129*1fd5a2e1SPrashanth Swaminathan 130*1fd5a2e1SPrashanth Swaminathan cmpq FFI_TYPE_DOUBLE,$r13 131*1fd5a2e1SPrashanth Swaminathan beq return_double_or_longlong 132*1fd5a2e1SPrashanth Swaminathan 133*1fd5a2e1SPrashanth Swaminathan cmpq FFI_TYPE_UINT64,$r13 134*1fd5a2e1SPrashanth Swaminathan beq return_double_or_longlong 135*1fd5a2e1SPrashanth Swaminathan 136*1fd5a2e1SPrashanth Swaminathan cmpq FFI_TYPE_SINT64,$r13 137*1fd5a2e1SPrashanth Swaminathan beq return_double_or_longlong 138*1fd5a2e1SPrashanth Swaminathan nop 139*1fd5a2e1SPrashanth Swaminathan 140*1fd5a2e1SPrashanth Swaminathan ;; Just return the 32 bit value. 141*1fd5a2e1SPrashanth Swaminathan ba return 142*1fd5a2e1SPrashanth Swaminathan nop 143*1fd5a2e1SPrashanth Swaminathan 144*1fd5a2e1SPrashanth Swaminathanreturn_double_or_longlong: 145*1fd5a2e1SPrashanth Swaminathan ;; Load half of the rval to r10 and the other half to r11. 146*1fd5a2e1SPrashanth Swaminathan move.d [$sp+16],$r13 147*1fd5a2e1SPrashanth Swaminathan move.d $r10,[$r13] 148*1fd5a2e1SPrashanth Swaminathan addq 4,$r13 149*1fd5a2e1SPrashanth Swaminathan move.d $r11,[$r13] 150*1fd5a2e1SPrashanth Swaminathan ba epilogue 151*1fd5a2e1SPrashanth Swaminathan nop 152*1fd5a2e1SPrashanth Swaminathan 153*1fd5a2e1SPrashanth Swaminathanreturn: 154*1fd5a2e1SPrashanth Swaminathan ;; Load the rval to r10. 155*1fd5a2e1SPrashanth Swaminathan move.d [$sp+16],$r13 156*1fd5a2e1SPrashanth Swaminathan move.d $r10,[$r13] 157*1fd5a2e1SPrashanth Swaminathan 158*1fd5a2e1SPrashanth Swaminathanepilogue: 159*1fd5a2e1SPrashanth Swaminathan pop $r8 160*1fd5a2e1SPrashanth Swaminathan pop $r7 161*1fd5a2e1SPrashanth Swaminathan pop $r6 162*1fd5a2e1SPrashanth Swaminathan Jump [$sp+] 163*1fd5a2e1SPrashanth Swaminathan 164*1fd5a2e1SPrashanth Swaminathan .size ffi_call_SYSV,.-ffi_call_SYSV 165*1fd5a2e1SPrashanth Swaminathan 166*1fd5a2e1SPrashanth Swaminathan/* Save R10..R13 into an array, somewhat like varargs. Copy the next 167*1fd5a2e1SPrashanth Swaminathan argument too, to simplify handling of any straddling parameter. 168*1fd5a2e1SPrashanth Swaminathan Save R9 and SP after those. Jump to function handling the rest. 169*1fd5a2e1SPrashanth Swaminathan Since this is a template, copied and the main function filled in by 170*1fd5a2e1SPrashanth Swaminathan the user. */ 171*1fd5a2e1SPrashanth Swaminathan 172*1fd5a2e1SPrashanth Swaminathan .globl L(ffi_cris_trampoline_template) 173*1fd5a2e1SPrashanth Swaminathan .type L(ffi_cris_trampoline_template),@function 174*1fd5a2e1SPrashanth Swaminathan .hidden L(ffi_cris_trampoline_template) 175*1fd5a2e1SPrashanth Swaminathan 176*1fd5a2e1SPrashanth SwaminathanL(ffi_cris_trampoline_template): 177*1fd5a2e1SPrashanth Swaminathan0: 178*1fd5a2e1SPrashanth Swaminathan /* The value we get for "PC" is right after the prefix instruction, 179*1fd5a2e1SPrashanth Swaminathan two bytes from the beginning, i.e. 0b+2. */ 180*1fd5a2e1SPrashanth Swaminathan move.d $r10,[$pc+2f-(0b+2)] 181*1fd5a2e1SPrashanth Swaminathan move.d $pc,$r10 182*1fd5a2e1SPrashanth Swaminathan1: 183*1fd5a2e1SPrashanth Swaminathan addq 2f-1b+4,$r10 184*1fd5a2e1SPrashanth Swaminathan move.d $r11,[$r10+] 185*1fd5a2e1SPrashanth Swaminathan move.d $r12,[$r10+] 186*1fd5a2e1SPrashanth Swaminathan move.d $r13,[$r10+] 187*1fd5a2e1SPrashanth Swaminathan move.d [$sp],$r11 188*1fd5a2e1SPrashanth Swaminathan move.d $r11,[$r10+] 189*1fd5a2e1SPrashanth Swaminathan move.d $r9,[$r10+] 190*1fd5a2e1SPrashanth Swaminathan move.d $sp,[$r10+] 191*1fd5a2e1SPrashanth Swaminathan subq FFI_CRIS_TRAMPOLINE_DATA_PART_SIZE,$r10 192*1fd5a2e1SPrashanth Swaminathan move.d 0,$r11 193*1fd5a2e1SPrashanth Swaminathan3: 194*1fd5a2e1SPrashanth Swaminathan jump 0 195*1fd5a2e1SPrashanth Swaminathan2: 196*1fd5a2e1SPrashanth Swaminathan .size ffi_cris_trampoline_template,.-0b 197*1fd5a2e1SPrashanth Swaminathan 198*1fd5a2e1SPrashanth Swaminathan/* This macro create a constant usable as "extern const int \name" in 199*1fd5a2e1SPrashanth Swaminathan C from within libffi, when \name has no prefix decoration. */ 200*1fd5a2e1SPrashanth Swaminathan 201*1fd5a2e1SPrashanth Swaminathan .macro const name,value 202*1fd5a2e1SPrashanth Swaminathan .globl \name 203*1fd5a2e1SPrashanth Swaminathan .type \name,@object 204*1fd5a2e1SPrashanth Swaminathan .hidden \name 205*1fd5a2e1SPrashanth Swaminathan\name: 206*1fd5a2e1SPrashanth Swaminathan .dword \value 207*1fd5a2e1SPrashanth Swaminathan .size \name,4 208*1fd5a2e1SPrashanth Swaminathan .endm 209*1fd5a2e1SPrashanth Swaminathan 210*1fd5a2e1SPrashanth Swaminathan/* Constants for offsets within the trampoline. We could do this with 211*1fd5a2e1SPrashanth Swaminathan just symbols, avoiding memory contents and memory accesses, but the 212*1fd5a2e1SPrashanth Swaminathan C usage code would look a bit stranger. */ 213*1fd5a2e1SPrashanth Swaminathan 214*1fd5a2e1SPrashanth Swaminathan const L(ffi_cris_trampoline_fn_offset),2b-4-0b 215*1fd5a2e1SPrashanth Swaminathan const L(ffi_cris_trampoline_closure_offset),3b-4-0b 216