From f2773d476c835fcc95e4e67d775736affa224552 Mon Sep 17 00:00:00 2001 From: JF Bastien Date: Thu, 24 Dec 2015 09:26:04 -0800 Subject: Simplify the bit functions... a bit! --- src/bits.h | 24 ++++++++++++++++++++++++ src/wasm-interpreter.h | 27 ++++++--------------------- 2 files changed, 30 insertions(+), 21 deletions(-) (limited to 'src') diff --git a/src/bits.h b/src/bits.h index 98bb96a4f..98ae5c4b7 100644 --- a/src/bits.h +++ b/src/bits.h @@ -17,6 +17,8 @@ #ifndef wasm_bits_h #define wasm_bits_h +#include + /* * Portable bit functions. * @@ -37,6 +39,18 @@ template inline T BitReverse(T /* v */); template inline int CountTrailingZeroes(T /* v */); template inline int CountLeadingZeroes(T /* v */); +// Convenience signed -> unsigned. It usually doesn't make much sense to use bit +// functions on signed types. +template inline int PopCount(T v) { + return PopCount(typename std::make_unsigned::type(v)); +} +template inline int CountTrailingZeroes(T v) { + return CountTrailingZeroes(typename std::make_unsigned::type(v)); +} +template inline int CountLeadingZeroes(T v) { + return CountLeadingZeroes(typename std::make_unsigned::type(v)); +} + // Implementations for the above templates. template<> inline int PopCount(uint8_t v) { @@ -84,6 +98,11 @@ template<> inline int CountTrailingZeroes(uint32_t v) { 32; } +template<> inline int CountTrailingZeroes(uint64_t v) { + return (uint32_t)v ? CountTrailingZeroes(v) + : 32 + CountTrailingZeroes(v >> 32); +} + template<> inline int CountLeadingZeroes(uint32_t v) { // See Stanford bithacks, find the log base 2 of an N-bit integer in // O(lg(N)) operations with multiply and lookup: @@ -102,6 +121,11 @@ template<> inline int CountLeadingZeroes(uint32_t v) { 32; } +template<> inline int CountLeadingZeroes(uint64_t v) { + return v >> 32 ? CountLeadingZeroes(v >> 32) + : 32 + CountLeadingZeroes(v); +} + } // namespace wasm #endif // wasm_bits_h diff --git a/src/wasm-interpreter.h b/src/wasm-interpreter.h index 012c1c347..d231aee42 100644 --- a/src/wasm-interpreter.h +++ b/src/wasm-interpreter.h @@ -360,15 +360,9 @@ private: if (value.type == i32) { int32_t v = value.geti32(); switch (curr->op) { - case Clz: { - if (v == 0) return Literal(32); - return Literal(CountLeadingZeroes((uint32_t)v)); - } - case Ctz: { - if (v == 0) return Literal(32); - return Literal(CountTrailingZeroes((uint32_t)v)); - } - case Popcnt: return Literal((int32_t)PopCount((uint32_t)v)); + case Clz: return Literal((int32_t)CountLeadingZeroes(v)); + case Ctz: return Literal((int32_t)CountTrailingZeroes(v)); + case Popcnt: return Literal((int32_t)PopCount(v)); case ReinterpretInt: { float v = value.reinterpretf32(); if (isnan(v)) { @@ -385,19 +379,10 @@ private: } if (value.type == i64) { int64_t v = value.geti64(); - int32_t high = v >> 32, low = v; switch (curr->op) { - case Clz: { - if (v == 0) return Literal((int64_t)64); - if (high == 0) return Literal(32+(int64_t)CountLeadingZeroes((uint32_t)low)); - return Literal((int64_t)CountLeadingZeroes((uint32_t)high)); - } - case Ctz: { - if (v == 0) return Literal((int64_t)64); - if (low == 0) return Literal(32+(int64_t)CountTrailingZeroes((uint32_t)high)); - return Literal((int64_t)CountTrailingZeroes((uint32_t)low)); - } - case Popcnt: return Literal((int64_t)PopCount((uint64_t)v)); + case Clz: return Literal((int64_t)CountLeadingZeroes(v)); + case Ctz: return Literal((int64_t)CountTrailingZeroes(v)); + case Popcnt: return Literal((int64_t)PopCount(v)); case WrapInt64: return Literal(int32_t(value.geti64())); case ReinterpretInt: { return Literal(value.reinterpretf64()); -- cgit v1.2.3