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