转换SSE和NEON内在函数 - 改组

Rah*_*hul 6 sse shuffle intrinsics neon

我正在尝试将用SSE3内在函数编写的代码转换为NEON SIMD,因为有一个shuffle函数而被卡住了.我看过GCC Intrinsic s,ARM手册和其他论坛,但一直无法找到解决方案.

码:

_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));
Run Code Online (Sandbox Code Playgroud)

虽然vtbl1_u8(uint8x8_t,uint8x8_t)指令创建了一个查找表,可用于为目标寄存器赋值,但它只能在64位寄存器上运行.而且随机操作在启动时执行比较,必须在NEON和我不知道如何有效地做到这一点.

r0 =(mask0&0x80)?0:SELECT(a,mask0&0x0f)// SELECT(a,n)从a中提取第n个8位参数.

r1 =(mask1和0x80)?0:SELECT(a,mask1和0x0f)

...

我找不到首先检查掩码的高位然后有效地选择掩码的低4位的指令.我知道我们可以比较寄存器中的每个位,然后在指定条件时选择低4位,但是我希望能有效地做到这一点.希望有人可以提供帮助或提供参考.

非常感谢,

干杯!

Jak*_*LEE 3

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

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

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

这样就可以了。

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

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

因此,您必须牺牲一个初始化为位掩码操作数的寄存器。

  1. vmov.u8,d1,#0x70
  2. 将查找表加载到 Q 寄存器中(例如 Q8)
  3. vbic.i8 d0、d0、d1
  4. vtbl.8 d0, {q8}, d0 (其中 d0 包含您的掩码)