Flatten some of the arrays in the X86 disassembler tables to reduce space needed to store pointers on 64-bit hosts and reduce relocations needed at startup. Part of PR11953.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@150161 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Craig Topper
2012-02-09 07:45:30 +00:00
parent 72a043f9d6
commit ce8f4c58d8
4 changed files with 44 additions and 45 deletions

View File

@@ -78,7 +78,7 @@
const char* name; const char* name;
#define INSTRUCTION_IDS \ #define INSTRUCTION_IDS \
const InstrUID *instructionIDs; unsigned instructionIDs;
#include "X86DisassemblerDecoderCommon.h" #include "X86DisassemblerDecoderCommon.h"

View File

@@ -131,14 +131,13 @@ static InstrUID decode(OpcodeType type,
debug("Corrupt table! Unknown modrm_type"); debug("Corrupt table! Unknown modrm_type");
return 0; return 0;
case MODRM_ONEENTRY: case MODRM_ONEENTRY:
return dec->instructionIDs[0]; return modRMTable[dec->instructionIDs];
case MODRM_SPLITRM: case MODRM_SPLITRM:
if (modFromModRM(modRM) == 0x3) if (modFromModRM(modRM) == 0x3)
return dec->instructionIDs[1]; return modRMTable[dec->instructionIDs+1];
else return modRMTable[dec->instructionIDs];
return dec->instructionIDs[0];
case MODRM_FULL: case MODRM_FULL:
return dec->instructionIDs[modRM]; return modRMTable[dec->instructionIDs+modRM];
} }
} }

View File

@@ -24,7 +24,7 @@ extern "C" {
const char* name; const char* name;
#define INSTRUCTION_IDS \ #define INSTRUCTION_IDS \
const InstrUID *instructionIDs; unsigned instructionIDs;
#include "X86DisassemblerDecoderCommon.h" #include "X86DisassemblerDecoderCommon.h"

View File

@@ -196,8 +196,7 @@ void DisassemblerTables::emitOneID(raw_ostream &o,
/// @param i - The indentation level for that output stream. /// @param i - The indentation level for that output stream.
static void emitEmptyTable(raw_ostream &o, uint32_t &i) static void emitEmptyTable(raw_ostream &o, uint32_t &i)
{ {
o.indent(i * 2) << "static const InstrUID modRMEmptyTable[1] = { 0 };\n"; o.indent(i * 2) << "0x0, /* EmptyTable */\n";
o << "\n";
} }
/// getDecisionType - Determines whether a ModRM decision with 255 entries can /// getDecisionType - Determines whether a ModRM decision with 255 entries can
@@ -293,71 +292,67 @@ void DisassemblerTables::emitModRMDecision(raw_ostream &o1,
ModRMDecision &decision) ModRMDecision &decision)
const { const {
static uint64_t sTableNumber = 0; static uint64_t sTableNumber = 0;
uint64_t thisTableNumber = sTableNumber; static uint64_t sEntryNumber = 1;
ModRMDecisionType dt = getDecisionType(decision); ModRMDecisionType dt = getDecisionType(decision);
uint16_t index; uint16_t index;
if (dt == MODRM_ONEENTRY && decision.instructionIDs[0] == 0) if (dt == MODRM_ONEENTRY && decision.instructionIDs[0] == 0)
{ {
o2.indent(i2) << "{ /* ModRMDecision */" << "\n"; o2.indent(i2) << "{ /* ModRMDecision */" << "\n";
i2++; i2++;
o2.indent(i2) << stringForDecisionType(dt) << "," << "\n"; o2.indent(i2) << stringForDecisionType(dt) << "," << "\n";
o2.indent(i2) << "modRMEmptyTable"; o2.indent(i2) << 0 << " /* EmptyTable */\n";
i2--; i2--;
o2.indent(i2) << "}"; o2.indent(i2) << "}";
return; return;
} }
o1.indent(i1) << "static const InstrUID modRMTable" << thisTableNumber;
switch (dt) {
default:
llvm_unreachable("Unknown decision type");
case MODRM_ONEENTRY:
o1 << "[1]";
break;
case MODRM_SPLITRM:
o1 << "[2]";
break;
case MODRM_FULL:
o1 << "[256]";
break;
}
o1 << " = {" << "\n"; o1 << "/* Table" << sTableNumber << " */\n";
i1++; i1++;
switch (dt) { switch (dt) {
default: default:
llvm_unreachable("Unknown decision type"); llvm_unreachable("Unknown decision type");
case MODRM_ONEENTRY: case MODRM_ONEENTRY:
emitOneID(o1, i1, decision.instructionIDs[0], false); emitOneID(o1, i1, decision.instructionIDs[0], true);
break; break;
case MODRM_SPLITRM: case MODRM_SPLITRM:
emitOneID(o1, i1, decision.instructionIDs[0x00], true); // mod = 0b00 emitOneID(o1, i1, decision.instructionIDs[0x00], true); // mod = 0b00
emitOneID(o1, i1, decision.instructionIDs[0xc0], false); // mod = 0b11 emitOneID(o1, i1, decision.instructionIDs[0xc0], true); // mod = 0b11
break; break;
case MODRM_FULL: case MODRM_FULL:
for (index = 0; index < 256; ++index) for (index = 0; index < 256; ++index)
emitOneID(o1, i1, decision.instructionIDs[index], index < 255); emitOneID(o1, i1, decision.instructionIDs[index], true);
break; break;
} }
i1--; i1--;
o1.indent(i1) << "};" << "\n";
o1 << "\n";
o2.indent(i2) << "{ /* struct ModRMDecision */" << "\n"; o2.indent(i2) << "{ /* struct ModRMDecision */" << "\n";
i2++; i2++;
o2.indent(i2) << stringForDecisionType(dt) << "," << "\n"; o2.indent(i2) << stringForDecisionType(dt) << "," << "\n";
o2.indent(i2) << "modRMTable" << sTableNumber << "\n"; o2.indent(i2) << sEntryNumber << " /* Table" << sTableNumber << " */\n";
i2--; i2--;
o2.indent(i2) << "}"; o2.indent(i2) << "}";
switch (dt) {
default:
llvm_unreachable("Unknown decision type");
case MODRM_ONEENTRY:
sEntryNumber += 1;
break;
case MODRM_SPLITRM:
sEntryNumber += 2;
break;
case MODRM_FULL:
sEntryNumber += 256;
break;
}
++sTableNumber; ++sTableNumber;
} }
@@ -598,11 +593,16 @@ void DisassemblerTables::emit(raw_ostream &o) const {
emitContextTable(o, i2); emitContextTable(o, i2);
o << "\n"; o << "\n";
o << "static const InstrUID modRMTable[] = {\n";
i1++;
emitEmptyTable(o1, i1); emitEmptyTable(o1, i1);
i1--;
emitContextDecisions(o1, o2, i1, i2); emitContextDecisions(o1, o2, i1, i2);
o << o1.str(); o << o1.str();
o << " 0x0\n";
o << "};\n";
o << "\n"; o << "\n";
o << o2.str(); o << o2.str();
o << "\n"; o << "\n";