Altivec アセンブラ ニーモニック

命令の中で出てくるUIMMは、5bit符号なし即値のこと。なお、AltiVec命令に影響を与える/影響される状態レジスタはcr6である。

AltiVecの各命令とほぼ一対一で結びつくC言語用の組み込み関数(intrinsic)がgccなどでは利用できるが、それについてはAppleのページでも参照すること。どうせこのページに書いてある命令を関数にしただけだし、ページを見ても意味がわからない命令はこのページで調べればいい。同じことをいちいちまとめるのも疲れたし…

各命令の種類別リンク

ベクトル算術命令 各バイトサイズ整数と浮動小数の基本的な算術演算。加減算と乗算、小数切捨て命令のみ。
ベクトル複合算術命令 各バイトサイズ整数と浮動小数の複雑な算術演算。おそらくプログラムの高速化に最も貢献する。
型変換ベクトル演算命令 整数を浮動小数に変換したり、整数同士で型変換をするのに使う命令。整数同士の型変換の場合、ベクトル撹拌命令を使う場合もある。
ベクトル論理演算命令 論理演算や各バイトサイズ用の算術/論理シフトを行う命令。選択命令は攪拌命令扱いにしているので、ここにはない。
ベクトル比較命令 各バイトサイズ変数と浮動小数の比較演算命令。
特に整数比較は「等しい」「以上」など最小限の命令しかないため、比較対象の順序をうまく変えて扱う必要がある。
ベクトル撹拌命令 SIMD命令セットのボトルネックであるデータ整列演算を行うための命令。
わかりにくい命令が多いが、これらをうまく扱えなければSIMD命令セットの真の力は引き出せない(と思う)。
その他の命令 データ転送命令、状態制御命令、ストレージ制御命令など。

ベクトル算術命令

除算命令はベクトル算術命令には存在しない。

また、浮動小数の乗算命令も存在しないので、ベクトル複合算術命令であるvmaddfpを利用すること。

