Question

This booth macros are causing a warning, when I try to compile them on a powerpc arch.

#define INNERMUL asm( \
   " mullw    16,%3,%4       \n\t" \
   " mulhwu   17,%3,%4       \n\t" \
   " addc     16,16,%0       \n\t" \
   " addze    17,17          \n\t" \
   " lwz      18,%1          \n\t" \
   " addc     16,16,18       \n\t" \
   " addze    %0,17          \n\t" \
   " stw      16,%1          \n\t" \
:"=r"(cy),"=m"(_c[0]):"0"(cy),"r"(mu),"r"(tmpm[0]),"1"(_c[0]):"16", "17", "18","%cc"); ++tmpm;

#define PROPCARRY \
asm( \
   " lwz      16,%1         \n\t" \
   " addc     16,16,%0      \n\t" \
   " stw      16,%1         \n\t" \
   " xor      %0,%0,%0      \n\t" \
   " addze    %0,%0         \n\t" \
:"=r"(cy),"=m"(_c[0]):"0"(cy),"1"(_c[0]):"16","%cc");

In each line the macros get called, I get this warning by compiler:

../../src/math/mont.c:650: warning: matching constraint does not allow a register

Any one could tell me what this means, and in which way it affects the code? And as I'm really not that used to assembler, maybe some one could help me out, what specially in my case causes the warning?

My system is freeBSD on 32 Bit I'm using gcc4.8.2

EDIT:

Here is the corresponding x86_64 code, which is executed and compiled on x86 without problems:

#define INNERMUL \
asm( \
   "movq %5,%%rax \n\t" \
   "mulq %4       \n\t" \
   "addq %1,%%rax \n\t" \
   "adcq $0,%%rdx \n\t" \
   "addq %%rax,%0 \n\t" \
   "adcq $0,%%rdx \n\t" \
   "movq %%rdx,%1 \n\t" \
:"=g"(_c[LO]), "=r"(cy) \
:"0"(_c[LO]), "1"(cy), "r"(mu), "r"(*tmpm++) \
: "%rax", "%rdx", "%cc")

#define PROPCARRY \
asm( \
   "addq   %1,%0    \n\t" \
   "setb   %%al     \n\t" \
   "movzbq %%al,%1 \n\t" \
:"=g"(_c[LO]), "=r"(cy) \
:"0"(_c[LO]), "1"(cy) \
: "%rax", "%cc")

Maybe this makes more clear what the code's behavior on powerpc's should be.

Was it helpful?

Solution

You have cy and _c[0] as an input/output variable in both cases. You have properly specified them as both output and input with a matching constraint. This may be PPC specific as in that "1" has an ambiguous meaning in extended asm (register number), I myself only work on x86.

You can get rid of the warning (and any bugs that may be associated with it) by specifying your variable as an input/output variable just once using the "+" output quantifier instead of "=":

#define INNERMUL asm( \
   " mullw    16,%2,%3       \n\t" \
   " mulhwu   17,%2,%3       \n\t" \
   " addc     16,16,%0       \n\t" \
   " addze    17,17          \n\t" \
   " lwz      18,%1          \n\t" \
   " addc     16,16,18       \n\t" \
   " addze    %0,17          \n\t" \
   " stw      16,%1          \n\t" \
:"+r"(cy) \
,"+m"(_c[0]) \
:"r"(mu) \
,"r"(tmpm[0]) \
:"16", "17", "18","cc"); ++tmpm;

#define PROPCARRY \
asm( \
   " lwz      16,%1         \n\t" \
   " addc     16,16,%0      \n\t" \
   " stw      16,%1         \n\t" \
   " xor      %0,%0,%0      \n\t" \
   " addze    %0,%0         \n\t" \
:"+r"(cy) \
,"+m"(_c[0]) \
: \
:"16","cc");

Edit: from the gcc extended asm manual:

Extended asm supports input-output or read-write operands. Use the constraint character ‘+’ to indicate such an operand and list it with the output operands.

Also I am not sure wether "%cc" is a valid clobber identifier, normally you don't prefix those with "%". On x86 the appropriate identifier is "cc".

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top