1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2024-10-19 11:02:59 +02:00

[X86] Properly encode a 32-bit address with an index register and no base register in 16-bit mode.

In 16-bit mode we can encode a 32-bit address using 0x67 prefix.
We were failing to do this when the index register was a 32-bit
register, the base register was not present, and the displacement
fit in 16-bits.

Fixes PR46866.
This commit is contained in:
Craig Topper 2020-07-27 21:11:42 -07:00
parent 51d4708437
commit 07857b037c
2 changed files with 14 additions and 8 deletions

View File

@ -164,17 +164,20 @@ static MCFixupKind getImmFixupKind(uint64_t TSFlags) {
/// \returns true if the specified instruction has a 16-bit memory operand.
static bool is16BitMemOperand(const MCInst &MI, unsigned Op,
const MCSubtargetInfo &STI) {
const MCOperand &BaseReg = MI.getOperand(Op + X86::AddrBaseReg);
const MCOperand &IndexReg = MI.getOperand(Op + X86::AddrIndexReg);
const MCOperand &Base = MI.getOperand(Op + X86::AddrBaseReg);
const MCOperand &Index = MI.getOperand(Op + X86::AddrIndexReg);
const MCOperand &Disp = MI.getOperand(Op + X86::AddrDisp);
if (STI.hasFeature(X86::Mode16Bit) && BaseReg.getReg() == 0 && Disp.isImm() &&
Disp.getImm() < 0x10000)
unsigned BaseReg = Base.getReg();
unsigned IndexReg = Index.getReg();
if (STI.hasFeature(X86::Mode16Bit) && BaseReg == 0 && IndexReg == 0 &&
Disp.isImm() && Disp.getImm() < 0x10000)
return true;
if ((BaseReg.getReg() != 0 &&
X86MCRegisterClasses[X86::GR16RegClassID].contains(BaseReg.getReg())) ||
(IndexReg.getReg() != 0 &&
X86MCRegisterClasses[X86::GR16RegClassID].contains(IndexReg.getReg())))
if ((BaseReg != 0 &&
X86MCRegisterClasses[X86::GR16RegClassID].contains(BaseReg)) ||
(IndexReg != 0 &&
X86MCRegisterClasses[X86::GR16RegClassID].contains(IndexReg)))
return true;
return false;
}
@ -498,6 +501,7 @@ void X86MCCodeEmitter::emitMemModRMByte(const MCInst &MI, unsigned Op,
// This is the [REG]+disp16 case.
emitByte(modRMByte(2, RegOpcodeField, RMfield), OS);
} else {
assert(IndexReg.getReg() == 0 && "Unexpected index register!");
// There is no BaseReg; this is the plain [disp16] case.
emitByte(modRMByte(0, RegOpcodeField, 6), OS);
}

View File

@ -62,6 +62,8 @@
//CHECK: popfl # encoding: [0x66,0x9d]
pushw 4
//CHECK: pushw 4 # encoding: [0xff,0x36,0x04,0x00]
addw $1, (,%eax,4)
//CHECK: addw $1, (,%eax,4) # encoding: [0x67,0x83,0x04,0x85,0x00,0x00,0x00,0x00,0x01]