1 /* Functional tests of the htm __builtin_... macros.  */
2 
3 /* { dg-do run } */
4 /* { dg-require-effective-target htm } */
5 /* { dg-options "-O3 -march=zEC12 -mzarch" } */
6 
7 /* ---------------------------- included header files ---------------------- */
8 
9 #include <stdio.h>
10 #include <string.h>
11 #include <stdint.h>
12 #include <htmintrin.h>
13 
14 /* ---------------------------- local definitions -------------------------- */
15 
16 #define DEFAULT_MAX_REPETITIONS 7
17 #define DEFAULT_REQUIRED_QUORUM 4
18 #define NUM_WARMUP_RUNS 2
19 
20 /* ---------------------------- local macros ------------------------------- */
21 
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 }
25 
26 /* ---------------------------- local types -------------------------------- */
27 
28 typedef int (*test_func_t)(void);
29 
30 typedef struct
31 {
32   const char *name;
33   test_func_t test_func;
34   int max_repetitions;
35   int required_quorum;
36 } test_table_entry_t;
37 
38 /* ---------------------------- local variables ---------------------------- */
39 
40 __attribute__ ((aligned(256))) static struct __htm_tdb local_tdb256;
41 static struct __htm_tdb local_tdb;
42 static int do_dump_tdb = 0;
43 
44 /* ---------------------------- exported variables (globals) --------------- */
45 
46 __attribute__ ((aligned(256))) struct
47 {
48   float float_1;
49   float float_2;
50   float float_3;
51 } global = { 1.0, 2.5, 0.0 };
52 
53 __attribute__ ((aligned(256))) struct
54 {
55   volatile uint64_t c1;
56   volatile uint64_t c2;
57   volatile uint64_t c3;
58 } counters = { 0, 0, 0 };
59 
60 /* ---------------------------- local helper functions --------------------- */
61 
dump_tdb(struct __htm_tdb * tdb)62 static void dump_tdb (struct __htm_tdb *tdb)
63 {
64   unsigned char *p;
65   int i;
66   int j;
67 
68   if (do_dump_tdb == 0)
69     {
70       return;
71     }
72   p = (unsigned char *)tdb;
73   for (i = 0; i < 16; i++)
74     {
75       fprintf (stderr, "0x%02x  ", i * 16);
76       for (j = 0; j < 16; j++)
77 	{
78 	  fprintf (stderr, "%02x", (int)p[i * 16 + j]);
79 	  if (j < 15)
80 	    {
81 	      fprintf (stderr, " ");
82 	    }
83 	  if (j == 7)
84 	    {
85 	      fprintf (stderr, " ");
86 	    }
87 	}
88       fprintf (stderr, "\n");
89     }
90 
91   return;
92 }
93 
94 /* ---------------------------- local test functions ----------------------- */
95 
96 /* Check values of the constants defined in htmintrin.h.  */
test_constants(void)97 static int test_constants (void)
98 {
99   if (_HTM_TBEGIN_STARTED != 0)
100     {
101       return 100 * _HTM_TBEGIN_STARTED + 1;
102     }
103   if (_HTM_TBEGIN_INDETERMINATE != 1)
104     {
105       return 100 * _HTM_TBEGIN_INDETERMINATE + 2;
106     }
107   if (_HTM_TBEGIN_TRANSIENT != 2)
108     {
109       return 100 * _HTM_TBEGIN_TRANSIENT + 3;
110     }
111   if (_HTM_TBEGIN_PERSISTENT != 3)
112     {
113       return 100 * _HTM_TBEGIN_PERSISTENT + 4;
114     }
115 
116   return 0;
117 }
118 
test_tbegin_ntstg_tend(void)119 static int test_tbegin_ntstg_tend (void)
120 {
121   int rc;
122 
123   counters.c1 = 0;
124   counters.c2 = 0;
125   if ((rc = __builtin_tbegin ((void *)0)) == 0)
126     {
127       __builtin_non_tx_store ((uint64_t *)&counters.c1, 1);
128       counters.c2 = 2;
129       rc = __builtin_tend ();
130       if (rc != 0)
131 	{
132 	  return 100 * rc + 5;
133 	}
134       if (counters.c1 != 1)
135 	{
136 	  return 100 * counters.c1 + 2;
137 	}
138       if (counters.c2 != 2)
139 	{
140 	  return 100 * counters.c2 + 3;
141 	}
142     }
143   else
144     {
145       return 100 * rc + 4;
146     }
147 
148   return 0;
149 }
150 
test_tbegin_ntstg_tabort(void)151 static int test_tbegin_ntstg_tabort (void)
152 {
153   float f;
154 
155   counters.c1 = 0;
156   counters.c2 = 0;
157   f = 0;
158   if (__builtin_tbegin ((void *)0) == 0)
159     {
160       __builtin_non_tx_store ((uint64_t *)&counters.c1, 1);
161       counters.c2 = 2;
162       f = 1;
163       __builtin_tabort (256);
164       return 1;
165     }
166   if (counters.c1 != 1)
167     {
168       return 100 * counters.c1 + 2;
169     }
170   if (counters.c2 != 0)
171     {
172       return 100 * counters.c2 + 3;
173     }
174   if (f != 0)
175     {
176       return 100 * f + 4;
177     }
178 
179   return 0;
180 }
181 
test_tbegin_nofloat(void)182 static int test_tbegin_nofloat (void)
183 {
184   int rc;
185 
186   counters.c1 = 0;
187   counters.c2 = 0;
188   if ((rc = __builtin_tbegin_nofloat ((void *)0)) == 0)
189     {
190       __builtin_non_tx_store ((uint64_t *)&counters.c1, 1);
191       counters.c2 = 2;
192       rc = __builtin_tend ();
193       if (rc != 0)
194 	{
195 	  return 100 * rc + 5;
196 	}
197       if (counters.c1 != 1)
198 	{
199 	  return 100 * counters.c1 + 2;
200 	}
201       if (counters.c2 != 2)
202 	{
203 	  return 100 * counters.c2 + 3;
204 	}
205     }
206   else
207     {
208       return 100 * rc + 4;
209     }
210 
211   return 0;
212 }
213 
test_tbegin_retry(void)214 static int test_tbegin_retry (void)
215 {
216   int rc;
217 
218   counters.c1 = 0;
219   counters.c2 = 0;
220   counters.c3 = 0;
221   if ((rc = __builtin_tbegin_retry ((void *)0, 5)) == 0)
222     {
223       int do_abort;
224 
225       do_abort = (counters.c1 == 0) ? 1 : 0;
226       __builtin_non_tx_store (
227 			     (uint64_t *)&counters.c1, counters.c1 + 1);
228       if (do_abort == 1)
229 	{
230 	  __builtin_tabort (256);
231 	}
232       counters.c2 = counters.c2 + 10;
233       __builtin_non_tx_store ((uint64_t *)&counters.c3, 3);
234       rc = __builtin_tend ();
235       if (rc != 0)
236 	{
237 	  return 100 * rc + 5;
238 	}
239       if (counters.c1 != 2)
240 	{
241 	  return 100 * counters.c1 + 2;
242 	}
243       if (counters.c2 != 10)
244 	{
245 	  return 100 * counters.c2 + 3;
246 	}
247       if (counters.c3 != 3)
248 	{
249 	  return 100 * counters.c3 + 6;
250 	}
251     }
252   else
253     {
254       return 100 * rc + 4;
255     }
256 
257   return 0;
258 }
259 
test_tbegin_retry_nofloat(void)260 static int test_tbegin_retry_nofloat (void)
261 {
262   int rc;
263 
264   counters.c1 = 0;
265   counters.c2 = 0;
266   counters.c3 = 0;
267   if ((rc = __builtin_tbegin_retry_nofloat ((void *)0, 5)) == 0)
268     {
269       int do_abort;
270 
271       do_abort = (counters.c1 == 0) ? 1 : 0;
272       __builtin_non_tx_store (
273 			     (uint64_t *)&counters.c1, counters.c1 + 1);
274       if (do_abort == 1)
275 	{
276 	  __builtin_tabort (256);
277 	}
278       counters.c2 = counters.c2 + 10;
279       __builtin_non_tx_store ((uint64_t *)&counters.c3, 3);
280       rc = __builtin_tend ();
281       if (rc != 0)
282 	{
283 	  return 100 * rc + 5;
284 	}
285       if (counters.c1 != 2)
286 	{
287 	  return 100 * counters.c1 + 2;
288 	}
289       if (counters.c2 != 10)
290 	{
291 	  return 100 * counters.c2 + 3;
292 	}
293       if (counters.c3 != 3)
294 	{
295 	  return 100 * counters.c3 + 6;
296 	}
297     }
298   else
299     {
300       return 100 * rc + 4;
301     }
302 
303   return 0;
304 }
305 
test_tbegin_aborts(void)306 static int test_tbegin_aborts (void)
307 {
308   float f;
309   int rc;
310 
311   f = 77;
312   if ((rc = __builtin_tbegin ((void *)0)) == 0)
313     {
314       f = 88;
315       __builtin_tabort (256);
316       return 2;
317     }
318   else if (rc != 2)
319     {
320       return 3;
321     }
322   if (f != 77)
323     {
324       return 4;
325     }
326   f = 66;
327   if ((rc = __builtin_tbegin ((void *)0)) == 0)
328     {
329       f = 99;
330       __builtin_tabort (257);
331       return 5;
332     }
333   else if (rc != 3)
334     {
335       return 100 * rc + 6;
336     }
337   if (f != 66)
338     {
339       return 100 * f + 7;
340     }
341   if ((rc = __builtin_tbegin ((void *)0)) == 0)
342     {
343       global.float_3 = global.float_1 + global.float_2;
344       rc = __builtin_tend ();
345       if (rc != 0)
346 	{
347 	  return 100 * rc + 8;
348 	}
349     }
350   else
351     {
352       return 100 * rc + 9;
353     }
354   if (global.float_3 != global.float_1 + global.float_2)
355     {
356       return 100 * rc + 10;
357     }
358 
359   return 0;
360 }
361 
indirect_abort(int abort_code)362 static __attribute__((noinline)) void indirect_abort(int abort_code)
363 {
364   __builtin_tabort (abort_code);
365 
366   return;
367 }
368 
test_tbegin_indirect_aborts(void)369 static int test_tbegin_indirect_aborts (void)
370 {
371   float f;
372   int rc;
373 
374   f = 77;
375   if ((rc = __builtin_tbegin ((void *)0)) == 0)
376     {
377       f = 88;
378       indirect_abort(256);
379       return 2;
380     }
381   else if (rc != 2)
382     {
383       return 100 * rc + 3;
384     }
385   if (f != 77)
386     {
387       return 100 * rc + 4;
388     }
389   f = 66;
390   if ((rc = __builtin_tbegin ((void *)0)) == 0)
391     {
392       f = 99;
393       indirect_abort(257);
394       return 5;
395     }
396   else if (rc != 3)
397     {
398       return 100 * rc + 6;
399     }
400   if (f != 66)
401     {
402       return 100 * f + 7;
403     }
404 
405   return 0;
406 }
407 
test_tbegin_nofloat_aborts(void)408 static int test_tbegin_nofloat_aborts (void)
409 {
410   int rc;
411 
412   if ((rc = __builtin_tbegin_nofloat ((void *)0)) == 0)
413     {
414       __builtin_tabort (256);
415       return 2;
416     }
417   if ((rc = __builtin_tbegin_nofloat ((void *)0)) == 0)
418     {
419       __builtin_tabort (257);
420       return 1005;
421     }
422   else if (rc != 3)
423     {
424       return 1000 * rc + 6;
425     }
426 
427   return 0;
428 }
429 
test_tbegin_nofloat_indirect_aborts(void)430 static int test_tbegin_nofloat_indirect_aborts (void)
431 {
432   int rc;
433 
434   if ((rc = __builtin_tbegin_nofloat ((void *)0)) == 0)
435     {
436       indirect_abort (256);
437       return 2;
438     }
439   if ((rc = __builtin_tbegin_nofloat ((void *)0)) == 0)
440     {
441       indirect_abort (257);
442       return 1005;
443     }
444   else if (rc != 3)
445     {
446       return 1000 * rc + 6;
447     }
448 
449   return 0;
450 }
451 
452 static
_test_tbegin_retry_aborts(int retries,uint64_t abort_code)453 int _test_tbegin_retry_aborts (int retries, uint64_t abort_code)
454 {
455   int rc;
456 
457   counters.c1 = 0;
458   if ((rc = __builtin_tbegin_retry ((void *)0, retries)) == 0)
459     {
460       __builtin_non_tx_store ((uint64_t *)&counters.c1, counters.c1 + 1);
461       __builtin_tabort (abort_code);
462       return 2;
463     }
464   else
465     {
466       if ((abort_code & 1) == 0)
467 	{
468 	  if (rc != 2)
469 	    {
470 	      return 100 * rc + 2003;
471 	    }
472 	  else if (counters.c1 != (uint64_t)retries + 1)
473 	    {
474 	      return 1000 * counters.c1 + 100 * retries + 4;
475 	    }
476 	}
477       else
478 	{
479 	  if (rc != 3)
480 	    {
481 	      return 100 * rc + 3005;
482 	    }
483 	  else if (counters.c1 != 1)
484 	    {
485 	      return 1000 * counters.c1 + 100 * retries + 6;
486 	    }
487 	}
488     }
489 
490   return 0;
491 }
492 
test_tbegin_retry_aborts(void)493 static int test_tbegin_retry_aborts (void)
494 {
495   int rc;
496   int retries;
497 
498   for (retries = 1; retries <= 3; retries++)
499     {
500       rc = _test_tbegin_retry_aborts (retries, 256);
501       if (rc != 0)
502 	{
503 	  return 10000 + rc;
504 	}
505     }
506   for (retries = 1; retries <= 3; retries++)
507     {
508       rc = _test_tbegin_retry_aborts (retries, 257);
509       if (rc != 0)
510 	{
511 	  return 20000 + rc;
512 	}
513     }
514   if ((rc = __builtin_tbegin_retry ((void *)0, 5)) == 0)
515     {
516       global.float_3 = global.float_1 + global.float_2;
517       rc = __builtin_tend ();
518       if (rc != 0)
519 	{
520 	  return 30000 + 100 * rc + 6;
521 	}
522     }
523   else
524     {
525       return 30000 + 100 * rc + 7;
526     }
527 
528   return 0;
529 }
530 
_test_tbegin_retry_nofloat_aborts(int retries,uint64_t abort_code)531 static int _test_tbegin_retry_nofloat_aborts (int retries, uint64_t abort_code)
532 {
533   int rc;
534 
535   counters.c1 = 0;
536   if ((rc = __builtin_tbegin_retry_nofloat ((void *)0, retries)) == 0)
537     {
538       __builtin_non_tx_store ((uint64_t *)&counters.c1, counters.c1 + 1);
539       __builtin_tabort (abort_code);
540       return 2;
541     }
542   else
543     {
544       if ((abort_code & 1) == 0)
545 	{
546 	  if (rc != 2)
547 	    {
548 	      return 100 * rc + 2003;
549 	    }
550 	  else if (counters.c1 != (uint64_t)retries + 1)
551 	    {
552 	      return 1000 * counters.c1 + 100 * retries + 4;
553 	    }
554 	}
555       else
556 	{
557 	  if (rc != 3)
558 	    {
559 	      return 100 * rc + 3005;
560 	    }
561 	  else if (counters.c1 != 1)
562 	    {
563 	      return 1000 * counters.c1 + 100 * retries + 6;
564 	    }
565 	}
566     }
567 
568   return 0;
569 }
570 
test_tbegin_retry_nofloat_aborts(void)571 static int test_tbegin_retry_nofloat_aborts (void)
572 {
573   int rc;
574   int retries;
575 
576   for (retries = 1; retries <= 3; retries++)
577     {
578       rc = _test_tbegin_retry_nofloat_aborts (retries, 256);
579       if (rc != 0)
580 	{
581 	  return 10 * retries + rc;
582 	}
583     }
584   for (retries = 1; retries <= 3; retries++)
585     {
586       rc = _test_tbegin_retry_nofloat_aborts (retries, 257);
587       if (rc != 0)
588 	{
589 	  return 10000 + 10 * retries + rc;
590 	}
591     }
592 
593   return 0;
594 }
595 
test_tbegin_tdb(void)596 static int test_tbegin_tdb (void)
597 {
598   int rc;
599 
600   local_tdb.format = 0;
601   if ((rc = __builtin_tbegin (&local_tdb)) == 0)
602     {
603       rc = __builtin_tend ();
604       if (rc != 0)
605 	{
606 	  return 100 * rc + 1;
607 	}
608       if (local_tdb.format != 0)
609 	{
610 	  dump_tdb (&local_tdb);
611 	  return 100 * local_tdb.format + 2;
612 	}
613     }
614   else
615     {
616       return 100 * rc + 3;
617     }
618   local_tdb.format = 0;
619   if ((rc = __builtin_tbegin (&local_tdb)) == 0)
620     {
621       __builtin_tabort (257);
622       return 4;
623     }
624   else
625     {
626       if (rc != 3)
627 	{
628 	  return 100 * rc + 5;
629 	}
630       if (local_tdb.format != 1)
631 	{
632 	  dump_tdb (&local_tdb);
633 	  return 100 * local_tdb.format + 6;
634 	}
635     }
636   local_tdb256.format = 0;
637   if ((rc = __builtin_tbegin (&local_tdb256)) == 0)
638     {
639       rc = __builtin_tend ();
640       if (rc != 0)
641 	{
642 	  return 1100 * rc + 1;
643 	}
644       if (local_tdb256.format != 0)
645 	{
646 	  dump_tdb (&local_tdb256);
647 	  return 1100 * local_tdb256.format + 2;
648 	}
649     }
650   else
651     {
652       return 1100 * rc + 3;
653     }
654   local_tdb256.format = 0;
655   if ((rc = __builtin_tbegin (&local_tdb256)) == 0)
656     {
657       __builtin_tabort (257);
658       return 2004;
659     }
660   else
661     {
662       if (rc != 3)
663 	{
664 	  return 2100 * rc + 5;
665 	}
666       if (local_tdb256.format != 1)
667 	{
668 	  dump_tdb (&local_tdb256);
669 	  return 2100 * local_tdb256.format + 6;
670 	}
671     }
672 
673   return 0;
674 }
675 
test_tbegin_nofloat_tdb(void)676 static int test_tbegin_nofloat_tdb (void)
677 {
678   int rc;
679 
680   local_tdb.format = 0;
681   if ((rc = __builtin_tbegin_nofloat (&local_tdb)) == 0)
682     {
683       rc = __builtin_tend ();
684       if (rc != 0)
685 	{
686 	  return 100 * rc + 1;
687 	}
688       if (local_tdb.format != 0)
689 	{
690 	  dump_tdb (&local_tdb);
691 	  return 100 * local_tdb.format + 2;
692 	}
693     }
694   else
695     {
696       return 3;
697     }
698   local_tdb.format = 0;
699   if ((rc = __builtin_tbegin_nofloat (&local_tdb)) == 0)
700     {
701       __builtin_tabort (257);
702       return 4;
703     }
704   else
705     {
706       if (rc != 3)
707 	{
708 	  return 100 * rc + 5;
709 	}
710       if (local_tdb.format != 1)
711 	{
712 	  dump_tdb (&local_tdb);
713 	  return 100 * local_tdb.format + 6;
714 	}
715     }
716   local_tdb256.format = 0;
717   if ((rc = __builtin_tbegin_nofloat (&local_tdb256)) == 0)
718     {
719       rc = __builtin_tend ();
720       if (rc != 0)
721 	{
722 	  return 1100 * rc + 1;
723 	}
724       if (local_tdb256.format != 0)
725 	{
726 	  dump_tdb (&local_tdb256);
727 	  return 1100 * local_tdb256.format + 2;
728 	}
729     }
730   else
731     {
732       return 1003;
733     }
734   local_tdb256.format = 0;
735   if ((rc = __builtin_tbegin_nofloat (&local_tdb256)) == 0)
736     {
737       __builtin_tabort (257);
738       return 2004;
739     }
740   else
741     {
742       if (rc != 3)
743 	{
744 	  return 2100 * rc + 5;
745 	}
746       if (local_tdb256.format != 1)
747 	{
748 	  dump_tdb (&local_tdb256);
749 	  return 2100 * local_tdb256.format + 6;
750 	}
751     }
752 
753   return 0;
754 }
755 
test_tbegin_retry_tdb(void)756 static int test_tbegin_retry_tdb (void)
757 {
758   int rc;
759 
760   local_tdb256.format = 0;
761   if ((rc = __builtin_tbegin_retry (&local_tdb256, 2)) == 0)
762     {
763       rc = __builtin_tend ();
764       if (rc != 0)
765 	{
766 	  return 1100 * rc + 1;
767 	}
768       if (local_tdb256.format != 0)
769 	{
770 	  dump_tdb (&local_tdb256);
771 	  return 1100 * local_tdb256.format + 2;
772 	}
773     }
774   else
775     {
776       return 1003;
777     }
778   local_tdb256.format = 0;
779   if ((rc = __builtin_tbegin_retry (&local_tdb256, 2)) == 0)
780     {
781       __builtin_tabort (257);
782       return 2004;
783     }
784   else
785     {
786       if (rc != 3)
787 	{
788 	  return 2100 * rc + 5;
789 	}
790       if (local_tdb256.format != 1)
791 	{
792 	  dump_tdb (&local_tdb256);
793 	  return 2100 * local_tdb256.format + 6;
794 	}
795     }
796 
797   return 0;
798 }
799 
test_tbegin_retry_nofloat_tdb(void)800 static int test_tbegin_retry_nofloat_tdb (void)
801 {
802   int rc;
803 
804   local_tdb.format = 0;
805   if ((rc = __builtin_tbegin_retry_nofloat (&local_tdb, 2)) == 0)
806     {
807       rc = __builtin_tend ();
808       if (rc != 0)
809 	{
810 	  return 100 * rc + 1;
811 	}
812       if (local_tdb.format != 0)
813 	{
814 	  dump_tdb (&local_tdb);
815 	  return 100 * local_tdb.format + 2;
816 	}
817     }
818   else
819     {
820       return 100 * rc + 3;
821     }
822   local_tdb.format = 0;
823   if ((rc = __builtin_tbegin_retry_nofloat (&local_tdb, 2)) == 0)
824     {
825       __builtin_tabort (257);
826       return 4;
827     }
828   else
829     {
830       if (rc != 3)
831 	{
832 	  return 100 * rc + 5;
833 	}
834       if (local_tdb.format != 1)
835 	{
836 	  dump_tdb (&local_tdb);
837 	  return 100 * local_tdb.format + 6;
838 	}
839     }
840   local_tdb256.format = 0;
841   if ((rc = __builtin_tbegin_retry_nofloat (&local_tdb256, 2)) == 0)
842     {
843       rc = __builtin_tend ();
844       if (rc != 0)
845 	{
846 	  return 1100 * rc + 1;
847 	}
848       if (local_tdb256.format != 0)
849 	{
850 	  dump_tdb (&local_tdb256);
851 	  return 1100 * local_tdb256.format + 2;
852 	}
853     }
854   else
855     {
856       return 1100 * rc + 3;
857     }
858   local_tdb256.format = 0;
859   if ((rc = __builtin_tbegin_retry_nofloat (&local_tdb256, 2)) == 0)
860     {
861       __builtin_tabort (257);
862       return 2004;
863     }
864   else
865     {
866       if (rc != 3)
867 	{
868 	  return 2100 * rc + 5;
869 	}
870       if (local_tdb256.format != 1)
871 	{
872 	  dump_tdb (&local_tdb256);
873 	  return 2100 * local_tdb256.format + 6;
874 	}
875     }
876 
877   return 0;
878 }
879 
test_etnd(void)880 static int test_etnd (void)
881 {
882   int rc;
883 
884   counters.c1 = 0;
885   counters.c2 = 0;
886   counters.c3 = 0;
887   if ((rc = __builtin_tbegin ((void *)0)) == 0)
888     {
889       counters.c1 = __builtin_tx_nesting_depth ();
890       if (__builtin_tbegin ((void *)0) == 0)
891 	{
892 	  counters.c2 = __builtin_tx_nesting_depth ();
893 	  if (__builtin_tbegin ((void *)0) == 0)
894 	    {
895 	      counters.c3 = __builtin_tx_nesting_depth ();
896 	      __builtin_tend ();
897 	    }
898 	  __builtin_tend ();
899 	}
900       __builtin_tend ();
901     }
902   else
903     {
904       return 100 * rc + 1;
905     }
906   if (counters.c1 != 1)
907     {
908       return 100 * counters.c1 + 2;
909     }
910   if (counters.c2 != 2)
911     {
912       return 100 * counters.c2 + 3;
913     }
914   if (counters.c3 != 3)
915     {
916       return 100 * counters.c3 + 4;
917     }
918 
919   return 0;
920 }
921 
test_tbeginc(void)922 static int test_tbeginc (void)
923 {
924   int rc;
925 
926   counters.c1 = 0;
927   __builtin_tbeginc ();
928   counters.c1 = 1;
929   rc = __builtin_tend ();
930   if (rc != 0)
931     {
932       return 10000 * rc + 1;
933     }
934   if (counters.c1 != 1)
935     {
936       return 100000 * counters.c1 + 3;
937     }
938 
939   return 0;
940 }
941 
942 /* ---------------------------- local testing framework functions ---------- */
943 
run_one_test(const test_table_entry_t * test_entry)944 static int run_one_test (const test_table_entry_t *test_entry)
945 {
946   int do_print_passes;
947   int succeeded;
948   int rc;
949   int i;
950 
951   /* Warmup run to get all necessary data and instruction pages into the page
952    * tables.  */
953   {
954     int run;
955 
956     do_dump_tdb = 0;
957     for (run = 0; run < NUM_WARMUP_RUNS; run++)
958       {
959 	test_entry->test_func ();
960       }
961     do_dump_tdb = 1;
962   }
963   do_print_passes = (
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)
968     {
969       printf (
970 	     "         (requires %d successful out of %d runs)\n",
971 	     test_entry->required_quorum,
972 	     test_entry->max_repetitions);
973     }
974   succeeded = 0;
975   rc = 0;
976   for (rc = 0, i = 0; i < test_entry->max_repetitions; i++)
977     {
978       if (do_print_passes == 1)
979 	{
980 	  if (i == 0)
981 	    {
982 	      printf ("        ");
983 	    }
984 	  else
985 	    {
986 	      printf (",");
987 	    }
988 	}
989       rc = test_entry->test_func ();
990       if (rc == 0)
991 	{
992 	  if (do_print_passes == 1)
993 	    {
994 	      printf (" success");
995 	    }
996 	  succeeded++;
997 	  if (succeeded >= test_entry->required_quorum)
998 	    {
999 	      break;
1000 	    }
1001 	}
1002       else
1003 	{
1004 	  printf (" failed (rc = %d)", rc);
1005 	}
1006     }
1007   if (do_print_passes == 1 || rc != 0)
1008     {
1009       printf ("\n");
1010     }
1011   if (succeeded >= test_entry->required_quorum)
1012     {
1013       printf ("+++ OK   %s\n", test_entry->name);
1014 
1015       return 0;
1016     }
1017   else
1018     {
1019       printf ("--- FAIL %s\n", test_entry->name);
1020 
1021       return (rc != 0) ? rc : -1;
1022     }
1023 }
1024 
run_all_tests(const test_table_entry_t * test_table)1025 static int run_all_tests (const test_table_entry_t *test_table)
1026 {
1027   const test_table_entry_t *test;
1028   int rc;
1029 
1030   for (
1031        rc = 0, test = &test_table[0];
1032        test->test_func != NULL && rc == 0; test++)
1033     {
1034       rc = run_one_test (test);
1035     }
1036 
1037   return rc;
1038 }
1039 
1040 /* ---------------------------- interface functions ------------------------ */
1041 
main(void)1042 int main (void)
1043 {
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),
1063     { (void *)0, 0, 0 }
1064   };
1065 
1066   {
1067     int rc;
1068 
1069     rc = run_all_tests (test_table);
1070 
1071     return rc;
1072   }
1073 }
1074