1 /* -----------------------------------------------------------------------
2 v9.S - Copyright (c) 2000, 2003, 2004, 2008 Red Hat, Inc.
4 SPARC 64-bit Foreign Function Interface
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:
14 The above copyright notice and this permission notice shall be included
15 in all copies or substantial portions of the Software.
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 ----------------------------------------------------------------------- */
28 #include <fficonfig.h>
34 #define C2(X, Y) X ## Y
35 #define C1(X, Y) C2(X, Y)
37 #ifdef __USER_LABEL_PREFIX__
38 # define C(Y) C1(__USER_LABEL_PREFIX__, Y)
42 #define L(Y) C1(.L, Y)
44 #if defined(__sun__) && defined(__svr4__)
45 # define E(INDEX) .align 16
47 # define E(INDEX) .align 16; .org 2b + INDEX * 16
50 #define STACK_BIAS 2047
55 .type C(ffi_call_v9),#function
56 FFI_HIDDEN(C(ffi_call_v9))
62 mov %i0, %o0 ! copy cif
63 add %sp, STACK_BIAS+128+48, %o1 ! load args area
64 mov %i2, %o2 ! copy rvalue
65 call C(ffi_prep_args_v9)
66 mov %i3, %o3 ! copy avalue
68 andcc %o0, SPARC_FLAG_FP_ARGS, %g0 ! need fp regs?
69 add %sp, 48, %sp ! deallocate prep frame
71 mov %o0, %l0 ! save flags
73 ldd [%sp+STACK_BIAS+128], %f0 ! load all fp arg regs
74 ldd [%sp+STACK_BIAS+128+8], %f2
75 ldd [%sp+STACK_BIAS+128+16], %f4
76 ldd [%sp+STACK_BIAS+128+24], %f6
77 ldd [%sp+STACK_BIAS+128+32], %f8
78 ldd [%sp+STACK_BIAS+128+40], %f10
79 ldd [%sp+STACK_BIAS+128+48], %f12
80 ldd [%sp+STACK_BIAS+128+56], %f14
81 ldd [%sp+STACK_BIAS+128+64], %f16
82 ldd [%sp+STACK_BIAS+128+72], %f18
83 ldd [%sp+STACK_BIAS+128+80], %f20
84 ldd [%sp+STACK_BIAS+128+88], %f22
85 ldd [%sp+STACK_BIAS+128+96], %f24
86 ldd [%sp+STACK_BIAS+128+104], %f26
87 ldd [%sp+STACK_BIAS+128+112], %f28
88 ldd [%sp+STACK_BIAS+128+120], %f30
90 1: ldx [%sp+STACK_BIAS+128], %o0 ! load all int arg regs
91 ldx [%sp+STACK_BIAS+128+8], %o1
92 ldx [%sp+STACK_BIAS+128+16], %o2
93 ldx [%sp+STACK_BIAS+128+24], %o3
94 ldx [%sp+STACK_BIAS+128+32], %o4
95 ldx [%sp+STACK_BIAS+128+40], %o5
97 mov %i5, %g5 ! load static chain
99 0: call 1f ! load pc in %o7
100 and %l0, SPARC_FLAG_RET_MASK, %l1
102 add %o7, %l1, %o7 ! o7 = 0b + ret_type*16
112 add %sp, STACK_BIAS-64+128+48, %l2
178 ! Finish the SPARC_RET_STRUCT sequence.
188 ! Copy the structure into place.
189 srl %l0, SPARC_SIZEMASK_SHIFT, %o0 ! load size_mask
190 mov %i2, %o1 ! load dst
191 mov %l2, %o2 ! load src_gp
192 call C(ffi_struct_float_copy)
193 add %l2, 32, %o3 ! load src_fp
199 .size C(ffi_call_v9), . - C(ffi_call_v9)
203 #define STACKFRAME 336 /* 16*8 register window +
204 6*8 args backing store +
206 #define FP %fp+STACK_BIAS
208 /* ffi_closure_v9(...)
210 Receives the closure argument in %g1. */
213 .globl C(ffi_go_closure_v9)
214 .type C(ffi_go_closure_v9),#function
215 FFI_HIDDEN(C(ffi_go_closure_v9))
217 C(ffi_go_closure_v9):
219 save %sp, -STACKFRAME, %sp
227 .size C(ffi_go_closure_v9), . - C(ffi_go_closure_v9)
230 .globl C(ffi_closure_v9)
231 .type C(ffi_closure_v9),#function
232 FFI_HIDDEN(C(ffi_closure_v9))
236 save %sp, -STACKFRAME, %sp
238 ldx [%g1+FFI_TRAMPOLINE_SIZE], %o0
239 ldx [%g1+FFI_TRAMPOLINE_SIZE+8], %o1
240 ldx [%g1+FFI_TRAMPOLINE_SIZE+16], %o2
242 ! Store all of the potential argument registers in va_list format.
250 ! Store possible floating point argument registers too.
268 ! Call ffi_closure_sparc_inner to do the bulk of the work.
269 add %fp, STACK_BIAS-160, %o3
270 add %fp, STACK_BIAS+128, %o4
271 call C(ffi_closure_sparc_inner_v9)
272 add %fp, STACK_BIAS-128, %o5
274 0: call 1f ! load pc in %o7
275 and %o0, SPARC_FLAG_RET_MASK, %o0
276 1: sll %o0, 4, %o0 ! o2 = i2 * 16
277 add %o7, %o0, %o7 ! o7 = 0b + i2*16
281 ! Note that we cannot load the data in the delay slot of
282 ! the return insn because the data is in the stack frame
283 ! that is deallocated by the return.
356 ! Finish the SPARC_RET_STRUCT sequence.
367 .size C(ffi_closure_v9), . - C(ffi_closure_v9)
369 #ifdef HAVE_RO_EH_FRAME
370 .section ".eh_frame",#alloc
372 .section ".eh_frame",#alloc,#write
375 #ifdef HAVE_AS_SPARC_UA_PCREL
376 # define FDE_RANGE(B, E) .long %r_disp32(B), E - B
378 # define FDE_RANGE(B, E) .align 8; .xword B, E - B
383 .long .LECIE - .LSCIE ! CIE Length
385 .long 0 ! CIE Identifier Tag
386 .byte 1 ! CIE Version
387 .ascii "zR\0" ! CIE Augmentation
388 .byte 4 ! CIE Code Alignment Factor
389 .byte 0x78 ! CIE Data Alignment Factor
390 .byte 15 ! CIE RA Column
391 .byte 1 ! Augmentation size
392 #ifdef HAVE_AS_SPARC_UA_PCREL
393 .byte 0x1b ! FDE Encoding (pcrel sdata4)
395 .byte 0x50 ! FDE Encoding (aligned absolute)
397 .byte 0xc, 14, 0xff, 0xf ! DW_CFA_def_cfa, %o6, offset 0x7ff
401 .long .LEFDE1 - .LSFDE1 ! FDE Length
403 .long .LSFDE1 - .LCIE ! FDE CIE offset
404 FDE_RANGE(.LUW0, .LUW2)
405 .byte 0 ! Augmentation size
406 .byte 0x40+1 ! DW_CFA_advance_loc 4
407 .byte 0xd, 30 ! DW_CFA_def_cfa_register, %i6
408 .byte 0x2d ! DW_CFA_GNU_window_save
409 .byte 0x9, 15, 31 ! DW_CFA_register, %o7, %i7
413 .long .LEFDE2 - .LSFDE2 ! FDE Length
415 .long .LSFDE2 - .LCIE ! FDE CIE offset
416 FDE_RANGE(.LUW3, .LUW5)
417 .byte 0 ! Augmentation size
418 .byte 0x40+1 ! DW_CFA_advance_loc 4
419 .byte 0xd, 30 ! DW_CFA_def_cfa_register, %i6
420 .byte 0x2d ! DW_CFA_GNU_window_save
421 .byte 0x9, 15, 31 ! DW_CFA_register, %o7, %i7
425 .long .LEFDE3 - .LSFDE3 ! FDE Length
427 .long .LSFDE3 - .LCIE ! FDE CIE offset
428 FDE_RANGE(.LUW6, .LUW8)
429 .byte 0 ! Augmentation size
430 .byte 0x40+1 ! DW_CFA_advance_loc 4
431 .byte 0xd, 30 ! DW_CFA_def_cfa_register, %i6
432 .byte 0x2d ! DW_CFA_GNU_window_save
433 .byte 0x9, 15, 31 ! DW_CFA_register, %o7, %i7
439 .section .note.GNU-stack,"",@progbits