__builtin_addcll 和 _addcarry_u64 之间的区别

Difference between __builtin_addcll and _addcarry_u64

早上好(或晚上好),

我在阅读我公司的一些遗留代码时发现使用了以下内在代码:

_addcarry_u64

但是,我必须将这段代码移植到不支持它的平台上。 经过一些研究,我偶然发现了一个似乎做完全相同工作的 Clang 内置函数:

__builtin_addcll

它具有相同的论点(顺序不同但仍然如此),但是,由于即使在 Clang 网站上也很少甚至没有关于它的 documentation,我不知道它们是否真的相同或不同,特别是因为 return 类型或参数顺序不一样。

我尝试使用宏来重新映射已使用的参数,但它不起作用(我知道它很脏)。

#define _addcarry_u64(carryIn, src1, src2, carryOut) __builtin_addcll(src1, src2, carryIn, carryOut)

我觉得我必须将它包装在一个函数中才能正常工作(我仍然不确定它是否会工作)

任何人都可以指出文档或任何可以解决我的问题的方法吗?

Clang 的签名是

unsigned long long __builtin_addcll(unsigned long long x,
                                    unsigned long long y,
                                    unsigned long long carryin,
                                    unsigned long long *carryout);

英特尔版本为

unsigned char _addcarry_u64 (unsigned char c_in,
                             unsigned __int64 a,
                             unsigned __int64 b,
                             unsigned __int64 * out)

所以你的宏不正确。 _addcarry_u64 加上 2 个数和 returns 进位 ,总和通过指针返回,如 Intel

所述

Add unsigned 64-bit integers a and b with unsigned 8-bit carry-in c_in (carry flag), and store the unsigned 64-bit result in out, and the carry-out in dst (carry or overflow flag).

__builtin_addcll OTOH returns 直接求和 并且进位通过指针返回,正如您从 Clang documentation link 中看到的那样

Clang provides a set of builtins which expose multiprecision arithmetic in a manner amenable to C. They all have the following form:

unsigned x = ..., y = ..., carryin = ..., carryout;
unsigned sum = __builtin_addc(x, y, carryin, &carryout);

所以相当于

int carryOut = _addcarry_u64(carryIn, x, y, &sum);

在 Clang 中是

auto sum = __builtin_addcll(x, y, carryIn, &carryOut);