parameter size mismatch in mpn_pi1_bdiv_q_1

Niels Möller nisse at
Fri Dec 15 13:19:05 CET 2023

Robert Yates <rob at> writes:

> mpn\arm64\bdiv_q_1.asm
> define(`cnt', `x5')
> PROLOGUE(mpn_pi1_bdiv_q_1)
> 	sub	n, n, #1
> 	subs	x6, x6, x6		C clear r6 and C flag
> 	ldr	x9, [up],#8
> 	cbz	cnt, L(norm)
> the cbz instruction acts upon parameter 6(32bit int) with the x5(64bit
> register).
> i work on an obfuscation compiler at quarkslab, and its possible that
> optimisations or our transformation can leave random bits in the upper
> data of x5 which will make the implementation of mpn_pi1_bdiv_q_1
> fail, since clangs codegen will not emit trunc instructions for the
> 64bit register as the function prototype clearly states `i32` type
> although the internal function uses a 64bit register.

Interesting. I'm not quite familar with arm64, but I think your right
that this is an obscure bug. Almost all use of the cnt register (and the
tnc register) is for shifts, and then I take it all but the least
significant 6 bits are ignored? Except for the comparison to zero in the
cbz instruction, which depends on the higher bits.

> i noticed this issue on apple-arm64.
> i believe the implemetation should be changed to use the `w5`
> register, or the function prototype should use `long`, either of these
> solves the issues ive seen.

Changing the type would be an abi break, so not lightly done (even if
this is an internal function).

Does it work to just change all related w-registers like below patch? Or
will the assembler be unhappy with mix of x and w registers for the
shift instructions?


--- a/mpn/arm64/bdiv_q_1.asm	Mon Oct 16 08:16:06 2023 +0200
+++ b/mpn/arm64/bdiv_q_1.asm	Fri Dec 15 13:12:48 2023 +0100
@@ -49,10 +49,10 @@ define(`up',  `x1')
 define(`n',   `x2')
 define(`d',   `x3')
 define(`di',  `x4')		C	just mpn_pi1_bdiv_q_1
-define(`cnt', `x5')		C	just mpn_pi1_bdiv_q_1
+define(`cnt', `w5')		C	just mpn_pi1_bdiv_q_1
 define(`cy',  `r7')
-define(`tnc', `x8')
+define(`tnc', `w8')
@@ -87,7 +87,7 @@ PROLOGUE(mpn_pi1_bdiv_q_1)
 	lsr	x12, x9, cnt
 	cbz	n, L(eu1)
-	sub	tnc, xzr, cnt
+	sub	tnc, wzr, cnt
 L(tpu):	ldr	x9, [up],#8
 	lsl	x7, x9, tnc

Niels Möller. PGP key CB4962D070D77D7FCB8BA36271D8F1FF368C6677.
Internet email is subject to wholesale government surveillance.

More information about the gmp-bugs mailing list