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