+void IntrinsicEmitter::
+EmitIntrinsicToNameTable(const std::vector<CodeGenIntrinsic> &Ints,
+ std::ostream &OS) {
+ OS << "// Intrinsic ID to name table\n";
+ OS << "#ifdef GET_INTRINSIC_NAME_TABLE\n";
+ OS << " // Note that entry #0 is the invalid intrinsic!\n";
+ for (unsigned i = 0, e = Ints.size(); i != e; ++i)
+ OS << " \"" << Ints[i].Name << "\",\n";
+ OS << "#endif\n\n";
+}
+
+static void EmitTypeForValueType(std::ostream &OS, MVT::SimpleValueType VT) {
+ if (MVT(VT).isInteger()) {
+ unsigned BitWidth = MVT(VT).getSizeInBits();
+ OS << "IntegerType::get(" << BitWidth << ")";
+ } else if (VT == MVT::Other) {
+ // MVT::OtherVT is used to mean the empty struct type here.
+ OS << "StructType::get(std::vector<const Type *>())";
+ } else if (VT == MVT::f32) {
+ OS << "Type::FloatTy";
+ } else if (VT == MVT::f64) {
+ OS << "Type::DoubleTy";
+ } else if (VT == MVT::f80) {
+ OS << "Type::X86_FP80Ty";
+ } else if (VT == MVT::f128) {
+ OS << "Type::FP128Ty";
+ } else if (VT == MVT::ppcf128) {
+ OS << "Type::PPC_FP128Ty";
+ } else if (VT == MVT::isVoid) {
+ OS << "Type::VoidTy";
+ } else {
+ assert(false && "Unsupported ValueType!");
+ }
+}
+
+static void EmitTypeGenerate(std::ostream &OS, const Record *ArgType,
+ unsigned &ArgNo);
+
+static void EmitTypeGenerate(std::ostream &OS,
+ const std::vector<Record*> &ArgTypes,
+ unsigned &ArgNo) {
+ if (ArgTypes.size() == 1) {
+ EmitTypeGenerate(OS, ArgTypes.front(), ArgNo);
+ return;
+ }
+
+ OS << "StructType::get(";
+
+ for (std::vector<Record*>::const_iterator
+ I = ArgTypes.begin(), E = ArgTypes.end(); I != E; ++I) {
+ EmitTypeGenerate(OS, *I, ArgNo);
+ OS << ", ";
+ }
+
+ OS << " NULL)";
+}
+
+static void EmitTypeGenerate(std::ostream &OS, const Record *ArgType,
+ unsigned &ArgNo) {
+ MVT::SimpleValueType VT = getValueType(ArgType->getValueAsDef("VT"));
+
+ if (ArgType->isSubClassOf("LLVMMatchType")) {
+ unsigned Number = ArgType->getValueAsInt("Number");
+ assert(Number < ArgNo && "Invalid matching number!");
+ OS << "Tys[" << Number << "]";
+ } else if (VT == MVT::iAny || VT == MVT::fAny) {
+ // NOTE: The ArgNo variable here is not the absolute argument number, it is
+ // the index of the "arbitrary" type in the Tys array passed to the
+ // Intrinsic::getDeclaration function. Consequently, we only want to
+ // increment it when we actually hit an overloaded type. Getting this wrong
+ // leads to very subtle bugs!
+ OS << "Tys[" << ArgNo++ << "]";
+ } else if (MVT(VT).isVector()) {
+ MVT VVT = VT;
+ OS << "VectorType::get(";
+ EmitTypeForValueType(OS, VVT.getVectorElementType().getSimpleVT());
+ OS << ", " << VVT.getVectorNumElements() << ")";
+ } else if (VT == MVT::iPTR) {
+ OS << "PointerType::getUnqual(";
+ EmitTypeGenerate(OS, ArgType->getValueAsDef("ElTy"), ArgNo);
+ OS << ")";
+ } else if (VT == MVT::iPTRAny) {
+ // Make sure the user has passed us an argument type to overload. If not,
+ // treat it as an ordinary (not overloaded) intrinsic.
+ OS << "(" << ArgNo << " < numTys) ? Tys[" << ArgNo
+ << "] : PointerType::getUnqual(";
+ EmitTypeGenerate(OS, ArgType->getValueAsDef("ElTy"), ArgNo);
+ OS << ")";
+ ++ArgNo;
+ } else if (VT == MVT::isVoid) {
+ if (ArgNo == 0)
+ OS << "Type::VoidTy";
+ else
+ // MVT::isVoid is used to mean varargs here.
+ OS << "...";
+ } else {
+ EmitTypeForValueType(OS, VT);
+ }
+}
+
+/// RecordListComparator - Provide a determinstic comparator for lists of
+/// records.
+namespace {
+ typedef std::pair<std::vector<Record*>, std::vector<Record*> > RecPair;
+ struct RecordListComparator {
+ bool operator()(const RecPair &LHS,
+ const RecPair &RHS) const {
+ unsigned i = 0;
+ const std::vector<Record*> *LHSVec = &LHS.first;
+ const std::vector<Record*> *RHSVec = &RHS.first;
+ unsigned RHSSize = RHSVec->size();
+ unsigned LHSSize = LHSVec->size();
+
+ do {
+ if (i == RHSSize) return false; // RHS is shorter than LHS.
+ if ((*LHSVec)[i] != (*RHSVec)[i])
+ return (*LHSVec)[i]->getName() < (*RHSVec)[i]->getName();
+ } while (++i != LHSSize);
+
+ if (i != RHSSize) return true;
+
+ i = 0;
+ LHSVec = &LHS.second;
+ RHSVec = &RHS.second;
+ RHSSize = RHSVec->size();
+ LHSSize = LHSVec->size();
+
+ for (i = 0; i != LHSSize; ++i) {
+ if (i == RHSSize) return false; // RHS is shorter than LHS.
+ if ((*LHSVec)[i] != (*RHSVec)[i])
+ return (*LHSVec)[i]->getName() < (*RHSVec)[i]->getName();
+ }
+
+ return i != RHSSize;
+ }
+ };
+}
+