Я пытаюсь изменить порядок 128-битного вектора (uint16x8).
Например, если у меня есть
a b c d e f g h
Я бы хотел получить
h g f e d c b a
Есть ли простой способ сделать это с помощью встроенных функций NEON? Я пробовал использовать VREV, но он не работает.
1 ответ
Вам нужна инструкция 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
Похожие вопросы
Новые вопросы
arm
Этот тег используется для вопросов, связанных с ARM (Advanced Riss Machine) семейством компьютеров; Это машины или электроника, работающие на процессорных процессорах ARM или системы с использованием ядра руки. Для вопросов, связанных с Azure, используйте [Azure-Resource-Manager].
vrev
?