runtime: copy mstats code from Go 1.7 runtime
[official-gcc.git] / libffi / src / powerpc / aix_closure.S
blobaabd3c3c1eedf9749bc19c68d741b87084ca1f48
1 /* -----------------------------------------------------------------------
2    aix_closure.S - Copyright (c) 2002, 2003, 2009 Free Software Foundation, Inc.
3    based on darwin_closure.S
5    PowerPC Assembly glue.
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:
15    The above copyright notice and this permission notice shall be included
16    in all copies or substantial portions of the Software.
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    ----------------------------------------------------------------------- */
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
82         .extern .ffi_closure_helper_DARWIN
84 #define LIBFFI_ASM
85 #define JUMPTARGET(name) name
86 #define L(x) x
87         .file "aix_closure.S"
88         .toc
89 LC..60:
90         .tc L..60[TC],L..60
91         .csect .text[PR]
92         .align 2
94 .csect .text[PR]
95         .align 2
96         .globl ffi_closure_ASM
97         .globl .ffi_closure_ASM
98 .csect ffi_closure_ASM[DS]
99 ffi_closure_ASM:
100 #ifdef __64BIT__
101         .llong .ffi_closure_ASM, TOC[tc0], 0
102         .csect .text[PR]
103 .ffi_closure_ASM:
104 /* we want to build up an area for the parameters passed */
105 /* in registers (both floating point and integer) */
107         /* we store gpr 3 to gpr 10 (aligned to 4)
108         in the parents outgoing area  */
109         std   r3, 48+(0*8)(r1)
110         std   r4, 48+(1*8)(r1)
111         std   r5, 48+(2*8)(r1)
112         std   r6, 48+(3*8)(r1)
113         mflr  r0
115         std   r7, 48+(4*8)(r1)
116         std   r8, 48+(5*8)(r1)
117         std   r9, 48+(6*8)(r1)
118         std   r10, 48+(7*8)(r1)
119         std   r0, 16(r1)        /* save the return address */
122         /* 48  Bytes (Linkage Area) */
123         /* 64  Bytes (params) */
124         /* 16  Bytes (result) */
125         /* 104 Bytes (13*8 from FPR) */
126         /* 8   Bytes (alignment) */
127         /* 240 Bytes */
129         stdu  r1, -240(r1)      /* skip over caller save area
130                                    keep stack aligned to 16  */
132         /* next save fpr 1 to fpr 13 (aligned to 8) */
133         stfd  f1, 128+(0*8)(r1)
134         stfd  f2, 128+(1*8)(r1)
135         stfd  f3, 128+(2*8)(r1)
136         stfd  f4, 128+(3*8)(r1)
137         stfd  f5, 128+(4*8)(r1)
138         stfd  f6, 128+(5*8)(r1)
139         stfd  f7, 128+(6*8)(r1)
140         stfd  f8, 128+(7*8)(r1)
141         stfd  f9, 128+(8*8)(r1)
142         stfd  f10, 128+(9*8)(r1)
143         stfd  f11, 128+(10*8)(r1)
144         stfd  f12, 128+(11*8)(r1)
145         stfd  f13, 128+(12*8)(r1)
147         /* set up registers for the routine that actually does the work */
148         /* get the context pointer from the trampoline */
149         mr r3, r11
151         /* now load up the pointer to the result storage */
152         addi r4, r1, 112
154         /* now load up the pointer to the saved gpr registers */
155         addi r5, r1, 288
157         /* now load up the pointer to the saved fpr registers */
158         addi r6, r1, 128
160         /* make the call */
161         bl .ffi_closure_helper_DARWIN
162         nop
164         /* now r3 contains the return type */
165         /* so use it to look up in a table */
166         /* so we know how to deal with each type */
168         /* look up the proper starting point in table  */
169         /* by using return type as offset */
170         lhz     r3, 10(r3)      /* load type from return type */
171         ld      r4, LC..60(2)   /* get address of jump table */
172         sldi    r3, r3, 4       /* now multiply return type by 16 */
173         ld      r0, 240+16(r1)  /* load return address */
174         add     r3, r3, r4      /* add contents of table to table address */
175         mtctr   r3
176         bctr                    /* jump to it */
178 /* Each fragment must be exactly 16 bytes long (4 instructions).
179    Align to 16 byte boundary for cache and dispatch efficiency.  */
180         .align 4
182 L..60:
183 /* case FFI_TYPE_VOID */
184         mtlr r0
185         addi r1, r1, 240
186         blr
187         nop
189 /* case FFI_TYPE_INT */
190         lwa r3, 112+4(r1)
191         mtlr r0
192         addi r1, r1, 240
193         blr
195 /* case FFI_TYPE_FLOAT */
196         lfs f1, 112+0(r1)
197         mtlr r0
198         addi r1, r1, 240
199         blr
201 /* case FFI_TYPE_DOUBLE */
202         lfd f1, 112+0(r1)
203         mtlr r0
204         addi r1, r1, 240
205         blr
207 /* case FFI_TYPE_LONGDOUBLE */
208         lfd f1, 112+0(r1)
209         mtlr r0
210         lfd f2, 112+8(r1)
211         b L..finish
213 /* case FFI_TYPE_UINT8 */
214         lbz r3, 112+7(r1)
215         mtlr r0
216         addi r1, r1, 240
217         blr
219 /* case FFI_TYPE_SINT8 */
220         lbz r3, 112+7(r1)
221         mtlr r0
222         extsb r3, r3
223         b L..finish
225 /* case FFI_TYPE_UINT16 */
226         lhz r3, 112+6(r1)
227         mtlr r0
228 L..finish:
229         addi r1, r1, 240
230         blr
232 /* case FFI_TYPE_SINT16 */
233         lha r3, 112+6(r1)
234         mtlr r0
235         addi r1, r1, 240
236         blr
238 /* case FFI_TYPE_UINT32 */
239         lwz r3, 112+4(r1)
240         mtlr r0
241         addi r1, r1, 240
242         blr
244 /* case FFI_TYPE_SINT32 */
245         lwa r3, 112+4(r1)
246         mtlr r0
247         addi r1, r1, 240
248         blr
250 /* case FFI_TYPE_UINT64 */
251         ld r3, 112+0(r1)
252         mtlr r0
253         addi r1, r1, 240
254         blr
256 /* case FFI_TYPE_SINT64 */
257         ld r3, 112+0(r1)
258         mtlr r0
259         addi r1, r1, 240
260         blr
262 /* case FFI_TYPE_STRUCT */
263         mtlr r0
264         addi r1, r1, 240
265         blr
266         nop
268 /* case FFI_TYPE_POINTER */
269         ld r3, 112+0(r1)
270         mtlr r0
271         addi r1, r1, 240
272         blr
274 #else /* ! __64BIT__ */
275         
276         .long .ffi_closure_ASM, TOC[tc0], 0
277         .csect .text[PR]
278 .ffi_closure_ASM:
279 /* we want to build up an area for the parameters passed */
280 /* in registers (both floating point and integer) */
282         /* we store gpr 3 to gpr 10 (aligned to 4)
283         in the parents outgoing area  */
284         stw   r3, 24+(0*4)(r1)
285         stw   r4, 24+(1*4)(r1)
286         stw   r5, 24+(2*4)(r1)
287         stw   r6, 24+(3*4)(r1)
288         mflr  r0
290         stw   r7, 24+(4*4)(r1)
291         stw   r8, 24+(5*4)(r1)
292         stw   r9, 24+(6*4)(r1)
293         stw   r10, 24+(7*4)(r1)
294         stw   r0, 8(r1)
296         /* 24 Bytes (Linkage Area) */
297         /* 32 Bytes (params) */
298         /* 16  Bytes (result) */
299         /* 104 Bytes (13*8 from FPR) */
300         /* 176 Bytes */
302         stwu  r1, -176(r1)      /* skip over caller save area
303                                    keep stack aligned to 16  */
305         /* next save fpr 1 to fpr 13 (aligned to 8) */
306         stfd  f1, 72+(0*8)(r1)
307         stfd  f2, 72+(1*8)(r1)
308         stfd  f3, 72+(2*8)(r1)
309         stfd  f4, 72+(3*8)(r1)
310         stfd  f5, 72+(4*8)(r1)
311         stfd  f6, 72+(5*8)(r1)
312         stfd  f7, 72+(6*8)(r1)
313         stfd  f8, 72+(7*8)(r1)
314         stfd  f9, 72+(8*8)(r1)
315         stfd  f10, 72+(9*8)(r1)
316         stfd  f11, 72+(10*8)(r1)
317         stfd  f12, 72+(11*8)(r1)
318         stfd  f13, 72+(12*8)(r1)
320         /* set up registers for the routine that actually does the work */
321         /* get the context pointer from the trampoline */
322         mr r3, r11
324         /* now load up the pointer to the result storage */
325         addi r4, r1, 56
327         /* now load up the pointer to the saved gpr registers */
328         addi r5, r1, 200
330         /* now load up the pointer to the saved fpr registers */
331         addi r6, r1, 72
333         /* make the call */
334         bl .ffi_closure_helper_DARWIN
335         nop
337         /* now r3 contains the return type */
338         /* so use it to look up in a table */
339         /* so we know how to deal with each type */
341         /* look up the proper starting point in table  */
342         /* by using return type as offset */
343         lhz     r3, 6(r3)       /* load type from return type */
344         lwz     r4, LC..60(2)   /* get address of jump table */
345         slwi    r3, r3, 4       /* now multiply return type by 16 */
346         lwz     r0, 176+8(r1)   /* load return address */
347         add     r3, r3, r4      /* add contents of table to table address */
348         mtctr   r3
349         bctr                    /* jump to it */
351 /* Each fragment must be exactly 16 bytes long (4 instructions).
352    Align to 16 byte boundary for cache and dispatch efficiency.  */
353         .align 4
355 L..60:
356 /* case FFI_TYPE_VOID */
357         mtlr r0
358         addi r1, r1, 176
359         blr
360         nop
362 /* case FFI_TYPE_INT */
363         lwz r3, 56+0(r1)
364         mtlr r0
365         addi r1, r1, 176
366         blr
368 /* case FFI_TYPE_FLOAT */
369         lfs f1, 56+0(r1)
370         mtlr r0
371         addi r1, r1, 176
372         blr
374 /* case FFI_TYPE_DOUBLE */
375         lfd f1, 56+0(r1)
376         mtlr r0
377         addi r1, r1, 176
378         blr
380 /* case FFI_TYPE_LONGDOUBLE */
381         lfd f1, 56+0(r1)
382         mtlr r0
383         lfd f2, 56+8(r1)
384         b L..finish
386 /* case FFI_TYPE_UINT8 */
387         lbz r3, 56+3(r1)
388         mtlr r0
389         addi r1, r1, 176
390         blr
392 /* case FFI_TYPE_SINT8 */
393         lbz r3, 56+3(r1)
394         mtlr r0
395         extsb r3, r3
396         b L..finish
398 /* case FFI_TYPE_UINT16 */
399         lhz r3, 56+2(r1)
400         mtlr r0
401         addi r1, r1, 176
402         blr
404 /* case FFI_TYPE_SINT16 */
405         lha r3, 56+2(r1)
406         mtlr r0
407         addi r1, r1, 176
408         blr
410 /* case FFI_TYPE_UINT32 */
411         lwz r3, 56+0(r1)
412         mtlr r0
413         addi r1, r1, 176
414         blr
416 /* case FFI_TYPE_SINT32 */
417         lwz r3, 56+0(r1)
418         mtlr r0
419         addi r1, r1, 176
420         blr
422 /* case FFI_TYPE_UINT64 */
423         lwz r3, 56+0(r1)
424         mtlr r0
425         lwz r4, 56+4(r1)
426         b L..finish
428 /* case FFI_TYPE_SINT64 */
429         lwz r3, 56+0(r1)
430         mtlr r0
431         lwz r4, 56+4(r1)
432         b L..finish
434 /* case FFI_TYPE_STRUCT */
435         mtlr r0
436         addi r1, r1, 176
437         blr
438         nop
440 /* case FFI_TYPE_POINTER */
441         lwz r3, 56+0(r1)
442         mtlr r0
443 L..finish:
444         addi r1, r1, 176
445         blr
446 #endif
447 /* END(ffi_closure_ASM) */