aboutsummaryrefslogtreecommitdiff
path: root/utils
diff options
context:
space:
mode:
authorCraig Topper <craig.topper@gmail.com>2012-08-01 07:39:18 +0000
committerCraig Topper <craig.topper@gmail.com>2012-08-01 07:39:18 +0000
commit5a2c607153993fb7f7e04f9482520b64dffe5757 (patch)
treef14464b140bcf52862a0fb65db6dde5b76d17fc7 /utils
parentadfe2637b839efe041165f27c9ad57e3befb2be0 (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.h1
-rw-r--r--utils/TableGen/X86DisassemblerTables.cpp82
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";