2000-11-17、Pentium III (Coppermine) / Microsoft Visual Studio 6.0 +SP4を使用中のときに発見しました。
Visual Studio 6.0 +SP4まで、インラインアセンブラで使用できる新命令はMMXまででした。 3DNow!やSSEが登場して時間が経つというのに、インラインアセンブラで簡単に利用できない状態は非常に不便で、要所要所に適用するといった形では、容易には活用しがたい状況でした。
少々遅ればせながら、Microsoft Visual Studio 6.0 +SP4以降用にMicrosoft Visual C++ Processor Packなるものの登場を知ったのでした。
MMX, 3DNow!, SSE, Pentium4のSSE2まで対応しています。これでずいぶん勝手が良くなります。(^^) VC用のプログラムにMASMや他の処理系、あるいは疑似命令_emitなどを持ち出さなくてもいいのですから。またインラインでない方法では、関数呼び出しのオーバーヘッドが問題にならないような所でしか効果を上げにくいという悩みもありました。
pseudo: 説明上の仮想的なメンバ union { struct { unsigned char b[8]; }; struct { unsigned short w[8]; }; struct { unsigned long d[8]; }; struct { unsigned __int64 q; }; };
b | w | d | q | |
---|---|---|---|---|
Move | ||||
movd | mm,mm/mm64 | |||
mm/mm64,mm | ||||
movq | mm,mm/mm64 | |||
mm/mm64,mm | ||||
maskmovq | mmA,mmB (writing mmA to [edi]) | |||
pmovmskb | * | * | r32,mm | |
* | pextrw | * | r32,mm,imm8 | |
* | pinsrw | * | mm,r32,imm8 | |
Shuffle | ||||
packsswb | packssdw | a=pack(a,b) (signed saturation) | ||
packuswb | * | a=pack(a,b) (unsigned saturation) | ||
punpckhbw | punpckhwd | punpckhdq | a=unpack(a,b) (high) | |
punpcklbw | punpcklwd | punpckldq | a=unpack(a,b) (low) | |
* | pshufw | * | shuffle | |
Arithmetic | ||||
paddb | paddw | paddd | paddq | a=a+b (signed) |
paddsb | paddsw | * | a=a+b (saturation) | |
paddusb | paddusw | * | a=a+b (unsigned saturation) | |
psubb | psubw | psubd | psubq | a=a-b (signed) |
psubsb | psubsw | * | a=a-b (saturation) | |
psubusb | psubusw | * | a=a-b (unsigned saturation) | |
* | pmulhw | * | a=high(a*b) (signed) | |
* | pmulhuw | * | a=high(a*b) (unsigned) | |
* | pmullw | * | a=low(a*b) (signed) | |
* | * | pmuludq | a.q=a.d[0]*b.d[0] (unsigned) | |
pavgb | pavgw | * | a=(a+b+1)>>1 | |
* | pmaddwd | a.d[0]=a.w[0]*b.w[0]+a.w[1]*b.w[1] a.d[1]=a.w[2]*b.w[2]+a.w[3]*b.w[3] | ||
* | psadbw | * | a.q[0]=abs(a.b[0]-b.b[0])=abs(a.b[1]-b.b[1])+abs(a.b[2]-b.b[2])+abs(a.b[3]-b.b[3])+abs(a.b[4]-b.b[4])=abs(a.b[5]-b.b[5])+abs(a.b[6]-b.b[6])+abs(a.b[7]-b.b[7]) | |
Shift | ||||
* | psllw | pslld | psllq | a<<=imm8 (logical) |
* | psraw | psrad | * | a>>=imm8 (arithmetic) |
* | psrlw | psrld | psrlq | a>>=imm8 (logical) |
Bitwise Logical | ||||
pand | a=a&b (bitwise) | |||
pandn | a=(~a)&b (bitwise) | |||
por | a=a|b (bitwise) | |||
pxor | a=a^b (bitwise) | |||
Compare | ||||
pcmpeqb | pcmpeqw | pcmpeqd | a=(a==b)?~0:0 | |
pcmpgtb | pcmpgtw | pcmpgtd | a=(a>b)?~0:0 | |
Maximum / Minimum | ||||
* | pmaxsw | * | a=(a>b)?a:b (signed) | |
pmaxub | * | * | a=(a>b)?a:b (unsigned) | |
* | pminsw | * | a=(a<b)?a:b (signed) | |
pminub | * | * | a=(a<b)?a:b (unsigned) |