SubtargetEmitter.cpp revision a11a6287a504d1d7503e744d14314df1e696f506
14bb9cbb73075c350eadaf51d2dab8403764c9a60Jim Laskey//===- SubtargetEmitter.cpp - Generate subtarget enumerations -------------===// 24bb9cbb73075c350eadaf51d2dab8403764c9a60Jim Laskey// 34bb9cbb73075c350eadaf51d2dab8403764c9a60Jim Laskey// The LLVM Compiler Infrastructure 44bb9cbb73075c350eadaf51d2dab8403764c9a60Jim Laskey// 53060910e290949a9ac5eda8726d030790c4d60ffChris Lattner// This file is distributed under the University of Illinois Open Source 63060910e290949a9ac5eda8726d030790c4d60ffChris Lattner// License. See LICENSE.TXT for details. 74bb9cbb73075c350eadaf51d2dab8403764c9a60Jim Laskey// 84bb9cbb73075c350eadaf51d2dab8403764c9a60Jim Laskey//===----------------------------------------------------------------------===// 94bb9cbb73075c350eadaf51d2dab8403764c9a60Jim Laskey// 103d87811ce0381c3364ce10aed77de8231a03bc48Chris Lattner// This tablegen backend emits subtarget enumerations. 114bb9cbb73075c350eadaf51d2dab8403764c9a60Jim Laskey// 124bb9cbb73075c350eadaf51d2dab8403764c9a60Jim Laskey//===----------------------------------------------------------------------===// 134bb9cbb73075c350eadaf51d2dab8403764c9a60Jim Laskey 144bb9cbb73075c350eadaf51d2dab8403764c9a60Jim Laskey#include "CodeGenTarget.h" 154bb9cbb73075c350eadaf51d2dab8403764c9a60Jim Laskey#include "llvm/ADT/StringExtras.h" 166f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen#include "llvm/MC/MCInstrItineraries.h" 174bb9cbb73075c350eadaf51d2dab8403764c9a60Jim Laskey#include "llvm/Support/Debug.h" 186f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen#include "llvm/TableGen/Record.h" 196f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen#include "llvm/TableGen/TableGenBackend.h" 209489c04efc47a68af65e226e50f03d488094ffceJeff Cohen#include <algorithm> 216f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen#include <map> 226f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen#include <string> 236f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen#include <vector> 244bb9cbb73075c350eadaf51d2dab8403764c9a60Jim Laskeyusing namespace llvm; 254bb9cbb73075c350eadaf51d2dab8403764c9a60Jim Laskey 266f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesennamespace { 276f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesenclass SubtargetEmitter { 286f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen 296f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen RecordKeeper &Records; 306f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen std::string Target; 316f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen bool HasItineraries; 326f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen 336f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen void Enumeration(raw_ostream &OS, const char *ClassName, bool isBits); 346f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen unsigned FeatureKeyValues(raw_ostream &OS); 356f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen unsigned CPUKeyValues(raw_ostream &OS); 366f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen unsigned CollectAllItinClasses(raw_ostream &OS, 376f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen std::map<std::string,unsigned> &ItinClassesMap, 386f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen std::vector<Record*> &ItinClassList); 396f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen void FormItineraryStageString(const std::string &Names, 406f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen Record *ItinData, std::string &ItinString, 416f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen unsigned &NStages); 426f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen void FormItineraryOperandCycleString(Record *ItinData, std::string &ItinString, 436f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen unsigned &NOperandCycles); 446f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen void FormItineraryBypassString(const std::string &Names, 456f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen Record *ItinData, 466f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen std::string &ItinString, unsigned NOperandCycles); 476f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen void EmitStageAndOperandCycleData(raw_ostream &OS, unsigned NItinClasses, 486f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen std::map<std::string, unsigned> &ItinClassesMap, 496f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen std::vector<Record*> &ItinClassList, 506f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen std::vector<std::vector<InstrItinerary> > &ProcList); 516f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen void EmitItineraryProp(raw_ostream &OS, const Record *R, const char *Name, 526f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen char Separator); 536f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen void EmitProcessorData(raw_ostream &OS, 546f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen std::vector<Record*> &ItinClassList, 556f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen std::vector<std::vector<InstrItinerary> > &ProcList); 566f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen void EmitProcessorLookup(raw_ostream &OS); 576f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen void EmitData(raw_ostream &OS); 586f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen void ParseFeaturesFunction(raw_ostream &OS, unsigned NumFeatures, 596f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen unsigned NumProcs); 606f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen 616f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesenpublic: 626f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen SubtargetEmitter(RecordKeeper &R) : Records(R), HasItineraries(false) {} 636f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen 646f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen void run(raw_ostream &o); 656f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen 666f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen}; 676f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen} // End anonymous namespace 686f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen 697dc02047fbb4b014e914458f54ea539c8ae58316Jim Laskey// 70581a8f79bc1ac3cbe5d621f0b4a0252ab2890bc1Jim Laskey// Enumeration - Emit the specified class as an enumeration. 71b3b1d5f097a4fbcf134259b743ccbd93d187c6cdJim Laskey// 721a55180238dbcf11113f610aea010447e51f595bDaniel Dunbarvoid SubtargetEmitter::Enumeration(raw_ostream &OS, 73581a8f79bc1ac3cbe5d621f0b4a0252ab2890bc1Jim Laskey const char *ClassName, 74581a8f79bc1ac3cbe5d621f0b4a0252ab2890bc1Jim Laskey bool isBits) { 75908ae27a9073e2f105f8a0a4dd092d7fea8472a4Jim Laskey // Get all records of class and sort 76f7bcde085440d1fd90eba8980ed9c512bc58824dJim Laskey std::vector<Record*> DefList = Records.getAllDerivedDefinitions(ClassName); 7742d24c71df88178eacf244a38b6c48847ee0d39bDuraid Madina std::sort(DefList.begin(), DefList.end(), LessRecord()); 784bb9cbb73075c350eadaf51d2dab8403764c9a60Jim Laskey 79b6a638898a92d5cd782209fbeb673fe7846a29ebEvan Cheng unsigned N = DefList.size(); 8094214703d97d8d9dfca88174ffc7e94820a85e62Evan Cheng if (N == 0) 8194214703d97d8d9dfca88174ffc7e94820a85e62Evan Cheng return; 82b6a638898a92d5cd782209fbeb673fe7846a29ebEvan Cheng if (N > 64) { 83b6a638898a92d5cd782209fbeb673fe7846a29ebEvan Cheng errs() << "Too many (> 64) subtarget features!\n"; 84b6a638898a92d5cd782209fbeb673fe7846a29ebEvan Cheng exit(1); 85b6a638898a92d5cd782209fbeb673fe7846a29ebEvan Cheng } 86b6a638898a92d5cd782209fbeb673fe7846a29ebEvan Cheng 8794214703d97d8d9dfca88174ffc7e94820a85e62Evan Cheng OS << "namespace " << Target << " {\n"; 8894214703d97d8d9dfca88174ffc7e94820a85e62Evan Cheng 89ac1ed44d95789400edc334fab6680b7bcf7d61a9Jakob Stoklund Olesen // For bit flag enumerations with more than 32 items, emit constants. 90ac1ed44d95789400edc334fab6680b7bcf7d61a9Jakob Stoklund Olesen // Emit an enum for everything else. 91ac1ed44d95789400edc334fab6680b7bcf7d61a9Jakob Stoklund Olesen if (isBits && N > 32) { 92ac1ed44d95789400edc334fab6680b7bcf7d61a9Jakob Stoklund Olesen // For each record 93ac1ed44d95789400edc334fab6680b7bcf7d61a9Jakob Stoklund Olesen for (unsigned i = 0; i < N; i++) { 94ac1ed44d95789400edc334fab6680b7bcf7d61a9Jakob Stoklund Olesen // Next record 95ac1ed44d95789400edc334fab6680b7bcf7d61a9Jakob Stoklund Olesen Record *Def = DefList[i]; 9694214703d97d8d9dfca88174ffc7e94820a85e62Evan Cheng 97ac1ed44d95789400edc334fab6680b7bcf7d61a9Jakob Stoklund Olesen // Get and emit name and expression (1 << i) 98ac1ed44d95789400edc334fab6680b7bcf7d61a9Jakob Stoklund Olesen OS << " const uint64_t " << Def->getName() << " = 1ULL << " << i << ";\n"; 99ac1ed44d95789400edc334fab6680b7bcf7d61a9Jakob Stoklund Olesen } 100ac1ed44d95789400edc334fab6680b7bcf7d61a9Jakob Stoklund Olesen } else { 101ac1ed44d95789400edc334fab6680b7bcf7d61a9Jakob Stoklund Olesen // Open enumeration 102ac1ed44d95789400edc334fab6680b7bcf7d61a9Jakob Stoklund Olesen OS << "enum {\n"; 103da96cf2029e47baf77df5c1ce6528a04246d6462Andrew Trick 104ac1ed44d95789400edc334fab6680b7bcf7d61a9Jakob Stoklund Olesen // For each record 105ac1ed44d95789400edc334fab6680b7bcf7d61a9Jakob Stoklund Olesen for (unsigned i = 0; i < N;) { 106ac1ed44d95789400edc334fab6680b7bcf7d61a9Jakob Stoklund Olesen // Next record 107ac1ed44d95789400edc334fab6680b7bcf7d61a9Jakob Stoklund Olesen Record *Def = DefList[i]; 108da96cf2029e47baf77df5c1ce6528a04246d6462Andrew Trick 109ac1ed44d95789400edc334fab6680b7bcf7d61a9Jakob Stoklund Olesen // Get and emit name 110ac1ed44d95789400edc334fab6680b7bcf7d61a9Jakob Stoklund Olesen OS << " " << Def->getName(); 111908ae27a9073e2f105f8a0a4dd092d7fea8472a4Jim Laskey 112ac1ed44d95789400edc334fab6680b7bcf7d61a9Jakob Stoklund Olesen // If bit flags then emit expression (1 << i) 113ac1ed44d95789400edc334fab6680b7bcf7d61a9Jakob Stoklund Olesen if (isBits) OS << " = " << " 1ULL << " << i; 114da96cf2029e47baf77df5c1ce6528a04246d6462Andrew Trick 115ac1ed44d95789400edc334fab6680b7bcf7d61a9Jakob Stoklund Olesen // Depending on 'if more in the list' emit comma 116ac1ed44d95789400edc334fab6680b7bcf7d61a9Jakob Stoklund Olesen if (++i < N) OS << ","; 117ac1ed44d95789400edc334fab6680b7bcf7d61a9Jakob Stoklund Olesen 118ac1ed44d95789400edc334fab6680b7bcf7d61a9Jakob Stoklund Olesen OS << "\n"; 119ac1ed44d95789400edc334fab6680b7bcf7d61a9Jakob Stoklund Olesen } 120da96cf2029e47baf77df5c1ce6528a04246d6462Andrew Trick 121ac1ed44d95789400edc334fab6680b7bcf7d61a9Jakob Stoklund Olesen // Close enumeration 122ac1ed44d95789400edc334fab6680b7bcf7d61a9Jakob Stoklund Olesen OS << "};\n"; 123ac1ed44d95789400edc334fab6680b7bcf7d61a9Jakob Stoklund Olesen } 12494214703d97d8d9dfca88174ffc7e94820a85e62Evan Cheng 12594214703d97d8d9dfca88174ffc7e94820a85e62Evan Cheng OS << "}\n"; 126b3b1d5f097a4fbcf134259b743ccbd93d187c6cdJim Laskey} 127b3b1d5f097a4fbcf134259b743ccbd93d187c6cdJim Laskey 128b3b1d5f097a4fbcf134259b743ccbd93d187c6cdJim Laskey// 1294222d806faae71ecc794cfdaa873817873c2f3d8Bill Wendling// FeatureKeyValues - Emit data of all the subtarget features. Used by the 1304222d806faae71ecc794cfdaa873817873c2f3d8Bill Wendling// command line. 131b3b1d5f097a4fbcf134259b743ccbd93d187c6cdJim Laskey// 13294214703d97d8d9dfca88174ffc7e94820a85e62Evan Chengunsigned SubtargetEmitter::FeatureKeyValues(raw_ostream &OS) { 133908ae27a9073e2f105f8a0a4dd092d7fea8472a4Jim Laskey // Gather and sort all the features 134f7bcde085440d1fd90eba8980ed9c512bc58824dJim Laskey std::vector<Record*> FeatureList = 135f7bcde085440d1fd90eba8980ed9c512bc58824dJim Laskey Records.getAllDerivedDefinitions("SubtargetFeature"); 13694214703d97d8d9dfca88174ffc7e94820a85e62Evan Cheng 13794214703d97d8d9dfca88174ffc7e94820a85e62Evan Cheng if (FeatureList.empty()) 13894214703d97d8d9dfca88174ffc7e94820a85e62Evan Cheng return 0; 13994214703d97d8d9dfca88174ffc7e94820a85e62Evan Cheng 1407c9a7728d9dd248ebee8f2dd969d303711d487a9Jim Grosbach std::sort(FeatureList.begin(), FeatureList.end(), LessRecordFieldName()); 141b3b1d5f097a4fbcf134259b743ccbd93d187c6cdJim Laskey 142908ae27a9073e2f105f8a0a4dd092d7fea8472a4Jim Laskey // Begin feature table 143581a8f79bc1ac3cbe5d621f0b4a0252ab2890bc1Jim Laskey OS << "// Sorted (by key) array of values for CPU features.\n" 1441a2f9886a2a60dbd41216468a240446bbfed3e76Benjamin Kramer << "extern const llvm::SubtargetFeatureKV " << Target 1451a2f9886a2a60dbd41216468a240446bbfed3e76Benjamin Kramer << "FeatureKV[] = {\n"; 146da96cf2029e47baf77df5c1ce6528a04246d6462Andrew Trick 147908ae27a9073e2f105f8a0a4dd092d7fea8472a4Jim Laskey // For each feature 14894214703d97d8d9dfca88174ffc7e94820a85e62Evan Cheng unsigned NumFeatures = 0; 149dbe4006cf3cf0802dc318a5f2070c04c326e170bJim Laskey for (unsigned i = 0, N = FeatureList.size(); i < N; ++i) { 150f7bcde085440d1fd90eba8980ed9c512bc58824dJim Laskey // Next feature 151f7bcde085440d1fd90eba8980ed9c512bc58824dJim Laskey Record *Feature = FeatureList[i]; 152f7bcde085440d1fd90eba8980ed9c512bc58824dJim Laskey 1534222d806faae71ecc794cfdaa873817873c2f3d8Bill Wendling const std::string &Name = Feature->getName(); 1544222d806faae71ecc794cfdaa873817873c2f3d8Bill Wendling const std::string &CommandLineName = Feature->getValueAsString("Name"); 1554222d806faae71ecc794cfdaa873817873c2f3d8Bill Wendling const std::string &Desc = Feature->getValueAsString("Desc"); 156da96cf2029e47baf77df5c1ce6528a04246d6462Andrew Trick 157dbe4006cf3cf0802dc318a5f2070c04c326e170bJim Laskey if (CommandLineName.empty()) continue; 158da96cf2029e47baf77df5c1ce6528a04246d6462Andrew Trick 159da4231f134989af7dc6bd3408821ba573def27b2Jim Grosbach // Emit as { "feature", "description", featureEnum, i1 | i2 | ... | in } 160b3b1d5f097a4fbcf134259b743ccbd93d187c6cdJim Laskey OS << " { " 161f7bcde085440d1fd90eba8980ed9c512bc58824dJim Laskey << "\"" << CommandLineName << "\", " 162b3b1d5f097a4fbcf134259b743ccbd93d187c6cdJim Laskey << "\"" << Desc << "\", " 16394214703d97d8d9dfca88174ffc7e94820a85e62Evan Cheng << Target << "::" << Name << ", "; 1644222d806faae71ecc794cfdaa873817873c2f3d8Bill Wendling 165da96cf2029e47baf77df5c1ce6528a04246d6462Andrew Trick const std::vector<Record*> &ImpliesList = 1664222d806faae71ecc794cfdaa873817873c2f3d8Bill Wendling Feature->getValueAsListOfDefs("Implies"); 167da96cf2029e47baf77df5c1ce6528a04246d6462Andrew Trick 1684222d806faae71ecc794cfdaa873817873c2f3d8Bill Wendling if (ImpliesList.empty()) { 169b6a638898a92d5cd782209fbeb673fe7846a29ebEvan Cheng OS << "0ULL"; 1704222d806faae71ecc794cfdaa873817873c2f3d8Bill Wendling } else { 1714222d806faae71ecc794cfdaa873817873c2f3d8Bill Wendling for (unsigned j = 0, M = ImpliesList.size(); j < M;) { 17294214703d97d8d9dfca88174ffc7e94820a85e62Evan Cheng OS << Target << "::" << ImpliesList[j]->getName(); 1734222d806faae71ecc794cfdaa873817873c2f3d8Bill Wendling if (++j < M) OS << " | "; 1744222d806faae71ecc794cfdaa873817873c2f3d8Bill Wendling } 1754222d806faae71ecc794cfdaa873817873c2f3d8Bill Wendling } 1764222d806faae71ecc794cfdaa873817873c2f3d8Bill Wendling 1774222d806faae71ecc794cfdaa873817873c2f3d8Bill Wendling OS << " }"; 17894214703d97d8d9dfca88174ffc7e94820a85e62Evan Cheng ++NumFeatures; 179da96cf2029e47baf77df5c1ce6528a04246d6462Andrew Trick 18010b1dd99f342d2d7af51dd43f3840f3bf40b0b87Jim Laskey // Depending on 'if more in the list' emit comma 181dbe4006cf3cf0802dc318a5f2070c04c326e170bJim Laskey if ((i + 1) < N) OS << ","; 182da96cf2029e47baf77df5c1ce6528a04246d6462Andrew Trick 183f7bcde085440d1fd90eba8980ed9c512bc58824dJim Laskey OS << "\n"; 184b3b1d5f097a4fbcf134259b743ccbd93d187c6cdJim Laskey } 185da96cf2029e47baf77df5c1ce6528a04246d6462Andrew Trick 186908ae27a9073e2f105f8a0a4dd092d7fea8472a4Jim Laskey // End feature table 187b3b1d5f097a4fbcf134259b743ccbd93d187c6cdJim Laskey OS << "};\n"; 188b3b1d5f097a4fbcf134259b743ccbd93d187c6cdJim Laskey 18994214703d97d8d9dfca88174ffc7e94820a85e62Evan Cheng return NumFeatures; 190b3b1d5f097a4fbcf134259b743ccbd93d187c6cdJim Laskey} 191b3b1d5f097a4fbcf134259b743ccbd93d187c6cdJim Laskey 192b3b1d5f097a4fbcf134259b743ccbd93d187c6cdJim Laskey// 193b3b1d5f097a4fbcf134259b743ccbd93d187c6cdJim Laskey// CPUKeyValues - Emit data of all the subtarget processors. Used by command 194b3b1d5f097a4fbcf134259b743ccbd93d187c6cdJim Laskey// line. 195b3b1d5f097a4fbcf134259b743ccbd93d187c6cdJim Laskey// 19694214703d97d8d9dfca88174ffc7e94820a85e62Evan Chengunsigned SubtargetEmitter::CPUKeyValues(raw_ostream &OS) { 197908ae27a9073e2f105f8a0a4dd092d7fea8472a4Jim Laskey // Gather and sort processor information 198f7bcde085440d1fd90eba8980ed9c512bc58824dJim Laskey std::vector<Record*> ProcessorList = 199f7bcde085440d1fd90eba8980ed9c512bc58824dJim Laskey Records.getAllDerivedDefinitions("Processor"); 20042d24c71df88178eacf244a38b6c48847ee0d39bDuraid Madina std::sort(ProcessorList.begin(), ProcessorList.end(), LessRecordFieldName()); 201b3b1d5f097a4fbcf134259b743ccbd93d187c6cdJim Laskey 202908ae27a9073e2f105f8a0a4dd092d7fea8472a4Jim Laskey // Begin processor table 203581a8f79bc1ac3cbe5d621f0b4a0252ab2890bc1Jim Laskey OS << "// Sorted (by key) array of values for CPU subtype.\n" 2041a2f9886a2a60dbd41216468a240446bbfed3e76Benjamin Kramer << "extern const llvm::SubtargetFeatureKV " << Target 2051a2f9886a2a60dbd41216468a240446bbfed3e76Benjamin Kramer << "SubTypeKV[] = {\n"; 206da96cf2029e47baf77df5c1ce6528a04246d6462Andrew Trick 207908ae27a9073e2f105f8a0a4dd092d7fea8472a4Jim Laskey // For each processor 208f7bcde085440d1fd90eba8980ed9c512bc58824dJim Laskey for (unsigned i = 0, N = ProcessorList.size(); i < N;) { 209f7bcde085440d1fd90eba8980ed9c512bc58824dJim Laskey // Next processor 210f7bcde085440d1fd90eba8980ed9c512bc58824dJim Laskey Record *Processor = ProcessorList[i]; 211f7bcde085440d1fd90eba8980ed9c512bc58824dJim Laskey 2124222d806faae71ecc794cfdaa873817873c2f3d8Bill Wendling const std::string &Name = Processor->getValueAsString("Name"); 213da96cf2029e47baf77df5c1ce6528a04246d6462Andrew Trick const std::vector<Record*> &FeatureList = 214b0e103d46bf8799ac5523157a6ed4a78d1751a89Chris Lattner Processor->getValueAsListOfDefs("Features"); 215da96cf2029e47baf77df5c1ce6528a04246d6462Andrew Trick 216908ae27a9073e2f105f8a0a4dd092d7fea8472a4Jim Laskey // Emit as { "cpu", "description", f1 | f2 | ... fn }, 217b3b1d5f097a4fbcf134259b743ccbd93d187c6cdJim Laskey OS << " { " 218b3b1d5f097a4fbcf134259b743ccbd93d187c6cdJim Laskey << "\"" << Name << "\", " 219b3b1d5f097a4fbcf134259b743ccbd93d187c6cdJim Laskey << "\"Select the " << Name << " processor\", "; 220da96cf2029e47baf77df5c1ce6528a04246d6462Andrew Trick 221f7bcde085440d1fd90eba8980ed9c512bc58824dJim Laskey if (FeatureList.empty()) { 222b6a638898a92d5cd782209fbeb673fe7846a29ebEvan Cheng OS << "0ULL"; 223b3b1d5f097a4fbcf134259b743ccbd93d187c6cdJim Laskey } else { 224f7bcde085440d1fd90eba8980ed9c512bc58824dJim Laskey for (unsigned j = 0, M = FeatureList.size(); j < M;) { 22594214703d97d8d9dfca88174ffc7e94820a85e62Evan Cheng OS << Target << "::" << FeatureList[j]->getName(); 226f7bcde085440d1fd90eba8980ed9c512bc58824dJim Laskey if (++j < M) OS << " | "; 2274bb9cbb73075c350eadaf51d2dab8403764c9a60Jim Laskey } 2284bb9cbb73075c350eadaf51d2dab8403764c9a60Jim Laskey } 229da96cf2029e47baf77df5c1ce6528a04246d6462Andrew Trick 2304222d806faae71ecc794cfdaa873817873c2f3d8Bill Wendling // The "0" is for the "implies" section of this data structure. 231b6a638898a92d5cd782209fbeb673fe7846a29ebEvan Cheng OS << ", 0ULL }"; 232da96cf2029e47baf77df5c1ce6528a04246d6462Andrew Trick 23310b1dd99f342d2d7af51dd43f3840f3bf40b0b87Jim Laskey // Depending on 'if more in the list' emit comma 234f7bcde085440d1fd90eba8980ed9c512bc58824dJim Laskey if (++i < N) OS << ","; 235da96cf2029e47baf77df5c1ce6528a04246d6462Andrew Trick 236f7bcde085440d1fd90eba8980ed9c512bc58824dJim Laskey OS << "\n"; 2374bb9cbb73075c350eadaf51d2dab8403764c9a60Jim Laskey } 238da96cf2029e47baf77df5c1ce6528a04246d6462Andrew Trick 239908ae27a9073e2f105f8a0a4dd092d7fea8472a4Jim Laskey // End processor table 240b3b1d5f097a4fbcf134259b743ccbd93d187c6cdJim Laskey OS << "};\n"; 241b3b1d5f097a4fbcf134259b743ccbd93d187c6cdJim Laskey 24294214703d97d8d9dfca88174ffc7e94820a85e62Evan Cheng return ProcessorList.size(); 2434bb9cbb73075c350eadaf51d2dab8403764c9a60Jim Laskey} 244b3b1d5f097a4fbcf134259b743ccbd93d187c6cdJim Laskey 245581a8f79bc1ac3cbe5d621f0b4a0252ab2890bc1Jim Laskey// 2460d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey// CollectAllItinClasses - Gathers and enumerates all the itinerary classes. 247908ae27a9073e2f105f8a0a4dd092d7fea8472a4Jim Laskey// Returns itinerary class count. 2480d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey// 2495f54ce347368105260be2cec497b6a4199dc5789Evan Chengunsigned SubtargetEmitter:: 2505f54ce347368105260be2cec497b6a4199dc5789Evan ChengCollectAllItinClasses(raw_ostream &OS, 2515f54ce347368105260be2cec497b6a4199dc5789Evan Cheng std::map<std::string, unsigned> &ItinClassesMap, 2525f54ce347368105260be2cec497b6a4199dc5789Evan Cheng std::vector<Record*> &ItinClassList) { 253f7bcde085440d1fd90eba8980ed9c512bc58824dJim Laskey // For each itinerary class 254f7bcde085440d1fd90eba8980ed9c512bc58824dJim Laskey unsigned N = ItinClassList.size(); 255f7bcde085440d1fd90eba8980ed9c512bc58824dJim Laskey for (unsigned i = 0; i < N; i++) { 256f7bcde085440d1fd90eba8980ed9c512bc58824dJim Laskey // Next itinerary class 2574222d806faae71ecc794cfdaa873817873c2f3d8Bill Wendling const Record *ItinClass = ItinClassList[i]; 258908ae27a9073e2f105f8a0a4dd092d7fea8472a4Jim Laskey // Get name of itinerary class 259908ae27a9073e2f105f8a0a4dd092d7fea8472a4Jim Laskey // Assign itinerary class a unique number 2604222d806faae71ecc794cfdaa873817873c2f3d8Bill Wendling ItinClassesMap[ItinClass->getName()] = i; 2610d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey } 262da96cf2029e47baf77df5c1ce6528a04246d6462Andrew Trick 263908ae27a9073e2f105f8a0a4dd092d7fea8472a4Jim Laskey // Return itinerary class count 264f7bcde085440d1fd90eba8980ed9c512bc58824dJim Laskey return N; 2650d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey} 2660d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey 2670d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey// 268fac8541dd40e01aa2b52962516f9ae67c99720ccDavid Goodwin// FormItineraryStageString - Compose a string containing the stage 269fac8541dd40e01aa2b52962516f9ae67c99720ccDavid Goodwin// data initialization for the specified itinerary. N is the number 270fac8541dd40e01aa2b52962516f9ae67c99720ccDavid Goodwin// of stages. 2710d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey// 272928eb49cae286c95dceecf4442997dd561c6e3b7Anton Korobeynikovvoid SubtargetEmitter::FormItineraryStageString(const std::string &Name, 273928eb49cae286c95dceecf4442997dd561c6e3b7Anton Korobeynikov Record *ItinData, 274fac8541dd40e01aa2b52962516f9ae67c99720ccDavid Goodwin std::string &ItinString, 275fac8541dd40e01aa2b52962516f9ae67c99720ccDavid Goodwin unsigned &NStages) { 276f7bcde085440d1fd90eba8980ed9c512bc58824dJim Laskey // Get states list 2774222d806faae71ecc794cfdaa873817873c2f3d8Bill Wendling const std::vector<Record*> &StageList = 2784222d806faae71ecc794cfdaa873817873c2f3d8Bill Wendling ItinData->getValueAsListOfDefs("Stages"); 279908ae27a9073e2f105f8a0a4dd092d7fea8472a4Jim Laskey 280908ae27a9073e2f105f8a0a4dd092d7fea8472a4Jim Laskey // For each stage 281f7bcde085440d1fd90eba8980ed9c512bc58824dJim Laskey unsigned N = NStages = StageList.size(); 2828dadf6b13a7cdd5b5b30c3b7af310c9756e4c68eChristopher Lamb for (unsigned i = 0; i < N;) { 283f7bcde085440d1fd90eba8980ed9c512bc58824dJim Laskey // Next stage 2844222d806faae71ecc794cfdaa873817873c2f3d8Bill Wendling const Record *Stage = StageList[i]; 285da96cf2029e47baf77df5c1ce6528a04246d6462Andrew Trick 28696085a36dbb9cf251c81bc150e41ea9c952c99c0Anton Korobeynikov // Form string as ,{ cycles, u1 | u2 | ... | un, timeinc, kind } 2870d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey int Cycles = Stage->getValueAsInt("Cycles"); 2887f39c14f52262a154285df9180f5edcdabe2d7dfJim Laskey ItinString += " { " + itostr(Cycles) + ", "; 289da96cf2029e47baf77df5c1ce6528a04246d6462Andrew Trick 290f7bcde085440d1fd90eba8980ed9c512bc58824dJim Laskey // Get unit list 2914222d806faae71ecc794cfdaa873817873c2f3d8Bill Wendling const std::vector<Record*> &UnitList = Stage->getValueAsListOfDefs("Units"); 292da96cf2029e47baf77df5c1ce6528a04246d6462Andrew Trick 293908ae27a9073e2f105f8a0a4dd092d7fea8472a4Jim Laskey // For each unit 294f7bcde085440d1fd90eba8980ed9c512bc58824dJim Laskey for (unsigned j = 0, M = UnitList.size(); j < M;) { 295f7bcde085440d1fd90eba8980ed9c512bc58824dJim Laskey // Add name and bitwise or 296928eb49cae286c95dceecf4442997dd561c6e3b7Anton Korobeynikov ItinString += Name + "FU::" + UnitList[j]->getName(); 297f7bcde085440d1fd90eba8980ed9c512bc58824dJim Laskey if (++j < M) ItinString += " | "; 2980d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey } 299da96cf2029e47baf77df5c1ce6528a04246d6462Andrew Trick 3001a8f36e3ce5b9c230781b66600c81536128abfb5David Goodwin int TimeInc = Stage->getValueAsInt("TimeInc"); 3011a8f36e3ce5b9c230781b66600c81536128abfb5David Goodwin ItinString += ", " + itostr(TimeInc); 3021a8f36e3ce5b9c230781b66600c81536128abfb5David Goodwin 30396085a36dbb9cf251c81bc150e41ea9c952c99c0Anton Korobeynikov int Kind = Stage->getValueAsInt("Kind"); 30496085a36dbb9cf251c81bc150e41ea9c952c99c0Anton Korobeynikov ItinString += ", (llvm::InstrStage::ReservationKinds)" + itostr(Kind); 30596085a36dbb9cf251c81bc150e41ea9c952c99c0Anton Korobeynikov 306908ae27a9073e2f105f8a0a4dd092d7fea8472a4Jim Laskey // Close off stage 307908ae27a9073e2f105f8a0a4dd092d7fea8472a4Jim Laskey ItinString += " }"; 3088dadf6b13a7cdd5b5b30c3b7af310c9756e4c68eChristopher Lamb if (++i < N) ItinString += ", "; 3090d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey } 3100d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey} 3110d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey 3120d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey// 313fac8541dd40e01aa2b52962516f9ae67c99720ccDavid Goodwin// FormItineraryOperandCycleString - Compose a string containing the 314fac8541dd40e01aa2b52962516f9ae67c99720ccDavid Goodwin// operand cycle initialization for the specified itinerary. N is the 315fac8541dd40e01aa2b52962516f9ae67c99720ccDavid Goodwin// number of operands that has cycles specified. 3160d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey// 317fac8541dd40e01aa2b52962516f9ae67c99720ccDavid Goodwinvoid SubtargetEmitter::FormItineraryOperandCycleString(Record *ItinData, 318fac8541dd40e01aa2b52962516f9ae67c99720ccDavid Goodwin std::string &ItinString, unsigned &NOperandCycles) { 319fac8541dd40e01aa2b52962516f9ae67c99720ccDavid Goodwin // Get operand cycle list 320fac8541dd40e01aa2b52962516f9ae67c99720ccDavid Goodwin const std::vector<int64_t> &OperandCycleList = 321fac8541dd40e01aa2b52962516f9ae67c99720ccDavid Goodwin ItinData->getValueAsListOfInts("OperandCycles"); 322fac8541dd40e01aa2b52962516f9ae67c99720ccDavid Goodwin 323fac8541dd40e01aa2b52962516f9ae67c99720ccDavid Goodwin // For each operand cycle 324fac8541dd40e01aa2b52962516f9ae67c99720ccDavid Goodwin unsigned N = NOperandCycles = OperandCycleList.size(); 325fac8541dd40e01aa2b52962516f9ae67c99720ccDavid Goodwin for (unsigned i = 0; i < N;) { 326fac8541dd40e01aa2b52962516f9ae67c99720ccDavid Goodwin // Next operand cycle 327fac8541dd40e01aa2b52962516f9ae67c99720ccDavid Goodwin const int OCycle = OperandCycleList[i]; 328da96cf2029e47baf77df5c1ce6528a04246d6462Andrew Trick 329fac8541dd40e01aa2b52962516f9ae67c99720ccDavid Goodwin ItinString += " " + itostr(OCycle); 330fac8541dd40e01aa2b52962516f9ae67c99720ccDavid Goodwin if (++i < N) ItinString += ", "; 331fac8541dd40e01aa2b52962516f9ae67c99720ccDavid Goodwin } 332fac8541dd40e01aa2b52962516f9ae67c99720ccDavid Goodwin} 333fac8541dd40e01aa2b52962516f9ae67c99720ccDavid Goodwin 33463d66eed16a6ee4e838f2f7a4c8299def0722c20Evan Chengvoid SubtargetEmitter::FormItineraryBypassString(const std::string &Name, 33563d66eed16a6ee4e838f2f7a4c8299def0722c20Evan Cheng Record *ItinData, 33663d66eed16a6ee4e838f2f7a4c8299def0722c20Evan Cheng std::string &ItinString, 33763d66eed16a6ee4e838f2f7a4c8299def0722c20Evan Cheng unsigned NOperandCycles) { 33863d66eed16a6ee4e838f2f7a4c8299def0722c20Evan Cheng const std::vector<Record*> &BypassList = 33963d66eed16a6ee4e838f2f7a4c8299def0722c20Evan Cheng ItinData->getValueAsListOfDefs("Bypasses"); 34063d66eed16a6ee4e838f2f7a4c8299def0722c20Evan Cheng unsigned N = BypassList.size(); 3413881cb7a5d54c0011b40997adcd742e1c7b91abdEvan Cheng unsigned i = 0; 3423881cb7a5d54c0011b40997adcd742e1c7b91abdEvan Cheng for (; i < N;) { 34363d66eed16a6ee4e838f2f7a4c8299def0722c20Evan Cheng ItinString += Name + "Bypass::" + BypassList[i]->getName(); 3443881cb7a5d54c0011b40997adcd742e1c7b91abdEvan Cheng if (++i < NOperandCycles) ItinString += ", "; 34563d66eed16a6ee4e838f2f7a4c8299def0722c20Evan Cheng } 3463881cb7a5d54c0011b40997adcd742e1c7b91abdEvan Cheng for (; i < NOperandCycles;) { 34763d66eed16a6ee4e838f2f7a4c8299def0722c20Evan Cheng ItinString += " 0"; 3483881cb7a5d54c0011b40997adcd742e1c7b91abdEvan Cheng if (++i < NOperandCycles) ItinString += ", "; 34963d66eed16a6ee4e838f2f7a4c8299def0722c20Evan Cheng } 35063d66eed16a6ee4e838f2f7a4c8299def0722c20Evan Cheng} 35163d66eed16a6ee4e838f2f7a4c8299def0722c20Evan Cheng 352fac8541dd40e01aa2b52962516f9ae67c99720ccDavid Goodwin// 353fac8541dd40e01aa2b52962516f9ae67c99720ccDavid Goodwin// EmitStageAndOperandCycleData - Generate unique itinerary stages and 354fac8541dd40e01aa2b52962516f9ae67c99720ccDavid Goodwin// operand cycle tables. Record itineraries for processors. 355fac8541dd40e01aa2b52962516f9ae67c99720ccDavid Goodwin// 356fac8541dd40e01aa2b52962516f9ae67c99720ccDavid Goodwinvoid SubtargetEmitter::EmitStageAndOperandCycleData(raw_ostream &OS, 357f7bcde085440d1fd90eba8980ed9c512bc58824dJim Laskey unsigned NItinClasses, 3585f54ce347368105260be2cec497b6a4199dc5789Evan Cheng std::map<std::string, unsigned> &ItinClassesMap, 3595f54ce347368105260be2cec497b6a4199dc5789Evan Cheng std::vector<Record*> &ItinClassList, 360f7bcde085440d1fd90eba8980ed9c512bc58824dJim Laskey std::vector<std::vector<InstrItinerary> > &ProcList) { 361908ae27a9073e2f105f8a0a4dd092d7fea8472a4Jim Laskey // Gather processor iteraries 362f7bcde085440d1fd90eba8980ed9c512bc58824dJim Laskey std::vector<Record*> ProcItinList = 363f7bcde085440d1fd90eba8980ed9c512bc58824dJim Laskey Records.getAllDerivedDefinitions("ProcessorItineraries"); 364da96cf2029e47baf77df5c1ce6528a04246d6462Andrew Trick 365908ae27a9073e2f105f8a0a4dd092d7fea8472a4Jim Laskey // If just no itinerary then don't bother 366f7bcde085440d1fd90eba8980ed9c512bc58824dJim Laskey if (ProcItinList.size() < 2) return; 367908ae27a9073e2f105f8a0a4dd092d7fea8472a4Jim Laskey 368928eb49cae286c95dceecf4442997dd561c6e3b7Anton Korobeynikov // Emit functional units for all the itineraries. 369928eb49cae286c95dceecf4442997dd561c6e3b7Anton Korobeynikov for (unsigned i = 0, N = ProcItinList.size(); i < N; ++i) { 370928eb49cae286c95dceecf4442997dd561c6e3b7Anton Korobeynikov // Next record 371928eb49cae286c95dceecf4442997dd561c6e3b7Anton Korobeynikov Record *Proc = ProcItinList[i]; 372928eb49cae286c95dceecf4442997dd561c6e3b7Anton Korobeynikov 373928eb49cae286c95dceecf4442997dd561c6e3b7Anton Korobeynikov std::vector<Record*> FUs = Proc->getValueAsListOfDefs("FU"); 374928eb49cae286c95dceecf4442997dd561c6e3b7Anton Korobeynikov if (FUs.empty()) 375928eb49cae286c95dceecf4442997dd561c6e3b7Anton Korobeynikov continue; 376928eb49cae286c95dceecf4442997dd561c6e3b7Anton Korobeynikov 377928eb49cae286c95dceecf4442997dd561c6e3b7Anton Korobeynikov const std::string &Name = Proc->getName(); 378928eb49cae286c95dceecf4442997dd561c6e3b7Anton Korobeynikov OS << "\n// Functional units for itineraries \"" << Name << "\"\n" 379928eb49cae286c95dceecf4442997dd561c6e3b7Anton Korobeynikov << "namespace " << Name << "FU {\n"; 380928eb49cae286c95dceecf4442997dd561c6e3b7Anton Korobeynikov 381928eb49cae286c95dceecf4442997dd561c6e3b7Anton Korobeynikov for (unsigned j = 0, FUN = FUs.size(); j < FUN; ++j) 382b460a3382961c5be9952a75d46228f624edbd39fHal Finkel OS << " const unsigned " << FUs[j]->getName() 383b460a3382961c5be9952a75d46228f624edbd39fHal Finkel << " = 1 << " << j << ";\n"; 384928eb49cae286c95dceecf4442997dd561c6e3b7Anton Korobeynikov 385928eb49cae286c95dceecf4442997dd561c6e3b7Anton Korobeynikov OS << "}\n"; 38663d66eed16a6ee4e838f2f7a4c8299def0722c20Evan Cheng 38763d66eed16a6ee4e838f2f7a4c8299def0722c20Evan Cheng std::vector<Record*> BPs = Proc->getValueAsListOfDefs("BP"); 3883881cb7a5d54c0011b40997adcd742e1c7b91abdEvan Cheng if (BPs.size()) { 3893881cb7a5d54c0011b40997adcd742e1c7b91abdEvan Cheng OS << "\n// Pipeline forwarding pathes for itineraries \"" << Name 3903881cb7a5d54c0011b40997adcd742e1c7b91abdEvan Cheng << "\"\n" << "namespace " << Name << "Bypass {\n"; 39163d66eed16a6ee4e838f2f7a4c8299def0722c20Evan Cheng 3921a2f9886a2a60dbd41216468a240446bbfed3e76Benjamin Kramer OS << " const unsigned NoBypass = 0;\n"; 3933881cb7a5d54c0011b40997adcd742e1c7b91abdEvan Cheng for (unsigned j = 0, BPN = BPs.size(); j < BPN; ++j) 3941a2f9886a2a60dbd41216468a240446bbfed3e76Benjamin Kramer OS << " const unsigned " << BPs[j]->getName() 3953881cb7a5d54c0011b40997adcd742e1c7b91abdEvan Cheng << " = 1 << " << j << ";\n"; 39663d66eed16a6ee4e838f2f7a4c8299def0722c20Evan Cheng 3973881cb7a5d54c0011b40997adcd742e1c7b91abdEvan Cheng OS << "}\n"; 3983881cb7a5d54c0011b40997adcd742e1c7b91abdEvan Cheng } 399928eb49cae286c95dceecf4442997dd561c6e3b7Anton Korobeynikov } 400928eb49cae286c95dceecf4442997dd561c6e3b7Anton Korobeynikov 401908ae27a9073e2f105f8a0a4dd092d7fea8472a4Jim Laskey // Begin stages table 4021a2f9886a2a60dbd41216468a240446bbfed3e76Benjamin Kramer std::string StageTable = "\nextern const llvm::InstrStage " + Target + 4031a2f9886a2a60dbd41216468a240446bbfed3e76Benjamin Kramer "Stages[] = {\n"; 40496085a36dbb9cf251c81bc150e41ea9c952c99c0Anton Korobeynikov StageTable += " { 0, 0, 0, llvm::InstrStage::Required }, // No itinerary\n"; 405da96cf2029e47baf77df5c1ce6528a04246d6462Andrew Trick 406fac8541dd40e01aa2b52962516f9ae67c99720ccDavid Goodwin // Begin operand cycle table 4071a2f9886a2a60dbd41216468a240446bbfed3e76Benjamin Kramer std::string OperandCycleTable = "extern const unsigned " + Target + 40894214703d97d8d9dfca88174ffc7e94820a85e62Evan Cheng "OperandCycles[] = {\n"; 409fac8541dd40e01aa2b52962516f9ae67c99720ccDavid Goodwin OperandCycleTable += " 0, // No itinerary\n"; 41063d66eed16a6ee4e838f2f7a4c8299def0722c20Evan Cheng 41163d66eed16a6ee4e838f2f7a4c8299def0722c20Evan Cheng // Begin pipeline bypass table 4121a2f9886a2a60dbd41216468a240446bbfed3e76Benjamin Kramer std::string BypassTable = "extern const unsigned " + Target + 413a11a6287a504d1d7503e744d14314df1e696f506Andrew Trick "ForwardingPaths[] = {\n"; 41463d66eed16a6ee4e838f2f7a4c8299def0722c20Evan Cheng BypassTable += " 0, // No itinerary\n"; 415da96cf2029e47baf77df5c1ce6528a04246d6462Andrew Trick 416fac8541dd40e01aa2b52962516f9ae67c99720ccDavid Goodwin unsigned StageCount = 1, OperandCycleCount = 1; 4173881cb7a5d54c0011b40997adcd742e1c7b91abdEvan Cheng std::map<std::string, unsigned> ItinStageMap, ItinOperandMap; 418f7bcde085440d1fd90eba8980ed9c512bc58824dJim Laskey for (unsigned i = 0, N = ProcItinList.size(); i < N; i++) { 419f7bcde085440d1fd90eba8980ed9c512bc58824dJim Laskey // Next record 420f7bcde085440d1fd90eba8980ed9c512bc58824dJim Laskey Record *Proc = ProcItinList[i]; 421da96cf2029e47baf77df5c1ce6528a04246d6462Andrew Trick 422908ae27a9073e2f105f8a0a4dd092d7fea8472a4Jim Laskey // Get processor itinerary name 4234222d806faae71ecc794cfdaa873817873c2f3d8Bill Wendling const std::string &Name = Proc->getName(); 424da96cf2029e47baf77df5c1ce6528a04246d6462Andrew Trick 425f7bcde085440d1fd90eba8980ed9c512bc58824dJim Laskey // Get itinerary data list 426b0e103d46bf8799ac5523157a6ed4a78d1751a89Chris Lattner std::vector<Record*> ItinDataList = Proc->getValueAsListOfDefs("IID"); 427d85934b3e5a96040e199e1b098705eb56cde584aAndrew Trick std::vector<InstrItinerary> ItinList; 428d85934b3e5a96040e199e1b098705eb56cde584aAndrew Trick 429d85934b3e5a96040e199e1b098705eb56cde584aAndrew Trick // Add an empty itinerary. 430d85934b3e5a96040e199e1b098705eb56cde584aAndrew Trick if (ItinDataList.empty()) { 431d85934b3e5a96040e199e1b098705eb56cde584aAndrew Trick ProcList.push_back(ItinList); 432d85934b3e5a96040e199e1b098705eb56cde584aAndrew Trick continue; 433d85934b3e5a96040e199e1b098705eb56cde584aAndrew Trick } 434d85934b3e5a96040e199e1b098705eb56cde584aAndrew Trick 435d85934b3e5a96040e199e1b098705eb56cde584aAndrew Trick // Expand processor itinerary to cover all itinerary classes 436d85934b3e5a96040e199e1b098705eb56cde584aAndrew Trick ItinList.resize(NItinClasses); 437da96cf2029e47baf77df5c1ce6528a04246d6462Andrew Trick 438f7bcde085440d1fd90eba8980ed9c512bc58824dJim Laskey // For each itinerary data 439f7bcde085440d1fd90eba8980ed9c512bc58824dJim Laskey for (unsigned j = 0, M = ItinDataList.size(); j < M; j++) { 440f7bcde085440d1fd90eba8980ed9c512bc58824dJim Laskey // Next itinerary data 441f7bcde085440d1fd90eba8980ed9c512bc58824dJim Laskey Record *ItinData = ItinDataList[j]; 442da96cf2029e47baf77df5c1ce6528a04246d6462Andrew Trick 443908ae27a9073e2f105f8a0a4dd092d7fea8472a4Jim Laskey // Get string and stage count 444fac8541dd40e01aa2b52962516f9ae67c99720ccDavid Goodwin std::string ItinStageString; 445f7bcde085440d1fd90eba8980ed9c512bc58824dJim Laskey unsigned NStages; 446928eb49cae286c95dceecf4442997dd561c6e3b7Anton Korobeynikov FormItineraryStageString(Name, ItinData, ItinStageString, NStages); 447fac8541dd40e01aa2b52962516f9ae67c99720ccDavid Goodwin 448fac8541dd40e01aa2b52962516f9ae67c99720ccDavid Goodwin // Get string and operand cycle count 449fac8541dd40e01aa2b52962516f9ae67c99720ccDavid Goodwin std::string ItinOperandCycleString; 450fac8541dd40e01aa2b52962516f9ae67c99720ccDavid Goodwin unsigned NOperandCycles; 451fac8541dd40e01aa2b52962516f9ae67c99720ccDavid Goodwin FormItineraryOperandCycleString(ItinData, ItinOperandCycleString, 452fac8541dd40e01aa2b52962516f9ae67c99720ccDavid Goodwin NOperandCycles); 453fac8541dd40e01aa2b52962516f9ae67c99720ccDavid Goodwin 45463d66eed16a6ee4e838f2f7a4c8299def0722c20Evan Cheng std::string ItinBypassString; 45563d66eed16a6ee4e838f2f7a4c8299def0722c20Evan Cheng FormItineraryBypassString(Name, ItinData, ItinBypassString, 45663d66eed16a6ee4e838f2f7a4c8299def0722c20Evan Cheng NOperandCycles); 45763d66eed16a6ee4e838f2f7a4c8299def0722c20Evan Cheng 458fac8541dd40e01aa2b52962516f9ae67c99720ccDavid Goodwin // Check to see if stage already exists and create if it doesn't 459fac8541dd40e01aa2b52962516f9ae67c99720ccDavid Goodwin unsigned FindStage = 0; 460fac8541dd40e01aa2b52962516f9ae67c99720ccDavid Goodwin if (NStages > 0) { 461fac8541dd40e01aa2b52962516f9ae67c99720ccDavid Goodwin FindStage = ItinStageMap[ItinStageString]; 462fac8541dd40e01aa2b52962516f9ae67c99720ccDavid Goodwin if (FindStage == 0) { 463234823297e0fc0babddd2ab84054bf68f64a54d1Andrew Trick // Emit as { cycles, u1 | u2 | ... | un, timeinc }, // indices 464234823297e0fc0babddd2ab84054bf68f64a54d1Andrew Trick StageTable += ItinStageString + ", // " + itostr(StageCount); 465234823297e0fc0babddd2ab84054bf68f64a54d1Andrew Trick if (NStages > 1) 466234823297e0fc0babddd2ab84054bf68f64a54d1Andrew Trick StageTable += "-" + itostr(StageCount + NStages - 1); 467234823297e0fc0babddd2ab84054bf68f64a54d1Andrew Trick StageTable += "\n"; 468fac8541dd40e01aa2b52962516f9ae67c99720ccDavid Goodwin // Record Itin class number. 469fac8541dd40e01aa2b52962516f9ae67c99720ccDavid Goodwin ItinStageMap[ItinStageString] = FindStage = StageCount; 470fac8541dd40e01aa2b52962516f9ae67c99720ccDavid Goodwin StageCount += NStages; 471fac8541dd40e01aa2b52962516f9ae67c99720ccDavid Goodwin } 472fac8541dd40e01aa2b52962516f9ae67c99720ccDavid Goodwin } 473da96cf2029e47baf77df5c1ce6528a04246d6462Andrew Trick 474fac8541dd40e01aa2b52962516f9ae67c99720ccDavid Goodwin // Check to see if operand cycle already exists and create if it doesn't 475fac8541dd40e01aa2b52962516f9ae67c99720ccDavid Goodwin unsigned FindOperandCycle = 0; 476fac8541dd40e01aa2b52962516f9ae67c99720ccDavid Goodwin if (NOperandCycles > 0) { 4773881cb7a5d54c0011b40997adcd742e1c7b91abdEvan Cheng std::string ItinOperandString = ItinOperandCycleString+ItinBypassString; 4783881cb7a5d54c0011b40997adcd742e1c7b91abdEvan Cheng FindOperandCycle = ItinOperandMap[ItinOperandString]; 479fac8541dd40e01aa2b52962516f9ae67c99720ccDavid Goodwin if (FindOperandCycle == 0) { 480fac8541dd40e01aa2b52962516f9ae67c99720ccDavid Goodwin // Emit as cycle, // index 481234823297e0fc0babddd2ab84054bf68f64a54d1Andrew Trick OperandCycleTable += ItinOperandCycleString + ", // "; 482234823297e0fc0babddd2ab84054bf68f64a54d1Andrew Trick std::string OperandIdxComment = itostr(OperandCycleCount); 483234823297e0fc0babddd2ab84054bf68f64a54d1Andrew Trick if (NOperandCycles > 1) 484234823297e0fc0babddd2ab84054bf68f64a54d1Andrew Trick OperandIdxComment += "-" 485234823297e0fc0babddd2ab84054bf68f64a54d1Andrew Trick + itostr(OperandCycleCount + NOperandCycles - 1); 486234823297e0fc0babddd2ab84054bf68f64a54d1Andrew Trick OperandCycleTable += OperandIdxComment + "\n"; 487fac8541dd40e01aa2b52962516f9ae67c99720ccDavid Goodwin // Record Itin class number. 488da96cf2029e47baf77df5c1ce6528a04246d6462Andrew Trick ItinOperandMap[ItinOperandCycleString] = 489fac8541dd40e01aa2b52962516f9ae67c99720ccDavid Goodwin FindOperandCycle = OperandCycleCount; 49063d66eed16a6ee4e838f2f7a4c8299def0722c20Evan Cheng // Emit as bypass, // index 491234823297e0fc0babddd2ab84054bf68f64a54d1Andrew Trick BypassTable += ItinBypassString + ", // " + OperandIdxComment + "\n"; 492fac8541dd40e01aa2b52962516f9ae67c99720ccDavid Goodwin OperandCycleCount += NOperandCycles; 493fac8541dd40e01aa2b52962516f9ae67c99720ccDavid Goodwin } 4940d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey } 495da96cf2029e47baf77df5c1ce6528a04246d6462Andrew Trick 496908ae27a9073e2f105f8a0a4dd092d7fea8472a4Jim Laskey // Locate where to inject into processor itinerary table 4974222d806faae71ecc794cfdaa873817873c2f3d8Bill Wendling const std::string &Name = ItinData->getValueAsDef("TheClass")->getName(); 498fac8541dd40e01aa2b52962516f9ae67c99720ccDavid Goodwin unsigned Find = ItinClassesMap[Name]; 499da96cf2029e47baf77df5c1ce6528a04246d6462Andrew Trick 5005f54ce347368105260be2cec497b6a4199dc5789Evan Cheng // Set up itinerary as location and location + stage count 501506bb19d10fd3f1a9486e9c8bef632f13da8fe4aChandler Carruth int NumUOps = ItinData->getValueAsInt("NumMicroOps"); 5025f54ce347368105260be2cec497b6a4199dc5789Evan Cheng InstrItinerary Intinerary = { NumUOps, FindStage, FindStage + NStages, 5035f54ce347368105260be2cec497b6a4199dc5789Evan Cheng FindOperandCycle, 5045f54ce347368105260be2cec497b6a4199dc5789Evan Cheng FindOperandCycle + NOperandCycles}; 5055f54ce347368105260be2cec497b6a4199dc5789Evan Cheng 506908ae27a9073e2f105f8a0a4dd092d7fea8472a4Jim Laskey // Inject - empty slots will be 0, 0 507f7bcde085440d1fd90eba8980ed9c512bc58824dJim Laskey ItinList[Find] = Intinerary; 5080d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey } 509da96cf2029e47baf77df5c1ce6528a04246d6462Andrew Trick 510908ae27a9073e2f105f8a0a4dd092d7fea8472a4Jim Laskey // Add process itinerary to list 511f7bcde085440d1fd90eba8980ed9c512bc58824dJim Laskey ProcList.push_back(ItinList); 5120d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey } 51363d66eed16a6ee4e838f2f7a4c8299def0722c20Evan Cheng 5147f39c14f52262a154285df9180f5edcdabe2d7dfJim Laskey // Closing stage 51596085a36dbb9cf251c81bc150e41ea9c952c99c0Anton Korobeynikov StageTable += " { 0, 0, 0, llvm::InstrStage::Required } // End itinerary\n"; 516fac8541dd40e01aa2b52962516f9ae67c99720ccDavid Goodwin StageTable += "};\n"; 517fac8541dd40e01aa2b52962516f9ae67c99720ccDavid Goodwin 518fac8541dd40e01aa2b52962516f9ae67c99720ccDavid Goodwin // Closing operand cycles 519fac8541dd40e01aa2b52962516f9ae67c99720ccDavid Goodwin OperandCycleTable += " 0 // End itinerary\n"; 520fac8541dd40e01aa2b52962516f9ae67c99720ccDavid Goodwin OperandCycleTable += "};\n"; 521fac8541dd40e01aa2b52962516f9ae67c99720ccDavid Goodwin 52263d66eed16a6ee4e838f2f7a4c8299def0722c20Evan Cheng BypassTable += " 0 // End itinerary\n"; 52363d66eed16a6ee4e838f2f7a4c8299def0722c20Evan Cheng BypassTable += "};\n"; 52463d66eed16a6ee4e838f2f7a4c8299def0722c20Evan Cheng 525fac8541dd40e01aa2b52962516f9ae67c99720ccDavid Goodwin // Emit tables. 526fac8541dd40e01aa2b52962516f9ae67c99720ccDavid Goodwin OS << StageTable; 527fac8541dd40e01aa2b52962516f9ae67c99720ccDavid Goodwin OS << OperandCycleTable; 52863d66eed16a6ee4e838f2f7a4c8299def0722c20Evan Cheng OS << BypassTable; 5290d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey} 5300d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey 531fc992996f751e0941951b6d08d8f1e80ebec1385Andrew Trickvoid SubtargetEmitter::EmitItineraryProp(raw_ostream &OS, const Record *R, 532fc992996f751e0941951b6d08d8f1e80ebec1385Andrew Trick const char *Name, char Separator) { 533fc992996f751e0941951b6d08d8f1e80ebec1385Andrew Trick OS << " "; 534fc992996f751e0941951b6d08d8f1e80ebec1385Andrew Trick int V = R->getValueAsInt(Name); 535fc992996f751e0941951b6d08d8f1e80ebec1385Andrew Trick if (V >= 0) 536fc992996f751e0941951b6d08d8f1e80ebec1385Andrew Trick OS << V << Separator << " // " << Name; 537fc992996f751e0941951b6d08d8f1e80ebec1385Andrew Trick else 5380076ad7eebb46c07288eec20e385dd8eaff736fbAndrew Trick OS << "InstrItineraryProps::Default" << Name << Separator; 539fc992996f751e0941951b6d08d8f1e80ebec1385Andrew Trick OS << '\n'; 540fc992996f751e0941951b6d08d8f1e80ebec1385Andrew Trick} 541fc992996f751e0941951b6d08d8f1e80ebec1385Andrew Trick 5420d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey// 54310b1dd99f342d2d7af51dd43f3840f3bf40b0b87Jim Laskey// EmitProcessorData - Generate data for processor itineraries. 5440d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey// 545234823297e0fc0babddd2ab84054bf68f64a54d1Andrew Trickvoid SubtargetEmitter:: 546234823297e0fc0babddd2ab84054bf68f64a54d1Andrew TrickEmitProcessorData(raw_ostream &OS, 547234823297e0fc0babddd2ab84054bf68f64a54d1Andrew Trick std::vector<Record*> &ItinClassList, 548234823297e0fc0babddd2ab84054bf68f64a54d1Andrew Trick std::vector<std::vector<InstrItinerary> > &ProcList) { 549fc992996f751e0941951b6d08d8f1e80ebec1385Andrew Trick 550908ae27a9073e2f105f8a0a4dd092d7fea8472a4Jim Laskey // Get an iterator for processor itinerary stages 551f7bcde085440d1fd90eba8980ed9c512bc58824dJim Laskey std::vector<std::vector<InstrItinerary> >::iterator 552f7bcde085440d1fd90eba8980ed9c512bc58824dJim Laskey ProcListIter = ProcList.begin(); 553da96cf2029e47baf77df5c1ce6528a04246d6462Andrew Trick 554908ae27a9073e2f105f8a0a4dd092d7fea8472a4Jim Laskey // For each processor itinerary 555f7bcde085440d1fd90eba8980ed9c512bc58824dJim Laskey std::vector<Record*> Itins = 556f7bcde085440d1fd90eba8980ed9c512bc58824dJim Laskey Records.getAllDerivedDefinitions("ProcessorItineraries"); 557f7bcde085440d1fd90eba8980ed9c512bc58824dJim Laskey for (unsigned i = 0, N = Itins.size(); i < N; i++) { 558f7bcde085440d1fd90eba8980ed9c512bc58824dJim Laskey // Next record 559f7bcde085440d1fd90eba8980ed9c512bc58824dJim Laskey Record *Itin = Itins[i]; 560f7bcde085440d1fd90eba8980ed9c512bc58824dJim Laskey 561908ae27a9073e2f105f8a0a4dd092d7fea8472a4Jim Laskey // Get processor itinerary name 5624222d806faae71ecc794cfdaa873817873c2f3d8Bill Wendling const std::string &Name = Itin->getName(); 563da96cf2029e47baf77df5c1ce6528a04246d6462Andrew Trick 564908ae27a9073e2f105f8a0a4dd092d7fea8472a4Jim Laskey // Skip default 565fc992996f751e0941951b6d08d8f1e80ebec1385Andrew Trick // Begin processor itinerary properties 566fc992996f751e0941951b6d08d8f1e80ebec1385Andrew Trick OS << "\n"; 567fc992996f751e0941951b6d08d8f1e80ebec1385Andrew Trick OS << "static const llvm::InstrItineraryProps " << Name << "Props(\n"; 568fc992996f751e0941951b6d08d8f1e80ebec1385Andrew Trick EmitItineraryProp(OS, Itin, "IssueWidth", ','); 569fc992996f751e0941951b6d08d8f1e80ebec1385Andrew Trick EmitItineraryProp(OS, Itin, "MinLatency", ','); 570fc992996f751e0941951b6d08d8f1e80ebec1385Andrew Trick EmitItineraryProp(OS, Itin, "LoadLatency", ','); 571fc992996f751e0941951b6d08d8f1e80ebec1385Andrew Trick EmitItineraryProp(OS, Itin, "HighLatency", ' '); 572fc992996f751e0941951b6d08d8f1e80ebec1385Andrew Trick OS << ");\n"; 573fc992996f751e0941951b6d08d8f1e80ebec1385Andrew Trick 574908ae27a9073e2f105f8a0a4dd092d7fea8472a4Jim Laskey // For each itinerary class 575f7bcde085440d1fd90eba8980ed9c512bc58824dJim Laskey std::vector<InstrItinerary> &ItinList = *ProcListIter++; 576d85934b3e5a96040e199e1b098705eb56cde584aAndrew Trick if (!ItinList.empty()) { 577d85934b3e5a96040e199e1b098705eb56cde584aAndrew Trick assert(ItinList.size() == ItinClassList.size() && "bad itinerary"); 578da96cf2029e47baf77df5c1ce6528a04246d6462Andrew Trick 579d85934b3e5a96040e199e1b098705eb56cde584aAndrew Trick // Begin processor itinerary table 580d85934b3e5a96040e199e1b098705eb56cde584aAndrew Trick OS << "\n"; 581d85934b3e5a96040e199e1b098705eb56cde584aAndrew Trick OS << "static const llvm::InstrItinerary " << Name << "Entries" 582d85934b3e5a96040e199e1b098705eb56cde584aAndrew Trick << "[] = {\n"; 583d85934b3e5a96040e199e1b098705eb56cde584aAndrew Trick 584d85934b3e5a96040e199e1b098705eb56cde584aAndrew Trick for (unsigned j = 0, M = ItinList.size(); j < M; ++j) { 585d85934b3e5a96040e199e1b098705eb56cde584aAndrew Trick InstrItinerary &Intinerary = ItinList[j]; 586d85934b3e5a96040e199e1b098705eb56cde584aAndrew Trick 587d85934b3e5a96040e199e1b098705eb56cde584aAndrew Trick // Emit in the form of 588d85934b3e5a96040e199e1b098705eb56cde584aAndrew Trick // { firstStage, lastStage, firstCycle, lastCycle } // index 589d85934b3e5a96040e199e1b098705eb56cde584aAndrew Trick if (Intinerary.FirstStage == 0) { 590d85934b3e5a96040e199e1b098705eb56cde584aAndrew Trick OS << " { 1, 0, 0, 0, 0 }"; 591d85934b3e5a96040e199e1b098705eb56cde584aAndrew Trick } else { 592d85934b3e5a96040e199e1b098705eb56cde584aAndrew Trick OS << " { " << 593d85934b3e5a96040e199e1b098705eb56cde584aAndrew Trick Intinerary.NumMicroOps << ", " << 594d85934b3e5a96040e199e1b098705eb56cde584aAndrew Trick Intinerary.FirstStage << ", " << 595d85934b3e5a96040e199e1b098705eb56cde584aAndrew Trick Intinerary.LastStage << ", " << 596d85934b3e5a96040e199e1b098705eb56cde584aAndrew Trick Intinerary.FirstOperandCycle << ", " << 597d85934b3e5a96040e199e1b098705eb56cde584aAndrew Trick Intinerary.LastOperandCycle << " }"; 598d85934b3e5a96040e199e1b098705eb56cde584aAndrew Trick } 599d85934b3e5a96040e199e1b098705eb56cde584aAndrew Trick OS << ", // " << j << " " << ItinClassList[j]->getName() << "\n"; 600d85934b3e5a96040e199e1b098705eb56cde584aAndrew Trick } 601d85934b3e5a96040e199e1b098705eb56cde584aAndrew Trick // End processor itinerary table 602d85934b3e5a96040e199e1b098705eb56cde584aAndrew Trick OS << " { 1, ~0U, ~0U, ~0U, ~0U } // end marker\n"; 603d85934b3e5a96040e199e1b098705eb56cde584aAndrew Trick OS << "};\n"; 6040d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey } 605fc992996f751e0941951b6d08d8f1e80ebec1385Andrew Trick OS << '\n'; 606fc992996f751e0941951b6d08d8f1e80ebec1385Andrew Trick OS << "static const llvm::InstrItinerarySubtargetValue " 607fc992996f751e0941951b6d08d8f1e80ebec1385Andrew Trick << Name << " = {\n"; 608fc992996f751e0941951b6d08d8f1e80ebec1385Andrew Trick OS << " &" << Name << "Props,\n"; 609d85934b3e5a96040e199e1b098705eb56cde584aAndrew Trick if (ItinList.empty()) 610d85934b3e5a96040e199e1b098705eb56cde584aAndrew Trick OS << " 0\n"; 611d85934b3e5a96040e199e1b098705eb56cde584aAndrew Trick else 612d85934b3e5a96040e199e1b098705eb56cde584aAndrew Trick OS << " " << Name << "Entries\n"; 613fc992996f751e0941951b6d08d8f1e80ebec1385Andrew Trick OS << "};\n"; 6140d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey } 61510b1dd99f342d2d7af51dd43f3840f3bf40b0b87Jim Laskey} 61610b1dd99f342d2d7af51dd43f3840f3bf40b0b87Jim Laskey 61710b1dd99f342d2d7af51dd43f3840f3bf40b0b87Jim Laskey// 61810b1dd99f342d2d7af51dd43f3840f3bf40b0b87Jim Laskey// EmitProcessorLookup - generate cpu name to itinerary lookup table. 61910b1dd99f342d2d7af51dd43f3840f3bf40b0b87Jim Laskey// 6201a55180238dbcf11113f610aea010447e51f595bDaniel Dunbarvoid SubtargetEmitter::EmitProcessorLookup(raw_ostream &OS) { 62110b1dd99f342d2d7af51dd43f3840f3bf40b0b87Jim Laskey // Gather and sort processor information 62210b1dd99f342d2d7af51dd43f3840f3bf40b0b87Jim Laskey std::vector<Record*> ProcessorList = 62310b1dd99f342d2d7af51dd43f3840f3bf40b0b87Jim Laskey Records.getAllDerivedDefinitions("Processor"); 62442d24c71df88178eacf244a38b6c48847ee0d39bDuraid Madina std::sort(ProcessorList.begin(), ProcessorList.end(), LessRecordFieldName()); 62510b1dd99f342d2d7af51dd43f3840f3bf40b0b87Jim Laskey 62610b1dd99f342d2d7af51dd43f3840f3bf40b0b87Jim Laskey // Begin processor table 62710b1dd99f342d2d7af51dd43f3840f3bf40b0b87Jim Laskey OS << "\n"; 62810b1dd99f342d2d7af51dd43f3840f3bf40b0b87Jim Laskey OS << "// Sorted (by key) array of itineraries for CPU subtype.\n" 6291a2f9886a2a60dbd41216468a240446bbfed3e76Benjamin Kramer << "extern const llvm::SubtargetInfoKV " 63094214703d97d8d9dfca88174ffc7e94820a85e62Evan Cheng << Target << "ProcItinKV[] = {\n"; 631da96cf2029e47baf77df5c1ce6528a04246d6462Andrew Trick 63210b1dd99f342d2d7af51dd43f3840f3bf40b0b87Jim Laskey // For each processor 63310b1dd99f342d2d7af51dd43f3840f3bf40b0b87Jim Laskey for (unsigned i = 0, N = ProcessorList.size(); i < N;) { 63410b1dd99f342d2d7af51dd43f3840f3bf40b0b87Jim Laskey // Next processor 63510b1dd99f342d2d7af51dd43f3840f3bf40b0b87Jim Laskey Record *Processor = ProcessorList[i]; 63610b1dd99f342d2d7af51dd43f3840f3bf40b0b87Jim Laskey 6374222d806faae71ecc794cfdaa873817873c2f3d8Bill Wendling const std::string &Name = Processor->getValueAsString("Name"); 6384222d806faae71ecc794cfdaa873817873c2f3d8Bill Wendling const std::string &ProcItin = 6394222d806faae71ecc794cfdaa873817873c2f3d8Bill Wendling Processor->getValueAsDef("ProcItin")->getName(); 640da96cf2029e47baf77df5c1ce6528a04246d6462Andrew Trick 64110b1dd99f342d2d7af51dd43f3840f3bf40b0b87Jim Laskey // Emit as { "cpu", procinit }, 64210b1dd99f342d2d7af51dd43f3840f3bf40b0b87Jim Laskey OS << " { " 64310b1dd99f342d2d7af51dd43f3840f3bf40b0b87Jim Laskey << "\"" << Name << "\", " 64410b1dd99f342d2d7af51dd43f3840f3bf40b0b87Jim Laskey << "(void *)&" << ProcItin; 645da96cf2029e47baf77df5c1ce6528a04246d6462Andrew Trick 64610b1dd99f342d2d7af51dd43f3840f3bf40b0b87Jim Laskey OS << " }"; 647da96cf2029e47baf77df5c1ce6528a04246d6462Andrew Trick 64810b1dd99f342d2d7af51dd43f3840f3bf40b0b87Jim Laskey // Depending on ''if more in the list'' emit comma 64910b1dd99f342d2d7af51dd43f3840f3bf40b0b87Jim Laskey if (++i < N) OS << ","; 650da96cf2029e47baf77df5c1ce6528a04246d6462Andrew Trick 65110b1dd99f342d2d7af51dd43f3840f3bf40b0b87Jim Laskey OS << "\n"; 65210b1dd99f342d2d7af51dd43f3840f3bf40b0b87Jim Laskey } 653da96cf2029e47baf77df5c1ce6528a04246d6462Andrew Trick 65410b1dd99f342d2d7af51dd43f3840f3bf40b0b87Jim Laskey // End processor table 65510b1dd99f342d2d7af51dd43f3840f3bf40b0b87Jim Laskey OS << "};\n"; 6560d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey} 6570d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey 6580d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey// 6590d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey// EmitData - Emits all stages and itineries, folding common patterns. 6600d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey// 6611a55180238dbcf11113f610aea010447e51f595bDaniel Dunbarvoid SubtargetEmitter::EmitData(raw_ostream &OS) { 662f7bcde085440d1fd90eba8980ed9c512bc58824dJim Laskey std::map<std::string, unsigned> ItinClassesMap; 6635f54ce347368105260be2cec497b6a4199dc5789Evan Cheng // Gather and sort all itinerary classes 6645f54ce347368105260be2cec497b6a4199dc5789Evan Cheng std::vector<Record*> ItinClassList = 6655f54ce347368105260be2cec497b6a4199dc5789Evan Cheng Records.getAllDerivedDefinitions("InstrItinClass"); 6665f54ce347368105260be2cec497b6a4199dc5789Evan Cheng std::sort(ItinClassList.begin(), ItinClassList.end(), LessRecord()); 667da96cf2029e47baf77df5c1ce6528a04246d6462Andrew Trick 668908ae27a9073e2f105f8a0a4dd092d7fea8472a4Jim Laskey // Enumerate all the itinerary classes 6695f54ce347368105260be2cec497b6a4199dc5789Evan Cheng unsigned NItinClasses = CollectAllItinClasses(OS, ItinClassesMap, 6705f54ce347368105260be2cec497b6a4199dc5789Evan Cheng ItinClassList); 6716cee630070b1a7183ed56a8404e812629f5ca538Jim Laskey // Make sure the rest is worth the effort 672387e4bdf002c78a1b43a10e10cf5147baf32f513Chris Lattner HasItineraries = NItinClasses != 1; // Ignore NoItinerary. 673da96cf2029e47baf77df5c1ce6528a04246d6462Andrew Trick 6746cee630070b1a7183ed56a8404e812629f5ca538Jim Laskey if (HasItineraries) { 6755f54ce347368105260be2cec497b6a4199dc5789Evan Cheng std::vector<std::vector<InstrItinerary> > ProcList; 6766cee630070b1a7183ed56a8404e812629f5ca538Jim Laskey // Emit the stage data 6775f54ce347368105260be2cec497b6a4199dc5789Evan Cheng EmitStageAndOperandCycleData(OS, NItinClasses, ItinClassesMap, 6785f54ce347368105260be2cec497b6a4199dc5789Evan Cheng ItinClassList, ProcList); 6796cee630070b1a7183ed56a8404e812629f5ca538Jim Laskey // Emit the processor itinerary data 680234823297e0fc0babddd2ab84054bf68f64a54d1Andrew Trick EmitProcessorData(OS, ItinClassList, ProcList); 6816cee630070b1a7183ed56a8404e812629f5ca538Jim Laskey // Emit the processor lookup data 6826cee630070b1a7183ed56a8404e812629f5ca538Jim Laskey EmitProcessorLookup(OS); 6836cee630070b1a7183ed56a8404e812629f5ca538Jim Laskey } 6840d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey} 6850d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey 6860d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey// 687581a8f79bc1ac3cbe5d621f0b4a0252ab2890bc1Jim Laskey// ParseFeaturesFunction - Produces a subtarget specific function for parsing 688581a8f79bc1ac3cbe5d621f0b4a0252ab2890bc1Jim Laskey// the subtarget features string. 689581a8f79bc1ac3cbe5d621f0b4a0252ab2890bc1Jim Laskey// 69094214703d97d8d9dfca88174ffc7e94820a85e62Evan Chengvoid SubtargetEmitter::ParseFeaturesFunction(raw_ostream &OS, 69194214703d97d8d9dfca88174ffc7e94820a85e62Evan Cheng unsigned NumFeatures, 69294214703d97d8d9dfca88174ffc7e94820a85e62Evan Cheng unsigned NumProcs) { 693f7bcde085440d1fd90eba8980ed9c512bc58824dJim Laskey std::vector<Record*> Features = 694f7bcde085440d1fd90eba8980ed9c512bc58824dJim Laskey Records.getAllDerivedDefinitions("SubtargetFeature"); 69542d24c71df88178eacf244a38b6c48847ee0d39bDuraid Madina std::sort(Features.begin(), Features.end(), LessRecord()); 696581a8f79bc1ac3cbe5d621f0b4a0252ab2890bc1Jim Laskey 697da96cf2029e47baf77df5c1ce6528a04246d6462Andrew Trick OS << "// ParseSubtargetFeatures - Parses features string setting specified\n" 698da96cf2029e47baf77df5c1ce6528a04246d6462Andrew Trick << "// subtarget options.\n" 699276365dd4bc0c2160f91fd8062ae1fc90c86c324Evan Cheng << "void llvm::"; 700581a8f79bc1ac3cbe5d621f0b4a0252ab2890bc1Jim Laskey OS << Target; 7010ddff1b5359433faf2eb1c4ff5320ddcbd42f52fEvan Cheng OS << "Subtarget::ParseSubtargetFeatures(StringRef CPU, StringRef FS) {\n" 702f0fd3afeffcb41202147f755bf770061f189a42bDavid Greene << " DEBUG(dbgs() << \"\\nFeatures:\" << FS);\n" 7033f696e568bae8afa5986e7af48156c2bac041ba7Hal Finkel << " DEBUG(dbgs() << \"\\nCPU:\" << CPU << \"\\n\\n\");\n"; 70494214703d97d8d9dfca88174ffc7e94820a85e62Evan Cheng 70594214703d97d8d9dfca88174ffc7e94820a85e62Evan Cheng if (Features.empty()) { 70694214703d97d8d9dfca88174ffc7e94820a85e62Evan Cheng OS << "}\n"; 70794214703d97d8d9dfca88174ffc7e94820a85e62Evan Cheng return; 70894214703d97d8d9dfca88174ffc7e94820a85e62Evan Cheng } 70994214703d97d8d9dfca88174ffc7e94820a85e62Evan Cheng 7100ddff1b5359433faf2eb1c4ff5320ddcbd42f52fEvan Cheng OS << " uint64_t Bits = ReInitMCSubtargetInfo(CPU, FS);\n"; 7114222d806faae71ecc794cfdaa873817873c2f3d8Bill Wendling 712f7bcde085440d1fd90eba8980ed9c512bc58824dJim Laskey for (unsigned i = 0; i < Features.size(); i++) { 713f7bcde085440d1fd90eba8980ed9c512bc58824dJim Laskey // Next record 714f7bcde085440d1fd90eba8980ed9c512bc58824dJim Laskey Record *R = Features[i]; 7154222d806faae71ecc794cfdaa873817873c2f3d8Bill Wendling const std::string &Instance = R->getName(); 7164222d806faae71ecc794cfdaa873817873c2f3d8Bill Wendling const std::string &Value = R->getValueAsString("Value"); 7174222d806faae71ecc794cfdaa873817873c2f3d8Bill Wendling const std::string &Attribute = R->getValueAsString("Attribute"); 71819c95507443ebd4f1cee80917d540c8bd27f8fe1Evan Cheng 719db01c8ba26f288636d3f574a96af3499ee6d2579Dale Johannesen if (Value=="true" || Value=="false") 7200ddff1b5359433faf2eb1c4ff5320ddcbd42f52fEvan Cheng OS << " if ((Bits & " << Target << "::" 7210ddff1b5359433faf2eb1c4ff5320ddcbd42f52fEvan Cheng << Instance << ") != 0) " 722db01c8ba26f288636d3f574a96af3499ee6d2579Dale Johannesen << Attribute << " = " << Value << ";\n"; 723db01c8ba26f288636d3f574a96af3499ee6d2579Dale Johannesen else 7240ddff1b5359433faf2eb1c4ff5320ddcbd42f52fEvan Cheng OS << " if ((Bits & " << Target << "::" 7250ddff1b5359433faf2eb1c4ff5320ddcbd42f52fEvan Cheng << Instance << ") != 0 && " 72694214703d97d8d9dfca88174ffc7e94820a85e62Evan Cheng << Attribute << " < " << Value << ") " 72794214703d97d8d9dfca88174ffc7e94820a85e62Evan Cheng << Attribute << " = " << Value << ";\n"; 7286cee630070b1a7183ed56a8404e812629f5ca538Jim Laskey } 72941a024385f1220eadc48b48cb4c044a5fbc1b361Anton Korobeynikov 730276365dd4bc0c2160f91fd8062ae1fc90c86c324Evan Cheng OS << "}\n"; 731581a8f79bc1ac3cbe5d621f0b4a0252ab2890bc1Jim Laskey} 732581a8f79bc1ac3cbe5d621f0b4a0252ab2890bc1Jim Laskey 73341a024385f1220eadc48b48cb4c044a5fbc1b361Anton Korobeynikov// 734b3b1d5f097a4fbcf134259b743ccbd93d187c6cdJim Laskey// SubtargetEmitter::run - Main subtarget enumeration emitter. 735b3b1d5f097a4fbcf134259b743ccbd93d187c6cdJim Laskey// 7361a55180238dbcf11113f610aea010447e51f595bDaniel Dunbarvoid SubtargetEmitter::run(raw_ostream &OS) { 73767db883487fca3472fdde51e931657e22d4d0495Chris Lattner Target = CodeGenTarget(Records).getName(); 738581a8f79bc1ac3cbe5d621f0b4a0252ab2890bc1Jim Laskey 7396f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen emitSourceFileHeader("Subtarget Enumeration Source Fragment", OS); 740b3b1d5f097a4fbcf134259b743ccbd93d187c6cdJim Laskey 741ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng OS << "\n#ifdef GET_SUBTARGETINFO_ENUM\n"; 742ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng OS << "#undef GET_SUBTARGETINFO_ENUM\n"; 743ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng 744ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng OS << "namespace llvm {\n"; 745ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng Enumeration(OS, "SubtargetFeature", true); 746ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng OS << "} // End llvm namespace \n"; 747ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng OS << "#endif // GET_SUBTARGETINFO_ENUM\n\n"; 748ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng 74994214703d97d8d9dfca88174ffc7e94820a85e62Evan Cheng OS << "\n#ifdef GET_SUBTARGETINFO_MC_DESC\n"; 75094214703d97d8d9dfca88174ffc7e94820a85e62Evan Cheng OS << "#undef GET_SUBTARGETINFO_MC_DESC\n"; 751928eb49cae286c95dceecf4442997dd561c6e3b7Anton Korobeynikov 75294214703d97d8d9dfca88174ffc7e94820a85e62Evan Cheng OS << "namespace llvm {\n"; 753c60f9b752381baa6c4b80c0739034660f1748c84Evan Cheng#if 0 754c60f9b752381baa6c4b80c0739034660f1748c84Evan Cheng OS << "namespace {\n"; 755c60f9b752381baa6c4b80c0739034660f1748c84Evan Cheng#endif 75694214703d97d8d9dfca88174ffc7e94820a85e62Evan Cheng unsigned NumFeatures = FeatureKeyValues(OS); 757c60f9b752381baa6c4b80c0739034660f1748c84Evan Cheng OS << "\n"; 75894214703d97d8d9dfca88174ffc7e94820a85e62Evan Cheng unsigned NumProcs = CPUKeyValues(OS); 759c60f9b752381baa6c4b80c0739034660f1748c84Evan Cheng OS << "\n"; 7600d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey EmitData(OS); 761c60f9b752381baa6c4b80c0739034660f1748c84Evan Cheng OS << "\n"; 762c60f9b752381baa6c4b80c0739034660f1748c84Evan Cheng#if 0 763c60f9b752381baa6c4b80c0739034660f1748c84Evan Cheng OS << "}\n"; 764c60f9b752381baa6c4b80c0739034660f1748c84Evan Cheng#endif 76594214703d97d8d9dfca88174ffc7e94820a85e62Evan Cheng 76694214703d97d8d9dfca88174ffc7e94820a85e62Evan Cheng // MCInstrInfo initialization routine. 76794214703d97d8d9dfca88174ffc7e94820a85e62Evan Cheng OS << "static inline void Init" << Target 76859ee62d2418df8db499eca1ae17f5900dc2dcbbaEvan Cheng << "MCSubtargetInfo(MCSubtargetInfo *II, " 76959ee62d2418df8db499eca1ae17f5900dc2dcbbaEvan Cheng << "StringRef TT, StringRef CPU, StringRef FS) {\n"; 77059ee62d2418df8db499eca1ae17f5900dc2dcbbaEvan Cheng OS << " II->InitMCSubtargetInfo(TT, CPU, FS, "; 77194214703d97d8d9dfca88174ffc7e94820a85e62Evan Cheng if (NumFeatures) 77294214703d97d8d9dfca88174ffc7e94820a85e62Evan Cheng OS << Target << "FeatureKV, "; 77394214703d97d8d9dfca88174ffc7e94820a85e62Evan Cheng else 77494214703d97d8d9dfca88174ffc7e94820a85e62Evan Cheng OS << "0, "; 77594214703d97d8d9dfca88174ffc7e94820a85e62Evan Cheng if (NumProcs) 77694214703d97d8d9dfca88174ffc7e94820a85e62Evan Cheng OS << Target << "SubTypeKV, "; 77794214703d97d8d9dfca88174ffc7e94820a85e62Evan Cheng else 77894214703d97d8d9dfca88174ffc7e94820a85e62Evan Cheng OS << "0, "; 77994214703d97d8d9dfca88174ffc7e94820a85e62Evan Cheng if (HasItineraries) { 78094214703d97d8d9dfca88174ffc7e94820a85e62Evan Cheng OS << Target << "ProcItinKV, " 78194214703d97d8d9dfca88174ffc7e94820a85e62Evan Cheng << Target << "Stages, " 78294214703d97d8d9dfca88174ffc7e94820a85e62Evan Cheng << Target << "OperandCycles, " 783a11a6287a504d1d7503e744d14314df1e696f506Andrew Trick << Target << "ForwardingPaths, "; 78494214703d97d8d9dfca88174ffc7e94820a85e62Evan Cheng } else 78594214703d97d8d9dfca88174ffc7e94820a85e62Evan Cheng OS << "0, 0, 0, 0, "; 78694214703d97d8d9dfca88174ffc7e94820a85e62Evan Cheng OS << NumFeatures << ", " << NumProcs << ");\n}\n\n"; 78794214703d97d8d9dfca88174ffc7e94820a85e62Evan Cheng 78894214703d97d8d9dfca88174ffc7e94820a85e62Evan Cheng OS << "} // End llvm namespace \n"; 78994214703d97d8d9dfca88174ffc7e94820a85e62Evan Cheng 79094214703d97d8d9dfca88174ffc7e94820a85e62Evan Cheng OS << "#endif // GET_SUBTARGETINFO_MC_DESC\n\n"; 79194214703d97d8d9dfca88174ffc7e94820a85e62Evan Cheng 79294214703d97d8d9dfca88174ffc7e94820a85e62Evan Cheng OS << "\n#ifdef GET_SUBTARGETINFO_TARGET_DESC\n"; 79394214703d97d8d9dfca88174ffc7e94820a85e62Evan Cheng OS << "#undef GET_SUBTARGETINFO_TARGET_DESC\n"; 79494214703d97d8d9dfca88174ffc7e94820a85e62Evan Cheng 79594214703d97d8d9dfca88174ffc7e94820a85e62Evan Cheng OS << "#include \"llvm/Support/Debug.h\"\n"; 79694214703d97d8d9dfca88174ffc7e94820a85e62Evan Cheng OS << "#include \"llvm/Support/raw_ostream.h\"\n"; 79794214703d97d8d9dfca88174ffc7e94820a85e62Evan Cheng ParseFeaturesFunction(OS, NumFeatures, NumProcs); 79894214703d97d8d9dfca88174ffc7e94820a85e62Evan Cheng 79994214703d97d8d9dfca88174ffc7e94820a85e62Evan Cheng OS << "#endif // GET_SUBTARGETINFO_TARGET_DESC\n\n"; 80094214703d97d8d9dfca88174ffc7e94820a85e62Evan Cheng 8015b1b4489cf3a0f56f8be0673fc5cc380a32d277bEvan Cheng // Create a TargetSubtargetInfo subclass to hide the MC layer initialization. 80294214703d97d8d9dfca88174ffc7e94820a85e62Evan Cheng OS << "\n#ifdef GET_SUBTARGETINFO_HEADER\n"; 80394214703d97d8d9dfca88174ffc7e94820a85e62Evan Cheng OS << "#undef GET_SUBTARGETINFO_HEADER\n"; 80494214703d97d8d9dfca88174ffc7e94820a85e62Evan Cheng 80594214703d97d8d9dfca88174ffc7e94820a85e62Evan Cheng std::string ClassName = Target + "GenSubtargetInfo"; 80694214703d97d8d9dfca88174ffc7e94820a85e62Evan Cheng OS << "namespace llvm {\n"; 807dc81e5da271ed394e2029c83458773c4ae2fc5f4Anshuman Dasgupta OS << "class DFAPacketizer;\n"; 8085b1b4489cf3a0f56f8be0673fc5cc380a32d277bEvan Cheng OS << "struct " << ClassName << " : public TargetSubtargetInfo {\n" 8090ddff1b5359433faf2eb1c4ff5320ddcbd42f52fEvan Cheng << " explicit " << ClassName << "(StringRef TT, StringRef CPU, " 8100ddff1b5359433faf2eb1c4ff5320ddcbd42f52fEvan Cheng << "StringRef FS);\n" 811dc81e5da271ed394e2029c83458773c4ae2fc5f4Anshuman Dasgupta << "public:\n" 812464f3a332f81364ee09794f9502f0b25671149c6Sebastian Pop << " DFAPacketizer *createDFAPacketizer(const InstrItineraryData *IID)" 813dc81e5da271ed394e2029c83458773c4ae2fc5f4Anshuman Dasgupta << " const;\n" 81494214703d97d8d9dfca88174ffc7e94820a85e62Evan Cheng << "};\n"; 81594214703d97d8d9dfca88174ffc7e94820a85e62Evan Cheng OS << "} // End llvm namespace \n"; 81694214703d97d8d9dfca88174ffc7e94820a85e62Evan Cheng 81794214703d97d8d9dfca88174ffc7e94820a85e62Evan Cheng OS << "#endif // GET_SUBTARGETINFO_HEADER\n\n"; 81894214703d97d8d9dfca88174ffc7e94820a85e62Evan Cheng 81994214703d97d8d9dfca88174ffc7e94820a85e62Evan Cheng OS << "\n#ifdef GET_SUBTARGETINFO_CTOR\n"; 82094214703d97d8d9dfca88174ffc7e94820a85e62Evan Cheng OS << "#undef GET_SUBTARGETINFO_CTOR\n"; 82194214703d97d8d9dfca88174ffc7e94820a85e62Evan Cheng 82294214703d97d8d9dfca88174ffc7e94820a85e62Evan Cheng OS << "namespace llvm {\n"; 8231a2f9886a2a60dbd41216468a240446bbfed3e76Benjamin Kramer OS << "extern const llvm::SubtargetFeatureKV " << Target << "FeatureKV[];\n"; 8241a2f9886a2a60dbd41216468a240446bbfed3e76Benjamin Kramer OS << "extern const llvm::SubtargetFeatureKV " << Target << "SubTypeKV[];\n"; 825c60f9b752381baa6c4b80c0739034660f1748c84Evan Cheng if (HasItineraries) { 8261a2f9886a2a60dbd41216468a240446bbfed3e76Benjamin Kramer OS << "extern const llvm::SubtargetInfoKV " << Target << "ProcItinKV[];\n"; 8271a2f9886a2a60dbd41216468a240446bbfed3e76Benjamin Kramer OS << "extern const llvm::InstrStage " << Target << "Stages[];\n"; 8281a2f9886a2a60dbd41216468a240446bbfed3e76Benjamin Kramer OS << "extern const unsigned " << Target << "OperandCycles[];\n"; 829a11a6287a504d1d7503e744d14314df1e696f506Andrew Trick OS << "extern const unsigned " << Target << "ForwardingPaths[];\n"; 830c60f9b752381baa6c4b80c0739034660f1748c84Evan Cheng } 831c60f9b752381baa6c4b80c0739034660f1748c84Evan Cheng 8320ddff1b5359433faf2eb1c4ff5320ddcbd42f52fEvan Cheng OS << ClassName << "::" << ClassName << "(StringRef TT, StringRef CPU, " 8330ddff1b5359433faf2eb1c4ff5320ddcbd42f52fEvan Cheng << "StringRef FS)\n" 8345b1b4489cf3a0f56f8be0673fc5cc380a32d277bEvan Cheng << " : TargetSubtargetInfo() {\n" 83559ee62d2418df8db499eca1ae17f5900dc2dcbbaEvan Cheng << " InitMCSubtargetInfo(TT, CPU, FS, "; 83694214703d97d8d9dfca88174ffc7e94820a85e62Evan Cheng if (NumFeatures) 83794214703d97d8d9dfca88174ffc7e94820a85e62Evan Cheng OS << Target << "FeatureKV, "; 83894214703d97d8d9dfca88174ffc7e94820a85e62Evan Cheng else 83994214703d97d8d9dfca88174ffc7e94820a85e62Evan Cheng OS << "0, "; 84094214703d97d8d9dfca88174ffc7e94820a85e62Evan Cheng if (NumProcs) 84194214703d97d8d9dfca88174ffc7e94820a85e62Evan Cheng OS << Target << "SubTypeKV, "; 84294214703d97d8d9dfca88174ffc7e94820a85e62Evan Cheng else 84394214703d97d8d9dfca88174ffc7e94820a85e62Evan Cheng OS << "0, "; 84494214703d97d8d9dfca88174ffc7e94820a85e62Evan Cheng if (HasItineraries) { 84594214703d97d8d9dfca88174ffc7e94820a85e62Evan Cheng OS << Target << "ProcItinKV, " 84694214703d97d8d9dfca88174ffc7e94820a85e62Evan Cheng << Target << "Stages, " 84794214703d97d8d9dfca88174ffc7e94820a85e62Evan Cheng << Target << "OperandCycles, " 848a11a6287a504d1d7503e744d14314df1e696f506Andrew Trick << Target << "ForwardingPaths, "; 84994214703d97d8d9dfca88174ffc7e94820a85e62Evan Cheng } else 85094214703d97d8d9dfca88174ffc7e94820a85e62Evan Cheng OS << "0, 0, 0, 0, "; 85194214703d97d8d9dfca88174ffc7e94820a85e62Evan Cheng OS << NumFeatures << ", " << NumProcs << ");\n}\n\n"; 85294214703d97d8d9dfca88174ffc7e94820a85e62Evan Cheng OS << "} // End llvm namespace \n"; 85394214703d97d8d9dfca88174ffc7e94820a85e62Evan Cheng 85494214703d97d8d9dfca88174ffc7e94820a85e62Evan Cheng OS << "#endif // GET_SUBTARGETINFO_CTOR\n\n"; 855b3b1d5f097a4fbcf134259b743ccbd93d187c6cdJim Laskey} 8566f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen 8576f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesennamespace llvm { 8586f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen 8596f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesenvoid EmitSubtarget(RecordKeeper &RK, raw_ostream &OS) { 8606f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen SubtargetEmitter(RK).run(OS); 8616f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen} 8626f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen 8636f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen} // End llvm namespace 864