vaddcuw vD, vA, vB
vAとvBで符号なし4byte整数加算×4を実行し、その結果の桁あふれキャリービット×4を、vDに符号なし4byte整数としてそれぞれ格納する。ゆえに、結果は1か0。
vaddfp vD, vA, vB
vAとvBで単精度浮動小数加算×4を実行し、その結果をvDに格納する。
レジスタバイトインデックス
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
vA a0 a1 a2 a3
vB b0 b1 b2 b3
vD <=a0+b0 <=a1+b1 <=a2+b2 <=a3+b3
vaddsbs vD, vA, vB
vAとvBで符号あり1byte整数飽和加算×16を実行し、その結果をvDに格納する。
和の結果が符号つき1byte整数の最大値以上になった場合、127に修正され、同じく符号つき1byte整数の最小値以下になった場合は、-128に修正される。
レジスタバイトインデックス
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
vA a0 a1 a2 a3 a4 a5 a6 a7 a8 a9 a10 a11 a12 a13 a14 a15
vB b0 b1 b2 b3 b4 b5 b6 b7 b8 b9 b10 b11 b12 b13 b14 b15
vD temp=a0+b0
if(temp<MIN_SCHAR) temp=MIN_SCHAR
if(temp>MAX_SCHAR) temp=MAX_SCHAR
<=temp
temp=a1+b1
if(temp<MIN_SCHAR) temp=MIN_SCHAR
if(temp>MAX_SCHAR) temp=MAX_SCHAR
<=temp
<=... <=... <=... <=... <=... <=... <=... <=... <=... <=... <=... <=... <=... <=...
vaddshs vD, vA, vB
vAとvBで符号あり2byte整数飽和加算×8を実行し、その結果をvDに格納する。
和の結果が符号つき2byte整数の最大値以上になった場合、32767に修正され、同じく符号つき2byte整数の最小値以下になった場合は、-32768に修正される。
レジスタバイトインデックス
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
vA a0 a1 a2 a3 a4 a5 a6 a7
vB b0 b1 b2 b3 b4 b5 b6 b7
vD temp=a0+b0
if(temp<MIN_SHRT) temp=MIN_SHRT
if(temp>MAX_SHRT) temp=MAX_SHRT
<=temp
temp=a1+b1
if(temp<MIN_SHRT) temp=MIN_SHRT
if(temp>MAX_SHRT) temp=MAX_SHRT
<=temp
<=... <=... <=... <=... <=... <=...
vaddsws vD, vA, vB
vAとvBで符号あり4byte整数飽和加算×4を実行し、その結果をvDに格納する。
和の結果が符号つき4byte整数の最大値以上になった場合、2147483647に修正され、同じく符号つき4byte整数の最小値以下になった場合は、-2147483648に修正される。
レジスタバイトインデックス
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
vA a0 a1 a2 a3
vB b0 b1 b2 b3
vD temp=a0+b0
if(temp>MAX_INT) temp=MAX_INT
if(temp<MIN_INT) temp=MIN_INT
<=temp
temp=a1+b1
if(temp>MAX_INT) temp=MAX_INT
if(temp<MIN_INT) temp=MIN_INT
<=temp
<=... <=...
vaddubs vD, vA, vB
vAとvBで符号なし1byte整数飽和加算×16を実行し、その結果をvDに格納する。
和の結果が符号なし1byte整数の最大値以上になった場合、255に修正される。
レジスタバイトインデックス
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
vAa0 a1 a2 a3 a4 a5 a6 a7 a8 a9 a10 a11 a12 a13 a14 a15
vBb0 b1 b2 b3 b4 b5 b6 b7 b8 b9 b10 b11 b12 b13 b14 b15
vD temp=a0+b0
if(temp>MAX_UCHAR) temp=MAX_UCHAR
<=temp
temp=a1+b1
if(temp>MAX_UCHAR) temp=MAX_UCHAR
<=temp
<=... <=... <=... <=... <=... <=... <=... <=... <=... <=... <=... <=... <=... <=...
vaddubm vD, vA, vB
vAとvBで符号なし1byte整数加算×16を実行し、その結果をvDに格納する。
飽和加算でない通常の加算命令は符号の有無に関わらずこちらを利用する。
レジスタバイトインデックス
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
vAa0 a1 a2 a3 a4 a5 a6 a7 a8 a9 a10 a11 a12 a13 a14 a15
vBb0 b1 b2 b3 b4 b5 b6 b7 b8 b9 b10 b11 b12 b13 b14 b15
vD <=a0+b0 <=a1+b1 <=... <=... <=... <=... <=... <=... <=... <=... <=... <=... <=... <=... <=... <=...
vadduhs vD, vA, vB
vAとvBで符号なし2byte整数飽和加算×8を実行し、その結果をvDに格納する。
和の結果が符号なし2byte整数の最大値以上になった場合、65535に修正される。
レジスタバイトインデックス
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
vAa0 a1 a2 a3 a4 a5 a6 a7
vB b0 b1 b2 b3 b4 b5 b6 b7
vD temp=a0+b0
if(temp>MAX_USHRT) temp=MAX_USHRT
<=temp
temp=a1+b1
if(temp>MAX_USHRT) temp=MAX_USHRT
<=temp
<=... <=... <=... <=... <=... <=...
vadduhm vD, vA, vB
vAとvBで符号なし2byte整数加算×8を実行し、その結果をvDに格納する。
飽和加算でない通常の加算命令は符号の有無に関わらずこちらを利用する。
レジスタバイトインデックス
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
vAa0 a1 a2 a3 a4 a5 a6 a7
vB b0 b1 b2 b3 b4 b5 b6 b7
vD <=a0+b0 <=a1+b1 <=... <=... <=... <=... <=... <=...
vadduws vD, vA, vB
vAとvBで符号なし4byte整数飽和加算×4を実行し、その結果をvDに格納する。
和の結果が符号なし4byte整数の最大値以上になった場合、4294967295に修正される。
レジスタバイトインデックス
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
vAa0 a1 a2 a3
vB b0 b1 b2 b3
vD temp=a0+b0
if(temp>MAX_UINT) temp=MAX_UINT
<=temp
temp=a1+b1
if(temp>MAX_UINT) temp=MAX_UINT
<=temp
<=... <=...
vadduwm vD, vA, vB
vAとvBで符号なし4byte整数加算×4を実行し、その結果をvDに格納する。
飽和加算でない通常の加算命令は符号の有無に関わらずこちらを利用する。
レジスタバイトインデックス
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
vAa0 a1 a2 a3
vB b0 b1 b2 b3
vD <=a0+b0 <=a1+b1 <=a2+b2 <=a3+b3
vmulesb vD, vA, vB
vA、vBを1byte符号あり整数×16とする。最上位の1byte同士の乗算結果をvDの最上位2byteに、上から2番目の1byte同士の乗算結果をvDの上から1番目の2byteに、というように、1区画とばしで乗算を行い、その結果をvDに入れていく。乗算の際に上位8bitの情報も出力するために、このような仕様になったと思われる。
レジスタバイトインデックス
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
vAa0 a1 a2 a3 a4 a5 a6 a7 a8 a9 a10 a11 a12 a13 a14 a15
vBb0 b1 b2 b3 b4 b5 b6 b7 b8 b9 b10 b11 b12 b13 b14 b15
vD <=a0×b0 <=a2×b2 <=a4×b4 <=... <=... <=... <=... <=...
vmulesh vD, vA, vB
vA、vBを2byte符号あり整数×8とする。最上位の2byte同士の乗算結果をvDの最上位4byteに、上から2番目の2byte同士の乗算結果をvDの上から1番目の4byteに、というように、1区画とばしで乗算を行い、その結果をvDに入れていく。乗算の際に上位16bitの情報も出力するために、このような仕様になったと思われる。
レジスタバイトインデックス
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
vAa0 a1 a2 a3 a4 a5 a6 a7
vB b0 b1 b2 b3 b4 b5 b6 b7
vD <=a0×b0 <=a2×b2 <=a4×b4 <=a6×b6
vmuleub vD, vA, vB
vA、vBを1byte符号なし整数×16とする。最上位の1byte同士の乗算結果をvDの最上位2byteに、上から2番目の1byte同士の乗算結果をvDの上から1番目の2byteに、というように、1区画とばしで乗算を行い、その結果をvDに入れていく。乗算の際に上位8bitの情報も出力するために、このような仕様になったと思われる。
レジスタバイトインデックス
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
vAa0 a1 a2 a3 a4 a5 a6 a7 a8 a9 a10 a11 a12 a13 a14 a15
vBb0 b1 b2 b3 b4 b5 b6 b7 b8 b9 b10 b11 b12 b13 b14 b15
vD <=a0×b0 <=a2×b2 <=a4×b4 <=... <=... <=... <=... <=...
vmuleuh vD, vA, vB
vA、vBを2byte符号なし整数×8とする。最上位の2byte同士の乗算結果をvDの最上位4byteに、上から2番目の2byte同士の乗算結果をvDの上から1番目の4byteに、というように、1区画とばしで乗算を行い、その結果をvDに入れていく。乗算の際に上位16bitの情報も出力するために、このような仕様になったと思われる。
レジスタバイトインデックス
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
vAa0 a1 a2 a3 a4 a5 a6 a7
vB b0 b1 b2 b3 b4 b5 b6 b7
vD <=a0×b0 <=a2×b2 <=a4×b4 <=a6×b6
vmulosb vD, vA, vB
vA、vBを1byte符号あり整数×16とする。上から1番目の1byte同士の乗算結果をvDの最上位2byteに、上から3番目の1byte同士の乗算結果をvDの上から1番目の2byteに、というように、1区画とばしで乗算を行い、その結果をvDに入れていく。乗算の際に上位8bitの情報も出力するために、このような仕様になったと思われる。
レジスタバイトインデックス
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
vAa0 a1 a2 a3 a4 a5 a6 a7 a8 a9 a10 a11 a12 a13 a14 a15
vBb0 b1 b2 b3 b4 b5 b6 b7 b8 b9 b10 b11 b12 b13 b14 b15
vD <=a1×b1 <=a3×b3 <=a5×b5 <=... <=... <=... <=... <=...
vmulosh vD, vA, vB
vA、vBを2byte符号あり整数×16とする。上から1番目の2byte同士の乗算結果をvDの最上位4byteに、上から3番目の2byte同士の乗算結果をvDの上から1番目の2byteに、というように、1区画とばしで乗算を行い、その結果をvDに入れていく。乗算の際に上位16bitの情報も出力するために、このような仕様になったと思われる。
レジスタバイトインデックス
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
vAa0 a1 a2 a3 a4 a5 a6 a7
vB b0 b1 b2 b3 b4 b5 b6 b7
vD <=a1×b1 <=a3×b3 <=a5×b5 <=a7×b7
vmuloub vD, vA, vB
vA、vBを1byte符号なし整数×16とする。上から1番目の1byte同士の乗算結果をvDの最上位2byteに、上から3番目の1byte同士の乗算結果をvDの上から1番目の2byteに、というように、1区画とばしで乗算を行い、その結果をvDに入れていく。乗算の際に上位8bitの情報も出力するために、このような仕様になったと思われる。
レジスタバイトインデックス
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
vAa0 a1 a2 a3 a4 a5 a6 a7 a8 a9 a10 a11 a12 a13 a14 a15
vBb0 b1 b2 b3 b4 b5 b6 b7 b8 b9 b10 b11 b12 b13 b14 b15
vD <=a1×b1 <=a3×b3 <=a5×b5 <=... <=... <=... <=... <=...
vmulouh vD, vA, vB
vA、vBを2byte符号なし整数×16とする。上から1番目の2byte同士の乗算結果をvDの最上位4byteに、上から3番目の2byte同士の乗算結果をvDの上から1番目の2byteに、というように、1区画とばしで乗算を行い、その結果をvDに入れていく。乗算の際に上位16bitの情報も出力するために、このような仕様になったと思われる。
レジスタバイトインデックス
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
vAa0 a1 a2 a3 a4 a5 a6 a7
vB b0 b1 b2 b3 b4 b5 b6 b7
vD <=a1×b1 <=a3×b3 <=a5×b5 <=a7×b7
vrfim vD, vB
vBを単精度浮動小数×4とする。vBの小数部を切り捨ててvDへ格納する(?)。
vrfin vD, vB
vBを単精度浮動小数×4とする。vBの小数部を近似し(四捨五入?)、小数部を取り除いてからvDへ格納する。
vrfip vD, vB
vBを単精度浮動小数×4とする。vBに小数部がある場合、それを切り捨てて1加算してから、vDへ格納する(?)。
vrfiz vD, vB
vBを単精度浮動小数×4とする。vBの小数部を切り捨ててvDへ格納する。
vsubcuw vD, vA, vB
vA、vBを4byte符号なし整数×4とする。vAとvBとの減算結果の桁借りボロービットbit×4を、vDに符合なし4byte整数としてそれぞれ格納する。つまり、結果は1か0。
vsubfp vD, vA, vB
vA、vBを単精度浮動小数×4とする。vAとvBとの減算結果をvDに格納する。
レジスタバイトインデックス
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
vAa0 a1 a2 a3
vB b0 b1 b2 b3
vD <=a0-b0 <=a1-b1 <=a2-b2 <=a3-b3
vsubsbs vD, vA, vB
vA、vBを1byte符号つき整数×16とする。vAとvBとの減算結果をvDに格納する。
ただし、結果が符号つき1byte整数の最大値以上になった場合、127に修正され、同じく符号つき1byte整数の最小値以下になった場合は、-128に修正される。
レジスタバイトインデックス
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
vAa0 a1 a2 a3 a4 a5 a6 a7 a8 a9 a10 a11 a12 a13 a14 a15
vBb0 b1 b2 b3 b4 b5 b6 b7 b8 b9 b10 b11 b12 b13 b14 b15
vD temp=a0-b0
if(temp<MIN_SCHAR) temp=MIN_SCHAR
if(temp>MAX_SCHAR) temp=MAX_SCHAR
<=temp
temp=a1-b1
if(temp<MIN_SCHAR) temp=MIN_SCHAR
if(temp>MAX_SCHAR) temp=MAX_SCHAR
<=temp
<=... <=... <=... <=... <=... <=... <=... <=... <=... <=... <=... <=... <=... <=...
vsubshs vD, vA, vB
vA、vBを2byte符号つき整数×8とする。vAとvBとの減算結果をvDに格納する。
ただし、結果が符号つき2byte整数の最大値以上になった場合、32767に修正され、同じく符号つき1byte整数の最小値以下になった場合は、-32768に修正される。
レジスタバイトインデックス
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
vAa0 a1 a2 a3 a4 a5 a6 a7
vB b0 b1 b2 b3 b4 b5 b6 b7
vD temp=a0-b0
if(temp<MIN_SHRT) temp=MIN_SHRT
if(temp>MAX_SHRT) temp=MAX_SHRT
<=temp
temp=a1-b1
if(temp<MIN_SHRT) temp=MIN_SHRT
if(temp>MAX_SHRT) temp=MAX_SHRT
<=temp
<=... <=... <=... <=... <=... <=...
vsubsws vD, vA, vB
vA、vBを4byte符号つき整数×4とする。vAとvBとの減算結果をvDに格納する。
ただし、結果が符号つき4byte整数の最大値以上になった場合、2147483647に修正され、同じく符号つき4byte整数の最小値以下になった場合は、-2147483648に修正される。
レジスタバイトインデックス
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
vAa0 a1 a2 a3
vB b0 b1 b2 b3
vD temp=a0-b0
if(temp<MIN_INT) temp=MIN_INT
if(temp>MAX_INT) temp=MAX_INT
<=temp
temp=a1-b1
if(temp<MIN_INT) temp=MIN_INT
if(temp>MAX_INT) temp=MAX_INT
<=temp
<=... <=...
vsububm vD, vA, vB
vA、vBを1byte符号なし整数×16とする。vAとvBとの減算結果をvDに格納する。結果的には、符号の有無に関係なく使える。
レジスタバイトインデックス
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
vAa0 a1 a2 a3 a4 a5 a6 a7 a8 a9 a10 a11 a12 a13 a14 a15
vBb0 b1 b2 b3 b4 b5 b6 b7 b8 b9 b10 b11 b12 b13 b14 b15
vD <=a0-b0 <=a1-b1 <=... <=... <=... <=... <=... <=... <=... <=... <=... <=... <=... <=... <=... <=...
vsububs vD, vA, vB
vA、vBを1byte符号なし整数×16とする。vAとvBとの減算結果をvDに格納する。
ただし、結果が符号なし1byte整数の最大値以上になった場合、255に修正され、0未満になった場合、0に修正される。
レジスタバイトインデックス
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
vAa0 a1 a2 a3 a4 a5 a6 a7 a8 a9 a10 a11 a12 a13 a14 a15
vBb0 b1 b2 b3 b4 b5 b6 b7 b8 b9 b10 b11 b12 b13 b14 b15
vD temp=a0-b0
if(temp>MAX_UCHAR) temp=MAX_UCHAR
<=temp
temp=a1-b1
if(temp>MAX_UCHAR) temp=MAX_UCHAR
<=temp
<=... <=... <=... <=... <=... <=... <=... <=... <=... <=... <=... <=... <=... <=...
vsubuhm vD, vA, vB
vA、vBを2byte符号なし整数×8とする。vAとvBとの減算結果をvDに格納する。結果的には、符号の有無に関係なく使える。
レジスタバイトインデックス
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
vAa0 a1 a2 a3 a4 a5 a6 a7
vB b0 b1 b2 b3 b4 b5 b6 b7
vD <=a0-b0 <=a1-b1 <=... <=... <=... <=... <=... <=...
vsubuhs vD, vA, vB
vA、vBを2byte符号なし整数×8とする。vAとvBとの減算結果をvDに格納する。
ただし、結果が符号なし2byte整数の最大値以上になった場合、65535に修正され、0未満になった場合、0に修正される。
レジスタバイトインデックス
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
vAa0 a1 a2 a3 a4 a5 a6 a7
vB b0 b1 b2 b3 b4 b5 b6 b7
vD temp=a0-b0
if(temp>MAX_USHRT) temp=MAX_USHRT
<=temp
temp=a1-b1
if(temp>MAX_USHRT) temp=MAX_USHRT
<=temp
<=... <=... <=... <=... <=... <=...
vsubuwm vD, vA, vB
vA、vBを4byte符号なし整数×4とする。vAとvBとの減算結果をvDに格納する。結果的には、符号の有無に関係なく使える。
レジスタバイトインデックス
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
vAa0 a1 a2 a3
vB b0 b1 b2 b3
vD <=a0-b0 <=a1-b1 <=a2-b2 <=a3-b3
vsubuws vD, vA, vB
vA、vBを4byte符号なし整数×4とする。vAとvBとの減算結果をvDに格納する。
ただし、結果が符号なし4byte整数の最大値以上になった場合、4294967295に修正され、0未満になった場合、0に修正される。
レジスタバイトインデックス
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
vAa0 a1 a2 a3
vB b0 b1 b2 b3
vD temp=a0-b0
if(temp>MAX_UINT) temp=MAX_UINT
<=temp
temp=a1-b1
if(temp>MAX_UINT) temp=MAX_UINT
<=temp
<=... <=...

ベクトル複合算術命令

複数の算術命令をまとめて実行したり、やや複雑な演算をする命令。

