authorgravatar for kcbanner@gmail.comCasey Banner <kcbanner@gmail.com> 2022-12-16 02:01:07-05:00
committergravatar for kcbanner@gmail.comCasey Banner <kcbanner@gmail.com> 2023-01-01 16:44:28-05:00
log2d34477dbb895b7a37284b50ebc1feb23ef77a64
tree275c35872d56df2c5f8c4c8f6d4923ffd97e84c5
parentf155ef2f4b3243fd31ae910c66587d672402144e

cbe: msvc atomics

- Implement most atomic operations for msvc - Disable "atomicrmw with floats" test for cbe

3 files changed, 195 insertions(+), 46 deletions(-)

lib/zig.h+176-42
...@@ -146,22 +146,25 @@ typedef char bool;...@@ -146,22 +146,25 @@ typedef char bool;
146#define zig_wasm_memory_grow(index, delta) zig_unimplemented()146#define zig_wasm_memory_grow(index, delta) zig_unimplemented()
147#endif147#endif
148148
149#define zig_concat(lhs, rhs) lhs##rhs
150#define zig_expand_concat(lhs, rhs) zig_concat(lhs, rhs)
151
149#if __STDC_VERSION__ >= 201112L && !defined(__STDC_NO_ATOMICS__)152#if __STDC_VERSION__ >= 201112L && !defined(__STDC_NO_ATOMICS__)
150#include <stdatomic.h>153#include <stdatomic.h>
151#define zig_atomic(type) _Atomic(type)154#define zig_atomic(type) _Atomic(type)
152#define zig_cmpxchg_strong(obj, expected, desired, succ, fail) atomic_compare_exchange_strong_explicit(obj, &(expected), desired, succ, fail)155#define zig_cmpxchg_strong(obj, expected, desired, succ, fail, type) atomic_compare_exchange_strong_explicit(obj, &(expected), desired, succ, fail)
153#define zig_cmpxchg_weak(obj, expected, desired, succ, fail) atomic_compare_exchange_weak_explicit (obj, &(expected), desired, succ, fail)156#define zig_cmpxchg_weak(obj, expected, desired, succ, fail, type) atomic_compare_exchange_weak_explicit (obj, &(expected), desired, succ, fail)
154#define zig_atomicrmw_xchg(obj, arg, order) atomic_exchange_explicit (obj, arg, order)157#define zig_atomicrmw_xchg(obj, arg, order, type) atomic_exchange_explicit (obj, arg, order)
155#define zig_atomicrmw_add(obj, arg, order) atomic_fetch_add_explicit (obj, arg, order)158#define zig_atomicrmw_add(obj, arg, order, type) atomic_fetch_add_explicit (obj, arg, order)
156#define zig_atomicrmw_sub(obj, arg, order) atomic_fetch_sub_explicit (obj, arg, order)159#define zig_atomicrmw_sub(obj, arg, order, type) atomic_fetch_sub_explicit (obj, arg, order)
157#define zig_atomicrmw_or(obj, arg, order) atomic_fetch_or_explicit (obj, arg, order)160#define zig_atomicrmw_or(obj, arg, order, type) atomic_fetch_or_explicit (obj, arg, order)
158#define zig_atomicrmw_xor(obj, arg, order) atomic_fetch_xor_explicit (obj, arg, order)161#define zig_atomicrmw_xor(obj, arg, order, type) atomic_fetch_xor_explicit (obj, arg, order)
159#define zig_atomicrmw_and(obj, arg, order) atomic_fetch_and_explicit (obj, arg, order)162#define zig_atomicrmw_and(obj, arg, order, type) atomic_fetch_and_explicit (obj, arg, order)
160#define zig_atomicrmw_nand(obj, arg, order) __atomic_fetch_nand (obj, arg, order)163#define zig_atomicrmw_nand(obj, arg, order, type) __atomic_fetch_nand (obj, arg, order)
161#define zig_atomicrmw_min(obj, arg, order) __atomic_fetch_min (obj, arg, order)164#define zig_atomicrmw_min(obj, arg, order, type) __atomic_fetch_min (obj, arg, order)
162#define zig_atomicrmw_max(obj, arg, order) __atomic_fetch_max (obj, arg, order)165#define zig_atomicrmw_max(obj, arg, order, type) __atomic_fetch_max (obj, arg, order)
163#define zig_atomic_store(obj, arg, order) atomic_store_explicit (obj, arg, order)166#define zig_atomic_store(obj, arg, order, type) atomic_store_explicit (obj, arg, order)
164#define zig_atomic_load(obj, order) atomic_load_explicit (obj, order)167#define zig_atomic_load(obj, order, type) atomic_load_explicit (obj, order)
165#define zig_fence(order) atomic_thread_fence(order)168#define zig_fence(order) atomic_thread_fence(order)
166#elif defined(__GNUC__)169#elif defined(__GNUC__)
167#define memory_order_relaxed __ATOMIC_RELAXED170#define memory_order_relaxed __ATOMIC_RELAXED
...@@ -171,20 +174,44 @@ typedef char bool;...@@ -171,20 +174,44 @@ typedef char bool;
171#define memory_order_acq_rel __ATOMIC_ACQ_REL174#define memory_order_acq_rel __ATOMIC_ACQ_REL
172#define memory_order_seq_cst __ATOMIC_SEQ_CST175#define memory_order_seq_cst __ATOMIC_SEQ_CST
173#define zig_atomic(type) type176#define zig_atomic(type) type
174#define zig_cmpxchg_strong(obj, expected, desired, succ, fail) __atomic_compare_exchange_n(obj, &(expected), desired, false, succ, fail)177#define zig_cmpxchg_strong(obj, expected, desired, succ, fail, types) __atomic_compare_exchange_n(obj, &(expected), desired, false, succ, fail)
175#define zig_cmpxchg_weak(obj, expected, desired, succ, fail) __atomic_compare_exchange_n(obj, &(expected), desired, true , succ, fail)178#define zig_cmpxchg_weak(obj, expected, desired, succ, fail, types) __atomic_compare_exchange_n(obj, &(expected), desired, true , succ, fail)
176#define zig_atomicrmw_xchg(obj, arg, order) __atomic_exchange_n(obj, arg, order)179#define zig_atomicrmw_xchg(obj, arg, order, type) __atomic_exchange_n(obj, arg, order)
177#define zig_atomicrmw_add(obj, arg, order) __atomic_fetch_add (obj, arg, order)180#define zig_atomicrmw_add(obj, arg, order, type) __atomic_fetch_add (obj, arg, order)
178#define zig_atomicrmw_sub(obj, arg, order) __atomic_fetch_sub (obj, arg, order)181#define zig_atomicrmw_sub(obj, arg, order, type) __atomic_fetch_sub (obj, arg, order)
179#define zig_atomicrmw_or(obj, arg, order) __atomic_fetch_or (obj, arg, order)182#define zig_atomicrmw_or(obj, arg, order, type) __atomic_fetch_or (obj, arg, order)
180#define zig_atomicrmw_xor(obj, arg, order) __atomic_fetch_xor (obj, arg, order)183#define zig_atomicrmw_xor(obj, arg, order, type) __atomic_fetch_xor (obj, arg, order)
181#define zig_atomicrmw_and(obj, arg, order) __atomic_fetch_and (obj, arg, order)184#define zig_atomicrmw_and(obj, arg, order, type) __atomic_fetch_and (obj, arg, order)
182#define zig_atomicrmw_nand(obj, arg, order) __atomic_fetch_nand(obj, arg, order)185#define zig_atomicrmw_nand(obj, arg, order, type) __atomic_fetch_nand(obj, arg, order)
183#define zig_atomicrmw_min(obj, arg, order) __atomic_fetch_min (obj, arg, order)186#define zig_atomicrmw_min(obj, arg, order, type) __atomic_fetch_min (obj, arg, order)
184#define zig_atomicrmw_max(obj, arg, order) __atomic_fetch_max (obj, arg, order)187#define zig_atomicrmw_max(obj, arg, order, type) __atomic_fetch_max (obj, arg, order)
185#define zig_atomic_store(obj, arg, order) __atomic_store_n (obj, arg, order)188#define zig_atomic_store(obj, arg, order, type) __atomic_store_n (obj, arg, order)
186#define zig_atomic_load(obj, order) __atomic_load_n (obj, order)189#define zig_atomic_load(obj, order, type) __atomic_load_n (obj, order)
187#define zig_fence(order) __atomic_thread_fence(order)190#define zig_fence(order) __atomic_thread_fence(order)
191#elif _MSC_VER && (_M_IX86 || _M_X64)
192#include <intrin.h>
193#define memory_order_relaxed 0
194#define memory_order_consume 1
195#define memory_order_acquire 2
196#define memory_order_release 3
197#define memory_order_acq_rel 4
198#define memory_order_seq_cst 5
199#define zig_atomic(type) type
200#define zig_cmpxchg_strong(obj, expected, desired, succ, fail, type) zig_expand_concat(zig_msvc_cmpxchg_, type)(obj, expected, desired)
201#define zig_cmpxchg_weak(obj, expected, desired, succ, fail, type) zig_cmpxchg_strong(obj, expected, desired, succ, fail, type)
202#define zig_atomicrmw_xchg(obj, arg, order, type) zig_expand_concat(zig_msvc_atomicrmw_xchg_, type)(obj, arg)
203#define zig_atomicrmw_add(obj, arg, order, type) zig_expand_concat(zig_msvc_atomicrmw_add_, type)(obj, arg)
204#define zig_atomicrmw_sub(obj, arg, order, type) zig_expand_concat(zig_msvc_atomicrmw_sub_, type)(obj, arg)
205#define zig_atomicrmw_or(obj, arg, order, type) zig_expand_concat(zig_msvc_atomicrmw_or_, type)(obj, arg)
206#define zig_atomicrmw_xor(obj, arg, order, type) zig_expand_concat(zig_msvc_atomicrmw_xor_, type)(obj, arg)
207#define zig_atomicrmw_and(obj, arg, order, type) zig_expand_concat(zig_msvc_atomicrmw_and_, type)(obj, arg)
208#define zig_atomicrmw_nand(obj, arg, order, type) zig_expand_concat(zig_msvc_atomicrmw_nand_, type)(obj, arg)
209#define zig_atomicrmw_min(obj, arg, order, type) zig_expand_concat(zig_msvc_atomicrmw_min_, type)(obj, arg)
210#define zig_atomicrmw_max(obj, arg, order, type) zig_expand_concat(zig_msvc_atomicrmw_max_, type)(obj, arg)
211#define zig_atomic_store(obj, arg, order, type) zig_expand_concat(zig_msvc_atomic_store_, type)(obj, arg)
212#define zig_atomic_load(obj, order, type) zig_expand_concat(zig_msvc_atomic_load_, type)(obj)
213#define zig_fence(order) __faststorefence()
214// TODO: _MSC_VER && (_M_ARM || _M_ARM64)
188#else215#else
189#define memory_order_relaxed 0216#define memory_order_relaxed 0
190#define memory_order_consume 1217#define memory_order_consume 1
...@@ -193,19 +220,19 @@ typedef char bool;...@@ -193,19 +220,19 @@ typedef char bool;
193#define memory_order_acq_rel 4220#define memory_order_acq_rel 4
194#define memory_order_seq_cst 5221#define memory_order_seq_cst 5
195#define zig_atomic(type) type222#define zig_atomic(type) type
196#define zig_cmpxchg_strong(obj, expected, desired, succ, fail) zig_unimplemented()223#define zig_cmpxchg_strong(obj, expected, desired, succ, fail, type) zig_unimplemented()
197#define zig_cmpxchg_weak(obj, expected, desired, succ, fail) zig_unimplemented()224#define zig_cmpxchg_weak(obj, expected, desired, succ, fail, type) zig_unimplemented()
198#define zig_atomicrmw_xchg(obj, arg, order) zig_unimplemented()225#define zig_atomicrmw_xchg(obj, arg, order, type) zig_unimplemented()
199#define zig_atomicrmw_add(obj, arg, order) zig_unimplemented()226#define zig_atomicrmw_add(obj, arg, order, type) zig_unimplemented()
200#define zig_atomicrmw_sub(obj, arg, order) zig_unimplemented()227#define zig_atomicrmw_sub(obj, arg, order, type) zig_unimplemented()
201#define zig_atomicrmw_or(obj, arg, order) zig_unimplemented()228#define zig_atomicrmw_or(obj, arg, order, type) zig_unimplemented()
202#define zig_atomicrmw_xor(obj, arg, order) zig_unimplemented()229#define zig_atomicrmw_xor(obj, arg, order, type) zig_unimplemented()
203#define zig_atomicrmw_and(obj, arg, order) zig_unimplemented()230#define zig_atomicrmw_and(obj, arg, order, type) zig_unimplemented()
204#define zig_atomicrmw_nand(obj, arg, order) zig_unimplemented()231#define zig_atomicrmw_nand(obj, arg, order, type) zig_unimplemented()
205#define zig_atomicrmw_min(obj, arg, order) zig_unimplemented()232#define zig_atomicrmw_min(obj, arg, order, type) zig_unimplemented()
206#define zig_atomicrmw_max(obj, arg, order) zig_unimplemented()233#define zig_atomicrmw_max(obj, arg, order, type) zig_unimplemented()
207#define zig_atomic_store(obj, arg, order) zig_unimplemented()234#define zig_atomic_store(obj, arg, order, type) zig_unimplemented()
208#define zig_atomic_load(obj, order) zig_unimplemented()235#define zig_atomic_load(obj, order, type) zig_unimplemented()
209#define zig_fence(order) zig_unimplemented()236#define zig_fence(order) zig_unimplemented()
210#endif237#endif
211238
...@@ -219,9 +246,6 @@ typedef char bool;...@@ -219,9 +246,6 @@ typedef char bool;
219#define zig_noreturn void246#define zig_noreturn void
220#endif247#endif
221248
222#define zig_concat(lhs, rhs) lhs##rhs
223#define zig_expand_concat(lhs, rhs) zig_concat(lhs, rhs)
224
225#define zig_bitSizeOf(T) (CHAR_BIT * sizeof(T))249#define zig_bitSizeOf(T) (CHAR_BIT * sizeof(T))
226250
227typedef uintptr_t zig_usize;251typedef uintptr_t zig_usize;
...@@ -1917,6 +1941,18 @@ typedef zig_i128 zig_c_longdouble;...@@ -1917,6 +1941,18 @@ typedef zig_i128 zig_c_longdouble;
1917#define zig_as_special_constant_c_longdouble(sign, name, arg, repr) repr1941#define zig_as_special_constant_c_longdouble(sign, name, arg, repr) repr
1918#endif1942#endif
19191943
1944#if zig_bitSizeOf_c_longdouble == 16
1945#define zig_compiler_rt_abbrev_c_longdouble zig_compiler_rt_abbrev_f16
1946#elif zig_bitSizeOf_c_longdouble == 32
1947#define zig_compiler_rt_abbrev_c_longdouble zig_compiler_rt_abbrev_f32
1948#elif zig_bitSizeOf_c_longdouble == 64
1949#define zig_compiler_rt_abbrev_c_longdouble zig_compiler_rt_abbrev_f64
1950#elif zig_bitSizeOf_c_longdouble == 80
1951#define zig_compiler_rt_abbrev_c_longdouble zig_compiler_rt_abbrev_f80
1952#elif zig_bitSizeOf_c_longdouble == 128
1953#define zig_compiler_rt_abbrev_c_longdouble zig_compiler_rt_abbrev_f128
1954#endif
1955
1920#define zig_cast_f16 (zig_f16)1956#define zig_cast_f16 (zig_f16)
1921#define zig_cast_f32 (zig_f32)1957#define zig_cast_f32 (zig_f32)
1922#define zig_cast_f64 (zig_f64)1958#define zig_cast_f64 (zig_f64)
...@@ -2054,3 +2090,101 @@ zig_float_builtins(f64)...@@ -2054,3 +2090,101 @@ zig_float_builtins(f64)
2054zig_float_builtins(f80)2090zig_float_builtins(f80)
2055zig_float_builtins(f128)2091zig_float_builtins(f128)
2056zig_float_builtins(c_longdouble)2092zig_float_builtins(c_longdouble)
2093
2094#if _MSC_VER && (_M_IX86 || _M_X64)
2095#include <intrin.h>
2096
2097// TODO: zig_msvc_atomic_load should load 32 bit without interlocked on x86, load 64 bit without interlocked on x64
2098// TODO: Fix obviously broken nand / min / max, these don't exist on msvc _InterlockedNand
2099
2100#define zig_msvc_atomics(type, suffix) \
2101 static inline bool zig_msvc_cmpxchg_##type(zig_##type volatile* obj, zig_##type expected, zig_##type desired) { \
2102 return _InterlockedCompareExchange##suffix(obj, desired, expected) == expected; \
2103 } \
2104 static inline zig_##type zig_msvc_atomicrmw_xchg_##type(zig_##type volatile* obj, zig_##type value) { \
2105 return _InterlockedExchange##suffix(obj, value); \
2106 } \
2107 static inline zig_##type zig_msvc_atomicrmw_add_##type(zig_##type volatile* obj, zig_##type value) { \
2108 return _InterlockedExchangeAdd##suffix(obj, value); \
2109 } \
2110 static inline zig_##type zig_msvc_atomicrmw_sub_##type(zig_##type volatile* obj, zig_##type value) { \
2111 return _InterlockedExchangeAdd##suffix(obj, -value); \
2112 } \
2113 static inline zig_##type zig_msvc_atomicrmw_or_##type(zig_##type volatile* obj, zig_##type value) { \
2114 return _InterlockedOr##suffix(obj, value); \
2115 } \
2116 static inline zig_##type zig_msvc_atomicrmw_xor_##type(zig_##type volatile* obj, zig_##type value) { \
2117 return _InterlockedXor##suffix(obj, value); \
2118 } \
2119 static inline zig_##type zig_msvc_atomicrmw_and_##type(zig_##type volatile* obj, zig_##type value) { \
2120 return _InterlockedAnd##suffix(obj, value); \
2121 } \
2122 static inline zig_##type zig_msvc_atomicrmw_nand_##type(zig_##type volatile* obj, zig_##type value) { \
2123 return 0; \
2124 } \
2125 static inline zig_##type zig_msvc_atomicrmw_min_##type(zig_##type volatile* obj, zig_##type value) { \
2126 return 0; \
2127 } \
2128 static inline zig_##type zig_msvc_atomicrmw_max_##type(zig_##type volatile* obj, zig_##type value) { \
2129 return 0; \
2130 } \
2131 static inline void zig_msvc_atomic_store_##type(zig_##type volatile* obj, zig_##type value) { \
2132 _InterlockedExchange##suffix(obj, value); \
2133 } \
2134 static inline zig_##type zig_msvc_atomic_load_##type(zig_##type volatile* obj) { \
2135 return _InterlockedOr##suffix(obj, 0); \
2136 }
2137
2138zig_msvc_atomics(u8, 8)
2139zig_msvc_atomics(i8, 8)
2140zig_msvc_atomics(u16, 16)
2141zig_msvc_atomics(i16, 16)
2142zig_msvc_atomics(u32, )
2143zig_msvc_atomics(i32, )
2144zig_msvc_atomics(u64, 64)
2145zig_msvc_atomics(i64, 64)
2146
2147static inline bool zig_msvc_cmpxchg_p32(void** obj, void* expected, void* desired) {
2148 return _InterlockedCompareExchangePointer(obj, desired, expected) == expected;
2149}
2150
2151static inline bool zig_msvc_cmpxchg_p64(void** obj, void* expected, void* desired) {
2152 return _InterlockedCompareExchangePointer(obj, desired, expected) == expected;
2153}
2154
2155#if _M_IX86
2156static inline void* zig_msvc_atomicrmw_xchg_p32(void** obj, zig_u32* arg) {
2157 return _InterlockedExchangePointer(obj, arg);
2158}
2159
2160static inline void zig_msvc_atomic_store_p32(void** obj, zig_u32* arg) {
2161 _InterlockedExchangePointer(obj, arg);
2162}
2163
2164static inline void* zig_msvc_atomic_load_p32(void** obj, zig_u32* arg) {
2165 return (void*)_InterlockedOr((void*)obj, 0);
2166}
2167#else
2168static inline void* zig_msvc_atomicrmw_xchg__p64(void** obj, zig_u64* arg) {
2169 return _InterlockedExchangePointer(obj, arg);
2170}
2171
2172static inline void zig_msvc_atomic_store_p64(void** obj, zig_u64* arg) {
2173 _InterlockedExchangePointer(obj, arg);
2174}
2175
2176static inline void* zig_msvc_atomic_load_p64(void** obj) {
2177 return (void*)_InterlockedOr64((void*)obj, 0);
2178}
2179#endif
2180
2181static inline bool zig_msvc_cmpxchg_u128(zig_u128 volatile* obj, zig_u128 expected, zig_u128 desired) {
2182 zig_u128 comparand_result = desired;
2183 return _InterlockedCompareExchange128((zig_i64 volatile*)obj, expected.hi, expected.lo, (zig_i64*)&comparand_result);
2184}
2185
2186static inline bool zig_msvc_cmpxchg_i128(zig_i128 volatile* obj, zig_i128 expected, zig_i128 desired) {
2187 zig_i128 comparand_result = desired;
2188 return _InterlockedCompareExchange128((zig_i64 volatile*)obj, expected.hi, expected.lo, (zig_u64*)&comparand_result);
2189}
2190#endif
src/codegen/c.zig+18-4
...@@ -2542,6 +2542,10 @@ pub const DeclGen = struct {...@@ -2542,6 +2542,10 @@ pub const DeclGen = struct {
2542 try writer.print("{c}{d}", .{ signAbbrev(int_info.signedness), c_bits });2542 try writer.print("{c}{d}", .{ signAbbrev(int_info.signedness), c_bits });
2543 } else if (ty.isRuntimeFloat()) {2543 } else if (ty.isRuntimeFloat()) {
2544 try ty.print(writer, dg.module);2544 try ty.print(writer, dg.module);
2545 } else if (ty.isPtrAtRuntime()) {
2546 try writer.print("p{d}", .{ ty.bitSize(target) });
2547 } else if (ty.zigTypeTag() == .Bool) {
2548 try writer.print("u8", .{});
2545 } else return dg.fail("TODO: CBE: implement renderTypeForBuiltinFnName for type {}", .{2549 } else return dg.fail("TODO: CBE: implement renderTypeForBuiltinFnName for type {}", .{
2546 ty.fmt(dg.module),2550 ty.fmt(dg.module),
2547 });2551 });
...@@ -6083,7 +6087,7 @@ fn airCmpxchg(f: *Function, inst: Air.Inst.Index, flavor: [*:0]const u8) !CValue...@@ -6083,7 +6087,7 @@ fn airCmpxchg(f: *Function, inst: Air.Inst.Index, flavor: [*:0]const u8) !CValue
6083 try writer.writeAll(";\n");6087 try writer.writeAll(";\n");
6084 try writer.writeAll("if (");6088 try writer.writeAll("if (");
6085 try writer.print("zig_cmpxchg_{s}((zig_atomic(", .{flavor});6089 try writer.print("zig_cmpxchg_{s}((zig_atomic(", .{flavor});
6086 try f.renderTypecast(writer, ptr_ty.elemType());6090 try f.renderTypecast(writer, ptr_ty.childType());
6087 try writer.writeByte(')');6091 try writer.writeByte(')');
6088 if (ptr_ty.isVolatilePtr()) try writer.writeAll(" volatile");6092 if (ptr_ty.isVolatilePtr()) try writer.writeAll(" volatile");
6089 try writer.writeAll(" *)");6093 try writer.writeAll(" *)");
...@@ -6096,6 +6100,8 @@ fn airCmpxchg(f: *Function, inst: Air.Inst.Index, flavor: [*:0]const u8) !CValue...@@ -6096,6 +6100,8 @@ fn airCmpxchg(f: *Function, inst: Air.Inst.Index, flavor: [*:0]const u8) !CValue
6096 try writeMemoryOrder(writer, extra.successOrder());6100 try writeMemoryOrder(writer, extra.successOrder());
6097 try writer.writeAll(", ");6101 try writer.writeAll(", ");
6098 try writeMemoryOrder(writer, extra.failureOrder());6102 try writeMemoryOrder(writer, extra.failureOrder());
6103 try writer.writeAll(", ");
6104 try f.object.dg.renderTypeForBuiltinFnName(writer, ptr_ty.childType());
6099 try writer.writeByte(')');6105 try writer.writeByte(')');
6100 try writer.writeAll(") {\n");6106 try writer.writeAll(") {\n");
6101 f.object.indent_writer.pushIndent();6107 f.object.indent_writer.pushIndent();
...@@ -6110,7 +6116,7 @@ fn airCmpxchg(f: *Function, inst: Air.Inst.Index, flavor: [*:0]const u8) !CValue...@@ -6110,7 +6116,7 @@ fn airCmpxchg(f: *Function, inst: Air.Inst.Index, flavor: [*:0]const u8) !CValue
6110 try writer.writeAll(";\n");6116 try writer.writeAll(";\n");
6111 try f.writeCValue(writer, local, .Other);6117 try f.writeCValue(writer, local, .Other);
6112 try writer.print(".is_null = zig_cmpxchg_{s}((zig_atomic(", .{flavor});6118 try writer.print(".is_null = zig_cmpxchg_{s}((zig_atomic(", .{flavor});
6113 try f.renderTypecast(writer, ptr_ty.elemType());6119 try f.renderTypecast(writer, ptr_ty.childType());
6114 try writer.writeByte(')');6120 try writer.writeByte(')');
6115 if (ptr_ty.isVolatilePtr()) try writer.writeAll(" volatile");6121 if (ptr_ty.isVolatilePtr()) try writer.writeAll(" volatile");
6116 try writer.writeAll(" *)");6122 try writer.writeAll(" *)");
...@@ -6123,6 +6129,8 @@ fn airCmpxchg(f: *Function, inst: Air.Inst.Index, flavor: [*:0]const u8) !CValue...@@ -6123,6 +6129,8 @@ fn airCmpxchg(f: *Function, inst: Air.Inst.Index, flavor: [*:0]const u8) !CValue
6123 try writeMemoryOrder(writer, extra.successOrder());6129 try writeMemoryOrder(writer, extra.successOrder());
6124 try writer.writeAll(", ");6130 try writer.writeAll(", ");
6125 try writeMemoryOrder(writer, extra.failureOrder());6131 try writeMemoryOrder(writer, extra.failureOrder());
6132 try writer.writeAll(", ");
6133 try f.object.dg.renderTypeForBuiltinFnName(writer, ptr_ty.childType());
6126 try writer.writeByte(')');6134 try writer.writeByte(')');
6127 try writer.writeAll(";\n");6135 try writer.writeAll(";\n");
6128 }6136 }
...@@ -6145,8 +6153,8 @@ fn airAtomicRmw(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -6145,8 +6153,8 @@ fn airAtomicRmw(f: *Function, inst: Air.Inst.Index) !CValue {
6145 try reap(f, inst, &.{ pl_op.operand, extra.operand });6153 try reap(f, inst, &.{ pl_op.operand, extra.operand });
6146 const writer = f.object.writer();6154 const writer = f.object.writer();
6147 const local = try f.allocLocal(inst, inst_ty);6155 const local = try f.allocLocal(inst, inst_ty);
6148 try f.writeCValue(writer, local, .Other);
61496156
6157 try f.writeCValue(writer, local, .Other);
6150 try writer.print(" = zig_atomicrmw_{s}((", .{toAtomicRmwSuffix(extra.op())});6158 try writer.print(" = zig_atomicrmw_{s}((", .{toAtomicRmwSuffix(extra.op())});
6151 switch (extra.op()) {6159 switch (extra.op()) {
6152 else => {6160 else => {
...@@ -6166,6 +6174,8 @@ fn airAtomicRmw(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -6166,6 +6174,8 @@ fn airAtomicRmw(f: *Function, inst: Air.Inst.Index) !CValue {
6166 try f.writeCValue(writer, operand, .FunctionArgument);6174 try f.writeCValue(writer, operand, .FunctionArgument);
6167 try writer.writeAll(", ");6175 try writer.writeAll(", ");
6168 try writeMemoryOrder(writer, extra.ordering());6176 try writeMemoryOrder(writer, extra.ordering());
6177 try writer.writeAll(", ");
6178 try f.object.dg.renderTypeForBuiltinFnName(writer, ptr_ty.childType());
6169 try writer.writeAll(");\n");6179 try writer.writeAll(");\n");
61706180
6171 if (f.liveness.isUnused(inst)) {6181 if (f.liveness.isUnused(inst)) {
...@@ -6198,6 +6208,8 @@ fn airAtomicLoad(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -6198,6 +6208,8 @@ fn airAtomicLoad(f: *Function, inst: Air.Inst.Index) !CValue {
6198 try f.writeCValue(writer, ptr, .Other);6208 try f.writeCValue(writer, ptr, .Other);
6199 try writer.writeAll(", ");6209 try writer.writeAll(", ");
6200 try writeMemoryOrder(writer, atomic_load.order);6210 try writeMemoryOrder(writer, atomic_load.order);
6211 try writer.writeAll(", ");
6212 try f.object.dg.renderTypeForBuiltinFnName(writer, ptr_ty.childType());
6201 try writer.writeAll(");\n");6213 try writer.writeAll(");\n");
62026214
6203 return local;6215 return local;
...@@ -6219,7 +6231,9 @@ fn airAtomicStore(f: *Function, inst: Air.Inst.Index, order: [*:0]const u8) !CVa...@@ -6219,7 +6231,9 @@ fn airAtomicStore(f: *Function, inst: Air.Inst.Index, order: [*:0]const u8) !CVa
6219 try f.writeCValue(writer, ptr, .Other);6231 try f.writeCValue(writer, ptr, .Other);
6220 try writer.writeAll(", ");6232 try writer.writeAll(", ");
6221 try f.writeCValue(writer, element, .FunctionArgument);6233 try f.writeCValue(writer, element, .FunctionArgument);
6222 try writer.print(", {s});\n", .{order});6234 try writer.print(", {s}, ", .{order});
6235 try f.object.dg.renderTypeForBuiltinFnName(writer, ptr_ty.childType());
6236 try writer.writeAll(");\n");
62236237
6224 return CValue.none;6238 return CValue.none;
6225}6239}
test/behavior/atomics.zig+1
...@@ -217,6 +217,7 @@ test "atomicrmw with floats" {...@@ -217,6 +217,7 @@ test "atomicrmw with floats" {
217 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO217 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
218 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO218 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
219 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO219 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
220 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
220221
221 if ((builtin.zig_backend == .stage2_llvm or builtin.zig_backend == .stage2_c) and222 if ((builtin.zig_backend == .stage2_llvm or builtin.zig_backend == .stage2_c) and
222 builtin.cpu.arch == .aarch64)223 builtin.cpu.arch == .aarch64)