summaryrefslogtreecommitdiff
path: root/src/support/bits.h
diff options
context:
space:
mode:
authorMax Graey <maxgraey@gmail.com>2020-06-18 04:13:59 +0300
committerGitHub <noreply@github.com>2020-06-17 18:13:59 -0700
commitf6eb790eec107064798b9e54552f1ef5966f6359 (patch)
tree25a51d7cb2d0722dc2ab015d10abc59078916477 /src/support/bits.h
parent251a68b603080c86cd417db4f02801510376b279 (diff)
downloadbinaryen-f6eb790eec107064798b9e54552f1ef5966f6359.tar.gz
binaryen-f6eb790eec107064798b9e54552f1ef5966f6359.tar.bz2
binaryen-f6eb790eec107064798b9e54552f1ef5966f6359.zip
Optimize bit count polyfills (#2914)
Diffstat (limited to 'src/support/bits.h')
-rw-r--r--src/support/bits.h14
1 files changed, 9 insertions, 5 deletions
diff --git a/src/support/bits.h b/src/support/bits.h
index f2241bea8..bd91fdec6 100644
--- a/src/support/bits.h
+++ b/src/support/bits.h
@@ -65,17 +65,21 @@ template<typename T> int CountTrailingZeroes(T v) {
template<typename T> int CountLeadingZeroes(T v) {
return CountLeadingZeroes(typename std::make_unsigned<T>::type(v));
}
-template<typename T> bool IsPowerOf2(T v) { return v != 0 && PopCount(v) == 1; }
+template<typename T> bool IsPowerOf2(T v) {
+ return v != 0 && (v & (v - 1)) == 0;
+}
template<typename T, typename U> inline static T RotateLeft(T val, U count) {
- T mask = sizeof(T) * CHAR_BIT - 1;
+ auto value = typename std::make_unsigned<T>::type(val);
+ U mask = sizeof(T) * CHAR_BIT - 1;
count &= mask;
- return (val << count) | (val >> (-count & mask));
+ return (value << count) | (value >> (-count & mask));
}
template<typename T, typename U> inline static T RotateRight(T val, U count) {
- T mask = sizeof(T) * CHAR_BIT - 1;
+ auto value = typename std::make_unsigned<T>::type(val);
+ U mask = sizeof(T) * CHAR_BIT - 1;
count &= mask;
- return (val >> count) | (val << (-count & mask));
+ return (value >> count) | (value << (-count & mask));
}
extern uint32_t Log2(uint32_t v);