vavgsb vD, vA, vB
vAとvBで符号あり1byte整数加算+1×16を実行した結果の値を右へ1bitシフトした値をvDに格納する。ちなみに、1を足すことで、vAとvBの和が負の数の場合は小数切捨て、正の数の場合は小数切り上げとなっている。
レジスタバイトインデックス
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
vAa0 a1 a2 a3 a4 a5 a6 a7 a8 a9 a10 a11 a12 a13 a14 a15
vBb0 b1 b2 b3 b4 b5 b6 b7 b8 b9 b10 b11 b12 b13 b14 b15
vD <=(a0+b0+1)/2 <=(a1+b1+1)/2 <=... <=... <=... <=... <=... <=... <=... <=... <=... <=... <=... <=... <=... <=...
vavgsh vD, vA, vB
vAとvBで符号あり2byte整数加算+1×8を実行した結果の値を右へ1bitシフトした値をvDに格納する。ちなみに、1を足すことで、vAとvBの和が負の数の場合は小数切捨て、正の数の場合は小数切り上げとなっている。
レジスタバイトインデックス
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
vAa0 a1 a2 a3 a4 a5 a6 a7
vB b0 b1 b2 b3 b4 b5 b6 b7
vD <=(a0+b0+1)/2 <=(a1+b1+1)/2 <=... <=... <=... <=... <=... <=...
vavgsw vD, vA, vB
vAとvBで符号あり4byte整数加算+1×4を実行した結果の値を右へ1bitシフトした値をvDに格納する。ちなみに、1を足すことで、vAとvBの和が負の数の場合は小数切捨て、正の数の場合は小数切り上げとなっている。
レジスタバイトインデックス
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
vAa0 a1 a2 a3
vB b0 b1 b2 b3
vD <=(a0+b0+1)/2 <=(a1+b1+1)/2 <=(a2+b2+1)/2 <=(a3+b3+1)/2
vavgub vD, vA, vB
vAとvBで符号なし1byte整数加算+1×16を実行した結果の値を右へ1bitシフトした値をvDに格納する。ちなみに、1を足すことで小数切り上げとなっている。
レジスタバイトインデックス
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
vAa0 a1 a2 a3 a4 a5 a6 a7 a8 a9 a10 a11 a12 a13 a14 a15
vBb0 b1 b2 b3 b4 b5 b6 b7 b8 b9 b10 b11 b12 b13 b14 b15
vD <=(a0+b0+1)/2 <=(a1+b1+1)/2 <=... <=... <=... <=... <=... <=... <=... <=... <=... <=... <=... <=... <=... <=...
vavguh vD, vA, vB
vAとvBで符号なし2byte整数加算+1×8を実行した結果の値を右へ1bitシフトした値をvDに格納する。ちなみに、1を足すことで小数切り上げとなっている。
レジスタバイトインデックス
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
vAa0 a1 a2 a3 a4 a5 a6 a7
vB b0 b1 b2 b3 b4 b5 b6 b7
vD <=(a0+b0+1)/2 <=(a1+b1+1)/2 <=... <=... <=... <=... <=... <=...
vavguw vD, vA, vB
vAとvBで符号なし4byte整数加算+1×4を実行した結果の値を右へ1bitシフトした値をvDに格納する。ちなみに、1を足すことで小数切り上げとなっている。
レジスタバイトインデックス
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
vAa0 a1 a2 a3
vB b0 b1 b2 b3
vD <=(a0+b0+1)/2 <=(a1+b1+1)/2 <=(a2+b2+1)/2 <=(a3+b3+1)/2
vexptefp vD, vB
vBを単精度浮動小数×4とする。2のvB乗の単精度浮動小数値をvDに格納する。誤差があるので計算が必要。具体的な内容は除算と似たような方法を使えばいいのだと思うが、詳しくは不明。
vlogefp vD, vB
vBを単精度浮動小数×4とする。log2(vB)の単精度浮動小数値をvDに格納する。vBが0未満の値だった場合、NaNになる。誤差があるので計算が必要。具体的な内容は除算と似たような方法を使えばいいのだと思うが、詳しくは不明。
vmaddfp vD, vA, vC, vB
vA、vC、vBを単精度浮動小数×4とする。vAとvCとの乗算結果にvBを足したものをvDに格納する。
レジスタバイトインデックス
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
vA a0 a1 a2 a3
vC c0 c1 c2 c3
vB b0 b1 b2 b3
vD <=a0×c0+b0 <=a1×c1+b1 <=a2×c2+b2 <=a3×c3+b3
vmaxfp vD, vA, vB
vA、vBを単精度浮動小数×4とする。vAとvBのどちらか大きい方をvDに格納する。
レジスタバイトインデックス
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
vAa0 a1 a2 a3
vB b0 b1 b2 b3
vD <=(a0>b0?a0:b0) <=(a1>b1?a1:b1) <=(a2>b2?a2:b2) <=(a3>b3?a3:b3)
vmaxsb vD, vA, vB
vA、vBを1byte符号あり整数×16とする。vAとvBのどちらか大きい方をvDに格納する。
レジスタバイトインデックス
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
vAa0 a1 a2 a3 a4 a5 a6 a7 a8 a9 a10 a11 a12 a13 a14 a15
vBb0 b1 b2 b3 b4 b5 b6 b7 b8 b9 b10 b11 b12 b13 b14 b15
vD <=(a0>b0?a0:b0) <=(a1>b1?a1:b1) <=... <=... <=... <=... <=... <=... <=... <=... <=... <=... <=... <=... <=... <=...
vmaxsh vD, vA, vB
vA、vBを2byte符号あり整数×8とする。vAとvBのどちらか大きい方をvDに格納する。
レジスタバイトインデックス
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
vAa0 a1 a2 a3 a4 a5 a6 a7
vB b0 b1 b2 b3 b4 b5 b6 b7
vD <=(a0>b0?a0:b0) <=(a1>b1?a1:b1) <=... <=... <=... <=... <=... <=...
vmaxsw vD, vA, vB
vA、vBを4byte符号あり整数×4とする。vAとvBのどちらか大きい方をvDに格納する。
レジスタバイトインデックス
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
vAa0 a1 a2 a3
vB b0 b1 b2 b3
vD <=(a0>b0?a0:b0) <=(a1>b1?a1:b1) <=(a2>b2?a2:b2) <=(a3>b3?a3:b3)
vmaxub vD, vA, vB
vA、vBを1byte符号なし整数×16とする。vAとvBのどちらか大きい方をvDに格納する。
レジスタバイトインデックス
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
vAa0 a1 a2 a3 a4 a5 a6 a7 a8 a9 a10 a11 a12 a13 a14 a15
vBb0 b1 b2 b3 b4 b5 b6 b7 b8 b9 b10 b11 b12 b13 b14 b15
vD <=(a0>b0?a0:b0) <=(a1>b1?a1:b1) <=... <=... <=... <=... <=... <=... <=... <=... <=... <=... <=... <=... <=... <=...
vmaxuh vD, vA, vB
vA、vBを2byte符号なし整数×8とする。vAとvBのどちらか大きい方をvDに格納する。
レジスタバイトインデックス
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
vAa0 a1 a2 a3 a4 a5 a6 a7
vB b0 b1 b2 b3 b4 b5 b6 b7
vD <=(a0>b0?a0:b0) <=(a1>b1?a1:b1) <=... <=... <=... <=... <=... <=...
vmaxuw vD, vA, vB
vA、vBを4byte符号なし整数×4とする。vAとvBのどちらか大きい方をvDに格納する。
レジスタバイトインデックス
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
vAa0 a1 a2 a3
vB b0 b1 b2 b3
vD <=(a0>b0?a0:b0) <=(a1>b1?a1:b1) <=(a2>b2?a2:b2) <=(a3>b3?a3:b3)
vmhaddshs vD, vA, vB, vC
vA、vB、vCを2byte符号あり整数×8とする。vAとvBとの乗算結果の上2byteとvCとの和をvDに入れる。ただし、結果が符号つき2byte整数の最大値以上だった場合は32767に修正され、符号つき2byte整数の最小値以下だった場合は-32768に修正される。
レジスタバイトインデックス
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
vA a0 a1 a2 a3 a4 a5 a6 a7
vB b0 b1 b2 b3 b4 b5 b6 b7
vC c0 c1 c2 c3 c4 c5 c6 c7
vD temp=a0×b0/65536+c0
if(temp<MIN_SHRT) temp=MIN_SHRT
if(temp>MAX_SHRT) temp=MAX_SHRT
<=temp
temp=a1×b1/65536+c1
if(temp<MIN_SHRT) temp=MIN_SHRT
if(temp>MAX_SHRT) temp=MAX_SHRT
<=temp
<=... <=... <=... <=... <=... <=...
vmhraddshs vD, vA, vB, vC
vA、vB、vCを2byte符号あり整数×8とする。vAとvBとの乗算結果と0x4000との和の上2byteとvCとの和をvDに入れる。ただし、結果が符号つき2byte整数の最大値以上だった場合は32767に修正され、符号つき2byte整数の最小値以下だった場合は-32768に修正される。
乗算結果と0x4000との和の処理は、上2byteを取り出す前の1bit繰り上げの処理である。
レジスタバイトインデックス
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
vA a0 a1 a2 a3 a4 a5 a6 a7
vB b0 b1 b2 b3 b4 b5 b6 b7
vC c0 c1 c2 c3 c4 c5 c6 c7
vD temp=(a0×b0+16384)/65536+c0
if(temp<MIN_SHRT) temp=MIN_SHRT
if(temp>MAX_SHRT) temp=MAX_SHRT
<=temp
temp=(a1×b1+16384)/65536+c1
if(temp<MIN_SHRT) temp=MIN_SHRT
if(temp>MAX_SHRT) temp=MAX_SHRT
<=temp
<=... <=... <=... <=... <=... <=...
vminfp vD, vA, vB
vA、vBを単精度浮動小数×4とする。vAとvBのどちらか小さい方をvDに格納する。
レジスタバイトインデックス
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
vAa0 a1 a2 a3
vB b0 b1 b2 b3
vD <=(a0<b0?a0:b0) <=(a1<b1?a1:b1) <=(a2<b2?a2:b2) <=(a3<b3?a3:b3)
vminsb vD, vA, vB
vA、vBを1byte符号つき整数×16とする。vAとvBのどちらか小さい方をvDに格納する。
レジスタバイトインデックス
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
vAa0 a1 a2 a3 a4 a5 a6 a7 a8 a9 a10 a11 a12 a13 a14 a15
vBb0 b1 b2 b3 b4 b5 b6 b7 b8 b9 b10 b11 b12 b13 b14 b15
vD <=(a0<b0?a0:b0) <=(a1<b1?a1:b1) <=... <=... <=... <=... <=... <=... <=... <=... <=... <=... <=... <=... <=... <=...
vminsh vD, vA, vB
vA、vBを2byte符号つき整数×8とする。vAとvBのどちらか小さい方をvDに格納する。
レジスタバイトインデックス
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
vAa0 a1 a2 a3 a4 a5 a6 a7
vB b0 b1 b2 b3 b4 b5 b6 b7
vD <=(a0<b0?a0:b0) <=(a1<b1?a1:b1) <=... <=... <=... <=... <=... <=...
vminsw vD, vA, vB
vA、vBを4byte符号つき整数×4とする。vAとvBのどちらか小さい方をvDに格納する。
レジスタバイトインデックス
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
vAa0 a1 a2 a3
vB b0 b1 b2 b3
vD <=(a0<b0?a0:b0) <=(a1<b1?a1:b1) <=(a2<b2?a2:b2) <=(a3<b3?a3:b3)
vminub vD, vA, vB
vA、vBを1byte符号なし整数×16とする。vAとvBのどちらか小さい方をvDに格納する。
レジスタバイトインデックス
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
vAa0 a1 a2 a3 a4 a5 a6 a7 a8 a9 a10 a11 a12 a13 a14 a15
vBb0 b1 b2 b3 b4 b5 b6 b7 b8 b9 b10 b11 b12 b13 b14 b15
vD <=(a0<b0?a0:b0) <=(a1<b1?a1:b1) <=... <=... <=... <=... <=... <=... <=... <=... <=... <=... <=... <=... <=... <=...
vminuh vD, vA, vB
vA、vBを2byte符号なし整数×8とする。vAとvBのどちらか小さい方をvDに格納する。
レジスタバイトインデックス
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
vAa0 a1 a2 a3 a4 a5 a6 a7
vB b0 b1 b2 b3 b4 b5 b6 b7
vD <=(a0<b0?a0:b0) <=(a1<b1?a1:b1) <=... <=... <=... <=... <=... <=...
vminuw vD, vA, vB
vA、vBを4byte符号なし整数×4とする。vAとvBのどちらか小さい方をvDに格納する。
レジスタバイトインデックス
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
vAa0 a1 a2 a3
vB b0 b1 b2 b3
vD <=(a0<b0?a0:b0) <=(a1<b1?a1:b1) <=(a2<b2?a2:b2) <=(a3<b3?a3:b3)
vmladduhm vD, vA, vB, vC
vA、vB、vCを2byte符号なし整数×8とする。vAとvBとの乗算結果の下2byteとvCとの和をvDに入れる。この命令は符号のありなしに関わらず使える。
レジスタバイトインデックス
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
vA a0 a1 a2 a3 a4 a5 a6 a7
vB b0 b1 b2 b3 b4 b5 b6 b7
vC c0 c1 c2 c3 c4 c5 c6 c7
vD <=a0×b0+c0 <=a1×b1+c1 <=... <=... <=... <=... <=... <=...
vmsummbm vD, vA, vB, vC
vA、vBを1byte符号つき整数×16とし、vCを4byte符号つき整数×4とする。vAとvBの乗算結果4つごとに、vCとまとめて足した結果をvDに格納する。
レジスタバイトインデックス
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
vAa0 a1 a2 a3 a4 a5 a6 a7 a8 a9 a10 a11 a12 a13 a14 a15
vBb0 b1 b2 b3 b4 b5 b6 b7 b8 b9 b10 b11 b12 b13 b14 b15
vCc0 c1 c2 c3
vD <=a0×b0+a1×b1+a2×b2+a3×b3+c0 <=a4×b4+a5×b5+a6×b6+a7×b7+c1 <=... <=...
vmsummhm vD, vA, vB, vC
vA、vBを2byte符号つき整数×8とし、vCを4byte符号つき整数×4とする。vAとvBの乗算結果2つごとに、vCとまとめて足した結果をvDに格納する。
レジスタバイトインデックス
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
vAa0 a1 a2 a3 a4 a5 a6 a7
vB b0 b1 b2 b3 b4 b5 b6 b7
vCc0 c1 c2 c3
vD <=a0×b0+a1×b1+c0 <=a2×b2+a3×b3+c1 <=... <=...
vmsumshs vD, vA, vB, vC
vA、vBを2byte符号つき整数×8とし、vCを4byte符号つき整数×4とする。vAとvBの乗算結果2つごとに、vCとまとめて足した結果をvDに格納する。
和の結果が符号つき4byte整数の最大値以上になった場合、2147483647に修正され、同じく符号つき4byte整数の最小値以下になった場合は、-2147483648に修正される。 C風に書くとこんな感じ。
レジスタバイトインデックス
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
vAa0 a1 a2 a3 a4 a5 a6 a7
vB b0 b1 b2 b3 b4 b5 b6 b7
vCc0 c1 c2 c3
vD temp=a0×b0+a1×b1+c0
if(temp>MAX_INT) temp=MAX_INT
if(temp<MIN_INT) temp=MIN_INT
<=temp
temp=a2×b2+a3×b3+c1
if(temp>MAX_INT) temp=MAX_INT
if(temp<MIN_INT) temp=MIN_INT
<=temp
<=... <=...
vmsumubm vD, vA, vB, vC
vA、vBを1byte符号なし整数×16とし、vCを4byte符号なし整数×4とする。vAとvBの乗算結果4つごとに、vCとまとめて足した結果をvDに格納する。
レジスタバイトインデックス
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
vAa0 a1 a2 a3 a4 a5 a6 a7 a8 a9 a10 a11 a12 a13 a14 a15
vBb0 b1 b2 b3 b4 b5 b6 b7 b8 b9 b10 b11 b12 b13 b14 b15
vCc0 c1 c2 c3
vD <=a0×b0+a1×b1+a2×b2+a3×b3+c0 <=a4×b4+a5×b5+a6×b6+a7×b7+c1 <=... <=...
vmsumuhm vD, vA, vB, vC
vA、vBを2byte符号なし整数×8とし、vCを4byte符号なし整数×4とする。vAとvBの乗算結果2つごとに、vCとまとめて足した結果をvDに格納する。
レジスタバイトインデックス
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
vAa0 a1 a2 a3 a4 a5 a6 a7
vB b0 b1 b2 b3 b4 b5 b6 b7
vCc0 c1 c2 c3
vD <=a0×b0+a1×b1+c0 <=a2×b2+a3×b3+c1 <=... <=...
vmsumuhs vD, vA, vB, vC
vA、vBを2byte符号なし整数×8とし、vCを4byte符号なし整数×4とする。vAとvBの乗算結果2つごとに、vCとまとめて足した結果をvDに格納する。
和の結果が符号なし4byte整数の最大値以上になった場合、4294967295に修正される。
レジスタバイトインデックス
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
vAa0 a1 a2 a3 a4 a5 a6 a7
vB b0 b1 b2 b3 b4 b5 b6 b7
vCc0 c1 c2 c3
vD temp=a0×b0+a1×b1+c0
if(temp>MAX_UINT) temp=MAX_UINT
<=temp
temp=a2×b2+a3×b3+c1
if(temp>MAX_UINT) temp=MAX_UINT
<=temp
<=... <=...
vnmsubfp vD, vA, vC, vB
vA、vC、vBを単精度浮動小数×4とする。vAとvCとの乗算結果からvBを引いたものを、さらに符号反転したものをvDに格納する。
結果的に、この命令の処理はvB - vA * vCとなる。
レジスタバイトインデックス
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
vAa0 a1 a2 a3
vCc0 c1 c2 c3
vB b0 b1 b2 b3
vD <=-(a0×c0-b0) <=-(a1×c1-b1) <=-(a2×c2-b2) <=-(a3×c3-b3)
vrefp vD, vB
vBを単精度浮動小数×4とする。1とvBの値の除算結果(つまり、vBの値の逆数)をvDに格納する。誤差があるので計算が必要。具体的な内容はAltiVecプログラミングテクニック参照。
vrsqrtefp vD, vB
vBを単精度浮動小数×4とする。vBの値の2乗根で1を割った値をvDに格納する。誤差があるので計算が必要。具体的な内容はAltiVecプログラミングテクニック参照。
vsumsws vD, vA, vB
vA、vBを4byte符号あり整数×4とする。vAの4つの整数と、vBの一番下の4byte整数の総和をvDの一番下の4byteに格納する。 このとき、vDの他のbitは全て0にクリアされる。
結果が符号つき4byte整数の最大値以上になった場合、2147483647に修正され、同じく符号つき4byte整数の最小値以下になった場合は、-2147483648に修正される。
レジスタバイトインデックス
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
vAa0 a1 a2 a3
vB b0 b1 b2 b3
vD <=0 <=0 <=0 temp=a0+a1+a2+a3+b3
if(temp>MAX_INT) temp=MAX_INT
if(temp<MIN_INT) temp=MIN_INT
<=temp
vsum2sws vD, vA, vB
vA、vBを4byte符号あり整数×4とする。vAとvBの上2つの4byte整数の総和を、vDの上から1番目の4byteに下2つの4byte整数の総和を、vDの一番下の4byteに格納する。 このとき、vDの他のbitは全て0にクリアされる。
結果が符号つき4byte整数の最大値以上になった場合、2147483647に修正され、同じく符号つき4byte整数の最小値以下になった場合は、-2147483648に修正される。
レジスタバイトインデックス
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
vAa0 a1 a2 a3
vB b0 b1 b2 b3
vD <=0 temp=a0+a1+b0+b1
if(temp>MAX_INT) temp=MAX_INT
if(temp<MIN_INT) temp=MIN_INT
<=temp
<=0 temp=a2+a3+b2+b3
if(temp>MAX_INT) temp=MAX_INT
if(temp<MIN_INT) temp=MIN_INT
<=temp
vsum4sbs vD, vA, vB
vAを1byte符号あり整数×16、vBを4byte符号あり整数×4とする。vAの1byte整数4つと、vBの4byte整数との総和をvDへ格納する。
結果が符号つき4byte整数の最大値以上になった場合、2147483647に修正され、同じく符号つき4byte整数の最小値以下になった場合は、-2147483648に修正される。
レジスタバイトインデックス
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
vAa0 a1 a2 a3 a4 a5 a6 a7 a8 a9 a10 a11 a12 a13 a14 a15
vB b0 b1 b2 b3
vD temp=a0+a1+a2+a3+b0
if(temp>MAX_INT) temp=MAX_INT
if(temp<MIN_INT) temp=MIN_INT
<=temp
temp=a4+a5+a6+a7+b1
if(temp>MAX_INT) temp=MAX_INT
if(temp<MIN_INT) temp=MIN_INT
<=temp
<=... <=...
vsum4shs vD, vA, vB
vAを2byte符号あり整数×8、vBを4byte符号あり整数×4とする。vAの2byte整数2つと、vBの4byte整数との総和をvDへ格納する。
結果が符号つき4byte整数の最大値以上になった場合、2147483647に修正され、同じく符号つき4byte整数の最小値以下になった場合は、-2147483648に修正される。
レジスタバイトインデックス
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
vAa0 a1 a2 a3 a4 a5 a6 a7
vB b0 b1 b2 b3
vD temp=a0+a1+b0
if(temp>MAX_INT) temp=MAX_INT
if(temp<MIN_INT) temp=MIN_INT
<=temp
temp=a2+a3+b1
if(temp>MAX_INT) temp=MAX_INT
if(temp<MIN_INT) temp=MIN_INT
<=temp
<=... <=...
vsum4ubs vD, vA, vB
vAを1byte符号なし整数×16、vBを4byte符号なし整数×4とする。vAの1byte整数4つと、vBの4byte整数との総和をvDへ格納する。
ただし、結果が符号なし4byte整数の最大値以上になった場合、4294967295に修正され、0未満になった場合、0に修正される。
レジスタバイトインデックス
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
vAa0 a1 a2 a3 a4 a5 a6 a7 a8 a9 a10 a11 a12 a13 a14 a15
vB b0 b1 b2 b3
vD temp=a0+a1+a2+a3+b0
if(temp>MAX_UINT) temp=MAX_UINT
<=temp
temp=a4+a5+a6+a7+b1
if(temp>MAX_UINT) temp=MAX_UINT
<=temp
<=... <=...

