【问题标题】:Are there ARM intrinsics for add-with-carry in C?C 中是否有 ARM 内部函数用于加法进位?
【发布时间】:2016-09-04 17:56:52
【问题描述】:

是否存在用于 ARM C 编译器进行加法运算的内在函数,或者是否有必要使用汇编语言?

在 x86 上,有 _addcarry_u64 用于 add-with-carry。 (还有用于特殊用途的较新的_addcarryx_u64。)

【问题讨论】:

  • 编译器通常在带有adc 的32 位机器上实现int64_t,所以你可以转换成那个。 64 位平台上的 GNU C (gcc / clang) 通常支持__int128_t
  • Aarch64 有一个 gcc 5.2 使用的 adc 指令。 (adds / adc 添加两个 __int128_t 参数),但 Aarch64 gcc 4.8 使用 cmov-and-increment csinc instruction。见the output on godbolt。 IDK 为什么 aarch64 gcc 4.8 不能只使用adc
  • 我没有看到用于 add-with-carry 的 gcc __builtin 函数 :(
  • 请注意,无论您尝试做什么都需要这样做,您同样需要另一个内在函数来首先设置进位标志。我很确定两者都不存在。
  • 对于 GCC 和 Clang stackoverflow.com/questions/33690791/…,x86 的情况并没有好转

标签: arm intrinsics


【解决方案1】:

当前版本的 gcc 没有内在特性。一个问题是“携带标志”的沟通。但是,ARM 后端确实知道并定义了一组ADC 原语,例如addsi3_carryin

对于example

unsigned long long big_inc(unsigned long long x)
{
  return ++x;
}

被翻译成,

big_inc(unsigned long long):
        @ args = 0, pretend = 0, frame = 0
        @ frame_needed = 0, uses_anonymous_args = 0
        @ link register save eliminated.
        adds    r0, r0, #1
        adc     r1, r1, #0
        bx      lr

当您有这样的问题时,查看开源多精度库总是很有启发性的。有 OpenSSL bignumGNU MP 图书馆没有任何研究。由于内在不存在更明确的答案(对于您的工作)取决于您想要实现的目标;素数、乘法、加法等。您始终可以使用汇编程序或更强大的脚本,为您的特定整数长度生成汇编程序。

【讨论】:

  • 许多通用库会执行类似Duff's device 的操作并运行到'int[]` 数组以执行adds/adc/adcs 适当地执行操作.但是,循环内部通常可以组合起来以提高效率,因为您不需要继续加载内存;上面关于它的评论取决于你想做什么......
猜你喜欢
  • 1970-01-01
  • 2015-12-14
  • 2020-05-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-08-07
  • 2013-11-09
  • 1970-01-01
相关资源
最近更新 更多