Remove old autovect-branch by moving to "dead" directory.
[official-gcc.git] / old-autovect-branch / libffi / src / powerpc / ppc_closure.S
blob36f8ac08769eb057e5923a6848330d3478ec28c0
1 #define LIBFFI_ASM
2 #include <fficonfig.h>
3 #include <ffi.h>
4 #include <powerpc/asm.h>
6         .file   "ppc_closure.S"
8 #ifndef __powerpc64__
10 ENTRY(ffi_closure_SYSV)
11 .LFB1:
12         stwu %r1,-144(%r1)
13 .LCFI0:
14         mflr %r0
15 .LCFI1:
16         stw %r0,148(%r1)
18 # we want to build up an areas for the parameters passed
19 # in registers (both floating point and integer)
21         # so first save gpr 3 to gpr 10 (aligned to 4)
22         stw   %r3, 16(%r1)
23         stw   %r4, 20(%r1)
24         stw   %r5, 24(%r1)
25         stw   %r6, 28(%r1)
26         stw   %r7, 32(%r1)
27         stw   %r8, 36(%r1)
28         stw   %r9, 40(%r1)
29         stw   %r10,44(%r1)
31         # next save fpr 1 to fpr 8 (aligned to 8)
32         stfd  %f1, 48(%r1)
33         stfd  %f2, 56(%r1)
34         stfd  %f3, 64(%r1)
35         stfd  %f4, 72(%r1)
36         stfd  %f5, 80(%r1)
37         stfd  %f6, 88(%r1)
38         stfd  %f7, 96(%r1)
39         stfd  %f8, 104(%r1)
41         # set up registers for the routine that actually does the work
42         # get the context pointer from the trampoline
43         mr %r3,%r11
45         # now load up the pointer to the result storage
46         addi %r4,%r1,112
48         # now load up the pointer to the saved gpr registers
49         addi %r5,%r1,16
51         # now load up the pointer to the saved fpr registers */
52         addi %r6,%r1,48
54         # now load up the pointer to the outgoing parameter
55         # stack in the previous frame
56         # i.e. the previous frame pointer + 8
57         addi %r7,%r1,152
59         # make the call
60         bl ffi_closure_helper_SYSV@local
62         # now r3 contains the return type
63         # so use it to look up in a table
64         # so we know how to deal with each type
66         # Extract the size of the return type for small structures.
67         # Then calculate (4 - size) and multiply the result by 8.
68         # This gives the value needed for the shift operation below.
69         # This part is only needed for FFI_SYSV and small structures.
70         addi    %r5,%r3,-(FFI_SYSV_TYPE_SMALL_STRUCT)
71         cmpwi   cr0,%r5,4
72         ble     cr0,.Lnext
73         addi    %r5,%r5,-4
74 .Lnext:
75         addi    %r5,%r5,-4
76         neg     %r5,%r5
77         slwi    %r5,%r5,3
79         # look up the proper starting point in table
80         # by using return type as offset
81         addi %r6,%r1,112   # get pointer to results area
82         bl .Lget_ret_type0_addr # get pointer to .Lret_type0 into LR
83         mflr %r4           # move to r4
84         slwi %r3,%r3,4     # now multiply return type by 16
85         add %r3,%r3,%r4    # add contents of table to table address
86         mtctr %r3
87         bctr               # jump to it
88 .LFE1:
90 # Each of the ret_typeX code fragments has to be exactly 16 bytes long
91 # (4 instructions). For cache effectiveness we align to a 16 byte boundary
92 # first.
93         .align 4
95         nop
96         nop
97         nop
98 .Lget_ret_type0_addr:
99         blrl
101 # case FFI_TYPE_VOID
102 .Lret_type0:
103         b .Lfinish
104         nop
105         nop
106         nop
108 # case FFI_TYPE_INT
109 .Lret_type1:
110         lwz %r3,0(%r6)
111         b .Lfinish
112         nop
113         nop
115 # case FFI_TYPE_FLOAT
116 .Lret_type2:
117         lfs %f1,0(%r6)
118         b .Lfinish
119         nop
120         nop
122 # case FFI_TYPE_DOUBLE
123 .Lret_type3:
124         lfd %f1,0(%r6)
125         b .Lfinish
126         nop
127         nop
129 # case FFI_TYPE_LONGDOUBLE
130 .Lret_type4:
131         lfd %f1,0(%r6)
132         b .Lfinish
133         nop
134         nop
136 # case FFI_TYPE_UINT8
137 .Lret_type5:
138         lbz %r3,3(%r6)
139         b .Lfinish
140         nop
141         nop
143 # case FFI_TYPE_SINT8
144 .Lret_type6:
145         lbz %r3,3(%r6)
146         extsb %r3,%r3
147         b .Lfinish
148         nop
150 # case FFI_TYPE_UINT16
151 .Lret_type7:
152         lhz %r3,2(%r6)
153         b .Lfinish
154         nop
155         nop
157 # case FFI_TYPE_SINT16
158 .Lret_type8:
159         lha %r3,2(%r6)
160         b .Lfinish
161         nop
162         nop
164 # case FFI_TYPE_UINT32
165 .Lret_type9:
166         lwz %r3,0(%r6)
167         b .Lfinish
168         nop
169         nop
171 # case FFI_TYPE_SINT32
172 .Lret_type10:
173         lwz %r3,0(%r6)
174         b .Lfinish
175         nop
176         nop
178 # case FFI_TYPE_UINT64
179 .Lret_type11:
180         lwz %r3,0(%r6)
181         lwz %r4,4(%r6)
182         b .Lfinish
183         nop
185 # case FFI_TYPE_SINT64
186 .Lret_type12:
187         lwz %r3,0(%r6)
188         lwz %r4,4(%r6)
189         b .Lfinish
190         nop
192 # case FFI_TYPE_STRUCT
193 .Lret_type13:
194         b .Lfinish
195         nop
196         nop
197         nop
199 # case FFI_TYPE_POINTER
200 .Lret_type14:
201         lwz %r3,0(%r6)
202         b .Lfinish
203         nop
204         nop
206 # The return types below are only used when the ABI type is FFI_SYSV.
207 # case FFI_SYSV_TYPE_SMALL_STRUCT + 1. One byte struct.
208 .Lret_type15:
209 # fall through.
210         nop
211         nop
212         nop
213         nop
215 # case FFI_SYSV_TYPE_SMALL_STRUCT + 2. Two byte struct.
216 .Lret_type16:
217 # fall through.
218         nop
219         nop
220         nop
221         nop
223 # case FFI_SYSV_TYPE_SMALL_STRUCT + 3. Three byte struct.
224 .Lret_type17:
225 # fall through.
226         nop
227         nop
228         nop
229         nop
231 # case FFI_SYSV_TYPE_SMALL_STRUCT + 4. Four byte struct.
232 .Lret_type18:
233 # this one handles the structs from above too.
234         lwz %r3,0(%r6)
235         srw %r3,%r3,%r5
236         b .Lfinish
237         nop
239 # case FFI_SYSV_TYPE_SMALL_STRUCT + 5. Five byte struct.
240 .Lret_type19:
241 # fall through.
242         nop
243         nop
244         nop
245         nop
247 # case FFI_SYSV_TYPE_SMALL_STRUCT + 6. Six byte struct.
248 .Lret_type20:
249 # fall through.
250         nop
251         nop
252         nop
253         nop
255 # case FFI_SYSV_TYPE_SMALL_STRUCT + 7. Seven byte struct.
256 .Lret_type21:
257 # fall through.
258         nop
259         nop
260         nop
261         nop
263 # case FFI_SYSV_TYPE_SMALL_STRUCT + 8. Eight byte struct.
264 .Lret_type22:
265 # this one handles the above unhandled structs.
266         lwz %r3,0(%r6)
267         lwz %r4,4(%r6)
268         bl __lshrdi3    # libgcc function to shift r3/r4, shift value in r5.
269         b .Lfinish
271 # case done
272 .Lfinish:
274         lwz %r0,148(%r1)
275         mtlr %r0
276         addi %r1,%r1,144
277         blr
278 END(ffi_closure_SYSV)
280         .section        ".eh_frame",EH_FRAME_FLAGS,@progbits
281 .Lframe1:
282         .4byte  .LECIE1-.LSCIE1  # Length of Common Information Entry
283 .LSCIE1:
284         .4byte  0x0      # CIE Identifier Tag
285         .byte   0x1      # CIE Version
286 #if defined _RELOCATABLE || defined __PIC__
287         .ascii "zR\0"    # CIE Augmentation
288 #else
289         .ascii "\0"      # CIE Augmentation
290 #endif
291         .uleb128 0x1     # CIE Code Alignment Factor
292         .sleb128 -4      # CIE Data Alignment Factor
293         .byte   0x41     # CIE RA Column
294 #if defined _RELOCATABLE || defined __PIC__
295         .uleb128 0x1     # Augmentation size
296         .byte   0x1b     # FDE Encoding (pcrel sdata4)
297 #endif
298         .byte   0xc      # DW_CFA_def_cfa
299         .uleb128 0x1
300         .uleb128 0x0
301         .align 2
302 .LECIE1:
303 .LSFDE1:
304         .4byte  .LEFDE1-.LASFDE1         # FDE Length
305 .LASFDE1:
306         .4byte  .LASFDE1-.Lframe1        # FDE CIE offset
307 #if defined _RELOCATABLE || defined __PIC__
308         .4byte  .LFB1-.  # FDE initial location
309 #else
310         .4byte  .LFB1    # FDE initial location
311 #endif
312         .4byte  .LFE1-.LFB1      # FDE address range
313 #if defined _RELOCATABLE || defined __PIC__
314         .uleb128 0x0     # Augmentation size
315 #endif
316         .byte   0x4      # DW_CFA_advance_loc4
317         .4byte  .LCFI0-.LFB1
318         .byte   0xe      # DW_CFA_def_cfa_offset
319         .uleb128 144
320         .byte   0x4      # DW_CFA_advance_loc4
321         .4byte  .LCFI1-.LCFI0
322         .byte   0x11     # DW_CFA_offset_extended_sf
323         .uleb128 0x41
324         .sleb128 -1
325         .align 2
326 .LEFDE1:
328 #endif