Skip to content

Commit

Permalink
[X86] Properly encode a 32-bit address with an index register and no …
Browse files Browse the repository at this point in the history
…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.
  • Loading branch information
topperc committed Jul 28, 2020
1 parent a23f623 commit a0ebac5
Show file tree
Hide file tree
Showing 2 changed files with 14 additions and 8 deletions.
20 changes: 12 additions & 8 deletions llvm/lib/Target/X86/MCTargetDesc/X86MCCodeEmitter.cpp
Expand Up @@ -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;
}
Expand Down Expand Up @@ -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);
}
Expand Down
2 changes: 2 additions & 0 deletions llvm/test/MC/X86/code16gcc.s
Expand Up @@ -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]



0 comments on commit a0ebac5

Please sign in to comment.