diff options
| author | Luuk de Gram <luuk@degram.dev> | 2023-03-17 07:09:01 +0100 |
|---|---|---|
| committer | Luuk de Gram <luuk@degram.dev> | 2023-03-18 20:13:30 +0100 |
| commit | 09d6938df9246bac20e84f5512743e96bccdfa3d (patch) | |
| tree | e9a4fc0d5c8f7a410d619526a89c45ddf18f73d9 /src | |
| parent | 9fce1df4cdab57951137c0da2b44fbe6da2442f2 (diff) | |
| download | zig-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.zig | 14 | ||||
| -rw-r--r-- | src/arch/wasm/Emit.zig | 18 | ||||
| -rw-r--r-- | src/arch/wasm/Mir.zig | 23 | ||||
| -rw-r--r-- | src/link/Wasm.zig | 4 |
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) |
