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

时间:2016-01-23 23:16:43

标签: arm neon arm64

我是AArch64 Advanced SIMD(NEON)的新手,我想将AArch32代码移植到AArch64。在AArch32中,如果我想访问寄存器的较低或较高的一半,我只使用Dn而不是Qn。例如,如果我想访问较低的64位Q12,我只需提到D24。但是,我无法弄清楚如何在AArch64中访问Vn寄存器的一半。 我想访问Vn寄存器的较高一半。所以,如果我写Vn.2S,我认为它给了我寄存器的下半部分。那是对的吗?如果是的话,我怎样才能访问更高的一半呢?

2 个答案:

答案 0 :(得分:0)

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

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

答案 1 :(得分:0)

我已经成功地使用指针选择了Arm Neon向量的上半部或下半部。

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。从本质上讲,这是在告诉编译器以组成四位寄存器的两个双寄存器对为目标。这并不一定意味着在执行此操作时将对内存进行读取或写入。而是看到您想直接将double寄存器作为目标。

这适用于GCC 8,也许也适用于旧版本。 Clang 7给出了“目标向量...”错误消息。我无法使用指针将目标指向双寄存器中的索引,但是由于源或目标一直有效,因此将其用作强制转换为数据类型的常规向量。下面是另一个示例,使用指针字节将向量交换一半。

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

针对不均匀索引(因为这些重叠寄存器)不是一个好习惯。我没有尝试查看这样做的结果,但是这样做可能会将数据移至临时寄存器通道周围以完成操作。当向量是结构的成员时,以这种方式使用指针也有效。