From 5cbbd7e1a5fb86e5495326c02f77356a357ec439 Mon Sep 17 00:00:00 2001 From: Craig Topper Date: Tue, 31 Dec 2013 17:21:44 +0000 Subject: 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 --- utils/TableGen/X86ModRMFilters.cpp | 2 ++ utils/TableGen/X86ModRMFilters.h | 20 ++++++++++++ utils/TableGen/X86RecognizableInstr.cpp | 54 ++++++++++++++++++--------------- 3 files changed, 51 insertions(+), 25 deletions(-) (limited to 'utils') 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) -- cgit v1.2.3