diagnostics: remove duplicate copies of diagnostic_kind_text
[official-gcc.git] / gcc / testsuite / gcc.target / s390 / htm-builtins-2.c
blob2e838caacc8c20cc3f9aa2270f3038e7a0f0dcfb
1 /* Functional tests of the htm __TM_... macros. */
3 /* { dg-do run } */
4 /* { dg-require-effective-target htm } */
5 /* { dg-options "-O3 -march=zEC12 -mzarch" } */
7 /* ---------------------------- included header files ---------------------- */
9 #include <stdio.h>
10 #include <string.h>
11 #include <inttypes.h>
12 #include <htmxlintrin.h>
14 /* ---------------------------- local definitions -------------------------- */
16 #define DEFAULT_MAX_REPETITIONS 7
17 #define DEFAULT_REQUIRED_QUORUM 4
18 #define DEFAULT_ABORT_ADDRESS (0x12345678u)
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);
30 typedef struct
32 const char *name;
33 test_func_t test_func;
34 int max_repetitions;
35 int required_quorum;
36 } test_table_entry_t;
38 typedef enum
40 ABORT_T_SYSTEM = 0,
41 ABORT_T_USER = 1,
42 } abort_user_t;
44 typedef enum
46 ABORT_T_NONE = 0,
47 ABORT_T_ILLEGAL,
48 ABORT_T_FOOTPRINT_EXCEEDED,
49 ABORT_T_NESTED_TOO_DEEP,
50 ABORT_T_CONFLICT,
52 ABORT_T_INVALID_ABORT_CODE
53 } abort_t;
55 /* ---------------------------- local variables ---------------------------- */
57 __attribute__ ((aligned(256))) static struct __htm_tdb local_tdb256;
58 static struct __htm_tdb local_tdb;
60 static abort_t const abort_classes[] =
62 ABORT_T_INVALID_ABORT_CODE,
63 ABORT_T_NONE,
64 ABORT_T_NONE,
65 ABORT_T_NONE,
67 ABORT_T_ILLEGAL,
68 ABORT_T_NONE,
69 ABORT_T_NONE,
70 ABORT_T_FOOTPRINT_EXCEEDED,
72 ABORT_T_FOOTPRINT_EXCEEDED,
73 ABORT_T_CONFLICT,
74 ABORT_T_CONFLICT,
75 ABORT_T_ILLEGAL,
77 ABORT_T_NONE,
78 ABORT_T_NESTED_TOO_DEEP,
79 ABORT_T_NONE,
80 ABORT_T_NONE,
82 ABORT_T_NONE
85 static size_t num_abort_classes = sizeof(abort_classes) / sizeof(abort_t);
87 /* ---------------------------- exported variables (globals) --------------- */
89 int global_int = 0;
90 uint64_t global_u64 = 0;
91 float global_float_1 = 1.0;
92 float global_float_2 = 2.5;
93 float global_float_3 = 0.0;
94 __attribute__ ((aligned(256))) struct
96 volatile uint64_t c1;
97 char pad1[256 - sizeof(uint64_t)];
98 volatile uint64_t c2;
99 char pad2[256 - sizeof(uint64_t)];
100 volatile uint64_t c3;
101 } counters = { 0 };
103 /* ---------------------------- local helper functions --------------------- */
105 static void dump_tdb(struct __htm_tdb *tdb)
107 unsigned char *p;
108 int i;
109 int j;
111 p = (unsigned char *)tdb;
112 for (i = 0; i < 16; i++)
114 fprintf(stderr, "0x%02x ", i * 16);
115 for (j = 0; j < 16; j++)
117 fprintf(stderr, "%02x", (int)p[i * 16 + j]);
118 if (j < 15)
120 fprintf(stderr, " ");
122 if (j == 7)
124 fprintf(stderr, " ");
127 fprintf(stderr, "\n");
130 return;
133 static void make_fake_tdb(struct __htm_tdb *tdb)
135 memset(tdb, 0, sizeof(*tdb));
136 tdb->format = 1;
137 tdb->nesting_depth = 1;
138 tdb->atia = DEFAULT_ABORT_ADDRESS;
139 tdb->abort_code = 11;
141 return;
144 static int check_abort_code_in_tdb(struct __htm_tdb *tdb, uint64_t abort_code)
146 long expect_rc;
147 long rc;
149 if (abort_code != 0)
151 long addr;
153 addr = __TM_failure_address(&local_tdb);
154 if (addr != DEFAULT_ABORT_ADDRESS)
156 return 11;
160 long long tdb_abort_code;
162 tdb_abort_code = __TM_failure_code(tdb);
163 if ((uint64_t)tdb_abort_code != abort_code)
165 fprintf(
166 stderr, "tm_ac %" PRIu64 ", ac %" PRIu64
167 ", tdb_ac %" PRIu64 "\n",
168 (uint64_t)tdb_abort_code, abort_code,
169 (uint64_t)tdb->abort_code);
170 return 10;
173 expect_rc = (abort_code >= 256) ? 1 : 0;
174 rc = __TM_is_user_abort(tdb);
175 if (rc != expect_rc)
177 fprintf(stderr, "rc %ld, expect_rc %ld\n", rc, expect_rc);
178 return 1;
181 unsigned char code;
183 code = 0xffu;
184 rc = __TM_is_named_user_abort(tdb, &code);
185 if (rc != expect_rc)
187 fprintf(
188 stderr, "rc %ld, expect_rc %ld\n", rc,
189 expect_rc);
190 return 2;
192 if (expect_rc == 1 && code != abort_code - 256)
194 return 3;
197 if (abort_code > (uint64_t)num_abort_classes)
199 abort_code = (uint64_t)num_abort_classes;
201 expect_rc = (abort_classes[abort_code] == ABORT_T_ILLEGAL) ? 1 : 0;
202 rc = __TM_is_illegal(tdb);
203 if (rc != expect_rc)
205 dump_tdb(tdb);
206 fprintf(stderr, "rc %ld, expect_rc %ld\n", rc, expect_rc);
207 return 4;
209 expect_rc =
210 (abort_classes[abort_code] == ABORT_T_FOOTPRINT_EXCEEDED) ?
211 1 : 0;
212 rc = __TM_is_footprint_exceeded(tdb);
213 if (rc != expect_rc)
215 dump_tdb(tdb);
216 fprintf(stderr, "rc %ld, expect_rc %ld\n", rc, expect_rc);
217 return 5;
219 expect_rc =
220 (abort_classes[abort_code] == ABORT_T_NESTED_TOO_DEEP) ? 1 : 0;
221 rc = __TM_is_nested_too_deep(tdb);
222 if (rc != expect_rc)
224 dump_tdb(tdb);
225 fprintf(stderr, "rc %ld, expect_rc %ld\n", rc, expect_rc);
226 return 6;
228 expect_rc = (abort_classes[abort_code] == ABORT_T_CONFLICT) ? 1 : 0;
229 rc = __TM_is_conflict(tdb);
230 if (rc != expect_rc)
232 dump_tdb(tdb);
233 fprintf(stderr, "rc %ld, expect_rc %ld\n", rc, expect_rc);
234 return 7;
237 return 0;
240 /* ---------------------------- local test functions ----------------------- */
242 /* Not a test; make sure that the involved global cachelines are reserved for
243 * writing. */
244 static int init_cache(void)
246 make_fake_tdb(&local_tdb);
247 make_fake_tdb(&local_tdb256);
248 global_int = 0;
249 global_u64 = 0;
250 global_float_1 = 1.0;
251 global_float_2 = 2.5;
252 global_float_3 = 0.0;
253 counters.c1 = 0;
254 counters.c2 = 0;
255 counters.c3 = 0;
257 return 0;
260 static int test_abort_classification(void)
262 int i;
264 make_fake_tdb(&local_tdb);
265 for (i = 0; i <= 256; i++)
267 int rc;
269 local_tdb.abort_code = (uint64_t)i;
270 rc = check_abort_code_in_tdb(&local_tdb, (uint64_t)i);
271 if (rc != 0)
273 return 100 * i + rc;
277 return 0;
280 static int test_cc_classification(void)
282 long rc;
284 rc = __TM_is_failure_persistent(0);
285 if (rc != 0)
287 return 1;
289 rc = __TM_is_failure_persistent(1);
290 if (rc != 0)
292 return 2;
294 rc = __TM_is_failure_persistent(2);
295 if (rc != 0)
297 return 3;
299 rc = __TM_is_failure_persistent(3);
300 if (rc != 1)
302 return 4;
305 return 0;
308 static int test_tbegin_ntstg_tend(void)
310 long rc;
312 counters.c1 = 0;
313 counters.c2 = 0;
314 if ((rc = __TM_simple_begin()) == 0)
316 __TM_non_transactional_store((uint64_t *)&counters.c1, 1);
317 counters.c2 = 2;
318 rc = __TM_end();
319 if (rc != 0)
321 return 100 * rc + 5;
323 if (counters.c1 != 1)
325 return 100 * counters.c1 + 2;
327 if (counters.c2 != 2)
329 return 100 * counters.c2 + 3;
332 else
334 return 100 * rc + 4;
337 return 0;
340 static int test_tbegin_ntstg_tabort(void)
342 register float f;
344 counters.c1 = 0;
345 counters.c2 = 0;
346 f = 0;
347 if (__TM_simple_begin() == 0)
349 __TM_non_transactional_store((uint64_t *)&counters.c1, 1);
350 counters.c2 = 2;
351 f = 1;
352 __TM_named_abort(0);
353 return 1;
355 if (counters.c1 != 1)
357 return 100 * counters.c1 + 2;
359 if (counters.c2 != 0)
361 return 100 * counters.c2 + 3;
363 if (f != 0)
365 return 100 * f + 4;
368 return 0;
371 static int test_tbegin_aborts(void)
373 float f;
374 long rc;
376 f = 77;
377 if ((rc = __TM_simple_begin()) == 0)
379 f = 88;
380 __TM_abort();
381 return 2;
383 else if (rc != 2)
385 return 3;
387 if (f != 77)
389 return 4;
391 f = 66;
392 if ((rc = __TM_simple_begin()) == 0)
394 f = 99;
395 __TM_named_abort(3);
396 return 5;
398 else if (rc != 3)
400 return 100 * rc + 6;
402 if (f != 66)
404 return 100 * f + 7;
406 if ((rc = __TM_simple_begin()) == 0)
408 global_float_3 = global_float_1 + global_float_2;
409 rc = __TM_end();
410 if (rc != 0)
412 return 100 * rc + 8;
415 else
417 return 100 * rc + 9;
419 if (global_float_3 != global_float_1 + global_float_2)
421 return 100 * rc + 10;
424 return 0;
427 static int test_tbegin_tdb(void)
429 long rc;
431 local_tdb.format = 0;
432 if ((rc = __TM_begin(&local_tdb)) == 0)
434 rc = __TM_end();
435 if (rc != 0)
437 return 100 * rc + 1;
439 if (local_tdb.format != 0)
441 dump_tdb(&local_tdb);
442 return 100 * local_tdb.format + 2;
445 else
447 return 100 * rc + 3;
449 local_tdb.format = 0;
450 if ((rc = __TM_begin(&local_tdb)) == 0)
452 __TM_named_abort(1);
453 return 4;
455 else
457 if (rc != 3)
459 return 100 * rc + 5;
461 if (local_tdb.format != 1)
463 dump_tdb(&local_tdb);
464 return 100 * local_tdb.format + 6;
467 local_tdb256.format = 0;
468 if ((rc = __TM_begin(&local_tdb256)) == 0)
470 rc = __TM_end();
471 if (rc != 0)
473 return 1100 * rc + 1;
475 if (local_tdb256.format != 0)
477 dump_tdb(&local_tdb256);
478 return 1100 * local_tdb256.format + 2;
481 else
483 return 1100 * rc + 3;
485 #if 1 /*!!!does not work*/
486 local_tdb256.format = 0;
487 if ((rc = __TM_begin(&local_tdb256)) == 0)
489 __TM_named_abort(1);
490 return 2004;
492 else
494 if (rc != 3)
496 return 2100 * rc + 5;
498 if (local_tdb256.format != 1)
500 dump_tdb(&local_tdb256);
501 return 2100 * local_tdb256.format + 6;
504 #endif
506 return 0;
509 static int test_etnd(void)
511 long rc;
514 long nd;
516 make_fake_tdb(&local_tdb);
517 local_tdb.nesting_depth = 0;
518 nd = __TM_nesting_depth(&local_tdb);
519 if (nd != 0)
521 return 1;
523 local_tdb.nesting_depth = 7;
524 nd = __TM_nesting_depth(&local_tdb);
525 if (nd != 7)
527 return 7;
529 local_tdb.format = 0;
530 nd = __TM_nesting_depth(&local_tdb);
531 if (nd != 0)
533 return 2;
536 counters.c1 = 0;
537 counters.c1 = 0;
538 counters.c2 = 0;
539 counters.c3 = 0;
540 if ((rc = __TM_simple_begin()) == 0)
542 counters.c1 = __TM_nesting_depth(0);
543 if (__TM_simple_begin() == 0)
545 counters.c2 = __TM_nesting_depth(0);
546 if (__TM_simple_begin() == 0)
548 counters.c3 = __TM_nesting_depth(0);
549 __TM_end();
551 __TM_end();
553 __TM_end();
555 else
557 return 100 * rc + 1;
559 if (counters.c1 != 1)
561 return 100 * counters.c1 + 2;
563 if (counters.c2 != 2)
565 return 100 * counters.c2 + 3;
567 if (counters.c3 != 3)
569 return 100 * counters.c3 + 4;
572 return 0;
575 /* ---------------------------- local testing framework functions ---------- */
577 static int run_one_test(const test_table_entry_t *test_entry)
579 int do_print_passes;
580 int succeeded;
581 int rc;
582 int i;
584 do_print_passes = (
585 test_entry->required_quorum != 1 ||
586 test_entry->max_repetitions != 1);
587 printf("RRR RUN %s\n", test_entry->name);
588 if (do_print_passes == 1)
590 printf(
591 " (requires %d successful out of %d runs)\n",
592 test_entry->required_quorum,
593 test_entry->max_repetitions);
595 succeeded = 0;
596 rc = 0;
597 for (rc = 0, i = 0; i < test_entry->max_repetitions; i++)
599 if (do_print_passes == 1)
601 if (i == 0)
603 printf(" ");
605 else
607 printf(",");
610 rc = test_entry->test_func();
611 if (rc == 0)
613 if (do_print_passes == 1)
615 printf(" success");
617 succeeded++;
618 if (succeeded >= test_entry->required_quorum)
620 break;
623 else
625 printf(" failed (rc = %d)", rc);
628 if (do_print_passes == 1 || rc != 0)
630 printf("\n");
632 if (succeeded >= test_entry->required_quorum)
634 printf("+++ OK %s\n", test_entry->name);
636 return 0;
638 else
640 printf("--- FAIL %s\n", test_entry->name);
642 return (rc != 0) ? rc : -1;
646 static int run_all_tests(const test_table_entry_t *test_table)
648 const test_table_entry_t *test;
649 int rc;
651 for (
652 rc = 0, test = &test_table[0];
653 test->test_func != NULL && rc == 0; test++)
655 rc = run_one_test(test);
658 return rc;
661 /* ---------------------------- interface functions ------------------------ */
663 int main(void)
665 const test_table_entry_t test_table[] = {
666 TEST_NO_REP(init_cache),
667 TEST_NO_REP(test_abort_classification),
668 TEST_NO_REP(test_cc_classification),
669 TEST_DF_REP(test_tbegin_ntstg_tend),
670 TEST_DF_REP(test_tbegin_ntstg_tabort),
671 TEST_DF_REP(test_tbegin_aborts),
672 TEST_DF_REP(test_tbegin_tdb),
673 TEST_DF_REP(test_etnd),
674 { (void *)0, 0, 0 }
678 int rc;
680 rc = run_all_tests(test_table);
682 return rc;