1b3302db18a779527a4b1cd7a2024543ade7e83c6Jim Laskey//===- SubtargetFeature.cpp - CPU characteristics Implementation ----------===// 2b3302db18a779527a4b1cd7a2024543ade7e83c6Jim Laskey// 3b3302db18a779527a4b1cd7a2024543ade7e83c6Jim Laskey// The LLVM Compiler Infrastructure 4b3302db18a779527a4b1cd7a2024543ade7e83c6Jim Laskey// 54ee451de366474b9c228b4e5fa573795a715216dChris Lattner// This file is distributed under the University of Illinois Open Source 64ee451de366474b9c228b4e5fa573795a715216dChris Lattner// License. See LICENSE.TXT for details. 7b3302db18a779527a4b1cd7a2024543ade7e83c6Jim Laskey// 8b3302db18a779527a4b1cd7a2024543ade7e83c6Jim Laskey//===----------------------------------------------------------------------===// 9b3302db18a779527a4b1cd7a2024543ade7e83c6Jim Laskey// 10b3302db18a779527a4b1cd7a2024543ade7e83c6Jim Laskey// This file implements the SubtargetFeature interface. 11b3302db18a779527a4b1cd7a2024543ade7e83c6Jim Laskey// 12b3302db18a779527a4b1cd7a2024543ade7e83c6Jim Laskey//===----------------------------------------------------------------------===// 13b3302db18a779527a4b1cd7a2024543ade7e83c6Jim Laskey 14ab8be96fd30ca9396e6b84fdddf1ac6208984cadEvan Cheng#include "llvm/MC/SubtargetFeature.h" 159759c305c2dbca2ba46645638ed39d5cb40b66d1David Greene#include "llvm/Support/Debug.h" 16962bad70f4277841cf6278306caa93ebce304b48Benjamin Kramer#include "llvm/Support/Format.h" 17e0c86afac63a2dbbcff0ad79ed7b93d860451385Chris Lattner#include "llvm/Support/raw_ostream.h" 18b3302db18a779527a4b1cd7a2024543ade7e83c6Jim Laskey#include <algorithm> 19b3302db18a779527a4b1cd7a2024543ade7e83c6Jim Laskey#include <cassert> 207cd57f4c452c39ee595de19633787ec37933eb34Jeff Cohen#include <cctype> 21476b242fe7a61e5f9ac6214b0bc5c680d24f152eNick Lewycky#include <cstdlib> 22b3302db18a779527a4b1cd7a2024543ade7e83c6Jim Laskeyusing namespace llvm; 23b3302db18a779527a4b1cd7a2024543ade7e83c6Jim Laskey 2454195c1a9d8ac23d2dc1dfca818384cd26abe19bChris Lattner//===----------------------------------------------------------------------===// 2554195c1a9d8ac23d2dc1dfca818384cd26abe19bChris Lattner// Static Helper Functions 2654195c1a9d8ac23d2dc1dfca818384cd26abe19bChris Lattner//===----------------------------------------------------------------------===// 2754195c1a9d8ac23d2dc1dfca818384cd26abe19bChris Lattner 2854195c1a9d8ac23d2dc1dfca818384cd26abe19bChris Lattner/// hasFlag - Determine if a feature has a flag; '+' or '-' 2954195c1a9d8ac23d2dc1dfca818384cd26abe19bChris Lattner/// 30e1bff38386b0af24b5564c3d20888c7bbb045099Evan Chengstatic inline bool hasFlag(const StringRef Feature) { 3154195c1a9d8ac23d2dc1dfca818384cd26abe19bChris Lattner assert(!Feature.empty() && "Empty string"); 3254195c1a9d8ac23d2dc1dfca818384cd26abe19bChris Lattner // Get first character 3354195c1a9d8ac23d2dc1dfca818384cd26abe19bChris Lattner char Ch = Feature[0]; 3454195c1a9d8ac23d2dc1dfca818384cd26abe19bChris Lattner // Check if first character is '+' or '-' flag 3554195c1a9d8ac23d2dc1dfca818384cd26abe19bChris Lattner return Ch == '+' || Ch =='-'; 3654195c1a9d8ac23d2dc1dfca818384cd26abe19bChris Lattner} 3754195c1a9d8ac23d2dc1dfca818384cd26abe19bChris Lattner 3854195c1a9d8ac23d2dc1dfca818384cd26abe19bChris Lattner/// StripFlag - Return string stripped of flag. 3954195c1a9d8ac23d2dc1dfca818384cd26abe19bChris Lattner/// 40e1bff38386b0af24b5564c3d20888c7bbb045099Evan Chengstatic inline std::string StripFlag(const StringRef Feature) { 4154195c1a9d8ac23d2dc1dfca818384cd26abe19bChris Lattner return hasFlag(Feature) ? Feature.substr(1) : Feature; 4254195c1a9d8ac23d2dc1dfca818384cd26abe19bChris Lattner} 4354195c1a9d8ac23d2dc1dfca818384cd26abe19bChris Lattner 4454195c1a9d8ac23d2dc1dfca818384cd26abe19bChris Lattner/// isEnabled - Return true if enable flag; '+'. 4554195c1a9d8ac23d2dc1dfca818384cd26abe19bChris Lattner/// 46e1bff38386b0af24b5564c3d20888c7bbb045099Evan Chengstatic inline bool isEnabled(const StringRef Feature) { 4754195c1a9d8ac23d2dc1dfca818384cd26abe19bChris Lattner assert(!Feature.empty() && "Empty string"); 4854195c1a9d8ac23d2dc1dfca818384cd26abe19bChris Lattner // Get first character 4954195c1a9d8ac23d2dc1dfca818384cd26abe19bChris Lattner char Ch = Feature[0]; 5054195c1a9d8ac23d2dc1dfca818384cd26abe19bChris Lattner // Check if first character is '+' for enabled 5154195c1a9d8ac23d2dc1dfca818384cd26abe19bChris Lattner return Ch == '+'; 5254195c1a9d8ac23d2dc1dfca818384cd26abe19bChris Lattner} 5354195c1a9d8ac23d2dc1dfca818384cd26abe19bChris Lattner 5454195c1a9d8ac23d2dc1dfca818384cd26abe19bChris Lattner/// Split - Splits a string of comma separated items in to a vector of strings. 5554195c1a9d8ac23d2dc1dfca818384cd26abe19bChris Lattner/// 56e1bff38386b0af24b5564c3d20888c7bbb045099Evan Chengstatic void Split(std::vector<std::string> &V, const StringRef S) { 57dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines SmallVector<StringRef, 2> Tmp; 58dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines S.split(Tmp, ",", -1, false /* KeepEmpty */); 59dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines V.assign(Tmp.begin(), Tmp.end()); 60b3302db18a779527a4b1cd7a2024543ade7e83c6Jim Laskey} 61b3302db18a779527a4b1cd7a2024543ade7e83c6Jim Laskey 62b3302db18a779527a4b1cd7a2024543ade7e83c6Jim Laskey/// Join a vector of strings to a string with a comma separating each element. 6354195c1a9d8ac23d2dc1dfca818384cd26abe19bChris Lattner/// 6454195c1a9d8ac23d2dc1dfca818384cd26abe19bChris Lattnerstatic std::string Join(const std::vector<std::string> &V) { 65b3302db18a779527a4b1cd7a2024543ade7e83c6Jim Laskey // Start with empty string. 66b3302db18a779527a4b1cd7a2024543ade7e83c6Jim Laskey std::string Result; 672684d9e3c702b2ef9fd430155d94671d12fa994fJim Grosbach // If the vector is not empty 68b3302db18a779527a4b1cd7a2024543ade7e83c6Jim Laskey if (!V.empty()) { 69276365dd4bc0c2160f91fd8062ae1fc90c86c324Evan Cheng // Start with the first feature 70b3302db18a779527a4b1cd7a2024543ade7e83c6Jim Laskey Result = V[0]; 71b3302db18a779527a4b1cd7a2024543ade7e83c6Jim Laskey // For each successive feature 72b3302db18a779527a4b1cd7a2024543ade7e83c6Jim Laskey for (size_t i = 1; i < V.size(); i++) { 73b3302db18a779527a4b1cd7a2024543ade7e83c6Jim Laskey // Add a comma 74b3302db18a779527a4b1cd7a2024543ade7e83c6Jim Laskey Result += ","; 75b3302db18a779527a4b1cd7a2024543ade7e83c6Jim Laskey // Add the feature 76b3302db18a779527a4b1cd7a2024543ade7e83c6Jim Laskey Result += V[i]; 77b3302db18a779527a4b1cd7a2024543ade7e83c6Jim Laskey } 78b3302db18a779527a4b1cd7a2024543ade7e83c6Jim Laskey } 792684d9e3c702b2ef9fd430155d94671d12fa994fJim Grosbach // Return the features string 80b3302db18a779527a4b1cd7a2024543ade7e83c6Jim Laskey return Result; 81b3302db18a779527a4b1cd7a2024543ade7e83c6Jim Laskey} 82b3302db18a779527a4b1cd7a2024543ade7e83c6Jim Laskey 83b3302db18a779527a4b1cd7a2024543ade7e83c6Jim Laskey/// Adding features. 84dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hinesvoid SubtargetFeatures::AddFeature(const StringRef String) { 85dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines // Don't add empty features or features we already have. 86dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines if (!String.empty()) 87dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines // Convert to lowercase, prepend flag if we don't already have a flag. 88dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines Features.push_back(hasFlag(String) ? String.str() : "+" + String.lower()); 89b3302db18a779527a4b1cd7a2024543ade7e83c6Jim Laskey} 90b3302db18a779527a4b1cd7a2024543ade7e83c6Jim Laskey 9134bd5d5d876212611d8b66a18f4c8604b342c6ebJim Laskey/// Find KV in array using binary search. 92dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hinesstatic const SubtargetFeatureKV *Find(StringRef S, 93dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines ArrayRef<SubtargetFeatureKV> A) { 94b3302db18a779527a4b1cd7a2024543ade7e83c6Jim Laskey // Binary search the array 95dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines auto F = std::lower_bound(A.begin(), A.end(), S); 96b3302db18a779527a4b1cd7a2024543ade7e83c6Jim Laskey // If not found then return NULL 97dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines if (F == A.end() || StringRef(F->Key) != S) return nullptr; 98b3302db18a779527a4b1cd7a2024543ade7e83c6Jim Laskey // Return the found array item 99b3302db18a779527a4b1cd7a2024543ade7e83c6Jim Laskey return F; 100b3302db18a779527a4b1cd7a2024543ade7e83c6Jim Laskey} 101b3302db18a779527a4b1cd7a2024543ade7e83c6Jim Laskey 1023e808a45b334608595a045c2ace7e2a107fb3b2bChris Lattner/// getLongestEntryLength - Return the length of the longest entry in the table. 10354195c1a9d8ac23d2dc1dfca818384cd26abe19bChris Lattner/// 104dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hinesstatic size_t getLongestEntryLength(ArrayRef<SubtargetFeatureKV> Table) { 10554195c1a9d8ac23d2dc1dfca818384cd26abe19bChris Lattner size_t MaxLen = 0; 106dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines for (auto &I : Table) 107dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines MaxLen = std::max(MaxLen, std::strlen(I.Key)); 1083e808a45b334608595a045c2ace7e2a107fb3b2bChris Lattner return MaxLen; 1093e808a45b334608595a045c2ace7e2a107fb3b2bChris Lattner} 110ba76c21858bac5fd953d4dbe2f0624d8e884c7b5Chris Lattner 1113e808a45b334608595a045c2ace7e2a107fb3b2bChris Lattner/// Display help for feature choices. 1123e808a45b334608595a045c2ace7e2a107fb3b2bChris Lattner/// 113dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hinesstatic void Help(ArrayRef<SubtargetFeatureKV> CPUTable, 114dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines ArrayRef<SubtargetFeatureKV> FeatTable) { 1153e808a45b334608595a045c2ace7e2a107fb3b2bChris Lattner // Determine the length of the longest CPU and Feature entries. 116dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines unsigned MaxCPULen = getLongestEntryLength(CPUTable); 117dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines unsigned MaxFeatLen = getLongestEntryLength(FeatTable); 118ba76c21858bac5fd953d4dbe2f0624d8e884c7b5Chris Lattner 1193e808a45b334608595a045c2ace7e2a107fb3b2bChris Lattner // Print the CPU table. 120e0c86afac63a2dbbcff0ad79ed7b93d860451385Chris Lattner errs() << "Available CPUs for this target:\n\n"; 121dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines for (auto &CPU : CPUTable) 122dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines errs() << format(" %-*s - %s.\n", MaxCPULen, CPU.Key, CPU.Desc); 123962bad70f4277841cf6278306caa93ebce304b48Benjamin Kramer errs() << '\n'; 124962bad70f4277841cf6278306caa93ebce304b48Benjamin Kramer 1253e808a45b334608595a045c2ace7e2a107fb3b2bChris Lattner // Print the Feature table. 126e0c86afac63a2dbbcff0ad79ed7b93d860451385Chris Lattner errs() << "Available features for this target:\n\n"; 127dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines for (auto &Feature : FeatTable) 128dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines errs() << format(" %-*s - %s.\n", MaxFeatLen, Feature.Key, Feature.Desc); 129962bad70f4277841cf6278306caa93ebce304b48Benjamin Kramer errs() << '\n'; 130962bad70f4277841cf6278306caa93ebce304b48Benjamin Kramer 131e0c86afac63a2dbbcff0ad79ed7b93d860451385Chris Lattner errs() << "Use +feature to enable a feature, or -feature to disable it.\n" 132962bad70f4277841cf6278306caa93ebce304b48Benjamin Kramer "For example, llc -mcpu=mycpu -mattr=+feature1,-feature2\n"; 13354195c1a9d8ac23d2dc1dfca818384cd26abe19bChris Lattner} 13454195c1a9d8ac23d2dc1dfca818384cd26abe19bChris Lattner 13554195c1a9d8ac23d2dc1dfca818384cd26abe19bChris Lattner//===----------------------------------------------------------------------===// 13654195c1a9d8ac23d2dc1dfca818384cd26abe19bChris Lattner// SubtargetFeatures Implementation 13754195c1a9d8ac23d2dc1dfca818384cd26abe19bChris Lattner//===----------------------------------------------------------------------===// 13854195c1a9d8ac23d2dc1dfca818384cd26abe19bChris Lattner 139e1bff38386b0af24b5564c3d20888c7bbb045099Evan ChengSubtargetFeatures::SubtargetFeatures(const StringRef Initial) { 14054195c1a9d8ac23d2dc1dfca818384cd26abe19bChris Lattner // Break up string into separate features 14154195c1a9d8ac23d2dc1dfca818384cd26abe19bChris Lattner Split(Features, Initial); 142839615a510c582ddcdb09a8e2934f30775daa032Jim Laskey} 143839615a510c582ddcdb09a8e2934f30775daa032Jim Laskey 14454195c1a9d8ac23d2dc1dfca818384cd26abe19bChris Lattner 1453f9b9eb57dafc2a25a6e3d9ee570bd5a884b11e3Rafael Espindolastd::string SubtargetFeatures::getString() const { 14654195c1a9d8ac23d2dc1dfca818384cd26abe19bChris Lattner return Join(Features); 14754195c1a9d8ac23d2dc1dfca818384cd26abe19bChris Lattner} 14854195c1a9d8ac23d2dc1dfca818384cd26abe19bChris Lattner 1494222d806faae71ecc794cfdaa873817873c2f3d8Bill Wendling/// SetImpliedBits - For each feature that is (transitively) implied by this 1504222d806faae71ecc794cfdaa873817873c2f3d8Bill Wendling/// feature, set it. 15141a024385f1220eadc48b48cb4c044a5fbc1b361Anton Korobeynikov/// 1524222d806faae71ecc794cfdaa873817873c2f3d8Bill Wendlingstatic 153b6a638898a92d5cd782209fbeb673fe7846a29ebEvan Chengvoid SetImpliedBits(uint64_t &Bits, const SubtargetFeatureKV *FeatureEntry, 154dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines ArrayRef<SubtargetFeatureKV> FeatureTable) { 155dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines for (auto &FE : FeatureTable) { 1564222d806faae71ecc794cfdaa873817873c2f3d8Bill Wendling if (FeatureEntry->Value == FE.Value) continue; 1574222d806faae71ecc794cfdaa873817873c2f3d8Bill Wendling 1584222d806faae71ecc794cfdaa873817873c2f3d8Bill Wendling if (FeatureEntry->Implies & FE.Value) { 1594222d806faae71ecc794cfdaa873817873c2f3d8Bill Wendling Bits |= FE.Value; 160dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines SetImpliedBits(Bits, &FE, FeatureTable); 1614222d806faae71ecc794cfdaa873817873c2f3d8Bill Wendling } 1624222d806faae71ecc794cfdaa873817873c2f3d8Bill Wendling } 1634222d806faae71ecc794cfdaa873817873c2f3d8Bill Wendling} 1644222d806faae71ecc794cfdaa873817873c2f3d8Bill Wendling 1654222d806faae71ecc794cfdaa873817873c2f3d8Bill Wendling/// ClearImpliedBits - For each feature that (transitively) implies this 1664222d806faae71ecc794cfdaa873817873c2f3d8Bill Wendling/// feature, clear it. 1672684d9e3c702b2ef9fd430155d94671d12fa994fJim Grosbach/// 1684222d806faae71ecc794cfdaa873817873c2f3d8Bill Wendlingstatic 169b6a638898a92d5cd782209fbeb673fe7846a29ebEvan Chengvoid ClearImpliedBits(uint64_t &Bits, const SubtargetFeatureKV *FeatureEntry, 170dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines ArrayRef<SubtargetFeatureKV> FeatureTable) { 171dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines for (auto &FE : FeatureTable) { 1724222d806faae71ecc794cfdaa873817873c2f3d8Bill Wendling if (FeatureEntry->Value == FE.Value) continue; 1734222d806faae71ecc794cfdaa873817873c2f3d8Bill Wendling 1744222d806faae71ecc794cfdaa873817873c2f3d8Bill Wendling if (FE.Implies & FeatureEntry->Value) { 1754222d806faae71ecc794cfdaa873817873c2f3d8Bill Wendling Bits &= ~FE.Value; 176dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines ClearImpliedBits(Bits, &FE, FeatureTable); 1774222d806faae71ecc794cfdaa873817873c2f3d8Bill Wendling } 1784222d806faae71ecc794cfdaa873817873c2f3d8Bill Wendling } 1794222d806faae71ecc794cfdaa873817873c2f3d8Bill Wendling} 18034bd5d5d876212611d8b66a18f4c8604b342c6ebJim Laskey 181ffc0e73046f737d75e0a62b3a83ef19bcef111e3Evan Cheng/// ToggleFeature - Toggle a feature and returns the newly updated feature 182ffc0e73046f737d75e0a62b3a83ef19bcef111e3Evan Cheng/// bits. 183ffc0e73046f737d75e0a62b3a83ef19bcef111e3Evan Chenguint64_t 184ffc0e73046f737d75e0a62b3a83ef19bcef111e3Evan ChengSubtargetFeatures::ToggleFeature(uint64_t Bits, const StringRef Feature, 185dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines ArrayRef<SubtargetFeatureKV> FeatureTable) { 186dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines 187ffc0e73046f737d75e0a62b3a83ef19bcef111e3Evan Cheng // Find feature in table. 188ffc0e73046f737d75e0a62b3a83ef19bcef111e3Evan Cheng const SubtargetFeatureKV *FeatureEntry = 189dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines Find(StripFlag(Feature), FeatureTable); 190ffc0e73046f737d75e0a62b3a83ef19bcef111e3Evan Cheng // If there is a match 191ffc0e73046f737d75e0a62b3a83ef19bcef111e3Evan Cheng if (FeatureEntry) { 192ffc0e73046f737d75e0a62b3a83ef19bcef111e3Evan Cheng if ((Bits & FeatureEntry->Value) == FeatureEntry->Value) { 193ffc0e73046f737d75e0a62b3a83ef19bcef111e3Evan Cheng Bits &= ~FeatureEntry->Value; 194ffc0e73046f737d75e0a62b3a83ef19bcef111e3Evan Cheng 195ffc0e73046f737d75e0a62b3a83ef19bcef111e3Evan Cheng // For each feature that implies this, clear it. 196dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines ClearImpliedBits(Bits, FeatureEntry, FeatureTable); 197ffc0e73046f737d75e0a62b3a83ef19bcef111e3Evan Cheng } else { 198ffc0e73046f737d75e0a62b3a83ef19bcef111e3Evan Cheng Bits |= FeatureEntry->Value; 199ffc0e73046f737d75e0a62b3a83ef19bcef111e3Evan Cheng 200ffc0e73046f737d75e0a62b3a83ef19bcef111e3Evan Cheng // For each feature that this implies, set it. 201dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines SetImpliedBits(Bits, FeatureEntry, FeatureTable); 202ffc0e73046f737d75e0a62b3a83ef19bcef111e3Evan Cheng } 203ffc0e73046f737d75e0a62b3a83ef19bcef111e3Evan Cheng } else { 204ffc0e73046f737d75e0a62b3a83ef19bcef111e3Evan Cheng errs() << "'" << Feature 205ffc0e73046f737d75e0a62b3a83ef19bcef111e3Evan Cheng << "' is not a recognized feature for this target" 206ffc0e73046f737d75e0a62b3a83ef19bcef111e3Evan Cheng << " (ignoring feature)\n"; 207ffc0e73046f737d75e0a62b3a83ef19bcef111e3Evan Cheng } 208ffc0e73046f737d75e0a62b3a83ef19bcef111e3Evan Cheng 209ffc0e73046f737d75e0a62b3a83ef19bcef111e3Evan Cheng return Bits; 210ffc0e73046f737d75e0a62b3a83ef19bcef111e3Evan Cheng} 2112684d9e3c702b2ef9fd430155d94671d12fa994fJim Grosbach 212ffc0e73046f737d75e0a62b3a83ef19bcef111e3Evan Cheng 213276365dd4bc0c2160f91fd8062ae1fc90c86c324Evan Cheng/// getFeatureBits - Get feature bits a CPU. 21454195c1a9d8ac23d2dc1dfca818384cd26abe19bChris Lattner/// 215dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hinesuint64_t 216dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen HinesSubtargetFeatures::getFeatureBits(const StringRef CPU, 217dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines ArrayRef<SubtargetFeatureKV> CPUTable, 218dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines ArrayRef<SubtargetFeatureKV> FeatureTable) { 219dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines 220dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines if (CPUTable.empty() || FeatureTable.empty()) 2210ddff1b5359433faf2eb1c4ff5320ddcbd42f52fEvan Cheng return 0; 2220ddff1b5359433faf2eb1c4ff5320ddcbd42f52fEvan Cheng 223b3302db18a779527a4b1cd7a2024543ade7e83c6Jim Laskey#ifndef NDEBUG 224dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines for (size_t i = 1, e = CPUTable.size(); i != e; ++i) { 225b3302db18a779527a4b1cd7a2024543ade7e83c6Jim Laskey assert(strcmp(CPUTable[i - 1].Key, CPUTable[i].Key) < 0 && 226b3302db18a779527a4b1cd7a2024543ade7e83c6Jim Laskey "CPU table is not sorted"); 227b3302db18a779527a4b1cd7a2024543ade7e83c6Jim Laskey } 228dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines for (size_t i = 1, e = FeatureTable.size(); i != e; ++i) { 229b3302db18a779527a4b1cd7a2024543ade7e83c6Jim Laskey assert(strcmp(FeatureTable[i - 1].Key, FeatureTable[i].Key) < 0 && 230b3302db18a779527a4b1cd7a2024543ade7e83c6Jim Laskey "CPU features table is not sorted"); 231b3302db18a779527a4b1cd7a2024543ade7e83c6Jim Laskey } 232b3302db18a779527a4b1cd7a2024543ade7e83c6Jim Laskey#endif 233b6a638898a92d5cd782209fbeb673fe7846a29ebEvan Cheng uint64_t Bits = 0; // Resulting bits 2343e808a45b334608595a045c2ace7e2a107fb3b2bChris Lattner 23534bd5d5d876212611d8b66a18f4c8604b342c6ebJim Laskey // Check if help is needed 236276365dd4bc0c2160f91fd8062ae1fc90c86c324Evan Cheng if (CPU == "help") 237dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines Help(CPUTable, FeatureTable); 2382684d9e3c702b2ef9fd430155d94671d12fa994fJim Grosbach 2390ddff1b5359433faf2eb1c4ff5320ddcbd42f52fEvan Cheng // Find CPU entry if CPU name is specified. 240dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines else if (!CPU.empty()) { 241dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines const SubtargetFeatureKV *CPUEntry = Find(CPU, CPUTable); 242dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines 2430ddff1b5359433faf2eb1c4ff5320ddcbd42f52fEvan Cheng // If there is a match 2440ddff1b5359433faf2eb1c4ff5320ddcbd42f52fEvan Cheng if (CPUEntry) { 2450ddff1b5359433faf2eb1c4ff5320ddcbd42f52fEvan Cheng // Set base feature bits 2460ddff1b5359433faf2eb1c4ff5320ddcbd42f52fEvan Cheng Bits = CPUEntry->Value; 2471a636de33bccc31337c1ea0811c7019fa0b31eeaBill Wendling 2480ddff1b5359433faf2eb1c4ff5320ddcbd42f52fEvan Cheng // Set the feature implied by this CPU feature, if any. 249dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines for (auto &FE : FeatureTable) { 2500ddff1b5359433faf2eb1c4ff5320ddcbd42f52fEvan Cheng if (CPUEntry->Value & FE.Value) 251dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines SetImpliedBits(Bits, &FE, FeatureTable); 2520ddff1b5359433faf2eb1c4ff5320ddcbd42f52fEvan Cheng } 2530ddff1b5359433faf2eb1c4ff5320ddcbd42f52fEvan Cheng } else { 2540ddff1b5359433faf2eb1c4ff5320ddcbd42f52fEvan Cheng errs() << "'" << CPU 2550ddff1b5359433faf2eb1c4ff5320ddcbd42f52fEvan Cheng << "' is not a recognized processor for this target" 2560ddff1b5359433faf2eb1c4ff5320ddcbd42f52fEvan Cheng << " (ignoring processor)\n"; 2571a636de33bccc31337c1ea0811c7019fa0b31eeaBill Wendling } 258b3302db18a779527a4b1cd7a2024543ade7e83c6Jim Laskey } 2590ddff1b5359433faf2eb1c4ff5320ddcbd42f52fEvan Cheng 260b3302db18a779527a4b1cd7a2024543ade7e83c6Jim Laskey // Iterate through each feature 261dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines for (auto &Feature : Features) { 262839615a510c582ddcdb09a8e2934f30775daa032Jim Laskey // Check for help 2633e808a45b334608595a045c2ace7e2a107fb3b2bChris Lattner if (Feature == "+help") 264dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines Help(CPUTable, FeatureTable); 2652684d9e3c702b2ef9fd430155d94671d12fa994fJim Grosbach 266b3302db18a779527a4b1cd7a2024543ade7e83c6Jim Laskey // Find feature in table. 267b3302db18a779527a4b1cd7a2024543ade7e83c6Jim Laskey const SubtargetFeatureKV *FeatureEntry = 268dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines Find(StripFlag(Feature), FeatureTable); 269b3302db18a779527a4b1cd7a2024543ade7e83c6Jim Laskey // If there is a match 270b3302db18a779527a4b1cd7a2024543ade7e83c6Jim Laskey if (FeatureEntry) { 271b3302db18a779527a4b1cd7a2024543ade7e83c6Jim Laskey // Enable/disable feature in bits 2724222d806faae71ecc794cfdaa873817873c2f3d8Bill Wendling if (isEnabled(Feature)) { 2734222d806faae71ecc794cfdaa873817873c2f3d8Bill Wendling Bits |= FeatureEntry->Value; 2744222d806faae71ecc794cfdaa873817873c2f3d8Bill Wendling 2754222d806faae71ecc794cfdaa873817873c2f3d8Bill Wendling // For each feature that this implies, set it. 276dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines SetImpliedBits(Bits, FeatureEntry, FeatureTable); 2774222d806faae71ecc794cfdaa873817873c2f3d8Bill Wendling } else { 2784222d806faae71ecc794cfdaa873817873c2f3d8Bill Wendling Bits &= ~FeatureEntry->Value; 2794222d806faae71ecc794cfdaa873817873c2f3d8Bill Wendling 2804222d806faae71ecc794cfdaa873817873c2f3d8Bill Wendling // For each feature that implies this, clear it. 281dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines ClearImpliedBits(Bits, FeatureEntry, FeatureTable); 2824222d806faae71ecc794cfdaa873817873c2f3d8Bill Wendling } 283b3302db18a779527a4b1cd7a2024543ade7e83c6Jim Laskey } else { 284e0c86afac63a2dbbcff0ad79ed7b93d860451385Chris Lattner errs() << "'" << Feature 285e0c86afac63a2dbbcff0ad79ed7b93d860451385Chris Lattner << "' is not a recognized feature for this target" 286e0c86afac63a2dbbcff0ad79ed7b93d860451385Chris Lattner << " (ignoring feature)\n"; 287b3302db18a779527a4b1cd7a2024543ade7e83c6Jim Laskey } 288b3302db18a779527a4b1cd7a2024543ade7e83c6Jim Laskey } 2894222d806faae71ecc794cfdaa873817873c2f3d8Bill Wendling 290b3302db18a779527a4b1cd7a2024543ade7e83c6Jim Laskey return Bits; 291b3302db18a779527a4b1cd7a2024543ade7e83c6Jim Laskey} 292b3302db18a779527a4b1cd7a2024543ade7e83c6Jim Laskey 29334bd5d5d876212611d8b66a18f4c8604b342c6ebJim Laskey/// print - Print feature string. 29434bd5d5d876212611d8b66a18f4c8604b342c6ebJim Laskey/// 295e0c86afac63a2dbbcff0ad79ed7b93d860451385Chris Lattnervoid SubtargetFeatures::print(raw_ostream &OS) const { 296dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines for (auto &F : Features) 297dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines OS << F << " "; 298b3302db18a779527a4b1cd7a2024543ade7e83c6Jim Laskey OS << "\n"; 299b3302db18a779527a4b1cd7a2024543ade7e83c6Jim Laskey} 300b3302db18a779527a4b1cd7a2024543ade7e83c6Jim Laskey 301286c4dc355b8be6806081b23c3097485821c7642Manman Ren#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP) 30234bd5d5d876212611d8b66a18f4c8604b342c6ebJim Laskey/// dump - Dump feature info. 30334bd5d5d876212611d8b66a18f4c8604b342c6ebJim Laskey/// 304b3302db18a779527a4b1cd7a2024543ade7e83c6Jim Laskeyvoid SubtargetFeatures::dump() const { 3059759c305c2dbca2ba46645638ed39d5cb40b66d1David Greene print(dbgs()); 306b3302db18a779527a4b1cd7a2024543ade7e83c6Jim Laskey} 307cc77eece74c8db09acc2af425e7e6c88a5bb30d1Manman Ren#endif 308e823db8bae7fe42cd4f1fa861bec8c36a636702bViktor Kutuzov 309c697f8b28832a0dcb8b7ceb919b02628050b7730Rafael Espindola/// Adds the default features for the specified target triple. 310e823db8bae7fe42cd4f1fa861bec8c36a636702bViktor Kutuzov/// 311e823db8bae7fe42cd4f1fa861bec8c36a636702bViktor Kutuzov/// FIXME: This is an inelegant way of specifying the features of a 312e823db8bae7fe42cd4f1fa861bec8c36a636702bViktor Kutuzov/// subtarget. It would be better if we could encode this information 313e823db8bae7fe42cd4f1fa861bec8c36a636702bViktor Kutuzov/// into the IR. See <rdar://5972456>. 314e823db8bae7fe42cd4f1fa861bec8c36a636702bViktor Kutuzov/// 315276365dd4bc0c2160f91fd8062ae1fc90c86c324Evan Chengvoid SubtargetFeatures::getDefaultSubtargetFeatures(const Triple& Triple) { 316f6d8481adad4b763a380186ea62637df2d480c99Bill Wendling if (Triple.getVendor() == Triple::Apple) { 317f6d8481adad4b763a380186ea62637df2d480c99Bill Wendling if (Triple.getArch() == Triple::ppc) { 318f6d8481adad4b763a380186ea62637df2d480c99Bill Wendling // powerpc-apple-* 319f6d8481adad4b763a380186ea62637df2d480c99Bill Wendling AddFeature("altivec"); 320f6d8481adad4b763a380186ea62637df2d480c99Bill Wendling } else if (Triple.getArch() == Triple::ppc64) { 321f6d8481adad4b763a380186ea62637df2d480c99Bill Wendling // powerpc64-apple-* 322f6d8481adad4b763a380186ea62637df2d480c99Bill Wendling AddFeature("64bit"); 323f6d8481adad4b763a380186ea62637df2d480c99Bill Wendling AddFeature("altivec"); 324e823db8bae7fe42cd4f1fa861bec8c36a636702bViktor Kutuzov } 32581043ee5dc4cca470db8d45e080ba0a38efbffc2Bill Wendling } 326e823db8bae7fe42cd4f1fa861bec8c36a636702bViktor Kutuzov} 327