authorgravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2022-02-28 15:25:40+01:00
committergravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2022-02-28 15:25:40+01:00
log16f9774d2d6f358c97637e35609dfe0fc14cb501
tree7f9978d06d450c715662c765a3257402915987d7
parenta61ac9ecbf42a97a4f56f7384e5b862dcb169f4a

x64: fix switch condition mir; pass more union tests


3 files changed, 24 insertions(+), 27 deletions(-)

src/arch/x86_64/CodeGen.zig+18-16
...@@ -3967,36 +3967,22 @@ fn genCondSwitchMir(self: *Self, ty: Type, condition: MCValue, case: MCValue) !u...@@ -3967,36 +3967,22 @@ fn genCondSwitchMir(self: *Self, ty: Type, condition: MCValue, case: MCValue) !u
3967 .dead, .unreach => unreachable,3967 .dead, .unreach => unreachable,
3968 .immediate => |imm| {3968 .immediate => |imm| {
3969 _ = try self.addInst(.{3969 _ = try self.addInst(.{
3970 .tag = .@"test",3970 .tag = .xor,
3971 .ops = (Mir.Ops{3971 .ops = (Mir.Ops{
3972 .reg1 = registerAlias(cond_reg, abi_size),3972 .reg1 = registerAlias(cond_reg, abi_size),
3973 }).encode(),3973 }).encode(),
3974 .data = .{ .imm = @intCast(u32, imm) },3974 .data = .{ .imm = @intCast(u32, imm) },
3975 });3975 });
3976 return self.addInst(.{
3977 .tag = .cond_jmp_eq_ne,
3978 .ops = (Mir.Ops{
3979 .flags = 0b00,
3980 }).encode(),
3981 .data = .{ .inst = undefined },
3982 });
3983 },3976 },
3984 .register => |reg| {3977 .register => |reg| {
3985 _ = try self.addInst(.{3978 _ = try self.addInst(.{
3986 .tag = .@"test",3979 .tag = .xor,
3987 .ops = (Mir.Ops{3980 .ops = (Mir.Ops{
3988 .reg1 = registerAlias(cond_reg, abi_size),3981 .reg1 = registerAlias(cond_reg, abi_size),
3989 .reg2 = registerAlias(reg, abi_size),3982 .reg2 = registerAlias(reg, abi_size),
3990 }).encode(),3983 }).encode(),
3991 .data = undefined,3984 .data = undefined,
3992 });3985 });
3993 return self.addInst(.{
3994 .tag = .cond_jmp_eq_ne,
3995 .ops = (Mir.Ops{
3996 .flags = 0b00,
3997 }).encode(),
3998 .data = .{ .inst = undefined },
3999 });
4000 },3986 },
4001 .stack_offset => {3987 .stack_offset => {
4002 if (abi_size <= 8) {3988 if (abi_size <= 8) {
...@@ -4010,6 +3996,22 @@ fn genCondSwitchMir(self: *Self, ty: Type, condition: MCValue, case: MCValue) !u...@@ -4010,6 +3996,22 @@ fn genCondSwitchMir(self: *Self, ty: Type, condition: MCValue, case: MCValue) !u
4010 return self.fail("TODO implement switch mir when case is {}", .{case});3996 return self.fail("TODO implement switch mir when case is {}", .{case});
4011 },3997 },
4012 }3998 }
3999
4000 _ = try self.addInst(.{
4001 .tag = .@"test",
4002 .ops = (Mir.Ops{
4003 .reg1 = registerAlias(cond_reg, abi_size),
4004 .reg2 = registerAlias(cond_reg, abi_size),
4005 }).encode(),
4006 .data = undefined,
4007 });
4008 return self.addInst(.{
4009 .tag = .cond_jmp_eq_ne,
4010 .ops = (Mir.Ops{
4011 .flags = 0b00,
4012 }).encode(),
4013 .data = .{ .inst = undefined },
4014 });
4013 },4015 },
4014 .stack_offset => {4016 .stack_offset => {
4015 try self.spillCompareFlagsIfOccupied();4017 try self.spillCompareFlagsIfOccupied();
src/arch/x86_64/Emit.zig+6
...@@ -1859,6 +1859,9 @@ fn lowerToRmEnc(...@@ -1859,6 +1859,9 @@ fn lowerToRmEnc(
1859 switch (reg_or_mem) {1859 switch (reg_or_mem) {
1860 .register => |src_reg| {1860 .register => |src_reg| {
1861 const encoder = try Encoder.init(code, 4);1861 const encoder = try Encoder.init(code, 4);
1862 if (reg.size() == 16) {
1863 encoder.prefix16BitMode();
1864 }
1862 encoder.rex(.{1865 encoder.rex(.{
1863 .w = setRexWRegister(reg) or setRexWRegister(src_reg),1866 .w = setRexWRegister(reg) or setRexWRegister(src_reg),
1864 .r = reg.isExtended(),1867 .r = reg.isExtended(),
...@@ -1902,6 +1905,9 @@ fn lowerToMrEnc(...@@ -1902,6 +1905,9 @@ fn lowerToMrEnc(
1902 switch (reg_or_mem) {1905 switch (reg_or_mem) {
1903 .register => |dst_reg| {1906 .register => |dst_reg| {
1904 const encoder = try Encoder.init(code, 3);1907 const encoder = try Encoder.init(code, 3);
1908 if (dst_reg.size() == 16) {
1909 encoder.prefix16BitMode();
1910 }
1905 encoder.rex(.{1911 encoder.rex(.{
1906 .w = setRexWRegister(dst_reg) or setRexWRegister(reg),1912 .w = setRexWRegister(dst_reg) or setRexWRegister(reg),
1907 .r = reg.isExtended(),1913 .r = reg.isExtended(),
test/behavior/union.zig-11
...@@ -171,7 +171,6 @@ test "access a member of tagged union with conflicting enum tag name" {...@@ -171,7 +171,6 @@ test "access a member of tagged union with conflicting enum tag name" {
171}171}
172172
173test "constant tagged union with payload" {173test "constant tagged union with payload" {
174 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;
175 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;174 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
176 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;175 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
177176
...@@ -271,7 +270,6 @@ fn testComparison() !void {...@@ -271,7 +270,6 @@ fn testComparison() !void {
271}270}
272271
273test "comparison between union and enum literal" {272test "comparison between union and enum literal" {
274 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;
275 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;273 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
276 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;274 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
277275
...@@ -343,7 +341,6 @@ pub const PackThis = union(enum) {...@@ -343,7 +341,6 @@ pub const PackThis = union(enum) {
343};341};
344342
345test "constant packed union" {343test "constant packed union" {
346 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;
347 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;344 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
348 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;345 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
349346
...@@ -509,7 +506,6 @@ test "update the tag value for zero-sized unions" {...@@ -509,7 +506,6 @@ test "update the tag value for zero-sized unions" {
509}506}
510507
511test "union initializer generates padding only if needed" {508test "union initializer generates padding only if needed" {
512 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;
513 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;509 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
514 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;510 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
515511
...@@ -522,7 +518,6 @@ test "union initializer generates padding only if needed" {...@@ -522,7 +518,6 @@ test "union initializer generates padding only if needed" {
522}518}
523519
524test "runtime tag name with single field" {520test "runtime tag name with single field" {
525 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;
526 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;521 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
527 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;522 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
528523
...@@ -535,7 +530,6 @@ test "runtime tag name with single field" {...@@ -535,7 +530,6 @@ test "runtime tag name with single field" {
535}530}
536531
537test "method call on an empty union" {532test "method call on an empty union" {
538 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;
539 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;533 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
540 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;534 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
541535
...@@ -599,7 +593,6 @@ test "tagged union type" {...@@ -599,7 +593,6 @@ test "tagged union type" {
599}593}
600594
601test "tagged union as return value" {595test "tagged union as return value" {
602 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;
603 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;596 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
604 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;597 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
605598
...@@ -680,7 +673,6 @@ fn testEnumWithSpecifiedAndUnspecifiedTagValues(x: MultipleChoice2) !void {...@@ -680,7 +673,6 @@ fn testEnumWithSpecifiedAndUnspecifiedTagValues(x: MultipleChoice2) !void {
680}673}
681674
682test "switch on union with only 1 field" {675test "switch on union with only 1 field" {
683 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
684 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO676 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
685 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO677 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
686678
...@@ -710,7 +702,6 @@ const PartialInstWithPayload = union(enum) {...@@ -710,7 +702,6 @@ const PartialInstWithPayload = union(enum) {
710};702};
711703
712test "union with only 1 field casted to its enum type which has enum value specified" {704test "union with only 1 field casted to its enum type which has enum value specified" {
713 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;
714 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;705 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
715 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;706 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
716707
...@@ -848,7 +839,6 @@ test "@unionInit stored to a const" {...@@ -848,7 +839,6 @@ test "@unionInit stored to a const" {
848}839}
849840
850test "@unionInit can modify a union type" {841test "@unionInit can modify a union type" {
851 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
852 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO842 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
853 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO843 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
854844
...@@ -891,7 +881,6 @@ test "@unionInit can modify a pointer value" {...@@ -891,7 +881,6 @@ test "@unionInit can modify a pointer value" {
891}881}
892882
893test "union no tag with struct member" {883test "union no tag with struct member" {
894 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
895 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO884 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
896 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO885 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
897886