authorgravatar for luuk@degram.devLuuk de Gram <luuk@degram.dev> 2022-01-22 14:11:12+01:00
committergravatar for luuk@degram.devLuuk de Gram <luuk@degram.dev> 2022-01-25 19:00:51+01:00
log288b407fa9c40addafe521862c3eef08c878b1f6
tree0867a8654ad1250dcd1f844e1ced953fbd28971a
parent4b939fb34d3707258789e3ef71ff698a7d6bf552
signature Commit is signed but in an unrecognized format.

wasm: Implement get_union_tag


1 files changed, 19 insertions(+), 1 deletions(-)

src/arch/wasm/CodeGen.zig+19-1
...@@ -1419,6 +1419,7 @@ fn genInst(self: *Self, inst: Air.Inst.Index) !WValue {...@@ -1419,6 +1419,7 @@ fn genInst(self: *Self, inst: Air.Inst.Index) !WValue {
1419 .dbg_stmt => WValue.none,1419 .dbg_stmt => WValue.none,
1420 .intcast => self.airIntcast(inst),1420 .intcast => self.airIntcast(inst),
1421 .float_to_int => self.airFloatToInt(inst),1421 .float_to_int => self.airFloatToInt(inst),
1422 .get_union_tag => self.airGetUnionTag(inst),
14221423
1423 .is_err => self.airIsErr(inst, .i32_ne),1424 .is_err => self.airIsErr(inst, .i32_ne),
1424 .is_non_err => self.airIsErr(inst, .i32_eq),1425 .is_non_err => self.airIsErr(inst, .i32_eq),
...@@ -1496,7 +1497,6 @@ fn genInst(self: *Self, inst: Air.Inst.Index) !WValue {...@@ -1496,7 +1497,6 @@ fn genInst(self: *Self, inst: Air.Inst.Index) !WValue {
1496 .unwrap_errunion_payload_ptr,1497 .unwrap_errunion_payload_ptr,
1497 .unwrap_errunion_err_ptr,1498 .unwrap_errunion_err_ptr,
14981499
1499 .get_union_tag,
1500 .ptr_slice_len_ptr,1500 .ptr_slice_len_ptr,
1501 .ptr_slice_ptr_ptr,1501 .ptr_slice_ptr_ptr,
1502 .int_to_float,1502 .int_to_float,
...@@ -3202,3 +3202,21 @@ fn airSetUnionTag(self: *Self, inst: Air.Inst.Index) InnerError!WValue {...@@ -3202,3 +3202,21 @@ fn airSetUnionTag(self: *Self, inst: Air.Inst.Index) InnerError!WValue {
3202 try self.store(union_ptr, new_tag, tag_ty, offset);3202 try self.store(union_ptr, new_tag, tag_ty, offset);
3203 return WValue{ .none = {} };3203 return WValue{ .none = {} };
3204}3204}
3205
3206fn airGetUnionTag(self: *Self, inst: Air.Inst.Index) InnerError!WValue {
3207 if (self.liveness.isUnused(inst)) return WValue{ .none = {} };
3208
3209 const ty_op = self.air.instructions.items(.data)[inst].ty_op;
3210 const un_ty = self.air.typeOf(ty_op.operand);
3211 const tag_ty = self.air.typeOfIndex(inst);
3212 const layout = un_ty.unionGetLayout(self.target);
3213 if (layout.tag_size == 0) return WValue{ .none = {} };
3214 const operand = try self.resolveInst(ty_op.operand);
3215
3216 // when the tag alignment is smaller than the payload, the field will be stored
3217 // after the payload.
3218 const offset = if (layout.tag_align < layout.payload_align) blk: {
3219 break :blk @intCast(u32, layout.payload_size);
3220 } else @as(u32, 0);
3221 return self.load(operand, tag_ty, offset);
3222}