我正在尝试将用SSE3内在函数编写的代码转换为NEON SIMD,由于随机播放功能而卡住了。我看过GCC IntrinsicARM manuals和其他论坛,但找不到解决方案。
代码:

_m128i upper = _mm_loadu_si128((__m128i*)p1);

register __m128i mask1 = _mm_set_epi8 (0x80,0x80,0x80,0x80,0x80,0x80,0x80,12,0x80,10,0x80,7,0x80,4,0x80,1);
register __m128i mask2 = _mm_set_epi8 (0x80,0x80,0x80,0x80,0x80,0x80,12,0x80,10,0x80,7,0x80,4,0x80,1,0x80);
__m128i temp1_upper = _mm_or_si128(_mm_shuffle_epi8(upper,mask1),_mm_shuffle_epi8(upper,mask2));
尽管vtbl1_u8(uint8x8_t,uint8x8_t)指令创建了一个可用于将值分配给目标寄存器的查找表,但它仅在64位寄存器上运行。 NEON和我不知道如何有效地做到这一点。

我找不到一条先检查掩码的高位然后有效选择掩码的低4位的指令。我知道我们可以比较寄存器中的每个位,然后在指定条件的情况下选择低4位,但是我希望能有效地做到这一点。希望有人可以提供帮助或提供引用。
非常感谢,
干杯!

最佳答案

当索引超出范围时,VTBL返回0。

由于它最多支持两个Q寄存器作为查找表,因此非常简单:

  • 将查找表加载到Q寄存器(例如Q8)中
  • vtbl.8 d0,{q8},d0(其中d0包含您的掩码)

  • 这样就可以了。

    如果您希望位4〜6不受影响,则可以在vtbl之前将其屏蔽掉。

    不幸的是,VBIC对于8位立即数绝对没有用。

    因此,您必须牺牲一个初始化为位掩码操作数的寄存器。
  • vmov.u8,d1,#0x70
  • 将查找表加载到Q寄存器(例如Q8)中
  • vbic.i8 d0,d0,d1
  • vtbl.8 d0,{q8},d0(其中d0包含您的掩码)
  • 09-26 21:11
    查看更多