zig

fork of https://codeberg.org/ziglang/zig
Log | Files | Refs | README | LICENSE

commit 1dc05e9e77e7213e384b9b79b370ae14174fdef1 (tree)
parent 4d658f83ed3893cf950615e9f58c2b533525b71d
Author: Jakub Konka <kubkon@jakubkonka.com>
Date:   Sun, 27 Feb 2022 11:34:33 +0100

x64: impl airSetUnionTag

Diffstat:
Msrc/arch/x86_64/CodeGen.zig | 42+++++++++++++++++++++++++++++++++++-------
1 file changed, 35 insertions(+), 7 deletions(-)

diff --git a/src/arch/x86_64/CodeGen.zig b/src/arch/x86_64/CodeGen.zig @@ -2098,17 +2098,42 @@ fn airPtrElemPtr(self: *Self, inst: Air.Inst.Index) !void { fn airSetUnionTag(self: *Self, inst: Air.Inst.Index) !void { const bin_op = self.air.instructions.items(.data)[inst].bin_op; - _ = bin_op; - return self.fail("TODO implement airSetUnionTag for {}", .{self.target.cpu.arch}); + const ptr_ty = self.air.typeOf(bin_op.lhs); + const union_ty = ptr_ty.childType(); + const tag_ty = self.air.typeOf(bin_op.rhs); + const layout = union_ty.unionGetLayout(self.target.*); + + if (layout.tag_size == 0) { + return self.finishAir(inst, .none, .{ bin_op.lhs, bin_op.rhs, .none }); + } + + const ptr = try self.resolveInst(bin_op.lhs); + ptr.freezeIfRegister(&self.register_manager); + defer ptr.unfreezeIfRegister(&self.register_manager); + + const tag = try self.resolveInst(bin_op.rhs); + tag.freezeIfRegister(&self.register_manager); + defer tag.unfreezeIfRegister(&self.register_manager); + + const adjusted_ptr: MCValue = if (layout.payload_size > 0 and layout.tag_align < layout.payload_align) blk: { + // TODO reusing the operand + const reg = try self.copyToTmpRegister(ptr_ty, ptr); + try self.genBinMathOpMir(.add, ptr_ty, .{ .register = reg }, .{ .immediate = layout.payload_size }); + break :blk MCValue{ .register = reg }; + } else ptr; + + try self.store(adjusted_ptr, tag, ptr_ty, tag_ty); + + return self.finishAir(inst, .none, .{ bin_op.lhs, bin_op.rhs, .none }); } fn airGetUnionTag(self: *Self, inst: Air.Inst.Index) !void { const ty_op = self.air.instructions.items(.data)[inst].ty_op; - const result: MCValue = if (self.liveness.isUnused(inst)) - .dead - else - return self.fail("TODO implement airGetUnionTag for {}", .{self.target.cpu.arch}); - return self.finishAir(inst, result, .{ ty_op.operand, .none, .none }); + if (self.liveness.isUnused(inst)) { + return self.finishAir(inst, .dead, .{ ty_op.operand, .none, .none }); + } + return self.fail("TODO implement airGetUnionTag for {}", .{self.target.cpu.arch}); + // return self.finishAir(inst, result, .{ ty_op.operand, .none, .none }); } fn airClz(self: *Self, inst: Air.Inst.Index) !void { @@ -5509,6 +5534,9 @@ fn genTypedValue(self: *Self, typed_value: TypedValue) InnerError!MCValue { .Struct => { return self.lowerUnnamedConst(typed_value); }, + .Union => { + return self.lowerUnnamedConst(typed_value); + }, else => return self.fail("TODO implement const of type '{}'", .{typed_value.ty}), } }