From 575541e32c45e04fa7c7218dd58bbb3f725f57fa Mon Sep 17 00:00:00 2001 From: "Richard C. Gobeille" Date: Wed, 10 Jun 2020 10:37:04 -0700 Subject: [PATCH] engine: update libdivide --- source/thirdparty/include/libdivide.h | 51 +++++++++++++++------------ 1 file changed, 29 insertions(+), 22 deletions(-) diff --git a/source/thirdparty/include/libdivide.h b/source/thirdparty/include/libdivide.h index a2a1008b7..204ce6556 100644 --- a/source/thirdparty/include/libdivide.h +++ b/source/thirdparty/include/libdivide.h @@ -11,8 +11,8 @@ #ifndef LIBDIVIDE_H #define LIBDIVIDE_H -#define LIBDIVIDE_VERSION "2.0" -#define LIBDIVIDE_VERSION_MAJOR 2 +#define LIBDIVIDE_VERSION "3.0" +#define LIBDIVIDE_VERSION_MAJOR 3 #define LIBDIVIDE_VERSION_MINOR 0 #include @@ -20,6 +20,7 @@ #if defined(__cplusplus) #include #include + #include #else #include #include @@ -297,10 +298,17 @@ static inline int32_t libdivide_count_leading_zeros32(uint32_t val) { } return 0; #else - int32_t result = 0; - uint32_t hi = 1U << 31; - for (; ~val & hi; hi >>= 1) { - result++; + if (val == 0) + return 32; + int32_t result = 8; + uint32_t hi = 0xFFU << 24; + while ((val & hi) == 0) { + hi >>= 8; + result += 8; + } + while (val & hi) { + result -= 1; + hi <<= 1; } return result; #endif @@ -1981,16 +1989,16 @@ enum { // The dispatcher selects a specific division algorithm for a given // type and ALGO using partial template specialization. -template struct dispatcher { }; +template struct dispatcher { }; -template<> struct dispatcher { DISPATCHER_GEN(int32_t, s32) }; -template<> struct dispatcher { DISPATCHER_GEN(int32_t, s32_branchfree) }; -template<> struct dispatcher { DISPATCHER_GEN(uint32_t, u32) }; -template<> struct dispatcher { DISPATCHER_GEN(uint32_t, u32_branchfree) }; -template<> struct dispatcher { DISPATCHER_GEN(int64_t, s64) }; -template<> struct dispatcher { DISPATCHER_GEN(int64_t, s64_branchfree) }; -template<> struct dispatcher { DISPATCHER_GEN(uint64_t, u64) }; -template<> struct dispatcher { DISPATCHER_GEN(uint64_t, u64_branchfree) }; +template<> struct dispatcher { DISPATCHER_GEN(int32_t, s32) }; +template<> struct dispatcher { DISPATCHER_GEN(int32_t, s32_branchfree) }; +template<> struct dispatcher { DISPATCHER_GEN(uint32_t, u32) }; +template<> struct dispatcher { DISPATCHER_GEN(uint32_t, u32_branchfree) }; +template<> struct dispatcher { DISPATCHER_GEN(int64_t, s64) }; +template<> struct dispatcher { DISPATCHER_GEN(int64_t, s64_branchfree) }; +template<> struct dispatcher { DISPATCHER_GEN(uint64_t, u64) }; +template<> struct dispatcher { DISPATCHER_GEN(uint64_t, u64_branchfree) }; // This is the main divider class for use by the user (C++ API). // The actual division algorithm is selected using the dispatcher struct @@ -2034,9 +2042,11 @@ public: return div.divide(n); } #endif + private: // Storage for the actual divisor - dispatcher div; + dispatcher::value, + std::is_signed::value, sizeof(T), ALGO> div; }; // Overload of operator / for scalar division @@ -2066,12 +2076,9 @@ T& operator/=(T& n, const divider& div) { } #endif -#if __cplusplus >= 201103L || \ - (defined(_MSC_VER) && _MSC_VER >= 1800) - // libdivdie::branchfree_divider - template - using branchfree_divider = divider; -#endif +// libdivdie::branchfree_divider +template +using branchfree_divider = divider; } // namespace libdivide