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 {...@@ -1783,8 +1783,9 @@ fn airUnwrapErrPayload(self: *Self, inst: Air.Inst.Index) !void {
1783 },1783 },
1784 .register => {1784 .register => {
1785 // TODO reuse operand1785 // TODO reuse operand
1786 const shift = @intCast(u6, err_ty.bitSize(self.target.*));
1786 const result = try self.copyToRegisterWithInstTracking(inst, err_union_ty, operand);1787 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);
1788 break :result MCValue{1789 break :result MCValue{
1789 .register = registerAlias(result.register, @intCast(u32, payload_ty.abiSize(self.target.*))),1790 .register = registerAlias(result.register, @intCast(u32, payload_ty.abiSize(self.target.*))),
1790 };1791 };
...@@ -2169,11 +2170,11 @@ fn airGetUnionTag(self: *Self, inst: Air.Inst.Index) !void {...@@ -2169,11 +2170,11 @@ fn airGetUnionTag(self: *Self, inst: Air.Inst.Index) !void {
2169 defer operand.unfreezeIfRegister(&self.register_manager);2170 defer operand.unfreezeIfRegister(&self.register_manager);
21702171
2171 const tag_abi_size = tag_ty.abiSize(self.target.*);2172 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;
2173 const dst_mcv: MCValue = blk: {2173 const dst_mcv: MCValue = blk: {
2174 switch (operand) {2174 switch (operand) {
2175 .stack_offset => |off| {2175 .stack_offset => |off| {
2176 if (tag_abi_size <= 8) {2176 if (tag_abi_size <= 8) {
2177 const offset: i32 = if (layout.tag_align < layout.payload_align) @intCast(i32, layout.payload_size) else 0;
2177 break :blk try self.copyToRegisterWithInstTracking(inst, tag_ty, .{2178 break :blk try self.copyToRegisterWithInstTracking(inst, tag_ty, .{
2178 .stack_offset = off - offset,2179 .stack_offset = off - offset,
2179 });2180 });
...@@ -2181,6 +2182,17 @@ fn airGetUnionTag(self: *Self, inst: Air.Inst.Index) !void {...@@ -2181,6 +2182,17 @@ fn airGetUnionTag(self: *Self, inst: Air.Inst.Index) !void {
21812182
2182 return self.fail("TODO implement get_union_tag for ABI larger than 8 bytes and operand {}", .{operand});2183 return self.fail("TODO implement get_union_tag for ABI larger than 8 bytes and operand {}", .{operand});
2183 },2184 },
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 },
2184 else => return self.fail("TODO implement get_union_tag for {}", .{operand}),2196 else => return self.fail("TODO implement get_union_tag for {}", .{operand}),
2185 }2197 }
2186 };2198 };
test/behavior/union.zig-5
...@@ -272,7 +272,6 @@ const TheUnion = union(TheTag) {...@@ -272,7 +272,6 @@ const TheUnion = union(TheTag) {
272 C: i32,272 C: i32,
273};273};
274test "cast union to tag type of union" {274test "cast union to tag type of union" {
275 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;
276 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;275 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
277 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;276 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
278277
...@@ -292,7 +291,6 @@ test "union field access gives the enum values" {...@@ -292,7 +291,6 @@ test "union field access gives the enum values" {
292}291}
293292
294test "cast tag type of union to union" {293test "cast tag type of union to union" {
295 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;
296 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;294 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
297 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;295 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
298296
...@@ -307,7 +305,6 @@ const Value2 = union(Letter2) {...@@ -307,7 +305,6 @@ const Value2 = union(Letter2) {
307};305};
308306
309test "implicit cast union to its tag type" {307test "implicit cast union to its tag type" {
310 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;
311 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;308 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
312 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;309 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
313310
...@@ -470,7 +467,6 @@ test "initialize global array of union" {...@@ -470,7 +467,6 @@ test "initialize global array of union" {
470}467}
471468
472test "update the tag value for zero-sized unions" {469test "update the tag value for zero-sized unions" {
473 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;
474 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;470 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
475 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;471 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...@@ -706,7 +702,6 @@ test "union with only 1 field casted to its enum type which has enum value speci
706}702}
707703
708test "@enumToInt works on unions" {704test "@enumToInt works on unions" {
709 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
710 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO705 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
711 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO706 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
712707