diff --git a/llvm/test/TableGen/pseudo-inst-expansion.td b/llvm/test/TableGen/pseudo-inst-expansion.td --- a/llvm/test/TableGen/pseudo-inst-expansion.td +++ b/llvm/test/TableGen/pseudo-inst-expansion.td @@ -35,3 +35,23 @@ PseudoInstExpansion<(INSTR GPR:$rd, SR.Encoding)>; // CHECK: .addOperand(MCOperand::createImm(3855)); + +def ComplexOp : Operand { let MIOperandInfo = (ops GPR, i32imm); } + +def INSTR2 : Instruction { + let OutOperandList = (outs); + let InOperandList = (ins ComplexOp:$cop, GPR:$r); +} + +def PSEUDO2 : Pseudo<(outs), (ins ComplexOp:$cop), []>, + PseudoInstExpansion<(INSTR2 ComplexOp:$cop, REG)>; + +// CHECK: TmpInst.setOpcode(::INSTR2); +// CHECK-NEXT: // Operand: cop +// CHECK-NEXT: lowerOperand(MI->getOperand(0), MCOp); +// CHECK-NEXT: TmpInst.addOperand(MCOp); +// CHECK-NEXT: lowerOperand(MI->getOperand(1), MCOp); +// CHECK-NEXT: TmpInst.addOperand(MCOp); +// CHECK-NEXT: // Operand: r +// CHECK-NEXT: TmpInst.addOperand(MCOperand::createReg(::REG)); +// CHECK-NEXT: EmitToStreamer(OutStreamer, TmpInst); diff --git a/llvm/utils/TableGen/PseudoLoweringEmitter.cpp b/llvm/utils/TableGen/PseudoLoweringEmitter.cpp --- a/llvm/utils/TableGen/PseudoLoweringEmitter.cpp +++ b/llvm/utils/TableGen/PseudoLoweringEmitter.cpp @@ -51,10 +51,9 @@ SmallVector Expansions; - unsigned addDagOperandMapping(Record *Rec, DagInit *Dag, - CodeGenInstruction &Insn, - IndexedMap &OperandMap, - unsigned BaseIdx); + void addDagOperandMapping(Record *Rec, DagInit *Dag, CodeGenInstruction &Insn, + IndexedMap &OperandMap, + unsigned &MIOperandNo); void evaluateExpansion(Record *Pseudo); void emitLoweringEmitter(raw_ostream &o); public: @@ -69,63 +68,59 @@ // The pseudo expansion really should take a list of dags, not just // a single dag, so we can do fancier things. -unsigned PseudoLoweringEmitter:: -addDagOperandMapping(Record *Rec, DagInit *Dag, CodeGenInstruction &Insn, - IndexedMap &OperandMap, unsigned BaseIdx) { - unsigned OpsAdded = 0; +void PseudoLoweringEmitter::addDagOperandMapping(Record *Rec, DagInit *Dag, + CodeGenInstruction &Insn, + IndexedMap &OperandMap, + unsigned &MIOperandNo) { for (unsigned i = 0, e = Dag->getNumArgs(); i != e; ++i) { + unsigned OperandNo = Insn.Operands.getSubOperandNumber(MIOperandNo).first; + const CGIOperandList::OperandInfo &OpInfo = Insn.Operands[OperandNo]; + if (DefInit *DI = dyn_cast(Dag->getArg(i))) { // Physical register reference. Explicit check for the special case // "zero_reg" definition. if (DI->getDef()->isSubClassOf("Register") || DI->getDef()->getName() == "zero_reg") { - OperandMap[BaseIdx + i].Kind = OpData::Reg; - OperandMap[BaseIdx + i].Data.Reg = DI->getDef(); - ++OpsAdded; + OperandMap[MIOperandNo].Kind = OpData::Reg; + OperandMap[MIOperandNo].Data.Reg = DI->getDef(); + ++MIOperandNo; continue; } // Normal operands should always have the same type, or we have a // problem. - // FIXME: We probably shouldn't ever get a non-zero BaseIdx here. - assert(BaseIdx == 0 && "Named subargument in pseudo expansion?!"); // FIXME: Are the message operand types backward? - if (DI->getDef() != Insn.Operands[BaseIdx + i].Rec) { + if (DI->getDef() != OpInfo.Rec) { PrintError(Rec, "In pseudo instruction '" + Rec->getName() + - "', operand type '" + DI->getDef()->getName() + - "' does not match expansion operand type '" + - Insn.Operands[BaseIdx + i].Rec->getName() + "'"); + "', operand type '" + DI->getDef()->getName() + + "' does not match expansion operand type '" + + OpInfo.Rec->getName() + "'"); PrintFatalNote(DI->getDef(), "Value was assigned at the following location:"); } // Source operand maps to destination operand. The Data element // will be filled in later, just set the Kind for now. Do it // for each corresponding MachineInstr operand, not just the first. - for (unsigned I = 0, E = Insn.Operands[i].MINumOperands; I != E; ++I) - OperandMap[BaseIdx + i + I].Kind = OpData::Operand; - OpsAdded += Insn.Operands[i].MINumOperands; + for (unsigned I = 0, E = OpInfo.MINumOperands; I != E; ++I) + OperandMap[MIOperandNo++].Kind = OpData::Operand; } else if (IntInit *II = dyn_cast(Dag->getArg(i))) { - OperandMap[BaseIdx + i].Kind = OpData::Imm; - OperandMap[BaseIdx + i].Data.Imm = II->getValue(); - ++OpsAdded; + OperandMap[MIOperandNo].Kind = OpData::Imm; + OperandMap[MIOperandNo].Data.Imm = II->getValue(); + ++MIOperandNo; } else if (auto *BI = dyn_cast(Dag->getArg(i))) { auto *II = cast(BI->convertInitializerTo(IntRecTy::get(Records))); - OperandMap[BaseIdx + i].Kind = OpData::Imm; - OperandMap[BaseIdx + i].Data.Imm = II->getValue(); - ++OpsAdded; + OperandMap[MIOperandNo].Kind = OpData::Imm; + OperandMap[MIOperandNo].Data.Imm = II->getValue(); + ++MIOperandNo; } else if (DagInit *SubDag = dyn_cast(Dag->getArg(i))) { // Just add the operands recursively. This is almost certainly // a constant value for a complex operand (> 1 MI operand). - unsigned NewOps = - addDagOperandMapping(Rec, SubDag, Insn, OperandMap, BaseIdx + i); - OpsAdded += NewOps; - // Since we added more than one, we also need to adjust the base. - BaseIdx += NewOps - 1; - } else + addDagOperandMapping(Rec, SubDag, Insn, OperandMap, MIOperandNo); + } else { llvm_unreachable("Unhandled pseudo-expansion argument type!"); + } } - return OpsAdded; } void PseudoLoweringEmitter::evaluateExpansion(Record *Rec) { @@ -177,7 +172,9 @@ IndexedMap OperandMap; OperandMap.grow(NumMIOperands); - addDagOperandMapping(Rec, Dag, Insn, OperandMap, 0); + unsigned MIOperandNo = 0; + addDagOperandMapping(Rec, Dag, Insn, OperandMap, MIOperandNo); + assert(MIOperandNo == NumMIOperands); // If there are more operands that weren't in the DAG, they have to // be operands that have default values, or we have an error. Currently,