[x86] Fix 16-bit disassembly of JCXZ/JECXZ
authorDavid Woodhouse <dwmw2@infradead.org>
Mon, 20 Jan 2014 12:02:48 +0000 (12:02 +0000)
committerDavid Woodhouse <dwmw2@infradead.org>
Mon, 20 Jan 2014 12:02:48 +0000 (12:02 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@199653 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Target/X86/Disassembler/X86DisassemblerDecoder.c
test/MC/Disassembler/X86/x86-16.txt

index 66badd95c32e508d77cc47439f6767c5a7b34e11..48c16977133c9f58f0659e914d213890273931c6 100644 (file)
@@ -987,6 +987,25 @@ static int getID(struct InternalInstruction* insn, const void *miiArg) {
   if (getIDWithAttrMask(&instructionID, insn, attrMask))
     return -1;
 
+  /*
+   * JCXZ/JECXZ need special handling for 16-bit mode because the meaning
+   * of the AdSize prefix is inverted w.r.t. 32-bit mode.
+   */
+  if (insn->mode == MODE_16BIT && insn->opcode == 0xE3) {
+    const struct InstructionSpecifier *spec;
+    spec = specifierForUID(instructionID);
+
+    /*
+     * Check for Ii8PCRel instructions. We could alternatively do a
+     * string-compare on the names, but this is probably cheaper.
+     */
+    if (x86OperandSets[spec->operands][0].type == TYPE_REL8) {
+      attrMask ^= ATTR_ADSIZE;
+      if (getIDWithAttrMask(&instructionID, insn, attrMask))
+        return -1;
+    }
+  }
+
   /* The following clauses compensate for limitations of the tables. */
 
   if ((insn->mode == MODE_16BIT || insn->prefixPresent[0x66]) &&
index 83be869fa26b98f40d80c6ddc8909e6ec7019bbe..93974d433e3d418c7f4abf55ba89dd9726163433 100644 (file)
 # CHECK: lcalll $2, $4660
 0x66 0x9a 0x34 0x12 0x00 0x00 0x02 0x00
 
-# CHECKX: jcxz
+# CHECK: jcxz
 0xe3 0x00
 
-# CHECKX: jecxz
+# CHECK: jecxz
 0x67 0xe3 0x00
 
 # CHECK: iretw