[PATCH v3 04/19] Add umul_ppmm to gmp-arch.hdoc
Adhemerval Zanella Netto
adhemerval.zanella@linaro.org
Thu Nov 6 10:32:51 GMT 2025
On 03/11/25 03:31, Maciej W. Rozycki wrote:
> On Fri, 31 Oct 2025, Adhemerval Zanella wrote:
>
>> 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. I kept only x86 optimization, where there is no
>> easy way to emit mul{q}. For the rest, the compiler generates good
>> enough code.
>
> Hmm, this reference code works for me:
>
> $ cat mulq.c
> typedef unsigned int __attribute__ ((mode (DI))) uint64_t;
> typedef unsigned int __attribute__ ((mode (TI))) uint128_t;
>
> uint128_t
> mulq (uint64_t x, uint64_t y)
> {
> return (uint128_t) x * (uint128_t) y;
> }
> $ x86_64-linux-gnu-gcc -O2 -S mulq.c -o x86_64-linux-gnu-mulq.s
> $ cat x86_64-linux-gnu-mulq.s
> .file "mulq.c"
> .text
> .p2align 4
> .globl mulq
> .type mulq, @function
> mulq:
> .LFB0:
> .cfi_startproc
> movq %rdi, %rax
> mulq %rsi
> ret
> .cfi_endproc
> .LFE0:
> .size mulq, .-mulq
> .ident "GCC: (GNU) 11.0.0 20200919 (experimental)"
> .section .note.GNU-stack,"",@progbits
> $
>
> Is this not what you need? It should work for any 64-bit platform that
> has a widening multiply operation defined in the compiler backend, e.g.
> for MIPS64:
You are right, I think I have missed something during my analysis.
I will refactor in terms of math_uint128.h as:
umul_ppmm_generic (mp_limb_t *w1, mp_limb_t *w0, mp_limb_t u, mp_limb_t v)
{
[...]
#if __MATH_INT128_BUILTIN_TYPE
u128 r = (u128)u * (u128)v;
*w1 = u128_high (r);
*w0 = u128_low (r);
#else
[...]
#endif
}
>
> $ mips64-linux-gnu-gcc -O2 -S mulq.c -o mips64-linux-gnu-mulq.s
> $ cat mips64-linux-gnu-mulq.s
> .file 1 "mulq.c"
> .section .mdebug.abi64
> .previous
> .nan legacy
> .module fp=64
> .module oddspreg
> .module arch=mips3
> .abicalls
> .text
> .align 2
> .align 3
> .globl mulq
> .set nomips16
> .set nomicromips
> .ent mulq
> .type mulq, @function
> mulq:
> .frame $sp,0,$31 # vars= 0, regs= 0/0, args= 0, gp= 0
> .mask 0x00000000,0
> .fmask 0x00000000,0
> .set noreorder
> .set nomacro
> dmultu $4,$5
> mflo $3
> mfhi $2
> jr $31
> nop
>
> .set macro
> .set reorder
> .end mulq
> .size mulq, .-mulq
> .ident "GCC: (GNU) 12.0.1 20220404 (experimental)"
> .section .note.GNU-stack,"",@progbits
> $
>
> Maciej
More information about the Libc-alpha
mailing list