aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJakub Konka <kubkon@jakubkonka.com>2021-12-23 20:51:48 +0100
committerJakub Konka <kubkon@jakubkonka.com>2021-12-23 20:51:48 +0100
commitdba5df64eacfbcca9727fe8596b186defb30a753 (patch)
tree00cdd4f4926243ef70e15a0c5dc06a916e65b281
parentc50bb2b80f3ccdc361a12034e7919f5288131c5e (diff)
downloadzig-dba5df64eacfbcca9727fe8596b186defb30a753.tar.gz
zig-dba5df64eacfbcca9727fe8596b186defb30a753.zip
stage2: use lowerToRmEnc to lower two-operand imul
Fix mismatched register sizes in codegen.
-rw-r--r--src/arch/x86_64/CodeGen.zig4
-rw-r--r--src/arch/x86_64/Emit.zig13
2 files changed, 5 insertions, 12 deletions
diff --git a/src/arch/x86_64/CodeGen.zig b/src/arch/x86_64/CodeGen.zig
index 65bd3b857c..08a926216c 100644
--- a/src/arch/x86_64/CodeGen.zig
+++ b/src/arch/x86_64/CodeGen.zig
@@ -1717,7 +1717,7 @@ fn genIMulOpMir(self: *Self, dst_ty: Type, dst_mcv: MCValue, src_mcv: MCValue) !
_ = try self.addInst(.{
.tag = .imul_complex,
.ops = (Mir.Ops{
- .reg1 = dst_reg,
+ .reg1 = registerAlias(dst_reg, @divExact(src_reg.size(), 8)),
.reg2 = src_reg,
}).encode(),
.data = undefined,
@@ -1766,7 +1766,7 @@ fn genIMulOpMir(self: *Self, dst_ty: Type, dst_mcv: MCValue, src_mcv: MCValue) !
_ = try self.addInst(.{
.tag = .imul_complex,
.ops = (Mir.Ops{
- .reg1 = dst_reg,
+ .reg1 = registerAlias(dst_reg, @divExact(src_reg.size(), 8)),
.reg2 = src_reg,
}).encode(),
.data = undefined,
diff --git a/src/arch/x86_64/Emit.zig b/src/arch/x86_64/Emit.zig
index 83268b5432..0694a6ed2c 100644
--- a/src/arch/x86_64/Emit.zig
+++ b/src/arch/x86_64/Emit.zig
@@ -380,6 +380,7 @@ const Tag = enum {
@"test",
brk,
nop,
+ imul,
syscall,
ret_near,
ret_far,
@@ -635,6 +636,7 @@ inline fn getOpCode(tag: Tag, enc: Encoding, is_one_byte: bool) ?OpCode {
.cmp => OpCode.oneByte(if (is_one_byte) 0x3a else 0x3b),
.mov => OpCode.oneByte(if (is_one_byte) 0x8a else 0x8b),
.lea => OpCode.oneByte(if (is_one_byte) 0x8c else 0x8d),
+ .imul => OpCode.twoByte(0x0f, 0xaf),
else => null,
},
.oi => return switch (tag) {
@@ -1378,16 +1380,7 @@ fn mirIMulComplex(emit: *Emit, inst: Mir.Inst.Index) InnerError!void {
assert(tag == .imul_complex);
const ops = Mir.Ops.decode(emit.mir.instructions.items(.ops)[inst]);
switch (ops.flags) {
- 0b00 => {
- const encoder = try Encoder.init(emit.code, 4);
- encoder.rex(.{
- .w = ops.reg1.size() == 64,
- .r = ops.reg1.isExtended(),
- .b = ops.reg2.isExtended(),
- });
- encoder.opcode_2byte(0x0f, 0xaf);
- encoder.modRm_direct(ops.reg1.lowId(), ops.reg2.lowId());
- },
+ 0b00 => return lowerToRmEnc(.imul, ops.reg1, RegisterOrMemory.reg(ops.reg2), emit.code),
0b10 => {
const imm = emit.mir.instructions.items(.data)[inst].imm;
const opc: u8 = if (imm <= math.maxInt(i8)) 0x6b else 0x69;