* gcc.dg/ppc64-abi-2.c: New test.
authorHartmut Penner <hpenner@de.ibm.com>
Tue, 20 Jan 2004 16:54:34 +0000 (16:54 +0000)
committerHartmut Penner <hpenner@gcc.gnu.org>
Tue, 20 Jan 2004 16:54:34 +0000 (16:54 +0000)
From-SVN: r76212

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

index fd010153d14eb5bd4a2ad27b05ae2851ca661eb9..9577cda1a32a43d98e260f2bba4197a81e43a19f 100644 (file)
@@ -1,3 +1,7 @@
+2004-01-20  Hartmut Penner  <hpenner@de.ibm.com>
+
+       * gcc.dg/ppc64-abi-2.c: New test.
+
 2004-01-18  James A. Morrison  <ja2morri@uwaterloo.ca>
 
         * lib/treelang.exp: Fill out this file.
diff --git a/gcc/testsuite/gcc.dg/ppc64-abi-2.c b/gcc/testsuite/gcc.dg/ppc64-abi-2.c
new file mode 100644 (file)
index 0000000..ab0e1a1
--- /dev/null
@@ -0,0 +1,405 @@
+/* { dg-do run { target powerpc64-*-linux* } } */
+/* { dg-options "-O2 -fprofile -mprofile-kernel -maltivec -mabi=altivec" } */
+#include <stdarg.h>
+#include <signal.h>
+#include <altivec.h>
+
+/* Testcase to check for ABI compliance of parameter passing
+   for the PowerPC64 ABI.  */
+
+void __attribute__((no_instrument_function))
+sig_ill_handler (int sig)
+{
+    exit(0);
+}
+
+extern void abort (void);
+
+typedef struct
+{
+  unsigned long gprs[8];
+  double fprs[13];
+  long pad;
+  vector int vrs[12];
+} reg_parms_t;
+
+reg_parms_t gparms;
+
+/* _mcount call is done on Linux ppc64 early in the prologue.
+   my_mcount will provide a entry point _mcount,
+   which will save all register to gparms. 
+   Note that _mcount need to restore lr to original value,
+   therefor use ctr to return.  
+*/
+
+void __attribute__((no_instrument_function))
+my_mcount() 
+{
+  asm volatile (".type _mcount,@function\n\t"
+               ".globl _mcount\n\t"
+               "_mcount:\n\t"
+                "mflr 0\n\t"
+                "mtctr 0\n\t"
+                "ld 0,16(1)\n\t"
+               "mtlr 0\n\t"
+               "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" 
+               "li 3,176\n\t"        
+               "stvx 2,3,11\n\t"       
+               "addi 3,3,16\n\t" 
+               "stvx 3,3,11\n\t"       
+               "addi 3,3,16\n\t"     
+               "stvx 4,3,11\n\t"       
+               "addi 3,3,16\n\t"     
+               "stvx 5,3,11\n\t"       
+               "addi 3,3,16\n\t"     
+               "stvx 6,3,11\n\t"       
+               "addi 3,3,16\n\t"     
+               "stvx 7,3,11\n\t"       
+               "addi 3,3,16\n\t"     
+               "stvx 8,3,11\n\t"       
+               "addi 3,3,16\n\t"     
+               "stvx 9,3,11\n\t"       
+               "addi 3,3,16\n\t"     
+               "stvx 10,3,11\n\t"      
+               "addi 3,3,16\n\t"     
+               "stvx 11,3,11\n\t"      
+               "addi 3,3,16\n\t"     
+               "stvx 12,3,11\n\t"      
+               "addi 3,3,16\n\t"     
+               "stvx 13,3,11\n\t"      
+               "ld 3,0(11)\n\t"
+               "bctr");
+}
+
+/* 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;
+
+typedef union
+{
+  unsigned int i[4];
+  unsigned long l[2];
+  vector int v;
+} vector_int_t;
+
+/* Paramter passing.
+   s : gpr 3
+   v : vpr 2
+   i : gpr 7
+*/
+void __attribute__ ((noinline))
+fcvi (char *s, vector int v, int i)
+{
+  reg_parms_t lparms = gparms;
+
+  if (s != (char *) lparms.gprs[0])
+    abort();
+
+  if (!vec_all_eq (v, lparms.vrs[0]))
+    abort ();
+
+  if ((long) i != lparms.gprs[4])
+    abort();
+}
+/* Paramter passing.
+   s : gpr 3
+   v : vpr 2
+   w : vpr 3
+*/
+
+void __attribute__ ((noinline))
+fcvv (char *s, vector int v, vector int w)
+{
+  vector int a, c = {6, 8, 10, 12};
+  reg_parms_t lparms = gparms;
+
+  if (s != (char *) lparms.gprs[0])
+    abort();
+
+  if (!vec_all_eq (v, lparms.vrs[0]))
+    abort ();
+
+  if (!vec_all_eq (w, lparms.vrs[1]))
+    abort ();
+
+  a = vec_add (v,w);
+
+  if (!vec_all_eq (a, c))
+    abort ();
+}
+
+/* Paramter passing.
+   s : gpr 3
+   i : gpr 4
+   v : vpr 2
+   w : vpr 3
+*/
+void __attribute__ ((noinline))
+fcivv (char *s, int i, vector int v, vector int w)
+{
+  vector int a, c = {6, 8, 10, 12};
+  reg_parms_t lparms = gparms;
+
+  if (s != (char *) lparms.gprs[0])
+    abort();
+
+  if ((long) i != lparms.gprs[1])
+    abort();
+
+  if (!vec_all_eq (v, lparms.vrs[0]))
+    abort ();
+
+  if (!vec_all_eq (w, lparms.vrs[1]))
+    abort ();
+
+  a = vec_add (v,w);
+  
+  if (!vec_all_eq (a, c))
+    abort ();
+}
+
+/* Paramter passing.
+   s : gpr 3
+   v : slot 2-3
+   w : slot 4-5
+*/
+
+void __attribute__ ((noinline))
+fcevv (char *s, ...)
+{
+  vector int a, c = {6, 8, 10, 12};
+  vector int v,w;
+  stack_frame_t *sp;
+  reg_parms_t lparms = gparms;
+  va_list arg;
+
+  va_start (arg, s);
+
+  if (s != (char *) lparms.gprs[0])
+    abort();
+
+  v = va_arg(arg, vector int);
+  w = va_arg(arg, vector int);
+  a = vec_add (v,w);
+  
+  if (!vec_all_eq (a, c))
+    abort ();
+
+  /* Go back one frame.  */
+  sp = __builtin_frame_address(0);
+  sp = sp->backchain;
+  
+  if (sp->slot[2].l != 0x100000002ULL
+      || sp->slot[4].l != 0x500000006ULL)
+    abort();
+}
+
+/* Paramter passing.
+   s : gpr 3
+   i : gpr 4
+   j : gpr 5
+   v : slot 4-5
+   w : slot 6-7
+*/
+void __attribute__ ((noinline))
+fciievv (char *s, int i, int j, ...)
+{
+  vector int a, c = {6, 8, 10, 12};
+  vector int v,w;
+  stack_frame_t *sp;
+  reg_parms_t lparms = gparms;
+  va_list arg;
+
+  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();
+  
+  v = va_arg(arg, vector int);
+  w = va_arg(arg, vector int);
+  a = vec_add (v,w);
+  
+  if (!vec_all_eq (a, c))
+    abort ();
+
+  sp = __builtin_frame_address(0);
+  sp = sp->backchain;
+  
+  if (sp->slot[4].l != 0x100000002ULL
+      || sp->slot[6].l != 0x500000006ULL)
+    abort();
+}
+
+void __attribute__ ((noinline))
+fcvevv (char *s, vector int x, ...)
+{
+  vector int a, c = {7, 10, 13, 16};
+  vector int v,w;
+  stack_frame_t *sp;
+  reg_parms_t lparms = gparms;
+  va_list arg;
+
+  va_start (arg, x);
+  
+  v = va_arg(arg, vector int);
+  w = va_arg(arg, vector int);
+
+  a = vec_add (v,w);
+  a = vec_add (a, x);
+  if (!vec_all_eq (a, c))
+    abort ();
+
+  sp = __builtin_frame_address(0);
+  sp = sp->backchain;
+  
+  if (sp->slot[4].l != 0x100000002ULL
+      || sp->slot[6].l != 0x500000006ULL)
+    abort();
+}
+
+void fnp_cvvvv();
+
+int __attribute__((no_instrument_function, noinline))
+main1() 
+{   
+  char *s = "vv";
+  vector int v = {1, 2, 3, 4};
+  vector int w = {5, 6, 7, 8};
+  fcvi (s, v, 2);
+  fcvv (s, v, w);
+  fnp_cvvvv (s, v, w, v, w);
+  fcivv (s, 1, v, w);
+  fcevv (s, v, w);
+  fciievv (s, 1, 2, v, w);
+  fcvevv (s, v, v, w);
+  return 0;
+}
+
+int __attribute__((no_instrument_function)) 
+main()
+{
+  /* Exit on systems without altivec.  */
+  signal (SIGILL, sig_ill_handler);
+  /* Altivec instruction, 'vor %v0,%v0,%v0'.  */
+  asm volatile (".long 0x10000484");
+  signal (SIGILL, SIG_DFL);
+
+  return main1 ();
+}
+
+/* Paramter passing.
+   Function called with no prototype.
+   s : gpr 3
+   v : vpr 2 gpr 5-6
+   w : vpr 3 gpr 7-8
+   x : vpr 4 gpr 9-10
+   y : vpr 5 slot 8-9
+*/
+void
+fnp_cvvvv (char *s, vector int v, vector int w,
+          vector int x, vector int y)
+{
+  vector int a, c = {12, 16, 20, 24};
+  reg_parms_t lparms = gparms;
+  stack_frame_t *sp;
+  vector_int_t v0, v1, v2, v3;
+
+  if (s != (char *) lparms.gprs[0])
+    abort();
+
+  if (!vec_all_eq (v, lparms.vrs[0]))
+    abort ();
+
+  if (!vec_all_eq (w, lparms.vrs[1]))
+    abort ();
+
+  if (!vec_all_eq (x, lparms.vrs[2]))
+    abort ();
+
+  if (!vec_all_eq (y, lparms.vrs[3]))
+    abort ();
+
+  a = vec_add (v,w);
+  a = vec_add (a,x);  
+  a = vec_add (a,y);  
+  
+  if (!vec_all_eq (a, c))
+    abort ();
+  
+  v0.v = lparms.vrs[0];
+  v1.v = lparms.vrs[1];
+  v2.v = lparms.vrs[2];
+  v3.v = lparms.vrs[3];
+
+  if (v0.l[0] != lparms.gprs[2])
+    abort ();
+
+  if (v0.l[1] != lparms.gprs[3])
+    abort ();
+
+  if (v1.l[0] != lparms.gprs[4])
+    abort ();
+
+  if (v1.l[1] != lparms.gprs[5])
+    abort ();
+
+  if (v2.l[0] != lparms.gprs[6])
+    abort ();
+
+  if (v2.l[1] != lparms.gprs[7])
+    abort ();
+
+  sp = __builtin_frame_address(0);
+  sp = sp->backchain;
+  
+  if (sp->slot[8].l != v3.l[0])
+    abort ();
+
+  if (sp->slot[9].l != v3.l[1])
+    abort ();
+}  
+