1 // AsmJit - Machine code generation for C++ 2 // 3 // * Official AsmJit Home Page: https://asmjit.com 4 // * Official Github Repository: https://github.com/asmjit/asmjit 5 // 6 // Copyright (c) 2008-2020 The AsmJit Authors 7 // 8 // This software is provided 'as-is', without any express or implied 9 // warranty. In no event will the authors be held liable for any damages 10 // arising from the use of this software. 11 // 12 // Permission is granted to anyone to use this software for any purpose, 13 // including commercial applications, and to alter it and redistribute it 14 // freely, subject to the following restrictions: 15 // 16 // 1. The origin of this software must not be misrepresented; you must not 17 // claim that you wrote the original software. If you use this software 18 // in a product, an acknowledgment in the product documentation would be 19 // appreciated but is not required. 20 // 2. Altered source versions must be plainly marked as such, and must not be 21 // misrepresented as being the original software. 22 // 3. This notice may not be removed or altered from any source distribution. 23 24 #ifndef ASMJIT_CORE_FEATURES_H_INCLUDED 25 #define ASMJIT_CORE_FEATURES_H_INCLUDED 26 27 #include "../core/globals.h" 28 #include "../core/support.h" 29 30 ASMJIT_BEGIN_NAMESPACE 31 32 //! \addtogroup asmjit_core 33 //! \{ 34 35 // ============================================================================ 36 // [asmjit::BaseFeatures] 37 // ============================================================================ 38 39 //! Base class that provides information about CPU features. 40 //! 41 //! Internally each feature is represented by a single bit in an embedded 42 //! bit-array, however, feature bits are defined by an architecture specific 43 //! implementations, like \ref x86::Features. 44 class BaseFeatures { 45 public: 46 typedef Support::BitWord BitWord; 47 typedef Support::BitVectorIterator<BitWord> Iterator; 48 49 enum : uint32_t { 50 kMaxFeatures = 256, 51 kNumBitWords = kMaxFeatures / Support::kBitWordSizeInBits 52 }; 53 54 BitWord _bits[kNumBitWords]; 55 56 //! \name Construction & Destruction 57 //! \{ 58 BaseFeatures()59 inline BaseFeatures() noexcept { reset(); } 60 inline BaseFeatures(const BaseFeatures& other) noexcept = default; BaseFeatures(Globals::NoInit_)61 inline explicit BaseFeatures(Globals::NoInit_) noexcept {} 62 reset()63 inline void reset() noexcept { 64 for (size_t i = 0; i < kNumBitWords; i++) 65 _bits[i] = 0; 66 } 67 68 //! \} 69 70 //! \name Overloaded Operators 71 //! \{ 72 73 inline BaseFeatures& operator=(const BaseFeatures& other) noexcept = default; 74 75 inline bool operator==(const BaseFeatures& other) noexcept { return eq(other); } 76 inline bool operator!=(const BaseFeatures& other) noexcept { return !eq(other); } 77 78 //! \} 79 80 //! \name Cast 81 //! \{ 82 83 //! Casts this base class into a derived type `T`. 84 template<typename T> as()85 inline T& as() noexcept { return static_cast<T&>(*this); } 86 87 //! Casts this base class into a derived type `T` (const). 88 template<typename T> as()89 inline const T& as() const noexcept { return static_cast<const T&>(*this); } 90 91 //! \} 92 93 //! \name Accessors 94 //! \{ 95 empty()96 inline bool empty() const noexcept { 97 for (uint32_t i = 0; i < kNumBitWords; i++) 98 if (_bits[i]) 99 return false; 100 return true; 101 } 102 103 //! Returns all features as array of bitwords (see \ref Support::BitWord). bits()104 inline BitWord* bits() noexcept { return _bits; } 105 //! Returns all features as array of bitwords (const). bits()106 inline const BitWord* bits() const noexcept { return _bits; } 107 108 //! Returns the number of BitWords returned by \ref bits(). bitWordCount()109 inline size_t bitWordCount() const noexcept { return kNumBitWords; } 110 111 //! Returns \ref Support::BitVectorIterator, that can be used to iterate 112 //! all features efficiently iterator()113 inline Iterator iterator() const noexcept { 114 return Iterator(_bits, kNumBitWords); 115 } 116 117 //! Tests whether the feature `featureId` is present. has(uint32_t featureId)118 inline bool has(uint32_t featureId) const noexcept { 119 ASMJIT_ASSERT(featureId < kMaxFeatures); 120 121 uint32_t idx = featureId / Support::kBitWordSizeInBits; 122 uint32_t bit = featureId % Support::kBitWordSizeInBits; 123 124 return bool((_bits[idx] >> bit) & 0x1); 125 } 126 127 //! Tests whether all features as defined by `other` are present. hasAll(const BaseFeatures & other)128 inline bool hasAll(const BaseFeatures& other) const noexcept { 129 for (uint32_t i = 0; i < kNumBitWords; i++) 130 if ((_bits[i] & other._bits[i]) != other._bits[i]) 131 return false; 132 return true; 133 } 134 135 //! \} 136 137 //! \name Utilities 138 //! \{ 139 140 //! Adds the given CPU `featureId` to the list of features. add(uint32_t featureId)141 inline void add(uint32_t featureId) noexcept { 142 ASMJIT_ASSERT(featureId < kMaxFeatures); 143 144 uint32_t idx = featureId / Support::kBitWordSizeInBits; 145 uint32_t bit = featureId % Support::kBitWordSizeInBits; 146 147 _bits[idx] |= BitWord(1) << bit; 148 } 149 150 template<typename... Args> add(uint32_t featureId,Args...otherIds)151 inline void add(uint32_t featureId, Args... otherIds) noexcept { 152 add(featureId); 153 add(otherIds...); 154 } 155 156 //! Removes the given CPU `featureId` from the list of features. remove(uint32_t featureId)157 inline void remove(uint32_t featureId) noexcept { 158 ASMJIT_ASSERT(featureId < kMaxFeatures); 159 160 uint32_t idx = featureId / Support::kBitWordSizeInBits; 161 uint32_t bit = featureId % Support::kBitWordSizeInBits; 162 163 _bits[idx] &= ~(BitWord(1) << bit); 164 } 165 166 template<typename... Args> remove(uint32_t featureId,Args...otherIds)167 inline void remove(uint32_t featureId, Args... otherIds) noexcept { 168 remove(featureId); 169 remove(otherIds...); 170 } 171 eq(const BaseFeatures & other)172 inline bool eq(const BaseFeatures& other) const noexcept { 173 for (size_t i = 0; i < kNumBitWords; i++) 174 if (_bits[i] != other._bits[i]) 175 return false; 176 return true; 177 } 178 179 //! \} 180 }; 181 182 //! \} 183 184 ASMJIT_END_NAMESPACE 185 186 #endif // ASMJIT_CORE_FEATURES_H_INCLUDED 187