summaryrefslogtreecommitdiff
path: root/utils
diff options
context:
space:
mode:
authorTim Northover <tnorthover@apple.com>2014-05-12 18:04:06 +0000
committerTim Northover <tnorthover@apple.com>2014-05-12 18:04:06 +0000
commitd6cd0381f676a6eb27d8b3b2aed70eed5fcb439d (patch)
tree34b8228b1fac3a8ba1810b8cfe9edd1f75263dfd /utils
parent2161fd6114b99ab3cf371b4289beb130f591b4ef (diff)
downloadllvm-d6cd0381f676a6eb27d8b3b2aed70eed5fcb439d.tar.gz
llvm-d6cd0381f676a6eb27d8b3b2aed70eed5fcb439d.tar.bz2
llvm-d6cd0381f676a6eb27d8b3b2aed70eed5fcb439d.tar.xz
TableGen: use PrintMethods to print more aliases
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@208607 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'utils')
-rw-r--r--utils/TableGen/AsmWriterEmitter.cpp97
1 files changed, 79 insertions, 18 deletions
diff --git a/utils/TableGen/AsmWriterEmitter.cpp b/utils/TableGen/AsmWriterEmitter.cpp
index 8e83df2009..de389c1283 100644
--- a/utils/TableGen/AsmWriterEmitter.cpp
+++ b/utils/TableGen/AsmWriterEmitter.cpp
@@ -39,6 +39,7 @@ class AsmWriterEmitter {
std::map<const CodeGenInstruction*, AsmWriterInst*> CGIAWIMap;
const std::vector<const CodeGenInstruction*> *NumberedInstructions;
std::vector<AsmWriterInst> Instructions;
+ std::vector<std::string> PrintMethods;
public:
AsmWriterEmitter(RecordKeeper &R);
@@ -629,22 +630,25 @@ namespace {
// alias for that pattern.
class IAPrinter {
std::vector<std::string> Conds;
- std::map<StringRef, unsigned> OpMap;
+ std::map<StringRef, std::pair<int, int>> OpMap;
+ SmallVector<Record*, 4> ReqFeatures;
+
std::string Result;
std::string AsmString;
- SmallVector<Record*, 4> ReqFeatures;
public:
- IAPrinter(std::string R, std::string AS)
- : Result(R), AsmString(AS) {}
+ IAPrinter(std::string R, std::string AS) : Result(R), AsmString(AS) {}
void addCond(const std::string &C) { Conds.push_back(C); }
- void addOperand(StringRef Op, unsigned Idx) {
- assert(Idx < 0xFF && "Index too large!");
- OpMap[Op] = Idx;
+ void addOperand(StringRef Op, int OpIdx, int PrintMethodIdx = -1) {
+ assert(OpIdx >= 0 && OpIdx < 0xFE && "Idx out of range");
+ assert(PrintMethodIdx == -1 || PrintMethodIdx < 0xFF && "Idx out of range");
+ OpMap[Op] = std::make_pair(OpIdx, PrintMethodIdx);
}
- unsigned getOpIndex(StringRef Op) { return OpMap[Op]; }
+
bool isOpMapped(StringRef Op) { return OpMap.find(Op) != OpMap.end(); }
+ int getOpIndex(StringRef Op) { return OpMap[Op].first; }
+ std::pair<int, int> &getOpData(StringRef Op) { return OpMap[Op]; }
void print(raw_ostream &O) {
if (Conds.empty() && ReqFeatures.empty()) {
@@ -686,7 +690,16 @@ public:
++I;
StringRef Name(Start, I - Start);
assert(isOpMapped(Name) && "Unmapped operand!");
- OS << format("\\x%02X", (unsigned char)getOpIndex(Name) + 1);
+
+ int OpIndex, PrintIndex;
+ std::tie(OpIndex, PrintIndex) = getOpData(Name);
+ if (PrintIndex == -1) {
+ // Can use the default printOperand route.
+ OS << format("\\x%02X", (unsigned char)OpIndex + 1);
+ } else
+ // 3 bytes if a PrintMethod is needed: 0xFF, the MCInst operand
+ // number, and which of our pre-detected Methods to call.
+ OS << format("\\xFF\\x%02X\\x%02X", OpIndex + 1, PrintIndex + 1);
} else {
++I;
}
@@ -755,6 +768,10 @@ void AsmWriterEmitter::EmitPrintAliasInstruction(raw_ostream &O) {
O << "\n#ifdef PRINT_ALIAS_INSTR\n";
O << "#undef PRINT_ALIAS_INSTR\n\n";
+ //////////////////////////////
+ // Gather information about aliases we need to print
+ //////////////////////////////
+
// Emit the method that prints the alias instruction.
std::string ClassName = AsmWriter->getValueAsString("AsmWriterClassName");
@@ -809,7 +826,22 @@ void AsmWriterEmitter::EmitPrintAliasInstruction(raw_ostream &O) {
case CodeGenInstAlias::ResultOperand::K_Record: {
const Record *Rec = RO.getRecord();
StringRef ROName = RO.getName();
-
+ int PrintMethodIdx = -1;
+
+ // These two may have a PrintMethod, which we want to record (if it's
+ // the first time we've seen it) and provide an index for the aliasing
+ // code to use.
+ if (Rec->isSubClassOf("RegisterOperand") ||
+ Rec->isSubClassOf("Operand")) {
+ std::string PrintMethod = Rec->getValueAsString("PrintMethod");
+ if (PrintMethod != "" && PrintMethod != "printOperand") {
+ PrintMethodIdx = std::find(PrintMethods.begin(),
+ PrintMethods.end(), PrintMethod) -
+ PrintMethods.begin();
+ if (static_cast<unsigned>(PrintMethodIdx) == PrintMethods.size())
+ PrintMethods.push_back(PrintMethod);
+ }
+ }
if (Rec->isSubClassOf("RegisterOperand"))
Rec = Rec->getValueAsDef("RegClass");
@@ -818,7 +850,7 @@ void AsmWriterEmitter::EmitPrintAliasInstruction(raw_ostream &O) {
IAP->addCond(Cond);
if (!IAP->isOpMapped(ROName)) {
- IAP->addOperand(ROName, i);
+ IAP->addOperand(ROName, i, PrintMethodIdx);
Record *R = CGA->ResultOperands[i].getRecord();
if (R->isSubClassOf("RegisterOperand"))
R = R->getValueAsDef("RegClass");
@@ -833,12 +865,9 @@ void AsmWriterEmitter::EmitPrintAliasInstruction(raw_ostream &O) {
IAP->addCond(Cond);
}
} else {
- assert(Rec->isSubClassOf("Operand") && "Unexpected operand!");
- // FIXME: We may need to handle these situations.
- delete IAP;
- IAP = nullptr;
- CantHandle = true;
- break;
+ // Assume all printable operands are desired for now. This can be
+ // overridden in the InstAlias instantiation if neccessary.
+ IAP->addOperand(ROName, i, PrintMethodIdx);
}
break;
@@ -878,6 +907,10 @@ void AsmWriterEmitter::EmitPrintAliasInstruction(raw_ostream &O) {
}
}
+ //////////////////////////////
+ // Write out the printAliasInstr function
+ //////////////////////////////
+
std::string Header;
raw_string_ostream HeaderO(Header);
@@ -951,7 +984,13 @@ void AsmWriterEmitter::EmitPrintAliasInstruction(raw_ostream &O) {
O << " do {\n";
O << " if (AsmString[I] == '$') {\n";
O << " ++I;\n";
- O << " printOperand(MI, unsigned(AsmString[I++]) - 1, OS);\n";
+ O << " if (AsmString[I] == (char)0xff) {\n";
+ O << " ++I;\n";
+ O << " int OpIdx = AsmString[I++] - 1;\n";
+ O << " int PrintMethodIdx = AsmString[I++] - 1;\n";
+ O << " printCustomAliasOperand(MI, OpIdx, PrintMethodIdx, OS);\n";
+ O << " } else\n";
+ O << " printOperand(MI, unsigned(AsmString[I++]) - 1, OS);\n";
O << " } else {\n";
O << " OS << AsmString[I++];\n";
O << " }\n";
@@ -961,6 +1000,28 @@ void AsmWriterEmitter::EmitPrintAliasInstruction(raw_ostream &O) {
O << " return true;\n";
O << "}\n\n";
+ //////////////////////////////
+ // Write out the printCustomAliasOperand function
+ //////////////////////////////
+
+ O << "void " << Target.getName() << ClassName << "::"
+ << "printCustomAliasOperand(\n"
+ << " const MCInst *MI, unsigned OpIdx,\n"
+ << " unsigned PrintMethodIdx, raw_ostream &OS) {\n"
+ << " switch (PrintMethodIdx) {\n"
+ << " default:\n"
+ << " llvm_unreachable(\"Unknown PrintMethod kind\");\n"
+ << " break;\n";
+
+ for (unsigned i = 0; i < PrintMethods.size(); ++i) {
+ O << " case " << i << ":\n"
+ << " " << PrintMethods[i] << "(MI, OpIdx, OS);\n"
+ << " break;\n";
+ }
+
+ O << " }\n"
+ << "}\n\n";
+
O << "#endif // PRINT_ALIAS_INSTR\n";
}