diff options
author | Tor Egge <Tor.Egge@broadpark.no> | 2019-03-19 13:25:00 +0100 |
---|---|---|
committer | Tor Egge <Tor.Egge@broadpark.no> | 2019-03-19 13:25:00 +0100 |
commit | 07a359ac7ed8e6feab05e7b19c172a2226a9ab5e (patch) | |
tree | a12d6ff5223beb3ee26c1aac9f932c8ffefc925c /vespalib | |
parent | 43b44b6d1fba5c5c7eb982716119bf37aeeb7604 (diff) |
Use fundamental integer types in vespalib::Optimized.
Diffstat (limited to 'vespalib')
-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 } |