- StringToOffsetTable StringTable;
- O <<
-"\n\n#ifdef GET_INSTRUCTION_NAME\n"
-"#undef GET_INSTRUCTION_NAME\n\n"
-"/// getInstructionName: This method is automatically generated by tblgen\n"
-"/// from the instruction set description. This returns the enum name of the\n"
-"/// specified instruction.\n"
- "const char *" << Target.getName() << ClassName
- << "::getInstructionName(unsigned Opcode) {\n"
- << " assert(Opcode < " << NumberedInstructions.size()
- << " && \"Invalid instruction number!\");\n"
- << "\n"
- << " static const unsigned InstAsmOffset[] = {";
- for (unsigned i = 0, e = NumberedInstructions.size(); i != e; ++i) {
- const CodeGenInstruction &Inst = *NumberedInstructions[i];
+ // A map of which conditions need to be met for each instruction operand
+ // before it can be matched to the mnemonic.
+ std::map<std::string, std::vector<IAPrinter*> > IAPrinterMap;
+
+ for (std::map<std::string, std::vector<CodeGenInstAlias*> >::iterator
+ I = AliasMap.begin(), E = AliasMap.end(); I != E; ++I) {
+ std::vector<CodeGenInstAlias*> &Aliases = I->second;
+
+ for (std::vector<CodeGenInstAlias*>::iterator
+ II = Aliases.begin(), IE = Aliases.end(); II != IE; ++II) {
+ const CodeGenInstAlias *CGA = *II;
+ unsigned LastOpNo = CGA->ResultInstOperandIndex.size();
+ unsigned NumResultOps =
+ CountResultNumOperands(CGA->ResultInst->AsmString);
+
+ // Don't emit the alias if it has more operands than what it's aliasing.
+ if (NumResultOps < CountNumOperands(CGA->AsmString))
+ continue;
+
+ IAPrinter *IAP = new IAPrinter(CGA->Result->getAsString(),
+ CGA->AsmString);
+
+ std::string Cond;
+ Cond = std::string("MI->getNumOperands() == ") + llvm::utostr(LastOpNo);
+ IAP->addCond(Cond);
+
+ std::map<StringRef, unsigned> OpMap;
+ bool CantHandle = false;
+
+ for (unsigned i = 0, e = LastOpNo; i != e; ++i) {
+ const CodeGenInstAlias::ResultOperand &RO = CGA->ResultOperands[i];
+
+ switch (RO.Kind) {
+ case CodeGenInstAlias::ResultOperand::K_Record: {
+ const Record *Rec = RO.getRecord();
+ StringRef ROName = RO.getName();
+
+
+ if (Rec->isSubClassOf("RegisterOperand"))
+ Rec = Rec->getValueAsDef("RegClass");
+ if (Rec->isSubClassOf("RegisterClass")) {
+ Cond = std::string("MI->getOperand(")+llvm::utostr(i)+").isReg()";
+ IAP->addCond(Cond);
+
+ if (!IAP->isOpMapped(ROName)) {
+ IAP->addOperand(ROName, i);
+ Cond = std::string("MRI.getRegClass(") + Target.getName() + "::" +
+ CGA->ResultOperands[i].getRecord()->getName() + "RegClassID)"
+ ".contains(MI->getOperand(" + llvm::utostr(i) + ").getReg())";
+ IAP->addCond(Cond);
+ } else {
+ Cond = std::string("MI->getOperand(") +
+ llvm::utostr(i) + ").getReg() == MI->getOperand(" +
+ llvm::utostr(IAP->getOpIndex(ROName)) + ").getReg()";
+ IAP->addCond(Cond);
+ }
+ } else {
+ assert(Rec->isSubClassOf("Operand") && "Unexpected operand!");
+ // FIXME: We may need to handle these situations.
+ delete IAP;
+ IAP = 0;
+ CantHandle = true;
+ break;
+ }