1/* { dg-do link } */ 2/* { dg-require-effective-target sync_int_128_runtime } */ 3/* { dg-options "-mcx16" { target { x86_64-*-* i?86-*-* } } } */ 4/* { dg-final { simulate-thread } } */ 5 6#include <stdio.h> 7#include "simulate-thread.h" 8 9/* Test all the __sync routines for proper atomicity on 16 byte values. */ 10 11__int128_t zero = 0; 12__int128_t max = ~0; 13__int128_t changing_value = 0; 14__int128_t value = 0; 15__int128_t ret; 16 17void test_abort() 18{ 19 static int reported = 0; 20 if (!reported) 21 { 22 printf ("FAIL: improper execution of __sync builtin.\n"); 23 reported = 1; 24 } 25} 26 27void simulate_thread_other_threads () 28{ 29} 30 31int simulate_thread_step_verify () 32{ 33 if (value != zero && value != max) 34 { 35 printf ("FAIL: invalid intermediate result for value.\n"); 36 return 1; 37 } 38 return 0; 39} 40 41int simulate_thread_final_verify () 42{ 43 if (value != 0) 44 { 45 printf ("FAIL: invalid final result for value.\n"); 46 return 1; 47 } 48 return 0; 49} 50 51/* All values written to 'value' alternate between 'zero' and 'max'. Any other 52 value detected by simulate_thread_step_verify() between instructions would indicate 53 that the value was only partially written, and would thus fail this 54 atomicity test. 55 56 This function tests each different __atomic routine once, with the 57 exception of the load instruction which requires special testing. */ 58__attribute__((noinline)) 59void simulate_thread_main() 60{ 61 62 ret = __atomic_exchange_n (&value, max, __ATOMIC_SEQ_CST); 63 if (ret != zero || value != max) 64 test_abort(); 65 66 __atomic_store_n (&value, zero, __ATOMIC_SEQ_CST); 67 if (value != zero) 68 test_abort(); 69 70 ret = __atomic_fetch_add (&value, max, __ATOMIC_SEQ_CST); 71 if (value != max || ret != zero) 72 test_abort (); 73 74 ret = __atomic_fetch_sub (&value, max, __ATOMIC_SEQ_CST); 75 if (value != zero || ret != max) 76 test_abort (); 77 78 ret = __atomic_fetch_or (&value, max, __ATOMIC_SEQ_CST); 79 if (value != max || ret != zero) 80 test_abort (); 81 82 ret = __atomic_fetch_and (&value, max, __ATOMIC_SEQ_CST); 83 if (value != max || ret != max) 84 test_abort (); 85 86 ret = __atomic_fetch_xor (&value, max, __ATOMIC_SEQ_CST); 87 if (value != zero || ret != max) 88 test_abort (); 89 90 ret = __atomic_add_fetch (&value, max, __ATOMIC_SEQ_CST); 91 if (value != max || ret != max) 92 test_abort (); 93 94 ret = __atomic_sub_fetch (&value, max, __ATOMIC_SEQ_CST); 95 if (value != zero || ret != zero) 96 test_abort (); 97 98 ret = __atomic_or_fetch (&value, max, __ATOMIC_SEQ_CST); 99 if (value != max || ret != max) 100 test_abort (); 101 102 ret = __atomic_and_fetch (&value, max, __ATOMIC_SEQ_CST); 103 if (value != max || ret != max) 104 test_abort (); 105 106 ret = __atomic_xor_fetch (&value, max, __ATOMIC_SEQ_CST); 107 if (value != zero || ret != zero) 108 test_abort (); 109} 110 111int main() 112{ 113 simulate_thread_main (); 114 simulate_thread_done (); 115 return 0; 116} 117