ARM предоставляет встроенные функции для работы с высокой частью векторных типов c, но я не вижу эквивалента для работы с нижней частью.
Рассмотрим простой пример для вычисления остатка двух буферов с 16 элементы 8 бит (8 бит - 8 бит = результат в 16 бит).
uint8x16_t src0, src1;
int16x8_t dst0, dst1;
src0 = vld1q_u8((uint8_t const *)src0_);
src1 = vld1q_u8((uint8_t const *)src1_);
dst0 = vreinterpretq_s16_u16(vsubl_u8(vget_low_u8(src0), vget_low_u8(src1)));
dst1 = vreinterpretq_s16_u16(vsubl_high_u8(src0, src1));
Для работы с старшей частью регистров у нас есть vsubl_high_u8
. Но для работы на низком уровне сначала необходимо выполнить извлечение низкого из входного регистра (который с некоторой задержкой), а затем использовать подинструкцию.
Asm обеспечивает доступ к низкому и высокому уровням отдельно через отдельные имена регистров (для 32 -bit ARM NEON), так что это только внутренний вопрос.
(Примечание редактора: AArch64 действительно имеет отдельные инструкции для низкого / высокого уровня asm, потому что каждые s
(32-битные) и d
(64) -бит) регистр является нижней частью отдельного q
(128-битного) векторного регистра.)