aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorLuuk de Gram <luuk@degram.dev>2023-03-17 07:09:01 +0100
committerLuuk de Gram <luuk@degram.dev>2023-03-18 20:13:30 +0100
commit09d6938df9246bac20e84f5512743e96bccdfa3d (patch)
treee9a4fc0d5c8f7a410d619526a89c45ddf18f73d9 /src
parent9fce1df4cdab57951137c0da2b44fbe6da2442f2 (diff)
downloadzig-09d6938df9246bac20e84f5512743e96bccdfa3d.tar.gz
zig-09d6938df9246bac20e84f5512743e96bccdfa3d.zip
wasm: add atomics opcodes and refactoring
This adds the atomic opcodes for the Threads proposal to the WebAssembly specification: https://github.com/WebAssembly/threads PrefixedOpcode has been renamed to MiscOpcode as there's multiple types of prefixed opcodes. This naming is similar to other tools such as LLVM. As we now use the 0xFE prefix, we moved the function_index MIR instruction as it was occupying the same value. This commit includes renaming all related opcodes.
Diffstat (limited to 'src')
-rw-r--r--src/arch/wasm/CodeGen.zig14
-rw-r--r--src/arch/wasm/Emit.zig18
-rw-r--r--src/arch/wasm/Mir.zig23
-rw-r--r--src/link/Wasm.zig4
4 files changed, 36 insertions, 23 deletions
diff --git a/src/arch/wasm/CodeGen.zig b/src/arch/wasm/CodeGen.zig
index e79129ddb8..c05f07a602 100644
--- a/src/arch/wasm/CodeGen.zig
+++ b/src/arch/wasm/CodeGen.zig
@@ -895,10 +895,10 @@ fn addTag(func: *CodeGen, tag: Mir.Inst.Tag) error{OutOfMemory}!void {
try func.addInst(.{ .tag = tag, .data = .{ .tag = {} } });
}
-fn addExtended(func: *CodeGen, opcode: wasm.PrefixedOpcode) error{OutOfMemory}!void {
+fn addExtended(func: *CodeGen, opcode: wasm.MiscOpcode) error{OutOfMemory}!void {
const extra_index = @intCast(u32, func.mir_extra.items.len);
try func.mir_extra.append(func.gpa, @enumToInt(opcode));
- try func.addInst(.{ .tag = .extended, .data = .{ .payload = extra_index } });
+ try func.addInst(.{ .tag = .misc_prefix, .data = .{ .payload = extra_index } });
}
fn addLabel(func: *CodeGen, tag: Mir.Inst.Tag, label: u32) error{OutOfMemory}!void {
@@ -925,7 +925,7 @@ fn addImm128(func: *CodeGen, index: u32) error{OutOfMemory}!void {
try func.mir_extra.ensureUnusedCapacity(func.gpa, 5);
func.mir_extra.appendAssumeCapacity(std.wasm.simdOpcode(.v128_const));
func.mir_extra.appendSliceAssumeCapacity(@alignCast(4, mem.bytesAsSlice(u32, &simd_values)));
- try func.addInst(.{ .tag = .simd, .data = .{ .payload = extra_index } });
+ try func.addInst(.{ .tag = .simd_prefix, .data = .{ .payload = extra_index } });
}
fn addFloat64(func: *CodeGen, float: f64) error{OutOfMemory}!void {
@@ -2310,7 +2310,7 @@ fn store(func: *CodeGen, lhs: WValue, rhs: WValue, ty: Type, offset: u32) InnerE
offset + lhs.offset(),
ty.abiAlignment(func.target),
});
- return func.addInst(.{ .tag = .simd, .data = .{ .payload = extra_index } });
+ return func.addInst(.{ .tag = .simd_prefix, .data = .{ .payload = extra_index } });
},
},
.Pointer => {
@@ -2420,7 +2420,7 @@ fn load(func: *CodeGen, operand: WValue, ty: Type, offset: u32) InnerError!WValu
offset + operand.offset(),
ty.abiAlignment(func.target),
});
- try func.addInst(.{ .tag = .simd, .data = .{ .payload = extra_index } });
+ try func.addInst(.{ .tag = .simd_prefix, .data = .{ .payload = extra_index } });
return WValue{ .stack = {} };
}
@@ -4477,7 +4477,7 @@ fn airSplat(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
operand.offset(),
elem_ty.abiAlignment(func.target),
});
- try func.addInst(.{ .tag = .simd, .data = .{ .payload = extra_index } });
+ try func.addInst(.{ .tag = .simd_prefix, .data = .{ .payload = extra_index } });
try func.addLabel(.local_set, result.local.value);
return func.finishAir(inst, result, &.{ty_op.operand});
},
@@ -4493,7 +4493,7 @@ fn airSplat(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
try func.emitWValue(operand);
const extra_index = @intCast(u32, func.mir_extra.items.len);
try func.mir_extra.append(func.gpa, opcode);
- try func.addInst(.{ .tag = .simd, .data = .{ .payload = extra_index } });
+ try func.addInst(.{ .tag = .simd_prefix, .data = .{ .payload = extra_index } });
try func.addLabel(.local_set, result.local.value);
return func.finishAir(inst, result, &.{ty_op.operand});
},
diff --git a/src/arch/wasm/Emit.zig b/src/arch/wasm/Emit.zig
index 7d44d3622f..5982d3b48c 100644
--- a/src/arch/wasm/Emit.zig
+++ b/src/arch/wasm/Emit.zig
@@ -239,8 +239,9 @@ pub fn emitMir(emit: *Emit) InnerError!void {
.i64_clz => try emit.emitTag(tag),
.i64_ctz => try emit.emitTag(tag),
- .extended => try emit.emitExtended(inst),
- .simd => try emit.emitSimd(inst),
+ .misc_prefix => try emit.emitExtended(inst),
+ .simd_prefix => try emit.emitSimd(inst),
+ .atomics_prefix => try emit.emitAtomic(inst),
}
}
}
@@ -433,9 +434,9 @@ fn emitExtended(emit: *Emit, inst: Mir.Inst.Index) !void {
const extra_index = emit.mir.instructions.items(.data)[inst].payload;
const opcode = emit.mir.extra[extra_index];
const writer = emit.code.writer();
- try emit.code.append(0xFC);
+ try emit.code.append(std.wasm.opcode(.misc_prefix));
try leb128.writeULEB128(writer, opcode);
- switch (@intToEnum(std.wasm.PrefixedOpcode, opcode)) {
+ switch (@intToEnum(std.wasm.MiscOpcode, opcode)) {
// bulk-memory opcodes
.data_drop => {
const segment = emit.mir.extra[extra_index + 1];
@@ -472,7 +473,7 @@ fn emitSimd(emit: *Emit, inst: Mir.Inst.Index) !void {
const extra_index = emit.mir.instructions.items(.data)[inst].payload;
const opcode = emit.mir.extra[extra_index];
const writer = emit.code.writer();
- try emit.code.append(0xFD);
+ try emit.code.append(std.wasm.opcode(.simd_prefix));
try leb128.writeULEB128(writer, opcode);
switch (@intToEnum(std.wasm.SimdOpcode, opcode)) {
.v128_store,
@@ -496,10 +497,15 @@ fn emitSimd(emit: *Emit, inst: Mir.Inst.Index) !void {
.f32x4_splat,
.f64x2_splat,
=> {}, // opcode already written
- else => |tag| return emit.fail("TODO: Implement simd instruction: {s}\n", .{@tagName(tag)}),
+ else => |tag| return emit.fail("TODO: Implement simd instruction: {s}", .{@tagName(tag)}),
}
}
+fn emitAtomic(emit: *Emit, inst: Mir.Inst.Index) !void {
+ _ = inst;
+ return emit.fail("TODO: Implement atomics instructions", .{});
+}
+
fn emitMemFill(emit: *Emit) !void {
try emit.code.append(0xFC);
try emit.code.append(0x0B);
diff --git a/src/arch/wasm/Mir.zig b/src/arch/wasm/Mir.zig
index 2d59c09e18..4c550d8637 100644
--- a/src/arch/wasm/Mir.zig
+++ b/src/arch/wasm/Mir.zig
@@ -87,6 +87,13 @@ pub const Inst = struct {
///
/// Uses `label`
call_indirect = 0x11,
+ /// Contains a symbol to a function pointer
+ /// uses `label`
+ ///
+ /// Note: This uses `0x16` as value which is reserved by the WebAssembly
+ /// specification but unused, meaning we must update this if the specification were to
+ /// use this value.
+ function_index = 0x16,
/// Pops three values from the stack and pushes
/// the first or second value dependent on the third value.
/// Uses `tag`
@@ -510,24 +517,24 @@ pub const Inst = struct {
i64_extend16_s = 0xC3,
/// Uses `tag`
i64_extend32_s = 0xC4,
- /// The instruction consists of an extension opcode.
+ /// The instruction consists of a prefixed opcode.
/// The prefixed opcode can be found at payload's index.
///
/// The `data` field depends on the extension instruction and
/// may contain additional data.
- extended = 0xFC,
+ misc_prefix = 0xFC,
/// The instruction consists of a simd opcode.
/// The actual simd-opcode is found at payload's index.
///
/// The `data` field depends on the simd instruction and
/// may contain additional data.
- simd = 0xFD,
- /// Contains a symbol to a function pointer
- /// uses `label`
+ simd_prefix = 0xFD,
+ /// The instruction consists of an atomics opcode.
+ /// The actual atomics-opcode is found at payload's index.
///
- /// Note: This uses `0xFE` as value as it is unused and not reserved
- /// by the wasm specification, making it safe to use.
- function_index = 0xFE,
+ /// The `data` field depends on the atomics instruction and
+ /// may contain additional data.
+ atomics_prefix = 0xFE,
/// Contains a symbol to a memory address
/// Uses `label`
///
diff --git a/src/link/Wasm.zig b/src/link/Wasm.zig
index eaaabcc89a..5175f760d1 100644
--- a/src/link/Wasm.zig
+++ b/src/link/Wasm.zig
@@ -2128,8 +2128,8 @@ fn initializeTLSFunction(wasm: *Wasm) !void {
}
// perform the bulk-memory operation to initialize the data segment
- try writer.writeByte(std.wasm.opcode(.prefixed));
- try leb.writeULEB128(writer, @enumToInt(std.wasm.PrefixedOpcode.memory_init));
+ try writer.writeByte(std.wasm.opcode(.misc_prefix));
+ try leb.writeULEB128(writer, std.wasm.miscOpcode(.memory_init));
// segment immediate
try leb.writeULEB128(writer, @intCast(u32, data_index));
// memory index immediate (always 0)