[llvm] r339622 - [X86] Don't ignore 0x66 prefix on relative jumps in 64-bit mode. Fix opcode selection of relative jumps in 16-bit mode. Treat jno/jo like other jcc instructions.

Craig Topper via llvm-commits llvm-commits at lists.llvm.org
Mon Aug 13 15:06:28 PDT 2018


Author: ctopper
Date: Mon Aug 13 15:06:28 2018
New Revision: 339622

URL: http://llvm.org/viewvc/llvm-project?rev=339622&view=rev
Log:
[X86] Don't ignore 0x66 prefix on relative jumps in 64-bit mode. Fix opcode selection of relative jumps in 16-bit mode. Treat jno/jo like other jcc instructions.

The behavior in 64-bit mode is different between Intel and AMD CPUs. Intel ignores the 0x66 prefix. AMD does not. objump doesn't ignore the 0x66 prefix. Since LLVM aims to match objdump behavior, we should do the same.

While I was trying to fix this I had change brtarget16/32 to use ENCODING_IW/ID instead of ENCODING_Iv to get the 0x66+REX.W case to act sort of sanely. It's still wrong, but that's a problem for another day.

The change in encoding exposed the fact that 16-bit mode disassembly of relative jumps was creating JMP_4 with a 2 byte immediate. It should have been JMP_2. From just printing you can't tell the difference, but if you dumped the encoding it wouldn't have matched what we started with.

While fixing that, it exposed that jo/jno opcodes were missing from the switch that this patch deleted and there were no test cases for them.

Fixes PR38537.

Modified:
    llvm/trunk/lib/Target/X86/Disassembler/X86DisassemblerDecoder.cpp
    llvm/trunk/test/MC/Disassembler/X86/x86-64.txt
    llvm/trunk/utils/TableGen/X86RecognizableInstr.cpp

Modified: llvm/trunk/lib/Target/X86/Disassembler/X86DisassemblerDecoder.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/Disassembler/X86DisassemblerDecoder.cpp?rev=339622&r1=339621&r2=339622&view=diff
==============================================================================
--- llvm/trunk/lib/Target/X86/Disassembler/X86DisassemblerDecoder.cpp (original)
+++ llvm/trunk/lib/Target/X86/Disassembler/X86DisassemblerDecoder.cpp Mon Aug 13 15:06:28 2018
@@ -983,45 +983,18 @@ static int getID(struct InternalInstruct
       insn->opcode == 0xE3)
     attrMask ^= ATTR_ADSIZE;
 
-  /*
-   * In 64-bit mode all f64 superscripted opcodes ignore opcode size prefix
-   * CALL/JMP/JCC instructions need to ignore 0x66 and consume 4 bytes
-   */
+  // If we're in 16-bit mode and this is one of the relative jumps and opsize
+  // prefix isn't present, we need to force the opsize attribute since the
+  // prefix is inverted relative to 32-bit mode.
+  if (insn->mode == MODE_16BIT && !insn->hasOpSize &&
+      insn->opcodeType == ONEBYTE &&
+      (insn->opcode == 0xE8 || insn->opcode == 0xE9))
+    attrMask |= ATTR_OPSIZE;
 
-  if ((insn->mode == MODE_64BIT) && insn->hasOpSize) {
-    switch (insn->opcode) {
-    case 0xE8:
-    case 0xE9:
-      // Take care of psubsb and other mmx instructions.
-      if (insn->opcodeType == ONEBYTE) {
-        attrMask ^= ATTR_OPSIZE;
-        insn->immediateSize = 4;
-        insn->displacementSize = 4;
-      }
-      break;
-    case 0x82:
-    case 0x83:
-    case 0x84:
-    case 0x85:
-    case 0x86:
-    case 0x87:
-    case 0x88:
-    case 0x89:
-    case 0x8A:
-    case 0x8B:
-    case 0x8C:
-    case 0x8D:
-    case 0x8E:
-    case 0x8F:
-      // Take care of lea and three byte ops.
-      if (insn->opcodeType == TWOBYTE) {
-        attrMask ^= ATTR_OPSIZE;
-        insn->immediateSize = 4;
-        insn->displacementSize = 4;
-      }
-      break;
-    }
-  }
+  if (insn->mode == MODE_16BIT && !insn->hasOpSize &&
+      insn->opcodeType == TWOBYTE &&
+      insn->opcode >= 0x80 && insn->opcode <= 0x8F)
+    attrMask |= ATTR_OPSIZE;
 
   if (getIDWithAttrMask(&instructionID, insn, attrMask))
     return -1;

