ARM64 上的 vtbl2 内在函数缺失

vtbl2 intrinsics on ARM64 missing

我有一些使用 vtbl2_u8 ARM Neon 内部函数的代码。当我使用 armv7armv7s 架构编译时,此代码可以正确编译(并执行)。但是,当我尝试编译目标 arm64 时,出现错误:

simd.h: error: call to unavailable function 'vtbl2_u8'

我的Xcode版本是6.1,iPhoneSDK 8.1。查看 arm64_neon_internal.hvtbl2_u8 的定义有一个 __attribute__(unavailable)vtbl2q_u8 有一个定义,但它采用不同的参数类型。 arm64vtbl2 内在函数是否有直接替代?

如 ARM NEON 内在函数参考 (http://infocenter.arm.com/help/topic/com.arm.doc.ihi0073a/IHI0073A_arm_neon_intrinsics_ref.pdf) 中所述,vtbl2_u8 预计由编译器提供,为 ARMv8-A 中的 AArch64 状态提供 ARM C 语言扩展实现。请注意,同一文档会建议 vtbl2q_u8 是一个 Xcode 扩展,而不是预期由 ACLE 编译器支持的内部函数。

那么你的问题的答案是,是否不需要替换 vtbl2_u8,因为它应该被提供。但是,这并不能帮助您解决真正的问题,也就是如何将指令与不提供指令的编译器一起使用。

查看您在 Xcode 中可用的内容,以及 vtbl2_u8 记录映射到的内容,我认为您应该能够通过以下方式模拟预期行为:

uint8x8_t vtbl2_u8 (uint8x8x2_t a, uint8x8_t b)
{
  /* Build the 128-bit vector mask from the two 64-bit halves.  */
  uint8x16_t new_mask = vcombine_u8 (a.val[0], a.val[1]);
  /* Use an Xcode specific intrinsic.  */
  return vtbl1q_u8 (new_mask, b);
}

虽然我没有 Xcode 工具链来测试,所以您必须确认它是否符合您的预期。

如果这出现在性能关键代码中,您可能会发现 vcombine_u8 是不可接受的额外指令。从根本上说,uint8x8x2_t 存在于两个连续的寄存器中,这在 AArch64 和 AArch32 之间提供了不同的布局(其中 Q0 是 D0:D1)。vtbl2_u8 内在需要一个 16 位掩码。

重写 uint8x8x2_t 数据的生成器以生成 uint8x16_t 是唯一的其他解决方法,并且可能是最有效的方法。请注意,即使在提供 vtbl2_u8 内部函数的编译器中(在撰写本文时,主干 GCC 和 Clang),也会插入执行 vcombine_u8 的指令,因此您可能仍会在幕后看到额外的移动指令。