#### Archived

This topic is now archived and is closed to further replies.

# MMXperts only (assembly)

This topic is 6219 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

## Recommended Posts

I'm trying to improve my MMX software renderer, but I've hit a snag: I can't figure out the pandn instruction. I'm trying to find the minimum of two registers, each containing packed unsigned words. To remind you, pcmpgtw compares the destination with the source. If the destination is greater than the source, all bits in the destination are set to 1. Otherwise, they are all set to zero. Here's the pseudocode of my algorithm: ; mm0 = Value1 ; mm1 = Value2 ; Now find min(mm0,mm1): mov mm2, mm0        ; mm2 = mm0 pcmpgtw mm2, mm1    ; mm2 = mm0 > mm1 ? FFFF : 0000 pandn mm0, mm2      ; mm0 = mm0 > mm1 ? 0000 : mm0; pand mm1, mm2       ; mm1 = mm0 > mm1 ? mm1 : 0000; por mm0, mm1        ; mm0 = mm0 > mm1 ? mm1 : mm0; See what I'm trying to do? BTW you can use paddw instead of por, it makes no difference in this case. I assumed "pandn" is like saying "if dest and not src" so if the src is all 1s, then dest should be zero; if src is all 0s, dest should be dest. Right? But pandn doesn't seem to do that. I can't figure out what it does, or more importantly how to write a min function. It must use MMX and be fast, because it's being used within my MMX code. ~CGameProgrammer( );

Edited by - CGameProgrammer on February 14, 2001 7:10:29 PM

##### Share on other sites
Here's what intel's pII manual says about the pandn instruction:

"Performs a bitwise logical NOT on the quadword destination operand (first operand). Then, the instruction performs a bitwise logical AND operation on the inverted destination operand and the quadword source operand (second operand).... The result is stored in the destination operand location."

I would write that in C as follows: dst = (~dst) & src.

So, here's what I would do to find the min for 4 pairs of signed words stored in registers mm0 and mm1.
   movq    mm2, mm1;   pcmpgtw mm2, mm0; // mask on where mm1 > mm0, off otherwise   pand    mm0, mm2; // get mm0 where mm1 > mm0   pandn   mm2, mm1; // get mm1 where !(mm1 > mm0) or mm1 <= mm0   por     mm0, mm2; // now combine the two results

I store the result in the mm0 register, since it appears that was what you were trying to do. I know you said you were trying to find the mins for packed *unsigned* words, but I believe, unhappily, that pcmpgtw makes a *signed* comparison. I'm not sure what to do about that .

I haven't done very much actual mmx programming, but I have been browsing through the manuals for the past few days. So, please correct me if I'm wrong or if there is a better way.

-- Bevan

Edited by - bevankj on February 14, 2001 9:02:32 PM

##### Share on other sites
Thanks, it didn''t occur to me to look up the Intel docs on that command, for some reason. Really, all I had to do is reverse the parameters that I passed -- I assumed the instruction performed the not on the source, but it does it on the dest. Thanks!

~CGameProgrammer( );

##### Share on other sites
Well, it worked. But I have another question that fits under this topic, and it's harder to research. How do you use assembly commands in VC++'s inline assembler that it doesn't know? Is there a way to insert opcodes or do you need to tinker with the .exe using a hex editor? I ask this because I want to code a Pentium 3 version of the code, PIIIs have an mmx command pminsw which does exactly what I want in just one command.

 Oh, and I don't mind that it's signed, since I don't use the entire word. The upper bit will always be zero.

~CGameProgrammer( );

Edited by - CGameProgrammer on February 14, 2001 10:16:33 PM

##### Share on other sites
Maybe if you install the processor pack (microsoft.com) for MSVC you can use it? It installs MMX, SSE, and 3DNow! assembly commands, maybe it has yours in it too? Or have you already done that?

http://www.gdarchive.net/druidgames/

##### Share on other sites
No, I haven''t done that, but I will. Thanks. It seems they only have a pack for VC++ 6.0, I guess I have no choice but to buy it... anyway I lost the VC++ 5.0 CD, so whatever.

~CGameProgrammer( );