From 7a0471f1497a762f7d2149c4dc9570ef6c84a851 Mon Sep 17 00:00:00 2001 From: Adhemerval Zanella Date: Thu, 20 Nov 2025 15:30:07 -0300 Subject: [PATCH] Add umul_ppmm to gmp-arch.hdoc MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit To enable “longlong.h” removal, the umul_ppmm is moved to a gmp-arch.h. The generic implementation now uses a static inline, which provides better type checking than the GNU extension to cast the asm constraint (and it works better with clang). Most of the architecture uses the generic implementation, which is expanded from a macro, except for alpha, arm, hppa, x86, m68k, mips, powerpc, and sparc. The 32 bit architectures the compiler generates good enough code using uint64_t types, where for 64 bit architecture the patch leverages the math_u128.h definitions that uses 128-bit integers when available (all 64 bit architectures on gcc 15). Reviewed-by: Wilco Dijkstra --- sysdeps/generic/gmp-arch.h | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/sysdeps/generic/gmp-arch.h b/sysdeps/generic/gmp-arch.h index 3adab10732..f1dba1384b 100644 --- a/sysdeps/generic/gmp-arch.h +++ b/sysdeps/generic/gmp-arch.h @@ -37,6 +37,32 @@ ll_highpart (mp_limb_t t) return t >> (BITS_PER_MP_LIMB / 2); } +/* umul_ppmm(high_prod, low_prod, multiplier, multiplicand) multiplies two + UWtype integers MULTIPLIER and MULTIPLICAND, and generates a two UWtype + word product in HIGH_PROD and LOW_PROD. */ +static __always_inline void +umul_ppmm_generic (mp_limb_t *w1, mp_limb_t *w0, mp_limb_t u, mp_limb_t v) +{ +#if __WORDSIZE == 32 + uint64_t t0 = (uint64_t)u * v; + *w1 = t0 >> 32; + *w0 = t0; +#else + u128 r = u128_mul(u128_from_u64 (u), u128_from_u64 (v)); + *w1 = u128_high (r); + *w0 = u128_low (r); +#endif +} +#undef umul_ppmm +#define umul_ppmm(__w1, __w0, __u, __v) \ + ({ \ + __typeof (__w0) __w0t; \ + __typeof (__w1) __w1t; \ + umul_ppmm_generic (&__w1t, &__w0t, __u, __v); \ + __w1 = __w1t; \ + __w0 = __w0t; \ + }) + /* udiv_qrnnd(quotient, remainder, high_numerator, low_numerator, denominator) divides a UDWtype, composed by the UWtype integers HIGH_NUMERATOR and LOW_NUMERATOR, by DENOMINATOR and places the quotient -- 2.47.3