diff options
author | Ben Cheng <bccheng@google.com> | 2014-03-25 22:37:19 -0700 |
---|---|---|
committer | Ben Cheng <bccheng@google.com> | 2014-03-25 22:37:19 -0700 |
commit | 1bc5aee63eb72b341f506ad058502cd0361f0d10 (patch) | |
tree | c607e8252f3405424ff15bc2d00aa38dadbb2518 /gcc-4.9/gcc/testsuite/gcc.target/s390 | |
parent | 283a0bf58fcf333c58a2a92c3ebbc41fb9eb1fdb (diff) | |
download | toolchain_gcc-1bc5aee63eb72b341f506ad058502cd0361f0d10.tar.gz toolchain_gcc-1bc5aee63eb72b341f506ad058502cd0361f0d10.tar.bz2 toolchain_gcc-1bc5aee63eb72b341f506ad058502cd0361f0d10.zip |
Initial checkin of GCC 4.9.0 from trunk (r208799).
Change-Id: I48a3c08bb98542aa215912a75f03c0890e497dba
Diffstat (limited to 'gcc-4.9/gcc/testsuite/gcc.target/s390')
56 files changed, 3611 insertions, 0 deletions
diff --git a/gcc-4.9/gcc/testsuite/gcc.target/s390/20020926-1.c b/gcc-4.9/gcc/testsuite/gcc.target/s390/20020926-1.c new file mode 100644 index 000000000..aaa134276 --- /dev/null +++ b/gcc-4.9/gcc/testsuite/gcc.target/s390/20020926-1.c @@ -0,0 +1,14 @@ +/* Make sure that LEGITIMIZE_ADDRESS is called to handle + negative displacements. */ + +/* { dg-do compile { target { s390-*-* } } } */ +/* { dg-options "-O2 -mesa" } */ + +int test (int *addr) +{ + return *(addr - 1); +} + +/* { dg-final { scan-assembler "-4096" } } */ +/* { dg-final { scan-assembler-not "ahi" } } */ + diff --git a/gcc-4.9/gcc/testsuite/gcc.target/s390/20030123-1.c b/gcc-4.9/gcc/testsuite/gcc.target/s390/20030123-1.c new file mode 100644 index 000000000..c426866fd --- /dev/null +++ b/gcc-4.9/gcc/testsuite/gcc.target/s390/20030123-1.c @@ -0,0 +1,19 @@ +/* This used to ICE due to a reload bug on s390*. */ + +/* { dg-do compile } */ +/* { dg-options "-O2 -fno-omit-frame-pointer" } */ + +extern void *alloca (__SIZE_TYPE__); + +void func (char *p); + +void test (void) +{ + char *p = alloca (4096); + long idx; + + asm volatile ("" : "=r" (idx) : : "1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "12"); + + func (p + idx + 1); +} + diff --git a/gcc-4.9/gcc/testsuite/gcc.target/s390/20030129-1.c b/gcc-4.9/gcc/testsuite/gcc.target/s390/20030129-1.c new file mode 100644 index 000000000..1cbd8b482 --- /dev/null +++ b/gcc-4.9/gcc/testsuite/gcc.target/s390/20030129-1.c @@ -0,0 +1,37 @@ +/* This used to ICE due to a reload bug on s390*. */ + +/* { dg-do compile } */ +/* { dg-options "-O2" } */ + +int f (unsigned int); +void g (void *); + +void test (void *p, void *dummy) +{ + unsigned int flags = 0; + + if (dummy) + g (dummy); + + if (p) + flags |= 0x80000000; + + asm volatile ("" : : : "1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12"); + + if (dummy) + g (dummy); + + if (p) + { + flags |= 0x20000000|0x80000000; + + if (!f (0)) + flags &= ~0x80000000; + } + + f (flags); + + if (dummy) + g (dummy); +} + diff --git a/gcc-4.9/gcc/testsuite/gcc.target/s390/20040305-1.c b/gcc-4.9/gcc/testsuite/gcc.target/s390/20040305-1.c new file mode 100644 index 000000000..a241f041c --- /dev/null +++ b/gcc-4.9/gcc/testsuite/gcc.target/s390/20040305-1.c @@ -0,0 +1,53 @@ + +/* The testcase failed due to corrupted alias information. + During the crossjump analyzing step the mem alias info of the + st instructions are merged and get copied during basic block + reordering which leads to an insn with wrong alias info. + The scheduler afterwards exchanges the mvc and st instructions + not recognizing the anti dependence. */ +/* { dg-do run } */ +/* { dg-options "-O3 -mtune=z990 -fno-inline" } */ + +extern void exit (int); +extern void abort (void); + +int f; +int g; +int h; + +int* x = &f; +int* p1 = &g; +int* p2 = &h; + +int +foo(void) +{ + + if (*x == 0) + { + x = p1; /* mvc - memory to memory */ + p1 = (int*)0; /* st - register to memory */ + return 1; + } + if (*x == 5) + { + f = 1; + g = 2; + + p2 = (int*)0; /* st */ + return 1; + } +} + +int +main (int argc, char** argv) +{ + foo (); + + /* If the scheduler has exchanged the mvc and st instructions, + x is 0. The expected result is &g. */ + if (x == &g) + exit (0); + else + abort (); +} diff --git a/gcc-4.9/gcc/testsuite/gcc.target/s390/20041109-1.c b/gcc-4.9/gcc/testsuite/gcc.target/s390/20041109-1.c new file mode 100644 index 000000000..bf768439c --- /dev/null +++ b/gcc-4.9/gcc/testsuite/gcc.target/s390/20041109-1.c @@ -0,0 +1,21 @@ +/* This used to ICE due to a literal pool handling bug on s390x. */ + +/* { dg-do compile } */ +/* { dg-options "-O2 -fno-omit-frame-pointer" } */ + +static struct table { int x; } table[3]; + +int test (void) +{ + struct table *t; + + for (t = table; t < &table[3]; t++) + asm volatile ("" : : : "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "12"); + + for (t = table; t < &table[3]; t++) + if (t->x) + return 1; + + return 0; +} + diff --git a/gcc-4.9/gcc/testsuite/gcc.target/s390/20041216-1.c b/gcc-4.9/gcc/testsuite/gcc.target/s390/20041216-1.c new file mode 100644 index 000000000..492ee6c18 --- /dev/null +++ b/gcc-4.9/gcc/testsuite/gcc.target/s390/20041216-1.c @@ -0,0 +1,23 @@ +/* This test case would get an unresolved symbol during link + because stabs referred to an optimized-away literal pool + entry. */ + +/* { dg-do run } */ +/* { dg-options "-O2 -fno-omit-frame-pointer -gstabs" } */ + +int main (void) +{ + static char buf[4096]; + char *p; + + do + { + p = buf; + asm volatile ("" : : : "memory", "0", "1", "2", "3", "4", "5", "6", + "7", "8", "9", "10", "12"); + } + while (*p); + + return 0; +} + diff --git a/gcc-4.9/gcc/testsuite/gcc.target/s390/20050409-1.c b/gcc-4.9/gcc/testsuite/gcc.target/s390/20050409-1.c new file mode 100644 index 000000000..4763afad3 --- /dev/null +++ b/gcc-4.9/gcc/testsuite/gcc.target/s390/20050409-1.c @@ -0,0 +1,18 @@ +/* This used to ICE due to a regmove problem on s390. */ + +/* { dg-do compile } */ +/* { dg-options "-O2" } */ + + +extern void abort (void); +extern void **alloc (void); + +void *test (void) +{ + void **p = alloc (); + if (!p) abort (); + + __builtin_set_thread_pointer (p); + return *p; +} + diff --git a/gcc-4.9/gcc/testsuite/gcc.target/s390/20050524-1.c b/gcc-4.9/gcc/testsuite/gcc.target/s390/20050524-1.c new file mode 100644 index 000000000..7b94fd0f0 --- /dev/null +++ b/gcc-4.9/gcc/testsuite/gcc.target/s390/20050524-1.c @@ -0,0 +1,34 @@ +/* This test case used to abort due to a reload bug with + elimination offsets. */ + +/* { dg-do run } */ +/* { dg-options "-O2 -mpacked-stack" } */ + +extern void abort (void); + +double bar (double) __attribute__ ((noinline)); +double bar (double x) { return x; } + +double +foo (int j, double f0, double f2, double f4, double f6, double x) __attribute__ ((noinline)); + +double +foo (int j, double f0, double f2, double f4, double f6, double x) +{ + if (j) + return bar (x) + 4.0; + else + return bar (x); +} + +int +main (void) +{ + if (foo (0, 0, 0, 0, 0, 10) != 10) + abort (); + if (foo (1, 0, 0, 0, 0, 10) != 14) + abort (); + + return 0; +} + diff --git a/gcc-4.9/gcc/testsuite/gcc.target/s390/20050824-1.c b/gcc-4.9/gcc/testsuite/gcc.target/s390/20050824-1.c new file mode 100644 index 000000000..c24e1e26f --- /dev/null +++ b/gcc-4.9/gcc/testsuite/gcc.target/s390/20050824-1.c @@ -0,0 +1,34 @@ +/* Make sure that the S/390 specific shift_count_operand + predicate work properly. */ + +/* { dg-do compile } */ +/* { dg-options "-O3" } */ + +unsigned long long +f (unsigned long long a, unsigned long b) +{ + asm ("" : : : +#ifdef __s390x__ + "r13", "r14", +#endif + "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", + "r8", "r9", "r10", "r11", "r12"); + + return a << ((b + 3) & 63); +} + +unsigned long long +g (unsigned long long a, char **b , int c, int d, int e, int f) +{ + char buffer [4096]; + + *b = &buffer[0]; + + return a << ((unsigned long)&f & 63); +} + +unsigned long long +h (unsigned long long a, int b, int c, int d, int e, int f) +{ + return a << (((unsigned long)&f + 3)); +} diff --git a/gcc-4.9/gcc/testsuite/gcc.target/s390/20071212-1.c b/gcc-4.9/gcc/testsuite/gcc.target/s390/20071212-1.c new file mode 100644 index 000000000..e5d05ad41 --- /dev/null +++ b/gcc-4.9/gcc/testsuite/gcc.target/s390/20071212-1.c @@ -0,0 +1,11 @@ +/* This used to fail due to bug in the On constraint causing a slgfi + to be emitted with an immediate not fitting into 32bit. */ + +/* { dg-do compile } */ +/* { dg-options "-O3 -march=z9-109" } */ + +long +foo (long a) +{ + return a - (1ULL << 32); +} diff --git a/gcc-4.9/gcc/testsuite/gcc.target/s390/20090223-1.c b/gcc-4.9/gcc/testsuite/gcc.target/s390/20090223-1.c new file mode 100644 index 000000000..1bf0f2fe8 --- /dev/null +++ b/gcc-4.9/gcc/testsuite/gcc.target/s390/20090223-1.c @@ -0,0 +1,60 @@ +/* The RTL loop optimizer used to replace the output register of the + inline assembly with a pseudo although the variable is declared as + register asm ("0"). */ + +/* { dg-do run } */ +/* { dg-options "-O2 -Wno-attributes" } */ + +extern void abort (void); + +static unsigned char __attribute__ ((always_inline)) +mytoupper (unsigned char c) +{ + if (c >= 'a' && c <= 'z') + c -= 'a' - 'A'; + return c; +} + +static unsigned long __attribute__ ((always_inline)) +strlen (const char *s) +{ + register unsigned long r0 asm ("0"); + const char *tmp = s; + + asm ( +#ifdef __s390x__ + " lghi %0, 0\n" +#else + " lhi %0, 0\n" +#endif + "0:srst %0,%1\n" + " jo 0b" + : "=d" (r0), "+a" (tmp) + : + :"cc"); + return r0 - (unsigned long) s; +} + +char boot_command_line[] = "this is a test"; + +void __attribute__ ((noinline)) +foo (char *str) +{ + if (strcmp (str, "THIS IS A TEST") != 0) + abort (); +} + +int +main () +{ + char upper_command_line[1024]; + int i; + + for (i = 0; i < strlen (boot_command_line); i++) + upper_command_line[i] = mytoupper (boot_command_line[i]); + + upper_command_line[strlen (boot_command_line)] = 0; + foo (upper_command_line); + + return 0; +} diff --git a/gcc-4.9/gcc/testsuite/gcc.target/s390/addr-constraints-1.c b/gcc-4.9/gcc/testsuite/gcc.target/s390/addr-constraints-1.c new file mode 100644 index 000000000..fbb48f282 --- /dev/null +++ b/gcc-4.9/gcc/testsuite/gcc.target/s390/addr-constraints-1.c @@ -0,0 +1,70 @@ +/* { dg-compile } */ +/* { dg-options "-O2" } */ + +static inline unsigned long +lay_uw(unsigned long addr) +{ + unsigned long result; + + __asm__ ("lay %[result],%a[addr]" + : [result] "=d" (result) + : [addr] "UW" (addr)); + return result; +} + +static inline unsigned long +la_u(unsigned long addr) +{ + unsigned long result; + + __asm__ ("la %[result],%a[addr]" + : [result] "=d" (result) + : [addr] "U" (addr)); + return result; +} + +static inline unsigned long +lay_zqzrzszt(unsigned long addr) +{ + unsigned long result; + + __asm__ ("lay %[result],%a[addr]" + : [result] "=d" (result) + : [addr] "ZQZRZSZT" (addr)); + return result; +} + +static inline unsigned long +la_zqzr(unsigned long addr) +{ + unsigned long result; + + __asm__ ("la %[result],%a[addr]" + : [result] "=d" (result) + : [addr] "ZQZR" (addr)); + return result; +} + + +extern unsigned long a[15]; + +int main(void) +{ + a[1] = lay_uw(3333); + a[2] = lay_uw(4444); + a[3] = lay_uw(1000000); + a[4] = lay_uw(a[0]); + + a[5] = la_u(2222); + a[6] = la_u(5555); + a[7] = la_u(a[0]); + + a[8] = lay_zqzrzszt(3333); + a[9] = lay_zqzrzszt(4444); + a[10] = lay_zqzrzszt(1000000); + a[11] = lay_zqzrzszt(a[0]); + + a[12] = la_zqzr(2222); + a[13] = la_zqzr(5555); + a[14] = la_zqzr(a[0]); +} diff --git a/gcc-4.9/gcc/testsuite/gcc.target/s390/fp2int1.c b/gcc-4.9/gcc/testsuite/gcc.target/s390/fp2int1.c new file mode 100644 index 000000000..4a90a8b91 --- /dev/null +++ b/gcc-4.9/gcc/testsuite/gcc.target/s390/fp2int1.c @@ -0,0 +1,95 @@ +/* Test for the 32 bit fp to 64 bit int conversion routines. + + On S/390 32 bit we use our own implementations in order to be IEEE + complaint as we are with our machine instructions. These missed to + throw FE_INVALID exceptions in a bunch of cases. */ + +/* { dg-do run { target s390-*-* } } */ +/* { dg-options "-O3 -mesa" } */ +/* { dg-require-effective-target fenv_exceptions } */ + +#define _GNU_SOURCE +#include <stdlib.h> +#include <stdio.h> +#include <fenv.h> + +#define INFINITYf (__builtin_inff()) +#define INFINITY (__builtin_inf()) +#define INFINITYl (__builtin_infl()) +#define NANf (__builtin_nanf ("")) +#define NAN (__builtin_nan ("")) +#define NANl (__builtin_nanl ("")) + +#define TESTEXCEPT_FUNC(FUNC, TYPE_FROM, TYPE_TO) \ + TYPE_TO \ + __attribute__((noinline)) FUNC (TYPE_FROM a) \ + { \ + asm volatile ("" : : "f" (a)); \ + return (TYPE_TO)a; \ + } + +#define TESTEXCEPT(FUNC, EXCEPT, EXPECT, VALUE, TYPE_TO) \ + { \ + TYPE_TO b; \ + feclearexcept (FE_ALL_EXCEPT); \ + b = FUNC (VALUE); \ + if ((fetestexcept (EXCEPT) & (EXCEPT)) != EXPECT) \ + { \ + printf ("FAIL in line: %d\n", __LINE__); \ + abort (); \ + } \ + } + +#define TESTEXCEPT_FUNC_ALLFLOATS(FUNC, TYPE_TO) \ + TESTEXCEPT_FUNC (FUNC##_f, float, TYPE_TO); \ + TESTEXCEPT_FUNC (FUNC##_d, double, TYPE_TO); \ + TESTEXCEPT_FUNC (FUNC##_l, long double, TYPE_TO); \ + +#define TESTEXCEPT_ALLFLOATS(FUNC, EXCEPT, EXPECT, VALUE, TYPE_TO) \ + TESTEXCEPT (FUNC##_f, EXCEPT, EXPECT, VALUE##f, TYPE_TO); \ + TESTEXCEPT (FUNC##_d, EXCEPT, EXPECT, VALUE, TYPE_TO); \ + TESTEXCEPT (FUNC##_l, EXCEPT, EXPECT, VALUE##l, TYPE_TO); \ + +TESTEXCEPT_FUNC_ALLFLOATS (a, unsigned long long); +TESTEXCEPT_FUNC_ALLFLOATS (u, long long); + + +int +main () +{ + /* Prevent getting signals. */ + fedisableexcept (FE_INVALID); + + /* To unsigned long long */ + + TESTEXCEPT_ALLFLOATS (a, FE_INVALID, FE_INVALID, INFINITY, unsigned long long); + TESTEXCEPT_ALLFLOATS (a, FE_INVALID, FE_INVALID, -INFINITY, unsigned long long); + TESTEXCEPT_ALLFLOATS (a, FE_INVALID, FE_INVALID, NAN, unsigned long long); + TESTEXCEPT_ALLFLOATS (a, FE_INVALID, FE_INVALID, -NAN, unsigned long long); + + /* Negative values >-1.0 must not cause FE_INVALID. */ + TESTEXCEPT_ALLFLOATS (a, FE_INVALID, 0, -0x0.ffffffp0, unsigned long long); + /* -1.0 instead must. */ + TESTEXCEPT_ALLFLOATS (a, FE_INVALID, FE_INVALID, -0x1.0p+0, unsigned long long); + TESTEXCEPT_ALLFLOATS (a, FE_INVALID, 0, 0x1.0p+63, unsigned long long); + TESTEXCEPT_ALLFLOATS (a, FE_INVALID, FE_INVALID, 0x1.0p+64, unsigned long long); + + /* To signed long long */ + + TESTEXCEPT_ALLFLOATS (u, FE_INVALID, FE_INVALID, INFINITY, long long); + TESTEXCEPT_ALLFLOATS (u, FE_INVALID, FE_INVALID, -INFINITY, long long); + TESTEXCEPT_ALLFLOATS (u, FE_INVALID, FE_INVALID, NAN, long long); + TESTEXCEPT_ALLFLOATS (u, FE_INVALID, FE_INVALID, -NAN, long long); + + TESTEXCEPT_ALLFLOATS (u, FE_INVALID, 0, -0x1.0p+63, long long); + TESTEXCEPT_ALLFLOATS (u, FE_INVALID, FE_INVALID, -0x1.1p+63, long long); + TESTEXCEPT_ALLFLOATS (u, FE_INVALID, 0, 0x0.fffffp+63, long long); + TESTEXCEPT_ALLFLOATS (u, FE_INVALID, FE_INVALID, 0x1.0p+63, long long); + + /* If there are additional bits which would not make it into the + integer value no exception is supposed to occur. */ + TESTEXCEPT (u_l, FE_INVALID, 0, -0x1.000000000000000123p+63l, long long); + TESTEXCEPT (u_l, FE_INVALID, FE_INVALID, -0x1.000000000000000223p+63l, long long); + + return 0; +} diff --git a/gcc-4.9/gcc/testsuite/gcc.target/s390/frame-addr1.c b/gcc-4.9/gcc/testsuite/gcc.target/s390/frame-addr1.c new file mode 100644 index 000000000..fda419ff0 --- /dev/null +++ b/gcc-4.9/gcc/testsuite/gcc.target/s390/frame-addr1.c @@ -0,0 +1,53 @@ +/* builtin_frame_address(n) with n>0 has always been troublesome ... + especially when the S/390 packed stack layout comes into play. */ + +/* { dg-do run } */ +/* { dg-options "-O3 -fno-optimize-sibling-calls -mbackchain -mpacked-stack -msoft-float" } */ + +#ifdef __s390x__ +/* 64bit: 3 words to be saved: backchain, r14 and r15 */ +#define SAVE_AREA_SIZE 3*8 +#else +/* 32bit: 4 words to be saved: backchain, r13, r14 and r15 */ +#define SAVE_AREA_SIZE 4*4 +#endif +extern void abort(void); + +#define EXPAND_CHECK(n) \ + void __attribute__((noinline)) \ + foo1_##n (void *p) \ + { \ + if (p - __builtin_frame_address (n) != SAVE_AREA_SIZE) \ + abort (); \ + } \ + void __attribute__((noinline)) \ + foo2_##n (void *p) \ + { \ + if (p - __builtin_frame_address (n) != SAVE_AREA_SIZE) \ + abort (); \ + foo1_##n (__builtin_frame_address (n)); \ + } \ + void __attribute__((noinline)) \ + foo3_##n () \ + { \ + foo2_##n (__builtin_frame_address (n)); \ + } \ + void __attribute__((noinline)) \ + foo4_##n () \ + { \ + foo3_##n (); \ + } + +EXPAND_CHECK (0) +EXPAND_CHECK (1) +EXPAND_CHECK (2) + +int +main () +{ + foo4_0 (); + foo4_1 (); + foo4_2 (); + + return 0; +} diff --git a/gcc-4.9/gcc/testsuite/gcc.target/s390/frame-addr2.c b/gcc-4.9/gcc/testsuite/gcc.target/s390/frame-addr2.c new file mode 100644 index 000000000..f6f9687a0 --- /dev/null +++ b/gcc-4.9/gcc/testsuite/gcc.target/s390/frame-addr2.c @@ -0,0 +1,50 @@ +/* builtin_frame_address(n) with n>0 has always been troublesome. */ + +/* { dg-do run } */ +/* { dg-options "-O3 -fno-optimize-sibling-calls -mbackchain" } */ + +#ifdef __s390x__ +#define SAVE_AREA_SIZE 160 +#else +#define SAVE_AREA_SIZE 96 +#endif +extern void abort(void); + +#define EXPAND_CHECK(n) \ + void __attribute__((noinline)) \ + foo1_##n (void *p) \ + { \ + if (p - __builtin_frame_address (n) != SAVE_AREA_SIZE) \ + abort (); \ + } \ + void __attribute__((noinline)) \ + foo2_##n (void *p) \ + { \ + if (p - __builtin_frame_address (n) != SAVE_AREA_SIZE) \ + abort (); \ + foo1_##n (__builtin_frame_address (n)); \ + } \ + void __attribute__((noinline)) \ + foo3_##n () \ + { \ + foo2_##n (__builtin_frame_address (n)); \ + } \ + void __attribute__((noinline)) \ + foo4_##n () \ + { \ + foo3_##n (); \ + } + +EXPAND_CHECK (0) +EXPAND_CHECK (1) +EXPAND_CHECK (2) + +int +main () +{ + foo4_0 (); + foo4_1 (); + foo4_2 (); + + return 0; +} diff --git a/gcc-4.9/gcc/testsuite/gcc.target/s390/hotpatch-1.c b/gcc-4.9/gcc/testsuite/gcc.target/s390/hotpatch-1.c new file mode 100644 index 000000000..b9d6139b0 --- /dev/null +++ b/gcc-4.9/gcc/testsuite/gcc.target/s390/hotpatch-1.c @@ -0,0 +1,20 @@ +/* Functional tests for the function hotpatching feature. */ + +/* { dg-do run } */ +/* { dg-options "-O3 -mzarch -mhotpatch --save-temps" } */ + +#include <stdio.h> + +void hp1(void) +{ + printf("hello, world!\n"); +} + +int main (void) +{ + return 0; +} + +/* Check number of occurences of certain instructions. */ +/* { dg-final { scan-assembler-times "nopr\t%r7" 12 } } */ +/* { dg-final { scan-assembler-times "nop\t0" 1 } } */ diff --git a/gcc-4.9/gcc/testsuite/gcc.target/s390/hotpatch-10.c b/gcc-4.9/gcc/testsuite/gcc.target/s390/hotpatch-10.c new file mode 100644 index 000000000..b91b3478e --- /dev/null +++ b/gcc-4.9/gcc/testsuite/gcc.target/s390/hotpatch-10.c @@ -0,0 +1,21 @@ +/* Functional tests for the function hotpatching feature. */ + +/* { dg-do run } */ +/* { dg-options "-O3 -mzarch -mno-hotpatch --save-temps" } */ + +#include <stdio.h> + +__attribute__ ((hotpatch(2))) +void hp1(void) +{ + printf("hello, world!\n"); +} + +int main (void) +{ + return 0; +} + +/* Check number of occurences of certain instructions. */ +/* { dg-final { scan-assembler-times "nopr\t%r7" 2 } } */ +/* { dg-final { scan-assembler-times "nop\t0" 1 } } */ diff --git a/gcc-4.9/gcc/testsuite/gcc.target/s390/hotpatch-11.c b/gcc-4.9/gcc/testsuite/gcc.target/s390/hotpatch-11.c new file mode 100644 index 000000000..491677342 --- /dev/null +++ b/gcc-4.9/gcc/testsuite/gcc.target/s390/hotpatch-11.c @@ -0,0 +1,20 @@ +/* Functional tests for the function hotpatching feature. */ + +/* { dg-do run } */ +/* { dg-options "-O3 -mzarch -mhotpatch -mno-hotpatch --save-temps" } */ + +#include <stdio.h> + +void hp1(void) +{ + printf("hello, world!\n"); +} + +int main (void) +{ + return 0; +} + +/* Check number of occurences of certain instructions. */ +/* { dg-final { scan-assembler-not "nopr\t%r7" } } */ +/* { dg-final { scan-assembler-not "nop\t0" } } */ diff --git a/gcc-4.9/gcc/testsuite/gcc.target/s390/hotpatch-12.c b/gcc-4.9/gcc/testsuite/gcc.target/s390/hotpatch-12.c new file mode 100644 index 000000000..b3e9427d4 --- /dev/null +++ b/gcc-4.9/gcc/testsuite/gcc.target/s390/hotpatch-12.c @@ -0,0 +1,20 @@ +/* Functional tests for the function hotpatching feature. */ + +/* { dg-do run } */ +/* { dg-options "-O3 -mzarch -mno-hotpatch -mhotpatch=1 --save-temps" } */ + +#include <stdio.h> + +void hp1(void) +{ + printf("hello, world!\n"); +} + +int main (void) +{ + return 0; +} + +/* Check number of occurences of certain instructions. */ +/* { dg-final { scan-assembler-times "nopr\t%r7" 1 } } */ +/* { dg-final { scan-assembler-times "nop\t0" 1 } } */ diff --git a/gcc-4.9/gcc/testsuite/gcc.target/s390/hotpatch-2.c b/gcc-4.9/gcc/testsuite/gcc.target/s390/hotpatch-2.c new file mode 100644 index 000000000..6cc29447d --- /dev/null +++ b/gcc-4.9/gcc/testsuite/gcc.target/s390/hotpatch-2.c @@ -0,0 +1,20 @@ +/* Functional tests for the function hotpatching feature. */ + +/* { dg-do run } */ +/* { dg-options "-O3 -mzarch -mhotpatch=1 --save-temps" } */ + +#include <stdio.h> + +void hp1(void) +{ + printf("hello, world!\n"); +} + +int main (void) +{ + return 0; +} + +/* Check number of occurences of certain instructions. */ +/* { dg-final { scan-assembler-times "nopr\t%r7" 1 } } */ +/* { dg-final { scan-assembler-times "nop\t0" 1 } } */ diff --git a/gcc-4.9/gcc/testsuite/gcc.target/s390/hotpatch-3.c b/gcc-4.9/gcc/testsuite/gcc.target/s390/hotpatch-3.c new file mode 100644 index 000000000..9f0b2b756 --- /dev/null +++ b/gcc-4.9/gcc/testsuite/gcc.target/s390/hotpatch-3.c @@ -0,0 +1,20 @@ +/* Functional tests for the function hotpatching feature. */ + +/* { dg-do run } */ +/* { dg-options "-O3 -mzarch -mhotpatch=0 --save-temps" } */ + +#include <stdio.h> + +void hp1(void) +{ + printf("hello, world!\n"); +} + +int main (void) +{ + return 0; +} + +/* Check number of occurences of certain instructions. */ +/* { dg-final { scan-assembler-not "nopr\t%r7" } } */ +/* { dg-final { scan-assembler-times "nop\t0" 1 } } */ diff --git a/gcc-4.9/gcc/testsuite/gcc.target/s390/hotpatch-4.c b/gcc-4.9/gcc/testsuite/gcc.target/s390/hotpatch-4.c new file mode 100644 index 000000000..c1dba20a3 --- /dev/null +++ b/gcc-4.9/gcc/testsuite/gcc.target/s390/hotpatch-4.c @@ -0,0 +1,26 @@ +/* Functional tests for the function hotpatching feature. */ + +/* { dg-do run } */ +/* { dg-options "-O3 -mzarch -mhotpatch --save-temps" } */ + +#include <stdio.h> + +inline void hp1(void) +{ + printf("hello, world!\n"); +} + +__attribute__ ((always_inline)) +void hp2(void) /* { dg-warning "always_inline function might not be inlinable" } */ +{ + printf("hello, world!\n"); +} /* { dg-warning "function 'hp2' with the 'always_inline' attribute is not hotpatchable" } */ + +int main (void) +{ + return 0; +} + +/* Check number of occurences of certain instructions. */ +/* { dg-final { scan-assembler-not "nopr\t%r7" } } */ +/* { dg-final { scan-assembler-not "nop\t0" } } */ diff --git a/gcc-4.9/gcc/testsuite/gcc.target/s390/hotpatch-5.c b/gcc-4.9/gcc/testsuite/gcc.target/s390/hotpatch-5.c new file mode 100644 index 000000000..ec267d65a --- /dev/null +++ b/gcc-4.9/gcc/testsuite/gcc.target/s390/hotpatch-5.c @@ -0,0 +1,21 @@ +/* Functional tests for the function hotpatching feature. */ + +/* { dg-do run } */ +/* { dg-options "-O3 -mzarch -mhotpatch --save-temps" } */ + +#include <stdio.h> + +__attribute__ ((hotpatch)) +void hp1(void) +{ + printf("hello, world!\n"); +} + +int main (void) +{ + return 0; +} + +/* Check number of occurences of certain instructions. */ +/* { dg-final { scan-assembler-times "nopr\t%r7" 12 } } */ +/* { dg-final { scan-assembler-times "nop\t0" 1 } } */ diff --git a/gcc-4.9/gcc/testsuite/gcc.target/s390/hotpatch-6.c b/gcc-4.9/gcc/testsuite/gcc.target/s390/hotpatch-6.c new file mode 100644 index 000000000..5af090d03 --- /dev/null +++ b/gcc-4.9/gcc/testsuite/gcc.target/s390/hotpatch-6.c @@ -0,0 +1,21 @@ +/* Functional tests for the function hotpatching feature. */ + +/* { dg-do run } */ +/* { dg-options "-O3 -mzarch -mhotpatch --save-temps" } */ + +#include <stdio.h> + +__attribute__ ((hotpatch(1))) +void hp1(void) +{ + printf("hello, world!\n"); +} + +int main (void) +{ + return 0; +} + +/* Check number of occurences of certain instructions. */ +/* { dg-final { scan-assembler-times "nopr\t%r7" 1 } } */ +/* { dg-final { scan-assembler-times "nop\t0" 1 } } */ diff --git a/gcc-4.9/gcc/testsuite/gcc.target/s390/hotpatch-7.c b/gcc-4.9/gcc/testsuite/gcc.target/s390/hotpatch-7.c new file mode 100644 index 000000000..e73a510b4 --- /dev/null +++ b/gcc-4.9/gcc/testsuite/gcc.target/s390/hotpatch-7.c @@ -0,0 +1,21 @@ +/* Functional tests for the function hotpatching feature. */ + +/* { dg-do run } */ +/* { dg-options "-O3 -mzarch -mhotpatch --save-temps" } */ + +#include <stdio.h> + +__attribute__ ((hotpatch(0))) +void hp1(void) +{ + printf("hello, world!\n"); +} + +int main (void) +{ + return 0; +} + +/* Check number of occurences of certain instructions. */ +/* { dg-final { scan-assembler-not "nopr\t%r7" } } */ +/* { dg-final { scan-assembler-times "nop\t0" 1 } } */ diff --git a/gcc-4.9/gcc/testsuite/gcc.target/s390/hotpatch-8.c b/gcc-4.9/gcc/testsuite/gcc.target/s390/hotpatch-8.c new file mode 100644 index 000000000..399aa7260 --- /dev/null +++ b/gcc-4.9/gcc/testsuite/gcc.target/s390/hotpatch-8.c @@ -0,0 +1,28 @@ +/* Functional tests for the function hotpatching feature. */ + +/* { dg-do run } */ +/* { dg-options "-O3 -mzarch -mhotpatch --save-temps" } */ + +#include <stdio.h> + +__attribute__ ((hotpatch)) +inline void hp1(void) +{ + printf("hello, world!\n"); +} + +__attribute__ ((hotpatch)) +__attribute__ ((always_inline)) +void hp2(void) /* { dg-warning "always_inline function might not be inlinable" } */ +{ + printf("hello, world!\n"); +} /* { dg-warning "function 'hp2' with the 'always_inline' attribute is not hotpatchable" } */ + +int main (void) +{ + return 0; +} + +/* Check number of occurences of certain instructions. */ +/* { dg-final { scan-assembler-not "nopr\t%r7" } } */ +/* { dg-final { scan-assembler-not "nop\t0" } } */ diff --git a/gcc-4.9/gcc/testsuite/gcc.target/s390/hotpatch-9.c b/gcc-4.9/gcc/testsuite/gcc.target/s390/hotpatch-9.c new file mode 100644 index 000000000..5da675866 --- /dev/null +++ b/gcc-4.9/gcc/testsuite/gcc.target/s390/hotpatch-9.c @@ -0,0 +1,21 @@ +/* Functional tests for the function hotpatching feature. */ + +/* { dg-do run } */ +/* { dg-options "-O3 -mzarch -mhotpatch=1 --save-temps" } */ + +#include <stdio.h> + +__attribute__ ((hotpatch(2))) +void hp1(void) +{ + printf("hello, world!\n"); +} + +int main (void) +{ + return 0; +} + +/* Check number of occurences of certain instructions. */ +/* { dg-final { scan-assembler-times "nopr\t%r7" 2 } } */ +/* { dg-final { scan-assembler-times "nop\t0" 1 } } */ diff --git a/gcc-4.9/gcc/testsuite/gcc.target/s390/hotpatch-compile-1.c b/gcc-4.9/gcc/testsuite/gcc.target/s390/hotpatch-compile-1.c new file mode 100644 index 000000000..45a2cc5dc --- /dev/null +++ b/gcc-4.9/gcc/testsuite/gcc.target/s390/hotpatch-compile-1.c @@ -0,0 +1,27 @@ +/* Functional tests for the function hotpatching feature. */ + +/* { dg-do run } */ +/* { dg-options "-O3 -mzarch -mhotpatch" } */ + +#include <stdio.h> + +void hp1(void) +{ + printf("hello, world!\n"); +} + +inline void hp2(void) +{ + printf("hello, world!\n"); +} + +__attribute__ ((always_inline)) +void hp3(void) /* { dg-warning "always_inline function might not be inlinable" } */ +{ + printf("hello, world!\n"); +} /* { dg-warning "function 'hp3' with the 'always_inline' attribute is not hotpatchable" } */ + +int main (void) +{ + return 0; +} diff --git a/gcc-4.9/gcc/testsuite/gcc.target/s390/hotpatch-compile-2.c b/gcc-4.9/gcc/testsuite/gcc.target/s390/hotpatch-compile-2.c new file mode 100644 index 000000000..5947f564f --- /dev/null +++ b/gcc-4.9/gcc/testsuite/gcc.target/s390/hotpatch-compile-2.c @@ -0,0 +1,27 @@ +/* Functional tests for the function hotpatching feature. */ + +/* { dg-do run } */ +/* { dg-options "-O3 -mzarch -mhotpatch=0" } */ + +#include <stdio.h> + +void hp1(void) +{ + printf("hello, world!\n"); +} + +inline void hp2(void) +{ + printf("hello, world!\n"); +} + +__attribute__ ((always_inline)) +void hp3(void) /* { dg-warning "always_inline function might not be inlinable" } */ +{ + printf("hello, world!\n"); +} /* { dg-warning "function 'hp3' with the 'always_inline' attribute is not hotpatchable" } */ + +int main (void) +{ + return 0; +} diff --git a/gcc-4.9/gcc/testsuite/gcc.target/s390/hotpatch-compile-3.c b/gcc-4.9/gcc/testsuite/gcc.target/s390/hotpatch-compile-3.c new file mode 100644 index 000000000..e0c7f6f52 --- /dev/null +++ b/gcc-4.9/gcc/testsuite/gcc.target/s390/hotpatch-compile-3.c @@ -0,0 +1,27 @@ +/* Functional tests for the function hotpatching feature. */ + +/* { dg-do run } */ +/* { dg-options "-O3 -mzarch -mhotpatch=1" } */ + +#include <stdio.h> + +void hp1(void) +{ + printf("hello, world!\n"); +} + +inline void hp2(void) +{ + printf("hello, world!\n"); +} + +__attribute__ ((always_inline)) +void hp3(void) /* { dg-warning "always_inline function might not be inlinable" } */ +{ + printf("hello, world!\n"); +} /* { dg-warning "function 'hp3' with the 'always_inline' attribute is not hotpatchable" } */ + +int main (void) +{ + return 0; +} diff --git a/gcc-4.9/gcc/testsuite/gcc.target/s390/hotpatch-compile-4.c b/gcc-4.9/gcc/testsuite/gcc.target/s390/hotpatch-compile-4.c new file mode 100644 index 000000000..d9f13425a --- /dev/null +++ b/gcc-4.9/gcc/testsuite/gcc.target/s390/hotpatch-compile-4.c @@ -0,0 +1,11 @@ +/* Functional tests for the function hotpatching feature. */ + +/* { dg-do compile } */ +/* { dg-options "-O3 -mzarch -mhotpatch=-1" } */ + +int main (void) +{ + return 0; +} + +/* { dg-excess-errors "argument to '-mhotpatch=' should be a non-negative integer" } */ diff --git a/gcc-4.9/gcc/testsuite/gcc.target/s390/hotpatch-compile-5.c b/gcc-4.9/gcc/testsuite/gcc.target/s390/hotpatch-compile-5.c new file mode 100644 index 000000000..53f7eac9e --- /dev/null +++ b/gcc-4.9/gcc/testsuite/gcc.target/s390/hotpatch-compile-5.c @@ -0,0 +1,28 @@ +/* Functional tests for the function hotpatching feature. */ + +/* { dg-do compile } */ +/* { dg-options "-O3 -mzarch -mhotpatch=1000000" } */ + +#include <stdio.h> + +void hp1(void) +{ + printf("hello, world!\n"); +} + +__attribute__ ((hotpatch(1000000))) +void hp2(void) +{ + printf("hello, world!\n"); +} + +__attribute__ ((hotpatch(1000001))) +void hp3(void) +{ /* { dg-error "requested 'hotpatch' attribute is not a non-negative integer constant or too large .max. 1000000." } */ + printf("hello, world!\n"); +} + +int main (void) +{ + return 0; +} diff --git a/gcc-4.9/gcc/testsuite/gcc.target/s390/hotpatch-compile-6.c b/gcc-4.9/gcc/testsuite/gcc.target/s390/hotpatch-compile-6.c new file mode 100644 index 000000000..cb10b66f0 --- /dev/null +++ b/gcc-4.9/gcc/testsuite/gcc.target/s390/hotpatch-compile-6.c @@ -0,0 +1,11 @@ +/* Functional tests for the function hotpatching feature. */ + +/* { dg-do compile } */ +/* { dg-options "-O3 -mzarch -mhotpatch=1000001" } */ + +int main (void) +{ + return 0; +} + +/* { dg-excess-errors "argument to '-mhotpatch=' is too large .max. 1000000." } */ diff --git a/gcc-4.9/gcc/testsuite/gcc.target/s390/hotpatch-compile-7.c b/gcc-4.9/gcc/testsuite/gcc.target/s390/hotpatch-compile-7.c new file mode 100644 index 000000000..98ccb42c0 --- /dev/null +++ b/gcc-4.9/gcc/testsuite/gcc.target/s390/hotpatch-compile-7.c @@ -0,0 +1,68 @@ +/* Functional tests for the function hotpatching feature. */ + +/* { dg-do run } */ +/* { dg-options "-O3 -mzarch -mno-hotpatch" } */ + +#include <stdio.h> + +__attribute__ ((hotpatch)) +void hp1(void) +{ + printf("hello, world!\n"); +} + +__attribute__ ((hotpatch)) +inline void hp2(void) +{ + printf("hello, world!\n"); +} + +__attribute__ ((hotpatch)) +__attribute__ ((always_inline)) +void hp3(void) /* { dg-warning "always_inline function might not be inlinable" } */ +{ + printf("hello, world!\n"); +} /* { dg-warning "function 'hp3' with the 'always_inline' attribute is not hotpatchable" } */ + +__attribute__ ((hotpatch(0))) +void hp4(void) +{ + printf("hello, world!\n"); +} + +__attribute__ ((hotpatch(0))) +inline void hp5(void) +{ + printf("hello, world!\n"); +} + +__attribute__ ((hotpatch(0))) +__attribute__ ((always_inline)) +void hp6(void) /* { dg-warning "always_inline function might not be inlinable" } */ +{ + printf("hello, world!\n"); +} /* { dg-warning "function 'hp6' with the 'always_inline' attribute is not hotpatchable" } */ + +__attribute__ ((hotpatch(1))) +void hp7(void) +{ + printf("hello, world!\n"); +} + +__attribute__ ((hotpatch(1))) +inline void hp8(void) +{ + printf("hello, world!\n"); +} + +__attribute__ ((hotpatch(1))) +__attribute__ ((always_inline)) +void hp9(void) /* { dg-warning "always_inline function might not be inlinable" } */ +{ + printf("hello, world!\n"); +} /* { dg-warning "function 'hp9' with the 'always_inline' attribute is not hotpatchable" } */ + +int main (void) +{ + return 0; +} diff --git a/gcc-4.9/gcc/testsuite/gcc.target/s390/hotpatch-compile-8.c b/gcc-4.9/gcc/testsuite/gcc.target/s390/hotpatch-compile-8.c new file mode 100644 index 000000000..489fc5dd9 --- /dev/null +++ b/gcc-4.9/gcc/testsuite/gcc.target/s390/hotpatch-compile-8.c @@ -0,0 +1,23 @@ +/* Functional tests for the function hotpatching feature. */ + +/* { dg-do run } */ +/* { dg-options "-O3 -mzarch -mhotpatch" } */ + +#include <stdio.h> + +int hp1(void) +{ + int nested1(void) /* { dg-warning "hotpatching is not compatible with nested functions" } */ + { return 1; } + + __attribute__ ((hotpatch)) + int nested2(void) /* { dg-warning "hotpatching is not compatible with nested functions" } */ + { return 1; } + + return nested1() - nested2(); +} + +int main (void) +{ + return hp1(); +} diff --git a/gcc-4.9/gcc/testsuite/gcc.target/s390/htm-builtins-1.c b/gcc-4.9/gcc/testsuite/gcc.target/s390/htm-builtins-1.c new file mode 100644 index 000000000..c90490faa --- /dev/null +++ b/gcc-4.9/gcc/testsuite/gcc.target/s390/htm-builtins-1.c @@ -0,0 +1,1073 @@ +/* Functional tests of the htm __builtin_... macros. */ + +/* { dg-do run } */ +/* { dg-require-effective-target htm } */ +/* { dg-options "-O3 -march=zEC12 -mzarch" } */ + +/* ---------------------------- included header files ---------------------- */ + +#include <stdio.h> +#include <string.h> +#include <stdint.h> +#include <htmintrin.h> + +/* ---------------------------- local definitions -------------------------- */ + +#define DEFAULT_MAX_REPETITIONS 5 +#define DEFAULT_REQUIRED_QUORUM ((DEFAULT_MAX_REPETITIONS) - 1) +#define NUM_WARMUP_RUNS 10 + +/* ---------------------------- local macros ------------------------------- */ + +#define TEST_DF_REP(name) \ + { #name, name, DEFAULT_MAX_REPETITIONS, DEFAULT_REQUIRED_QUORUM } +#define TEST_NO_REP(name) { #name, name, 1, 1 } + +/* ---------------------------- local types -------------------------------- */ + +typedef int (*test_func_t)(void); + +typedef struct +{ + const char *name; + test_func_t test_func; + int max_repetitions; + int required_quorum; +} test_table_entry_t; + +/* ---------------------------- local variables ---------------------------- */ + +__attribute__ ((aligned(256))) static struct __htm_tdb local_tdb256; +static struct __htm_tdb local_tdb; +static int do_dump_tdb = 0; + +/* ---------------------------- exported variables (globals) --------------- */ + +__attribute__ ((aligned(256))) struct +{ + float float_1; + float float_2; + float float_3; +} global = { 1.0, 2.5, 0.0 }; + +__attribute__ ((aligned(256))) struct +{ + volatile uint64_t c1; + volatile uint64_t c2; + volatile uint64_t c3; +} counters = { 0, 0, 0 }; + +/* ---------------------------- local helper functions --------------------- */ + +static void dump_tdb (struct __htm_tdb *tdb) +{ + unsigned char *p; + int i; + int j; + + if (do_dump_tdb == 0) + { + return; + } + p = (unsigned char *)tdb; + for (i = 0; i < 16; i++) + { + fprintf (stderr, "0x%02x ", i * 16); + for (j = 0; j < 16; j++) + { + fprintf (stderr, "%02x", (int)p[i * 16 + j]); + if (j < 15) + { + fprintf (stderr, " "); + } + if (j == 7) + { + fprintf (stderr, " "); + } + } + fprintf (stderr, "\n"); + } + + return; +} + +/* ---------------------------- local test functions ----------------------- */ + +/* Check values of the constants defined in htmintrin.h. */ +static int test_constants (void) +{ + if (_HTM_TBEGIN_STARTED != 0) + { + return 100 * _HTM_TBEGIN_STARTED + 1; + } + if (_HTM_TBEGIN_INDETERMINATE != 1) + { + return 100 * _HTM_TBEGIN_INDETERMINATE + 2; + } + if (_HTM_TBEGIN_TRANSIENT != 2) + { + return 100 * _HTM_TBEGIN_TRANSIENT + 3; + } + if (_HTM_TBEGIN_PERSISTENT != 3) + { + return 100 * _HTM_TBEGIN_PERSISTENT + 4; + } + + return 0; +} + +static int test_tbegin_ntstg_tend (void) +{ + int rc; + + counters.c1 = 0; + counters.c2 = 0; + if ((rc = __builtin_tbegin ((void *)0)) == 0) + { + __builtin_non_tx_store ((uint64_t *)&counters.c1, 1); + counters.c2 = 2; + rc = __builtin_tend (); + if (rc != 0) + { + return 100 * rc + 5; + } + if (counters.c1 != 1) + { + return 100 * counters.c1 + 2; + } + if (counters.c2 != 2) + { + return 100 * counters.c2 + 3; + } + } + else + { + return 100 * rc + 4; + } + + return 0; +} + +static int test_tbegin_ntstg_tabort (void) +{ + float f; + + counters.c1 = 0; + counters.c2 = 0; + f = 0; + if (__builtin_tbegin ((void *)0) == 0) + { + __builtin_non_tx_store ((uint64_t *)&counters.c1, 1); + counters.c2 = 2; + f = 1; + __builtin_tabort (256); + return 1; + } + if (counters.c1 != 1) + { + return 100 * counters.c1 + 2; + } + if (counters.c2 != 0) + { + return 100 * counters.c2 + 3; + } + if (f != 0) + { + return 100 * f + 4; + } + + return 0; +} + +static int test_tbegin_nofloat (void) +{ + int rc; + + counters.c1 = 0; + counters.c2 = 0; + if ((rc = __builtin_tbegin_nofloat ((void *)0)) == 0) + { + __builtin_non_tx_store ((uint64_t *)&counters.c1, 1); + counters.c2 = 2; + rc = __builtin_tend (); + if (rc != 0) + { + return 100 * rc + 5; + } + if (counters.c1 != 1) + { + return 100 * counters.c1 + 2; + } + if (counters.c2 != 2) + { + return 100 * counters.c2 + 3; + } + } + else + { + return 100 * rc + 4; + } + + return 0; +} + +static int test_tbegin_retry (void) +{ + int rc; + + counters.c1 = 0; + counters.c2 = 0; + counters.c3 = 0; + if ((rc = __builtin_tbegin_retry ((void *)0, 5)) == 0) + { + int do_abort; + + do_abort = (counters.c1 == 0) ? 1 : 0; + __builtin_non_tx_store ( + (uint64_t *)&counters.c1, counters.c1 + 1); + if (do_abort == 1) + { + __builtin_tabort (256); + } + counters.c2 = counters.c2 + 10; + __builtin_non_tx_store ((uint64_t *)&counters.c3, 3); + rc = __builtin_tend (); + if (rc != 0) + { + return 100 * rc + 5; + } + if (counters.c1 != 2) + { + return 100 * counters.c1 + 2; + } + if (counters.c2 != 10) + { + return 100 * counters.c2 + 3; + } + if (counters.c3 != 3) + { + return 100 * counters.c3 + 6; + } + } + else + { + return 100 * rc + 4; + } + + return 0; +} + +static int test_tbegin_retry_nofloat (void) +{ + int rc; + + counters.c1 = 0; + counters.c2 = 0; + counters.c3 = 0; + if ((rc = __builtin_tbegin_retry_nofloat ((void *)0, 5)) == 0) + { + int do_abort; + + do_abort = (counters.c1 == 0) ? 1 : 0; + __builtin_non_tx_store ( + (uint64_t *)&counters.c1, counters.c1 + 1); + if (do_abort == 1) + { + __builtin_tabort (256); + } + counters.c2 = counters.c2 + 10; + __builtin_non_tx_store ((uint64_t *)&counters.c3, 3); + rc = __builtin_tend (); + if (rc != 0) + { + return 100 * rc + 5; + } + if (counters.c1 != 2) + { + return 100 * counters.c1 + 2; + } + if (counters.c2 != 10) + { + return 100 * counters.c2 + 3; + } + if (counters.c3 != 3) + { + return 100 * counters.c3 + 6; + } + } + else + { + return 100 * rc + 4; + } + + return 0; +} + +static int test_tbegin_aborts (void) +{ + float f; + int rc; + + f = 77; + if ((rc = __builtin_tbegin ((void *)0)) == 0) + { + f = 88; + __builtin_tabort (256); + return 2; + } + else if (rc != 2) + { + return 3; + } + if (f != 77) + { + return 4; + } + f = 66; + if ((rc = __builtin_tbegin ((void *)0)) == 0) + { + f = 99; + __builtin_tabort (257); + return 5; + } + else if (rc != 3) + { + return 100 * rc + 6; + } + if (f != 66) + { + return 100 * f + 7; + } + if ((rc = __builtin_tbegin ((void *)0)) == 0) + { + global.float_3 = global.float_1 + global.float_2; + rc = __builtin_tend (); + if (rc != 0) + { + return 100 * rc + 8; + } + } + else + { + return 100 * rc + 9; + } + if (global.float_3 != global.float_1 + global.float_2) + { + return 100 * rc + 10; + } + + return 0; +} + +static __attribute__((noinline)) void indirect_abort(int abort_code) +{ + __builtin_tabort (abort_code); + + return; +} + +static int test_tbegin_indirect_aborts (void) +{ + float f; + int rc; + + f = 77; + if ((rc = __builtin_tbegin ((void *)0)) == 0) + { + f = 88; + indirect_abort(256); + return 2; + } + else if (rc != 2) + { + return 100 * rc + 3; + } + if (f != 77) + { + return 100 * rc + 4; + } + f = 66; + if ((rc = __builtin_tbegin ((void *)0)) == 0) + { + f = 99; + indirect_abort(257); + return 5; + } + else if (rc != 3) + { + return 100 * rc + 6; + } + if (f != 66) + { + return 100 * f + 7; + } + + return 0; +} + +static int test_tbegin_nofloat_aborts (void) +{ + int rc; + + if ((rc = __builtin_tbegin_nofloat ((void *)0)) == 0) + { + __builtin_tabort (256); + return 2; + } + if ((rc = __builtin_tbegin_nofloat ((void *)0)) == 0) + { + __builtin_tabort (257); + return 1005; + } + else if (rc != 3) + { + return 1000 * rc + 6; + } + + return 0; +} + +static int test_tbegin_nofloat_indirect_aborts (void) +{ + int rc; + + if ((rc = __builtin_tbegin_nofloat ((void *)0)) == 0) + { + indirect_abort (256); + return 2; + } + if ((rc = __builtin_tbegin_nofloat ((void *)0)) == 0) + { + indirect_abort (257); + return 1005; + } + else if (rc != 3) + { + return 1000 * rc + 6; + } + + return 0; +} + +static +int _test_tbegin_retry_aborts (int retries, uint64_t abort_code) +{ + int rc; + + counters.c1 = 0; + if ((rc = __builtin_tbegin_retry ((void *)0, retries)) == 0) + { + __builtin_non_tx_store ((uint64_t *)&counters.c1, counters.c1 + 1); + __builtin_tabort (abort_code); + return 2; + } + else + { + if ((abort_code & 1) == 0) + { + if (rc != 2) + { + return 100 * rc + 2003; + } + else if (counters.c1 != (uint64_t)retries + 1) + { + return 1000 * counters.c1 + 100 * retries + 4; + } + } + else + { + if (rc != 3) + { + return 100 * rc + 3005; + } + else if (counters.c1 != 1) + { + return 1000 * counters.c1 + 100 * retries + 6; + } + } + } + + return 0; +} + +static int test_tbegin_retry_aborts (void) +{ + int rc; + int retries; + + for (retries = 1; retries <= 3; retries++) + { + rc = _test_tbegin_retry_aborts (retries, 256); + if (rc != 0) + { + return 10000 + rc; + } + } + for (retries = 1; retries <= 3; retries++) + { + rc = _test_tbegin_retry_aborts (retries, 257); + if (rc != 0) + { + return 20000 + rc; + } + } + if ((rc = __builtin_tbegin_retry ((void *)0, 5)) == 0) + { + global.float_3 = global.float_1 + global.float_2; + rc = __builtin_tend (); + if (rc != 0) + { + return 30000 + 100 * rc + 6; + } + } + else + { + return 30000 + 100 * rc + 7; + } + + return 0; +} + +static int _test_tbegin_retry_nofloat_aborts (int retries, uint64_t abort_code) +{ + int rc; + + counters.c1 = 0; + if ((rc = __builtin_tbegin_retry_nofloat ((void *)0, retries)) == 0) + { + __builtin_non_tx_store ((uint64_t *)&counters.c1, counters.c1 + 1); + __builtin_tabort (abort_code); + return 2; + } + else + { + if ((abort_code & 1) == 0) + { + if (rc != 2) + { + return 100 * rc + 2003; + } + else if (counters.c1 != (uint64_t)retries + 1) + { + return 1000 * counters.c1 + 100 * retries + 4; + } + } + else + { + if (rc != 3) + { + return 100 * rc + 3005; + } + else if (counters.c1 != 1) + { + return 1000 * counters.c1 + 100 * retries + 6; + } + } + } + + return 0; +} + +static int test_tbegin_retry_nofloat_aborts (void) +{ + int rc; + int retries; + + for (retries = 1; retries <= 3; retries++) + { + rc = _test_tbegin_retry_nofloat_aborts (retries, 256); + if (rc != 0) + { + return 10 * retries + rc; + } + } + for (retries = 1; retries <= 3; retries++) + { + rc = _test_tbegin_retry_nofloat_aborts (retries, 257); + if (rc != 0) + { + return 10000 + 10 * retries + rc; + } + } + + return 0; +} + +static int test_tbegin_tdb (void) +{ + int rc; + + local_tdb.format = 0; + if ((rc = __builtin_tbegin (&local_tdb)) == 0) + { + rc = __builtin_tend (); + if (rc != 0) + { + return 100 * rc + 1; + } + if (local_tdb.format != 0) + { + dump_tdb (&local_tdb); + return 100 * local_tdb.format + 2; + } + } + else + { + return 100 * rc + 3; + } + local_tdb.format = 0; + if ((rc = __builtin_tbegin (&local_tdb)) == 0) + { + __builtin_tabort (257); + return 4; + } + else + { + if (rc != 3) + { + return 100 * rc + 5; + } + if (local_tdb.format != 1) + { + dump_tdb (&local_tdb); + return 100 * local_tdb.format + 6; + } + } + local_tdb256.format = 0; + if ((rc = __builtin_tbegin (&local_tdb256)) == 0) + { + rc = __builtin_tend (); + if (rc != 0) + { + return 1100 * rc + 1; + } + if (local_tdb256.format != 0) + { + dump_tdb (&local_tdb256); + return 1100 * local_tdb256.format + 2; + } + } + else + { + return 1100 * rc + 3; + } + local_tdb256.format = 0; + if ((rc = __builtin_tbegin (&local_tdb256)) == 0) + { + __builtin_tabort (257); + return 2004; + } + else + { + if (rc != 3) + { + return 2100 * rc + 5; + } + if (local_tdb256.format != 1) + { + dump_tdb (&local_tdb256); + return 2100 * local_tdb256.format + 6; + } + } + + return 0; +} + +static int test_tbegin_nofloat_tdb (void) +{ + int rc; + + local_tdb.format = 0; + if ((rc = __builtin_tbegin_nofloat (&local_tdb)) == 0) + { + rc = __builtin_tend (); + if (rc != 0) + { + return 100 * rc + 1; + } + if (local_tdb.format != 0) + { + dump_tdb (&local_tdb); + return 100 * local_tdb.format + 2; + } + } + else + { + return 3; + } + local_tdb.format = 0; + if ((rc = __builtin_tbegin_nofloat (&local_tdb)) == 0) + { + __builtin_tabort (257); + return 4; + } + else + { + if (rc != 3) + { + return 100 * rc + 5; + } + if (local_tdb.format != 1) + { + dump_tdb (&local_tdb); + return 100 * local_tdb.format + 6; + } + } + local_tdb256.format = 0; + if ((rc = __builtin_tbegin_nofloat (&local_tdb256)) == 0) + { + rc = __builtin_tend (); + if (rc != 0) + { + return 1100 * rc + 1; + } + if (local_tdb256.format != 0) + { + dump_tdb (&local_tdb256); + return 1100 * local_tdb256.format + 2; + } + } + else + { + return 1003; + } + local_tdb256.format = 0; + if ((rc = __builtin_tbegin_nofloat (&local_tdb256)) == 0) + { + __builtin_tabort (257); + return 2004; + } + else + { + if (rc != 3) + { + return 2100 * rc + 5; + } + if (local_tdb256.format != 1) + { + dump_tdb (&local_tdb256); + return 2100 * local_tdb256.format + 6; + } + } + + return 0; +} + +static int test_tbegin_retry_tdb (void) +{ + int rc; + + local_tdb256.format = 0; + if ((rc = __builtin_tbegin_retry (&local_tdb256, 2)) == 0) + { + rc = __builtin_tend (); + if (rc != 0) + { + return 1100 * rc + 1; + } + if (local_tdb256.format != 0) + { + dump_tdb (&local_tdb256); + return 1100 * local_tdb256.format + 2; + } + } + else + { + return 1003; + } + local_tdb256.format = 0; + if ((rc = __builtin_tbegin_retry (&local_tdb256, 2)) == 0) + { + __builtin_tabort (257); + return 2004; + } + else + { + if (rc != 3) + { + return 2100 * rc + 5; + } + if (local_tdb256.format != 1) + { + dump_tdb (&local_tdb256); + return 2100 * local_tdb256.format + 6; + } + } + + return 0; +} + +static int test_tbegin_retry_nofloat_tdb (void) +{ + int rc; + + local_tdb.format = 0; + if ((rc = __builtin_tbegin_retry_nofloat (&local_tdb, 2)) == 0) + { + rc = __builtin_tend (); + if (rc != 0) + { + return 100 * rc + 1; + } + if (local_tdb.format != 0) + { + dump_tdb (&local_tdb); + return 100 * local_tdb.format + 2; + } + } + else + { + return 100 * rc + 3; + } + local_tdb.format = 0; + if ((rc = __builtin_tbegin_retry_nofloat (&local_tdb, 2)) == 0) + { + __builtin_tabort (257); + return 4; + } + else + { + if (rc != 3) + { + return 100 * rc + 5; + } + if (local_tdb.format != 1) + { + dump_tdb (&local_tdb); + return 100 * local_tdb.format + 6; + } + } + local_tdb256.format = 0; + if ((rc = __builtin_tbegin_retry_nofloat (&local_tdb256, 2)) == 0) + { + rc = __builtin_tend (); + if (rc != 0) + { + return 1100 * rc + 1; + } + if (local_tdb256.format != 0) + { + dump_tdb (&local_tdb256); + return 1100 * local_tdb256.format + 2; + } + } + else + { + return 1100 * rc + 3; + } + local_tdb256.format = 0; + if ((rc = __builtin_tbegin_retry_nofloat (&local_tdb256, 2)) == 0) + { + __builtin_tabort (257); + return 2004; + } + else + { + if (rc != 3) + { + return 2100 * rc + 5; + } + if (local_tdb256.format != 1) + { + dump_tdb (&local_tdb256); + return 2100 * local_tdb256.format + 6; + } + } + + return 0; +} + +static int test_etnd (void) +{ + int rc; + + counters.c1 = 0; + counters.c2 = 0; + counters.c3 = 0; + if ((rc = __builtin_tbegin ((void *)0)) == 0) + { + counters.c1 = __builtin_tx_nesting_depth (); + if (__builtin_tbegin ((void *)0) == 0) + { + counters.c2 = __builtin_tx_nesting_depth (); + if (__builtin_tbegin ((void *)0) == 0) + { + counters.c3 = __builtin_tx_nesting_depth (); + __builtin_tend (); + } + __builtin_tend (); + } + __builtin_tend (); + } + else + { + return 100 * rc + 1; + } + if (counters.c1 != 1) + { + return 100 * counters.c1 + 2; + } + if (counters.c2 != 2) + { + return 100 * counters.c2 + 3; + } + if (counters.c3 != 3) + { + return 100 * counters.c3 + 4; + } + + return 0; +} + +static int test_tbeginc (void) +{ + int rc; + + counters.c1 = 0; + __builtin_tbeginc (); + counters.c1 = 1; + rc = __builtin_tend (); + if (rc != 0) + { + return 10000 * rc + 1; + } + if (counters.c1 != 1) + { + return 100000 * counters.c1 + 3; + } + + return 0; +} + +/* ---------------------------- local testing framework functions ---------- */ + +static int run_one_test (const test_table_entry_t *test_entry) +{ + int do_print_passes; + int succeeded; + int rc; + int i; + + /* Warmup run to get all necessary data and instruction pages into the page + * tables. */ + { + int run; + + do_dump_tdb = 0; + for (run = 0; run < NUM_WARMUP_RUNS; run++) + { + test_entry->test_func (); + } + do_dump_tdb = 1; + } + do_print_passes = ( + test_entry->required_quorum != 1 || + test_entry->max_repetitions != 1); + printf ("RRR RUN %s\n", test_entry->name); + if (do_print_passes == 1) + { + printf ( + " (requires %d successful out of %d runs)\n", + test_entry->required_quorum, + test_entry->max_repetitions); + } + succeeded = 0; + rc = 0; + for (rc = 0, i = 0; i < test_entry->max_repetitions; i++) + { + if (do_print_passes == 1) + { + if (i == 0) + { + printf (" "); + } + else + { + printf (","); + } + } + rc = test_entry->test_func (); + if (rc == 0) + { + if (do_print_passes == 1) + { + printf (" success"); + } + succeeded++; + if (succeeded >= test_entry->required_quorum) + { + break; + } + } + else + { + printf (" failed (rc = %d)", rc); + } + } + if (do_print_passes == 1 || rc != 0) + { + printf ("\n"); + } + if (succeeded >= test_entry->required_quorum) + { + printf ("+++ OK %s\n", test_entry->name); + + return 0; + } + else + { + printf ("--- FAIL %s\n", test_entry->name); + + return (rc != 0) ? rc : -1; + } +} + +static int run_all_tests (const test_table_entry_t *test_table) +{ + const test_table_entry_t *test; + int rc; + + for ( + rc = 0, test = &test_table[0]; + test->test_func != NULL && rc == 0; test++) + { + rc = run_one_test (test); + } + + return rc; +} + +/* ---------------------------- interface functions ------------------------ */ + +int main (void) +{ + const test_table_entry_t test_table[] = { + TEST_NO_REP (test_constants), + TEST_DF_REP (test_tbegin_ntstg_tend), + TEST_DF_REP (test_tbegin_ntstg_tabort), + TEST_DF_REP (test_tbegin_nofloat), + TEST_NO_REP (test_tbegin_retry), + TEST_NO_REP (test_tbegin_retry_nofloat), + TEST_DF_REP (test_tbegin_aborts), + TEST_DF_REP (test_tbegin_indirect_aborts), + TEST_DF_REP (test_tbegin_nofloat_aborts), + TEST_DF_REP (test_tbegin_nofloat_indirect_aborts), + TEST_NO_REP (test_tbegin_retry_aborts), + TEST_NO_REP (test_tbegin_retry_nofloat_aborts), + TEST_DF_REP (test_tbegin_tdb), + TEST_DF_REP (test_tbegin_nofloat_tdb), + TEST_NO_REP (test_tbegin_retry_tdb), + TEST_NO_REP (test_tbegin_retry_nofloat_tdb), + TEST_DF_REP (test_etnd), + TEST_DF_REP (test_tbeginc), + { (void *)0, 0, 0 } + }; + + { + int rc; + + rc = run_all_tests (test_table); + + return rc; + } +} diff --git a/gcc-4.9/gcc/testsuite/gcc.target/s390/htm-builtins-2.c b/gcc-4.9/gcc/testsuite/gcc.target/s390/htm-builtins-2.c new file mode 100644 index 000000000..15b0d12ae --- /dev/null +++ b/gcc-4.9/gcc/testsuite/gcc.target/s390/htm-builtins-2.c @@ -0,0 +1,682 @@ +/* Functional tests of the htm __TM_... macros. */ + +/* { dg-do run } */ +/* { dg-require-effective-target htm } */ +/* { dg-options "-O3 -march=zEC12 -mzarch" } */ + +/* ---------------------------- included header files ---------------------- */ + +#include <stdio.h> +#include <string.h> +#include <inttypes.h> +#include <htmxlintrin.h> + +/* ---------------------------- local definitions -------------------------- */ + +#define DEFAULT_MAX_REPETITIONS 5 +#define DEFAULT_REQUIRED_QUORUM ((DEFAULT_MAX_REPETITIONS) - 1) +#define DEFAULT_ABORT_ADDRESS (0x12345678u) + +/* ---------------------------- local macros ------------------------------- */ + +#define TEST_DF_REP(name) \ + { #name, name, DEFAULT_MAX_REPETITIONS, DEFAULT_REQUIRED_QUORUM } +#define TEST_NO_REP(name) { #name, name, 1, 1 } + +/* ---------------------------- local types -------------------------------- */ + +typedef int (*test_func_t)(void); + +typedef struct +{ + const char *name; + test_func_t test_func; + int max_repetitions; + int required_quorum; +} test_table_entry_t; + +typedef enum +{ + ABORT_T_SYSTEM = 0, + ABORT_T_USER = 1, +} abort_user_t; + +typedef enum +{ + ABORT_T_NONE = 0, + ABORT_T_ILLEGAL, + ABORT_T_FOOTPRINT_EXCEEDED, + ABORT_T_NESTED_TOO_DEEP, + ABORT_T_CONFLICT, + + ABORT_T_INVALID_ABORT_CODE +} abort_t; + +/* ---------------------------- local variables ---------------------------- */ + +__attribute__ ((aligned(256))) static struct __htm_tdb local_tdb256; +static struct __htm_tdb local_tdb; + +static abort_t const abort_classes[] = +{ + ABORT_T_INVALID_ABORT_CODE, + ABORT_T_NONE, + ABORT_T_NONE, + ABORT_T_NONE, + + ABORT_T_ILLEGAL, + ABORT_T_NONE, + ABORT_T_NONE, + ABORT_T_FOOTPRINT_EXCEEDED, + + ABORT_T_FOOTPRINT_EXCEEDED, + ABORT_T_CONFLICT, + ABORT_T_CONFLICT, + ABORT_T_ILLEGAL, + + ABORT_T_NONE, + ABORT_T_NESTED_TOO_DEEP, + ABORT_T_NONE, + ABORT_T_NONE, + + ABORT_T_NONE +}; + +static size_t num_abort_classes = sizeof(abort_classes) / sizeof(abort_t); + +/* ---------------------------- exported variables (globals) --------------- */ + +int global_int = 0; +uint64_t global_u64 = 0; +float global_float_1 = 1.0; +float global_float_2 = 2.5; +float global_float_3 = 0.0; +__attribute__ ((aligned(256))) struct +{ + volatile uint64_t c1; + volatile uint64_t c2; + volatile uint64_t c3; +} counters = { 0, 0, 0 }; + +/* ---------------------------- local helper functions --------------------- */ + +static void dump_tdb(struct __htm_tdb *tdb) +{ + unsigned char *p; + int i; + int j; + + p = (unsigned char *)tdb; + for (i = 0; i < 16; i++) + { + fprintf(stderr, "0x%02x ", i * 16); + for (j = 0; j < 16; j++) + { + fprintf(stderr, "%02x", (int)p[i * 16 + j]); + if (j < 15) + { + fprintf(stderr, " "); + } + if (j == 7) + { + fprintf(stderr, " "); + } + } + fprintf(stderr, "\n"); + } + + return; +} + +static void make_fake_tdb(struct __htm_tdb *tdb) +{ + memset(tdb, 0, sizeof(*tdb)); + tdb->format = 1; + tdb->nesting_depth = 1; + tdb->atia = DEFAULT_ABORT_ADDRESS; + tdb->abort_code = 11; + + return; +} + +static int check_abort_code_in_tdb(struct __htm_tdb *tdb, uint64_t abort_code) +{ + long expect_rc; + long rc; + + if (abort_code != 0) + { + long addr; + + addr = __TM_failure_address(&local_tdb); + if (addr != DEFAULT_ABORT_ADDRESS) + { + return 11; + } + } + { + long long tdb_abort_code; + + tdb_abort_code = __TM_failure_code(tdb); + if ((uint64_t)tdb_abort_code != abort_code) + { + fprintf( + stderr, "tm_ac %" PRIu64 ", ac %" PRIu64 + ", tdb_ac %" PRIu64 "\n", + (uint64_t)tdb_abort_code, abort_code, + (uint64_t)tdb->abort_code); + return 10; + } + } + expect_rc = (abort_code >= 256) ? 1 : 0; + rc = __TM_is_user_abort(tdb); + if (rc != expect_rc) + { + fprintf(stderr, "rc %ld, expect_rc %ld\n", rc, expect_rc); + return 1; + } + { + unsigned char code; + + code = 0xffu; + rc = __TM_is_named_user_abort(tdb, &code); + if (rc != expect_rc) + { + fprintf( + stderr, "rc %ld, expect_rc %ld\n", rc, + expect_rc); + return 2; + } + if (expect_rc == 1 && code != abort_code - 256) + { + return 3; + } + } + if (abort_code > (uint64_t)num_abort_classes) + { + abort_code = (uint64_t)num_abort_classes; + } + expect_rc = (abort_classes[abort_code] == ABORT_T_ILLEGAL) ? 1 : 0; + rc = __TM_is_illegal(tdb); + if (rc != expect_rc) + { + dump_tdb(tdb); + fprintf(stderr, "rc %ld, expect_rc %ld\n", rc, expect_rc); + return 4; + } + expect_rc = + (abort_classes[abort_code] == ABORT_T_FOOTPRINT_EXCEEDED) ? + 1 : 0; + rc = __TM_is_footprint_exceeded(tdb); + if (rc != expect_rc) + { + dump_tdb(tdb); + fprintf(stderr, "rc %ld, expect_rc %ld\n", rc, expect_rc); + return 5; + } + expect_rc = + (abort_classes[abort_code] == ABORT_T_NESTED_TOO_DEEP) ? 1 : 0; + rc = __TM_is_nested_too_deep(tdb); + if (rc != expect_rc) + { + dump_tdb(tdb); + fprintf(stderr, "rc %ld, expect_rc %ld\n", rc, expect_rc); + return 6; + } + expect_rc = (abort_classes[abort_code] == ABORT_T_CONFLICT) ? 1 : 0; + rc = __TM_is_conflict(tdb); + if (rc != expect_rc) + { + dump_tdb(tdb); + fprintf(stderr, "rc %ld, expect_rc %ld\n", rc, expect_rc); + return 7; + } + + return 0; +} + +/* ---------------------------- local test functions ----------------------- */ + +/* Not a test; make sure that the involved global cachelines are reserved for + * writing. */ +static int init_cache(void) +{ + make_fake_tdb(&local_tdb); + make_fake_tdb(&local_tdb256); + global_int = 0; + global_u64 = 0; + global_float_1 = 1.0; + global_float_2 = 2.5; + global_float_3 = 0.0; + counters.c1 = 0; + counters.c2 = 0; + counters.c3 = 0; + + return 0; +} + +static int test_abort_classification(void) +{ + int i; + + make_fake_tdb(&local_tdb); + for (i = 0; i <= 256; i++) + { + int rc; + + local_tdb.abort_code = (uint64_t)i; + rc = check_abort_code_in_tdb(&local_tdb, (uint64_t)i); + if (rc != 0) + { + return 100 * i + rc; + } + } + + return 0; +} + +static int test_cc_classification(void) +{ + long rc; + + rc = __TM_is_failure_persistent(0); + if (rc != 0) + { + return 1; + } + rc = __TM_is_failure_persistent(1); + if (rc != 0) + { + return 2; + } + rc = __TM_is_failure_persistent(2); + if (rc != 0) + { + return 3; + } + rc = __TM_is_failure_persistent(3); + if (rc != 1) + { + return 4; + } + + return 0; +} + +static int test_tbegin_ntstg_tend(void) +{ + long rc; + + counters.c1 = 0; + counters.c2 = 0; + if ((rc = __TM_simple_begin()) == 0) + { + __TM_non_transactional_store((uint64_t *)&counters.c1, 1); + counters.c2 = 2; + rc = __TM_end(); + if (rc != 0) + { + return 100 * rc + 5; + } + if (counters.c1 != 1) + { + return 100 * counters.c1 + 2; + } + if (counters.c2 != 2) + { + return 100 * counters.c2 + 3; + } + } + else + { + return 100 * rc + 4; + } + + return 0; +} + +static int test_tbegin_ntstg_tabort(void) +{ + register float f; + + counters.c1 = 0; + counters.c2 = 0; + f = 0; + if (__TM_simple_begin() == 0) + { + __TM_non_transactional_store((uint64_t *)&counters.c1, 1); + counters.c2 = 2; + f = 1; + __TM_named_abort(0); + return 1; + } + if (counters.c1 != 1) + { + return 100 * counters.c1 + 2; + } + if (counters.c2 != 0) + { + return 100 * counters.c2 + 3; + } + if (f != 0) + { + return 100 * f + 4; + } + + return 0; +} + +static int test_tbegin_aborts(void) +{ + float f; + long rc; + + f = 77; + if ((rc = __TM_simple_begin()) == 0) + { + f = 88; + __TM_abort(); + return 2; + } + else if (rc != 2) + { + return 3; + } + if (f != 77) + { + return 4; + } + f = 66; + if ((rc = __TM_simple_begin()) == 0) + { + f = 99; + __TM_named_abort(3); + return 5; + } + else if (rc != 3) + { + return 100 * rc + 6; + } + if (f != 66) + { + return 100 * f + 7; + } + if ((rc = __TM_simple_begin()) == 0) + { + global_float_3 = global_float_1 + global_float_2; + rc = __TM_end(); + if (rc != 0) + { + return 100 * rc + 8; + } + } + else + { + return 100 * rc + 9; + } + if (global_float_3 != global_float_1 + global_float_2) + { + return 100 * rc + 10; + } + + return 0; +} + +static int test_tbegin_tdb(void) +{ + long rc; + + local_tdb.format = 0; + if ((rc = __TM_begin(&local_tdb)) == 0) + { + rc = __TM_end(); + if (rc != 0) + { + return 100 * rc + 1; + } + if (local_tdb.format != 0) + { + dump_tdb(&local_tdb); + return 100 * local_tdb.format + 2; + } + } + else + { + return 100 * rc + 3; + } + local_tdb.format = 0; + if ((rc = __TM_begin(&local_tdb)) == 0) + { + __TM_named_abort(1); + return 4; + } + else + { + if (rc != 3) + { + return 100 * rc + 5; + } + if (local_tdb.format != 1) + { + dump_tdb(&local_tdb); + return 100 * local_tdb.format + 6; + } + } + local_tdb256.format = 0; + if ((rc = __TM_begin(&local_tdb256)) == 0) + { + rc = __TM_end(); + if (rc != 0) + { + return 1100 * rc + 1; + } + if (local_tdb256.format != 0) + { + dump_tdb(&local_tdb256); + return 1100 * local_tdb256.format + 2; + } + } + else + { + return 1100 * rc + 3; + } +#if 1 /*!!!does not work*/ + local_tdb256.format = 0; + if ((rc = __TM_begin(&local_tdb256)) == 0) + { + __TM_named_abort(1); + return 2004; + } + else + { + if (rc != 3) + { + return 2100 * rc + 5; + } + if (local_tdb256.format != 1) + { + dump_tdb(&local_tdb256); + return 2100 * local_tdb256.format + 6; + } + } +#endif + + return 0; +} + +static int test_etnd(void) +{ + long rc; + + { + long nd; + + make_fake_tdb(&local_tdb); + local_tdb.nesting_depth = 0; + nd = __TM_nesting_depth(&local_tdb); + if (nd != 0) + { + return 1; + } + local_tdb.nesting_depth = 7; + nd = __TM_nesting_depth(&local_tdb); + if (nd != 7) + { + return 7; + } + local_tdb.format = 0; + nd = __TM_nesting_depth(&local_tdb); + if (nd != 0) + { + return 2; + } + } + counters.c1 = 0; + counters.c1 = 0; + counters.c2 = 0; + counters.c3 = 0; + if ((rc = __TM_simple_begin()) == 0) + { + counters.c1 = __TM_nesting_depth(0); + if (__TM_simple_begin() == 0) + { + counters.c2 = __TM_nesting_depth(0); + if (__TM_simple_begin() == 0) + { + counters.c3 = __TM_nesting_depth(0); + __TM_end(); + } + __TM_end(); + } + __TM_end(); + } + else + { + return 100 * rc + 1; + } + if (counters.c1 != 1) + { + return 100 * counters.c1 + 2; + } + if (counters.c2 != 2) + { + return 100 * counters.c2 + 3; + } + if (counters.c3 != 3) + { + return 100 * counters.c3 + 4; + } + + return 0; +} + +/* ---------------------------- local testing framework functions ---------- */ + +static int run_one_test(const test_table_entry_t *test_entry) +{ + int do_print_passes; + int succeeded; + int rc; + int i; + + do_print_passes = ( + test_entry->required_quorum != 1 || + test_entry->max_repetitions != 1); + printf("RRR RUN %s\n", test_entry->name); + if (do_print_passes == 1) + { + printf( + " (requires %d successful out of %d runs)\n", + test_entry->required_quorum, + test_entry->max_repetitions); + } + succeeded = 0; + rc = 0; + for (rc = 0, i = 0; i < test_entry->max_repetitions; i++) + { + if (do_print_passes == 1) + { + if (i == 0) + { + printf(" "); + } + else + { + printf(","); + } + } + rc = test_entry->test_func(); + if (rc == 0) + { + if (do_print_passes == 1) + { + printf(" success"); + } + succeeded++; + if (succeeded >= test_entry->required_quorum) + { + break; + } + } + else + { + printf(" failed (rc = %d)", rc); + } + } + if (do_print_passes == 1 || rc != 0) + { + printf("\n"); + } + if (succeeded >= test_entry->required_quorum) + { + printf("+++ OK %s\n", test_entry->name); + + return 0; + } + else + { + printf("--- FAIL %s\n", test_entry->name); + + return (rc != 0) ? rc : -1; + } +} + +static int run_all_tests(const test_table_entry_t *test_table) +{ + const test_table_entry_t *test; + int rc; + + for ( + rc = 0, test = &test_table[0]; + test->test_func != NULL && rc == 0; test++) + { + rc = run_one_test(test); + } + + return rc; +} + +/* ---------------------------- interface functions ------------------------ */ + +int main(void) +{ + const test_table_entry_t test_table[] = { + TEST_NO_REP(init_cache), + TEST_NO_REP(test_abort_classification), + TEST_NO_REP(test_cc_classification), + TEST_DF_REP(test_tbegin_ntstg_tend), + TEST_DF_REP(test_tbegin_ntstg_tabort), + TEST_DF_REP(test_tbegin_aborts), + TEST_DF_REP(test_tbegin_tdb), + TEST_DF_REP(test_etnd), + { (void *)0, 0, 0 } + }; + + { + int rc; + + rc = run_all_tests(test_table); + + return rc; + } +} diff --git a/gcc-4.9/gcc/testsuite/gcc.target/s390/htm-builtins-compile-1.c b/gcc-4.9/gcc/testsuite/gcc.target/s390/htm-builtins-compile-1.c new file mode 100644 index 000000000..c1b98e2bb --- /dev/null +++ b/gcc-4.9/gcc/testsuite/gcc.target/s390/htm-builtins-compile-1.c @@ -0,0 +1,164 @@ +/* This checks the availability of the low-level builtins introduced + for transactional execution. */ + +/* { dg-do compile } */ +/* { dg-options "-O3 -march=zEC12 -mzarch" } */ + +#include <stdint.h> +#include <htmintrin.h> + +int global = 0; +uint64_t g; +struct __htm_tdb global_tdb; + +int +foo (struct __htm_tdb* tdb, int reg, int *mem, uint64_t *mem64) +{ + + int cc; + int n; + + __builtin_tbegin ((void *)0); + __builtin_tbegin ((void *)-99999); + __builtin_tbegin ((void *)99999); + while (__builtin_tbegin ((void *)0) != 0) + { + } + cc = __builtin_tbegin ((void *)0x12345678); + cc = __builtin_tbegin (tdb); + cc = __builtin_tbegin (&global_tdb); + cc = __builtin_tbegin ((void *)(long long)(reg + 0x12345678)); + cc = __builtin_tbegin ((void *)(long long)(reg)); + + __builtin_tbegin_nofloat ((void *)0); + __builtin_tbegin_nofloat ((void *)-99999); + __builtin_tbegin_nofloat ((void *)99999); + cc = __builtin_tbegin_nofloat ((void *)0x12345678); + cc = __builtin_tbegin_nofloat (tdb); + cc = __builtin_tbegin_nofloat (&global_tdb); + cc = __builtin_tbegin_nofloat ((void *)(long long)(reg + 0x12345678)); + cc = __builtin_tbegin_nofloat ((void *)(long long)(reg)); + + __builtin_tbegin_retry ((void *)0, 0); + cc = __builtin_tbegin_retry ((void *)0, 1); + cc = __builtin_tbegin_retry ((void *)0, -1); + cc = __builtin_tbegin_retry ((void *)0, 42); + cc = __builtin_tbegin_retry ((void *)0, reg); + cc = __builtin_tbegin_retry ((void *)0, *mem); + cc = __builtin_tbegin_retry ((void *)0, global); + cc = __builtin_tbegin_retry (tdb, 42); + cc = __builtin_tbegin_retry (&global_tdb, 42); + cc = __builtin_tbegin_retry ((void *)0x12345678, global); + cc = __builtin_tbegin_retry ( + (void *)(long long) (reg + 0x12345678), global + 1); + cc = __builtin_tbegin_retry ( + (void *)(long long)(reg), global - 1); + + __builtin_tbegin_retry_nofloat ((void *)0, 0); + cc = __builtin_tbegin_retry_nofloat ((void *)0, 1); + cc = __builtin_tbegin_retry_nofloat ((void *)0, -1); + cc = __builtin_tbegin_retry_nofloat ((void *)0, 42); + cc = __builtin_tbegin_retry_nofloat ((void *)0, reg); + cc = __builtin_tbegin_retry_nofloat ((void *)0, *mem); + cc = __builtin_tbegin_retry_nofloat ((void *)0, global); + cc = __builtin_tbegin_retry_nofloat (tdb, 42); + cc = __builtin_tbegin_retry_nofloat (&global_tdb, 42); + cc = __builtin_tbegin_retry_nofloat ((void *)0x12345678, global); + cc = __builtin_tbegin_retry_nofloat ( + (void *)(long long) (reg + 0x12345678), global + 1); + cc = __builtin_tbegin_retry_nofloat ( + (void *)(long long)(reg), global - 1); + + __builtin_tbeginc (); + + __builtin_tx_nesting_depth (); + n = __builtin_tx_nesting_depth (); + + __builtin_non_tx_store (mem64, 0); + { + const uint64_t val_var = 0x1122334455667788; + + __builtin_non_tx_store (mem64, val_var); + } + __builtin_non_tx_store (mem64, (uint64_t)reg); + __builtin_non_tx_store (mem64, g); + __builtin_non_tx_store ((uint64_t *)0, 0); + __builtin_non_tx_store ((uint64_t *)0x12345678, 0); + __builtin_non_tx_store (&g, 23); + __builtin_non_tx_store (&g, reg); + __builtin_non_tx_store (&g, *mem); + __builtin_non_tx_store (&g, global); + + __builtin_tend(); + + __builtin_tx_assist (0); + __builtin_tx_assist (1); + __builtin_tx_assist (reg); + __builtin_tx_assist (*mem); + __builtin_tx_assist (global); +} + +/* The taborts must go into separate function since they are + "noreturn". */ + +void +tabort1 () +{ + __builtin_tabort (256); +} + +void +tabort2 (int reg) +{ + __builtin_tabort (reg); +} + +void +tabort3 (int reg) +{ + /* { dg-final { scan-assembler-times "tabort\t255" 1 } } */ + __builtin_tabort (reg + 255); +} + +void +tabort4 (int *mem) +{ + __builtin_tabort (*mem); +} + +void +tabort5 () +{ + __builtin_tabort (global); +} + +void +tabort6 (int *mem) +{ + /* Here global + 255 gets reloaded into a reg. Better would be to + just reload global or *mem and get the +255 for free as address + arithmetic. */ + __builtin_tabort (*mem + 255); +} + +void +tabort7 () +{ + __builtin_tabort (global + 255); +} + +void +tabort8 () +{ + __builtin_tabort (-1); +} + + +/* Make sure the tdb NULL argument ends up as immediate value in the + instruction. */ +/* { dg-final { scan-assembler-times "tbegin\t0," 17 } } */ +/* { dg-final { scan-assembler-times "tbegin\t" 41 } } */ +/* Check number of occurences of certain instructions. */ +/* { dg-final { scan-assembler-times "tbeginc\t" 1 } } */ +/* { dg-final { scan-assembler-times "tabort\t" 8 } } */ +/* { dg-final { scan-assembler "ppa\t" } } */ diff --git a/gcc-4.9/gcc/testsuite/gcc.target/s390/htm-builtins-compile-2.c b/gcc-4.9/gcc/testsuite/gcc.target/s390/htm-builtins-compile-2.c new file mode 100644 index 000000000..67d76a6d3 --- /dev/null +++ b/gcc-4.9/gcc/testsuite/gcc.target/s390/htm-builtins-compile-2.c @@ -0,0 +1,12 @@ +/* { dg-do compile } */ +/* { dg-options "-O3 -march=zEC12 -mzarch" } */ + +void must_not_compile1 (void) +{ + __builtin_tabort (0); /* { dg-error "Invalid transaction abort code:" } */ +} + +void must_not_compile2 (void) +{ + __builtin_tabort (255); /* { dg-error "Invalid transaction abort code:" } */ +} diff --git a/gcc-4.9/gcc/testsuite/gcc.target/s390/htm-builtins-compile-3.c b/gcc-4.9/gcc/testsuite/gcc.target/s390/htm-builtins-compile-3.c new file mode 100644 index 000000000..77ceeb770 --- /dev/null +++ b/gcc-4.9/gcc/testsuite/gcc.target/s390/htm-builtins-compile-3.c @@ -0,0 +1,37 @@ +/* This checks the availability of the XL compiler intrinsics for + transactional execution with the expected prototypes. */ + +/* { dg-do compile } */ +/* { dg-options "-O3 -march=zEC12 -mzarch" } */ + +#include <htmxlintrin.h> + +int a = 0; +unsigned long g; + +int +foo () +{ + struct __htm_tdb *tdb_struct; + void * const tdb = tdb_struct; + long result; + unsigned char code; + + result = __TM_simple_begin (); + result = __TM_begin (tdb); + result = __TM_end (); + __TM_abort (); + __TM_named_abort (42); + __TM_non_transactional_store (&g, 42); + result = __TM_nesting_depth (tdb); + + result = __TM_is_user_abort (tdb); + result = __TM_is_named_user_abort (tdb, &code); + result = __TM_is_illegal (tdb); + result = __TM_is_footprint_exceeded (tdb); + result = __TM_is_nested_too_deep (tdb); + result = __TM_is_conflict (tdb); + result = __TM_is_failure_persistent (result); + result = __TM_failure_address (tdb); + result = __TM_failure_code (tdb); +} diff --git a/gcc-4.9/gcc/testsuite/gcc.target/s390/htm-nofloat-1.c b/gcc-4.9/gcc/testsuite/gcc.target/s390/htm-nofloat-1.c new file mode 100644 index 000000000..df7e2bac8 --- /dev/null +++ b/gcc-4.9/gcc/testsuite/gcc.target/s390/htm-nofloat-1.c @@ -0,0 +1,12 @@ +/* { dg-do compile } */ +/* { dg-options "-O3 -march=zEC12 -mzarch" } */ + +int +foo () +{ + __builtin_tbegin_nofloat (0); + __builtin_tbegin_retry_nofloat (0, 42); +} +/* Make sure no FPR saves/restores are emitted. */ +/* { dg-final { scan-assembler-not "std" } } */ +/* { dg-final { scan-assembler-not "ld" } } */ diff --git a/gcc-4.9/gcc/testsuite/gcc.target/s390/htm-nofloat-2.c b/gcc-4.9/gcc/testsuite/gcc.target/s390/htm-nofloat-2.c new file mode 100644 index 000000000..59621a4c1 --- /dev/null +++ b/gcc-4.9/gcc/testsuite/gcc.target/s390/htm-nofloat-2.c @@ -0,0 +1,55 @@ +/* { dg-do run } */ +/* { dg-options "-O3 -mhtm -Wa,-march=zEC12,-mzarch --save-temps" } */ + +/* __builtin_tbegin has to emit clobbers for all FPRs since the tbegin + instruction does not automatically preserves them. If the + transaction body is fully contained in a function the backend tries + after reload to get rid of the FPR save/restore operations + triggered by the clobbers. This testcase failed since the backend + was able to get rid of all FPR saves/restores and since these were + the only stack operations also of the entire stack space. So even + the save/restore of the stack pointer was omitted in the end. + However, since the frame layout has been fixed before, the prologue + still generated the stack pointer decrement making foo return with + a modified stack pointer. */ + +void abort(void); + +void __attribute__((noinline)) +foo (int a) +{ + /* This is just to prevent the tbegin code from actually being + executed. That way the test may even run on machines prior to + zEC12. */ + if (a == 42) + return; + + if (__builtin_tbegin (0) == 0) + __builtin_tend (); +} + +#ifdef __s390x__ +#define GET_STACK_POINTER(SP) \ + asm volatile ("stg %%r15, %0" : "=QRST" (SP)); +#else +#define GET_STACK_POINTER(SP) \ + asm volatile ("st %%r15, %0" : "=QR" (SP)); +#endif + +int main(void) +{ + unsigned long new_sp, old_sp; + + GET_STACK_POINTER (old_sp); + foo(42); + GET_STACK_POINTER (new_sp); + + if (old_sp != new_sp) + abort (); + + return 0; +} + +/* Make sure no FPR saves/restores are emitted. */ +/* { dg-final { scan-assembler-not "\tstd\t" } } */ +/* { dg-final { scan-assembler-not "\tld\t" } } */ diff --git a/gcc-4.9/gcc/testsuite/gcc.target/s390/nearestint-1.c b/gcc-4.9/gcc/testsuite/gcc.target/s390/nearestint-1.c new file mode 100644 index 000000000..1d9a753b3 --- /dev/null +++ b/gcc-4.9/gcc/testsuite/gcc.target/s390/nearestint-1.c @@ -0,0 +1,48 @@ +/* Since z196 the nearest integer functions can be expanded to single + instructions. */ + +/* { dg-do compile } */ +/* { dg-options "-O3 -march=z196 -mzarch" } */ + +extern float ceilf (float x); +extern double ceil (double x); +extern long double ceill (long double x); +extern float floorf (float x); +extern double floor (double x); +extern long double floorl (long double x); +extern float truncf (float x); +extern double trunc (double x); +extern long double truncl (long double x); +extern float nearbyintf (float x); +extern double nearbyint (double x); +extern long double nearbyintl (long double x); +extern float rintf (float x); +extern double rint (double x); +extern long double rintl (long double x); + +float my_ceilf (float x) { return ceilf (x); } +double my_ceil (double x) { return ceil (x); } +long double my_ceill (long double x) { return ceill (x); } + +float my_floorf (float x) { return floorf (x); } +double my_floor (double x) { return floor (x); } +long double my_floorl (long double x) { return floorl (x); } + +float my_truncf (float x) { return truncf (x); } +double my_trunc (double x) { return trunc (x); } +long double my_truncl (long double x) { return truncl (x); } + +float my_nearbyintf (float x) { return nearbyintf (x); } +double my_nearbyint (double x) { return nearbyint (x); } +long double my_nearbyintl (long double x) { return nearbyintl (x); } + +float my_rintf (float x) { return rintf (x); } +double my_rint (double x) { return rint (x); } +long double my_rintl (long double x) { return rintl (x); } + +/* { dg-final { scan-assembler-times "fiebr\t" 1 } } */ +/* { dg-final { scan-assembler-times "fidbr\t" 1 } } */ +/* { dg-final { scan-assembler-times "fixbr\t" 1 } } */ +/* { dg-final { scan-assembler-times "fiebra\t" 4 } } */ +/* { dg-final { scan-assembler-times "fidbra\t" 4 } } */ +/* { dg-final { scan-assembler-times "fixbra\t" 4 } } */ diff --git a/gcc-4.9/gcc/testsuite/gcc.target/s390/pr20927.c b/gcc-4.9/gcc/testsuite/gcc.target/s390/pr20927.c new file mode 100644 index 000000000..dbc990f15 --- /dev/null +++ b/gcc-4.9/gcc/testsuite/gcc.target/s390/pr20927.c @@ -0,0 +1,23 @@ +/* This caused an ICE on s390x due to a reload inheritance bug. */ + +/* { dg-do compile } */ +/* { dg-options "-O2" } */ + +struct point { double x, y; }; +extern void use (struct point); + +void test (struct point *pc, struct point p1) +{ + struct point p0 = *pc; + + if (p0.x == p1.x && p0.y == p1.y) + use (p0); + + asm ("" : : : "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "10"); + + p1.y -= p0.y; + + use (p0); + use (p1); +} + diff --git a/gcc-4.9/gcc/testsuite/gcc.target/s390/pr24624.c b/gcc-4.9/gcc/testsuite/gcc.target/s390/pr24624.c new file mode 100644 index 000000000..bc2070c4b --- /dev/null +++ b/gcc-4.9/gcc/testsuite/gcc.target/s390/pr24624.c @@ -0,0 +1,67 @@ +/* This used to ICE due to a backend problem on s390. */ + +/* { dg-do compile } */ +/* { dg-options "-O1 -mpacked-stack" } */ + +typedef unsigned int __u32; +typedef struct +{ + volatile int counter; +} __attribute__ ((aligned (4))) atomic_t; +static __inline__ __attribute__ ((always_inline)) + void atomic_inc (volatile atomic_t * v) +{ + ( + { + typeof (v->counter) old_val, new_val; + __asm__ __volatile__ ( + " l %0,0(%3)\n" + "0: lr %1,%0\n" + " ar %1,%4\n" + " cs %0,%1,0(%3)\n" + " jl 0b": + "=&d" (old_val), "=&d" (new_val), "=m" (((atomic_t *) (v))->counter): + "a" (v), "d" (1), "m" (((atomic_t *) (v))->counter): + "cc", "memory"); + }); +} +extern unsigned long volatile __attribute__ ((section (".data"))) jiffies; +struct inet_peer +{ + unsigned long dtime; + atomic_t refcnt; +}; +static volatile int peer_total; +int inet_peer_threshold = 65536 + 128; +int inet_peer_minttl = 120 * 100; +int inet_peer_maxttl = 10 * 60 * 100; +static int +cleanup_once (unsigned long ttl) +{ + struct inet_peer *p; + if (p != ((void *) 0)) + { + if ((( + { + 1;} + ) && ((long) (jiffies) - (long) (p->dtime + ttl) < 0))) + { + return -1; + } + atomic_inc (&p->refcnt); + } +} +struct inet_peer * +inet_getpeer (__u32 daddr, int create) +{ + int i; + int ttl; + if (peer_total >= inet_peer_threshold) + ttl = inet_peer_minttl; + else + ttl = + inet_peer_maxttl - (inet_peer_maxttl - + inet_peer_minttl) / 100 * peer_total / + inet_peer_threshold * 100; + for (i = 0; i < 30 && !cleanup_once (ttl); i++); +} diff --git a/gcc-4.9/gcc/testsuite/gcc.target/s390/pr27661.c b/gcc-4.9/gcc/testsuite/gcc.target/s390/pr27661.c new file mode 100644 index 000000000..1ff6dcc7c --- /dev/null +++ b/gcc-4.9/gcc/testsuite/gcc.target/s390/pr27661.c @@ -0,0 +1,25 @@ +/* This used to ICE on s390 due to a reload bug. */ + +/* { dg-do compile } */ +/* { dg-options "-O2 -march=z990 -ftracer" } */ + +extern int memcmp (const void *s1, const void *s2, unsigned long n); +extern int printf (__const char *__restrict __format, ...); + +struct test +{ + char tmp[4096]; + char msgtype[2]; +}; + +void test (struct test *testtb) +{ + if (testtb) + printf ("a"); + + if (memcmp(testtb->msgtype, "a", 2)) + printf ("a"); + + printf ("b"); +} + diff --git a/gcc-4.9/gcc/testsuite/gcc.target/s390/pr36822.c b/gcc-4.9/gcc/testsuite/gcc.target/s390/pr36822.c new file mode 100644 index 000000000..fb021f214 --- /dev/null +++ b/gcc-4.9/gcc/testsuite/gcc.target/s390/pr36822.c @@ -0,0 +1,16 @@ +/* This used to ICE on s390 due to bug in the definition of the 'R' + constraint which replaced the 'm' constraint (together with 'T') + while adding z10 support. */ + +/* { dg-do compile } */ +/* { dg-options "-O" } */ + +int boo() +{ + struct { + unsigned char pad[4096]; + unsigned long bar; + } *foo; + asm volatile( "" : "=m" (*(unsigned long long*)(foo->bar)) + : "a" (&foo->bar)); +} diff --git a/gcc-4.9/gcc/testsuite/gcc.target/s390/pr42224.c b/gcc-4.9/gcc/testsuite/gcc.target/s390/pr42224.c new file mode 100644 index 000000000..c1ccf28d5 --- /dev/null +++ b/gcc-4.9/gcc/testsuite/gcc.target/s390/pr42224.c @@ -0,0 +1,36 @@ + +/* { dg-do compile } */ +/* { dg-options "-O0" } */ + +typedef char* __char_ptr32 __attribute__ (( mode (SI) )); +typedef __char_ptr32 *__char_ptr_char_ptr32 __attribute__ ((mode (SI))); + +void to_ptr32 (int x) +{ + __char_ptr32 ptr = (__char_ptr32) x; +} + +void to_int (__char_ptr32 ptr) +{ + int x = (int) ptr; +} + +__char_ptr_char_ptr32 +to_ptr32_ptr32 (char **ptr64) +{ + int argc; + __char_ptr_char_ptr32 short_argv; + + for (argc=0; ptr64[argc]; argc++); + + short_argv = (__char_ptr_char_ptr32) malloc32 + (sizeof (__char_ptr32) * (argc + 1)); + + for (argc=0; ptr64[argc]; argc++) + short_argv[argc] = (__char_ptr32) strdup32 (ptr64[argc]); + + short_argv[argc] = (__char_ptr32) 0; + return short_argv; + +} + diff --git a/gcc-4.9/gcc/testsuite/gcc.target/s390/pr55718.c b/gcc-4.9/gcc/testsuite/gcc.target/s390/pr55718.c new file mode 100644 index 000000000..a82d43522 --- /dev/null +++ b/gcc-4.9/gcc/testsuite/gcc.target/s390/pr55718.c @@ -0,0 +1,29 @@ +/* PR target/55717 */ + +/* { dg-do compile } */ +/* { dg-options "-O2 -march=z10 -fPIC" } */ + +extern char temp[]; +short ansi_value[256]; +void terminal_state(void) +{ + static const char *puc[] = { "", "<", "=", ">", "?", 0}; + int i, j, k, l, modes_found; + char buf[256]; + k = (int) __builtin_strlen(temp); + for (j = l = 0; j < 255 && j - l < 50; j++) + { + __builtin_sprintf(temp, "\033[%s%d$p", puc[i], j); + if (ansi_value[1]) + { + l = j; + buf[k] = '\0'; + put_crlf(); + ptextln(buf); + buf[k++] = ' '; + k = (int) __builtin_strlen(temp); + } + } + for (i = j = 0; j < modes_found; j = ++i >> 1) + ; +} diff --git a/gcc-4.9/gcc/testsuite/gcc.target/s390/pr57559.c b/gcc-4.9/gcc/testsuite/gcc.target/s390/pr57559.c new file mode 100644 index 000000000..15c3878c4 --- /dev/null +++ b/gcc-4.9/gcc/testsuite/gcc.target/s390/pr57559.c @@ -0,0 +1,24 @@ +/* PR rtl-optimization/57559 */ + +/* { dg-do compile } */ +/* { dg-options "-march=z10 -m64 -mzarch -O1" } */ + +typedef int int32_t; +typedef unsigned char uint8_t; +typedef unsigned int uint32_t; +struct _IO_marker +{ +}; +static const int32_t mfcone = 1; +static const uint8_t *mfctop = (const uint8_t *) &mfcone; +int32_t +decContextTestEndian (uint8_t quiet) +{ + int32_t res = 0; + uint32_t dle = (uint32_t) 0; + if (*(int *) 10 != 0) + { + res = (int32_t) * mfctop - dle; + } + return res; +} diff --git a/gcc-4.9/gcc/testsuite/gcc.target/s390/pr57960.c b/gcc-4.9/gcc/testsuite/gcc.target/s390/pr57960.c new file mode 100644 index 000000000..ee751edc8 --- /dev/null +++ b/gcc-4.9/gcc/testsuite/gcc.target/s390/pr57960.c @@ -0,0 +1,30 @@ +/* PR rtl-optimization/57960 */ + +/* { dg-do compile } */ +/* { dg-options "-march=z10 -m64 -mzarch -O1" } */ + +typedef union +{ + long double value; + struct + { + unsigned int w0, w1, w2, w3; + } + parts32; +} + ieee854_long_double_shape_type; +static const long double one = 1.0L; +long double +__ieee754_acosl (long double x) +{ + long double z, w; + int ix; + ieee854_long_double_shape_type u; + + z = (one - u.value) * 0.5; + u.parts32.w2 = 0; + u.parts32.w3 = 0; + w = z - u.value * u.value; + return 2.0 * w; + +} diff --git a/gcc-4.9/gcc/testsuite/gcc.target/s390/return-addr1.c b/gcc-4.9/gcc/testsuite/gcc.target/s390/return-addr1.c new file mode 100644 index 000000000..8872b89b7 --- /dev/null +++ b/gcc-4.9/gcc/testsuite/gcc.target/s390/return-addr1.c @@ -0,0 +1,46 @@ +/* builtin_return_address(n) with n>0 has always been troublesome ... + especially when the S/390 packed stack layout comes into play. */ + +/* { dg-do run } */ +/* { dg-options "-O3 -fno-optimize-sibling-calls -mbackchain -mpacked-stack -msoft-float" } */ + +void *addr1; + +extern void abort (void); + +void * __attribute__((noinline)) +foo1 () +{ + addr1 = __builtin_return_address (2); +} + +void * __attribute__((noinline)) +foo2 () +{ + foo1 (); +} + +void * __attribute__((noinline)) +foo3 () +{ + foo2 (); +} + +void __attribute__((noinline)) +bar () +{ + void *addr2; + + foo3 (); + asm volatile ("basr %0,0\n\t" : "=d" (addr2)); + /* basr is two bytes in length. */ + if (addr2 - addr1 != 2) + abort (); +} + +int +main () +{ + bar(); + return 0; +} diff --git a/gcc-4.9/gcc/testsuite/gcc.target/s390/return-addr2.c b/gcc-4.9/gcc/testsuite/gcc.target/s390/return-addr2.c new file mode 100644 index 000000000..c94d05284 --- /dev/null +++ b/gcc-4.9/gcc/testsuite/gcc.target/s390/return-addr2.c @@ -0,0 +1,45 @@ +/* builtin_return_address(n) with n>0 has always been troublesome. */ + +/* { dg-do run } */ +/* { dg-options "-O3 -fno-optimize-sibling-calls -mbackchain" } */ + +void *addr1; + +extern void abort (void); + +void * __attribute__((noinline)) +foo1 () +{ + addr1 = __builtin_return_address (2); +} + +void * __attribute__((noinline)) +foo2 () +{ + foo1 (); +} + +void * __attribute__((noinline)) +foo3 () +{ + foo2 (); +} + +void __attribute__((noinline)) +bar () +{ + void *addr2; + + foo3 (); + asm volatile ("basr %0,0\n\t" : "=d" (addr2)); + /* basr is two bytes in length. */ + if (addr2 - addr1 != 2) + abort (); +} + +int +main () +{ + bar(); + return 0; +} diff --git a/gcc-4.9/gcc/testsuite/gcc.target/s390/s390.exp b/gcc-4.9/gcc/testsuite/gcc.target/s390/s390.exp new file mode 100644 index 000000000..1b6d94a23 --- /dev/null +++ b/gcc-4.9/gcc/testsuite/gcc.target/s390/s390.exp @@ -0,0 +1,54 @@ +# Copyright (C) 2007-2014 Free Software Foundation, Inc. + +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with GCC; see the file COPYING3. If not see +# <http://www.gnu.org/licenses/>. + +# GCC testsuite that uses the `dg.exp' driver. + +# Exit immediately if this isn't a s390 target. +if ![istarget s390*-*-*] then { + return +} + +# Load support procs. +load_lib gcc-dg.exp + +# Return 1 if htm (etnd - extract nesting depth) instructions can be +# compiled. +proc check_effective_target_htm { } { + if { ![check_runtime s390_check_htm [subst { + int main (void) + { + unsigned int nd = 77; + asm (".insn rre,0xb2ec0000,%0,0" : "=d" (nd)); + return nd; + } + }]] } { return 0 } else { return 1 } +} + +# If a testcase doesn't have special options, use these. +global DEFAULT_CFLAGS +if ![info exists DEFAULT_CFLAGS] then { + set DEFAULT_CFLAGS " -ansi -pedantic-errors" +} + +# Initialize `dg'. +dg-init + +# Main loop. +dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/*.\[cS\]]] \ + "" $DEFAULT_CFLAGS + +# All done. +dg-finish diff --git a/gcc-4.9/gcc/testsuite/gcc.target/s390/stackcheck1.c b/gcc-4.9/gcc/testsuite/gcc.target/s390/stackcheck1.c new file mode 100644 index 000000000..ab46a92d7 --- /dev/null +++ b/gcc-4.9/gcc/testsuite/gcc.target/s390/stackcheck1.c @@ -0,0 +1,14 @@ +/* The automatically chosen stack guard value caused an ICE in that + case. */ + +/* { dg-do compile } */ +/* { dg-options "-O2 -mstack-size=4096" } */ + +extern void bar (char *); + +void +foo () +{ + char a[2500]; + bar (a); +} /* { dg-warning "more than half" } */ diff --git a/gcc-4.9/gcc/testsuite/gcc.target/s390/tf_to_di-1.c b/gcc-4.9/gcc/testsuite/gcc.target/s390/tf_to_di-1.c new file mode 100644 index 000000000..d79e6f350 --- /dev/null +++ b/gcc-4.9/gcc/testsuite/gcc.target/s390/tf_to_di-1.c @@ -0,0 +1,46 @@ +/* { dg-options "-O0 -mlong-double-128" } */ + +#include <stdio.h> +#include <stdlib.h> + +void +check_ll (long double ld, long long ll) +{ + if ((long long)ld != ll) + { + printf ("ld: %Lf expect: %lld result: %lld\n", + ld, ll, (long long)ld); + abort (); + } +} + +void +check_ull (long double ld, unsigned long long ull) +{ + if ((unsigned long long)ld != ull) + { + printf ("ld: %Lf expect: %llu result: %llu\n", + ld, ull, (unsigned long long)ld); + abort (); + } +} + +int +main () +{ + const long long ll_max = (long long)((1ULL << 63) - 1); + const long long ll_min = -ll_max - 1; + + check_ll (206.23253, 206LL); + check_ull (206.23253, 206ULL); + check_ll ((long double)ll_max, ll_max); + check_ull ((long double)ll_max, ll_max); + check_ll ((long double)ll_min, ll_min); + check_ll (0.0, 0); + check_ull (0.0, 0); + check_ll (-1.0, -1); + check_ll ((long double)0xffffffffffffffffULL, ll_max); + check_ull ((long double)0xffffffffffffffffULL, 0xffffffffffffffffULL); + + return 0; +} |