型変換ベクトル演算命令

vcfsx vD, vB, UIMM
vBを符号あり整数×4とし、それを2のUIMM乗で割った値を単精度浮動小数値×4に変換してvDに格納する。
レジスタバイトインデックス
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
vAa0 a1 a2 a3
vD <=(float)a0/2^UIMM <=(float)a1/2^UIMM <=... <=...
vcfux vD, vB, UIMM
vBを符号なし整数×4とし、それを2のUIMM乗で割った値を単精度浮動小数値×4に変換してvDに格納する。
レジスタバイトインデックス
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
vAa0 a1 a2 a3
vD <=(float)a0/2^UIMM <=(float)a1/2^UIMM <=... <=...
vctsxs vD, vB, UIMM
vBを単精度浮動小数×4とし、それを2のUIMM乗で割った値を符号つき4byte整数×4に変換してvDに格納する。
変換した値が符号つき4byte整数の最大値以上になった場合、2147483647に修正され、同じく符号つき4byte整数の最小値以下になった場合は、-2147483648に修正されてvDに格納される。
レジスタバイトインデックス
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
vAa0 a1 a2 a3
vD temp=(signed int)(a0/2^UIMM)
if(temp>MAX_INT) temp=MAX_INT
if(temp<MIN_INT) temp=MIN_INT
<=temp
temp=(signed int)(a1/2^UIMM)
if(temp>MAX_INT) temp=MAX_INT
if(temp<MIN_INT) temp=MIN_INT
<=temp
<=... <=...
vctuxs vD, vB, UIMM
vBを単精度浮動小数×4とし、それを2のUIMM乗で割った値を符号なし4byte整数×4に変換してvDに格納する。
変換した値が符号なし4byte整数の最大値以上になった場合、4294967295に修正されてvDに格納される。
レジスタバイトインデックス
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
vAa0 a1 a2 a3
vD temp=(unsigned int)(a0/2^UIMM)
if(temp>MAX_UINT) temp=MAX_UINT
if(temp<0) temp=0
<=temp
temp=(unsigned int)(a1/2^UIMM)
if(temp>MAX_UINT) temp=MAX_UINT
if(temp<0) temp=0
<=temp
<=... <=...
vpkpx vD, vA, vB
vAとvBを4byteで分けて4区画にする。vDの上8byteにはvA、下8byteにはvBが対応し、元レジスタの4byteデータを2byteに圧縮してvDへ格納する。
厳密には、4byte入力の上から7つめのbitが、2byte出力の最上位bitとなり、入力の上から1byte目を3bit右シフトした値が出力の上1 ~ 5bit目までの値となり、入力の上から2byte目を3bit右シフトした値が出力の上6 ~ 11bit目までの値となり、入力の上から3byte目を3bit右シフトした値が出力の上12 ~ 16bit目までの値となる。 C風に書くとこんな感じ。
  temp = vA << 16 | vB;
