+ // Emit all of the operands.
+ std::vector<std::pair<unsigned, unsigned> > NumTemps(EmitOrder.size());
+ for (unsigned i = 0, e = EmitOrder.size(); i != e; ++i) {
+ unsigned OpOrder = EmitOrder[i].first;
+ TreePatternNode *Child = EmitOrder[i].second;
+ std::pair<unsigned, unsigned> NumTemp = EmitResultCode(Child);
+ NumTemps[OpOrder] = NumTemp;
+ }
+
+ // List all the operands in the right order.
+ std::vector<unsigned> Ops;
+ for (unsigned i = 0, e = NumTemps.size(); i != e; i++) {
+ for (unsigned j = 0; j < NumTemps[i].first; j++)
+ Ops.push_back(NumTemps[i].second + j);
+ }
+
+ const CodeGenTarget &CGT = ISE.getTargetInfo();
+ CodeGenInstruction &II = CGT.getInstruction(Op->getName());
+
+ // Emit all the chain and CopyToReg stuff.
+ if (II.hasCtrlDep)
+ OS << " Chain = Select(Chain);\n";
+ if (InFlag)
+ EmitCopyToRegs(Pattern, "N", II.hasCtrlDep);
+
+ unsigned NumResults = Inst.getNumResults();
+ unsigned ResNo = TmpNo++;
+ if (!isRoot) {
+ OS << " SDOperand Tmp" << ResNo << " = CurDAG->getTargetNode("
+ << II.Namespace << "::" << II.TheDef->getName();
+ if (N->getType() != MVT::isVoid)
+ OS << ", MVT::" << getEnumName(N->getType());
+ if (OutFlag)
+ OS << ", MVT::Flag";
+
+ unsigned LastOp = 0;
+ for (unsigned i = 0, e = Ops.size(); i != e; ++i) {
+ LastOp = Ops[i];
+ OS << ", Tmp" << LastOp;
+ }
+ OS << ");\n";
+ if (II.hasCtrlDep) {
+ // Must have at least one result
+ OS << " Chain = Tmp" << LastOp << ".getValue("
+ << NumResults << ");\n";
+ }
+ } else if (II.hasCtrlDep || OutFlag) {
+ OS << " SDOperand Result = CurDAG->getTargetNode("
+ << II.Namespace << "::" << II.TheDef->getName();
+
+ // Output order: results, chain, flags
+ // Result types.
+ if (NumResults > 0) {
+ // TODO: multiple results?
+ if (N->getType() != MVT::isVoid)
+ OS << ", MVT::" << getEnumName(N->getType());
+ }
+ if (II.hasCtrlDep)
+ OS << ", MVT::Other";
+ if (OutFlag)
+ OS << ", MVT::Flag";
+
+ // Inputs.
+ for (unsigned i = 0, e = Ops.size(); i != e; ++i)
+ OS << ", Tmp" << Ops[i];
+ if (II.hasCtrlDep) OS << ", Chain";
+ if (InFlag) OS << ", InFlag";
+ OS << ");\n";
+
+ unsigned ValNo = 0;
+ for (unsigned i = 0; i < NumResults; i++) {
+ OS << " CodeGenMap[N.getValue(" << ValNo << ")] = Result"
+ << ".getValue(" << ValNo << ");\n";
+ ValNo++;
+ }
+
+ if (II.hasCtrlDep) {
+ OS << " Chain = Result.getValue(" << ValNo << ");\n";
+ if (OutFlag)
+ OS << " InFlag = Result.getValue(" << ValNo+1 << ");\n";
+ } else if (OutFlag)
+ OS << " InFlag = Result.getValue(" << ValNo << ");\n";
+
+ if (OutFlag)
+ IsCopyFromReg = EmitCopyFromRegs(N, II.hasCtrlDep);
+ if (IsCopyFromReg)
+ OS << " CodeGenMap[N.getValue(" << ValNo++ << ")] = Result;\n";
+
+ if (OutFlag)
+ OS << " CodeGenMap[N.getValue(" << ValNo++ << ")] = InFlag;\n";
+
+ if (IsCopyFromReg || II.hasCtrlDep) {
+ OS << " ";
+ if (IsCopyFromReg || NodeHasChain(Pattern, ISE))
+ OS << "CodeGenMap[N.getValue(" << ValNo << ")] = ";
+ for (unsigned j = 0, e = FoldedChains.size(); j < e; j++)
+ OS << "CodeGenMap[" << FoldedChains[j].first << ".getValue("
+ << FoldedChains[j].second << ")] = ";
+ OS << "Chain;\n";
+ }
+
+ // FIXME: this only works because (for now) an instruction can either
+ // produce a single result or a single flag.
+ if (II.hasCtrlDep && OutFlag) {
+ if (IsCopyFromReg)
+ OS << " return (N.ResNo == 0) ? Result : "
+ << "((N.ResNo == 2) ? Chain : InFlag);"
+ << " // Chain comes before flag.\n";
+ else
+ OS << " return (N.ResNo) ? Chain : InFlag;"
+ << " // Chain comes before flag.\n";
+ } else {
+ OS << " return Result.getValue(N.ResNo);\n";
+ }
+ } else {
+ // If this instruction is the root, and if there is only one use of it,
+ // use SelectNodeTo instead of getTargetNode to avoid an allocation.
+ OS << " if (N.Val->hasOneUse()) {\n";
+ OS << " return CurDAG->SelectNodeTo(N.Val, "
+ << II.Namespace << "::" << II.TheDef->getName();
+ if (N->getType() != MVT::isVoid)
+ OS << ", MVT::" << getEnumName(N->getType());
+ if (OutFlag)
+ OS << ", MVT::Flag";
+ for (unsigned i = 0, e = Ops.size(); i != e; ++i)
+ OS << ", Tmp" << Ops[i];
+ if (InFlag)
+ OS << ", InFlag";
+ OS << ");\n";
+ OS << " } else {\n";
+ OS << " return CodeGenMap[N] = CurDAG->getTargetNode("
+ << II.Namespace << "::" << II.TheDef->getName();
+ if (N->getType() != MVT::isVoid)
+ OS << ", MVT::" << getEnumName(N->getType());
+ if (OutFlag)
+ OS << ", MVT::Flag";
+ for (unsigned i = 0, e = Ops.size(); i != e; ++i)
+ OS << ", Tmp" << Ops[i];
+ if (InFlag)
+ OS << ", InFlag";
+ OS << ");\n";
+ OS << " }\n";
+ }
+
+ return std::make_pair(1, ResNo);
+ } else if (Op->isSubClassOf("SDNodeXForm")) {
+ assert(N->getNumChildren() == 1 && "node xform should have one child!");
+ unsigned OpVal = EmitResultCode(N->getChild(0)).second;
+ unsigned ResNo = TmpNo++;
+ OS << " SDOperand Tmp" << ResNo << " = Transform_" << Op->getName()
+ << "(Tmp" << OpVal << ".Val);\n";
+ if (isRoot) {
+ OS << " CodeGenMap[N] = Tmp" << ResNo << ";\n";
+ OS << " return Tmp" << ResNo << ";\n";
+ }
+ return std::make_pair(1, ResNo);