diff --git a/include/CppCore/Math/Util.h b/include/CppCore/Math/Util.h index 4c6f0a3a..b145774c 100644 --- a/include/CppCore/Math/Util.h +++ b/include/CppCore/Math/Util.h @@ -534,6 +534,35 @@ namespace CppCore }; #pragma pack(pop) + //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + // TEMPLATE UNIONS + //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + + /// + /// Union of two types + /// + template + union U2 + { + public: + T1 t1; + T2 t2; + INLINE U2() {} + }; + + /// + /// Union of three types + /// + template + union U3 + { + public: + T1 t1; + T2 t2; + T3 t3; + INLINE U3() {} + }; + //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // ADDITION OPERATIONS WITH OVERFLOW BIT //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// @@ -1284,12 +1313,12 @@ namespace CppCore l = _mulx_u64(a, b, (unsigned long long*)&h); #elif defined(CPPCORE_CPU_X64) && defined(CPPCORE_COMPILER_MSVC) l = _umul128(a, b, &h); - #elif defined(CPPCORE_CPU_X64) && defined(CPPCORE_COMPILER_CLANG) - __asm("MULQ %4" : "=a" (l), "=d" (h) : "0" (a), "1" (b), "r" (b)); #elif defined(CPPCORE_COMPILER_CLANG) && defined(__SIZEOF_INT128__) __uint128_t t = (__uint128_t)a * b; l = (uint64_t)t; h = (uint64_t)(t >> 64); + #elif defined(CPPCORE_CPU_X64) && defined(CPPCORE_COMPILER_CLANG) + __asm("MULQ %3" : "=a" (l), "=d" (h) : "0" (a), "r" (b)); #else uint32_t al = (uint32_t)a; uint32_t ah = (uint32_t)(a >> 32); @@ -2656,6 +2685,13 @@ namespace CppCore CppCore::clone(r, t.v); } #if defined(CPPCORE_CPU_64BIT) + else if constexpr (sizeof(UINT1) == 16 && sizeof(UINT2) == 16 && sizeof(UINT3) == 16) + { + uint64_t* ap = (uint64_t*)&a; + uint64_t* bp = (uint64_t*)&b; + uint64_t* rp = (uint64_t*)&r; + CppCore::umul128(ap[0], ap[1], bp[0], bp[1], rp[0], rp[1]); + } else if constexpr (sizeof(UINT1) % 8 == 0 && sizeof(UINT2) % 8 == 0 && sizeof(UINT3) % 8 == 0) { // 64-Bit CPU and Multiples of 64-Bit @@ -3014,6 +3050,7 @@ namespace CppCore { static_assert(sizeof(UINT1) % 4 == 0); static_assert(sizeof(UINT2) % 4 == 0); + static_assert(sizeof(UINT1) >= sizeof(UINT2)); assert(&q != &u && &r != &v); CppCore::clear(q); #if defined(CPPCORE_CPU_X64) @@ -3031,7 +3068,7 @@ namespace CppCore uint32_t n = N; while (n != 0U && vp[n-1] == 0U) n--; - if (((M < n) | (n == 0)) != 0) + if (n == 0U) return false; if (n == 1U) { uint64_t k; @@ -3121,7 +3158,7 @@ namespace CppCore uint32_t n = N; while (n != 0U && vp[n-1] == 0U) n--; - if (((M < n) | (n == 0)) != 0) + if (n == 0U) return false; if (n == 1U) { uint32_t k; @@ -3253,6 +3290,7 @@ namespace CppCore assert(&r != &v); static_assert(sizeof(UINT1) % 4 == 0); static_assert(sizeof(UINT2) % 4 == 0); + static_assert(sizeof(UINT1) >= sizeof(UINT2)); #if defined(CPPCORE_CPU_X64) if constexpr (sizeof(UINT1) % 8 == 0 && sizeof(UINT2) % 8 == 0) { @@ -3268,7 +3306,7 @@ namespace CppCore uint32_t n = N; while (n != 0U && vp[n-1] == 0U) n--; - if (((M < n) | (n == 0U)) != 0) + if (n == 0U) return; if (n == 1U) { CppCore::clear(r); @@ -3363,7 +3401,7 @@ namespace CppCore uint32_t n = N; while (n != 0U && vp[n-1] == 0U) n--; - if (((M < n) | (n == 0)) != 0) + if (n == 0U) return; if (n == 1U) { CppCore::clear(r);