Доступ к половине регистра в расширенной SIMD AArch64
Я новичок в AArch64 Advanced SIMD (NEON) и хочу перенести код AArch32 в AArch64. В AArch32, если я хотел получить доступ к нижней или верхней половине регистра, я просто использовал Dn
вместо Qn
, Например, если я хочу получить доступ к младшей 64-битной Q12
Я просто сослался на D24
, Тем не менее, я не могу понять, как я могу получить доступ к половине Vn
зарегистрироваться в AArch64. Я хотел бы получить доступ к верхней половине Vn
регистр. Итак, если я напишу Vn.2S
Я предполагаю, что это дает мне нижнюю половину регистра. Это верно? Если да, то как я могу получить доступ к верхней половине?
1 ответ
Даже я пытался получить доступ. Согласно руководству, я думаю, что нет никакого способа, чтобы получить доступ к тискам слота. V0 -> d0 -> s0 имеет те же данные.
В то время как в ARM32 у Q0 есть d0 и d1, а далее у d0 есть s0 и s1.
Я успешно использовал указатели для выбора верхней или нижней половины вектора 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
, Это внутренне указывает компилятору нацеливаться на любую из пар двойных регистров, которые составляют четырехугольные регистры. Это не обязательно означает, что при этом будет выполняться чтение или запись в память. Вместо этого он видит, что вы хотите нацелиться на двойной регистр напрямую.
Это работает с GCC 8, возможно, также и с более старыми версиями. Clang 7 выдал сообщение об ошибке "вектор таргетинга...". Я не смог использовать указатель на целевые индексы в двойном регистре, однако, используя его в качестве обычного вектора типа данных, к которому он приведен, либо как источник, либо как место назначения, всегда работал. Ниже приведен еще один пример замены байта на половину вектора с помощью указателя.
*lowerhalf = vreinterpret_u32_u8(vrev32_u8(vreinterpret_u8_u32(*lowerhalf)));
Нецелесообразно ориентироваться на неравные индексы, так как эти регистры перекрываются. Я не пытался увидеть, что это делает, но, скорее всего, он будет перетасовывать данные во временные регистры, чтобы завершить операцию при этом. Использование указателей таким образом также работает, когда векторы являются членами структуры.