aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPaul Eggert <eggert@cs.ucla.edu>2025-07-05 11:04:54 -0700
committerPaul Eggert <eggert@cs.ucla.edu>2025-07-09 17:12:40 -0700
commitd70e07668ca92b812ea31d0fd21f0bace4edeef8 (patch)
treeb33cd990515dacbec6427b479d40f2692d91afe6
parentfactor: streamline gcd2_odd (diff)
downloadcoreutils-d70e07668ca92b812ea31d0fd21f0bace4edeef8.tar.gz
coreutils-d70e07668ca92b812ea31d0fd21f0bace4edeef8.zip
factor: speed up umul_ppmm when !USE_LONGLONG_H
* src/factor.c (umul_ppmm): When !USE_LONGLONG_H so we need to define this, speed things up if there is an unsigned type uuroom_t wide enough to hold two words. Do not make a similar change for udiv_qrnnd, as it is not performance critical and anyway on GCC 15 x86-64 that would mean a subroutine call.
-rw-r--r--src/factor.c27
1 files changed, 20 insertions, 7 deletions
diff --git a/src/factor.c b/src/factor.c
index b62ec32e3..96ef8e828 100644
--- a/src/factor.c
+++ b/src/factor.c
@@ -179,13 +179,6 @@ typedef uint64_t UDItype;
# define HAVE_HOST_CPU_FAMILY_powerpc 1
# endif
# include "longlong.h"
-
-#else /* not USE_LONGLONG_H */
-
-static mp_limb_t const __ll_B = (mp_limb_t) 1 << (W_TYPE_SIZE / 2);
-static mp_limb_t __ll_lowpart (mp_limb_t t) { return t & (__ll_B - 1); }
-static mp_limb_t __ll_highpart (mp_limb_t t) { return t >> (W_TYPE_SIZE / 2); }
-
#endif
/* 2*3*5*7*11...*101 fits in 128 bits, and has 26 prime factors.
@@ -307,6 +300,26 @@ static void factor_up (struct factors *, mp_limb_t, mp_limb_t,
/* Set (w1,w0) = u * v. */
#ifndef umul_ppmm
+/* Speed things up if there is an unsigned type uuroom_t that is wide
+ enough to hold two words. */
+# if W_TYPE_SIZE <= UINTMAX_WIDTH / 2
+# define uuroom_t uintmax_t
+# elif W_TYPE_SIZE <= 64 && defined __SIZEOF_INT128__
+# define uuroom_t unsigned __int128
+# endif
+# ifdef uuroom_t
+# define umul_ppmm(w1, w0, u, v) \
+ do { \
+ uuroom_t _u = u, _w = _u * (v); \
+ (w1) = _w >> W_TYPE_SIZE; \
+ (w0) = _w; \
+ } while (0)
+# endif
+#endif
+#ifndef umul_ppmm
+static mp_limb_t const __ll_B = (mp_limb_t) 1 << (W_TYPE_SIZE / 2);
+static mp_limb_t __ll_lowpart (mp_limb_t t) { return t & (__ll_B - 1); }
+static mp_limb_t __ll_highpart (mp_limb_t t) { return t >> (W_TYPE_SIZE / 2); }
# define umul_ppmm(w1, w0, u, v) \
do { \
mp_limb_t __u = u, __v = v, \