aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorLuuk de Gram <luuk@degram.dev>2022-03-23 20:42:11 +0100
committerLuuk de Gram <luuk@degram.dev>2022-03-23 21:40:33 +0100
commit60676a0ba50ece8363883bdbaa803f31d8284c8c (patch)
treea2eb7c44d0b505967895eba446ee79a928f71624 /src
parent685f05b562b1e5d001ae2da23485c03b704d19f6 (diff)
downloadzig-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.zig58
-rw-r--r--src/arch/wasm/Emit.zig8
-rw-r--r--src/arch/wasm/Mir.zig16
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,