Add umul_ppmm to gmp-arch.hdoc

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  <Wilco.Dijkstra@arm.com>
This commit is contained in:
Adhemerval Zanella 2025-11-20 15:30:07 -03:00
parent 8cd6efca5b
commit 7a0471f149
1 changed files with 26 additions and 0 deletions

View File

@ -37,6 +37,32 @@ ll_highpart (mp_limb_t t)
return t >> (BITS_PER_MP_LIMB / 2); 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, /* udiv_qrnnd(quotient, remainder, high_numerator, low_numerator,
denominator) divides a UDWtype, composed by the UWtype integers denominator) divides a UDWtype, composed by the UWtype integers
HIGH_NUMERATOR and LOW_NUMERATOR, by DENOMINATOR and places the quotient HIGH_NUMERATOR and LOW_NUMERATOR, by DENOMINATOR and places the quotient