diff options
Diffstat (limited to 'gcc-4.8/gcc/testsuite/gcc.target/s390/htm-builtins-1.c')
-rw-r--r-- | gcc-4.8/gcc/testsuite/gcc.target/s390/htm-builtins-1.c | 1073 |
1 files changed, 1073 insertions, 0 deletions
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; + } +} |