summaryrefslogtreecommitdiffstats
path: root/mpi
diff options
context:
space:
mode:
authorKaz Kylheku <kaz@kylheku.com>2019-02-19 06:39:02 -0800
committerKaz Kylheku <kaz@kylheku.com>2019-02-19 06:39:02 -0800
commit15b7c542dc44899e8db7addfcc2f1c1c4a188b49 (patch)
tree3857de5f06aae8f5bf25acebe306920545fc7ee4 /mpi
parent2b3179ea5e50778f1f19054b9d6d8aa06d683081 (diff)
downloadtxr-15b7c542dc44899e8db7addfcc2f1c1c4a188b49.tar.gz
txr-15b7c542dc44899e8db7addfcc2f1c1c4a188b49.tar.bz2
txr-15b7c542dc44899e8db7addfcc2f1c1c4a188b49.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.
Diffstat (limited to 'mpi')
-rw-r--r--mpi/mpi.c8
1 files changed, 7 insertions, 1 deletions
diff --git a/mpi/mpi.c b/mpi/mpi.c
index 6aa905bb..579a43a6 100644
--- a/mpi/mpi.c
+++ b/mpi/mpi.c
@@ -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) {