Assembly vld1.32{d20-d21}和vld1q q10之间的差异?
我在看一些我们测试的ARM开发板的ARM分解。它们是用氖内在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霓虹
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]