ホームに戻る
 MMX命令の覚え書き

*** よくある処理 ***

ビットを 0 で埋める
pxor mm0, mm0

ビットを 1 で埋める
pcmpeqb mm0, mm0

下位32ビットを上位32ビットにコピー
punpckldq mm0, mm0

上位32ビットを下位32ビットにコピー
punpckhdq mm0, mm0

上位32ビットと下位32ビットのスワップ
punpckldq mm1,mm0   ; mm0 = [A:B] → mm1 = [B:*]
punpckhdq mm0,mm1   ; mm1 = [B:*] → mm0 = [B:A]

*** 移動 ***

32ビット値を移動(上位32ビットはそのまま)
movd mm0, mm1

64ビット値を移動
movq mm0, mm1

*** ビット演算 ***

それぞれAND,AND NOT,OR,XOR (64ビットのみ)
pand mm0, mm1
pandn mm0, mm1
por mm0, mm1
pxor mm0, mm1

*** シフト ***

符号無しシフト(左へ)
psllw mm0, 1
pslld mm0, 2
psllq mm0, 3
符号無しシフト(右へ)
psrlw mm0, 1
psrld mm0, 2
psrlq mm0, 3
符号ありシフト(右のみ 左は無い 空きは0で埋める)
psraw mm0, 1
psrad mm0, 2

*** 演算 ***

加算(符号無し 最大値に1を足すと最小値に 最小値から1を引くと最大値に)
paddb mm0, mm1
paddw mm0, mm1
paddd mm0, mm1
加算(符号有り 最大値以上、最小値以下にならない)
paddsb mm0, mm1
paddsw mm0, mm1
加算(符号無し 最大値以上、最小値以下にならない)
paddusb mm0, mm1
paddusw mm0, mm1

減算(加算の逆)
psubb mm0, mm1
psubw mm0, mm1
psubd mm0, mm1
psubsb mm0, mm1
psubsw mm0, mm1
psubusb mm0, mm1
psubusw mm0, mm1

乗算(符号あり 乗算の結果より上位16ビットを得る)
pmulhw mm0, mm1

mm0: | A1 | A2 | A3 | A4 |
mm1: | B1 | B2 | B3 | B4 |

           ↓(pmulhw)

mm0: | C1 | C2 | C3 | C4 |

C1 = A1 * B1 (C1は結果の上位16ビット)
C2 = A2 * B2 (C2は結果の上位16ビット)
C3 = A3 * B3 (C3は結果の上位16ビット)
C4 = A4 * B4 (C4は結果の上位16ビット)

乗算(符号あり 乗算の結果より下位16ビットを得る)
pmullw mm0, mm1

mm0: | A1 | A2 | A3 | A4 |
mm1: | B1 | B2 | B3 | B4 |

           ↓(pmullw)

mm0: | C1 | C2 | C3 | C4 |

C1 = A1 * B1 (C1は結果の下位16ビット)
C2 = A2 * B2 (C2は結果の下位16ビット)
C3 = A3 * B3 (C3は結果の下位16ビット)
C4 = A4 * B4 (C4は結果の下位16ビット)

乗算(乗加算 ちょっと難解)
pmaddwd mm0, mm1

mm0: | A1 | A2 | A3 | A4 |
mm1: | B1 | B2 | B3 | B4 |

           ↓(pmaddwd)

mm0: |    C1   |    C2   |

C1 = A1 * B1 + A2 * B2
C2 = A3 * B3 + A4 * B4

*** 比較 ***

等しいか?(等しければ1で埋める 等しくなければ0で埋める)
pcmpeqb mm0, 0xFF
pcmpeqw mm0, 0xFFFF
pcmpeqd mm0, 0xFFFFFFFF

mm0: | 1010 | 1010 | 1010 | 1010 |
mm1: | 0505 | 0A0A | 1010 | 4B4B |

           ↓(pcmpeqw)

mm0: | 0000 | 0000 | FFFF | 0000 |

大きいか?(大きければ1で埋める 大きくなければ0で埋める)
pcmpgtb mm0, 0xFF
pcmpgtw mm0, 0xFFFF
pcmpgtd mm0, 0xFFFFFFFF

*** パック演算 ***

パックとは32ビット値を16ビット値に縮めたりする方法
アンパックはその逆

パック演算(符号有り→符号有り 上位32ビットにmm1の結果 下位32ビットにmm0の結果)
packsswb mm0, mm1
packssdw mm0, mm1

mm0: | 0011 | 0022 | 3333 | AAAA |
mm1: | DDDD | 0001 | 0002 | 0003 |

           ↓(packsswb)

mm0: | 80 | 01 | 02 | 03 | 11 | 22 | 7F | 80 |


パック演算(符号有り→符号無し 上位32ビットにmm1の結果 下位32ビットにmm0の結果)
packuswb mm0, mm1

mm0: | 0011 | 0022 | 3333 | AAAA |
mm1: | DDDD | 0001 | 0002 | 0003 |

           ↓(packuswb)

mm0: | 00 | 01 | 02 | 03 | 11 | 22 | FF | 00 |

アンパック演算(上位バイト)
punpckhbw mm0, mm1
punpckhwd mm0, mm1
punpckhdq mm0, mm1

mm0: | FFFF | BBBB | 8888 | 4444 |
mm1: | EEEE | AAAA | 7777 | 3333 |

           ↓(punpckhwd)

mm0: | EEEE   FFFF | AAAA   BBBB |

アンパック演算(下位バイト)
punpcklbw mm0, mm1
punpcklwd mm0, mm1
punpckldq mm0, mm1

mm0: | FFFF | BBBB | 8888 | 4444 |
mm1: | EEEE | AAAA | 7777 | 3333 |

           ↓(punpcklwd)

mm0: | 7777   8888 | 3333   4444 |

inserted by FC2 system