for(k = 0; k < 8; k++){
  pix = ((unsigned long)temp)[k];
  ((unsigned short*)vD)[k] = ((pix >> 24) & 1) | ((pix >> 16) & 0x1f) |
                             ((pix >> 8) & 0x1f) | (pix & 0x1f);
}
vpkshss vD, vA, vB
vA、vBを2byte符号つき整数とする。各区画の2byte整数を1byte符号つき整数に変換して、それをvDに1byte符号つき整数として格納する。vDの上8byteにvA、下8byteにvBの変換値を格納する。
なお、格納する値が符号つき1byte整数の最大値以上になった場合、127に修正され、同じく符号つき1byte整数の最小値以下になった場合は、-128に修正される。
レジスタバイトインデックス
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
vAa0 a1 a2 a3 a4 a5 a6 a7
vB b0 b1 b2 b3 b4 b5 b6 b7
vD temp=a0
if(temp<MIN_SCHAR) temp=MIN_SCHAR
if(temp>MAX_SCHAR) temp=MAX_SCHAR
<=temp
<=... <=... <=... <=... <=... <=... <=... temp=b0
if(temp<MIN_SCHAR) temp=MIN_SCHAR
if(temp>MAX_SCHAR) temp=MAX_SCHAR
<=temp
<=... <=... <=... <=... <=... <=... <=...
vpkshus vD, vA, vB
vA、vBを2byte符号つき整数とする。各区画の2byte整数を1byte符号なし整数に変換して、それをvDに1byte符号なし整数として格納する。vDの上8byteにvA、下8byteにvBの変換値を格納する。
なお、格納する値が符号なし1byte整数の最大値以上になった場合、255に修正され、0未満の値だった場合は0に修正される。
レジスタバイトインデックス
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
vAa0 a1 a2 a3 a4 a5 a6 a7
vB b0 b1 b2 b3 b4 b5 b6 b7
vD temp=a0
if(temp<0) temp=0
if(temp>MAX_UCHAR) temp=MAX_UCHAR
<=temp
<=... <=... <=... <=... <=... <=... <=... temp=b0
if(temp<0) temp=0
if(temp>MAX_UCHAR) temp=MAX_UCHAR
<=temp
<=... <=... <=... <=... <=... <=... <=...
vpkswss vD, vA, vB
vA、vBを4byte符号つき整数とする。各区画の4byte整数を2byte符号つき整数に変換して、それをvDに2byte符号つき整数として格納する。vDの上8byteにvA、下8byteにvBの変換値を格納する。
なお、格納する値が符号つき2byte整数の最大値以上になった場合、32767に修正され、同じく符号つき2byte整数の最小値以下になった場合は、-32768に修正される。
レジスタバイトインデックス
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
vAa0 a1 a2 a3
vB b0 b1 b2 b3
vD temp=a0
if(temp<MIN_SHRT) temp=MIN_SHRT
if(temp>MAX_SHRT) temp=MAX_SHRT
<=temp
<=... <=... <=... temp=b0
if(temp<MIN_SHRT) temp=MIN_SHRT
if(temp>MAX_SHRT) temp=MAX_SHRT
<=temp
<=... <=... <=...
vpkswus vD, vA, vB
vA、vBを4byte符号つき整数とする。各区画の4byte整数を2byte符号なし整数に変換して、それをvDに2byte符号なし整数として格納する。vDの上8byteにvA、下8byteにvBの変換値を格納する。
なお、格納する値が符号なし2byte整数の最大値以上になった場合、65535に修正され、0未満の場合は0に修正される。
レジスタバイトインデックス
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
vAa0 a1 a2 a3
vB b0 b1 b2 b3
vD temp=a0
if(temp<0) temp=0
if(temp>MAX_USHRT) temp=MAX_USHRT
<=temp
<=... <=... <=... temp=b0
if(temp<0) temp=0
if(temp>MAX_USHRT) temp=MAX_USHRT
<=temp
<=... <=... <=...
vpkuhum vD, vA, vB
vA、vBを2byte符号なし整数とする。各区画の2byte整数を1byte符号なし整数に変換して、それをvDに1byte符号なし整数として格納する。vDの上8byteにvA、下8byteにvBの変換値を格納する。
値を丸める必要がないのであれば、符号がある場合にも使える。
レジスタバイトインデックス
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
vAa0 a1 a2 a3 a4 a5 a6 a7
vB b0 b1 b2 b3 b4 b5 b6 b7
vD <=a0 <=... <=... <=... <=... <=... <=... <=... <=b0 <=... <=... <=... <=... <=... <=... <=...
vpkuhus vD, vA, vB
vA、vBを2byte符号なし整数とする。各区画の2byte整数を1byte符号なし整数に変換して、それをvDに1byte符号なし整数として格納する。vDの上8byteにvA、下8byteにvBの変換値を格納する。
なお、格納する値が符号なし1byte整数の最大値以上になった場合、255に修正される。
レジスタバイトインデックス
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
vAa0 a1 a2 a3 a4 a5 a6 a7
vB b0 b1 b2 b3 b4 b5 b6 b7
vD temp=a0
if(temp>MAX_UCHAR) temp=MAX_UCHAR
<=temp
<=... <=... <=... <=... <=... <=... <=... temp=b0
if(temp>MAX_UCHAR) temp=MAX_UCHAR
<=temp
<=... <=... <=... <=... <=... <=... <=...
vpkuwum vD, vA, vB
vA、vBを4byte符号なし整数とする。各区画の4byte整数を2byte符号なし整数に変換して、それをvDに2byte符号なし整数として格納する。vDの上8byteにvA、下8byteにvBの変換値を格納する。
値を丸める必要がないのであれば、符号がある場合にも使える。
レジスタバイトインデックス
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
vAa0 a1 a2 a3
vB b0 b1 b2 b3
vD <=a0 <=... <=... <=... <=b0 <=... <=... <=...
vpkuwus vD, vA, vB
vA、vBを4byte符号なし整数とする。各区画の4byte整数を2byte符号なし整数に変換して、それをvDに2byte符号なし整数として格納する。vDの上8byteにvA、下8byteにvBの変換値を格納する。
なお、格納する値が符号なし2byte整数の最大値以上になった場合、65535に修正される。
レジスタバイトインデックス
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
vAa0 a1 a2 a3
vB b0 b1 b2 b3
vD temp=a0
if(temp>MAX_USHRT) temp=MAX_USHRT
<=temp
<=... <=... <=... temp=b0
if(temp>MAX_USHRT) temp=MAX_USHRT
<=temp
<=... <=... <=...
vupkhpx vD, vB
vBを2byteで区切り、8区間に分ける。vBを上から順に、値の上1bitを1byteに符号拡張してvDの上1byteとし、 vBの次の5bitを1byteに符号なし拡張してvDの次の1byteとし、 vBの次の5bitを1byteに符号なし拡張してvDの次の1byteとし、 vBの次の5bitを1byteに符号なし拡張してvDの次の1byteとする。
このようにして、vDに4つの拡張したデータをセットする。
この命令の挙動は以下の通り。
for(k = 0; k < 4; k++){
  alpha = ( (short*)vB)[k] >> 15;
  red = ( ( (short*)vB)[k] >> 10) & 0x1f;
  green = ( ( (short*)vB)[k] >> 5) & 0x1f;
  blue = ( (short*)vB)[k] & 0x1f;

  ( (long*)vD)[k] = ( (char)alpha << 24) | ( (char)red << 16) | ( (char)green << 8) | (char)blue;
}
vupkhsb vD, vB
vBを符号つき1byte整数×16とする。vBの上の1byteから順番に、2byte符号拡張しながらvDの先頭から順に格納していく。
レジスタバイトインデックス
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
vBb0 b1 b2 b3 b4 b5 b6 b7 b8 b9 b10 b11 b12 b13 b14 b15
vD <=(short)b0 <=(short)b1 <=... <=... <=... <=... <=... <=...
vupkhsh vD, vB
vBを符号つき2byte整数×8とする。vBの上の2byteから順番に、vDの先頭から順に4byte符号拡張しながら格納していく。
レジスタバイトインデックス
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
vB b0 b1 b2 b3 b4 b5 b6 b7
vD <=(int)b0 <=(int)b1 <=(int)b2 <=(int)b3
vupklpx vD, vB
vBを2byteで区切り、8区間に分ける。vBを、上4区画を飛ばして8byte目から、値の上1bitを1byteに符号拡張してvDの上1byteとし、 vBの次の5bitを1byteに符号なし拡張してvDの次の1byteとし、 vBの次の5bitを1byteに符号なし拡張してvDの次の1byteとし、 vBの次の5bitを1byteに符号なし拡張してvDの次の1byteとする。
このようにして、vDに4つの拡張したデータをセットする。
この命令の挙動は以下の通り。
for(k = 0; k < 4; k++){
  alpha = ( (short*)vB)[k] >> 15;
  red = ( ( (short*)vB)[k] >> 10) & 0x1f;
  green = ( ( (short*)vB)[k] >> 5) & 0x1f;
  blue = ( (short*)vB)[k] & 0x1f;

  ( (long*)vD)[k + 4] = ( (char)alpha << 24) | ( (char)red << 16) | ( (char)green << 8) | (char)blue;
}
vupklsb vD, vB
vBを符号つき1byte整数×16とする。vBの上から8byte目から順番に、2byte符号拡張しながらvDの先頭から順に格納していく。
レジスタバイトインデックス
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
vBb0 b1 b2 b3 b4 b5 b6 b7 b8 b9 b10 b11 b12 b13 b14 b15
vD <=(short)b8 <=(short)b9 <=... <=... <=... <=... <=... <=...
vupklsh vD, vB
vBを符号つき2byte整数×8とする。vBの上の4byte目から順番に、vDの先頭から順に4byte符号拡張しながら格納していく。
レジスタバイトインデックス
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
vB b0 b1 b2 b3 b4 b5 b6 b7
vD <=(int)b4 <=(int)b5 <=(int)b6 <=(int)b7

