diff options
author | Henning Baldersheim <balder@yahoo-inc.com> | 2019-03-19 17:30:09 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2019-03-19 17:30:09 +0100 |
commit | f2f62ba59977ba198555217066f99d096aa0782c (patch) | |
tree | 2cb5e42958e64f2b7f3eec1175402641dece2c26 | |
parent | 3ecb6309e876747e84d26543feefc2c5ae1a458e (diff) | |
parent | 07a359ac7ed8e6feab05e7b19c172a2226a9ab5e (diff) |
Merge pull request #8836 from vespa-engine/toregge/use-fundamental-integer-types-in-vespalib-optimized
Use fundamental integer types in vespalib::Optimized
-rw-r--r-- | vespalib/src/tests/optimized/optimized_test.cpp | 29 | ||||
-rw-r--r-- | vespalib/src/vespa/vespalib/util/optimized.h | 51 |
2 files changed, 52 insertions, 28 deletions
diff --git a/vespalib/src/tests/optimized/optimized_test.cpp b/vespalib/src/tests/optimized/optimized_test.cpp index 21442859107..2146cb9353f 100644 --- a/vespalib/src/tests/optimized/optimized_test.cpp +++ b/vespalib/src/tests/optimized/optimized_test.cpp @@ -12,6 +12,8 @@ private: void testMsbIdx(); template<typename T> void testLsbIdx(); + template<typename T> + void testPopCount(); public: int Main() override; }; @@ -47,24 +49,31 @@ void Test::testLsbIdx() } } +template<typename T> +void Test::testPopCount() +{ + EXPECT_EQUAL(0, Optimized::popCount(T(0))); + EXPECT_EQUAL(1, Optimized::popCount(T(1))); + EXPECT_EQUAL(int(8 * sizeof(T)), Optimized::popCount(T(-1))); +} + int Test::Main() { TEST_INIT("optimized_test"); - testMsbIdx<uint32_t>(); - testMsbIdx<uint64_t>(); + testMsbIdx<unsigned int>(); + testMsbIdx<unsigned long>(); + testMsbIdx<unsigned long long>(); TEST_FLUSH(); - testLsbIdx<uint32_t>(); - testLsbIdx<uint64_t>(); + testLsbIdx<unsigned int>(); + testLsbIdx<unsigned long>(); + testLsbIdx<unsigned long long>(); TEST_FLUSH(); - EXPECT_EQUAL(Optimized::popCount(0u), 0); - EXPECT_EQUAL(Optimized::popCount(1u), 1); - EXPECT_EQUAL(Optimized::popCount(uint32_t(-1)), 32); - EXPECT_EQUAL(Optimized::popCount(0ul), 0); - EXPECT_EQUAL(Optimized::popCount(1ul), 1); - EXPECT_EQUAL(Optimized::popCount(uint64_t(-1l)), 64); + testPopCount<unsigned int>(); + testPopCount<unsigned long>(); + testPopCount<unsigned long long>(); TEST_FLUSH(); TEST_DONE(); diff --git a/vespalib/src/vespa/vespalib/util/optimized.h b/vespalib/src/vespa/vespalib/util/optimized.h index 28dee703a5f..92cf1f0ca24 100644 --- a/vespalib/src/vespa/vespalib/util/optimized.h +++ b/vespalib/src/vespa/vespalib/util/optimized.h @@ -16,12 +16,15 @@ namespace vespalib { class Optimized { public: - static int msbIdx(uint32_t v); - static int msbIdx(uint64_t v); - static int lsbIdx(uint32_t v); - static int lsbIdx(uint64_t v); - static int popCount(uint32_t v) { return __builtin_popcount(v); } - static int popCount(uint64_t v) { return __builtin_popcountl(v); } + static int msbIdx(unsigned int v); + static int msbIdx(unsigned long v); + static int msbIdx(unsigned long long v); + static int lsbIdx(unsigned int v); + static int lsbIdx(unsigned long v); + static int lsbIdx(unsigned long long v); + static int popCount(unsigned int v) { return __builtin_popcount(v); } + static int popCount(unsigned long v) { return __builtin_popcountl(v); } + static int popCount(unsigned long long v) { return __builtin_popcountll(v); } }; /** @@ -61,31 +64,43 @@ public: **/ #ifdef __x86_64__ -inline int Optimized::msbIdx(uint32_t v) { - int32_t result; +inline int Optimized::msbIdx(unsigned int v) { + unsigned int result; __asm __volatile("bsrl %0,%0" : "=r" (result) : "0" (v)); return result; } -inline int Optimized::lsbIdx(uint32_t v) { - int32_t result; +inline int Optimized::lsbIdx(unsigned int v) { + unsigned int result; __asm __volatile("bsfl %0,%0" : "=r" (result) : "0" (v)); return result; } -inline int Optimized::msbIdx(uint64_t v) { - int64_t result; +inline int Optimized::msbIdx(unsigned long v) { + unsigned long result; __asm __volatile("bsrq %0,%0" : "=r" (result) : "0" (v)); return result; } -inline int Optimized::lsbIdx(uint64_t v) { - int64_t result; +inline int Optimized::lsbIdx(unsigned long v) { + unsigned long result; + __asm __volatile("bsfq %0,%0" : "=r" (result) : "0" (v)); + return result; +} +inline int Optimized::msbIdx(unsigned long long v) { + unsigned long long result; + __asm __volatile("bsrq %0,%0" : "=r" (result) : "0" (v)); + return result; +} +inline int Optimized::lsbIdx(unsigned long long v) { + unsigned long long result; __asm __volatile("bsfq %0,%0" : "=r" (result) : "0" (v)); return result; } #else -inline int Optimized::msbIdx(uint32_t v) { return v ? 31 - __builtin_clz(v) : 0; } -inline int Optimized::msbIdx(uint64_t v) { return v ? 63 - __builtin_clzl(v) : 0; } -inline int Optimized::lsbIdx(uint32_t v) { return v ? 31 - __builtin_ctz(v) : 0; } -inline int Optimized::lsbIdx(uint64_t v) { return v ? 63 - __builtin_ctzl(v) : 0; } +inline int Optimized::msbIdx(unsigned int v) { return v ? sizeof(unsigned int) * 8 - 1 - __builtin_clz(v) : 0; } +inline int Optimized::msbIdx(unsigned long v) { return v ? sizeof(unsigned long) * 8 - 1 - __builtin_clzl(v) : 0; } +inline int Optimized::msbIdx(unsigned long long v) { return v ? sizeof(unsigned long long) * 8 - 1 - __builtin_clzll(v) : 0; } +inline int Optimized::lsbIdx(unsigned int v) { return v ? __builtin_ctz(v) : 0; } +inline int Optimized::lsbIdx(unsigned long v) { return v ? __builtin_ctzl(v) : 0; } +inline int Optimized::lsbIdx(unsigned long long v) { return v ? __builtin_ctzll(v) : 0; } #endif } |