From d8e9382573eb2401a79c89d93d4885a6b88e23d6 Mon Sep 17 00:00:00 2001 From: Nekotekina Date: Tue, 24 Nov 2020 12:30:03 +0300 Subject: [PATCH] asm.hpp: constexpr refactoring Removed asm (what an irony), made many functions constexpr. Removed some unused function, readding them should be trivial. --- rpcs3/util/asm.hpp | 296 ++++++++++++++++----------------------------- 1 file changed, 107 insertions(+), 189 deletions(-) diff --git a/rpcs3/util/asm.hpp b/rpcs3/util/asm.hpp index 31fe5bbee9..6b9d3c59a5 100644 --- a/rpcs3/util/asm.hpp +++ b/rpcs3/util/asm.hpp @@ -111,259 +111,177 @@ namespace utils return _m_prefetchw(ptr); } -#if defined(__GNUG__) - - inline u8 rol8(u8 x, u8 n) + constexpr u8 rol8(u8 x, u8 n) { -#if __has_builtin(__builtin_rotateleft8) - return __builtin_rotateleft8(x, n); -#else - u8 result = x; - __asm__("rolb %[n], %[result]" : [result] "+g"(result) : [n] "c"(n)); - return result; -#endif - } - - inline u8 ror8(u8 x, u8 n) - { -#if __has_builtin(__builtin_rotateright8) - return __builtin_rotateright8(x, n); -#else - u8 result = x; - __asm__("rorb %[n], %[result]" : [result] "+g"(result) : [n] "c"(n)); - return result; -#endif - } - - inline u16 rol16(u16 x, u16 n) - { -#if __has_builtin(__builtin_rotateleft16) - return __builtin_rotateleft16(x, n); -#else - u16 result = x; - __asm__("rolw %b[n], %[result]" : [result] "+g"(result) : [n] "c"(n)); - return result; -#endif - } - - inline u16 ror16(u16 x, u16 n) - { -#if __has_builtin(__builtin_rotateright16) - return __builtin_rotateright16(x, n); -#else - u16 result = x; - __asm__("rorw %b[n], %[result]" : [result] "+g"(result) : [n] "c"(n)); - return result; -#endif - } - - inline u32 rol32(u32 x, u32 n) - { -#if __has_builtin(__builtin_rotateleft32) - return __builtin_rotateleft32(x, n); -#else - u32 result = x; - __asm__("roll %b[n], %[result]" : [result] "+g"(result) : [n] "c"(n)); - return result; -#endif - } - - inline u32 ror32(u32 x, u32 n) - { -#if __has_builtin(__builtin_rotateright32) - return __builtin_rotateright32(x, n); -#else - u32 result = x; - __asm__("rorl %b[n], %[result]" : [result] "+g"(result) : [n] "c"(n)); - return result; -#endif - } - - inline u64 rol64(u64 x, u64 n) - { -#if __has_builtin(__builtin_rotateleft64) - return __builtin_rotateleft64(x, n); -#else - u64 result = x; - __asm__("rolq %b[n], %[result]" : [result] "+g"(result) : [n] "c"(n)); - return result; -#endif - } - - inline u64 ror64(u64 x, u64 n) - { -#if __has_builtin(__builtin_rotateright64) - return __builtin_rotateright64(x, n); -#else - u64 result = x; - __asm__("rorq %b[n], %[result]" : [result] "+g"(result) : [n] "c"(n)); - return result; -#endif - } - - constexpr u64 umulh64(u64 a, u64 b) - { - const __uint128_t x = a; - const __uint128_t y = b; - return (x * y) >> 64; - } - - constexpr s64 mulh64(s64 a, s64 b) - { - const __int128_t x = a; - const __int128_t y = b; - return (x * y) >> 64; - } - - constexpr s64 div128(s64 high, s64 low, s64 divisor, s64* remainder = nullptr) - { - const __int128_t x = (__uint128_t{u64(high)} << 64) | u64(low); - const __int128_t r = x / divisor; - - if (remainder) + if (std::is_constant_evaluated()) { - *remainder = x % divisor; + return (x << (n & 7)) | (x >> ((-n & 7))); } - return r; - } - - constexpr u64 udiv128(u64 high, u64 low, u64 divisor, u64* remainder = nullptr) - { - const __uint128_t x = (__uint128_t{high} << 64) | low; - const __uint128_t r = x / divisor; - - if (remainder) - { - *remainder = x % divisor; - } - - return r; - } - - inline u32 ctz128(u128 arg) - { - if (u64 lo = static_cast(arg)) - { - return std::countr_zero(lo); - } - else - { - return std::countr_zero(arg >> 64) + 64; - } - } - - inline u32 clz128(u128 arg) - { - if (u64 hi = static_cast(arg >> 64)) - { - return std::countl_zero(hi); - } - else - { - return std::countl_zero(arg) + 64; - } - } - -#elif defined(_MSC_VER) - inline u8 rol8(u8 x, u8 n) - { +#ifdef _MSC_VER return _rotl8(x, n); +#else + return __rolb(x, n); +#endif } - inline u8 ror8(u8 x, u8 n) + constexpr u16 rol16(u16 x, u16 n) { - return _rotr8(x, n); + if (std::is_constant_evaluated()) + { + return (x << (n & 15)) | (x >> ((-n & 15))); + } + +#ifdef _MSC_VER + return _rotl16(x, n); +#else + return __rolw(x, n); +#endif } - inline u16 rol16(u16 x, u16 n) + constexpr u32 rol32(u32 x, u32 n) { - return _rotl16(x, (u8)n); + if (std::is_constant_evaluated()) + { + return (x << (n & 31)) | (x >> (((0 - n) & 31))); + } + +#ifdef _MSC_VER + return _rotl(x, n); +#else + return __rold(x, n); +#endif } - inline u16 ror16(u16 x, u16 n) + constexpr u32 ror32(u32 x, u32 n) { - return _rotr16(x, (u8)n); + if (std::is_constant_evaluated()) + { + return (x >> (n & 31)) | (x << (((0 - n) & 31))); + } + +#ifdef _MSC_VER + return _rotr(x, n); +#else + return __rord(x, n); +#endif } - inline u32 rol32(u32 x, u32 n) + constexpr u64 rol64(u64 x, u64 n) { - return _rotl(x, (int)n); + if (std::is_constant_evaluated()) + { + return (x << (n & 63)) | (x >> (((0 - n) & 63))); + } + +#ifdef _MSC_VER + return _rotl64(x, static_cast(n)); +#else + return __rolq(x, static_cast(n)); +#endif } - inline u32 ror32(u32 x, u32 n) + constexpr u64 umulh64(u64 x, u64 y) { - return _rotr(x, (int)n); - } +#ifdef _MSC_VER + if (std::is_constant_evaluated()) + { + u128 a = (u32)x * (u64)(u32)y; + u128 b = (x >> 32) * (u32)y; + u128 c = (u32)x * (y >> 32); + u128 d = (x >> 32) * (y >> 32); + a += (b << 32); + a += (c << 32); + a.hi += d.lo; + return a.hi; + } - inline u64 rol64(u64 x, u64 n) - { - return _rotl64(x, (int)n); - } - - inline u64 ror64(u64 x, u64 n) - { - return _rotr64(x, (int)n); - } - - inline u64 umulh64(u64 x, u64 y) - { return __umulh(x, y); +#else + return (u128{x} * u128{y}) >> 64; +#endif } inline s64 mulh64(s64 x, s64 y) { +#ifdef _MSC_VER return __mulh(x, y); +#else + return (s128{x} * s128{y}) >> 64; +#endif } inline s64 div128(s64 high, s64 low, s64 divisor, s64* remainder = nullptr) { - s64 rem; +#ifdef _MSC_VER + s64 rem = 0; s64 r = _div128(high, low, divisor, &rem); if (remainder) { *remainder = rem; } +#else + const s128 x = (u128{static_cast(high)} << 64) | u64(low); + const s128 r = x / divisor; + if (remainder) + { + *remainder = x % divisor; + } +#endif return r; } inline u64 udiv128(u64 high, u64 low, u64 divisor, u64* remainder = nullptr) { - u64 rem; +#ifdef _MSC_VER + u64 rem = 0; u64 r = _udiv128(high, low, divisor, &rem); if (remainder) { *remainder = rem; } +#else + const u128 x = (u128{high} << 64) | low; + const u128 r = x / divisor; + if (remainder) + { + *remainder = x % divisor; + } +#endif return r; } - inline u32 ctz128(u128 arg) + constexpr u32 ctz128(u128 arg) { +#ifdef _MSC_VER if (!arg.lo) - { return std::countr_zero(arg.hi) + 64u; - } else - { return std::countr_zero(arg.lo); - } +#else + if (u64 lo = static_cast(arg)) + return std::countr_zero(lo); + else + return std::countr_zero(arg >> 64) + 64; +#endif } - inline u32 clz128(u128 arg) + constexpr u32 clz128(u128 arg) { +#ifdef _MSC_VER if (arg.hi) - { return std::countl_zero(arg.hi); - } else - { return std::countl_zero(arg.lo) + 64; - } - } +#else + if (u64 hi = static_cast(arg >> 64)) + return std::countl_zero(hi); + else + return std::countl_zero(arg) + 64; #endif + } } // namespace utils