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
39673967 .dead, .unreach => unreachable,
39683968 .immediate => |imm| {
39693969 _ = try self.addInst(.{
3970 .tag = .@"test",
3970 .tag = .xor,
39713971 .ops = (Mir.Ops{
39723972 .reg1 = registerAlias(cond_reg, abi_size),
39733973 }).encode(),
39743974 .data = .{ .imm = @intCast(u32, imm) },
39753975 });
3976 return self.addInst(.{
3977 .tag = .cond_jmp_eq_ne,
3978 .ops = (Mir.Ops{
3979 .flags = 0b00,
3980 }).encode(),
3981 .data = .{ .inst = undefined },
3982 });
39833976 },
39843977 .register => |reg| {
39853978 _ = try self.addInst(.{
3986 .tag = .@"test",
3979 .tag = .xor,
39873980 .ops = (Mir.Ops{
39883981 .reg1 = registerAlias(cond_reg, abi_size),
39893982 .reg2 = registerAlias(reg, abi_size),
39903983 }).encode(),
39913984 .data = undefined,
39923985 });
3993 return self.addInst(.{
3994 .tag = .cond_jmp_eq_ne,
3995 .ops = (Mir.Ops{
3996 .flags = 0b00,
3997 }).encode(),
3998 .data = .{ .inst = undefined },
3999 });
40003986 },
40013987 .stack_offset => {
40023988 if (abi_size <= 8) {
......@@ -4010,6 +3996,22 @@ fn genCondSwitchMir(self: *Self, ty: Type, condition: MCValue, case: MCValue) !u
40103996 return self.fail("TODO implement switch mir when case is {}", .{case});
40113997 },
40123998 }
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 });
40134015 },
40144016 .stack_offset => {
40154017 try self.spillCompareFlagsIfOccupied();
src/arch/x86_64/Emit.zig+6
......@@ -1859,6 +1859,9 @@ fn lowerToRmEnc(
18591859 switch (reg_or_mem) {
18601860 .register => |src_reg| {
18611861 const encoder = try Encoder.init(code, 4);
1862 if (reg.size() == 16) {
1863 encoder.prefix16BitMode();
1864 }
18621865 encoder.rex(.{
18631866 .w = setRexWRegister(reg) or setRexWRegister(src_reg),
18641867 .r = reg.isExtended(),
......@@ -1902,6 +1905,9 @@ fn lowerToMrEnc(
19021905 switch (reg_or_mem) {
19031906 .register => |dst_reg| {
19041907 const encoder = try Encoder.init(code, 3);
1908 if (dst_reg.size() == 16) {
1909 encoder.prefix16BitMode();
1910 }
19051911 encoder.rex(.{
19061912 .w = setRexWRegister(dst_reg) or setRexWRegister(reg),
19071913 .r = reg.isExtended(),
test/behavior/union.zig-11
......@@ -171,7 +171,6 @@ test "access a member of tagged union with conflicting enum tag name" {
171171}
172172
173173test "constant tagged union with payload" {
174 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;
175174 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
176175 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
177176
......@@ -271,7 +270,6 @@ fn testComparison() !void {
271270}
272271
273272test "comparison between union and enum literal" {
274 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;
275273 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
276274 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
277275
......@@ -343,7 +341,6 @@ pub const PackThis = union(enum) {
343341};
344342
345343test "constant packed union" {
346 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;
347344 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
348345 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
349346
......@@ -509,7 +506,6 @@ test "update the tag value for zero-sized unions" {
509506}
510507
511508test "union initializer generates padding only if needed" {
512 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;
513509 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
514510 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
515511
......@@ -522,7 +518,6 @@ test "union initializer generates padding only if needed" {
522518}
523519
524520test "runtime tag name with single field" {
525 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;
526521 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
527522 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
528523
......@@ -535,7 +530,6 @@ test "runtime tag name with single field" {
535530}
536531
537532test "method call on an empty union" {
538 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;
539533 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
540534 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
541535
......@@ -599,7 +593,6 @@ test "tagged union type" {
599593}
600594
601595test "tagged union as return value" {
602 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;
603596 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
604597 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
605598
......@@ -680,7 +673,6 @@ fn testEnumWithSpecifiedAndUnspecifiedTagValues(x: MultipleChoice2) !void {
680673}
681674
682675test "switch on union with only 1 field" {
683 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
684676 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
685677 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
686678
......@@ -710,7 +702,6 @@ const PartialInstWithPayload = union(enum) {
710702};
711703
712704test "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;
714705 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
715706 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
716707
......@@ -848,7 +839,6 @@ test "@unionInit stored to a const" {
848839}
849840
850841test "@unionInit can modify a union type" {
851 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
852842 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
853843 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
854844
......@@ -891,7 +881,6 @@ test "@unionInit can modify a pointer value" {
891881}
892882
893883test "union no tag with struct member" {
894 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
895884 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
896885 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
897886