Побитовые операции над 128-битными значениями в дуге, отличной от sse2 - PullRequest
0 голосов
/ 07 июня 2019

Я пишу подпрограмму на C, предназначенную для встроенной платформы.В процедуре мне нужно выполнить побитовые операции XOR и SHIFT RIGHT над 128-битными значениями.Целевая арка не имеет SSE2, поэтому не поддерживаются собственные 128-битные операции.Я наткнулся на этот ответ, который имитирует SHIFT операции в программном обеспечении.Мой вопрос заключается в том, существуют ли лучшие способы сделать это, я имею в виду лучшую структуру данных для представления 128-битных значений и оптимальный способ имитации операций SHIFT и XOR, чем при использовании рекурсии (как это сделано в ответе по ссылке).Я хочу минимизировать использование ограниченной памяти стека.

Ответы [ 2 ]

0 голосов
/ 07 июня 2019
uint32_t *shiftL(uint32_t *val, const size_t size, const size_t nbits)  // <= 32
{
    uint32_t mask = (1 << nbits) - 1;

    mask <<= 32 - nbits;

    for(size_t cword = size; cword - 1 ; cword --)
    {
        uint32_t temp = (val[cword - 2] & mask) >> nbits
        val[cword - 1] <<= nbits;
        val |= temp;
    }
    val[0] <<= nbits;
    return val;
}
0 голосов
/ 07 июня 2019

Вы можете использовать структуру для хранения 128-битных данных следующим образом

typedef struct
{
    uint32_t a;
    uint32_t b;
    uint32_t c;
    uint32_t d;
} Type_128bit;

Затем вы можете написать функцию сдвига влево следующим образом

int leftshift(Type_128bit in, Type_128bit out, int value)
{
    int val;
    if (value >= 128)
    {
        return (-1); // error condition
    }
    else if (value < 32)
    {
        out->a = (in->a << value) | (in->b >> value);
        out->b = (in->b << value) | (in->c >> value);
        out->c = (in->c << value) | (in->d >> value);
        out->d = in->d << value;
    }
    else if (value < 64)
    {
        val = value - 32;
        out->a = (in->b << val) | (in->c >> val);
        out->b = (in->c << val) | (in->d >> val);
        out->c = (in->d << val);
        out->d = 0x00;
    }
    else if (value < 96)
    {
        val = value - 64;
        out->a = (in->c << val) | (in->d >> val);
        out->b = (in->d << val);
        out->c = 0x00;
        out->d = 0x00;
    }
    else // value < 128
    {
        val = value - 96;
        out->a = (in->d << val);
        out->b = 0x00;
        out->c = 0x00;
        out->d = 0x00;
    }
    return (0); //success
}

Это позволит избежать рекурсииупомянутое решение и даст лучшее время выполнения.Но размер кода увеличится, и вам необходимо тщательно протестировать код.

...