x64: implement get_union_tag for register
This commit is contained in:
@@ -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}),
|
||||
}
|
||||
};
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
Reference in New Issue
Block a user