summaryrefslogtreecommitdiff
path: root/llvm/utils/TableGen/AsmWriterEmitter.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/utils/TableGen/AsmWriterEmitter.cpp')
-rw-r--r--llvm/utils/TableGen/AsmWriterEmitter.cpp113
1 files changed, 71 insertions, 42 deletions
diff --git a/llvm/utils/TableGen/AsmWriterEmitter.cpp b/llvm/utils/TableGen/AsmWriterEmitter.cpp
index d10ea71e97e3..92df204475b9 100644
--- a/llvm/utils/TableGen/AsmWriterEmitter.cpp
+++ b/llvm/utils/TableGen/AsmWriterEmitter.cpp
@@ -64,9 +64,15 @@ public:
AsmWriterEmitter(RecordKeeper &R);
void run(raw_ostream &o);
-
private:
- void EmitPrintInstruction(raw_ostream &o);
+ void EmitGetMnemonic(
+ raw_ostream &o,
+ std::vector<std::vector<std::string>> &TableDrivenOperandPrinters,
+ unsigned &BitsLeft, unsigned &AsmStrBits);
+ void EmitPrintInstruction(
+ raw_ostream &o,
+ std::vector<std::vector<std::string>> &TableDrivenOperandPrinters,
+ unsigned &BitsLeft, unsigned &AsmStrBits);
void EmitGetRegisterName(raw_ostream &o);
void EmitPrintAliasInstruction(raw_ostream &O);
@@ -212,12 +218,11 @@ FindUniqueOperandCommands(std::vector<std::string> &UniqueOperandCommands,
// Otherwise, scan to see if all of the other instructions in this command
// set share the operand.
- if (std::any_of(Idxs.begin()+1, Idxs.end(),
- [&](unsigned Idx) {
- const AsmWriterInst &OtherInst = Instructions[Idx];
- return OtherInst.Operands.size() == Op ||
- OtherInst.Operands[Op] != FirstInst.Operands[Op];
- }))
+ if (any_of(drop_begin(Idxs), [&](unsigned Idx) {
+ const AsmWriterInst &OtherInst = Instructions[Idx];
+ return OtherInst.Operands.size() == Op ||
+ OtherInst.Operands[Op] != FirstInst.Operands[Op];
+ }))
break;
// Okay, everything in this command set has the same next operand. Add it
@@ -288,22 +293,19 @@ static void UnescapeAliasString(std::string &Str) {
}
}
-/// EmitPrintInstruction - Generate the code for the "printInstruction" method
-/// implementation. Destroys all instances of AsmWriterInst information, by
-/// clearing the Instructions vector.
-void AsmWriterEmitter::EmitPrintInstruction(raw_ostream &O) {
+void AsmWriterEmitter::EmitGetMnemonic(
+ raw_ostream &O,
+ std::vector<std::vector<std::string>> &TableDrivenOperandPrinters,
+ unsigned &BitsLeft, unsigned &AsmStrBits) {
Record *AsmWriter = Target.getAsmWriter();
StringRef ClassName = AsmWriter->getValueAsString("AsmWriterClassName");
bool PassSubtarget = AsmWriter->getValueAsInt("PassSubtarget");
- O << "/// printInstruction - This method is automatically generated by "
+ O << "/// getMnemonic - This method is automatically generated by "
"tablegen\n"
"/// from the instruction set description.\n"
- "void "
- << Target.getName() << ClassName
- << "::printInstruction(const MCInst *MI, uint64_t Address, "
- << (PassSubtarget ? "const MCSubtargetInfo &STI, " : "")
- << "raw_ostream &O) {\n";
+ "std::pair<const char *, uint64_t> "
+ << Target.getName() << ClassName << "::getMnemonic(const MCInst *MI) {\n";
// Build an aggregate string, and build a table of offsets into it.
SequenceToOffsetTable<std::string> StringTable;
@@ -349,13 +351,11 @@ void AsmWriterEmitter::EmitPrintInstruction(raw_ostream &O) {
}
// Figure out how many bits we used for the string index.
- unsigned AsmStrBits = Log2_32_Ceil(MaxStringIdx+2);
+ AsmStrBits = Log2_32_Ceil(MaxStringIdx + 2);
// To reduce code size, we compactify common instructions into a few bits
// in the opcode-indexed table.
- unsigned BitsLeft = OpcodeInfoBits-AsmStrBits;
-
- std::vector<std::vector<std::string>> TableDrivenOperandPrinters;
+ BitsLeft = OpcodeInfoBits - AsmStrBits;
while (true) {
std::vector<std::string> UniqueOperandCommands;
@@ -435,15 +435,47 @@ void AsmWriterEmitter::EmitPrintInstruction(raw_ostream &O) {
++Table;
}
- // Emit the initial tab character.
- O << " O << \"\\t\";\n\n";
-
O << " // Emit the opcode for the instruction.\n";
O << BitsString;
+ // Return mnemonic string and bits.
+ O << " return {AsmStrs+(Bits & " << (1 << AsmStrBits) - 1
+ << ")-1, Bits};\n\n";
+
+ O << "}\n";
+}
+
+/// EmitPrintInstruction - Generate the code for the "printInstruction" method
+/// implementation. Destroys all instances of AsmWriterInst information, by
+/// clearing the Instructions vector.
+void AsmWriterEmitter::EmitPrintInstruction(
+ raw_ostream &O,
+ std::vector<std::vector<std::string>> &TableDrivenOperandPrinters,
+ unsigned &BitsLeft, unsigned &AsmStrBits) {
+ const unsigned OpcodeInfoBits = 64;
+ Record *AsmWriter = Target.getAsmWriter();
+ StringRef ClassName = AsmWriter->getValueAsString("AsmWriterClassName");
+ bool PassSubtarget = AsmWriter->getValueAsInt("PassSubtarget");
+
+ O << "/// printInstruction - This method is automatically generated by "
+ "tablegen\n"
+ "/// from the instruction set description.\n"
+ "void "
+ << Target.getName() << ClassName
+ << "::printInstruction(const MCInst *MI, uint64_t Address, "
+ << (PassSubtarget ? "const MCSubtargetInfo &STI, " : "")
+ << "raw_ostream &O) {\n";
+
+ // Emit the initial tab character.
+ O << " O << \"\\t\";\n\n";
+
// Emit the starting string.
- O << " assert(Bits != 0 && \"Cannot print this instruction.\");\n"
- << " O << AsmStrs+(Bits & " << (1 << AsmStrBits)-1 << ")-1;\n\n";
+ O << " auto MnemonicInfo = getMnemonic(MI);\n\n";
+ O << " O << MnemonicInfo.first;\n\n";
+
+ O << " uint" << ((BitsLeft < (OpcodeInfoBits - 32)) ? 64 : 32)
+ << "_t Bits = MnemonicInfo.second;\n"
+ << " assert(Bits != 0 && \"Cannot print this instruction.\");\n";
// Output the table driven operand information.
BitsLeft = OpcodeInfoBits-AsmStrBits;
@@ -489,10 +521,8 @@ void AsmWriterEmitter::EmitPrintInstruction(raw_ostream &O) {
}
// Okay, delete instructions with no operand info left.
- auto I = llvm::remove_if(Instructions,
- [](AsmWriterInst &Inst) { return Inst.Operands.empty(); });
- Instructions.erase(I, Instructions.end());
-
+ llvm::erase_if(Instructions,
+ [](AsmWriterInst &Inst) { return Inst.Operands.empty(); });
// Because this is a vector, we want to emit from the end. Reverse all of the
// elements in the vector.
@@ -683,9 +713,7 @@ public:
++Next;
} else {
// $name, just eat the usual suspects.
- while (I != End &&
- ((*I >= 'a' && *I <= 'z') || (*I >= 'A' && *I <= 'Z') ||
- (*I >= '0' && *I <= '9') || *I == '_'))
+ while (I != End && (isAlnum(*I) || *I == '_'))
++I;
Next = I;
}
@@ -1232,13 +1260,10 @@ void AsmWriterEmitter::EmitPrintAliasInstruction(raw_ostream &O) {
<< " break;\n";
for (unsigned i = 0; i < MCOpPredicates.size(); ++i) {
- Init *MCOpPred = MCOpPredicates[i]->getValueInit("MCOperandPredicate");
- if (CodeInit *SI = dyn_cast<CodeInit>(MCOpPred)) {
- O << " case " << i + 1 << ": {\n"
- << SI->getValue() << "\n"
- << " }\n";
- } else
- llvm_unreachable("Unexpected MCOperandPredicate field!");
+ StringRef MCOpPred = MCOpPredicates[i]->getValueAsString("MCOperandPredicate");
+ O << " case " << i + 1 << ": {\n"
+ << MCOpPred.data() << "\n"
+ << " }\n";
}
O << " }\n"
<< "}\n\n";
@@ -1262,7 +1287,11 @@ AsmWriterEmitter::AsmWriterEmitter(RecordKeeper &R) : Records(R), Target(R) {
}
void AsmWriterEmitter::run(raw_ostream &O) {
- EmitPrintInstruction(O);
+ std::vector<std::vector<std::string>> TableDrivenOperandPrinters;
+ unsigned BitsLeft = 0;
+ unsigned AsmStrBits = 0;
+ EmitGetMnemonic(O, TableDrivenOperandPrinters, BitsLeft, AsmStrBits);
+ EmitPrintInstruction(O, TableDrivenOperandPrinters, BitsLeft, AsmStrBits);
EmitGetRegisterName(O);
EmitPrintAliasInstruction(O);
}