aboutsummaryrefslogtreecommitdiffstats
path: root/gcc-4.8.1/gcc/testsuite/gcc.target/powerpc/ppc64-abi-1.c
diff options
context:
space:
mode:
authorDan Albert <danalbert@google.com>2016-01-14 16:43:34 -0800
committerDan Albert <danalbert@google.com>2016-01-22 14:51:24 -0800
commit3186be22b6598fbd467b126347d1c7f48ccb7f71 (patch)
tree2b176d3ce027fa5340160978effeb88ec9054aaa /gcc-4.8.1/gcc/testsuite/gcc.target/powerpc/ppc64-abi-1.c
parenta45222a0e5951558bd896b0513bf638eb376e086 (diff)
downloadtoolchain_gcc-3186be22b6598fbd467b126347d1c7f48ccb7f71.tar.gz
toolchain_gcc-3186be22b6598fbd467b126347d1c7f48ccb7f71.tar.bz2
toolchain_gcc-3186be22b6598fbd467b126347d1c7f48ccb7f71.zip
Check in a pristine copy of GCC 4.8.1.
The copy of GCC that we use for Android is still not working for mingw. Rather than finding all the differences that have crept into our GCC, just check in a copy from ftp://ftp.gnu.org/gnu/gcc/gcc-4.9.3/gcc-4.8.1.tar.bz2. GCC 4.8.1 was chosen because it is what we have been using for mingw thus far, and the emulator doesn't yet work when upgrading to 4.9. Bug: http://b/26523949 Change-Id: Iedc0f05243d4332cc27ccd46b8a4b203c88dcaa3
Diffstat (limited to 'gcc-4.8.1/gcc/testsuite/gcc.target/powerpc/ppc64-abi-1.c')
-rw-r--r--gcc-4.8.1/gcc/testsuite/gcc.target/powerpc/ppc64-abi-1.c364
1 files changed, 364 insertions, 0 deletions
diff --git a/gcc-4.8.1/gcc/testsuite/gcc.target/powerpc/ppc64-abi-1.c b/gcc-4.8.1/gcc/testsuite/gcc.target/powerpc/ppc64-abi-1.c
new file mode 100644
index 000000000..8fcb7fd7f
--- /dev/null
+++ b/gcc-4.8.1/gcc/testsuite/gcc.target/powerpc/ppc64-abi-1.c
@@ -0,0 +1,364 @@
+/* { dg-do run { target { powerpc*-*-* && lp64 } } } */
+/* { dg-skip-if "" { *-*-darwin* } { "*" } { "" } } */
+/* { 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;
+}