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