SubtargetEmitter.cpp revision f0fd3afeffcb41202147f755bf770061f189a42b
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 "SubtargetEmitter.h" 154bb9cbb73075c350eadaf51d2dab8403764c9a60Jim Laskey#include "CodeGenTarget.h" 164bb9cbb73075c350eadaf51d2dab8403764c9a60Jim Laskey#include "Record.h" 174bb9cbb73075c350eadaf51d2dab8403764c9a60Jim Laskey#include "llvm/ADT/StringExtras.h" 184bb9cbb73075c350eadaf51d2dab8403764c9a60Jim Laskey#include "llvm/Support/Debug.h" 199489c04efc47a68af65e226e50f03d488094ffceJeff Cohen#include <algorithm> 204bb9cbb73075c350eadaf51d2dab8403764c9a60Jim Laskeyusing namespace llvm; 214bb9cbb73075c350eadaf51d2dab8403764c9a60Jim Laskey 227dc02047fbb4b014e914458f54ea539c8ae58316Jim Laskey// 23581a8f79bc1ac3cbe5d621f0b4a0252ab2890bc1Jim Laskey// Enumeration - Emit the specified class as an enumeration. 24b3b1d5f097a4fbcf134259b743ccbd93d187c6cdJim Laskey// 251a55180238dbcf11113f610aea010447e51f595bDaniel Dunbarvoid SubtargetEmitter::Enumeration(raw_ostream &OS, 26581a8f79bc1ac3cbe5d621f0b4a0252ab2890bc1Jim Laskey const char *ClassName, 27581a8f79bc1ac3cbe5d621f0b4a0252ab2890bc1Jim Laskey bool isBits) { 28908ae27a9073e2f105f8a0a4dd092d7fea8472a4Jim Laskey // Get all records of class and sort 29f7bcde085440d1fd90eba8980ed9c512bc58824dJim Laskey std::vector<Record*> DefList = Records.getAllDerivedDefinitions(ClassName); 3042d24c71df88178eacf244a38b6c48847ee0d39bDuraid Madina std::sort(DefList.begin(), DefList.end(), LessRecord()); 314bb9cbb73075c350eadaf51d2dab8403764c9a60Jim Laskey 32908ae27a9073e2f105f8a0a4dd092d7fea8472a4Jim Laskey // Open enumeration 33b3b1d5f097a4fbcf134259b743ccbd93d187c6cdJim Laskey OS << "enum {\n"; 344bb9cbb73075c350eadaf51d2dab8403764c9a60Jim Laskey 35908ae27a9073e2f105f8a0a4dd092d7fea8472a4Jim Laskey // For each record 36f7bcde085440d1fd90eba8980ed9c512bc58824dJim Laskey for (unsigned i = 0, N = DefList.size(); i < N;) { 37f7bcde085440d1fd90eba8980ed9c512bc58824dJim Laskey // Next record 38f7bcde085440d1fd90eba8980ed9c512bc58824dJim Laskey Record *Def = DefList[i]; 39f7bcde085440d1fd90eba8980ed9c512bc58824dJim Laskey 40908ae27a9073e2f105f8a0a4dd092d7fea8472a4Jim Laskey // Get and emit name 414222d806faae71ecc794cfdaa873817873c2f3d8Bill Wendling OS << " " << Def->getName(); 42908ae27a9073e2f105f8a0a4dd092d7fea8472a4Jim Laskey 43908ae27a9073e2f105f8a0a4dd092d7fea8472a4Jim Laskey // If bit flags then emit expression (1 << i) 44f7bcde085440d1fd90eba8980ed9c512bc58824dJim Laskey if (isBits) OS << " = " << " 1 << " << i; 45908ae27a9073e2f105f8a0a4dd092d7fea8472a4Jim Laskey 4610b1dd99f342d2d7af51dd43f3840f3bf40b0b87Jim Laskey // Depending on 'if more in the list' emit comma 47f7bcde085440d1fd90eba8980ed9c512bc58824dJim Laskey if (++i < N) OS << ","; 48f7bcde085440d1fd90eba8980ed9c512bc58824dJim Laskey 49f7bcde085440d1fd90eba8980ed9c512bc58824dJim Laskey OS << "\n"; 504bb9cbb73075c350eadaf51d2dab8403764c9a60Jim Laskey } 514bb9cbb73075c350eadaf51d2dab8403764c9a60Jim Laskey 52908ae27a9073e2f105f8a0a4dd092d7fea8472a4Jim Laskey // Close enumeration 53b3b1d5f097a4fbcf134259b743ccbd93d187c6cdJim Laskey OS << "};\n"; 54b3b1d5f097a4fbcf134259b743ccbd93d187c6cdJim Laskey} 55b3b1d5f097a4fbcf134259b743ccbd93d187c6cdJim Laskey 56b3b1d5f097a4fbcf134259b743ccbd93d187c6cdJim Laskey// 574222d806faae71ecc794cfdaa873817873c2f3d8Bill Wendling// FeatureKeyValues - Emit data of all the subtarget features. Used by the 584222d806faae71ecc794cfdaa873817873c2f3d8Bill Wendling// command line. 59b3b1d5f097a4fbcf134259b743ccbd93d187c6cdJim Laskey// 601a55180238dbcf11113f610aea010447e51f595bDaniel Dunbarvoid SubtargetEmitter::FeatureKeyValues(raw_ostream &OS) { 61908ae27a9073e2f105f8a0a4dd092d7fea8472a4Jim Laskey // Gather and sort all the features 62f7bcde085440d1fd90eba8980ed9c512bc58824dJim Laskey std::vector<Record*> FeatureList = 63f7bcde085440d1fd90eba8980ed9c512bc58824dJim Laskey Records.getAllDerivedDefinitions("SubtargetFeature"); 647c9a7728d9dd248ebee8f2dd969d303711d487a9Jim Grosbach std::sort(FeatureList.begin(), FeatureList.end(), LessRecordFieldName()); 65b3b1d5f097a4fbcf134259b743ccbd93d187c6cdJim Laskey 66908ae27a9073e2f105f8a0a4dd092d7fea8472a4Jim Laskey // Begin feature table 67581a8f79bc1ac3cbe5d621f0b4a0252ab2890bc1Jim Laskey OS << "// Sorted (by key) array of values for CPU features.\n" 68cfbb2f074da2842e42956d3b4c21e91b37f36f06Dan Gohman << "static const llvm::SubtargetFeatureKV FeatureKV[] = {\n"; 69908ae27a9073e2f105f8a0a4dd092d7fea8472a4Jim Laskey 70908ae27a9073e2f105f8a0a4dd092d7fea8472a4Jim Laskey // For each feature 71dbe4006cf3cf0802dc318a5f2070c04c326e170bJim Laskey for (unsigned i = 0, N = FeatureList.size(); i < N; ++i) { 72f7bcde085440d1fd90eba8980ed9c512bc58824dJim Laskey // Next feature 73f7bcde085440d1fd90eba8980ed9c512bc58824dJim Laskey Record *Feature = FeatureList[i]; 74f7bcde085440d1fd90eba8980ed9c512bc58824dJim Laskey 754222d806faae71ecc794cfdaa873817873c2f3d8Bill Wendling const std::string &Name = Feature->getName(); 764222d806faae71ecc794cfdaa873817873c2f3d8Bill Wendling const std::string &CommandLineName = Feature->getValueAsString("Name"); 774222d806faae71ecc794cfdaa873817873c2f3d8Bill Wendling const std::string &Desc = Feature->getValueAsString("Desc"); 78908ae27a9073e2f105f8a0a4dd092d7fea8472a4Jim Laskey 79dbe4006cf3cf0802dc318a5f2070c04c326e170bJim Laskey if (CommandLineName.empty()) continue; 80dbe4006cf3cf0802dc318a5f2070c04c326e170bJim Laskey 81da4231f134989af7dc6bd3408821ba573def27b2Jim Grosbach // Emit as { "feature", "description", featureEnum, i1 | i2 | ... | in } 82b3b1d5f097a4fbcf134259b743ccbd93d187c6cdJim Laskey OS << " { " 83f7bcde085440d1fd90eba8980ed9c512bc58824dJim Laskey << "\"" << CommandLineName << "\", " 84b3b1d5f097a4fbcf134259b743ccbd93d187c6cdJim Laskey << "\"" << Desc << "\", " 854222d806faae71ecc794cfdaa873817873c2f3d8Bill Wendling << Name << ", "; 864222d806faae71ecc794cfdaa873817873c2f3d8Bill Wendling 874222d806faae71ecc794cfdaa873817873c2f3d8Bill Wendling const std::vector<Record*> &ImpliesList = 884222d806faae71ecc794cfdaa873817873c2f3d8Bill Wendling Feature->getValueAsListOfDefs("Implies"); 894222d806faae71ecc794cfdaa873817873c2f3d8Bill Wendling 904222d806faae71ecc794cfdaa873817873c2f3d8Bill Wendling if (ImpliesList.empty()) { 914222d806faae71ecc794cfdaa873817873c2f3d8Bill Wendling OS << "0"; 924222d806faae71ecc794cfdaa873817873c2f3d8Bill Wendling } else { 934222d806faae71ecc794cfdaa873817873c2f3d8Bill Wendling for (unsigned j = 0, M = ImpliesList.size(); j < M;) { 944222d806faae71ecc794cfdaa873817873c2f3d8Bill Wendling OS << ImpliesList[j]->getName(); 954222d806faae71ecc794cfdaa873817873c2f3d8Bill Wendling if (++j < M) OS << " | "; 964222d806faae71ecc794cfdaa873817873c2f3d8Bill Wendling } 974222d806faae71ecc794cfdaa873817873c2f3d8Bill Wendling } 984222d806faae71ecc794cfdaa873817873c2f3d8Bill Wendling 994222d806faae71ecc794cfdaa873817873c2f3d8Bill Wendling OS << " }"; 100f7bcde085440d1fd90eba8980ed9c512bc58824dJim Laskey 10110b1dd99f342d2d7af51dd43f3840f3bf40b0b87Jim Laskey // Depending on 'if more in the list' emit comma 102dbe4006cf3cf0802dc318a5f2070c04c326e170bJim Laskey if ((i + 1) < N) OS << ","; 103f7bcde085440d1fd90eba8980ed9c512bc58824dJim Laskey 104f7bcde085440d1fd90eba8980ed9c512bc58824dJim Laskey OS << "\n"; 105b3b1d5f097a4fbcf134259b743ccbd93d187c6cdJim Laskey } 106908ae27a9073e2f105f8a0a4dd092d7fea8472a4Jim Laskey 107908ae27a9073e2f105f8a0a4dd092d7fea8472a4Jim Laskey // End feature table 108b3b1d5f097a4fbcf134259b743ccbd93d187c6cdJim Laskey OS << "};\n"; 109b3b1d5f097a4fbcf134259b743ccbd93d187c6cdJim Laskey 110908ae27a9073e2f105f8a0a4dd092d7fea8472a4Jim Laskey // Emit size of table 111b3b1d5f097a4fbcf134259b743ccbd93d187c6cdJim Laskey OS<<"\nenum {\n"; 112b3b1d5f097a4fbcf134259b743ccbd93d187c6cdJim Laskey OS<<" FeatureKVSize = sizeof(FeatureKV)/sizeof(llvm::SubtargetFeatureKV)\n"; 113b3b1d5f097a4fbcf134259b743ccbd93d187c6cdJim Laskey OS<<"};\n"; 114b3b1d5f097a4fbcf134259b743ccbd93d187c6cdJim Laskey} 115b3b1d5f097a4fbcf134259b743ccbd93d187c6cdJim Laskey 116b3b1d5f097a4fbcf134259b743ccbd93d187c6cdJim Laskey// 117b3b1d5f097a4fbcf134259b743ccbd93d187c6cdJim Laskey// CPUKeyValues - Emit data of all the subtarget processors. Used by command 118b3b1d5f097a4fbcf134259b743ccbd93d187c6cdJim Laskey// line. 119b3b1d5f097a4fbcf134259b743ccbd93d187c6cdJim Laskey// 1201a55180238dbcf11113f610aea010447e51f595bDaniel Dunbarvoid SubtargetEmitter::CPUKeyValues(raw_ostream &OS) { 121908ae27a9073e2f105f8a0a4dd092d7fea8472a4Jim Laskey // Gather and sort processor information 122f7bcde085440d1fd90eba8980ed9c512bc58824dJim Laskey std::vector<Record*> ProcessorList = 123f7bcde085440d1fd90eba8980ed9c512bc58824dJim Laskey Records.getAllDerivedDefinitions("Processor"); 12442d24c71df88178eacf244a38b6c48847ee0d39bDuraid Madina std::sort(ProcessorList.begin(), ProcessorList.end(), LessRecordFieldName()); 125b3b1d5f097a4fbcf134259b743ccbd93d187c6cdJim Laskey 126908ae27a9073e2f105f8a0a4dd092d7fea8472a4Jim Laskey // Begin processor table 127581a8f79bc1ac3cbe5d621f0b4a0252ab2890bc1Jim Laskey OS << "// Sorted (by key) array of values for CPU subtype.\n" 128b3b1d5f097a4fbcf134259b743ccbd93d187c6cdJim Laskey << "static const llvm::SubtargetFeatureKV SubTypeKV[] = {\n"; 129908ae27a9073e2f105f8a0a4dd092d7fea8472a4Jim Laskey 130908ae27a9073e2f105f8a0a4dd092d7fea8472a4Jim Laskey // For each processor 131f7bcde085440d1fd90eba8980ed9c512bc58824dJim Laskey for (unsigned i = 0, N = ProcessorList.size(); i < N;) { 132f7bcde085440d1fd90eba8980ed9c512bc58824dJim Laskey // Next processor 133f7bcde085440d1fd90eba8980ed9c512bc58824dJim Laskey Record *Processor = ProcessorList[i]; 134f7bcde085440d1fd90eba8980ed9c512bc58824dJim Laskey 1354222d806faae71ecc794cfdaa873817873c2f3d8Bill Wendling const std::string &Name = Processor->getValueAsString("Name"); 1364222d806faae71ecc794cfdaa873817873c2f3d8Bill Wendling const std::vector<Record*> &FeatureList = 137b0e103d46bf8799ac5523157a6ed4a78d1751a89Chris Lattner Processor->getValueAsListOfDefs("Features"); 1380d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey 139908ae27a9073e2f105f8a0a4dd092d7fea8472a4Jim Laskey // Emit as { "cpu", "description", f1 | f2 | ... fn }, 140b3b1d5f097a4fbcf134259b743ccbd93d187c6cdJim Laskey OS << " { " 141b3b1d5f097a4fbcf134259b743ccbd93d187c6cdJim Laskey << "\"" << Name << "\", " 142b3b1d5f097a4fbcf134259b743ccbd93d187c6cdJim Laskey << "\"Select the " << Name << " processor\", "; 143b3b1d5f097a4fbcf134259b743ccbd93d187c6cdJim Laskey 144f7bcde085440d1fd90eba8980ed9c512bc58824dJim Laskey if (FeatureList.empty()) { 145b3b1d5f097a4fbcf134259b743ccbd93d187c6cdJim Laskey OS << "0"; 146b3b1d5f097a4fbcf134259b743ccbd93d187c6cdJim Laskey } else { 147f7bcde085440d1fd90eba8980ed9c512bc58824dJim Laskey for (unsigned j = 0, M = FeatureList.size(); j < M;) { 1484222d806faae71ecc794cfdaa873817873c2f3d8Bill Wendling OS << FeatureList[j]->getName(); 149f7bcde085440d1fd90eba8980ed9c512bc58824dJim Laskey if (++j < M) OS << " | "; 1504bb9cbb73075c350eadaf51d2dab8403764c9a60Jim Laskey } 1514bb9cbb73075c350eadaf51d2dab8403764c9a60Jim Laskey } 152b3b1d5f097a4fbcf134259b743ccbd93d187c6cdJim Laskey 1534222d806faae71ecc794cfdaa873817873c2f3d8Bill Wendling // The "0" is for the "implies" section of this data structure. 1544222d806faae71ecc794cfdaa873817873c2f3d8Bill Wendling OS << ", 0 }"; 155f7bcde085440d1fd90eba8980ed9c512bc58824dJim Laskey 15610b1dd99f342d2d7af51dd43f3840f3bf40b0b87Jim Laskey // Depending on 'if more in the list' emit comma 157f7bcde085440d1fd90eba8980ed9c512bc58824dJim Laskey if (++i < N) OS << ","; 158f7bcde085440d1fd90eba8980ed9c512bc58824dJim Laskey 159f7bcde085440d1fd90eba8980ed9c512bc58824dJim Laskey OS << "\n"; 1604bb9cbb73075c350eadaf51d2dab8403764c9a60Jim Laskey } 161908ae27a9073e2f105f8a0a4dd092d7fea8472a4Jim Laskey 162908ae27a9073e2f105f8a0a4dd092d7fea8472a4Jim Laskey // End processor table 163b3b1d5f097a4fbcf134259b743ccbd93d187c6cdJim Laskey OS << "};\n"; 164b3b1d5f097a4fbcf134259b743ccbd93d187c6cdJim Laskey 165908ae27a9073e2f105f8a0a4dd092d7fea8472a4Jim Laskey // Emit size of table 166d4d079785187ce923edc245aee527e4768b1d180Chris Lattner OS<<"\nenum {\n"; 167d4d079785187ce923edc245aee527e4768b1d180Chris Lattner OS<<" SubTypeKVSize = sizeof(SubTypeKV)/sizeof(llvm::SubtargetFeatureKV)\n"; 168d4d079785187ce923edc245aee527e4768b1d180Chris Lattner OS<<"};\n"; 1694bb9cbb73075c350eadaf51d2dab8403764c9a60Jim Laskey} 170b3b1d5f097a4fbcf134259b743ccbd93d187c6cdJim Laskey 171581a8f79bc1ac3cbe5d621f0b4a0252ab2890bc1Jim Laskey// 1720d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey// CollectAllItinClasses - Gathers and enumerates all the itinerary classes. 173908ae27a9073e2f105f8a0a4dd092d7fea8472a4Jim Laskey// Returns itinerary class count. 1740d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey// 1751a55180238dbcf11113f610aea010447e51f595bDaniel Dunbarunsigned SubtargetEmitter::CollectAllItinClasses(raw_ostream &OS, 1766cee630070b1a7183ed56a8404e812629f5ca538Jim Laskey std::map<std::string, unsigned> &ItinClassesMap) { 177908ae27a9073e2f105f8a0a4dd092d7fea8472a4Jim Laskey // Gather and sort all itinerary classes 178f7bcde085440d1fd90eba8980ed9c512bc58824dJim Laskey std::vector<Record*> ItinClassList = 179f7bcde085440d1fd90eba8980ed9c512bc58824dJim Laskey Records.getAllDerivedDefinitions("InstrItinClass"); 18042d24c71df88178eacf244a38b6c48847ee0d39bDuraid Madina std::sort(ItinClassList.begin(), ItinClassList.end(), LessRecord()); 181f7bcde085440d1fd90eba8980ed9c512bc58824dJim Laskey 182f7bcde085440d1fd90eba8980ed9c512bc58824dJim Laskey // For each itinerary class 183f7bcde085440d1fd90eba8980ed9c512bc58824dJim Laskey unsigned N = ItinClassList.size(); 184f7bcde085440d1fd90eba8980ed9c512bc58824dJim Laskey for (unsigned i = 0; i < N; i++) { 185f7bcde085440d1fd90eba8980ed9c512bc58824dJim Laskey // Next itinerary class 1864222d806faae71ecc794cfdaa873817873c2f3d8Bill Wendling const Record *ItinClass = ItinClassList[i]; 187908ae27a9073e2f105f8a0a4dd092d7fea8472a4Jim Laskey // Get name of itinerary class 188908ae27a9073e2f105f8a0a4dd092d7fea8472a4Jim Laskey // Assign itinerary class a unique number 1894222d806faae71ecc794cfdaa873817873c2f3d8Bill Wendling ItinClassesMap[ItinClass->getName()] = i; 1900d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey } 1910d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey 1926cee630070b1a7183ed56a8404e812629f5ca538Jim Laskey // Emit size of table 1936cee630070b1a7183ed56a8404e812629f5ca538Jim Laskey OS<<"\nenum {\n"; 1946cee630070b1a7183ed56a8404e812629f5ca538Jim Laskey OS<<" ItinClassesSize = " << N << "\n"; 1956cee630070b1a7183ed56a8404e812629f5ca538Jim Laskey OS<<"};\n"; 1966cee630070b1a7183ed56a8404e812629f5ca538Jim Laskey 197908ae27a9073e2f105f8a0a4dd092d7fea8472a4Jim Laskey // Return itinerary class count 198f7bcde085440d1fd90eba8980ed9c512bc58824dJim Laskey return N; 1990d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey} 2000d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey 2010d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey// 202fac8541dd40e01aa2b52962516f9ae67c99720ccDavid Goodwin// FormItineraryStageString - Compose a string containing the stage 203fac8541dd40e01aa2b52962516f9ae67c99720ccDavid Goodwin// data initialization for the specified itinerary. N is the number 204fac8541dd40e01aa2b52962516f9ae67c99720ccDavid Goodwin// of stages. 2050d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey// 206fac8541dd40e01aa2b52962516f9ae67c99720ccDavid Goodwinvoid SubtargetEmitter::FormItineraryStageString(Record *ItinData, 207fac8541dd40e01aa2b52962516f9ae67c99720ccDavid Goodwin std::string &ItinString, 208fac8541dd40e01aa2b52962516f9ae67c99720ccDavid Goodwin unsigned &NStages) { 209f7bcde085440d1fd90eba8980ed9c512bc58824dJim Laskey // Get states list 2104222d806faae71ecc794cfdaa873817873c2f3d8Bill Wendling const std::vector<Record*> &StageList = 2114222d806faae71ecc794cfdaa873817873c2f3d8Bill Wendling ItinData->getValueAsListOfDefs("Stages"); 212908ae27a9073e2f105f8a0a4dd092d7fea8472a4Jim Laskey 213908ae27a9073e2f105f8a0a4dd092d7fea8472a4Jim Laskey // For each stage 214f7bcde085440d1fd90eba8980ed9c512bc58824dJim Laskey unsigned N = NStages = StageList.size(); 2158dadf6b13a7cdd5b5b30c3b7af310c9756e4c68eChristopher Lamb for (unsigned i = 0; i < N;) { 216f7bcde085440d1fd90eba8980ed9c512bc58824dJim Laskey // Next stage 2174222d806faae71ecc794cfdaa873817873c2f3d8Bill Wendling const Record *Stage = StageList[i]; 218f7bcde085440d1fd90eba8980ed9c512bc58824dJim Laskey 2191a8f36e3ce5b9c230781b66600c81536128abfb5David Goodwin // Form string as ,{ cycles, u1 | u2 | ... | un, timeinc } 2200d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey int Cycles = Stage->getValueAsInt("Cycles"); 2217f39c14f52262a154285df9180f5edcdabe2d7dfJim Laskey ItinString += " { " + itostr(Cycles) + ", "; 2220d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey 223f7bcde085440d1fd90eba8980ed9c512bc58824dJim Laskey // Get unit list 2244222d806faae71ecc794cfdaa873817873c2f3d8Bill Wendling const std::vector<Record*> &UnitList = Stage->getValueAsListOfDefs("Units"); 225f7bcde085440d1fd90eba8980ed9c512bc58824dJim Laskey 226908ae27a9073e2f105f8a0a4dd092d7fea8472a4Jim Laskey // For each unit 227f7bcde085440d1fd90eba8980ed9c512bc58824dJim Laskey for (unsigned j = 0, M = UnitList.size(); j < M;) { 228f7bcde085440d1fd90eba8980ed9c512bc58824dJim Laskey // Add name and bitwise or 2294222d806faae71ecc794cfdaa873817873c2f3d8Bill Wendling ItinString += UnitList[j]->getName(); 230f7bcde085440d1fd90eba8980ed9c512bc58824dJim Laskey if (++j < M) ItinString += " | "; 2310d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey } 232908ae27a9073e2f105f8a0a4dd092d7fea8472a4Jim Laskey 2331a8f36e3ce5b9c230781b66600c81536128abfb5David Goodwin int TimeInc = Stage->getValueAsInt("TimeInc"); 2341a8f36e3ce5b9c230781b66600c81536128abfb5David Goodwin ItinString += ", " + itostr(TimeInc); 2351a8f36e3ce5b9c230781b66600c81536128abfb5David Goodwin 236908ae27a9073e2f105f8a0a4dd092d7fea8472a4Jim Laskey // Close off stage 237908ae27a9073e2f105f8a0a4dd092d7fea8472a4Jim Laskey ItinString += " }"; 2388dadf6b13a7cdd5b5b30c3b7af310c9756e4c68eChristopher Lamb if (++i < N) ItinString += ", "; 2390d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey } 2400d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey} 2410d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey 2420d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey// 243fac8541dd40e01aa2b52962516f9ae67c99720ccDavid Goodwin// FormItineraryOperandCycleString - Compose a string containing the 244fac8541dd40e01aa2b52962516f9ae67c99720ccDavid Goodwin// operand cycle initialization for the specified itinerary. N is the 245fac8541dd40e01aa2b52962516f9ae67c99720ccDavid Goodwin// number of operands that has cycles specified. 2460d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey// 247fac8541dd40e01aa2b52962516f9ae67c99720ccDavid Goodwinvoid SubtargetEmitter::FormItineraryOperandCycleString(Record *ItinData, 248fac8541dd40e01aa2b52962516f9ae67c99720ccDavid Goodwin std::string &ItinString, unsigned &NOperandCycles) { 249fac8541dd40e01aa2b52962516f9ae67c99720ccDavid Goodwin // Get operand cycle list 250fac8541dd40e01aa2b52962516f9ae67c99720ccDavid Goodwin const std::vector<int64_t> &OperandCycleList = 251fac8541dd40e01aa2b52962516f9ae67c99720ccDavid Goodwin ItinData->getValueAsListOfInts("OperandCycles"); 252fac8541dd40e01aa2b52962516f9ae67c99720ccDavid Goodwin 253fac8541dd40e01aa2b52962516f9ae67c99720ccDavid Goodwin // For each operand cycle 254fac8541dd40e01aa2b52962516f9ae67c99720ccDavid Goodwin unsigned N = NOperandCycles = OperandCycleList.size(); 255fac8541dd40e01aa2b52962516f9ae67c99720ccDavid Goodwin for (unsigned i = 0; i < N;) { 256fac8541dd40e01aa2b52962516f9ae67c99720ccDavid Goodwin // Next operand cycle 257fac8541dd40e01aa2b52962516f9ae67c99720ccDavid Goodwin const int OCycle = OperandCycleList[i]; 258fac8541dd40e01aa2b52962516f9ae67c99720ccDavid Goodwin 259fac8541dd40e01aa2b52962516f9ae67c99720ccDavid Goodwin ItinString += " " + itostr(OCycle); 260fac8541dd40e01aa2b52962516f9ae67c99720ccDavid Goodwin if (++i < N) ItinString += ", "; 261fac8541dd40e01aa2b52962516f9ae67c99720ccDavid Goodwin } 262fac8541dd40e01aa2b52962516f9ae67c99720ccDavid Goodwin} 263fac8541dd40e01aa2b52962516f9ae67c99720ccDavid Goodwin 264fac8541dd40e01aa2b52962516f9ae67c99720ccDavid Goodwin// 265fac8541dd40e01aa2b52962516f9ae67c99720ccDavid Goodwin// EmitStageAndOperandCycleData - Generate unique itinerary stages and 266fac8541dd40e01aa2b52962516f9ae67c99720ccDavid Goodwin// operand cycle tables. Record itineraries for processors. 267fac8541dd40e01aa2b52962516f9ae67c99720ccDavid Goodwin// 268fac8541dd40e01aa2b52962516f9ae67c99720ccDavid Goodwinvoid SubtargetEmitter::EmitStageAndOperandCycleData(raw_ostream &OS, 269f7bcde085440d1fd90eba8980ed9c512bc58824dJim Laskey unsigned NItinClasses, 270f7bcde085440d1fd90eba8980ed9c512bc58824dJim Laskey std::map<std::string, unsigned> &ItinClassesMap, 271f7bcde085440d1fd90eba8980ed9c512bc58824dJim Laskey std::vector<std::vector<InstrItinerary> > &ProcList) { 272908ae27a9073e2f105f8a0a4dd092d7fea8472a4Jim Laskey // Gather processor iteraries 273f7bcde085440d1fd90eba8980ed9c512bc58824dJim Laskey std::vector<Record*> ProcItinList = 274f7bcde085440d1fd90eba8980ed9c512bc58824dJim Laskey Records.getAllDerivedDefinitions("ProcessorItineraries"); 275908ae27a9073e2f105f8a0a4dd092d7fea8472a4Jim Laskey 276908ae27a9073e2f105f8a0a4dd092d7fea8472a4Jim Laskey // If just no itinerary then don't bother 277f7bcde085440d1fd90eba8980ed9c512bc58824dJim Laskey if (ProcItinList.size() < 2) return; 278908ae27a9073e2f105f8a0a4dd092d7fea8472a4Jim Laskey 279908ae27a9073e2f105f8a0a4dd092d7fea8472a4Jim Laskey // Begin stages table 280fac8541dd40e01aa2b52962516f9ae67c99720ccDavid Goodwin std::string StageTable = "static const llvm::InstrStage Stages[] = {\n"; 281fac8541dd40e01aa2b52962516f9ae67c99720ccDavid Goodwin StageTable += " { 0, 0, 0 }, // No itinerary\n"; 2820d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey 283fac8541dd40e01aa2b52962516f9ae67c99720ccDavid Goodwin // Begin operand cycle table 284fac8541dd40e01aa2b52962516f9ae67c99720ccDavid Goodwin std::string OperandCycleTable = "static const unsigned OperandCycles[] = {\n"; 285fac8541dd40e01aa2b52962516f9ae67c99720ccDavid Goodwin OperandCycleTable += " 0, // No itinerary\n"; 286fac8541dd40e01aa2b52962516f9ae67c99720ccDavid Goodwin 287fac8541dd40e01aa2b52962516f9ae67c99720ccDavid Goodwin unsigned StageCount = 1, OperandCycleCount = 1; 288fac8541dd40e01aa2b52962516f9ae67c99720ccDavid Goodwin unsigned ItinStageEnum = 1, ItinOperandCycleEnum = 1; 289fac8541dd40e01aa2b52962516f9ae67c99720ccDavid Goodwin std::map<std::string, unsigned> ItinStageMap, ItinOperandCycleMap; 290f7bcde085440d1fd90eba8980ed9c512bc58824dJim Laskey for (unsigned i = 0, N = ProcItinList.size(); i < N; i++) { 291f7bcde085440d1fd90eba8980ed9c512bc58824dJim Laskey // Next record 292f7bcde085440d1fd90eba8980ed9c512bc58824dJim Laskey Record *Proc = ProcItinList[i]; 293f7bcde085440d1fd90eba8980ed9c512bc58824dJim Laskey 294908ae27a9073e2f105f8a0a4dd092d7fea8472a4Jim Laskey // Get processor itinerary name 2954222d806faae71ecc794cfdaa873817873c2f3d8Bill Wendling const std::string &Name = Proc->getName(); 296908ae27a9073e2f105f8a0a4dd092d7fea8472a4Jim Laskey 297908ae27a9073e2f105f8a0a4dd092d7fea8472a4Jim Laskey // Skip default 2980d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey if (Name == "NoItineraries") continue; 2990d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey 300908ae27a9073e2f105f8a0a4dd092d7fea8472a4Jim Laskey // Create and expand processor itinerary to cover all itinerary classes 301f7bcde085440d1fd90eba8980ed9c512bc58824dJim Laskey std::vector<InstrItinerary> ItinList; 302f7bcde085440d1fd90eba8980ed9c512bc58824dJim Laskey ItinList.resize(NItinClasses); 303f7bcde085440d1fd90eba8980ed9c512bc58824dJim Laskey 304f7bcde085440d1fd90eba8980ed9c512bc58824dJim Laskey // Get itinerary data list 305b0e103d46bf8799ac5523157a6ed4a78d1751a89Chris Lattner std::vector<Record*> ItinDataList = Proc->getValueAsListOfDefs("IID"); 3060d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey 307f7bcde085440d1fd90eba8980ed9c512bc58824dJim Laskey // For each itinerary data 308f7bcde085440d1fd90eba8980ed9c512bc58824dJim Laskey for (unsigned j = 0, M = ItinDataList.size(); j < M; j++) { 309f7bcde085440d1fd90eba8980ed9c512bc58824dJim Laskey // Next itinerary data 310f7bcde085440d1fd90eba8980ed9c512bc58824dJim Laskey Record *ItinData = ItinDataList[j]; 311f7bcde085440d1fd90eba8980ed9c512bc58824dJim Laskey 312908ae27a9073e2f105f8a0a4dd092d7fea8472a4Jim Laskey // Get string and stage count 313fac8541dd40e01aa2b52962516f9ae67c99720ccDavid Goodwin std::string ItinStageString; 314f7bcde085440d1fd90eba8980ed9c512bc58824dJim Laskey unsigned NStages; 315fac8541dd40e01aa2b52962516f9ae67c99720ccDavid Goodwin FormItineraryStageString(ItinData, ItinStageString, NStages); 316fac8541dd40e01aa2b52962516f9ae67c99720ccDavid Goodwin 317fac8541dd40e01aa2b52962516f9ae67c99720ccDavid Goodwin // Get string and operand cycle count 318fac8541dd40e01aa2b52962516f9ae67c99720ccDavid Goodwin std::string ItinOperandCycleString; 319fac8541dd40e01aa2b52962516f9ae67c99720ccDavid Goodwin unsigned NOperandCycles; 320fac8541dd40e01aa2b52962516f9ae67c99720ccDavid Goodwin FormItineraryOperandCycleString(ItinData, ItinOperandCycleString, 321fac8541dd40e01aa2b52962516f9ae67c99720ccDavid Goodwin NOperandCycles); 322fac8541dd40e01aa2b52962516f9ae67c99720ccDavid Goodwin 323fac8541dd40e01aa2b52962516f9ae67c99720ccDavid Goodwin // Check to see if stage already exists and create if it doesn't 324fac8541dd40e01aa2b52962516f9ae67c99720ccDavid Goodwin unsigned FindStage = 0; 325fac8541dd40e01aa2b52962516f9ae67c99720ccDavid Goodwin if (NStages > 0) { 326fac8541dd40e01aa2b52962516f9ae67c99720ccDavid Goodwin FindStage = ItinStageMap[ItinStageString]; 327fac8541dd40e01aa2b52962516f9ae67c99720ccDavid Goodwin if (FindStage == 0) { 328fac8541dd40e01aa2b52962516f9ae67c99720ccDavid Goodwin // Emit as { cycles, u1 | u2 | ... | un, timeinc }, // index 329fac8541dd40e01aa2b52962516f9ae67c99720ccDavid Goodwin StageTable += ItinStageString + ", // " + itostr(ItinStageEnum) + "\n"; 330fac8541dd40e01aa2b52962516f9ae67c99720ccDavid Goodwin // Record Itin class number. 331fac8541dd40e01aa2b52962516f9ae67c99720ccDavid Goodwin ItinStageMap[ItinStageString] = FindStage = StageCount; 332fac8541dd40e01aa2b52962516f9ae67c99720ccDavid Goodwin StageCount += NStages; 333fac8541dd40e01aa2b52962516f9ae67c99720ccDavid Goodwin ItinStageEnum++; 334fac8541dd40e01aa2b52962516f9ae67c99720ccDavid Goodwin } 335fac8541dd40e01aa2b52962516f9ae67c99720ccDavid Goodwin } 3360d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey 337fac8541dd40e01aa2b52962516f9ae67c99720ccDavid Goodwin // Check to see if operand cycle already exists and create if it doesn't 338fac8541dd40e01aa2b52962516f9ae67c99720ccDavid Goodwin unsigned FindOperandCycle = 0; 339fac8541dd40e01aa2b52962516f9ae67c99720ccDavid Goodwin if (NOperandCycles > 0) { 340fac8541dd40e01aa2b52962516f9ae67c99720ccDavid Goodwin FindOperandCycle = ItinOperandCycleMap[ItinOperandCycleString]; 341fac8541dd40e01aa2b52962516f9ae67c99720ccDavid Goodwin if (FindOperandCycle == 0) { 342fac8541dd40e01aa2b52962516f9ae67c99720ccDavid Goodwin // Emit as cycle, // index 343fac8541dd40e01aa2b52962516f9ae67c99720ccDavid Goodwin OperandCycleTable += ItinOperandCycleString + ", // " + 344fac8541dd40e01aa2b52962516f9ae67c99720ccDavid Goodwin itostr(ItinOperandCycleEnum) + "\n"; 345fac8541dd40e01aa2b52962516f9ae67c99720ccDavid Goodwin // Record Itin class number. 346fac8541dd40e01aa2b52962516f9ae67c99720ccDavid Goodwin ItinOperandCycleMap[ItinOperandCycleString] = 347fac8541dd40e01aa2b52962516f9ae67c99720ccDavid Goodwin FindOperandCycle = OperandCycleCount; 348fac8541dd40e01aa2b52962516f9ae67c99720ccDavid Goodwin OperandCycleCount += NOperandCycles; 349fac8541dd40e01aa2b52962516f9ae67c99720ccDavid Goodwin ItinOperandCycleEnum++; 350fac8541dd40e01aa2b52962516f9ae67c99720ccDavid Goodwin } 3510d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey } 3520d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey 353908ae27a9073e2f105f8a0a4dd092d7fea8472a4Jim Laskey // Set up itinerary as location and location + stage count 354fac8541dd40e01aa2b52962516f9ae67c99720ccDavid Goodwin InstrItinerary Intinerary = { FindStage, FindStage + NStages, 355fac8541dd40e01aa2b52962516f9ae67c99720ccDavid Goodwin FindOperandCycle, FindOperandCycle + NOperandCycles}; 3560d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey 357908ae27a9073e2f105f8a0a4dd092d7fea8472a4Jim Laskey // Locate where to inject into processor itinerary table 3584222d806faae71ecc794cfdaa873817873c2f3d8Bill Wendling const std::string &Name = ItinData->getValueAsDef("TheClass")->getName(); 359fac8541dd40e01aa2b52962516f9ae67c99720ccDavid Goodwin unsigned Find = ItinClassesMap[Name]; 360908ae27a9073e2f105f8a0a4dd092d7fea8472a4Jim Laskey 361908ae27a9073e2f105f8a0a4dd092d7fea8472a4Jim Laskey // Inject - empty slots will be 0, 0 362f7bcde085440d1fd90eba8980ed9c512bc58824dJim Laskey ItinList[Find] = Intinerary; 3630d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey } 3640d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey 365908ae27a9073e2f105f8a0a4dd092d7fea8472a4Jim Laskey // Add process itinerary to list 366f7bcde085440d1fd90eba8980ed9c512bc58824dJim Laskey ProcList.push_back(ItinList); 3670d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey } 3680d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey 3697f39c14f52262a154285df9180f5edcdabe2d7dfJim Laskey // Closing stage 370fac8541dd40e01aa2b52962516f9ae67c99720ccDavid Goodwin StageTable += " { 0, 0, 0 } // End itinerary\n"; 371fac8541dd40e01aa2b52962516f9ae67c99720ccDavid Goodwin StageTable += "};\n"; 372fac8541dd40e01aa2b52962516f9ae67c99720ccDavid Goodwin 373fac8541dd40e01aa2b52962516f9ae67c99720ccDavid Goodwin // Closing operand cycles 374fac8541dd40e01aa2b52962516f9ae67c99720ccDavid Goodwin OperandCycleTable += " 0 // End itinerary\n"; 375fac8541dd40e01aa2b52962516f9ae67c99720ccDavid Goodwin OperandCycleTable += "};\n"; 376fac8541dd40e01aa2b52962516f9ae67c99720ccDavid Goodwin 377fac8541dd40e01aa2b52962516f9ae67c99720ccDavid Goodwin // Emit tables. 378fac8541dd40e01aa2b52962516f9ae67c99720ccDavid Goodwin OS << StageTable; 379fac8541dd40e01aa2b52962516f9ae67c99720ccDavid Goodwin OS << OperandCycleTable; 3806cee630070b1a7183ed56a8404e812629f5ca538Jim Laskey 381fac8541dd40e01aa2b52962516f9ae67c99720ccDavid Goodwin // Emit size of tables 3826cee630070b1a7183ed56a8404e812629f5ca538Jim Laskey OS<<"\nenum {\n"; 383fac8541dd40e01aa2b52962516f9ae67c99720ccDavid Goodwin OS<<" StagesSize = sizeof(Stages)/sizeof(llvm::InstrStage),\n"; 384fac8541dd40e01aa2b52962516f9ae67c99720ccDavid Goodwin OS<<" OperandCyclesSize = sizeof(OperandCycles)/sizeof(unsigned)\n"; 3856cee630070b1a7183ed56a8404e812629f5ca538Jim Laskey OS<<"};\n"; 3860d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey} 3870d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey 3880d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey// 38910b1dd99f342d2d7af51dd43f3840f3bf40b0b87Jim Laskey// EmitProcessorData - Generate data for processor itineraries. 3900d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey// 3911a55180238dbcf11113f610aea010447e51f595bDaniel Dunbarvoid SubtargetEmitter::EmitProcessorData(raw_ostream &OS, 392f7bcde085440d1fd90eba8980ed9c512bc58824dJim Laskey std::vector<std::vector<InstrItinerary> > &ProcList) { 393908ae27a9073e2f105f8a0a4dd092d7fea8472a4Jim Laskey // Get an iterator for processor itinerary stages 394f7bcde085440d1fd90eba8980ed9c512bc58824dJim Laskey std::vector<std::vector<InstrItinerary> >::iterator 395f7bcde085440d1fd90eba8980ed9c512bc58824dJim Laskey ProcListIter = ProcList.begin(); 396908ae27a9073e2f105f8a0a4dd092d7fea8472a4Jim Laskey 397908ae27a9073e2f105f8a0a4dd092d7fea8472a4Jim Laskey // For each processor itinerary 398f7bcde085440d1fd90eba8980ed9c512bc58824dJim Laskey std::vector<Record*> Itins = 399f7bcde085440d1fd90eba8980ed9c512bc58824dJim Laskey Records.getAllDerivedDefinitions("ProcessorItineraries"); 400f7bcde085440d1fd90eba8980ed9c512bc58824dJim Laskey for (unsigned i = 0, N = Itins.size(); i < N; i++) { 401f7bcde085440d1fd90eba8980ed9c512bc58824dJim Laskey // Next record 402f7bcde085440d1fd90eba8980ed9c512bc58824dJim Laskey Record *Itin = Itins[i]; 403f7bcde085440d1fd90eba8980ed9c512bc58824dJim Laskey 404908ae27a9073e2f105f8a0a4dd092d7fea8472a4Jim Laskey // Get processor itinerary name 4054222d806faae71ecc794cfdaa873817873c2f3d8Bill Wendling const std::string &Name = Itin->getName(); 406908ae27a9073e2f105f8a0a4dd092d7fea8472a4Jim Laskey 407908ae27a9073e2f105f8a0a4dd092d7fea8472a4Jim Laskey // Skip default 4080d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey if (Name == "NoItineraries") continue; 4090d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey 410908ae27a9073e2f105f8a0a4dd092d7fea8472a4Jim Laskey // Begin processor itinerary table 4110d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey OS << "\n"; 412cfbb2f074da2842e42956d3b4c21e91b37f36f06Dan Gohman OS << "static const llvm::InstrItinerary " << Name << "[] = {\n"; 4130d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey 414908ae27a9073e2f105f8a0a4dd092d7fea8472a4Jim Laskey // For each itinerary class 415f7bcde085440d1fd90eba8980ed9c512bc58824dJim Laskey std::vector<InstrItinerary> &ItinList = *ProcListIter++; 4161f528956921561f277a8c697e0202ac1e9a9c1d5David Goodwin for (unsigned j = 0, M = ItinList.size(); j < M; ++j) { 417f7bcde085440d1fd90eba8980ed9c512bc58824dJim Laskey InstrItinerary &Intinerary = ItinList[j]; 4180d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey 419fac8541dd40e01aa2b52962516f9ae67c99720ccDavid Goodwin // Emit in the form of 420fac8541dd40e01aa2b52962516f9ae67c99720ccDavid Goodwin // { firstStage, lastStage, firstCycle, lastCycle } // index 421fac8541dd40e01aa2b52962516f9ae67c99720ccDavid Goodwin if (Intinerary.FirstStage == 0) { 422fac8541dd40e01aa2b52962516f9ae67c99720ccDavid Goodwin OS << " { 0, 0, 0, 0 }"; 4230d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey } else { 424fac8541dd40e01aa2b52962516f9ae67c99720ccDavid Goodwin OS << " { " << Intinerary.FirstStage << ", " << 425fac8541dd40e01aa2b52962516f9ae67c99720ccDavid Goodwin Intinerary.LastStage << ", " << 426fac8541dd40e01aa2b52962516f9ae67c99720ccDavid Goodwin Intinerary.FirstOperandCycle << ", " << 427fac8541dd40e01aa2b52962516f9ae67c99720ccDavid Goodwin Intinerary.LastOperandCycle << " }"; 4280d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey } 4290d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey 4301f528956921561f277a8c697e0202ac1e9a9c1d5David Goodwin OS << ", // " << j << "\n"; 4310d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey } 432908ae27a9073e2f105f8a0a4dd092d7fea8472a4Jim Laskey 433908ae27a9073e2f105f8a0a4dd092d7fea8472a4Jim Laskey // End processor itinerary table 4341f528956921561f277a8c697e0202ac1e9a9c1d5David Goodwin OS << " { ~0U, ~0U, ~0U, ~0U } // end marker\n"; 4350d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey OS << "};\n"; 4360d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey } 43710b1dd99f342d2d7af51dd43f3840f3bf40b0b87Jim Laskey} 43810b1dd99f342d2d7af51dd43f3840f3bf40b0b87Jim Laskey 43910b1dd99f342d2d7af51dd43f3840f3bf40b0b87Jim Laskey// 44010b1dd99f342d2d7af51dd43f3840f3bf40b0b87Jim Laskey// EmitProcessorLookup - generate cpu name to itinerary lookup table. 44110b1dd99f342d2d7af51dd43f3840f3bf40b0b87Jim Laskey// 4421a55180238dbcf11113f610aea010447e51f595bDaniel Dunbarvoid SubtargetEmitter::EmitProcessorLookup(raw_ostream &OS) { 44310b1dd99f342d2d7af51dd43f3840f3bf40b0b87Jim Laskey // Gather and sort processor information 44410b1dd99f342d2d7af51dd43f3840f3bf40b0b87Jim Laskey std::vector<Record*> ProcessorList = 44510b1dd99f342d2d7af51dd43f3840f3bf40b0b87Jim Laskey Records.getAllDerivedDefinitions("Processor"); 44642d24c71df88178eacf244a38b6c48847ee0d39bDuraid Madina std::sort(ProcessorList.begin(), ProcessorList.end(), LessRecordFieldName()); 44710b1dd99f342d2d7af51dd43f3840f3bf40b0b87Jim Laskey 44810b1dd99f342d2d7af51dd43f3840f3bf40b0b87Jim Laskey // Begin processor table 44910b1dd99f342d2d7af51dd43f3840f3bf40b0b87Jim Laskey OS << "\n"; 45010b1dd99f342d2d7af51dd43f3840f3bf40b0b87Jim Laskey OS << "// Sorted (by key) array of itineraries for CPU subtype.\n" 4517f39c14f52262a154285df9180f5edcdabe2d7dfJim Laskey << "static const llvm::SubtargetInfoKV ProcItinKV[] = {\n"; 45210b1dd99f342d2d7af51dd43f3840f3bf40b0b87Jim Laskey 45310b1dd99f342d2d7af51dd43f3840f3bf40b0b87Jim Laskey // For each processor 45410b1dd99f342d2d7af51dd43f3840f3bf40b0b87Jim Laskey for (unsigned i = 0, N = ProcessorList.size(); i < N;) { 45510b1dd99f342d2d7af51dd43f3840f3bf40b0b87Jim Laskey // Next processor 45610b1dd99f342d2d7af51dd43f3840f3bf40b0b87Jim Laskey Record *Processor = ProcessorList[i]; 45710b1dd99f342d2d7af51dd43f3840f3bf40b0b87Jim Laskey 4584222d806faae71ecc794cfdaa873817873c2f3d8Bill Wendling const std::string &Name = Processor->getValueAsString("Name"); 4594222d806faae71ecc794cfdaa873817873c2f3d8Bill Wendling const std::string &ProcItin = 4604222d806faae71ecc794cfdaa873817873c2f3d8Bill Wendling Processor->getValueAsDef("ProcItin")->getName(); 46110b1dd99f342d2d7af51dd43f3840f3bf40b0b87Jim Laskey 46210b1dd99f342d2d7af51dd43f3840f3bf40b0b87Jim Laskey // Emit as { "cpu", procinit }, 46310b1dd99f342d2d7af51dd43f3840f3bf40b0b87Jim Laskey OS << " { " 46410b1dd99f342d2d7af51dd43f3840f3bf40b0b87Jim Laskey << "\"" << Name << "\", " 46510b1dd99f342d2d7af51dd43f3840f3bf40b0b87Jim Laskey << "(void *)&" << ProcItin; 46610b1dd99f342d2d7af51dd43f3840f3bf40b0b87Jim Laskey 46710b1dd99f342d2d7af51dd43f3840f3bf40b0b87Jim Laskey OS << " }"; 46810b1dd99f342d2d7af51dd43f3840f3bf40b0b87Jim Laskey 46910b1dd99f342d2d7af51dd43f3840f3bf40b0b87Jim Laskey // Depending on ''if more in the list'' emit comma 47010b1dd99f342d2d7af51dd43f3840f3bf40b0b87Jim Laskey if (++i < N) OS << ","; 47110b1dd99f342d2d7af51dd43f3840f3bf40b0b87Jim Laskey 47210b1dd99f342d2d7af51dd43f3840f3bf40b0b87Jim Laskey OS << "\n"; 47310b1dd99f342d2d7af51dd43f3840f3bf40b0b87Jim Laskey } 47410b1dd99f342d2d7af51dd43f3840f3bf40b0b87Jim Laskey 47510b1dd99f342d2d7af51dd43f3840f3bf40b0b87Jim Laskey // End processor table 47610b1dd99f342d2d7af51dd43f3840f3bf40b0b87Jim Laskey OS << "};\n"; 47710b1dd99f342d2d7af51dd43f3840f3bf40b0b87Jim Laskey 47810b1dd99f342d2d7af51dd43f3840f3bf40b0b87Jim Laskey // Emit size of table 47910b1dd99f342d2d7af51dd43f3840f3bf40b0b87Jim Laskey OS<<"\nenum {\n"; 4807f39c14f52262a154285df9180f5edcdabe2d7dfJim Laskey OS<<" ProcItinKVSize = sizeof(ProcItinKV)/" 48110b1dd99f342d2d7af51dd43f3840f3bf40b0b87Jim Laskey "sizeof(llvm::SubtargetInfoKV)\n"; 48210b1dd99f342d2d7af51dd43f3840f3bf40b0b87Jim Laskey OS<<"};\n"; 4830d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey} 4840d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey 4850d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey// 4860d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey// EmitData - Emits all stages and itineries, folding common patterns. 4870d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey// 4881a55180238dbcf11113f610aea010447e51f595bDaniel Dunbarvoid SubtargetEmitter::EmitData(raw_ostream &OS) { 489f7bcde085440d1fd90eba8980ed9c512bc58824dJim Laskey std::map<std::string, unsigned> ItinClassesMap; 490f7bcde085440d1fd90eba8980ed9c512bc58824dJim Laskey std::vector<std::vector<InstrItinerary> > ProcList; 4910d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey 492908ae27a9073e2f105f8a0a4dd092d7fea8472a4Jim Laskey // Enumerate all the itinerary classes 4936cee630070b1a7183ed56a8404e812629f5ca538Jim Laskey unsigned NItinClasses = CollectAllItinClasses(OS, ItinClassesMap); 4946cee630070b1a7183ed56a8404e812629f5ca538Jim Laskey // Make sure the rest is worth the effort 495387e4bdf002c78a1b43a10e10cf5147baf32f513Chris Lattner HasItineraries = NItinClasses != 1; // Ignore NoItinerary. 4966cee630070b1a7183ed56a8404e812629f5ca538Jim Laskey 4976cee630070b1a7183ed56a8404e812629f5ca538Jim Laskey if (HasItineraries) { 4986cee630070b1a7183ed56a8404e812629f5ca538Jim Laskey // Emit the stage data 499fac8541dd40e01aa2b52962516f9ae67c99720ccDavid Goodwin EmitStageAndOperandCycleData(OS, NItinClasses, ItinClassesMap, ProcList); 5006cee630070b1a7183ed56a8404e812629f5ca538Jim Laskey // Emit the processor itinerary data 5016cee630070b1a7183ed56a8404e812629f5ca538Jim Laskey EmitProcessorData(OS, ProcList); 5026cee630070b1a7183ed56a8404e812629f5ca538Jim Laskey // Emit the processor lookup data 5036cee630070b1a7183ed56a8404e812629f5ca538Jim Laskey EmitProcessorLookup(OS); 5046cee630070b1a7183ed56a8404e812629f5ca538Jim Laskey } 5050d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey} 5060d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey 5070d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey// 508581a8f79bc1ac3cbe5d621f0b4a0252ab2890bc1Jim Laskey// ParseFeaturesFunction - Produces a subtarget specific function for parsing 509581a8f79bc1ac3cbe5d621f0b4a0252ab2890bc1Jim Laskey// the subtarget features string. 510581a8f79bc1ac3cbe5d621f0b4a0252ab2890bc1Jim Laskey// 5111a55180238dbcf11113f610aea010447e51f595bDaniel Dunbarvoid SubtargetEmitter::ParseFeaturesFunction(raw_ostream &OS) { 512f7bcde085440d1fd90eba8980ed9c512bc58824dJim Laskey std::vector<Record*> Features = 513f7bcde085440d1fd90eba8980ed9c512bc58824dJim Laskey Records.getAllDerivedDefinitions("SubtargetFeature"); 51442d24c71df88178eacf244a38b6c48847ee0d39bDuraid Madina std::sort(Features.begin(), Features.end(), LessRecord()); 515581a8f79bc1ac3cbe5d621f0b4a0252ab2890bc1Jim Laskey 516581a8f79bc1ac3cbe5d621f0b4a0252ab2890bc1Jim Laskey OS << "// ParseSubtargetFeatures - Parses features string setting specified\n" 5174222d806faae71ecc794cfdaa873817873c2f3d8Bill Wendling << "// subtarget options.\n" 51841a024385f1220eadc48b48cb4c044a5fbc1b361Anton Korobeynikov << "std::string llvm::"; 519581a8f79bc1ac3cbe5d621f0b4a0252ab2890bc1Jim Laskey OS << Target; 520581a8f79bc1ac3cbe5d621f0b4a0252ab2890bc1Jim Laskey OS << "Subtarget::ParseSubtargetFeatures(const std::string &FS,\n" 5214222d806faae71ecc794cfdaa873817873c2f3d8Bill Wendling << " const std::string &CPU) {\n" 522f0fd3afeffcb41202147f755bf770061f189a42bDavid Greene << " DEBUG(dbgs() << \"\\nFeatures:\" << FS);\n" 523f0fd3afeffcb41202147f755bf770061f189a42bDavid Greene << " DEBUG(dbgs() << \"\\nCPU:\" << CPU);\n" 5244222d806faae71ecc794cfdaa873817873c2f3d8Bill Wendling << " SubtargetFeatures Features(FS);\n" 5254222d806faae71ecc794cfdaa873817873c2f3d8Bill Wendling << " Features.setCPUIfNone(CPU);\n" 5264222d806faae71ecc794cfdaa873817873c2f3d8Bill Wendling << " uint32_t Bits = Features.getBits(SubTypeKV, SubTypeKVSize,\n" 5274222d806faae71ecc794cfdaa873817873c2f3d8Bill Wendling << " FeatureKV, FeatureKVSize);\n"; 5284222d806faae71ecc794cfdaa873817873c2f3d8Bill Wendling 529f7bcde085440d1fd90eba8980ed9c512bc58824dJim Laskey for (unsigned i = 0; i < Features.size(); i++) { 530f7bcde085440d1fd90eba8980ed9c512bc58824dJim Laskey // Next record 531f7bcde085440d1fd90eba8980ed9c512bc58824dJim Laskey Record *R = Features[i]; 5324222d806faae71ecc794cfdaa873817873c2f3d8Bill Wendling const std::string &Instance = R->getName(); 5334222d806faae71ecc794cfdaa873817873c2f3d8Bill Wendling const std::string &Value = R->getValueAsString("Value"); 5344222d806faae71ecc794cfdaa873817873c2f3d8Bill Wendling const std::string &Attribute = R->getValueAsString("Attribute"); 53519c95507443ebd4f1cee80917d540c8bd27f8fe1Evan Cheng 536db01c8ba26f288636d3f574a96af3499ee6d2579Dale Johannesen if (Value=="true" || Value=="false") 537db01c8ba26f288636d3f574a96af3499ee6d2579Dale Johannesen OS << " if ((Bits & " << Instance << ") != 0) " 538db01c8ba26f288636d3f574a96af3499ee6d2579Dale Johannesen << Attribute << " = " << Value << ";\n"; 539db01c8ba26f288636d3f574a96af3499ee6d2579Dale Johannesen else 540db01c8ba26f288636d3f574a96af3499ee6d2579Dale Johannesen OS << " if ((Bits & " << Instance << ") != 0 && " << Attribute << 541db01c8ba26f288636d3f574a96af3499ee6d2579Dale Johannesen " < " << Value << ") " << Attribute << " = " << Value << ";\n"; 542581a8f79bc1ac3cbe5d621f0b4a0252ab2890bc1Jim Laskey } 5434222d806faae71ecc794cfdaa873817873c2f3d8Bill Wendling 5446cee630070b1a7183ed56a8404e812629f5ca538Jim Laskey if (HasItineraries) { 5456cee630070b1a7183ed56a8404e812629f5ca538Jim Laskey OS << "\n" 5466cee630070b1a7183ed56a8404e812629f5ca538Jim Laskey << " InstrItinerary *Itinerary = (InstrItinerary *)" 5474222d806faae71ecc794cfdaa873817873c2f3d8Bill Wendling << "Features.getInfo(ProcItinKV, ProcItinKVSize);\n" 548fac8541dd40e01aa2b52962516f9ae67c99720ccDavid Goodwin << " InstrItins = InstrItineraryData(Stages, OperandCycles, Itinerary);\n"; 5496cee630070b1a7183ed56a8404e812629f5ca538Jim Laskey } 55041a024385f1220eadc48b48cb4c044a5fbc1b361Anton Korobeynikov 55141a024385f1220eadc48b48cb4c044a5fbc1b361Anton Korobeynikov OS << " return Features.getCPU();\n" 55241a024385f1220eadc48b48cb4c044a5fbc1b361Anton Korobeynikov << "}\n"; 553581a8f79bc1ac3cbe5d621f0b4a0252ab2890bc1Jim Laskey} 554581a8f79bc1ac3cbe5d621f0b4a0252ab2890bc1Jim Laskey 55541a024385f1220eadc48b48cb4c044a5fbc1b361Anton Korobeynikov// 556b3b1d5f097a4fbcf134259b743ccbd93d187c6cdJim Laskey// SubtargetEmitter::run - Main subtarget enumeration emitter. 557b3b1d5f097a4fbcf134259b743ccbd93d187c6cdJim Laskey// 5581a55180238dbcf11113f610aea010447e51f595bDaniel Dunbarvoid SubtargetEmitter::run(raw_ostream &OS) { 5596c302fc0757c20a6de52a788ffc675e5c5980971Jim Laskey Target = CodeGenTarget().getName(); 560581a8f79bc1ac3cbe5d621f0b4a0252ab2890bc1Jim Laskey 561b3b1d5f097a4fbcf134259b743ccbd93d187c6cdJim Laskey EmitSourceFileHeader("Subtarget Enumeration Source Fragment", OS); 562b3b1d5f097a4fbcf134259b743ccbd93d187c6cdJim Laskey 563bf177ee6fd234dee70ebf6f0ef7c39b55f8ed4f5Sandeep Patel OS << "#include \"llvm/Support/Debug.h\"\n"; 564bf177ee6fd234dee70ebf6f0ef7c39b55f8ed4f5Sandeep Patel OS << "#include \"llvm/Support/raw_ostream.h\"\n"; 5650d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey OS << "#include \"llvm/Target/SubtargetFeature.h\"\n"; 5660d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey OS << "#include \"llvm/Target/TargetInstrItineraries.h\"\n\n"; 567b3b1d5f097a4fbcf134259b743ccbd93d187c6cdJim Laskey 568581a8f79bc1ac3cbe5d621f0b4a0252ab2890bc1Jim Laskey Enumeration(OS, "FuncUnit", true); 569581a8f79bc1ac3cbe5d621f0b4a0252ab2890bc1Jim Laskey OS<<"\n"; 570908ae27a9073e2f105f8a0a4dd092d7fea8472a4Jim Laskey// Enumeration(OS, "InstrItinClass", false); 571908ae27a9073e2f105f8a0a4dd092d7fea8472a4Jim Laskey// OS<<"\n"; 572581a8f79bc1ac3cbe5d621f0b4a0252ab2890bc1Jim Laskey Enumeration(OS, "SubtargetFeature", true); 573581a8f79bc1ac3cbe5d621f0b4a0252ab2890bc1Jim Laskey OS<<"\n"; 574b3b1d5f097a4fbcf134259b743ccbd93d187c6cdJim Laskey FeatureKeyValues(OS); 575581a8f79bc1ac3cbe5d621f0b4a0252ab2890bc1Jim Laskey OS<<"\n"; 576b3b1d5f097a4fbcf134259b743ccbd93d187c6cdJim Laskey CPUKeyValues(OS); 577581a8f79bc1ac3cbe5d621f0b4a0252ab2890bc1Jim Laskey OS<<"\n"; 5780d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey EmitData(OS); 5790d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey OS<<"\n"; 580581a8f79bc1ac3cbe5d621f0b4a0252ab2890bc1Jim Laskey ParseFeaturesFunction(OS); 581b3b1d5f097a4fbcf134259b743ccbd93d187c6cdJim Laskey} 582