diff options
Diffstat (limited to 'lib/Target/X86/Disassembler/X86DisassemblerDecoder.cpp')
-rw-r--r-- | lib/Target/X86/Disassembler/X86DisassemblerDecoder.cpp | 63 |
1 files changed, 32 insertions, 31 deletions
diff --git a/lib/Target/X86/Disassembler/X86DisassemblerDecoder.cpp b/lib/Target/X86/Disassembler/X86DisassemblerDecoder.cpp index 98b3440..619a0d4 100644 --- a/lib/Target/X86/Disassembler/X86DisassemblerDecoder.cpp +++ b/lib/Target/X86/Disassembler/X86DisassemblerDecoder.cpp @@ -975,27 +975,16 @@ static int getID(struct InternalInstruction* insn, const void *miiArg) { if (insn->rexPrefix & 0x08) attrMask |= ATTR_REXW; - 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); + if (insn->mode == MODE_16BIT && insn->opcodeType == ONEBYTE && + insn->opcode == 0xE3) + attrMask ^= ATTR_ADSIZE; - /* - * 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; - } - } + if (getIDWithAttrMask(&instructionID, insn, attrMask)) + return -1; /* The following clauses compensate for limitations of the tables. */ @@ -1030,6 +1019,32 @@ static int getID(struct InternalInstruction* insn, const void *miiArg) { } } + /* + * Absolute moves need special handling. + * -For 16-bit mode because the meaning of the AdSize and OpSize prefixes are + * inverted w.r.t. + * -For 32-bit mode we need to ensure the ADSIZE prefix is observed in + * any position. + */ + if (insn->opcodeType == ONEBYTE && ((insn->opcode & 0xFC) == 0xA0)) { + /* Make sure we observed the prefixes in any position. */ + if (insn->prefixPresent[0x67]) + attrMask |= ATTR_ADSIZE; + if (insn->prefixPresent[0x66]) + attrMask |= ATTR_OPSIZE; + + /* In 16-bit, invert the attributes. */ + if (insn->mode == MODE_16BIT) + attrMask ^= ATTR_ADSIZE | ATTR_OPSIZE; + + if (getIDWithAttrMask(&instructionID, insn, attrMask)) + return -1; + + insn->instructionID = instructionID; + insn->spec = specifierForUID(instructionID); + return 0; + } + if ((insn->mode == MODE_16BIT || insn->prefixPresent[0x66]) && !(attrMask & ATTR_OPSIZE)) { /* @@ -1445,22 +1460,14 @@ static int readModRM(struct InternalInstruction* insn) { case TYPE_VK16: \ return prefix##_K0 + index; \ case TYPE_MM64: \ - case TYPE_MM32: \ - case TYPE_MM: \ - if (index > 7) \ - *valid = 0; \ - return prefix##_MM0 + index; \ + return prefix##_MM0 + (index & 0x7); \ case TYPE_SEGMENTREG: \ if (index > 5) \ *valid = 0; \ return prefix##_ES + index; \ case TYPE_DEBUGREG: \ - if (index > 7) \ - *valid = 0; \ return prefix##_DR0 + index; \ case TYPE_CONTROLREG: \ - if (index > 8) \ - *valid = 0; \ return prefix##_CR0 + index; \ } \ } @@ -1737,12 +1744,6 @@ static int readOperands(struct InternalInstruction* insn) { } if (readImmediate(insn, 1)) return -1; - if (Op.type == TYPE_IMM3 && - insn->immediates[insn->numImmediatesConsumed - 1] > 7) - return -1; - if (Op.type == TYPE_IMM5 && - insn->immediates[insn->numImmediatesConsumed - 1] > 31) - return -1; if (Op.type == TYPE_XMM128 || Op.type == TYPE_XMM256) sawRegImm = 1; |