Arm 访问AArch64高级SIMD中寄存器的一半

Arm 访问AArch64高级SIMD中寄存器的一半,arm,neon,arm64,Arm,Neon,Arm64,我是AArch64高级SIMD(NEON)的新手,我想将AArch32代码移植到AArch64。在AArch32中,如果我想访问寄存器的下半部分或上半部分,我只需使用Dn而不是Qn。例如,如果我想访问Q12的低64位,我只需参考D24。但是,我不知道如何访问AArch64中Vn寄存器的一半。 我想访问Vn寄存器的上半部分。因此,如果我写Vn.2S,我假设它给出了寄存器的下半部分。对吗?如果是,那么如何访问上半部分呢?即使我尝试了访问。 根据手册,我想没有办法接近槽虎钳。 V0->d0->s0具有

我是AArch64高级SIMD(NEON)的新手,我想将AArch32代码移植到AArch64。在AArch32中,如果我想访问寄存器的下半部分或上半部分,我只需使用
Dn
而不是
Qn
。例如,如果我想访问
Q12
的低64位,我只需参考
D24
。但是,我不知道如何访问AArch64中
Vn
寄存器的一半。 我想访问
Vn
寄存器的上半部分。因此,如果我写
Vn.2S
,我假设它给出了寄存器的下半部分。对吗?如果是,那么如何访问上半部分呢?

即使我尝试了访问。 根据手册,我想没有办法接近槽虎钳。 V0->d0->s0具有相同的数据


而在ARM32中,Q0有d0和d1,而d0有s0和s1。

我已经成功地使用指针来选择手臂向量的上半部分或下半部分

uint32x4_t vector = { 1, 2, 3, 4 };
uint32x2_t *upperhalf = (uint32x2_t *) &vector[2];
uint32x2_t *lowerhalf = (uint32x2_t *) &vector[0];

*lowerhalf = *upperhalf;
printf("%u", vector[0]);
打印出
3
。这本质上是告诉编译器以构成四寄存器的双寄存器对为目标。这并不一定意味着在执行此操作时它将读取或写入内存。相反,它看到您希望直接将双寄存器作为目标

这适用于GCC 8,可能也适用于较旧的版本。Clang7给出了一条“目标向量…”错误消息。我无法在双寄存器中使用指向目标索引的指针,但是将其用作数据类型的常规向量,因为无论是源还是目标都一直有效。下面是另一个示例,使用指针对向量的一半进行字节交换

*lowerhalf = vreinterpret_u32_u8(vrev32_u8(vreinterpret_u8_u32(*lowerhalf)));

将不均匀索引作为目标不是一种好的做法,因为这些寄存器重叠。我还没有试着去看它做了什么,但这样做的时候,它很可能会把数据拖到临时注册通道来完成一个操作。当向量是结构的成员时,以这种方式使用指针也有效。

当指令影响向量寄存器128位中的64位时,使用较低的64位。以“2”结尾的指令的第二个版本(例如PMULL2)会影响向量寄存器的上64位。@BitBank假设我想将128位向量寄存器的上64位与另一个128位向量寄存器相乘。我的意思是我有一个64x128的乘法运算。我该如何实现这一点
PMULL2
影响向量的上64位。我不相信有128位乘法,但如果您想同时访问下64位和上64位,我相信您需要使用寄存器索引符号(例如v5.s[2])将数据移动到另一个寄存器中。@BitBank是的,您是对的!128位乘法不存在。我的错,谢谢你的评论。我正在寻找你提到的类似
vn.s[2]
的东西。