Home | History | Annotate | Download | only in sparc
      1 /* -----------------------------------------------------------------------
      2    v8.S - Copyright (c) 1996, 1997, 2003, 2004, 2008 Red Hat, Inc.
      3 
      4    SPARC 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 
     31 #define STACKFRAME 96		/* Minimum stack framesize for SPARC */
     32 #define ARGS (64+4)		/* Offset of register area in frame */
     33 
     34 .text
     35         .align 8
     36 .globl ffi_call_v8
     37 .globl _ffi_call_v8
     38 
     39 ffi_call_v8:
     40 _ffi_call_v8:
     41 .LLFB1:
     42 	save	%sp, -STACKFRAME, %sp
     43 .LLCFI0:
     44 
     45 	sub	%sp, %i2, %sp	! alloca() space in stack for frame to set up
     46 	add	%sp, STACKFRAME, %l0	! %l0 has start of
     47 					! frame to set up
     48 
     49 	mov	%l0, %o0	! call routine to set up frame
     50 	call	%i0
     51 	mov	%i1, %o1	! (delay)
     52 
     53 	ld	[%l0+ARGS], %o0	! call foreign function
     54 	ld	[%l0+ARGS+4], %o1
     55 	ld	[%l0+ARGS+8], %o2
     56 	ld	[%l0+ARGS+12], %o3
     57 	ld	[%l0+ARGS+16], %o4
     58 	ld	[%l0+ARGS+20], %o5
     59 	call	%i5
     60 	mov	%l0, %sp	! (delay) switch to frame
     61 	nop			! STRUCT returning functions skip 12 instead of 8 bytes
     62 
     63 	! If the return value pointer is NULL, assume no return value.
     64 	tst	%i4
     65 	bz	done
     66 	nop
     67 
     68 	cmp	%i3, FFI_TYPE_INT
     69 	be,a	done
     70 	st	%o0, [%i4]	! (delay)
     71 
     72 	cmp	%i3, FFI_TYPE_FLOAT
     73 	be,a	done
     74 	st	%f0, [%i4+0]	! (delay)
     75 
     76 	cmp	%i3, FFI_TYPE_SINT64
     77 	be	longlong
     78 
     79 	cmp	%i3, FFI_TYPE_DOUBLE
     80 	bne	done
     81 	nop
     82 	st	%f0, [%i4+0]
     83 	st	%f1, [%i4+4]
     84 
     85 done:
     86 	ret
     87 	restore
     88 
     89 longlong:
     90 	st	%o0, [%i4+0]
     91 	st	%o1, [%i4+4]
     92 	ret
     93 	restore
     94 .LLFE1:
     95 
     96 .ffi_call_v8_end:
     97 	.size	ffi_call_v8,.ffi_call_v8_end-ffi_call_v8
     98 
     99 
    100 #undef STACKFRAME
    101 #define	STACKFRAME	104	/* 16*4 register window +
    102 				   1*4 struct return +
    103 				   6*4 args backing store +
    104 				   3*4 locals */
    105 
    106 /* ffi_closure_v8(...)
    107 
    108    Receives the closure argument in %g2.   */
    109 
    110 	.text
    111 	.align 8
    112 	.globl ffi_closure_v8
    113 
    114 ffi_closure_v8:
    115 #ifdef HAVE_AS_REGISTER_PSEUDO_OP
    116 		.register	%g2, #scratch
    117 #endif
    118 .LLFB2:
    119 	! Reserve frame space for all arguments in case
    120 	! we need to align them on a 8-byte boundary.
    121 	ld	[%g2+FFI_TRAMPOLINE_SIZE], %g1
    122 	ld	[%g1+4], %g1
    123 	sll	%g1, 3, %g1
    124 	add	%g1, STACKFRAME, %g1
    125 	! %g1 == STACKFRAME + 8*nargs
    126 	neg	%g1
    127 	save	%sp, %g1, %sp
    128 .LLCFI1:
    129 
    130 	! Store all of the potential argument registers in va_list format.
    131 	st	%i0, [%fp+68+0]
    132 	st	%i1, [%fp+68+4]
    133 	st	%i2, [%fp+68+8]
    134 	st	%i3, [%fp+68+12]
    135 	st	%i4, [%fp+68+16]
    136 	st	%i5, [%fp+68+20]
    137 
    138 	! Call ffi_closure_sparc_inner to do the bulk of the work.
    139 	mov	%g2, %o0
    140 	add	%fp, -8, %o1
    141 	add	%fp,  64, %o2
    142 	call	ffi_closure_sparc_inner_v8
    143 	 add	%fp, -16, %o3
    144 
    145 	! Load up the return value in the proper type.
    146 	! See ffi_prep_cif_machdep for the list of cases.
    147 	cmp	%o0, FFI_TYPE_VOID
    148 	be	done1
    149 
    150 	cmp	%o0, FFI_TYPE_INT
    151 	be	integer
    152 
    153 	cmp	%o0, FFI_TYPE_FLOAT
    154 	be,a	done1
    155 	 ld	[%fp-8], %f0
    156 
    157 	cmp	%o0, FFI_TYPE_DOUBLE
    158 	be,a	done1
    159 	 ldd	[%fp-8], %f0
    160 
    161 #if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
    162 	cmp	%o0, FFI_TYPE_LONGDOUBLE
    163 	be	done2
    164 #endif
    165 
    166 	cmp	%o0, FFI_TYPE_STRUCT
    167 	be	done2
    168 
    169 	! FFI_TYPE_SINT64
    170 	! FFI_TYPE_UINT64
    171 	ld	[%fp-4], %i1
    172 
    173 integer:
    174 	ld	[%fp-8], %i0
    175 
    176 done1:
    177 	jmp	%i7+8
    178 	 restore
    179 done2:
    180 	! Skip 'unimp'.
    181 	jmp	%i7+12
    182 	 restore
    183 .LLFE2:
    184 
    185 .ffi_closure_v8_end:
    186 	.size	ffi_closure_v8,.ffi_closure_v8_end-ffi_closure_v8
    187 
    188 #ifdef SPARC64
    189 #define WS 8
    190 #define nword	xword
    191 #define uanword	uaxword
    192 #else
    193 #define WS 4
    194 #define nword	long
    195 #define uanword	uaword
    196 #endif
    197 
    198 #ifdef HAVE_RO_EH_FRAME
    199 	.section	".eh_frame",#alloc
    200 #else
    201 	.section	".eh_frame",#alloc,#write
    202 #endif
    203 .LLframe1:
    204 	.uaword	.LLECIE1-.LLSCIE1	! Length of Common Information Entry
    205 .LLSCIE1:
    206 	.uaword	0x0	! CIE Identifier Tag
    207 	.byte	0x1	! CIE Version
    208 	.ascii "zR\0"	! CIE Augmentation
    209 	.byte	0x1	! uleb128 0x1; CIE Code Alignment Factor
    210 	.byte	0x80-WS	! sleb128 -WS; CIE Data Alignment Factor
    211 	.byte	0xf	! CIE RA Column
    212 	.byte	0x1	! uleb128 0x1; Augmentation size
    213 #ifdef HAVE_AS_SPARC_UA_PCREL
    214 	.byte	0x1b	! FDE Encoding (pcrel sdata4)
    215 #else
    216 	.byte	0x50	! FDE Encoding (aligned absolute)
    217 #endif
    218 	.byte	0xc	! DW_CFA_def_cfa
    219 	.byte	0xe	! uleb128 0xe
    220 	.byte	0x0	! uleb128 0x0
    221 	.align	WS
    222 .LLECIE1:
    223 .LLSFDE1:
    224 	.uaword	.LLEFDE1-.LLASFDE1	! FDE Length
    225 .LLASFDE1:
    226 	.uaword	.LLASFDE1-.LLframe1	! FDE CIE offset
    227 #ifdef HAVE_AS_SPARC_UA_PCREL
    228 	.uaword	%r_disp32(.LLFB1)
    229 	.uaword	.LLFE1-.LLFB1	! FDE address range
    230 #else
    231 	.align	WS
    232 	.nword	.LLFB1
    233 	.uanword .LLFE1-.LLFB1	! FDE address range
    234 #endif
    235 	.byte	0x0	! uleb128 0x0; Augmentation size
    236 	.byte	0x4	! DW_CFA_advance_loc4
    237 	.uaword	.LLCFI0-.LLFB1
    238 	.byte	0xd	! DW_CFA_def_cfa_register
    239 	.byte	0x1e	! uleb128 0x1e
    240 	.byte	0x2d	! DW_CFA_GNU_window_save
    241 	.byte	0x9	! DW_CFA_register
    242 	.byte	0xf	! uleb128 0xf
    243 	.byte	0x1f	! uleb128 0x1f
    244 	.align	WS
    245 .LLEFDE1:
    246 .LLSFDE2:
    247 	.uaword	.LLEFDE2-.LLASFDE2	! FDE Length
    248 .LLASFDE2:
    249 	.uaword	.LLASFDE2-.LLframe1	! FDE CIE offset
    250 #ifdef HAVE_AS_SPARC_UA_PCREL
    251 	.uaword	%r_disp32(.LLFB2)
    252 	.uaword	.LLFE2-.LLFB2	! FDE address range
    253 #else
    254 	.align	WS
    255 	.nword	.LLFB2
    256 	.uanword .LLFE2-.LLFB2	! FDE address range
    257 #endif
    258 	.byte	0x0	! uleb128 0x0; Augmentation size
    259 	.byte	0x4	! DW_CFA_advance_loc4
    260 	.uaword	.LLCFI1-.LLFB2
    261 	.byte	0xd	! DW_CFA_def_cfa_register
    262 	.byte	0x1e	! uleb128 0x1e
    263 	.byte	0x2d	! DW_CFA_GNU_window_save
    264 	.byte	0x9	! DW_CFA_register
    265 	.byte	0xf	! uleb128 0xf
    266 	.byte	0x1f	! uleb128 0x1f
    267 	.align	WS
    268 .LLEFDE2:
    269 
    270 #if defined __ELF__ && defined __linux__
    271 	.section	.note.GNU-stack,"",@progbits
    272 #endif
    273