Assembly vld1.32{d20-d21}和vld1q q10之间的差异?

Assembly vld1.32{d20-d21}和vld1q q10之间的差异?,assembly,arm,intrinsics,neon,armv7,Assembly,Arm,Intrinsics,Neon,Armv7,我在看一些我们测试的ARM开发板的ARM分解。它们是用氖内在vld1q_u32生产的,使用-march=armv7-a-mfloat abi=hard-mfpu=NEON 我们看到一台带有霓虹灯的特定机器(/proc/cpuinfo half thumb fastmult vfp edsp NEON vfpv3 tls vfpv4 idiva idivt vfpd32 lpae evtstrm): 在另一台霓虹灯机器上,我们看到(/proc/cpuinfo:swp半拇指快速多vfp edsp霓虹

我在看一些我们测试的ARM开发板的ARM分解。它们是用氖内在
vld1q_u32
生产的,使用
-march=armv7-a-mfloat abi=hard-mfpu=NEON

我们看到一台带有霓虹灯的特定机器(
/proc/cpuinfo half thumb fastmult vfp edsp NEON vfpv3 tls vfpv4 idiva idivt vfpd32 lpae evtstrm
):

在另一台霓虹灯机器上,我们看到(
/proc/cpuinfo:swp半拇指快速多vfp edsp霓虹灯vfpv3 tls vfpv4 idiva idivt
):

在ARMv8机器上,我们看到(
/proc/cpuinfo:fp asimd evtstrm aes pmull sha1 sha2 crc32
):

我知道2D和1Q只是对同一事物的不同看法。我不清楚的是为什么ARMv7 NEON要执行多寄存器加载而不是1Q加载


我的问题是,
vld1.32{2-D}
vld1q.32 1-Q
之间有什么区别。或者为什么编译器不能在所有情况下生成1-Q加载?

这里的区别在于32位ARM(也称为AArch32)和AArch64

对于32位模式,2D寄存器在一个Q寄存器上出现混叠的事实是正确的,但在64位模式下则不然。在AArch64中,
dX
qX
的前半部分,而不是AArch32中的
q(X/2)
,并且没有
d
寄存器名来寻址
q
寄存器的上半部分

如果在AArch32中汇编指令
vld1.32{q0},[r0]
,它将变成与汇编
vld1.32{d0-d1},[r0]
相同的操作码
f920 0a8f
(在拇指模式下)。因此,基本上是由反汇编程序选择它更喜欢使用哪种形式来显示(尽管可能有反汇编程序的指南,说它应该更喜欢使用D寄存器形式)

在AArch64上,这两种形式是不同的,因为寄存器的别名不相同,因此,如果您要求向Q寄存器加载128位,这就是您得到的结果,并且没有任何歧义

 0: b5f0        push    {r4, r5, r6, r7, lr}
...
20: f964 4a8f   vld1.32 {d20-d21}, [r4]
 0:   e92d 4ff0       stmdb   sp!, {r4, r5, r6, r7, r8, r9, sl, fp, lr}
...
28:   f964 2a8f       vld1.32 {d18-d19}, [r4]
 0:   3dc00021        ldr     q1, [x1]
...
10:   3dc00c22        ldr     q2, [x1,#48]
14:   3dc01023        ldr     q3, [x1,#64]