OSDN Git Service

93c121c463df5bb930b69abff8367f3c16c36234
[pf3gnuchains/gcc-fork.git] / gcc / testsuite / gcc.dg / ppc64-abi-2.c
1 /* { dg-do run { target powerpc64-*-linux* } } */
2 /* { dg-options "-O2 -fprofile -mprofile-kernel -maltivec -mabi=altivec" } */
3 #include <stdarg.h>
4 #include <signal.h>
5 #include <altivec.h>
6 #include <stdlib.h>
7
8 /* Testcase to check for ABI compliance of parameter passing
9    for the PowerPC64 ABI.  */
10
11 void __attribute__((no_instrument_function))
12 sig_ill_handler (int sig)
13 {
14     exit(0);
15 }
16
17 extern void abort (void);
18
19 typedef struct
20 {
21   unsigned long gprs[8];
22   double fprs[13];
23   long pad;
24   vector int vrs[12];
25 } reg_parms_t;
26
27 reg_parms_t gparms;
28
29 /* _mcount call is done on Linux ppc64 early in the prologue.
30    my_mcount will provide a entry point _mcount,
31    which will save all register to gparms. 
32    Note that _mcount need to restore lr to original value,
33    therefor use ctr to return.  
34 */
35
36 void __attribute__((no_instrument_function))
37 my_mcount() 
38 {
39   asm volatile (".type  _mcount,@function\n\t"
40                 ".globl _mcount\n\t"
41                 "_mcount:\n\t"
42                 "mflr 0\n\t"
43                 "mtctr 0\n\t"
44                 "ld 0,16(1)\n\t"
45                 "mtlr 0\n\t"
46                 "ld 11,gparms@got(2)\n\t" 
47                 "std 3,0(11)\n\t"               
48                 "std 4,8(11)\n\t"
49                 "std 5,16(11)\n\t"      
50                 "std 6,24(11)\n\t"      
51                 "std 7,32(11)\n\t"      
52                 "std 8,40(11)\n\t"      
53                 "std 9,48(11)\n\t"      
54                 "std 10,56(11)\n\t"   
55                 "stfd 1,64(11)\n\t"     
56                 "stfd 2,72(11)\n\t"     
57                 "stfd 3,80(11)\n\t"     
58                 "stfd 4,88(11)\n\t"     
59                 "stfd 5,96(11)\n\t"     
60                 "stfd 6,104(11)\n\t"    
61                 "stfd 7,112(11)\n\t"    
62                 "stfd 8,120(11)\n\t"    
63                 "stfd 9,128(11)\n\t"    
64                 "stfd 10,136(11)\n\t"   
65                 "stfd 11,144(11)\n\t"   
66                 "stfd 12,152(11)\n\t" 
67                 "stfd 13,160(11)\n\t" 
68                 "li 3,176\n\t"        
69                 "stvx 2,3,11\n\t"       
70                 "addi 3,3,16\n\t" 
71                 "stvx 3,3,11\n\t"       
72                 "addi 3,3,16\n\t"     
73                 "stvx 4,3,11\n\t"       
74                 "addi 3,3,16\n\t"     
75                 "stvx 5,3,11\n\t"       
76                 "addi 3,3,16\n\t"     
77                 "stvx 6,3,11\n\t"       
78                 "addi 3,3,16\n\t"     
79                 "stvx 7,3,11\n\t"       
80                 "addi 3,3,16\n\t"     
81                 "stvx 8,3,11\n\t"       
82                 "addi 3,3,16\n\t"     
83                 "stvx 9,3,11\n\t"       
84                 "addi 3,3,16\n\t"     
85                 "stvx 10,3,11\n\t"      
86                 "addi 3,3,16\n\t"     
87                 "stvx 11,3,11\n\t"      
88                 "addi 3,3,16\n\t"     
89                 "stvx 12,3,11\n\t"      
90                 "addi 3,3,16\n\t"     
91                 "stvx 13,3,11\n\t"      
92                 "ld 3,0(11)\n\t"
93                 "bctr");
94 }
95
96 /* Stackframe structure relevant for parameter passing.  */
97 typedef union
98 {
99   double d;
100   unsigned long l;
101   unsigned int i[2];
102 } parm_t;
103
104 typedef struct sf
105 {
106   struct sf *backchain;
107   long a1;
108   long a2;
109   long a3;
110   long a4;
111   long a5;
112   parm_t slot[100];
113 } stack_frame_t;
114
115 typedef union
116 {
117   unsigned int i[4];
118   unsigned long l[2];
119   vector int v;
120 } vector_int_t;
121
122 /* Paramter passing.
123    s : gpr 3
124    v : vpr 2
125    i : gpr 7
126 */
127 void __attribute__ ((noinline))
128 fcvi (char *s, vector int v, int i)
129 {
130   reg_parms_t lparms = gparms;
131
132   if (s != (char *) lparms.gprs[0])
133     abort();
134
135   if (!vec_all_eq (v, lparms.vrs[0]))
136     abort ();
137
138   if ((long) i != lparms.gprs[4])
139     abort();
140 }
141 /* Paramter passing.
142    s : gpr 3
143    v : vpr 2
144    w : vpr 3
145 */
146
147 void __attribute__ ((noinline))
148 fcvv (char *s, vector int v, vector int w)
149 {
150   vector int a, c = {6, 8, 10, 12};
151   reg_parms_t lparms = gparms;
152
153   if (s != (char *) lparms.gprs[0])
154     abort();
155
156   if (!vec_all_eq (v, lparms.vrs[0]))
157     abort ();
158
159   if (!vec_all_eq (w, lparms.vrs[1]))
160     abort ();
161
162   a = vec_add (v,w);
163
164   if (!vec_all_eq (a, c))
165     abort ();
166 }
167
168 /* Paramter passing.
169    s : gpr 3
170    i : gpr 4
171    v : vpr 2
172    w : vpr 3
173 */
174 void __attribute__ ((noinline))
175 fcivv (char *s, int i, vector int v, vector int w)
176 {
177   vector int a, c = {6, 8, 10, 12};
178   reg_parms_t lparms = gparms;
179
180   if (s != (char *) lparms.gprs[0])
181     abort();
182
183   if ((long) i != lparms.gprs[1])
184     abort();
185
186   if (!vec_all_eq (v, lparms.vrs[0]))
187     abort ();
188
189   if (!vec_all_eq (w, lparms.vrs[1]))
190     abort ();
191
192   a = vec_add (v,w);
193   
194   if (!vec_all_eq (a, c))
195     abort ();
196 }
197
198 /* Paramter passing.
199    s : gpr 3
200    v : slot 2-3
201    w : slot 4-5
202 */
203
204 void __attribute__ ((noinline))
205 fcevv (char *s, ...)
206 {
207   vector int a, c = {6, 8, 10, 12};
208   vector int v,w;
209   stack_frame_t *sp;
210   reg_parms_t lparms = gparms;
211   va_list arg;
212
213   va_start (arg, s);
214
215   if (s != (char *) lparms.gprs[0])
216     abort();
217
218   v = va_arg(arg, vector int);
219   w = va_arg(arg, vector int);
220   a = vec_add (v,w);
221   
222   if (!vec_all_eq (a, c))
223     abort ();
224
225   /* Go back one frame.  */
226   sp = __builtin_frame_address(0);
227   sp = sp->backchain;
228   
229   if (sp->slot[2].l != 0x100000002ULL
230       || sp->slot[4].l != 0x500000006ULL)
231     abort();
232 }
233
234 /* Paramter passing.
235    s : gpr 3
236    i : gpr 4
237    j : gpr 5
238    v : slot 4-5
239    w : slot 6-7
240 */
241 void __attribute__ ((noinline))
242 fciievv (char *s, int i, int j, ...)
243 {
244   vector int a, c = {6, 8, 10, 12};
245   vector int v,w;
246   stack_frame_t *sp;
247   reg_parms_t lparms = gparms;
248   va_list arg;
249
250   va_start (arg, j);
251
252   if (s != (char *) lparms.gprs[0])
253     abort();
254
255   if ((long) i != lparms.gprs[1])
256     abort();
257
258   if ((long) j != lparms.gprs[2])
259     abort();
260   
261   v = va_arg(arg, vector int);
262   w = va_arg(arg, vector int);
263   a = vec_add (v,w);
264   
265   if (!vec_all_eq (a, c))
266     abort ();
267
268   sp = __builtin_frame_address(0);
269   sp = sp->backchain;
270   
271   if (sp->slot[4].l != 0x100000002ULL
272       || sp->slot[6].l != 0x500000006ULL)
273     abort();
274 }
275
276 void __attribute__ ((noinline))
277 fcvevv (char *s, vector int x, ...)
278 {
279   vector int a, c = {7, 10, 13, 16};
280   vector int v,w;
281   stack_frame_t *sp;
282   reg_parms_t lparms = gparms;
283   va_list arg;
284
285   va_start (arg, x);
286   
287   v = va_arg(arg, vector int);
288   w = va_arg(arg, vector int);
289
290   a = vec_add (v,w);
291   a = vec_add (a, x);
292  
293   if (!vec_all_eq (a, c))
294     abort ();
295
296   sp = __builtin_frame_address(0);
297   sp = sp->backchain;
298   
299   if (sp->slot[4].l != 0x100000002ULL
300       || sp->slot[6].l != 0x500000006ULL)
301     abort();
302 }
303
304 void fnp_cvvvv();
305
306 int __attribute__((no_instrument_function, noinline))
307 main1() 
308 {   
309   char *s = "vv";
310   vector int v = {1, 2, 3, 4};
311   vector int w = {5, 6, 7, 8};
312  
313   fcvi (s, v, 2);
314   fcvv (s, v, w);
315   fnp_cvvvv (s, v, w, v, w);
316   fcivv (s, 1, v, w);
317   fcevv (s, v, w);
318   fciievv (s, 1, 2, v, w);
319   fcvevv (s, v, v, w);
320   return 0;
321 }
322
323 int __attribute__((no_instrument_function)) 
324 main()
325 {
326   /* Exit on systems without altivec.  */
327   signal (SIGILL, sig_ill_handler);
328   /* Altivec instruction, 'vor %v0,%v0,%v0'.  */
329   asm volatile (".long 0x10000484");
330   signal (SIGILL, SIG_DFL);
331
332   return main1 ();
333 }
334
335 /* Paramter passing.
336    Function called with no prototype.
337    s : gpr 3
338    v : vpr 2 gpr 5-6
339    w : vpr 3 gpr 7-8
340    x : vpr 4 gpr 9-10
341    y : vpr 5 slot 8-9
342 */
343 void
344 fnp_cvvvv (char *s, vector int v, vector int w,
345            vector int x, vector int y)
346 {
347   vector int a, c = {12, 16, 20, 24};
348   reg_parms_t lparms = gparms;
349   stack_frame_t *sp;
350   vector_int_t v0, v1, v2, v3;
351
352   if (s != (char *) lparms.gprs[0])
353     abort();
354
355   if (!vec_all_eq (v, lparms.vrs[0]))
356     abort ();
357
358   if (!vec_all_eq (w, lparms.vrs[1]))
359     abort ();
360
361   if (!vec_all_eq (x, lparms.vrs[2]))
362     abort ();
363
364   if (!vec_all_eq (y, lparms.vrs[3]))
365     abort ();
366
367   a = vec_add (v,w);
368   a = vec_add (a,x);  
369   a = vec_add (a,y);  
370   
371   if (!vec_all_eq (a, c))
372     abort ();
373   
374   v0.v = lparms.vrs[0];
375   v1.v = lparms.vrs[1];
376   v2.v = lparms.vrs[2];
377   v3.v = lparms.vrs[3];
378
379   if (v0.l[0] != lparms.gprs[2])
380     abort ();
381
382   if (v0.l[1] != lparms.gprs[3])
383     abort ();
384
385   if (v1.l[0] != lparms.gprs[4])
386     abort ();
387
388   if (v1.l[1] != lparms.gprs[5])
389     abort ();
390
391   if (v2.l[0] != lparms.gprs[6])
392     abort ();
393
394   if (v2.l[1] != lparms.gprs[7])
395     abort ();
396
397   sp = __builtin_frame_address(0);
398   sp = sp->backchain;
399   
400   if (sp->slot[8].l != v3.l[0])
401     abort ();
402
403   if (sp->slot[9].l != v3.l[1])
404     abort ();
405 }  
406