1457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique/* ----------------------------------------------------------------------- 2457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique sysv.S - Copyright (c) 2004 Simon Posnjak 3457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique Copyright (c) 2005 Axis Communications AB 4457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique 5457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique CRIS Foreign Function Interface 6457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique 7457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique Permission is hereby granted, free of charge, to any person obtaining 8457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique a copy of this software and associated documentation files (the 9457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique ``Software''), to deal in the Software without restriction, including 10457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique without limitation the rights to use, copy, modify, merge, publish, 11457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique distribute, sublicense, and/or sell copies of the Software, and to 12457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique permit persons to whom the Software is furnished to do so, subject to 13457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique the following conditions: 14457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique 15457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique The above copyright notice and this permission notice shall be included 16457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique in all copies or substantial portions of the Software. 17457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique 18457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS 19457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 20457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 21457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique IN NO EVENT SHALL SIMON POSNJAK BE LIABLE FOR ANY CLAIM, DAMAGES OR 22457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 23457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 24457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique OTHER DEALINGS IN THE SOFTWARE. 25457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique ----------------------------------------------------------------------- */ 26457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique 27457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique#define LIBFFI_ASM 28457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique#include <ffi.h> 29457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique#define CONCAT(x,y) x ## y 30457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique#define XCONCAT(x,y) CONCAT (x, y) 31457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique#define L(x) XCONCAT (__USER_LABEL_PREFIX__, x) 32457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique 33457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique .text 34457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique 35457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique ;; OK, when we get called we should have this (according to 36457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique ;; AXIS ETRAX 100LX Programmer's Manual chapter 6.3). 37457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique ;; 38457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique ;; R10: ffi_prep_args (func. pointer) 39457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique ;; R11: &ecif 40457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique ;; R12: cif->bytes 41457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique ;; R13: fig->flags 42457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique ;; sp+0: ecif.rvalue 43457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique ;; sp+4: fn (function pointer to the function that we need to call) 44457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique 45457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique .globl L(ffi_call_SYSV) 46457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique .type L(ffi_call_SYSV),@function 47457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique .hidden L(ffi_call_SYSV) 48457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique 49457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd PiqueL(ffi_call_SYSV): 50457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique ;; Save the regs to the stack. 51457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique push $srp 52457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique ;; Used for stack pointer saving. 53457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique push $r6 54457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique ;; Used for function address pointer. 55457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique push $r7 56457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique ;; Used for stack pointer saving. 57457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique push $r8 58457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique ;; We save fig->flags to stack we will need them after we 59457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique ;; call The Function. 60457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique push $r13 61457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique 62457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique ;; Saving current stack pointer. 63457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique move.d $sp,$r8 64457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique move.d $sp,$r6 65457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique 66457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique ;; Move address of ffi_prep_args to r13. 67457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique move.d $r10,$r13 68457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique 69457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique ;; Make room on the stack for the args of fn. 70457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique sub.d $r12,$sp 71457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique 72457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique ;; Function void ffi_prep_args(char *stack, extended_cif *ecif) parameters are: 73457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique ;; r10 <-- stack pointer 74457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique ;; r11 <-- &ecif (already there) 75457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique move.d $sp,$r10 76457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique 77457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique ;; Call the function. 78457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique jsr $r13 79457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique 80457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique ;; Save the size of the structures which are passed on stack. 81457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique move.d $r10,$r7 82457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique 83457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique ;; Move first four args in to r10..r13. 84457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique move.d [$sp+0],$r10 85457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique move.d [$sp+4],$r11 86457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique move.d [$sp+8],$r12 87457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique move.d [$sp+12],$r13 88457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique 89457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique ;; Adjust the stack and check if any parameters are given on stack. 90457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique addq 16,$sp 91457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique sub.d $r7,$r6 92457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique cmp.d $sp,$r6 93457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique 94457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique bpl go_on 95457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique nop 96457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique 97457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Piquego_on_no_params_on_stack: 98457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique move.d $r6,$sp 99457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique 100457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Piquego_on: 101457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique ;; Discover if we need to put rval address in to r9. 102457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique move.d [$r8+0],$r7 103457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique cmpq FFI_TYPE_STRUCT,$r7 104457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique bne call_now 105457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique nop 106457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique 107457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique ;; Move rval address to $r9. 108457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique move.d [$r8+20],$r9 109457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique 110457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Piquecall_now: 111457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique ;; Move address of The Function in to r7. 112457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique move.d [$r8+24],$r7 113457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique 114457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique ;; Call The Function. 115457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique jsr $r7 116457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique 117457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique ;; Reset stack. 118457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique move.d $r8,$sp 119457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique 120457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique ;; Load rval type (fig->flags) in to r13. 121457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique pop $r13 122457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique 123457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique ;; Detect rval type. 124457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique cmpq FFI_TYPE_VOID,$r13 125457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique beq epilogue 126457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique 127457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique cmpq FFI_TYPE_STRUCT,$r13 128457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique beq epilogue 129457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique 130457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique cmpq FFI_TYPE_DOUBLE,$r13 131457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique beq return_double_or_longlong 132457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique 133457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique cmpq FFI_TYPE_UINT64,$r13 134457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique beq return_double_or_longlong 135457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique 136457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique cmpq FFI_TYPE_SINT64,$r13 137457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique beq return_double_or_longlong 138457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique nop 139457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique 140457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique ;; Just return the 32 bit value. 141457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique ba return 142457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique nop 143457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique 144457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Piquereturn_double_or_longlong: 145457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique ;; Load half of the rval to r10 and the other half to r11. 146457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique move.d [$sp+16],$r13 147457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique move.d $r10,[$r13] 148457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique addq 4,$r13 149457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique move.d $r11,[$r13] 150457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique ba epilogue 151457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique nop 152457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique 153457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Piquereturn: 154457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique ;; Load the rval to r10. 155457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique move.d [$sp+16],$r13 156457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique move.d $r10,[$r13] 157457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique 158457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Piqueepilogue: 159457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique pop $r8 160457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique pop $r7 161457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique pop $r6 162457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique Jump [$sp+] 163457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique 164457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique .size ffi_call_SYSV,.-ffi_call_SYSV 165457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique 166457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique/* Save R10..R13 into an array, somewhat like varargs. Copy the next 167457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique argument too, to simplify handling of any straddling parameter. 168457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique Save R9 and SP after those. Jump to function handling the rest. 169457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique Since this is a template, copied and the main function filled in by 170457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique the user. */ 171457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique 172457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique .globl L(ffi_cris_trampoline_template) 173457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique .type L(ffi_cris_trampoline_template),@function 174457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique .hidden L(ffi_cris_trampoline_template) 175457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique 176457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd PiqueL(ffi_cris_trampoline_template): 177457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique0: 178457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique /* The value we get for "PC" is right after the prefix instruction, 179457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique two bytes from the beginning, i.e. 0b+2. */ 180457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique move.d $r10,[$pc+2f-(0b+2)] 181457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique move.d $pc,$r10 182457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique1: 183457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique addq 2f-1b+4,$r10 184457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique move.d $r11,[$r10+] 185457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique move.d $r12,[$r10+] 186457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique move.d $r13,[$r10+] 187457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique move.d [$sp],$r11 188457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique move.d $r11,[$r10+] 189457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique move.d $r9,[$r10+] 190457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique move.d $sp,[$r10+] 191457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique subq FFI_CRIS_TRAMPOLINE_DATA_PART_SIZE,$r10 192457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique move.d 0,$r11 193457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique3: 194457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique jump 0 195457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique2: 196457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique .size ffi_cris_trampoline_template,.-0b 197457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique 198457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique/* This macro create a constant usable as "extern const int \name" in 199457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique C from within libffi, when \name has no prefix decoration. */ 200457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique 201457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique .macro const name,value 202457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique .globl \name 203457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique .type \name,@object 204457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique .hidden \name 205457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique\name: 206457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique .dword \value 207457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique .size \name,4 208457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique .endm 209457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique 210457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique/* Constants for offsets within the trampoline. We could do this with 211457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique just symbols, avoiding memory contents and memory accesses, but the 212457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique C usage code would look a bit stranger. */ 213457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique 214457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique const L(ffi_cris_trampoline_fn_offset),2b-4-0b 215457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique const L(ffi_cris_trampoline_closure_offset),3b-4-0b 216