2010-01-26 14 views
1

C'est très simple, mais je n'ai pas encore réussi à le comprendre.Question de logique de masque d'assemblage

Cette question concerne un assemblage mmx, mais c'est de la pure logique.

Imaginez le scénario suivant:

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 

Ce que je veux est de savoir remplir les zéros de MM0 avec 02. Je suppose que je devrais inverser MM0 vous inscrire à l'étape 2, en changeant les FF de 00 S et les 00 ' à FF puis faire un et à MM1 et enfin un ou à fusionner les deux.

Si j'ai pu obtenir:

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! 

En résumé, comment puis-je obtenir ce registre Mm3 00 00 FF FF 00 FF 00? Comment puis-je inverser les bits, prouvant que je n'ai que des instructions AND, OR, XOR et NAND disponibles dans les registres MMX?

Toute réponse est grandement appréciée. Merci.

+2

Alors ... quelle est la question? On dirait que vous avez répondu vous-même. –

+0

Dans ma question on peut lire: "Si j'étais capable d'avoir", ce qui signifie que je n'ai toujours pas et je vous demande comment. – nunos

Répondre

1

Vous pouvez également générer le masque en utilisant pcmpgtw et échanger l'ordre des arguments. De cette façon, vous pouvez enregistrer un registre:

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 

Vous pourriez avoir à faire une copie de l'argument MM1 car il se détruit lors de la génération de masque, mais cela est souvent plus rapide que le chargement/générer une constante de 64 bits.

Une alternative serait d'utiliser 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

Vous avez donc un mask = 0xFFFF0000FFFF0000; alors:

all_ones = 0xFFFFFFFFFFFFFFFF; 

inverted_mask = mask XOR all_ones; 

fusion M0 et M1 est:

M0 = M0 AND mask; 
M1 = M1 AND inverted_mask; 
M0 = M0 OR M1; 

cette édite M0 et M1 en place de sorte que leurs valeurs sont détruites. Si vous souhaitez conserver M1 alors vous devez stocker le résultat intermédiaire dans une variable temporaire/registre/mémoire:

M0 = M0 AND mask; 
TEMP = M1 AND inverted_mask; 
M0 = M0 OR TEMP;