FPGA開発日記

カテゴリ別記事インデックス https://msyksphinz.github.io/github_pages , English Version https://fpgadevdiary.hatenadiary.com/

RISC-Vベクトル拡張仕様書 v1.0 を読み直す (24. ベクトルデータ移動命令)

RISC-Vベクトル拡張仕様書の読み直し。次はベクトルデータ移動命令。圧縮や全体移動などのいろんな命令がある。

github.com

github.com


16.3. ベクトルレジスタギャザー命令

ベクトル・レジスタ・ギャザー命令は、第2のソースベクトルレジスタグループによって与えられる位置から第1のソースベクトルレジスタグループの要素を読み出します。 第2ベクトルのインデックス値は、符号なし整数として扱われます。 ソースベクトルは、vl にかかわらず、任意のインデックス < VLMAX で読み取ることができます。 書き込みレジスタに書き込む最大要素数は vl で与えられ、vl を過ぎた残りの要素は現在の末尾要素のポリシ (Tail Agnostic とVector Mask Agnostic vta と vma節) に従って処理されます。 この操作はマスクすることができ、非アクティブな要素に対しては、マスク undisturbed/agnostic ポリシに従います。

vrgather.vv vd, vs2, vs1, vm # vd[i] = (vs1[i] >= VLMAX) ? 0 : vs2[vs1[i]];
vrgatherei16.vv vd, vs2, vs1, vm # vd[i] = (vs1[i] >= VLMAX) ? 0 : vs2[vs1[i]];

vrgather.vv 形式では、データとインデックスの両方に SEW/LMUL を使用しています。 また、vrgatherei16.vv 形式では、vs2 のデータには SEW/LMUL を使用しますが、 vs1 のインデックスには EEW=16 と EMUL = (16/SEW)*LMUL を使用します。

Note: SEW=8の場合、vrgather.vv は0~255のベクトル要素しか参照できません。 また,vrgatherei16 形式では,64K 個の要素のインデックスを作成することができ, SEW > 16 の場合にインデックスを保持するために必要なレジスタの容量を減らすために使用することもできます。 要素のインデックスが範囲外の場合 ( vs1[i] ≥ VLMAX )、要素の値は 0 を返します。

レジスタギャザーのベクトルスカラ形式とベクトル即値形式も用意されています。 これらは、与えられたインデックスでソース・ベクトルから1つの要素を読み、この値を書き込みベクトルレジスタの最初のアクティブの要素に書き込みます。 スカラレジスタのインデックス値と、XLENビットまでゼロ拡張された即値は、符号なし整数として扱われます。 XLEN > SEWの場合,インデックス値はSEWビットまで切り捨てられません。

Note: これらの形式では、任意のベクトル要素をベクトル全体に「分散」することができます。

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 命令では、書き込みベクトルレジスタグループはソースベクトルレジスタグループとオーバーラップすることはできません。

16.4. ベクトル圧縮命令

ベクトル圧縮命令は、ソースベクトルレジスタ群からベクトルマスクレジスタによって選択された要素を、 書き込みベクトルレジスタ群の先頭の連続した要素にパックすることができます。

  vcompress.vm vd, vs2, vs1  # vs1で有効なvs2の要素をvdに圧縮する

vs1 で指定されたベクトルマスクレジスタは、ベクトルレジスタグループ vs2 の最初の vl 要素のうち、 どの要素を抽出して、ベクトルレジスタ vd の先頭の連続した要素にパックすべきかを示します。 vd の残りの要素は、現在の末尾要素ポリシ (Tail Agnostic とVector Mask Agnostic vta と vma節) に従って、末尾要素として扱われます。

    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)は予約されています。

書き込みベクトルレジスタグループはソースベクトルレジスタグループやソースマスクレジスタと重なることはできません。

非ゼロの vstart で vcompress 命令を実行すると、不正命令例外が発生します。

Note: 可能ではありますが、vcompress は非ゼロの vstart で再起動するのがより困難な命令の一つであるため、 実装ではこれを行わずに要素 0 から再起動することを想定しています。

16.4.1. vdecompress の合成

逆の操作を行う vdecompress 命令は定義されていませんが、この操作はiota命令とマスク付き vrgather 命令を用いて合成できます。

    `vdecompress` の所望の動作
      7 6 5 4 3 2 1 0     # vid

            e d c b a     # パッキングされたベクトルの5要素
      1 0 0 1 1 1 0 1     # 8要素のベクトルマスク
      p q r s t u v w     # vdecompress実行前の書き込みレジスタ

      e q r d c b v a     # vdecompress実行後
     # v0はマスクを保持している
     # v1はパックデータを保持している
     # v11は展開されたベクトルと結果を保持している
     viota.m v10, v0                 # v0のマスクを使用してiotaを実行する
     vrgather.vv v11, v1, v10, v0.t  # 書き込みレジスタを展開する
   p q r s t u v w    # v11書き込みレジスタ
         e d c b a    # v1ソースレジスタ
   1 0 0 1 1 1 0 1    # v0マスクレジスタ

   4 4 4 3 2 1 1 0    # viota.m実行後のv10レジスタ
   e q r d c b v a    # マスク付きviota.mを用いたvrgatherの書き込みレジスタ

16.5. ベクトルレジスタ全体移動命令

vmvr.v 命令は、ベクトルレジスタ全体(VLENビット全て)をコピーし、 ベクトルレジスタグループ全体をコピーすることができます。 EEW=SEW、EMUL=nr 、実効長 evl =EMUL * VLEN/SEWのように動作します。

Note: これらの命令は、コンパイラが vl や vtype を知ったり変更したりすることなく、 ベクトルレジスタをシャッフルすることを支援するためのものです。

Note: vstart ≥ vl の場合に全ての要素に書き込まれないという通常の特性は適用されません。 代わりに、vstart ≥ evl の場合には要素は書き込まれません。

Note: vd が vs2 と等しい場合、その命令はアーキテクチャ的には NOP ですが、内部的にデータを再配置する実装に対しては、 そのレジスタグループが次に SEW に等しい EEW でアクセスされることを示すヒントとして扱われます。

この命令はOPIVI命令としてエンコードされます。 コピーするベクトルレジスタの数は、 メモリ命令の nf フィールドと同じエンコーディングで simm フィールドの下位3ビットにエンコードされます。 nr フィールドの値は、1、2、4、8のいずれかでなければならず、その他の値は予約されています。

Note: 将来の拡張機能では、移動するレジスタの数を他の数にすることができます。0, 1, 3, 7 以外の simm の値は現在予約されています。 Note: この命令は、vsmul 命令と同じfunct6エンコーディングを使用していますが、オペランドは即値で、マスクされていないバージョン(vm=1) のみです。 このエンコーディングが選ばれたのは、関連する vmerge エンコーディングに近いことと、vsmul 命令が即値フォームから恩恵を受ける可能性が低いことによります。

    vmv<nr>r.v vd, vs2  # 一般的なフォーム

    vmv1r.v v1, v2   #  v2をv1にコピーする
    vmv2r.v v10, v12 #  v12をv10にコピーし、v13をv11にコピーする
    vmv4r.v v4, v8   #  v8をv4に、v9をv5に、v10をv6に、v11をv7にコピーする
    vmv8r.v v0, v8   #  v8をv0に、v9をv1に、... v15をv7にコピーする

ソースと書き込みのベクトルレジスタ番号は、ベクトルレジスタグループのサイズに合わせて適切にアラインメントする必要があり、 他のベクトルレジスタ番号とのエンコーディングは予約されています。

Note: 将来の拡張により、ベクターレジスターのアラインメント制限が緩和される可能性があります。