(root)/
gcc-13.2.0/
gcc/
testsuite/
gcc.target/
s390/
htm-builtins-1.c
       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  
      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.  */
      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  
     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  
     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  
     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  
     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  
     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  
     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  
     362  static __attribute__((noinline)) void indirect_abort(int abort_code)
     363  {
     364    __builtin_tabort (abort_code);
     365  
     366    return;
     367  }
     368  
     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  
     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  
     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
     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  
     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  
     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  
     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  
     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  
     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  
     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  
     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  
     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  
     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  
     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  
    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  
    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  }