+
+ const RecPair &ArgTypes = I->first;
+ const std::vector<Record*> &RetTys = ArgTypes.first;
+ const std::vector<Record*> &ParamTys = ArgTypes.second;
+ std::vector<unsigned> OverloadedTypeIndices;
+
+ OS << " VerifyIntrinsicPrototype(ID, IF, " << RetTys.size() << ", "
+ << ParamTys.size();
+
+ // Emit return types.
+ for (unsigned j = 0, je = RetTys.size(); j != je; ++j) {
+ Record *ArgType = RetTys[j];
+ OS << ", ";
+
+ if (ArgType->isSubClassOf("LLVMMatchType")) {
+ unsigned Number = ArgType->getValueAsInt("Number");
+ assert(Number < OverloadedTypeIndices.size() &&
+ "Invalid matching number!");
+ Number = OverloadedTypeIndices[Number];
+ if (ArgType->isSubClassOf("LLVMExtendedElementVectorType"))
+ OS << "~(ExtendedElementVectorType | " << Number << ")";
+ else if (ArgType->isSubClassOf("LLVMTruncatedElementVectorType"))
+ OS << "~(TruncatedElementVectorType | " << Number << ")";
+ else
+ OS << "~" << Number;
+ } else {
+ MVT::SimpleValueType VT = getValueType(ArgType->getValueAsDef("VT"));
+ OS << getEnumName(VT);
+
+ if (EVT(VT).isOverloaded())
+ OverloadedTypeIndices.push_back(j);
+
+ if (VT == MVT::isVoid && j != 0 && j != je - 1)
+ throw "Var arg type not last argument";
+ }
+ }
+
+ // Emit the parameter types.
+ for (unsigned j = 0, je = ParamTys.size(); j != je; ++j) {
+ Record *ArgType = ParamTys[j];
+ OS << ", ";
+
+ if (ArgType->isSubClassOf("LLVMMatchType")) {
+ unsigned Number = ArgType->getValueAsInt("Number");
+ assert(Number < OverloadedTypeIndices.size() &&
+ "Invalid matching number!");
+ Number = OverloadedTypeIndices[Number];
+ if (ArgType->isSubClassOf("LLVMExtendedElementVectorType"))
+ OS << "~(ExtendedElementVectorType | " << Number << ")";
+ else if (ArgType->isSubClassOf("LLVMTruncatedElementVectorType"))
+ OS << "~(TruncatedElementVectorType | " << Number << ")";
+ else
+ OS << "~" << Number;
+ } else {
+ MVT::SimpleValueType VT = getValueType(ArgType->getValueAsDef("VT"));
+ OS << getEnumName(VT);
+
+ if (EVT(VT).isOverloaded())
+ OverloadedTypeIndices.push_back(j + RetTys.size());
+
+ if (VT == MVT::isVoid && j != 0 && j != je - 1)
+ throw "Var arg type not last argument";
+ }
+ }
+
+ OS << ");\n";
+ OS << " break;\n";
+ }
+ OS << " }\n";
+ OS << "#endif\n\n";
+}
+
+void IntrinsicEmitter::EmitGenerator(const std::vector<CodeGenIntrinsic> &Ints,
+ raw_ostream &OS) {
+ OS << "// Code for generating Intrinsic function declarations.\n";
+ OS << "#ifdef GET_INTRINSIC_GENERATOR\n";
+ OS << " switch (id) {\n";
+ OS << " default: assert(0 && \"Invalid intrinsic!\");\n";
+
+ // Similar to GET_INTRINSIC_VERIFIER, batch up cases that have identical
+ // types.
+ typedef std::map<RecPair, std::vector<unsigned>, RecordListComparator> MapTy;
+ MapTy UniqueArgInfos;
+
+ // Compute the unique argument type info.
+ for (unsigned i = 0, e = Ints.size(); i != e; ++i)
+ UniqueArgInfos[make_pair(Ints[i].IS.RetTypeDefs,
+ Ints[i].IS.ParamTypeDefs)].push_back(i);
+
+ // Loop through the array, emitting one generator for each batch.
+ std::string IntrinsicStr = TargetPrefix + "Intrinsic::";
+
+ for (MapTy::iterator I = UniqueArgInfos.begin(),
+ E = UniqueArgInfos.end(); I != E; ++I) {
+ for (unsigned i = 0, e = I->second.size(); i != e; ++i)
+ OS << " case " << IntrinsicStr << Ints[I->second[i]].EnumName
+ << ":\t\t// " << Ints[I->second[i]].Name << "\n";
+
+ const RecPair &ArgTypes = I->first;
+ const std::vector<Record*> &RetTys = ArgTypes.first;
+ const std::vector<Record*> &ParamTys = ArgTypes.second;
+
+ unsigned N = ParamTys.size();
+
+ if (N > 1 &&
+ getValueType(ParamTys[N - 1]->getValueAsDef("VT")) == MVT::isVoid) {
+ OS << " IsVarArg = true;\n";
+ --N;