Commit 66d28d0f20
Changed files (2)
src
arch
x86_64
test
behavior
src/arch/x86_64/CodeGen.zig
@@ -1783,8 +1783,9 @@ fn airUnwrapErrPayload(self: *Self, inst: Air.Inst.Index) !void {
},
.register => {
// TODO reuse operand
+ const shift = @intCast(u6, err_ty.bitSize(self.target.*));
const result = try self.copyToRegisterWithInstTracking(inst, err_union_ty, operand);
- try self.shiftRegister(result.register.to64(), @intCast(u6, err_ty.bitSize(self.target.*)));
+ try self.shiftRegister(result.register.to64(), shift);
break :result MCValue{
.register = registerAlias(result.register, @intCast(u32, payload_ty.abiSize(self.target.*))),
};
@@ -2169,11 +2170,11 @@ fn airGetUnionTag(self: *Self, inst: Air.Inst.Index) !void {
defer operand.unfreezeIfRegister(&self.register_manager);
const tag_abi_size = tag_ty.abiSize(self.target.*);
- const offset: i32 = if (layout.tag_align < layout.payload_align) @intCast(i32, layout.payload_size) else 0;
const dst_mcv: MCValue = blk: {
switch (operand) {
.stack_offset => |off| {
if (tag_abi_size <= 8) {
+ const offset: i32 = if (layout.tag_align < layout.payload_align) @intCast(i32, layout.payload_size) else 0;
break :blk try self.copyToRegisterWithInstTracking(inst, tag_ty, .{
.stack_offset = off - offset,
});
@@ -2181,6 +2182,17 @@ fn airGetUnionTag(self: *Self, inst: Air.Inst.Index) !void {
return self.fail("TODO implement get_union_tag for ABI larger than 8 bytes and operand {}", .{operand});
},
+ .register => {
+ const shift: u6 = if (layout.tag_align < layout.payload_align)
+ @intCast(u6, layout.payload_size * 8)
+ else
+ 0;
+ const result = try self.copyToRegisterWithInstTracking(inst, union_ty, operand);
+ try self.shiftRegister(result.register.to64(), shift);
+ break :blk MCValue{
+ .register = registerAlias(result.register, @intCast(u32, layout.tag_size)),
+ };
+ },
else => return self.fail("TODO implement get_union_tag for {}", .{operand}),
}
};
test/behavior/union.zig
@@ -272,7 +272,6 @@ const TheUnion = union(TheTag) {
C: i32,
};
test "cast union to tag type of union" {
- if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
@@ -292,7 +291,6 @@ test "union field access gives the enum values" {
}
test "cast tag type of union to union" {
- if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
@@ -307,7 +305,6 @@ const Value2 = union(Letter2) {
};
test "implicit cast union to its tag type" {
- if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
@@ -470,7 +467,6 @@ test "initialize global array of union" {
}
test "update the tag value for zero-sized unions" {
- if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
@@ -706,7 +702,6 @@ test "union with only 1 field casted to its enum type which has enum value speci
}
test "@enumToInt works on unions" {
- if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO