diff options
author | Kaz Kylheku <kaz@kylheku.com> | 2019-02-19 06:39:02 -0800 |
---|---|---|
committer | Kaz Kylheku <kaz@kylheku.com> | 2019-02-19 06:39:02 -0800 |
commit | 42afd74dc9c8b31e30f7407b5644737f2451fef3 (patch) | |
tree | 3857de5f06aae8f5bf25acebe306920545fc7ee4 | |
parent | 34259df7db9d3ab46f0c8586849d43f49d5b9271 (diff) | |
download | txr-42afd74dc9c8b31e30f7407b5644737f2451fef3.tar.gz txr-42afd74dc9c8b31e30f7407b5644737f2451fef3.tar.bz2 txr-42afd74dc9c8b31e30f7407b5644737f2451fef3.zip |
mpi/arith: optimize "highest bit" with GCC builtins.
* arith.c (highest_bit): On GCC, use __builtin_clz.
* mpi/mpi.c (s_highest_bit): Likewise.
-rw-r--r-- | arith.c | 8 | ||||
-rw-r--r-- | mpi/mpi.c | 8 |
2 files changed, 14 insertions, 2 deletions
@@ -268,7 +268,13 @@ val bignum_len(val num) int highest_bit(int_ptr_t n) { -#if CHAR_BIT * SIZEOF_PTR == 64 +#if defined __GNUC__ && SIZEOF_PTR == SIZEOF_INT + return (n == 0) ? 0 : (CHAR_BIT * SIZEOF_PTR - __builtin_clz(n)); +#elif defined __GNUC__ && SIZEOF_PTR == SIZEOF_LONG + return (n == 0) ? 0 : (CHAR_BIT * SIZEOF_PTR - __builtin_clzl(n)); +#elif defined __GNUC__ && SIZEOF_PTR == SIZEOF_LONGLONG_T + return (n == 0) ? 0 : (CHAR_BIT * SIZEOF_PTR - __builtin_clzll(n)); +#elif CHAR_BIT * SIZEOF_PTR == 64 if (n & 0x7FFFFFFF00000000) { if (n & 0x7FFF000000000000) { if (n & 0x7F00000000000000) { @@ -2949,7 +2949,13 @@ void s_mp_clamp(mp_int *mp) static mp_size s_highest_bit(mp_digit n) { -#if MP_DIGIT_SIZE == 8 +#if defined __GNUC__ && MP_DIGIT_SIZE == SIZEOF_INT + return (n == 0) ? 0 : (MP_DIGIT_BIT - __builtin_clz(n)); +#elif defined __GNUC__ && MP_DIGIT_SIZE == SIZEOF_LONG + return (n == 0) ? 0 : (MP_DIGIT_BIT - __builtin_clzl(n)); +#elif defined __GNUC__ && MP_DIGIT_SIZE == SIZEOF_LONGLONG_T + return (n == 0) ? 0 : (MP_DIGIT_BIT - __builtin_clzll(n)); +#elif MP_DIGIT_SIZE == 8 if (n & 0xFFFFFFFF00000000) { if (n & 0xFFFF000000000000) { if (n & 0xFF00000000000000) { |