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/// PrependFlag - Return a string with a prepended flag; '+' or '-'. 5554195c1a9d8ac23d2dc1dfca818384cd26abe19bChris Lattner/// 5624e11afad266498ca447649b8522e01ac2073798Francois Pichetstatic inline std::string PrependFlag(const StringRef Feature, 57e1bff38386b0af24b5564c3d20888c7bbb045099Evan Cheng bool IsEnabled) { 5854195c1a9d8ac23d2dc1dfca818384cd26abe19bChris Lattner assert(!Feature.empty() && "Empty string"); 59e1bff38386b0af24b5564c3d20888c7bbb045099Evan Cheng if (hasFlag(Feature)) 60e1bff38386b0af24b5564c3d20888c7bbb045099Evan Cheng return Feature; 61e1bff38386b0af24b5564c3d20888c7bbb045099Evan Cheng std::string Prefix = IsEnabled ? "+" : "-"; 62e1bff38386b0af24b5564c3d20888c7bbb045099Evan Cheng Prefix += Feature; 6324e11afad266498ca447649b8522e01ac2073798Francois Pichet return Prefix; 6454195c1a9d8ac23d2dc1dfca818384cd26abe19bChris Lattner} 6554195c1a9d8ac23d2dc1dfca818384cd26abe19bChris Lattner 6654195c1a9d8ac23d2dc1dfca818384cd26abe19bChris Lattner/// Split - Splits a string of comma separated items in to a vector of strings. 6754195c1a9d8ac23d2dc1dfca818384cd26abe19bChris Lattner/// 68e1bff38386b0af24b5564c3d20888c7bbb045099Evan Chengstatic void Split(std::vector<std::string> &V, const StringRef S) { 69276365dd4bc0c2160f91fd8062ae1fc90c86c324Evan Cheng if (S.empty()) 70276365dd4bc0c2160f91fd8062ae1fc90c86c324Evan Cheng return; 71276365dd4bc0c2160f91fd8062ae1fc90c86c324Evan Cheng 72b3302db18a779527a4b1cd7a2024543ade7e83c6Jim Laskey // Start at beginning of string. 73b3302db18a779527a4b1cd7a2024543ade7e83c6Jim Laskey size_t Pos = 0; 74b3302db18a779527a4b1cd7a2024543ade7e83c6Jim Laskey while (true) { 75b3302db18a779527a4b1cd7a2024543ade7e83c6Jim Laskey // Find the next comma 76b3302db18a779527a4b1cd7a2024543ade7e83c6Jim Laskey size_t Comma = S.find(',', Pos); 77f451cb870efcf9e0302d25ed05f4cac6bb494e42Dan Gohman // If no comma found then the rest of the string is used 78b3302db18a779527a4b1cd7a2024543ade7e83c6Jim Laskey if (Comma == std::string::npos) { 79b3302db18a779527a4b1cd7a2024543ade7e83c6Jim Laskey // Add string to vector 80b3302db18a779527a4b1cd7a2024543ade7e83c6Jim Laskey V.push_back(S.substr(Pos)); 81b3302db18a779527a4b1cd7a2024543ade7e83c6Jim Laskey break; 82b3302db18a779527a4b1cd7a2024543ade7e83c6Jim Laskey } 83b3302db18a779527a4b1cd7a2024543ade7e83c6Jim Laskey // Otherwise add substring to vector 84b3302db18a779527a4b1cd7a2024543ade7e83c6Jim Laskey V.push_back(S.substr(Pos, Comma - Pos)); 85b3302db18a779527a4b1cd7a2024543ade7e83c6Jim Laskey // Advance to next item 86b3302db18a779527a4b1cd7a2024543ade7e83c6Jim Laskey Pos = Comma + 1; 87b3302db18a779527a4b1cd7a2024543ade7e83c6Jim Laskey } 88b3302db18a779527a4b1cd7a2024543ade7e83c6Jim Laskey} 89b3302db18a779527a4b1cd7a2024543ade7e83c6Jim Laskey 90b3302db18a779527a4b1cd7a2024543ade7e83c6Jim Laskey/// Join a vector of strings to a string with a comma separating each element. 9154195c1a9d8ac23d2dc1dfca818384cd26abe19bChris Lattner/// 9254195c1a9d8ac23d2dc1dfca818384cd26abe19bChris Lattnerstatic std::string Join(const std::vector<std::string> &V) { 93b3302db18a779527a4b1cd7a2024543ade7e83c6Jim Laskey // Start with empty string. 94b3302db18a779527a4b1cd7a2024543ade7e83c6Jim Laskey std::string Result; 952684d9e3c702b2ef9fd430155d94671d12fa994fJim Grosbach // If the vector is not empty 96b3302db18a779527a4b1cd7a2024543ade7e83c6Jim Laskey if (!V.empty()) { 97276365dd4bc0c2160f91fd8062ae1fc90c86c324Evan Cheng // Start with the first feature 98b3302db18a779527a4b1cd7a2024543ade7e83c6Jim Laskey Result = V[0]; 99b3302db18a779527a4b1cd7a2024543ade7e83c6Jim Laskey // For each successive feature 100b3302db18a779527a4b1cd7a2024543ade7e83c6Jim Laskey for (size_t i = 1; i < V.size(); i++) { 101b3302db18a779527a4b1cd7a2024543ade7e83c6Jim Laskey // Add a comma 102b3302db18a779527a4b1cd7a2024543ade7e83c6Jim Laskey Result += ","; 103b3302db18a779527a4b1cd7a2024543ade7e83c6Jim Laskey // Add the feature 104b3302db18a779527a4b1cd7a2024543ade7e83c6Jim Laskey Result += V[i]; 105b3302db18a779527a4b1cd7a2024543ade7e83c6Jim Laskey } 106b3302db18a779527a4b1cd7a2024543ade7e83c6Jim Laskey } 1072684d9e3c702b2ef9fd430155d94671d12fa994fJim Grosbach // Return the features string 108b3302db18a779527a4b1cd7a2024543ade7e83c6Jim Laskey return Result; 109b3302db18a779527a4b1cd7a2024543ade7e83c6Jim Laskey} 110b3302db18a779527a4b1cd7a2024543ade7e83c6Jim Laskey 111b3302db18a779527a4b1cd7a2024543ade7e83c6Jim Laskey/// Adding features. 112e1bff38386b0af24b5564c3d20888c7bbb045099Evan Chengvoid SubtargetFeatures::AddFeature(const StringRef String, 113b3302db18a779527a4b1cd7a2024543ade7e83c6Jim Laskey bool IsEnabled) { 114b3302db18a779527a4b1cd7a2024543ade7e83c6Jim Laskey // Don't add empty features 115b3302db18a779527a4b1cd7a2024543ade7e83c6Jim Laskey if (!String.empty()) { 116b3302db18a779527a4b1cd7a2024543ade7e83c6Jim Laskey // Convert to lowercase, prepend flag and add to vector 117590853667345d6fb191764b9d0bd2ff13589e3a3Benjamin Kramer Features.push_back(PrependFlag(String.lower(), IsEnabled)); 118b3302db18a779527a4b1cd7a2024543ade7e83c6Jim Laskey } 119b3302db18a779527a4b1cd7a2024543ade7e83c6Jim Laskey} 120b3302db18a779527a4b1cd7a2024543ade7e83c6Jim Laskey 12134bd5d5d876212611d8b66a18f4c8604b342c6ebJim Laskey/// Find KV in array using binary search. 122e1bff38386b0af24b5564c3d20888c7bbb045099Evan Chengtemplate<typename T> const T *Find(const StringRef S, const T *A, size_t L) { 1239471c8a93b117d8ac01c4ef1cb9faa583e03dec0Jeff Cohen // Make the lower bound element we're looking for 1249471c8a93b117d8ac01c4ef1cb9faa583e03dec0Jeff Cohen T KV; 125e1bff38386b0af24b5564c3d20888c7bbb045099Evan Cheng KV.Key = S.data(); 126b3302db18a779527a4b1cd7a2024543ade7e83c6Jim Laskey // Determine the end of the array 12734bd5d5d876212611d8b66a18f4c8604b342c6ebJim Laskey const T *Hi = A + L; 128b3302db18a779527a4b1cd7a2024543ade7e83c6Jim Laskey // Binary search the array 1299471c8a93b117d8ac01c4ef1cb9faa583e03dec0Jeff Cohen const T *F = std::lower_bound(A, Hi, KV); 130b3302db18a779527a4b1cd7a2024543ade7e83c6Jim Laskey // If not found then return NULL 1314d9af61a48639f37f1e0db745b26e4bf9ccdf1a0Evan Cheng if (F == Hi || StringRef(F->Key) != S) return NULL; 132b3302db18a779527a4b1cd7a2024543ade7e83c6Jim Laskey // Return the found array item 133b3302db18a779527a4b1cd7a2024543ade7e83c6Jim Laskey return F; 134b3302db18a779527a4b1cd7a2024543ade7e83c6Jim Laskey} 135b3302db18a779527a4b1cd7a2024543ade7e83c6Jim Laskey 1363e808a45b334608595a045c2ace7e2a107fb3b2bChris Lattner/// getLongestEntryLength - Return the length of the longest entry in the table. 13754195c1a9d8ac23d2dc1dfca818384cd26abe19bChris Lattner/// 1383e808a45b334608595a045c2ace7e2a107fb3b2bChris Lattnerstatic size_t getLongestEntryLength(const SubtargetFeatureKV *Table, 1393e808a45b334608595a045c2ace7e2a107fb3b2bChris Lattner size_t Size) { 14054195c1a9d8ac23d2dc1dfca818384cd26abe19bChris Lattner size_t MaxLen = 0; 1413e808a45b334608595a045c2ace7e2a107fb3b2bChris Lattner for (size_t i = 0; i < Size; i++) 14254195c1a9d8ac23d2dc1dfca818384cd26abe19bChris Lattner MaxLen = std::max(MaxLen, std::strlen(Table[i].Key)); 1433e808a45b334608595a045c2ace7e2a107fb3b2bChris Lattner return MaxLen; 1443e808a45b334608595a045c2ace7e2a107fb3b2bChris Lattner} 145ba76c21858bac5fd953d4dbe2f0624d8e884c7b5Chris Lattner 1463e808a45b334608595a045c2ace7e2a107fb3b2bChris Lattner/// Display help for feature choices. 1473e808a45b334608595a045c2ace7e2a107fb3b2bChris Lattner/// 1483e808a45b334608595a045c2ace7e2a107fb3b2bChris Lattnerstatic void Help(const SubtargetFeatureKV *CPUTable, size_t CPUTableSize, 1493e808a45b334608595a045c2ace7e2a107fb3b2bChris Lattner const SubtargetFeatureKV *FeatTable, size_t FeatTableSize) { 1503e808a45b334608595a045c2ace7e2a107fb3b2bChris Lattner // Determine the length of the longest CPU and Feature entries. 1513e808a45b334608595a045c2ace7e2a107fb3b2bChris Lattner unsigned MaxCPULen = getLongestEntryLength(CPUTable, CPUTableSize); 1523e808a45b334608595a045c2ace7e2a107fb3b2bChris Lattner unsigned MaxFeatLen = getLongestEntryLength(FeatTable, FeatTableSize); 153ba76c21858bac5fd953d4dbe2f0624d8e884c7b5Chris Lattner 1543e808a45b334608595a045c2ace7e2a107fb3b2bChris Lattner // Print the CPU table. 155e0c86afac63a2dbbcff0ad79ed7b93d860451385Chris Lattner errs() << "Available CPUs for this target:\n\n"; 1563e808a45b334608595a045c2ace7e2a107fb3b2bChris Lattner for (size_t i = 0; i != CPUTableSize; i++) 157962bad70f4277841cf6278306caa93ebce304b48Benjamin Kramer errs() << format(" %-*s - %s.\n", 158962bad70f4277841cf6278306caa93ebce304b48Benjamin Kramer MaxCPULen, CPUTable[i].Key, CPUTable[i].Desc); 159962bad70f4277841cf6278306caa93ebce304b48Benjamin Kramer errs() << '\n'; 160962bad70f4277841cf6278306caa93ebce304b48Benjamin Kramer 1613e808a45b334608595a045c2ace7e2a107fb3b2bChris Lattner // Print the Feature table. 162e0c86afac63a2dbbcff0ad79ed7b93d860451385Chris Lattner errs() << "Available features for this target:\n\n"; 1633e808a45b334608595a045c2ace7e2a107fb3b2bChris Lattner for (size_t i = 0; i != FeatTableSize; i++) 164962bad70f4277841cf6278306caa93ebce304b48Benjamin Kramer errs() << format(" %-*s - %s.\n", 165962bad70f4277841cf6278306caa93ebce304b48Benjamin Kramer MaxFeatLen, FeatTable[i].Key, FeatTable[i].Desc); 166962bad70f4277841cf6278306caa93ebce304b48Benjamin Kramer errs() << '\n'; 167962bad70f4277841cf6278306caa93ebce304b48Benjamin Kramer 168e0c86afac63a2dbbcff0ad79ed7b93d860451385Chris Lattner errs() << "Use +feature to enable a feature, or -feature to disable it.\n" 169962bad70f4277841cf6278306caa93ebce304b48Benjamin Kramer "For example, llc -mcpu=mycpu -mattr=+feature1,-feature2\n"; 1702402123413080aee8e9418e4f08b8613ef5cc360Nick Lewycky std::exit(1); 17154195c1a9d8ac23d2dc1dfca818384cd26abe19bChris Lattner} 17254195c1a9d8ac23d2dc1dfca818384cd26abe19bChris Lattner 17354195c1a9d8ac23d2dc1dfca818384cd26abe19bChris Lattner//===----------------------------------------------------------------------===// 17454195c1a9d8ac23d2dc1dfca818384cd26abe19bChris Lattner// SubtargetFeatures Implementation 17554195c1a9d8ac23d2dc1dfca818384cd26abe19bChris Lattner//===----------------------------------------------------------------------===// 17654195c1a9d8ac23d2dc1dfca818384cd26abe19bChris Lattner 177e1bff38386b0af24b5564c3d20888c7bbb045099Evan ChengSubtargetFeatures::SubtargetFeatures(const StringRef Initial) { 17854195c1a9d8ac23d2dc1dfca818384cd26abe19bChris Lattner // Break up string into separate features 17954195c1a9d8ac23d2dc1dfca818384cd26abe19bChris Lattner Split(Features, Initial); 180839615a510c582ddcdb09a8e2934f30775daa032Jim Laskey} 181839615a510c582ddcdb09a8e2934f30775daa032Jim Laskey 18254195c1a9d8ac23d2dc1dfca818384cd26abe19bChris Lattner 1833f9b9eb57dafc2a25a6e3d9ee570bd5a884b11e3Rafael Espindolastd::string SubtargetFeatures::getString() const { 18454195c1a9d8ac23d2dc1dfca818384cd26abe19bChris Lattner return Join(Features); 18554195c1a9d8ac23d2dc1dfca818384cd26abe19bChris Lattner} 18654195c1a9d8ac23d2dc1dfca818384cd26abe19bChris Lattner 1874222d806faae71ecc794cfdaa873817873c2f3d8Bill Wendling/// SetImpliedBits - For each feature that is (transitively) implied by this 1884222d806faae71ecc794cfdaa873817873c2f3d8Bill Wendling/// feature, set it. 18941a024385f1220eadc48b48cb4c044a5fbc1b361Anton Korobeynikov/// 1904222d806faae71ecc794cfdaa873817873c2f3d8Bill Wendlingstatic 191b6a638898a92d5cd782209fbeb673fe7846a29ebEvan Chengvoid SetImpliedBits(uint64_t &Bits, const SubtargetFeatureKV *FeatureEntry, 1924222d806faae71ecc794cfdaa873817873c2f3d8Bill Wendling const SubtargetFeatureKV *FeatureTable, 1934222d806faae71ecc794cfdaa873817873c2f3d8Bill Wendling size_t FeatureTableSize) { 1944222d806faae71ecc794cfdaa873817873c2f3d8Bill Wendling for (size_t i = 0; i < FeatureTableSize; ++i) { 1954222d806faae71ecc794cfdaa873817873c2f3d8Bill Wendling const SubtargetFeatureKV &FE = FeatureTable[i]; 1964222d806faae71ecc794cfdaa873817873c2f3d8Bill Wendling 1974222d806faae71ecc794cfdaa873817873c2f3d8Bill Wendling if (FeatureEntry->Value == FE.Value) continue; 1984222d806faae71ecc794cfdaa873817873c2f3d8Bill Wendling 1994222d806faae71ecc794cfdaa873817873c2f3d8Bill Wendling if (FeatureEntry->Implies & FE.Value) { 2004222d806faae71ecc794cfdaa873817873c2f3d8Bill Wendling Bits |= FE.Value; 2014222d806faae71ecc794cfdaa873817873c2f3d8Bill Wendling SetImpliedBits(Bits, &FE, FeatureTable, FeatureTableSize); 2024222d806faae71ecc794cfdaa873817873c2f3d8Bill Wendling } 2034222d806faae71ecc794cfdaa873817873c2f3d8Bill Wendling } 2044222d806faae71ecc794cfdaa873817873c2f3d8Bill Wendling} 2054222d806faae71ecc794cfdaa873817873c2f3d8Bill Wendling 2064222d806faae71ecc794cfdaa873817873c2f3d8Bill Wendling/// ClearImpliedBits - For each feature that (transitively) implies this 2074222d806faae71ecc794cfdaa873817873c2f3d8Bill Wendling/// feature, clear it. 2082684d9e3c702b2ef9fd430155d94671d12fa994fJim Grosbach/// 2094222d806faae71ecc794cfdaa873817873c2f3d8Bill Wendlingstatic 210b6a638898a92d5cd782209fbeb673fe7846a29ebEvan Chengvoid ClearImpliedBits(uint64_t &Bits, const SubtargetFeatureKV *FeatureEntry, 2114222d806faae71ecc794cfdaa873817873c2f3d8Bill Wendling const SubtargetFeatureKV *FeatureTable, 2124222d806faae71ecc794cfdaa873817873c2f3d8Bill Wendling size_t FeatureTableSize) { 2134222d806faae71ecc794cfdaa873817873c2f3d8Bill Wendling for (size_t i = 0; i < FeatureTableSize; ++i) { 2144222d806faae71ecc794cfdaa873817873c2f3d8Bill Wendling const SubtargetFeatureKV &FE = FeatureTable[i]; 2154222d806faae71ecc794cfdaa873817873c2f3d8Bill Wendling 2164222d806faae71ecc794cfdaa873817873c2f3d8Bill Wendling if (FeatureEntry->Value == FE.Value) continue; 2174222d806faae71ecc794cfdaa873817873c2f3d8Bill Wendling 2184222d806faae71ecc794cfdaa873817873c2f3d8Bill Wendling if (FE.Implies & FeatureEntry->Value) { 2194222d806faae71ecc794cfdaa873817873c2f3d8Bill Wendling Bits &= ~FE.Value; 2204222d806faae71ecc794cfdaa873817873c2f3d8Bill Wendling ClearImpliedBits(Bits, &FE, FeatureTable, FeatureTableSize); 2214222d806faae71ecc794cfdaa873817873c2f3d8Bill Wendling } 2224222d806faae71ecc794cfdaa873817873c2f3d8Bill Wendling } 2234222d806faae71ecc794cfdaa873817873c2f3d8Bill Wendling} 22434bd5d5d876212611d8b66a18f4c8604b342c6ebJim Laskey 225ffc0e73046f737d75e0a62b3a83ef19bcef111e3Evan Cheng/// ToggleFeature - Toggle a feature and returns the newly updated feature 226ffc0e73046f737d75e0a62b3a83ef19bcef111e3Evan Cheng/// bits. 227ffc0e73046f737d75e0a62b3a83ef19bcef111e3Evan Chenguint64_t 228ffc0e73046f737d75e0a62b3a83ef19bcef111e3Evan ChengSubtargetFeatures::ToggleFeature(uint64_t Bits, const StringRef Feature, 229ffc0e73046f737d75e0a62b3a83ef19bcef111e3Evan Cheng const SubtargetFeatureKV *FeatureTable, 230ffc0e73046f737d75e0a62b3a83ef19bcef111e3Evan Cheng size_t FeatureTableSize) { 231ffc0e73046f737d75e0a62b3a83ef19bcef111e3Evan Cheng // Find feature in table. 232ffc0e73046f737d75e0a62b3a83ef19bcef111e3Evan Cheng const SubtargetFeatureKV *FeatureEntry = 233ffc0e73046f737d75e0a62b3a83ef19bcef111e3Evan Cheng Find(StripFlag(Feature), FeatureTable, FeatureTableSize); 234ffc0e73046f737d75e0a62b3a83ef19bcef111e3Evan Cheng // If there is a match 235ffc0e73046f737d75e0a62b3a83ef19bcef111e3Evan Cheng if (FeatureEntry) { 236ffc0e73046f737d75e0a62b3a83ef19bcef111e3Evan Cheng if ((Bits & FeatureEntry->Value) == FeatureEntry->Value) { 237ffc0e73046f737d75e0a62b3a83ef19bcef111e3Evan Cheng Bits &= ~FeatureEntry->Value; 238ffc0e73046f737d75e0a62b3a83ef19bcef111e3Evan Cheng 239ffc0e73046f737d75e0a62b3a83ef19bcef111e3Evan Cheng // For each feature that implies this, clear it. 240ffc0e73046f737d75e0a62b3a83ef19bcef111e3Evan Cheng ClearImpliedBits(Bits, FeatureEntry, FeatureTable, FeatureTableSize); 241ffc0e73046f737d75e0a62b3a83ef19bcef111e3Evan Cheng } else { 242ffc0e73046f737d75e0a62b3a83ef19bcef111e3Evan Cheng Bits |= FeatureEntry->Value; 243ffc0e73046f737d75e0a62b3a83ef19bcef111e3Evan Cheng 244ffc0e73046f737d75e0a62b3a83ef19bcef111e3Evan Cheng // For each feature that this implies, set it. 245ffc0e73046f737d75e0a62b3a83ef19bcef111e3Evan Cheng SetImpliedBits(Bits, FeatureEntry, FeatureTable, FeatureTableSize); 246ffc0e73046f737d75e0a62b3a83ef19bcef111e3Evan Cheng } 247ffc0e73046f737d75e0a62b3a83ef19bcef111e3Evan Cheng } else { 248ffc0e73046f737d75e0a62b3a83ef19bcef111e3Evan Cheng errs() << "'" << Feature 249ffc0e73046f737d75e0a62b3a83ef19bcef111e3Evan Cheng << "' is not a recognized feature for this target" 250ffc0e73046f737d75e0a62b3a83ef19bcef111e3Evan Cheng << " (ignoring feature)\n"; 251ffc0e73046f737d75e0a62b3a83ef19bcef111e3Evan Cheng } 252ffc0e73046f737d75e0a62b3a83ef19bcef111e3Evan Cheng 253ffc0e73046f737d75e0a62b3a83ef19bcef111e3Evan Cheng return Bits; 254ffc0e73046f737d75e0a62b3a83ef19bcef111e3Evan Cheng} 2552684d9e3c702b2ef9fd430155d94671d12fa994fJim Grosbach 256ffc0e73046f737d75e0a62b3a83ef19bcef111e3Evan Cheng 257276365dd4bc0c2160f91fd8062ae1fc90c86c324Evan Cheng/// getFeatureBits - Get feature bits a CPU. 25854195c1a9d8ac23d2dc1dfca818384cd26abe19bChris Lattner/// 259e1bff38386b0af24b5564c3d20888c7bbb045099Evan Chenguint64_t SubtargetFeatures::getFeatureBits(const StringRef CPU, 260276365dd4bc0c2160f91fd8062ae1fc90c86c324Evan Cheng const SubtargetFeatureKV *CPUTable, 261276365dd4bc0c2160f91fd8062ae1fc90c86c324Evan Cheng size_t CPUTableSize, 262276365dd4bc0c2160f91fd8062ae1fc90c86c324Evan Cheng const SubtargetFeatureKV *FeatureTable, 263276365dd4bc0c2160f91fd8062ae1fc90c86c324Evan Cheng size_t FeatureTableSize) { 2640ddff1b5359433faf2eb1c4ff5320ddcbd42f52fEvan Cheng if (!FeatureTableSize || !CPUTableSize) 2650ddff1b5359433faf2eb1c4ff5320ddcbd42f52fEvan Cheng return 0; 2660ddff1b5359433faf2eb1c4ff5320ddcbd42f52fEvan Cheng 267b3302db18a779527a4b1cd7a2024543ade7e83c6Jim Laskey#ifndef NDEBUG 268b3302db18a779527a4b1cd7a2024543ade7e83c6Jim Laskey for (size_t i = 1; i < CPUTableSize; i++) { 269b3302db18a779527a4b1cd7a2024543ade7e83c6Jim Laskey assert(strcmp(CPUTable[i - 1].Key, CPUTable[i].Key) < 0 && 270b3302db18a779527a4b1cd7a2024543ade7e83c6Jim Laskey "CPU table is not sorted"); 271b3302db18a779527a4b1cd7a2024543ade7e83c6Jim Laskey } 272b3302db18a779527a4b1cd7a2024543ade7e83c6Jim Laskey for (size_t i = 1; i < FeatureTableSize; i++) { 273b3302db18a779527a4b1cd7a2024543ade7e83c6Jim Laskey assert(strcmp(FeatureTable[i - 1].Key, FeatureTable[i].Key) < 0 && 274b3302db18a779527a4b1cd7a2024543ade7e83c6Jim Laskey "CPU features table is not sorted"); 275b3302db18a779527a4b1cd7a2024543ade7e83c6Jim Laskey } 276b3302db18a779527a4b1cd7a2024543ade7e83c6Jim Laskey#endif 277b6a638898a92d5cd782209fbeb673fe7846a29ebEvan Cheng uint64_t Bits = 0; // Resulting bits 2783e808a45b334608595a045c2ace7e2a107fb3b2bChris Lattner 27934bd5d5d876212611d8b66a18f4c8604b342c6ebJim Laskey // Check if help is needed 280276365dd4bc0c2160f91fd8062ae1fc90c86c324Evan Cheng if (CPU == "help") 2813e808a45b334608595a045c2ace7e2a107fb3b2bChris Lattner Help(CPUTable, CPUTableSize, FeatureTable, FeatureTableSize); 2822684d9e3c702b2ef9fd430155d94671d12fa994fJim Grosbach 2830ddff1b5359433faf2eb1c4ff5320ddcbd42f52fEvan Cheng // Find CPU entry if CPU name is specified. 2840ddff1b5359433faf2eb1c4ff5320ddcbd42f52fEvan Cheng if (!CPU.empty()) { 2850ddff1b5359433faf2eb1c4ff5320ddcbd42f52fEvan Cheng const SubtargetFeatureKV *CPUEntry = Find(CPU, CPUTable, CPUTableSize); 2860ddff1b5359433faf2eb1c4ff5320ddcbd42f52fEvan Cheng // If there is a match 2870ddff1b5359433faf2eb1c4ff5320ddcbd42f52fEvan Cheng if (CPUEntry) { 2880ddff1b5359433faf2eb1c4ff5320ddcbd42f52fEvan Cheng // Set base feature bits 2890ddff1b5359433faf2eb1c4ff5320ddcbd42f52fEvan Cheng Bits = CPUEntry->Value; 2901a636de33bccc31337c1ea0811c7019fa0b31eeaBill Wendling 2910ddff1b5359433faf2eb1c4ff5320ddcbd42f52fEvan Cheng // Set the feature implied by this CPU feature, if any. 2920ddff1b5359433faf2eb1c4ff5320ddcbd42f52fEvan Cheng for (size_t i = 0; i < FeatureTableSize; ++i) { 2930ddff1b5359433faf2eb1c4ff5320ddcbd42f52fEvan Cheng const SubtargetFeatureKV &FE = FeatureTable[i]; 2940ddff1b5359433faf2eb1c4ff5320ddcbd42f52fEvan Cheng if (CPUEntry->Value & FE.Value) 2950ddff1b5359433faf2eb1c4ff5320ddcbd42f52fEvan Cheng SetImpliedBits(Bits, &FE, FeatureTable, FeatureTableSize); 2960ddff1b5359433faf2eb1c4ff5320ddcbd42f52fEvan Cheng } 2970ddff1b5359433faf2eb1c4ff5320ddcbd42f52fEvan Cheng } else { 2980ddff1b5359433faf2eb1c4ff5320ddcbd42f52fEvan Cheng errs() << "'" << CPU 2990ddff1b5359433faf2eb1c4ff5320ddcbd42f52fEvan Cheng << "' is not a recognized processor for this target" 3000ddff1b5359433faf2eb1c4ff5320ddcbd42f52fEvan Cheng << " (ignoring processor)\n"; 3011a636de33bccc31337c1ea0811c7019fa0b31eeaBill Wendling } 302b3302db18a779527a4b1cd7a2024543ade7e83c6Jim Laskey } 3030ddff1b5359433faf2eb1c4ff5320ddcbd42f52fEvan Cheng 304b3302db18a779527a4b1cd7a2024543ade7e83c6Jim Laskey // Iterate through each feature 305276365dd4bc0c2160f91fd8062ae1fc90c86c324Evan Cheng for (size_t i = 0, E = Features.size(); i < E; i++) { 306e1bff38386b0af24b5564c3d20888c7bbb045099Evan Cheng const StringRef Feature = Features[i]; 3072684d9e3c702b2ef9fd430155d94671d12fa994fJim Grosbach 308839615a510c582ddcdb09a8e2934f30775daa032Jim Laskey // Check for help 3093e808a45b334608595a045c2ace7e2a107fb3b2bChris Lattner if (Feature == "+help") 3103e808a45b334608595a045c2ace7e2a107fb3b2bChris Lattner Help(CPUTable, CPUTableSize, FeatureTable, FeatureTableSize); 3112684d9e3c702b2ef9fd430155d94671d12fa994fJim Grosbach 312b3302db18a779527a4b1cd7a2024543ade7e83c6Jim Laskey // Find feature in table. 313b3302db18a779527a4b1cd7a2024543ade7e83c6Jim Laskey const SubtargetFeatureKV *FeatureEntry = 314b3302db18a779527a4b1cd7a2024543ade7e83c6Jim Laskey Find(StripFlag(Feature), FeatureTable, FeatureTableSize); 315b3302db18a779527a4b1cd7a2024543ade7e83c6Jim Laskey // If there is a match 316b3302db18a779527a4b1cd7a2024543ade7e83c6Jim Laskey if (FeatureEntry) { 317b3302db18a779527a4b1cd7a2024543ade7e83c6Jim Laskey // Enable/disable feature in bits 3184222d806faae71ecc794cfdaa873817873c2f3d8Bill Wendling if (isEnabled(Feature)) { 3194222d806faae71ecc794cfdaa873817873c2f3d8Bill Wendling Bits |= FeatureEntry->Value; 3204222d806faae71ecc794cfdaa873817873c2f3d8Bill Wendling 3214222d806faae71ecc794cfdaa873817873c2f3d8Bill Wendling // For each feature that this implies, set it. 3224222d806faae71ecc794cfdaa873817873c2f3d8Bill Wendling SetImpliedBits(Bits, FeatureEntry, FeatureTable, FeatureTableSize); 3234222d806faae71ecc794cfdaa873817873c2f3d8Bill Wendling } else { 3244222d806faae71ecc794cfdaa873817873c2f3d8Bill Wendling Bits &= ~FeatureEntry->Value; 3254222d806faae71ecc794cfdaa873817873c2f3d8Bill Wendling 3264222d806faae71ecc794cfdaa873817873c2f3d8Bill Wendling // For each feature that implies this, clear it. 3274222d806faae71ecc794cfdaa873817873c2f3d8Bill Wendling ClearImpliedBits(Bits, FeatureEntry, FeatureTable, FeatureTableSize); 3284222d806faae71ecc794cfdaa873817873c2f3d8Bill Wendling } 329b3302db18a779527a4b1cd7a2024543ade7e83c6Jim Laskey } else { 330e0c86afac63a2dbbcff0ad79ed7b93d860451385Chris Lattner errs() << "'" << Feature 331e0c86afac63a2dbbcff0ad79ed7b93d860451385Chris Lattner << "' is not a recognized feature for this target" 332e0c86afac63a2dbbcff0ad79ed7b93d860451385Chris Lattner << " (ignoring feature)\n"; 333b3302db18a779527a4b1cd7a2024543ade7e83c6Jim Laskey } 334b3302db18a779527a4b1cd7a2024543ade7e83c6Jim Laskey } 3354222d806faae71ecc794cfdaa873817873c2f3d8Bill Wendling 336b3302db18a779527a4b1cd7a2024543ade7e83c6Jim Laskey return Bits; 337b3302db18a779527a4b1cd7a2024543ade7e83c6Jim Laskey} 338b3302db18a779527a4b1cd7a2024543ade7e83c6Jim Laskey 339276365dd4bc0c2160f91fd8062ae1fc90c86c324Evan Cheng/// Get scheduling itinerary of a CPU. 34098eb98b0f2e6573f5aee67ce3e75624392d637b7Roman Divackyconst void *SubtargetFeatures::getItinerary(const StringRef CPU, 34198eb98b0f2e6573f5aee67ce3e75624392d637b7Roman Divacky const SubtargetInfoKV *Table, 34298eb98b0f2e6573f5aee67ce3e75624392d637b7Roman Divacky size_t TableSize) { 34334bd5d5d876212611d8b66a18f4c8604b342c6ebJim Laskey assert(Table && "missing table"); 34434bd5d5d876212611d8b66a18f4c8604b342c6ebJim Laskey#ifndef NDEBUG 34534bd5d5d876212611d8b66a18f4c8604b342c6ebJim Laskey for (size_t i = 1; i < TableSize; i++) { 34634bd5d5d876212611d8b66a18f4c8604b342c6ebJim Laskey assert(strcmp(Table[i - 1].Key, Table[i].Key) < 0 && "Table is not sorted"); 34734bd5d5d876212611d8b66a18f4c8604b342c6ebJim Laskey } 34834bd5d5d876212611d8b66a18f4c8604b342c6ebJim Laskey#endif 34934bd5d5d876212611d8b66a18f4c8604b342c6ebJim Laskey 35034bd5d5d876212611d8b66a18f4c8604b342c6ebJim Laskey // Find entry 351276365dd4bc0c2160f91fd8062ae1fc90c86c324Evan Cheng const SubtargetInfoKV *Entry = Find(CPU, Table, TableSize); 3522684d9e3c702b2ef9fd430155d94671d12fa994fJim Grosbach 35334bd5d5d876212611d8b66a18f4c8604b342c6ebJim Laskey if (Entry) { 35434bd5d5d876212611d8b66a18f4c8604b342c6ebJim Laskey return Entry->Value; 35534bd5d5d876212611d8b66a18f4c8604b342c6ebJim Laskey } else { 356276365dd4bc0c2160f91fd8062ae1fc90c86c324Evan Cheng errs() << "'" << CPU 357e0c86afac63a2dbbcff0ad79ed7b93d860451385Chris Lattner << "' is not a recognized processor for this target" 358e0c86afac63a2dbbcff0ad79ed7b93d860451385Chris Lattner << " (ignoring processor)\n"; 35934bd5d5d876212611d8b66a18f4c8604b342c6ebJim Laskey return NULL; 36034bd5d5d876212611d8b66a18f4c8604b342c6ebJim Laskey } 36134bd5d5d876212611d8b66a18f4c8604b342c6ebJim Laskey} 36234bd5d5d876212611d8b66a18f4c8604b342c6ebJim Laskey 36334bd5d5d876212611d8b66a18f4c8604b342c6ebJim Laskey/// print - Print feature string. 36434bd5d5d876212611d8b66a18f4c8604b342c6ebJim Laskey/// 365e0c86afac63a2dbbcff0ad79ed7b93d860451385Chris Lattnervoid SubtargetFeatures::print(raw_ostream &OS) const { 366e0c86afac63a2dbbcff0ad79ed7b93d860451385Chris Lattner for (size_t i = 0, e = Features.size(); i != e; ++i) 367b3302db18a779527a4b1cd7a2024543ade7e83c6Jim Laskey OS << Features[i] << " "; 368b3302db18a779527a4b1cd7a2024543ade7e83c6Jim Laskey OS << "\n"; 369b3302db18a779527a4b1cd7a2024543ade7e83c6Jim Laskey} 370b3302db18a779527a4b1cd7a2024543ade7e83c6Jim Laskey 371cc77eece74c8db09acc2af425e7e6c88a5bb30d1Manman Ren#ifndef NDEBUG 37234bd5d5d876212611d8b66a18f4c8604b342c6ebJim Laskey/// dump - Dump feature info. 37334bd5d5d876212611d8b66a18f4c8604b342c6ebJim Laskey/// 374b3302db18a779527a4b1cd7a2024543ade7e83c6Jim Laskeyvoid SubtargetFeatures::dump() const { 3759759c305c2dbca2ba46645638ed39d5cb40b66d1David Greene print(dbgs()); 376b3302db18a779527a4b1cd7a2024543ade7e83c6Jim Laskey} 377cc77eece74c8db09acc2af425e7e6c88a5bb30d1Manman Ren#endif 378e823db8bae7fe42cd4f1fa861bec8c36a636702bViktor Kutuzov 37981043ee5dc4cca470db8d45e080ba0a38efbffc2Bill Wendling/// getDefaultSubtargetFeatures - Return a string listing the features 38081043ee5dc4cca470db8d45e080ba0a38efbffc2Bill Wendling/// associated with the target triple. 381e823db8bae7fe42cd4f1fa861bec8c36a636702bViktor Kutuzov/// 382e823db8bae7fe42cd4f1fa861bec8c36a636702bViktor Kutuzov/// FIXME: This is an inelegant way of specifying the features of a 383e823db8bae7fe42cd4f1fa861bec8c36a636702bViktor Kutuzov/// subtarget. It would be better if we could encode this information 384e823db8bae7fe42cd4f1fa861bec8c36a636702bViktor Kutuzov/// into the IR. See <rdar://5972456>. 385e823db8bae7fe42cd4f1fa861bec8c36a636702bViktor Kutuzov/// 386276365dd4bc0c2160f91fd8062ae1fc90c86c324Evan Chengvoid SubtargetFeatures::getDefaultSubtargetFeatures(const Triple& Triple) { 387f6d8481adad4b763a380186ea62637df2d480c99Bill Wendling if (Triple.getVendor() == Triple::Apple) { 388f6d8481adad4b763a380186ea62637df2d480c99Bill Wendling if (Triple.getArch() == Triple::ppc) { 389f6d8481adad4b763a380186ea62637df2d480c99Bill Wendling // powerpc-apple-* 390f6d8481adad4b763a380186ea62637df2d480c99Bill Wendling AddFeature("altivec"); 391f6d8481adad4b763a380186ea62637df2d480c99Bill Wendling } else if (Triple.getArch() == Triple::ppc64) { 392f6d8481adad4b763a380186ea62637df2d480c99Bill Wendling // powerpc64-apple-* 393f6d8481adad4b763a380186ea62637df2d480c99Bill Wendling AddFeature("64bit"); 394f6d8481adad4b763a380186ea62637df2d480c99Bill Wendling AddFeature("altivec"); 395e823db8bae7fe42cd4f1fa861bec8c36a636702bViktor Kutuzov } 39681043ee5dc4cca470db8d45e080ba0a38efbffc2Bill Wendling } 397e823db8bae7fe42cd4f1fa861bec8c36a636702bViktor Kutuzov} 398