[X86][Disassembler] Shrink X86GenDisassemblerTables.inc from 36M to 6.1M

In x86Disassembler{OneByte,TwoByte,...}Codes,
"/* EmptyTable */" is very common. Omitting it saves lots of space.
Also, there is no need to display a table entry in multiple lines.

It is also common that the whole OpcodeDecision is { MODRM_ONEENTRY, 0}.
Make use of zero-initialization.
This commit is contained in:
Fangrui Song 2020-01-11 16:27:25 -08:00
parent 1e8ce7492e
commit f719c540bb

View File

@ -667,16 +667,9 @@ void DisassemblerTables::emitModRMDecision(raw_ostream &o1, raw_ostream &o2,
static uint32_t sEntryNumber = 1;
ModRMDecisionType dt = getDecisionType(decision);
if (dt == MODRM_ONEENTRY && decision.instructionIDs[0] == 0)
{
o2.indent(i2) << "{ /* ModRMDecision */" << "\n";
i2++;
o2.indent(i2) << stringForDecisionType(dt) << "," << "\n";
o2.indent(i2) << 0 << " /* EmptyTable */\n";
i2--;
o2.indent(i2) << "}";
if (dt == MODRM_ONEENTRY && decision.instructionIDs[0] == 0) {
// Empty table.
o2 << "{ " << stringForDecisionType(dt) << ", 0 }";
return;
}
@ -725,14 +718,8 @@ void DisassemblerTables::emitModRMDecision(raw_ostream &o1, raw_ostream &o2,
i1--;
}
o2.indent(i2) << "{ /* struct ModRMDecision */" << "\n";
i2++;
o2.indent(i2) << stringForDecisionType(dt) << "," << "\n";
o2.indent(i2) << EntryNumber << " /* Table" << EntryNumber << " */\n";
i2--;
o2.indent(i2) << "}";
o2 << "{ " << stringForDecisionType(dt) << ", " << EntryNumber << " /* Table"
<< EntryNumber << " */ }";
switch (dt) {
default:
@ -764,30 +751,43 @@ 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++;
o2.indent(i2) << "{" << "\n";
i2++;
OpcodeDecision &opDecision) const {
o2 << "{";
++i2;
for (unsigned index = 0; index < 256; ++index) {
o2.indent(i2);
o2 << "/* 0x" << format("%02hhx", index) << " */" << "\n";
emitModRMDecision(o1, o2, i1, i2, ModRMTableNum,
decision.modRMDecisions[index]);
if (index < 255)
o2 << ",";
o2 << "\n";
unsigned index;
for (index = 0; index < 256; ++index) {
auto &decision = opDecision.modRMDecisions[index];
ModRMDecisionType dt = getDecisionType(decision);
if (!(dt == MODRM_ONEENTRY && decision.instructionIDs[0] == 0))
break;
}
if (index == 256) {
// If all 256 entries are MODRM_ONEENTRY, omit output.
assert(MODRM_ONEENTRY == 0);
--i2;
o2 << "},\n";
} else {
o2 << " /* struct OpcodeDecision */ {\n";
++i2;
for (index = 0; index < 256; ++index) {
o2.indent(i2);
i2--;
o2.indent(i2) << "}" << "\n";
i2--;
o2.indent(i2) << "}" << "\n";
o2 << "/* 0x" << format("%02hhx", index) << " */ ";
emitModRMDecision(o1, o2, i1, i2, ModRMTableNum,
opDecision.modRMDecisions[index]);
if (index < 255)
o2 << ",";
o2 << "\n";
}
--i2;
o2.indent(i2) << "}\n";
--i2;
o2.indent(i2) << "},\n";
}
}
void DisassemblerTables::emitContextDecision(raw_ostream &o1, raw_ostream &o2,
@ -803,14 +803,10 @@ void DisassemblerTables::emitContextDecision(raw_ostream &o1, raw_ostream &o2,
for (unsigned index = 0; index < IC_max; ++index) {
o2.indent(i2) << "/* ";
o2 << stringForContext((InstructionContext)index);
o2 << " */";
o2 << "\n";
o2 << " */ ";
emitOpcodeDecision(o1, o2, i1, i2, ModRMTableNum,
decision.opcodeDecisions[index]);
if (index + 1 < IC_max)
o2 << ", ";
}
i2--;