【发布时间】:2013-09-03 09:52:13
【问题描述】:
当我尝试在 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 上的行为应该是什么。
【问题讨论】:
-
我不知道 PowerPC,但您要求参数 0 作为寄存器 - 是否所有使用
%0作为操作数的操作都允许在该位置使用寄存器操作数? -
@KerrekSB 如果是这种情况,他会收到汇编错误,而不是 C 警告。 C 编译器不会检查 asm 是否有意义。
-
由于我做了很多 x86 汇编,我可以向你保证
"%rax"和"%cc"不是有效的clobber 标识符,编译器会直接忽略它们。正确的方法是"rax", "cc" -
@Sergey L. 你确定吗?因为这段代码是 libtom 的一部分,如果它被忽略,mathlib 不应该运行。
-
我不相信,我相信这是一个偶然“好”的错误。我在 gcc 扩展 asm 文档中的任何地方都找不到必须在 clobber 标识符前面加上
%的前缀。这是 AT&T 汇编器特定的语法,gcc 支持各种汇编器语法。 Clobbers 向编译器指示您打算覆盖的那些寄存器,而这些寄存器是编译器无法知道的。但是正如我之前所说的,rax是一个非常常用的寄存器,许多指令都隐含地使用它,所以很可能在使用该代码的任何地方,该部分并不重要。但这是猜测。
标签: c gcc freebsd inline-assembly powerpc