// [AsmJit] // Complete x86/x64 JIT and Remote Assembler for C++. // // [License] // Zlib - See LICENSE.md file in the package. // [Guard] #ifndef _ASMJIT_BASE_UTILS_H #define _ASMJIT_BASE_UTILS_H // [Dependencies] #include "../base/globals.h" #if ASMJIT_CC_MSC_GE(14, 0, 0) # include #endif // ASMJIT_OS_WINDOWS // [Api-Begin] #include "../asmjit_apibegin.h" namespace asmjit { //! \addtogroup asmjit_base //! \{ // ============================================================================ // [asmjit::IntTraits] // ============================================================================ //! \internal //! \{ template struct IntTraitsPrivate {}; // Let it fail if not specialized! template<> struct IntTraitsPrivate<1, 0> { typedef int IntType; typedef int8_t SignedType; typedef uint8_t UnsignedType; }; template<> struct IntTraitsPrivate<1, 1> { typedef int IntType; typedef int8_t SignedType; typedef uint8_t UnsignedType; }; template<> struct IntTraitsPrivate<2, 0> { typedef int IntType; typedef int16_t SignedType; typedef uint16_t UnsignedType; }; template<> struct IntTraitsPrivate<2, 1> { typedef int IntType; typedef int16_t SignedType; typedef uint16_t UnsignedType; }; template<> struct IntTraitsPrivate<4, 0> { typedef int64_t IntType; typedef int32_t SignedType; typedef uint32_t UnsignedType; }; template<> struct IntTraitsPrivate<4, 1> { typedef int IntType; typedef int32_t SignedType; typedef uint32_t UnsignedType; }; template<> struct IntTraitsPrivate<8, 0> { typedef int64_t IntType; typedef int64_t SignedType; typedef uint64_t UnsignedType; }; template<> struct IntTraitsPrivate<8, 1> { typedef int64_t IntType; typedef int64_t SignedType; typedef uint64_t UnsignedType; }; //! \internal template struct IntTraits { enum { kIsSigned = static_cast(~static_cast(0)) < static_cast(0), kIsUnsigned = !kIsSigned, kIs8Bit = sizeof(T) == 1, kIs16Bit = sizeof(T) == 2, kIs32Bit = sizeof(T) == 4, kIs64Bit = sizeof(T) == 8, kIsIntPtr = sizeof(T) == sizeof(intptr_t) }; typedef typename IntTraitsPrivate::IntType IntType; typedef typename IntTraitsPrivate::SignedType SignedType; typedef typename IntTraitsPrivate::UnsignedType UnsignedType; //! Get a minimum value of `T`. static ASMJIT_INLINE T minValue() noexcept { return kIsSigned ? T((~static_cast(0) >> 1) + static_cast(1)) : T(0); } //! Get a maximum value of `T`. static ASMJIT_INLINE T maxValue() noexcept { return kIsSigned ? T(~static_cast(0) >> 1) : ~T(0); } }; //! \} // ============================================================================ // [asmjit::Utils] // ============================================================================ //! AsmJit utilities - integer, string, etc... namespace Utils { // -------------------------------------------------------------------------- // [Float <-> Int] // -------------------------------------------------------------------------- //! \internal union FloatBits { int32_t i; float f; }; //! \internal union DoubleBits { int64_t i; double d; }; //! Bit-cast `float` to a 32-bit integer. static ASMJIT_INLINE int32_t floatAsInt(float f) noexcept { FloatBits m; m.f = f; return m.i; } //! Bit-cast 32-bit integer to `float`. static ASMJIT_INLINE float intAsFloat(int32_t i) noexcept { FloatBits m; m.i = i; return m.f; } //! Bit-cast `double` to a 64-bit integer. static ASMJIT_INLINE int64_t doubleAsInt(double d) noexcept { DoubleBits m; m.d = d; return m.i; } //! Bit-cast 64-bit integer to `double`. static ASMJIT_INLINE double intAsDouble(int64_t i) noexcept { DoubleBits m; m.i = i; return m.d; } // -------------------------------------------------------------------------- // [Pack / Unpack] // -------------------------------------------------------------------------- //! Pack four 8-bit integer into a 32-bit integer as it is an array of `{b0,b1,b2,b3}`. static ASMJIT_INLINE uint32_t pack32_4x8(uint32_t b0, uint32_t b1, uint32_t b2, uint32_t b3) noexcept { return ASMJIT_PACK32_4x8(b0, b1, b2, b3); } //! Pack two 32-bit integer into a 64-bit integer as it is an array of `{u0,u1}`. static ASMJIT_INLINE uint64_t pack64_2x32(uint32_t u0, uint32_t u1) noexcept { return ASMJIT_ARCH_LE ? (static_cast(u1) << 32) + u0 : (static_cast(u0) << 32) + u1; } // -------------------------------------------------------------------------- // [Position of byte (in bit-shift)] // -------------------------------------------------------------------------- static ASMJIT_INLINE uint32_t byteShiftOfDWordStruct(uint32_t index) noexcept { if (ASMJIT_ARCH_LE) return index * 8; else return (sizeof(uint32_t) - 1 - index) * 8; } // -------------------------------------------------------------------------- // [Lower/Upper] // -------------------------------------------------------------------------- template static ASMJIT_INLINE T toLower(T c) noexcept { return c ^ (static_cast(c >= T('A') && c <= T('Z')) << 5); } template static ASMJIT_INLINE T toUpper(T c) noexcept { return c ^ (static_cast(c >= T('a') && c <= T('z')) << 5); } // -------------------------------------------------------------------------- // [Hash] // -------------------------------------------------------------------------- // \internal static ASMJIT_INLINE uint32_t hashRound(uint32_t hash, uint32_t c) noexcept { return hash * 65599 + c; } // Get a hash of the given string `str` of `len` length. Length must be valid // as this function doesn't check for a null terminator and allows it in the // middle of the string. static ASMJIT_INLINE uint32_t hashString(const char* str, size_t len) noexcept { uint32_t hVal = 0; for (uint32_t i = 0; i < len; i++) hVal = hashRound(hVal, str[i]); return hVal; } // -------------------------------------------------------------------------- // [Swap] // -------------------------------------------------------------------------- template static ASMJIT_INLINE void swap(T& a, T& b) noexcept { T tmp = a; a = b; b = tmp; } // -------------------------------------------------------------------------- // [InInterval] // -------------------------------------------------------------------------- //! Get whether `x` is greater than or equal to `a` and lesses than or equal to `b`. template static ASMJIT_INLINE bool inInterval(T x, T a, T b) noexcept { return x >= a && x <= b; } // -------------------------------------------------------------------------- // [AsInt] // -------------------------------------------------------------------------- //! Map an integer `x` of type `T` to `int` or `int64_t` depending on the //! type. Used internally by AsmJit to dispatch arguments that can be of //! arbitrary integer type into a function argument that is either `int` or //! `int64_t`. template static ASMJIT_INLINE typename IntTraits::IntType asInt(T x) noexcept { return static_cast::IntType>(x); } // -------------------------------------------------------------------------- // [IsInt / IsUInt] // -------------------------------------------------------------------------- //! Get whether the given integer `x` can be casted to a 4-bit signed integer. template static ASMJIT_INLINE bool isInt4(T x) noexcept { typedef typename IntTraits::SignedType SignedType; typedef typename IntTraits::UnsignedType UnsignedType; if (IntTraits::kIsSigned) return inInterval(SignedType(x), -8, 7); else return UnsignedType(x) <= UnsignedType(7U); } //! Get whether the given integer `x` can be casted to an 8-bit signed integer. template static ASMJIT_INLINE bool isInt8(T x) noexcept { typedef typename IntTraits::SignedType SignedType; typedef typename IntTraits::UnsignedType UnsignedType; if (IntTraits::kIsSigned) return sizeof(T) <= 1 || inInterval(SignedType(x), -128, 127); else return UnsignedType(x) <= UnsignedType(127U); } //! Get whether the given integer `x` can be casted to a 16-bit signed integer. template static ASMJIT_INLINE bool isInt16(T x) noexcept { typedef typename IntTraits::SignedType SignedType; typedef typename IntTraits::UnsignedType UnsignedType; if (IntTraits::kIsSigned) return sizeof(T) <= 2 || inInterval(SignedType(x), -32768, 32767); else return sizeof(T) <= 1 || UnsignedType(x) <= UnsignedType(32767U); } //! Get whether the given integer `x` can be casted to a 32-bit signed integer. template static ASMJIT_INLINE bool isInt32(T x) noexcept { typedef typename IntTraits::SignedType SignedType; typedef typename IntTraits::UnsignedType UnsignedType; if (IntTraits::kIsSigned) return sizeof(T) <= 4 || inInterval(SignedType(x), -2147483647 - 1, 2147483647); else return sizeof(T) <= 2 || UnsignedType(x) <= UnsignedType(2147483647U); } //! Get whether the given integer `x` can be casted to a 4-bit unsigned integer. template static ASMJIT_INLINE bool isUInt4(T x) noexcept { typedef typename IntTraits::UnsignedType UnsignedType; if (IntTraits::kIsSigned) return x >= T(0) && x <= T(15); else return UnsignedType(x) <= UnsignedType(15U); } //! Get whether the given integer `x` can be casted to an 8-bit unsigned integer. template static ASMJIT_INLINE bool isUInt8(T x) noexcept { typedef typename IntTraits::UnsignedType UnsignedType; if (IntTraits::kIsSigned) return x >= T(0) && (sizeof(T) <= 1 ? true : x <= T(255)); else return sizeof(T) <= 1 || UnsignedType(x) <= UnsignedType(255U); } //! Get whether the given integer `x` can be casted to a 12-bit unsigned integer (ARM specific). template static ASMJIT_INLINE bool isUInt12(T x) noexcept { typedef typename IntTraits::UnsignedType UnsignedType; if (IntTraits::kIsSigned) return x >= T(0) && (sizeof(T) <= 1 ? true : x <= T(4095)); else return sizeof(T) <= 1 || UnsignedType(x) <= UnsignedType(4095U); } //! Get whether the given integer `x` can be casted to a 16-bit unsigned integer. template static ASMJIT_INLINE bool isUInt16(T x) noexcept { typedef typename IntTraits::UnsignedType UnsignedType; if (IntTraits::kIsSigned) return x >= T(0) && (sizeof(T) <= 2 ? true : x <= T(65535)); else return sizeof(T) <= 2 || UnsignedType(x) <= UnsignedType(65535U); } //! Get whether the given integer `x` can be casted to a 32-bit unsigned integer. template static ASMJIT_INLINE bool isUInt32(T x) noexcept { typedef typename IntTraits::UnsignedType UnsignedType; if (IntTraits::kIsSigned) return x >= T(0) && (sizeof(T) <= 4 ? true : x <= T(4294967295U)); else return sizeof(T) <= 4 || UnsignedType(x) <= UnsignedType(4294967295U); } // -------------------------------------------------------------------------- // [IsPowerOf2] // -------------------------------------------------------------------------- //! Get whether the `n` value is a power of two (only one bit is set). template static ASMJIT_INLINE bool isPowerOf2(T n) noexcept { return n != 0 && (n & (n - 1)) == 0; } // -------------------------------------------------------------------------- // [Mask] // -------------------------------------------------------------------------- //! Generate a bit-mask that has `x` bit set. static ASMJIT_INLINE uint32_t mask(uint32_t x) noexcept { ASMJIT_ASSERT(x < 32); return static_cast(1) << x; } //! Generate a bit-mask that has `x0` and `x1` bits set. static ASMJIT_INLINE uint32_t mask(uint32_t x0, uint32_t x1) noexcept { return mask(x0) | mask(x1); } //! Generate a bit-mask that has `x0`, `x1` and `x2` bits set. static ASMJIT_INLINE uint32_t mask(uint32_t x0, uint32_t x1, uint32_t x2) noexcept { return mask(x0, x1) | mask(x2); } //! Generate a bit-mask that has `x0`, `x1`, `x2` and `x3` bits set. static ASMJIT_INLINE uint32_t mask(uint32_t x0, uint32_t x1, uint32_t x2, uint32_t x3) noexcept { return mask(x0, x1) | mask(x2, x3); } //! Generate a bit-mask that has `x0`, `x1`, `x2`, `x3` and `x4` bits set. static ASMJIT_INLINE uint32_t mask(uint32_t x0, uint32_t x1, uint32_t x2, uint32_t x3, uint32_t x4) noexcept { return mask(x0, x1) | mask(x2, x3) | mask(x4); } //! Generate a bit-mask that has `x0`, `x1`, `x2`, `x3`, `x4` and `x5` bits set. static ASMJIT_INLINE uint32_t mask(uint32_t x0, uint32_t x1, uint32_t x2, uint32_t x3, uint32_t x4, uint32_t x5) noexcept { return mask(x0, x1) | mask(x2, x3) | mask(x4, x5); } //! Generate a bit-mask that has `x0`, `x1`, `x2`, `x3`, `x4`, `x5` and `x6` bits set. static ASMJIT_INLINE uint32_t mask(uint32_t x0, uint32_t x1, uint32_t x2, uint32_t x3, uint32_t x4, uint32_t x5, uint32_t x6) noexcept { return mask(x0, x1) | mask(x2, x3) | mask(x4, x5) | mask(x6); } //! Generate a bit-mask that has `x0`, `x1`, `x2`, `x3`, `x4`, `x5`, `x6` and `x7` bits set. static ASMJIT_INLINE uint32_t mask(uint32_t x0, uint32_t x1, uint32_t x2, uint32_t x3, uint32_t x4, uint32_t x5, uint32_t x6, uint32_t x7) noexcept { return mask(x0, x1) | mask(x2, x3) | mask(x4, x5) | mask(x6, x7); } //! Generate a bit-mask that has `x0`, `x1`, `x2`, `x3`, `x4`, `x5`, `x6`, `x7` and `x8` bits set. static ASMJIT_INLINE uint32_t mask(uint32_t x0, uint32_t x1, uint32_t x2, uint32_t x3, uint32_t x4, uint32_t x5, uint32_t x6, uint32_t x7, uint32_t x8) noexcept { return mask(x0, x1) | mask(x2, x3) | mask(x4, x5) | mask(x6, x7) | mask(x8); } //! Generate a bit-mask that has `x0`, `x1`, `x2`, `x3`, `x4`, `x5`, `x6`, `x7`, `x8` and `x9` bits set. static ASMJIT_INLINE uint32_t mask(uint32_t x0, uint32_t x1, uint32_t x2, uint32_t x3, uint32_t x4, uint32_t x5, uint32_t x6, uint32_t x7, uint32_t x8, uint32_t x9) noexcept { return mask(x0, x1) | mask(x2, x3) | mask(x4, x5) | mask(x6, x7) | mask(x8, x9); } // -------------------------------------------------------------------------- // [Bits] // -------------------------------------------------------------------------- //! Generate a bit-mask that has `x` least significant bits set. static ASMJIT_INLINE uint32_t bits(uint32_t x) noexcept { // Shifting more bits than the type has results in undefined behavior. In // such case asmjit trashes the result by ORing with `overflow` mask, which // discards the undefined value returned by the shift. uint32_t overflow = static_cast( -static_cast(x >= sizeof(uint32_t) * 8)); return ((static_cast(1) << x) - 1U) | overflow; } // -------------------------------------------------------------------------- // [HasBit] // -------------------------------------------------------------------------- //! Get whether `x` has bit `n` set. template static ASMJIT_INLINE bool hasBit(T x, Index n) noexcept { return (x & (static_cast(1) << n)) != 0; } // -------------------------------------------------------------------------- // [BitCount] // -------------------------------------------------------------------------- static ASMJIT_INLINE uint32_t bitCountSlow(uint32_t x) noexcept { // From: http://graphics.stanford.edu/~seander/bithacks.html x = x - ((x >> 1) & 0x55555555U); x = (x & 0x33333333U) + ((x >> 2) & 0x33333333U); return (((x + (x >> 4)) & 0x0F0F0F0FU) * 0x01010101U) >> 24; } //! Get count of bits in `x`. static ASMJIT_INLINE uint32_t bitCount(uint32_t x) noexcept { #if ASMJIT_CC_GCC || ASMJIT_CC_CLANG return __builtin_popcount(x); #else return bitCountSlow(x); #endif } // -------------------------------------------------------------------------- // [FirstBitOf] // -------------------------------------------------------------------------- template struct FirstBitOfTImpl { enum { _shift = (In & ASMJIT_UINT64_C(0x0000FFFFFFFFFFFF)) == 0 ? 48 : (In & ASMJIT_UINT64_C(0x00000000FFFFFFFF)) == 0 ? 32 : (In & ASMJIT_UINT64_C(0x000000000000FFFF)) == 0 ? 16 : 0, kValue = ((In >> _shift) & 0x0001) ? (_shift + 0) : ((In >> _shift) & 0x0002) ? (_shift + 1) : ((In >> _shift) & 0x0004) ? (_shift + 2) : ((In >> _shift) & 0x0008) ? (_shift + 3) : ((In >> _shift) & 0x0010) ? (_shift + 4) : ((In >> _shift) & 0x0020) ? (_shift + 5) : ((In >> _shift) & 0x0040) ? (_shift + 6) : ((In >> _shift) & 0x0080) ? (_shift + 7) : ((In >> _shift) & 0x0100) ? (_shift + 8) : ((In >> _shift) & 0x0200) ? (_shift + 9) : ((In >> _shift) & 0x0400) ? (_shift + 10) : ((In >> _shift) & 0x0800) ? (_shift + 11) : ((In >> _shift) & 0x1000) ? (_shift + 12) : ((In >> _shift) & 0x2000) ? (_shift + 13) : ((In >> _shift) & 0x4000) ? (_shift + 14) : ((In >> _shift) & 0x8000) ? (_shift + 15) : 0 }; }; template<> struct FirstBitOfTImpl<0> {}; template static ASMJIT_INLINE uint32_t firstBitOfT() noexcept { return FirstBitOfTImpl::kValue; } // -------------------------------------------------------------------------- // [FindFirstBit] // -------------------------------------------------------------------------- //! \internal static ASMJIT_INLINE uint32_t findFirstBitSlow(uint32_t mask) noexcept { // This is a reference (slow) implementation of `findFirstBit()`, used when // we don't have a C++ compiler support. The implementation speed has been // improved to check for 2 bits per iteration. uint32_t i = 1; while (mask != 0) { uint32_t two = mask & 0x3; if (two != 0x0) return i - (two & 0x1); i += 2; mask >>= 2; } return 0xFFFFFFFFU; } //! Find a first bit in `mask`. static ASMJIT_INLINE uint32_t findFirstBit(uint32_t mask) noexcept { #if ASMJIT_CC_MSC_GE(14, 0, 0) && (ASMJIT_ARCH_X86 || ASMJIT_ARCH_ARM32 || \ ASMJIT_ARCH_X64 || ASMJIT_ARCH_ARM64) DWORD i; if (_BitScanForward(&i, mask)) return static_cast(i); else return 0xFFFFFFFFU; #elif ASMJIT_CC_GCC_GE(3, 4, 6) || ASMJIT_CC_CLANG if (mask) return __builtin_ctz(mask); else return 0xFFFFFFFFU; #else return findFirstBitSlow(mask); #endif } // -------------------------------------------------------------------------- // [Misc] // -------------------------------------------------------------------------- static ASMJIT_INLINE uint32_t keepNOnesFromRight(uint32_t mask, uint32_t nBits) noexcept { uint32_t m = 0x1; do { nBits -= (mask & m) != 0; m <<= 1; if (nBits == 0) { m -= 1; mask &= m; break; } } while (m); return mask; } static ASMJIT_INLINE uint32_t indexNOnesFromRight(uint8_t* dst, uint32_t mask, uint32_t nBits) noexcept { uint32_t totalBits = nBits; uint8_t i = 0; uint32_t m = 0x1; do { if (mask & m) { *dst++ = i; if (--nBits == 0) break; } m <<= 1; i++; } while (m); return totalBits - nBits; } // -------------------------------------------------------------------------- // [Alignment] // -------------------------------------------------------------------------- template static ASMJIT_INLINE bool isAligned(X base, Y alignment) noexcept { typedef typename IntTraitsPrivate::UnsignedType U; return ((U)base % (U)alignment) == 0; } template static ASMJIT_INLINE X alignTo(X x, Y alignment) noexcept { typedef typename IntTraitsPrivate::UnsignedType U; return (X)( ((U)x + (U)(alignment - 1)) & ~(static_cast(alignment) - 1) ); } //! Get delta required to align `base` to `alignment`. template static ASMJIT_INLINE X alignDiff(X base, Y alignment) noexcept { return alignTo(base, alignment) - base; } template static ASMJIT_INLINE T alignToPowerOf2(T base) noexcept { // Implementation is from "Hacker's Delight" by Henry S. Warren, Jr. base -= 1; #if defined(_MSC_VER) # pragma warning(push) # pragma warning(disable: 4293) #endif // _MSC_VER base = base | (base >> 1); base = base | (base >> 2); base = base | (base >> 4); // 8/16/32 constants are multiplied by the condition to prevent a compiler // complaining about the 'shift count >= type width' (GCC). if (sizeof(T) >= 2) base = base | (base >> ( 8 * (sizeof(T) >= 2))); // Base >> 8. if (sizeof(T) >= 4) base = base | (base >> (16 * (sizeof(T) >= 4))); // Base >> 16. if (sizeof(T) >= 8) base = base | (base >> (32 * (sizeof(T) >= 8))); // Base >> 32. #if defined(_MSC_VER) # pragma warning(pop) #endif // _MSC_VER return base + 1; } // -------------------------------------------------------------------------- // [String] // -------------------------------------------------------------------------- static ASMJIT_INLINE size_t strLen(const char* s, size_t maxlen) noexcept { size_t i; for (i = 0; i < maxlen; i++) if (!s[i]) break; return i; } static ASMJIT_INLINE const char* findPackedString(const char* p, uint32_t id) noexcept { uint32_t i = 0; while (i < id) { while (p[0]) p++; p++; i++; } return p; } //! \internal //! //! Compare two instruction names. //! //! `a` is a null terminated instruction name from `???InstDB::nameData[]` table. //! `b` is a non-null terminated instruction name passed to `???Inst::getIdByName()`. static ASMJIT_INLINE int cmpInstName(const char* a, const char* b, size_t len) noexcept { for (size_t i = 0; i < len; i++) { int c = static_cast(static_cast(a[i])) - static_cast(static_cast(b[i])) ; if (c != 0) return c; } return static_cast(a[len]); } // -------------------------------------------------------------------------- // [BSwap] // -------------------------------------------------------------------------- static ASMJIT_INLINE uint32_t byteswap32(uint32_t x) noexcept { #if ASMJIT_CC_MSC return static_cast(_byteswap_ulong(x)); #elif ASMJIT_CC_GCC_GE(4, 3, 0) || ASMJIT_CC_CLANG_GE(2, 6, 0) return __builtin_bswap32(x); #else uint32_t y = x & 0x00FFFF00U; x = (x << 24) + (x >> 24); y = (y << 8) + (y >> 8); return x + (y & 0x00FFFF00U); #endif } // -------------------------------------------------------------------------- // [ReadMem] // -------------------------------------------------------------------------- static ASMJIT_INLINE uint32_t readU8(const void* p) noexcept { return static_cast(static_cast(p)[0]); } static ASMJIT_INLINE int32_t readI8(const void* p) noexcept { return static_cast(static_cast(p)[0]); } template static ASMJIT_INLINE uint32_t readU16xLE(const void* p) noexcept { ASMJIT_ASSUME_ALIGNED(p, Alignment > 1 ? Alignment : 1U); if (ASMJIT_ARCH_LE && (ASMJIT_ARCH_UNALIGNED_16 || Alignment >= 2)) { return static_cast(static_cast(p)[0]); } else { uint32_t x = static_cast(static_cast(p)[0]); uint32_t y = static_cast(static_cast(p)[1]); return x + (y << 8); } } template static ASMJIT_INLINE uint32_t readU16xBE(const void* p) noexcept { ASMJIT_ASSUME_ALIGNED(p, Alignment > 1 ? Alignment : 1U); if (ASMJIT_ARCH_BE && (ASMJIT_ARCH_UNALIGNED_16 || Alignment >= 2)) { return static_cast(static_cast(p)[0]); } else { uint32_t x = static_cast(static_cast(p)[0]); uint32_t y = static_cast(static_cast(p)[1]); return (x << 8) + y; } } template static ASMJIT_INLINE uint32_t readU16x(const void* p) noexcept { return ASMJIT_ARCH_LE ? readU16xLE(p) : readU16xBE(p); } template static ASMJIT_INLINE int32_t readI16xLE(const void* p) noexcept { ASMJIT_ASSUME_ALIGNED(p, Alignment > 1 ? Alignment : 1U); if (ASMJIT_ARCH_LE && (ASMJIT_ARCH_UNALIGNED_16 || Alignment >= 2)) { return static_cast(static_cast(p)[0]); } else { int32_t x = static_cast(static_cast(p)[0]); int32_t y = static_cast(static_cast(p)[1]); return x + (y << 8); } } template static ASMJIT_INLINE int32_t readI16xBE(const void* p) noexcept { ASMJIT_ASSUME_ALIGNED(p, Alignment > 1 ? Alignment : 1U); if (ASMJIT_ARCH_BE && (ASMJIT_ARCH_UNALIGNED_16 || Alignment >= 2)) { return static_cast(static_cast(p)[0]); } else { int32_t x = static_cast(static_cast(p)[0]); int32_t y = static_cast(static_cast(p)[1]); return (x << 8) + y; } } template static ASMJIT_INLINE int32_t readI16x(const void* p) noexcept { return ASMJIT_ARCH_LE ? readI16xLE(p) : readI16xBE(p); } static ASMJIT_INLINE uint32_t readU16aLE(const void* p) noexcept { return readU16xLE<2>(p); } static ASMJIT_INLINE uint32_t readU16uLE(const void* p) noexcept { return readU16xLE<0>(p); } static ASMJIT_INLINE uint32_t readU16aBE(const void* p) noexcept { return readU16xBE<2>(p); } static ASMJIT_INLINE uint32_t readU16uBE(const void* p) noexcept { return readU16xBE<0>(p); } static ASMJIT_INLINE uint32_t readU16a(const void* p) noexcept { return readU16x<2>(p); } static ASMJIT_INLINE uint32_t readU16u(const void* p) noexcept { return readU16x<0>(p); } static ASMJIT_INLINE int32_t readI16aLE(const void* p) noexcept { return readI16xLE<2>(p); } static ASMJIT_INLINE int32_t readI16uLE(const void* p) noexcept { return readI16xLE<0>(p); } static ASMJIT_INLINE int32_t readI16aBE(const void* p) noexcept { return readI16xBE<2>(p); } static ASMJIT_INLINE int32_t readI16uBE(const void* p) noexcept { return readI16xBE<0>(p); } static ASMJIT_INLINE int32_t readI16a(const void* p) noexcept { return readI16x<2>(p); } static ASMJIT_INLINE int32_t readI16u(const void* p) noexcept { return readI16x<0>(p); } template static ASMJIT_INLINE uint32_t readU32xLE(const void* p) noexcept { ASMJIT_ASSUME_ALIGNED(p, Alignment > 1 ? Alignment : 1U); if (ASMJIT_ARCH_UNALIGNED_32 || Alignment >= 4) { uint32_t x = static_cast(p)[0]; return ASMJIT_ARCH_LE ? x : byteswap32(x); } else { uint32_t x = readU16xLE(static_cast(p) + 0); uint32_t y = readU16xLE(static_cast(p) + 2); return x + (y << 16); } } template static ASMJIT_INLINE uint32_t readU32xBE(const void* p) noexcept { ASMJIT_ASSUME_ALIGNED(p, Alignment > 1 ? Alignment : 1U); if (ASMJIT_ARCH_UNALIGNED_32 || Alignment >= 4) { uint32_t x = static_cast(p)[0]; return ASMJIT_ARCH_BE ? x : byteswap32(x); } else { uint32_t x = readU16xBE(static_cast(p) + 0); uint32_t y = readU16xBE(static_cast(p) + 2); return (x << 16) + y; } } template static ASMJIT_INLINE uint32_t readU32x(const void* p) noexcept { return ASMJIT_ARCH_LE ? readU32xLE(p) : readU32xBE(p); } template static ASMJIT_INLINE int32_t readI32xLE(const void* p) noexcept { return static_cast(readU32xLE(p)); } template static ASMJIT_INLINE int32_t readI32xBE(const void* p) noexcept { return static_cast(readU32xBE(p)); } template static ASMJIT_INLINE int32_t readI32x(const void* p) noexcept { return ASMJIT_ARCH_LE ? readI32xLE(p) : readI32xBE(p); } static ASMJIT_INLINE uint32_t readU32a(const void* p) noexcept { return readU32x<4>(p); } static ASMJIT_INLINE uint32_t readU32u(const void* p) noexcept { return readU32x<0>(p); } static ASMJIT_INLINE uint32_t readU32aLE(const void* p) noexcept { return readU32xLE<4>(p); } static ASMJIT_INLINE uint32_t readU32uLE(const void* p) noexcept { return readU32xLE<0>(p); } static ASMJIT_INLINE uint32_t readU32aBE(const void* p) noexcept { return readU32xBE<4>(p); } static ASMJIT_INLINE uint32_t readU32uBE(const void* p) noexcept { return readU32xBE<0>(p); } static ASMJIT_INLINE int32_t readI32a(const void* p) noexcept { return readI32x<4>(p); } static ASMJIT_INLINE int32_t readI32u(const void* p) noexcept { return readI32x<0>(p); } static ASMJIT_INLINE int32_t readI32aLE(const void* p) noexcept { return readI32xLE<4>(p); } static ASMJIT_INLINE int32_t readI32uLE(const void* p) noexcept { return readI32xLE<0>(p); } static ASMJIT_INLINE int32_t readI32aBE(const void* p) noexcept { return readI32xBE<4>(p); } static ASMJIT_INLINE int32_t readI32uBE(const void* p) noexcept { return readI32xBE<0>(p); } template static ASMJIT_INLINE uint64_t readU64xLE(const void* p) noexcept { ASMJIT_ASSUME_ALIGNED(p, Alignment > 1 ? Alignment : 1U); if (ASMJIT_ARCH_LE && (ASMJIT_ARCH_UNALIGNED_64 || Alignment >= 8)) { return static_cast(p)[0]; } else { uint32_t x = readU32xLE(static_cast(p) + 0); uint32_t y = readU32xLE(static_cast(p) + 4); return static_cast(x) + (static_cast(y) << 32); } } template static ASMJIT_INLINE uint64_t readU64xBE(const void* p) noexcept { ASMJIT_ASSUME_ALIGNED(p, Alignment > 1 ? Alignment : 1U); if (ASMJIT_ARCH_BE && (ASMJIT_ARCH_UNALIGNED_64 || Alignment >= 8)) { return static_cast(p)[0]; } else { uint32_t x = readU32xLE(static_cast(p) + 0); uint32_t y = readU32xLE(static_cast(p) + 4); return (static_cast(x) << 32) + static_cast(y); } } template static ASMJIT_INLINE uint64_t readU64x(const void* p) noexcept { return ASMJIT_ARCH_LE ? readU64xLE(p) : readU64xBE(p); } template static ASMJIT_INLINE int64_t readI64xLE(const void* p) noexcept { return static_cast(readU64xLE(p)); } template static ASMJIT_INLINE int64_t readI64xBE(const void* p) noexcept { return static_cast(readU64xBE(p)); } template static ASMJIT_INLINE int64_t readI64x(const void* p) noexcept { return ASMJIT_ARCH_LE ? readI64xLE(p) : readI64xBE(p); } static ASMJIT_INLINE uint64_t readU64a(const void* p) noexcept { return readU64x<8>(p); } static ASMJIT_INLINE uint64_t readU64u(const void* p) noexcept { return readU64x<0>(p); } static ASMJIT_INLINE uint64_t readU64aLE(const void* p) noexcept { return readU64xLE<8>(p); } static ASMJIT_INLINE uint64_t readU64uLE(const void* p) noexcept { return readU64xLE<0>(p); } static ASMJIT_INLINE uint64_t readU64aBE(const void* p) noexcept { return readU64xBE<8>(p); } static ASMJIT_INLINE uint64_t readU64uBE(const void* p) noexcept { return readU64xBE<0>(p); } static ASMJIT_INLINE int64_t readI64a(const void* p) noexcept { return readI64x<8>(p); } static ASMJIT_INLINE int64_t readI64u(const void* p) noexcept { return readI64x<0>(p); } static ASMJIT_INLINE int64_t readI64aLE(const void* p) noexcept { return readI64xLE<8>(p); } static ASMJIT_INLINE int64_t readI64uLE(const void* p) noexcept { return readI64xLE<0>(p); } static ASMJIT_INLINE int64_t readI64aBE(const void* p) noexcept { return readI64xBE<8>(p); } static ASMJIT_INLINE int64_t readI64uBE(const void* p) noexcept { return readI64xBE<0>(p); } // -------------------------------------------------------------------------- // [WriteMem] // -------------------------------------------------------------------------- static ASMJIT_INLINE void writeU8(void* p, uint32_t x) noexcept { static_cast(p)[0] = static_cast(x & 0xFFU); } static ASMJIT_INLINE void writeI8(void* p, int32_t x) noexcept { static_cast(p)[0] = static_cast(x & 0xFF); } template static ASMJIT_INLINE void writeU16xLE(void* p, uint32_t x) noexcept { ASMJIT_ASSUME_ALIGNED(p, Alignment > 1 ? Alignment : 1U); if (ASMJIT_ARCH_LE && (ASMJIT_ARCH_UNALIGNED_16 || Alignment >= 2)) { static_cast(p)[0] = static_cast(x & 0xFFFFU); } else { static_cast(p)[0] = static_cast((x ) & 0xFFU); static_cast(p)[1] = static_cast((x >> 8) & 0xFFU); } } template static ASMJIT_INLINE void writeU16xBE(void* p, uint32_t x) noexcept { ASMJIT_ASSUME_ALIGNED(p, Alignment > 1 ? Alignment : 1U); if (ASMJIT_ARCH_BE && (ASMJIT_ARCH_UNALIGNED_16 || Alignment >= 2)) { static_cast(p)[0] = static_cast(x & 0xFFFFU); } else { static_cast(p)[0] = static_cast((x >> 8) & 0xFFU); static_cast(p)[1] = static_cast((x ) & 0xFFU); } } template static ASMJIT_INLINE void writeU16x(void* p, uint32_t x) noexcept { if (ASMJIT_ARCH_LE) writeU16xLE(p, x); else writeU16xBE(p, x); } template static ASMJIT_INLINE void writeI16xLE(void* p, int32_t x) noexcept { writeU16xLE(p, static_cast(x)); } template static ASMJIT_INLINE void writeI16xBE(void* p, int32_t x) noexcept { writeU16xBE(p, static_cast(x)); } template static ASMJIT_INLINE void writeI16x(void* p, int32_t x) noexcept { writeU16x(p, static_cast(x)); } static ASMJIT_INLINE void writeU16aLE(void* p, uint32_t x) noexcept { writeU16xLE<2>(p, x); } static ASMJIT_INLINE void writeU16uLE(void* p, uint32_t x) noexcept { writeU16xLE<0>(p, x); } static ASMJIT_INLINE void writeU16aBE(void* p, uint32_t x) noexcept { writeU16xBE<2>(p, x); } static ASMJIT_INLINE void writeU16uBE(void* p, uint32_t x) noexcept { writeU16xBE<0>(p, x); } static ASMJIT_INLINE void writeU16a(void* p, uint32_t x) noexcept { writeU16x<2>(p, x); } static ASMJIT_INLINE void writeU16u(void* p, uint32_t x) noexcept { writeU16x<0>(p, x); } static ASMJIT_INLINE void writeI16aLE(void* p, int32_t x) noexcept { writeI16xLE<2>(p, x); } static ASMJIT_INLINE void writeI16uLE(void* p, int32_t x) noexcept { writeI16xLE<0>(p, x); } static ASMJIT_INLINE void writeI16aBE(void* p, int32_t x) noexcept { writeI16xBE<2>(p, x); } static ASMJIT_INLINE void writeI16uBE(void* p, int32_t x) noexcept { writeI16xBE<0>(p, x); } static ASMJIT_INLINE void writeI16a(void* p, int32_t x) noexcept { writeI16x<2>(p, x); } static ASMJIT_INLINE void writeI16u(void* p, int32_t x) noexcept { writeI16x<0>(p, x); } template static ASMJIT_INLINE void writeU32xLE(void* p, uint32_t x) noexcept { ASMJIT_ASSUME_ALIGNED(p, Alignment > 1 ? Alignment : 1U); if (ASMJIT_ARCH_UNALIGNED_32 || Alignment >= 4) { static_cast(p)[0] = ASMJIT_ARCH_LE ? x : byteswap32(x); } else { writeU16xLE(static_cast(p) + 0, x >> 16); writeU16xLE(static_cast(p) + 2, x); } } template static ASMJIT_INLINE void writeU32xBE(void* p, uint32_t x) noexcept { ASMJIT_ASSUME_ALIGNED(p, Alignment > 1 ? Alignment : 1U); if (ASMJIT_ARCH_UNALIGNED_32 || Alignment >= 4) { static_cast(p)[0] = ASMJIT_ARCH_BE ? x : byteswap32(x); } else { writeU16xBE(static_cast(p) + 0, x); writeU16xBE(static_cast(p) + 2, x >> 16); } } template static ASMJIT_INLINE void writeU32x(void* p, uint32_t x) noexcept { if (ASMJIT_ARCH_LE) writeU32xLE(p, x); else writeU32xBE(p, x); } template static ASMJIT_INLINE void writeI32xLE(void* p, int32_t x) noexcept { writeU32xLE(p, static_cast(x)); } template static ASMJIT_INLINE void writeI32xBE(void* p, int32_t x) noexcept { writeU32xBE(p, static_cast(x)); } template static ASMJIT_INLINE void writeI32x(void* p, int32_t x) noexcept { writeU32x(p, static_cast(x)); } static ASMJIT_INLINE void writeU32aLE(void* p, uint32_t x) noexcept { writeU32xLE<4>(p, x); } static ASMJIT_INLINE void writeU32uLE(void* p, uint32_t x) noexcept { writeU32xLE<0>(p, x); } static ASMJIT_INLINE void writeU32aBE(void* p, uint32_t x) noexcept { writeU32xBE<4>(p, x); } static ASMJIT_INLINE void writeU32uBE(void* p, uint32_t x) noexcept { writeU32xBE<0>(p, x); } static ASMJIT_INLINE void writeU32a(void* p, uint32_t x) noexcept { writeU32x<4>(p, x); } static ASMJIT_INLINE void writeU32u(void* p, uint32_t x) noexcept { writeU32x<0>(p, x); } static ASMJIT_INLINE void writeI32aLE(void* p, int32_t x) noexcept { writeI32xLE<4>(p, x); } static ASMJIT_INLINE void writeI32uLE(void* p, int32_t x) noexcept { writeI32xLE<0>(p, x); } static ASMJIT_INLINE void writeI32aBE(void* p, int32_t x) noexcept { writeI32xBE<4>(p, x); } static ASMJIT_INLINE void writeI32uBE(void* p, int32_t x) noexcept { writeI32xBE<0>(p, x); } static ASMJIT_INLINE void writeI32a(void* p, int32_t x) noexcept { writeI32x<4>(p, x); } static ASMJIT_INLINE void writeI32u(void* p, int32_t x) noexcept { writeI32x<0>(p, x); } template static ASMJIT_INLINE void writeU64xLE(void* p, uint64_t x) noexcept { ASMJIT_ASSUME_ALIGNED(p, Alignment > 1 ? Alignment : 1U); if (ASMJIT_ARCH_LE && (ASMJIT_ARCH_UNALIGNED_64 || Alignment >= 8)) { static_cast(p)[0] = x; } else { writeU32xLE(static_cast(p) + 0, static_cast(x >> 32)); writeU32xLE(static_cast(p) + 4, static_cast(x & 0xFFFFFFFFU)); } } template static ASMJIT_INLINE void writeU64xBE(void* p, uint64_t x) noexcept { ASMJIT_ASSUME_ALIGNED(p, Alignment > 1 ? Alignment : 1U); if (ASMJIT_ARCH_BE && (ASMJIT_ARCH_UNALIGNED_64 || Alignment >= 8)) { static_cast(p)[0] = x; } else { writeU32xBE(static_cast(p) + 0, static_cast(x & 0xFFFFFFFFU)); writeU32xBE(static_cast(p) + 4, static_cast(x >> 32)); } } template static ASMJIT_INLINE void writeU64x(void* p, uint64_t x) noexcept { if (ASMJIT_ARCH_LE) writeU64xLE(p, x); else writeU64xBE(p, x); } template static ASMJIT_INLINE void writeI64xLE(void* p, int64_t x) noexcept { writeU64xLE(p, static_cast(x)); } template static ASMJIT_INLINE void writeI64xBE(void* p, int64_t x) noexcept { writeU64xBE(p, static_cast(x)); } template static ASMJIT_INLINE void writeI64x(void* p, int64_t x) noexcept { writeU64x(p, static_cast(x)); } static ASMJIT_INLINE void writeU64aLE(void* p, uint64_t x) noexcept { writeU64xLE<8>(p, x); } static ASMJIT_INLINE void writeU64uLE(void* p, uint64_t x) noexcept { writeU64xLE<0>(p, x); } static ASMJIT_INLINE void writeU64aBE(void* p, uint64_t x) noexcept { writeU64xBE<8>(p, x); } static ASMJIT_INLINE void writeU64uBE(void* p, uint64_t x) noexcept { writeU64xBE<0>(p, x); } static ASMJIT_INLINE void writeU64a(void* p, uint64_t x) noexcept { writeU64x<8>(p, x); } static ASMJIT_INLINE void writeU64u(void* p, uint64_t x) noexcept { writeU64x<0>(p, x); } static ASMJIT_INLINE void writeI64aLE(void* p, int64_t x) noexcept { writeI64xLE<8>(p, x); } static ASMJIT_INLINE void writeI64uLE(void* p, int64_t x) noexcept { writeI64xLE<0>(p, x); } static ASMJIT_INLINE void writeI64aBE(void* p, int64_t x) noexcept { writeI64xBE<8>(p, x); } static ASMJIT_INLINE void writeI64uBE(void* p, int64_t x) noexcept { writeI64xBE<0>(p, x); } static ASMJIT_INLINE void writeI64a(void* p, int64_t x) noexcept { writeI64x<8>(p, x); } static ASMJIT_INLINE void writeI64u(void* p, int64_t x) noexcept { writeI64x<0>(p, x); } } // Utils namespace // ============================================================================ // [asmjit::UInt64] // ============================================================================ union UInt64 { // -------------------------------------------------------------------------- // [Construction / Destruction] // -------------------------------------------------------------------------- ASMJIT_INLINE UInt64 fromUInt64(uint64_t val) noexcept { UInt64 data; data.setUInt64(val); return data; } ASMJIT_INLINE UInt64 fromUInt64(const UInt64& val) noexcept { UInt64 data; data.setUInt64(val); return data; } // -------------------------------------------------------------------------- // [Reset] // -------------------------------------------------------------------------- ASMJIT_INLINE void reset() noexcept { if (ASMJIT_ARCH_64BIT) { u64 = 0; } else { u32[0] = 0; u32[1] = 0; } } // -------------------------------------------------------------------------- // [Accessors] // -------------------------------------------------------------------------- ASMJIT_INLINE uint64_t getUInt64() const noexcept { return u64; } ASMJIT_INLINE UInt64& setUInt64(uint64_t val) noexcept { u64 = val; return *this; } ASMJIT_INLINE UInt64& setUInt64(const UInt64& val) noexcept { if (ASMJIT_ARCH_64BIT) { u64 = val.u64; } else { u32[0] = val.u32[0]; u32[1] = val.u32[1]; } return *this; } ASMJIT_INLINE UInt64& setPacked_2x32(uint32_t u0, uint32_t u1) noexcept { if (ASMJIT_ARCH_64BIT) { u64 = Utils::pack64_2x32(u0, u1); } else { u32[0] = u0; u32[1] = u1; } return *this; } // -------------------------------------------------------------------------- // [Add] // -------------------------------------------------------------------------- ASMJIT_INLINE UInt64& add(uint64_t val) noexcept { u64 += val; return *this; } ASMJIT_INLINE UInt64& add(const UInt64& val) noexcept { if (ASMJIT_ARCH_64BIT) { u64 += val.u64; } else { u32[0] += val.u32[0]; u32[1] += val.u32[1]; } return *this; } // -------------------------------------------------------------------------- // [Sub] // -------------------------------------------------------------------------- ASMJIT_INLINE UInt64& sub(uint64_t val) noexcept { u64 -= val; return *this; } ASMJIT_INLINE UInt64& sub(const UInt64& val) noexcept { if (ASMJIT_ARCH_64BIT) { u64 -= val.u64; } else { u32[0] -= val.u32[0]; u32[1] -= val.u32[1]; } return *this; } // -------------------------------------------------------------------------- // [And] // -------------------------------------------------------------------------- ASMJIT_INLINE UInt64& and_(uint64_t val) noexcept { u64 &= val; return *this; } ASMJIT_INLINE UInt64& and_(const UInt64& val) noexcept { if (ASMJIT_ARCH_64BIT) { u64 &= val.u64; } else { u32[0] &= val.u32[0]; u32[1] &= val.u32[1]; } return *this; } // -------------------------------------------------------------------------- // [AndNot] // -------------------------------------------------------------------------- ASMJIT_INLINE UInt64& andNot(uint64_t val) noexcept { u64 &= ~val; return *this; } ASMJIT_INLINE UInt64& andNot(const UInt64& val) noexcept { if (ASMJIT_ARCH_64BIT) { u64 &= ~val.u64; } else { u32[0] &= ~val.u32[0]; u32[1] &= ~val.u32[1]; } return *this; } // -------------------------------------------------------------------------- // [Or] // -------------------------------------------------------------------------- ASMJIT_INLINE UInt64& or_(uint64_t val) noexcept { u64 |= val; return *this; } ASMJIT_INLINE UInt64& or_(const UInt64& val) noexcept { if (ASMJIT_ARCH_64BIT) { u64 |= val.u64; } else { u32[0] |= val.u32[0]; u32[1] |= val.u32[1]; } return *this; } // -------------------------------------------------------------------------- // [Xor] // -------------------------------------------------------------------------- ASMJIT_INLINE UInt64& xor_(uint64_t val) noexcept { u64 ^= val; return *this; } ASMJIT_INLINE UInt64& xor_(const UInt64& val) noexcept { if (ASMJIT_ARCH_64BIT) { u64 ^= val.u64; } else { u32[0] ^= val.u32[0]; u32[1] ^= val.u32[1]; } return *this; } // -------------------------------------------------------------------------- // [Eq] // -------------------------------------------------------------------------- ASMJIT_INLINE bool isZero() const noexcept { if (ASMJIT_ARCH_64BIT) return u64 == 0; else return (u32[0] | u32[1]) == 0; } ASMJIT_INLINE bool isNonZero() const noexcept { if (ASMJIT_ARCH_64BIT) return u64 != 0; else return (u32[0] | u32[1]) != 0; } ASMJIT_INLINE bool eq(uint64_t val) const noexcept { return u64 == val; } ASMJIT_INLINE bool eq(const UInt64& val) const noexcept { if (ASMJIT_ARCH_64BIT) return u64 == val.u64; else return u32[0] == val.u32[0] && u32[1] == val.u32[1]; } // -------------------------------------------------------------------------- // [Operator Overload] // -------------------------------------------------------------------------- ASMJIT_INLINE UInt64& operator+=(uint64_t val) noexcept { return add(val); } ASMJIT_INLINE UInt64& operator+=(const UInt64& val) noexcept { return add(val); } ASMJIT_INLINE UInt64& operator-=(uint64_t val) noexcept { return sub(val); } ASMJIT_INLINE UInt64& operator-=(const UInt64& val) noexcept { return sub(val); } ASMJIT_INLINE UInt64& operator&=(uint64_t val) noexcept { return and_(val); } ASMJIT_INLINE UInt64& operator&=(const UInt64& val) noexcept { return and_(val); } ASMJIT_INLINE UInt64& operator|=(uint64_t val) noexcept { return or_(val); } ASMJIT_INLINE UInt64& operator|=(const UInt64& val) noexcept { return or_(val); } ASMJIT_INLINE UInt64& operator^=(uint64_t val) noexcept { return xor_(val); } ASMJIT_INLINE UInt64& operator^=(const UInt64& val) noexcept { return xor_(val); } ASMJIT_INLINE bool operator==(uint64_t val) const noexcept { return eq(val); } ASMJIT_INLINE bool operator==(const UInt64& val) const noexcept { return eq(val); } ASMJIT_INLINE bool operator!=(uint64_t val) const noexcept { return !eq(val); } ASMJIT_INLINE bool operator!=(const UInt64& val) const noexcept { return !eq(val); } ASMJIT_INLINE bool operator<(uint64_t val) const noexcept { return u64 < val; } ASMJIT_INLINE bool operator<(const UInt64& val) const noexcept { return u64 < val.u64; } ASMJIT_INLINE bool operator<=(uint64_t val) const noexcept { return u64 <= val; } ASMJIT_INLINE bool operator<=(const UInt64& val) const noexcept { return u64 <= val.u64; } ASMJIT_INLINE bool operator>(uint64_t val) const noexcept { return u64 > val; } ASMJIT_INLINE bool operator>(const UInt64& val) const noexcept { return u64 > val.u64; } ASMJIT_INLINE bool operator>=(uint64_t val) const noexcept { return u64 >= val; } ASMJIT_INLINE bool operator>=(const UInt64& val) const noexcept { return u64 >= val.u64; } // -------------------------------------------------------------------------- // [Members] // -------------------------------------------------------------------------- int8_t i8[8]; //!< 8-bit signed integer (8x). uint8_t u8[8]; //!< 8-bit unsigned integer (8x). int16_t i16[4]; //!< 16-bit signed integer (4x). uint16_t u16[4]; //!< 16-bit unsigned integer (4x). int32_t i32[2]; //!< 32-bit signed integer (2x). uint32_t u32[2]; //!< 32-bit unsigned integer (2x). int64_t i64; //!< 64-bit signed integer. uint64_t u64; //!< 64-bit unsigned integer. float f32[2]; //!< 32-bit floating point (2x). double f64; //!< 64-bit floating point. #if ASMJIT_ARCH_LE struct { float f32Lo, f32Hi; }; struct { int32_t i32Lo, i32Hi; }; struct { uint32_t u32Lo, u32Hi; }; #else struct { float f32Hi, f32Lo; }; struct { int32_t i32Hi, i32Lo; }; struct { uint32_t u32Hi, u32Lo; }; #endif // ASMJIT_ARCH_LE }; //! \} } // asmjit namespace // [Api-End] #include "../asmjit_apiend.h" // [Guard] #endif // _ASMJIT_BASE_UTILS_H