ベクトル論理演算命令

SHBは4bitの符号なし値。

vand vD, vA, vB
vAとvBの論理積をvDに格納する。
vandc vD, vA, vB
vAとvBの否定との論理積をvDに格納する。
vnor vD, vA, vB
vAとvBとの論理和の否定をvDに格納する。
vor vD, vA, vB
vAとvBとの論理和をvDに格納する。
vrlb vD, vA, vB
vAとvBを1byteに分けて16区画にする。各vAの値をvBの値ぶんだけ左回転シフトした値をvDに格納する。
vrlh vD, vA, vB
vAとvBを2byteに分けて8区画にする。各vAの値をvBの値ぶんだけ左回転シフトした値をvDに格納する。
vrlw vD, vA, vB
vAとvBを4byteに分けて4区画にする。各vAの値をvBの値ぶんだけ左回転シフトした値をvDに格納する。
vslb vD, vA, vB
vBとvAを1byteに分け、16区画にする。vBの下3bit分だけvAの値をシフトしてvDへ格納する。
vslh vD, vA, vB
vA、vBを2byteに分け、8区画にする。vBの下4bitの値ぶんだけ、vAを左シフトした値をvDへ格納する。
vslh vD, vA, vB
vA、vBを4byteに分け、4区画にする。vBの下5bitの値ぶんだけ、vAを左シフトした値をvDへ格納する。
vsrab vD, vA, vB
vA、vBを1byteに分け、16区画にする。vBの下3bitの値ぶんだけ、vAを算術右シフトした値をvDへ格納する。
vsrah vD, vA, vB
vA、vBを2byteに分け、8区画にする。vBの下4bitの値ぶんだけ、vAを算術右シフトした値をvDへ格納する。
vsraw vD, vA, vB
vA、vBを4byteに分け、4区画にする。vBの下5bitの値ぶんだけ、vAを算術右シフトした値をvDへ格納する。
vsrb vD, vA, vB
vA、vBを1byteに分け、16区画にする。vBの下3bitの値ぶんだけ、vAを論理右シフトした値をvDへ格納する。
vsrh vD, vA, vB
vA、vBを2byteに分け、8区画にする。vBの下4bitの値ぶんだけ、vAを論理右シフトした値をvDへ格納する。
vsrw vD, vA, vB
vA、vBを4byteに分け、4区画にする。vBの下5bitの値ぶんだけ、vAを論理右シフトした値をvDへ格納する。
vxor vD, vA, vB
vAとvBとの排他的論理和をvDに格納する。

ベクトル比較命令

ベクトル比較命令は、Rc(Record bit)の値が1の場合(要するに命令に"."をつけるだけ)、状態レジスタcr6に比較結果を出力する。

その内容は、

下から何bit目か 3210
ベクトル比較命令1の場合:比較した全要素が条件成立01の場合:比較した全要素が条件不成立0
ベクトル領域比較命令001の場合:vcmpbfp命令の実行結果が0だった
0の場合:vcmpbfp命令の実行結果が一部0でなかった
0
となる。
vcmpbfp(.) vD, vA, vB
vAとvBで単精度浮動小数×4の比較を行い、その結果をvDに、4byte整数として格納する。
vA側の値がvB側の値より大きい場合、vDの格納先の最上bitが1に、vA側の値がvB側の値を符号反転した値より小さい場合、vDの格納先の上から1bit目が1になる。
命令に.をつけた場合、cr6にはvAの内容が全てvB ~ -1 * vBの領域内かどうかが入れられる。
この命令の挙動は以下の通り。
for(k = 0; k < 4; k++){
  lesseq = ((float*)vA)[k] <= ((float*)vB)[k];
  greatereq = ((float*)vA)[k] >= -((float*)vB)[k];

  ((long*)vD)[k] = (~lesseq << 31) | (~greatereq << 30);
}
vcmpeqfp(.) vD, vA, vB
vAとvBで単精度浮動小数×4の比較を行う。結果、値が等しいなら0xffffffffを、でなければ0x00000000を、vDの対応する領域に格納する。
命令に.をつけた場合、cr6にはvAとvBの内容が全て等しかったか、全て等しくなかったかどうかが入れられる。
この命令の挙動は以下の通り。
for(k = 0; k < 4; k++){
  ((long*)vD)[k] = ((float*)vA)[k] == ((float*)vB)[k] ? 0xffffffff : 0x0;
}
vcmpequb(.) vD, vA, vB
vAとvBで符号なし(実質符号ありでもこの命令で動く)1byte整数×16の比較を行う。結果、値が等しいなら0xffを、でなければ0x00を、vDの対応する領域に格納する。
命令に.をつけた場合、cr6にはvAとvBの内容が全て等しかったか、全て等しくなかったかどうかが入れられる。
この命令の挙動は以下の通り。
for(k = 0; k < 16; k++){
  ((char*)vD)[k] = ((unsigned char*)vA)[k] == ((unsigned char*)vB)[k] ? 0xff : 0x0;
}
vcmpequh(.) vD, vA, vB
vAとvBで符号なし(実質符号ありでもこの命令で動く)2byte整数×8の比較を行う。結果、値が等しいなら0xffffを、でなければ0x0000を、vDの対応する領域に格納する。
命令に.をつけた場合、cr6にはvAとvBの内容が全て等しかったか、全て等しくなかったかどうかが入れられる。
この命令の挙動は以下の通り。
for(k = 0; k < 8; k++){
  ((short*)vD)[k] = ((unsigned short*)vA)[k] == ((unsigned short*)vB)[k] ? 0xffff : 0x0;
}
vcmpequw(.) vD, vA, vB
vAとvBで符号なし(実質符号ありでもこの命令で動く)4byte整数×4の比較を行う。結果、値が等しいなら0xffffffffを、でなければ0x00000000を、vDの対応する領域に格納する。
命令に.をつけた場合、cr6にはvAとvBの内容が全て等しかったか、全て等しくなかったかどうかが入れられる。
この命令の挙動は以下の通り。
for(k = 0; k < 4; k++){
  ((long*)vD)[k] = ((unsigned long*)vA)[k] == ((unsigned long*)vB)[k] ? 0xffffffff : 0x0;
}
vcmpgefp(.) vD, vA, vB
vAとvBで単精度浮動小数×4の比較を行う。結果、vAの値がvBの値以上なら0xffffffffを、でなければ0x00000000を、vDの対応する領域に格納する。
命令に.をつけた場合、cr6には、全てのvAの値がvBの値以上だったか、全て未満だったかかどうかが入れられる。
この命令の挙動は以下の通り。
for(k = 0; k < 4; k++){
  ((long*)vD)[k] = ((float*)vA)[k] >= ((float*)vB)[k] ? 0xffffffff : 0x0;
}
vcmpgtfp(.) vD, vA, vB
vAとvBで単精度浮動小数×4の比較を行う。結果、vAの値がvBの値より大きいなら0xffffffffを、でなければ0x00000000を、vDの対応する領域に格納する。
命令に.をつけた場合、cr6には、全てのvAの値がvBの値より大きかったか、全て以下だったかどうかが入れられる。
この命令の挙動は以下の通り。
for(k = 0; k < 4; k++){
  ((long*)vD)[k] = ((float*)vA)[k] > ((float*)vB)[k] ? 0xffffffff : 0x0;
}
vcmpgtsb(.) vD, vA, vB
vAとvBで符号あり1byte整数×16の比較を行う。結果、vAの値がvBの値より大きいなら0xffffffffを、でなければ0x00000000を、vDの対応する領域に格納する。
命令に.をつけた場合、cr6には、全てのvAの値がvBの値より大きかったか、全て以下だったかどうかが入れられる。
この命令の挙動は以下の通り。
for(k = 0; k < 16; k++){
  ((char*)vD)[k] = ((char*)vA)[k] > ((char*)vB)[k] ? 0xff : 0x0;
}
vcmpgtsh(.) vD, vA, vB
vAとvBで符号あり2byte整数×8の比較を行う。結果、vAの値がvBの値より大きいなら0xffffffffを、でなければ0x00000000を、vDの対応する領域に格納する。
命令に.をつけた場合、cr6には、全てのvAの値がvBの値より大きかったか、全て以下だったかどうかが入れられる。
この命令の挙動は以下の通り。
for(k = 0; k < 8; k++){
  ((short*)vD)[k] = ((short*)vA)[k] > ((short*)vB)[k] ? 0xffff : 0x0;
}
vcmpgtsw(.) vD, vA, vB
vAとvBで符号あり4byte整数×4の比較を行う。結果、vAの値がvBの値より大きいなら0xffffffffを、でなければ0x00000000を、vDの対応する領域に格納する。
命令に.をつけた場合、cr6には、全てのvAの値がvBの値より大きかったか、全て以下だったかどうかが入れられる。
この命令の挙動は以下の通り。
for(k = 0; k < 4; k++){
  ((long*)vD)[k] = ((long*)vA)[k] > ((long*)vB)[k] ? 0xffffffff : 0x0;
}
vcmpgtub(.) vD, vA, vB
vAとvBで符号なし1byte整数×16の比較を行う。結果、vAの値がvBの値より大きいなら0xffffffffを、でなければ0x00000000を、vDの対応する領域に格納する。
命令に.をつけた場合、cr6には、全てのvAの値がvBの値より大きかったか、全て以下だったかどうかが入れられる。
この命令の挙動は以下の通り。
for(k = 0; k < 16; k++){
  ((char*)vD)[k] = ((unsigned char*)vA)[k] > ((unsigned char*)vB)[k] ? 0xff : 0x0;
}
vcmpgtuh(.) vD, vA, vB
vAとvBで符号なし2byte整数×8の比較を行う。結果、vAの値がvBの値より大きいなら0xffffffffを、でなければ0x00000000を、vDの対応する領域に格納する。
命令に.をつけた場合、cr6には、全てのvAの値がvBの値より大きかったか、全て以下だったかどうかが入れられる。
この命令の挙動は以下の通り。
for(k = 0; k < 8; k++){
  ((short*)vD)[k] = ((unsigned short*)vA)[k] > ((unsigned short*)vB)[k] ? 0xffff : 0x0;
}
vcmpgtuw(.) vD, vA, vB
vAとvBで符号なし4byte整数×4の比較を行う。結果、vAの値がvBの値より大きいなら0xffffffffを、でなければ0x00000000を、vDの対応する領域に格納する。
命令に.をつけた場合、cr6には、全てのvAの値がvBの値より大きかったか、全て以下だったかどうかが入れられる。
この命令の挙動は以下の通り。
for(k = 0; k < 4; k++){
  ((long*)vD)[k] = ((unsigned long*)vA)[k] > ((unsigned  long*)vB)[k] ? 0xffffffff : 0x0;
}

