cbe: fix msvc cmpxchg implementations

This commit is contained in:
kcbanner 2022-12-17 00:27:34 -05:00
parent 4f8f7b749c
commit 047fe58a53

View File

@ -196,7 +196,7 @@ typedef char bool;
#define memory_order_acq_rel 4
#define memory_order_seq_cst 5
#define zig_atomic(type) type
#define zig_cmpxchg_strong(obj, expected, desired, succ, fail, type) zig_expand_concat(zig_msvc_cmpxchg_, type)(obj, expected, desired)
#define zig_cmpxchg_strong(obj, expected, desired, succ, fail, type) zig_expand_concat(zig_msvc_cmpxchg_, type)(obj, &(expected), desired)
#define zig_cmpxchg_weak(obj, expected, desired, succ, fail, type) zig_cmpxchg_strong(obj, expected, desired, succ, fail, type)
#define zig_atomicrmw_xchg(obj, arg, order, type) zig_expand_concat(zig_msvc_atomicrmw_xchg_, type)(obj, arg)
#define zig_atomicrmw_add(obj, arg, order, type) zig_expand_concat(zig_msvc_atomicrmw_add_, type)(obj, arg)
@ -2096,12 +2096,18 @@ zig_float_builtins(c_longdouble)
#if _MSC_VER && (_M_IX86 || _M_X64)
#include <intrin.h>
// TODO: zig_msvc_atomic_load should load 32 bit without interlocked on x86, load 64 bit without interlocked on x64
// TODO: Fix obviously broken nand / min / max, these don't exist on msvc _InterlockedNand
// TODO: zig_msvc_atomic_load should just load 32 bit without interlocked on x86, and just load 64 bit without interlocked on x64
// TODO: Fix obviously broken nand / min / max, these don't exist on msvc
#define zig_msvc_atomics(type, suffix) \
static inline bool zig_msvc_cmpxchg_##type(zig_##type volatile* obj, zig_##type expected, zig_##type desired) { \
return _InterlockedCompareExchange##suffix(obj, desired, expected) == expected; \
static inline bool zig_msvc_cmpxchg_##type(zig_##type volatile* obj, zig_##type* expected, zig_##type desired) { \
zig_##type comparand = *expected; \
zig_##type initial = _InterlockedCompareExchange##suffix(obj, desired, comparand); \
bool exchanged = initial == comparand; \
if (!exchanged) { \
*expected = initial; \
} \
return exchanged; \
} \
static inline zig_##type zig_msvc_atomicrmw_xchg_##type(zig_##type volatile* obj, zig_##type value) { \
return _InterlockedExchange##suffix(obj, value); \
@ -2146,12 +2152,24 @@ zig_msvc_atomics(i32, )
zig_msvc_atomics(u64, 64)
zig_msvc_atomics(i64, 64)
static inline bool zig_msvc_cmpxchg_p32(void** obj, void* expected, void* desired) {
return _InterlockedCompareExchangePointer(obj, desired, expected) == expected;
static inline bool zig_msvc_cmpxchg_p32(void** obj, void** expected, void* desired) {
void* comparand = *expected;
void* initial = _InterlockedCompareExchangePointer(obj, desired, comparand);
bool exchanged = initial == comparand;
if (!exchanged) {
*expected = initial;
}
return exchanged;
}
static inline bool zig_msvc_cmpxchg_p64(void** obj, void* expected, void* desired) {
return _InterlockedCompareExchangePointer(obj, desired, expected) == expected;
static inline bool zig_msvc_cmpxchg_p64(void** obj, void** expected, void* desired) {
void* comparand = *expected;
void* initial = _InterlockedCompareExchangePointer(obj, desired, comparand);
bool exchanged = initial == comparand;
if (!exchanged) {
*expected = initial;
}
return exchanged;
}
#if _M_IX86
@ -2180,13 +2198,11 @@ static inline void* zig_msvc_atomic_load_p64(void** obj) {
}
#endif
static inline bool zig_msvc_cmpxchg_u128(zig_u128 volatile* obj, zig_u128 expected, zig_u128 desired) {
zig_u128 comparand_result = desired;
return _InterlockedCompareExchange128((zig_i64 volatile*)obj, expected.hi, expected.lo, (zig_i64*)&comparand_result);
static inline bool zig_msvc_cmpxchg_u128(zig_u128 volatile* obj, zig_u128* expected, zig_u128 desired) {
return _InterlockedCompareExchange128((zig_i64 volatile*)obj, desired.hi, desired.lo, (zig_i64*)expected);
}
static inline bool zig_msvc_cmpxchg_i128(zig_i128 volatile* obj, zig_i128 expected, zig_i128 desired) {
zig_i128 comparand_result = desired;
return _InterlockedCompareExchange128((zig_i64 volatile*)obj, expected.hi, expected.lo, (zig_u64*)&comparand_result);
static inline bool zig_msvc_cmpxchg_i128(zig_i128 volatile* obj, zig_i128* expected, zig_i128 desired) {
return _InterlockedCompareExchange128((zig_i64 volatile*)obj, desired.hi, desired.lo, (zig_u64*)expected);
}
#endif