aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorCraig Topper <craig.topper@gmail.com>2013-09-30 06:23:19 +0000
committerCraig Topper <craig.topper@gmail.com>2013-09-30 06:23:19 +0000
commit39004b537beb1acc26675c8943c2cce4ca8a0499 (patch)
treef82ffa2f5160ca043e0b0b0efba832fd337e2e70
parent6b85c4e56102bbaa21a643cf0487b7e506c7f083 (diff)
downloadexternal_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.cpp99
-rw-r--r--utils/TableGen/X86DisassemblerTables.h55
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.