2016-03-01 426 views
1

我想在ASIMD汇编指令中实现按位提取矢量指令。让我这样说吧,在ARMv7的NEON指令,假设我有内部q15q11一些价值观,我有:ASIMD指令中的按位提取矢量(ARM平台)

"vext.8 d30, d30, d22, #4 \n\t" 
"vext.8 d31, d31, d23, #4 \n\t" 

正如你所看到的,我提取从底部4字节元素d22的结尾和d30的顶端的4个字节的元素。然后我将它们组合成一个64位寄存器d30(上面的第一条指令)。在q载体的后半部分(d31d23)上完成相同的操作。现在,我想在ARMv8 ASIMD指令中实现完全相同的逻辑。在ASIMD vext替换指令是ext和它的定义为:

EXT VD(T),VN(T),VM(T),#INDEX

按位提取物(载体)。 。其中(T)是8B或16B。该索引是0到nelem((T)) - 1范围内的即时值。

我的问题是,我如何使用这个指令来构建我的两个SIMD向量相同的逻辑注册v15v11例如。

回答

2

您应该首先注意到,在Aarch64中,寄存器的组织方式不同。在Aarch32中,Q15是{D31,D30}。在Aarch64中,D31是Q31的底部,在谈论元素时可以将其描述为V31。

没有直接等同于Aarch64在这种情况下,因为你不能直接访问四寄存器的顶部64位,但我认为你应该能够取代它:

INS V15.S[0], V11.S[0] 
INS V15.S[2], V11.S[2] 

参考: http://infocenter.arm.com/help/topic/com.arm.doc.dui0802b/INS_advsimd_elt_vector.html

+0

我不确定我的答案是否很清楚。 ''EXT v15.8,v15.8,v11.8,#4“似乎在向量寄存器的下半部分(我的意思是'v15.d [0]'和'v11.d [0 ]')。然而,没有办法可以在这些向量的后半部分(我的意思是'v15.d [1]'和'v11.d [1]')做这个操作。在ARMv7中,正如你可以在我的问题中看到的,我们可以简单地用'“vext.8”做到这一点。“d31,d31,d23,#4 \ n \ t”' – A23149577

+0

对不起,我误解了你的描述。 – Dric512

0

不知道,如果你发现你的答案,或者如果这是你的预期目标:

正如@ Dric512表示,我认为你可以使用SIMD数据移动指令,INS。

在下面的例子中,我们将数字3和2分别插入到32位通道中的向量10和11中。

然后我们将相应的元素插入向量15的两个32位通道;由此导致所有的位进入向量的64位通道15.

mov w1, 3                                     
mov w2, 2                                     

ins v10.s[0], w1                                    
ins v11.s[1], w2                                    

ins v15.s[1], v11.s[1]                                  
ins v15.s[0], v10.s[0] 

下面是使用P/T ...,显示的gdb结果$ v10.ss,$ v11.ss,$ v15.ss在基数2中,最后的p/t $ v15.ds显示64位的位模式。我不确定这是否有帮助,但也许它会启动泵。

67    mov w1, 3 
(gdb) si 
$82 = {0, 0, 0, 0} 
$83 = {0, 0, 0, 0} 
$84 = {0, 0, 0, 0} 
68    mov w2, 2 
(gdb) 
$85 = {0, 0, 0, 0} 
$86 = {0, 0, 0, 0} 
$87 = {0, 0, 0, 0} 
70    ins v10.s[0], w1 
(gdb) 
$88 = {11, 0, 0, 0} 
$89 = {0, 0, 0, 0} 
$90 = {0, 0, 0, 0} 
71    ins v11.s[1], w2 
(gdb) 
$91 = {11, 0, 0, 0} 
$92 = {0, 10, 0, 0} 
$93 = {0, 0, 0, 0} 
73    ins v15.s[1], v11.s[1] 
(gdb) 
$94 = {11, 0, 0, 0} 
$95 = {0, 10, 0, 0} 
$96 = {0, 10, 0, 0} 
74    ins v15.s[0], v10.s[0] 
(gdb) 
$97 = {11, 0, 0, 0} 
$98 = {0, 10, 0, 0} 
$99 = {11, 10, 0, 0} 
.exit0() at stuff.s:78 
78  _exit 
(gdb) p/t $v15.d.s 
$100 = {1000000000000000000000000000000011, 0}