Как эмулировать * действительно простые * переменные битовые сдвиги с SSE? - PullRequest
0 голосов
/ 12 октября 2019

У меня есть два фрагмента кода с переменным битовым сдвигом, которые я хочу векторизовать 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;
    }
}
...