assembly 多个 neon 寄存器上的位分散

uemypmqf  于 2023-08-06  发布在  其他
关注(0)|答案(1)|浏览(103)

将内存中的位均匀分布到多个向量寄存器的最有效方法是什么?所有数据必须以目标寄存器的最低有效位结束。
例如,如何将来自内存的2个字节分布在8个字上(在两个通道中)?

V0.S4             |  V1.S4
S[3]: [data bit 6 + 7]  |  [data bit 14 + 15]
S[2]: [data bit 4 + 5]  |  [data bit 12 + 13]
S[1]: [data bit 2 + 3]  |  [data bit 10 + 11]
S[0]: [data bit 0 + 1]  |  [data bit 8 + 9]

字符串
使用LD1和扩展指令可以轻松实现8、16和32位分割。3位拆分可能会很混乱。

vbopmzt1

vbopmzt11#

向量USHL/SSHL允许每元素移位计数,其中负计数产生右移位。戴着面具跟着它,你就有生意了。
首先用我们需要的常量初始化一些寄存器。这只需要做一次。

V8.4S = { 0, -2, -4, -6 }
V9.4S = { -8, -10, -12, -14 }
V10.4S = {3, 3, 3, 3}

字符串
然后

LD1R   V2.8H, [X0]       // load 2 bytes, replicate across all elements
                       // note we only really care about half of them
USHL   V0.4S, V2.4S, V8.4S
USHL   V1.4S, V2.4S, V9.4S
AND    V0.16B, V0.16B, V10.16B
AND    V1.16B, V1.16B, V10.16B


或者,要保存常量,也可以执行

V8.4S = {0, -2, -4, -6}
V10.4S = {3, 3, 3, 3}

LD2R   { V2.16B, V3.16B }, [X0]
USHL   V0.4S, V2.4S, V8.4S
USHL   V1.4S, V3.4S, V8.4S
AND    V0.16B, V0.16B, V10.16B
AND    V1.16B, V1.16B, V10.16B


其中两个字节中的每一个在其自己的寄存器上被复制。
您可以从LD1R V2.4S, [X0](然后是四个不同的移位计数向量)或LD4R { V2.16B, ..., V5.16B }, [X0]开始,按照第二种方法一次加载四个字节。您甚至可以使用LD4R { V2.4S, ..., V5.4S }, [X0]一次加载16个字节,然后重复第一个版本四次。

相关问题