authorgravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2021-12-23 20:51:48+01:00
committergravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2021-12-23 20:51:48+01:00
logdba5df64eacfbcca9727fe8596b186defb30a753
tree00cdd4f4926243ef70e15a0c5dc06a916e65b281
parentc50bb2b80f3ccdc361a12034e7919f5288131c5e

stage2: use lowerToRmEnc to lower two-operand imul

Fix mismatched register sizes in codegen.

2 files changed, 5 insertions(+), 12 deletions(-)

src/arch/x86_64/CodeGen.zig+2-2
...@@ -1717,7 +1717,7 @@ fn genIMulOpMir(self: *Self, dst_ty: Type, dst_mcv: MCValue, src_mcv: MCValue) !...@@ -1717,7 +1717,7 @@ fn genIMulOpMir(self: *Self, dst_ty: Type, dst_mcv: MCValue, src_mcv: MCValue) !
1717 _ = try self.addInst(.{1717 _ = try self.addInst(.{
1718 .tag = .imul_complex,1718 .tag = .imul_complex,
1719 .ops = (Mir.Ops{1719 .ops = (Mir.Ops{
1720 .reg1 = dst_reg,1720 .reg1 = registerAlias(dst_reg, @divExact(src_reg.size(), 8)),
1721 .reg2 = src_reg,1721 .reg2 = src_reg,
1722 }).encode(),1722 }).encode(),
1723 .data = undefined,1723 .data = undefined,
...@@ -1766,7 +1766,7 @@ fn genIMulOpMir(self: *Self, dst_ty: Type, dst_mcv: MCValue, src_mcv: MCValue) !...@@ -1766,7 +1766,7 @@ fn genIMulOpMir(self: *Self, dst_ty: Type, dst_mcv: MCValue, src_mcv: MCValue) !
1766 _ = try self.addInst(.{1766 _ = try self.addInst(.{
1767 .tag = .imul_complex,1767 .tag = .imul_complex,
1768 .ops = (Mir.Ops{1768 .ops = (Mir.Ops{
1769 .reg1 = dst_reg,1769 .reg1 = registerAlias(dst_reg, @divExact(src_reg.size(), 8)),
1770 .reg2 = src_reg,1770 .reg2 = src_reg,
1771 }).encode(),1771 }).encode(),
1772 .data = undefined,1772 .data = undefined,
src/arch/x86_64/Emit.zig+3-10
...@@ -380,6 +380,7 @@ const Tag = enum {...@@ -380,6 +380,7 @@ const Tag = enum {
380 @"test",380 @"test",
381 brk,381 brk,
382 nop,382 nop,
383 imul,
383 syscall,384 syscall,
384 ret_near,385 ret_near,
385 ret_far,386 ret_far,
...@@ -635,6 +636,7 @@ inline fn getOpCode(tag: Tag, enc: Encoding, is_one_byte: bool) ?OpCode {...@@ -635,6 +636,7 @@ inline fn getOpCode(tag: Tag, enc: Encoding, is_one_byte: bool) ?OpCode {
635 .cmp => OpCode.oneByte(if (is_one_byte) 0x3a else 0x3b),636 .cmp => OpCode.oneByte(if (is_one_byte) 0x3a else 0x3b),
636 .mov => OpCode.oneByte(if (is_one_byte) 0x8a else 0x8b),637 .mov => OpCode.oneByte(if (is_one_byte) 0x8a else 0x8b),
637 .lea => OpCode.oneByte(if (is_one_byte) 0x8c else 0x8d),638 .lea => OpCode.oneByte(if (is_one_byte) 0x8c else 0x8d),
639 .imul => OpCode.twoByte(0x0f, 0xaf),
638 else => null,640 else => null,
639 },641 },
640 .oi => return switch (tag) {642 .oi => return switch (tag) {
...@@ -1378,16 +1380,7 @@ fn mirIMulComplex(emit: *Emit, inst: Mir.Inst.Index) InnerError!void {...@@ -1378,16 +1380,7 @@ fn mirIMulComplex(emit: *Emit, inst: Mir.Inst.Index) InnerError!void {
1378 assert(tag == .imul_complex);1380 assert(tag == .imul_complex);
1379 const ops = Mir.Ops.decode(emit.mir.instructions.items(.ops)[inst]);1381 const ops = Mir.Ops.decode(emit.mir.instructions.items(.ops)[inst]);
1380 switch (ops.flags) {1382 switch (ops.flags) {
1381 0b00 => {1383 0b00 => return lowerToRmEnc(.imul, ops.reg1, RegisterOrMemory.reg(ops.reg2), emit.code),
1382 const encoder = try Encoder.init(emit.code, 4);
1383 encoder.rex(.{
1384 .w = ops.reg1.size() == 64,
1385 .r = ops.reg1.isExtended(),
1386 .b = ops.reg2.isExtended(),
1387 });
1388 encoder.opcode_2byte(0x0f, 0xaf);
1389 encoder.modRm_direct(ops.reg1.lowId(), ops.reg2.lowId());
1390 },
1391 0b10 => {1384 0b10 => {
1392 const imm = emit.mir.instructions.items(.data)[inst].imm;1385 const imm = emit.mir.instructions.items(.data)[inst].imm;
1393 const opc: u8 = if (imm <= math.maxInt(i8)) 0x6b else 0x69;1386 const opc: u8 = if (imm <= math.maxInt(i8)) 0x6b else 0x69;