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

Assembly 如何在保持一个值不变的情况下翻转SSE中的范围?,assembly,x86,vectorization,x86-64,sse,Assembly,X86,Vectorization,X86 64,Sse,我有一个向量,包含8个范围为0的无符号8位数字。。12英寸xmm0。我想对向量中的每个元素e执行以下转换: if (e != 12) e = 11 - e; 也就是说,数字0,1,…,11更改为11,10,…,0,而12保持不变。其他值不会出现,我不关心它们会发生什么 如何使用SSE4指令集有效地执行此操作?对于SSE2(您没有问,但是…),我建议如下,重用比较中的掩码进行有趣的求反: e = (e ^ mask) + (12 & mask) 对于一个真实的面具,它会变成~e

我有一个向量,包含8个范围为0的无符号8位数字。。12英寸
xmm0
。我想对向量中的每个元素
e
执行以下转换:

if (e != 12)
    e = 11 - e;
也就是说,数字0,1,…,11更改为11,10,…,0,而12保持不变。其他值不会出现,我不关心它们会发生什么

如何使用SSE4指令集有效地执行此操作?

对于SSE2(您没有问,但是…),我建议如下,重用比较中的掩码进行有趣的求反:

e = (e ^ mask) + (12 & mask)
对于一个真实的面具,它会变成
~e+12=-e+-1+12=11-e
,而对于一个虚假的面具,它显然是身份

或者在载体材料中,(未测试)

对于SSSE3和更高版本,您可以使用我们的老朋友
pshufb
,因为使用此范围的值可以进行16个条目的表格查找:(未测试)

表的外观(未测试)


哦,哇,我完全忘了pshufb!对于第一个,我想做(((12-v)+243)-243),其中加法是饱和加法,这会将结果移动到正确的位置。但是有了所有的掩码加载,您的方法可能会更快。
movdqa xmm1, [vec12]
pcmpgtb xmm1, xmm0
pxor xmm0, xmm1
pand xmm1, [vec12]
paddb xmm0, xmm1
movdqa xmm1, [table]
pshufb xmm1, xmm0
.db 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0, 12, "yolo"