* cipher/bithelp.h (_gcry_ctz_no_zero): New. (_gcry_ctz): Use '_gcry_ctz_no_zero'. * cipher/cipher-internal.h (ocb_get_l): Use '_gcry_ctz_no_zero'. --
Signed-off-by: Jussi Kivilinna <jussi.kivili...@iki.fi> --- cipher/bithelp.h | 33 ++++++++++++++++++++++++++++----- cipher/cipher-internal.h | 2 +- 2 files changed, 29 insertions(+), 6 deletions(-) diff --git a/cipher/bithelp.h b/cipher/bithelp.h index 7793ce7c..a4faf345 100644 --- a/cipher/bithelp.h +++ b/cipher/bithelp.h @@ -19,6 +19,7 @@ #ifndef GCRYPT_BITHELP_H #define GCRYPT_BITHELP_H +#include "config.h" #include "types.h" @@ -77,13 +78,25 @@ _gcry_bswap64(u64 x) /* Count trailing zero bits in an unsigend int. We return an int - because that is what gcc's builtin does. Returns the number of - bits in X if X is 0. */ + because that is what gcc's builtin does. X must not be zero. */ static inline int -_gcry_ctz (unsigned int x) +_gcry_ctz_no_zero (unsigned int x) { -#if defined (HAVE_BUILTIN_CTZ) - return x ? __builtin_ctz (x) : 8 * sizeof (x); +#if defined(__riscv) && \ + (defined(__riscv_f) && __riscv_f >= 2002000) && \ + (!defined(__riscv_zbb) || __riscv_zbb < 2002000) && \ + defined(HAVE_GCC_ATTRIBUTE_MAY_ALIAS) + /* Use float cast approach when building for RISC-V without Zbb extension. + * Without Zbb, GCC gives us slower generic version for __builtin_ctz(). + * + * See: + * http://graphics.stanford.edu/~seander/bithacks.html#ZerosOnRightFloatCast + */ + float f = (float)(x & -x); + typedef u32 __attribute__((may_alias)) may_alias_u32; + return ((*(const may_alias_u32 *)&f) >> 23) - 0x7f; +#elif defined (HAVE_BUILTIN_CTZ) + return __builtin_ctz (x); #else /* See * http://graphics.stanford.edu/~seander/bithacks.html#ZerosOnRightModLookup @@ -100,6 +113,16 @@ _gcry_ctz (unsigned int x) } +/* Count trailing zero bits in an unsigend int. We return an int + because that is what gcc's builtin does. Returns the number of + bits in X if X is 0. */ +static inline int +_gcry_ctz (unsigned int x) +{ + return x ? _gcry_ctz_no_zero (x) : 8 * sizeof (x); +} + + /* Count trailing zero bits in an u64. We return an int because that is what gcc's builtin does. Returns the number of bits in X if X is 0. */ diff --git a/cipher/cipher-internal.h b/cipher/cipher-internal.h index ddf8fbb5..19b3eada 100644 --- a/cipher/cipher-internal.h +++ b/cipher/cipher-internal.h @@ -775,7 +775,7 @@ ocb_get_l (gcry_cipher_hd_t c, u64 n) : [low] "r" ((unsigned long)n) : "cc"); #else - ntz = _gcry_ctz (n); + ntz = _gcry_ctz_no_zero (n); #endif return c->u_mode.ocb.L[ntz]; -- 2.45.2 _______________________________________________ Gcrypt-devel mailing list Gcrypt-devel@gnupg.org https://lists.gnupg.org/mailman/listinfo/gcrypt-devel