| ... | @@ -948,6 +948,12 @@ fn addAtomicMemArg(func: *CodeGen, tag: wasm.AtomicsOpcode, mem_arg: Mir.MemArg) | ... | @@ -948,6 +948,12 @@ fn addAtomicMemArg(func: *CodeGen, tag: wasm.AtomicsOpcode, mem_arg: Mir.MemArg) |
| 948 | try func.addInst(.{ .tag = .atomics_prefix, .data = .{ .payload = extra_index } }); | 948 | try func.addInst(.{ .tag = .atomics_prefix, .data = .{ .payload = extra_index } }); |
| 949 | } | 949 | } |
| 950 | | 950 | |
| | 951 | /// Helper function to emit atomic mir opcodes. |
| | 952 | fn addAtomicTag(func: *CodeGen, tag: wasm.AtomicsOpcode) error{OutOfMemory}!void { |
| | 953 | const extra_index = try func.addExtra(@as(struct { val: u32 }, .{ .val = wasm.atomicsOpcode(tag) })); |
| | 954 | try func.addInst(.{ .tag = .atomics_prefix, .data = .{ .payload = extra_index } }); |
| | 955 | } |
| | 956 | |
| 951 | /// Appends entries to `mir_extra` based on the type of `extra`. | 957 | /// Appends entries to `mir_extra` based on the type of `extra`. |
| 952 | /// Returns the index into `mir_extra` | 958 | /// Returns the index into `mir_extra` |
| 953 | fn addExtra(func: *CodeGen, extra: anytype) error{OutOfMemory}!u32 { | 959 | fn addExtra(func: *CodeGen, extra: anytype) error{OutOfMemory}!u32 { |
| ... | @@ -1964,7 +1970,6 @@ fn genInst(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { | ... | @@ -1964,7 +1970,6 @@ fn genInst(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 1964 | .is_err_ptr, | 1970 | .is_err_ptr, |
| 1965 | .is_non_err_ptr, | 1971 | .is_non_err_ptr, |
| 1966 | | 1972 | |
| 1967 | .fence, | | |
| 1968 | .atomic_store_unordered, | 1973 | .atomic_store_unordered, |
| 1969 | .atomic_store_monotonic, | 1974 | .atomic_store_monotonic, |
| 1970 | .atomic_store_release, | 1975 | .atomic_store_release, |
| ... | @@ -1985,6 +1990,7 @@ fn genInst(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { | ... | @@ -1985,6 +1990,7 @@ fn genInst(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 1985 | .atomic_rmw => func.airAtomicRmw(inst), | 1990 | .atomic_rmw => func.airAtomicRmw(inst), |
| 1986 | .cmpxchg_weak => func.airCmpxchg(inst), | 1991 | .cmpxchg_weak => func.airCmpxchg(inst), |
| 1987 | .cmpxchg_strong => func.airCmpxchg(inst), | 1992 | .cmpxchg_strong => func.airCmpxchg(inst), |
| | 1993 | .fence => func.airFence(inst), |
| 1988 | | 1994 | |
| 1989 | .add_optimized, | 1995 | .add_optimized, |
| 1990 | .addwrap_optimized, | 1996 | .addwrap_optimized, |
| ... | @@ -6863,3 +6869,14 @@ fn airAtomicRmw(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { | ... | @@ -6863,3 +6869,14 @@ fn airAtomicRmw(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 6863 | return func.finishAir(inst, result, &.{ pl_op.operand, extra.operand }); | 6869 | return func.finishAir(inst, result, &.{ pl_op.operand, extra.operand }); |
| 6864 | } | 6870 | } |
| 6865 | } | 6871 | } |
| | 6872 | |
| | 6873 | fn airFence(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| | 6874 | // Only when the atomic feature is enabled, and we're not building |
| | 6875 | // for a single-threaded build, can we emit the `fence` instruction. |
| | 6876 | // In all other cases, we emit no instructions for a fence. |
| | 6877 | if (func.useAtomicFeature() and !func.bin_file.base.options.single_threaded) { |
| | 6878 | try func.addAtomicTag(.atomic_fence); |
| | 6879 | } |
| | 6880 | |
| | 6881 | return func.finishAir(inst, .none, &.{}); |
| | 6882 | } |