| ... | @@ -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), |
| 1422 | | 1423 | |
| 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, |
| 1498 | | 1499 | |
| 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 | |
| | 3206 | fn 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 | } |