在ARM / AArch64上,可以使用UMULL、MLA和UDIV指令模拟带双宽度被除数的缩小除法。以下是一个示例函数,它使用这些指令来计算DIVQ的等效值:
uint64_t divq(uint64_t a, uint64_t b) {
if (a < b) return 0;
if (a == b) return 1;
uint32_t leading_zeros = __builtin_clzll(b);
uint64_t r = b << leading_zeros;
uint64_t q = 0;
for (int i = 0; i < 64 - leading_zeros; i++) {
uint64_t t = ((q << 1) | ((a >> (63 - i)) & 1)) - r;
if (t >> 63 == 0) {
q = (q << 1) | ((a >> (63 - i)) & 1);
} else {
q = (q << 1) | (((a >> (63 - i)) & 1) ^ 1);
t += r;
}
r = (r >> 1) | (t >> 63);
}
return q;
}
这个函数计算a / b的整数部分,并返回它作为uint64_t类型的结果。