寻找用于非立即移位值的sse 128位移位操作

内部_mm_slli_si128将在128位寄存器的左侧进行逻辑移位,但仅限于立即移位值,并按字节而不是位移位。

我可以使用像_mm_sll_epi64_mm_sll_epi32这样的内部函数在__m128i寄存器中向左移位一组值,但这些值不带“溢出”位。

对于N位的移位想象我可以做类似的事情:

  • _mm_sll_epi64
  • _mm_srr_epi64 (对于我想要携带的位:将它们移动到低位)
  • 洗牌srr结果
  • 或者这些在一起。

(但可能还必须包括N相对于64的检查)。

有没有更好的办法?

这不是您理想的解决方案,但如果您希望将SSE寄存器旋转或移位8位的倍数,那么PSHUFB指令(和_mm_shuffle_epi8()内在函数)可以提供帮助。 它需要第二个SSE寄存器作为输入; 寄存器中的每个字节都有一个值,用于索引第一个输入寄存器中的字节。

这在一篇关于不寻常的C预处理器用途的博客文章(我的)中是一个副作用。 对于127个不同的移位偏移,对于位移,存在四种不同的SSE2指令的最佳序列。 预处理器使得构造一个相当于129路开关语句的移位function变得合理。 请原谅原始代码; 我不熟悉直接在这里发布代码。 查看博客文章,了解正在发生的事情。

 #include  typedef __m128i XMM; #define xmbshl(x,n) _mm_slli_si128(x,n) // xm <<= 8*n -- BYTE shift left #define xmbshr(x,n) _mm_srli_si128(x,n) // xm >>= 8*n -- BYTE shift right #define xmshl64(x,n) _mm_slli_epi64(x,n) // xm.hi <<= n, xm.lo <<= n #define xmshr64(x,n) _mm_srli_epi64(x,n) // xm.hi >>= n, xm.lo >>= n #define xmand(a,b) _mm_and_si128(a,b) #define xmor(a,b) _mm_or_si128(a,b) #define xmxor(a,b) _mm_xor_si128(a,b) #define xmzero _mm_setzero_si128() XMM xm_shl(XMM x, unsigned nbits) { // These macros generate (1,2,5,6) SSE2 instructions, respectively: #define F1(n) case 8*(n): x = xmbshl(x, n); break; #define F2(n) case n: x = xmshl64(xmbshl(x, (n)>>3), (n)&15); break; #define F5(n) case n: x = xmor(xmshl64(x, n), xmshr64(xmbshl(x, 8), 64-(n))); break; #define F6(n) case n: x = xmor(xmshl64(xmbshl(x, (n)>>3), (n)&15),\ xmshr64(xmbshl(x, 8+((n)>>3)), 64-((n)&155))); break; // These macros expand to 7 or 49 cases each: #define DO_7(f,x) f((x)+1) f((x)+2) f((x)+3) f((x)+4) f((x)+5) f((x)+6) f((x)+7) #define DO_7x7(f,y) DO_7(f,(y)+1*8) DO_7(f,(y)+2*8) DO_7(f,(y)+3*8) DO_7(f,(y)+4*8) \ DO_7(f,(y)+5*8) DO_7(f,(y)+6*8) DO_7(f,(y)+7*8) switch (nbits) { case 0: break; DO_7(F5, 0) // 1..7 DO_7(F1, 0) // 8,16,..56 DO_7(F1, 7) // 64,72,..120 DO_7x7(F6, 0) // 9..15 17..23 ... 57..63 ie [9..63]\[16,24,..,56] DO_7x7(F2,56) // 65..71 73..79 ... 121..127 ie [65..127]\[64,72,..,120] default: x = xmzero; } return x; } 

xm_shr相当于上面但在F [1256]宏中到处交换“shl”和“shr”。 HTH。