1 // [AsmJit] 2 // Complete JIT Assembler for C++ Language. 3 // 4 // [License] 5 // Zlib - See COPYING file in this package. 6 7 // [Guard] 8 #ifndef _ASMJIT_CORE_INTUTIL_H 9 #define _ASMJIT_CORE_INTUTIL_H 10 11 // [Dependencies - AsmJit] 12 #include "../core/assert.h" 13 14 // [Api-Begin] 15 #include "../core/apibegin.h" 16 17 namespace AsmJit { 18 19 //! @addtogroup AsmJit_Core 20 //! @{ 21 22 // ============================================================================ 23 // [AsmJit::I32FPUnion] 24 // ============================================================================ 25 26 //! @internal 27 //! 28 //! @brief used to cast from float to 32-bit integer and vica versa. 29 union I32FPUnion 30 { 31 //! @brief 32-bit signed integer value. 32 int32_t i; 33 //! @brief 32-bit SP-FP value. 34 float f; 35 }; 36 37 // ============================================================================ 38 // [AsmJit::I64FPUnion] 39 // ============================================================================ 40 41 //! @internal 42 //! 43 //! @brief used to cast from double to 64-bit integer and vica versa. 44 union I64FPUnion 45 { 46 //! @brief 64-bit signed integer value. 47 int64_t i; 48 //! @brief 64-bit DP-FP value. 49 double f; 50 }; 51 52 // ============================================================================ 53 // [AsmJit::IntUtil] 54 // ============================================================================ 55 56 namespace IntUtil 57 { 58 // -------------------------------------------------------------------------- 59 // [Min/Max] 60 // -------------------------------------------------------------------------- 61 62 // NOTE: Because some environments declare min() and max() as macros, we 63 // decided to use different name so we never collide. 64 65 template<typename T> _min(const T & a,const T & b)66 static inline T _min(const T& a, const T& b) { return a < b ? a : b; } 67 template<typename T> _max(const T & a,const T & b)68 static inline T _max(const T& a, const T& b) { return a > b ? a : b; } 69 70 // -------------------------------------------------------------------------- 71 // [Limits] 72 // -------------------------------------------------------------------------- 73 74 template<typename T> maxValue()75 static inline T maxValue() { return ~T(0); } 76 77 // -------------------------------------------------------------------------- 78 // [IsInt / IsUInt] 79 // -------------------------------------------------------------------------- 80 81 //! @brief Returns @c true if a given integer @a x is signed 8-bit integer isInt8(intptr_t x)82 static inline bool isInt8(intptr_t x) { return x >= -128 && x <= 127; } 83 //! @brief Returns @c true if a given integer @a x is unsigned 8-bit integer isUInt8(intptr_t x)84 static inline bool isUInt8(intptr_t x) { return x >= 0 && x <= 255; } 85 86 //! @brief Returns @c true if a given integer @a x is signed 16-bit integer isInt16(intptr_t x)87 static inline bool isInt16(intptr_t x) { return x >= -32768 && x <= 32767; } 88 //! @brief Returns @c true if a given integer @a x is unsigned 16-bit integer isUInt16(intptr_t x)89 static inline bool isUInt16(intptr_t x) { return x >= 0 && x <= 65535; } 90 91 //! @brief Returns @c true if a given integer @a x is signed 16-bit integer isInt32(intptr_t x)92 static inline bool isInt32(intptr_t x) 93 { 94 #if defined(ASMJIT_X86) 95 return true; 96 #else 97 return x >= ASMJIT_INT64_C(-2147483648) && x <= ASMJIT_INT64_C(2147483647); 98 #endif 99 } 100 //! @brief Returns @c true if a given integer @a x is unsigned 16-bit integer isUInt32(intptr_t x)101 static inline bool isUInt32(intptr_t x) 102 { 103 #if defined(ASMJIT_X86) 104 return x >= 0; 105 #else 106 return x >= 0 && x <= ASMJIT_INT64_C(4294967295); 107 #endif 108 } 109 110 // -------------------------------------------------------------------------- 111 // [Masking] 112 // -------------------------------------------------------------------------- 113 maskFromIndex(uint32_t x)114 static inline uint32_t maskFromIndex(uint32_t x) 115 { 116 ASMJIT_ASSERT(x < 32); 117 return (1U << x); 118 } 119 maskUpToIndex(uint32_t x)120 static inline uint32_t maskUpToIndex(uint32_t x) 121 { 122 if (x >= 32) 123 return 0xFFFFFFFF; 124 else 125 return (1U << x) - 1; 126 } 127 128 // -------------------------------------------------------------------------- 129 // [Bits] 130 // -------------------------------------------------------------------------- 131 132 // From http://graphics.stanford.edu/~seander/bithacks.html . bitCount(uint32_t x)133 static inline uint32_t bitCount(uint32_t x) 134 { 135 x = x - ((x >> 1) & 0x55555555U); 136 x = (x & 0x33333333U) + ((x >> 2) & 0x33333333U); 137 return (((x + (x >> 4)) & 0x0F0F0F0FU) * 0x01010101U) >> 24; 138 } 139 findFirstBit(uint32_t mask)140 static inline uint32_t findFirstBit(uint32_t mask) 141 { 142 for (uint32_t i = 0; i < sizeof(uint32_t) * 8; i++, mask >>= 1) 143 { 144 if (mask & 0x1) 145 return i; 146 } 147 148 // kInvalidValue. 149 return 0xFFFFFFFF; 150 } 151 152 // -------------------------------------------------------------------------- 153 // [Alignment] 154 // -------------------------------------------------------------------------- 155 156 template<typename T> isAligned(T base,T alignment)157 static inline bool isAligned(T base, T alignment) 158 { 159 return (base % alignment) == 0; 160 } 161 162 //! @brief Align @a base to @a alignment. 163 template<typename T> align(T base,T alignment)164 static inline T align(T base, T alignment) 165 { 166 return (base + (alignment - 1)) & ~(alignment - 1); 167 } 168 169 //! @brief Get delta required to align @a base to @a alignment. 170 template<typename T> delta(T base,T alignment)171 static inline T delta(T base, T alignment) 172 { 173 return align(base, alignment) - base; 174 } 175 176 // -------------------------------------------------------------------------- 177 // [Round] 178 // -------------------------------------------------------------------------- 179 180 template<typename T> roundUp(T base,T alignment)181 static inline T roundUp(T base, T alignment) 182 { 183 T over = base % alignment; 184 return base + (over > 0 ? alignment - over : 0); 185 } 186 187 template<typename T> roundUpToPowerOf2(T base)188 static inline T roundUpToPowerOf2(T base) 189 { 190 // Implementation is from "Hacker's Delight" by Henry S. Warren, Jr., 191 // figure 3-3, page 48, where the function is called clp2. 192 base -= 1; 193 194 // I'm trying to make this portable and MSVC strikes me the warning C4293: 195 // "Shift count negative or too big, undefined behavior" 196 // Fixing... 197 #if defined(_MSC_VER) 198 # pragma warning(push) 199 # pragma warning(disable: 4293) 200 #endif // _MSC_VER 201 202 base = base | (base >> 1); 203 base = base | (base >> 2); 204 base = base | (base >> 4); 205 206 if (sizeof(T) >= 2) base = base | (base >> 8); 207 if (sizeof(T) >= 4) base = base | (base >> 16); 208 if (sizeof(T) >= 8) base = base | (base >> 16 >> 16); 209 210 #if defined(_MSC_VER) 211 # pragma warning(pop) 212 #endif // _MSC_VER 213 214 return base + 1; 215 } 216 217 // -------------------------------------------------------------------------- 218 // [Cast] 219 // -------------------------------------------------------------------------- 220 221 //! @brief Binary cast from 32-bit integer to SP-FP value (@c float). int32AsFloat(int32_t i)222 static inline float int32AsFloat(int32_t i) 223 { 224 I32FPUnion u; 225 u.i = i; 226 return u.f; 227 } 228 229 //! @brief Binary cast SP-FP value (@c float) to 32-bit integer. floatAsInt32(float f)230 static inline int32_t floatAsInt32(float f) 231 { 232 I32FPUnion u; 233 u.f = f; 234 return u.i; 235 } 236 237 //! @brief Binary cast from 64-bit integer to DP-FP value (@c double). int64AsDouble(int64_t i)238 static inline double int64AsDouble(int64_t i) 239 { 240 I64FPUnion u; 241 u.i = i; 242 return u.f; 243 } 244 245 //! @brief Binary cast from DP-FP value (@c double) to 64-bit integer. doubleAsInt64(double f)246 static inline int64_t doubleAsInt64(double f) 247 { 248 I64FPUnion u; 249 u.f = f; 250 return u.i; 251 } 252 }; 253 254 //! @} 255 256 } // AsmJit namespace 257 258 // [Api-End] 259 #include "../core/apiend.h" 260 261 // [Guard] 262 #endif // _ASMJIT_CORE_INTUTIL_H 263