2

このブース マクロを 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");

マクロが呼び出される各行で、コンパイラによって次の警告が表示されます。

../../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

どちらの場合も、入力/出力変数としてcyand があります。_c[0]一致する制約を使用して、出力と入力の両方としてそれらを適切に指定しました。"1"これは、拡張 asm (レジスタ番号) であいまいな意味を持つため、PPC 固有である可能性があります。私自身は 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"、wether が有効な clobber 識別子であるかどうかもわかりません。通常、それらの前に"%". x86 では、適切な識別子は"cc".

于 2013-09-03T10:32:10.230 に答える