authorgravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2022-02-27 11:34:33+01:00
committergravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2022-02-28 11:40:21+01:00
log1dc05e9e77e7213e384b9b79b370ae14174fdef1
tree77d25d2bf00ff4ed349f40baeee1c305e849357a
parent4d658f83ed3893cf950615e9f58c2b533525b71d

x64: impl airSetUnionTag


1 files changed, 35 insertions(+), 7 deletions(-)

src/arch/x86_64/CodeGen.zig+35-7
......@@ -2098,17 +2098,42 @@ fn airPtrElemPtr(self: *Self, inst: Air.Inst.Index) !void {
20982098
20992099fn airSetUnionTag(self: *Self, inst: Air.Inst.Index) !void {
21002100 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 });
21032128}
21042129
21052130fn airGetUnionTag(self: *Self, inst: Air.Inst.Index) !void {
21062131 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 });
21122137}
21132138
21142139fn airClz(self: *Self, inst: Air.Inst.Index) !void {
......@@ -5509,6 +5534,9 @@ fn genTypedValue(self: *Self, typed_value: TypedValue) InnerError!MCValue {
55095534 .Struct => {
55105535 return self.lowerUnnamedConst(typed_value);
55115536 },
5537 .Union => {
5538 return self.lowerUnnamedConst(typed_value);
5539 },
55125540 else => return self.fail("TODO implement const of type '{}'", .{typed_value.ty}),
55135541 }
55145542}