【问题标题】:Bitwise Extract Vector in ASIMD instruction (ARM platform)ASIMD 指令中的按位提取向量(ARM 平台)
【发布时间】:2016-06-14 11:46:39
【问题描述】:

我想在 ASIMD 汇编指令中实现按位提取向量指令。让我这么说吧,在 ARMv7 NEON 指令中,假设我在 q15q11 中有一些值,我有:

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

正如您在此处看到的,我从d22 的底端提取4 字节元素,从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 中构造相同的逻辑。

【问题讨论】:

    标签: assembly arm arm64


    【解决方案1】:

    您首先应该注意,在 Aarch64 中,寄存器的组织方式不同。在 Aarch32 中,Q15 是 {D31, D30}。在Aarch64中,D31是Q31的底层,说到元素,可以说是V31。

    在这种情况下,Aarch64 中没有直接等效项,因为您无法直接访问 Quad 寄存器的前 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

    【讨论】:

    • 我不确定我是否对你的回答很清楚。 "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"
    【解决方案2】:

    不确定您是否找到了答案,或者这是否是您的预期目标:

    正如@Dric512 所指出的,我认为您可以使用 SIMD 数据移动指令 INS。

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

    然后我们将各自的元素插入向量 15 的两个 32 位通道中;从而导致所有位进入向量 15 的 64 位通道。

     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... 以基数 2 显示 $v10.ss、$v11.ss、$v15.ss 的 gdb 结果,然后最终 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}
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-01-31
      • 2010-09-10
      • 1970-01-01
      • 2021-06-05
      • 2013-12-01
      相关资源
      最近更新 更多