【发布时间】:2013-09-16 15:13:26
【问题描述】:
我正在尝试反转 128 位向量 (uint16x8) 的顺序。
例如,如果我有
a b c d e f g h
我想获得
h g f e d c b a
有没有一种简单的方法可以使用 NEON 内在函数来做到这一点? 我尝试使用 VREV,但它不起作用。
【问题讨论】:
-
你是如何尝试
vrev的?
标签: arm neon intrinsics
我正在尝试反转 128 位向量 (uint16x8) 的顺序。
例如,如果我有
a b c d e f g h
我想获得
h g f e d c b a
有没有一种简单的方法可以使用 NEON 内在函数来做到这一点? 我尝试使用 VREV,但它不起作用。
【问题讨论】:
vrev的?
标签: arm neon intrinsics
您想要vrev64.16 指令,但它不会在单个四寄存器的双寄存器之间交换。您需要使用额外的vswp 来实现这一点。
对于内在函数
q = vrev64q_u16(q)
应该在双字内部进行交换,然后您需要在四元寄存器中交换双字。然而,这会变得很麻烦,因为没有直接的 vswp 内在函数迫使你使用类似的东西
q = vcombine_u16(vget_high_u16(q), vget_low_u16(q))
实际上以vswp 指令结束。
请参阅下面的示例。
#include <stdio.h>
#include <stdlib.h>
#include <arm_neon.h>
int main() {
uint16_t s[] = {0x101, 0x102, 0x103, 0x104, 0x105, 0x106, 0x107, 0x108};
uint16_t *t = malloc(sizeof(uint16_t) * 8);
for (int i = 0; i < 8; i++) {
t[i] = 0;
}
uint16x8_t a = vld1q_u16(s);
a = vrev64q_u16(a);
a = vcombine_u16(vget_high_u16(a), vget_low_u16(a));
vst1q_u16(t, a);
for (int i = 0; i < 8; i++) {
printf("0x%3x ", t[i]);
}
printf("\n");
return 0;
}
生成如下所示的程序集
vld1.16 {d16-d17}, [sp:64]
movs r4, #0
vrev64.16 q8, q8
vswp d16, d17
vst1.16 {d16-d17}, [r5]
和输出
$ rev
0x108 0x107 0x106 0x105 0x104 0x103 0x102 0x101
【讨论】: