非 sse2 arch 上 128 位值的按位运算
Bitwise operations on 128-bit values on a non-sse2 arch
我正在用 C 编写针对嵌入式平台的例程。
在例程中,我需要对 128 位值执行按位 XOR
和 SHIFT RIGHT
操作。
目标 arch 没有 SSE2,因此不支持本机 128 位操作。
我遇到了 this 模拟软件中的 SHIFT
操作的答案。
我的问题是,有没有更好的方法来做到这一点,我的意思是用更好的数据结构来表示 128 位值和模拟 SHIFT 和 XOR 操作的最佳方法而不是使用递归(如在答案中所做的那样) link)。我希望尽量减少对有限堆栈内存的使用。
可以使用结构体存储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
}
这将避免上述解决方案的递归并提供更好的运行时间。但是代码量会增加,需要仔细测试代码。
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;
}
我正在用 C 编写针对嵌入式平台的例程。
在例程中,我需要对 128 位值执行按位 XOR
和 SHIFT RIGHT
操作。
目标 arch 没有 SSE2,因此不支持本机 128 位操作。
我遇到了 this 模拟软件中的 SHIFT
操作的答案。
我的问题是,有没有更好的方法来做到这一点,我的意思是用更好的数据结构来表示 128 位值和模拟 SHIFT 和 XOR 操作的最佳方法而不是使用递归(如在答案中所做的那样) link)。我希望尽量减少对有限堆栈内存的使用。
可以使用结构体存储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
}
这将避免上述解决方案的递归并提供更好的运行时间。但是代码量会增加,需要仔细测试代码。
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;
}