OSDN Git Service

2008-03-26 Daniel Jacobowitz <dan@debian.org>
[pf3gnuchains/gcc-fork.git] / libffi / src / powerpc / ppc_closure.S
1 #define LIBFFI_ASM
2 #include <fficonfig.h>
3 #include <ffi.h>
4 #include <powerpc/asm.h>
5
6         .file   "ppc_closure.S"
7
8 #ifndef __powerpc64__
9
10 ENTRY(ffi_closure_SYSV)
11 .LFB1:
12         stwu %r1,-144(%r1)
13 .LCFI0:
14         mflr %r0
15 .LCFI1:
16         stw %r0,148(%r1)
17
18 # we want to build up an areas for the parameters passed
19 # in registers (both floating point and integer)
20
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)
30
31 #ifndef __NO_FPRS__
32         # next save fpr 1 to fpr 8 (aligned to 8)
33         stfd  %f1, 48(%r1)
34         stfd  %f2, 56(%r1)
35         stfd  %f3, 64(%r1)
36         stfd  %f4, 72(%r1)
37         stfd  %f5, 80(%r1)
38         stfd  %f6, 88(%r1)
39         stfd  %f7, 96(%r1)
40         stfd  %f8, 104(%r1)
41 #endif
42
43         # set up registers for the routine that actually does the work
44         # get the context pointer from the trampoline
45         mr %r3,%r11
46
47         # now load up the pointer to the result storage
48         addi %r4,%r1,112
49
50         # now load up the pointer to the saved gpr registers
51         addi %r5,%r1,16
52
53         # now load up the pointer to the saved fpr registers */
54         addi %r6,%r1,48
55
56         # now load up the pointer to the outgoing parameter
57         # stack in the previous frame
58         # i.e. the previous frame pointer + 8
59         addi %r7,%r1,152
60
61         # make the call
62         bl ffi_closure_helper_SYSV@local
63 .Lret:
64         # now r3 contains the return type
65         # so use it to look up in a table
66         # so we know how to deal with each type
67
68         # look up the proper starting point in table
69         # by using return type as offset
70
71         mflr %r4                # move address of .Lret to r4
72         slwi %r3,%r3,4          # now multiply return type by 16
73         addi %r4, %r4, .Lret_type0 - .Lret
74         lwz %r0,148(%r1)
75         add %r3,%r3,%r4         # add contents of table to table address
76         mtctr %r3
77         bctr                    # jump to it
78 .LFE1:
79
80 # Each of the ret_typeX code fragments has to be exactly 16 bytes long
81 # (4 instructions). For cache effectiveness we align to a 16 byte boundary
82 # first.
83         .align 4
84 # case FFI_TYPE_VOID
85 .Lret_type0:
86         mtlr %r0
87         addi %r1,%r1,144
88         blr
89         nop
90
91 # case FFI_TYPE_INT
92         lwz %r3,112+0(%r1)
93         mtlr %r0
94 .Lfinish:
95         addi %r1,%r1,144
96         blr
97
98 # case FFI_TYPE_FLOAT
99         lfs %f1,112+0(%r1)
100         mtlr %r0
101         addi %r1,%r1,144
102         blr
103
104 # case FFI_TYPE_DOUBLE
105         lfd %f1,112+0(%r1)
106         mtlr %r0
107         addi %r1,%r1,144
108         blr
109
110 # case FFI_TYPE_LONGDOUBLE
111         lfd %f1,112+0(%r1)
112         lfd %f2,112+8(%r1)
113         mtlr %r0
114         b .Lfinish
115
116 # case FFI_TYPE_UINT8
117         lbz %r3,112+3(%r1)
118         mtlr %r0
119         addi %r1,%r1,144
120         blr
121
122 # case FFI_TYPE_SINT8
123         lbz %r3,112+3(%r1)
124         extsb %r3,%r3
125         mtlr %r0
126         b .Lfinish
127
128 # case FFI_TYPE_UINT16
129         lhz %r3,112+2(%r1)
130         mtlr %r0
131         addi %r1,%r1,144
132         blr
133
134 # case FFI_TYPE_SINT16
135         lha %r3,112+2(%r1)
136         mtlr %r0
137         addi %r1,%r1,144
138         blr
139
140 # case FFI_TYPE_UINT32
141         lwz %r3,112+0(%r1)
142         mtlr %r0
143         addi %r1,%r1,144
144         blr
145
146 # case FFI_TYPE_SINT32
147         lwz %r3,112+0(%r1)
148         mtlr %r0
149         addi %r1,%r1,144
150         blr
151
152 # case FFI_TYPE_UINT64
153         lwz %r3,112+0(%r1)
154         lwz %r4,112+4(%r1)
155         mtlr %r0
156         b .Lfinish
157
158 # case FFI_TYPE_SINT64
159         lwz %r3,112+0(%r1)
160         lwz %r4,112+4(%r1)
161         mtlr %r0
162         b .Lfinish
163
164 # case FFI_TYPE_STRUCT
165         mtlr %r0
166         addi %r1,%r1,144
167         blr
168         nop
169
170 # case FFI_TYPE_POINTER
171         lwz %r3,112+0(%r1)
172         mtlr %r0
173         addi %r1,%r1,144
174         blr
175
176 # case FFI_TYPE_UINT128
177         lwz %r3,112+0(%r1)
178         lwz %r4,112+4(%r1)
179         lwz %r5,112+8(%r1)
180         bl .Luint128
181
182 # The return types below are only used when the ABI type is FFI_SYSV.
183 # case FFI_SYSV_TYPE_SMALL_STRUCT + 1. One byte struct.
184         lbz %r3,112+0(%r1)
185         mtlr %r0
186         addi %r1,%r1,144
187         blr
188
189 # case FFI_SYSV_TYPE_SMALL_STRUCT + 2. Two byte struct.
190         lhz %r3,112+0(%r1)
191         mtlr %r0
192         addi %r1,%r1,144
193         blr
194
195 # case FFI_SYSV_TYPE_SMALL_STRUCT + 3. Three byte struct.
196         lwz %r3,112+0(%r1)
197         srwi %r3,%r3,8
198         mtlr %r0
199         b .Lfinish
200
201 # case FFI_SYSV_TYPE_SMALL_STRUCT + 4. Four byte struct.
202         lwz %r3,112+0(%r1)
203         mtlr %r0
204         addi %r1,%r1,144
205         blr
206
207 # case FFI_SYSV_TYPE_SMALL_STRUCT + 5. Five byte struct.
208         lwz %r3,112+0(%r1)
209         lwz %r4,112+4(%r1)
210         li %r5,24
211         b .Lstruct567
212
213 # case FFI_SYSV_TYPE_SMALL_STRUCT + 6. Six byte struct.
214         lwz %r3,112+0(%r1)
215         lwz %r4,112+4(%r1)
216         li %r5,16
217         b .Lstruct567
218
219 # case FFI_SYSV_TYPE_SMALL_STRUCT + 7. Seven byte struct.
220         lwz %r3,112+0(%r1)
221         lwz %r4,112+4(%r1)
222         li %r5,8
223         b .Lstruct567
224
225 # case FFI_SYSV_TYPE_SMALL_STRUCT + 8. Eight byte struct.
226         lwz %r3,112+0(%r1)
227         lwz %r4,112+4(%r1)
228         mtlr %r0
229         b .Lfinish
230
231 .Lstruct567:
232         subfic %r6,%r5,32
233         srw %r4,%r4,%r5
234         slw %r6,%r3,%r6
235         srw %r3,%r3,%r5
236         or %r4,%r6,%r4
237         mtlr %r0
238         addi %r1,%r1,144
239         blr
240
241 .Luint128:
242         lwz %r6,112+12(%r1)
243         mtlr %r0
244         addi %r1,%r1,144
245         blr
246
247 END(ffi_closure_SYSV)
248
249         .section        ".eh_frame",EH_FRAME_FLAGS,@progbits
250 .Lframe1:
251         .4byte  .LECIE1-.LSCIE1  # Length of Common Information Entry
252 .LSCIE1:
253         .4byte  0x0      # CIE Identifier Tag
254         .byte   0x1      # CIE Version
255 #if defined _RELOCATABLE || defined __PIC__
256         .ascii "zR\0"    # CIE Augmentation
257 #else
258         .ascii "\0"      # CIE Augmentation
259 #endif
260         .uleb128 0x1     # CIE Code Alignment Factor
261         .sleb128 -4      # CIE Data Alignment Factor
262         .byte   0x41     # CIE RA Column
263 #if defined _RELOCATABLE || defined __PIC__
264         .uleb128 0x1     # Augmentation size
265         .byte   0x1b     # FDE Encoding (pcrel sdata4)
266 #endif
267         .byte   0xc      # DW_CFA_def_cfa
268         .uleb128 0x1
269         .uleb128 0x0
270         .align 2
271 .LECIE1:
272 .LSFDE1:
273         .4byte  .LEFDE1-.LASFDE1         # FDE Length
274 .LASFDE1:
275         .4byte  .LASFDE1-.Lframe1        # FDE CIE offset
276 #if defined _RELOCATABLE || defined __PIC__
277         .4byte  .LFB1-.  # FDE initial location
278 #else
279         .4byte  .LFB1    # FDE initial location
280 #endif
281         .4byte  .LFE1-.LFB1      # FDE address range
282 #if defined _RELOCATABLE || defined __PIC__
283         .uleb128 0x0     # Augmentation size
284 #endif
285         .byte   0x4      # DW_CFA_advance_loc4
286         .4byte  .LCFI0-.LFB1
287         .byte   0xe      # DW_CFA_def_cfa_offset
288         .uleb128 144
289         .byte   0x4      # DW_CFA_advance_loc4
290         .4byte  .LCFI1-.LCFI0
291         .byte   0x11     # DW_CFA_offset_extended_sf
292         .uleb128 0x41
293         .sleb128 -1
294         .align 2
295 .LEFDE1:
296
297 #endif
298
299 #if defined __ELF__ && defined __linux__
300         .section        .note.GNU-stack,"",@progbits
301 #endif