mirror of
https://github.com/ziglang/zig.git
synced 2026-02-21 16:54:52 +00:00
stage2: use lowerToRmEnc to lower two-operand imul
Fix mismatched register sizes in codegen.
This commit is contained in:
parent
c50bb2b80f
commit
dba5df64ea
@ -1717,7 +1717,7 @@ fn genIMulOpMir(self: *Self, dst_ty: Type, dst_mcv: MCValue, src_mcv: MCValue) !
|
|||||||
_ = try self.addInst(.{
|
_ = try self.addInst(.{
|
||||||
.tag = .imul_complex,
|
.tag = .imul_complex,
|
||||||
.ops = (Mir.Ops{
|
.ops = (Mir.Ops{
|
||||||
.reg1 = dst_reg,
|
.reg1 = registerAlias(dst_reg, @divExact(src_reg.size(), 8)),
|
||||||
.reg2 = src_reg,
|
.reg2 = src_reg,
|
||||||
}).encode(),
|
}).encode(),
|
||||||
.data = undefined,
|
.data = undefined,
|
||||||
@ -1766,7 +1766,7 @@ fn genIMulOpMir(self: *Self, dst_ty: Type, dst_mcv: MCValue, src_mcv: MCValue) !
|
|||||||
_ = try self.addInst(.{
|
_ = try self.addInst(.{
|
||||||
.tag = .imul_complex,
|
.tag = .imul_complex,
|
||||||
.ops = (Mir.Ops{
|
.ops = (Mir.Ops{
|
||||||
.reg1 = dst_reg,
|
.reg1 = registerAlias(dst_reg, @divExact(src_reg.size(), 8)),
|
||||||
.reg2 = src_reg,
|
.reg2 = src_reg,
|
||||||
}).encode(),
|
}).encode(),
|
||||||
.data = undefined,
|
.data = undefined,
|
||||||
|
|||||||
@ -380,6 +380,7 @@ const Tag = enum {
|
|||||||
@"test",
|
@"test",
|
||||||
brk,
|
brk,
|
||||||
nop,
|
nop,
|
||||||
|
imul,
|
||||||
syscall,
|
syscall,
|
||||||
ret_near,
|
ret_near,
|
||||||
ret_far,
|
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),
|
.cmp => OpCode.oneByte(if (is_one_byte) 0x3a else 0x3b),
|
||||||
.mov => OpCode.oneByte(if (is_one_byte) 0x8a else 0x8b),
|
.mov => OpCode.oneByte(if (is_one_byte) 0x8a else 0x8b),
|
||||||
.lea => OpCode.oneByte(if (is_one_byte) 0x8c else 0x8d),
|
.lea => OpCode.oneByte(if (is_one_byte) 0x8c else 0x8d),
|
||||||
|
.imul => OpCode.twoByte(0x0f, 0xaf),
|
||||||
else => null,
|
else => null,
|
||||||
},
|
},
|
||||||
.oi => return switch (tag) {
|
.oi => return switch (tag) {
|
||||||
@ -1378,16 +1380,7 @@ fn mirIMulComplex(emit: *Emit, inst: Mir.Inst.Index) InnerError!void {
|
|||||||
assert(tag == .imul_complex);
|
assert(tag == .imul_complex);
|
||||||
const ops = Mir.Ops.decode(emit.mir.instructions.items(.ops)[inst]);
|
const ops = Mir.Ops.decode(emit.mir.instructions.items(.ops)[inst]);
|
||||||
switch (ops.flags) {
|
switch (ops.flags) {
|
||||||
0b00 => {
|
0b00 => return lowerToRmEnc(.imul, ops.reg1, RegisterOrMemory.reg(ops.reg2), emit.code),
|
||||||
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());
|
|
||||||
},
|
|
||||||
0b10 => {
|
0b10 => {
|
||||||
const imm = emit.mir.instructions.items(.data)[inst].imm;
|
const imm = emit.mir.instructions.items(.data)[inst].imm;
|
||||||
const opc: u8 = if (imm <= math.maxInt(i8)) 0x6b else 0x69;
|
const opc: u8 = if (imm <= math.maxInt(i8)) 0x6b else 0x69;
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user