Modified: llvm/trunk/test/MC/Disassembler/X86/x86-64.txt
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/Disassembler/X86/x86-64.txt?rev=339622&r1=339621&r2=339622&view=diff
==============================================================================
--- llvm/trunk/test/MC/Disassembler/X86/x86-64.txt (original)
+++ llvm/trunk/test/MC/Disassembler/X86/x86-64.txt Mon Aug 13 15:06:28 2018
@@ -326,104 +326,116 @@
 # CHECK: movq %rax, 1515870810
 0x67, 0x48 0xa3 0x5a 0x5a 0x5a 0x5a
 
-# CHECK: callq -32769
-0x66 0xe8 0xff 0x7f 0xff 0xff
+# CHECK: callw 32767
+0x66 0xe8 0xff 0x7f
 
-# CHECK: callq -32769
-0x66 0x66 0x48 0xe8 0xff 0x7f 0xff 0xff
+# CHECK: callw 32767
+0x66 0x66 0x48 0xe8 0xff 0x7f
 
 # CHECK: jmp -32769
 0xe9 0xff 0x7f 0xff 0xff
 
-# CHECK: jmp -32769
-0x66 0xe9 0xff 0x7f 0xff 0xff
+# CHECK: jmp 32767
+0x66 0xe9 0xff 0x7f
 
-# CHECK: jmp -32769
-0x66 0x66 0x48 0xe9 0xff 0x7f 0xff 0xff
+# CHECK: jmp 32767
+0x66 0x66 0x48 0xe9 0xff 0x7f
+
+# CHECK: jo -32769
+0x0f 0x80 0xff 0x7f 0xff 0xff
+
+# CHECK: jo 32767
+0x66 0x0f 0x80 0xff 0x7f
+
+# CHECK: jno -32769
+0x0f 0x81 0xff 0x7f 0xff 0xff
+
+# CHECK: jno 32767
+0x66 0x0f 0x81 0xff 0x7f
 
 # CHECK: jb -32769
 0x0f 0x82 0xff 0x7f 0xff 0xff
 
-# CHECK: jb -32769
-0x66 0x0f 0x82 0xff 0x7f 0xff 0xff
+# CHECK: jb 32767
+0x66 0x0f 0x82 0xff 0x7f
 
 # CHECK: jae -32769
 0x0f 0x83 0xff 0x7f 0xff 0xff
 
-# CHECK: jae -32769
-0x66 0x0f 0x83 0xff 0x7f 0xff 0xff
+# CHECK: jae 32767
+0x66 0x0f 0x83 0xff 0x7f
 
 # CHECK: je -32769
 0x0f 0x84 0xff 0x7f 0xff 0xff
 
-# CHECK: je -32769
-0x66 0x0f 0x84 0xff 0x7f 0xff 0xff
+# CHECK: je 32767
+0x66 0x0f 0x84 0xff 0x7f
 
 # CHECK: jne -32769
 0x0f 0x85 0xff 0x7f 0xff 0xff
 
-# CHECK: jne -32769
-0x66 0x0f 0x85 0xff 0x7f 0xff 0xff
+# CHECK: jne 32767
+0x66 0x0f 0x85 0xff 0x7f
 
 # CHECK: jbe -32769
 0x0f 0x86 0xff 0x7f 0xff 0xff
 
-# CHECK: jbe -32769
-0x66 0x0f 0x86 0xff 0x7f 0xff 0xff
+# CHECK: jbe 32767
+0x66 0x0f 0x86 0xff 0x7f
 
 # CHECK: ja -32769
 0x0f 0x87 0xff 0x7f 0xff 0xff
 
