c - 内联汇编中的 "matching constraint"是什么意思?

标签 c gcc freebsd inline-assembly powerpc

当我尝试在 powerpc arch 上编译它们时,此 Booth 宏会引发警告。

#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 上的行为更加清晰。

最佳答案

您有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 手册:

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.

我也不确定是否 "%cc"是一个有效的破坏标识符,通常您不使用 "%" 作为前缀。 。在 x86 上,适当的标识符是 "cc" .

关于c - 内联汇编中的 "matching constraint"是什么意思?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18589200/

相关文章:

c - 结构指针数组和分配结构数据

mysql - 使用依赖库编译nginx模块

gcc - gdb - 如何进入多行宏

c++ - 为什么在我的 Mac 上编译的 C++ 库不能在服务器上运行?

c - gcc静态链接 undefined reference

makefile - 用于构建库的旧 Makefile 在 FreeBSD 下不再工作

c - 在处理二进制文件时,fread 获得的字符比我在 c 中要求的要多

c - 列 "symbol"显示地址而不是函数名

C Sharedmemory only 1024 int in forked process

linux - Ubuntu 上的 FreeBSD 功能使用