diff options
Diffstat (limited to 'utils/TableGen/AsmWriterEmitter.cpp')
-rw-r--r-- | utils/TableGen/AsmWriterEmitter.cpp | 66 |
1 files changed, 52 insertions, 14 deletions
diff --git a/utils/TableGen/AsmWriterEmitter.cpp b/utils/TableGen/AsmWriterEmitter.cpp index 2741d8f..c7fe9df 100644 --- a/utils/TableGen/AsmWriterEmitter.cpp +++ b/utils/TableGen/AsmWriterEmitter.cpp @@ -806,6 +806,10 @@ void AsmWriterEmitter::EmitPrintAliasInstruction(raw_ostream &O) { // before it can be matched to the mnemonic. std::map<std::string, std::vector<IAPrinter*> > IAPrinterMap; + // A list of MCOperandPredicates for all operands in use, and the reverse map + std::vector<const Record*> MCOpPredicates; + DenseMap<const Record*, unsigned> MCOpPredicateMap; + for (auto &Aliases : AliasMap) { for (auto &Alias : Aliases.second) { const CodeGenInstAlias *CGA = Alias.first; @@ -832,6 +836,8 @@ void AsmWriterEmitter::EmitPrintAliasInstruction(raw_ostream &O) { unsigned MIOpNum = 0; for (unsigned i = 0, e = LastOpNo; i != e; ++i) { + std::string Op = "MI->getOperand(" + llvm::utostr(MIOpNum) + ")"; + const CodeGenInstAlias::ResultOperand &RO = CGA->ResultOperands[i]; switch (RO.Kind) { @@ -858,9 +864,7 @@ void AsmWriterEmitter::EmitPrintAliasInstruction(raw_ostream &O) { if (Rec->isSubClassOf("RegisterOperand")) Rec = Rec->getValueAsDef("RegClass"); if (Rec->isSubClassOf("RegisterClass")) { - Cond = std::string("MI->getOperand(") + llvm::utostr(MIOpNum) + - ").isReg()"; - IAP->addCond(Cond); + IAP->addCond(Op + ".isReg()"); if (!IAP->isOpMapped(ROName)) { IAP->addOperand(ROName, MIOpNum, PrintMethodIdx); @@ -869,26 +873,34 @@ void AsmWriterEmitter::EmitPrintAliasInstruction(raw_ostream &O) { R = R->getValueAsDef("RegClass"); Cond = std::string("MRI.getRegClass(") + Target.getName() + "::" + R->getName() + "RegClassID)" - ".contains(MI->getOperand(" + - llvm::utostr(MIOpNum) + ").getReg())"; - IAP->addCond(Cond); + ".contains(" + Op + ".getReg())"; } else { - Cond = std::string("MI->getOperand(") + - llvm::utostr(MIOpNum) + ").getReg() == MI->getOperand(" + + Cond = Op + ".getReg() == MI->getOperand(" + llvm::utostr(IAP->getOpIndex(ROName)) + ").getReg()"; - IAP->addCond(Cond); } } else { // Assume all printable operands are desired for now. This can be // overridden in the InstAlias instantiation if necessary. IAP->addOperand(ROName, MIOpNum, PrintMethodIdx); - } + // There might be an additional predicate on the MCOperand + unsigned Entry = MCOpPredicateMap[Rec]; + if (!Entry) { + if (!Rec->isValueUnset("MCOperandPredicate")) { + MCOpPredicates.push_back(Rec); + Entry = MCOpPredicates.size(); + MCOpPredicateMap[Rec] = Entry; + } else + break; // No conditions on this operand at all + } + Cond = Target.getName() + ClassName + "ValidateMCOperand(" + + Op + ", " + llvm::utostr(Entry) + ")"; + } + // for all subcases of ResultOperand::K_Record: + IAP->addCond(Cond); break; } case CodeGenInstAlias::ResultOperand::K_Imm: { - std::string Op = "MI->getOperand(" + llvm::utostr(MIOpNum) + ")"; - // Just because the alias has an immediate result, doesn't mean the // MCInst will. An MCExpr could be present, for example. IAP->addCond(Op + ".isImm()"); @@ -906,8 +918,7 @@ void AsmWriterEmitter::EmitPrintAliasInstruction(raw_ostream &O) { break; } - Cond = std::string("MI->getOperand(") + - llvm::utostr(MIOpNum) + ").getReg() == " + Target.getName() + + Cond = Op + ".getReg() == " + Target.getName() + "::" + CGA->ResultOperands[i].getRegister()->getName(); IAP->addCond(Cond); break; @@ -980,6 +991,11 @@ void AsmWriterEmitter::EmitPrintAliasInstruction(raw_ostream &O) { return; } + if (MCOpPredicates.size()) + O << "static bool " << Target.getName() << ClassName + << "ValidateMCOperand(\n" + << " const MCOperand &MCOp, unsigned PredicateIndex);\n"; + O << HeaderO.str(); O.indent(2) << "const char *AsmString;\n"; O.indent(2) << "switch (MI->getOpcode()) {\n"; @@ -1041,6 +1057,28 @@ void AsmWriterEmitter::EmitPrintAliasInstruction(raw_ostream &O) { } O << "}\n\n"; + if (MCOpPredicates.size()) { + O << "static bool " << Target.getName() << ClassName + << "ValidateMCOperand(\n" + << " const MCOperand &MCOp, unsigned PredicateIndex) {\n" + << " switch (PredicateIndex) {\n" + << " default:\n" + << " llvm_unreachable(\"Unknown MCOperandPredicate kind\");\n" + << " break;\n"; + + for (unsigned i = 0; i < MCOpPredicates.size(); ++i) { + Init *MCOpPred = MCOpPredicates[i]->getValueInit("MCOperandPredicate"); + if (StringInit *SI = dyn_cast<StringInit>(MCOpPred)) { + O << " case " << i + 1 << ": {\n" + << SI->getValue() << "\n" + << " }\n"; + } else + llvm_unreachable("Unexpected MCOperandPredicate field!"); + } + O << " }\n" + << "}\n\n"; + } + O << "#endif // PRINT_ALIAS_INSTR\n"; } |