我正在使用 ARM 发布的内在函数来使用 ARM NEON。 我希望我的代码能够在 ARMv7 和 AArch64 上运行。 我用来检查向量是否全为零的一个惯用语是这个汇编惯用语:
shrn v0.8b, v0.8h, #4 // compress bytes in v0 into nibbles
fcmp d0, #0.0
如果
v0
的所有字节都是 0x00 或 0xff(我的代码就是这种情况),则此方法可以正常工作。
为了将这个习惯用法翻译成 C 代码,我尝试使用这样的代码,它成功地构建在 AArch64 上并生成所需的机器代码:
static int
veq_zero(uint8x16_t v)
{
uint8x8_t narrowed;
/* narrow each byte to a nibble */
narrowed = vshrn_n_u16(vreinterpretq_u16_u8(v), 4);
/* check if that vector is all zero */
return (vdupd_lane_f64(vreinterpret_f64_u16(narrowed), 0) == 0.0);
}
不幸的是,
vdupd_lane_f64
和vreinterpret_f64_u16
调用在ARMv7上都不可用;看起来确实整个 float64x1_t
类型及其所有相关功能都不存在。
将此程序惯用语转换为具有内在函数的 C 语言的最佳方法是什么,以便它既可以为带有 NEON 的 ARMv7 也可以为 AArch64 进行编译?
static int
veq_zero(uint8x16_t v)
{
/* check if that vector is all zero */
return vmaxvq_u8(narrowed) == 0;
}