OSDN Git Service

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