我正在 GAS 内联汇编中编写汇编长加法,
template <std::size_t NumBits>
void inline KA_add(vli<NumBits> & x, vli<NumBits> const& y);
如果我专攻,我可以:
template <>
void inline KA_add<128>(vli<128> & x, vli<128> const& y){
asm("addq %2, %0; adcq %3, %1;" :"+r"(x[0]),"+r"(x[1]):"g"(y[0]),"g"(y[1]):"cc");
}
很好,现在如果我尝试概括以允许模板内联,并让我的编译器工作任何长度......
template <std::size_t NumBits>
void inline KA_add(vli<NumBits> & x, vli<NumBits> const& y){
asm("addq %1, %0;" :"+r"(x[0]):"g"(y[0]):"cc");
for(int i(1); i < vli<NumBits>::numwords;++i)
asm("adcq %1, %0;" :"+r"(x[i]):"g"(y[i]):"cc");
};
好吧,它不起作用我不能保证进位位(CB)被传播。第一个 asm 行和第二个 asm 行之间不守恒。这可能是合乎逻辑的,因为循环增加了 i 并因此“删除”了 CB I 事物,它应该存在 GAS 约束以在两个 ASM 调用中保存 CB。不幸的是,我没有找到这样的信息。
任何的想法 ?
谢谢你,谢谢!
PS 我重写了我的函数以删除 C++ 意识形态
template <std::size_t NumBits>
inline void KA_add_test(boost::uint64_t* x, boost::uint64_t const* y){
asm ("addq %1, %0;" :"+r"(x[0]):"g"(y[0]):"cc");
for(int i(1); i < vli<NumBits>::numwords;++i)
asm ("adcq %1, %0;" :"+r"(x[i]):"g"(y[i]):"cc");
};
asm 给出(GCC 调试模式),
应用程序
addq %rdx, %rax;
NO_APP
movq -24(%rbp), %rdx
movq %rax, (%rdx)
.LBB94:.loc 9 55 0
movl $1, -4(%rbp)
jmp .L323
.L324:
.loc 9 56 0
movl -4(%rbp), %eax
cltq
salq $3, %rax
movq %rax, %rdx
addq -24(%rbp), %rdx <----------------- Break the carry bit
movl -4(%rbp), %eax
cltq
salq $3, %rax
addq -32(%rbp), %rax
movq (%rax), %rcx
movq (%rdx), %rax
应用程序
adcq %rcx, %rax;
NO_APP
正如我们所读到的,还有额外的 addq,它破坏了 CB 的传播