仅使用SSE3替换_mm_cvtepi16_epi32

时间:2016-02-25 14:18:54

标签: x86 sse intrinsics

_mm_cvtepi16_epi32pmovsxwd)需要SSE4.1

我们如何仅用SSE3或SSE2签署扩展向量元素?

SSSE3答案可能也很有趣。

1 个答案:

答案 0 :(得分:3)

使用解压缩复制每个16位元素(从低半部分),然后使用算术右移在每个32b元素的上半部分留下符号位的副本。

__m128i v16 = ...;
v32 = _mm_unpacklo_epi16(v16, v16);  // [ a a b b c c d d ]
v32 = _mm_srai_epi32(v32, 16);

这只是SSE2。这是两个快速说明,所以我不认为从SSE3或SSSE3可以获得任何东西,并且无法想到任何事情。唯一比这更好的是非破坏性的方法(如果我们仍然需要它,编译器就不必复制v16。)

如果您已经可以在一条指令中执行此操作,则可能未引入pmovsxwd。 (尽管它可能与其他pmovsx形式保持一致。pmovsx真正发光的地方是从字节到双字,或从字节到qword。同样,它的加载形式很好,甚至虽然内在函数使得它很难用作负载。)

对于其他元素大小,有psraw,因此8-> 16也有效,但没有psraq(64位元素只有逻辑左/右移位)。 pmovsxdq更难模仿。 pblendw也是SSE4.1。我想可能用零解包,然后算术右移。然后你可以用另一种方式用零解压缩的向量进行OR。

这样做的好处是能够使用_mm_unpackhi获取上半部分,pmovsz / pmovzx很遗憾不会这样做。