如何在ARM64平台使用MSVC生成高效的128位移位实现?
ARM64平台下让MSVC生成高效128位移位代码的方案
问题说明
在ARM64平台,GCC/Clang编译以下代码时,会自动生成ARM64专属的extr指令,实现高效的128位右移操作:
#include <cstdint> uint64_t shiftright61(uint64_t lo, uint64_t hi) { return ((((__uint128_t) hi) << 64) | lo) >> 61; }
对应的汇编输出为:
shiftright61(unsigned long, unsigned long): extr x0, x1, x0, 61 ret
但在ARM64平台使用MSVC时,x64平台可用的__shiftright128 intrinsic会提示未定义,无法直接复用。以下是两种可行的解决办法:
解决办法
1. 直接使用ARM64内联汇编
直接嵌入extr指令,精准实现所需功能:
#include <cstdint> uint64_t shiftright61(uint64_t lo, uint64_t hi) { uint64_t result; __asm { extr x0, x1, x0, 61 ; 从x1(hi)和x0(lo)中提取位组合,结果存x0 mov result, x0 } return result; }
extr指令的作用是将第二个寄存器的高位与第一个寄存器的低位拼接,最后一个参数61表示提取的偏移量,完全匹配原128位右移61位的逻辑。
2. 纯位运算实现(MSVC可自动优化为extr)
无需汇编,用纯C++代码实现等价逻辑,MSVC的ARM64编译器会自动将其优化为extr指令:
#include <cstdint> uint64_t shiftright61(uint64_t lo, uint64_t hi) { // 等价于128位值(hi<<64 | lo)右移61位的结果 return (hi << 3) | (lo >> 61); }
这段代码的逻辑是:将hi左移3位(对应128位右移后hi部分的有效位),拼接上lo右移61位得到的低3位,最终结果与原128位位移逻辑完全一致。
内容的提问来源于stack exchange,提问作者orlp
相关产品推荐
相关产品推荐

