(root)/
gcc-13.2.0/
gcc/
testsuite/
gcc.target/
riscv/
inline-atomics-3.c
       1  /* Check all char alignments.  */
       2  /* Duplicate logic as libatomic/testsuite/libatomic.c/atomic-op-1.c */
       3  /* Test __atomic routines for existence and proper execution on 1 byte
       4     values with each valid memory model.  */
       5  /* { dg-do run } */
       6  /* { dg-options "-minline-atomics -Wno-address-of-packed-member" } */
       7  
       8  /* Test the execution of the __atomic_*OP builtin routines for a char.  */
       9  
      10  extern void abort(void);
      11  
      12  char count, res;
      13  const char init = ~0;
      14  
      15  struct A
      16  {
      17     char a;
      18     char b;
      19     char c;
      20     char d;
      21  } __attribute__ ((packed)) A;
      22  
      23  /* The fetch_op routines return the original value before the operation.  */
      24  
      25  void
      26  test_fetch_add (char* v)
      27  {
      28    *v = 0;
      29    count = 1;
      30  
      31    if (__atomic_fetch_add (v, count, __ATOMIC_RELAXED) != 0)
      32      abort ();
      33  
      34    if (__atomic_fetch_add (v, 1, __ATOMIC_CONSUME) != 1)
      35      abort ();
      36  
      37    if (__atomic_fetch_add (v, count, __ATOMIC_ACQUIRE) != 2)
      38      abort ();
      39  
      40    if (__atomic_fetch_add (v, 1, __ATOMIC_RELEASE) != 3)
      41      abort ();
      42  
      43    if (__atomic_fetch_add (v, count, __ATOMIC_ACQ_REL) != 4)
      44      abort ();
      45  
      46    if (__atomic_fetch_add (v, 1, __ATOMIC_SEQ_CST) != 5)
      47      abort ();
      48  }
      49  
      50  
      51  void
      52  test_fetch_sub (char* v)
      53  {
      54    *v = res = 20;
      55    count = 0;
      56  
      57    if (__atomic_fetch_sub (v, count + 1, __ATOMIC_RELAXED) !=  res--)
      58      abort ();
      59  
      60    if (__atomic_fetch_sub (v, 1, __ATOMIC_CONSUME) !=  res--)
      61      abort ();
      62  
      63    if (__atomic_fetch_sub (v, count + 1, __ATOMIC_ACQUIRE) !=  res--)
      64      abort ();
      65  
      66    if (__atomic_fetch_sub (v, 1, __ATOMIC_RELEASE) !=  res--)
      67      abort ();
      68  
      69    if (__atomic_fetch_sub (v, count + 1, __ATOMIC_ACQ_REL) !=  res--)
      70      abort ();
      71  
      72    if (__atomic_fetch_sub (v, 1, __ATOMIC_SEQ_CST) !=  res--)
      73      abort ();
      74  }
      75  
      76  void
      77  test_fetch_and (char* v)
      78  {
      79    *v = init;
      80  
      81    if (__atomic_fetch_and (v, 0, __ATOMIC_RELAXED) !=  init)
      82      abort ();
      83  
      84    if (__atomic_fetch_and (v, init, __ATOMIC_CONSUME) !=  0)
      85      abort ();
      86  
      87    if (__atomic_fetch_and (v, 0, __ATOMIC_ACQUIRE) !=  0)
      88      abort ();
      89  
      90    *v = ~*v;
      91    if (__atomic_fetch_and (v, init, __ATOMIC_RELEASE) !=  init)
      92      abort ();
      93  
      94    if (__atomic_fetch_and (v, 0, __ATOMIC_ACQ_REL) !=  init)
      95      abort ();
      96  
      97    if (__atomic_fetch_and (v, 0, __ATOMIC_SEQ_CST) !=  0)
      98      abort ();
      99  }
     100  
     101  void
     102  test_fetch_nand (char* v)
     103  {
     104    *v = init;
     105  
     106    if (__atomic_fetch_nand (v, 0, __ATOMIC_RELAXED) !=  init)
     107      abort ();
     108  
     109    if (__atomic_fetch_nand (v, init, __ATOMIC_CONSUME) !=  init)
     110      abort ();
     111  
     112    if (__atomic_fetch_nand (v, 0, __ATOMIC_ACQUIRE) !=  0 )
     113      abort ();
     114  
     115    if (__atomic_fetch_nand (v, init, __ATOMIC_RELEASE) !=  init)
     116      abort ();
     117  
     118    if (__atomic_fetch_nand (v, init, __ATOMIC_ACQ_REL) !=  0)
     119      abort ();
     120  
     121    if (__atomic_fetch_nand (v, 0, __ATOMIC_SEQ_CST) !=  init)
     122      abort ();
     123  }
     124  
     125  void
     126  test_fetch_xor (char* v)
     127  {
     128    *v = init;
     129    count = 0;
     130  
     131    if (__atomic_fetch_xor (v, count, __ATOMIC_RELAXED) !=  init)
     132      abort ();
     133  
     134    if (__atomic_fetch_xor (v, ~count, __ATOMIC_CONSUME) !=  init)
     135      abort ();
     136  
     137    if (__atomic_fetch_xor (v, 0, __ATOMIC_ACQUIRE) !=  0)
     138      abort ();
     139  
     140    if (__atomic_fetch_xor (v, ~count, __ATOMIC_RELEASE) !=  0)
     141      abort ();
     142  
     143    if (__atomic_fetch_xor (v, 0, __ATOMIC_ACQ_REL) !=  init)
     144      abort ();
     145  
     146    if (__atomic_fetch_xor (v, ~count, __ATOMIC_SEQ_CST) !=  init)
     147      abort ();
     148  }
     149  
     150  void
     151  test_fetch_or (char* v)
     152  {
     153    *v = 0;
     154    count = 1;
     155  
     156    if (__atomic_fetch_or (v, count, __ATOMIC_RELAXED) !=  0)
     157      abort ();
     158  
     159    count *= 2;
     160    if (__atomic_fetch_or (v, 2, __ATOMIC_CONSUME) !=  1)
     161      abort ();
     162  
     163    count *= 2;
     164    if (__atomic_fetch_or (v, count, __ATOMIC_ACQUIRE) !=  3)
     165      abort ();
     166  
     167    count *= 2;
     168    if (__atomic_fetch_or (v, 8, __ATOMIC_RELEASE) !=  7)
     169      abort ();
     170  
     171    count *= 2;
     172    if (__atomic_fetch_or (v, count, __ATOMIC_ACQ_REL) !=  15)
     173      abort ();
     174  
     175    count *= 2;
     176    if (__atomic_fetch_or (v, count, __ATOMIC_SEQ_CST) !=  31)
     177      abort ();
     178  }
     179  
     180  /* The OP_fetch routines return the new value after the operation.  */
     181  
     182  void
     183  test_add_fetch (char* v)
     184  {
     185    *v = 0;
     186    count = 1;
     187  
     188    if (__atomic_add_fetch (v, count, __ATOMIC_RELAXED) != 1)
     189      abort ();
     190  
     191    if (__atomic_add_fetch (v, 1, __ATOMIC_CONSUME) != 2)
     192      abort ();
     193  
     194    if (__atomic_add_fetch (v, count, __ATOMIC_ACQUIRE) != 3)
     195      abort ();
     196  
     197    if (__atomic_add_fetch (v, 1, __ATOMIC_RELEASE) != 4)
     198      abort ();
     199  
     200    if (__atomic_add_fetch (v, count, __ATOMIC_ACQ_REL) != 5)
     201      abort ();
     202  
     203    if (__atomic_add_fetch (v, count, __ATOMIC_SEQ_CST) != 6)
     204      abort ();
     205  }
     206  
     207  
     208  void
     209  test_sub_fetch (char* v)
     210  {
     211    *v = res = 20;
     212    count = 0;
     213  
     214    if (__atomic_sub_fetch (v, count + 1, __ATOMIC_RELAXED) !=  --res)
     215      abort ();
     216  
     217    if (__atomic_sub_fetch (v, 1, __ATOMIC_CONSUME) !=  --res)
     218      abort ();
     219  
     220    if (__atomic_sub_fetch (v, count + 1, __ATOMIC_ACQUIRE) !=  --res)
     221      abort ();
     222  
     223    if (__atomic_sub_fetch (v, 1, __ATOMIC_RELEASE) !=  --res)
     224      abort ();
     225  
     226    if (__atomic_sub_fetch (v, count + 1, __ATOMIC_ACQ_REL) !=  --res)
     227      abort ();
     228  
     229    if (__atomic_sub_fetch (v, count + 1, __ATOMIC_SEQ_CST) !=  --res)
     230      abort ();
     231  }
     232  
     233  void
     234  test_and_fetch (char* v)
     235  {
     236    *v = init;
     237  
     238    if (__atomic_and_fetch (v, 0, __ATOMIC_RELAXED) !=  0)
     239      abort ();
     240  
     241    *v = init;
     242    if (__atomic_and_fetch (v, init, __ATOMIC_CONSUME) !=  init)
     243      abort ();
     244  
     245    if (__atomic_and_fetch (v, 0, __ATOMIC_ACQUIRE) !=  0)
     246      abort ();
     247  
     248    *v = ~*v;
     249    if (__atomic_and_fetch (v, init, __ATOMIC_RELEASE) !=  init)
     250      abort ();
     251  
     252    if (__atomic_and_fetch (v, 0, __ATOMIC_ACQ_REL) !=  0)
     253      abort ();
     254  
     255    *v = ~*v;
     256    if (__atomic_and_fetch (v, 0, __ATOMIC_SEQ_CST) !=  0)
     257      abort ();
     258  }
     259  
     260  void
     261  test_nand_fetch (char* v)
     262  {
     263    *v = init;
     264  
     265    if (__atomic_nand_fetch (v, 0, __ATOMIC_RELAXED) !=  init)
     266      abort ();
     267  
     268    if (__atomic_nand_fetch (v, init, __ATOMIC_CONSUME) !=  0)
     269      abort ();
     270  
     271    if (__atomic_nand_fetch (v, 0, __ATOMIC_ACQUIRE) !=  init)
     272      abort ();
     273  
     274    if (__atomic_nand_fetch (v, init, __ATOMIC_RELEASE) !=  0)
     275      abort ();
     276  
     277    if (__atomic_nand_fetch (v, init, __ATOMIC_ACQ_REL) !=  init)
     278      abort ();
     279  
     280    if (__atomic_nand_fetch (v, 0, __ATOMIC_SEQ_CST) !=  init)
     281      abort ();
     282  }
     283  
     284  
     285  
     286  void
     287  test_xor_fetch (char* v)
     288  {
     289    *v = init;
     290    count = 0;
     291  
     292    if (__atomic_xor_fetch (v, count, __ATOMIC_RELAXED) !=  init)
     293      abort ();
     294  
     295    if (__atomic_xor_fetch (v, ~count, __ATOMIC_CONSUME) !=  0)
     296      abort ();
     297  
     298    if (__atomic_xor_fetch (v, 0, __ATOMIC_ACQUIRE) !=  0)
     299      abort ();
     300  
     301    if (__atomic_xor_fetch (v, ~count, __ATOMIC_RELEASE) !=  init)
     302      abort ();
     303  
     304    if (__atomic_xor_fetch (v, 0, __ATOMIC_ACQ_REL) !=  init)
     305      abort ();
     306  
     307    if (__atomic_xor_fetch (v, ~count, __ATOMIC_SEQ_CST) !=  0)
     308      abort ();
     309  }
     310  
     311  void
     312  test_or_fetch (char* v)
     313  {
     314    *v = 0;
     315    count = 1;
     316  
     317    if (__atomic_or_fetch (v, count, __ATOMIC_RELAXED) !=  1)
     318      abort ();
     319  
     320    count *= 2;
     321    if (__atomic_or_fetch (v, 2, __ATOMIC_CONSUME) !=  3)
     322      abort ();
     323  
     324    count *= 2;
     325    if (__atomic_or_fetch (v, count, __ATOMIC_ACQUIRE) !=  7)
     326      abort ();
     327  
     328    count *= 2;
     329    if (__atomic_or_fetch (v, 8, __ATOMIC_RELEASE) !=  15)
     330      abort ();
     331  
     332    count *= 2;
     333    if (__atomic_or_fetch (v, count, __ATOMIC_ACQ_REL) !=  31)
     334      abort ();
     335  
     336    count *= 2;
     337    if (__atomic_or_fetch (v, count, __ATOMIC_SEQ_CST) !=  63)
     338      abort ();
     339  }
     340  
     341  
     342  /* Test the OP routines with a result which isn't used. Use both variations
     343     within each function.  */
     344  
     345  void
     346  test_add (char* v)
     347  {
     348    *v = 0;
     349    count = 1;
     350  
     351    __atomic_add_fetch (v, count, __ATOMIC_RELAXED);
     352    if (*v != 1)
     353      abort ();
     354  
     355    __atomic_fetch_add (v, count, __ATOMIC_CONSUME);
     356    if (*v != 2)
     357      abort ();
     358  
     359    __atomic_add_fetch (v, 1 , __ATOMIC_ACQUIRE);
     360    if (*v != 3)
     361      abort ();
     362  
     363    __atomic_fetch_add (v, 1, __ATOMIC_RELEASE);
     364    if (*v != 4)
     365      abort ();
     366  
     367    __atomic_add_fetch (v, count, __ATOMIC_ACQ_REL);
     368    if (*v != 5)
     369      abort ();
     370  
     371    __atomic_fetch_add (v, count, __ATOMIC_SEQ_CST);
     372    if (*v != 6)
     373      abort ();
     374  }
     375  
     376  
     377  void
     378  test_sub (char* v)
     379  {
     380    *v = res = 20;
     381    count = 0;
     382  
     383    __atomic_sub_fetch (v, count + 1, __ATOMIC_RELAXED);
     384    if (*v != --res)
     385      abort ();
     386  
     387    __atomic_fetch_sub (v, count + 1, __ATOMIC_CONSUME);
     388    if (*v != --res)
     389      abort ();
     390  
     391    __atomic_sub_fetch (v, 1, __ATOMIC_ACQUIRE);
     392    if (*v != --res)
     393      abort ();
     394  
     395    __atomic_fetch_sub (v, 1, __ATOMIC_RELEASE);
     396    if (*v != --res)
     397      abort ();
     398  
     399    __atomic_sub_fetch (v, count + 1, __ATOMIC_ACQ_REL);
     400    if (*v != --res)
     401      abort ();
     402  
     403    __atomic_fetch_sub (v, count + 1, __ATOMIC_SEQ_CST);
     404    if (*v != --res)
     405      abort ();
     406  }
     407  
     408  void
     409  test_and (char* v)
     410  {
     411    *v = init;
     412  
     413    __atomic_and_fetch (v, 0, __ATOMIC_RELAXED);
     414    if (*v != 0)
     415      abort ();
     416  
     417    *v = init;
     418    __atomic_fetch_and (v, init, __ATOMIC_CONSUME);
     419    if (*v != init)
     420      abort ();
     421  
     422    __atomic_and_fetch (v, 0, __ATOMIC_ACQUIRE);
     423    if (*v != 0)
     424      abort ();
     425  
     426    *v = ~*v;
     427    __atomic_fetch_and (v, init, __ATOMIC_RELEASE);
     428    if (*v != init)
     429      abort ();
     430  
     431    __atomic_and_fetch (v, 0, __ATOMIC_ACQ_REL);
     432    if (*v != 0)
     433      abort ();
     434  
     435    *v = ~*v;
     436    __atomic_fetch_and (v, 0, __ATOMIC_SEQ_CST);
     437    if (*v != 0)
     438      abort ();
     439  }
     440  
     441  void
     442  test_nand (char* v)
     443  {
     444    *v = init;
     445  
     446    __atomic_fetch_nand (v, 0, __ATOMIC_RELAXED);
     447    if (*v != init)
     448      abort ();
     449  
     450    __atomic_fetch_nand (v, init, __ATOMIC_CONSUME);
     451    if (*v != 0)
     452      abort ();
     453  
     454    __atomic_nand_fetch (v, 0, __ATOMIC_ACQUIRE);
     455    if (*v != init)
     456      abort ();
     457  
     458    __atomic_nand_fetch (v, init, __ATOMIC_RELEASE);
     459    if (*v != 0)
     460      abort ();
     461  
     462    __atomic_fetch_nand (v, init, __ATOMIC_ACQ_REL);
     463    if (*v != init)
     464      abort ();
     465  
     466    __atomic_nand_fetch (v, 0, __ATOMIC_SEQ_CST);
     467    if (*v != init)
     468      abort ();
     469  }
     470  
     471  
     472  
     473  void
     474  test_xor (char* v)
     475  {
     476    *v = init;
     477    count = 0;
     478  
     479    __atomic_xor_fetch (v, count, __ATOMIC_RELAXED);
     480    if (*v != init)
     481      abort ();
     482  
     483    __atomic_fetch_xor (v, ~count, __ATOMIC_CONSUME);
     484    if (*v != 0)
     485      abort ();
     486  
     487    __atomic_xor_fetch (v, 0, __ATOMIC_ACQUIRE);
     488    if (*v != 0)
     489      abort ();
     490  
     491    __atomic_fetch_xor (v, ~count, __ATOMIC_RELEASE);
     492    if (*v != init)
     493      abort ();
     494  
     495    __atomic_fetch_xor (v, 0, __ATOMIC_ACQ_REL);
     496    if (*v != init)
     497      abort ();
     498  
     499    __atomic_xor_fetch (v, ~count, __ATOMIC_SEQ_CST);
     500    if (*v != 0)
     501      abort ();
     502  }
     503  
     504  void
     505  test_or (char* v)
     506  {
     507    *v = 0;
     508    count = 1;
     509  
     510    __atomic_or_fetch (v, count, __ATOMIC_RELAXED);
     511    if (*v != 1)
     512      abort ();
     513  
     514    count *= 2;
     515    __atomic_fetch_or (v, count, __ATOMIC_CONSUME);
     516    if (*v != 3)
     517      abort ();
     518  
     519    count *= 2;
     520    __atomic_or_fetch (v, 4, __ATOMIC_ACQUIRE);
     521    if (*v != 7)
     522      abort ();
     523  
     524    count *= 2;
     525    __atomic_fetch_or (v, 8, __ATOMIC_RELEASE);
     526    if (*v != 15)
     527      abort ();
     528  
     529    count *= 2;
     530    __atomic_or_fetch (v, count, __ATOMIC_ACQ_REL);
     531    if (*v != 31)
     532      abort ();
     533  
     534    count *= 2;
     535    __atomic_fetch_or (v, count, __ATOMIC_SEQ_CST);
     536    if (*v != 63)
     537      abort ();
     538  }
     539  
     540  int
     541  main ()
     542  {
     543    char* V[] = {&A.a, &A.b, &A.c, &A.d};
     544  
     545    for (int i = 0; i < 4; i++) {
     546      test_fetch_add (V[i]);
     547      test_fetch_sub (V[i]);
     548      test_fetch_and (V[i]);
     549      test_fetch_nand (V[i]);
     550      test_fetch_xor (V[i]);
     551      test_fetch_or (V[i]);
     552  
     553      test_add_fetch (V[i]);
     554      test_sub_fetch (V[i]);
     555      test_and_fetch (V[i]);
     556      test_nand_fetch (V[i]);
     557      test_xor_fetch (V[i]);
     558      test_or_fetch (V[i]);
     559  
     560      test_add (V[i]);
     561      test_sub (V[i]);
     562      test_and (V[i]);
     563      test_nand (V[i]);
     564      test_xor (V[i]);
     565      test_or (V[i]);
     566    }
     567  
     568    return 0;
     569  }