diff --git a/lib/zig.h b/lib/zig.h index 53e7c81dda..8b0f59f344 100644 --- a/lib/zig.h +++ b/lib/zig.h @@ -2202,6 +2202,46 @@ zig_msvc_atomics(i32, ) zig_msvc_atomics(u64, 64) zig_msvc_atomics(i64, 64) +#define zig_msvc_flt_atomics(Type, ReprType, suffix) \ + static inline bool zig_msvc_cmpxchg_##Type(zig_##Type volatile* obj, zig_##Type* expected, zig_##Type desired) { \ + zig_##ReprType comparand = *((zig_##ReprType*)expected); \ + zig_##ReprType initial = _InterlockedCompareExchange##suffix((zig_##ReprType volatile*)obj, *((zig_##ReprType*)&desired), comparand); \ + bool exchanged = initial == comparand; \ + if (!exchanged) { \ + *expected = *((zig_##Type*)&initial); \ + } \ + return exchanged; \ + } \ + static inline zig_##Type zig_msvc_atomicrmw_xchg_##Type(zig_##Type volatile* obj, zig_##Type value) { \ + zig_##ReprType initial = _InterlockedExchange##suffix((zig_##ReprType volatile*)obj, *((zig_##ReprType*)&value)); \ + return *((zig_##Type*)&initial); \ + } \ + static inline zig_##Type zig_msvc_atomicrmw_add_##Type(zig_##Type volatile* obj, zig_##Type value) { \ + bool success = false; \ + zig_##ReprType new; \ + zig_##Type prev; \ + while (!success) { \ + prev = *obj; \ + new = prev + value; \ + success = zig_msvc_cmpxchg_##Type(obj, &prev, *((zig_##ReprType*)&new)); \ + } \ + return prev; \ + } \ + static inline zig_##Type zig_msvc_atomicrmw_sub_##Type(zig_##Type volatile* obj, zig_##Type value) { \ + bool success = false; \ + zig_##ReprType new; \ + zig_##Type prev; \ + while (!success) { \ + prev = *obj; \ + new = prev - value; \ + success = zig_msvc_cmpxchg_##Type(obj, &prev, *((zig_##ReprType*)&new)); \ + } \ + return prev; \ + } + +zig_msvc_flt_atomics(f32, u32, ) +zig_msvc_flt_atomics(f64, u64, 32) + #if _M_IX86 static inline void* zig_msvc_atomicrmw_xchg_p32(void** obj, zig_u32* arg) { return _InterlockedExchangePointer(obj, arg); diff --git a/test/behavior/atomics.zig b/test/behavior/atomics.zig index f6463ad80a..92ed027008 100644 --- a/test/behavior/atomics.zig +++ b/test/behavior/atomics.zig @@ -217,7 +217,6 @@ test "atomicrmw with floats" { if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO - if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO if ((builtin.zig_backend == .stage2_llvm or builtin.zig_backend == .stage2_c) and builtin.cpu.arch == .aarch64)