OSDN Git Service

272278b938b09bbbab55ba1f725a7662f273e732
[pf3gnuchains/gcc-fork.git] / libffi / src / powerpc / darwin_closure.S
1 /* -----------------------------------------------------------------------
2    darwin_closure.S - Copyright (c) 2002, 2003, 2004, Free Software Foundation,
3    Inc. based on ppc_closure.S
4
5    PowerPC Assembly glue.
6
7    Permission is hereby granted, free of charge, to any person obtaining
8    a copy of this software and associated documentation files (the
9    ``Software''), to deal in the Software without restriction, including
10    without limitation the rights to use, copy, modify, merge, publish,
11    distribute, sublicense, and/or sell copies of the Software, and to
12    permit persons to whom the Software is furnished to do so, subject to
13    the following conditions:
14
15    The above copyright notice and this permission notice shall be included
16    in all copies or substantial portions of the Software.
17
18    THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS
19    OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20    MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
21    IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY CLAIM, DAMAGES OR
22    OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
23    ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
24    OTHER DEALINGS IN THE SOFTWARE.
25    ----------------------------------------------------------------------- */
26
27 #define LIBFFI_ASM
28 #define L(x) x
29
30         .file   "darwin_closure.S"
31 .text
32         .align 2
33 .globl _ffi_closure_ASM
34
35 .text
36         .align 2
37 _ffi_closure_ASM:
38 LFB1:
39         mflr    r0              /* extract return address  */
40         stw     r0,8(r1)        /* save the return address  */
41 LCFI0:
42         /* 24 Bytes (Linkage Area)
43            32 Bytes (outgoing parameter area, always reserved)
44            104 Bytes (13*8 from FPR)
45            16 Bytes (result)
46            176 Bytes  */
47
48         stwu    r1,-176(r1)     /* skip over caller save area
49                                 keep stack aligned to 16.  */
50 LCFI1:
51         /* We want to build up an area for the parameters passed
52            in registers. (both floating point and integer)  */
53
54         /* We store gpr 3 to gpr 10 (aligned to 4)
55            in the parents outgoing area.  */
56         stw   r3,200(r1)
57         stw   r4,204(r1)
58         stw   r5,208(r1)
59         stw   r6,212(r1)
60         stw   r7,216(r1)
61         stw   r8,220(r1)
62         stw   r9,224(r1)
63         stw   r10,228(r1)
64
65         /* We save fpr 1 to fpr 13. (aligned to 8)  */
66         stfd  f1,56(r1)
67         stfd  f2,64(r1)
68         stfd  f3,72(r1)
69         stfd  f4,80(r1)
70         stfd  f5,88(r1)
71         stfd  f6,96(r1)
72         stfd  f7,104(r1)
73         stfd  f8,112(r1)
74         stfd  f9,120(r1)
75         stfd  f10,128(r1)
76         stfd  f11,136(r1)
77         stfd  f12,144(r1)
78         stfd  f13,152(r1)
79
80         /* Set up registers for the routine that actually does the work
81            get the context pointer from the trampoline.  */
82         mr r3,r11
83
84         /* Now load up the pointer to the result storage.  */
85         addi r4,r1,160
86
87         /* Now load up the pointer to the saved gpr registers.  */
88         addi r5,r1,200
89
90         /* Now load up the pointer to the saved fpr registers.  */
91         addi r6,r1,56
92
93         /* Make the call.  */
94         bl      Lffi_closure_helper_DARWIN$stub
95
96         /* Now r3 contains the return type
97            so use it to look up in a table
98            so we know how to deal with each type.  */
99
100         /* Look up the proper starting point in table
101            by using return type as offset.  */
102         addi  r5,r1,160           /* Get pointer to results area.  */
103         bl    Lget_ret_type0_addr /* Get pointer to Lret_type0 into LR.  */
104         mflr  r4                  /* Move to r4.  */
105         slwi  r3,r3,4             /* Now multiply return type by 16.  */
106         add   r3,r3,r4            /* Add contents of table to table address.  */
107         mtctr r3
108         bctr                      /* Jump to it.  */
109 LFE1:
110 /* Each of the ret_typeX code fragments has to be exactly 16 bytes long
111    (4 instructions). For cache effectiveness we align to a 16 byte boundary
112    first.  */
113
114         .align 4
115
116         nop
117         nop
118         nop
119 Lget_ret_type0_addr:
120         blrl
121
122 /* case FFI_TYPE_VOID  */
123 Lret_type0:
124         b       Lfinish
125         nop
126         nop
127         nop
128
129 /* case FFI_TYPE_INT  */
130 Lret_type1:
131         lwz     r3,0(r5)
132         b       Lfinish
133         nop
134         nop
135
136 /* case FFI_TYPE_FLOAT  */
137 Lret_type2:
138         lfs     f1,0(r5)
139         b       Lfinish
140         nop
141         nop
142
143 /* case FFI_TYPE_DOUBLE  */
144 Lret_type3:
145         lfd     f1,0(r5)
146         b       Lfinish
147         nop
148         nop
149
150 /* case FFI_TYPE_LONGDOUBLE  */
151 Lret_type4:
152         lfd     f1,0(r5)
153         lfd     f2,8(r5)
154         b       Lfinish
155         nop
156
157 /* case FFI_TYPE_UINT8  */
158 Lret_type5:
159         lbz     r3,3(r5)
160         b       Lfinish
161         nop
162         nop
163
164 /* case FFI_TYPE_SINT8  */
165 Lret_type6:
166         lbz     r3,3(r5)
167         extsb   r3,r3
168         b       Lfinish
169         nop
170
171 /* case FFI_TYPE_UINT16  */
172 Lret_type7:
173         lhz     r3,2(r5)
174         b       Lfinish
175         nop
176         nop
177
178 /* case FFI_TYPE_SINT16  */
179 Lret_type8:
180         lha     r3,2(r5)
181         b       Lfinish
182         nop
183         nop
184
185 /* case FFI_TYPE_UINT32  */
186 Lret_type9:
187         lwz     r3,0(r5)
188         b       Lfinish
189         nop
190         nop
191
192 /* case FFI_TYPE_SINT32  */
193 Lret_type10:
194         lwz     r3,0(r5)
195         b       Lfinish
196         nop
197         nop
198
199 /* case FFI_TYPE_UINT64  */
200 Lret_type11:
201         lwz     r3,0(r5)
202         lwz     r4,4(r5)
203         b       Lfinish
204         nop
205
206 /* case FFI_TYPE_SINT64  */
207 Lret_type12:
208         lwz     r3,0(r5)
209         lwz     r4,4(r5)
210         b       Lfinish
211         nop
212
213 /* case FFI_TYPE_STRUCT  */
214 Lret_type13:
215         b       Lfinish
216         nop
217         nop
218         nop
219
220 /* case FFI_TYPE_POINTER  */
221 Lret_type14:
222         lwz     r3,0(r5)
223         b       Lfinish
224         nop
225         nop
226
227 /* case done  */
228 Lfinish:
229         addi    r1,r1,176       /* Restore stack pointer.  */
230         lwz     r0,8(r1)        /* Get return address.  */
231         mtlr    r0              /* Reset link register.  */
232         blr
233
234 /* END(ffi_closure_ASM)  */
235
236 .data
237 .section __TEXT,__eh_frame,coalesced,no_toc+strip_static_syms
238 EH_frame1:
239         .set    L$set$0,LECIE1-LSCIE1
240         .long   L$set$0 ; Length of Common Information Entry
241 LSCIE1:
242         .long   0x0     ; CIE Identifier Tag
243         .byte   0x1     ; CIE Version
244         .ascii  "zR\0"  ; CIE Augmentation
245         .byte   0x1     ; uleb128 0x1; CIE Code Alignment Factor
246         .byte   0x7c    ; sleb128 -4; CIE Data Alignment Factor
247         .byte   0x41    ; CIE RA Column
248         .byte   0x1     ; uleb128 0x1; Augmentation size
249         .byte   0x90    ; FDE Encoding (indirect pcrel)
250         .byte   0xc     ; DW_CFA_def_cfa
251         .byte   0x1     ; uleb128 0x1
252         .byte   0x0     ; uleb128 0x0
253         .align  2
254 LECIE1:
255 .globl _ffi_closure_ASM.eh
256 _ffi_closure_ASM.eh:
257 LSFDE1:
258         .set    L$set$1,LEFDE1-LASFDE1
259         .long   L$set$1 ; FDE Length
260
261 LASFDE1:
262         .long   LASFDE1-EH_frame1       ; FDE CIE offset
263         .long   LLFB1$non_lazy_ptr-.    ; FDE initial location
264         .set    L$set$3,LFE1-LFB1
265         .long   L$set$3 ; FDE address range
266         .byte   0x0     ; uleb128 0x0; Augmentation size
267         .byte   0x4     ; DW_CFA_advance_loc4
268         .set    L$set$3,LCFI1-LCFI0
269         .long   L$set$3
270         .byte   0xe     ; DW_CFA_def_cfa_offset
271         .byte   176,1   ; uleb128 176
272         .byte   0x4     ; DW_CFA_advance_loc4
273         .set    L$set$4,LCFI0-LFB1
274         .long   L$set$4
275         .byte   0x11    ; DW_CFA_offset_extended_sf
276         .byte   0x41    ; uleb128 0x41
277         .byte   0x7e    ; sleb128 -2
278         .align  2
279 LEFDE1:
280 .data
281         .align  2
282 LDFCM0:
283 .section __TEXT,__picsymbolstub1,symbol_stubs,pure_instructions,32
284         .align  2
285 Lffi_closure_helper_DARWIN$stub:
286         .indirect_symbol _ffi_closure_helper_DARWIN
287         mflr    r0
288         bcl     20,31,LO$ffi_closure_helper_DARWIN
289 LO$ffi_closure_helper_DARWIN:
290         mflr    r11
291         addis   r11,r11,ha16(L_ffi_closure_helper_DARWIN$lazy_ptr - LO$ffi_closure_helper_DARWIN)
292         mtlr    r0
293         lwzu    r12,lo16(L_ffi_closure_helper_DARWIN$lazy_ptr - LO$ffi_closure_helper_DARWIN)(r11)
294         mtctr   r12
295         bctr
296 .data
297 .lazy_symbol_pointer
298 L_ffi_closure_helper_DARWIN$lazy_ptr:
299         .indirect_symbol _ffi_closure_helper_DARWIN
300         .long   dyld_stub_binding_helper
301 .data
302         .align 2
303 LLFB1$non_lazy_ptr:
304         .long LFB1