diff options
author | Craig Topper <craig.topper@gmail.com> | 2013-12-31 17:21:44 +0000 |
---|---|---|
committer | Craig Topper <craig.topper@gmail.com> | 2013-12-31 17:21:44 +0000 |
commit | 5cbbd7e1a5fb86e5495326c02f77356a357ec439 (patch) | |
tree | 2b6b3dd5ba8117f007b5111075bafbc452b13878 /utils | |
parent | 31b27056a6b3585ddd2bd21689434a73d79fe888 (diff) | |
download | llvm-5cbbd7e1a5fb86e5495326c02f77356a357ec439.tar.gz llvm-5cbbd7e1a5fb86e5495326c02f77356a357ec439.tar.bz2 llvm-5cbbd7e1a5fb86e5495326c02f77356a357ec439.tar.xz |
Revert r198238 and add FP disassembler tests. It didn't work and I didn't realized we had no FP disassembler test cases.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@198265 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'utils')
-rw-r--r-- | utils/TableGen/X86ModRMFilters.cpp | 2 | ||||
-rw-r--r-- | utils/TableGen/X86ModRMFilters.h | 20 | ||||
-rw-r--r-- | utils/TableGen/X86RecognizableInstr.cpp | 54 |
3 files changed, 51 insertions, 25 deletions
diff --git a/utils/TableGen/X86ModRMFilters.cpp b/utils/TableGen/X86ModRMFilters.cpp index 1641613aa3..a311603df9 100644 --- a/utils/TableGen/X86ModRMFilters.cpp +++ b/utils/TableGen/X86ModRMFilters.cpp @@ -17,6 +17,8 @@ void DumbFilter::anchor() { } void ModFilter::anchor() { } +void AddRegEscapeFilter::anchor() { } + void ExtendedFilter::anchor() { } void ExactFilter::anchor() { } diff --git a/utils/TableGen/X86ModRMFilters.h b/utils/TableGen/X86ModRMFilters.h index 049cfc1d3b..5ab1a48846 100644 --- a/utils/TableGen/X86ModRMFilters.h +++ b/utils/TableGen/X86ModRMFilters.h @@ -84,6 +84,26 @@ public: } }; +/// AddRegEscapeFilter - Some escape opcodes have one of the register operands +/// added to the ModR/M byte, meaning that a range of eight ModR/M values +/// maps to a single instruction. Such instructions require the ModR/M byte +/// to fall between 0xc0 and 0xff. +class AddRegEscapeFilter : public ModRMFilter { + virtual void anchor(); + uint8_t ModRM; +public: + /// Constructor + /// + /// \param modRM The value of the ModR/M byte when the register operand + /// refers to the first register in the register set. + AddRegEscapeFilter(uint8_t modRM) : ModRM(modRM) { + } + + bool accepts(uint8_t modRM) const { + return (modRM >= ModRM && modRM < ModRM + 8); + } +}; + /// ExtendedFilter - Extended opcodes are classified based on the value of the /// mod field [bits 7-6] and the value of the nnn field [bits 5-3]. class ExtendedFilter : public ModRMFilter { diff --git a/utils/TableGen/X86RecognizableInstr.cpp b/utils/TableGen/X86RecognizableInstr.cpp index 6a2a0d504f..1eb579df3f 100644 --- a/utils/TableGen/X86RecognizableInstr.cpp +++ b/utils/TableGen/X86RecognizableInstr.cpp @@ -1075,9 +1075,14 @@ void RecognizableInstr::emitDecodePath(DisassemblerTables &tables) const { case X86Local::DE: case X86Local::DF: assert(Opcode >= 0xc0 && "Unexpected opcode for an escape opcode"); - assert(Form == X86Local::RawFrm); opcodeType = ONEBYTE; - filter = new ExactFilter(Opcode); + if (Form == X86Local::AddRegFrm) { + Spec->modifierType = MODIFIER_MODRM; + Spec->modifierBase = Opcode; + filter = new AddRegEscapeFilter(Opcode); + } else { + filter = new ExactFilter(Opcode); + } opcodeToSet = 0xd8 + (Prefix - X86Local::D8); break; case X86Local::REP: @@ -1125,16 +1130,6 @@ void RecognizableInstr::emitDecodePath(DisassemblerTables &tables) const { switch (Form) { default: llvm_unreachable("Unhandled escape opcode form"); - case X86Local::MRM0r: - case X86Local::MRM1r: - case X86Local::MRM2r: - case X86Local::MRM3r: - case X86Local::MRM4r: - case X86Local::MRM5r: - case X86Local::MRM6r: - case X86Local::MRM7r: - filter = new ExtendedFilter(true, Form - X86Local::MRM0r); - break; case X86Local::MRM0m: case X86Local::MRM1m: case X86Local::MRM2m: @@ -1162,22 +1157,31 @@ void RecognizableInstr::emitDecodePath(DisassemblerTables &tables) const { assert(filter && "Filter not set"); if (Form == X86Local::AddRegFrm) { - assert(opcodeToSet < 0xf9 && - "Not enough room for all ADDREG_FRM operands"); - - uint8_t currentOpcode; - - for (currentOpcode = opcodeToSet; - currentOpcode < opcodeToSet + 8; - ++currentOpcode) + if(Spec->modifierType != MODIFIER_MODRM) { + assert(opcodeToSet < 0xf9 && + "Not enough room for all ADDREG_FRM operands"); + + uint8_t currentOpcode; + + for (currentOpcode = opcodeToSet; + currentOpcode < opcodeToSet + 8; + ++currentOpcode) + tables.setTableFields(opcodeType, + insnContext(), + currentOpcode, + *filter, + UID, Is32Bit, IgnoresVEX_L); + + Spec->modifierType = MODIFIER_OPCODE; + Spec->modifierBase = opcodeToSet; + } else { + // modifierBase was set where MODIFIER_MODRM was set tables.setTableFields(opcodeType, insnContext(), - currentOpcode, + opcodeToSet, *filter, UID, Is32Bit, IgnoresVEX_L); - - Spec->modifierType = MODIFIER_OPCODE; - Spec->modifierBase = opcodeToSet; + } } else { tables.setTableFields(opcodeType, insnContext(), @@ -1337,7 +1341,6 @@ OperandEncoding RecognizableInstr::immediateEncodingFromString OperandEncoding RecognizableInstr::rmRegisterEncodingFromString (const std::string &s, bool hasOpSizePrefix) { - ENCODING("RST", ENCODING_I) ENCODING("GR16", ENCODING_RM) ENCODING("GR32", ENCODING_RM) ENCODING("GR32orGR64", ENCODING_RM) @@ -1490,6 +1493,7 @@ OperandEncoding RecognizableInstr::relocationEncodingFromString OperandEncoding RecognizableInstr::opcodeModifierEncodingFromString (const std::string &s, bool hasOpSizePrefix) { + ENCODING("RST", ENCODING_I) ENCODING("GR32", ENCODING_Rv) ENCODING("GR64", ENCODING_RO) ENCODING("GR16", ENCODING_Rv) |