diff options
| author | Luuk de Gram <luuk@degram.dev> | 2022-03-23 20:42:11 +0100 |
|---|---|---|
| committer | Luuk de Gram <luuk@degram.dev> | 2022-03-23 21:40:33 +0100 |
| commit | 60676a0ba50ece8363883bdbaa803f31d8284c8c (patch) | |
| tree | a2eb7c44d0b505967895eba446ee79a928f71624 /src | |
| parent | 685f05b562b1e5d001ae2da23485c03b704d19f6 (diff) | |
| download | zig-60676a0ba50ece8363883bdbaa803f31d8284c8c.tar.gz zig-60676a0ba50ece8363883bdbaa803f31d8284c8c.zip | |
wasm: Implement more instructions
Implements the following instructions:
- int_to_float
- ptr_slice_len_ptr
- ptr_slice_ptr_ptr
- unwrap_errunion_payload_ptr
- unwrap_errunion_err_ptr
Diffstat (limited to 'src')
| -rw-r--r-- | src/arch/wasm/CodeGen.zig | 58 | ||||
| -rw-r--r-- | src/arch/wasm/Emit.zig | 8 | ||||
| -rw-r--r-- | src/arch/wasm/Mir.zig | 16 |
3 files changed, 69 insertions, 13 deletions
diff --git a/src/arch/wasm/CodeGen.zig b/src/arch/wasm/CodeGen.zig index 0415d8c90a..eb8d72a994 100644 --- a/src/arch/wasm/CodeGen.zig +++ b/src/arch/wasm/CodeGen.zig @@ -1329,6 +1329,7 @@ fn genInst(self: *Self, inst: Air.Inst.Index) !WValue { .fptrunc => self.airFptrunc(inst), .fpext => self.airFpext(inst), .float_to_int => self.airFloatToInt(inst), + .int_to_float => self.airIntToFloat(inst), .get_union_tag => self.airGetUnionTag(inst), // TODO @@ -1382,6 +1383,8 @@ fn genInst(self: *Self, inst: Air.Inst.Index) !WValue { .slice_elem_val => self.airSliceElemVal(inst), .slice_elem_ptr => self.airSliceElemPtr(inst), .slice_ptr => self.airSlicePtr(inst), + .ptr_slice_len_ptr => self.airPtrSliceFieldPtr(inst, self.ptrSize()), + .ptr_slice_ptr_ptr => self.airPtrSliceFieldPtr(inst, 0), .store => self.airStore(inst), .set_union_tag => self.airSetUnionTag(inst), @@ -1398,8 +1401,10 @@ fn genInst(self: *Self, inst: Air.Inst.Index) !WValue { .unreach => self.airUnreachable(inst), .wrap_optional => self.airWrapOptional(inst), - .unwrap_errunion_payload => self.airUnwrapErrUnionPayload(inst), - .unwrap_errunion_err => self.airUnwrapErrUnionError(inst), + .unwrap_errunion_payload => self.airUnwrapErrUnionPayload(inst, false), + .unwrap_errunion_payload_ptr => self.airUnwrapErrUnionPayload(inst, true), + .unwrap_errunion_err => self.airUnwrapErrUnionError(inst, false), + .unwrap_errunion_err_ptr => self.airUnwrapErrUnionError(inst, true), .wrap_errunion_payload => self.airWrapErrUnionPayload(inst), .wrap_errunion_err => self.airWrapErrUnionErr(inst), .errunion_payload_ptr_set => self.airErrUnionPayloadPtrSet(inst), @@ -1429,8 +1434,6 @@ fn genInst(self: *Self, inst: Air.Inst.Index) !WValue { .bit_reverse, .is_err_ptr, .is_non_err_ptr, - .unwrap_errunion_payload_ptr, - .unwrap_errunion_err_ptr, .sqrt, .sin, @@ -1446,9 +1449,6 @@ fn genInst(self: *Self, inst: Air.Inst.Index) !WValue { .round, .trunc_float, - .ptr_slice_len_ptr, - .ptr_slice_ptr_ptr, - .int_to_float, .cmpxchg_weak, .cmpxchg_strong, .fence, @@ -2560,30 +2560,32 @@ fn airIsErr(self: *Self, inst: Air.Inst.Index, opcode: wasm.Opcode) InnerError!W return is_err_tmp; } -fn airUnwrapErrUnionPayload(self: *Self, inst: Air.Inst.Index) InnerError!WValue { +fn airUnwrapErrUnionPayload(self: *Self, inst: Air.Inst.Index, op_is_ptr: bool) InnerError!WValue { if (self.liveness.isUnused(inst)) return WValue{ .none = {} }; const ty_op = self.air.instructions.items(.data)[inst].ty_op; const operand = try self.resolveInst(ty_op.operand); - const err_ty = self.air.typeOf(ty_op.operand); + const op_ty = self.air.typeOf(ty_op.operand); + const err_ty = if (op_is_ptr) op_ty.childType() else op_ty; const payload_ty = err_ty.errorUnionPayload(); if (!payload_ty.hasRuntimeBits()) return WValue{ .none = {} }; const err_align = err_ty.abiAlignment(self.target); const set_size = err_ty.errorUnionSet().abiSize(self.target); const offset = mem.alignForwardGeneric(u64, set_size, err_align); - if (isByRef(payload_ty, self.target)) { + if (op_is_ptr or isByRef(payload_ty, self.target)) { return self.buildPointerOffset(operand, offset, .new); } return self.load(operand, payload_ty, @intCast(u32, offset)); } -fn airUnwrapErrUnionError(self: *Self, inst: Air.Inst.Index) InnerError!WValue { +fn airUnwrapErrUnionError(self: *Self, inst: Air.Inst.Index, op_is_ptr: bool) InnerError!WValue { if (self.liveness.isUnused(inst)) return WValue{ .none = {} }; const ty_op = self.air.instructions.items(.data)[inst].ty_op; const operand = try self.resolveInst(ty_op.operand); - const err_ty = self.air.typeOf(ty_op.operand); + const op_ty = self.air.typeOf(ty_op.operand); + const err_ty = if (op_is_ptr) op_ty.childType() else op_ty; const payload_ty = err_ty.errorUnionPayload(); - if (!payload_ty.hasRuntimeBits()) { + if (op_is_ptr or !payload_ty.hasRuntimeBits()) { return operand; } @@ -3231,6 +3233,28 @@ fn airFloatToInt(self: *Self, inst: Air.Inst.Index) InnerError!WValue { return result; } +fn airIntToFloat(self: *Self, inst: Air.Inst.Index) InnerError!WValue { + if (self.liveness.isUnused(inst)) return WValue{ .none = {} }; + + const ty_op = self.air.instructions.items(.data)[inst].ty_op; + const operand = try self.resolveInst(ty_op.operand); + const dest_ty = self.air.typeOfIndex(inst); + const op_ty = self.air.typeOf(ty_op.operand); + + try self.emitWValue(operand); + const op = buildOpcode(.{ + .op = .convert, + .valtype1 = typeToValtype(dest_ty, self.target), + .valtype2 = typeToValtype(op_ty, self.target), + .signedness = if (op_ty.isSignedInt()) .signed else .unsigned, + }); + try self.addTag(Mir.Inst.Tag.fromOpcode(op)); + + const result = try self.allocLocal(dest_ty); + try self.addLabel(.local_set, result.local); + return result; +} + fn airSplat(self: *Self, inst: Air.Inst.Index) InnerError!WValue { if (self.liveness.isUnused(inst)) return WValue{ .none = {} }; @@ -3682,3 +3706,11 @@ fn airErrorName(self: *Self, inst: Air.Inst.Index) InnerError!WValue { try self.addLabel(.local_set, result_ptr.local); return result_ptr; } + +fn airPtrSliceFieldPtr(self: *Self, inst: Air.Inst.Index, offset: u32) InnerError!WValue { + if (self.liveness.isUnused(inst)) return WValue{ .none = {} }; + + const ty_op = self.air.instructions.items(.data)[inst].ty_op; + const slice_ptr = try self.resolveInst(ty_op.operand); + return self.buildPointerOffset(slice_ptr, offset, .new); +} diff --git a/src/arch/wasm/Emit.zig b/src/arch/wasm/Emit.zig index f0f4cfae5d..7487b014be 100644 --- a/src/arch/wasm/Emit.zig +++ b/src/arch/wasm/Emit.zig @@ -203,6 +203,14 @@ pub fn emitMir(emit: *Emit) InnerError!void { .i64_trunc_f32_u => try emit.emitTag(tag), .i64_trunc_f64_s => try emit.emitTag(tag), .i64_trunc_f64_u => try emit.emitTag(tag), + .f32_convert_i32_s => try emit.emitTag(tag), + .f32_convert_i32_u => try emit.emitTag(tag), + .f32_convert_i64_s => try emit.emitTag(tag), + .f32_convert_i64_u => try emit.emitTag(tag), + .f64_convert_i32_s => try emit.emitTag(tag), + .f64_convert_i32_u => try emit.emitTag(tag), + .f64_convert_i64_s => try emit.emitTag(tag), + .f64_convert_i64_u => try emit.emitTag(tag), .i32_rem_s => try emit.emitTag(tag), .i32_rem_u => try emit.emitTag(tag), .i64_rem_s => try emit.emitTag(tag), diff --git a/src/arch/wasm/Mir.zig b/src/arch/wasm/Mir.zig index 09a0c32901..395e9bb17c 100644 --- a/src/arch/wasm/Mir.zig +++ b/src/arch/wasm/Mir.zig @@ -451,8 +451,24 @@ pub const Inst = struct { /// Uses `tag` i64_trunc_f64_u = 0xB1, /// Uses `tag` + f32_convert_i32_s = 0xB2, + /// Uses `tag` + f32_convert_i32_u = 0xB3, + /// Uses `tag` + f32_convert_i64_s = 0xB4, + /// Uses `tag` + f32_convert_i64_u = 0xB5, + /// Uses `tag` f32_demote_f64 = 0xB6, /// Uses `tag` + f64_convert_i32_s = 0xB7, + /// Uses `tag` + f64_convert_i32_u = 0xB8, + /// Uses `tag` + f64_convert_i64_s = 0xB9, + /// Uses `tag` + f64_convert_i64_u = 0xBA, + /// Uses `tag` f64_promote_f32 = 0xBB, /// Uses `tag` i32_reinterpret_f32 = 0xBC, |
