c++ 如何使用MSVC在ARM64上生成高效的128位移位?

i2byvkas  于 2023-06-25  发布在  其他
关注(0)|答案(1)|浏览(174)

在ARM 64上使用GCC/Clang编译以下代码:

  1. #include <cstdint>
  2. uint64_t shiftright61(uint64_t lo, uint64_t hi) {
  3. return ((((__uint128_t) hi) << 64) | lo) >> 61;
  4. }

生成高效的实现:

  1. shiftright61(unsigned long, unsigned long):
  2. extr x0, x1, x0, 61
  3. ret

有没有办法让MSVC在ARM 64上生成这个128位移位?在x64上,以下代码可以生成SHRD 128位移位指令,但在ARM 64上,MSVC会抱怨__shiftright128没有定义:

  1. #include <cstdint>
  2. #include <intrin.h>
  3. uint64_t shiftright61(uint64_t lo, uint64_t hi) {
  4. return __shiftright128(lo, hi, 61);
  5. }
ulmd4ohb

ulmd4ohb1#

编译器识别以下内容以生成有效的移位:

  1. uint64_t shiftright61(uint64_t lo, uint64_t hi) {
  2. return (lo >> 61) | (hi << 3);
  3. }
  1. unsigned __int64 shiftright61(unsigned __int64,unsigned __int64):
  2. extr x0,x1,x0,#0x3D
  3. ret

在提出这个问题之前,我使用+而不是|来合并低偏移和高偏移,优化器没有识别出这一点。
有趣的是,上面的指令在x64上是,你仍然必须使用__shiftright128 intrary来让编译器发出SHRD指令。

相关问题