OSDN Git Service

2003-07-28 Andreas Tobler <a.tobler@schweiz.ch>
[pf3gnuchains/gcc-fork.git] / libffi / src / sparc / v9.S
1 /* -----------------------------------------------------------------------
2    v9.S - Copyright (c) 2000, 2003 Cygnus Solutions
3    
4    Sparc 64bit 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, 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    ----------------------------------------------------------------------- */
25
26 #define LIBFFI_ASM      
27 #include <ffi.h>
28
29 #ifdef SPARC64
30 /* Only compile this in for 64bit builds, because otherwise the object file
31    will have inproper architecture due to used instructions.  */
32
33 #define STACKFRAME 128          /* Minimum stack framesize for SPARC */
34 #define STACK_BIAS 2047
35 #define ARGS (128)              /* Offset of register area in frame */
36
37 .text
38         .align 8
39 .globl ffi_call_V9
40 .globl _ffi_call_V9
41
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
51
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
57
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
74
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
82
83         ! If the return value pointer is NULL, assume no return value.
84         brz,pn  %i4, done
85          nop
86
87         cmp     %i3, FFI_TYPE_INT
88         be,a,pt %icc, done
89          stx    %o0, [%i4]      ! (delay)
90
91         cmp     %i3, FFI_TYPE_FLOAT
92         be,a,pn %icc, done
93          st     %f0, [%i4+0]    ! (delay)
94
95         cmp     %i3, FFI_TYPE_DOUBLE
96         be,a,pn %icc, done
97          std    %f0, [%i4+0]    ! (delay)
98
99         cmp     %i3, FFI_TYPE_STRUCT
100         be,pn   %icc, dostruct
101
102         cmp     %i3, FFI_TYPE_LONGDOUBLE
103         bne,pt  %icc, done
104          nop
105         std     %f0, [%i4+0]
106         std     %f2, [%i4+8]
107
108 done:   ret
109          restore
110
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:
124
125 .ffi_call_V9_end:
126         .size   ffi_call_V9,.ffi_call_V9_end-ffi_call_V9
127
128
129 #define STACKFRAME       320    /* 16*8 register window +
130                                    6*8 args backing store +
131                                    18*8 locals */
132 #define FP              %fp+STACK_BIAS
133
134 /* ffi_closure_v9(...)
135
136    Receives the closure argument in %g1.   */
137
138         .text
139         .align 8
140         .globl ffi_closure_v9
141
142 ffi_closure_v9:
143 .LLFB2:
144         save    %sp, -STACKFRAME, %sp
145 .LLCFI1:
146
147         ! Store all of the potential argument registers in va_list format.
148         stx     %i0, [FP+128+0]
149         stx     %i1, [FP+128+8]
150         stx     %i2, [FP+128+16]
151         stx     %i3, [FP+128+24]
152         stx     %i4, [FP+128+32]
153         stx     %i5, [FP+128+40]
154
155         ! Store possible floating point argument registers too.
156         std     %f0,  [FP-128]
157         std     %f2,  [FP-120]
158         std     %f4,  [FP-112]
159         std     %f6,  [FP-104]
160         std     %f8,  [FP-96]
161         std     %f10, [FP-88]
162         std     %f12, [FP-80]
163         std     %f14, [FP-72]
164         std     %f16, [FP-64]
165         std     %f18, [FP-56]
166         std     %f20, [FP-48]
167         std     %f22, [FP-40]
168         std     %f24, [FP-32]
169         std     %f26, [FP-24]
170         std     %f28, [FP-16]
171         std     %f30, [FP-8]
172
173         ! Call ffi_closure_sparc_inner to do the bulk of the work.
174         mov     %g1, %o0
175         add     %fp, STACK_BIAS-144, %o1
176         add     %fp, STACK_BIAS+128, %o2
177         call    ffi_closure_sparc_inner
178         add     %fp, STACK_BIAS-128, %o3
179
180         ! Load up the return value in the proper type.
181         cmp     %o0, FFI_TYPE_VOID
182         be,pn   %icc, done1
183
184         cmp     %o0, FFI_TYPE_FLOAT
185         be,a,pn %icc, done1
186          ld     [FP-144], %f0
187
188         cmp     %o0, FFI_TYPE_DOUBLE
189         be,a,pn %icc, done1
190          ldd    [FP-144], %f0
191
192         cmp     %o0, FFI_TYPE_LONGDOUBLE
193         be,a,pn %icc, longdouble1
194          ldd    [FP-144], %f0
195
196         cmp     %o0, FFI_TYPE_STRUCT
197         be,pn   %icc, struct1
198
199         ! FFI_TYPE_UINT64 | FFI_TYPE_SINT64 | FFI_TYPE_POINTER
200         ldx     [FP-144], %i0
201
202 done1:
203         ret
204          restore
205
206 struct1:
207         ldx     [FP-136], %i2
208         ret
209          restore
210
211 longdouble1:
212         ldd     [FP-136], %f2
213         ret
214          restore
215 .LLFE2:
216
217 .ffi_closure_v9_end:
218         .size   ffi_closure_v9,.ffi_closure_v9_end-ffi_closure_v9
219
220 #ifdef HAVE_RO_EH_FRAME
221         .section        ".eh_frame",#alloc
222 #else
223         .section        ".eh_frame",#alloc,#write
224 #endif
225 .LLframe1:
226         .uaword .LLECIE1-.LLSCIE1       ! Length of Common Information Entry
227 .LLSCIE1:
228         .uaword 0x0     ! CIE Identifier Tag
229         .byte   0x1     ! CIE Version
230         .ascii "zR\0"   ! CIE Augmentation
231         .byte   0x1     ! uleb128 0x1; CIE Code Alignment Factor
232         .byte   0x78    ! sleb128 -8; CIE Data Alignment Factor
233         .byte   0xf     ! CIE RA Column
234         .byte   0x1     ! uleb128 0x1; Augmentation size
235 #ifdef HAVE_AS_SPARC_UA_PCREL
236         .byte   0x1b    ! FDE Encoding (pcrel sdata4)
237 #else
238         .byte   0x50    ! FDE Encoding (aligned absolute)
239 #endif
240         .byte   0xc     ! DW_CFA_def_cfa
241         .byte   0xe     ! uleb128 0xe
242         .byte   0xff,0xf        ! uleb128 0x7ff
243         .align 8
244 .LLECIE1:
245 .LLSFDE1:
246         .uaword .LLEFDE1-.LLASFDE1      ! FDE Length
247 .LLASFDE1:
248         .uaword .LLASFDE1-.LLframe1     ! FDE CIE offset
249 #ifdef HAVE_AS_SPARC_UA_PCREL
250         .uaword %r_disp32(.LLFB1)
251         .uaword .LLFE1-.LLFB1           ! FDE address range
252 #else
253         .align 8
254         .xword  .LLFB1
255         .uaxword        .LLFE1-.LLFB1   ! FDE address range
256 #endif
257         .byte   0x0     ! uleb128 0x0; Augmentation size
258         .byte   0x4     ! DW_CFA_advance_loc4
259         .uaword .LLCFI0-.LLFB1
260         .byte   0xd     ! DW_CFA_def_cfa_register
261         .byte   0x1e    ! uleb128 0x1e
262         .byte   0x2d    ! DW_CFA_GNU_window_save
263         .byte   0x9     ! DW_CFA_register
264         .byte   0xf     ! uleb128 0xf
265         .byte   0x1f    ! uleb128 0x1f
266         .align 8
267 .LLEFDE1:
268 .LLSFDE2:
269         .uaword .LLEFDE2-.LLASFDE2      ! FDE Length
270 .LLASFDE2:
271         .uaword .LLASFDE2-.LLframe1     ! FDE CIE offset
272 #ifdef HAVE_AS_SPARC_UA_PCREL
273         .uaword %r_disp32(.LLFB2)
274         .uaword .LLFE2-.LLFB2           ! FDE address range
275 #else
276         .align 8
277         .xword  .LLFB2
278         .uaxword        .LLFE2-.LLFB2   ! FDE address range
279 #endif
280         .byte   0x0     ! uleb128 0x0; Augmentation size
281         .byte   0x4     ! DW_CFA_advance_loc4
282         .uaword .LLCFI1-.LLFB2
283         .byte   0xd     ! DW_CFA_def_cfa_register
284         .byte   0x1e    ! uleb128 0x1e
285         .byte   0x2d    ! DW_CFA_GNU_window_save
286         .byte   0x9     ! DW_CFA_register
287         .byte   0xf     ! uleb128 0xf
288         .byte   0x1f    ! uleb128 0x1f
289         .align 8
290 .LLEFDE2:
291 #endif