github.com/prattmic/llgo-embedded@v0.0.0-20150820070356-41cfecea0e1e/third_party/gofrontend/libffi/src/sparc/v9.S (about) 1 /* ----------------------------------------------------------------------- 2 v9.S - Copyright (c) 2000, 2003, 2004, 2008 Red Hat, Inc. 3 4 SPARC 64-bit 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 #ifdef SPARC64 34 35 #define C2(X, Y) X ## Y 36 #define C1(X, Y) C2(X, Y) 37 38 #ifdef __USER_LABEL_PREFIX__ 39 # define C(Y) C1(__USER_LABEL_PREFIX__, Y) 40 #else 41 # define C(Y) Y 42 #endif 43 #define L(Y) C1(.L, Y) 44 45 .macro E index 46 .align 16 47 .org 2b + \index * 16 48 .endm 49 50 #define STACK_BIAS 2047 51 52 .text 53 .align 8 54 .globl C(ffi_call_v9) 55 .type C(ffi_call_v9),@function 56 FFI_HIDDEN(C(ffi_call_v9)) 57 58 C(ffi_call_v9): 59 cfi_startproc 60 save %sp, %o4, %sp 61 cfi_def_cfa_register(%fp) 62 cfi_window_save 63 64 mov %i0, %o0 ! copy cif 65 add %sp, STACK_BIAS+128+48, %o1 ! load args area 66 mov %i2, %o2 ! copy rvalue 67 call C(ffi_prep_args_v9) 68 mov %i3, %o3 ! copy avalue 69 70 andcc %o0, SPARC_FLAG_FP_ARGS, %g0 ! need fp regs? 71 add %sp, 48, %sp ! deallocate prep frame 72 be,pt %xcc, 1f 73 mov %o0, %l0 ! save flags 74 75 ldd [%sp+STACK_BIAS+128], %f0 ! load all fp arg regs 76 ldd [%sp+STACK_BIAS+128+8], %f2 77 ldd [%sp+STACK_BIAS+128+16], %f4 78 ldd [%sp+STACK_BIAS+128+24], %f6 79 ldd [%sp+STACK_BIAS+128+32], %f8 80 ldd [%sp+STACK_BIAS+128+40], %f10 81 ldd [%sp+STACK_BIAS+128+48], %f12 82 ldd [%sp+STACK_BIAS+128+56], %f14 83 ldd [%sp+STACK_BIAS+128+64], %f16 84 ldd [%sp+STACK_BIAS+128+72], %f18 85 ldd [%sp+STACK_BIAS+128+80], %f20 86 ldd [%sp+STACK_BIAS+128+88], %f22 87 ldd [%sp+STACK_BIAS+128+96], %f24 88 ldd [%sp+STACK_BIAS+128+104], %f26 89 ldd [%sp+STACK_BIAS+128+112], %f28 90 ldd [%sp+STACK_BIAS+128+120], %f30 91 92 1: ldx [%sp+STACK_BIAS+128], %o0 ! load all int arg regs 93 ldx [%sp+STACK_BIAS+128+8], %o1 94 ldx [%sp+STACK_BIAS+128+16], %o2 95 ldx [%sp+STACK_BIAS+128+24], %o3 96 ldx [%sp+STACK_BIAS+128+32], %o4 97 ldx [%sp+STACK_BIAS+128+40], %o5 98 call %i1 99 mov %i5, %g5 ! load static chain 100 101 0: call 1f ! load pc in %o7 102 and %l0, SPARC_FLAG_RET_MASK, %l1 103 1: sll %l1, 4, %l1 104 add %o7, %l1, %o7 ! o7 = 0b + ret_type*16 105 jmp %o7+(2f-0b) 106 nop 107 108 .align 16 109 2: 110 E SPARC_RET_VOID 111 return %i7+8 112 nop 113 E SPARC_RET_STRUCT 114 add %sp, STACK_BIAS-64+128+48, %l2 115 sub %sp, 64, %sp 116 b 8f 117 stx %o0, [%l2] 118 E SPARC_RET_UINT8 119 and %o0, 0xff, %i0 120 return %i7+8 121 stx %o0, [%o2] 122 E SPARC_RET_SINT8 123 sll %o0, 24, %o0 124 sra %o0, 24, %i0 125 return %i7+8 126 stx %o0, [%o2] 127 E SPARC_RET_UINT16 128 sll %o0, 16, %o0 129 srl %o0, 16, %i0 130 return %i7+8 131 stx %o0, [%o2] 132 E SPARC_RET_SINT16 133 sll %o0, 16, %o0 134 sra %o0, 16, %i0 135 return %i7+8 136 stx %o0, [%o2] 137 E SPARC_RET_UINT32 138 srl %o0, 0, %i0 139 return %i7+8 140 stx %o0, [%o2] 141 E SP_V9_RET_SINT32 142 sra %o0, 0, %i0 143 return %i7+8 144 stx %o0, [%o2] 145 E SPARC_RET_INT64 146 stx %o0, [%i2] 147 return %i7+8 148 nop 149 E SPARC_RET_INT128 150 stx %o0, [%i2] 151 stx %o1, [%i2+8] 152 return %i7+8 153 nop 154 E SPARC_RET_F_8 155 st %f7, [%i2+7*4] 156 nop 157 st %f6, [%i2+6*4] 158 nop 159 E SPARC_RET_F_6 160 st %f5, [%i2+5*4] 161 nop 162 st %f4, [%i2+4*4] 163 nop 164 E SPARC_RET_F_4 165 std %f2, [%i2+2*4] 166 return %i7+8 167 std %f0, [%o2] 168 E SPARC_RET_F_2 169 return %i7+8 170 std %f0, [%o2] 171 E SP_V9_RET_F_3 172 st %f2, [%i2+2*4] 173 nop 174 st %f1, [%i2+1*4] 175 nop 176 E SPARC_RET_F_1 177 return %i7+8 178 st %f0, [%o2] 179 180 ! Finish the SPARC_RET_STRUCT sequence. 181 .align 8 182 8: stx %o1, [%l2+8] 183 stx %o2, [%l2+16] 184 stx %o3, [%l2+24] 185 std %f0, [%l2+32] 186 std %f2, [%l2+40] 187 std %f4, [%l2+48] 188 std %f6, [%l2+56] 189 190 ! Copy the structure into place. 191 srl %l0, SPARC_SIZEMASK_SHIFT, %o0 ! load size_mask 192 mov %i2, %o1 ! load dst 193 mov %l2, %o2 ! load src_gp 194 call C(ffi_struct_float_copy) 195 add %l2, 32, %o3 ! load src_fp 196 197 return %i7+8 198 nop 199 200 cfi_endproc 201 .size C(ffi_call_v9), . - C(ffi_call_v9) 202 203 204 #undef STACKFRAME 205 #define STACKFRAME 336 /* 16*8 register window + 206 6*8 args backing store + 207 20*8 locals */ 208 #define FP %fp+STACK_BIAS 209 210 /* ffi_closure_v9(...) 211 212 Receives the closure argument in %g1. */ 213 214 .align 8 215 .globl C(ffi_go_closure_v9) 216 .type C(ffi_go_closure_v9),@function 217 FFI_HIDDEN(C(ffi_go_closure_v9)) 218 219 C(ffi_go_closure_v9): 220 cfi_startproc 221 save %sp, -STACKFRAME, %sp 222 cfi_def_cfa_register(%fp) 223 cfi_window_save 224 225 ldx [%g5+8], %o0 226 ldx [%g5+16], %o1 227 b 0f 228 mov %g5, %o2 229 230 cfi_endproc 231 .size C(ffi_go_closure_v9), . - C(ffi_go_closure_v9) 232 233 .align 8 234 .globl C(ffi_closure_v9) 235 .type C(ffi_closure_v9),@function 236 FFI_HIDDEN(C(ffi_closure_v9)) 237 238 C(ffi_closure_v9): 239 cfi_startproc 240 save %sp, -STACKFRAME, %sp 241 cfi_def_cfa_register(%fp) 242 cfi_window_save 243 244 ldx [%g1+FFI_TRAMPOLINE_SIZE], %o0 245 ldx [%g1+FFI_TRAMPOLINE_SIZE+8], %o1 246 ldx [%g1+FFI_TRAMPOLINE_SIZE+16], %o2 247 0: 248 ! Store all of the potential argument registers in va_list format. 249 stx %i0, [FP+128+0] 250 stx %i1, [FP+128+8] 251 stx %i2, [FP+128+16] 252 stx %i3, [FP+128+24] 253 stx %i4, [FP+128+32] 254 stx %i5, [FP+128+40] 255 256 ! Store possible floating point argument registers too. 257 std %f0, [FP-128] 258 std %f2, [FP-120] 259 std %f4, [FP-112] 260 std %f6, [FP-104] 261 std %f8, [FP-96] 262 std %f10, [FP-88] 263 std %f12, [FP-80] 264 std %f14, [FP-72] 265 std %f16, [FP-64] 266 std %f18, [FP-56] 267 std %f20, [FP-48] 268 std %f22, [FP-40] 269 std %f24, [FP-32] 270 std %f26, [FP-24] 271 std %f28, [FP-16] 272 std %f30, [FP-8] 273 274 ! Call ffi_closure_sparc_inner to do the bulk of the work. 275 add %fp, STACK_BIAS-160, %o3 276 add %fp, STACK_BIAS+128, %o4 277 call C(ffi_closure_sparc_inner_v9) 278 add %fp, STACK_BIAS-128, %o5 279 280 0: call 1f ! load pc in %o7 281 and %o0, SPARC_FLAG_RET_MASK, %o0 282 1: sll %o0, 4, %o0 ! o2 = i2 * 16 283 add %o7, %o0, %o7 ! o7 = 0b + i2*16 284 jmp %o7+(2f-0b) 285 nop 286 287 ! Note that we cannot load the data in the delay slot of 288 ! the return insn because the data is in the stack frame 289 ! that is deallocated by the return. 290 .align 16 291 2: 292 E SPARC_RET_VOID 293 return %i7+8 294 nop 295 E SPARC_RET_STRUCT 296 ldx [FP-160], %i0 297 ldd [FP-160], %f0 298 b 8f 299 ldx [FP-152], %i1 300 E SPARC_RET_UINT8 301 ldub [FP-160+7], %i0 302 return %i7+8 303 nop 304 E SPARC_RET_SINT8 305 ldsb [FP-160+7], %i0 306 return %i7+8 307 nop 308 E SPARC_RET_UINT16 309 lduh [FP-160+6], %i0 310 return %i7+8 311 nop 312 E SPARC_RET_SINT16 313 ldsh [FP-160+6], %i0 314 return %i7+8 315 nop 316 E SPARC_RET_UINT32 317 lduw [FP-160+4], %i0 318 return %i7+8 319 nop 320 E SP_V9_RET_SINT32 321 ldsw [FP-160+4], %i0 322 return %i7+8 323 nop 324 E SPARC_RET_INT64 325 ldx [FP-160], %i0 326 return %i7+8 327 nop 328 E SPARC_RET_INT128 329 ldx [FP-160], %i0 330 ldx [FP-160+8], %i1 331 return %i7+8 332 nop 333 E SPARC_RET_F_8 334 ld [FP-160+7*4], %f7 335 nop 336 ld [FP-160+6*4], %f6 337 nop 338 E SPARC_RET_F_6 339 ld [FP-160+5*4], %f5 340 nop 341 ld [FP-160+4*4], %f4 342 nop 343 E SPARC_RET_F_4 344 ldd [FP-160], %f0 345 ldd [FP-160+8], %f2 346 return %i7+8 347 nop 348 E SPARC_RET_F_2 349 ldd [FP-160], %f0 350 return %i7+8 351 nop 352 E SP_V9_RET_F_3 353 ld [FP-160+2*4], %f2 354 nop 355 ld [FP-160+1*4], %f1 356 nop 357 E SPARC_RET_F_1 358 ld [FP-160], %f0 359 return %i7+8 360 nop 361 362 ! Finish the SPARC_RET_STRUCT sequence. 363 .align 8 364 8: ldd [FP-152], %f2 365 ldx [FP-144], %i2 366 ldd [FP-144], %f4 367 ldx [FP-136], %i3 368 ldd [FP-136], %f6 369 return %i7+8 370 nop 371 372 cfi_endproc 373 .size C(ffi_closure_v9), . - C(ffi_closure_v9) 374 #endif /* SPARC64 */ 375 #ifdef __linux__ 376 .section .note.GNU-stack,"",@progbits 377 #endif