rv64_atomic_widths_orders.c (2068B)
1 /* Atomic load/store/exchange across the 32- and 64-bit widths rv64 2 * implements directly via the A extension (lr.w/sc.w, lr.d/sc.d, 3 * amo*.w, amo*.d). Hits every memory order the rv64 lowering must 4 * accept: relaxed, acquire, release, acq_rel, seq_cst. Single-threaded 5 * shape — the goal is to validate the codegen path, not detect races. */ 6 7 static int i32_loc; 8 static long i64_loc; 9 10 int test_main(void) { 11 /* 32-bit relaxed store + acquire load. */ 12 __atomic_store_n(&i32_loc, 1, __ATOMIC_RELAXED); 13 if (__atomic_load_n(&i32_loc, __ATOMIC_ACQUIRE) != 1) return 1; 14 15 /* 32-bit release-store + relaxed-load. */ 16 __atomic_store_n(&i32_loc, 2, __ATOMIC_RELEASE); 17 if (__atomic_load_n(&i32_loc, __ATOMIC_RELAXED) != 2) return 2; 18 19 /* 32-bit exchange seq_cst. */ 20 int old = __atomic_exchange_n(&i32_loc, 7, __ATOMIC_SEQ_CST); 21 if (old != 2 || i32_loc != 7) return 3; 22 23 /* 32-bit fetch_add acq_rel. */ 24 old = __atomic_fetch_add(&i32_loc, 3, __ATOMIC_ACQ_REL); 25 if (old != 7 || i32_loc != 10) return 4; 26 27 /* 32-bit compare-exchange (weak then strong). */ 28 int expected = 10; 29 if (!__atomic_compare_exchange_n(&i32_loc, &expected, 99, 0 /*strong*/, 30 __ATOMIC_SEQ_CST, __ATOMIC_RELAXED)) 31 return 5; 32 if (i32_loc != 99 || expected != 10) return 6; 33 34 /* 64-bit lane, same shape. */ 35 __atomic_store_n(&i64_loc, 1L, __ATOMIC_RELAXED); 36 if (__atomic_load_n(&i64_loc, __ATOMIC_ACQUIRE) != 1L) return 7; 37 __atomic_store_n(&i64_loc, 2L, __ATOMIC_RELEASE); 38 if (__atomic_load_n(&i64_loc, __ATOMIC_RELAXED) != 2L) return 8; 39 long old64 = __atomic_exchange_n(&i64_loc, 0x100000000L, __ATOMIC_SEQ_CST); 40 if (old64 != 2L || i64_loc != 0x100000000L) return 9; 41 old64 = __atomic_fetch_add(&i64_loc, 5L, __ATOMIC_ACQ_REL); 42 if (old64 != 0x100000000L || i64_loc != 0x100000005L) return 10; 43 44 long expected64 = 0x100000005L; 45 if (!__atomic_compare_exchange_n(&i64_loc, &expected64, 0L, 0, 46 __ATOMIC_SEQ_CST, __ATOMIC_RELAXED)) 47 return 11; 48 if (i64_loc != 0L) return 12; 49 return 42; 50 }