diff options
-rw-r--r-- | lib/Target/X86/Disassembler/X86DisassemblerDecoder.c | 2 | ||||
-rw-r--r-- | lib/Target/X86/Disassembler/X86DisassemblerDecoderCommon.h | 8 | ||||
-rw-r--r-- | lib/Target/X86/X86InstrControl.td | 2 | ||||
-rw-r--r-- | test/MC/Disassembler/X86/simple-tests.txt | 5 | ||||
-rw-r--r-- | test/MC/Disassembler/X86/x86-32.txt | 6 | ||||
-rw-r--r-- | utils/TableGen/X86DisassemblerTables.cpp | 9 | ||||
-rw-r--r-- | utils/TableGen/X86RecognizableInstr.cpp | 5 | ||||
-rw-r--r-- | utils/TableGen/X86RecognizableInstr.h | 2 |
8 files changed, 36 insertions, 3 deletions
diff --git a/lib/Target/X86/Disassembler/X86DisassemblerDecoder.c b/lib/Target/X86/Disassembler/X86DisassemblerDecoder.c index e2c76b7..b0e66f0 100644 --- a/lib/Target/X86/Disassembler/X86DisassemblerDecoder.c +++ b/lib/Target/X86/Disassembler/X86DisassemblerDecoder.c @@ -763,6 +763,8 @@ static int getID(struct InternalInstruction* insn, void *miiArg) { else { if (isPrefixAtLocation(insn, 0x66, insn->necessaryPrefixLocation)) attrMask |= ATTR_OPSIZE; + else if (isPrefixAtLocation(insn, 0x67, insn->necessaryPrefixLocation)) + attrMask |= ATTR_ADSIZE; else if (isPrefixAtLocation(insn, 0xf3, insn->necessaryPrefixLocation)) attrMask |= ATTR_XS; else if (isPrefixAtLocation(insn, 0xf2, insn->necessaryPrefixLocation)) diff --git a/lib/Target/X86/Disassembler/X86DisassemblerDecoderCommon.h b/lib/Target/X86/Disassembler/X86DisassemblerDecoderCommon.h index b5995c1..d5e7c69 100644 --- a/lib/Target/X86/Disassembler/X86DisassemblerDecoderCommon.h +++ b/lib/Target/X86/Disassembler/X86DisassemblerDecoderCommon.h @@ -54,8 +54,9 @@ ENUM_ENTRY(ATTR_XD, 0x04) \ ENUM_ENTRY(ATTR_REXW, 0x08) \ ENUM_ENTRY(ATTR_OPSIZE, 0x10) \ - ENUM_ENTRY(ATTR_VEX, 0x20) \ - ENUM_ENTRY(ATTR_VEXL, 0x40) + ENUM_ENTRY(ATTR_ADSIZE, 0x20) \ + ENUM_ENTRY(ATTR_VEX, 0x40) \ + ENUM_ENTRY(ATTR_VEXL, 0x80) #define ENUM_ENTRY(n, v) n = v, enum attributeBits { @@ -77,6 +78,8 @@ enum attributeBits { "64-bit mode but no more") \ ENUM_ENTRY(IC_OPSIZE, 3, "requires an OPSIZE prefix, so " \ "operands change width") \ + ENUM_ENTRY(IC_ADSIZE, 3, "requires an ADSIZE prefix, so " \ + "operands change width") \ ENUM_ENTRY(IC_XD, 2, "may say something about the opcode " \ "but not the operands") \ ENUM_ENTRY(IC_XS, 2, "may say something about the opcode " \ @@ -88,6 +91,7 @@ enum attributeBits { ENUM_ENTRY(IC_64BIT_REXW, 4, "requires a REX.W prefix, so operands "\ "change width; overrides IC_OPSIZE") \ ENUM_ENTRY(IC_64BIT_OPSIZE, 3, "Just as meaningful as IC_OPSIZE") \ + ENUM_ENTRY(IC_64BIT_ADSIZE, 3, "Just as meaningful as IC_ADSIZE") \ ENUM_ENTRY(IC_64BIT_XD, 5, "XD instructions are SSE; REX.W is " \ "secondary") \ ENUM_ENTRY(IC_64BIT_XS, 5, "Just as meaningful as IC_64BIT_XD") \ diff --git a/lib/Target/X86/X86InstrControl.td b/lib/Target/X86/X86InstrControl.td index f393875..ba86098 100644 --- a/lib/Target/X86/X86InstrControl.td +++ b/lib/Target/X86/X86InstrControl.td @@ -77,7 +77,7 @@ defm JLE : ICBr<0x7E, 0x8E, "jle\t$dst", X86_COND_LE>; defm JG : ICBr<0x7F, 0x8F, "jg\t$dst" , X86_COND_G>; // jcx/jecx/jrcx instructions. -let isAsmParserOnly = 1, isBranch = 1, isTerminator = 1 in { +let isBranch = 1, isTerminator = 1 in { // These are the 32-bit versions of this instruction for the asmparser. In // 32-bit mode, the address size prefix is jcxz and the unprefixed version is // jecxz. diff --git a/test/MC/Disassembler/X86/simple-tests.txt b/test/MC/Disassembler/X86/simple-tests.txt index 42213a6..840d5fa 100644 --- a/test/MC/Disassembler/X86/simple-tests.txt +++ b/test/MC/Disassembler/X86/simple-tests.txt @@ -6,6 +6,11 @@ # CHECK: int $33 0xCD 0x21 +# CHECK: jrcxz -127 +0xe3 0x81 + +# CHECK: jecxz -127 +0x67 0xe3 0x81 # CHECK: addb %al, (%rax) 0 0 diff --git a/test/MC/Disassembler/X86/x86-32.txt b/test/MC/Disassembler/X86/x86-32.txt index 4120ed0..5f2f608 100644 --- a/test/MC/Disassembler/X86/x86-32.txt +++ b/test/MC/Disassembler/X86/x86-32.txt @@ -11,6 +11,12 @@ # CHECK: calll 0xff 0xd0 +# CHECK: jecxz -127 +0xe3 0x81 + +# CHECK: jcxz -127 +0x67 0xe3 0x81 + # CHECK: incl 0x40 diff --git a/utils/TableGen/X86DisassemblerTables.cpp b/utils/TableGen/X86DisassemblerTables.cpp index 33cc017..52b2486 100644 --- a/utils/TableGen/X86DisassemblerTables.cpp +++ b/utils/TableGen/X86DisassemblerTables.cpp @@ -41,15 +41,20 @@ static inline bool inheritsFrom(InstructionContext child, case IC: return(inheritsFrom(child, IC_64BIT) || inheritsFrom(child, IC_OPSIZE) || + inheritsFrom(child, IC_ADSIZE) || inheritsFrom(child, IC_XD) || inheritsFrom(child, IC_XS)); case IC_64BIT: return(inheritsFrom(child, IC_64BIT_REXW) || inheritsFrom(child, IC_64BIT_OPSIZE) || + inheritsFrom(child, IC_64BIT_ADSIZE) || inheritsFrom(child, IC_64BIT_XD) || inheritsFrom(child, IC_64BIT_XS)); case IC_OPSIZE: return inheritsFrom(child, IC_64BIT_OPSIZE); + case IC_ADSIZE: + case IC_64BIT_ADSIZE: + return false; case IC_XD: return inheritsFrom(child, IC_64BIT_XD); case IC_XS: @@ -553,6 +558,8 @@ void DisassemblerTables::emitContextTable(raw_ostream &o, uint32_t &i) const { o << "IC_64BIT_XD"; else if ((index & ATTR_64BIT) && (index & ATTR_OPSIZE)) o << "IC_64BIT_OPSIZE"; + else if ((index & ATTR_64BIT) && (index & ATTR_ADSIZE)) + o << "IC_64BIT_ADSIZE"; else if ((index & ATTR_64BIT) && (index & ATTR_REXW)) o << "IC_64BIT_REXW"; else if ((index & ATTR_64BIT)) @@ -567,6 +574,8 @@ void DisassemblerTables::emitContextTable(raw_ostream &o, uint32_t &i) const { o << "IC_XD"; else if (index & ATTR_OPSIZE) o << "IC_OPSIZE"; + else if (index & ATTR_ADSIZE) + o << "IC_ADSIZE"; else o << "IC"; diff --git a/utils/TableGen/X86RecognizableInstr.cpp b/utils/TableGen/X86RecognizableInstr.cpp index 0055291..5bf473d 100644 --- a/utils/TableGen/X86RecognizableInstr.cpp +++ b/utils/TableGen/X86RecognizableInstr.cpp @@ -225,6 +225,7 @@ RecognizableInstr::RecognizableInstr(DisassemblerTables &tables, SegOvr = byteFromRec(Rec, "SegOvrBits"); HasOpSizePrefix = Rec->getValueAsBit("hasOpSizePrefix"); + HasAdSizePrefix = Rec->getValueAsBit("hasAdSizePrefix"); HasREX_WPrefix = Rec->getValueAsBit("hasREX_WPrefix"); HasVEXPrefix = Rec->getValueAsBit("hasVEXPrefix"); HasVEX_4VPrefix = Rec->getValueAsBit("hasVEX_4VPrefix"); @@ -343,6 +344,8 @@ InstructionContext RecognizableInstr::insnContext() const { insnContext = IC_64BIT_XS_OPSIZE; else if (HasOpSizePrefix) insnContext = IC_64BIT_OPSIZE; + else if (HasAdSizePrefix) + insnContext = IC_64BIT_ADSIZE; else if (HasREX_WPrefix && (Prefix == X86Local::XS || Prefix == X86Local::T8XS)) insnContext = IC_64BIT_REXW_XS; @@ -369,6 +372,8 @@ InstructionContext RecognizableInstr::insnContext() const { insnContext = IC_XS_OPSIZE; else if (HasOpSizePrefix) insnContext = IC_OPSIZE; + else if (HasAdSizePrefix) + insnContext = IC_ADSIZE; else if (Prefix == X86Local::XD || Prefix == X86Local::T8XD || Prefix == X86Local::TAXD) insnContext = IC_XD; diff --git a/utils/TableGen/X86RecognizableInstr.h b/utils/TableGen/X86RecognizableInstr.h index 3ae112b..6c0a234 100644 --- a/utils/TableGen/X86RecognizableInstr.h +++ b/utils/TableGen/X86RecognizableInstr.h @@ -50,6 +50,8 @@ private: uint8_t SegOvr; /// The hasOpSizePrefix field from the record bool HasOpSizePrefix; + /// The hasAdSizePrefix field from the record + bool HasAdSizePrefix; /// The hasREX_WPrefix field from the record bool HasREX_WPrefix; /// The hasVEXPrefix field from the record |