__builtin_addcll 和 _addcarry_u64 之间的区别

发布于 2025-01-16 16:39:53 字数 651 浏览 3 评论 0原文

早上好(或晚上好),

我正在阅读公司中的一些遗留代码,我发现使用了以下内在函数:

_addcarry_u64

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

__builtin_addcll

它具有相同的参数(顺序不同,但仍然如此),但是,因为几乎没有 文档 即使在 Clang 网站上,我也不知道它们是否真的相同,尤其是因为返回类型或参数顺序不同。

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

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

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

任何人都可以向我指出文档或任何可以解决我的问题的内容吗?

Good morning (or good evening),

I was reading some legacy code in my company and I found the following intrinsic was used:

_addcarry_u64

However, I have to port this code on a platform that does not support it.
After some research, I stumbled upon a Clang builtin that seemed to do the exact same job:

__builtin_addcll

It has the same arguments (not in the same order but still), however, since there is little to no documentation about it even on Clang website, I have no clue if they truly are the same or not, especially since return types or argument order is not the same.

I tried to use a macro to remap already used arguments however it did not work (I know it's dirty).

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

I feel I will have to wrap it in a function for it to work correctly (still I'm not sure it would work)

Can anyone point me to a documentation or to anything that could solve my problem?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

江南烟雨〆相思醉 2025-01-23 16:39:53

Clang 的签名是

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

,Intel 版本是

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

所以你的宏不正确。 _addcarry_u64 添加 2 个数字并返回进位,并且按照 Intel 的规定通过指针返回总和

将无符号 64 位整数 ab 与无符号 8 位进位输入 c_in(进位标志)相加,并存储无符号 64 位结果在 out 中,进位在 dst 中(进位或溢出标志)。

__builtin_addcll OTOH 直接返回总和,并且执行结果通过指针返回,正如您可以从 Clang 文档链接

Clang 提供了一组内置函数,它们以适合 C 的方式公开多精度算术。它们都具有以下形式:

无符号 x = ..., y = ..., 进位 = ..., 进位;
无符号和 = __builtin_addc(x, y, 进位, &carryout);

的等价物是

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

因此Clang 中

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

The signature for Clang is

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

and the Intel version is

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

So your macro is incorrect. _addcarry_u64 adds 2 number and returns the carry, and the sum is returned via a pointer as stated by 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 the sum directly and the carry out is returned via a pointer as you can see right from your 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);

So the equivalent to

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

in Clang is

auto sum = __builtin_addcll(x, y, carryIn, &carryOut);
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文