1*1fd5a2e1SPrashanth Swaminathan/* Copyright (c) 2009, 2010, 2011, 2012 ARM Ltd. 2*1fd5a2e1SPrashanth Swaminathan 3*1fd5a2e1SPrashanth SwaminathanPermission is hereby granted, free of charge, to any person obtaining 4*1fd5a2e1SPrashanth Swaminathana copy of this software and associated documentation files (the 5*1fd5a2e1SPrashanth Swaminathan``Software''), to deal in the Software without restriction, including 6*1fd5a2e1SPrashanth Swaminathanwithout limitation the rights to use, copy, modify, merge, publish, 7*1fd5a2e1SPrashanth Swaminathandistribute, sublicense, and/or sell copies of the Software, and to 8*1fd5a2e1SPrashanth Swaminathanpermit persons to whom the Software is furnished to do so, subject to 9*1fd5a2e1SPrashanth Swaminathanthe following conditions: 10*1fd5a2e1SPrashanth Swaminathan 11*1fd5a2e1SPrashanth SwaminathanThe above copyright notice and this permission notice shall be 12*1fd5a2e1SPrashanth Swaminathanincluded in all copies or substantial portions of the Software. 13*1fd5a2e1SPrashanth Swaminathan 14*1fd5a2e1SPrashanth SwaminathanTHE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, 15*1fd5a2e1SPrashanth SwaminathanEXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 16*1fd5a2e1SPrashanth SwaminathanMERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 17*1fd5a2e1SPrashanth SwaminathanIN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 18*1fd5a2e1SPrashanth SwaminathanCLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 19*1fd5a2e1SPrashanth SwaminathanTORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 20*1fd5a2e1SPrashanth SwaminathanSOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ 21*1fd5a2e1SPrashanth Swaminathan 22*1fd5a2e1SPrashanth Swaminathan#if defined(__aarch64__) || defined(__arm64__) 23*1fd5a2e1SPrashanth Swaminathan#define LIBFFI_ASM 24*1fd5a2e1SPrashanth Swaminathan#include <fficonfig.h> 25*1fd5a2e1SPrashanth Swaminathan#include <ffi.h> 26*1fd5a2e1SPrashanth Swaminathan#include <ffi_cfi.h> 27*1fd5a2e1SPrashanth Swaminathan#include "internal.h" 28*1fd5a2e1SPrashanth Swaminathan 29*1fd5a2e1SPrashanth Swaminathan#ifdef HAVE_MACHINE_ASM_H 30*1fd5a2e1SPrashanth Swaminathan#include <machine/asm.h> 31*1fd5a2e1SPrashanth Swaminathan#else 32*1fd5a2e1SPrashanth Swaminathan#ifdef __USER_LABEL_PREFIX__ 33*1fd5a2e1SPrashanth Swaminathan#define CONCAT1(a, b) CONCAT2(a, b) 34*1fd5a2e1SPrashanth Swaminathan#define CONCAT2(a, b) a ## b 35*1fd5a2e1SPrashanth Swaminathan 36*1fd5a2e1SPrashanth Swaminathan/* Use the right prefix for global labels. */ 37*1fd5a2e1SPrashanth Swaminathan#define CNAME(x) CONCAT1 (__USER_LABEL_PREFIX__, x) 38*1fd5a2e1SPrashanth Swaminathan#else 39*1fd5a2e1SPrashanth Swaminathan#define CNAME(x) x 40*1fd5a2e1SPrashanth Swaminathan#endif 41*1fd5a2e1SPrashanth Swaminathan#endif 42*1fd5a2e1SPrashanth Swaminathan 43*1fd5a2e1SPrashanth Swaminathan#ifdef __AARCH64EB__ 44*1fd5a2e1SPrashanth Swaminathan# define BE(X) X 45*1fd5a2e1SPrashanth Swaminathan#else 46*1fd5a2e1SPrashanth Swaminathan# define BE(X) 0 47*1fd5a2e1SPrashanth Swaminathan#endif 48*1fd5a2e1SPrashanth Swaminathan 49*1fd5a2e1SPrashanth Swaminathan#ifdef __ILP32__ 50*1fd5a2e1SPrashanth Swaminathan#define PTR_REG(n) w##n 51*1fd5a2e1SPrashanth Swaminathan#else 52*1fd5a2e1SPrashanth Swaminathan#define PTR_REG(n) x##n 53*1fd5a2e1SPrashanth Swaminathan#endif 54*1fd5a2e1SPrashanth Swaminathan 55*1fd5a2e1SPrashanth Swaminathan#ifdef __ILP32__ 56*1fd5a2e1SPrashanth Swaminathan#define PTR_SIZE 4 57*1fd5a2e1SPrashanth Swaminathan#else 58*1fd5a2e1SPrashanth Swaminathan#define PTR_SIZE 8 59*1fd5a2e1SPrashanth Swaminathan#endif 60*1fd5a2e1SPrashanth Swaminathan 61*1fd5a2e1SPrashanth Swaminathan .text 62*1fd5a2e1SPrashanth Swaminathan .align 4 63*1fd5a2e1SPrashanth Swaminathan 64*1fd5a2e1SPrashanth Swaminathan/* ffi_call_SYSV 65*1fd5a2e1SPrashanth Swaminathan extern void ffi_call_SYSV (void *stack, void *frame, 66*1fd5a2e1SPrashanth Swaminathan void (*fn)(void), void *rvalue, 67*1fd5a2e1SPrashanth Swaminathan int flags, void *closure); 68*1fd5a2e1SPrashanth Swaminathan 69*1fd5a2e1SPrashanth Swaminathan Therefore on entry we have: 70*1fd5a2e1SPrashanth Swaminathan 71*1fd5a2e1SPrashanth Swaminathan x0 stack 72*1fd5a2e1SPrashanth Swaminathan x1 frame 73*1fd5a2e1SPrashanth Swaminathan x2 fn 74*1fd5a2e1SPrashanth Swaminathan x3 rvalue 75*1fd5a2e1SPrashanth Swaminathan x4 flags 76*1fd5a2e1SPrashanth Swaminathan x5 closure 77*1fd5a2e1SPrashanth Swaminathan*/ 78*1fd5a2e1SPrashanth Swaminathan 79*1fd5a2e1SPrashanth Swaminathan cfi_startproc 80*1fd5a2e1SPrashanth SwaminathanCNAME(ffi_call_SYSV): 81*1fd5a2e1SPrashanth Swaminathan /* Use a stack frame allocated by our caller. */ 82*1fd5a2e1SPrashanth Swaminathan cfi_def_cfa(x1, 32); 83*1fd5a2e1SPrashanth Swaminathan stp x29, x30, [x1] 84*1fd5a2e1SPrashanth Swaminathan mov x29, x1 85*1fd5a2e1SPrashanth Swaminathan mov sp, x0 86*1fd5a2e1SPrashanth Swaminathan cfi_def_cfa_register(x29) 87*1fd5a2e1SPrashanth Swaminathan cfi_rel_offset (x29, 0) 88*1fd5a2e1SPrashanth Swaminathan cfi_rel_offset (x30, 8) 89*1fd5a2e1SPrashanth Swaminathan 90*1fd5a2e1SPrashanth Swaminathan mov x9, x2 /* save fn */ 91*1fd5a2e1SPrashanth Swaminathan mov x8, x3 /* install structure return */ 92*1fd5a2e1SPrashanth Swaminathan#ifdef FFI_GO_CLOSURES 93*1fd5a2e1SPrashanth Swaminathan mov x18, x5 /* install static chain */ 94*1fd5a2e1SPrashanth Swaminathan#endif 95*1fd5a2e1SPrashanth Swaminathan stp x3, x4, [x29, #16] /* save rvalue and flags */ 96*1fd5a2e1SPrashanth Swaminathan 97*1fd5a2e1SPrashanth Swaminathan /* Load the vector argument passing registers, if necessary. */ 98*1fd5a2e1SPrashanth Swaminathan tbz w4, #AARCH64_FLAG_ARG_V_BIT, 1f 99*1fd5a2e1SPrashanth Swaminathan ldp q0, q1, [sp, #0] 100*1fd5a2e1SPrashanth Swaminathan ldp q2, q3, [sp, #32] 101*1fd5a2e1SPrashanth Swaminathan ldp q4, q5, [sp, #64] 102*1fd5a2e1SPrashanth Swaminathan ldp q6, q7, [sp, #96] 103*1fd5a2e1SPrashanth Swaminathan1: 104*1fd5a2e1SPrashanth Swaminathan /* Load the core argument passing registers, including 105*1fd5a2e1SPrashanth Swaminathan the structure return pointer. */ 106*1fd5a2e1SPrashanth Swaminathan ldp x0, x1, [sp, #16*N_V_ARG_REG + 0] 107*1fd5a2e1SPrashanth Swaminathan ldp x2, x3, [sp, #16*N_V_ARG_REG + 16] 108*1fd5a2e1SPrashanth Swaminathan ldp x4, x5, [sp, #16*N_V_ARG_REG + 32] 109*1fd5a2e1SPrashanth Swaminathan ldp x6, x7, [sp, #16*N_V_ARG_REG + 48] 110*1fd5a2e1SPrashanth Swaminathan 111*1fd5a2e1SPrashanth Swaminathan /* Deallocate the context, leaving the stacked arguments. */ 112*1fd5a2e1SPrashanth Swaminathan add sp, sp, #CALL_CONTEXT_SIZE 113*1fd5a2e1SPrashanth Swaminathan 114*1fd5a2e1SPrashanth Swaminathan blr x9 /* call fn */ 115*1fd5a2e1SPrashanth Swaminathan 116*1fd5a2e1SPrashanth Swaminathan ldp x3, x4, [x29, #16] /* reload rvalue and flags */ 117*1fd5a2e1SPrashanth Swaminathan 118*1fd5a2e1SPrashanth Swaminathan /* Partially deconstruct the stack frame. */ 119*1fd5a2e1SPrashanth Swaminathan mov sp, x29 120*1fd5a2e1SPrashanth Swaminathan cfi_def_cfa_register (sp) 121*1fd5a2e1SPrashanth Swaminathan ldp x29, x30, [x29] 122*1fd5a2e1SPrashanth Swaminathan 123*1fd5a2e1SPrashanth Swaminathan /* Save the return value as directed. */ 124*1fd5a2e1SPrashanth Swaminathan adr x5, 0f 125*1fd5a2e1SPrashanth Swaminathan and w4, w4, #AARCH64_RET_MASK 126*1fd5a2e1SPrashanth Swaminathan add x5, x5, x4, lsl #3 127*1fd5a2e1SPrashanth Swaminathan br x5 128*1fd5a2e1SPrashanth Swaminathan 129*1fd5a2e1SPrashanth Swaminathan /* Note that each table entry is 2 insns, and thus 8 bytes. 130*1fd5a2e1SPrashanth Swaminathan For integer data, note that we're storing into ffi_arg 131*1fd5a2e1SPrashanth Swaminathan and therefore we want to extend to 64 bits; these types 132*1fd5a2e1SPrashanth Swaminathan have two consecutive entries allocated for them. */ 133*1fd5a2e1SPrashanth Swaminathan .align 4 134*1fd5a2e1SPrashanth Swaminathan0: ret /* VOID */ 135*1fd5a2e1SPrashanth Swaminathan nop 136*1fd5a2e1SPrashanth Swaminathan1: str x0, [x3] /* INT64 */ 137*1fd5a2e1SPrashanth Swaminathan ret 138*1fd5a2e1SPrashanth Swaminathan2: stp x0, x1, [x3] /* INT128 */ 139*1fd5a2e1SPrashanth Swaminathan ret 140*1fd5a2e1SPrashanth Swaminathan3: brk #1000 /* UNUSED */ 141*1fd5a2e1SPrashanth Swaminathan ret 142*1fd5a2e1SPrashanth Swaminathan4: brk #1000 /* UNUSED */ 143*1fd5a2e1SPrashanth Swaminathan ret 144*1fd5a2e1SPrashanth Swaminathan5: brk #1000 /* UNUSED */ 145*1fd5a2e1SPrashanth Swaminathan ret 146*1fd5a2e1SPrashanth Swaminathan6: brk #1000 /* UNUSED */ 147*1fd5a2e1SPrashanth Swaminathan ret 148*1fd5a2e1SPrashanth Swaminathan7: brk #1000 /* UNUSED */ 149*1fd5a2e1SPrashanth Swaminathan ret 150*1fd5a2e1SPrashanth Swaminathan8: st4 { v0.s, v1.s, v2.s, v3.s }[0], [x3] /* S4 */ 151*1fd5a2e1SPrashanth Swaminathan ret 152*1fd5a2e1SPrashanth Swaminathan9: st3 { v0.s, v1.s, v2.s }[0], [x3] /* S3 */ 153*1fd5a2e1SPrashanth Swaminathan ret 154*1fd5a2e1SPrashanth Swaminathan10: stp s0, s1, [x3] /* S2 */ 155*1fd5a2e1SPrashanth Swaminathan ret 156*1fd5a2e1SPrashanth Swaminathan11: str s0, [x3] /* S1 */ 157*1fd5a2e1SPrashanth Swaminathan ret 158*1fd5a2e1SPrashanth Swaminathan12: st4 { v0.d, v1.d, v2.d, v3.d }[0], [x3] /* D4 */ 159*1fd5a2e1SPrashanth Swaminathan ret 160*1fd5a2e1SPrashanth Swaminathan13: st3 { v0.d, v1.d, v2.d }[0], [x3] /* D3 */ 161*1fd5a2e1SPrashanth Swaminathan ret 162*1fd5a2e1SPrashanth Swaminathan14: stp d0, d1, [x3] /* D2 */ 163*1fd5a2e1SPrashanth Swaminathan ret 164*1fd5a2e1SPrashanth Swaminathan15: str d0, [x3] /* D1 */ 165*1fd5a2e1SPrashanth Swaminathan ret 166*1fd5a2e1SPrashanth Swaminathan16: str q3, [x3, #48] /* Q4 */ 167*1fd5a2e1SPrashanth Swaminathan nop 168*1fd5a2e1SPrashanth Swaminathan17: str q2, [x3, #32] /* Q3 */ 169*1fd5a2e1SPrashanth Swaminathan nop 170*1fd5a2e1SPrashanth Swaminathan18: stp q0, q1, [x3] /* Q2 */ 171*1fd5a2e1SPrashanth Swaminathan ret 172*1fd5a2e1SPrashanth Swaminathan19: str q0, [x3] /* Q1 */ 173*1fd5a2e1SPrashanth Swaminathan ret 174*1fd5a2e1SPrashanth Swaminathan20: uxtb w0, w0 /* UINT8 */ 175*1fd5a2e1SPrashanth Swaminathan str x0, [x3] 176*1fd5a2e1SPrashanth Swaminathan21: ret /* reserved */ 177*1fd5a2e1SPrashanth Swaminathan nop 178*1fd5a2e1SPrashanth Swaminathan22: uxth w0, w0 /* UINT16 */ 179*1fd5a2e1SPrashanth Swaminathan str x0, [x3] 180*1fd5a2e1SPrashanth Swaminathan23: ret /* reserved */ 181*1fd5a2e1SPrashanth Swaminathan nop 182*1fd5a2e1SPrashanth Swaminathan24: mov w0, w0 /* UINT32 */ 183*1fd5a2e1SPrashanth Swaminathan str x0, [x3] 184*1fd5a2e1SPrashanth Swaminathan25: ret /* reserved */ 185*1fd5a2e1SPrashanth Swaminathan nop 186*1fd5a2e1SPrashanth Swaminathan26: sxtb x0, w0 /* SINT8 */ 187*1fd5a2e1SPrashanth Swaminathan str x0, [x3] 188*1fd5a2e1SPrashanth Swaminathan27: ret /* reserved */ 189*1fd5a2e1SPrashanth Swaminathan nop 190*1fd5a2e1SPrashanth Swaminathan28: sxth x0, w0 /* SINT16 */ 191*1fd5a2e1SPrashanth Swaminathan str x0, [x3] 192*1fd5a2e1SPrashanth Swaminathan29: ret /* reserved */ 193*1fd5a2e1SPrashanth Swaminathan nop 194*1fd5a2e1SPrashanth Swaminathan30: sxtw x0, w0 /* SINT32 */ 195*1fd5a2e1SPrashanth Swaminathan str x0, [x3] 196*1fd5a2e1SPrashanth Swaminathan31: ret /* reserved */ 197*1fd5a2e1SPrashanth Swaminathan nop 198*1fd5a2e1SPrashanth Swaminathan 199*1fd5a2e1SPrashanth Swaminathan cfi_endproc 200*1fd5a2e1SPrashanth Swaminathan 201*1fd5a2e1SPrashanth Swaminathan .globl CNAME(ffi_call_SYSV) 202*1fd5a2e1SPrashanth Swaminathan FFI_HIDDEN(CNAME(ffi_call_SYSV)) 203*1fd5a2e1SPrashanth Swaminathan#ifdef __ELF__ 204*1fd5a2e1SPrashanth Swaminathan .type CNAME(ffi_call_SYSV), #function 205*1fd5a2e1SPrashanth Swaminathan .size CNAME(ffi_call_SYSV), .-CNAME(ffi_call_SYSV) 206*1fd5a2e1SPrashanth Swaminathan#endif 207*1fd5a2e1SPrashanth Swaminathan 208*1fd5a2e1SPrashanth Swaminathan/* ffi_closure_SYSV 209*1fd5a2e1SPrashanth Swaminathan 210*1fd5a2e1SPrashanth Swaminathan Closure invocation glue. This is the low level code invoked directly by 211*1fd5a2e1SPrashanth Swaminathan the closure trampoline to setup and call a closure. 212*1fd5a2e1SPrashanth Swaminathan 213*1fd5a2e1SPrashanth Swaminathan On entry x17 points to a struct ffi_closure, x16 has been clobbered 214*1fd5a2e1SPrashanth Swaminathan all other registers are preserved. 215*1fd5a2e1SPrashanth Swaminathan 216*1fd5a2e1SPrashanth Swaminathan We allocate a call context and save the argument passing registers, 217*1fd5a2e1SPrashanth Swaminathan then invoked the generic C ffi_closure_SYSV_inner() function to do all 218*1fd5a2e1SPrashanth Swaminathan the real work, on return we load the result passing registers back from 219*1fd5a2e1SPrashanth Swaminathan the call context. 220*1fd5a2e1SPrashanth Swaminathan*/ 221*1fd5a2e1SPrashanth Swaminathan 222*1fd5a2e1SPrashanth Swaminathan#define ffi_closure_SYSV_FS (8*2 + CALL_CONTEXT_SIZE + 64) 223*1fd5a2e1SPrashanth Swaminathan 224*1fd5a2e1SPrashanth Swaminathan .align 4 225*1fd5a2e1SPrashanth SwaminathanCNAME(ffi_closure_SYSV_V): 226*1fd5a2e1SPrashanth Swaminathan cfi_startproc 227*1fd5a2e1SPrashanth Swaminathan stp x29, x30, [sp, #-ffi_closure_SYSV_FS]! 228*1fd5a2e1SPrashanth Swaminathan cfi_adjust_cfa_offset (ffi_closure_SYSV_FS) 229*1fd5a2e1SPrashanth Swaminathan cfi_rel_offset (x29, 0) 230*1fd5a2e1SPrashanth Swaminathan cfi_rel_offset (x30, 8) 231*1fd5a2e1SPrashanth Swaminathan 232*1fd5a2e1SPrashanth Swaminathan /* Save the argument passing vector registers. */ 233*1fd5a2e1SPrashanth Swaminathan stp q0, q1, [sp, #16 + 0] 234*1fd5a2e1SPrashanth Swaminathan stp q2, q3, [sp, #16 + 32] 235*1fd5a2e1SPrashanth Swaminathan stp q4, q5, [sp, #16 + 64] 236*1fd5a2e1SPrashanth Swaminathan stp q6, q7, [sp, #16 + 96] 237*1fd5a2e1SPrashanth Swaminathan b 0f 238*1fd5a2e1SPrashanth Swaminathan cfi_endproc 239*1fd5a2e1SPrashanth Swaminathan 240*1fd5a2e1SPrashanth Swaminathan .globl CNAME(ffi_closure_SYSV_V) 241*1fd5a2e1SPrashanth Swaminathan FFI_HIDDEN(CNAME(ffi_closure_SYSV_V)) 242*1fd5a2e1SPrashanth Swaminathan#ifdef __ELF__ 243*1fd5a2e1SPrashanth Swaminathan .type CNAME(ffi_closure_SYSV_V), #function 244*1fd5a2e1SPrashanth Swaminathan .size CNAME(ffi_closure_SYSV_V), . - CNAME(ffi_closure_SYSV_V) 245*1fd5a2e1SPrashanth Swaminathan#endif 246*1fd5a2e1SPrashanth Swaminathan 247*1fd5a2e1SPrashanth Swaminathan .align 4 248*1fd5a2e1SPrashanth Swaminathan cfi_startproc 249*1fd5a2e1SPrashanth SwaminathanCNAME(ffi_closure_SYSV): 250*1fd5a2e1SPrashanth Swaminathan stp x29, x30, [sp, #-ffi_closure_SYSV_FS]! 251*1fd5a2e1SPrashanth Swaminathan cfi_adjust_cfa_offset (ffi_closure_SYSV_FS) 252*1fd5a2e1SPrashanth Swaminathan cfi_rel_offset (x29, 0) 253*1fd5a2e1SPrashanth Swaminathan cfi_rel_offset (x30, 8) 254*1fd5a2e1SPrashanth Swaminathan0: 255*1fd5a2e1SPrashanth Swaminathan mov x29, sp 256*1fd5a2e1SPrashanth Swaminathan 257*1fd5a2e1SPrashanth Swaminathan /* Save the argument passing core registers. */ 258*1fd5a2e1SPrashanth Swaminathan stp x0, x1, [sp, #16 + 16*N_V_ARG_REG + 0] 259*1fd5a2e1SPrashanth Swaminathan stp x2, x3, [sp, #16 + 16*N_V_ARG_REG + 16] 260*1fd5a2e1SPrashanth Swaminathan stp x4, x5, [sp, #16 + 16*N_V_ARG_REG + 32] 261*1fd5a2e1SPrashanth Swaminathan stp x6, x7, [sp, #16 + 16*N_V_ARG_REG + 48] 262*1fd5a2e1SPrashanth Swaminathan 263*1fd5a2e1SPrashanth Swaminathan /* Load ffi_closure_inner arguments. */ 264*1fd5a2e1SPrashanth Swaminathan ldp PTR_REG(0), PTR_REG(1), [x17, #FFI_TRAMPOLINE_CLOSURE_OFFSET] /* load cif, fn */ 265*1fd5a2e1SPrashanth Swaminathan ldr PTR_REG(2), [x17, #FFI_TRAMPOLINE_CLOSURE_OFFSET+PTR_SIZE*2] /* load user_data */ 266*1fd5a2e1SPrashanth Swaminathan.Ldo_closure: 267*1fd5a2e1SPrashanth Swaminathan add x3, sp, #16 /* load context */ 268*1fd5a2e1SPrashanth Swaminathan add x4, sp, #ffi_closure_SYSV_FS /* load stack */ 269*1fd5a2e1SPrashanth Swaminathan add x5, sp, #16+CALL_CONTEXT_SIZE /* load rvalue */ 270*1fd5a2e1SPrashanth Swaminathan mov x6, x8 /* load struct_rval */ 271*1fd5a2e1SPrashanth Swaminathan bl CNAME(ffi_closure_SYSV_inner) 272*1fd5a2e1SPrashanth Swaminathan 273*1fd5a2e1SPrashanth Swaminathan /* Load the return value as directed. */ 274*1fd5a2e1SPrashanth Swaminathan adr x1, 0f 275*1fd5a2e1SPrashanth Swaminathan and w0, w0, #AARCH64_RET_MASK 276*1fd5a2e1SPrashanth Swaminathan add x1, x1, x0, lsl #3 277*1fd5a2e1SPrashanth Swaminathan add x3, sp, #16+CALL_CONTEXT_SIZE 278*1fd5a2e1SPrashanth Swaminathan br x1 279*1fd5a2e1SPrashanth Swaminathan 280*1fd5a2e1SPrashanth Swaminathan /* Note that each table entry is 2 insns, and thus 8 bytes. */ 281*1fd5a2e1SPrashanth Swaminathan .align 4 282*1fd5a2e1SPrashanth Swaminathan0: b 99f /* VOID */ 283*1fd5a2e1SPrashanth Swaminathan nop 284*1fd5a2e1SPrashanth Swaminathan1: ldr x0, [x3] /* INT64 */ 285*1fd5a2e1SPrashanth Swaminathan b 99f 286*1fd5a2e1SPrashanth Swaminathan2: ldp x0, x1, [x3] /* INT128 */ 287*1fd5a2e1SPrashanth Swaminathan b 99f 288*1fd5a2e1SPrashanth Swaminathan3: brk #1000 /* UNUSED */ 289*1fd5a2e1SPrashanth Swaminathan nop 290*1fd5a2e1SPrashanth Swaminathan4: brk #1000 /* UNUSED */ 291*1fd5a2e1SPrashanth Swaminathan nop 292*1fd5a2e1SPrashanth Swaminathan5: brk #1000 /* UNUSED */ 293*1fd5a2e1SPrashanth Swaminathan nop 294*1fd5a2e1SPrashanth Swaminathan6: brk #1000 /* UNUSED */ 295*1fd5a2e1SPrashanth Swaminathan nop 296*1fd5a2e1SPrashanth Swaminathan7: brk #1000 /* UNUSED */ 297*1fd5a2e1SPrashanth Swaminathan nop 298*1fd5a2e1SPrashanth Swaminathan8: ldr s3, [x3, #12] /* S4 */ 299*1fd5a2e1SPrashanth Swaminathan nop 300*1fd5a2e1SPrashanth Swaminathan9: ldr s2, [x3, #8] /* S3 */ 301*1fd5a2e1SPrashanth Swaminathan nop 302*1fd5a2e1SPrashanth Swaminathan10: ldp s0, s1, [x3] /* S2 */ 303*1fd5a2e1SPrashanth Swaminathan b 99f 304*1fd5a2e1SPrashanth Swaminathan11: ldr s0, [x3] /* S1 */ 305*1fd5a2e1SPrashanth Swaminathan b 99f 306*1fd5a2e1SPrashanth Swaminathan12: ldr d3, [x3, #24] /* D4 */ 307*1fd5a2e1SPrashanth Swaminathan nop 308*1fd5a2e1SPrashanth Swaminathan13: ldr d2, [x3, #16] /* D3 */ 309*1fd5a2e1SPrashanth Swaminathan nop 310*1fd5a2e1SPrashanth Swaminathan14: ldp d0, d1, [x3] /* D2 */ 311*1fd5a2e1SPrashanth Swaminathan b 99f 312*1fd5a2e1SPrashanth Swaminathan15: ldr d0, [x3] /* D1 */ 313*1fd5a2e1SPrashanth Swaminathan b 99f 314*1fd5a2e1SPrashanth Swaminathan16: ldr q3, [x3, #48] /* Q4 */ 315*1fd5a2e1SPrashanth Swaminathan nop 316*1fd5a2e1SPrashanth Swaminathan17: ldr q2, [x3, #32] /* Q3 */ 317*1fd5a2e1SPrashanth Swaminathan nop 318*1fd5a2e1SPrashanth Swaminathan18: ldp q0, q1, [x3] /* Q2 */ 319*1fd5a2e1SPrashanth Swaminathan b 99f 320*1fd5a2e1SPrashanth Swaminathan19: ldr q0, [x3] /* Q1 */ 321*1fd5a2e1SPrashanth Swaminathan b 99f 322*1fd5a2e1SPrashanth Swaminathan20: ldrb w0, [x3, #BE(7)] /* UINT8 */ 323*1fd5a2e1SPrashanth Swaminathan b 99f 324*1fd5a2e1SPrashanth Swaminathan21: brk #1000 /* reserved */ 325*1fd5a2e1SPrashanth Swaminathan nop 326*1fd5a2e1SPrashanth Swaminathan22: ldrh w0, [x3, #BE(6)] /* UINT16 */ 327*1fd5a2e1SPrashanth Swaminathan b 99f 328*1fd5a2e1SPrashanth Swaminathan23: brk #1000 /* reserved */ 329*1fd5a2e1SPrashanth Swaminathan nop 330*1fd5a2e1SPrashanth Swaminathan24: ldr w0, [x3, #BE(4)] /* UINT32 */ 331*1fd5a2e1SPrashanth Swaminathan b 99f 332*1fd5a2e1SPrashanth Swaminathan25: brk #1000 /* reserved */ 333*1fd5a2e1SPrashanth Swaminathan nop 334*1fd5a2e1SPrashanth Swaminathan26: ldrsb x0, [x3, #BE(7)] /* SINT8 */ 335*1fd5a2e1SPrashanth Swaminathan b 99f 336*1fd5a2e1SPrashanth Swaminathan27: brk #1000 /* reserved */ 337*1fd5a2e1SPrashanth Swaminathan nop 338*1fd5a2e1SPrashanth Swaminathan28: ldrsh x0, [x3, #BE(6)] /* SINT16 */ 339*1fd5a2e1SPrashanth Swaminathan b 99f 340*1fd5a2e1SPrashanth Swaminathan29: brk #1000 /* reserved */ 341*1fd5a2e1SPrashanth Swaminathan nop 342*1fd5a2e1SPrashanth Swaminathan30: ldrsw x0, [x3, #BE(4)] /* SINT32 */ 343*1fd5a2e1SPrashanth Swaminathan nop 344*1fd5a2e1SPrashanth Swaminathan31: /* reserved */ 345*1fd5a2e1SPrashanth Swaminathan99: ldp x29, x30, [sp], #ffi_closure_SYSV_FS 346*1fd5a2e1SPrashanth Swaminathan cfi_adjust_cfa_offset (-ffi_closure_SYSV_FS) 347*1fd5a2e1SPrashanth Swaminathan cfi_restore (x29) 348*1fd5a2e1SPrashanth Swaminathan cfi_restore (x30) 349*1fd5a2e1SPrashanth Swaminathan ret 350*1fd5a2e1SPrashanth Swaminathan cfi_endproc 351*1fd5a2e1SPrashanth Swaminathan 352*1fd5a2e1SPrashanth Swaminathan .globl CNAME(ffi_closure_SYSV) 353*1fd5a2e1SPrashanth Swaminathan FFI_HIDDEN(CNAME(ffi_closure_SYSV)) 354*1fd5a2e1SPrashanth Swaminathan#ifdef __ELF__ 355*1fd5a2e1SPrashanth Swaminathan .type CNAME(ffi_closure_SYSV), #function 356*1fd5a2e1SPrashanth Swaminathan .size CNAME(ffi_closure_SYSV), . - CNAME(ffi_closure_SYSV) 357*1fd5a2e1SPrashanth Swaminathan#endif 358*1fd5a2e1SPrashanth Swaminathan 359*1fd5a2e1SPrashanth Swaminathan#if FFI_EXEC_TRAMPOLINE_TABLE 360*1fd5a2e1SPrashanth Swaminathan 361*1fd5a2e1SPrashanth Swaminathan#ifdef __MACH__ 362*1fd5a2e1SPrashanth Swaminathan#include <mach/machine/vm_param.h> 363*1fd5a2e1SPrashanth Swaminathan .align PAGE_MAX_SHIFT 364*1fd5a2e1SPrashanth SwaminathanCNAME(ffi_closure_trampoline_table_page): 365*1fd5a2e1SPrashanth Swaminathan .rept PAGE_MAX_SIZE / FFI_TRAMPOLINE_SIZE 366*1fd5a2e1SPrashanth Swaminathan adr x16, -PAGE_MAX_SIZE 367*1fd5a2e1SPrashanth Swaminathan ldp x17, x16, [x16] 368*1fd5a2e1SPrashanth Swaminathan br x16 369*1fd5a2e1SPrashanth Swaminathan nop /* each entry in the trampoline config page is 2*sizeof(void*) so the trampoline itself cannot be smaller that 16 bytes */ 370*1fd5a2e1SPrashanth Swaminathan .endr 371*1fd5a2e1SPrashanth Swaminathan 372*1fd5a2e1SPrashanth Swaminathan .globl CNAME(ffi_closure_trampoline_table_page) 373*1fd5a2e1SPrashanth Swaminathan FFI_HIDDEN(CNAME(ffi_closure_trampoline_table_page)) 374*1fd5a2e1SPrashanth Swaminathan #ifdef __ELF__ 375*1fd5a2e1SPrashanth Swaminathan .type CNAME(ffi_closure_trampoline_table_page), #function 376*1fd5a2e1SPrashanth Swaminathan .size CNAME(ffi_closure_trampoline_table_page), . - CNAME(ffi_closure_trampoline_table_page) 377*1fd5a2e1SPrashanth Swaminathan #endif 378*1fd5a2e1SPrashanth Swaminathan#endif 379*1fd5a2e1SPrashanth Swaminathan 380*1fd5a2e1SPrashanth Swaminathan#endif /* FFI_EXEC_TRAMPOLINE_TABLE */ 381*1fd5a2e1SPrashanth Swaminathan 382*1fd5a2e1SPrashanth Swaminathan#ifdef FFI_GO_CLOSURES 383*1fd5a2e1SPrashanth Swaminathan .align 4 384*1fd5a2e1SPrashanth SwaminathanCNAME(ffi_go_closure_SYSV_V): 385*1fd5a2e1SPrashanth Swaminathan cfi_startproc 386*1fd5a2e1SPrashanth Swaminathan stp x29, x30, [sp, #-ffi_closure_SYSV_FS]! 387*1fd5a2e1SPrashanth Swaminathan cfi_adjust_cfa_offset (ffi_closure_SYSV_FS) 388*1fd5a2e1SPrashanth Swaminathan cfi_rel_offset (x29, 0) 389*1fd5a2e1SPrashanth Swaminathan cfi_rel_offset (x30, 8) 390*1fd5a2e1SPrashanth Swaminathan 391*1fd5a2e1SPrashanth Swaminathan /* Save the argument passing vector registers. */ 392*1fd5a2e1SPrashanth Swaminathan stp q0, q1, [sp, #16 + 0] 393*1fd5a2e1SPrashanth Swaminathan stp q2, q3, [sp, #16 + 32] 394*1fd5a2e1SPrashanth Swaminathan stp q4, q5, [sp, #16 + 64] 395*1fd5a2e1SPrashanth Swaminathan stp q6, q7, [sp, #16 + 96] 396*1fd5a2e1SPrashanth Swaminathan b 0f 397*1fd5a2e1SPrashanth Swaminathan cfi_endproc 398*1fd5a2e1SPrashanth Swaminathan 399*1fd5a2e1SPrashanth Swaminathan .globl CNAME(ffi_go_closure_SYSV_V) 400*1fd5a2e1SPrashanth Swaminathan FFI_HIDDEN(CNAME(ffi_go_closure_SYSV_V)) 401*1fd5a2e1SPrashanth Swaminathan#ifdef __ELF__ 402*1fd5a2e1SPrashanth Swaminathan .type CNAME(ffi_go_closure_SYSV_V), #function 403*1fd5a2e1SPrashanth Swaminathan .size CNAME(ffi_go_closure_SYSV_V), . - CNAME(ffi_go_closure_SYSV_V) 404*1fd5a2e1SPrashanth Swaminathan#endif 405*1fd5a2e1SPrashanth Swaminathan 406*1fd5a2e1SPrashanth Swaminathan .align 4 407*1fd5a2e1SPrashanth Swaminathan cfi_startproc 408*1fd5a2e1SPrashanth SwaminathanCNAME(ffi_go_closure_SYSV): 409*1fd5a2e1SPrashanth Swaminathan stp x29, x30, [sp, #-ffi_closure_SYSV_FS]! 410*1fd5a2e1SPrashanth Swaminathan cfi_adjust_cfa_offset (ffi_closure_SYSV_FS) 411*1fd5a2e1SPrashanth Swaminathan cfi_rel_offset (x29, 0) 412*1fd5a2e1SPrashanth Swaminathan cfi_rel_offset (x30, 8) 413*1fd5a2e1SPrashanth Swaminathan0: 414*1fd5a2e1SPrashanth Swaminathan mov x29, sp 415*1fd5a2e1SPrashanth Swaminathan 416*1fd5a2e1SPrashanth Swaminathan /* Save the argument passing core registers. */ 417*1fd5a2e1SPrashanth Swaminathan stp x0, x1, [sp, #16 + 16*N_V_ARG_REG + 0] 418*1fd5a2e1SPrashanth Swaminathan stp x2, x3, [sp, #16 + 16*N_V_ARG_REG + 16] 419*1fd5a2e1SPrashanth Swaminathan stp x4, x5, [sp, #16 + 16*N_V_ARG_REG + 32] 420*1fd5a2e1SPrashanth Swaminathan stp x6, x7, [sp, #16 + 16*N_V_ARG_REG + 48] 421*1fd5a2e1SPrashanth Swaminathan 422*1fd5a2e1SPrashanth Swaminathan /* Load ffi_closure_inner arguments. */ 423*1fd5a2e1SPrashanth Swaminathan ldp PTR_REG(0), PTR_REG(1), [x18, #PTR_SIZE]/* load cif, fn */ 424*1fd5a2e1SPrashanth Swaminathan mov x2, x18 /* load user_data */ 425*1fd5a2e1SPrashanth Swaminathan b .Ldo_closure 426*1fd5a2e1SPrashanth Swaminathan cfi_endproc 427*1fd5a2e1SPrashanth Swaminathan 428*1fd5a2e1SPrashanth Swaminathan .globl CNAME(ffi_go_closure_SYSV) 429*1fd5a2e1SPrashanth Swaminathan FFI_HIDDEN(CNAME(ffi_go_closure_SYSV)) 430*1fd5a2e1SPrashanth Swaminathan#ifdef __ELF__ 431*1fd5a2e1SPrashanth Swaminathan .type CNAME(ffi_go_closure_SYSV), #function 432*1fd5a2e1SPrashanth Swaminathan .size CNAME(ffi_go_closure_SYSV), . - CNAME(ffi_go_closure_SYSV) 433*1fd5a2e1SPrashanth Swaminathan#endif 434*1fd5a2e1SPrashanth Swaminathan#endif /* FFI_GO_CLOSURES */ 435*1fd5a2e1SPrashanth Swaminathan#endif /* __arm64__ */ 436*1fd5a2e1SPrashanth Swaminathan 437*1fd5a2e1SPrashanth Swaminathan#if defined __ELF__ && defined __linux__ 438*1fd5a2e1SPrashanth Swaminathan .section .note.GNU-stack,"",%progbits 439*1fd5a2e1SPrashanth Swaminathan#endif 440*1fd5a2e1SPrashanth Swaminathan 441