- //===- llvm/MC/SubtargetFeature.h - CPU characteristics ---------*- C++ -*-===// 
- // 
- // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 
- // See https://llvm.org/LICENSE.txt for license information. 
- // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 
- // 
- //===----------------------------------------------------------------------===// 
- // 
- /// \file Defines and manages user or tool specified CPU characteristics. 
- /// The intent is to be able to package specific features that should or should 
- /// not be used on a specific target processor.  A tool, such as llc, could, as 
- /// as example, gather chip info from the command line, a long with features 
- /// that should be used on that chip. 
- // 
- //===----------------------------------------------------------------------===// 
-   
- #ifndef LLVM_MC_SUBTARGETFEATURE_H 
- #define LLVM_MC_SUBTARGETFEATURE_H 
-   
- #include "llvm/ADT/ArrayRef.h" 
- #include "llvm/ADT/STLExtras.h" 
- #include "llvm/ADT/StringRef.h" 
- #include "llvm/Support/MathExtras.h" 
- #include <array> 
- #include <initializer_list> 
- #include <string> 
- #include <vector> 
-   
- namespace llvm { 
-   
- class raw_ostream; 
- class Triple; 
-   
- const unsigned MAX_SUBTARGET_WORDS = 4; 
- const unsigned MAX_SUBTARGET_FEATURES = MAX_SUBTARGET_WORDS * 64; 
-   
- /// Container class for subtarget features. 
- /// This is a constexpr reimplementation of a subset of std::bitset. It would be 
- /// nice to use std::bitset directly, but it doesn't support constant 
- /// initialization. 
- class FeatureBitset { 
-   static_assert((MAX_SUBTARGET_FEATURES % 64) == 0, 
-                 "Should be a multiple of 64!"); 
-   std::array<uint64_t, MAX_SUBTARGET_WORDS> Bits{}; 
-   
- protected: 
-   constexpr FeatureBitset(const std::array<uint64_t, MAX_SUBTARGET_WORDS> &B) 
-       : Bits{B} {} 
-   
- public: 
-   constexpr FeatureBitset() = default; 
-   constexpr FeatureBitset(std::initializer_list<unsigned> Init) { 
-     for (auto I : Init) 
-       set(I); 
-   } 
-   
-   FeatureBitset &set() { 
-     std::fill(std::begin(Bits), std::end(Bits), -1ULL); 
-     return *this; 
-   } 
-   
-   constexpr FeatureBitset &set(unsigned I) { 
-     // GCC <6.2 crashes if this is written in a single statement. 
-     uint64_t NewBits = Bits[I / 64] | (uint64_t(1) << (I % 64)); 
-     Bits[I / 64] = NewBits; 
-     return *this; 
-   } 
-   
-   constexpr FeatureBitset &reset(unsigned I) { 
-     // GCC <6.2 crashes if this is written in a single statement. 
-     uint64_t NewBits = Bits[I / 64] & ~(uint64_t(1) << (I % 64)); 
-     Bits[I / 64] = NewBits; 
-     return *this; 
-   } 
-   
-   constexpr FeatureBitset &flip(unsigned I) { 
-     // GCC <6.2 crashes if this is written in a single statement. 
-     uint64_t NewBits = Bits[I / 64] ^ (uint64_t(1) << (I % 64)); 
-     Bits[I / 64] = NewBits; 
-     return *this; 
-   } 
-   
-   constexpr bool operator[](unsigned I) const { 
-     uint64_t Mask = uint64_t(1) << (I % 64); 
-     return (Bits[I / 64] & Mask) != 0; 
-   } 
-   
-   constexpr bool test(unsigned I) const { return (*this)[I]; } 
-   
-   constexpr size_t size() const { return MAX_SUBTARGET_FEATURES; } 
-   
-   bool any() const { 
-     return llvm::any_of(Bits, [](uint64_t I) { return I != 0; }); 
-   } 
-   bool none() const { return !any(); } 
-   size_t count() const { 
-     size_t Count = 0; 
-     for (auto B : Bits) 
-       Count += llvm::popcount(B); 
-     return Count; 
-   } 
-   
-   constexpr FeatureBitset &operator^=(const FeatureBitset &RHS) { 
-     for (unsigned I = 0, E = Bits.size(); I != E; ++I) { 
-       Bits[I] ^= RHS.Bits[I]; 
-     } 
-     return *this; 
-   } 
-   constexpr FeatureBitset operator^(const FeatureBitset &RHS) const { 
-     FeatureBitset Result = *this; 
-     Result ^= RHS; 
-     return Result; 
-   } 
-   
-   constexpr FeatureBitset &operator&=(const FeatureBitset &RHS) { 
-     for (unsigned I = 0, E = Bits.size(); I != E; ++I) { 
-       Bits[I] &= RHS.Bits[I]; 
-     } 
-     return *this; 
-   } 
-   constexpr FeatureBitset operator&(const FeatureBitset &RHS) const { 
-     FeatureBitset Result = *this; 
-     Result &= RHS; 
-     return Result; 
-   } 
-   
-   constexpr FeatureBitset &operator|=(const FeatureBitset &RHS) { 
-     for (unsigned I = 0, E = Bits.size(); I != E; ++I) { 
-       Bits[I] |= RHS.Bits[I]; 
-     } 
-     return *this; 
-   } 
-   constexpr FeatureBitset operator|(const FeatureBitset &RHS) const { 
-     FeatureBitset Result = *this; 
-     Result |= RHS; 
-     return Result; 
-   } 
-   
-   constexpr FeatureBitset operator~() const { 
-     FeatureBitset Result = *this; 
-     for (auto &B : Result.Bits) 
-       B = ~B; 
-     return Result; 
-   } 
-   
-   bool operator==(const FeatureBitset &RHS) const { 
-     return std::equal(std::begin(Bits), std::end(Bits), std::begin(RHS.Bits)); 
-   } 
-   
-   bool operator!=(const FeatureBitset &RHS) const { return !(*this == RHS); } 
-   
-   bool operator < (const FeatureBitset &Other) const { 
-     for (unsigned I = 0, E = size(); I != E; ++I) { 
-       bool LHS = test(I), RHS = Other.test(I); 
-       if (LHS != RHS) 
-         return LHS < RHS; 
-     } 
-     return false; 
-   } 
- }; 
-   
- /// Class used to store the subtarget bits in the tables created by tablegen. 
- class FeatureBitArray : public FeatureBitset { 
- public: 
-   constexpr FeatureBitArray(const std::array<uint64_t, MAX_SUBTARGET_WORDS> &B) 
-       : FeatureBitset(B) {} 
-   
-   const FeatureBitset &getAsBitset() const { return *this; } 
- }; 
-   
- //===----------------------------------------------------------------------===// 
-   
- /// Manages the enabling and disabling of subtarget specific features. 
- /// 
- /// Features are encoded as a string of the form 
- ///   "+attr1,+attr2,-attr3,...,+attrN" 
- /// A comma separates each feature from the next (all lowercase.) 
- /// Each of the remaining features is prefixed with + or - indicating whether 
- /// that feature should be enabled or disabled contrary to the cpu 
- /// specification. 
- class SubtargetFeatures { 
-   std::vector<std::string> Features;    ///< Subtarget features as a vector 
-   
- public: 
-   explicit SubtargetFeatures(StringRef Initial = ""); 
-   
-   /// Returns features as a string. 
-   std::string getString() const; 
-   
-   /// Adds Features. 
-   void AddFeature(StringRef String, bool Enable = true); 
-   
-   void addFeaturesVector(const ArrayRef<std::string> OtherFeatures); 
-   
-   /// Returns the vector of individual subtarget features. 
-   const std::vector<std::string> &getFeatures() const { return Features; } 
-   
-   /// Prints feature string. 
-   void print(raw_ostream &OS) const; 
-   
-   // Dumps feature info. 
-   void dump() const; 
-   
-   /// Adds the default features for the specified target triple. 
-   void getDefaultSubtargetFeatures(const Triple& Triple); 
-   
-   /// Determine if a feature has a flag; '+' or '-' 
-   static bool hasFlag(StringRef Feature) { 
-     assert(!Feature.empty() && "Empty string"); 
-     // Get first character 
-     char Ch = Feature[0]; 
-     // Check if first character is '+' or '-' flag 
-     return Ch == '+' || Ch =='-'; 
-   } 
-   
-   /// Return string stripped of flag. 
-   static StringRef StripFlag(StringRef Feature) { 
-     return hasFlag(Feature) ? Feature.substr(1) : Feature; 
-   } 
-   
-   /// Return true if enable flag; '+'. 
-   static inline bool isEnabled(StringRef Feature) { 
-     assert(!Feature.empty() && "Empty string"); 
-     // Get first character 
-     char Ch = Feature[0]; 
-     // Check if first character is '+' for enabled 
-     return Ch == '+'; 
-   } 
-   
-   /// Splits a string of comma separated items in to a vector of strings. 
-   static void Split(std::vector<std::string> &V, StringRef S); 
- }; 
-   
- } // end namespace llvm 
-   
- #endif // LLVM_MC_SUBTARGETFEATURE_H 
-