Introduction
MMX was the first x86 SIMD extension: one instruction works on several small integers at once. It came with Intel’s Pentium MMX in January 1997, and AMD’s K6 the same year. Each instruction works on a 64-bit value seen as eight bytes, four words (16 bits), two doublewords (32 bits) or one quadword.
MMX added eight 64-bit registers, mm0 to mm7, but no new state: each one is the low 64 bits (the significand) of an x87 register, R0 to R7. So an operating system that saves the x87 state saves the MMX state too. The cost is that the two cannot be used at the same time:
- an MMX instruction sets the x87 stack top to 0 and marks every x87 register valid in the tag word; one that writes an MMX register also sets bits 79:64 of the x87 register to all ones;
emmsmarks every x87 register empty again. A program runs it at the end of its MMX code, before any x87 code.
A program checks for MMX with CPUID leaf 1: EDX bit 23.
Later sets added more instructions on MMX registers: SSE
(pshufw,
pavgb, pminub …), SSE2 (paddq,
psubq, pmuludq), SSSE3 and AMD’s
3DNow!. SSE2 also gave each instruction below
a 128-bit form on the XMM registers, with a 66 prefix; each row links to it.
The instructions
In the forms, mm is the ModRM.reg operand and mm/m64 the
ModRM.r/m operand. NP means that no 66, F2 or F3 prefix may be present:
with 66 the same opcode is the SSE2 instruction on XMM registers.
Moves and state
| Instruction | Forms | Encoding | What it does | Set |
|---|---|---|---|---|
movd | mm, r/m32r/m32, mm | NP 0F 6E /rNP 0F 7E /r | Copies a doubleword between a general register or memory and the low half of an MMX register; a load zeroes bits 63:32. SSE2 form on XMM registers: movd. | MMX (Intel Pentium MMX, 1997) |
movq | mm, mm/m64mm/m64, mmmm, r/m64r/m64, mm | NP 0F 6F /rNP 0F 7F /rNP REX.W 0F 6E /rNP REX.W 0F 7E /r | Copies a quadword. The last two forms, with a 64-bit general register, exist only in 64-bit mode. SSE2 forms: movq. | MMX (Intel Pentium MMX, 1997) |
emms | – | NP 0F 77 | Empties the MMX state: sets the x87 tag word to FFFFh, all registers empty. With a VEX prefix the same opcode is vzeroupper or vzeroall. | MMX (Intel Pentium MMX, 1997) |
Addition and subtraction
Plain forms wrap around; the s forms saturate to the signed range and
the us forms to the unsigned range.
| Instruction | Forms | Encoding | What it does | Set |
|---|---|---|---|---|
paddb | mm, mm/m64 | NP 0F FC /r | Adds eight pairs of bytes, wrapping. SSE2 form: paddb. | MMX (Intel Pentium MMX, 1997) |
paddw | mm, mm/m64 | NP 0F FD /r | Adds four pairs of words, wrapping. SSE2 form: paddw. | MMX (Intel Pentium MMX, 1997) |
paddd | mm, mm/m64 | NP 0F FE /r | Adds two pairs of doublewords, wrapping. SSE2 form: paddd. | MMX (Intel Pentium MMX, 1997) |
paddsb | mm, mm/m64 | NP 0F EC /r | Adds signed bytes with signed saturation (−128 to 127). SSE2 form: paddsb. | MMX (Intel Pentium MMX, 1997) |
paddsw | mm, mm/m64 | NP 0F ED /r | Adds signed words with signed saturation. SSE2 form: paddsw. | MMX (Intel Pentium MMX, 1997) |
paddusb | mm, mm/m64 | NP 0F DC /r | Adds unsigned bytes with unsigned saturation (0 to 255). SSE2 form: paddusb. | MMX (Intel Pentium MMX, 1997) |
paddusw | mm, mm/m64 | NP 0F DD /r | Adds unsigned words with unsigned saturation. SSE2 form: paddusw. | MMX (Intel Pentium MMX, 1997) |
psubb | mm, mm/m64 | NP 0F F8 /r | Subtracts the source bytes from the destination bytes, wrapping. SSE2 form: psubb. | MMX (Intel Pentium MMX, 1997) |
psubw | mm, mm/m64 | NP 0F F9 /r | Subtracts words, wrapping. SSE2 form: psubw. | MMX (Intel Pentium MMX, 1997) |
psubd | mm, mm/m64 | NP 0F FA /r | Subtracts doublewords, wrapping. SSE2 form: psubd. | MMX (Intel Pentium MMX, 1997) |
psubsb | mm, mm/m64 | NP 0F E8 /r | Subtracts signed bytes with signed saturation. SSE2 form: psubsb. | MMX (Intel Pentium MMX, 1997) |
psubsw | mm, mm/m64 | NP 0F E9 /r | Subtracts signed words with signed saturation. SSE2 form: psubsw. | MMX (Intel Pentium MMX, 1997) |
psubusb | mm, mm/m64 | NP 0F D8 /r | Subtracts unsigned bytes with unsigned saturation: a negative result becomes 0. SSE2 form: psubusb. | MMX (Intel Pentium MMX, 1997) |
psubusw | mm, mm/m64 | NP 0F D9 /r | Subtracts unsigned words with unsigned saturation. SSE2 form: psubusw. | MMX (Intel Pentium MMX, 1997) |
Multiplication
| Instruction | Forms | Encoding | What it does | Set |
|---|---|---|---|---|
pmullw | mm, mm/m64 | NP 0F D5 /r | Multiplies four pairs of signed words and keeps the low 16 bits of each product. SSE2 form: pmullw. | MMX (Intel Pentium MMX, 1997) |
pmulhw | mm, mm/m64 | NP 0F E5 /r | Multiplies four pairs of signed words and keeps the high 16 bits of each product. SSE2 form: pmulhw. | MMX (Intel Pentium MMX, 1997) |
pmaddwd | mm, mm/m64 | NP 0F F5 /r | Multiplies four pairs of signed words, and adds the 32-bit products in pairs into two doublewords. SSE2 form: pmaddwd. | MMX (Intel Pentium MMX, 1997) |
Comparison
Each element of the result is all ones where the comparison is true and zero where
it is false. The gt forms compare signed integers.
| Instruction | Forms | Encoding | What it does | Set |
|---|---|---|---|---|
pcmpeqb | mm, mm/m64 | NP 0F 74 /r | Compares bytes for equality. SSE2 form: pcmpeqb. | MMX (Intel Pentium MMX, 1997) |
pcmpeqw | mm, mm/m64 | NP 0F 75 /r | Compares words for equality. SSE2 form: pcmpeqw. | MMX (Intel Pentium MMX, 1997) |
pcmpeqd | mm, mm/m64 | NP 0F 76 /r | Compares doublewords for equality. SSE2 form: pcmpeqd. | MMX (Intel Pentium MMX, 1997) |
pcmpgtb | mm, mm/m64 | NP 0F 64 /r | Destination byte > source byte, signed. SSE2 form: pcmpgtb. | MMX (Intel Pentium MMX, 1997) |
pcmpgtw | mm, mm/m64 | NP 0F 65 /r | Destination word > source word, signed. SSE2 form: pcmpgtw. | MMX (Intel Pentium MMX, 1997) |
pcmpgtd | mm, mm/m64 | NP 0F 66 /r | Destination doubleword > source doubleword, signed. SSE2 form: pcmpgtd. | MMX (Intel Pentium MMX, 1997) |
Logic
| Instruction | Forms | Encoding | What it does | Set |
|---|---|---|---|---|
pand | mm, mm/m64 | NP 0F DB /r | Bitwise AND of 64 bits. SSE2 form: pand. | MMX (Intel Pentium MMX, 1997) |
pandn | mm, mm/m64 | NP 0F DF /r | Inverts the destination, then ANDs it with the source. SSE2 form: pandn. | MMX (Intel Pentium MMX, 1997) |
por | mm, mm/m64 | NP 0F EB /r | Bitwise OR. SSE2 form: por. | MMX (Intel Pentium MMX, 1997) |
pxor | mm, mm/m64 | NP 0F EF /r | Bitwise exclusive OR; pxor mm0, mm0 is the usual way to zero a register. SSE2 form: pxor. | MMX (Intel Pentium MMX, 1997) |
Shifts
Each shift takes its count from an MMX register or memory (all 64 bits of it), or from an immediate byte. A count larger than the element width gives zero for the logical shifts, and fills each element with its sign bit for the arithmetic ones.
| Instruction | Forms | Encoding | What it does | Set |
|---|---|---|---|---|
psllw | mm, mm/m64mm, imm8 | NP 0F F1 /rNP 0F 71 /6 ib | Shifts each word left, filling with zeros. SSE2 form: psllw. | MMX (Intel Pentium MMX, 1997) |
pslld | mm, mm/m64mm, imm8 | NP 0F F2 /rNP 0F 72 /6 ib | Shifts each doubleword left. SSE2 form: pslld. | MMX (Intel Pentium MMX, 1997) |
psllq | mm, mm/m64mm, imm8 | NP 0F F3 /rNP 0F 73 /6 ib | Shifts the quadword left. SSE2 form: psllq. | MMX (Intel Pentium MMX, 1997) |
psrlw | mm, mm/m64mm, imm8 | NP 0F D1 /rNP 0F 71 /2 ib | Shifts each word right, filling with zeros. SSE2 form: psrlw. | MMX (Intel Pentium MMX, 1997) |
psrld | mm, mm/m64mm, imm8 | NP 0F D2 /rNP 0F 72 /2 ib | Shifts each doubleword right, filling with zeros. SSE2 form: psrld. | MMX (Intel Pentium MMX, 1997) |
psrlq | mm, mm/m64mm, imm8 | NP 0F D3 /rNP 0F 73 /2 ib | Shifts the quadword right, filling with zeros. SSE2 form: psrlq. | MMX (Intel Pentium MMX, 1997) |
psraw | mm, mm/m64mm, imm8 | NP 0F E1 /rNP 0F 71 /4 ib | Shifts each word right, filling with its sign bit. SSE2 form: psraw. | MMX (Intel Pentium MMX, 1997) |
psrad | mm, mm/m64mm, imm8 | NP 0F E2 /rNP 0F 72 /4 ib | Shifts each doubleword right, filling with its sign bit. SSE2 form: psrad. | MMX (Intel Pentium MMX, 1997) |
Packing and unpacking
| Instruction | Forms | Encoding | What it does | Set |
|---|---|---|---|---|
packsswb | mm, mm/m64 | NP 0F 63 /r | Packs the four signed words of the destination and the four of the source into eight bytes, with signed saturation. SSE2 form: packsswb. | MMX (Intel Pentium MMX, 1997) |
packssdw | mm, mm/m64 | NP 0F 6B /r | Packs two signed doublewords from each operand into four words, with signed saturation. SSE2 form: packssdw. | MMX (Intel Pentium MMX, 1997) |
packuswb | mm, mm/m64 | NP 0F 67 /r | Packs signed words into unsigned bytes, saturating to 0 to 255. SSE2 form: packuswb. | MMX (Intel Pentium MMX, 1997) |
punpcklbw | mm, mm/m32 | NP 0F 60 /r | Interleaves the low four bytes of the destination and the source. SSE2 form: punpcklbw. | MMX (Intel Pentium MMX, 1997) |
punpcklwd | mm, mm/m32 | NP 0F 61 /r | Interleaves the low two words. SSE2 form: punpcklwd. | MMX (Intel Pentium MMX, 1997) |
punpckldq | mm, mm/m32 | NP 0F 62 /r | Interleaves the low doublewords: the result is source low : destination low. SSE2 form: punpckldq. | MMX (Intel Pentium MMX, 1997) |
punpckhbw | mm, mm/m64 | NP 0F 68 /r | Interleaves the high four bytes of the destination and the source. SSE2 form: punpckhbw. | MMX (Intel Pentium MMX, 1997) |
punpckhwd | mm, mm/m64 | NP 0F 69 /r | Interleaves the high two words. SSE2 form: punpckhwd. | MMX (Intel Pentium MMX, 1997) |
punpckhdq | mm, mm/m64 | NP 0F 6A /r | Interleaves the high doublewords: the result is source high : destination high. SSE2 form: punpckhdq. | MMX (Intel Pentium MMX, 1997) |
Notes
- Flags and exceptions. The MMX instructions change no flags and raise no arithmetic exceptions. They raise #UD when CR0.EM is set, #NM when CR0.TS is set (so the operating system can save the x87 state lazily), and #MF if an unmasked x87 exception is pending.
- 64-bit mode. There are still only eight MMX registers: REX.R and
REX.B do not change which one is chosen, though REX.B still picks the general
register of
movdandmovq, and REX.W turnsmovdinto the 64-bitmovq. - Alignment. The 64-bit memory operands need no alignment.
- The low unpacks read only 32 bits from memory, which is why
their form is
mm/m32.
Links
Reference
- Intel 64 and IA-32 Architectures Software Developer’s Manuals – Intel’s manuals; volume 2 describes each instruction, volume 1 chapter 9 describes MMX
- AMD64 Architecture Programmer’s Manual, Volume 5 – AMD’s reference to the 64-bit media (MMX and 3DNow!) and x87 instructions
- x86 and amd64 instruction reference – Félix Cloutier’s web copy of the instruction pages of Intel’s manual