SubtargetEmitter.cpp revision db01c8ba26f288636d3f574a96af3499ee6d2579
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//
237dc02047fbb4b014e914458f54ea539c8ae58316Jim Laskey// Record sort by name function.
247dc02047fbb4b014e914458f54ea539c8ae58316Jim Laskey//
257dc02047fbb4b014e914458f54ea539c8ae58316Jim Laskeystruct LessRecord {
267dc02047fbb4b014e914458f54ea539c8ae58316Jim Laskey  bool operator()(const Record *Rec1, const Record *Rec2) const {
277dc02047fbb4b014e914458f54ea539c8ae58316Jim Laskey    return Rec1->getName() < Rec2->getName();
287dc02047fbb4b014e914458f54ea539c8ae58316Jim Laskey  }
297dc02047fbb4b014e914458f54ea539c8ae58316Jim Laskey};
304bb9cbb73075c350eadaf51d2dab8403764c9a60Jim Laskey
317dc02047fbb4b014e914458f54ea539c8ae58316Jim Laskey//
327dc02047fbb4b014e914458f54ea539c8ae58316Jim Laskey// Record sort by field "Name" function.
337dc02047fbb4b014e914458f54ea539c8ae58316Jim Laskey//
347dc02047fbb4b014e914458f54ea539c8ae58316Jim Laskeystruct LessRecordFieldName {
357dc02047fbb4b014e914458f54ea539c8ae58316Jim Laskey  bool operator()(const Record *Rec1, const Record *Rec2) const {
367dc02047fbb4b014e914458f54ea539c8ae58316Jim Laskey    return Rec1->getValueAsString("Name") < Rec2->getValueAsString("Name");
377dc02047fbb4b014e914458f54ea539c8ae58316Jim Laskey  }
387dc02047fbb4b014e914458f54ea539c8ae58316Jim Laskey};
397dc02047fbb4b014e914458f54ea539c8ae58316Jim Laskey
404bb9cbb73075c350eadaf51d2dab8403764c9a60Jim Laskey//
41581a8f79bc1ac3cbe5d621f0b4a0252ab2890bc1Jim Laskey// Enumeration - Emit the specified class as an enumeration.
42b3b1d5f097a4fbcf134259b743ccbd93d187c6cdJim Laskey//
43581a8f79bc1ac3cbe5d621f0b4a0252ab2890bc1Jim Laskeyvoid SubtargetEmitter::Enumeration(std::ostream &OS,
44581a8f79bc1ac3cbe5d621f0b4a0252ab2890bc1Jim Laskey                                   const char *ClassName,
45581a8f79bc1ac3cbe5d621f0b4a0252ab2890bc1Jim Laskey                                   bool isBits) {
46908ae27a9073e2f105f8a0a4dd092d7fea8472a4Jim Laskey  // Get all records of class and sort
47f7bcde085440d1fd90eba8980ed9c512bc58824dJim Laskey  std::vector<Record*> DefList = Records.getAllDerivedDefinitions(ClassName);
4842d24c71df88178eacf244a38b6c48847ee0d39bDuraid Madina  std::sort(DefList.begin(), DefList.end(), LessRecord());
494bb9cbb73075c350eadaf51d2dab8403764c9a60Jim Laskey
50908ae27a9073e2f105f8a0a4dd092d7fea8472a4Jim Laskey  // Open enumeration
51b3b1d5f097a4fbcf134259b743ccbd93d187c6cdJim Laskey  OS << "enum {\n";
524bb9cbb73075c350eadaf51d2dab8403764c9a60Jim Laskey
53908ae27a9073e2f105f8a0a4dd092d7fea8472a4Jim Laskey  // For each record
54f7bcde085440d1fd90eba8980ed9c512bc58824dJim Laskey  for (unsigned i = 0, N = DefList.size(); i < N;) {
55f7bcde085440d1fd90eba8980ed9c512bc58824dJim Laskey    // Next record
56f7bcde085440d1fd90eba8980ed9c512bc58824dJim Laskey    Record *Def = DefList[i];
57f7bcde085440d1fd90eba8980ed9c512bc58824dJim Laskey
58908ae27a9073e2f105f8a0a4dd092d7fea8472a4Jim Laskey    // Get and emit name
594222d806faae71ecc794cfdaa873817873c2f3d8Bill Wendling    OS << "  " << Def->getName();
60908ae27a9073e2f105f8a0a4dd092d7fea8472a4Jim Laskey
61908ae27a9073e2f105f8a0a4dd092d7fea8472a4Jim Laskey    // If bit flags then emit expression (1 << i)
62f7bcde085440d1fd90eba8980ed9c512bc58824dJim Laskey    if (isBits)  OS << " = " << " 1 << " << i;
63908ae27a9073e2f105f8a0a4dd092d7fea8472a4Jim Laskey
6410b1dd99f342d2d7af51dd43f3840f3bf40b0b87Jim Laskey    // Depending on 'if more in the list' emit comma
65f7bcde085440d1fd90eba8980ed9c512bc58824dJim Laskey    if (++i < N) OS << ",";
66f7bcde085440d1fd90eba8980ed9c512bc58824dJim Laskey
67f7bcde085440d1fd90eba8980ed9c512bc58824dJim Laskey    OS << "\n";
684bb9cbb73075c350eadaf51d2dab8403764c9a60Jim Laskey  }
694bb9cbb73075c350eadaf51d2dab8403764c9a60Jim Laskey
70908ae27a9073e2f105f8a0a4dd092d7fea8472a4Jim Laskey  // Close enumeration
71b3b1d5f097a4fbcf134259b743ccbd93d187c6cdJim Laskey  OS << "};\n";
72b3b1d5f097a4fbcf134259b743ccbd93d187c6cdJim Laskey}
73b3b1d5f097a4fbcf134259b743ccbd93d187c6cdJim Laskey
74b3b1d5f097a4fbcf134259b743ccbd93d187c6cdJim Laskey//
754222d806faae71ecc794cfdaa873817873c2f3d8Bill Wendling// FeatureKeyValues - Emit data of all the subtarget features.  Used by the
764222d806faae71ecc794cfdaa873817873c2f3d8Bill Wendling// command line.
77b3b1d5f097a4fbcf134259b743ccbd93d187c6cdJim Laskey//
78b3b1d5f097a4fbcf134259b743ccbd93d187c6cdJim Laskeyvoid SubtargetEmitter::FeatureKeyValues(std::ostream &OS) {
79908ae27a9073e2f105f8a0a4dd092d7fea8472a4Jim Laskey  // Gather and sort all the features
80f7bcde085440d1fd90eba8980ed9c512bc58824dJim Laskey  std::vector<Record*> FeatureList =
81f7bcde085440d1fd90eba8980ed9c512bc58824dJim Laskey                           Records.getAllDerivedDefinitions("SubtargetFeature");
8242d24c71df88178eacf244a38b6c48847ee0d39bDuraid Madina  std::sort(FeatureList.begin(), FeatureList.end(), LessRecord());
83b3b1d5f097a4fbcf134259b743ccbd93d187c6cdJim Laskey
84908ae27a9073e2f105f8a0a4dd092d7fea8472a4Jim Laskey  // Begin feature table
85581a8f79bc1ac3cbe5d621f0b4a0252ab2890bc1Jim Laskey  OS << "// Sorted (by key) array of values for CPU features.\n"
86b3b1d5f097a4fbcf134259b743ccbd93d187c6cdJim Laskey     << "static llvm::SubtargetFeatureKV FeatureKV[] = {\n";
87908ae27a9073e2f105f8a0a4dd092d7fea8472a4Jim Laskey
88908ae27a9073e2f105f8a0a4dd092d7fea8472a4Jim Laskey  // For each feature
89dbe4006cf3cf0802dc318a5f2070c04c326e170bJim Laskey  for (unsigned i = 0, N = FeatureList.size(); i < N; ++i) {
90f7bcde085440d1fd90eba8980ed9c512bc58824dJim Laskey    // Next feature
91f7bcde085440d1fd90eba8980ed9c512bc58824dJim Laskey    Record *Feature = FeatureList[i];
92f7bcde085440d1fd90eba8980ed9c512bc58824dJim Laskey
934222d806faae71ecc794cfdaa873817873c2f3d8Bill Wendling    const std::string &Name = Feature->getName();
944222d806faae71ecc794cfdaa873817873c2f3d8Bill Wendling    const std::string &CommandLineName = Feature->getValueAsString("Name");
954222d806faae71ecc794cfdaa873817873c2f3d8Bill Wendling    const std::string &Desc = Feature->getValueAsString("Desc");
96908ae27a9073e2f105f8a0a4dd092d7fea8472a4Jim Laskey
97dbe4006cf3cf0802dc318a5f2070c04c326e170bJim Laskey    if (CommandLineName.empty()) continue;
98dbe4006cf3cf0802dc318a5f2070c04c326e170bJim Laskey
994222d806faae71ecc794cfdaa873817873c2f3d8Bill Wendling    // Emit as { "feature", "decription", feactureEnum, i1 | i2 | ... | in }
100b3b1d5f097a4fbcf134259b743ccbd93d187c6cdJim Laskey    OS << "  { "
101f7bcde085440d1fd90eba8980ed9c512bc58824dJim Laskey       << "\"" << CommandLineName << "\", "
102b3b1d5f097a4fbcf134259b743ccbd93d187c6cdJim Laskey       << "\"" << Desc << "\", "
1034222d806faae71ecc794cfdaa873817873c2f3d8Bill Wendling       << Name << ", ";
1044222d806faae71ecc794cfdaa873817873c2f3d8Bill Wendling
1054222d806faae71ecc794cfdaa873817873c2f3d8Bill Wendling    const std::vector<Record*> &ImpliesList =
1064222d806faae71ecc794cfdaa873817873c2f3d8Bill Wendling      Feature->getValueAsListOfDefs("Implies");
1074222d806faae71ecc794cfdaa873817873c2f3d8Bill Wendling
1084222d806faae71ecc794cfdaa873817873c2f3d8Bill Wendling    if (ImpliesList.empty()) {
1094222d806faae71ecc794cfdaa873817873c2f3d8Bill Wendling      OS << "0";
1104222d806faae71ecc794cfdaa873817873c2f3d8Bill Wendling    } else {
1114222d806faae71ecc794cfdaa873817873c2f3d8Bill Wendling      for (unsigned j = 0, M = ImpliesList.size(); j < M;) {
1124222d806faae71ecc794cfdaa873817873c2f3d8Bill Wendling        OS << ImpliesList[j]->getName();
1134222d806faae71ecc794cfdaa873817873c2f3d8Bill Wendling        if (++j < M) OS << " | ";
1144222d806faae71ecc794cfdaa873817873c2f3d8Bill Wendling      }
1154222d806faae71ecc794cfdaa873817873c2f3d8Bill Wendling    }
1164222d806faae71ecc794cfdaa873817873c2f3d8Bill Wendling
1174222d806faae71ecc794cfdaa873817873c2f3d8Bill Wendling    OS << " }";
118f7bcde085440d1fd90eba8980ed9c512bc58824dJim Laskey
11910b1dd99f342d2d7af51dd43f3840f3bf40b0b87Jim Laskey    // Depending on 'if more in the list' emit comma
120dbe4006cf3cf0802dc318a5f2070c04c326e170bJim Laskey    if ((i + 1) < N) OS << ",";
121f7bcde085440d1fd90eba8980ed9c512bc58824dJim Laskey
122f7bcde085440d1fd90eba8980ed9c512bc58824dJim Laskey    OS << "\n";
123b3b1d5f097a4fbcf134259b743ccbd93d187c6cdJim Laskey  }
124908ae27a9073e2f105f8a0a4dd092d7fea8472a4Jim Laskey
125908ae27a9073e2f105f8a0a4dd092d7fea8472a4Jim Laskey  // End feature table
126b3b1d5f097a4fbcf134259b743ccbd93d187c6cdJim Laskey  OS << "};\n";
127b3b1d5f097a4fbcf134259b743ccbd93d187c6cdJim Laskey
128908ae27a9073e2f105f8a0a4dd092d7fea8472a4Jim Laskey  // Emit size of table
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) {
139908ae27a9073e2f105f8a0a4dd092d7fea8472a4Jim Laskey  // Gather and sort processor information
140f7bcde085440d1fd90eba8980ed9c512bc58824dJim Laskey  std::vector<Record*> ProcessorList =
141f7bcde085440d1fd90eba8980ed9c512bc58824dJim Laskey                          Records.getAllDerivedDefinitions("Processor");
14242d24c71df88178eacf244a38b6c48847ee0d39bDuraid Madina  std::sort(ProcessorList.begin(), ProcessorList.end(), LessRecordFieldName());
143b3b1d5f097a4fbcf134259b743ccbd93d187c6cdJim Laskey
144908ae27a9073e2f105f8a0a4dd092d7fea8472a4Jim Laskey  // Begin processor table
145581a8f79bc1ac3cbe5d621f0b4a0252ab2890bc1Jim Laskey  OS << "// Sorted (by key) array of values for CPU subtype.\n"
146b3b1d5f097a4fbcf134259b743ccbd93d187c6cdJim Laskey     << "static const llvm::SubtargetFeatureKV SubTypeKV[] = {\n";
147908ae27a9073e2f105f8a0a4dd092d7fea8472a4Jim Laskey
148908ae27a9073e2f105f8a0a4dd092d7fea8472a4Jim Laskey  // For each processor
149f7bcde085440d1fd90eba8980ed9c512bc58824dJim Laskey  for (unsigned i = 0, N = ProcessorList.size(); i < N;) {
150f7bcde085440d1fd90eba8980ed9c512bc58824dJim Laskey    // Next processor
151f7bcde085440d1fd90eba8980ed9c512bc58824dJim Laskey    Record *Processor = ProcessorList[i];
152f7bcde085440d1fd90eba8980ed9c512bc58824dJim Laskey
1534222d806faae71ecc794cfdaa873817873c2f3d8Bill Wendling    const std::string &Name = Processor->getValueAsString("Name");
1544222d806faae71ecc794cfdaa873817873c2f3d8Bill Wendling    const std::vector<Record*> &FeatureList =
155b0e103d46bf8799ac5523157a6ed4a78d1751a89Chris Lattner      Processor->getValueAsListOfDefs("Features");
1560d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey
157908ae27a9073e2f105f8a0a4dd092d7fea8472a4Jim Laskey    // Emit as { "cpu", "description", f1 | f2 | ... fn },
158b3b1d5f097a4fbcf134259b743ccbd93d187c6cdJim Laskey    OS << "  { "
159b3b1d5f097a4fbcf134259b743ccbd93d187c6cdJim Laskey       << "\"" << Name << "\", "
160b3b1d5f097a4fbcf134259b743ccbd93d187c6cdJim Laskey       << "\"Select the " << Name << " processor\", ";
161b3b1d5f097a4fbcf134259b743ccbd93d187c6cdJim Laskey
162f7bcde085440d1fd90eba8980ed9c512bc58824dJim Laskey    if (FeatureList.empty()) {
163b3b1d5f097a4fbcf134259b743ccbd93d187c6cdJim Laskey      OS << "0";
164b3b1d5f097a4fbcf134259b743ccbd93d187c6cdJim Laskey    } else {
165f7bcde085440d1fd90eba8980ed9c512bc58824dJim Laskey      for (unsigned j = 0, M = FeatureList.size(); j < M;) {
1664222d806faae71ecc794cfdaa873817873c2f3d8Bill Wendling        OS << FeatureList[j]->getName();
167f7bcde085440d1fd90eba8980ed9c512bc58824dJim Laskey        if (++j < M) OS << " | ";
1684bb9cbb73075c350eadaf51d2dab8403764c9a60Jim Laskey      }
1694bb9cbb73075c350eadaf51d2dab8403764c9a60Jim Laskey    }
170b3b1d5f097a4fbcf134259b743ccbd93d187c6cdJim Laskey
1714222d806faae71ecc794cfdaa873817873c2f3d8Bill Wendling    // The "0" is for the "implies" section of this data structure.
1724222d806faae71ecc794cfdaa873817873c2f3d8Bill Wendling    OS << ", 0 }";
173f7bcde085440d1fd90eba8980ed9c512bc58824dJim Laskey
17410b1dd99f342d2d7af51dd43f3840f3bf40b0b87Jim Laskey    // Depending on 'if more in the list' emit comma
175f7bcde085440d1fd90eba8980ed9c512bc58824dJim Laskey    if (++i < N) OS << ",";
176f7bcde085440d1fd90eba8980ed9c512bc58824dJim Laskey
177f7bcde085440d1fd90eba8980ed9c512bc58824dJim Laskey    OS << "\n";
1784bb9cbb73075c350eadaf51d2dab8403764c9a60Jim Laskey  }
179908ae27a9073e2f105f8a0a4dd092d7fea8472a4Jim Laskey
180908ae27a9073e2f105f8a0a4dd092d7fea8472a4Jim Laskey  // End processor table
181b3b1d5f097a4fbcf134259b743ccbd93d187c6cdJim Laskey  OS << "};\n";
182b3b1d5f097a4fbcf134259b743ccbd93d187c6cdJim Laskey
183908ae27a9073e2f105f8a0a4dd092d7fea8472a4Jim Laskey  // Emit size of table
184d4d079785187ce923edc245aee527e4768b1d180Chris Lattner  OS<<"\nenum {\n";
185d4d079785187ce923edc245aee527e4768b1d180Chris Lattner  OS<<"  SubTypeKVSize = sizeof(SubTypeKV)/sizeof(llvm::SubtargetFeatureKV)\n";
186d4d079785187ce923edc245aee527e4768b1d180Chris Lattner  OS<<"};\n";
1874bb9cbb73075c350eadaf51d2dab8403764c9a60Jim Laskey}
188b3b1d5f097a4fbcf134259b743ccbd93d187c6cdJim Laskey
189581a8f79bc1ac3cbe5d621f0b4a0252ab2890bc1Jim Laskey//
1900d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey// CollectAllItinClasses - Gathers and enumerates all the itinerary classes.
191908ae27a9073e2f105f8a0a4dd092d7fea8472a4Jim Laskey// Returns itinerary class count.
1920d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey//
1936cee630070b1a7183ed56a8404e812629f5ca538Jim Laskeyunsigned SubtargetEmitter::CollectAllItinClasses(std::ostream &OS,
1946cee630070b1a7183ed56a8404e812629f5ca538Jim Laskey                              std::map<std::string, unsigned> &ItinClassesMap) {
195908ae27a9073e2f105f8a0a4dd092d7fea8472a4Jim Laskey  // Gather and sort all itinerary classes
196f7bcde085440d1fd90eba8980ed9c512bc58824dJim Laskey  std::vector<Record*> ItinClassList =
197f7bcde085440d1fd90eba8980ed9c512bc58824dJim Laskey                            Records.getAllDerivedDefinitions("InstrItinClass");
19842d24c71df88178eacf244a38b6c48847ee0d39bDuraid Madina  std::sort(ItinClassList.begin(), ItinClassList.end(), LessRecord());
199f7bcde085440d1fd90eba8980ed9c512bc58824dJim Laskey
200f7bcde085440d1fd90eba8980ed9c512bc58824dJim Laskey  // For each itinerary class
201f7bcde085440d1fd90eba8980ed9c512bc58824dJim Laskey  unsigned N = ItinClassList.size();
202f7bcde085440d1fd90eba8980ed9c512bc58824dJim Laskey  for (unsigned i = 0; i < N; i++) {
203f7bcde085440d1fd90eba8980ed9c512bc58824dJim Laskey    // Next itinerary class
2044222d806faae71ecc794cfdaa873817873c2f3d8Bill Wendling    const Record *ItinClass = ItinClassList[i];
205908ae27a9073e2f105f8a0a4dd092d7fea8472a4Jim Laskey    // Get name of itinerary class
206908ae27a9073e2f105f8a0a4dd092d7fea8472a4Jim Laskey    // Assign itinerary class a unique number
2074222d806faae71ecc794cfdaa873817873c2f3d8Bill Wendling    ItinClassesMap[ItinClass->getName()] = i;
2080d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey  }
2090d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey
2106cee630070b1a7183ed56a8404e812629f5ca538Jim Laskey  // Emit size of table
2116cee630070b1a7183ed56a8404e812629f5ca538Jim Laskey  OS<<"\nenum {\n";
2126cee630070b1a7183ed56a8404e812629f5ca538Jim Laskey  OS<<"  ItinClassesSize = " << N << "\n";
2136cee630070b1a7183ed56a8404e812629f5ca538Jim Laskey  OS<<"};\n";
2146cee630070b1a7183ed56a8404e812629f5ca538Jim Laskey
215908ae27a9073e2f105f8a0a4dd092d7fea8472a4Jim Laskey  // Return itinerary class count
216f7bcde085440d1fd90eba8980ed9c512bc58824dJim Laskey  return N;
2170d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey}
2180d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey
2190d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey//
2200d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey// FormItineraryString - Compose a string containing the data initialization
2210d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey// for the specified itinerary.  N is the number of stages.
2220d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey//
2230d841e05677bdc55d003720e85e12d28dfe31862Jim Laskeyvoid SubtargetEmitter::FormItineraryString(Record *ItinData,
2240d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey                                           std::string &ItinString,
225f7bcde085440d1fd90eba8980ed9c512bc58824dJim Laskey                                           unsigned &NStages) {
226f7bcde085440d1fd90eba8980ed9c512bc58824dJim Laskey  // Get states list
2274222d806faae71ecc794cfdaa873817873c2f3d8Bill Wendling  const std::vector<Record*> &StageList =
2284222d806faae71ecc794cfdaa873817873c2f3d8Bill Wendling    ItinData->getValueAsListOfDefs("Stages");
229908ae27a9073e2f105f8a0a4dd092d7fea8472a4Jim Laskey
230908ae27a9073e2f105f8a0a4dd092d7fea8472a4Jim Laskey  // For each stage
231f7bcde085440d1fd90eba8980ed9c512bc58824dJim Laskey  unsigned N = NStages = StageList.size();
2328dadf6b13a7cdd5b5b30c3b7af310c9756e4c68eChristopher Lamb  for (unsigned i = 0; i < N;) {
233f7bcde085440d1fd90eba8980ed9c512bc58824dJim Laskey    // Next stage
2344222d806faae71ecc794cfdaa873817873c2f3d8Bill Wendling    const Record *Stage = StageList[i];
235f7bcde085440d1fd90eba8980ed9c512bc58824dJim Laskey
236908ae27a9073e2f105f8a0a4dd092d7fea8472a4Jim Laskey    // Form string as ,{ cycles, u1 | u2 | ... | un }
2370d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey    int Cycles = Stage->getValueAsInt("Cycles");
2387f39c14f52262a154285df9180f5edcdabe2d7dfJim Laskey    ItinString += "  { " + itostr(Cycles) + ", ";
2390d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey
240f7bcde085440d1fd90eba8980ed9c512bc58824dJim Laskey    // Get unit list
2414222d806faae71ecc794cfdaa873817873c2f3d8Bill Wendling    const std::vector<Record*> &UnitList = Stage->getValueAsListOfDefs("Units");
242f7bcde085440d1fd90eba8980ed9c512bc58824dJim Laskey
243908ae27a9073e2f105f8a0a4dd092d7fea8472a4Jim Laskey    // For each unit
244f7bcde085440d1fd90eba8980ed9c512bc58824dJim Laskey    for (unsigned j = 0, M = UnitList.size(); j < M;) {
245f7bcde085440d1fd90eba8980ed9c512bc58824dJim Laskey      // Add name and bitwise or
2464222d806faae71ecc794cfdaa873817873c2f3d8Bill Wendling      ItinString += UnitList[j]->getName();
247f7bcde085440d1fd90eba8980ed9c512bc58824dJim Laskey      if (++j < M) ItinString += " | ";
2480d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey    }
249908ae27a9073e2f105f8a0a4dd092d7fea8472a4Jim Laskey
250908ae27a9073e2f105f8a0a4dd092d7fea8472a4Jim Laskey    // Close off stage
251908ae27a9073e2f105f8a0a4dd092d7fea8472a4Jim Laskey    ItinString += " }";
2528dadf6b13a7cdd5b5b30c3b7af310c9756e4c68eChristopher Lamb    if (++i < N) ItinString += ", ";
2530d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey  }
2540d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey}
2550d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey
2560d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey//
2570d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey// EmitStageData - Generate unique itinerary stages.  Record itineraries for
2580d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey// processors.
2590d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey//
2600d841e05677bdc55d003720e85e12d28dfe31862Jim Laskeyvoid SubtargetEmitter::EmitStageData(std::ostream &OS,
261f7bcde085440d1fd90eba8980ed9c512bc58824dJim Laskey       unsigned NItinClasses,
262f7bcde085440d1fd90eba8980ed9c512bc58824dJim Laskey       std::map<std::string, unsigned> &ItinClassesMap,
263f7bcde085440d1fd90eba8980ed9c512bc58824dJim Laskey       std::vector<std::vector<InstrItinerary> > &ProcList) {
264908ae27a9073e2f105f8a0a4dd092d7fea8472a4Jim Laskey  // Gather processor iteraries
265f7bcde085440d1fd90eba8980ed9c512bc58824dJim Laskey  std::vector<Record*> ProcItinList =
266f7bcde085440d1fd90eba8980ed9c512bc58824dJim Laskey                       Records.getAllDerivedDefinitions("ProcessorItineraries");
267908ae27a9073e2f105f8a0a4dd092d7fea8472a4Jim Laskey
268908ae27a9073e2f105f8a0a4dd092d7fea8472a4Jim Laskey  // If just no itinerary then don't bother
269f7bcde085440d1fd90eba8980ed9c512bc58824dJim Laskey  if (ProcItinList.size() < 2) return;
270908ae27a9073e2f105f8a0a4dd092d7fea8472a4Jim Laskey
271908ae27a9073e2f105f8a0a4dd092d7fea8472a4Jim Laskey  // Begin stages table
2720d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey  OS << "static llvm::InstrStage Stages[] = {\n"
2737f39c14f52262a154285df9180f5edcdabe2d7dfJim Laskey        "  { 0, 0 }, // No itinerary\n";
2740d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey
275f7bcde085440d1fd90eba8980ed9c512bc58824dJim Laskey  unsigned ItinEnum = 1;
276f7bcde085440d1fd90eba8980ed9c512bc58824dJim Laskey  std::map<std::string, unsigned> ItinMap;
277f7bcde085440d1fd90eba8980ed9c512bc58824dJim Laskey  for (unsigned i = 0, N = ProcItinList.size(); i < N; i++) {
278f7bcde085440d1fd90eba8980ed9c512bc58824dJim Laskey    // Next record
279f7bcde085440d1fd90eba8980ed9c512bc58824dJim Laskey    Record *Proc = ProcItinList[i];
280f7bcde085440d1fd90eba8980ed9c512bc58824dJim Laskey
281908ae27a9073e2f105f8a0a4dd092d7fea8472a4Jim Laskey    // Get processor itinerary name
2824222d806faae71ecc794cfdaa873817873c2f3d8Bill Wendling    const std::string &Name = Proc->getName();
283908ae27a9073e2f105f8a0a4dd092d7fea8472a4Jim Laskey
284908ae27a9073e2f105f8a0a4dd092d7fea8472a4Jim Laskey    // Skip default
2850d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey    if (Name == "NoItineraries") continue;
2860d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey
287908ae27a9073e2f105f8a0a4dd092d7fea8472a4Jim Laskey    // Create and expand processor itinerary to cover all itinerary classes
288f7bcde085440d1fd90eba8980ed9c512bc58824dJim Laskey    std::vector<InstrItinerary> ItinList;
289f7bcde085440d1fd90eba8980ed9c512bc58824dJim Laskey    ItinList.resize(NItinClasses);
290f7bcde085440d1fd90eba8980ed9c512bc58824dJim Laskey
291f7bcde085440d1fd90eba8980ed9c512bc58824dJim Laskey    // Get itinerary data list
292b0e103d46bf8799ac5523157a6ed4a78d1751a89Chris Lattner    std::vector<Record*> ItinDataList = Proc->getValueAsListOfDefs("IID");
2930d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey
294f7bcde085440d1fd90eba8980ed9c512bc58824dJim Laskey    // For each itinerary data
295f7bcde085440d1fd90eba8980ed9c512bc58824dJim Laskey    for (unsigned j = 0, M = ItinDataList.size(); j < M; j++) {
296f7bcde085440d1fd90eba8980ed9c512bc58824dJim Laskey      // Next itinerary data
297f7bcde085440d1fd90eba8980ed9c512bc58824dJim Laskey      Record *ItinData = ItinDataList[j];
298f7bcde085440d1fd90eba8980ed9c512bc58824dJim Laskey
299908ae27a9073e2f105f8a0a4dd092d7fea8472a4Jim Laskey      // Get string and stage count
3000d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey      std::string ItinString;
301f7bcde085440d1fd90eba8980ed9c512bc58824dJim Laskey      unsigned NStages;
302f7bcde085440d1fd90eba8980ed9c512bc58824dJim Laskey      FormItineraryString(ItinData, ItinString, NStages);
3030d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey
304908ae27a9073e2f105f8a0a4dd092d7fea8472a4Jim Laskey      // Check to see if it already exists
3050d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey      unsigned Find = ItinMap[ItinString];
3060d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey
307908ae27a9073e2f105f8a0a4dd092d7fea8472a4Jim Laskey      // If new itinerary
3080d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey      if (Find == 0) {
3097f39c14f52262a154285df9180f5edcdabe2d7dfJim Laskey        // Emit as { cycles, u1 | u2 | ... | un }, // index
3107f39c14f52262a154285df9180f5edcdabe2d7dfJim Laskey        OS << ItinString << ", // " << ItinEnum << "\n";
3117f39c14f52262a154285df9180f5edcdabe2d7dfJim Laskey        // Record Itin class number
312f7bcde085440d1fd90eba8980ed9c512bc58824dJim Laskey        ItinMap[ItinString] = Find = ItinEnum++;
3130d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey      }
3140d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey
315908ae27a9073e2f105f8a0a4dd092d7fea8472a4Jim Laskey      // Set up itinerary as location and location + stage count
316f7bcde085440d1fd90eba8980ed9c512bc58824dJim Laskey      InstrItinerary Intinerary = { Find, Find + NStages };
3170d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey
318908ae27a9073e2f105f8a0a4dd092d7fea8472a4Jim Laskey      // Locate where to inject into processor itinerary table
3194222d806faae71ecc794cfdaa873817873c2f3d8Bill Wendling      const std::string &Name = ItinData->getValueAsDef("TheClass")->getName();
3200d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey      Find = ItinClassesMap[Name];
321908ae27a9073e2f105f8a0a4dd092d7fea8472a4Jim Laskey
322908ae27a9073e2f105f8a0a4dd092d7fea8472a4Jim Laskey      // Inject - empty slots will be 0, 0
323f7bcde085440d1fd90eba8980ed9c512bc58824dJim Laskey      ItinList[Find] = Intinerary;
3240d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey    }
3250d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey
326908ae27a9073e2f105f8a0a4dd092d7fea8472a4Jim Laskey    // Add process itinerary to list
327f7bcde085440d1fd90eba8980ed9c512bc58824dJim Laskey    ProcList.push_back(ItinList);
3280d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey  }
3290d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey
3307f39c14f52262a154285df9180f5edcdabe2d7dfJim Laskey  // Closing stage
3317f39c14f52262a154285df9180f5edcdabe2d7dfJim Laskey  OS << "  { 0, 0 } // End itinerary\n";
332908ae27a9073e2f105f8a0a4dd092d7fea8472a4Jim Laskey  // End stages table
3330d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey  OS << "};\n";
3346cee630070b1a7183ed56a8404e812629f5ca538Jim Laskey
3356cee630070b1a7183ed56a8404e812629f5ca538Jim Laskey  // Emit size of table
3366cee630070b1a7183ed56a8404e812629f5ca538Jim Laskey  OS<<"\nenum {\n";
3376cee630070b1a7183ed56a8404e812629f5ca538Jim Laskey  OS<<"  StagesSize = sizeof(Stages)/sizeof(llvm::InstrStage)\n";
3386cee630070b1a7183ed56a8404e812629f5ca538Jim Laskey  OS<<"};\n";
3390d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey}
3400d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey
3410d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey//
34210b1dd99f342d2d7af51dd43f3840f3bf40b0b87Jim Laskey// EmitProcessorData - Generate data for processor itineraries.
3430d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey//
34410b1dd99f342d2d7af51dd43f3840f3bf40b0b87Jim Laskeyvoid SubtargetEmitter::EmitProcessorData(std::ostream &OS,
345f7bcde085440d1fd90eba8980ed9c512bc58824dJim Laskey      std::vector<std::vector<InstrItinerary> > &ProcList) {
346908ae27a9073e2f105f8a0a4dd092d7fea8472a4Jim Laskey  // Get an iterator for processor itinerary stages
347f7bcde085440d1fd90eba8980ed9c512bc58824dJim Laskey  std::vector<std::vector<InstrItinerary> >::iterator
348f7bcde085440d1fd90eba8980ed9c512bc58824dJim Laskey      ProcListIter = ProcList.begin();
349908ae27a9073e2f105f8a0a4dd092d7fea8472a4Jim Laskey
350908ae27a9073e2f105f8a0a4dd092d7fea8472a4Jim Laskey  // For each processor itinerary
351f7bcde085440d1fd90eba8980ed9c512bc58824dJim Laskey  std::vector<Record*> Itins =
352f7bcde085440d1fd90eba8980ed9c512bc58824dJim Laskey                       Records.getAllDerivedDefinitions("ProcessorItineraries");
353f7bcde085440d1fd90eba8980ed9c512bc58824dJim Laskey  for (unsigned i = 0, N = Itins.size(); i < N; i++) {
354f7bcde085440d1fd90eba8980ed9c512bc58824dJim Laskey    // Next record
355f7bcde085440d1fd90eba8980ed9c512bc58824dJim Laskey    Record *Itin = Itins[i];
356f7bcde085440d1fd90eba8980ed9c512bc58824dJim Laskey
357908ae27a9073e2f105f8a0a4dd092d7fea8472a4Jim Laskey    // Get processor itinerary name
3584222d806faae71ecc794cfdaa873817873c2f3d8Bill Wendling    const std::string &Name = Itin->getName();
359908ae27a9073e2f105f8a0a4dd092d7fea8472a4Jim Laskey
360908ae27a9073e2f105f8a0a4dd092d7fea8472a4Jim Laskey    // Skip default
3610d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey    if (Name == "NoItineraries") continue;
3620d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey
363908ae27a9073e2f105f8a0a4dd092d7fea8472a4Jim Laskey    // Begin processor itinerary table
3640d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey    OS << "\n";
3650d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey    OS << "static llvm::InstrItinerary " << Name << "[] = {\n";
3660d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey
367908ae27a9073e2f105f8a0a4dd092d7fea8472a4Jim Laskey    // For each itinerary class
368f7bcde085440d1fd90eba8980ed9c512bc58824dJim Laskey    std::vector<InstrItinerary> &ItinList = *ProcListIter++;
369f7bcde085440d1fd90eba8980ed9c512bc58824dJim Laskey    for (unsigned j = 0, M = ItinList.size(); j < M;) {
370f7bcde085440d1fd90eba8980ed9c512bc58824dJim Laskey      InstrItinerary &Intinerary = ItinList[j];
3710d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey
372908ae27a9073e2f105f8a0a4dd092d7fea8472a4Jim Laskey      // Emit in the form of { first, last } // index
3730d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey      if (Intinerary.First == 0) {
3740d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey        OS << "  { 0, 0 }";
3750d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey      } else {
3760d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey        OS << "  { " << Intinerary.First << ", " << Intinerary.Last << " }";
3770d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey      }
3780d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey
379f7bcde085440d1fd90eba8980ed9c512bc58824dJim Laskey      // If more in list add comma
380f7bcde085440d1fd90eba8980ed9c512bc58824dJim Laskey      if (++j < M) OS << ",";
381f7bcde085440d1fd90eba8980ed9c512bc58824dJim Laskey
382f7bcde085440d1fd90eba8980ed9c512bc58824dJim Laskey      OS << " // " << (j - 1) << "\n";
3830d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey    }
384908ae27a9073e2f105f8a0a4dd092d7fea8472a4Jim Laskey
385908ae27a9073e2f105f8a0a4dd092d7fea8472a4Jim Laskey    // End processor itinerary table
3860d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey    OS << "};\n";
3870d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey  }
38810b1dd99f342d2d7af51dd43f3840f3bf40b0b87Jim Laskey}
38910b1dd99f342d2d7af51dd43f3840f3bf40b0b87Jim Laskey
39010b1dd99f342d2d7af51dd43f3840f3bf40b0b87Jim Laskey//
39110b1dd99f342d2d7af51dd43f3840f3bf40b0b87Jim Laskey// EmitProcessorLookup - generate cpu name to itinerary lookup table.
39210b1dd99f342d2d7af51dd43f3840f3bf40b0b87Jim Laskey//
39310b1dd99f342d2d7af51dd43f3840f3bf40b0b87Jim Laskeyvoid SubtargetEmitter::EmitProcessorLookup(std::ostream &OS) {
39410b1dd99f342d2d7af51dd43f3840f3bf40b0b87Jim Laskey  // Gather and sort processor information
39510b1dd99f342d2d7af51dd43f3840f3bf40b0b87Jim Laskey  std::vector<Record*> ProcessorList =
39610b1dd99f342d2d7af51dd43f3840f3bf40b0b87Jim Laskey                          Records.getAllDerivedDefinitions("Processor");
39742d24c71df88178eacf244a38b6c48847ee0d39bDuraid Madina  std::sort(ProcessorList.begin(), ProcessorList.end(), LessRecordFieldName());
39810b1dd99f342d2d7af51dd43f3840f3bf40b0b87Jim Laskey
39910b1dd99f342d2d7af51dd43f3840f3bf40b0b87Jim Laskey  // Begin processor table
40010b1dd99f342d2d7af51dd43f3840f3bf40b0b87Jim Laskey  OS << "\n";
40110b1dd99f342d2d7af51dd43f3840f3bf40b0b87Jim Laskey  OS << "// Sorted (by key) array of itineraries for CPU subtype.\n"
4027f39c14f52262a154285df9180f5edcdabe2d7dfJim Laskey     << "static const llvm::SubtargetInfoKV ProcItinKV[] = {\n";
40310b1dd99f342d2d7af51dd43f3840f3bf40b0b87Jim Laskey
40410b1dd99f342d2d7af51dd43f3840f3bf40b0b87Jim Laskey  // For each processor
40510b1dd99f342d2d7af51dd43f3840f3bf40b0b87Jim Laskey  for (unsigned i = 0, N = ProcessorList.size(); i < N;) {
40610b1dd99f342d2d7af51dd43f3840f3bf40b0b87Jim Laskey    // Next processor
40710b1dd99f342d2d7af51dd43f3840f3bf40b0b87Jim Laskey    Record *Processor = ProcessorList[i];
40810b1dd99f342d2d7af51dd43f3840f3bf40b0b87Jim Laskey
4094222d806faae71ecc794cfdaa873817873c2f3d8Bill Wendling    const std::string &Name = Processor->getValueAsString("Name");
4104222d806faae71ecc794cfdaa873817873c2f3d8Bill Wendling    const std::string &ProcItin =
4114222d806faae71ecc794cfdaa873817873c2f3d8Bill Wendling      Processor->getValueAsDef("ProcItin")->getName();
41210b1dd99f342d2d7af51dd43f3840f3bf40b0b87Jim Laskey
41310b1dd99f342d2d7af51dd43f3840f3bf40b0b87Jim Laskey    // Emit as { "cpu", procinit },
41410b1dd99f342d2d7af51dd43f3840f3bf40b0b87Jim Laskey    OS << "  { "
41510b1dd99f342d2d7af51dd43f3840f3bf40b0b87Jim Laskey       << "\"" << Name << "\", "
41610b1dd99f342d2d7af51dd43f3840f3bf40b0b87Jim Laskey       << "(void *)&" << ProcItin;
41710b1dd99f342d2d7af51dd43f3840f3bf40b0b87Jim Laskey
41810b1dd99f342d2d7af51dd43f3840f3bf40b0b87Jim Laskey    OS << " }";
41910b1dd99f342d2d7af51dd43f3840f3bf40b0b87Jim Laskey
42010b1dd99f342d2d7af51dd43f3840f3bf40b0b87Jim Laskey    // Depending on ''if more in the list'' emit comma
42110b1dd99f342d2d7af51dd43f3840f3bf40b0b87Jim Laskey    if (++i < N) OS << ",";
42210b1dd99f342d2d7af51dd43f3840f3bf40b0b87Jim Laskey
42310b1dd99f342d2d7af51dd43f3840f3bf40b0b87Jim Laskey    OS << "\n";
42410b1dd99f342d2d7af51dd43f3840f3bf40b0b87Jim Laskey  }
42510b1dd99f342d2d7af51dd43f3840f3bf40b0b87Jim Laskey
42610b1dd99f342d2d7af51dd43f3840f3bf40b0b87Jim Laskey  // End processor table
42710b1dd99f342d2d7af51dd43f3840f3bf40b0b87Jim Laskey  OS << "};\n";
42810b1dd99f342d2d7af51dd43f3840f3bf40b0b87Jim Laskey
42910b1dd99f342d2d7af51dd43f3840f3bf40b0b87Jim Laskey  // Emit size of table
43010b1dd99f342d2d7af51dd43f3840f3bf40b0b87Jim Laskey  OS<<"\nenum {\n";
4317f39c14f52262a154285df9180f5edcdabe2d7dfJim Laskey  OS<<"  ProcItinKVSize = sizeof(ProcItinKV)/"
43210b1dd99f342d2d7af51dd43f3840f3bf40b0b87Jim Laskey                            "sizeof(llvm::SubtargetInfoKV)\n";
43310b1dd99f342d2d7af51dd43f3840f3bf40b0b87Jim Laskey  OS<<"};\n";
4340d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey}
4350d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey
4360d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey//
4370d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey// EmitData - Emits all stages and itineries, folding common patterns.
4380d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey//
4390d841e05677bdc55d003720e85e12d28dfe31862Jim Laskeyvoid SubtargetEmitter::EmitData(std::ostream &OS) {
440f7bcde085440d1fd90eba8980ed9c512bc58824dJim Laskey  std::map<std::string, unsigned> ItinClassesMap;
441f7bcde085440d1fd90eba8980ed9c512bc58824dJim Laskey  std::vector<std::vector<InstrItinerary> > ProcList;
4420d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey
443908ae27a9073e2f105f8a0a4dd092d7fea8472a4Jim Laskey  // Enumerate all the itinerary classes
4446cee630070b1a7183ed56a8404e812629f5ca538Jim Laskey  unsigned NItinClasses = CollectAllItinClasses(OS, ItinClassesMap);
4456cee630070b1a7183ed56a8404e812629f5ca538Jim Laskey  // Make sure the rest is worth the effort
446387e4bdf002c78a1b43a10e10cf5147baf32f513Chris Lattner  HasItineraries = NItinClasses != 1;   // Ignore NoItinerary.
4476cee630070b1a7183ed56a8404e812629f5ca538Jim Laskey
4486cee630070b1a7183ed56a8404e812629f5ca538Jim Laskey  if (HasItineraries) {
4496cee630070b1a7183ed56a8404e812629f5ca538Jim Laskey    // Emit the stage data
4506cee630070b1a7183ed56a8404e812629f5ca538Jim Laskey    EmitStageData(OS, NItinClasses, ItinClassesMap, ProcList);
4516cee630070b1a7183ed56a8404e812629f5ca538Jim Laskey    // Emit the processor itinerary data
4526cee630070b1a7183ed56a8404e812629f5ca538Jim Laskey    EmitProcessorData(OS, ProcList);
4536cee630070b1a7183ed56a8404e812629f5ca538Jim Laskey    // Emit the processor lookup data
4546cee630070b1a7183ed56a8404e812629f5ca538Jim Laskey    EmitProcessorLookup(OS);
4556cee630070b1a7183ed56a8404e812629f5ca538Jim Laskey  }
4560d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey}
4570d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey
4580d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey//
459581a8f79bc1ac3cbe5d621f0b4a0252ab2890bc1Jim Laskey// ParseFeaturesFunction - Produces a subtarget specific function for parsing
460581a8f79bc1ac3cbe5d621f0b4a0252ab2890bc1Jim Laskey// the subtarget features string.
461581a8f79bc1ac3cbe5d621f0b4a0252ab2890bc1Jim Laskey//
462581a8f79bc1ac3cbe5d621f0b4a0252ab2890bc1Jim Laskeyvoid SubtargetEmitter::ParseFeaturesFunction(std::ostream &OS) {
463f7bcde085440d1fd90eba8980ed9c512bc58824dJim Laskey  std::vector<Record*> Features =
464f7bcde085440d1fd90eba8980ed9c512bc58824dJim Laskey                       Records.getAllDerivedDefinitions("SubtargetFeature");
46542d24c71df88178eacf244a38b6c48847ee0d39bDuraid Madina  std::sort(Features.begin(), Features.end(), LessRecord());
466581a8f79bc1ac3cbe5d621f0b4a0252ab2890bc1Jim Laskey
467581a8f79bc1ac3cbe5d621f0b4a0252ab2890bc1Jim Laskey  OS << "// ParseSubtargetFeatures - Parses features string setting specified\n"
4684222d806faae71ecc794cfdaa873817873c2f3d8Bill Wendling     << "// subtarget options.\n"
4694222d806faae71ecc794cfdaa873817873c2f3d8Bill Wendling     << "void llvm::";
470581a8f79bc1ac3cbe5d621f0b4a0252ab2890bc1Jim Laskey  OS << Target;
471581a8f79bc1ac3cbe5d621f0b4a0252ab2890bc1Jim Laskey  OS << "Subtarget::ParseSubtargetFeatures(const std::string &FS,\n"
4724222d806faae71ecc794cfdaa873817873c2f3d8Bill Wendling     << "                                  const std::string &CPU) {\n"
4734222d806faae71ecc794cfdaa873817873c2f3d8Bill Wendling     << "  SubtargetFeatures Features(FS);\n"
4744222d806faae71ecc794cfdaa873817873c2f3d8Bill Wendling     << "  Features.setCPUIfNone(CPU);\n"
4754222d806faae71ecc794cfdaa873817873c2f3d8Bill Wendling     << "  uint32_t Bits =  Features.getBits(SubTypeKV, SubTypeKVSize,\n"
4764222d806faae71ecc794cfdaa873817873c2f3d8Bill Wendling     << "                                    FeatureKV, FeatureKVSize);\n";
4774222d806faae71ecc794cfdaa873817873c2f3d8Bill Wendling
478f7bcde085440d1fd90eba8980ed9c512bc58824dJim Laskey  for (unsigned i = 0; i < Features.size(); i++) {
479f7bcde085440d1fd90eba8980ed9c512bc58824dJim Laskey    // Next record
480f7bcde085440d1fd90eba8980ed9c512bc58824dJim Laskey    Record *R = Features[i];
4814222d806faae71ecc794cfdaa873817873c2f3d8Bill Wendling    const std::string &Instance = R->getName();
4824222d806faae71ecc794cfdaa873817873c2f3d8Bill Wendling    const std::string &Value = R->getValueAsString("Value");
4834222d806faae71ecc794cfdaa873817873c2f3d8Bill Wendling    const std::string &Attribute = R->getValueAsString("Attribute");
48419c95507443ebd4f1cee80917d540c8bd27f8fe1Evan Cheng
485db01c8ba26f288636d3f574a96af3499ee6d2579Dale Johannesen    if (Value=="true" || Value=="false")
486db01c8ba26f288636d3f574a96af3499ee6d2579Dale Johannesen      OS << "  if ((Bits & " << Instance << ") != 0) "
487db01c8ba26f288636d3f574a96af3499ee6d2579Dale Johannesen         << Attribute << " = " << Value << ";\n";
488db01c8ba26f288636d3f574a96af3499ee6d2579Dale Johannesen    else
489db01c8ba26f288636d3f574a96af3499ee6d2579Dale Johannesen      OS << "  if ((Bits & " << Instance << ") != 0 && " << Attribute <<
490db01c8ba26f288636d3f574a96af3499ee6d2579Dale Johannesen            " < " << Value << ") " << Attribute << " = " << Value << ";\n";
491581a8f79bc1ac3cbe5d621f0b4a0252ab2890bc1Jim Laskey  }
4924222d806faae71ecc794cfdaa873817873c2f3d8Bill Wendling
4936cee630070b1a7183ed56a8404e812629f5ca538Jim Laskey  if (HasItineraries) {
4946cee630070b1a7183ed56a8404e812629f5ca538Jim Laskey    OS << "\n"
4956cee630070b1a7183ed56a8404e812629f5ca538Jim Laskey       << "  InstrItinerary *Itinerary = (InstrItinerary *)"
4964222d806faae71ecc794cfdaa873817873c2f3d8Bill Wendling       <<              "Features.getInfo(ProcItinKV, ProcItinKVSize);\n"
4974222d806faae71ecc794cfdaa873817873c2f3d8Bill Wendling       << "  InstrItins = InstrItineraryData(Stages, Itinerary);\n";
4986cee630070b1a7183ed56a8404e812629f5ca538Jim Laskey  }
4996cee630070b1a7183ed56a8404e812629f5ca538Jim Laskey
500581a8f79bc1ac3cbe5d621f0b4a0252ab2890bc1Jim Laskey  OS << "}\n";
501581a8f79bc1ac3cbe5d621f0b4a0252ab2890bc1Jim Laskey}
502581a8f79bc1ac3cbe5d621f0b4a0252ab2890bc1Jim Laskey
503b3b1d5f097a4fbcf134259b743ccbd93d187c6cdJim Laskey//
504b3b1d5f097a4fbcf134259b743ccbd93d187c6cdJim Laskey// SubtargetEmitter::run - Main subtarget enumeration emitter.
505b3b1d5f097a4fbcf134259b743ccbd93d187c6cdJim Laskey//
506b3b1d5f097a4fbcf134259b743ccbd93d187c6cdJim Laskeyvoid SubtargetEmitter::run(std::ostream &OS) {
5076c302fc0757c20a6de52a788ffc675e5c5980971Jim Laskey  Target = CodeGenTarget().getName();
508581a8f79bc1ac3cbe5d621f0b4a0252ab2890bc1Jim Laskey
509b3b1d5f097a4fbcf134259b743ccbd93d187c6cdJim Laskey  EmitSourceFileHeader("Subtarget Enumeration Source Fragment", OS);
510b3b1d5f097a4fbcf134259b743ccbd93d187c6cdJim Laskey
5110d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey  OS << "#include \"llvm/Target/SubtargetFeature.h\"\n";
5120d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey  OS << "#include \"llvm/Target/TargetInstrItineraries.h\"\n\n";
513b3b1d5f097a4fbcf134259b743ccbd93d187c6cdJim Laskey
514581a8f79bc1ac3cbe5d621f0b4a0252ab2890bc1Jim Laskey  Enumeration(OS, "FuncUnit", true);
515581a8f79bc1ac3cbe5d621f0b4a0252ab2890bc1Jim Laskey  OS<<"\n";
516908ae27a9073e2f105f8a0a4dd092d7fea8472a4Jim Laskey//  Enumeration(OS, "InstrItinClass", false);
517908ae27a9073e2f105f8a0a4dd092d7fea8472a4Jim Laskey//  OS<<"\n";
518581a8f79bc1ac3cbe5d621f0b4a0252ab2890bc1Jim Laskey  Enumeration(OS, "SubtargetFeature", true);
519581a8f79bc1ac3cbe5d621f0b4a0252ab2890bc1Jim Laskey  OS<<"\n";
520b3b1d5f097a4fbcf134259b743ccbd93d187c6cdJim Laskey  FeatureKeyValues(OS);
521581a8f79bc1ac3cbe5d621f0b4a0252ab2890bc1Jim Laskey  OS<<"\n";
522b3b1d5f097a4fbcf134259b743ccbd93d187c6cdJim Laskey  CPUKeyValues(OS);
523581a8f79bc1ac3cbe5d621f0b4a0252ab2890bc1Jim Laskey  OS<<"\n";
5240d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey  EmitData(OS);
5250d841e05677bdc55d003720e85e12d28dfe31862Jim Laskey  OS<<"\n";
526581a8f79bc1ac3cbe5d621f0b4a0252ab2890bc1Jim Laskey  ParseFeaturesFunction(OS);
527b3b1d5f097a4fbcf134259b743ccbd93d187c6cdJim Laskey}
528