2003-12-26 Guilhem Lavaux <guilhem@kaffe.org>
[official-gcc.git] / libffi / src / sparc / v9.S
blob03b487bb54d9d7a8b1a532fd43bd8d03dacaa6b4
1 /* -----------------------------------------------------------------------
2    v9.S - Copyright (c) 2000, 2003 Red Hat, Inc.
3    
4    Sparc 64bit 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]      ! (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 #define STACKFRAME       320    /* 16*8 register window +
131                                    6*8 args backing store +
132                                    18*8 locals */
133 #define FP              %fp+STACK_BIAS
135 /* ffi_closure_v9(...)
137    Receives the closure argument in %g1.   */
139         .text
140         .align 8
141         .globl ffi_closure_v9
143 ffi_closure_v9:
144 .LLFB2:
145         save    %sp, -STACKFRAME, %sp
146 .LLCFI1:
148         ! Store all of the potential argument registers in va_list format.
149         stx     %i0, [FP+128+0]
150         stx     %i1, [FP+128+8]
151         stx     %i2, [FP+128+16]
152         stx     %i3, [FP+128+24]
153         stx     %i4, [FP+128+32]
154         stx     %i5, [FP+128+40]
156         ! Store possible floating point argument registers too.
157         std     %f0,  [FP-128]
158         std     %f2,  [FP-120]
159         std     %f4,  [FP-112]
160         std     %f6,  [FP-104]
161         std     %f8,  [FP-96]
162         std     %f10, [FP-88]
163         std     %f12, [FP-80]
164         std     %f14, [FP-72]
165         std     %f16, [FP-64]
166         std     %f18, [FP-56]
167         std     %f20, [FP-48]
168         std     %f22, [FP-40]
169         std     %f24, [FP-32]
170         std     %f26, [FP-24]
171         std     %f28, [FP-16]
172         std     %f30, [FP-8]
174         ! Call ffi_closure_sparc_inner to do the bulk of the work.
175         mov     %g1, %o0
176         add     %fp, STACK_BIAS-144, %o1
177         add     %fp, STACK_BIAS+128, %o2
178         call    ffi_closure_sparc_inner
179         add     %fp, STACK_BIAS-128, %o3
181         ! Load up the return value in the proper type.
182         cmp     %o0, FFI_TYPE_VOID
183         be,pn   %icc, done1
185         cmp     %o0, FFI_TYPE_FLOAT
186         be,a,pn %icc, done1
187          ld     [FP-144], %f0
189         cmp     %o0, FFI_TYPE_DOUBLE
190         be,a,pn %icc, done1
191          ldd    [FP-144], %f0
193         cmp     %o0, FFI_TYPE_LONGDOUBLE
194         be,a,pn %icc, longdouble1
195          ldd    [FP-144], %f0
197         cmp     %o0, FFI_TYPE_STRUCT
198         be,pn   %icc, struct1
200         ! FFI_TYPE_UINT64 | FFI_TYPE_SINT64 | FFI_TYPE_POINTER
201         ldx     [FP-144], %i0
203 done1:
204         ret
205          restore
207 struct1:
208         ldx     [FP-136], %i2
209         ret
210          restore
212 longdouble1:
213         ldd     [FP-136], %f2
214         ret
215          restore
216 .LLFE2:
218 .ffi_closure_v9_end:
219         .size   ffi_closure_v9,.ffi_closure_v9_end-ffi_closure_v9
221 #ifdef HAVE_RO_EH_FRAME
222         .section        ".eh_frame",#alloc
223 #else
224         .section        ".eh_frame",#alloc,#write
225 #endif
226 .LLframe1:
227         .uaword .LLECIE1-.LLSCIE1       ! Length of Common Information Entry
228 .LLSCIE1:
229         .uaword 0x0     ! CIE Identifier Tag
230         .byte   0x1     ! CIE Version
231         .ascii "zR\0"   ! CIE Augmentation
232         .byte   0x1     ! uleb128 0x1; CIE Code Alignment Factor
233         .byte   0x78    ! sleb128 -8; CIE Data Alignment Factor
234         .byte   0xf     ! CIE RA Column
235         .byte   0x1     ! uleb128 0x1; Augmentation size
236 #ifdef HAVE_AS_SPARC_UA_PCREL
237         .byte   0x1b    ! FDE Encoding (pcrel sdata4)
238 #else
239         .byte   0x50    ! FDE Encoding (aligned absolute)
240 #endif
241         .byte   0xc     ! DW_CFA_def_cfa
242         .byte   0xe     ! uleb128 0xe
243         .byte   0xff,0xf        ! uleb128 0x7ff
244         .align 8
245 .LLECIE1:
246 .LLSFDE1:
247         .uaword .LLEFDE1-.LLASFDE1      ! FDE Length
248 .LLASFDE1:
249         .uaword .LLASFDE1-.LLframe1     ! FDE CIE offset
250 #ifdef HAVE_AS_SPARC_UA_PCREL
251         .uaword %r_disp32(.LLFB1)
252         .uaword .LLFE1-.LLFB1           ! FDE address range
253 #else
254         .align 8
255         .xword  .LLFB1
256         .uaxword        .LLFE1-.LLFB1   ! FDE address range
257 #endif
258         .byte   0x0     ! uleb128 0x0; Augmentation size
259         .byte   0x4     ! DW_CFA_advance_loc4
260         .uaword .LLCFI0-.LLFB1
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 8
268 .LLEFDE1:
269 .LLSFDE2:
270         .uaword .LLEFDE2-.LLASFDE2      ! FDE Length
271 .LLASFDE2:
272         .uaword .LLASFDE2-.LLframe1     ! FDE CIE offset
273 #ifdef HAVE_AS_SPARC_UA_PCREL
274         .uaword %r_disp32(.LLFB2)
275         .uaword .LLFE2-.LLFB2           ! FDE address range
276 #else
277         .align 8
278         .xword  .LLFB2
279         .uaxword        .LLFE2-.LLFB2   ! FDE address range
280 #endif
281         .byte   0x0     ! uleb128 0x0; Augmentation size
282         .byte   0x4     ! DW_CFA_advance_loc4
283         .uaword .LLCFI1-.LLFB2
284         .byte   0xd     ! DW_CFA_def_cfa_register
285         .byte   0x1e    ! uleb128 0x1e
286         .byte   0x2d    ! DW_CFA_GNU_window_save
287         .byte   0x9     ! DW_CFA_register
288         .byte   0xf     ! uleb128 0xf
289         .byte   0x1f    ! uleb128 0x1f
290         .align 8
291 .LLEFDE2:
292 #endif