/js/src/ctypes/libffi/src/sparc/v9.S
http://github.com/zpao/v8monkey · Assembly · 307 lines · 236 code · 38 blank · 33 comment · 5 complexity · cbae30a5242be298ba2710482e8737de MD5 · raw file
- /* -----------------------------------------------------------------------
- v9.S - Copyright (c) 2000, 2003, 2004, 2008 Red Hat, Inc.
-
- SPARC 64-bit Foreign Function Interface
- Permission is hereby granted, free of charge, to any person obtaining
- a copy of this software and associated documentation files (the
- ``Software''), to deal in the Software without restriction, including
- without limitation the rights to use, copy, modify, merge, publish,
- distribute, sublicense, and/or sell copies of the Software, and to
- permit persons to whom the Software is furnished to do so, subject to
- the following conditions:
- The above copyright notice and this permission notice shall be included
- in all copies or substantial portions of the Software.
- THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,
- EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
- HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- DEALINGS IN THE SOFTWARE.
- ----------------------------------------------------------------------- */
- #define LIBFFI_ASM
- #include <fficonfig.h>
- #include <ffi.h>
- #ifdef SPARC64
- /* Only compile this in for 64bit builds, because otherwise the object file
- will have inproper architecture due to used instructions. */
- #define STACKFRAME 128 /* Minimum stack framesize for SPARC */
- #define STACK_BIAS 2047
- #define ARGS (128) /* Offset of register area in frame */
- .text
- .align 8
- .globl ffi_call_v9
- .globl _ffi_call_v9
- ffi_call_v9:
- _ffi_call_v9:
- .LLFB1:
- save %sp, -STACKFRAME, %sp
- .LLCFI0:
-
- sub %sp, %i2, %sp ! alloca() space in stack for frame to set up
- add %sp, STACKFRAME+STACK_BIAS, %l0 ! %l0 has start of
- ! frame to set up
- mov %l0, %o0 ! call routine to set up frame
- call %i0
- mov %i1, %o1 ! (delay)
- brz,pt %o0, 1f
- ldx [%l0+ARGS], %o0 ! call foreign function
- ldd [%l0+ARGS], %f0
- ldd [%l0+ARGS+8], %f2
- ldd [%l0+ARGS+16], %f4
- ldd [%l0+ARGS+24], %f6
- ldd [%l0+ARGS+32], %f8
- ldd [%l0+ARGS+40], %f10
- ldd [%l0+ARGS+48], %f12
- ldd [%l0+ARGS+56], %f14
- ldd [%l0+ARGS+64], %f16
- ldd [%l0+ARGS+72], %f18
- ldd [%l0+ARGS+80], %f20
- ldd [%l0+ARGS+88], %f22
- ldd [%l0+ARGS+96], %f24
- ldd [%l0+ARGS+104], %f26
- ldd [%l0+ARGS+112], %f28
- ldd [%l0+ARGS+120], %f30
- 1: ldx [%l0+ARGS+8], %o1
- ldx [%l0+ARGS+16], %o2
- ldx [%l0+ARGS+24], %o3
- ldx [%l0+ARGS+32], %o4
- ldx [%l0+ARGS+40], %o5
- call %i5
- sub %l0, STACK_BIAS, %sp ! (delay) switch to frame
- ! If the return value pointer is NULL, assume no return value.
- brz,pn %i4, done
- nop
- cmp %i3, FFI_TYPE_INT
- be,a,pt %icc, done
- stx %o0, [%i4+0] ! (delay)
- cmp %i3, FFI_TYPE_FLOAT
- be,a,pn %icc, done
- st %f0, [%i4+0] ! (delay)
- cmp %i3, FFI_TYPE_DOUBLE
- be,a,pn %icc, done
- std %f0, [%i4+0] ! (delay)
- cmp %i3, FFI_TYPE_STRUCT
- be,pn %icc, dostruct
- cmp %i3, FFI_TYPE_LONGDOUBLE
- bne,pt %icc, done
- nop
- std %f0, [%i4+0]
- std %f2, [%i4+8]
- done: ret
- restore
- dostruct:
- /* This will not work correctly for unions. */
- stx %o0, [%i4+0]
- stx %o1, [%i4+8]
- stx %o2, [%i4+16]
- stx %o3, [%i4+24]
- std %f0, [%i4+32]
- std %f2, [%i4+40]
- std %f4, [%i4+48]
- std %f6, [%i4+56]
- ret
- restore
- .LLFE1:
- .ffi_call_v9_end:
- .size ffi_call_v9,.ffi_call_v9_end-ffi_call_v9
- #undef STACKFRAME
- #define STACKFRAME 336 /* 16*8 register window +
- 6*8 args backing store +
- 20*8 locals */
- #define FP %fp+STACK_BIAS
- /* ffi_closure_v9(...)
- Receives the closure argument in %g1. */
- .text
- .align 8
- .globl ffi_closure_v9
- ffi_closure_v9:
- .LLFB2:
- save %sp, -STACKFRAME, %sp
- .LLCFI1:
- ! Store all of the potential argument registers in va_list format.
- stx %i0, [FP+128+0]
- stx %i1, [FP+128+8]
- stx %i2, [FP+128+16]
- stx %i3, [FP+128+24]
- stx %i4, [FP+128+32]
- stx %i5, [FP+128+40]
- ! Store possible floating point argument registers too.
- std %f0, [FP-128]
- std %f2, [FP-120]
- std %f4, [FP-112]
- std %f6, [FP-104]
- std %f8, [FP-96]
- std %f10, [FP-88]
- std %f12, [FP-80]
- std %f14, [FP-72]
- std %f16, [FP-64]
- std %f18, [FP-56]
- std %f20, [FP-48]
- std %f22, [FP-40]
- std %f24, [FP-32]
- std %f26, [FP-24]
- std %f28, [FP-16]
- std %f30, [FP-8]
- ! Call ffi_closure_sparc_inner to do the bulk of the work.
- mov %g1, %o0
- add %fp, STACK_BIAS-160, %o1
- add %fp, STACK_BIAS+128, %o2
- call ffi_closure_sparc_inner_v9
- add %fp, STACK_BIAS-128, %o3
- ! Load up the return value in the proper type.
- ! See ffi_prep_cif_machdep for the list of cases.
- cmp %o0, FFI_TYPE_VOID
- be,pn %icc, done1
- cmp %o0, FFI_TYPE_INT
- be,pn %icc, integer
- cmp %o0, FFI_TYPE_FLOAT
- be,a,pn %icc, done1
- ld [FP-160], %f0
- cmp %o0, FFI_TYPE_DOUBLE
- be,a,pn %icc, done1
- ldd [FP-160], %f0
- #if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
- cmp %o0, FFI_TYPE_LONGDOUBLE
- be,a,pn %icc, longdouble1
- ldd [FP-160], %f0
- #endif
- ! FFI_TYPE_STRUCT
- ldx [FP-152], %i1
- ldx [FP-144], %i2
- ldx [FP-136], %i3
- ldd [FP-160], %f0
- ldd [FP-152], %f2
- ldd [FP-144], %f4
- ldd [FP-136], %f6
- integer:
- ldx [FP-160], %i0
- done1:
- ret
- restore
- #if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
- longdouble1:
- ldd [FP-152], %f2
- ret
- restore
- #endif
- .LLFE2:
- .ffi_closure_v9_end:
- .size ffi_closure_v9,.ffi_closure_v9_end-ffi_closure_v9
- #ifdef HAVE_RO_EH_FRAME
- .section ".eh_frame",#alloc
- #else
- .section ".eh_frame",#alloc,#write
- #endif
- .LLframe1:
- .uaword .LLECIE1-.LLSCIE1 ! Length of Common Information Entry
- .LLSCIE1:
- .uaword 0x0 ! CIE Identifier Tag
- .byte 0x1 ! CIE Version
- .ascii "zR\0" ! CIE Augmentation
- .byte 0x1 ! uleb128 0x1; CIE Code Alignment Factor
- .byte 0x78 ! sleb128 -8; CIE Data Alignment Factor
- .byte 0xf ! CIE RA Column
- .byte 0x1 ! uleb128 0x1; Augmentation size
- #ifdef HAVE_AS_SPARC_UA_PCREL
- .byte 0x1b ! FDE Encoding (pcrel sdata4)
- #else
- .byte 0x50 ! FDE Encoding (aligned absolute)
- #endif
- .byte 0xc ! DW_CFA_def_cfa
- .byte 0xe ! uleb128 0xe
- .byte 0xff,0xf ! uleb128 0x7ff
- .align 8
- .LLECIE1:
- .LLSFDE1:
- .uaword .LLEFDE1-.LLASFDE1 ! FDE Length
- .LLASFDE1:
- .uaword .LLASFDE1-.LLframe1 ! FDE CIE offset
- #ifdef HAVE_AS_SPARC_UA_PCREL
- .uaword %r_disp32(.LLFB1)
- .uaword .LLFE1-.LLFB1 ! FDE address range
- #else
- .align 8
- .xword .LLFB1
- .uaxword .LLFE1-.LLFB1 ! FDE address range
- #endif
- .byte 0x0 ! uleb128 0x0; Augmentation size
- .byte 0x4 ! DW_CFA_advance_loc4
- .uaword .LLCFI0-.LLFB1
- .byte 0xd ! DW_CFA_def_cfa_register
- .byte 0x1e ! uleb128 0x1e
- .byte 0x2d ! DW_CFA_GNU_window_save
- .byte 0x9 ! DW_CFA_register
- .byte 0xf ! uleb128 0xf
- .byte 0x1f ! uleb128 0x1f
- .align 8
- .LLEFDE1:
- .LLSFDE2:
- .uaword .LLEFDE2-.LLASFDE2 ! FDE Length
- .LLASFDE2:
- .uaword .LLASFDE2-.LLframe1 ! FDE CIE offset
- #ifdef HAVE_AS_SPARC_UA_PCREL
- .uaword %r_disp32(.LLFB2)
- .uaword .LLFE2-.LLFB2 ! FDE address range
- #else
- .align 8
- .xword .LLFB2
- .uaxword .LLFE2-.LLFB2 ! FDE address range
- #endif
- .byte 0x0 ! uleb128 0x0; Augmentation size
- .byte 0x4 ! DW_CFA_advance_loc4
- .uaword .LLCFI1-.LLFB2
- .byte 0xd ! DW_CFA_def_cfa_register
- .byte 0x1e ! uleb128 0x1e
- .byte 0x2d ! DW_CFA_GNU_window_save
- .byte 0x9 ! DW_CFA_register
- .byte 0xf ! uleb128 0xf
- .byte 0x1f ! uleb128 0x1f
- .align 8
- .LLEFDE2:
- #endif
- #ifdef __linux__
- .section .note.GNU-stack,"",@progbits
- #endif