diff options
author | Craig Topper <craig.topper@gmail.com> | 2012-08-01 07:39:18 +0000 |
---|---|---|
committer | Craig Topper <craig.topper@gmail.com> | 2012-08-01 07:39:18 +0000 |
commit | 5a2c607153993fb7f7e04f9482520b64dffe5757 (patch) | |
tree | f14464b140bcf52862a0fb65db6dde5b76d17fc7 /utils | |
parent | adfe2637b839efe041165f27c9ad57e3befb2be0 (diff) |
Add more indirection to the disassembler tables to reduce amount of space used to store the operand types and encodings. Store only the unique combinations in a separate table and store indices in the instruction table. Saves about 32K of static data.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@161101 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'utils')
-rw-r--r-- | utils/TableGen/X86DisassemblerShared.h | 1 | ||||
-rw-r--r-- | utils/TableGen/X86DisassemblerTables.cpp | 82 |
2 files changed, 54 insertions, 29 deletions
diff --git a/utils/TableGen/X86DisassemblerShared.h b/utils/TableGen/X86DisassemblerShared.h index 0417e9dece..c13a0cc467 100644 --- a/utils/TableGen/X86DisassemblerShared.h +++ b/utils/TableGen/X86DisassemblerShared.h @@ -14,6 +14,7 @@ #include <string.h> #define INSTRUCTION_SPECIFIER_FIELDS \ + struct OperandSpecifier operands[X86_MAX_OPERANDS]; \ bool filtered; \ InstructionContext insnContext; \ std::string name; \ diff --git a/utils/TableGen/X86DisassemblerTables.cpp b/utils/TableGen/X86DisassemblerTables.cpp index 749557b2d0..f3bd373708 100644 --- a/utils/TableGen/X86DisassemblerTables.cpp +++ b/utils/TableGen/X86DisassemblerTables.cpp @@ -21,6 +21,7 @@ #include "llvm/ADT/STLExtras.h" #include "llvm/Support/ErrorHandling.h" #include "llvm/Support/Format.h" +#include <map> using namespace llvm; using namespace X86Disassembler; @@ -424,48 +425,71 @@ void DisassemblerTables::emitContextDecision(raw_ostream &o1, raw_ostream &o2, void DisassemblerTables::emitInstructionInfo(raw_ostream &o, unsigned &i) const { + unsigned NumInstructions = InstructionSpecifiers.size(); + + o << "static const struct OperandSpecifier x86OperandSets[][" + << X86_MAX_OPERANDS << "] = {\n"; + + typedef std::vector<std::pair<const char *, const char *> > OperandListTy; + std::map<OperandListTy, unsigned> OperandSets; + + unsigned OperandSetNum = 0; + for (unsigned Index = 0; Index < NumInstructions; ++Index) { + OperandListTy OperandList; + + for (unsigned OperandIndex = 0; OperandIndex < X86_MAX_OPERANDS; + ++OperandIndex) { + const char *Encoding = + stringForOperandEncoding((OperandEncoding)InstructionSpecifiers[Index] + .operands[OperandIndex].encoding); + const char *Type = + stringForOperandType((OperandType)InstructionSpecifiers[Index] + .operands[OperandIndex].type); + OperandList.push_back(std::make_pair(Encoding, Type)); + } + unsigned &N = OperandSets[OperandList]; + if (N != 0) continue; + + N = ++OperandSetNum; + + o << " { /* " << (OperandSetNum - 1) << " */\n"; + for (unsigned i = 0, e = OperandList.size(); i != e; ++i) { + o << " { " << OperandList[i].first << ", " + << OperandList[i].second << " },\n"; + } + o << " },\n"; + } + o << "};" << "\n\n"; + o.indent(i * 2) << "static const struct InstructionSpecifier "; o << INSTRUCTIONS_STR "[" << InstructionSpecifiers.size() << "] = {\n"; i++; - unsigned numInstructions = InstructionSpecifiers.size(); - - for (unsigned index = 0; index < numInstructions; ++index) { + for (unsigned index = 0; index < NumInstructions; ++index) { o.indent(i * 2) << "{ /* " << index << " */" << "\n"; i++; o.indent(i * 2) << stringForModifierType( (ModifierType)InstructionSpecifiers[index].modifierType); - o << "," << "\n"; + o << ",\n"; o.indent(i * 2) << "0x"; o << format("%02hhx", (uint16_t)InstructionSpecifiers[index].modifierBase); - o << "," << "\n"; - - o.indent(i * 2) << "{" << "\n"; - i++; - - for (unsigned operandIndex = 0; operandIndex < X86_MAX_OPERANDS; - ++operandIndex) { - o.indent(i * 2) << "{ "; - o <<stringForOperandEncoding((OperandEncoding)InstructionSpecifiers[index] - .operands[operandIndex] - .encoding); - o << ", "; - o << stringForOperandType((OperandType)InstructionSpecifiers[index] - .operands[operandIndex] - .type); - o << " }"; - - if (operandIndex < X86_MAX_OPERANDS - 1) - o << ","; - - o << "\n"; + o << ",\n"; + + OperandListTy OperandList; + for (unsigned OperandIndex = 0; OperandIndex < X86_MAX_OPERANDS; + ++OperandIndex) { + const char *Encoding = + stringForOperandEncoding((OperandEncoding)InstructionSpecifiers[index] + .operands[OperandIndex].encoding); + const char *Type = + stringForOperandType((OperandType)InstructionSpecifiers[index] + .operands[OperandIndex].type); + OperandList.push_back(std::make_pair(Encoding, Type)); } - - i--; - o.indent(i * 2) << "}," << "\n"; + o.indent(i * 2) << (OperandSets[OperandList] - 1) << ",\n"; o.indent(i * 2) << "/* " << InstructionSpecifiers[index].name << " */"; o << "\n"; @@ -473,7 +497,7 @@ void DisassemblerTables::emitInstructionInfo(raw_ostream &o, i--; o.indent(i * 2) << "}"; - if (index + 1 < numInstructions) + if (index + 1 < NumInstructions) o << ","; o << "\n"; |