OSDN Git Service

PR c/17844
[pf3gnuchains/gcc-fork.git] / gcc / testsuite / gcc.dg / ppc64-abi-1.c
1 /* { dg-do run { target powerpc64-*-* } } */
2 /* { dg-options "-O2" } */
3 #include <stdarg.h>
4 #include <signal.h>
5 #include <stdio.h>
6
7 /* Testcase to check for ABI compliance of parameter passing
8    for the PowerPC64 ABI.  
9    Parameter passing of integral and floating point is tested.  */
10
11 extern void abort (void);
12
13 typedef struct
14 {
15   unsigned long gprs[8];
16   double fprs[13];
17 } reg_parms_t;
18
19 reg_parms_t gparms;
20
21
22 /* Testcase could break on future gcc's, if parameter regs
23    are changed before this asm.  */
24
25 #ifndef __MACH__
26 #define save_parms(lparms)                              \
27     asm volatile ("ld 11,gparms@got(2)\n\t"                \
28                   "std 3,0(11)\n\t"                     \
29                   "std 4,8(11)\n\t"                     \
30                   "std 5,16(11)\n\t"                    \
31                   "std 6,24(11)\n\t"                    \
32                   "std 7,32(11)\n\t"                    \
33                   "std 8,40(11)\n\t"                    \
34                   "std 9,48(11)\n\t"                    \
35                   "std 10,56(11)\n\t"                 \
36                   "stfd 1,64(11)\n\t"                   \
37                   "stfd 2,72(11)\n\t"                   \
38                   "stfd 3,80(11)\n\t"                   \
39                   "stfd 4,88(11)\n\t"                   \
40                   "stfd 5,96(11)\n\t"                   \
41                   "stfd 6,104(11)\n\t"                  \
42                   "stfd 7,112(11)\n\t"                  \
43                   "stfd 8,120(11)\n\t"                  \
44                   "stfd 9,128(11)\n\t"                  \
45                   "stfd 10,136(11)\n\t"                 \
46                   "stfd 11,144(11)\n\t"                 \
47                   "stfd 12,152(11)\n\t"                 \
48                   "stfd 13,160(11)\n\t":::"11", "memory");  \
49                   lparms = gparms;
50 #else
51 #define save_parms(lparms)                              \
52     asm volatile ("ld r11,gparms@got(r2)\n\t"           \
53                   "std r3,0(r11)\n\t"                   \
54                   "std r4,8(r11)\n\t"                   \
55                   "std r5,16(r11)\n\t"                  \
56                   "std r6,24(r11)\n\t"                  \
57                   "std r7,32(r11)\n\t"                  \
58                   "std r8,40(r11)\n\t"                  \
59                   "std r9,48(r11)\n\t"                  \
60                   "std r10,56(r11)\n\t"                 \
61                   "stfd f1,64(r11)\n\t"                 \
62                   "stfd f2,72(r11)\n\t"                 \
63                   "stfd f3,80(r11)\n\t"                 \
64                   "stfd f4,88(r11)\n\t"                 \
65                   "stfd f5,96(r11)\n\t"                 \
66                   "stfd f6,104(r11)\n\t"                \
67                   "stfd f7,112(r11)\n\t"                \
68                   "stfd f8,120(r11)\n\t"                \
69                   "stfd f9,128(r11)\n\t"                \
70                   "stfd f10,136(r11)\n\t"               \
71                   "stfd f11,144(r11)\n\t"               \
72                   "stfd f12,152(r11)\n\t"               \
73                   "stfd f13,160(r11)\n\t":::"r11", "memory");  \
74                   lparms = gparms;
75 #endif
76
77 /* Stackframe structure relevant for parameter passing.  */
78 typedef union
79 {
80   double d;
81   unsigned long l;
82   unsigned int i[2];
83 } parm_t;
84
85 typedef struct sf
86 {
87   struct sf *backchain;
88   long a1;
89   long a2;
90   long a3;
91   long a4;
92   long a5;
93   parm_t slot[100];
94 } stack_frame_t;
95
96
97 /* Paramter passing.
98    s : gpr 3
99    l : gpr 4
100    d : fpr 1
101 */
102 void __attribute__ ((noinline)) fcld (char *s, long l, double d)
103 {
104   reg_parms_t lparms;
105   save_parms (lparms);
106
107   if (s != (char *) lparms.gprs[0])
108     abort ();
109
110   if (l != lparms.gprs[1])
111     abort ();
112
113   if (d != lparms.fprs[0])
114     abort ();
115 }
116
117 /* Paramter passing.
118    s : gpr 3
119    l : gpr 4
120    d : fpr 2
121    i : gpr 5
122 */
123 void __attribute__ ((noinline))
124 fcldi (char *s, long l, double d, signed int i)
125 {
126   reg_parms_t lparms;
127   save_parms (lparms);
128
129   if (s != (char *) lparms.gprs[0])
130     abort ();
131
132   if (l != lparms.gprs[1])
133     abort ();
134
135   if (d != lparms.fprs[0])
136     abort ();
137
138   if ((signed long) i != lparms.gprs[3])
139     abort ();
140 }
141
142 /* Paramter passing.
143    s : gpr 3
144    l : gpr 4
145    d : fpr 2
146    i : gpr 5
147 */
148 void __attribute__ ((noinline))
149 fcldu (char *s, long l, float d, unsigned int i)
150 {
151   reg_parms_t lparms;
152   save_parms (lparms);
153
154   if (s != (char *) lparms.gprs[0])
155     abort ();
156
157   if (l != lparms.gprs[1])
158     abort ();
159
160   if ((double) d != lparms.fprs[0])
161     abort ();
162
163   if ((unsigned long) i != lparms.gprs[3])
164     abort ();
165 }
166
167 /* Paramter passing.
168    s : gpr 3
169    l : slot 1
170    d : slot 2
171 */
172
173 void __attribute__ ((noinline)) fceld (char *s, ...)
174 {
175   stack_frame_t *sp;
176   reg_parms_t lparms;
177   va_list arg;
178   double d;
179   long l;
180   save_parms (lparms);
181
182   va_start (arg, s);
183
184   if (s != (char *) lparms.gprs[0])
185     abort ();
186
187   l = va_arg (arg, long);
188   d = va_arg (arg, double);
189
190   /* Go back one frame.  */
191   sp = __builtin_frame_address (0);
192   sp = sp->backchain;
193
194   if (sp->slot[1].l != l)
195     abort ();
196
197   if (sp->slot[2].d != d)
198     abort ();
199 }
200
201 /* Paramter passing.
202    s : gpr 3
203    i : gpr 4
204    j : gpr 5
205    d : slot 3
206    l : slot 4
207 */
208 void __attribute__ ((noinline)) fciiedl (char *s, int i, int j, ...)
209 {
210   stack_frame_t *sp;
211   reg_parms_t lparms;
212   va_list arg;
213   double d;
214   long l;
215   save_parms (lparms);
216
217   va_start (arg, j);
218
219   if (s != (char *) lparms.gprs[0])
220     abort ();
221
222   if ((long) i != lparms.gprs[1])
223     abort ();
224
225   if ((long) j != lparms.gprs[2])
226     abort ();
227
228   d = va_arg (arg, double);
229   l = va_arg (arg, long);
230
231   sp = __builtin_frame_address (0);
232   sp = sp->backchain;
233
234   if (sp->slot[3].d != d)
235     abort ();
236
237   if (sp->slot[4].l != l)
238     abort ();
239 }
240
241 /* 
242 Parameter     Register     Offset in parameter save area
243 c             r3           0-7    (not stored in parameter save area)
244 ff            f1           8-15   (not stored)
245 d             r5           16-23  (not stored)
246 ld            f2           24-31  (not stored)
247 f             r7           32-39  (not stored)
248 s             r8,r9        40-55  (not stored)
249 gg            f3           56-63  (not stored)
250 t             (none)       64-79  (stored in parameter save area)
251 e             (none)       80-87  (stored)
252 hh            f4           88-95  (stored)  
253
254 */
255
256 typedef struct
257 {
258   int a;
259   double dd;
260 } sparm;
261
262 typedef union
263 {
264   int i[2];
265   long l;
266   double d;
267 } double_t;
268
269 /* Example from ABI documentation with slight changes.
270    Paramter passing. 
271    c  : gpr 3
272    ff : fpr 1
273    d  : gpr 5
274    ld : fpr 2
275    f  : gpr 7
276    s  : gpr 8 - 9
277    gg : fpr 3
278    t  : save area offset 64 - 79 
279    e  : save area offset 80 - 88
280    hh : fpr 4   
281 */
282
283 void __attribute__ ((noinline))
284 fididisdsid (int c, double ff, int d, double ld, int f,
285              sparm s, double gg, sparm t, int e, double hh)
286 {
287   stack_frame_t *sp;
288   reg_parms_t lparms;
289   double_t dx, dy;
290
291   save_parms (lparms);
292
293   /* Parm 0: int.  */
294   if ((long) c != lparms.gprs[0])
295     abort ();
296
297   /* Parm 1: double.  */
298   if (ff != lparms.fprs[0])
299     abort ();
300
301   /* Parm 2: int.  */
302   if ((long) d != lparms.gprs[2])
303     abort ();
304
305   /* Parm 3: double.  */
306   if (ld != lparms.fprs[1])
307     abort ();
308
309   /* Parm 4: int.  */
310   if ((long) f != lparms.gprs[4])
311     abort ();
312
313   /* Parm 5: struct sparm.  */
314   dx.l = lparms.gprs[5];
315   dy.l = lparms.gprs[6];
316
317   if (s.a != dx.i[0])
318     abort ();
319   if (s.dd != dy.d)
320     abort ();
321
322   /* Parm 6: double.  */
323   if (gg != lparms.fprs[2])
324     abort ();
325
326   sp = __builtin_frame_address (0);
327   sp = sp->backchain;
328
329   /* Parm 7: struct sparm.  */
330   dx.l = sp->slot[8].l;
331   dy.l = sp->slot[9].l;
332   if (t.a != dx.i[0])
333     abort ();
334   if (t.dd != dy.d)
335     abort ();
336
337   /* Parm 8: int.  */
338   if (e != sp->slot[10].l)
339     abort ();
340
341   /* Parm 9: double.  */
342
343   if (hh != lparms.fprs[3])
344     abort ();
345 }
346
347 int
348 main ()
349 {
350   char *s = "ii";
351
352   fcld (s, 1, 1.0);
353   fcldi (s, 1, 1.0, -2);
354   fcldu (s, 1, 1.0, 2);
355   fceld (s, 1, 1.0);
356   fciiedl (s, 1, 2, 1.0, 3);
357   fididisdsid (1, 1.0, 2, 2.0, -1, (sparm)
358                {
359                3, 3.0}, 4.0, (sparm)
360                {
361                5, 5.0}, 6, 7.0);
362   return 0;
363 }