ARM64上的vtbl2特性丢失

vtbl2 intrinsics on ARM64 missing

本文关键字:上的 vtbl2 ARM64      更新时间:2023-10-16

我有一些使用vtbl2_u8 ARM Neon固有函数的代码。当我用armv7armv7s架构编译时,这段代码可以正确编译(并执行)。但是,当我尝试针对arm64编译时,我得到错误:

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

我的Xcode版本是6.1,iPhone SDK 8.1。看看arm64_neon_internal.h, vtbl2_u8的定义有一个__attribute__(unavailable)vtbl2q_u8有一个定义,但它采用不同的参数类型。是否有直接替代arm64固有的vtbl2 ?

正如ARM NEON intrinsic参考(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内在特性的编译器中(编写时为trunk GCC和Clang),也会插入执行vcombine_u8的指令,因此您可能仍然会在幕后看到额外的move指令。