1/* ----------------------------------------------------------------------- 2 osf.S - Copyright (c) 1998, 2001, 2007, 2008, 2011, 2014 Red Hat 3 4 Alpha/OSF Foreign Function Interface 5 6 Permission is hereby granted, free of charge, to any person obtaining 7 a copy of this software and associated documentation files (the 8 ``Software''), to deal in the Software without restriction, including 9 without limitation the rights to use, copy, modify, merge, publish, 10 distribute, sublicense, and/or sell copies of the Software, and to 11 permit persons to whom the Software is furnished to do so, subject to 12 the following conditions: 13 14 The above copyright notice and this permission notice shall be included 15 in all copies or substantial portions of the Software. 16 17 THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, 18 EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 19 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 20 NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 21 HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 22 WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 23 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 24 DEALINGS IN THE SOFTWARE. 25 ----------------------------------------------------------------------- */ 26 27#define LIBFFI_ASM 28#include <fficonfig.h> 29#include <ffi.h> 30#include <ffi_cfi.h> 31#include "internal.h" 32 33 .arch ev6 34 .text 35 36/* Aid in building a direct addressed jump table, 4 insns per entry. */ 37.macro E index 38 .align 4 39 .org 99b + \index * 16 40.endm 41 42/* ffi_call_osf (void *stack, void *frame, unsigned flags, 43 void *raddr, void (*fnaddr)(void), void *closure) 44 45 Bit o trickiness here -- FRAME is the base of the stack frame 46 for this function. This has been allocated by ffi_call. We also 47 deallocate some of the stack that has been alloca'd. */ 48 49 .align 4 50 .globl ffi_call_osf 51 .ent ffi_call_osf 52 FFI_HIDDEN(ffi_call_osf) 53 54ffi_call_osf: 55 cfi_startproc 56 cfi_def_cfa($17, 32) 57 mov $16, $30 58 stq $26, 0($17) 59 stq $15, 8($17) 60 mov $17, $15 61 .prologue 0 62 cfi_def_cfa_register($15) 63 cfi_rel_offset($26, 0) 64 cfi_rel_offset($15, 8) 65 66 stq $18, 16($17) # save flags into frame 67 stq $19, 24($17) # save rvalue into frame 68 mov $20, $27 # fn into place for call 69 mov $21, $1 # closure into static chain 70 71 # Load up all of the (potential) argument registers. 72 ldq $16, 0($30) 73 ldt $f16, 0($30) 74 ldt $f17, 8($30) 75 ldq $17, 8($30) 76 ldt $f18, 16($30) 77 ldq $18, 16($30) 78 ldt $f19, 24($30) 79 ldq $19, 24($30) 80 ldt $f20, 32($30) 81 ldq $20, 32($30) 82 ldt $f21, 40($30) 83 ldq $21, 40($30) 84 85 # Deallocate the register argument area. 86 lda $30, 48($30) 87 88 jsr $26, ($27), 0 890: 90 ldah $29, 0($26) !gpdisp!1 91 ldq $2, 24($15) # reload rvalue 92 lda $29, 0($29) !gpdisp!1 93 ldq $3, 16($15) # reload flags 94 lda $1, 99f-0b($26) 95 ldq $26, 0($15) 96 ldq $15, 8($15) 97 cfi_restore($26) 98 cfi_restore($15) 99 cfi_def_cfa($sp, 0) 100 cmoveq $2, ALPHA_ST_VOID, $3 # mash null rvalue to void 101 addq $3, $3, $3 102 s8addq $3, $1, $1 # 99f + stcode * 16 103 jmp $31, ($1), $st_int 104 105 .align 4 10699: 107E ALPHA_ST_VOID 108 ret 109E ALPHA_ST_INT 110$st_int: 111 stq $0, 0($2) 112 ret 113E ALPHA_ST_FLOAT 114 sts $f0, 0($2) 115 ret 116E ALPHA_ST_DOUBLE 117 stt $f0, 0($2) 118 ret 119E ALPHA_ST_CPLXF 120 sts $f0, 0($2) 121 sts $f1, 4($2) 122 ret 123E ALPHA_ST_CPLXD 124 stt $f0, 0($2) 125 stt $f1, 8($2) 126 ret 127 128 cfi_endproc 129 .end ffi_call_osf 130 131/* ffi_closure_osf(...) 132 133 Receives the closure argument in $1. */ 134 135#define CLOSURE_FS (16*8) 136 137 .align 4 138 .globl ffi_go_closure_osf 139 .ent ffi_go_closure_osf 140 FFI_HIDDEN(ffi_go_closure_osf) 141 142ffi_go_closure_osf: 143 cfi_startproc 144 ldgp $29, 0($27) 145 subq $30, CLOSURE_FS, $30 146 cfi_adjust_cfa_offset(CLOSURE_FS) 147 stq $26, 0($30) 148 .prologue 1 149 cfi_rel_offset($26, 0) 150 151 stq $16, 10*8($30) 152 stq $17, 11*8($30) 153 stq $18, 12*8($30) 154 155 ldq $16, 8($1) # load cif 156 ldq $17, 16($1) # load fun 157 mov $1, $18 # closure is user_data 158 br $do_closure 159 160 cfi_endproc 161 .end ffi_go_closure_osf 162 163 .align 4 164 .globl ffi_closure_osf 165 .ent ffi_closure_osf 166 FFI_HIDDEN(ffi_closure_osf) 167 168ffi_closure_osf: 169 cfi_startproc 170 ldgp $29, 0($27) 171 subq $30, CLOSURE_FS, $30 172 cfi_adjust_cfa_offset(CLOSURE_FS) 173 stq $26, 0($30) 174 .prologue 1 175 cfi_rel_offset($26, 0) 176 177 # Store all of the potential argument registers in va_list format. 178 stq $16, 10*8($30) 179 stq $17, 11*8($30) 180 stq $18, 12*8($30) 181 182 ldq $16, 24($1) # load cif 183 ldq $17, 32($1) # load fun 184 ldq $18, 40($1) # load user_data 185 186$do_closure: 187 stq $19, 13*8($30) 188 stq $20, 14*8($30) 189 stq $21, 15*8($30) 190 stt $f16, 4*8($30) 191 stt $f17, 5*8($30) 192 stt $f18, 6*8($30) 193 stt $f19, 7*8($30) 194 stt $f20, 8*8($30) 195 stt $f21, 9*8($30) 196 197 # Call ffi_closure_osf_inner to do the bulk of the work. 198 lda $19, 2*8($30) 199 lda $20, 10*8($30) 200 jsr $26, ffi_closure_osf_inner 2010: 202 ldah $29, 0($26) !gpdisp!2 203 lda $2, 99f-0b($26) 204 s4addq $0, 0, $1 # ldcode * 4 205 ldq $0, 16($30) # preload return value 206 s4addq $1, $2, $1 # 99f + ldcode * 16 207 lda $29, 0($29) !gpdisp!2 208 ldq $26, 0($30) 209 cfi_restore($26) 210 jmp $31, ($1), $load_32 211 212.macro epilogue 213 addq $30, CLOSURE_FS, $30 214 cfi_adjust_cfa_offset(-CLOSURE_FS) 215 ret 216 .align 4 217 cfi_adjust_cfa_offset(CLOSURE_FS) 218.endm 219 220 .align 4 22199: 222E ALPHA_LD_VOID 223 epilogue 224 225E ALPHA_LD_INT64 226 epilogue 227 228E ALPHA_LD_INT32 229$load_32: 230 sextl $0, $0 231 epilogue 232 233E ALPHA_LD_UINT16 234 zapnot $0, 3, $0 235 epilogue 236 237E ALPHA_LD_SINT16 238#ifdef __alpha_bwx__ 239 sextw $0, $0 240#else 241 sll $0, 48, $0 242 sra $0, 48, $0 243#endif 244 epilogue 245 246E ALPHA_LD_UINT8 247 and $0, 0xff, $0 248 epilogue 249 250E ALPHA_LD_SINT8 251#ifdef __alpha_bwx__ 252 sextb $0, $0 253#else 254 sll $0, 56, $0 255 sra $0, 56, $0 256#endif 257 epilogue 258 259E ALPHA_LD_FLOAT 260 lds $f0, 16($sp) 261 epilogue 262 263E ALPHA_LD_DOUBLE 264 ldt $f0, 16($sp) 265 epilogue 266 267E ALPHA_LD_CPLXF 268 lds $f0, 16($sp) 269 lds $f1, 20($sp) 270 epilogue 271 272E ALPHA_LD_CPLXD 273 ldt $f0, 16($sp) 274 ldt $f1, 24($sp) 275 epilogue 276 277 cfi_endproc 278 .end ffi_closure_osf 279 280#if defined __ELF__ && defined __linux__ 281 .section .note.GNU-stack,"",@progbits 282#endif 283