1*1fd5a2e1SPrashanth Swaminathan/* Copyright (c) 2009, 2010, 2011, 2012 ARM Ltd. 2*1fd5a2e1SPrashanth SwaminathanPermission is hereby granted, free of charge, to any person obtaining 3*1fd5a2e1SPrashanth Swaminathana copy of this software and associated documentation files (the 4*1fd5a2e1SPrashanth Swaminathan``Software''), to deal in the Software without restriction, including 5*1fd5a2e1SPrashanth Swaminathanwithout limitation the rights to use, copy, modify, merge, publish, 6*1fd5a2e1SPrashanth Swaminathandistribute, sublicense, and/or sell copies of the Software, and to 7*1fd5a2e1SPrashanth Swaminathanpermit persons to whom the Software is furnished to do so, subject to 8*1fd5a2e1SPrashanth Swaminathanthe following conditions: 9*1fd5a2e1SPrashanth SwaminathanThe above copyright notice and this permission notice shall be 10*1fd5a2e1SPrashanth Swaminathanincluded in all copies or substantial portions of the Software. 11*1fd5a2e1SPrashanth SwaminathanTHE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, 12*1fd5a2e1SPrashanth SwaminathanEXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 13*1fd5a2e1SPrashanth SwaminathanMERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 14*1fd5a2e1SPrashanth SwaminathanIN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 15*1fd5a2e1SPrashanth SwaminathanCLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 16*1fd5a2e1SPrashanth SwaminathanTORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 17*1fd5a2e1SPrashanth SwaminathanSOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ 18*1fd5a2e1SPrashanth Swaminathan 19*1fd5a2e1SPrashanth Swaminathan#define LIBFFI_ASM 20*1fd5a2e1SPrashanth Swaminathan#include <fficonfig.h> 21*1fd5a2e1SPrashanth Swaminathan#include <ffi.h> 22*1fd5a2e1SPrashanth Swaminathan#include <ffi_cfi.h> 23*1fd5a2e1SPrashanth Swaminathan#include "internal.h" 24*1fd5a2e1SPrashanth Swaminathan 25*1fd5a2e1SPrashanth Swaminathan OPT 2 /*disable listing */ 26*1fd5a2e1SPrashanth Swaminathan/* For some macros to add unwind information */ 27*1fd5a2e1SPrashanth Swaminathan#include "ksarm64.h" 28*1fd5a2e1SPrashanth Swaminathan OPT 1 /*re-enable listing */ 29*1fd5a2e1SPrashanth Swaminathan 30*1fd5a2e1SPrashanth Swaminathan#define BE(X) 0 31*1fd5a2e1SPrashanth Swaminathan#define PTR_REG(n) x##n 32*1fd5a2e1SPrashanth Swaminathan#define PTR_SIZE 8 33*1fd5a2e1SPrashanth Swaminathan 34*1fd5a2e1SPrashanth Swaminathan IMPORT ffi_closure_SYSV_inner 35*1fd5a2e1SPrashanth Swaminathan EXPORT ffi_call_SYSV 36*1fd5a2e1SPrashanth Swaminathan EXPORT ffi_closure_SYSV_V 37*1fd5a2e1SPrashanth Swaminathan EXPORT ffi_closure_SYSV 38*1fd5a2e1SPrashanth Swaminathan EXPORT extend_hfa_type 39*1fd5a2e1SPrashanth Swaminathan EXPORT compress_hfa_type 40*1fd5a2e1SPrashanth Swaminathan#ifdef FFI_GO_CLOSURES 41*1fd5a2e1SPrashanth Swaminathan EXPORT ffi_go_closure_SYSV_V 42*1fd5a2e1SPrashanth Swaminathan EXPORT ffi_go_closure_SYSV 43*1fd5a2e1SPrashanth Swaminathan#endif 44*1fd5a2e1SPrashanth Swaminathan 45*1fd5a2e1SPrashanth Swaminathan TEXTAREA, ALLIGN=8 46*1fd5a2e1SPrashanth Swaminathan 47*1fd5a2e1SPrashanth Swaminathan/* ffi_call_SYSV 48*1fd5a2e1SPrashanth Swaminathan extern void ffi_call_SYSV (void *stack, void *frame, 49*1fd5a2e1SPrashanth Swaminathan void (*fn)(void), void *rvalue, 50*1fd5a2e1SPrashanth Swaminathan int flags, void *closure); 51*1fd5a2e1SPrashanth Swaminathan Therefore on entry we have: 52*1fd5a2e1SPrashanth Swaminathan x0 stack 53*1fd5a2e1SPrashanth Swaminathan x1 frame 54*1fd5a2e1SPrashanth Swaminathan x2 fn 55*1fd5a2e1SPrashanth Swaminathan x3 rvalue 56*1fd5a2e1SPrashanth Swaminathan x4 flags 57*1fd5a2e1SPrashanth Swaminathan x5 closure 58*1fd5a2e1SPrashanth Swaminathan*/ 59*1fd5a2e1SPrashanth Swaminathan 60*1fd5a2e1SPrashanth Swaminathan NESTED_ENTRY ffi_call_SYSV_fake 61*1fd5a2e1SPrashanth Swaminathan 62*1fd5a2e1SPrashanth Swaminathan /* For unwind information, Windows has to store fp and lr */ 63*1fd5a2e1SPrashanth Swaminathan PROLOG_SAVE_REG_PAIR x29, x30, #-32! 64*1fd5a2e1SPrashanth Swaminathan 65*1fd5a2e1SPrashanth Swaminathan ALTERNATE_ENTRY ffi_call_SYSV 66*1fd5a2e1SPrashanth Swaminathan /* Use a stack frame allocated by our caller. */ 67*1fd5a2e1SPrashanth Swaminathan stp x29, x30, [x1] 68*1fd5a2e1SPrashanth Swaminathan mov x29, x1 69*1fd5a2e1SPrashanth Swaminathan mov sp, x0 70*1fd5a2e1SPrashanth Swaminathan 71*1fd5a2e1SPrashanth Swaminathan mov x9, x2 /* save fn */ 72*1fd5a2e1SPrashanth Swaminathan mov x8, x3 /* install structure return */ 73*1fd5a2e1SPrashanth Swaminathan#ifdef FFI_GO_CLOSURES 74*1fd5a2e1SPrashanth Swaminathan /*mov x18, x5 install static chain */ 75*1fd5a2e1SPrashanth Swaminathan#endif 76*1fd5a2e1SPrashanth Swaminathan stp x3, x4, [x29, #16] /* save rvalue and flags */ 77*1fd5a2e1SPrashanth Swaminathan 78*1fd5a2e1SPrashanth Swaminathan /* Load the vector argument passing registers, if necessary. */ 79*1fd5a2e1SPrashanth Swaminathan tbz x4, #AARCH64_FLAG_ARG_V_BIT, ffi_call_SYSV_L1 80*1fd5a2e1SPrashanth Swaminathan ldp q0, q1, [sp, #0] 81*1fd5a2e1SPrashanth Swaminathan ldp q2, q3, [sp, #32] 82*1fd5a2e1SPrashanth Swaminathan ldp q4, q5, [sp, #64] 83*1fd5a2e1SPrashanth Swaminathan ldp q6, q7, [sp, #96] 84*1fd5a2e1SPrashanth Swaminathan 85*1fd5a2e1SPrashanth Swaminathanffi_call_SYSV_L1 86*1fd5a2e1SPrashanth Swaminathan /* Load the core argument passing registers, including 87*1fd5a2e1SPrashanth Swaminathan the structure return pointer. */ 88*1fd5a2e1SPrashanth Swaminathan ldp x0, x1, [sp, #16*N_V_ARG_REG + 0] 89*1fd5a2e1SPrashanth Swaminathan ldp x2, x3, [sp, #16*N_V_ARG_REG + 16] 90*1fd5a2e1SPrashanth Swaminathan ldp x4, x5, [sp, #16*N_V_ARG_REG + 32] 91*1fd5a2e1SPrashanth Swaminathan ldp x6, x7, [sp, #16*N_V_ARG_REG + 48] 92*1fd5a2e1SPrashanth Swaminathan 93*1fd5a2e1SPrashanth Swaminathan /* Deallocate the context, leaving the stacked arguments. */ 94*1fd5a2e1SPrashanth Swaminathan add sp, sp, #CALL_CONTEXT_SIZE 95*1fd5a2e1SPrashanth Swaminathan 96*1fd5a2e1SPrashanth Swaminathan blr x9 /* call fn */ 97*1fd5a2e1SPrashanth Swaminathan 98*1fd5a2e1SPrashanth Swaminathan ldp x3, x4, [x29, #16] /* reload rvalue and flags */ 99*1fd5a2e1SPrashanth Swaminathan 100*1fd5a2e1SPrashanth Swaminathan /* Partially deconstruct the stack frame. */ 101*1fd5a2e1SPrashanth Swaminathan mov sp, x29 102*1fd5a2e1SPrashanth Swaminathan ldp x29, x30, [x29] 103*1fd5a2e1SPrashanth Swaminathan 104*1fd5a2e1SPrashanth Swaminathan /* Save the return value as directed. */ 105*1fd5a2e1SPrashanth Swaminathan adr x5, ffi_call_SYSV_return 106*1fd5a2e1SPrashanth Swaminathan and w4, w4, #AARCH64_RET_MASK 107*1fd5a2e1SPrashanth Swaminathan add x5, x5, x4, lsl #3 108*1fd5a2e1SPrashanth Swaminathan br x5 109*1fd5a2e1SPrashanth Swaminathan 110*1fd5a2e1SPrashanth Swaminathan /* Note that each table entry is 2 insns, and thus 8 bytes. 111*1fd5a2e1SPrashanth Swaminathan For integer data, note that we're storing into ffi_arg 112*1fd5a2e1SPrashanth Swaminathan and therefore we want to extend to 64 bits; these types 113*1fd5a2e1SPrashanth Swaminathan have two consecutive entries allocated for them. */ 114*1fd5a2e1SPrashanth Swaminathan ALIGN 4 115*1fd5a2e1SPrashanth Swaminathanffi_call_SYSV_return 116*1fd5a2e1SPrashanth Swaminathan ret /* VOID */ 117*1fd5a2e1SPrashanth Swaminathan nop 118*1fd5a2e1SPrashanth Swaminathan str x0, [x3] /* INT64 */ 119*1fd5a2e1SPrashanth Swaminathan ret 120*1fd5a2e1SPrashanth Swaminathan stp x0, x1, [x3] /* INT128 */ 121*1fd5a2e1SPrashanth Swaminathan ret 122*1fd5a2e1SPrashanth Swaminathan brk #1000 /* UNUSED */ 123*1fd5a2e1SPrashanth Swaminathan ret 124*1fd5a2e1SPrashanth Swaminathan brk #1000 /* UNUSED */ 125*1fd5a2e1SPrashanth Swaminathan ret 126*1fd5a2e1SPrashanth Swaminathan brk #1000 /* UNUSED */ 127*1fd5a2e1SPrashanth Swaminathan ret 128*1fd5a2e1SPrashanth Swaminathan brk #1000 /* UNUSED */ 129*1fd5a2e1SPrashanth Swaminathan ret 130*1fd5a2e1SPrashanth Swaminathan brk #1000 /* UNUSED */ 131*1fd5a2e1SPrashanth Swaminathan ret 132*1fd5a2e1SPrashanth Swaminathan st4 { v0.s, v1.s, v2.s, v3.s }[0], [x3] /* S4 */ 133*1fd5a2e1SPrashanth Swaminathan ret 134*1fd5a2e1SPrashanth Swaminathan st3 { v0.s, v1.s, v2.s }[0], [x3] /* S3 */ 135*1fd5a2e1SPrashanth Swaminathan ret 136*1fd5a2e1SPrashanth Swaminathan stp s0, s1, [x3] /* S2 */ 137*1fd5a2e1SPrashanth Swaminathan ret 138*1fd5a2e1SPrashanth Swaminathan str s0, [x3] /* S1 */ 139*1fd5a2e1SPrashanth Swaminathan ret 140*1fd5a2e1SPrashanth Swaminathan st4 { v0.d, v1.d, v2.d, v3.d }[0], [x3] /* D4 */ 141*1fd5a2e1SPrashanth Swaminathan ret 142*1fd5a2e1SPrashanth Swaminathan st3 { v0.d, v1.d, v2.d }[0], [x3] /* D3 */ 143*1fd5a2e1SPrashanth Swaminathan ret 144*1fd5a2e1SPrashanth Swaminathan stp d0, d1, [x3] /* D2 */ 145*1fd5a2e1SPrashanth Swaminathan ret 146*1fd5a2e1SPrashanth Swaminathan str d0, [x3] /* D1 */ 147*1fd5a2e1SPrashanth Swaminathan ret 148*1fd5a2e1SPrashanth Swaminathan str q3, [x3, #48] /* Q4 */ 149*1fd5a2e1SPrashanth Swaminathan nop 150*1fd5a2e1SPrashanth Swaminathan str q2, [x3, #32] /* Q3 */ 151*1fd5a2e1SPrashanth Swaminathan nop 152*1fd5a2e1SPrashanth Swaminathan stp q0, q1, [x3] /* Q2 */ 153*1fd5a2e1SPrashanth Swaminathan ret 154*1fd5a2e1SPrashanth Swaminathan str q0, [x3] /* Q1 */ 155*1fd5a2e1SPrashanth Swaminathan ret 156*1fd5a2e1SPrashanth Swaminathan uxtb w0, w0 /* UINT8 */ 157*1fd5a2e1SPrashanth Swaminathan str x0, [x3] 158*1fd5a2e1SPrashanth Swaminathan ret /* reserved */ 159*1fd5a2e1SPrashanth Swaminathan nop 160*1fd5a2e1SPrashanth Swaminathan uxth w0, w0 /* UINT16 */ 161*1fd5a2e1SPrashanth Swaminathan str x0, [x3] 162*1fd5a2e1SPrashanth Swaminathan ret /* reserved */ 163*1fd5a2e1SPrashanth Swaminathan nop 164*1fd5a2e1SPrashanth Swaminathan mov w0, w0 /* UINT32 */ 165*1fd5a2e1SPrashanth Swaminathan str x0, [x3] 166*1fd5a2e1SPrashanth Swaminathan ret /* reserved */ 167*1fd5a2e1SPrashanth Swaminathan nop 168*1fd5a2e1SPrashanth Swaminathan sxtb x0, w0 /* SINT8 */ 169*1fd5a2e1SPrashanth Swaminathan str x0, [x3] 170*1fd5a2e1SPrashanth Swaminathan ret /* reserved */ 171*1fd5a2e1SPrashanth Swaminathan nop 172*1fd5a2e1SPrashanth Swaminathan sxth x0, w0 /* SINT16 */ 173*1fd5a2e1SPrashanth Swaminathan str x0, [x3] 174*1fd5a2e1SPrashanth Swaminathan ret /* reserved */ 175*1fd5a2e1SPrashanth Swaminathan nop 176*1fd5a2e1SPrashanth Swaminathan sxtw x0, w0 /* SINT32 */ 177*1fd5a2e1SPrashanth Swaminathan str x0, [x3] 178*1fd5a2e1SPrashanth Swaminathan ret /* reserved */ 179*1fd5a2e1SPrashanth Swaminathan nop 180*1fd5a2e1SPrashanth Swaminathan 181*1fd5a2e1SPrashanth Swaminathan 182*1fd5a2e1SPrashanth Swaminathan NESTED_END ffi_call_SYSV_fake 183*1fd5a2e1SPrashanth Swaminathan 184*1fd5a2e1SPrashanth Swaminathan 185*1fd5a2e1SPrashanth Swaminathan/* ffi_closure_SYSV 186*1fd5a2e1SPrashanth Swaminathan Closure invocation glue. This is the low level code invoked directly by 187*1fd5a2e1SPrashanth Swaminathan the closure trampoline to setup and call a closure. 188*1fd5a2e1SPrashanth Swaminathan On entry x17 points to a struct ffi_closure, x16 has been clobbered 189*1fd5a2e1SPrashanth Swaminathan all other registers are preserved. 190*1fd5a2e1SPrashanth Swaminathan We allocate a call context and save the argument passing registers, 191*1fd5a2e1SPrashanth Swaminathan then invoked the generic C ffi_closure_SYSV_inner() function to do all 192*1fd5a2e1SPrashanth Swaminathan the real work, on return we load the result passing registers back from 193*1fd5a2e1SPrashanth Swaminathan the call context. 194*1fd5a2e1SPrashanth Swaminathan*/ 195*1fd5a2e1SPrashanth Swaminathan 196*1fd5a2e1SPrashanth Swaminathan#define ffi_closure_SYSV_FS (8*2 + CALL_CONTEXT_SIZE + 64) 197*1fd5a2e1SPrashanth Swaminathan 198*1fd5a2e1SPrashanth Swaminathan NESTED_ENTRY ffi_closure_SYSV_V 199*1fd5a2e1SPrashanth Swaminathan PROLOG_SAVE_REG_PAIR x29, x30, #-ffi_closure_SYSV_FS! 200*1fd5a2e1SPrashanth Swaminathan 201*1fd5a2e1SPrashanth Swaminathan /* Save the argument passing vector registers. */ 202*1fd5a2e1SPrashanth Swaminathan stp q0, q1, [sp, #16 + 0] 203*1fd5a2e1SPrashanth Swaminathan stp q2, q3, [sp, #16 + 32] 204*1fd5a2e1SPrashanth Swaminathan stp q4, q5, [sp, #16 + 64] 205*1fd5a2e1SPrashanth Swaminathan stp q6, q7, [sp, #16 + 96] 206*1fd5a2e1SPrashanth Swaminathan 207*1fd5a2e1SPrashanth Swaminathan b ffi_closure_SYSV_save_argument 208*1fd5a2e1SPrashanth Swaminathan NESTED_END ffi_closure_SYSV_V 209*1fd5a2e1SPrashanth Swaminathan 210*1fd5a2e1SPrashanth Swaminathan NESTED_ENTRY ffi_closure_SYSV 211*1fd5a2e1SPrashanth Swaminathan PROLOG_SAVE_REG_PAIR x29, x30, #-ffi_closure_SYSV_FS! 212*1fd5a2e1SPrashanth Swaminathan 213*1fd5a2e1SPrashanth Swaminathanffi_closure_SYSV_save_argument 214*1fd5a2e1SPrashanth Swaminathan /* Save the argument passing core registers. */ 215*1fd5a2e1SPrashanth Swaminathan stp x0, x1, [sp, #16 + 16*N_V_ARG_REG + 0] 216*1fd5a2e1SPrashanth Swaminathan stp x2, x3, [sp, #16 + 16*N_V_ARG_REG + 16] 217*1fd5a2e1SPrashanth Swaminathan stp x4, x5, [sp, #16 + 16*N_V_ARG_REG + 32] 218*1fd5a2e1SPrashanth Swaminathan stp x6, x7, [sp, #16 + 16*N_V_ARG_REG + 48] 219*1fd5a2e1SPrashanth Swaminathan 220*1fd5a2e1SPrashanth Swaminathan /* Load ffi_closure_inner arguments. */ 221*1fd5a2e1SPrashanth Swaminathan ldp PTR_REG(0), PTR_REG(1), [x17, #FFI_TRAMPOLINE_CLOSURE_OFFSET] /* load cif, fn */ 222*1fd5a2e1SPrashanth Swaminathan ldr PTR_REG(2), [x17, #FFI_TRAMPOLINE_CLOSURE_OFFSET+PTR_SIZE*2] /* load user_data */ 223*1fd5a2e1SPrashanth Swaminathan 224*1fd5a2e1SPrashanth Swaminathando_closure 225*1fd5a2e1SPrashanth Swaminathan add x3, sp, #16 /* load context */ 226*1fd5a2e1SPrashanth Swaminathan add x4, sp, #ffi_closure_SYSV_FS /* load stack */ 227*1fd5a2e1SPrashanth Swaminathan add x5, sp, #16+CALL_CONTEXT_SIZE /* load rvalue */ 228*1fd5a2e1SPrashanth Swaminathan mov x6, x8 /* load struct_rval */ 229*1fd5a2e1SPrashanth Swaminathan 230*1fd5a2e1SPrashanth Swaminathan bl ffi_closure_SYSV_inner 231*1fd5a2e1SPrashanth Swaminathan 232*1fd5a2e1SPrashanth Swaminathan /* Load the return value as directed. */ 233*1fd5a2e1SPrashanth Swaminathan adr x1, ffi_closure_SYSV_return_base 234*1fd5a2e1SPrashanth Swaminathan and w0, w0, #AARCH64_RET_MASK 235*1fd5a2e1SPrashanth Swaminathan add x1, x1, x0, lsl #3 236*1fd5a2e1SPrashanth Swaminathan add x3, sp, #16+CALL_CONTEXT_SIZE 237*1fd5a2e1SPrashanth Swaminathan br x1 238*1fd5a2e1SPrashanth Swaminathan 239*1fd5a2e1SPrashanth Swaminathan /* Note that each table entry is 2 insns, and thus 8 bytes. */ 240*1fd5a2e1SPrashanth Swaminathan ALIGN 8 241*1fd5a2e1SPrashanth Swaminathanffi_closure_SYSV_return_base 242*1fd5a2e1SPrashanth Swaminathan b ffi_closure_SYSV_epilog /* VOID */ 243*1fd5a2e1SPrashanth Swaminathan nop 244*1fd5a2e1SPrashanth Swaminathan ldr x0, [x3] /* INT64 */ 245*1fd5a2e1SPrashanth Swaminathan b ffi_closure_SYSV_epilog 246*1fd5a2e1SPrashanth Swaminathan ldp x0, x1, [x3] /* INT128 */ 247*1fd5a2e1SPrashanth Swaminathan b ffi_closure_SYSV_epilog 248*1fd5a2e1SPrashanth Swaminathan brk #1000 /* UNUSED */ 249*1fd5a2e1SPrashanth Swaminathan nop 250*1fd5a2e1SPrashanth Swaminathan brk #1000 /* UNUSED */ 251*1fd5a2e1SPrashanth Swaminathan nop 252*1fd5a2e1SPrashanth Swaminathan brk #1000 /* UNUSED */ 253*1fd5a2e1SPrashanth Swaminathan nop 254*1fd5a2e1SPrashanth Swaminathan brk #1000 /* UNUSED */ 255*1fd5a2e1SPrashanth Swaminathan nop 256*1fd5a2e1SPrashanth Swaminathan brk #1000 /* UNUSED */ 257*1fd5a2e1SPrashanth Swaminathan nop 258*1fd5a2e1SPrashanth Swaminathan ldr s3, [x3, #12] /* S4 */ 259*1fd5a2e1SPrashanth Swaminathan nop 260*1fd5a2e1SPrashanth Swaminathan ldr s2, [x3, #8] /* S3 */ 261*1fd5a2e1SPrashanth Swaminathan nop 262*1fd5a2e1SPrashanth Swaminathan ldp s0, s1, [x3] /* S2 */ 263*1fd5a2e1SPrashanth Swaminathan b ffi_closure_SYSV_epilog 264*1fd5a2e1SPrashanth Swaminathan ldr s0, [x3] /* S1 */ 265*1fd5a2e1SPrashanth Swaminathan b ffi_closure_SYSV_epilog 266*1fd5a2e1SPrashanth Swaminathan ldr d3, [x3, #24] /* D4 */ 267*1fd5a2e1SPrashanth Swaminathan nop 268*1fd5a2e1SPrashanth Swaminathan ldr d2, [x3, #16] /* D3 */ 269*1fd5a2e1SPrashanth Swaminathan nop 270*1fd5a2e1SPrashanth Swaminathan ldp d0, d1, [x3] /* D2 */ 271*1fd5a2e1SPrashanth Swaminathan b ffi_closure_SYSV_epilog 272*1fd5a2e1SPrashanth Swaminathan ldr d0, [x3] /* D1 */ 273*1fd5a2e1SPrashanth Swaminathan b ffi_closure_SYSV_epilog 274*1fd5a2e1SPrashanth Swaminathan ldr q3, [x3, #48] /* Q4 */ 275*1fd5a2e1SPrashanth Swaminathan nop 276*1fd5a2e1SPrashanth Swaminathan ldr q2, [x3, #32] /* Q3 */ 277*1fd5a2e1SPrashanth Swaminathan nop 278*1fd5a2e1SPrashanth Swaminathan ldp q0, q1, [x3] /* Q2 */ 279*1fd5a2e1SPrashanth Swaminathan b ffi_closure_SYSV_epilog 280*1fd5a2e1SPrashanth Swaminathan ldr q0, [x3] /* Q1 */ 281*1fd5a2e1SPrashanth Swaminathan b ffi_closure_SYSV_epilog 282*1fd5a2e1SPrashanth Swaminathan ldrb w0, [x3, #BE(7)] /* UINT8 */ 283*1fd5a2e1SPrashanth Swaminathan b ffi_closure_SYSV_epilog 284*1fd5a2e1SPrashanth Swaminathan brk #1000 /* reserved */ 285*1fd5a2e1SPrashanth Swaminathan nop 286*1fd5a2e1SPrashanth Swaminathan ldrh w0, [x3, #BE(6)] /* UINT16 */ 287*1fd5a2e1SPrashanth Swaminathan b ffi_closure_SYSV_epilog 288*1fd5a2e1SPrashanth Swaminathan brk #1000 /* reserved */ 289*1fd5a2e1SPrashanth Swaminathan nop 290*1fd5a2e1SPrashanth Swaminathan ldr w0, [x3, #BE(4)] /* UINT32 */ 291*1fd5a2e1SPrashanth Swaminathan b ffi_closure_SYSV_epilog 292*1fd5a2e1SPrashanth Swaminathan brk #1000 /* reserved */ 293*1fd5a2e1SPrashanth Swaminathan nop 294*1fd5a2e1SPrashanth Swaminathan ldrsb x0, [x3, #BE(7)] /* SINT8 */ 295*1fd5a2e1SPrashanth Swaminathan b ffi_closure_SYSV_epilog 296*1fd5a2e1SPrashanth Swaminathan brk #1000 /* reserved */ 297*1fd5a2e1SPrashanth Swaminathan nop 298*1fd5a2e1SPrashanth Swaminathan ldrsh x0, [x3, #BE(6)] /* SINT16 */ 299*1fd5a2e1SPrashanth Swaminathan b ffi_closure_SYSV_epilog 300*1fd5a2e1SPrashanth Swaminathan brk #1000 /* reserved */ 301*1fd5a2e1SPrashanth Swaminathan nop 302*1fd5a2e1SPrashanth Swaminathan ldrsw x0, [x3, #BE(4)] /* SINT32 */ 303*1fd5a2e1SPrashanth Swaminathan nop 304*1fd5a2e1SPrashanth Swaminathan /* reserved */ 305*1fd5a2e1SPrashanth Swaminathan 306*1fd5a2e1SPrashanth Swaminathanffi_closure_SYSV_epilog 307*1fd5a2e1SPrashanth Swaminathan EPILOG_RESTORE_REG_PAIR x29, x30, #ffi_closure_SYSV_FS! 308*1fd5a2e1SPrashanth Swaminathan EPILOG_RETURN 309*1fd5a2e1SPrashanth Swaminathan NESTED_END ffi_closure_SYSV 310*1fd5a2e1SPrashanth Swaminathan 311*1fd5a2e1SPrashanth Swaminathan 312*1fd5a2e1SPrashanth Swaminathan#ifdef FFI_GO_CLOSURES 313*1fd5a2e1SPrashanth Swaminathan NESTED_ENTRY ffi_go_closure_SYSV_V 314*1fd5a2e1SPrashanth Swaminathan PROLOG_SAVE_REG_PAIR x29, x30, #-ffi_closure_SYSV_FS! 315*1fd5a2e1SPrashanth Swaminathan 316*1fd5a2e1SPrashanth Swaminathan /* Save the argument passing vector registers. */ 317*1fd5a2e1SPrashanth Swaminathan stp q0, q1, [sp, #16 + 0] 318*1fd5a2e1SPrashanth Swaminathan stp q2, q3, [sp, #16 + 32] 319*1fd5a2e1SPrashanth Swaminathan stp q4, q5, [sp, #16 + 64] 320*1fd5a2e1SPrashanth Swaminathan stp q6, q7, [sp, #16 + 96] 321*1fd5a2e1SPrashanth Swaminathan b ffi_go_closure_SYSV_save_argument 322*1fd5a2e1SPrashanth Swaminathan NESTED_END ffi_go_closure_SYSV_V 323*1fd5a2e1SPrashanth Swaminathan 324*1fd5a2e1SPrashanth Swaminathan NESTED_ENTRY ffi_go_closure_SYSV 325*1fd5a2e1SPrashanth Swaminathan PROLOG_SAVE_REG_PAIR x29, x30, #-ffi_closure_SYSV_FS! 326*1fd5a2e1SPrashanth Swaminathan 327*1fd5a2e1SPrashanth Swaminathanffi_go_closure_SYSV_save_argument 328*1fd5a2e1SPrashanth Swaminathan /* Save the argument passing core registers. */ 329*1fd5a2e1SPrashanth Swaminathan stp x0, x1, [sp, #16 + 16*N_V_ARG_REG + 0] 330*1fd5a2e1SPrashanth Swaminathan stp x2, x3, [sp, #16 + 16*N_V_ARG_REG + 16] 331*1fd5a2e1SPrashanth Swaminathan stp x4, x5, [sp, #16 + 16*N_V_ARG_REG + 32] 332*1fd5a2e1SPrashanth Swaminathan stp x6, x7, [sp, #16 + 16*N_V_ARG_REG + 48] 333*1fd5a2e1SPrashanth Swaminathan 334*1fd5a2e1SPrashanth Swaminathan /* Load ffi_closure_inner arguments. */ 335*1fd5a2e1SPrashanth Swaminathan ldp PTR_REG(0), PTR_REG(1), [x18, #PTR_SIZE]/* load cif, fn */ 336*1fd5a2e1SPrashanth Swaminathan mov x2, x18 /* load user_data */ 337*1fd5a2e1SPrashanth Swaminathan b do_closure 338*1fd5a2e1SPrashanth Swaminathan NESTED_END ffi_go_closure_SYSV 339*1fd5a2e1SPrashanth Swaminathan 340*1fd5a2e1SPrashanth Swaminathan#endif /* FFI_GO_CLOSURES */ 341*1fd5a2e1SPrashanth Swaminathan 342*1fd5a2e1SPrashanth Swaminathan 343*1fd5a2e1SPrashanth Swaminathan/* void extend_hfa_type (void *dest, void *src, int h) */ 344*1fd5a2e1SPrashanth Swaminathan 345*1fd5a2e1SPrashanth Swaminathan LEAF_ENTRY extend_hfa_type 346*1fd5a2e1SPrashanth Swaminathan 347*1fd5a2e1SPrashanth Swaminathan adr x3, extend_hfa_type_jump_base 348*1fd5a2e1SPrashanth Swaminathan and w2, w2, #AARCH64_RET_MASK 349*1fd5a2e1SPrashanth Swaminathan sub x2, x2, #AARCH64_RET_S4 350*1fd5a2e1SPrashanth Swaminathan add x3, x3, x2, lsl #4 351*1fd5a2e1SPrashanth Swaminathan br x3 352*1fd5a2e1SPrashanth Swaminathan 353*1fd5a2e1SPrashanth Swaminathan ALIGN 4 354*1fd5a2e1SPrashanth Swaminathanextend_hfa_type_jump_base 355*1fd5a2e1SPrashanth Swaminathan ldp s16, s17, [x1] /* S4 */ 356*1fd5a2e1SPrashanth Swaminathan ldp s18, s19, [x1, #8] 357*1fd5a2e1SPrashanth Swaminathan b extend_hfa_type_store_4 358*1fd5a2e1SPrashanth Swaminathan nop 359*1fd5a2e1SPrashanth Swaminathan 360*1fd5a2e1SPrashanth Swaminathan ldp s16, s17, [x1] /* S3 */ 361*1fd5a2e1SPrashanth Swaminathan ldr s18, [x1, #8] 362*1fd5a2e1SPrashanth Swaminathan b extend_hfa_type_store_3 363*1fd5a2e1SPrashanth Swaminathan nop 364*1fd5a2e1SPrashanth Swaminathan 365*1fd5a2e1SPrashanth Swaminathan ldp s16, s17, [x1] /* S2 */ 366*1fd5a2e1SPrashanth Swaminathan b extend_hfa_type_store_2 367*1fd5a2e1SPrashanth Swaminathan nop 368*1fd5a2e1SPrashanth Swaminathan nop 369*1fd5a2e1SPrashanth Swaminathan 370*1fd5a2e1SPrashanth Swaminathan ldr s16, [x1] /* S1 */ 371*1fd5a2e1SPrashanth Swaminathan b extend_hfa_type_store_1 372*1fd5a2e1SPrashanth Swaminathan nop 373*1fd5a2e1SPrashanth Swaminathan nop 374*1fd5a2e1SPrashanth Swaminathan 375*1fd5a2e1SPrashanth Swaminathan ldp d16, d17, [x1] /* D4 */ 376*1fd5a2e1SPrashanth Swaminathan ldp d18, d19, [x1, #16] 377*1fd5a2e1SPrashanth Swaminathan b extend_hfa_type_store_4 378*1fd5a2e1SPrashanth Swaminathan nop 379*1fd5a2e1SPrashanth Swaminathan 380*1fd5a2e1SPrashanth Swaminathan ldp d16, d17, [x1] /* D3 */ 381*1fd5a2e1SPrashanth Swaminathan ldr d18, [x1, #16] 382*1fd5a2e1SPrashanth Swaminathan b extend_hfa_type_store_3 383*1fd5a2e1SPrashanth Swaminathan nop 384*1fd5a2e1SPrashanth Swaminathan 385*1fd5a2e1SPrashanth Swaminathan ldp d16, d17, [x1] /* D2 */ 386*1fd5a2e1SPrashanth Swaminathan b extend_hfa_type_store_2 387*1fd5a2e1SPrashanth Swaminathan nop 388*1fd5a2e1SPrashanth Swaminathan nop 389*1fd5a2e1SPrashanth Swaminathan 390*1fd5a2e1SPrashanth Swaminathan ldr d16, [x1] /* D1 */ 391*1fd5a2e1SPrashanth Swaminathan b extend_hfa_type_store_1 392*1fd5a2e1SPrashanth Swaminathan nop 393*1fd5a2e1SPrashanth Swaminathan nop 394*1fd5a2e1SPrashanth Swaminathan 395*1fd5a2e1SPrashanth Swaminathan ldp q16, q17, [x1] /* Q4 */ 396*1fd5a2e1SPrashanth Swaminathan ldp q18, q19, [x1, #16] 397*1fd5a2e1SPrashanth Swaminathan b extend_hfa_type_store_4 398*1fd5a2e1SPrashanth Swaminathan nop 399*1fd5a2e1SPrashanth Swaminathan 400*1fd5a2e1SPrashanth Swaminathan ldp q16, q17, [x1] /* Q3 */ 401*1fd5a2e1SPrashanth Swaminathan ldr q18, [x1, #16] 402*1fd5a2e1SPrashanth Swaminathan b extend_hfa_type_store_3 403*1fd5a2e1SPrashanth Swaminathan nop 404*1fd5a2e1SPrashanth Swaminathan 405*1fd5a2e1SPrashanth Swaminathan ldp q16, q17, [x1] /* Q2 */ 406*1fd5a2e1SPrashanth Swaminathan b extend_hfa_type_store_2 407*1fd5a2e1SPrashanth Swaminathan nop 408*1fd5a2e1SPrashanth Swaminathan nop 409*1fd5a2e1SPrashanth Swaminathan 410*1fd5a2e1SPrashanth Swaminathan ldr q16, [x1] /* Q1 */ 411*1fd5a2e1SPrashanth Swaminathan b extend_hfa_type_store_1 412*1fd5a2e1SPrashanth Swaminathan 413*1fd5a2e1SPrashanth Swaminathanextend_hfa_type_store_4 414*1fd5a2e1SPrashanth Swaminathan str q19, [x0, #48] 415*1fd5a2e1SPrashanth Swaminathanextend_hfa_type_store_3 416*1fd5a2e1SPrashanth Swaminathan str q18, [x0, #32] 417*1fd5a2e1SPrashanth Swaminathanextend_hfa_type_store_2 418*1fd5a2e1SPrashanth Swaminathan str q17, [x0, #16] 419*1fd5a2e1SPrashanth Swaminathanextend_hfa_type_store_1 420*1fd5a2e1SPrashanth Swaminathan str q16, [x0] 421*1fd5a2e1SPrashanth Swaminathan ret 422*1fd5a2e1SPrashanth Swaminathan 423*1fd5a2e1SPrashanth Swaminathan LEAF_END extend_hfa_type 424*1fd5a2e1SPrashanth Swaminathan 425*1fd5a2e1SPrashanth Swaminathan 426*1fd5a2e1SPrashanth Swaminathan/* void compress_hfa_type (void *dest, void *reg, int h) */ 427*1fd5a2e1SPrashanth Swaminathan 428*1fd5a2e1SPrashanth Swaminathan LEAF_ENTRY compress_hfa_type 429*1fd5a2e1SPrashanth Swaminathan 430*1fd5a2e1SPrashanth Swaminathan adr x3, compress_hfa_type_jump_base 431*1fd5a2e1SPrashanth Swaminathan and w2, w2, #AARCH64_RET_MASK 432*1fd5a2e1SPrashanth Swaminathan sub x2, x2, #AARCH64_RET_S4 433*1fd5a2e1SPrashanth Swaminathan add x3, x3, x2, lsl #4 434*1fd5a2e1SPrashanth Swaminathan br x3 435*1fd5a2e1SPrashanth Swaminathan 436*1fd5a2e1SPrashanth Swaminathan ALIGN 4 437*1fd5a2e1SPrashanth Swaminathancompress_hfa_type_jump_base 438*1fd5a2e1SPrashanth Swaminathan ldp q16, q17, [x1] /* S4 */ 439*1fd5a2e1SPrashanth Swaminathan ldp q18, q19, [x1, #32] 440*1fd5a2e1SPrashanth Swaminathan st4 { v16.s, v17.s, v18.s, v19.s }[0], [x0] 441*1fd5a2e1SPrashanth Swaminathan ret 442*1fd5a2e1SPrashanth Swaminathan 443*1fd5a2e1SPrashanth Swaminathan ldp q16, q17, [x1] /* S3 */ 444*1fd5a2e1SPrashanth Swaminathan ldr q18, [x1, #32] 445*1fd5a2e1SPrashanth Swaminathan st3 { v16.s, v17.s, v18.s }[0], [x0] 446*1fd5a2e1SPrashanth Swaminathan ret 447*1fd5a2e1SPrashanth Swaminathan 448*1fd5a2e1SPrashanth Swaminathan ldp q16, q17, [x1] /* S2 */ 449*1fd5a2e1SPrashanth Swaminathan st2 { v16.s, v17.s }[0], [x0] 450*1fd5a2e1SPrashanth Swaminathan ret 451*1fd5a2e1SPrashanth Swaminathan nop 452*1fd5a2e1SPrashanth Swaminathan 453*1fd5a2e1SPrashanth Swaminathan ldr q16, [x1] /* S1 */ 454*1fd5a2e1SPrashanth Swaminathan st1 { v16.s }[0], [x0] 455*1fd5a2e1SPrashanth Swaminathan ret 456*1fd5a2e1SPrashanth Swaminathan nop 457*1fd5a2e1SPrashanth Swaminathan 458*1fd5a2e1SPrashanth Swaminathan ldp q16, q17, [x1] /* D4 */ 459*1fd5a2e1SPrashanth Swaminathan ldp q18, q19, [x1, #32] 460*1fd5a2e1SPrashanth Swaminathan st4 { v16.d, v17.d, v18.d, v19.d }[0], [x0] 461*1fd5a2e1SPrashanth Swaminathan ret 462*1fd5a2e1SPrashanth Swaminathan 463*1fd5a2e1SPrashanth Swaminathan ldp q16, q17, [x1] /* D3 */ 464*1fd5a2e1SPrashanth Swaminathan ldr q18, [x1, #32] 465*1fd5a2e1SPrashanth Swaminathan st3 { v16.d, v17.d, v18.d }[0], [x0] 466*1fd5a2e1SPrashanth Swaminathan ret 467*1fd5a2e1SPrashanth Swaminathan 468*1fd5a2e1SPrashanth Swaminathan ldp q16, q17, [x1] /* D2 */ 469*1fd5a2e1SPrashanth Swaminathan st2 { v16.d, v17.d }[0], [x0] 470*1fd5a2e1SPrashanth Swaminathan ret 471*1fd5a2e1SPrashanth Swaminathan nop 472*1fd5a2e1SPrashanth Swaminathan 473*1fd5a2e1SPrashanth Swaminathan ldr q16, [x1] /* D1 */ 474*1fd5a2e1SPrashanth Swaminathan st1 { v16.d }[0], [x0] 475*1fd5a2e1SPrashanth Swaminathan ret 476*1fd5a2e1SPrashanth Swaminathan nop 477*1fd5a2e1SPrashanth Swaminathan 478*1fd5a2e1SPrashanth Swaminathan ldp q16, q17, [x1] /* Q4 */ 479*1fd5a2e1SPrashanth Swaminathan ldp q18, q19, [x1, #32] 480*1fd5a2e1SPrashanth Swaminathan b compress_hfa_type_store_q4 481*1fd5a2e1SPrashanth Swaminathan nop 482*1fd5a2e1SPrashanth Swaminathan 483*1fd5a2e1SPrashanth Swaminathan ldp q16, q17, [x1] /* Q3 */ 484*1fd5a2e1SPrashanth Swaminathan ldr q18, [x1, #32] 485*1fd5a2e1SPrashanth Swaminathan b compress_hfa_type_store_q3 486*1fd5a2e1SPrashanth Swaminathan nop 487*1fd5a2e1SPrashanth Swaminathan 488*1fd5a2e1SPrashanth Swaminathan ldp q16, q17, [x1] /* Q2 */ 489*1fd5a2e1SPrashanth Swaminathan stp q16, q17, [x0] 490*1fd5a2e1SPrashanth Swaminathan ret 491*1fd5a2e1SPrashanth Swaminathan nop 492*1fd5a2e1SPrashanth Swaminathan 493*1fd5a2e1SPrashanth Swaminathan ldr q16, [x1] /* Q1 */ 494*1fd5a2e1SPrashanth Swaminathan str q16, [x0] 495*1fd5a2e1SPrashanth Swaminathan ret 496*1fd5a2e1SPrashanth Swaminathan 497*1fd5a2e1SPrashanth Swaminathancompress_hfa_type_store_q4 498*1fd5a2e1SPrashanth Swaminathan str q19, [x0, #48] 499*1fd5a2e1SPrashanth Swaminathancompress_hfa_type_store_q3 500*1fd5a2e1SPrashanth Swaminathan str q18, [x0, #32] 501*1fd5a2e1SPrashanth Swaminathan stp q16, q17, [x0] 502*1fd5a2e1SPrashanth Swaminathan ret 503*1fd5a2e1SPrashanth Swaminathan 504*1fd5a2e1SPrashanth Swaminathan LEAF_END compress_hfa_type 505*1fd5a2e1SPrashanth Swaminathan 506*1fd5a2e1SPrashanth Swaminathan END