| ... | ... | @@ -2098,17 +2098,42 @@ fn airPtrElemPtr(self: *Self, inst: Air.Inst.Index) !void { |
| 2098 | 2098 | |
| 2099 | 2099 | fn airSetUnionTag(self: *Self, inst: Air.Inst.Index) !void { |
| 2100 | 2100 | const bin_op = self.air.instructions.items(.data)[inst].bin_op; |
| 2101 | | _ = bin_op; |
| 2102 | | return self.fail("TODO implement airSetUnionTag for {}", .{self.target.cpu.arch}); |
| 2101 | const ptr_ty = self.air.typeOf(bin_op.lhs); |
| 2102 | const union_ty = ptr_ty.childType(); |
| 2103 | const tag_ty = self.air.typeOf(bin_op.rhs); |
| 2104 | const layout = union_ty.unionGetLayout(self.target.*); |
| 2105 | |
| 2106 | if (layout.tag_size == 0) { |
| 2107 | return self.finishAir(inst, .none, .{ bin_op.lhs, bin_op.rhs, .none }); |
| 2108 | } |
| 2109 | |
| 2110 | const ptr = try self.resolveInst(bin_op.lhs); |
| 2111 | ptr.freezeIfRegister(&self.register_manager); |
| 2112 | defer ptr.unfreezeIfRegister(&self.register_manager); |
| 2113 | |
| 2114 | const tag = try self.resolveInst(bin_op.rhs); |
| 2115 | tag.freezeIfRegister(&self.register_manager); |
| 2116 | defer tag.unfreezeIfRegister(&self.register_manager); |
| 2117 | |
| 2118 | const adjusted_ptr: MCValue = if (layout.payload_size > 0 and layout.tag_align < layout.payload_align) blk: { |
| 2119 | // TODO reusing the operand |
| 2120 | const reg = try self.copyToTmpRegister(ptr_ty, ptr); |
| 2121 | try self.genBinMathOpMir(.add, ptr_ty, .{ .register = reg }, .{ .immediate = layout.payload_size }); |
| 2122 | break :blk MCValue{ .register = reg }; |
| 2123 | } else ptr; |
| 2124 | |
| 2125 | try self.store(adjusted_ptr, tag, ptr_ty, tag_ty); |
| 2126 | |
| 2127 | return self.finishAir(inst, .none, .{ bin_op.lhs, bin_op.rhs, .none }); |
| 2103 | 2128 | } |
| 2104 | 2129 | |
| 2105 | 2130 | fn airGetUnionTag(self: *Self, inst: Air.Inst.Index) !void { |
| 2106 | 2131 | const ty_op = self.air.instructions.items(.data)[inst].ty_op; |
| 2107 | | const result: MCValue = if (self.liveness.isUnused(inst)) |
| 2108 | | .dead |
| 2109 | | else |
| 2110 | | return self.fail("TODO implement airGetUnionTag for {}", .{self.target.cpu.arch}); |
| 2111 | | return self.finishAir(inst, result, .{ ty_op.operand, .none, .none }); |
| 2132 | if (self.liveness.isUnused(inst)) { |
| 2133 | return self.finishAir(inst, .dead, .{ ty_op.operand, .none, .none }); |
| 2134 | } |
| 2135 | return self.fail("TODO implement airGetUnionTag for {}", .{self.target.cpu.arch}); |
| 2136 | // return self.finishAir(inst, result, .{ ty_op.operand, .none, .none }); |
| 2112 | 2137 | } |
| 2113 | 2138 | |
| 2114 | 2139 | fn airClz(self: *Self, inst: Air.Inst.Index) !void { |
| ... | ... | @@ -5509,6 +5534,9 @@ fn genTypedValue(self: *Self, typed_value: TypedValue) InnerError!MCValue { |
| 5509 | 5534 | .Struct => { |
| 5510 | 5535 | return self.lowerUnnamedConst(typed_value); |
| 5511 | 5536 | }, |
| 5537 | .Union => { |
| 5538 | return self.lowerUnnamedConst(typed_value); |
| 5539 | }, |
| 5512 | 5540 | else => return self.fail("TODO implement const of type '{}'", .{typed_value.ty}), |
| 5513 | 5541 | } |
| 5514 | 5542 | } |