Commit 8628d6e6 by Martin Sebor Committed by Jeff Law

re PR target/65109 (r220674 causes FAIL: gcc.target/powerpc/ppc64-abi-1.c execution test)

	PR target/65109
	* gcc.target/powerpc/ppc64-abi-1.c: Split test functions into
	two parts.  One to save registers, the other to verify the
	registers have the right values.  Save register state into
	static data rather than on the stack.

From-SVN: r220920
parent 86ee2038
2015-02-23 Martin Sebor <msebor@redhat.com>
PR target/65109
* gcc.target/powerpc/ppc64-abi-1.c: Split test functions into
two parts. One to save registers, the other to verify the
registers have the right values. Save register state into
static data rather than on the stack.
2015-02-20 Jakub Jelinek <jakub@redhat.com> 2015-02-20 Jakub Jelinek <jakub@redhat.com>
PR bootstrap/63888 PR bootstrap/63888
......
/* { dg-do run { target { powerpc*-*-* && lp64 } } } */ /* { dg-do run { target { powerpc*-*-* && lp64 } } } */
/* { dg-skip-if "" { *-*-darwin* } { "*" } { "" } } */ /* { dg-skip-if "" { *-*-darwin* } { "*" } { "" } } */
/* { dg-options "-O2" } */ /* { dg-options "-O2" } */
#include <stdarg.h>
#include <signal.h> typedef __builtin_va_list va_list;
#include <stdio.h> #define va_start(ap, arg) __builtin_va_start (ap, arg)
#define va_arg(ap, type) __builtin_va_arg (ap, type)
/* Testcase to check for ABI compliance of parameter passing /* Testcase to check for ABI compliance of parameter passing
for the PowerPC64 ABI. for the PowerPC64 ABI.
...@@ -17,64 +18,68 @@ typedef struct ...@@ -17,64 +18,68 @@ typedef struct
double fprs[13]; double fprs[13];
} reg_parms_t; } reg_parms_t;
reg_parms_t gparms; volatile reg_parms_t gparms;
/* Testcase could break on future gcc's, if parameter regs /* Testcase could break on future gcc's, if parameter regs are changed
are changed before this asm. */ before this asm. To minimize the risk of that happening the test
consists of two sets of functions wih identical signatures:
foo, which does nothing except save function argument registers
to prevent them from getting clobbered (see PR65109),
foo_check, which verifies that the values of function registers
saved by foo match those passed to foo_check by the caller. */
#ifndef __MACH__ #ifndef __MACH__
#define save_parms(lparms) \ #define save_parms() \
asm volatile ("ld 11,gparms@got(2)\n\t" \ asm volatile ("ld 11,gparms@got(2)\n\t" \
"std 3,0(11)\n\t" \ "std 3,0(11)\n\t" \
"std 4,8(11)\n\t" \ "std 4,8(11)\n\t" \
"std 5,16(11)\n\t" \ "std 5,16(11)\n\t" \
"std 6,24(11)\n\t" \ "std 6,24(11)\n\t" \
"std 7,32(11)\n\t" \ "std 7,32(11)\n\t" \
"std 8,40(11)\n\t" \ "std 8,40(11)\n\t" \
"std 9,48(11)\n\t" \ "std 9,48(11)\n\t" \
"std 10,56(11)\n\t" \ "std 10,56(11)\n\t" \
"stfd 1,64(11)\n\t" \ "stfd 1,64(11)\n\t" \
"stfd 2,72(11)\n\t" \ "stfd 2,72(11)\n\t" \
"stfd 3,80(11)\n\t" \ "stfd 3,80(11)\n\t" \
"stfd 4,88(11)\n\t" \ "stfd 4,88(11)\n\t" \
"stfd 5,96(11)\n\t" \ "stfd 5,96(11)\n\t" \
"stfd 6,104(11)\n\t" \ "stfd 6,104(11)\n\t" \
"stfd 7,112(11)\n\t" \ "stfd 7,112(11)\n\t" \
"stfd 8,120(11)\n\t" \ "stfd 8,120(11)\n\t" \
"stfd 9,128(11)\n\t" \ "stfd 9,128(11)\n\t" \
"stfd 10,136(11)\n\t" \ "stfd 10,136(11)\n\t" \
"stfd 11,144(11)\n\t" \ "stfd 11,144(11)\n\t" \
"stfd 12,152(11)\n\t" \ "stfd 12,152(11)\n\t" \
"stfd 13,160(11)\n\t":::"11", "memory"); \ "stfd 13,160(11)\n\t":::"11", "memory")
lparms = gparms;
#else #else
#define save_parms(lparms) \ #define save_parms() \
asm volatile ("ld r11,gparms@got(r2)\n\t" \ asm volatile ("ld r11,gparms@got(r2)\n\t" \
"std r3,0(r11)\n\t" \ "std r3,0(r11)\n\t" \
"std r4,8(r11)\n\t" \ "std r4,8(r11)\n\t" \
"std r5,16(r11)\n\t" \ "std r5,16(r11)\n\t" \
"std r6,24(r11)\n\t" \ "std r6,24(r11)\n\t" \
"std r7,32(r11)\n\t" \ "std r7,32(r11)\n\t" \
"std r8,40(r11)\n\t" \ "std r8,40(r11)\n\t" \
"std r9,48(r11)\n\t" \ "std r9,48(r11)\n\t" \
"std r10,56(r11)\n\t" \ "std r10,56(r11)\n\t" \
"stfd f1,64(r11)\n\t" \ "stfd f1,64(r11)\n\t" \
"stfd f2,72(r11)\n\t" \ "stfd f2,72(r11)\n\t" \
"stfd f3,80(r11)\n\t" \ "stfd f3,80(r11)\n\t" \
"stfd f4,88(r11)\n\t" \ "stfd f4,88(r11)\n\t" \
"stfd f5,96(r11)\n\t" \ "stfd f5,96(r11)\n\t" \
"stfd f6,104(r11)\n\t" \ "stfd f6,104(r11)\n\t" \
"stfd f7,112(r11)\n\t" \ "stfd f7,112(r11)\n\t" \
"stfd f8,120(r11)\n\t" \ "stfd f8,120(r11)\n\t" \
"stfd f9,128(r11)\n\t" \ "stfd f9,128(r11)\n\t" \
"stfd f10,136(r11)\n\t" \ "stfd f10,136(r11)\n\t" \
"stfd f11,144(r11)\n\t" \ "stfd f11,144(r11)\n\t" \
"stfd f12,152(r11)\n\t" \ "stfd f12,152(r11)\n\t" \
"stfd f13,160(r11)\n\t":::"r11", "memory"); \ "stfd f13,160(r11)\n\t":::"r11", "memory")
lparms = gparms;
#endif #endif
/* Stackframe structure relevant for parameter passing. */ /* Stackframe structure relevant for parameter passing. */
typedef union typedef union
{ {
...@@ -104,16 +109,18 @@ typedef struct sf ...@@ -104,16 +109,18 @@ typedef struct sf
*/ */
void __attribute__ ((noinline)) fcld (char *s, long l, double d) void __attribute__ ((noinline)) fcld (char *s, long l, double d)
{ {
reg_parms_t lparms; save_parms ();
save_parms (lparms);
if (s != (char *) lparms.gprs[0]) }
void __attribute__ ((noinline)) fcld_check (char *s, long l, double d)
{
if (s != (char *) gparms.gprs[0])
abort (); abort ();
if (l != lparms.gprs[1]) if (l != gparms.gprs[1])
abort (); abort ();
if (d != lparms.fprs[0]) if (d != gparms.fprs[0])
abort (); abort ();
} }
...@@ -126,19 +133,22 @@ void __attribute__ ((noinline)) fcld (char *s, long l, double d) ...@@ -126,19 +133,22 @@ void __attribute__ ((noinline)) fcld (char *s, long l, double d)
void __attribute__ ((noinline)) void __attribute__ ((noinline))
fcldi (char *s, long l, double d, signed int i) fcldi (char *s, long l, double d, signed int i)
{ {
reg_parms_t lparms; save_parms ();
save_parms (lparms); }
if (s != (char *) lparms.gprs[0]) void __attribute__ ((noinline))
fcldi_check (char *s, long l, double d, signed int i)
{
if (s != (char *) gparms.gprs[0])
abort (); abort ();
if (l != lparms.gprs[1]) if (l != gparms.gprs[1])
abort (); abort ();
if (d != lparms.fprs[0]) if (d != gparms.fprs[0])
abort (); abort ();
if ((signed long) i != lparms.gprs[3]) if ((signed long) i != gparms.gprs[3])
abort (); abort ();
} }
...@@ -151,19 +161,22 @@ fcldi (char *s, long l, double d, signed int i) ...@@ -151,19 +161,22 @@ fcldi (char *s, long l, double d, signed int i)
void __attribute__ ((noinline)) void __attribute__ ((noinline))
fcldu (char *s, long l, float d, unsigned int i) fcldu (char *s, long l, float d, unsigned int i)
{ {
reg_parms_t lparms; save_parms ();
save_parms (lparms); }
if (s != (char *) lparms.gprs[0]) void __attribute__ ((noinline))
fcldu_check (char *s, long l, float d, unsigned int i)
{
if (s != (char *) gparms.gprs[0])
abort (); abort ();
if (l != lparms.gprs[1]) if (l != gparms.gprs[1])
abort (); abort ();
if ((double) d != lparms.fprs[0]) if ((double) d != gparms.fprs[0])
abort (); abort ();
if ((unsigned long) i != lparms.gprs[3]) if ((unsigned long) i != gparms.gprs[3])
abort (); abort ();
} }
...@@ -172,19 +185,21 @@ fcldu (char *s, long l, float d, unsigned int i) ...@@ -172,19 +185,21 @@ fcldu (char *s, long l, float d, unsigned int i)
l : slot 1 l : slot 1
d : slot 2 d : slot 2
*/ */
void __attribute__ ((noinline)) fceld (char *s, ...) void __attribute__ ((noinline)) fceld (char *s, ...)
{ {
save_parms ();
}
void __attribute__ ((noinline)) fceld_check (char *s, ...)
{
stack_frame_t *sp; stack_frame_t *sp;
reg_parms_t lparms;
va_list arg; va_list arg;
double d; double d;
long l; long l;
save_parms (lparms);
va_start (arg, s); va_start (arg, s);
if (s != (char *) lparms.gprs[0]) if (s != (char *) gparms.gprs[0])
abort (); abort ();
l = va_arg (arg, long); l = va_arg (arg, long);
...@@ -210,22 +225,25 @@ void __attribute__ ((noinline)) fceld (char *s, ...) ...@@ -210,22 +225,25 @@ void __attribute__ ((noinline)) fceld (char *s, ...)
*/ */
void __attribute__ ((noinline)) fciiedl (char *s, int i, int j, ...) void __attribute__ ((noinline)) fciiedl (char *s, int i, int j, ...)
{ {
save_parms ();
}
void __attribute__ ((noinline)) fciiedl_check (char *s, int i, int j, ...)
{
stack_frame_t *sp; stack_frame_t *sp;
reg_parms_t lparms;
va_list arg; va_list arg;
double d; double d;
long l; long l;
save_parms (lparms);
va_start (arg, j); va_start (arg, j);
if (s != (char *) lparms.gprs[0]) if (s != (char *) gparms.gprs[0])
abort (); abort ();
if ((long) i != lparms.gprs[1]) if ((long) i != gparms.gprs[1])
abort (); abort ();
if ((long) j != lparms.gprs[2]) if ((long) j != gparms.gprs[2])
abort (); abort ();
d = va_arg (arg, double); d = va_arg (arg, double);
...@@ -287,35 +305,39 @@ void __attribute__ ((noinline)) ...@@ -287,35 +305,39 @@ void __attribute__ ((noinline))
fididisdsid (int c, double ff, int d, double ld, int f, fididisdsid (int c, double ff, int d, double ld, int f,
sparm s, double gg, sparm t, int e, double hh) sparm s, double gg, sparm t, int e, double hh)
{ {
save_parms ();
}
void
fididisdsid_check (int c, double ff, int d, double ld, int f,
sparm s, double gg, sparm t, int e, double hh)
{
stack_frame_t *sp; stack_frame_t *sp;
reg_parms_t lparms;
double_t dx, dy; double_t dx, dy;
save_parms (lparms);
/* Parm 0: int. */ /* Parm 0: int. */
if ((long) c != lparms.gprs[0]) if ((long) c != gparms.gprs[0])
abort (); abort ();
/* Parm 1: double. */ /* Parm 1: double. */
if (ff != lparms.fprs[0]) if (ff != gparms.fprs[0])
abort (); abort ();
/* Parm 2: int. */ /* Parm 2: int. */
if ((long) d != lparms.gprs[2]) if ((long) d != gparms.gprs[2])
abort (); abort ();
/* Parm 3: double. */ /* Parm 3: double. */
if (ld != lparms.fprs[1]) if (ld != gparms.fprs[1])
abort (); abort ();
/* Parm 4: int. */ /* Parm 4: int. */
if ((long) f != lparms.gprs[4]) if ((long) f != gparms.gprs[4])
abort (); abort ();
/* Parm 5: struct sparm. */ /* Parm 5: struct sparm. */
dx.l = lparms.gprs[5]; dx.l = gparms.gprs[5];
dy.l = lparms.gprs[6]; dy.l = gparms.gprs[6];
if (s.a != dx.i[0]) if (s.a != dx.i[0])
abort (); abort ();
...@@ -323,11 +345,10 @@ fididisdsid (int c, double ff, int d, double ld, int f, ...@@ -323,11 +345,10 @@ fididisdsid (int c, double ff, int d, double ld, int f,
abort (); abort ();
/* Parm 6: double. */ /* Parm 6: double. */
if (gg != lparms.fprs[2]) if (gg != gparms.fprs[2])
abort (); abort ();
sp = __builtin_frame_address (0); sp = ((stack_frame_t*)__builtin_frame_address (0))->backchain;
sp = sp->backchain;
/* Parm 7: struct sparm. */ /* Parm 7: struct sparm. */
dx.l = sp->slot[8].l; dx.l = sp->slot[8].l;
...@@ -343,7 +364,7 @@ fididisdsid (int c, double ff, int d, double ld, int f, ...@@ -343,7 +364,7 @@ fididisdsid (int c, double ff, int d, double ld, int f,
/* Parm 9: double. */ /* Parm 9: double. */
if (hh != lparms.fprs[3]) if (hh != gparms.fprs[3])
abort (); abort ();
} }
...@@ -352,15 +373,17 @@ main () ...@@ -352,15 +373,17 @@ main ()
{ {
char *s = "ii"; char *s = "ii";
fcld (s, 1, 1.0); #define ABI_CHECK(func, args) \
fcldi (s, 1, 1.0, -2); func args, func ## _check args
fcldu (s, 1, 1.0, 2);
fceld (s, 1, 1.0); ABI_CHECK (fcld, (s, 1, 1.0));
fciiedl (s, 1, 2, 1.0, 3); ABI_CHECK (fcldi, (s, 1, 1.0, -2));
fididisdsid (1, 1.0, 2, 2.0, -1, (sparm) ABI_CHECK (fcldu, (s, 1, 1.0, 2));
{ ABI_CHECK (fceld, (s, 1, 1.0));
3, 3.0}, 4.0, (sparm) ABI_CHECK (fciiedl, (s, 1, 2, 1.0, 3));
{ ABI_CHECK (fididisdsid, (1, 1.0, 2, 2.0, -1,
5, 5.0}, 6, 7.0); (sparm){3, 3.0}, 4.0, (sparm){5, 5.0},
6, 7.0));
return 0; return 0;
} }
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment