[arm64] Negative immediates

Marc Glisse marc.glisse at inria.fr
Mon Sep 22 20:51:33 UTC 2014

On Mon, 22 Sep 2014, Torbjörn Granlund wrote:

> Marc Glisse <marc.glisse at inria.fr> writes:
>  The compilation is quite noisy with -Wasm-operand-widths. In
>  particular, it complains about calling count_leading_zeros(a,b) where
>  a has 32 bits. The compiler is right in that the clz instruction wants
>  2 registers of the same size, though I doubt it can cause any trouble.
> I suppose that we might want to have the asm use a 64-bit destination
> reg then.

Something like this?

#define count_leading_zeros(count, x) \
   do { \
     UWtype __count; \
     __asm__ ("clz\t%0, %1" : "=r" (__count) : "r" (x)); \
     (count) = __count; \
   } while (0)

(aarch64 is likely not the only implementation with this issue)

Note that count_leading_zeros_gcc_clz seems to work just fine, we could 
use that instead.

>  I am also seeing it with umul_ppmm (digit, frac, frac, 10) because of
>  the last argument.
> OK.

Should we cast in the callers?
umul_ppmm (digit, frac, frac, (mp_limb_t)10)

Or in many umul_ppmm implementations? Probably the first solution I 

>  By the way, inline asm on aarch64 confuses me, it seems important to
>  name the registers properly (w0 vs x0) but I only see the "r"
>  constraint and clang does not seem to use the type of the argument to
>  disambiguate between w and x.
> The type width of the expression will be used, just like for x86-64
> where registers are named differently for different operation widths.

On aarch64, with "r"(var), gcc and clang always name the register x0 
(never w0), whether var is an int or a long long. On amd64, I get %al / 
%ax / %eax / %rax depending on the type of var.

Marc Glisse

More information about the gmp-bugs mailing list