У меня есть два фрагмента кода с переменным битовым сдвигом, которые я хочу векторизовать SSE некоторыми способами:
1) a = 1 << b (where b = 0..7 exactly), i.e. 0/1/2/3/4/5/6/7 -> 1/2/4/8/16/32/64/128/256
2) a = 1 << (8 * b) (where b = 0..7 exactly), i.e. 0/1/2/3/4/5/6/7 -> 1/0x100/0x10000/etc
Хорошо, я знаю, что AMD XOP VPSHLQ сделает это, как и VPSHLQ AVX2. Но моя проблема здесь заключается в том, может ли это быть достигнуто на «нормальном» (т. Е. До SSE4.2) SSE.
Итак, есть ли какая-нибудь прикольная последовательность кода операции семейства SSE, которая достигнет эффекта любого из этихфрагменты кода? Это нужно только для получения перечисленных выходных значений для конкретных входных значений (0-7).
Обновление: вот моя попытка 1), основанная на предложении Питера Кордеса об использовании показателя с плавающей запятой для создания простой переменнойсдвиг битов:
#include <stdint.h>
typedef union
{
int32_t i;
float f;
} uSpec;
void do_pow2(uint64_t *in_array, uint64_t *out_array, int num_loops)
{
uSpec u;
for (int i=0; i<num_loops; i++)
{
int32_t x = *(int32_t *)&in_array[i];
u.i = (127 + x) << 23;
int32_t r = (int32_t) u.f;
out_array[i] = r;
}
}