From 727f5b3fc6bb10da6a9803ec6bdd21fe78a83b4f Mon Sep 17 00:00:00 2001 From: anthony-zy Date: Mon, 10 Nov 2025 10:37:19 +0800 Subject: [PATCH 1/2] add zbb check macro --- snappy-stubs-internal.h | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/snappy-stubs-internal.h b/snappy-stubs-internal.h index 526c38b..0b0e726 100644 --- a/snappy-stubs-internal.h +++ b/snappy-stubs-internal.h @@ -304,7 +304,10 @@ class Bits { void operator=(const Bits&); }; -#if HAVE_BUILTIN_CTZ +// Check if the built-in __builtin_ctz (count trailing zeros) is available. +// Require either a non-RISC-V target, or a RISC-V core that implements +// the Zbb bit-manipulation extension where ctz is guaranteed. +#if HAVE_BUILTIN_CTZ && (!defined(__riscv) || defined(__riscv_zbb)) inline int Bits::Log2FloorNonZero(uint32_t n) { assert(n != 0); @@ -393,7 +396,10 @@ inline int Bits::FindLSBSetNonZero(uint32_t n) { #endif // End portable versions. -#if HAVE_BUILTIN_CTZ +// Check if the built-in __builtin_ctz (count trailing zeros) is available. +// Require either a non-RISC-V target, or a RISC-V core that implements +// the Zbb bit-manipulation extension where ctz is guaranteed. +#if HAVE_BUILTIN_CTZ && (!defined(__riscv) || defined(__riscv_zbb)) inline int Bits::FindLSBSetNonZero64(uint64_t n) { assert(n != 0); From 30dbdc272856f8a7b3c89af050442e08f6e9269e Mon Sep 17 00:00:00 2001 From: anthony-zy Date: Mon, 10 Nov 2025 10:37:19 +0800 Subject: [PATCH 2/2] add zbb check macro --- CMakeLists.txt | 16 +++++++++++++--- snappy-stubs-internal.h | 3 ++- 2 files changed, 15 insertions(+), 4 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 490f5b8..ac43da3 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -155,10 +155,20 @@ int main() { return __builtin_expect(0, 1); }" HAVE_BUILTIN_EXPECT) +# Check if the built-in __builtin_ctz (count trailing zeros) is available. +# Require either a non-RISC-V target, or a RISC-V core that implements +# the Zbb bit-manipulation extension where ctz is guaranteed. check_cxx_source_compiles(" -int main() { - return __builtin_ctzll(0); -}" HAVE_BUILTIN_CTZ) +#ifdef __riscv + #ifdef __riscv_zbb + int main() { return __builtin_ctzll(0); } + #else + #error \"ZBB not enabled in current config\" + #endif +#else + int main() { return __builtin_ctzll(0); } +#endif +" HAVE_BUILTIN_CTZ) check_cxx_source_compiles(" int main() { diff --git a/snappy-stubs-internal.h b/snappy-stubs-internal.h index 526c38b..59ba003 100644 --- a/snappy-stubs-internal.h +++ b/snappy-stubs-internal.h @@ -304,8 +304,8 @@ class Bits { void operator=(const Bits&); }; +// In RISC-V, CLZ is supported by instructions from the ZBB bit-manipulation extension. #if HAVE_BUILTIN_CTZ - inline int Bits::Log2FloorNonZero(uint32_t n) { assert(n != 0); // (31 ^ x) is equivalent to (31 - x) for x in [0, 31]. An easy proof @@ -393,6 +393,7 @@ inline int Bits::FindLSBSetNonZero(uint32_t n) { #endif // End portable versions. +// the Zbb bit-manipulation extension where ctz is guaranteed. #if HAVE_BUILTIN_CTZ inline int Bits::FindLSBSetNonZero64(uint64_t n) {