-# CHECK: ja -32769
-0x66 0x0f 0x87 0xff 0x7f 0xff 0xff
+# CHECK: ja 32767
+0x66 0x0f 0x87 0xff 0x7f
 
 # CHECK: js -32769
 0x0f 0x88 0xff 0x7f 0xff 0xff
 
-# CHECK: js -32769
-0x66 0x0f 0x88 0xff 0x7f 0xff 0xff
+# CHECK: js 32767
+0x66 0x0f 0x88 0xff 0x7f
 
 # CHECK: jns -32769
 0x0f 0x89 0xff 0x7f 0xff 0xff
 
-# CHECK: jns -32769
-0x66 0x0f 0x89 0xff 0x7f 0xff 0xff
+# CHECK: jns 32767
+0x66 0x0f 0x89 0xff 0x7f
 
 # CHECK: jp -32769
 0x0f 0x8a 0xff 0x7f 0xff 0xff
 
-# CHECK: jp -32769
-0x66 0x0f 0x8a 0xff 0x7f 0xff 0xff
+# CHECK: jp 32767
+0x66 0x0f 0x8a 0xff 0x7f
 
 # CHECK: jnp -32769
 0x0f 0x8b 0xff 0x7f 0xff 0xff
 
-# CHECK: jnp -32769
-0x66 0x0f 0x8b 0xff 0x7f 0xff 0xff
+# CHECK: jnp 32767
+0x66 0x0f 0x8b 0xff 0x7f
 
 # CHECK: jl -32769
 0x0f 0x8c 0xff 0x7f 0xff 0xff
 
-# CHECK: jl -32769
-0x66 0x0f 0x8c 0xff 0x7f 0xff 0xff
+# CHECK: jl 32767
+0x66 0x0f 0x8c 0xff 0x7f
 
 # CHECK: jge -32769
 0x0f 0x8d 0xff 0x7f 0xff 0xff
 
-# CHECK: jge -32769
-0x66 0x0f 0x8d 0xff 0x7f 0xff 0xff
+# CHECK: jge 32767
+0x66 0x0f 0x8d 0xff 0x7f
 
 # CHECK: jle -32769
 0x0f 0x8e 0xff 0x7f 0xff 0xff
 
-# CHECK: jle -32769
-0x66 0x0f 0x8e 0xff 0x7f 0xff 0xff
+# CHECK: jle 32767
+0x66 0x0f 0x8e 0xff 0x7f
 
 # CHECK: jg -32769
 0x0f 0x8f 0xff 0x7f 0xff 0xff
 
-# CHECK: jg -32769
-0x66 0x0f 0x8f 0xff 0x7f 0xff 0xff
+# CHECK: jg 32767
+0x66 0x0f 0x8f 0xff 0x7f
 
 # CHECK: lcallw	*-32769(%rip)
 0x66 0xff 0x1d 0xff 0x7f 0xff 0xff

Modified: llvm/trunk/utils/TableGen/X86RecognizableInstr.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/X86RecognizableInstr.cpp?rev=339622&r1=339621&r2=339622&view=diff
==============================================================================
--- llvm/trunk/utils/TableGen/X86RecognizableInstr.cpp (original)
+++ llvm/trunk/utils/TableGen/X86RecognizableInstr.cpp Mon Aug 13 15:06:28 2018
@@ -1132,8 +1132,8 @@ RecognizableInstr::relocationEncodingFro
   ENCODING("i64i32imm_pcrel", ENCODING_ID)
   ENCODING("i16imm_pcrel",    ENCODING_IW)
   ENCODING("i32imm_pcrel",    ENCODING_ID)
-  ENCODING("brtarget32",      ENCODING_Iv)
-  ENCODING("brtarget16",      ENCODING_Iv)
+  ENCODING("brtarget32",      ENCODING_ID)
+  ENCODING("brtarget16",      ENCODING_IW)
   ENCODING("brtarget8",       ENCODING_IB)
   ENCODING("i64imm",          ENCODING_IO)
   ENCODING("offset16_8",      ENCODING_Ia)




More information about the llvm-commits mailing list