diff options
| author | Jakub Konka <kubkon@jakubkonka.com> | 2022-02-28 15:25:40 +0100 |
|---|---|---|
| committer | Jakub Konka <kubkon@jakubkonka.com> | 2022-02-28 15:25:40 +0100 |
| commit | 16f9774d2d6f358c97637e35609dfe0fc14cb501 (patch) | |
| tree | 7f9978d06d450c715662c765a3257402915987d7 /src | |
| parent | a61ac9ecbf42a97a4f56f7384e5b862dcb169f4a (diff) | |
| download | zig-16f9774d2d6f358c97637e35609dfe0fc14cb501.tar.gz zig-16f9774d2d6f358c97637e35609dfe0fc14cb501.zip | |
x64: fix switch condition mir; pass more union tests
Diffstat (limited to 'src')
| -rw-r--r-- | src/arch/x86_64/CodeGen.zig | 34 | ||||
| -rw-r--r-- | src/arch/x86_64/Emit.zig | 6 |
2 files changed, 24 insertions, 16 deletions
diff --git a/src/arch/x86_64/CodeGen.zig b/src/arch/x86_64/CodeGen.zig index bf5ebf4d41..45d9767320 100644 --- a/src/arch/x86_64/CodeGen.zig +++ b/src/arch/x86_64/CodeGen.zig @@ -3967,36 +3967,22 @@ fn genCondSwitchMir(self: *Self, ty: Type, condition: MCValue, case: MCValue) !u .dead, .unreach => unreachable, .immediate => |imm| { _ = try self.addInst(.{ - .tag = .@"test", + .tag = .xor, .ops = (Mir.Ops{ .reg1 = registerAlias(cond_reg, abi_size), }).encode(), .data = .{ .imm = @intCast(u32, imm) }, }); - return self.addInst(.{ - .tag = .cond_jmp_eq_ne, - .ops = (Mir.Ops{ - .flags = 0b00, - }).encode(), - .data = .{ .inst = undefined }, - }); }, .register => |reg| { _ = try self.addInst(.{ - .tag = .@"test", + .tag = .xor, .ops = (Mir.Ops{ .reg1 = registerAlias(cond_reg, abi_size), .reg2 = registerAlias(reg, abi_size), }).encode(), .data = undefined, }); - return self.addInst(.{ - .tag = .cond_jmp_eq_ne, - .ops = (Mir.Ops{ - .flags = 0b00, - }).encode(), - .data = .{ .inst = undefined }, - }); }, .stack_offset => { if (abi_size <= 8) { @@ -4010,6 +3996,22 @@ fn genCondSwitchMir(self: *Self, ty: Type, condition: MCValue, case: MCValue) !u return self.fail("TODO implement switch mir when case is {}", .{case}); }, } + + _ = try self.addInst(.{ + .tag = .@"test", + .ops = (Mir.Ops{ + .reg1 = registerAlias(cond_reg, abi_size), + .reg2 = registerAlias(cond_reg, abi_size), + }).encode(), + .data = undefined, + }); + return self.addInst(.{ + .tag = .cond_jmp_eq_ne, + .ops = (Mir.Ops{ + .flags = 0b00, + }).encode(), + .data = .{ .inst = undefined }, + }); }, .stack_offset => { try self.spillCompareFlagsIfOccupied(); diff --git a/src/arch/x86_64/Emit.zig b/src/arch/x86_64/Emit.zig index fc43e61c17..f4d365dc4f 100644 --- a/src/arch/x86_64/Emit.zig +++ b/src/arch/x86_64/Emit.zig @@ -1859,6 +1859,9 @@ fn lowerToRmEnc( switch (reg_or_mem) { .register => |src_reg| { const encoder = try Encoder.init(code, 4); + if (reg.size() == 16) { + encoder.prefix16BitMode(); + } encoder.rex(.{ .w = setRexWRegister(reg) or setRexWRegister(src_reg), .r = reg.isExtended(), @@ -1902,6 +1905,9 @@ fn lowerToMrEnc( switch (reg_or_mem) { .register => |dst_reg| { const encoder = try Encoder.init(code, 3); + if (dst_reg.size() == 16) { + encoder.prefix16BitMode(); + } encoder.rex(.{ .w = setRexWRegister(dst_reg) or setRexWRegister(reg), .r = reg.isExtended(), |
