如何将值加载到 neon s 寄存器中?

How to load a value into a neon s-register?

我想通过多次操作一次来优化我们的汇编程序算法。这可以通过在 arm 汇编器中使用 neon 模块的向量来完成。

我正在尝试将一个矢量(2x32 位)添加到另一个矢量。 如果我没理解错的话,d0 由 s0 和 s1 组成。 我想将一个值加载到 s0 中,将另一个值加载到 s1 中。 所以我可以将 s0 和 s1 同时添加到 s2 和 s3(d1 的)。

VADD.I32    d1, d0 

但要做到这一点,我首先必须将数据加载到 d1 和 d0 中。 我试过了

VMOV    s0, d5

VMOV    d0[0], d5

但是它们都在编译时抛出错误。

感谢您的帮助!

您可能需要查看目标机器的汇编器、处理器文档。这个粗略的例子在 Scaleway 的 Cortex-A9 Marvell PJ4Bv7 上运行。

movw r0, #0xc0de
movw r1, #0xdead
vmov s0, s1, r0, r1

movw r0, #0xf00d
movw r1, #0xbaad
vmov s2, s3, r0, r1


(gdb) i r a 
d0             1.2096437008836935e-309  (raw 0x0000dead0000c0de)
d1             1.0140805688480121e-309  (raw 0x0000baad0000f00d)

编辑: 您还可以将值加载到内存中,比方说,d0:

array: .byte 3,1,4,1,5,9,2,6,5,3,5,9
...
ldr r0,=array
vldr d0, [r0]

D0 中 8 个无符号字节大小整数的 GDB 结果

(gdb) print $d0.u8
 = {3, 1, 4, 1, 5, 9, 2, 6}

@michidk 由于 Sx 寄存器可能与 Dx 寄存器配对;例如,{S0, S1} = D0。您通常会将 Dm 移动到 Dd 或执行类似 vmov d1, d2 的操作,因为我认为您不能将 Dx 移动到 Sx。

所以让我们分别将一些值放入 s1 和 s1。

movw r1, #0x123
movw r2, #0xabc
vmov s1, r1             // s1 in this case is d0.u32[1]
vmov s2, r2             // s2 in this case is d1.u32[0]

vorr d1, d0             // 

...

GDB 显示原始值确实存在。此外,您会看到 D0 和 D1 的无符号 32 位部分的值是可行的。

(gdb) info register all 
s1             4.07777853e-43   (raw 0x00000123)
s2             3.85076818e-42   (raw 0x00000abc)

(gdb) p/x $d0.u32
 = {0x0, 0x123}

(gdb) p/x $d1.u32
 = {0xabc, 0x0}

通过指令"vorr d1, d0",我们将d0.u32[1]复制到d1.u32[1]即s3;不打扰 d1.u32[0] 即 s2。所以在这个意义上我们将D0的一部分移动到S3。

(gdb) p/x $d1.u32
 = {0xabc, 0x123}

(geb) info register s3
s3             4.07777853e-43   (raw 0x00000123)