ベクトル撹拌命令

わかりにくい命令ばかりだが、データ整列に役に立つ。

lvsl vD, rA, rB
インデックスアドレスの下4bitの値をベースとして、1バイトごとに値をインクリメントして格納する。説明を見ただけでは何の役に立つのかさっぱりわからない命令。lvx及びvpermと組み合わせて使うことで、メモリ境界が不明のアドレスから正しいオーダーでデータをロードするのに役に立つ。もちろん、即値の生成にも使える。
生成できる数値配列は以下の通り。
rA+rBの下4bitの値 ベクトルレジスタ中の各バイトに格納される値
0 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
1 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
2 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
3 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
4 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
5 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
6 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
7 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
8 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
9 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
10 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
11 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
12 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
13 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
14 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
15 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30
ちなみに、この命令は基本的にメモリアクセス演算ユニットに組み込まれているので、ベクトル演算ユニットの命令ではない。
lvsr vD, rA, rB
16からインデックスアドレスの下4bitの値を引いた値をベースとして、1バイトごとに値をインクリメントして格納する。lvslと同じく、説明だけではさっぱりわからない。stvx及びvpermと組み合わせて使うことで、メモリ境界が不明のアドレスへ正しいオーダーでデータをストアするのに役に立つ。もちろん、即値の生成にも使える。
生成できる数値配列は以下の通り。
rA+rBの下4bitの値 ベクトルレジスタ中の各バイトに格納される値
0 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
1 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30
2 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
3 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
4 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
5 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
6 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
7 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
8 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
9 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
10 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
11 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
12 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
13 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
14 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
15 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
ちなみに、この命令は基本的にメモリアクセス演算ユニットに組み込まれているので、ベクトル演算ユニットの命令ではない。
vmrghb vD, vA, vB
vA、vBを1byteで区切り、16区画に分割する。vA、vBの上8区画を、上から交互にvDに格納していく。
レジスタバイトインデックス
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
vAa0 a1 a2 a3 a4 a5 a6 a7 a8 a9 a10 a11 a12 a13 a14 a15
vBb0 b1 b2 b3 b4 b5 b6 b7 b8 b9 b10 b11 b12 b13 b14 b15
vD <=a0 <=b0 <=a1 <=... <=... <=... <=... <=... <=... <=... <=... <=... <=... <=... <=... <=...
vmrghh vD, vA, vB
vA、vBを2byteで区切り、8区画に分割する。vA、vBの上4区画を、上から交互にvDに格納していく。
レジスタバイトインデックス
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
vAa0 a1 a2 a3 a4 a5 a6 a7
vB b0 b1 b2 b3 b4 b5 b6 b7
vD <=a0 <=b0 <=a1 <=... <=... <=... <=... <=...
vmrghw vD, vA, vB
vA、vBを4byteで区切り、4区画に分割する。vA、vBの上2区画を、上から交互にvDに格納していく。
レジスタバイトインデックス
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
vAa0 a1 a2 a3
vB b0 b1 b2 b3
vD <=a0 <=b0 <=a1 <=b1
vmrglb vD, vA, vB
vA、vBを1byteで区切り、16区画に分割する。vA、vBの下8区画を、上から交互にvDに格納していく。
レジスタバイトインデックス
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
vAa0 a1 a2 a3 a4 a5 a6 a7 a8 a9 a10 a11 a12 a13 a14 a15
vBb0 b1 b2 b3 b4 b5 b6 b7 b8 b9 b10 b11 b12 b13 b14 b15
vD <=a8 <=b8 <=a9 <=... <=... <=... <=... <=... <=... <=... <=... <=... <=... <=... <=... <=...
vmrglh vD, vA, vB
vA、vBを2byteで区切り、8区画に分割する。vA、vBの下4区画を、上から交互にvDに格納していく。
レジスタバイトインデックス
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
vAa0 a1 a2 a3 a4 a5 a6 a7
vB b0 b1 b2 b3 b4 b5 b6 b7
vD <=a4 <=b4 <=a5 <=... <=... <=... <=... <=...
vmrglw vD, vA, vB
vA、vBを2byteで区切り、4区画に分割する。vA、vBの下2区画を、上から交互にvDに格納していく。
レジスタバイトインデックス
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
vAa0 a1 a2 a3
vB b0 b1 b2 b3
vD <=a2 <=b2 <=a3 <=b3
vperm vD, vA, vB, vC
説明を読むより図を見た方が早い。
各レジスタを1バイト単位で区切る。vCの各要素の下5bitを見て、16未満ならvAの対応するインデックスの要素を、16以上ならvCの要素から16引いたインデックスにあるvBの要素を取り出し、新たなベクトルとする。
レジスタバイトインデックス
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
vAa0 a1 a2 a3 a4 a5 a6 a7 a8 a9 a10 a11 a12 a13 a14 a15
vBb0 b1 b2 b3 b4 b5 b6 b7 b8 b9 b10 b11 b12 b13 b14 b15
vCc0 c1 c2 c3 c4 c5 c6 c7 c8 c9 c10 c11 c12 c13 c14 c15
vD temp=c0&31
<=(temp<16?a[temp]:b[temp-16])
temp=c1&31
<=(temp<16?a[temp]:b[temp-16])
<=... <=... <=... <=... <=... <=... <=... <=... <=... <=... <=... <=... <=... <=...
vsel vD, vA, vB, vC
vA、vB、vCを1bitに分け、128区画にする。vCの値が0の場合、vAの値を取り出す。vCの値が1の場合、vBの値を取り出す。取り出した値をvDへ格納する。
レジスタビットインデックス
0 1 ... 126 127
vAa0 a1 ... a126 a127
vBb0 b1 ... b126 b127
vCc0 c1 ... c126 c127
vD <=(c0==0?a0:b0) <=(c1==0?a1:b1) ... <=(c126==0?a126:b126) <=(c127==0?a127:b127)
vsl vD, vA, vB
vBを1byteに分け、16区画にする。vBの一番下の1byteの下3bitの値ぶんだけ、vAを左シフトした値をvDへ格納する。vBの各byteの下3bitが一番下の1byteの下3bitの内容と同じでない場合は、シフト命令の後にvDへ格納される値は不定になる
vsldoi vD, vA, vB, SHB
説明より図を見た方がわかりやすい。
vAの後ろにvBをくっつけた32byteの長さのベクトルの、上からSHB byte目から下はSHB+15byte目までを取り出してvDへ格納する。
レジスタバイトインデックス
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
vAa0 a1 a2 a3 a4 a5 a6 a7 a8 a9 a10 a11 a12 a13 a14 a15
vBb0 b1 b2 b3 b4 b5 b6 b7 b8 b9 b10 b11 b12 b13 b14 b15
0 1 ... 15 16 17 ... 31
(vC)c0=a0 c1=a1 ... c15=a15 c16=b0 c17=b1 ... c31=b15
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
vD <=c[SHB] <=c[SHB+1] <=c[SHB+2] <=... <=... <=... <=... <=... <=... <=... <=... <=... <=... <=... <=... <=...
vslo vD, vA, vB
vAを、vBの下7bitの下3bitを切り捨てた値分だけ左シフトして、vDに格納する。
vspltb vD, vB, UIMM
vBを1byteに分け、16区画にする。左からUIMM番目のvBの1byteを、vDの1byte×16区画に格納する。
レジスタバイトインデックス
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
vBb0 b1 b2 b3 b4 b5 b6 b7 b8 b9 b10 b11 b12 b13 b14 b15
vD <=b[UIMM] <=b[UIMM] <=... <=... <=... <=... <=... <=... <=... <=... <=... <=... <=... <=... <=... <=...
vsplth vD, vB, UIMM
vBを2byteに分け、8区画にする。左からUIMM番目のvBの2byteを、vDの2byte×8区画に格納する。
レジスタバイトインデックス
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
vB b0 b1 b2 b3 b4 b5 b6 b7
vD <=b[UIMM] <=b[UIMM] <=... <=... <=... <=... <=... <=...
vspltisb vD, SIMM
SIMMの値を符号付き1byte値に拡張してから、vDの1byte×16区画に格納する。
レジスタバイトインデックス
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
vD <=SIMM <=SIMM <=... <=... <=... <=... <=... <=... <=... <=... <=... <=... <=... <=... <=... <=...
vspltish vD, SIMM
SIMMの値を符号付き2byte値に拡張してから、vDの2byte×8区画に格納する。
レジスタバイトインデックス
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
vD <=SIMM <=SIMM <=... <=... <=... <=... <=... <=...
vspltisw vD, SIMM
SIMMの値を符号付き4byte値に拡張してから、vDの4byte×4区画に格納する。
レジスタバイトインデックス
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
vD <=SIMM <=SIMM <=SIMM <=SIMM
vspltw vD, vB, UIMM
vBを4byteに分け、4区画にする。左からUIMM番目のvBの4byteを、vDの4byte×4区画に格納する。
レジスタバイトインデックス
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
vB b0 b1 b2 b3
vD <=b[UIMM] <=b[UIMM] <=b[UIMM] <=b[UIMM]
vsr vD, vA, vB
vBを1byteに分け、16区画にする。vBの一番下の1byteの下3bitの値ぶんだけ、vAを右シフトした値をvDへ格納する。vBの各byteの下3bitが、一番下の1byteの下3bitの内容と同じでない場合は、シフト命令の後にvDへ格納される値は不定になる
vsro vD, vA, vB
vAを、vBの下7bitの下3bitを切り捨てた値分だけ右シフトして、vDに格納する。

