authorgravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2022-02-28 19:49:46+01:00
committergravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2022-02-28 23:20:05+01:00
log66d28d0f20bda4c8653816e9f9179b6cc047506e
tree12611449e625546b658217221d54d817262d6e86
parentdecc90e0e76bb657bb670c6fa74db1f76248be4b

x64: implement get_union_tag for register


2 files changed, 14 insertions(+), 7 deletions(-)

src/arch/x86_64/CodeGen.zig+14-2
......@@ -1783,8 +1783,9 @@ fn airUnwrapErrPayload(self: *Self, inst: Air.Inst.Index) !void {
17831783 },
17841784 .register => {
17851785 // TODO reuse operand
1786 const shift = @intCast(u6, err_ty.bitSize(self.target.*));
17861787 const result = try self.copyToRegisterWithInstTracking(inst, err_union_ty, operand);
1787 try self.shiftRegister(result.register.to64(), @intCast(u6, err_ty.bitSize(self.target.*)));
1788 try self.shiftRegister(result.register.to64(), shift);
17881789 break :result MCValue{
17891790 .register = registerAlias(result.register, @intCast(u32, payload_ty.abiSize(self.target.*))),
17901791 };
......@@ -2169,11 +2170,11 @@ fn airGetUnionTag(self: *Self, inst: Air.Inst.Index) !void {
21692170 defer operand.unfreezeIfRegister(&self.register_manager);
21702171
21712172 const tag_abi_size = tag_ty.abiSize(self.target.*);
2172 const offset: i32 = if (layout.tag_align < layout.payload_align) @intCast(i32, layout.payload_size) else 0;
21732173 const dst_mcv: MCValue = blk: {
21742174 switch (operand) {
21752175 .stack_offset => |off| {
21762176 if (tag_abi_size <= 8) {
2177 const offset: i32 = if (layout.tag_align < layout.payload_align) @intCast(i32, layout.payload_size) else 0;
21772178 break :blk try self.copyToRegisterWithInstTracking(inst, tag_ty, .{
21782179 .stack_offset = off - offset,
21792180 });
......@@ -2181,6 +2182,17 @@ fn airGetUnionTag(self: *Self, inst: Air.Inst.Index) !void {
21812182
21822183 return self.fail("TODO implement get_union_tag for ABI larger than 8 bytes and operand {}", .{operand});
21832184 },
2185 .register => {
2186 const shift: u6 = if (layout.tag_align < layout.payload_align)
2187 @intCast(u6, layout.payload_size * 8)
2188 else
2189 0;
2190 const result = try self.copyToRegisterWithInstTracking(inst, union_ty, operand);
2191 try self.shiftRegister(result.register.to64(), shift);
2192 break :blk MCValue{
2193 .register = registerAlias(result.register, @intCast(u32, layout.tag_size)),
2194 };
2195 },
21842196 else => return self.fail("TODO implement get_union_tag for {}", .{operand}),
21852197 }
21862198 };
test/behavior/union.zig-5
......@@ -272,7 +272,6 @@ const TheUnion = union(TheTag) {
272272 C: i32,
273273};
274274test "cast union to tag type of union" {
275 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;
276275 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
277276 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
278277
......@@ -292,7 +291,6 @@ test "union field access gives the enum values" {
292291}
293292
294293test "cast tag type of union to union" {
295 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;
296294 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
297295 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
298296
......@@ -307,7 +305,6 @@ const Value2 = union(Letter2) {
307305};
308306
309307test "implicit cast union to its tag type" {
310 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;
311308 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
312309 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
313310
......@@ -470,7 +467,6 @@ test "initialize global array of union" {
470467}
471468
472469test "update the tag value for zero-sized unions" {
473 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;
474470 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
475471 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
476472
......@@ -706,7 +702,6 @@ test "union with only 1 field casted to its enum type which has enum value speci
706702}
707703
708704test "@enumToInt works on unions" {
709 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
710705 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
711706 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
712707