如何在保持一个值不变的情况下翻转SSE中的范围?

时间:2016-07-31 12:59:51

标签: assembly x86 vectorization x86-64 sse

我在xmm0中的0 .. 12范围内有8个无符号8位数的向量。我想对向量中的每个元素e执行以下转换:

if (e != 12)
    e = 11 - e;

即,数字0,1,...,11变为11,10,...,0而12保持不变。其他价值观不会发生,我不关心他们会发生什么。

如何使用SSE4指令集有效地实现此操作?

1 个答案:

答案 0 :(得分:6)

对于SSE2(你没有问,但是......),我提出以下建议,重新使用比较中的掩码来做有趣的否定:

e = (e ^ mask) + (12 & mask)

对于真正的面具变为~e + 12 = -e + -1 + 12 = 11 - e,对于假面具,它显然是身份。

或在矢量中,(未经测试)

movdqa xmm1, [vec12]
pcmpgtb xmm1, xmm0
pxor xmm0, xmm1
pand xmm1, [vec12]
paddb xmm0, xmm1

对于SSSE3及更高版本,您可以使用我们的老朋友pshufb,因为对于这个值范围,它可以是16项表查找:(未测试)

movdqa xmm1, [table]
pshufb xmm1, xmm0

表格看起来像(未经测试)

.db 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0, 12, "yolo"