OSDN Git Service

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