xref: /aosp_15_r20/external/llvm/lib/MC/SubtargetFeature.cpp (revision 9880d6810fe72a1726cb53787c6711e909410d58)
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