* lra-constraints.c (process_address_1): Swap base_term and index_term
[official-gcc.git] / libffi / src / sparc / v9.S
blob2c97673e351ae5ddaeb517f54706c754c30f33e5
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    ----------------------------------------------------------------------- */
27 #define LIBFFI_ASM      
28 #include <fficonfig.h>
29 #include <ffi.h>
31 #ifdef SPARC64
33 #define STACKFRAME 176          /* Minimum stack framesize for SPARC 64-bit */
34 #define STACK_BIAS 2047
35 #define ARGS (128)              /* Offset of register area in frame */
37 .text
38         .align 8
39 .globl ffi_call_v9
40 .globl _ffi_call_v9
42 ffi_call_v9:
43 _ffi_call_v9:
44 .LLFB1:
45         save    %sp, -STACKFRAME, %sp
46 .LLCFI0:
47         
48         sub     %sp, %i2, %sp   ! alloca() space in stack for frame to set up
49         add     %sp, STACKFRAME+STACK_BIAS, %l0 ! %l0 has start of 
50                                                 ! frame to set up
52         mov     %l0, %o0        ! call routine to set up frame
53         call    %i0
54          mov    %i1, %o1        ! (delay)
55         brz,pt  %o0, 1f
56          ldx    [%l0+ARGS], %o0 ! call foreign function
58         ldd     [%l0+ARGS], %f0
59         ldd     [%l0+ARGS+8], %f2
60         ldd     [%l0+ARGS+16], %f4
61         ldd     [%l0+ARGS+24], %f6
62         ldd     [%l0+ARGS+32], %f8
63         ldd     [%l0+ARGS+40], %f10
64         ldd     [%l0+ARGS+48], %f12
65         ldd     [%l0+ARGS+56], %f14
66         ldd     [%l0+ARGS+64], %f16
67         ldd     [%l0+ARGS+72], %f18
68         ldd     [%l0+ARGS+80], %f20
69         ldd     [%l0+ARGS+88], %f22
70         ldd     [%l0+ARGS+96], %f24
71         ldd     [%l0+ARGS+104], %f26
72         ldd     [%l0+ARGS+112], %f28
73         ldd     [%l0+ARGS+120], %f30
75 1:      ldx     [%l0+ARGS+8], %o1
76         ldx     [%l0+ARGS+16], %o2
77         ldx     [%l0+ARGS+24], %o3
78         ldx     [%l0+ARGS+32], %o4
79         ldx     [%l0+ARGS+40], %o5
80         call    %i5
81          sub    %l0, STACK_BIAS, %sp    ! (delay) switch to frame
83         ! If the return value pointer is NULL, assume no return value.
84         brz,pn  %i4, done
85          nop
87         cmp     %i3, FFI_TYPE_INT
88         be,a,pt %icc, done
89          stx    %o0, [%i4+0]    ! (delay)
91         cmp     %i3, FFI_TYPE_FLOAT
92         be,a,pn %icc, done
93          st     %f0, [%i4+0]    ! (delay)
95         cmp     %i3, FFI_TYPE_DOUBLE
96         be,a,pn %icc, done
97          std    %f0, [%i4+0]    ! (delay)
99         cmp     %i3, FFI_TYPE_STRUCT
100         be,pn   %icc, dostruct
102         cmp     %i3, FFI_TYPE_LONGDOUBLE
103         bne,pt  %icc, done
104          nop
105         std     %f0, [%i4+0]
106         std     %f2, [%i4+8]
108 done:   ret
109          restore
111 dostruct:
112         /* This will not work correctly for unions. */
113         stx     %o0, [%i4+0]
114         stx     %o1, [%i4+8]
115         stx     %o2, [%i4+16]
116         stx     %o3, [%i4+24]
117         std     %f0, [%i4+32]
118         std     %f2, [%i4+40]
119         std     %f4, [%i4+48]
120         std     %f6, [%i4+56]
121         ret
122          restore
123 .LLFE1:
125 .ffi_call_v9_end:
126         .size   ffi_call_v9,.ffi_call_v9_end-ffi_call_v9
129 #undef STACKFRAME
130 #define STACKFRAME       336    /* 16*8 register window +
131                                    6*8 args backing store +
132                                    20*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-160, %o1
177         add     %fp, STACK_BIAS+128, %o2
178         call    ffi_closure_sparc_inner_v9
179          add    %fp, STACK_BIAS-128, %o3
181         ! Load up the return value in the proper type.
182         ! See ffi_prep_cif_machdep for the list of cases.
183         cmp     %o0, FFI_TYPE_VOID
184         be,pn   %icc, done1
186         cmp     %o0, FFI_TYPE_INT
187         be,pn   %icc, integer
189         cmp     %o0, FFI_TYPE_FLOAT
190         be,a,pn %icc, done1
191          ld     [FP-160], %f0
193         cmp     %o0, FFI_TYPE_DOUBLE
194         be,a,pn %icc, done1
195          ldd    [FP-160], %f0
197 #if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
198         cmp     %o0, FFI_TYPE_LONGDOUBLE
199         be,a,pn %icc, longdouble1
200          ldd    [FP-160], %f0
201 #endif
203         ! FFI_TYPE_STRUCT
204         ldx     [FP-152], %i1
205         ldx     [FP-144], %i2
206         ldx     [FP-136], %i3
207         ldd     [FP-160], %f0
208         ldd     [FP-152], %f2
209         ldd     [FP-144], %f4
210         ldd     [FP-136], %f6
212 integer:
213         ldx     [FP-160], %i0
215 done1:
216         ret
217          restore
219 #if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
220 longdouble1:
221         ldd     [FP-152], %f2
222         ret
223          restore
224 #endif
225 .LLFE2:
227 .ffi_closure_v9_end:
228         .size   ffi_closure_v9,.ffi_closure_v9_end-ffi_closure_v9
230 #ifdef HAVE_RO_EH_FRAME
231         .section        ".eh_frame",#alloc
232 #else
233         .section        ".eh_frame",#alloc,#write
234 #endif
235 .LLframe1:
236         .uaword .LLECIE1-.LLSCIE1       ! Length of Common Information Entry
237 .LLSCIE1:
238         .uaword 0x0     ! CIE Identifier Tag
239         .byte   0x1     ! CIE Version
240         .ascii "zR\0"   ! CIE Augmentation
241         .byte   0x1     ! uleb128 0x1; CIE Code Alignment Factor
242         .byte   0x78    ! sleb128 -8; CIE Data Alignment Factor
243         .byte   0xf     ! CIE RA Column
244         .byte   0x1     ! uleb128 0x1; Augmentation size
245 #ifdef HAVE_AS_SPARC_UA_PCREL
246         .byte   0x1b    ! FDE Encoding (pcrel sdata4)
247 #else
248         .byte   0x50    ! FDE Encoding (aligned absolute)
249 #endif
250         .byte   0xc     ! DW_CFA_def_cfa
251         .byte   0xe     ! uleb128 0xe
252         .byte   0xff,0xf        ! uleb128 0x7ff
253         .align 8
254 .LLECIE1:
255 .LLSFDE1:
256         .uaword .LLEFDE1-.LLASFDE1      ! FDE Length
257 .LLASFDE1:
258         .uaword .LLASFDE1-.LLframe1     ! FDE CIE offset
259 #ifdef HAVE_AS_SPARC_UA_PCREL
260         .uaword %r_disp32(.LLFB1)
261         .uaword .LLFE1-.LLFB1           ! FDE address range
262 #else
263         .align 8
264         .xword  .LLFB1
265         .uaxword        .LLFE1-.LLFB1   ! FDE address range
266 #endif
267         .byte   0x0     ! uleb128 0x0; Augmentation size
268         .byte   0x4     ! DW_CFA_advance_loc4
269         .uaword .LLCFI0-.LLFB1
270         .byte   0xd     ! DW_CFA_def_cfa_register
271         .byte   0x1e    ! uleb128 0x1e
272         .byte   0x2d    ! DW_CFA_GNU_window_save
273         .byte   0x9     ! DW_CFA_register
274         .byte   0xf     ! uleb128 0xf
275         .byte   0x1f    ! uleb128 0x1f
276         .align 8
277 .LLEFDE1:
278 .LLSFDE2:
279         .uaword .LLEFDE2-.LLASFDE2      ! FDE Length
280 .LLASFDE2:
281         .uaword .LLASFDE2-.LLframe1     ! FDE CIE offset
282 #ifdef HAVE_AS_SPARC_UA_PCREL
283         .uaword %r_disp32(.LLFB2)
284         .uaword .LLFE2-.LLFB2           ! FDE address range
285 #else
286         .align 8
287         .xword  .LLFB2
288         .uaxword        .LLFE2-.LLFB2   ! FDE address range
289 #endif
290         .byte   0x0     ! uleb128 0x0; Augmentation size
291         .byte   0x4     ! DW_CFA_advance_loc4
292         .uaword .LLCFI1-.LLFB2
293         .byte   0xd     ! DW_CFA_def_cfa_register
294         .byte   0x1e    ! uleb128 0x1e
295         .byte   0x2d    ! DW_CFA_GNU_window_save
296         .byte   0x9     ! DW_CFA_register
297         .byte   0xf     ! uleb128 0xf
298         .byte   0x1f    ! uleb128 0x1f
299         .align 8
300 .LLEFDE2:
301 #endif
303 #ifdef __linux__
304         .section        .note.GNU-stack,"",@progbits
305 #endif