mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-03-20 11:32:33 +00:00
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
This commit is contained in:
parent
6b85c4e561
commit
39004b537b
@ -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";
|
||||
|
@ -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.
|
||||
|
Loading…
x
Reference in New Issue
Block a user