Fix xfail for 32-bit hppa*-*-* in gcc.dg/pr84877.c
[official-gcc.git] / libffi / src / powerpc / linux64.S
blob1f876ea39eddc2caf732f662458d58f41c8fb68b
1 /* -----------------------------------------------------------------------
2    sysv.h - Copyright (c) 2003 Jakub Jelinek <jakub@redhat.com>
3             Copyright (c) 2008 Red Hat, Inc.
5    PowerPC64 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,
19    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20    MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
21    NONINFRINGEMENT.  IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
22    HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
23    WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
24    OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
25    DEALINGS IN THE SOFTWARE.
26    ----------------------------------------------------------------------- */
28 #define LIBFFI_ASM
29 #include <fficonfig.h>
30 #include <ffi.h>
32         .machine altivec
34 #ifdef POWERPC64
35         .hidden ffi_call_LINUX64
36         .globl  ffi_call_LINUX64
37         .text
38         .cfi_startproc
39 # if _CALL_ELF == 2
40 ffi_call_LINUX64:
41 #  ifndef __PCREL__
42         addis   %r2, %r12, .TOC.-ffi_call_LINUX64@ha
43         addi    %r2, %r2, .TOC.-ffi_call_LINUX64@l
44 #  endif
45         .localentry ffi_call_LINUX64, . - ffi_call_LINUX64
46 # else
47         .section        ".opd","aw"
48         .align  3
49 ffi_call_LINUX64:
50 #  ifdef _CALL_LINUX
51         .quad   .L.ffi_call_LINUX64,.TOC.@tocbase,0
52         .type   ffi_call_LINUX64,@function
53         .text
54 .L.ffi_call_LINUX64:
55 #  else
56         .hidden .ffi_call_LINUX64
57         .globl  .ffi_call_LINUX64
58         .quad   .ffi_call_LINUX64,.TOC.@tocbase,0
59         .size   ffi_call_LINUX64,24
60         .type   .ffi_call_LINUX64,@function
61         .text
62 .ffi_call_LINUX64:
63 #  endif
64 # endif
65         mflr    %r0
66         std     %r28, -32(%r1)
67         std     %r29, -24(%r1)
68         std     %r30, -16(%r1)
69         std     %r31, -8(%r1)
70         std     %r7, 8(%r1)     /* closure, saved in cr field.  */
71         std     %r0, 16(%r1)
73         mr      %r28, %r1       /* our AP.  */
74         .cfi_def_cfa_register 28
75         .cfi_offset 65, 16
76         .cfi_offset 31, -8
77         .cfi_offset 30, -16
78         .cfi_offset 29, -24
79         .cfi_offset 28, -32
81         stdux   %r1, %r1, %r8
82         mr      %r31, %r6       /* flags, */
83         mr      %r30, %r5       /* rvalue, */
84         mr      %r29, %r4       /* function address.  */
85 /* Save toc pointer, not for the ffi_prep_args64 call, but for the later
86    bctrl function call.  */
87 # if _CALL_ELF == 2
88         std     %r2, 24(%r1)
89 # else
90         std     %r2, 40(%r1)
91 # endif
93         /* Call ffi_prep_args64.  */
94         mr      %r4, %r1
95 # if defined _CALL_LINUX || _CALL_ELF == 2
96 #  ifdef __PCREL__
97         bl      ffi_prep_args64@notoc
98 #  else
99         bl      ffi_prep_args64
100         nop
101 #  endif
102 # else
103         bl      .ffi_prep_args64
104         nop
105 # endif
107 # if _CALL_ELF == 2
108         mr      %r12, %r29
109 # else
110         ld      %r12, 0(%r29)
111         ld      %r2, 8(%r29)
112 # endif
113         /* Now do the call.  */
114         /* Set up cr1 with bits 3-7 of the flags.  */
115         mtcrf   0xc0, %r31
117         /* Get the address to call into CTR.  */
118         mtctr   %r12
119         /* Load all those argument registers.  */
120         addi    %r29, %r28, -32-(8*8)
121         ld      %r3,  (0*8)(%r29)
122         ld      %r4,  (1*8)(%r29)
123         ld      %r5,  (2*8)(%r29)
124         ld      %r6,  (3*8)(%r29)
125         bf-     5, 1f
126         ld      %r7,  (4*8)(%r29)
127         ld      %r8,  (5*8)(%r29)
128         ld      %r9,  (6*8)(%r29)
129         ld      %r10, (7*8)(%r29)
132         /* Load all the FP registers.  */
133         bf-     6, 2f
134         addi    %r29, %r29, -(14*8)
135         lfd     %f1,  ( 1*8)(%r29)
136         lfd     %f2,  ( 2*8)(%r29)
137         lfd     %f3,  ( 3*8)(%r29)
138         lfd     %f4,  ( 4*8)(%r29)
139         lfd     %f5,  ( 5*8)(%r29)
140         lfd     %f6,  ( 6*8)(%r29)
141         lfd     %f7,  ( 7*8)(%r29)
142         lfd     %f8,  ( 8*8)(%r29)
143         lfd     %f9,  ( 9*8)(%r29)
144         lfd     %f10, (10*8)(%r29)
145         lfd     %f11, (11*8)(%r29)
146         lfd     %f12, (12*8)(%r29)
147         lfd     %f13, (13*8)(%r29)
150         /* Load all the vector registers.  */
151         bf-     3, 3f
152         addi    %r29, %r29, -16
153         lvx     %v13, 0, %r29
154         addi    %r29, %r29, -16
155         lvx     %v12, 0, %r29
156         addi    %r29, %r29, -16
157         lvx     %v11, 0, %r29
158         addi    %r29, %r29, -16
159         lvx     %v10, 0, %r29
160         addi    %r29, %r29, -16
161         lvx     %v9,  0, %r29
162         addi    %r29, %r29, -16
163         lvx     %v8,  0, %r29
164         addi    %r29, %r29, -16
165         lvx     %v7,  0, %r29
166         addi    %r29, %r29, -16
167         lvx     %v6,  0, %r29
168         addi    %r29, %r29, -16
169         lvx     %v5,  0, %r29
170         addi    %r29, %r29, -16
171         lvx     %v4,  0, %r29
172         addi    %r29, %r29, -16
173         lvx     %v3,  0, %r29
174         addi    %r29, %r29, -16
175         lvx     %v2,  0, %r29
178         /* Make the call.  */
179         ld      %r11, 8(%r28)
180         bctrl
182         /* This must follow the call immediately, the unwinder
183            uses this to find out if r2 has been saved or not.  */
184 # if _CALL_ELF == 2
185         ld      %r2, 24(%r1)
186 # else
187         ld      %r2, 40(%r1)
188 # endif
190         /* Now, deal with the return value.  */
191         mtcrf   0x01, %r31
192         bt      31, .Lstruct_return_value
193         bt      30, .Ldone_return_value
194         bt      29, .Lfp_return_value
195         bt      28, .Lvec_return_value
196         std     %r3, 0(%r30)
197         /* Fall through...  */
199 .Ldone_return_value:
200         /* Restore the registers we used and return.  */
201         mr      %r1, %r28
202         .cfi_def_cfa_register 1
203         ld      %r0, 16(%r28)
204         ld      %r28, -32(%r28)
205         mtlr    %r0
206         ld      %r29, -24(%r1)
207         ld      %r30, -16(%r1)
208         ld      %r31, -8(%r1)
209         blr
211 .Lvec_return_value:
212         stvx    %v2, 0, %r30
213         b       .Ldone_return_value
215 .Lfp_return_value:
216         .cfi_def_cfa_register 28
217         mtcrf   0x02, %r31 /* cr6  */
218         bf      27, .Lfloat_return_value
219         stfd    %f1, 0(%r30)
220         bf      26, .Ldone_return_value
221         stfd    %f2, 8(%r30)
222         b       .Ldone_return_value
223 .Lfloat_return_value:
224         stfs    %f1, 0(%r30)
225         b       .Ldone_return_value
227 .Lstruct_return_value:
228         bf      29, .Lvec_homog_or_small_struct
229         mtcrf   0x02, %r31 /* cr6  */
230         bf      27, .Lfloat_homog_return_value
231         stfd    %f1, 0(%r30)
232         stfd    %f2, 8(%r30)
233         stfd    %f3, 16(%r30)
234         stfd    %f4, 24(%r30)
235         stfd    %f5, 32(%r30)
236         stfd    %f6, 40(%r30)
237         stfd    %f7, 48(%r30)
238         stfd    %f8, 56(%r30)
239         b       .Ldone_return_value
241 .Lfloat_homog_return_value:
242         stfs    %f1, 0(%r30)
243         stfs    %f2, 4(%r30)
244         stfs    %f3, 8(%r30)
245         stfs    %f4, 12(%r30)
246         stfs    %f5, 16(%r30)
247         stfs    %f6, 20(%r30)
248         stfs    %f7, 24(%r30)
249         stfs    %f8, 28(%r30)
250         b       .Ldone_return_value
252 .Lvec_homog_or_small_struct:
253         bf      28, .Lsmall_struct
254         stvx    %v2, 0, %r30
255         addi    %r30, %r30, 16
256         stvx    %v3, 0, %r30
257         addi    %r30, %r30, 16
258         stvx    %v4, 0, %r30
259         addi    %r30, %r30, 16
260         stvx    %v5, 0, %r30
261         addi    %r30, %r30, 16
262         stvx    %v6, 0, %r30
263         addi    %r30, %r30, 16
264         stvx    %v7, 0, %r30
265         addi    %r30, %r30, 16
266         stvx    %v8, 0, %r30
267         addi    %r30, %r30, 16
268         stvx    %v9, 0, %r30
269         b       .Ldone_return_value
271 .Lsmall_struct:
272         std     %r3, 0(%r30)
273         std     %r4, 8(%r30)
274         b       .Ldone_return_value
276         .cfi_endproc
277 # if _CALL_ELF == 2
278         .size   ffi_call_LINUX64,.-ffi_call_LINUX64
279 # else
280 #  ifdef _CALL_LINUX
281         .size   ffi_call_LINUX64,.-.L.ffi_call_LINUX64
282 #  else
283         .long   0
284         .byte   0,12,0,1,128,4,0,0
285         .size   .ffi_call_LINUX64,.-.ffi_call_LINUX64
286 #  endif
287 # endif
289 #endif
291 #if (defined __ELF__ && defined __linux__) || _CALL_ELF == 2
292         .section        .note.GNU-stack,"",@progbits
293 #endif