我是AArch64 Advanced SIMD(NEON)的新手,我想将AArch32代码移植到AArch64。在AArch32中,如果我想访问寄存器的较低或较高的一半,我只使用Dn
而不是Qn
。例如,如果我想访问较低的64位Q12
,我只需提到D24
。但是,我无法弄清楚如何在AArch64中访问Vn
寄存器的一半。
我想访问Vn
寄存器的较高一半。所以,如果我写Vn.2S
,我认为它给了我寄存器的下半部分。那是对的吗?如果是的话,我怎样才能访问更高的一半呢?
答案 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)));
针对不均匀索引(因为这些重叠寄存器)不是一个好习惯。我没有尝试查看这样做的结果,但是这样做可能会将数据移至临时寄存器通道周围以完成操作。当向量是结构的成员时,以这种方式使用指针也有效。