OSDN Git Service

e1a60b468328d34ccd0519e4f26c04ab5fd329de
[pf3gnuchains/gcc-fork.git] / libffi / src / powerpc / aix_closure.S
1 /* -----------------------------------------------------------------------
2    aix_closure.S - Copyright (c) 2002, 2003, 2009 Free Software Foundation, Inc.
3    based on darwin_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         .set r0,0
28         .set r1,1
29         .set r2,2
30         .set r3,3
31         .set r4,4
32         .set r5,5
33         .set r6,6
34         .set r7,7
35         .set r8,8
36         .set r9,9
37         .set r10,10
38         .set r11,11
39         .set r12,12
40         .set r13,13
41         .set r14,14
42         .set r15,15
43         .set r16,16
44         .set r17,17
45         .set r18,18
46         .set r19,19
47         .set r20,20
48         .set r21,21
49         .set r22,22
50         .set r23,23
51         .set r24,24
52         .set r25,25
53         .set r26,26
54         .set r27,27
55         .set r28,28
56         .set r29,29
57         .set r30,30
58         .set r31,31
59         .set f0,0
60         .set f1,1
61         .set f2,2
62         .set f3,3
63         .set f4,4
64         .set f5,5
65         .set f6,6
66         .set f7,7
67         .set f8,8
68         .set f9,9
69         .set f10,10
70         .set f11,11
71         .set f12,12
72         .set f13,13
73         .set f14,14
74         .set f15,15
75         .set f16,16
76         .set f17,17
77         .set f18,18
78         .set f19,19
79         .set f20,20
80         .set f21,21
81
82 #define LIBFFI_ASM
83 #define JUMPTARGET(name) name
84 #define L(x) x
85         .file "aix_closure.S"
86         .toc
87 LC..60:
88         .tc L..60[TC],L..60
89         .csect .text[PR]
90         .align 2
91
92 .csect .text[PR]
93         .align 2
94         .globl ffi_closure_ASM
95         .globl .ffi_closure_ASM
96 .csect ffi_closure_ASM[DS]
97 ffi_closure_ASM:
98 #ifdef __64BIT__
99         .llong .ffi_closure_ASM, TOC[tc0], 0
100         .csect .text[PR]
101 .ffi_closure_ASM:
102
103         mflr r0                 /* extract return address */
104         std r0,16(r1)           /* save the return address */
105
106         /* 48  Bytes (Linkage Area) */
107         /* 64  Bytes (params) */
108         /* 104 Bytes (13*8 from FPR) */
109         /* 32  Bytes (result) */
110         /* 248 Bytes */
111
112         stdu r1,-248(r1)        /* skip over caller save area
113                                    keep stack aligned to 16  */
114
115 /* we want to build up an area for the parameters passed */
116 /* in registers (both floating point and integer) */
117
118         /* we store gpr 3 to gpr 10 (aligned to 4)
119         in the parents outgoing area  */
120         std   r3, (304+0*8)(r1)
121         std   r4, (304+1*8)(r1)
122         std   r5, (304+2*8)(r1)
123         std   r6, (304+3*8)(r1)
124         std   r7, (304+4*8)(r1)
125         std   r8, (304+5*8)(r1)
126         std   r9, (304+6*8)(r1)
127         std   r10, (304+7*8)(r1)
128
129         /* next save fpr 1 to fpr 13 (aligned to 8) */
130         stfd  f1, (112+0*8)(r1)
131         stfd  f2, (112+1*8)(r1)
132         stfd  f3, (112+2*8)(r1)
133         stfd  f4, (112+3*8)(r1)
134         stfd  f5, (112+4*8)(r1)
135         stfd  f6, (112+5*8)(r1)
136         stfd  f7, (112+6*8)(r1)
137         stfd  f8, (112+7*8)(r1)
138         stfd  f9, (112+8*8)(r1)
139         stfd  f10, (112+9*8)(r1)
140         stfd  f11, (112+10*8)(r1)
141         stfd  f12, (112+11*8)(r1)
142         stfd  f13, (112+12*8)(r1)
143
144         /* set up registers for the routine that actually does the work */
145         /* get the context pointer from the trampoline */
146         mr r3,r11
147
148         /* now load up the pointer to the result storage */
149         addi r4,r1,216
150
151         /* now load up the pointer to the saved gpr registers */
152         addi r5,r1,304
153
154         /* now load up the pointer to the saved fpr registers */
155         addi r6,r1,112
156
157         /* make the call */
158         bl .ffi_closure_helper_DARWIN
159         nop
160
161         /* now r3 contains the return type */
162         /* so use it to look up in a table */
163         /* so we know how to deal with each type */
164
165         /* look up the proper starting point in table  */
166         /* by using return type as offset */
167         addi r5,r1,216          /* get pointer to results area */
168         ld r4,LC..60(2)         /* get address of jump table */
169         sldi r3,r3,2            /* now multiply return type by 4 */
170         lwzx r3,r4,r3           /* get the contents of that table value */
171         add r3,r3,r4            /* add contents of table to table address */
172         mtctr r3
173         bctr                    /* jump to it */
174
175 L..60:
176         .long L..44-L..60    /* FFI_TYPE_VOID */
177         .long L..51-L..60    /* FFI_TYPE_INT */
178         .long L..47-L..60    /* FFI_TYPE_FLOAT */
179         .long L..46-L..60    /* FFI_TYPE_DOUBLE */
180         .long L..45-L..60    /* FFI_TYPE_LONGDOUBLE */
181         .long L..56-L..60    /* FFI_TYPE_UINT8 */
182         .long L..55-L..60    /* FFI_TYPE_SINT8 */
183         .long L..58-L..60    /* FFI_TYPE_UINT16 */
184         .long L..57-L..60    /* FFI_TYPE_SINT16 */
185         .long L..50-L..60    /* FFI_TYPE_UINT32 */
186         .long L..51-L..60    /* FFI_TYPE_SINT32 */
187         .long L..48-L..60    /* FFI_TYPE_UINT64 */
188         .long L..48-L..60    /* FFI_TYPE_SINT64 */
189         .long L..44-L..60    /* FFI_TYPE_STRUCT */
190         .long L..48-L..60    /* FFI_TYPE_POINTER */
191
192
193 /* case long double */
194 L..45:
195         lfd f1,0(r5)
196         lfd f2,8(r5)
197         b L..44
198
199 /* case double */
200 L..46:
201         lfd f1,0(r5)
202         b L..44
203
204 /* case float */
205 L..47:
206         lfs f1,0(r5)
207         b L..44
208
209 /* case long long / pointer */
210 L..48:
211         ld r3,0(r5)
212         b L..44
213
214 /* case uint32 */
215 L..50:
216         lwz r3,4(r5)
217         b L..44
218
219 /* case int / sint32 */
220 L..51:
221         lwa r3,4(r5)
222         b L..44
223
224 /* case signed int8 */
225 L..55:
226         lbz r3,7(r5)
227         extsb r3,r3
228         b L..44
229
230 /* case unsigned int8 */
231 L..56:
232         lbz r3,7(r5)
233         b L..44
234
235 /* case signed int16 */
236 L..57:
237         lha r3,6(r5)
238         b L..44
239
240 /* case unsigned int16 */
241 L..58:
242         lhz r3,6(r5)
243
244 /* case void / done      */
245 L..44:
246         addi r1,r1,248          /* restore stack pointer */
247         ld r0,16(r1)            /* get return address */
248         mtlr r0                 /* reset link register */
249         blr
250
251 #else /* ! __64BIT__ */
252         
253         .long .ffi_closure_ASM, TOC[tc0], 0
254         .csect .text[PR]
255 .ffi_closure_ASM:
256
257         mflr r0                 /* extract return address */
258         stw r0, 8(r1)           /* save the return address */
259
260         /* 24 Bytes (Linkage Area) */
261         /* 32 Bytes (params) */
262         /* 104 Bytes (13*8 from FPR) */
263         /* 16  Bytes (result) */
264         /* 176 Bytes */
265
266         stwu r1,-176(r1)        /* skip over caller save area
267                                 keep stack aligned to 16  */
268
269 /* we want to build up an area for the parameters passed */
270 /* in registers (both floating point and integer) */
271
272         /* we store gpr 3 to gpr 10 (aligned to 4)
273         in the parents outgoing area  */
274         stw   r3, 200(r1)
275         stw   r4, 204(r1)
276         stw   r5, 208(r1)
277         stw   r6, 212(r1)
278         stw   r7, 216(r1)
279         stw   r8, 220(r1)
280         stw   r9, 224(r1)
281         stw   r10, 228(r1)
282
283         /* next save fpr 1 to fpr 13 (aligned to 8) */
284         stfd  f1, 56(r1)
285         stfd  f2, 64(r1)
286         stfd  f3, 72(r1)
287         stfd  f4, 80(r1)
288         stfd  f5, 88(r1)
289         stfd  f6, 96(r1)
290         stfd  f7, 104(r1)
291         stfd  f8, 112(r1)
292         stfd  f9, 120(r1)
293         stfd  f10, 128(r1)
294         stfd  f11, 136(r1)
295         stfd  f12, 144(r1)
296         stfd  f13, 152(r1)
297
298         /* set up registers for the routine that actually does the work */
299         /* get the context pointer from the trampoline */
300         mr r3,r11
301
302         /* now load up the pointer to the result storage */
303         addi r4,r1,160
304
305         /* now load up the pointer to the saved gpr registers */
306         addi r5,r1,200
307
308         /* now load up the pointer to the saved fpr registers */
309         addi r6,r1,56
310
311         /* make the call */
312         bl .ffi_closure_helper_DARWIN
313         nop
314
315         /* now r3 contains the return type */
316         /* so use it to look up in a table */
317         /* so we know how to deal with each type */
318
319         /* look up the proper starting point in table  */
320         /* by using return type as offset */
321         addi r5,r1,160          /* get pointer to results area */
322         lwz r4,LC..60(2)        /* get address of jump table */
323         slwi r3,r3,2            /* now multiply return type by 4 */
324         lwzx r3,r4,r3           /* get the contents of that table value */
325         add r3,r3,r4            /* add contents of table to table address */
326         mtctr r3
327         bctr                    /* jump to it */
328
329 L..60:
330         .long L..44-L..60    /* FFI_TYPE_VOID */
331         .long L..50-L..60    /* FFI_TYPE_INT */
332         .long L..47-L..60    /* FFI_TYPE_FLOAT */
333         .long L..46-L..60    /* FFI_TYPE_DOUBLE */
334         .long L..45-L..60    /* FFI_TYPE_LONGDOUBLE */
335         .long L..56-L..60    /* FFI_TYPE_UINT8 */
336         .long L..55-L..60    /* FFI_TYPE_SINT8 */
337         .long L..58-L..60    /* FFI_TYPE_UINT16 */
338         .long L..57-L..60    /* FFI_TYPE_SINT16 */
339         .long L..50-L..60    /* FFI_TYPE_UINT32 */
340         .long L..50-L..60    /* FFI_TYPE_SINT32 */
341         .long L..48-L..60    /* FFI_TYPE_UINT64 */
342         .long L..48-L..60    /* FFI_TYPE_SINT64 */
343         .long L..44-L..60    /* FFI_TYPE_STRUCT */
344         .long L..50-L..60    /* FFI_TYPE_POINTER */
345
346
347 /* case long double */
348 L..45:
349         lfd f1,0(r5)
350         lfd f2,8(r5)
351         b L..44
352
353 /* case double */
354 L..46:
355         lfd f1,0(r5)
356         b L..44
357
358 /* case float */
359 L..47:
360         lfs f1,0(r5)
361         b L..44
362
363 /* case long long */
364 L..48:
365         lwz r3,0(r5)
366         lwz r4,4(r5)
367         b L..44
368
369 /* case default / int32 / pointer */
370 L..50:
371         lwz r3,0(r5)
372         b L..44
373
374 /* case signed int8 */
375 L..55:
376         lbz r3,3(r5)
377         extsb r3,r3
378         b L..44
379
380 /* case unsigned int8 */
381 L..56:
382         lbz r3,3(r5)
383         b L..44
384
385 /* case signed int16 */
386 L..57:
387         lha r3,2(r5)
388         b L..44
389
390 /* case unsigned int16 */
391 L..58:
392         lhz r3,2(r5)
393
394 /* case void / done      */
395 L..44:
396         addi r1,r1,176          /* restore stack pointer */
397         lwz r0,8(r1)            /* get return address */
398         mtlr r0                 /* reset link register */
399         blr
400 #endif
401 /* END(ffi_closure_ASM) */