1  /* { dg-do compile { target { powerpc*-*-* && lp64 } } } */
       2  /* { dg-skip-if "" { powerpc*-*-darwin* } } */
       3  /* { dg-require-effective-target powerpc_p8vector_ok } */
       4  /* { dg-options "-mdejagnu-cpu=power8 -O2" } */
       5  /* { dg-final { scan-assembler-times "lbarx" 7 } } */
       6  /* { dg-final { scan-assembler-times "lharx" 7 } } */
       7  /* { dg-final { scan-assembler-times "lwarx" 7 } } */
       8  /* { dg-final { scan-assembler-times "ldarx" 7 } } */
       9  /* { dg-final { scan-assembler-times "lqarx" 7 } } */
      10  /* { dg-final { scan-assembler-times "stbcx" 7 } } */
      11  /* { dg-final { scan-assembler-times "sthcx" 7 } } */
      12  /* { dg-final { scan-assembler-times "stwcx" 7 } } */
      13  /* { dg-final { scan-assembler-times "stdcx" 7 } } */
      14  /* { dg-final { scan-assembler-times "stqcx" 7 } } */
      15  /* { dg-final { scan-assembler-not "bl __atomic" } } */
      16  /* As since PR59448 GCC promotes consume to acquire, the expected isync count
      17     is 25 rather than 20.  */
      18  /* { dg-final { scan-assembler-times "isync" 25 } } */
      19  /* { dg-final { scan-assembler-times "lwsync" 10 } } */
      20  /* { dg-final { scan-assembler-not "mtvsrd" } } */
      21  /* { dg-final { scan-assembler-not "mtvsrwa" } } */
      22  /* { dg-final { scan-assembler-not "mtvsrwz" } } */
      23  /* { dg-final { scan-assembler-not "mfvsrd" } } */
      24  /* { dg-final { scan-assembler-not "mfvsrwz" } } */
      25  
      26  /* Test for the byte atomic operations on power8 using lbarx/stbcx.  */
      27  char
      28  char_fetch_add_relaxed (char *ptr, int value)
      29  {
      30    return __atomic_fetch_add (ptr, value, __ATOMIC_RELAXED);
      31  }
      32  
      33  char
      34  char_fetch_sub_consume (char *ptr, int value)
      35  {
      36    return __atomic_fetch_sub (ptr, value, __ATOMIC_CONSUME);
      37  }
      38  
      39  char
      40  char_fetch_and_acquire (char *ptr, int value)
      41  {
      42    return __atomic_fetch_and (ptr, value, __ATOMIC_ACQUIRE);
      43  }
      44  
      45  char
      46  char_fetch_ior_release (char *ptr, int value)
      47  {
      48    return __atomic_fetch_or (ptr, value, __ATOMIC_RELEASE);
      49  }
      50  
      51  char
      52  char_fetch_xor_acq_rel (char *ptr, int value)
      53  {
      54    return __atomic_fetch_xor (ptr, value, __ATOMIC_ACQ_REL);
      55  }
      56  
      57  char
      58  char_fetch_nand_seq_cst (char *ptr, int value)
      59  {
      60    return __atomic_fetch_nand (ptr, value, __ATOMIC_SEQ_CST);
      61  }
      62  
      63  void
      64  char_val_compare_and_swap (char *p, int i, int j, char *q)
      65  {
      66    *q = __sync_val_compare_and_swap (p, i, j);
      67  }
      68  
      69  /* Test for the half word atomic operations on power8 using lharx/sthcx.  */
      70  short
      71  short_fetch_add_relaxed (short *ptr, int value)
      72  {
      73    return __atomic_fetch_add (ptr, value, __ATOMIC_RELAXED);
      74  }
      75  
      76  short
      77  short_fetch_sub_consume (short *ptr, int value)
      78  {
      79    return __atomic_fetch_sub (ptr, value, __ATOMIC_CONSUME);
      80  }
      81  
      82  short
      83  short_fetch_and_acquire (short *ptr, int value)
      84  {
      85    return __atomic_fetch_and (ptr, value, __ATOMIC_ACQUIRE);
      86  }
      87  
      88  short
      89  short_fetch_ior_release (short *ptr, int value)
      90  {
      91    return __atomic_fetch_or (ptr, value, __ATOMIC_RELEASE);
      92  }
      93  
      94  short
      95  short_fetch_xor_acq_rel (short *ptr, int value)
      96  {
      97    return __atomic_fetch_xor (ptr, value, __ATOMIC_ACQ_REL);
      98  }
      99  
     100  short
     101  short_fetch_nand_seq_cst (short *ptr, int value)
     102  {
     103    return __atomic_fetch_nand (ptr, value, __ATOMIC_SEQ_CST);
     104  }
     105  
     106  void
     107  short_val_compare_and_swap (short *p, int i, int j, short *q)
     108  {
     109    *q = __sync_val_compare_and_swap (p, i, j);
     110  }
     111  
     112  /* Test for the word atomic operations on power8 using lwarx/stwcx.  */
     113  int
     114  int_fetch_add_relaxed (int *ptr, int value)
     115  {
     116    return __atomic_fetch_add (ptr, value, __ATOMIC_RELAXED);
     117  }
     118  
     119  int
     120  int_fetch_sub_consume (int *ptr, int value)
     121  {
     122    return __atomic_fetch_sub (ptr, value, __ATOMIC_CONSUME);
     123  }
     124  
     125  int
     126  int_fetch_and_acquire (int *ptr, int value)
     127  {
     128    return __atomic_fetch_and (ptr, value, __ATOMIC_ACQUIRE);
     129  }
     130  
     131  int
     132  int_fetch_ior_release (int *ptr, int value)
     133  {
     134    return __atomic_fetch_or (ptr, value, __ATOMIC_RELEASE);
     135  }
     136  
     137  int
     138  int_fetch_xor_acq_rel (int *ptr, int value)
     139  {
     140    return __atomic_fetch_xor (ptr, value, __ATOMIC_ACQ_REL);
     141  }
     142  
     143  int
     144  int_fetch_nand_seq_cst (int *ptr, int value)
     145  {
     146    return __atomic_fetch_nand (ptr, value, __ATOMIC_SEQ_CST);
     147  }
     148  
     149  void
     150  int_val_compare_and_swap (int *p, int i, int j, int *q)
     151  {
     152    *q = __sync_val_compare_and_swap (p, i, j);
     153  }
     154  
     155  /* Test for the double word atomic operations on power8 using ldarx/stdcx.  */
     156  long
     157  long_fetch_add_relaxed (long *ptr, long value)
     158  {
     159    return __atomic_fetch_add (ptr, value, __ATOMIC_RELAXED);
     160  }
     161  
     162  long
     163  long_fetch_sub_consume (long *ptr, long value)
     164  {
     165    return __atomic_fetch_sub (ptr, value, __ATOMIC_CONSUME);
     166  }
     167  
     168  long
     169  long_fetch_and_acquire (long *ptr, long value)
     170  {
     171    return __atomic_fetch_and (ptr, value, __ATOMIC_ACQUIRE);
     172  }
     173  
     174  long
     175  long_fetch_ior_release (long *ptr, long value)
     176  {
     177    return __atomic_fetch_or (ptr, value, __ATOMIC_RELEASE);
     178  }
     179  
     180  long
     181  long_fetch_xor_acq_rel (long *ptr, long value)
     182  {
     183    return __atomic_fetch_xor (ptr, value, __ATOMIC_ACQ_REL);
     184  }
     185  
     186  long
     187  long_fetch_nand_seq_cst (long *ptr, long value)
     188  {
     189    return __atomic_fetch_nand (ptr, value, __ATOMIC_SEQ_CST);
     190  }
     191  
     192  void
     193  long_val_compare_and_swap (long *p, long i, long j, long *q)
     194  {
     195    *q = __sync_val_compare_and_swap (p, i, j);
     196  }
     197  
     198  /* Test for the quad word atomic operations on power8 using ldarx/stdcx.  */
     199  __int128_t
     200  quad_fetch_add_relaxed (__int128_t *ptr, __int128_t value)
     201  {
     202    return __atomic_fetch_add (ptr, value, __ATOMIC_RELAXED);
     203  }
     204  
     205  __int128_t
     206  quad_fetch_sub_consume (__int128_t *ptr, __int128_t value)
     207  {
     208    return __atomic_fetch_sub (ptr, value, __ATOMIC_CONSUME);
     209  }
     210  
     211  __int128_t
     212  quad_fetch_and_acquire (__int128_t *ptr, __int128_t value)
     213  {
     214    return __atomic_fetch_and (ptr, value, __ATOMIC_ACQUIRE);
     215  }
     216  
     217  __int128_t
     218  quad_fetch_ior_release (__int128_t *ptr, __int128_t value)
     219  {
     220    return __atomic_fetch_or (ptr, value, __ATOMIC_RELEASE);
     221  }
     222  
     223  __int128_t
     224  quad_fetch_xor_acq_rel (__int128_t *ptr, __int128_t value)
     225  {
     226    return __atomic_fetch_xor (ptr, value, __ATOMIC_ACQ_REL);
     227  }
     228  
     229  __int128_t
     230  quad_fetch_nand_seq_cst (__int128_t *ptr, __int128_t value)
     231  {
     232    return __atomic_fetch_nand (ptr, value, __ATOMIC_SEQ_CST);
     233  }
     234  
     235  void
     236  quad_val_compare_and_swap (__int128_t *p, __int128_t i, __int128_t j, __int128_t *q)
     237  {
     238    *q = __sync_val_compare_and_swap (p, i, j);
     239  }