質問

GCCでのアセンブリをインライン化するとき、私は以前のブロックで変数を生かし続けるために空のASMブロックを定期的に追加しなければならないのです。

asm("rcr $1,%[borrow];"
    "movq 0(%[b_],%[i],8),%%rax;"
    "adcq %%rax,0(%[r_top],%[i],8);"
    "rcl $1,%[borrow];"
    : [borrow]"+r"(borrow)
    : [i]"r"(i),[b_]"r"(b_.data),[r_top]"r"(r_top.data)
    : "%rax","%rdx");

asm("" : : "r"(borrow) : ); // work-around to keep borrow alive ...
.

他の奇妙さの例は、以下のコードが最適化なしで最適化されていないが-O3 ITセグオームを持つものです。

ulong carry = 0,hi = 0,qh = s.data[1],ql = s.data[0];
asm("movq 0(%[b]),%%rax;"
    "mulq %[ql];"
    "movq %%rax,0(%[sb]);"
    "movq %%rdx,%[hi];"
    : [hi]"=r"(hi)
    : [ql]"r"(ql),[b]"r"(b.data),[sb]"r"(sb.data)
    : "%rax","%rdx","memory");
for (long i = 1; i < b.size; i++)
{
    asm("movq 0(%[b],%[i],8),%%rax;"
        "mulq %[ql];"
        "xorq %%r10,%%r10;"
        "addq %%rax,%[hi];"
        "adcq %%rdx,%[carry];"
        "adcq $0,%%r10;"
        "movq -8(%[b],%[i],8),%%rax;"
        "mulq %[qh];"
        "addq %%rax,%[hi];"
        "adcq %%rdx,%[carry];"
        "adcq $0,%%r10;"
        "movq %[hi],0(%[sb],%[i],8);"
        "movq %[carry],%[hi];"
        "movq %%r10,%[carry];"
        : [carry]"+r"(carry),[hi]"+r"(hi)
        : [i]"r"(i),[ql]"r"(ql),[qh]"r"(qh),[b]"r"(b.data),[sb]"r"(sb.data)
        : "%rax","%rdx","%r10","memory");
}
asm("movq -8(%[b],%[i],8),%%rax;"
    "mulq %[qh];"
    "addq %%rax,%[hi];"
    "adcq %%rdx,%[carry];"
    "movq %[hi],0(%[sb],%[i],8);"
    "movq %[carry],8(%[sb],%[i],8);"
    : [hi]"+r"(hi),[carry]"+r"(carry)
    : [i]"r"(long(b.size)),[qh]"r"(qh),[b]"r"(b.data),[sb]"r"(sb.data)
    : "%rax","%rdx","memory");
.

私はそれが非常に多くのレジスタを使用しているという事実と関係があると思います。ここに抜け出しているものがありますか、またはGCCインラインアセンブリに本当にバグがバグの登録の登録はありますか?

役に立ちましたか?

解決

What you're missing is that GCC's optimiser will assume that the only side-effect of an asm block is to change the output operands. If those operands are not subsequently used, it may assume that the asm block in unnecessary and can be deleted.

e.g. in your first example, if borrow is not subsequently used, it is free to assume that there is no point in including the asm block at all, because its only side-effect is to update a variable that is never used again. And in the second example, if hi and carry are not used again after the code you've shown, it will probably infer that it can delete pretty much everything!

You can tell GCC that your inline assembly blocks should not be deleted by writing asm volatile(...) instead of just asm(...).

For more detail about this, see http://gcc.gnu.org/onlinedocs/gcc/Extended-Asm.html (about half-way down the page).

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top