This commit was manufactured by cvs2svn to create branch
[official-gcc.git] / libffi / src / sparc / v9.S
blobd640e0232d5cd1e9b63bee966a756f56c9900f85
1 /* -----------------------------------------------------------------------
2    v9.S - Copyright (c) 2000, 2003, 2004 Red Hat, Inc.
3    
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, EXPRESS
18    OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
19    MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
20    IN NO EVENT SHALL CYGNUS SOLUTIONS BE LIABLE FOR ANY CLAIM, DAMAGES OR
21    OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
22    ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
23    OTHER DEALINGS IN THE SOFTWARE.
24    ----------------------------------------------------------------------- */
26 #define LIBFFI_ASM      
27 #include <fficonfig.h>
28 #include <ffi.h>
30 #ifdef SPARC64
31 /* Only compile this in for 64bit builds, because otherwise the object file
32    will have inproper architecture due to used instructions.  */
34 #define STACKFRAME 128          /* Minimum stack framesize for SPARC */
35 #define STACK_BIAS 2047
36 #define ARGS (128)              /* Offset of register area in frame */
38 .text
39         .align 8
40 .globl ffi_call_v9
41 .globl _ffi_call_v9
43 ffi_call_v9:
44 _ffi_call_v9:
45 .LLFB1:
46         save    %sp, -STACKFRAME, %sp
47 .LLCFI0:
48         
49         sub     %sp, %i2, %sp   ! alloca() space in stack for frame to set up
50         add     %sp, STACKFRAME+STACK_BIAS, %l0 ! %l0 has start of 
51                                                 ! frame to set up
53         mov     %l0, %o0        ! call routine to set up frame
54         call    %i0
55          mov    %i1, %o1        ! (delay)
56         brz,pt  %o0, 1f
57          ldx    [%l0+ARGS], %o0 ! call foreign function
59         ldd     [%l0+ARGS], %f0
60         ldd     [%l0+ARGS+8], %f2
61         ldd     [%l0+ARGS+16], %f4
62         ldd     [%l0+ARGS+24], %f6
63         ldd     [%l0+ARGS+32], %f8
64         ldd     [%l0+ARGS+40], %f10
65         ldd     [%l0+ARGS+48], %f12
66         ldd     [%l0+ARGS+56], %f14
67         ldd     [%l0+ARGS+64], %f16
68         ldd     [%l0+ARGS+72], %f18
69         ldd     [%l0+ARGS+80], %f20
70         ldd     [%l0+ARGS+88], %f22
71         ldd     [%l0+ARGS+96], %f24
72         ldd     [%l0+ARGS+104], %f26
73         ldd     [%l0+ARGS+112], %f28
74         ldd     [%l0+ARGS+120], %f30
76 1:      ldx     [%l0+ARGS+8], %o1
77         ldx     [%l0+ARGS+16], %o2
78         ldx     [%l0+ARGS+24], %o3
79         ldx     [%l0+ARGS+32], %o4
80         ldx     [%l0+ARGS+40], %o5
81         call    %i5
82          sub    %l0, STACK_BIAS, %sp    ! (delay) switch to frame
84         ! If the return value pointer is NULL, assume no return value.
85         brz,pn  %i4, done
86          nop
88         cmp     %i3, FFI_TYPE_INT
89         be,a,pt %icc, done
90          stx    %o0, [%i4+0]    ! (delay)
92         cmp     %i3, FFI_TYPE_FLOAT
93         be,a,pn %icc, done
94          st     %f0, [%i4+0]    ! (delay)
96         cmp     %i3, FFI_TYPE_DOUBLE
97         be,a,pn %icc, done
98          std    %f0, [%i4+0]    ! (delay)
100         cmp     %i3, FFI_TYPE_STRUCT
101         be,pn   %icc, dostruct
103         cmp     %i3, FFI_TYPE_LONGDOUBLE
104         bne,pt  %icc, done
105          nop
106         std     %f0, [%i4+0]
107         std     %f2, [%i4+8]
109 done:   ret
110          restore
112 dostruct:
113         /* This will not work correctly for unions. */
114         stx     %o0, [%i4+0]
115         stx     %o1, [%i4+8]
116         stx     %o2, [%i4+16]
117         stx     %o3, [%i4+24]
118         std     %f0, [%i4+32]
119         std     %f2, [%i4+40]
120         std     %f4, [%i4+48]
121         std     %f6, [%i4+56]
122         ret
123          restore
124 .LLFE1:
126 .ffi_call_v9_end:
127         .size   ffi_call_v9,.ffi_call_v9_end-ffi_call_v9
130 #undef STACKFRAME
131 #define STACKFRAME       336    /* 16*8 register window +
132                                    6*8 args backing store +
133                                    20*8 locals */
134 #define FP              %fp+STACK_BIAS
136 /* ffi_closure_v9(...)
138    Receives the closure argument in %g1.   */
140         .text
141         .align 8
142         .globl ffi_closure_v9
144 ffi_closure_v9:
145 .LLFB2:
146         save    %sp, -STACKFRAME, %sp
147 .LLCFI1:
149         ! Store all of the potential argument registers in va_list format.
150         stx     %i0, [FP+128+0]
151         stx     %i1, [FP+128+8]
152         stx     %i2, [FP+128+16]
153         stx     %i3, [FP+128+24]
154         stx     %i4, [FP+128+32]
155         stx     %i5, [FP+128+40]
157         ! Store possible floating point argument registers too.
158         std     %f0,  [FP-128]
159         std     %f2,  [FP-120]
160         std     %f4,  [FP-112]
161         std     %f6,  [FP-104]
162         std     %f8,  [FP-96]
163         std     %f10, [FP-88]
164         std     %f12, [FP-80]
165         std     %f14, [FP-72]
166         std     %f16, [FP-64]
167         std     %f18, [FP-56]
168         std     %f20, [FP-48]
169         std     %f22, [FP-40]
170         std     %f24, [FP-32]
171         std     %f26, [FP-24]
172         std     %f28, [FP-16]
173         std     %f30, [FP-8]
175         ! Call ffi_closure_sparc_inner to do the bulk of the work.
176         mov     %g1, %o0
177         add     %fp, STACK_BIAS-160, %o1
178         add     %fp, STACK_BIAS+128, %o2
179         call    ffi_closure_sparc_inner_v9
180          add    %fp, STACK_BIAS-128, %o3
182         ! Load up the return value in the proper type.
183         ! See ffi_prep_cif_machdep for the list of cases.
184         cmp     %o0, FFI_TYPE_VOID
185         be,pn   %icc, done1
187         cmp     %o0, FFI_TYPE_INT
188         be,pn   %icc, integer
190         cmp     %o0, FFI_TYPE_FLOAT
191         be,a,pn %icc, done1
192          ld     [FP-160], %f0
194         cmp     %o0, FFI_TYPE_DOUBLE
195         be,a,pn %icc, done1
196          ldd    [FP-160], %f0
198 #if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
199         cmp     %o0, FFI_TYPE_LONGDOUBLE
200         be,a,pn %icc, longdouble1
201          ldd    [FP-160], %f0
202 #endif
204         ! FFI_TYPE_STRUCT
205         ldx     [FP-152], %i1
206         ldx     [FP-144], %i2
207         ldx     [FP-136], %i3
208         ldd     [FP-160], %f0
209         ldd     [FP-152], %f2
210         ldd     [FP-144], %f4
211         ldd     [FP-136], %f6
213 integer:
214         ldx     [FP-160], %i0
216 done1:
217         ret
218          restore
220 #if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
221 longdouble1:
222         ldd     [FP-152], %f2
223         ret
224          restore
225 #endif
226 .LLFE2:
228 .ffi_closure_v9_end:
229         .size   ffi_closure_v9,.ffi_closure_v9_end-ffi_closure_v9
231 #ifdef HAVE_RO_EH_FRAME
232         .section        ".eh_frame",#alloc
233 #else
234         .section        ".eh_frame",#alloc,#write
235 #endif
236 .LLframe1:
237         .uaword .LLECIE1-.LLSCIE1       ! Length of Common Information Entry
238 .LLSCIE1:
239         .uaword 0x0     ! CIE Identifier Tag
240         .byte   0x1     ! CIE Version
241         .ascii "zR\0"   ! CIE Augmentation
242         .byte   0x1     ! uleb128 0x1; CIE Code Alignment Factor
243         .byte   0x78    ! sleb128 -8; CIE Data Alignment Factor
244         .byte   0xf     ! CIE RA Column
245         .byte   0x1     ! uleb128 0x1; Augmentation size
246 #ifdef HAVE_AS_SPARC_UA_PCREL
247         .byte   0x1b    ! FDE Encoding (pcrel sdata4)
248 #else
249         .byte   0x50    ! FDE Encoding (aligned absolute)
250 #endif
251         .byte   0xc     ! DW_CFA_def_cfa
252         .byte   0xe     ! uleb128 0xe
253         .byte   0xff,0xf        ! uleb128 0x7ff
254         .align 8
255 .LLECIE1:
256 .LLSFDE1:
257         .uaword .LLEFDE1-.LLASFDE1      ! FDE Length
258 .LLASFDE1:
259         .uaword .LLASFDE1-.LLframe1     ! FDE CIE offset
260 #ifdef HAVE_AS_SPARC_UA_PCREL
261         .uaword %r_disp32(.LLFB1)
262         .uaword .LLFE1-.LLFB1           ! FDE address range
263 #else
264         .align 8
265         .xword  .LLFB1
266         .uaxword        .LLFE1-.LLFB1   ! FDE address range
267 #endif
268         .byte   0x0     ! uleb128 0x0; Augmentation size
269         .byte   0x4     ! DW_CFA_advance_loc4
270         .uaword .LLCFI0-.LLFB1
271         .byte   0xd     ! DW_CFA_def_cfa_register
272         .byte   0x1e    ! uleb128 0x1e
273         .byte   0x2d    ! DW_CFA_GNU_window_save
274         .byte   0x9     ! DW_CFA_register
275         .byte   0xf     ! uleb128 0xf
276         .byte   0x1f    ! uleb128 0x1f
277         .align 8
278 .LLEFDE1:
279 .LLSFDE2:
280         .uaword .LLEFDE2-.LLASFDE2      ! FDE Length
281 .LLASFDE2:
282         .uaword .LLASFDE2-.LLframe1     ! FDE CIE offset
283 #ifdef HAVE_AS_SPARC_UA_PCREL
284         .uaword %r_disp32(.LLFB2)
285         .uaword .LLFE2-.LLFB2           ! FDE address range
286 #else
287         .align 8
288         .xword  .LLFB2
289         .uaxword        .LLFE2-.LLFB2   ! FDE address range
290 #endif
291         .byte   0x0     ! uleb128 0x0; Augmentation size
292         .byte   0x4     ! DW_CFA_advance_loc4
293         .uaword .LLCFI1-.LLFB2
294         .byte   0xd     ! DW_CFA_def_cfa_register
295         .byte   0x1e    ! uleb128 0x1e
296         .byte   0x2d    ! DW_CFA_GNU_window_save
297         .byte   0x9     ! DW_CFA_register
298         .byte   0xf     ! uleb128 0xf
299         .byte   0x1f    ! uleb128 0x1f
300         .align 8
301 .LLEFDE2:
302 #endif