【发布时间】:2015-12-09 00:49:42
【问题描述】:
在 x86_64 中,我知道 mul 和 div opp 代码支持 128 个整数,方法是将低 64 位放在 rax 中,将高位放在 rdx 寄存器中。我在 intel 内在函数指南中寻找某种内在函数来执行此操作,但我找不到。我正在编写一个字长为 64 位的大数字库。现在我正在用这样的一个单词进行除法。
int ubi_div_i64(ubigint_t* a, ubi_i64_t b, ubi_i64_t* rem)
{
if(b == 0)
return UBI_MATH_ERR;
ubi_i64_t r = 0;
for(size_t i = a->used; i-- > 0;)
{
ubi_i64_t out;
__asm__("\t"
"div %[d] \n\t"
: "=a"(out), "=d"(r)
: "a"(a->data[i]), "d"(r), [d]"r"(b)
: "cc");
a->data[i] = out;
//ubi_i128_t top = (r << 64) + a->data[i];
//r = top % b;
//a->data[i] = top / b;
}
if(rem)
*rem = r;
return ubi_strip_leading_zeros(a);
}
如果我可以在 x86intrinsics.h 标头中使用某些东西而不是内联 asm,那就太好了。
【问题讨论】:
-
由于 asm 已经是特定于编译器的,您不妨只使用
__int128类型,它会自动执行您想要的操作。 -
看看_mulx_u64。看起来非常适合您使用,尽管它会生成仅在较新的 x86 处理器上存在的 mulx 指令。
-
在特定于架构的内在函数和特定于架构的程序集之间进行选择;后者有更好的文档、更好的支持、更广泛的理解和更易于维护(无需猜测编译器实际上做了什么)。
标签: c gcc inline-assembly intrinsics 128-bit