1*1fd5a2e1SPrashanth Swaminathan/* ----------------------------------------------------------------------- 2*1fd5a2e1SPrashanth Swaminathan sysv.S - Copyright (c) 2013 Tensilica, Inc. 3*1fd5a2e1SPrashanth Swaminathan 4*1fd5a2e1SPrashanth Swaminathan XTENSA 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 20*1fd5a2e1SPrashanth Swaminathan NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 21*1fd5a2e1SPrashanth Swaminathan HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 22*1fd5a2e1SPrashanth Swaminathan WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 23*1fd5a2e1SPrashanth Swaminathan OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 24*1fd5a2e1SPrashanth Swaminathan DEALINGS IN THE SOFTWARE. 25*1fd5a2e1SPrashanth Swaminathan ----------------------------------------------------------------------- */ 26*1fd5a2e1SPrashanth Swaminathan 27*1fd5a2e1SPrashanth Swaminathan#define LIBFFI_ASM 28*1fd5a2e1SPrashanth Swaminathan#include <fficonfig.h> 29*1fd5a2e1SPrashanth Swaminathan#include <ffi.h> 30*1fd5a2e1SPrashanth Swaminathan 31*1fd5a2e1SPrashanth Swaminathan#define ENTRY(name) .text; .globl name; .type name,@function; .align 4; name: 32*1fd5a2e1SPrashanth Swaminathan#define END(name) .size name , . - name 33*1fd5a2e1SPrashanth Swaminathan 34*1fd5a2e1SPrashanth Swaminathan/* Assert that the table below is in sync with ffi.h. */ 35*1fd5a2e1SPrashanth Swaminathan 36*1fd5a2e1SPrashanth Swaminathan#if FFI_TYPE_UINT8 != 5 \ 37*1fd5a2e1SPrashanth Swaminathan || FFI_TYPE_SINT8 != 6 \ 38*1fd5a2e1SPrashanth Swaminathan || FFI_TYPE_UINT16 != 7 \ 39*1fd5a2e1SPrashanth Swaminathan || FFI_TYPE_SINT16 != 8 \ 40*1fd5a2e1SPrashanth Swaminathan || FFI_TYPE_UINT32 != 9 \ 41*1fd5a2e1SPrashanth Swaminathan || FFI_TYPE_SINT32 != 10 \ 42*1fd5a2e1SPrashanth Swaminathan || FFI_TYPE_UINT64 != 11 43*1fd5a2e1SPrashanth Swaminathan#error "xtensa/sysv.S out of sync with ffi.h" 44*1fd5a2e1SPrashanth Swaminathan#endif 45*1fd5a2e1SPrashanth Swaminathan 46*1fd5a2e1SPrashanth Swaminathan 47*1fd5a2e1SPrashanth Swaminathan/* ffi_call_SYSV (rvalue, rbytes, flags, (*fnaddr)(), bytes, ecif) 48*1fd5a2e1SPrashanth Swaminathan void *rvalue; a2 49*1fd5a2e1SPrashanth Swaminathan unsigned long rbytes; a3 50*1fd5a2e1SPrashanth Swaminathan unsigned flags; a4 51*1fd5a2e1SPrashanth Swaminathan void (*fnaddr)(); a5 52*1fd5a2e1SPrashanth Swaminathan unsigned long bytes; a6 53*1fd5a2e1SPrashanth Swaminathan extended_cif* ecif) a7 54*1fd5a2e1SPrashanth Swaminathan*/ 55*1fd5a2e1SPrashanth Swaminathan 56*1fd5a2e1SPrashanth SwaminathanENTRY(ffi_call_SYSV) 57*1fd5a2e1SPrashanth Swaminathan 58*1fd5a2e1SPrashanth Swaminathan entry a1, 32 # 32 byte frame for using call8 below 59*1fd5a2e1SPrashanth Swaminathan 60*1fd5a2e1SPrashanth Swaminathan mov a10, a7 # a10(->arg0): ecif 61*1fd5a2e1SPrashanth Swaminathan sub a11, a1, a6 # a11(->arg1): stack pointer 62*1fd5a2e1SPrashanth Swaminathan mov a7, a1 # fp 63*1fd5a2e1SPrashanth Swaminathan movsp a1, a11 # set new sp = old_sp - bytes 64*1fd5a2e1SPrashanth Swaminathan 65*1fd5a2e1SPrashanth Swaminathan movi a8, ffi_prep_args 66*1fd5a2e1SPrashanth Swaminathan callx8 a8 # ffi_prep_args(ecif, stack) 67*1fd5a2e1SPrashanth Swaminathan 68*1fd5a2e1SPrashanth Swaminathan # prepare to move stack pointer back up to 6 arguments 69*1fd5a2e1SPrashanth Swaminathan # note that 'bytes' is already aligned 70*1fd5a2e1SPrashanth Swaminathan 71*1fd5a2e1SPrashanth Swaminathan movi a10, 6*4 72*1fd5a2e1SPrashanth Swaminathan sub a11, a6, a10 73*1fd5a2e1SPrashanth Swaminathan movgez a6, a10, a11 74*1fd5a2e1SPrashanth Swaminathan add a6, a1, a6 75*1fd5a2e1SPrashanth Swaminathan 76*1fd5a2e1SPrashanth Swaminathan 77*1fd5a2e1SPrashanth Swaminathan # we can pass up to 6 arguments in registers 78*1fd5a2e1SPrashanth Swaminathan # for simplicity, just load 6 arguments 79*1fd5a2e1SPrashanth Swaminathan # (the stack size is at least 32 bytes, so no risk to cross boundaries) 80*1fd5a2e1SPrashanth Swaminathan 81*1fd5a2e1SPrashanth Swaminathan l32i a10, a1, 0 82*1fd5a2e1SPrashanth Swaminathan l32i a11, a1, 4 83*1fd5a2e1SPrashanth Swaminathan l32i a12, a1, 8 84*1fd5a2e1SPrashanth Swaminathan l32i a13, a1, 12 85*1fd5a2e1SPrashanth Swaminathan l32i a14, a1, 16 86*1fd5a2e1SPrashanth Swaminathan l32i a15, a1, 20 87*1fd5a2e1SPrashanth Swaminathan 88*1fd5a2e1SPrashanth Swaminathan # move stack pointer 89*1fd5a2e1SPrashanth Swaminathan 90*1fd5a2e1SPrashanth Swaminathan movsp a1, a6 91*1fd5a2e1SPrashanth Swaminathan 92*1fd5a2e1SPrashanth Swaminathan callx8 a5 # (*fn)(args...) 93*1fd5a2e1SPrashanth Swaminathan 94*1fd5a2e1SPrashanth Swaminathan # Handle return value(s) 95*1fd5a2e1SPrashanth Swaminathan 96*1fd5a2e1SPrashanth Swaminathan beqz a2, .Lexit 97*1fd5a2e1SPrashanth Swaminathan 98*1fd5a2e1SPrashanth Swaminathan movi a5, FFI_TYPE_STRUCT 99*1fd5a2e1SPrashanth Swaminathan bne a4, a5, .Lstore 100*1fd5a2e1SPrashanth Swaminathan movi a5, 16 101*1fd5a2e1SPrashanth Swaminathan blt a5, a3, .Lexit 102*1fd5a2e1SPrashanth Swaminathan 103*1fd5a2e1SPrashanth Swaminathan s32i a10, a2, 0 104*1fd5a2e1SPrashanth Swaminathan blti a3, 5, .Lexit 105*1fd5a2e1SPrashanth Swaminathan addi a3, a3, -1 106*1fd5a2e1SPrashanth Swaminathan s32i a11, a2, 4 107*1fd5a2e1SPrashanth Swaminathan blti a3, 8, .Lexit 108*1fd5a2e1SPrashanth Swaminathan s32i a12, a2, 8 109*1fd5a2e1SPrashanth Swaminathan blti a3, 12, .Lexit 110*1fd5a2e1SPrashanth Swaminathan s32i a13, a2, 12 111*1fd5a2e1SPrashanth Swaminathan 112*1fd5a2e1SPrashanth Swaminathan.Lexit: retw 113*1fd5a2e1SPrashanth Swaminathan 114*1fd5a2e1SPrashanth Swaminathan.Lstore: 115*1fd5a2e1SPrashanth Swaminathan addi a4, a4, -FFI_TYPE_UINT8 116*1fd5a2e1SPrashanth Swaminathan bgei a4, 7, .Lexit # should never happen 117*1fd5a2e1SPrashanth Swaminathan movi a6, store_calls 118*1fd5a2e1SPrashanth Swaminathan add a4, a4, a4 119*1fd5a2e1SPrashanth Swaminathan addx4 a6, a4, a6 # store_table + idx * 8 120*1fd5a2e1SPrashanth Swaminathan jx a6 121*1fd5a2e1SPrashanth Swaminathan 122*1fd5a2e1SPrashanth Swaminathan .align 8 123*1fd5a2e1SPrashanth Swaminathanstore_calls: 124*1fd5a2e1SPrashanth Swaminathan # UINT8 125*1fd5a2e1SPrashanth Swaminathan s8i a10, a2, 0 126*1fd5a2e1SPrashanth Swaminathan retw 127*1fd5a2e1SPrashanth Swaminathan 128*1fd5a2e1SPrashanth Swaminathan # SINT8 129*1fd5a2e1SPrashanth Swaminathan .align 8 130*1fd5a2e1SPrashanth Swaminathan s8i a10, a2, 0 131*1fd5a2e1SPrashanth Swaminathan retw 132*1fd5a2e1SPrashanth Swaminathan 133*1fd5a2e1SPrashanth Swaminathan # UINT16 134*1fd5a2e1SPrashanth Swaminathan .align 8 135*1fd5a2e1SPrashanth Swaminathan s16i a10, a2, 0 136*1fd5a2e1SPrashanth Swaminathan retw 137*1fd5a2e1SPrashanth Swaminathan 138*1fd5a2e1SPrashanth Swaminathan # SINT16 139*1fd5a2e1SPrashanth Swaminathan .align 8 140*1fd5a2e1SPrashanth Swaminathan s16i a10, a2, 0 141*1fd5a2e1SPrashanth Swaminathan retw 142*1fd5a2e1SPrashanth Swaminathan 143*1fd5a2e1SPrashanth Swaminathan # UINT32 144*1fd5a2e1SPrashanth Swaminathan .align 8 145*1fd5a2e1SPrashanth Swaminathan s32i a10, a2, 0 146*1fd5a2e1SPrashanth Swaminathan retw 147*1fd5a2e1SPrashanth Swaminathan 148*1fd5a2e1SPrashanth Swaminathan # SINT32 149*1fd5a2e1SPrashanth Swaminathan .align 8 150*1fd5a2e1SPrashanth Swaminathan s32i a10, a2, 0 151*1fd5a2e1SPrashanth Swaminathan retw 152*1fd5a2e1SPrashanth Swaminathan 153*1fd5a2e1SPrashanth Swaminathan # UINT64 154*1fd5a2e1SPrashanth Swaminathan .align 8 155*1fd5a2e1SPrashanth Swaminathan s32i a10, a2, 0 156*1fd5a2e1SPrashanth Swaminathan s32i a11, a2, 4 157*1fd5a2e1SPrashanth Swaminathan retw 158*1fd5a2e1SPrashanth Swaminathan 159*1fd5a2e1SPrashanth SwaminathanEND(ffi_call_SYSV) 160*1fd5a2e1SPrashanth Swaminathan 161*1fd5a2e1SPrashanth Swaminathan 162*1fd5a2e1SPrashanth Swaminathan/* 163*1fd5a2e1SPrashanth Swaminathan * void ffi_cacheflush (unsigned long start, unsigned long end) 164*1fd5a2e1SPrashanth Swaminathan */ 165*1fd5a2e1SPrashanth Swaminathan 166*1fd5a2e1SPrashanth Swaminathan#define EXTRA_ARGS_SIZE 24 167*1fd5a2e1SPrashanth Swaminathan 168*1fd5a2e1SPrashanth SwaminathanENTRY(ffi_cacheflush) 169*1fd5a2e1SPrashanth Swaminathan 170*1fd5a2e1SPrashanth Swaminathan entry a1, 16 171*1fd5a2e1SPrashanth Swaminathan 172*1fd5a2e1SPrashanth Swaminathan1: 173*1fd5a2e1SPrashanth Swaminathan#if XCHAL_DCACHE_SIZE 174*1fd5a2e1SPrashanth Swaminathan dhwbi a2, 0 175*1fd5a2e1SPrashanth Swaminathan#endif 176*1fd5a2e1SPrashanth Swaminathan#if XCHAL_ICACHE_SIZE 177*1fd5a2e1SPrashanth Swaminathan ihi a2, 0 178*1fd5a2e1SPrashanth Swaminathan#endif 179*1fd5a2e1SPrashanth Swaminathan addi a2, a2, 4 180*1fd5a2e1SPrashanth Swaminathan blt a2, a3, 1b 181*1fd5a2e1SPrashanth Swaminathan 182*1fd5a2e1SPrashanth Swaminathan retw 183*1fd5a2e1SPrashanth Swaminathan 184*1fd5a2e1SPrashanth SwaminathanEND(ffi_cacheflush) 185*1fd5a2e1SPrashanth Swaminathan 186*1fd5a2e1SPrashanth Swaminathan/* ffi_trampoline is copied to the stack */ 187*1fd5a2e1SPrashanth Swaminathan 188*1fd5a2e1SPrashanth SwaminathanENTRY(ffi_trampoline) 189*1fd5a2e1SPrashanth Swaminathan 190*1fd5a2e1SPrashanth Swaminathan entry a1, 16 + (FFI_REGISTER_NARGS * 4) + (4 * 4) # [ 0] 191*1fd5a2e1SPrashanth Swaminathan j 2f # [ 3] 192*1fd5a2e1SPrashanth Swaminathan .align 4 # [ 6] 193*1fd5a2e1SPrashanth Swaminathan1: .long 0 # [ 8] 194*1fd5a2e1SPrashanth Swaminathan2: l32r a15, 1b # [12] 195*1fd5a2e1SPrashanth Swaminathan _mov a14, a0 # [15] 196*1fd5a2e1SPrashanth Swaminathan callx0 a15 # [18] 197*1fd5a2e1SPrashanth Swaminathan # [21] 198*1fd5a2e1SPrashanth SwaminathanEND(ffi_trampoline) 199*1fd5a2e1SPrashanth Swaminathan 200*1fd5a2e1SPrashanth Swaminathan/* 201*1fd5a2e1SPrashanth Swaminathan * ffi_closure() 202*1fd5a2e1SPrashanth Swaminathan * 203*1fd5a2e1SPrashanth Swaminathan * a0: closure + 21 204*1fd5a2e1SPrashanth Swaminathan * a14: return address (a0) 205*1fd5a2e1SPrashanth Swaminathan */ 206*1fd5a2e1SPrashanth Swaminathan 207*1fd5a2e1SPrashanth SwaminathanENTRY(ffi_closure_SYSV) 208*1fd5a2e1SPrashanth Swaminathan 209*1fd5a2e1SPrashanth Swaminathan /* intentionally omitting entry here */ 210*1fd5a2e1SPrashanth Swaminathan 211*1fd5a2e1SPrashanth Swaminathan # restore return address (a0) and move pointer to closure to a10 212*1fd5a2e1SPrashanth Swaminathan addi a10, a0, -21 213*1fd5a2e1SPrashanth Swaminathan mov a0, a14 214*1fd5a2e1SPrashanth Swaminathan 215*1fd5a2e1SPrashanth Swaminathan # allow up to 4 arguments as return values 216*1fd5a2e1SPrashanth Swaminathan addi a11, a1, 4 * 4 217*1fd5a2e1SPrashanth Swaminathan 218*1fd5a2e1SPrashanth Swaminathan # save up to 6 arguments to stack (allocated by entry below) 219*1fd5a2e1SPrashanth Swaminathan s32i a2, a11, 0 220*1fd5a2e1SPrashanth Swaminathan s32i a3, a11, 4 221*1fd5a2e1SPrashanth Swaminathan s32i a4, a11, 8 222*1fd5a2e1SPrashanth Swaminathan s32i a5, a11, 12 223*1fd5a2e1SPrashanth Swaminathan s32i a6, a11, 16 224*1fd5a2e1SPrashanth Swaminathan s32i a7, a11, 20 225*1fd5a2e1SPrashanth Swaminathan 226*1fd5a2e1SPrashanth Swaminathan movi a8, ffi_closure_SYSV_inner 227*1fd5a2e1SPrashanth Swaminathan mov a12, a1 228*1fd5a2e1SPrashanth Swaminathan callx8 a8 # .._inner(*closure, **avalue, *rvalue) 229*1fd5a2e1SPrashanth Swaminathan 230*1fd5a2e1SPrashanth Swaminathan # load up to four return arguments 231*1fd5a2e1SPrashanth Swaminathan l32i a2, a1, 0 232*1fd5a2e1SPrashanth Swaminathan l32i a3, a1, 4 233*1fd5a2e1SPrashanth Swaminathan l32i a4, a1, 8 234*1fd5a2e1SPrashanth Swaminathan l32i a5, a1, 12 235*1fd5a2e1SPrashanth Swaminathan 236*1fd5a2e1SPrashanth Swaminathan # (sign-)extend return value 237*1fd5a2e1SPrashanth Swaminathan movi a11, FFI_TYPE_UINT8 238*1fd5a2e1SPrashanth Swaminathan bne a10, a11, 1f 239*1fd5a2e1SPrashanth Swaminathan extui a2, a2, 0, 8 240*1fd5a2e1SPrashanth Swaminathan retw 241*1fd5a2e1SPrashanth Swaminathan 242*1fd5a2e1SPrashanth Swaminathan1: movi a11, FFI_TYPE_SINT8 243*1fd5a2e1SPrashanth Swaminathan bne a10, a11, 1f 244*1fd5a2e1SPrashanth Swaminathan sext a2, a2, 7 245*1fd5a2e1SPrashanth Swaminathan retw 246*1fd5a2e1SPrashanth Swaminathan 247*1fd5a2e1SPrashanth Swaminathan1: movi a11, FFI_TYPE_UINT16 248*1fd5a2e1SPrashanth Swaminathan bne a10, a11, 1f 249*1fd5a2e1SPrashanth Swaminathan extui a2, a2, 0, 16 250*1fd5a2e1SPrashanth Swaminathan retw 251*1fd5a2e1SPrashanth Swaminathan 252*1fd5a2e1SPrashanth Swaminathan1: movi a11, FFI_TYPE_SINT16 253*1fd5a2e1SPrashanth Swaminathan bne a10, a11, 1f 254*1fd5a2e1SPrashanth Swaminathan sext a2, a2, 15 255*1fd5a2e1SPrashanth Swaminathan 256*1fd5a2e1SPrashanth Swaminathan1: retw 257*1fd5a2e1SPrashanth Swaminathan 258*1fd5a2e1SPrashanth SwaminathanEND(ffi_closure_SYSV) 259