SubtargetEmitter.cpp revision 0d841e05677bdc55d003720e85e12d28dfe31862
14bb9cbb73075c350eadaf51d2dab8403764c9a60Jim Laskey//===- SubtargetEmitter.cpp - Generate subtarget enumerations -------------===// 24bb9cbb73075c350eadaf51d2dab8403764c9a60Jim Laskey// 34bb9cbb73075c350eadaf51d2dab8403764c9a60Jim Laskey// The LLVM Compiler Infrastructure 44bb9cbb73075c350eadaf51d2dab8403764c9a60Jim Laskey// 54bb9cbb73075c350eadaf51d2dab8403764c9a60Jim Laskey// This file was developed by James M. Laskey and is distributed under 64bb9cbb73075c350eadaf51d2dab8403764c9a60Jim Laskey// the University of Illinois Open Source License. See LICENSE.TXT for details. 74bb9cbb73075c350eadaf51d2dab8403764c9a60Jim Laskey// 84bb9cbb73075c350eadaf51d2dab8403764c9a60Jim Laskey//===----------------------------------------------------------------------===// 94bb9cbb73075c350eadaf51d2dab8403764c9a60Jim Laskey// 104bb9cbb73075c350eadaf51d2dab8403764c9a60Jim Laskey// 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" 194bb9cbb73075c350eadaf51d2dab8403764c9a60Jim Laskeyusing namespace llvm; 204bb9cbb73075c350eadaf51d2dab8403764c9a60Jim Laskey 217dc02047fbb4b014e914458f54ea539c8ae58316Jim Laskey// 227dc02047fbb4b014e914458f54ea539c8ae58316Jim Laskey// Convenience types. 237dc02047fbb4b014e914458f54ea539c8ae58316Jim Laskey// 244bb9cbb73075c350eadaf51d2dab8403764c9a60Jim Laskeytypedef std::vector<Record*> RecordList; 250d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey 260d841e05677bdc55d003720e85e12d28dfe31862Jim Laskeystruct RecordListIter { 270d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey std::vector<Record*>::iterator RI; 280d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey std::vector<Record*>::iterator E; 290d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey 300d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey RecordListIter(RecordList &RL) 310d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey : RI(RL.begin()), E(RL.end()) 320d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey {} 330d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey 340d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey bool isMore() const { return RI != E; } 350d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey 360d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey Record *next() { return isMore() ? *RI++ : NULL; } 370d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey}; 380d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey 390d841e05677bdc55d003720e85e12d28dfe31862Jim Laskeystruct DefListIter { 400d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey ListInit *List; 410d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey unsigned N; 420d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey unsigned i; 430d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey 440d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey DefListIter(Record *R, const std::string &Name) 450d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey : List(R->getValueAsListInit(Name)), N(List->getSize()), i(0) 460d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey {} 470d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey 480d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey bool isMore() const { return i < N; } 490d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey 500d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey Record *next() { 510d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey if (isMore()) { 520d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey if (DefInit *DI = dynamic_cast<DefInit*>(List->getElement(i++))) { 530d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey return DI->getDef(); 540d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey } 550d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey } 560d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey return NULL; 570d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey } 580d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey}; 594bb9cbb73075c350eadaf51d2dab8403764c9a60Jim Laskey 607dc02047fbb4b014e914458f54ea539c8ae58316Jim Laskey// 617dc02047fbb4b014e914458f54ea539c8ae58316Jim Laskey// Record sort by name function. 627dc02047fbb4b014e914458f54ea539c8ae58316Jim Laskey// 637dc02047fbb4b014e914458f54ea539c8ae58316Jim Laskeystruct LessRecord { 647dc02047fbb4b014e914458f54ea539c8ae58316Jim Laskey bool operator()(const Record *Rec1, const Record *Rec2) const { 657dc02047fbb4b014e914458f54ea539c8ae58316Jim Laskey return Rec1->getName() < Rec2->getName(); 667dc02047fbb4b014e914458f54ea539c8ae58316Jim Laskey } 677dc02047fbb4b014e914458f54ea539c8ae58316Jim Laskey}; 684bb9cbb73075c350eadaf51d2dab8403764c9a60Jim Laskey 697dc02047fbb4b014e914458f54ea539c8ae58316Jim Laskey// 707dc02047fbb4b014e914458f54ea539c8ae58316Jim Laskey// Record sort by field "Name" function. 717dc02047fbb4b014e914458f54ea539c8ae58316Jim Laskey// 727dc02047fbb4b014e914458f54ea539c8ae58316Jim Laskeystruct LessRecordFieldName { 737dc02047fbb4b014e914458f54ea539c8ae58316Jim Laskey bool operator()(const Record *Rec1, const Record *Rec2) const { 747dc02047fbb4b014e914458f54ea539c8ae58316Jim Laskey return Rec1->getValueAsString("Name") < Rec2->getValueAsString("Name"); 757dc02047fbb4b014e914458f54ea539c8ae58316Jim Laskey } 767dc02047fbb4b014e914458f54ea539c8ae58316Jim Laskey}; 777dc02047fbb4b014e914458f54ea539c8ae58316Jim Laskey 784bb9cbb73075c350eadaf51d2dab8403764c9a60Jim Laskey// 79581a8f79bc1ac3cbe5d621f0b4a0252ab2890bc1Jim Laskey// Enumeration - Emit the specified class as an enumeration. 80b3b1d5f097a4fbcf134259b743ccbd93d187c6cdJim Laskey// 81581a8f79bc1ac3cbe5d621f0b4a0252ab2890bc1Jim Laskeyvoid SubtargetEmitter::Enumeration(std::ostream &OS, 82581a8f79bc1ac3cbe5d621f0b4a0252ab2890bc1Jim Laskey const char *ClassName, 83581a8f79bc1ac3cbe5d621f0b4a0252ab2890bc1Jim Laskey bool isBits) { 84581a8f79bc1ac3cbe5d621f0b4a0252ab2890bc1Jim Laskey RecordList Defs = Records.getAllDerivedDefinitions(ClassName); 85581a8f79bc1ac3cbe5d621f0b4a0252ab2890bc1Jim Laskey sort(Defs.begin(), Defs.end(), LessRecord()); 864bb9cbb73075c350eadaf51d2dab8403764c9a60Jim Laskey 87b3b1d5f097a4fbcf134259b743ccbd93d187c6cdJim Laskey int i = 0; 884bb9cbb73075c350eadaf51d2dab8403764c9a60Jim Laskey 89b3b1d5f097a4fbcf134259b743ccbd93d187c6cdJim Laskey OS << "enum {\n"; 904bb9cbb73075c350eadaf51d2dab8403764c9a60Jim Laskey 910d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey RecordListIter DI(Defs); 920d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey while (Record *R = DI.next()) { 93b3b1d5f097a4fbcf134259b743ccbd93d187c6cdJim Laskey std::string Instance = R->getName(); 94b3b1d5f097a4fbcf134259b743ccbd93d187c6cdJim Laskey OS << " " 95581a8f79bc1ac3cbe5d621f0b4a0252ab2890bc1Jim Laskey << Instance; 96581a8f79bc1ac3cbe5d621f0b4a0252ab2890bc1Jim Laskey if (isBits) { 97581a8f79bc1ac3cbe5d621f0b4a0252ab2890bc1Jim Laskey OS << " = " 98581a8f79bc1ac3cbe5d621f0b4a0252ab2890bc1Jim Laskey << " 1 << " << i++; 99581a8f79bc1ac3cbe5d621f0b4a0252ab2890bc1Jim Laskey } 1000d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey OS << (DI.isMore() ? ",\n" : "\n"); 1014bb9cbb73075c350eadaf51d2dab8403764c9a60Jim Laskey } 1024bb9cbb73075c350eadaf51d2dab8403764c9a60Jim Laskey 103b3b1d5f097a4fbcf134259b743ccbd93d187c6cdJim Laskey OS << "};\n"; 104b3b1d5f097a4fbcf134259b743ccbd93d187c6cdJim Laskey} 105b3b1d5f097a4fbcf134259b743ccbd93d187c6cdJim Laskey 106b3b1d5f097a4fbcf134259b743ccbd93d187c6cdJim Laskey// 107b3b1d5f097a4fbcf134259b743ccbd93d187c6cdJim Laskey// FeatureKeyValues - Emit data of all the subtarget features. Used by command 108b3b1d5f097a4fbcf134259b743ccbd93d187c6cdJim Laskey// line. 109b3b1d5f097a4fbcf134259b743ccbd93d187c6cdJim Laskey// 110b3b1d5f097a4fbcf134259b743ccbd93d187c6cdJim Laskeyvoid SubtargetEmitter::FeatureKeyValues(std::ostream &OS) { 111b3b1d5f097a4fbcf134259b743ccbd93d187c6cdJim Laskey RecordList Features = Records.getAllDerivedDefinitions("SubtargetFeature"); 112b3b1d5f097a4fbcf134259b743ccbd93d187c6cdJim Laskey sort(Features.begin(), Features.end(), LessRecord()); 113b3b1d5f097a4fbcf134259b743ccbd93d187c6cdJim Laskey 114581a8f79bc1ac3cbe5d621f0b4a0252ab2890bc1Jim Laskey OS << "// Sorted (by key) array of values for CPU features.\n" 115b3b1d5f097a4fbcf134259b743ccbd93d187c6cdJim Laskey << "static llvm::SubtargetFeatureKV FeatureKV[] = {\n"; 1160d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey RecordListIter FI(Features); 1170d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey while (Record *R = FI.next()) { 118b3b1d5f097a4fbcf134259b743ccbd93d187c6cdJim Laskey std::string Instance = R->getName(); 119b3b1d5f097a4fbcf134259b743ccbd93d187c6cdJim Laskey std::string Name = R->getValueAsString("Name"); 120b3b1d5f097a4fbcf134259b743ccbd93d187c6cdJim Laskey std::string Desc = R->getValueAsString("Desc"); 121b3b1d5f097a4fbcf134259b743ccbd93d187c6cdJim Laskey OS << " { " 122b3b1d5f097a4fbcf134259b743ccbd93d187c6cdJim Laskey << "\"" << Name << "\", " 123b3b1d5f097a4fbcf134259b743ccbd93d187c6cdJim Laskey << "\"" << Desc << "\", " 124b3b1d5f097a4fbcf134259b743ccbd93d187c6cdJim Laskey << Instance 1250d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey << (FI.isMore() ? " },\n" : " }\n"); 126b3b1d5f097a4fbcf134259b743ccbd93d187c6cdJim Laskey } 127b3b1d5f097a4fbcf134259b743ccbd93d187c6cdJim Laskey OS << "};\n"; 128b3b1d5f097a4fbcf134259b743ccbd93d187c6cdJim Laskey 129b3b1d5f097a4fbcf134259b743ccbd93d187c6cdJim Laskey OS<<"\nenum {\n"; 130b3b1d5f097a4fbcf134259b743ccbd93d187c6cdJim Laskey OS<<" FeatureKVSize = sizeof(FeatureKV)/sizeof(llvm::SubtargetFeatureKV)\n"; 131b3b1d5f097a4fbcf134259b743ccbd93d187c6cdJim Laskey OS<<"};\n"; 132b3b1d5f097a4fbcf134259b743ccbd93d187c6cdJim Laskey} 133b3b1d5f097a4fbcf134259b743ccbd93d187c6cdJim Laskey 134b3b1d5f097a4fbcf134259b743ccbd93d187c6cdJim Laskey// 135b3b1d5f097a4fbcf134259b743ccbd93d187c6cdJim Laskey// CPUKeyValues - Emit data of all the subtarget processors. Used by command 136b3b1d5f097a4fbcf134259b743ccbd93d187c6cdJim Laskey// line. 137b3b1d5f097a4fbcf134259b743ccbd93d187c6cdJim Laskey// 138b3b1d5f097a4fbcf134259b743ccbd93d187c6cdJim Laskeyvoid SubtargetEmitter::CPUKeyValues(std::ostream &OS) { 139b3b1d5f097a4fbcf134259b743ccbd93d187c6cdJim Laskey RecordList Processors = Records.getAllDerivedDefinitions("Processor"); 140b3b1d5f097a4fbcf134259b743ccbd93d187c6cdJim Laskey sort(Processors.begin(), Processors.end(), LessRecordFieldName()); 141b3b1d5f097a4fbcf134259b743ccbd93d187c6cdJim Laskey 142581a8f79bc1ac3cbe5d621f0b4a0252ab2890bc1Jim Laskey OS << "// Sorted (by key) array of values for CPU subtype.\n" 143b3b1d5f097a4fbcf134259b743ccbd93d187c6cdJim Laskey << "static const llvm::SubtargetFeatureKV SubTypeKV[] = {\n"; 1440d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey RecordListIter PI(Processors); 1450d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey while (Record *R = PI.next()) { 146b3b1d5f097a4fbcf134259b743ccbd93d187c6cdJim Laskey std::string Name = R->getValueAsString("Name"); 1470d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey DefListIter FI(R, "Features"); 1480d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey 149b3b1d5f097a4fbcf134259b743ccbd93d187c6cdJim Laskey OS << " { " 150b3b1d5f097a4fbcf134259b743ccbd93d187c6cdJim Laskey << "\"" << Name << "\", " 151b3b1d5f097a4fbcf134259b743ccbd93d187c6cdJim Laskey << "\"Select the " << Name << " processor\", "; 152b3b1d5f097a4fbcf134259b743ccbd93d187c6cdJim Laskey 1530d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey if (!FI.isMore()) { 154b3b1d5f097a4fbcf134259b743ccbd93d187c6cdJim Laskey OS << "0"; 155b3b1d5f097a4fbcf134259b743ccbd93d187c6cdJim Laskey } else { 1560d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey while (Record *Feature = FI.next()) { 1570d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey std::string Name = Feature->getName(); 1580d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey OS << Name; 1590d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey if (FI.isMore()) OS << " | "; 1604bb9cbb73075c350eadaf51d2dab8403764c9a60Jim Laskey } 1614bb9cbb73075c350eadaf51d2dab8403764c9a60Jim Laskey } 162b3b1d5f097a4fbcf134259b743ccbd93d187c6cdJim Laskey 1630d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey OS << (PI.isMore() ? " },\n" : " }\n"); 1644bb9cbb73075c350eadaf51d2dab8403764c9a60Jim Laskey } 165b3b1d5f097a4fbcf134259b743ccbd93d187c6cdJim Laskey OS << "};\n"; 166b3b1d5f097a4fbcf134259b743ccbd93d187c6cdJim Laskey 167d4d079785187ce923edc245aee527e4768b1d180Chris Lattner OS<<"\nenum {\n"; 168d4d079785187ce923edc245aee527e4768b1d180Chris Lattner OS<<" SubTypeKVSize = sizeof(SubTypeKV)/sizeof(llvm::SubtargetFeatureKV)\n"; 169d4d079785187ce923edc245aee527e4768b1d180Chris Lattner OS<<"};\n"; 1704bb9cbb73075c350eadaf51d2dab8403764c9a60Jim Laskey} 171b3b1d5f097a4fbcf134259b743ccbd93d187c6cdJim Laskey 172581a8f79bc1ac3cbe5d621f0b4a0252ab2890bc1Jim Laskey// 1730d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey// CollectAllItinClasses - Gathers and enumerates all the itinerary classes. 1740d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey// 1750d841e05677bdc55d003720e85e12d28dfe31862Jim Laskeyunsigned SubtargetEmitter::CollectAllItinClasses(IntMap &ItinClassesMap) { 1760d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey RecordList ICL = Records.getAllDerivedDefinitions("InstrItinClass"); 1770d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey sort(ICL.begin(), ICL.end(), LessRecord()); 1780d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey 1790d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey RecordListIter ICI(ICL); 1800d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey unsigned Index = 0; 1810d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey while (Record *ItinClass = ICI.next()) { 1820d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey std::string Name = ItinClass->getName(); 1830d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey ItinClassesMap[Name] = Index++; 1840d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey } 1850d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey 1860d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey return Index; 1870d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey} 1880d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey 1890d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey// 1900d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey// FormItineraryString - Compose a string containing the data initialization 1910d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey// for the specified itinerary. N is the number of stages. 1920d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey// 1930d841e05677bdc55d003720e85e12d28dfe31862Jim Laskeyvoid SubtargetEmitter::FormItineraryString(Record *ItinData, 1940d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey std::string &ItinString, 1950d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey unsigned &N) { 1960d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey DefListIter SLI(ItinData, "Stages"); 1970d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey N = SLI.N; 1980d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey while (Record *Stage = SLI.next()) { 1990d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey int Cycles = Stage->getValueAsInt("Cycles"); 2000d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey ItinString += " ,{ " + itostr(Cycles) + ", "; 2010d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey 2020d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey DefListIter ULI(Stage, "Units"); 2030d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey while (Record *Unit = ULI.next()) { 2040d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey std::string Name = Unit->getName(); 2050d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey ItinString += Name; 2060d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey if (ULI.isMore())ItinString += " | "; 2070d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey } 2080d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey } 2090d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey 2100d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey ItinString += " }"; 2110d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey} 2120d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey 2130d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey// 2140d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey// EmitStageData - Generate unique itinerary stages. Record itineraries for 2150d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey// processors. 2160d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey// 2170d841e05677bdc55d003720e85e12d28dfe31862Jim Laskeyvoid SubtargetEmitter::EmitStageData(std::ostream &OS, 2180d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey unsigned N, 2190d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey IntMap &ItinClassesMap, 2200d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey ProcessorList &ProcList) { 2210d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey OS << "static llvm::InstrStage Stages[] = {\n" 2220d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey " { 0, 0 } // No itinerary\n"; 2230d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey 2240d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey IntMap ItinMap; 2250d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey unsigned Index = 1; 2260d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey RecordList Itins = Records.getAllDerivedDefinitions("ProcessorItineraries"); 2270d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey RecordListIter II(Itins); 2280d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey while (Record *Itin = II.next()) { 2290d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey std::string Name = Itin->getName(); 2300d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey if (Name == "NoItineraries") continue; 2310d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey 2320d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey IntineraryList IL; 2330d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey IL.resize(N); 2340d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey 2350d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey DefListIter IDLI(Itin, "IID"); 2360d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey while (Record *ItinData = IDLI.next()) { 2370d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey std::string ItinString; 2380d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey unsigned M; 2390d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey FormItineraryString(ItinData, ItinString, M); 2400d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey 2410d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey unsigned Find = ItinMap[ItinString]; 2420d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey 2430d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey if (Find == 0) { 2440d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey OS << ItinString << " // " << Index << "\n"; 2450d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey ItinMap[ItinString] = Find = Index++; 2460d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey } 2470d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey 2480d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey InstrItinerary Intinerary = { Find, Find + M }; 2490d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey 2500d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey std::string Name = ItinData->getValueAsDef("TheClass")->getName(); 2510d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey Find = ItinClassesMap[Name]; 2520d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey IL[Find] = Intinerary; 2530d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey } 2540d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey 2550d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey ProcList.push_back(IL); 2560d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey } 2570d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey 2580d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey OS << "};\n"; 2590d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey} 2600d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey 2610d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey// 2620d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey// EmitProcessData - Generate data for processor itineraries. 2630d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey// 2640d841e05677bdc55d003720e85e12d28dfe31862Jim Laskeyvoid SubtargetEmitter::EmitProcessData(std::ostream &OS, 2650d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey ProcessorList &ProcList) { 2660d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey ProcessorList::iterator PLI = ProcList.begin(); 2670d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey RecordList Itins = Records.getAllDerivedDefinitions("ProcessorItineraries"); 2680d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey RecordListIter II(Itins); 2690d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey while (Record *Itin = II.next()) { 2700d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey std::string Name = Itin->getName(); 2710d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey if (Name == "NoItineraries") continue; 2720d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey 2730d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey OS << "\n"; 2740d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey OS << "static llvm::InstrItinerary " << Name << "[] = {\n"; 2750d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey 2760d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey IntineraryList &IL = *PLI++; 2770d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey unsigned Index = 0; 2780d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey for (IntineraryList::iterator ILI = IL.begin(), E = IL.end(); ILI != E;) { 2790d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey InstrItinerary &Intinerary = *ILI++; 2800d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey 2810d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey if (Intinerary.First == 0) { 2820d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey OS << " { 0, 0 }"; 2830d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey } else { 2840d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey OS << " { " << Intinerary.First << ", " << Intinerary.Last << " }"; 2850d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey } 2860d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey 2870d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey if (ILI != E) OS << ","; 2880d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey OS << " // " << Index++ << "\n"; 2890d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey } 2900d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey OS << "};\n"; 2910d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey } 2920d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey} 2930d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey 2940d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey// 2950d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey// EmitData - Emits all stages and itineries, folding common patterns. 2960d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey// 2970d841e05677bdc55d003720e85e12d28dfe31862Jim Laskeyvoid SubtargetEmitter::EmitData(std::ostream &OS) { 2980d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey IntMap ItinClassesMap; 2990d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey ProcessorList ProcList; 3000d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey 3010d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey unsigned N = CollectAllItinClasses(ItinClassesMap); 3020d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey EmitStageData(OS, N, ItinClassesMap, ProcList); 3030d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey EmitProcessData(OS, ProcList); 3040d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey} 3050d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey 3060d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey// 307581a8f79bc1ac3cbe5d621f0b4a0252ab2890bc1Jim Laskey// ParseFeaturesFunction - Produces a subtarget specific function for parsing 308581a8f79bc1ac3cbe5d621f0b4a0252ab2890bc1Jim Laskey// the subtarget features string. 309581a8f79bc1ac3cbe5d621f0b4a0252ab2890bc1Jim Laskey// 310581a8f79bc1ac3cbe5d621f0b4a0252ab2890bc1Jim Laskeyvoid SubtargetEmitter::ParseFeaturesFunction(std::ostream &OS) { 311581a8f79bc1ac3cbe5d621f0b4a0252ab2890bc1Jim Laskey RecordList Features = Records.getAllDerivedDefinitions("SubtargetFeature"); 312581a8f79bc1ac3cbe5d621f0b4a0252ab2890bc1Jim Laskey sort(Features.begin(), Features.end(), LessRecord()); 313581a8f79bc1ac3cbe5d621f0b4a0252ab2890bc1Jim Laskey 314581a8f79bc1ac3cbe5d621f0b4a0252ab2890bc1Jim Laskey OS << "// ParseSubtargetFeatures - Parses features string setting specified\n" 315581a8f79bc1ac3cbe5d621f0b4a0252ab2890bc1Jim Laskey "// subtarget options.\n" 316581a8f79bc1ac3cbe5d621f0b4a0252ab2890bc1Jim Laskey "void llvm::"; 317581a8f79bc1ac3cbe5d621f0b4a0252ab2890bc1Jim Laskey OS << Target; 318581a8f79bc1ac3cbe5d621f0b4a0252ab2890bc1Jim Laskey OS << "Subtarget::ParseSubtargetFeatures(const std::string &FS,\n" 319581a8f79bc1ac3cbe5d621f0b4a0252ab2890bc1Jim Laskey " const std::string &CPU) {\n" 320581a8f79bc1ac3cbe5d621f0b4a0252ab2890bc1Jim Laskey " SubtargetFeatures Features(FS);\n" 321581a8f79bc1ac3cbe5d621f0b4a0252ab2890bc1Jim Laskey " Features.setCPUIfNone(CPU);\n" 322581a8f79bc1ac3cbe5d621f0b4a0252ab2890bc1Jim Laskey " uint32_t Bits = Features.getBits(SubTypeKV, SubTypeKVSize,\n" 323581a8f79bc1ac3cbe5d621f0b4a0252ab2890bc1Jim Laskey " FeatureKV, FeatureKVSize);\n"; 324581a8f79bc1ac3cbe5d621f0b4a0252ab2890bc1Jim Laskey 3250d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey RecordListIter FI(Features); 3260d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey while (Record *R = FI.next()) { 327581a8f79bc1ac3cbe5d621f0b4a0252ab2890bc1Jim Laskey std::string Instance = R->getName(); 328581a8f79bc1ac3cbe5d621f0b4a0252ab2890bc1Jim Laskey std::string Name = R->getValueAsString("Name"); 329581a8f79bc1ac3cbe5d621f0b4a0252ab2890bc1Jim Laskey std::string Type = R->getValueAsString("Type"); 330581a8f79bc1ac3cbe5d621f0b4a0252ab2890bc1Jim Laskey std::string Attribute = R->getValueAsString("Attribute"); 331581a8f79bc1ac3cbe5d621f0b4a0252ab2890bc1Jim Laskey 332581a8f79bc1ac3cbe5d621f0b4a0252ab2890bc1Jim Laskey OS << " " << Attribute << " = (Bits & " << Instance << ") != 0;\n"; 333581a8f79bc1ac3cbe5d621f0b4a0252ab2890bc1Jim Laskey } 334581a8f79bc1ac3cbe5d621f0b4a0252ab2890bc1Jim Laskey OS << "}\n"; 335581a8f79bc1ac3cbe5d621f0b4a0252ab2890bc1Jim Laskey} 336581a8f79bc1ac3cbe5d621f0b4a0252ab2890bc1Jim Laskey 337b3b1d5f097a4fbcf134259b743ccbd93d187c6cdJim Laskey// 338b3b1d5f097a4fbcf134259b743ccbd93d187c6cdJim Laskey// SubtargetEmitter::run - Main subtarget enumeration emitter. 339b3b1d5f097a4fbcf134259b743ccbd93d187c6cdJim Laskey// 340b3b1d5f097a4fbcf134259b743ccbd93d187c6cdJim Laskeyvoid SubtargetEmitter::run(std::ostream &OS) { 3416c302fc0757c20a6de52a788ffc675e5c5980971Jim Laskey Target = CodeGenTarget().getName(); 342581a8f79bc1ac3cbe5d621f0b4a0252ab2890bc1Jim Laskey 343b3b1d5f097a4fbcf134259b743ccbd93d187c6cdJim Laskey EmitSourceFileHeader("Subtarget Enumeration Source Fragment", OS); 344b3b1d5f097a4fbcf134259b743ccbd93d187c6cdJim Laskey 3450d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey OS << "#include \"llvm/Target/SubtargetFeature.h\"\n"; 3460d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey OS << "#include \"llvm/Target/TargetInstrItineraries.h\"\n\n"; 347b3b1d5f097a4fbcf134259b743ccbd93d187c6cdJim Laskey 348581a8f79bc1ac3cbe5d621f0b4a0252ab2890bc1Jim Laskey Enumeration(OS, "FuncUnit", true); 349581a8f79bc1ac3cbe5d621f0b4a0252ab2890bc1Jim Laskey OS<<"\n"; 350581a8f79bc1ac3cbe5d621f0b4a0252ab2890bc1Jim Laskey Enumeration(OS, "InstrItinClass", false); 351581a8f79bc1ac3cbe5d621f0b4a0252ab2890bc1Jim Laskey OS<<"\n"; 352581a8f79bc1ac3cbe5d621f0b4a0252ab2890bc1Jim Laskey Enumeration(OS, "SubtargetFeature", true); 353581a8f79bc1ac3cbe5d621f0b4a0252ab2890bc1Jim Laskey OS<<"\n"; 354b3b1d5f097a4fbcf134259b743ccbd93d187c6cdJim Laskey FeatureKeyValues(OS); 355581a8f79bc1ac3cbe5d621f0b4a0252ab2890bc1Jim Laskey OS<<"\n"; 356b3b1d5f097a4fbcf134259b743ccbd93d187c6cdJim Laskey CPUKeyValues(OS); 357581a8f79bc1ac3cbe5d621f0b4a0252ab2890bc1Jim Laskey OS<<"\n"; 3580d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey EmitData(OS); 3590d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey OS<<"\n"; 360581a8f79bc1ac3cbe5d621f0b4a0252ab2890bc1Jim Laskey ParseFeaturesFunction(OS); 361b3b1d5f097a4fbcf134259b743ccbd93d187c6cdJim Laskey} 362