2

当我尝试在 powerpc 架构上编译它们时,这个展位宏会引起警告。

#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");

在调用宏的每一行中,编译器都会收到以下警告:

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

任何人都可以告诉我这意味着什么,以及它以何种方式影响代码?而且由于我真的不习惯汇编程序,也许有人可以帮助我,在我的情况下特别是什么导致了警告?

我的系统是 32 位的 freeBSD 我正在使用 gcc4.8.2

编辑:

下面是对应的x86_64代码,在x86上执行编译没有问题:

#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")

也许这更清楚地说明了代码在 powerpc 上的行为应该是什么。

4

1 回答 1

3

在这两种情况下,您都有cy_c[0]作为输入/输出变量。您已正确地将它们指定为具有匹配约束的输出和输入。这可能是 PPC 特定的,因为它"1"在扩展 asm(寄存器号)中具有模棱两可的含义,我自己只在 x86 上工作。

"+"您可以通过使用输出量词而不是将变量指定为输入/输出变量一次来消除警告(以及可能与之相关的任何错误)"="

#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");

编辑:来自 gcc 扩展 asm 手册:

扩展 asm 支持输入输出或读写操作数。使用约束字符“+”来表示这样的操作数并将其与输出操作数一起列出。

另外我不确定是否"%cc"是一个有效的clobber标识符,通常你不会在那些前面加上"%". 在 x86 上,适当的标识符是"cc".

于 2013-09-03T10:32:10.230 回答