1*1fd5a2e1SPrashanth Swaminathan/* ----------------------------------------------------------------------- 2*1fd5a2e1SPrashanth Swaminathan osf.S - Copyright (c) 1998, 2001, 2007, 2008, 2011, 2014 Red Hat 3*1fd5a2e1SPrashanth Swaminathan 4*1fd5a2e1SPrashanth Swaminathan Alpha/OSF 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#include <ffi_cfi.h> 31*1fd5a2e1SPrashanth Swaminathan#include "internal.h" 32*1fd5a2e1SPrashanth Swaminathan 33*1fd5a2e1SPrashanth Swaminathan .arch ev6 34*1fd5a2e1SPrashanth Swaminathan .text 35*1fd5a2e1SPrashanth Swaminathan 36*1fd5a2e1SPrashanth Swaminathan/* Aid in building a direct addressed jump table, 4 insns per entry. */ 37*1fd5a2e1SPrashanth Swaminathan.macro E index 38*1fd5a2e1SPrashanth Swaminathan .align 4 39*1fd5a2e1SPrashanth Swaminathan .org 99b + \index * 16 40*1fd5a2e1SPrashanth Swaminathan.endm 41*1fd5a2e1SPrashanth Swaminathan 42*1fd5a2e1SPrashanth Swaminathan/* ffi_call_osf (void *stack, void *frame, unsigned flags, 43*1fd5a2e1SPrashanth Swaminathan void *raddr, void (*fnaddr)(void), void *closure) 44*1fd5a2e1SPrashanth Swaminathan 45*1fd5a2e1SPrashanth Swaminathan Bit o trickiness here -- FRAME is the base of the stack frame 46*1fd5a2e1SPrashanth Swaminathan for this function. This has been allocated by ffi_call. We also 47*1fd5a2e1SPrashanth Swaminathan deallocate some of the stack that has been alloca'd. */ 48*1fd5a2e1SPrashanth Swaminathan 49*1fd5a2e1SPrashanth Swaminathan .align 4 50*1fd5a2e1SPrashanth Swaminathan .globl ffi_call_osf 51*1fd5a2e1SPrashanth Swaminathan .ent ffi_call_osf 52*1fd5a2e1SPrashanth Swaminathan FFI_HIDDEN(ffi_call_osf) 53*1fd5a2e1SPrashanth Swaminathan 54*1fd5a2e1SPrashanth Swaminathanffi_call_osf: 55*1fd5a2e1SPrashanth Swaminathan cfi_startproc 56*1fd5a2e1SPrashanth Swaminathan cfi_def_cfa($17, 32) 57*1fd5a2e1SPrashanth Swaminathan mov $16, $30 58*1fd5a2e1SPrashanth Swaminathan stq $26, 0($17) 59*1fd5a2e1SPrashanth Swaminathan stq $15, 8($17) 60*1fd5a2e1SPrashanth Swaminathan mov $17, $15 61*1fd5a2e1SPrashanth Swaminathan .prologue 0 62*1fd5a2e1SPrashanth Swaminathan cfi_def_cfa_register($15) 63*1fd5a2e1SPrashanth Swaminathan cfi_rel_offset($26, 0) 64*1fd5a2e1SPrashanth Swaminathan cfi_rel_offset($15, 8) 65*1fd5a2e1SPrashanth Swaminathan 66*1fd5a2e1SPrashanth Swaminathan stq $18, 16($17) # save flags into frame 67*1fd5a2e1SPrashanth Swaminathan stq $19, 24($17) # save rvalue into frame 68*1fd5a2e1SPrashanth Swaminathan mov $20, $27 # fn into place for call 69*1fd5a2e1SPrashanth Swaminathan mov $21, $1 # closure into static chain 70*1fd5a2e1SPrashanth Swaminathan 71*1fd5a2e1SPrashanth Swaminathan # Load up all of the (potential) argument registers. 72*1fd5a2e1SPrashanth Swaminathan ldq $16, 0($30) 73*1fd5a2e1SPrashanth Swaminathan ldt $f16, 0($30) 74*1fd5a2e1SPrashanth Swaminathan ldt $f17, 8($30) 75*1fd5a2e1SPrashanth Swaminathan ldq $17, 8($30) 76*1fd5a2e1SPrashanth Swaminathan ldt $f18, 16($30) 77*1fd5a2e1SPrashanth Swaminathan ldq $18, 16($30) 78*1fd5a2e1SPrashanth Swaminathan ldt $f19, 24($30) 79*1fd5a2e1SPrashanth Swaminathan ldq $19, 24($30) 80*1fd5a2e1SPrashanth Swaminathan ldt $f20, 32($30) 81*1fd5a2e1SPrashanth Swaminathan ldq $20, 32($30) 82*1fd5a2e1SPrashanth Swaminathan ldt $f21, 40($30) 83*1fd5a2e1SPrashanth Swaminathan ldq $21, 40($30) 84*1fd5a2e1SPrashanth Swaminathan 85*1fd5a2e1SPrashanth Swaminathan # Deallocate the register argument area. 86*1fd5a2e1SPrashanth Swaminathan lda $30, 48($30) 87*1fd5a2e1SPrashanth Swaminathan 88*1fd5a2e1SPrashanth Swaminathan jsr $26, ($27), 0 89*1fd5a2e1SPrashanth Swaminathan0: 90*1fd5a2e1SPrashanth Swaminathan ldah $29, 0($26) !gpdisp!1 91*1fd5a2e1SPrashanth Swaminathan ldq $2, 24($15) # reload rvalue 92*1fd5a2e1SPrashanth Swaminathan lda $29, 0($29) !gpdisp!1 93*1fd5a2e1SPrashanth Swaminathan ldq $3, 16($15) # reload flags 94*1fd5a2e1SPrashanth Swaminathan lda $1, 99f-0b($26) 95*1fd5a2e1SPrashanth Swaminathan ldq $26, 0($15) 96*1fd5a2e1SPrashanth Swaminathan ldq $15, 8($15) 97*1fd5a2e1SPrashanth Swaminathan cfi_restore($26) 98*1fd5a2e1SPrashanth Swaminathan cfi_restore($15) 99*1fd5a2e1SPrashanth Swaminathan cfi_def_cfa($sp, 0) 100*1fd5a2e1SPrashanth Swaminathan cmoveq $2, ALPHA_ST_VOID, $3 # mash null rvalue to void 101*1fd5a2e1SPrashanth Swaminathan addq $3, $3, $3 102*1fd5a2e1SPrashanth Swaminathan s8addq $3, $1, $1 # 99f + stcode * 16 103*1fd5a2e1SPrashanth Swaminathan jmp $31, ($1), $st_int 104*1fd5a2e1SPrashanth Swaminathan 105*1fd5a2e1SPrashanth Swaminathan .align 4 106*1fd5a2e1SPrashanth Swaminathan99: 107*1fd5a2e1SPrashanth SwaminathanE ALPHA_ST_VOID 108*1fd5a2e1SPrashanth Swaminathan ret 109*1fd5a2e1SPrashanth SwaminathanE ALPHA_ST_INT 110*1fd5a2e1SPrashanth Swaminathan$st_int: 111*1fd5a2e1SPrashanth Swaminathan stq $0, 0($2) 112*1fd5a2e1SPrashanth Swaminathan ret 113*1fd5a2e1SPrashanth SwaminathanE ALPHA_ST_FLOAT 114*1fd5a2e1SPrashanth Swaminathan sts $f0, 0($2) 115*1fd5a2e1SPrashanth Swaminathan ret 116*1fd5a2e1SPrashanth SwaminathanE ALPHA_ST_DOUBLE 117*1fd5a2e1SPrashanth Swaminathan stt $f0, 0($2) 118*1fd5a2e1SPrashanth Swaminathan ret 119*1fd5a2e1SPrashanth SwaminathanE ALPHA_ST_CPLXF 120*1fd5a2e1SPrashanth Swaminathan sts $f0, 0($2) 121*1fd5a2e1SPrashanth Swaminathan sts $f1, 4($2) 122*1fd5a2e1SPrashanth Swaminathan ret 123*1fd5a2e1SPrashanth SwaminathanE ALPHA_ST_CPLXD 124*1fd5a2e1SPrashanth Swaminathan stt $f0, 0($2) 125*1fd5a2e1SPrashanth Swaminathan stt $f1, 8($2) 126*1fd5a2e1SPrashanth Swaminathan ret 127*1fd5a2e1SPrashanth Swaminathan 128*1fd5a2e1SPrashanth Swaminathan cfi_endproc 129*1fd5a2e1SPrashanth Swaminathan .end ffi_call_osf 130*1fd5a2e1SPrashanth Swaminathan 131*1fd5a2e1SPrashanth Swaminathan/* ffi_closure_osf(...) 132*1fd5a2e1SPrashanth Swaminathan 133*1fd5a2e1SPrashanth Swaminathan Receives the closure argument in $1. */ 134*1fd5a2e1SPrashanth Swaminathan 135*1fd5a2e1SPrashanth Swaminathan#define CLOSURE_FS (16*8) 136*1fd5a2e1SPrashanth Swaminathan 137*1fd5a2e1SPrashanth Swaminathan .align 4 138*1fd5a2e1SPrashanth Swaminathan .globl ffi_go_closure_osf 139*1fd5a2e1SPrashanth Swaminathan .ent ffi_go_closure_osf 140*1fd5a2e1SPrashanth Swaminathan FFI_HIDDEN(ffi_go_closure_osf) 141*1fd5a2e1SPrashanth Swaminathan 142*1fd5a2e1SPrashanth Swaminathanffi_go_closure_osf: 143*1fd5a2e1SPrashanth Swaminathan cfi_startproc 144*1fd5a2e1SPrashanth Swaminathan ldgp $29, 0($27) 145*1fd5a2e1SPrashanth Swaminathan subq $30, CLOSURE_FS, $30 146*1fd5a2e1SPrashanth Swaminathan cfi_adjust_cfa_offset(CLOSURE_FS) 147*1fd5a2e1SPrashanth Swaminathan stq $26, 0($30) 148*1fd5a2e1SPrashanth Swaminathan .prologue 1 149*1fd5a2e1SPrashanth Swaminathan cfi_rel_offset($26, 0) 150*1fd5a2e1SPrashanth Swaminathan 151*1fd5a2e1SPrashanth Swaminathan stq $16, 10*8($30) 152*1fd5a2e1SPrashanth Swaminathan stq $17, 11*8($30) 153*1fd5a2e1SPrashanth Swaminathan stq $18, 12*8($30) 154*1fd5a2e1SPrashanth Swaminathan 155*1fd5a2e1SPrashanth Swaminathan ldq $16, 8($1) # load cif 156*1fd5a2e1SPrashanth Swaminathan ldq $17, 16($1) # load fun 157*1fd5a2e1SPrashanth Swaminathan mov $1, $18 # closure is user_data 158*1fd5a2e1SPrashanth Swaminathan br $do_closure 159*1fd5a2e1SPrashanth Swaminathan 160*1fd5a2e1SPrashanth Swaminathan cfi_endproc 161*1fd5a2e1SPrashanth Swaminathan .end ffi_go_closure_osf 162*1fd5a2e1SPrashanth Swaminathan 163*1fd5a2e1SPrashanth Swaminathan .align 4 164*1fd5a2e1SPrashanth Swaminathan .globl ffi_closure_osf 165*1fd5a2e1SPrashanth Swaminathan .ent ffi_closure_osf 166*1fd5a2e1SPrashanth Swaminathan FFI_HIDDEN(ffi_closure_osf) 167*1fd5a2e1SPrashanth Swaminathan 168*1fd5a2e1SPrashanth Swaminathanffi_closure_osf: 169*1fd5a2e1SPrashanth Swaminathan cfi_startproc 170*1fd5a2e1SPrashanth Swaminathan ldgp $29, 0($27) 171*1fd5a2e1SPrashanth Swaminathan subq $30, CLOSURE_FS, $30 172*1fd5a2e1SPrashanth Swaminathan cfi_adjust_cfa_offset(CLOSURE_FS) 173*1fd5a2e1SPrashanth Swaminathan stq $26, 0($30) 174*1fd5a2e1SPrashanth Swaminathan .prologue 1 175*1fd5a2e1SPrashanth Swaminathan cfi_rel_offset($26, 0) 176*1fd5a2e1SPrashanth Swaminathan 177*1fd5a2e1SPrashanth Swaminathan # Store all of the potential argument registers in va_list format. 178*1fd5a2e1SPrashanth Swaminathan stq $16, 10*8($30) 179*1fd5a2e1SPrashanth Swaminathan stq $17, 11*8($30) 180*1fd5a2e1SPrashanth Swaminathan stq $18, 12*8($30) 181*1fd5a2e1SPrashanth Swaminathan 182*1fd5a2e1SPrashanth Swaminathan ldq $16, 24($1) # load cif 183*1fd5a2e1SPrashanth Swaminathan ldq $17, 32($1) # load fun 184*1fd5a2e1SPrashanth Swaminathan ldq $18, 40($1) # load user_data 185*1fd5a2e1SPrashanth Swaminathan 186*1fd5a2e1SPrashanth Swaminathan$do_closure: 187*1fd5a2e1SPrashanth Swaminathan stq $19, 13*8($30) 188*1fd5a2e1SPrashanth Swaminathan stq $20, 14*8($30) 189*1fd5a2e1SPrashanth Swaminathan stq $21, 15*8($30) 190*1fd5a2e1SPrashanth Swaminathan stt $f16, 4*8($30) 191*1fd5a2e1SPrashanth Swaminathan stt $f17, 5*8($30) 192*1fd5a2e1SPrashanth Swaminathan stt $f18, 6*8($30) 193*1fd5a2e1SPrashanth Swaminathan stt $f19, 7*8($30) 194*1fd5a2e1SPrashanth Swaminathan stt $f20, 8*8($30) 195*1fd5a2e1SPrashanth Swaminathan stt $f21, 9*8($30) 196*1fd5a2e1SPrashanth Swaminathan 197*1fd5a2e1SPrashanth Swaminathan # Call ffi_closure_osf_inner to do the bulk of the work. 198*1fd5a2e1SPrashanth Swaminathan lda $19, 2*8($30) 199*1fd5a2e1SPrashanth Swaminathan lda $20, 10*8($30) 200*1fd5a2e1SPrashanth Swaminathan jsr $26, ffi_closure_osf_inner 201*1fd5a2e1SPrashanth Swaminathan0: 202*1fd5a2e1SPrashanth Swaminathan ldah $29, 0($26) !gpdisp!2 203*1fd5a2e1SPrashanth Swaminathan lda $2, 99f-0b($26) 204*1fd5a2e1SPrashanth Swaminathan s4addq $0, 0, $1 # ldcode * 4 205*1fd5a2e1SPrashanth Swaminathan ldq $0, 16($30) # preload return value 206*1fd5a2e1SPrashanth Swaminathan s4addq $1, $2, $1 # 99f + ldcode * 16 207*1fd5a2e1SPrashanth Swaminathan lda $29, 0($29) !gpdisp!2 208*1fd5a2e1SPrashanth Swaminathan ldq $26, 0($30) 209*1fd5a2e1SPrashanth Swaminathan cfi_restore($26) 210*1fd5a2e1SPrashanth Swaminathan jmp $31, ($1), $load_32 211*1fd5a2e1SPrashanth Swaminathan 212*1fd5a2e1SPrashanth Swaminathan.macro epilogue 213*1fd5a2e1SPrashanth Swaminathan addq $30, CLOSURE_FS, $30 214*1fd5a2e1SPrashanth Swaminathan cfi_adjust_cfa_offset(-CLOSURE_FS) 215*1fd5a2e1SPrashanth Swaminathan ret 216*1fd5a2e1SPrashanth Swaminathan .align 4 217*1fd5a2e1SPrashanth Swaminathan cfi_adjust_cfa_offset(CLOSURE_FS) 218*1fd5a2e1SPrashanth Swaminathan.endm 219*1fd5a2e1SPrashanth Swaminathan 220*1fd5a2e1SPrashanth Swaminathan .align 4 221*1fd5a2e1SPrashanth Swaminathan99: 222*1fd5a2e1SPrashanth SwaminathanE ALPHA_LD_VOID 223*1fd5a2e1SPrashanth Swaminathan epilogue 224*1fd5a2e1SPrashanth Swaminathan 225*1fd5a2e1SPrashanth SwaminathanE ALPHA_LD_INT64 226*1fd5a2e1SPrashanth Swaminathan epilogue 227*1fd5a2e1SPrashanth Swaminathan 228*1fd5a2e1SPrashanth SwaminathanE ALPHA_LD_INT32 229*1fd5a2e1SPrashanth Swaminathan$load_32: 230*1fd5a2e1SPrashanth Swaminathan sextl $0, $0 231*1fd5a2e1SPrashanth Swaminathan epilogue 232*1fd5a2e1SPrashanth Swaminathan 233*1fd5a2e1SPrashanth SwaminathanE ALPHA_LD_UINT16 234*1fd5a2e1SPrashanth Swaminathan zapnot $0, 3, $0 235*1fd5a2e1SPrashanth Swaminathan epilogue 236*1fd5a2e1SPrashanth Swaminathan 237*1fd5a2e1SPrashanth SwaminathanE ALPHA_LD_SINT16 238*1fd5a2e1SPrashanth Swaminathan#ifdef __alpha_bwx__ 239*1fd5a2e1SPrashanth Swaminathan sextw $0, $0 240*1fd5a2e1SPrashanth Swaminathan#else 241*1fd5a2e1SPrashanth Swaminathan sll $0, 48, $0 242*1fd5a2e1SPrashanth Swaminathan sra $0, 48, $0 243*1fd5a2e1SPrashanth Swaminathan#endif 244*1fd5a2e1SPrashanth Swaminathan epilogue 245*1fd5a2e1SPrashanth Swaminathan 246*1fd5a2e1SPrashanth SwaminathanE ALPHA_LD_UINT8 247*1fd5a2e1SPrashanth Swaminathan and $0, 0xff, $0 248*1fd5a2e1SPrashanth Swaminathan epilogue 249*1fd5a2e1SPrashanth Swaminathan 250*1fd5a2e1SPrashanth SwaminathanE ALPHA_LD_SINT8 251*1fd5a2e1SPrashanth Swaminathan#ifdef __alpha_bwx__ 252*1fd5a2e1SPrashanth Swaminathan sextb $0, $0 253*1fd5a2e1SPrashanth Swaminathan#else 254*1fd5a2e1SPrashanth Swaminathan sll $0, 56, $0 255*1fd5a2e1SPrashanth Swaminathan sra $0, 56, $0 256*1fd5a2e1SPrashanth Swaminathan#endif 257*1fd5a2e1SPrashanth Swaminathan epilogue 258*1fd5a2e1SPrashanth Swaminathan 259*1fd5a2e1SPrashanth SwaminathanE ALPHA_LD_FLOAT 260*1fd5a2e1SPrashanth Swaminathan lds $f0, 16($sp) 261*1fd5a2e1SPrashanth Swaminathan epilogue 262*1fd5a2e1SPrashanth Swaminathan 263*1fd5a2e1SPrashanth SwaminathanE ALPHA_LD_DOUBLE 264*1fd5a2e1SPrashanth Swaminathan ldt $f0, 16($sp) 265*1fd5a2e1SPrashanth Swaminathan epilogue 266*1fd5a2e1SPrashanth Swaminathan 267*1fd5a2e1SPrashanth SwaminathanE ALPHA_LD_CPLXF 268*1fd5a2e1SPrashanth Swaminathan lds $f0, 16($sp) 269*1fd5a2e1SPrashanth Swaminathan lds $f1, 20($sp) 270*1fd5a2e1SPrashanth Swaminathan epilogue 271*1fd5a2e1SPrashanth Swaminathan 272*1fd5a2e1SPrashanth SwaminathanE ALPHA_LD_CPLXD 273*1fd5a2e1SPrashanth Swaminathan ldt $f0, 16($sp) 274*1fd5a2e1SPrashanth Swaminathan ldt $f1, 24($sp) 275*1fd5a2e1SPrashanth Swaminathan epilogue 276*1fd5a2e1SPrashanth Swaminathan 277*1fd5a2e1SPrashanth Swaminathan cfi_endproc 278*1fd5a2e1SPrashanth Swaminathan .end ffi_closure_osf 279*1fd5a2e1SPrashanth Swaminathan 280*1fd5a2e1SPrashanth Swaminathan#if defined __ELF__ && defined __linux__ 281*1fd5a2e1SPrashanth Swaminathan .section .note.GNU-stack,"",@progbits 282*1fd5a2e1SPrashanth Swaminathan#endif 283