| ... | ... | @@ -1419,6 +1419,7 @@ fn genInst(self: *Self, inst: Air.Inst.Index) !WValue { |
| 1419 | 1419 | .dbg_stmt => WValue.none, |
| 1420 | 1420 | .intcast => self.airIntcast(inst), |
| 1421 | 1421 | .float_to_int => self.airFloatToInt(inst), |
| 1422 | .get_union_tag => self.airGetUnionTag(inst), |
| 1422 | 1423 | |
| 1423 | 1424 | .is_err => self.airIsErr(inst, .i32_ne), |
| 1424 | 1425 | .is_non_err => self.airIsErr(inst, .i32_eq), |
| ... | ... | @@ -1496,7 +1497,6 @@ fn genInst(self: *Self, inst: Air.Inst.Index) !WValue { |
| 1496 | 1497 | .unwrap_errunion_payload_ptr, |
| 1497 | 1498 | .unwrap_errunion_err_ptr, |
| 1498 | 1499 | |
| 1499 | | .get_union_tag, |
| 1500 | 1500 | .ptr_slice_len_ptr, |
| 1501 | 1501 | .ptr_slice_ptr_ptr, |
| 1502 | 1502 | .int_to_float, |
| ... | ... | @@ -3202,3 +3202,21 @@ fn airSetUnionTag(self: *Self, inst: Air.Inst.Index) InnerError!WValue { |
| 3202 | 3202 | try self.store(union_ptr, new_tag, tag_ty, offset); |
| 3203 | 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 | } |