如何在 ARM/ACLE 中交换向量中各个单词的字节顺序

Dan*_*Niu 2 arm simd cpu-word endianness neon

我通常编写可移植的 C 代码,并尝试严格遵守编译器支持的功能子集的标准。

不过,我正在编写利用 ARM v8 加密扩展来实现 SHA-1(以及几天后的 SHA-256)的代码。我面临的一个问题是,FIPS-180 使用大端字节顺序指定哈希算法,而大多数基于 ARM 的操作系统 ABI 都是小端字节顺序。

如果它是单个整数操作数(在通用寄存器上),我可以使用为下一个 POSIX 标准指定的 API,但我正在使用 SIMD 寄存器,因为它是 ARMv8 Crypto 工作的地方。

那么:如何在 ARM 上的向量寄存器中交换字的字节顺序?我对汇编答案很满意,但更喜欢 ACLE 内在函数的答案。

Dan*_*Niu 7

说明是:

\n
    \n
  • REV16对于字节交换短整数,
  • \n
  • REV32对于字节交换 32 位整数,以及
  • \n
  • REV64用于字节交换 64 位整数。
  • \n
\n

它们可用于交换严格小于其名称所示长度的任何长度的字节和字顺序。它们在Arm\xc2\xae 架构参考手册\nArmv8 的 C7.2.219~C7.2.221 节中定义,针对 A-profile 架构“DDI0487G_b_armv8_arm.pdf”

\n

例如REV32可用于反转每个 32 位字内 2 个短整数的顺序:

\n
[00][01][02][03][04][05][06][07]\nto\n[02][03][00][01][06][07][04][05]\n
Run Code Online (Sandbox Code Playgroud)\n

它们的内在函数在单独的文档中定义:Arm Neon Intrinsics Reference “advsimd-2021Q2.pdf”

\n

要交换 128 位向量中的 32 位字,请使用 intrinsic vrev32q_u8vreinterpretq_*需要使用相关的内在函数来重新解释操作数的类型。

\n