データ転送命令

他のPowerPCのロードストア命令と異なり、ほとんどのベクトルレジスタ用ロードストアは、アラインがそろってなければ正常なロードストアはできない。アラインがそろってない場合のロードストアをする場合、アラインをそろえるために下数bitを無視してしまう。

また、AltiVecのロードストア命令は非常に特殊な振る舞いをするので注意。

lvebx vD, rA, rB
rA(r0の場合、0)とrBの和のアドレスのデータを1byte読み込んでvDの1byteに書き込む。ただし、vDへの書き込み場所は、読み出すアドレスによって変わる。読み出すアドレスの下4bitの値をshとすると、vDの下から(15 - sh)番目の1byteに、データをロードする。リトルエンディアンモードでは、vDの下からsh番目の1byteにロードする。ロードされた領域以外は未定義の値が入るので注意。
ビッグエンディアン時の命令をC風に書くとこんな感じ。
addr = (rA  != r0 ? rA : 0)+ rB;
sh = 15 - (addr & 0x15);

vD = (vD & ~(0xff << sh)) | (unsigned char)(*addr) << sh;
lvehx vD, rA, rB
rA(r0の場合、0)とrBの和のアドレスのデータを2byte読み込んでvDの2byteに書き込む。ただし、vDへの書き込み場所は、読み出すアドレスによって変わる。読み出すアドレスの下4bitの値をshとすると、vDの下から(7 - sh / 2)番目の2byteに、データをロードする。リトルエンディアンモードでは、vDの下からsh / 2番目の2byteにロードする。ロードされた領域以外は未定義の値が入るので注意。
この命令は、ロード先アドレスの下1bitを無視する。
ビッグエンディアン時の命令をC風に書くとこんな感じ。
addr = ( (rA  != r0 ? rA : 0)+ rB) & ~0x1;
sh = 7 - (addr & 0x15) / 2;

vD = (vD & ~(0xffff << sh)) | (unsigned short)(*addr) << sh;
lvewx vD, rA, rB
rA(r0の場合、0)とrBの和のアドレスのデータを4byte読み込んでvDの4byteに書き込む。ただし、vDへの書き込み場所は、読み出すアドレスによって変わる。読み出すアドレスの下4bitの値をshとすると、vDの下から(3 - sh / 4)番目の4byteに、データをロードする。リトルエンディアンモードでは、vDの下からsh / 4番目の4byteにロードする。ロードされた領域以外は未定義の値が入るので注意。
この命令は、ロード先アドレスの下2bitを無視する。
ビッグエンディアン時の命令を C風に書くとこんな感じ。
addr = ( (rA  != r0 ? rA : 0)+ rB) & ~0x3;
sh = 3 - (addr & 0x15) / 4;

vD = (vD & ~(0xffffffff << sh)) | (unsigned long)(*addr) << sh;
lvx vD, rA, rB
rA(r0の場合、0)とrBの和のアドレスのデータを16byte読み込んでvDに書き込む。
この命令は、ロード先アドレスの下4bitを無視する。
lvxl vD, rA, rB
基本動作はlvxと同じ。ただし、この命令でアクセスされたメモリは、当分使われないものと見なされ、キャッシュから取り除かれる…らしい。
stvebx vD, rA, rB
vDの1byteのデータをrA(r0の場合、0)とrBの和のアドレスへ1byte書き込む。ただし、書き出すデータ位置は、書き出しアドレスによって変わる。書き出すアドレスの下4bitの値をshとすると、vDの下から(15 - sh)番目の1byteを書き出す。リトルエンディアンモードでは、vDの下からsh番目の1byteを書き出す。
ビッグエンディアン時の命令をC風に書くとこんな感じ。
addr = (rA  != r0 ? rA : 0)+ rB;
sh = 15 - (addr & 0x15);

*(unsigned char*)addr = (unsigned char)(vD >> sh);
stvehx vD, rA, rB
vDの2byteのデータをrA(r0の場合、0)とrBの和のアドレスへ2byte書き込む。ただし、書き出すデータ位置は、書き出しアドレスによって変わる。書き出すアドレスの下4bitの値をshとすると、vDの下から(7 - sh / 2)番目の2byteを書き出す。リトルエンディアンモードでは、vDの下からsh / 2番目の2byteを書き出す。
この命令は、ストア先アドレスの下1bitを無視する。
ビッグエンディアン時の命令をC風に書くとこんな感じ。
addr = (rA  != r0 ? rA : 0)+ rB;
sh = 7 - (addr & 0x15) / 2;

*(unsigned short*)addr = (unsigned short)(vD >> sh);
stvewx vD, rA, rB
vDの4byteのデータをrA(r0の場合、0)とrBの和のアドレスへ4byte書き込む。ただし、書き出すデータ位置は、書き出しアドレスによって変わる。書き出すアドレスの下4bitの値をshとすると、vDの下から(3 - sh / 4)番目の4byteを書き出す。リトルエンディアンモードでは、vDの下からsh / 4番目の4byteを書き出す。
この命令は、ストア先アドレスの下2bitを無視する。
ビッグエンディアン時の命令をC風に書くとこんな感じ。
addr = (rA  != r0 ? rA : 0)+ rB;
sh = 3 - (addr & 0x15) / 4;

*(unsigned long*)addr = (unsigned long)(vD >> sh);
stvx vD, rA, rB
vDのデータをrA(r0の場合、0)とrBの和のアドレスへ16byte書き込む。ビッグエンディアンモードではそのまま書き出し。リトルエンディアンモードでは、上8byteを下8byte、下8byteを上8byteとして書き出す。
この命令は、ストア先アドレスの下4bitを無視する。
stvxl vD, rA, rB
基本動作はstvxと同じ。この命令でアクセスされたメモリは、しばらく使われないものとして、キャッシュから取り除かれる…らしい。

状態制御命令

VSCR(ベクトル状態/制御レジスタ)にアクセスする命令。

mfvscr vD
VSCRの内容を取り出してvDに転送。プログラマがAltiVec命令を使用する場合、必ずこの命令を読んでVSCRの内容を退避すること。また、AltiVec命令の使用が終了した場合には、VSCRの内容をmtvscrで戻すこと。
mtvscr vD
vDの内容をVSCRへ転送する。mfvscrとセットで使う。

ストレージ制御命令

キャッシュへのデータのプリフェッチなどをコントロールする命令セット。

あらかじめ使用するデータをキャッシュへロードしておくことで、後のロード/ストア命令の高速化をはかることができる。

STRMは2bitの符号なし整数。

dstdststといったプリフェッチ命令の2番目の汎用レジスタに入力するデータのフォーマットは以下の通り。

ストレージコントロールのデータフォーマット
上から何bit目からか データの内容
3 000
8 5bitの符号なし整数(ただし、0は32と識別される)。1ブロックのサイズが16byteベクトル何個分であるか。
16 8bitの符号なし整数(ただし、0は256と識別される)。ブロックの数
31 16bitの符号あり整数(ただし、0は32768と識別される)。あるブロックから、次にアクセスされるブロックまでのアドレスの差。基本的にはどんな値でも入力できるが、16バイト境界が最も効率がいい。
dss STRM
STRM番目のストリームの行っているデータのプリフェッチを止める。
dssall
全てのストリームの行っているデータのプリフェッチを止める。
dst rA, rB, STRM
STRM番目のストリームを使用して、rAのアドレスから、rBに入力された情報に基づいて、プリフェッチを行う。非常にアクセスされる回数や局所性が多いデータに対しては、dsttよりこちらの命令を使うべきである。
dstt rA, rB, STRM
STRM番目のストリームを使用して、rAのアドレスから、rBに入力された情報に基づいて、プリフェッチを行う。この命令でプリフェッチされたデータは、1次から取り除かれる時に、2、3次キャッシュへ退避されず、メモリまで退避される。あまり参照されず、局所性もないようなら、dstよりこの命令を使うべきである。
dstst rA, rB, STRM
STRM番目のストリームを使用して、rAのアドレスから、rBに入力された情報に基づいて、ストア命令向けのプリフェッチを行う。何度か書きこまれ、局所性のあるデータに対しては、dststtよりこちらの命令を使うべきである。
dststt rA, rB, STRM
STRM番目のストリームを使用して、rAのアドレスから、rBに入力された情報に基づいて、ストア命令向けのプリフェッチを行う。この命令でプリフェッチされたデータは、1次から取り除かれる時に、2、3次キャッシュへ退避されず、メモリまで退避される。あまり書きこまれず、局所性もないようなら、dststよりこちらの命令を使うべきである。

戻る