* gcc.dg/ppc64-abi-1.c: New test.
authorHartmut Penner <hpenner@de.ibm.com>
Wed, 14 Jan 2004 09:23:06 +0000 (09:23 +0000)
committerHartmut Penner <hpenner@gcc.gnu.org>
Wed, 14 Jan 2004 09:23:06 +0000 (09:23 +0000)
From-SVN: r75852

gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/ppc64-abi-1.c [new file with mode: 0644]

index 5c3c302..05a6b60 100644 (file)
@@ -1,3 +1,7 @@
+2004-01-14  Hartmut Penner  <hpenner@de.ibm.com>
+
+       * gcc.dg/ppc64-abi-1.c: New test.
+
 2004-01-14  Danny Smith  <dannysmith@users.sourceforge.net>
 
         * g++.dg/ext/attrib9.C: Add dg-warnings.
diff --git a/gcc/testsuite/gcc.dg/ppc64-abi-1.c b/gcc/testsuite/gcc.dg/ppc64-abi-1.c
new file mode 100644 (file)
index 0000000..fa19659
--- /dev/null
@@ -0,0 +1,363 @@
+/* { dg-do run { target powerpc64-*-* } } */
+/* { dg-options "-O2" } */
+#include <stdarg.h>
+#include <signal.h>
+#include <stdio.h>
+
+/* Testcase to check for ABI compliance of parameter passing
+   for the PowerPC64 ABI.  
+   Parameter passing of integral and floating point is tested.  */
+
+extern void abort (void);
+
+typedef struct
+{
+  unsigned long gprs[8];
+  double fprs[13];
+} reg_parms_t;
+
+reg_parms_t gparms;
+
+
+/* Testcase could break on future gcc's, if parameter regs
+   are changed before this asm.  */
+
+#ifndef __MACH__
+#define save_parms(lparms)                             \
+    asm volatile ("ld 11,gparms@got(2)\n\t"                \
+                  "std 3,0(11)\n\t"                    \
+                 "std 4,8(11)\n\t"                     \
+                 "std 5,16(11)\n\t"                    \
+                 "std 6,24(11)\n\t"                    \
+                 "std 7,32(11)\n\t"                    \
+                 "std 8,40(11)\n\t"                    \
+                 "std 9,48(11)\n\t"                    \
+                 "std 10,56(11)\n\t"                 \
+                  "stfd 1,64(11)\n\t"                  \
+                 "stfd 2,72(11)\n\t"                   \
+                 "stfd 3,80(11)\n\t"                   \
+                 "stfd 4,88(11)\n\t"                   \
+                 "stfd 5,96(11)\n\t"                   \
+                 "stfd 6,104(11)\n\t"                  \
+                 "stfd 7,112(11)\n\t"                  \
+                 "stfd 8,120(11)\n\t"                  \
+                 "stfd 9,128(11)\n\t"                  \
+                 "stfd 10,136(11)\n\t"                 \
+                 "stfd 11,144(11)\n\t"                 \
+                 "stfd 12,152(11)\n\t"                 \
+                 "stfd 13,160(11)\n\t":::"11", "memory");  \
+                  lparms = gparms;
+#else
+#define save_parms(lparms)                             \
+    asm volatile ("ld r11,gparms@got(r2)\n\t"           \
+                  "std r3,0(r11)\n\t"                  \
+                 "std r4,8(r11)\n\t"                   \
+                 "std r5,16(r11)\n\t"                  \
+                 "std r6,24(r11)\n\t"                  \
+                 "std r7,32(r11)\n\t"                  \
+                 "std r8,40(r11)\n\t"                  \
+                 "std r9,48(r11)\n\t"                  \
+                 "std r10,56(r11)\n\t"                 \
+                  "stfd f1,64(r11)\n\t"                        \
+                 "stfd f2,72(r11)\n\t"                 \
+                 "stfd f3,80(r11)\n\t"                 \
+                 "stfd f4,88(r11)\n\t"                 \
+                 "stfd f5,96(r11)\n\t"                 \
+                 "stfd f6,104(r11)\n\t"                \
+                 "stfd f7,112(r11)\n\t"                \
+                 "stfd f8,120(r11)\n\t"                \
+                 "stfd f9,128(r11)\n\t"                \
+                 "stfd f10,136(r11)\n\t"               \
+                 "stfd f11,144(r11)\n\t"               \
+                 "stfd f12,152(r11)\n\t"               \
+                 "stfd f13,160(r11)\n\t":::"r11", "memory");  \
+                  lparms = gparms;
+#endif
+
+/* Stackframe structure relevant for parameter passing.  */
+typedef union
+{
+  double d;
+  unsigned long l;
+  unsigned int i[2];
+} parm_t;
+
+typedef struct sf
+{
+  struct sf *backchain;
+  long a1;
+  long a2;
+  long a3;
+  long a4;
+  long a5;
+  parm_t slot[100];
+} stack_frame_t;
+
+
+/* Paramter passing.
+   s : gpr 3
+   l : gpr 4
+   d : fpr 1
+*/
+void __attribute__ ((noinline)) fcld (char *s, long l, double d)
+{
+  reg_parms_t lparms;
+  save_parms (lparms);
+
+  if (s != (char *) lparms.gprs[0])
+    abort ();
+
+  if (l != lparms.gprs[1])
+    abort ();
+
+  if (d != lparms.fprs[0])
+    abort ();
+}
+
+/* Paramter passing.
+   s : gpr 3
+   l : gpr 4
+   d : fpr 2
+   i : gpr 5
+*/
+void __attribute__ ((noinline))
+fcldi (char *s, long l, double d, signed int i)
+{
+  reg_parms_t lparms;
+  save_parms (lparms);
+
+  if (s != (char *) lparms.gprs[0])
+    abort ();
+
+  if (l != lparms.gprs[1])
+    abort ();
+
+  if (d != lparms.fprs[0])
+    abort ();
+
+  if ((signed long) i != lparms.gprs[3])
+    abort ();
+}
+
+/* Paramter passing.
+   s : gpr 3
+   l : gpr 4
+   d : fpr 2
+   i : gpr 5
+*/
+void __attribute__ ((noinline))
+fcldu (char *s, long l, float d, unsigned int i)
+{
+  reg_parms_t lparms;
+  save_parms (lparms);
+
+  if (s != (char *) lparms.gprs[0])
+    abort ();
+
+  if (l != lparms.gprs[1])
+    abort ();
+
+  if ((double) d != lparms.fprs[0])
+    abort ();
+
+  if ((unsigned long) i != lparms.gprs[3])
+    abort ();
+}
+
+/* Paramter passing.
+   s : gpr 3
+   l : slot 1
+   d : slot 2
+*/
+
+void __attribute__ ((noinline)) fceld (char *s, ...)
+{
+  stack_frame_t *sp;
+  reg_parms_t lparms;
+  va_list arg;
+  double d;
+  long l;
+  save_parms (lparms);
+
+  va_start (arg, s);
+
+  if (s != (char *) lparms.gprs[0])
+    abort ();
+
+  l = va_arg (arg, long);
+  d = va_arg (arg, double);
+
+  /* Go back one frame.  */
+  sp = __builtin_frame_address (0);
+  sp = sp->backchain;
+
+  if (sp->slot[1].l != l)
+    abort ();
+
+  if (sp->slot[2].d != d)
+    abort ();
+}
+
+/* Paramter passing.
+   s : gpr 3
+   i : gpr 4
+   j : gpr 5
+   d : slot 3
+   l : slot 4
+*/
+void __attribute__ ((noinline)) fciiedl (char *s, int i, int j, ...)
+{
+  stack_frame_t *sp;
+  reg_parms_t lparms;
+  va_list arg;
+  double d;
+  long l;
+  save_parms (lparms);
+
+  va_start (arg, j);
+
+  if (s != (char *) lparms.gprs[0])
+    abort ();
+
+  if ((long) i != lparms.gprs[1])
+    abort ();
+
+  if ((long) j != lparms.gprs[2])
+    abort ();
+
+  d = va_arg (arg, double);
+  l = va_arg (arg, long);
+
+  sp = __builtin_frame_address (0);
+  sp = sp->backchain;
+
+  if (sp->slot[3].d != d)
+    abort ();
+
+  if (sp->slot[4].l != l)
+    abort ();
+}
+
+/* 
+Parameter     Register     Offset in parameter save area
+c             r3           0-7    (not stored in parameter save area)
+ff            f1           8-15   (not stored)
+d             r5           16-23  (not stored)
+ld            f2           24-31  (not stored)
+f             r7           32-39  (not stored)
+s             r8,r9        40-55  (not stored)
+gg            f3           56-63  (not stored)
+t             (none)       64-79  (stored in parameter save area)
+e             (none)       80-87  (stored)
+hh            f4           88-95  (stored)  
+
+*/
+
+typedef struct
+{
+  int a;
+  double dd;
+} sparm;
+
+typedef union
+{
+  int i[2];
+  long l;
+  double d;
+} double_t;
+
+/* Example from ABI documentation with slight changes.
+   Paramter passing. 
+   c  : gpr 3
+   ff : fpr 1
+   d  : gpr 5
+   ld : fpr 2
+   f  : gpr 7
+   s  : gpr 8 - 9
+   gg : fpr 3
+   t  : save area offset 64 - 79 
+   e  : save area offset 80 - 88
+   hh : fpr 4   
+*/
+
+void __attribute__ ((noinline))
+fididisdsid (int c, double ff, int d, double ld, int f,
+            sparm s, double gg, sparm t, int e, double hh)
+{
+  stack_frame_t *sp;
+  reg_parms_t lparms;
+  double_t dx, dy;
+
+  save_parms (lparms);
+
+  /* Parm 0: int.  */
+  if ((long) c != lparms.gprs[0])
+    abort ();
+
+  /* Parm 1: double.  */
+  if (ff != lparms.fprs[0])
+    abort ();
+
+  /* Parm 2: int.  */
+  if ((long) d != lparms.gprs[2])
+    abort ();
+
+  /* Parm 3: double.  */
+  if (ld != lparms.fprs[1])
+    abort ();
+
+  /* Parm 4: int.  */
+  if ((long) f != lparms.gprs[4])
+    abort ();
+
+  /* Parm 5: struct sparm.  */
+  dx.l = lparms.gprs[5];
+  dy.l = lparms.gprs[6];
+
+  if (s.a != dx.i[0])
+    abort ();
+  if (s.dd != dy.d)
+    abort ();
+
+  /* Parm 6: double.  */
+  if (gg != lparms.fprs[2])
+    abort ();
+
+  sp = __builtin_frame_address (0);
+  sp = sp->backchain;
+
+  /* Parm 7: struct sparm.  */
+  dx.l = sp->slot[8].l;
+  dy.l = sp->slot[9].l;
+  if (t.a != dx.i[0])
+    abort ();
+  if (t.dd != dy.d)
+    abort ();
+
+  /* Parm 8: int.  */
+  if (e != sp->slot[10].l)
+    abort ();
+
+  /* Parm 9: double.  */
+
+  if (hh != lparms.fprs[3])
+    abort ();
+}
+
+int
+main ()
+{
+  char *s = "ii";
+
+  fcld (s, 1, 1.0);
+  fcldi (s, 1, 1.0, -2);
+  fcldu (s, 1, 1.0, 2);
+  fceld (s, 1, 1.0);
+  fciiedl (s, 1, 2, 1.0, 3);
+  fididisdsid (1, 1.0, 2, 2.0, -1, (sparm)
+              {
+              3, 3.0}, 4.0, (sparm)
+              {
+              5, 5.0}, 6, 7.0);
+  return 0;
+}