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

Craig Topper via llvm-commits llvm-commits at lists.llvm.org
Mon Jul 27 21:17:10 PDT 2020


Author: Craig Topper
Date: 2020-07-27T21:11:42-07:00
New Revision: a0ebac52df6d890fcba52e7db9ac66d0fc7c2582

URL: https://github.com/llvm/llvm-project/commit/a0ebac52df6d890fcba52e7db9ac66d0fc7c2582
DIFF: https://github.com/llvm/llvm-project/commit/a0ebac52df6d890fcba52e7db9ac66d0fc7c2582.diff

LOG: [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.

Added: 
    

Modified: 
    llvm/lib/Target/X86/MCTargetDesc/X86MCCodeEmitter.cpp
    llvm/test/MC/X86/code16gcc.s

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Target/X86/MCTargetDesc/X86MCCodeEmitter.cpp b/llvm/lib/Target/X86/MCTargetDesc/X86MCCodeEmitter.cpp
index 7dea0760a831..5f1b5b5e2b96 100644
--- a/llvm/lib/Target/X86/MCTargetDesc/X86MCCodeEmitter.cpp
+++ b/llvm/lib/Target/X86/MCTargetDesc/X86MCCodeEmitter.cpp
@@ -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);
     }

diff  --git a/llvm/test/MC/X86/code16gcc.s b/llvm/test/MC/X86/code16gcc.s
index 2391aeffe99a..8d8589a1117d 100644
--- a/llvm/test/MC/X86/code16gcc.s
+++ b/llvm/test/MC/X86/code16gcc.s
@@ -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]
 
 	
 


        


More information about the llvm-commits mailing list