1*9880d681SAndroid Build Coastguard Worker //===- SubtargetFeature.cpp - CPU characteristics Implementation ----------===//
2*9880d681SAndroid Build Coastguard Worker //
3*9880d681SAndroid Build Coastguard Worker // The LLVM Compiler Infrastructure
4*9880d681SAndroid Build Coastguard Worker //
5*9880d681SAndroid Build Coastguard Worker // This file is distributed under the University of Illinois Open Source
6*9880d681SAndroid Build Coastguard Worker // License. See LICENSE.TXT for details.
7*9880d681SAndroid Build Coastguard Worker //
8*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===//
9*9880d681SAndroid Build Coastguard Worker //
10*9880d681SAndroid Build Coastguard Worker // This file implements the SubtargetFeature interface.
11*9880d681SAndroid Build Coastguard Worker //
12*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===//
13*9880d681SAndroid Build Coastguard Worker
14*9880d681SAndroid Build Coastguard Worker #include "llvm/MC/SubtargetFeature.h"
15*9880d681SAndroid Build Coastguard Worker #include "llvm/ADT/ArrayRef.h"
16*9880d681SAndroid Build Coastguard Worker #include "llvm/ADT/StringExtras.h"
17*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/Debug.h"
18*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/Format.h"
19*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/raw_ostream.h"
20*9880d681SAndroid Build Coastguard Worker #include <algorithm>
21*9880d681SAndroid Build Coastguard Worker #include <cassert>
22*9880d681SAndroid Build Coastguard Worker #include <cctype>
23*9880d681SAndroid Build Coastguard Worker #include <cstdlib>
24*9880d681SAndroid Build Coastguard Worker using namespace llvm;
25*9880d681SAndroid Build Coastguard Worker
26*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===//
27*9880d681SAndroid Build Coastguard Worker // Static Helper Functions
28*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===//
29*9880d681SAndroid Build Coastguard Worker
30*9880d681SAndroid Build Coastguard Worker /// hasFlag - Determine if a feature has a flag; '+' or '-'
31*9880d681SAndroid Build Coastguard Worker ///
hasFlag(StringRef Feature)32*9880d681SAndroid Build Coastguard Worker static inline bool hasFlag(StringRef Feature) {
33*9880d681SAndroid Build Coastguard Worker assert(!Feature.empty() && "Empty string");
34*9880d681SAndroid Build Coastguard Worker // Get first character
35*9880d681SAndroid Build Coastguard Worker char Ch = Feature[0];
36*9880d681SAndroid Build Coastguard Worker // Check if first character is '+' or '-' flag
37*9880d681SAndroid Build Coastguard Worker return Ch == '+' || Ch =='-';
38*9880d681SAndroid Build Coastguard Worker }
39*9880d681SAndroid Build Coastguard Worker
40*9880d681SAndroid Build Coastguard Worker /// StripFlag - Return string stripped of flag.
41*9880d681SAndroid Build Coastguard Worker ///
StripFlag(StringRef Feature)42*9880d681SAndroid Build Coastguard Worker static inline std::string StripFlag(StringRef Feature) {
43*9880d681SAndroid Build Coastguard Worker return hasFlag(Feature) ? Feature.substr(1) : Feature;
44*9880d681SAndroid Build Coastguard Worker }
45*9880d681SAndroid Build Coastguard Worker
46*9880d681SAndroid Build Coastguard Worker /// isEnabled - Return true if enable flag; '+'.
47*9880d681SAndroid Build Coastguard Worker ///
isEnabled(StringRef Feature)48*9880d681SAndroid Build Coastguard Worker static inline bool isEnabled(StringRef Feature) {
49*9880d681SAndroid Build Coastguard Worker assert(!Feature.empty() && "Empty string");
50*9880d681SAndroid Build Coastguard Worker // Get first character
51*9880d681SAndroid Build Coastguard Worker char Ch = Feature[0];
52*9880d681SAndroid Build Coastguard Worker // Check if first character is '+' for enabled
53*9880d681SAndroid Build Coastguard Worker return Ch == '+';
54*9880d681SAndroid Build Coastguard Worker }
55*9880d681SAndroid Build Coastguard Worker
56*9880d681SAndroid Build Coastguard Worker /// Split - Splits a string of comma separated items in to a vector of strings.
57*9880d681SAndroid Build Coastguard Worker ///
Split(std::vector<std::string> & V,StringRef S)58*9880d681SAndroid Build Coastguard Worker static void Split(std::vector<std::string> &V, StringRef S) {
59*9880d681SAndroid Build Coastguard Worker SmallVector<StringRef, 3> Tmp;
60*9880d681SAndroid Build Coastguard Worker S.split(Tmp, ',', -1, false /* KeepEmpty */);
61*9880d681SAndroid Build Coastguard Worker V.assign(Tmp.begin(), Tmp.end());
62*9880d681SAndroid Build Coastguard Worker }
63*9880d681SAndroid Build Coastguard Worker
64*9880d681SAndroid Build Coastguard Worker /// Adding features.
AddFeature(StringRef String,bool Enable)65*9880d681SAndroid Build Coastguard Worker void SubtargetFeatures::AddFeature(StringRef String, bool Enable) {
66*9880d681SAndroid Build Coastguard Worker // Don't add empty features.
67*9880d681SAndroid Build Coastguard Worker if (!String.empty())
68*9880d681SAndroid Build Coastguard Worker // Convert to lowercase, prepend flag if we don't already have a flag.
69*9880d681SAndroid Build Coastguard Worker Features.push_back(hasFlag(String) ? String.lower()
70*9880d681SAndroid Build Coastguard Worker : (Enable ? "+" : "-") + String.lower());
71*9880d681SAndroid Build Coastguard Worker }
72*9880d681SAndroid Build Coastguard Worker
73*9880d681SAndroid Build Coastguard Worker /// Find KV in array using binary search.
Find(StringRef S,ArrayRef<SubtargetFeatureKV> A)74*9880d681SAndroid Build Coastguard Worker static const SubtargetFeatureKV *Find(StringRef S,
75*9880d681SAndroid Build Coastguard Worker ArrayRef<SubtargetFeatureKV> A) {
76*9880d681SAndroid Build Coastguard Worker // Binary search the array
77*9880d681SAndroid Build Coastguard Worker auto F = std::lower_bound(A.begin(), A.end(), S);
78*9880d681SAndroid Build Coastguard Worker // If not found then return NULL
79*9880d681SAndroid Build Coastguard Worker if (F == A.end() || StringRef(F->Key) != S) return nullptr;
80*9880d681SAndroid Build Coastguard Worker // Return the found array item
81*9880d681SAndroid Build Coastguard Worker return F;
82*9880d681SAndroid Build Coastguard Worker }
83*9880d681SAndroid Build Coastguard Worker
84*9880d681SAndroid Build Coastguard Worker /// getLongestEntryLength - Return the length of the longest entry in the table.
85*9880d681SAndroid Build Coastguard Worker ///
getLongestEntryLength(ArrayRef<SubtargetFeatureKV> Table)86*9880d681SAndroid Build Coastguard Worker static size_t getLongestEntryLength(ArrayRef<SubtargetFeatureKV> Table) {
87*9880d681SAndroid Build Coastguard Worker size_t MaxLen = 0;
88*9880d681SAndroid Build Coastguard Worker for (auto &I : Table)
89*9880d681SAndroid Build Coastguard Worker MaxLen = std::max(MaxLen, std::strlen(I.Key));
90*9880d681SAndroid Build Coastguard Worker return MaxLen;
91*9880d681SAndroid Build Coastguard Worker }
92*9880d681SAndroid Build Coastguard Worker
93*9880d681SAndroid Build Coastguard Worker /// Display help for feature choices.
94*9880d681SAndroid Build Coastguard Worker ///
Help(ArrayRef<SubtargetFeatureKV> CPUTable,ArrayRef<SubtargetFeatureKV> FeatTable)95*9880d681SAndroid Build Coastguard Worker static void Help(ArrayRef<SubtargetFeatureKV> CPUTable,
96*9880d681SAndroid Build Coastguard Worker ArrayRef<SubtargetFeatureKV> FeatTable) {
97*9880d681SAndroid Build Coastguard Worker // Determine the length of the longest CPU and Feature entries.
98*9880d681SAndroid Build Coastguard Worker unsigned MaxCPULen = getLongestEntryLength(CPUTable);
99*9880d681SAndroid Build Coastguard Worker unsigned MaxFeatLen = getLongestEntryLength(FeatTable);
100*9880d681SAndroid Build Coastguard Worker
101*9880d681SAndroid Build Coastguard Worker // Print the CPU table.
102*9880d681SAndroid Build Coastguard Worker errs() << "Available CPUs for this target:\n\n";
103*9880d681SAndroid Build Coastguard Worker for (auto &CPU : CPUTable)
104*9880d681SAndroid Build Coastguard Worker errs() << format(" %-*s - %s.\n", MaxCPULen, CPU.Key, CPU.Desc);
105*9880d681SAndroid Build Coastguard Worker errs() << '\n';
106*9880d681SAndroid Build Coastguard Worker
107*9880d681SAndroid Build Coastguard Worker // Print the Feature table.
108*9880d681SAndroid Build Coastguard Worker errs() << "Available features for this target:\n\n";
109*9880d681SAndroid Build Coastguard Worker for (auto &Feature : FeatTable)
110*9880d681SAndroid Build Coastguard Worker errs() << format(" %-*s - %s.\n", MaxFeatLen, Feature.Key, Feature.Desc);
111*9880d681SAndroid Build Coastguard Worker errs() << '\n';
112*9880d681SAndroid Build Coastguard Worker
113*9880d681SAndroid Build Coastguard Worker errs() << "Use +feature to enable a feature, or -feature to disable it.\n"
114*9880d681SAndroid Build Coastguard Worker "For example, llc -mcpu=mycpu -mattr=+feature1,-feature2\n";
115*9880d681SAndroid Build Coastguard Worker }
116*9880d681SAndroid Build Coastguard Worker
117*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===//
118*9880d681SAndroid Build Coastguard Worker // SubtargetFeatures Implementation
119*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===//
120*9880d681SAndroid Build Coastguard Worker
SubtargetFeatures(StringRef Initial)121*9880d681SAndroid Build Coastguard Worker SubtargetFeatures::SubtargetFeatures(StringRef Initial) {
122*9880d681SAndroid Build Coastguard Worker // Break up string into separate features
123*9880d681SAndroid Build Coastguard Worker Split(Features, Initial);
124*9880d681SAndroid Build Coastguard Worker }
125*9880d681SAndroid Build Coastguard Worker
126*9880d681SAndroid Build Coastguard Worker
getString() const127*9880d681SAndroid Build Coastguard Worker std::string SubtargetFeatures::getString() const {
128*9880d681SAndroid Build Coastguard Worker return join(Features.begin(), Features.end(), ",");
129*9880d681SAndroid Build Coastguard Worker }
130*9880d681SAndroid Build Coastguard Worker
131*9880d681SAndroid Build Coastguard Worker /// SetImpliedBits - For each feature that is (transitively) implied by this
132*9880d681SAndroid Build Coastguard Worker /// feature, set it.
133*9880d681SAndroid Build Coastguard Worker ///
134*9880d681SAndroid Build Coastguard Worker static
SetImpliedBits(FeatureBitset & Bits,const SubtargetFeatureKV * FeatureEntry,ArrayRef<SubtargetFeatureKV> FeatureTable)135*9880d681SAndroid Build Coastguard Worker void SetImpliedBits(FeatureBitset &Bits, const SubtargetFeatureKV *FeatureEntry,
136*9880d681SAndroid Build Coastguard Worker ArrayRef<SubtargetFeatureKV> FeatureTable) {
137*9880d681SAndroid Build Coastguard Worker for (auto &FE : FeatureTable) {
138*9880d681SAndroid Build Coastguard Worker if (FeatureEntry->Value == FE.Value) continue;
139*9880d681SAndroid Build Coastguard Worker
140*9880d681SAndroid Build Coastguard Worker if ((FeatureEntry->Implies & FE.Value).any()) {
141*9880d681SAndroid Build Coastguard Worker Bits |= FE.Value;
142*9880d681SAndroid Build Coastguard Worker SetImpliedBits(Bits, &FE, FeatureTable);
143*9880d681SAndroid Build Coastguard Worker }
144*9880d681SAndroid Build Coastguard Worker }
145*9880d681SAndroid Build Coastguard Worker }
146*9880d681SAndroid Build Coastguard Worker
147*9880d681SAndroid Build Coastguard Worker /// ClearImpliedBits - For each feature that (transitively) implies this
148*9880d681SAndroid Build Coastguard Worker /// feature, clear it.
149*9880d681SAndroid Build Coastguard Worker ///
150*9880d681SAndroid Build Coastguard Worker static
ClearImpliedBits(FeatureBitset & Bits,const SubtargetFeatureKV * FeatureEntry,ArrayRef<SubtargetFeatureKV> FeatureTable)151*9880d681SAndroid Build Coastguard Worker void ClearImpliedBits(FeatureBitset &Bits,
152*9880d681SAndroid Build Coastguard Worker const SubtargetFeatureKV *FeatureEntry,
153*9880d681SAndroid Build Coastguard Worker ArrayRef<SubtargetFeatureKV> FeatureTable) {
154*9880d681SAndroid Build Coastguard Worker for (auto &FE : FeatureTable) {
155*9880d681SAndroid Build Coastguard Worker if (FeatureEntry->Value == FE.Value) continue;
156*9880d681SAndroid Build Coastguard Worker
157*9880d681SAndroid Build Coastguard Worker if ((FE.Implies & FeatureEntry->Value).any()) {
158*9880d681SAndroid Build Coastguard Worker Bits &= ~FE.Value;
159*9880d681SAndroid Build Coastguard Worker ClearImpliedBits(Bits, &FE, FeatureTable);
160*9880d681SAndroid Build Coastguard Worker }
161*9880d681SAndroid Build Coastguard Worker }
162*9880d681SAndroid Build Coastguard Worker }
163*9880d681SAndroid Build Coastguard Worker
164*9880d681SAndroid Build Coastguard Worker /// ToggleFeature - Toggle a feature and update the feature bits.
165*9880d681SAndroid Build Coastguard Worker void
ToggleFeature(FeatureBitset & Bits,StringRef Feature,ArrayRef<SubtargetFeatureKV> FeatureTable)166*9880d681SAndroid Build Coastguard Worker SubtargetFeatures::ToggleFeature(FeatureBitset &Bits, StringRef Feature,
167*9880d681SAndroid Build Coastguard Worker ArrayRef<SubtargetFeatureKV> FeatureTable) {
168*9880d681SAndroid Build Coastguard Worker
169*9880d681SAndroid Build Coastguard Worker // Find feature in table.
170*9880d681SAndroid Build Coastguard Worker const SubtargetFeatureKV *FeatureEntry =
171*9880d681SAndroid Build Coastguard Worker Find(StripFlag(Feature), FeatureTable);
172*9880d681SAndroid Build Coastguard Worker // If there is a match
173*9880d681SAndroid Build Coastguard Worker if (FeatureEntry) {
174*9880d681SAndroid Build Coastguard Worker if ((Bits & FeatureEntry->Value) == FeatureEntry->Value) {
175*9880d681SAndroid Build Coastguard Worker Bits &= ~FeatureEntry->Value;
176*9880d681SAndroid Build Coastguard Worker // For each feature that implies this, clear it.
177*9880d681SAndroid Build Coastguard Worker ClearImpliedBits(Bits, FeatureEntry, FeatureTable);
178*9880d681SAndroid Build Coastguard Worker } else {
179*9880d681SAndroid Build Coastguard Worker Bits |= FeatureEntry->Value;
180*9880d681SAndroid Build Coastguard Worker
181*9880d681SAndroid Build Coastguard Worker // For each feature that this implies, set it.
182*9880d681SAndroid Build Coastguard Worker SetImpliedBits(Bits, FeatureEntry, FeatureTable);
183*9880d681SAndroid Build Coastguard Worker }
184*9880d681SAndroid Build Coastguard Worker } else {
185*9880d681SAndroid Build Coastguard Worker errs() << "'" << Feature
186*9880d681SAndroid Build Coastguard Worker << "' is not a recognized feature for this target"
187*9880d681SAndroid Build Coastguard Worker << " (ignoring feature)\n";
188*9880d681SAndroid Build Coastguard Worker }
189*9880d681SAndroid Build Coastguard Worker }
190*9880d681SAndroid Build Coastguard Worker
ApplyFeatureFlag(FeatureBitset & Bits,StringRef Feature,ArrayRef<SubtargetFeatureKV> FeatureTable)191*9880d681SAndroid Build Coastguard Worker void SubtargetFeatures::ApplyFeatureFlag(FeatureBitset &Bits, StringRef Feature,
192*9880d681SAndroid Build Coastguard Worker ArrayRef<SubtargetFeatureKV> FeatureTable) {
193*9880d681SAndroid Build Coastguard Worker
194*9880d681SAndroid Build Coastguard Worker assert(hasFlag(Feature));
195*9880d681SAndroid Build Coastguard Worker
196*9880d681SAndroid Build Coastguard Worker // Find feature in table.
197*9880d681SAndroid Build Coastguard Worker const SubtargetFeatureKV *FeatureEntry =
198*9880d681SAndroid Build Coastguard Worker Find(StripFlag(Feature), FeatureTable);
199*9880d681SAndroid Build Coastguard Worker // If there is a match
200*9880d681SAndroid Build Coastguard Worker if (FeatureEntry) {
201*9880d681SAndroid Build Coastguard Worker // Enable/disable feature in bits
202*9880d681SAndroid Build Coastguard Worker if (isEnabled(Feature)) {
203*9880d681SAndroid Build Coastguard Worker Bits |= FeatureEntry->Value;
204*9880d681SAndroid Build Coastguard Worker
205*9880d681SAndroid Build Coastguard Worker // For each feature that this implies, set it.
206*9880d681SAndroid Build Coastguard Worker SetImpliedBits(Bits, FeatureEntry, FeatureTable);
207*9880d681SAndroid Build Coastguard Worker } else {
208*9880d681SAndroid Build Coastguard Worker Bits &= ~FeatureEntry->Value;
209*9880d681SAndroid Build Coastguard Worker
210*9880d681SAndroid Build Coastguard Worker // For each feature that implies this, clear it.
211*9880d681SAndroid Build Coastguard Worker ClearImpliedBits(Bits, FeatureEntry, FeatureTable);
212*9880d681SAndroid Build Coastguard Worker }
213*9880d681SAndroid Build Coastguard Worker } else {
214*9880d681SAndroid Build Coastguard Worker errs() << "'" << Feature
215*9880d681SAndroid Build Coastguard Worker << "' is not a recognized feature for this target"
216*9880d681SAndroid Build Coastguard Worker << " (ignoring feature)\n";
217*9880d681SAndroid Build Coastguard Worker }
218*9880d681SAndroid Build Coastguard Worker }
219*9880d681SAndroid Build Coastguard Worker
220*9880d681SAndroid Build Coastguard Worker
221*9880d681SAndroid Build Coastguard Worker /// getFeatureBits - Get feature bits a CPU.
222*9880d681SAndroid Build Coastguard Worker ///
223*9880d681SAndroid Build Coastguard Worker FeatureBitset
getFeatureBits(StringRef CPU,ArrayRef<SubtargetFeatureKV> CPUTable,ArrayRef<SubtargetFeatureKV> FeatureTable)224*9880d681SAndroid Build Coastguard Worker SubtargetFeatures::getFeatureBits(StringRef CPU,
225*9880d681SAndroid Build Coastguard Worker ArrayRef<SubtargetFeatureKV> CPUTable,
226*9880d681SAndroid Build Coastguard Worker ArrayRef<SubtargetFeatureKV> FeatureTable) {
227*9880d681SAndroid Build Coastguard Worker
228*9880d681SAndroid Build Coastguard Worker if (CPUTable.empty() || FeatureTable.empty())
229*9880d681SAndroid Build Coastguard Worker return FeatureBitset();
230*9880d681SAndroid Build Coastguard Worker
231*9880d681SAndroid Build Coastguard Worker #ifndef NDEBUG
232*9880d681SAndroid Build Coastguard Worker assert(std::is_sorted(std::begin(CPUTable), std::end(CPUTable)) &&
233*9880d681SAndroid Build Coastguard Worker "CPU table is not sorted");
234*9880d681SAndroid Build Coastguard Worker assert(std::is_sorted(std::begin(FeatureTable), std::end(FeatureTable)) &&
235*9880d681SAndroid Build Coastguard Worker "CPU features table is not sorted");
236*9880d681SAndroid Build Coastguard Worker #endif
237*9880d681SAndroid Build Coastguard Worker // Resulting bits
238*9880d681SAndroid Build Coastguard Worker FeatureBitset Bits;
239*9880d681SAndroid Build Coastguard Worker
240*9880d681SAndroid Build Coastguard Worker // Check if help is needed
241*9880d681SAndroid Build Coastguard Worker if (CPU == "help")
242*9880d681SAndroid Build Coastguard Worker Help(CPUTable, FeatureTable);
243*9880d681SAndroid Build Coastguard Worker
244*9880d681SAndroid Build Coastguard Worker // Find CPU entry if CPU name is specified.
245*9880d681SAndroid Build Coastguard Worker else if (!CPU.empty()) {
246*9880d681SAndroid Build Coastguard Worker const SubtargetFeatureKV *CPUEntry = Find(CPU, CPUTable);
247*9880d681SAndroid Build Coastguard Worker
248*9880d681SAndroid Build Coastguard Worker // If there is a match
249*9880d681SAndroid Build Coastguard Worker if (CPUEntry) {
250*9880d681SAndroid Build Coastguard Worker // Set base feature bits
251*9880d681SAndroid Build Coastguard Worker Bits = CPUEntry->Value;
252*9880d681SAndroid Build Coastguard Worker
253*9880d681SAndroid Build Coastguard Worker // Set the feature implied by this CPU feature, if any.
254*9880d681SAndroid Build Coastguard Worker for (auto &FE : FeatureTable) {
255*9880d681SAndroid Build Coastguard Worker if ((CPUEntry->Value & FE.Value).any())
256*9880d681SAndroid Build Coastguard Worker SetImpliedBits(Bits, &FE, FeatureTable);
257*9880d681SAndroid Build Coastguard Worker }
258*9880d681SAndroid Build Coastguard Worker } else {
259*9880d681SAndroid Build Coastguard Worker errs() << "'" << CPU
260*9880d681SAndroid Build Coastguard Worker << "' is not a recognized processor for this target"
261*9880d681SAndroid Build Coastguard Worker << " (ignoring processor)\n";
262*9880d681SAndroid Build Coastguard Worker }
263*9880d681SAndroid Build Coastguard Worker }
264*9880d681SAndroid Build Coastguard Worker
265*9880d681SAndroid Build Coastguard Worker // Iterate through each feature
266*9880d681SAndroid Build Coastguard Worker for (auto &Feature : Features) {
267*9880d681SAndroid Build Coastguard Worker // Check for help
268*9880d681SAndroid Build Coastguard Worker if (Feature == "+help")
269*9880d681SAndroid Build Coastguard Worker Help(CPUTable, FeatureTable);
270*9880d681SAndroid Build Coastguard Worker
271*9880d681SAndroid Build Coastguard Worker ApplyFeatureFlag(Bits, Feature, FeatureTable);
272*9880d681SAndroid Build Coastguard Worker }
273*9880d681SAndroid Build Coastguard Worker
274*9880d681SAndroid Build Coastguard Worker return Bits;
275*9880d681SAndroid Build Coastguard Worker }
276*9880d681SAndroid Build Coastguard Worker
277*9880d681SAndroid Build Coastguard Worker /// print - Print feature string.
278*9880d681SAndroid Build Coastguard Worker ///
print(raw_ostream & OS) const279*9880d681SAndroid Build Coastguard Worker void SubtargetFeatures::print(raw_ostream &OS) const {
280*9880d681SAndroid Build Coastguard Worker for (auto &F : Features)
281*9880d681SAndroid Build Coastguard Worker OS << F << " ";
282*9880d681SAndroid Build Coastguard Worker OS << "\n";
283*9880d681SAndroid Build Coastguard Worker }
284*9880d681SAndroid Build Coastguard Worker
285*9880d681SAndroid Build Coastguard Worker #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
286*9880d681SAndroid Build Coastguard Worker /// dump - Dump feature info.
287*9880d681SAndroid Build Coastguard Worker ///
dump() const288*9880d681SAndroid Build Coastguard Worker LLVM_DUMP_METHOD void SubtargetFeatures::dump() const {
289*9880d681SAndroid Build Coastguard Worker print(dbgs());
290*9880d681SAndroid Build Coastguard Worker }
291*9880d681SAndroid Build Coastguard Worker #endif
292*9880d681SAndroid Build Coastguard Worker
293*9880d681SAndroid Build Coastguard Worker /// Adds the default features for the specified target triple.
294*9880d681SAndroid Build Coastguard Worker ///
295*9880d681SAndroid Build Coastguard Worker /// FIXME: This is an inelegant way of specifying the features of a
296*9880d681SAndroid Build Coastguard Worker /// subtarget. It would be better if we could encode this information
297*9880d681SAndroid Build Coastguard Worker /// into the IR. See <rdar://5972456>.
298*9880d681SAndroid Build Coastguard Worker ///
getDefaultSubtargetFeatures(const Triple & Triple)299*9880d681SAndroid Build Coastguard Worker void SubtargetFeatures::getDefaultSubtargetFeatures(const Triple& Triple) {
300*9880d681SAndroid Build Coastguard Worker if (Triple.getVendor() == Triple::Apple) {
301*9880d681SAndroid Build Coastguard Worker if (Triple.getArch() == Triple::ppc) {
302*9880d681SAndroid Build Coastguard Worker // powerpc-apple-*
303*9880d681SAndroid Build Coastguard Worker AddFeature("altivec");
304*9880d681SAndroid Build Coastguard Worker } else if (Triple.getArch() == Triple::ppc64) {
305*9880d681SAndroid Build Coastguard Worker // powerpc64-apple-*
306*9880d681SAndroid Build Coastguard Worker AddFeature("64bit");
307*9880d681SAndroid Build Coastguard Worker AddFeature("altivec");
308*9880d681SAndroid Build Coastguard Worker }
309*9880d681SAndroid Build Coastguard Worker }
310*9880d681SAndroid Build Coastguard Worker }
311