diff options
Diffstat (limited to 'gcc-4.8/gcc/testsuite/gcc.target/s390')
30 files changed, 2483 insertions, 136 deletions
diff --git a/gcc-4.8/gcc/testsuite/gcc.target/s390/hotpatch-1.c b/gcc-4.8/gcc/testsuite/gcc.target/s390/hotpatch-1.c new file mode 100644 index 000000000..b9d6139b0 --- /dev/null +++ b/gcc-4.8/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.8/gcc/testsuite/gcc.target/s390/hotpatch-10.c b/gcc-4.8/gcc/testsuite/gcc.target/s390/hotpatch-10.c new file mode 100644 index 000000000..b91b3478e --- /dev/null +++ b/gcc-4.8/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.8/gcc/testsuite/gcc.target/s390/hotpatch-11.c b/gcc-4.8/gcc/testsuite/gcc.target/s390/hotpatch-11.c new file mode 100644 index 000000000..491677342 --- /dev/null +++ b/gcc-4.8/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.8/gcc/testsuite/gcc.target/s390/hotpatch-12.c b/gcc-4.8/gcc/testsuite/gcc.target/s390/hotpatch-12.c new file mode 100644 index 000000000..b3e9427d4 --- /dev/null +++ b/gcc-4.8/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.8/gcc/testsuite/gcc.target/s390/hotpatch-2.c b/gcc-4.8/gcc/testsuite/gcc.target/s390/hotpatch-2.c new file mode 100644 index 000000000..6cc29447d --- /dev/null +++ b/gcc-4.8/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.8/gcc/testsuite/gcc.target/s390/hotpatch-3.c b/gcc-4.8/gcc/testsuite/gcc.target/s390/hotpatch-3.c new file mode 100644 index 000000000..9f0b2b756 --- /dev/null +++ b/gcc-4.8/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.8/gcc/testsuite/gcc.target/s390/hotpatch-4.c b/gcc-4.8/gcc/testsuite/gcc.target/s390/hotpatch-4.c new file mode 100644 index 000000000..c1dba20a3 --- /dev/null +++ b/gcc-4.8/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.8/gcc/testsuite/gcc.target/s390/hotpatch-5.c b/gcc-4.8/gcc/testsuite/gcc.target/s390/hotpatch-5.c new file mode 100644 index 000000000..ec267d65a --- /dev/null +++ b/gcc-4.8/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.8/gcc/testsuite/gcc.target/s390/hotpatch-6.c b/gcc-4.8/gcc/testsuite/gcc.target/s390/hotpatch-6.c new file mode 100644 index 000000000..5af090d03 --- /dev/null +++ b/gcc-4.8/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.8/gcc/testsuite/gcc.target/s390/hotpatch-7.c b/gcc-4.8/gcc/testsuite/gcc.target/s390/hotpatch-7.c new file mode 100644 index 000000000..e73a510b4 --- /dev/null +++ b/gcc-4.8/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.8/gcc/testsuite/gcc.target/s390/hotpatch-8.c b/gcc-4.8/gcc/testsuite/gcc.target/s390/hotpatch-8.c new file mode 100644 index 000000000..399aa7260 --- /dev/null +++ b/gcc-4.8/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.8/gcc/testsuite/gcc.target/s390/hotpatch-9.c b/gcc-4.8/gcc/testsuite/gcc.target/s390/hotpatch-9.c new file mode 100644 index 000000000..5da675866 --- /dev/null +++ b/gcc-4.8/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.8/gcc/testsuite/gcc.target/s390/hotpatch-compile-1.c b/gcc-4.8/gcc/testsuite/gcc.target/s390/hotpatch-compile-1.c new file mode 100644 index 000000000..45a2cc5dc --- /dev/null +++ b/gcc-4.8/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.8/gcc/testsuite/gcc.target/s390/hotpatch-compile-2.c b/gcc-4.8/gcc/testsuite/gcc.target/s390/hotpatch-compile-2.c new file mode 100644 index 000000000..5947f564f --- /dev/null +++ b/gcc-4.8/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.8/gcc/testsuite/gcc.target/s390/hotpatch-compile-3.c b/gcc-4.8/gcc/testsuite/gcc.target/s390/hotpatch-compile-3.c new file mode 100644 index 000000000..e0c7f6f52 --- /dev/null +++ b/gcc-4.8/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.8/gcc/testsuite/gcc.target/s390/hotpatch-compile-4.c b/gcc-4.8/gcc/testsuite/gcc.target/s390/hotpatch-compile-4.c new file mode 100644 index 000000000..d9f13425a --- /dev/null +++ b/gcc-4.8/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.8/gcc/testsuite/gcc.target/s390/hotpatch-compile-5.c b/gcc-4.8/gcc/testsuite/gcc.target/s390/hotpatch-compile-5.c new file mode 100644 index 000000000..53f7eac9e --- /dev/null +++ b/gcc-4.8/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.8/gcc/testsuite/gcc.target/s390/hotpatch-compile-6.c b/gcc-4.8/gcc/testsuite/gcc.target/s390/hotpatch-compile-6.c new file mode 100644 index 000000000..cb10b66f0 --- /dev/null +++ b/gcc-4.8/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.8/gcc/testsuite/gcc.target/s390/hotpatch-compile-7.c b/gcc-4.8/gcc/testsuite/gcc.target/s390/hotpatch-compile-7.c new file mode 100644 index 000000000..98ccb42c0 --- /dev/null +++ b/gcc-4.8/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.8/gcc/testsuite/gcc.target/s390/hotpatch-compile-8.c b/gcc-4.8/gcc/testsuite/gcc.target/s390/hotpatch-compile-8.c new file mode 100644 index 000000000..489fc5dd9 --- /dev/null +++ b/gcc-4.8/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.8/gcc/testsuite/gcc.target/s390/htm-1.c b/gcc-4.8/gcc/testsuite/gcc.target/s390/htm-1.c deleted file mode 100644 index 245ba2c7e..000000000 --- a/gcc-4.8/gcc/testsuite/gcc.target/s390/htm-1.c +++ /dev/null @@ -1,73 +0,0 @@ -/* 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; - - cc = __builtin_tbegin (0); - cc = __builtin_tbegin (tdb); - cc = __builtin_tbegin (&global_tdb); - - cc = __builtin_tbegin_nofloat (0); - cc = __builtin_tbegin_nofloat (&global_tdb); - - cc = __builtin_tbegin_retry (0, 42); - cc = __builtin_tbegin_retry (0, reg); - cc = __builtin_tbegin_retry (0, *mem); - cc = __builtin_tbegin_retry (0, global); - cc = __builtin_tbegin_retry (tdb, 42); - cc = __builtin_tbegin_retry (&global_tdb, 42); - - cc = __builtin_tbegin_retry_nofloat (0, 42); - cc = __builtin_tbegin_retry_nofloat (0, reg); - cc = __builtin_tbegin_retry_nofloat (0, *mem); - cc = __builtin_tbegin_retry_nofloat (0, global); - cc = __builtin_tbegin_retry_nofloat (&global_tdb, 42); - - __builtin_tbeginc (); - - n = __builtin_tx_nesting_depth(); - - __builtin_non_tx_store(&g, 23); - __builtin_non_tx_store(mem64, 23); - __builtin_non_tx_store(&g, reg); - __builtin_non_tx_store(&g, *mem); - __builtin_non_tx_store(&g, global); - - __builtin_tabort (42 + 255); - __builtin_tabort (reg); - /* { dg-final { scan-assembler-times "tabort\t255" 1 } } */ - __builtin_tabort (reg + 255); - __builtin_tabort (*mem); - __builtin_tabort (global); - /* 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); - __builtin_tabort (global + 255); - - __builtin_tend(); - - __builtin_tx_assist (23); - __builtin_tx_assist (reg); - __builtin_tx_assist (*mem); - __builtin_tx_assist (global); -} - -/* Make sure the tdb NULL argument ends up as immediate value in the - instruction. */ -/* { dg-final { scan-assembler-times "tbegin\t0," 10 } } */ diff --git a/gcc-4.8/gcc/testsuite/gcc.target/s390/htm-builtins-1.c b/gcc-4.8/gcc/testsuite/gcc.target/s390/htm-builtins-1.c new file mode 100644 index 000000000..c90490faa --- /dev/null +++ b/gcc-4.8/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.8/gcc/testsuite/gcc.target/s390/htm-builtins-2.c b/gcc-4.8/gcc/testsuite/gcc.target/s390/htm-builtins-2.c new file mode 100644 index 000000000..15b0d12ae --- /dev/null +++ b/gcc-4.8/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.8/gcc/testsuite/gcc.target/s390/htm-builtins-compile-1.c b/gcc-4.8/gcc/testsuite/gcc.target/s390/htm-builtins-compile-1.c new file mode 100644 index 000000000..982a7483d --- /dev/null +++ b/gcc-4.8/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)(reg + 0x12345678)); + cc = __builtin_tbegin ((void *)(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)(reg + 0x12345678)); + cc = __builtin_tbegin_nofloat ((void *)(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) (reg + 0x12345678), global + 1); + cc = __builtin_tbegin_retry ( + (void *)(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) (reg + 0x12345678), global + 1); + cc = __builtin_tbegin_retry_nofloat ( + (void *)(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.8/gcc/testsuite/gcc.target/s390/htm-builtins-compile-2.c b/gcc-4.8/gcc/testsuite/gcc.target/s390/htm-builtins-compile-2.c new file mode 100644 index 000000000..67d76a6d3 --- /dev/null +++ b/gcc-4.8/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.8/gcc/testsuite/gcc.target/s390/htm-xl-intrin-1.c b/gcc-4.8/gcc/testsuite/gcc.target/s390/htm-builtins-compile-3.c index 77ceeb770..77ceeb770 100644 --- a/gcc-4.8/gcc/testsuite/gcc.target/s390/htm-xl-intrin-1.c +++ b/gcc-4.8/gcc/testsuite/gcc.target/s390/htm-builtins-compile-3.c diff --git a/gcc-4.8/gcc/testsuite/gcc.target/s390/htm-nofloat-1.c b/gcc-4.8/gcc/testsuite/gcc.target/s390/htm-nofloat-1.c index df7e2bac8..6022efb97 100644 --- a/gcc-4.8/gcc/testsuite/gcc.target/s390/htm-nofloat-1.c +++ b/gcc-4.8/gcc/testsuite/gcc.target/s390/htm-nofloat-1.c @@ -1,12 +1,50 @@ -/* { dg-do compile } */ -/* { dg-options "-O3 -march=zEC12 -mzarch" } */ +/* { dg-do run } */ +/* { dg-require-effective-target htm } */ +/* { dg-options "-O3 -march=zEC12 -mzarch --save-temps" } */ -int -foo () +/* __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) +{ + 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) { - __builtin_tbegin_nofloat (0); - __builtin_tbegin_retry_nofloat (0, 42); + 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 "std" } } */ -/* { dg-final { scan-assembler-not "ld" } } */ +/* { dg-final { scan-assembler-not "\tstd\t" } } */ +/* { dg-final { scan-assembler-not "\tld\t" } } */ diff --git a/gcc-4.8/gcc/testsuite/gcc.target/s390/htm-nofloat-2.c b/gcc-4.8/gcc/testsuite/gcc.target/s390/htm-nofloat-2.c deleted file mode 100644 index 59621a4c1..000000000 --- a/gcc-4.8/gcc/testsuite/gcc.target/s390/htm-nofloat-2.c +++ /dev/null @@ -1,55 +0,0 @@ -/* { 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.8/gcc/testsuite/gcc.target/s390/htm-nofloat-compile-1.c b/gcc-4.8/gcc/testsuite/gcc.target/s390/htm-nofloat-compile-1.c new file mode 100644 index 000000000..df7e2bac8 --- /dev/null +++ b/gcc-4.8/gcc/testsuite/gcc.target/s390/htm-nofloat-compile-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.8/gcc/testsuite/gcc.target/s390/s390.exp b/gcc-4.8/gcc/testsuite/gcc.target/s390/s390.exp index a4a6609cb..141c0eef2 100644 --- a/gcc-4.8/gcc/testsuite/gcc.target/s390/s390.exp +++ b/gcc-4.8/gcc/testsuite/gcc.target/s390/s390.exp @@ -24,6 +24,19 @@ if ![istarget s390*-*-*] then { # Load support procs. load_lib gcc-dg.exp +# Return 1 if htm (etnd - extract nesting depth) instructions are +# understood by the assembler and can be executed. +proc check_effective_target_htm { } { + if { ![check_runtime s390_check_htm [subst { + int main (void) + { + unsigned int nd; + asm ("etnd %0" : "=d" (nd)); + return nd; + } + }] "-march=zEC12 -mzarch" ] } { return 0 } else { return 1 } +} + # If a testcase doesn't have special options, use these. global DEFAULT_CFLAGS if ![info exists DEFAULT_CFLAGS] then { |