这很简单,但我还没弄清楚。
这个问题是关于程序集mmx,但它是纯粹的逻辑。
想象一下以下场景:
MM0: 04 03 02 01 04 03 02 01 <-- input
MM1: 02 02 02 02 02 02 02 02
MM2: 04 03 02 01 04 03 02 01 <-- copy of input
after pcmpgtw MM0, MM1
MM0: FF FF 00 00 FF FF 00 00 <-- words where MM0 is greater than MM1 (comparing words)
MM1: 02 02 02 02 02 02 02 02
MM2: 04 03 02 01 04 03 02 01
after pand MM0, MM2
MM0: 04 03 00 00 04 03 00 00 <-- almost there...
MM1: 02 02 02 02 02 02 02 02
MM2: 04 03 02 01 04 03 02 01
我想要的是知道用02填充MM0的零。我想我必须在步骤2中反转MM0寄存器,将FF改为00,将00改为FF,然后执行a到MM1,最后是a或者将这两者合并。
如果我能得到:
MM3: 00 00 FF FF 00 00 FF FF
then, pand MM2, MM3
MM1: 04 03 00 00 04 03 00 00
MM2: 00 00 02 02 00 00 02 02
finally por MM0, MM1 would give me the desired outcome:
MM0: 04 03 02 02 04 03 02 02 <-- Aha!
总结一下,如何将MM3寄存器设为00 00 FF FF 00 00 FF?如何反转这些位,证明我只在MMX寄存器中提供AND,OR,XOR和NAND指令?
非常感谢任何答案。感谢。
答案 0 :(得分:1)
所以你有mask = 0xFFFF0000FFFF0000;
然后:
all_ones = 0xFFFFFFFFFFFFFFFF;
inverted_mask = mask XOR all_ones;
合并M0和M1是:
M0 = M0 AND mask;
M1 = M1 AND inverted_mask;
M0 = M0 OR M1;
这会编辑M0和M1,因此它们的值会被破坏。如果要保留M1,则需要将中间结果存储到临时变量/寄存器/存储器中:
M0 = M0 AND mask;
TEMP = M1 AND inverted_mask;
M0 = M0 OR TEMP;
答案 1 :(得分:1)
您还可以使用pcmpgtw生成掩码并交换参数的顺序。这样你就可以保存一个寄存器:
MM0: 04 03 02 01 04 03 02 01 <-- input
MM1: 02 02 02 02 02 02 02 02
MM2: 04 03 02 01 04 03 02 01 <-- copy of input
pcmpgtw MM0, MM1 ; MM0 = FF FF 00 00 FF FF 00 00
pcmpgtw MM1, MM2 ; MM1 = 00 00 FF FF 00 00 FF FF
您可能必须复制MM1参数,因为它会在掩码生成期间被破坏,但这通常比加载/生成64位常量更快。
另一种方法是使用PNAND:
pcmpgtw MM0, MM1 ; MM0 = FF FF 00 00 FF FF 00 00
pand MM2, MM0 ; leave bytes with FF intact
pnand MM1, MM0 ; leave bytes with 00 intact
por MM1, MM2 ; combine the results.