1 /* Functional tests of the htm __builtin_... macros. */
4 /* { dg-require-effective-target htm } */
5 /* { dg-options "-O3 -march=zEC12 -mzarch" } */
7 /* ---------------------------- included header files ---------------------- */
12 #include <htmintrin.h>
14 /* ---------------------------- local definitions -------------------------- */
16 #define DEFAULT_MAX_REPETITIONS 7
17 #define DEFAULT_REQUIRED_QUORUM 4
18 #define NUM_WARMUP_RUNS 2
20 /* ---------------------------- local macros ------------------------------- */
22 #define TEST_DF_REP(name) \
23 { #name, name, DEFAULT_MAX_REPETITIONS, DEFAULT_REQUIRED_QUORUM }
24 #define TEST_NO_REP(name) { #name, name, 1, 1 }
26 /* ---------------------------- local types -------------------------------- */
28 typedef int (*test_func_t
)(void);
33 test_func_t test_func
;
38 /* ---------------------------- local variables ---------------------------- */
40 __attribute__ ((aligned(256))) static struct __htm_tdb local_tdb256
;
41 static struct __htm_tdb local_tdb
;
42 static int do_dump_tdb
= 0;
44 /* ---------------------------- exported variables (globals) --------------- */
46 __attribute__ ((aligned(256))) struct
51 } global
= { 1.0, 2.5, 0.0 };
53 __attribute__ ((aligned(256))) struct
58 } counters
= { 0, 0, 0 };
60 /* ---------------------------- local helper functions --------------------- */
62 static void dump_tdb (struct __htm_tdb
*tdb
)
72 p
= (unsigned char *)tdb
;
73 for (i
= 0; i
< 16; i
++)
75 fprintf (stderr
, "0x%02x ", i
* 16);
76 for (j
= 0; j
< 16; j
++)
78 fprintf (stderr
, "%02x", (int)p
[i
* 16 + j
]);
81 fprintf (stderr
, " ");
85 fprintf (stderr
, " ");
88 fprintf (stderr
, "\n");
94 /* ---------------------------- local test functions ----------------------- */
96 /* Check values of the constants defined in htmintrin.h. */
97 static int test_constants (void)
99 if (_HTM_TBEGIN_STARTED
!= 0)
101 return 100 * _HTM_TBEGIN_STARTED
+ 1;
103 if (_HTM_TBEGIN_INDETERMINATE
!= 1)
105 return 100 * _HTM_TBEGIN_INDETERMINATE
+ 2;
107 if (_HTM_TBEGIN_TRANSIENT
!= 2)
109 return 100 * _HTM_TBEGIN_TRANSIENT
+ 3;
111 if (_HTM_TBEGIN_PERSISTENT
!= 3)
113 return 100 * _HTM_TBEGIN_PERSISTENT
+ 4;
119 static int test_tbegin_ntstg_tend (void)
125 if ((rc
= __builtin_tbegin ((void *)0)) == 0)
127 __builtin_non_tx_store ((uint64_t *)&counters
.c1
, 1);
129 rc
= __builtin_tend ();
134 if (counters
.c1
!= 1)
136 return 100 * counters
.c1
+ 2;
138 if (counters
.c2
!= 2)
140 return 100 * counters
.c2
+ 3;
151 static int test_tbegin_ntstg_tabort (void)
158 if (__builtin_tbegin ((void *)0) == 0)
160 __builtin_non_tx_store ((uint64_t *)&counters
.c1
, 1);
163 __builtin_tabort (256);
166 if (counters
.c1
!= 1)
168 return 100 * counters
.c1
+ 2;
170 if (counters
.c2
!= 0)
172 return 100 * counters
.c2
+ 3;
182 static int test_tbegin_nofloat (void)
188 if ((rc
= __builtin_tbegin_nofloat ((void *)0)) == 0)
190 __builtin_non_tx_store ((uint64_t *)&counters
.c1
, 1);
192 rc
= __builtin_tend ();
197 if (counters
.c1
!= 1)
199 return 100 * counters
.c1
+ 2;
201 if (counters
.c2
!= 2)
203 return 100 * counters
.c2
+ 3;
214 static int test_tbegin_retry (void)
221 if ((rc
= __builtin_tbegin_retry ((void *)0, 5)) == 0)
225 do_abort
= (counters
.c1
== 0) ? 1 : 0;
226 __builtin_non_tx_store (
227 (uint64_t *)&counters
.c1
, counters
.c1
+ 1);
230 __builtin_tabort (256);
232 counters
.c2
= counters
.c2
+ 10;
233 __builtin_non_tx_store ((uint64_t *)&counters
.c3
, 3);
234 rc
= __builtin_tend ();
239 if (counters
.c1
!= 2)
241 return 100 * counters
.c1
+ 2;
243 if (counters
.c2
!= 10)
245 return 100 * counters
.c2
+ 3;
247 if (counters
.c3
!= 3)
249 return 100 * counters
.c3
+ 6;
260 static int test_tbegin_retry_nofloat (void)
267 if ((rc
= __builtin_tbegin_retry_nofloat ((void *)0, 5)) == 0)
271 do_abort
= (counters
.c1
== 0) ? 1 : 0;
272 __builtin_non_tx_store (
273 (uint64_t *)&counters
.c1
, counters
.c1
+ 1);
276 __builtin_tabort (256);
278 counters
.c2
= counters
.c2
+ 10;
279 __builtin_non_tx_store ((uint64_t *)&counters
.c3
, 3);
280 rc
= __builtin_tend ();
285 if (counters
.c1
!= 2)
287 return 100 * counters
.c1
+ 2;
289 if (counters
.c2
!= 10)
291 return 100 * counters
.c2
+ 3;
293 if (counters
.c3
!= 3)
295 return 100 * counters
.c3
+ 6;
306 static int test_tbegin_aborts (void)
312 if ((rc
= __builtin_tbegin ((void *)0)) == 0)
315 __builtin_tabort (256);
327 if ((rc
= __builtin_tbegin ((void *)0)) == 0)
330 __builtin_tabort (257);
341 if ((rc
= __builtin_tbegin ((void *)0)) == 0)
343 global
.float_3
= global
.float_1
+ global
.float_2
;
344 rc
= __builtin_tend ();
354 if (global
.float_3
!= global
.float_1
+ global
.float_2
)
356 return 100 * rc
+ 10;
362 static __attribute__((noinline
)) void indirect_abort(int abort_code
)
364 __builtin_tabort (abort_code
);
369 static int test_tbegin_indirect_aborts (void)
375 if ((rc
= __builtin_tbegin ((void *)0)) == 0)
390 if ((rc
= __builtin_tbegin ((void *)0)) == 0)
408 static int test_tbegin_nofloat_aborts (void)
412 if ((rc
= __builtin_tbegin_nofloat ((void *)0)) == 0)
414 __builtin_tabort (256);
417 if ((rc
= __builtin_tbegin_nofloat ((void *)0)) == 0)
419 __builtin_tabort (257);
424 return 1000 * rc
+ 6;
430 static int test_tbegin_nofloat_indirect_aborts (void)
434 if ((rc
= __builtin_tbegin_nofloat ((void *)0)) == 0)
436 indirect_abort (256);
439 if ((rc
= __builtin_tbegin_nofloat ((void *)0)) == 0)
441 indirect_abort (257);
446 return 1000 * rc
+ 6;
453 int _test_tbegin_retry_aborts (int retries
, uint64_t abort_code
)
458 if ((rc
= __builtin_tbegin_retry ((void *)0, retries
)) == 0)
460 __builtin_non_tx_store ((uint64_t *)&counters
.c1
, counters
.c1
+ 1);
461 __builtin_tabort (abort_code
);
466 if ((abort_code
& 1) == 0)
470 return 100 * rc
+ 2003;
472 else if (counters
.c1
!= (uint64_t)retries
+ 1)
474 return 1000 * counters
.c1
+ 100 * retries
+ 4;
481 return 100 * rc
+ 3005;
483 else if (counters
.c1
!= 1)
485 return 1000 * counters
.c1
+ 100 * retries
+ 6;
493 static int test_tbegin_retry_aborts (void)
498 for (retries
= 1; retries
<= 3; retries
++)
500 rc
= _test_tbegin_retry_aborts (retries
, 256);
506 for (retries
= 1; retries
<= 3; retries
++)
508 rc
= _test_tbegin_retry_aborts (retries
, 257);
514 if ((rc
= __builtin_tbegin_retry ((void *)0, 5)) == 0)
516 global
.float_3
= global
.float_1
+ global
.float_2
;
517 rc
= __builtin_tend ();
520 return 30000 + 100 * rc
+ 6;
525 return 30000 + 100 * rc
+ 7;
531 static int _test_tbegin_retry_nofloat_aborts (int retries
, uint64_t abort_code
)
536 if ((rc
= __builtin_tbegin_retry_nofloat ((void *)0, retries
)) == 0)
538 __builtin_non_tx_store ((uint64_t *)&counters
.c1
, counters
.c1
+ 1);
539 __builtin_tabort (abort_code
);
544 if ((abort_code
& 1) == 0)
548 return 100 * rc
+ 2003;
550 else if (counters
.c1
!= (uint64_t)retries
+ 1)
552 return 1000 * counters
.c1
+ 100 * retries
+ 4;
559 return 100 * rc
+ 3005;
561 else if (counters
.c1
!= 1)
563 return 1000 * counters
.c1
+ 100 * retries
+ 6;
571 static int test_tbegin_retry_nofloat_aborts (void)
576 for (retries
= 1; retries
<= 3; retries
++)
578 rc
= _test_tbegin_retry_nofloat_aborts (retries
, 256);
581 return 10 * retries
+ rc
;
584 for (retries
= 1; retries
<= 3; retries
++)
586 rc
= _test_tbegin_retry_nofloat_aborts (retries
, 257);
589 return 10000 + 10 * retries
+ rc
;
596 static int test_tbegin_tdb (void)
600 local_tdb
.format
= 0;
601 if ((rc
= __builtin_tbegin (&local_tdb
)) == 0)
603 rc
= __builtin_tend ();
608 if (local_tdb
.format
!= 0)
610 dump_tdb (&local_tdb
);
611 return 100 * local_tdb
.format
+ 2;
618 local_tdb
.format
= 0;
619 if ((rc
= __builtin_tbegin (&local_tdb
)) == 0)
621 __builtin_tabort (257);
630 if (local_tdb
.format
!= 1)
632 dump_tdb (&local_tdb
);
633 return 100 * local_tdb
.format
+ 6;
636 local_tdb256
.format
= 0;
637 if ((rc
= __builtin_tbegin (&local_tdb256
)) == 0)
639 rc
= __builtin_tend ();
642 return 1100 * rc
+ 1;
644 if (local_tdb256
.format
!= 0)
646 dump_tdb (&local_tdb256
);
647 return 1100 * local_tdb256
.format
+ 2;
652 return 1100 * rc
+ 3;
654 local_tdb256
.format
= 0;
655 if ((rc
= __builtin_tbegin (&local_tdb256
)) == 0)
657 __builtin_tabort (257);
664 return 2100 * rc
+ 5;
666 if (local_tdb256
.format
!= 1)
668 dump_tdb (&local_tdb256
);
669 return 2100 * local_tdb256
.format
+ 6;
676 static int test_tbegin_nofloat_tdb (void)
680 local_tdb
.format
= 0;
681 if ((rc
= __builtin_tbegin_nofloat (&local_tdb
)) == 0)
683 rc
= __builtin_tend ();
688 if (local_tdb
.format
!= 0)
690 dump_tdb (&local_tdb
);
691 return 100 * local_tdb
.format
+ 2;
698 local_tdb
.format
= 0;
699 if ((rc
= __builtin_tbegin_nofloat (&local_tdb
)) == 0)
701 __builtin_tabort (257);
710 if (local_tdb
.format
!= 1)
712 dump_tdb (&local_tdb
);
713 return 100 * local_tdb
.format
+ 6;
716 local_tdb256
.format
= 0;
717 if ((rc
= __builtin_tbegin_nofloat (&local_tdb256
)) == 0)
719 rc
= __builtin_tend ();
722 return 1100 * rc
+ 1;
724 if (local_tdb256
.format
!= 0)
726 dump_tdb (&local_tdb256
);
727 return 1100 * local_tdb256
.format
+ 2;
734 local_tdb256
.format
= 0;
735 if ((rc
= __builtin_tbegin_nofloat (&local_tdb256
)) == 0)
737 __builtin_tabort (257);
744 return 2100 * rc
+ 5;
746 if (local_tdb256
.format
!= 1)
748 dump_tdb (&local_tdb256
);
749 return 2100 * local_tdb256
.format
+ 6;
756 static int test_tbegin_retry_tdb (void)
760 local_tdb256
.format
= 0;
761 if ((rc
= __builtin_tbegin_retry (&local_tdb256
, 2)) == 0)
763 rc
= __builtin_tend ();
766 return 1100 * rc
+ 1;
768 if (local_tdb256
.format
!= 0)
770 dump_tdb (&local_tdb256
);
771 return 1100 * local_tdb256
.format
+ 2;
778 local_tdb256
.format
= 0;
779 if ((rc
= __builtin_tbegin_retry (&local_tdb256
, 2)) == 0)
781 __builtin_tabort (257);
788 return 2100 * rc
+ 5;
790 if (local_tdb256
.format
!= 1)
792 dump_tdb (&local_tdb256
);
793 return 2100 * local_tdb256
.format
+ 6;
800 static int test_tbegin_retry_nofloat_tdb (void)
804 local_tdb
.format
= 0;
805 if ((rc
= __builtin_tbegin_retry_nofloat (&local_tdb
, 2)) == 0)
807 rc
= __builtin_tend ();
812 if (local_tdb
.format
!= 0)
814 dump_tdb (&local_tdb
);
815 return 100 * local_tdb
.format
+ 2;
822 local_tdb
.format
= 0;
823 if ((rc
= __builtin_tbegin_retry_nofloat (&local_tdb
, 2)) == 0)
825 __builtin_tabort (257);
834 if (local_tdb
.format
!= 1)
836 dump_tdb (&local_tdb
);
837 return 100 * local_tdb
.format
+ 6;
840 local_tdb256
.format
= 0;
841 if ((rc
= __builtin_tbegin_retry_nofloat (&local_tdb256
, 2)) == 0)
843 rc
= __builtin_tend ();
846 return 1100 * rc
+ 1;
848 if (local_tdb256
.format
!= 0)
850 dump_tdb (&local_tdb256
);
851 return 1100 * local_tdb256
.format
+ 2;
856 return 1100 * rc
+ 3;
858 local_tdb256
.format
= 0;
859 if ((rc
= __builtin_tbegin_retry_nofloat (&local_tdb256
, 2)) == 0)
861 __builtin_tabort (257);
868 return 2100 * rc
+ 5;
870 if (local_tdb256
.format
!= 1)
872 dump_tdb (&local_tdb256
);
873 return 2100 * local_tdb256
.format
+ 6;
880 static int test_etnd (void)
887 if ((rc
= __builtin_tbegin ((void *)0)) == 0)
889 counters
.c1
= __builtin_tx_nesting_depth ();
890 if (__builtin_tbegin ((void *)0) == 0)
892 counters
.c2
= __builtin_tx_nesting_depth ();
893 if (__builtin_tbegin ((void *)0) == 0)
895 counters
.c3
= __builtin_tx_nesting_depth ();
906 if (counters
.c1
!= 1)
908 return 100 * counters
.c1
+ 2;
910 if (counters
.c2
!= 2)
912 return 100 * counters
.c2
+ 3;
914 if (counters
.c3
!= 3)
916 return 100 * counters
.c3
+ 4;
922 static int test_tbeginc (void)
927 __builtin_tbeginc ();
929 rc
= __builtin_tend ();
932 return 10000 * rc
+ 1;
934 if (counters
.c1
!= 1)
936 return 100000 * counters
.c1
+ 3;
942 /* ---------------------------- local testing framework functions ---------- */
944 static int run_one_test (const test_table_entry_t
*test_entry
)
951 /* Warmup run to get all necessary data and instruction pages into the page
957 for (run
= 0; run
< NUM_WARMUP_RUNS
; run
++)
959 test_entry
->test_func ();
964 test_entry
->required_quorum
!= 1 ||
965 test_entry
->max_repetitions
!= 1);
966 printf ("RRR RUN %s\n", test_entry
->name
);
967 if (do_print_passes
== 1)
970 " (requires %d successful out of %d runs)\n",
971 test_entry
->required_quorum
,
972 test_entry
->max_repetitions
);
976 for (rc
= 0, i
= 0; i
< test_entry
->max_repetitions
; i
++)
978 if (do_print_passes
== 1)
989 rc
= test_entry
->test_func ();
992 if (do_print_passes
== 1)
997 if (succeeded
>= test_entry
->required_quorum
)
1004 printf (" failed (rc = %d)", rc
);
1007 if (do_print_passes
== 1 || rc
!= 0)
1011 if (succeeded
>= test_entry
->required_quorum
)
1013 printf ("+++ OK %s\n", test_entry
->name
);
1019 printf ("--- FAIL %s\n", test_entry
->name
);
1021 return (rc
!= 0) ? rc
: -1;
1025 static int run_all_tests (const test_table_entry_t
*test_table
)
1027 const test_table_entry_t
*test
;
1031 rc
= 0, test
= &test_table
[0];
1032 test
->test_func
!= NULL
&& rc
== 0; test
++)
1034 rc
= run_one_test (test
);
1040 /* ---------------------------- interface functions ------------------------ */
1044 const test_table_entry_t test_table
[] = {
1045 TEST_NO_REP (test_constants
),
1046 TEST_DF_REP (test_tbegin_ntstg_tend
),
1047 TEST_DF_REP (test_tbegin_ntstg_tabort
),
1048 TEST_DF_REP (test_tbegin_nofloat
),
1049 TEST_NO_REP (test_tbegin_retry
),
1050 TEST_NO_REP (test_tbegin_retry_nofloat
),
1051 TEST_DF_REP (test_tbegin_aborts
),
1052 TEST_DF_REP (test_tbegin_indirect_aborts
),
1053 TEST_DF_REP (test_tbegin_nofloat_aborts
),
1054 TEST_DF_REP (test_tbegin_nofloat_indirect_aborts
),
1055 TEST_NO_REP (test_tbegin_retry_aborts
),
1056 TEST_NO_REP (test_tbegin_retry_nofloat_aborts
),
1057 TEST_DF_REP (test_tbegin_tdb
),
1058 TEST_DF_REP (test_tbegin_nofloat_tdb
),
1059 TEST_NO_REP (test_tbegin_retry_tdb
),
1060 TEST_NO_REP (test_tbegin_retry_nofloat_tdb
),
1061 TEST_DF_REP (test_etnd
),
1062 TEST_DF_REP (test_tbeginc
),
1069 rc
= run_all_tests (test_table
);