17. ベクトル並べ替え命令¶
ベクトル要素間でデータを並べ替えるための並べ替え命令が定義されている。
17.1. 整数スカラ移動命令¶
整数スカラ読み書き命令は、スカラの整数レジスタx
と、ベクトルレジスタの要素0の値を移動するための命令である。この命令はLMULとベクトルレジスタグループの設定を無視する。
vmv.x.s rd, vs2 # rd = vs2[0] (rs1=0)
vmv.s.x vd, rs1 # vd[0] = rs1 (vs2=0)
vmv.x.s
命令はベクトルレジスタの要素0から1つのSEW長の要素をコピーして、整数レジスタに書き込む。SEW
>
XLENであれば、XLENビットの最下位ビットが書き込まれ、SEW-XLENビットの上位ビットは無視される。SEW
< XLENであれば、その値はXLENビットまでゼロ拡張されてコピーされる。
vmv.s.x
命令は、スカラ整数レジスタの値を書き込みベクトルレジスタの要素0にコピーする。SEW
<
XLENであれば、SEWビット幅の下位ビットがコピーされ、XLEN-SEWビットの上位ビットは無視される。SEW
>
XLENであれば、値はSEWビットまでゼロ拡張される。書き込みベクトルレジスタの他の要素(0
< index < VLEN/SEW)はゼロが設定される。 vstart
≥ vl
の場合、書き込みベクトルレジスタに対する操作は行われない。
結果とし、vl
=0の場合、vstart
の値に関わらず書き込みベクトルレジスタグループに対するデータの更新は行われない。
エンコーディングでは、vmv.x.s
and vmv.s.x
のマスクされたバリエーション(vm=0
)の命令は予約されている。
17.2. 浮動小数点スカラ移動命令¶
浮動小数点スカラ読み書き命令は、スカラの浮動小数点レジスタf
と、ベクトルレジスタの要素0の値を移動するための命令であるうこの命令はLMULとベクトルレジスタグループの設定を無視する。
vfmv.f.s rd, vs2 # rd = vs2[0] (rs1=0)
vfmv.s.f vd, rs1 # vd[0] = rs1 (vs2=0)
vfmv.f.s
命令はベクトルレジスタの要素0から1つのSEW長の要素をコピーして、浮動小数点レジスタに書き込む。SEW
>
FLENであれば、FLENビットの最下位ビットが書き込まれ、SEW-FLENビットの上位ビットは無視される。SEW
< FLENであれば、その値はFLENビットにNaN Boxing(1拡張)される。
vfmv.s.f
命令は、スカラ浮動小数点レジスタの値を書き込みベクトルレジスタの要素0にコピーする。SEW
<
FLENであれば、SEWビット幅の下位ビットがコピーされ、FLEN-SEWビットの上位ビットは無視される。SEW
>
FLENであれば、値はSEWビットまでNaN-Boxing(1拡張)される。書き込みベクトルレジスタの他の要素(0
< index < VLEN/SEW)はゼロが設定される。 vstart
≥ vl
の場合、書き込みベクトルレジスタに対する操作は行われない。
結果とし、vl
=0の場合、vstart
の値に関わらず書き込みベクトルレジスタグループに対するデータの更新は行われない。
エンコーディングでは、vfmv.f.s
and vfmv.s.f
のマスクされたバリエーション(vm=0
)の命令は予約されている。
17.3. ベクトルスライド命令¶
ベクトルの要素の位置を変更するための命令が定義されている。
レジスタのギャザー命令を使用するより、スライド操作はより効率的に実装することができる。実装ではvslideup
とvslidedown
命令のための特定のOFFSET値に最適化することができる。特に、オフセットの値が2の累乗である場合は他のオフセットよりも全体的に高速な実装を実現できる。
vslideup
, vslidedown
, vslide1up
,
vslide1down
命令のすべてでは、vstart
≥
vl
であれば、命令は何も実行せず、書き込みベクトルレジスタの値は更新されない。
結果として、vl
=0であれば、vstart
の値に関わらず書き込みベクトルレジスタグループは更新されない。
マスク要素\(i\)が書き込み要素\(i\)を制御しているスライド命令はマスクされる。
17.3.1. ベクトルスライドアップ命令¶
vslideup.vx vd, vs2, rs1, vm # vd[i+rs1] = vs2[i]
vslideup.vi vd, vs2, uimm[4:0], vm # vd[i+uimm] = vs2[i]
vslideup
命令では、vl
の値は書き込まれるベクトルの最大要素の数を示している。書き込みレジスタの開始インデックス(OFFSET)は符号なし整数として整数x
レジスタに格納しておき、rs1
として参照するか、5ビットのサイズまでであれば即値命令を使用して指定できる。
XLEN >
SEWであるならば、SEWビットは切り取られない。マスクされておらず、かつOFFSET
< vl
ならばOFFSETからvl
-1までの要素は書き込まれる。
vslideup命令での書き込みベクトル要素の動作
OFFSETはスライドアップの量であり、xレジスタもしくは5ビットの即値で与えられる。
0 < i < max(vstart, OFFSET) 変化なし
max(vstart, OFFSET) <= i < vl マスクが有効ならばvd[i] = vs2[i-OFFSET]
そうでなければ変化なし
vl <= i < VLMAX テール要素。変更なし。
vslideup
の書き込みベクトルレジスタグループとソースベクトルレジスタグループとオーバラップすることはできなない。操作がマスクされてベクトルマスクレジスタとオーバラップしないならば良いが、そうでなければ不正命令例外が発生する。
オーバラップしない条件は、入力ベクトルに対するWARハザードの発生を抑止する目的と、非ゼロのvstart
から再開するためである。
17.3.2. ベクトルストライドダウン命令¶
vslidedown.vx vd, vs2, rs1, vm # vd[i] = vs2[i+rs1]
vslidedown.vi vd, vs2, uimm[4:0], vm # vd[i] = vs2[i+uimm]
vslidedown
命令では、vl
の値はいくつの書き込み先要素に書き込みが行われるかを示す。
vslidedownの要素iのソース要素の動作
0 <= i+OFFSET < VLMAX vs2[i+OFFSET]を読み出す。
VLMAX <= i+OFFSET 0として読みだされる。
vslidedownの要素iの書き込み要素の動作
0 < i < vstart 変更なし。
vstart <= i < vl マスクが有効ならばアップデートされる。そうでなければアップデートされない。
vl <= i < VLMAX 変更なし。
17.3.3. ベクトルSlide1up命令¶
ベクトルのスライド命令に対するバリエーションとして、要素1つ分のみベクトルをスライド可能だが、空いた要素に対してスカラの整数を挿入可能な命令を定義する。
vslide1up.vx vd, vs2, rs1, vm # vd[0]=x[rs1], vd[i+1] = vs2[i]
vslide1up
命令はx
レジスタ引数を取り、書き込みベクトルレジスタの要素0番がアクティブであればその値を挿入し、そうでなければその書き込み要素は変化しない。XLEN
< SEWであれば、値はSEWビットまで符号拡張される。XLEN >
SEWであれば、SEWビット分の値がコピーされ、SEW-XLENビット分の値は無視される。
残っているアクティブなvl
-1個の要素はソースベクトルレジスタのインデックスiから書き込みベクトルレジスタグループのi+1要素にコピーされる。
vl
レジスタは書き込みベクトルレジスタ要素のうちいくつの要素に書き込みが行われるかを示しており、テールの要素はゼロが設定される。
vslide1upの動作
i < vstart 変化なし
0 = i = vstart マスクが有効ならば vd[i] = x[rs1]、そうでなければ変化なし。
max(vstart, 1) <= i < vl マスクが有効ならば vd[i] = vs2[i-1]、そうでなければ変化なし。
vl <= i < VLMAX テール要素。 変更なし。
vslide1up
命令は、マスクレジスタがマスクされており、書き込み先ベクトルレジスタとオーバラップしてはならない。そうでなければ、不正命令例外が発生する。
17.3.4. ベクトルSlide1down命令¶
vslide1down
命令はアクティブなベクトル要素のうち最初のvl
-1個のアクティブの要素をi+1のソースベクトルレジスタインデックスから書き込みベクトルレジスタグループのiのインデックスにコピーする。
vl
レジスタは書き込みベクトルレジスタ要素のうちいくつの要素に書き込みが行われるかを示しており、テールの要素の値は変更されない。
vslide1down.vx vd, vs2, rs1, vm # vd[i] = vs2[i+1], vd[vl-1]=x[rs1]
vslide1down
命令はx
レジスタ引数を取り、書き込みベクトルレジスタの要素vl
-1番がアクティブであればその値を挿入し、そうでなければその書き込み要素は変化しない。XLEN
< SEWであれば、値はSEWビットまでゼロ拡張される。XLEN >
SEWであれば、SEWビット分の値がコピーされ、SEW-XLENビット分の値は無視される。
vslide1downの動作
i < vstart 変化しない
vstart <= i < vl-1 マスクが有効ならばvd[i] = vs2[i+1]。そうでなければ変化なし。
vstart <= i = vl-1 マスクが有効ならばvd[vl-1] = x[rs1]。そうでなければ変化なし。
vl <= i < VLMAX テール要素。変更なし。
vslide1down
命令はメモリを使用せずに、他のベクトルレジスタを汚すことなく値をベクトルレジスタにロードすることができる。これはデバッガがベクトルレジスタの値をデバッグするときに使用でるが、非常に低速であり、またvslide1down
命令を何度も発行する必要がある。
17.4. ベクトルレジスタギャザー命令¶
ベクトルレジスタギャザー命令は最初のソースベクトルレジスタグループから2番目のソースベクトルレジスタグループが示す場所のデータを読み込む。2番目のベクトルに入っているインデックス値は符号なし整数として扱われる。ソースベクトルは、vl
の値に関わらず、index
<
VLMAXの範囲で読み込むことができる。書き込むことのできるレジスタ数はvl
で与えられ、vl
以降の書き込みベクトルレジスタの値は変更されない。この演算はマスクされることができる。
vrgather.vv vd, vs2, vs1, vm # vd[i] = (vs1[i] >= VLMAX) ? 0 : vs2[vs1[i]];
指定したインデックスが範囲外である場合(vs1[i]
>
VLMAX)、要素の値としてゼロが返される。
ベクトル - スカラおよびベクトル -
即値の形式をとることができる。これらの命令では、ソースベクトルレジスタからインデックスを読み込み、ベクトルレジスタの最初の位置からvl
この要素を書き込む。スカラレジスタに格納されているインデックスの値および即値の値は符号なし整数として扱われる。
この命令の形式は、任意のベクトル要素を、すべてのベクトルに対して展開するために使用できる。
vrgather.vx vd, vs2, rs1, vm # vd[i] = (x[rs1] >= VLMAX) ? 0 : vs2[x[rs1]]
vrgather.vi vd, vs2, uimm, vm # vd[i] = (uimm >= VLMAX) ? 0 : vs2[uimm]
任意のvrgather
命令では、書き込みベクトルレジスタぐルールはマスクレジスタを含めて書き込みベクトルレジスタとオーバラップしてはならない。そうでなければ、不定命令例外が発生する。
SEW=8の場合、vgather.vv
命令はベクトル要素0-255のみが参照可能である。
17.5. ベクトル圧縮命令¶
ベクトル圧縮命令はソースベクトルレジスタグループからベクトルマスクレジスタにより選択された要素を、書き込みベクトルレジスタグループの先頭から連続した要素に並べ替える。
vcompress.vm vd, vs2, vs1 # vs1が有効なマスクであるvs2の要素を圧縮してvd2に書き込む。
vs1
により指定されるベクトルマスクレジスタは、最初のvl
この要素を使用してvs2
ベクトルの要素を抽出し連続する要素にパックし、vd
の先頭から書き込む。任意の残されたvd
の値は変更されない。
vcompress命令の使用例
1 1 0 1 0 0 1 0 1 v0
8 7 6 5 4 3 2 1 0 v1
1 2 3 4 5 6 7 8 9 v2
vcompress.vm v2, v1, v0
1 2 3 4 8 7 5 2 0 v2
vcompress
はマスクされない命令(vm=1
)としてエンコードされる。マスクされる命令(vm=0
)のエンコードは予約である。
書き込みベクトルレジスタグループは、ソースベクトルレジスタ及びソースベクトルマスクレジスタとオーバラップしてはならないという制約がある。そうでなければ、不正命令例外が発生する。
vcompress
命令の例外は、常にvstart
が0であるとして通知される。vstart
非ゼロのままでvcompress
命令を実行すると、不正命令例外が発生する。
不可能ではないものの、vcompress
命令はvstart
がゼロでないとして最も再開が難しい命令の非辰である。つまり、実装はそのような動作はしないものとして実装するか、その代わりに要素0から再開するものとして実装する。これは、vstart
書き込みレジスタの要素はすでにアップデートされているものと仮定していることを意味する。
17.6 全体ベクトルレジスタ移動命令¶
vmv<nf>r.v
命令は現在のvl
およびvtype
レジスタの設定を無視してすべてのベクトルレジスタ(例えば、すべてのVLENビット)をコピーする。すべてのベクトルレジスタをコピーすることも可能である。
この命令はコンパイラがベクトルレジスタをvl
およびvtype
を使用せずにシャッフルすることを助けるための命令である。
この命令はOPIVI命令としてエンコードされる。コピーされるベクトルレジスタの数はsimmフィールドの最下位ビットとしてエンコードされ、メモリアクセス命令のnfフィールドと同様である。simmフィールドの上位ビットはゼロを設定しなければならず、他のエンコーディングは予約されている。nf
の値は1,
2, 4, 8レジスタのどれかを指定しなければならない。
将来の拡張では移動することのできるレジスタの数を上記以外でもサポートする予定である。しかし、現在ではnfが3, 5, 6, 7の場合のエンコーディングは予約されている。
この命令はvsmul命令と同様のエンコーディングをfunct6で使用しているが、即値オペランドを持っており、アンマスクされたバージョンしか定義されていない(vm=1
)。エンコーディングは関連したvmerge
のエンコーディングと近いものを選択しており、vsmul
命令と違い即値の形式の利点を活用している。
ソースレジスタと書き込みレジスタはベクトルレジスタグループサイズにアラインしたアドレスでなければならない。
将来の拡張では、このアラインの制約を除去する予定である。
vd
がvs2
と同じである場合、この命令はNOPである。