Ассамблея маска логика вопрос - PullRequest
1 голос
/ 26 января 2010

Это очень просто, но я пока не смог понять.

Этот вопрос касается сборки 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  

Мне нужно знать, чтобы заполнить нули MM0 02. Я полагаю, что на шаге 2 мне нужно инвертировать регистр MM0, меняя FF на 00, а 00 на FF, а затем делать a и MM1 и, наконец, объединить два.

Если бы я смог получить:

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?

Любой ответ с благодарностью. Спасибо.

Ответы [ 2 ]

1 голос
/ 24 февраля 2010

Вы также можете сгенерировать маску с помощью 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.
1 голос
/ 26 января 2010

Итак, у вас есть 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;
...