diff options
author | Craig Topper <craig.topper@gmail.com> | 2013-09-30 06:23:19 +0000 |
---|---|---|
committer | Craig Topper <craig.topper@gmail.com> | 2013-09-30 06:23:19 +0000 |
commit | 39004b537beb1acc26675c8943c2cce4ca8a0499 (patch) | |
tree | f82ffa2f5160ca043e0b0b0efba832fd337e2e70 | |
parent | 6b85c4e56102bbaa21a643cf0487b7e506c7f083 (diff) | |
download | external_llvm-39004b537beb1acc26675c8943c2cce4ca8a0499.zip external_llvm-39004b537beb1acc26675c8943c2cce4ca8a0499.tar.gz external_llvm-39004b537beb1acc26675c8943c2cce4ca8a0499.tar.bz2 |
Filter out repeated sections from the X86 disassembler modRMTable. Saves about ~43K from a released build. Unfortunately the disassembler tables are still upwards of 800K.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@191652 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r-- | utils/TableGen/X86DisassemblerTables.cpp | 99 | ||||
-rw-r--r-- | utils/TableGen/X86DisassemblerTables.h | 55 |
2 files changed, 67 insertions, 87 deletions
diff --git a/utils/TableGen/X86DisassemblerTables.cpp b/utils/TableGen/X86DisassemblerTables.cpp index db0964f..98a4797 100644 --- a/utils/TableGen/X86DisassemblerTables.cpp +++ b/utils/TableGen/X86DisassemblerTables.cpp @@ -265,35 +265,6 @@ static inline const char* stringForOperandEncoding(OperandEncoding encoding) { } } -void DisassemblerTables::emitOneID(raw_ostream &o, unsigned &i, InstrUID id, - bool addComma) const { - if (id) - o.indent(i * 2) << format("0x%hx", id); - else - o.indent(i * 2) << 0; - - if (addComma) - o << ", "; - else - o << " "; - - o << "/* "; - o << InstructionSpecifiers[id].name; - o << "*/"; - - o << "\n"; -} - -/// emitEmptyTable - Emits the modRMEmptyTable, which is used as a ID table by -/// all ModR/M decisions for instructions that are invalid for all possible -/// ModR/M byte values. -/// -/// @param o - The output stream on which to emit the table. -/// @param i - The indentation level for that output stream. -static void emitEmptyTable(raw_ostream &o, unsigned &i) { - o.indent(i * 2) << "0x0, /* EmptyTable */\n"; -} - /// getDecisionType - Determines whether a ModRM decision with 255 entries can /// be compacted by eliminating redundant information. /// @@ -393,6 +364,7 @@ DisassemblerTables::~DisassemblerTables() { void DisassemblerTables::emitModRMDecision(raw_ostream &o1, raw_ostream &o2, unsigned &i1, unsigned &i2, + unsigned &ModRMTableNum, ModRMDecision &decision) const { static uint32_t sTableNumber = 0; static uint32_t sEntryNumber = 1; @@ -411,44 +383,56 @@ void DisassemblerTables::emitModRMDecision(raw_ostream &o1, raw_ostream &o2, return; } - o1 << "/* Table" << sTableNumber << " */\n"; - i1++; + std::vector<unsigned> ModRMDecision; switch (dt) { default: llvm_unreachable("Unknown decision type"); case MODRM_ONEENTRY: - emitOneID(o1, i1, decision.instructionIDs[0], true); + ModRMDecision.push_back(decision.instructionIDs[0]); break; case MODRM_SPLITRM: - emitOneID(o1, i1, decision.instructionIDs[0x00], true); // mod = 0b00 - emitOneID(o1, i1, decision.instructionIDs[0xc0], true); // mod = 0b11 + ModRMDecision.push_back(decision.instructionIDs[0x00]); + ModRMDecision.push_back(decision.instructionIDs[0xc0]); break; case MODRM_SPLITREG: for (unsigned index = 0; index < 64; index += 8) - emitOneID(o1, i1, decision.instructionIDs[index], true); + ModRMDecision.push_back(decision.instructionIDs[index]); for (unsigned index = 0xc0; index < 256; index += 8) - emitOneID(o1, i1, decision.instructionIDs[index], true); + ModRMDecision.push_back(decision.instructionIDs[index]); break; case MODRM_SPLITMISC: for (unsigned index = 0; index < 64; index += 8) - emitOneID(o1, i1, decision.instructionIDs[index], true); + ModRMDecision.push_back(decision.instructionIDs[index]); for (unsigned index = 0xc0; index < 256; ++index) - emitOneID(o1, i1, decision.instructionIDs[index], true); + ModRMDecision.push_back(decision.instructionIDs[index]); break; case MODRM_FULL: for (unsigned index = 0; index < 256; ++index) - emitOneID(o1, i1, decision.instructionIDs[index], true); + ModRMDecision.push_back(decision.instructionIDs[index]); break; } - i1--; + unsigned &EntryNumber = ModRMTable[ModRMDecision]; + if (EntryNumber == 0) { + EntryNumber = ModRMTableNum; + + ModRMTableNum += ModRMDecision.size(); + o1 << "/* Table" << EntryNumber << " */\n"; + i1++; + for (std::vector<unsigned>::const_iterator I = ModRMDecision.begin(), + E = ModRMDecision.end(); I != E; ++I) { + o1.indent(i1 * 2) << format("0x%hx", *I) << ", /* " + << InstructionSpecifiers[*I].name << " */\n"; + } + i1--; + } o2.indent(i2) << "{ /* struct ModRMDecision */" << "\n"; i2++; o2.indent(i2) << stringForDecisionType(dt) << "," << "\n"; - o2.indent(i2) << sEntryNumber << " /* Table" << sTableNumber << " */\n"; + o2.indent(i2) << EntryNumber << " /* Table" << EntryNumber << " */\n"; i2--; o2.indent(i2) << "}"; @@ -482,6 +466,7 @@ void DisassemblerTables::emitModRMDecision(raw_ostream &o1, raw_ostream &o2, void DisassemblerTables::emitOpcodeDecision(raw_ostream &o1, raw_ostream &o2, unsigned &i1, unsigned &i2, + unsigned &ModRMTableNum, OpcodeDecision &decision) const { o2.indent(i2) << "{ /* struct OpcodeDecision */" << "\n"; i2++; @@ -493,7 +478,8 @@ void DisassemblerTables::emitOpcodeDecision(raw_ostream &o1, raw_ostream &o2, o2 << "/* 0x" << format("%02hhx", index) << " */" << "\n"; - emitModRMDecision(o1, o2, i1, i2, decision.modRMDecisions[index]); + emitModRMDecision(o1, o2, i1, i2, ModRMTableNum, + decision.modRMDecisions[index]); if (index < 255) o2 << ","; @@ -509,6 +495,7 @@ void DisassemblerTables::emitOpcodeDecision(raw_ostream &o1, raw_ostream &o2, void DisassemblerTables::emitContextDecision(raw_ostream &o1, raw_ostream &o2, unsigned &i1, unsigned &i2, + unsigned &ModRMTableNum, ContextDecision &decision, const char* name) const { o2.indent(i2) << "static const struct ContextDecision " << name << " = {\n"; @@ -522,7 +509,8 @@ void DisassemblerTables::emitContextDecision(raw_ostream &o1, raw_ostream &o2, o2 << " */"; o2 << "\n"; - emitOpcodeDecision(o1, o2, i1, i2, decision.opcodeDecisions[index]); + emitOpcodeDecision(o1, o2, i1, i2, ModRMTableNum, + decision.opcodeDecisions[index]); if (index + 1 < IC_max) o2 << ", "; @@ -711,13 +699,14 @@ void DisassemblerTables::emitContextTable(raw_ostream &o, unsigned &i) const { } void DisassemblerTables::emitContextDecisions(raw_ostream &o1, raw_ostream &o2, - unsigned &i1, unsigned &i2) const { - emitContextDecision(o1, o2, i1, i2, *Tables[0], ONEBYTE_STR); - emitContextDecision(o1, o2, i1, i2, *Tables[1], TWOBYTE_STR); - emitContextDecision(o1, o2, i1, i2, *Tables[2], THREEBYTE38_STR); - emitContextDecision(o1, o2, i1, i2, *Tables[3], THREEBYTE3A_STR); - emitContextDecision(o1, o2, i1, i2, *Tables[4], THREEBYTEA6_STR); - emitContextDecision(o1, o2, i1, i2, *Tables[5], THREEBYTEA7_STR); + unsigned &i1, unsigned &i2, + unsigned &ModRMTableNum) const { + emitContextDecision(o1, o2, i1, i2, ModRMTableNum, *Tables[0], ONEBYTE_STR); + emitContextDecision(o1, o2, i1, i2, ModRMTableNum, *Tables[1], TWOBYTE_STR); + emitContextDecision(o1, o2, i1, i2, ModRMTableNum, *Tables[2], THREEBYTE38_STR); + emitContextDecision(o1, o2, i1, i2, ModRMTableNum, *Tables[3], THREEBYTE3A_STR); + emitContextDecision(o1, o2, i1, i2, ModRMTableNum, *Tables[4], THREEBYTEA6_STR); + emitContextDecision(o1, o2, i1, i2, ModRMTableNum, *Tables[5], THREEBYTEA7_STR); } void DisassemblerTables::emit(raw_ostream &o) const { @@ -736,11 +725,17 @@ void DisassemblerTables::emit(raw_ostream &o) const { emitContextTable(o, i2); o << "\n"; + unsigned ModRMTableNum = 0; + o << "static const InstrUID modRMTable[] = {\n"; i1++; - emitEmptyTable(o1, i1); + std::vector<unsigned> EmptyTable(1, 0); + ModRMTable[EmptyTable] = ModRMTableNum; + ModRMTableNum += EmptyTable.size(); + o1 << "/* EmptyTable */\n"; + o1.indent(i1 * 2) << "0x0,\n"; i1--; - emitContextDecisions(o1, o2, i1, i2); + emitContextDecisions(o1, o2, i1, i2, ModRMTableNum); o << o1.str(); o << " 0x0\n"; diff --git a/utils/TableGen/X86DisassemblerTables.h b/utils/TableGen/X86DisassemblerTables.h index 01aeaaf..3861b74 100644 --- a/utils/TableGen/X86DisassemblerTables.h +++ b/utils/TableGen/X86DisassemblerTables.h @@ -20,6 +20,7 @@ #include "X86DisassemblerShared.h" #include "X86ModRMFilters.h" #include "llvm/Support/raw_ostream.h" +#include <map> #include <vector> namespace llvm { @@ -41,28 +42,16 @@ private: /// [5] three-byte opcodes of the form 0f a7 __ ContextDecision* Tables[6]; + // Table of ModRM encodings. + typedef std::map<std::vector<unsigned>, unsigned> ModRMMapTy; + mutable ModRMMapTy ModRMTable; + /// The instruction information table std::vector<InstructionSpecifier> InstructionSpecifiers; /// True if there are primary decode conflicts in the instruction set bool HasConflicts; - /// emitOneID - Emits a table entry for a single instruction entry, at the - /// innermost level of the structure hierarchy. The entry is printed out - /// in the format "nnnn, /* MNEMONIC */" where nnnn is the ID in decimal, - /// the comma is printed if addComma is true, and the menonic is the name - /// of the instruction as listed in the LLVM tables. - /// - /// @param o - The output stream to print the entry on. - /// @param i - The indentation level for o. - /// @param id - The unique ID of the instruction to print. - /// @param addComma - Whether or not to print a comma after the ID. True if - /// additional items will follow. - void emitOneID(raw_ostream &o, - uint32_t &i, - InstrUID id, - bool addComma) const; - /// emitModRMDecision - Emits a table of entries corresponding to a single /// ModR/M decision. Compacts the ModR/M decision if possible. ModR/M /// decisions are printed as: @@ -91,12 +80,11 @@ private: /// @param o2 - The output stream to print the decision structure to. /// @param i1 - The indentation level to use with stream o1. /// @param i2 - The indentation level to use with stream o2. + /// @param ModRMTableNum - next table number for adding to ModRMTable. /// @param decision - The ModR/M decision to emit. This decision has 256 /// entries - emitModRMDecision decides how to compact it. - void emitModRMDecision(raw_ostream &o1, - raw_ostream &o2, - uint32_t &i1, - uint32_t &i2, + void emitModRMDecision(raw_ostream &o1, raw_ostream &o2, + unsigned &i1, unsigned &i2, unsigned &ModRMTableNum, ModRMDecision &decision) const; /// emitOpcodeDecision - Emits an OpcodeDecision and all its subsidiary ModR/M @@ -120,12 +108,11 @@ private: /// @param o2 - The output stream for the decision structure itself. /// @param i1 - The indent level to use with stream o1. /// @param i2 - The indent level to use with stream o2. + /// @param ModRMTableNum - next table number for adding to ModRMTable. /// @param decision - The OpcodeDecision to emit along with its subsidiary /// structures. - void emitOpcodeDecision(raw_ostream &o1, - raw_ostream &o2, - uint32_t &i1, - uint32_t &i2, + void emitOpcodeDecision(raw_ostream &o1, raw_ostream &o2, + unsigned &i1, unsigned &i2, unsigned &ModRMTableNum, OpcodeDecision &decision) const; /// emitContextDecision - Emits a ContextDecision and all its subsidiary @@ -155,15 +142,13 @@ private: /// @param o2 - The output stream to print the decision structure to. /// @param i1 - The indent level to use with stream o1. /// @param i2 - The indent level to use with stream o2. + /// @param ModRMTableNum - next table number for adding to ModRMTable. /// @param decision - The ContextDecision to emit along with its subsidiary /// structures. /// @param name - The name for the ContextDecision. - void emitContextDecision(raw_ostream &o1, - raw_ostream &o2, - uint32_t &i1, - uint32_t &i2, - ContextDecision &decision, - const char* name) const; + void emitContextDecision(raw_ostream &o1, raw_ostream &o2, + unsigned &i1, unsigned &i2, unsigned &ModRMTableNum, + ContextDecision &decision, const char* name) const; /// emitInstructionInfo - Prints the instruction specifier table, which has /// one entry for each instruction, and contains name and operand @@ -194,7 +179,7 @@ private: /// @param o - The output stream to which the instruction table should be /// written. /// @param i - The indent level for use with the stream. - void emitInstructionInfo(raw_ostream &o, uint32_t &i) const; + void emitInstructionInfo(raw_ostream &o, unsigned &i) const; /// emitContextTable - Prints the table that is used to translate from an /// instruction attribute mask to an instruction context. This table is @@ -220,10 +205,10 @@ private: /// @param o2 - The output stream to print the decision structures to. /// @param i1 - The indent level to use with stream o1. /// @param i2 - The indent level to use with stream o2. - void emitContextDecisions(raw_ostream &o1, - raw_ostream &o2, - uint32_t &i1, - uint32_t &i2) const; + /// @param ModRMTableNum - next table number for adding to ModRMTable. + void emitContextDecisions(raw_ostream &o1, raw_ostream &o2, + unsigned &i1, unsigned &i2, + unsigned &ModRMTableNum) const; /// setTableFields - Uses a ModRMFilter to set the appropriate entries in a /// ModRMDecision to refer to a particular instruction ID. |