FPGA開発日記

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

RISC-Vベクトル拡張仕様書 v1.0 を読み直す (21. 浮動小数点その他の命令)

RISC-Vベクトル拡張仕様書の読み直し。次はマスクを操作するための命令。論理命令など。

github.com

github.com


15. ベクトルマスク命令

ベクトルレジスタに格納されているマスクを操作するための命令がいくつか提供されています。

15.1. ベクトルマスクレジスタ論理命令

ベクトルマスクレジスタ論理命令は、マスクレジスタに対して演算を実行します。 マスクレジスタの各要素は1ビットであり、従ってこれらの命令はvtypeフィールド内のvlmulの設定に関係なく単一のベクトルレジスタを操作します。 これらの命令はvlmulの設定を変更しません。 書き込みベクトルレジスタはソースベクトルレジスタと同一である可能性があります。

他のベクトル命令と同様に、vstartインデックスよりも小さな要素は変更されず、命令実行後にはvstartの値は0にリセットされます。 ベクトルマスク論理命令は常にマスクは適用されず、従って非アクティブ要素はありませんん。vm=0に相当するエンコーディングは予約されています。 vl以降のマスク要素、つまり末尾エレメントは常にtail-agnosticポリシに基づいて更新されます。

    vmand.mm vd, vs2, vs1     # vd.mask[i] =   vs2.mask[i] &&  vs1.mask[i]
    vmnand.mm vd, vs2, vs1    # vd.mask[i] = !(vs2.mask[i] &&  vs1.mask[i])
    vmandnot.mm vd, vs2, vs1  # vd.mask[i] =   vs2.mask[i] && !vs1.mask[i]
    vmxor.mm  vd, vs2, vs1    # vd.mask[i] =   vs2.mask[i] ^^  vs1.mask[i]
    vmor.mm  vd, vs2, vs1     # vd.mask[i] =   vs2.mask[i] ||  vs1.mask[i]
    vmnor.mm  vd, vs2, vs1    # vd.mask[i] = !(vs2.mask[i] ||  vs1.mask[i])
    vmornot.mm  vd, vs2, vs1  # vd.mask[i] =   vs2.mask[i] || !vs1.mask[i]
    vmxnor.mm vd, vs2, vs1    # vd.mask[i] = !(vs2.mask[i] ^^  vs1.mask[i])

一般的に使用されるマスク論理操作のために、いくつかのアセンブラ疑似命令が定義されています。

    vmmv.m vd, vs  => vmand.mm vd, vs, vs  # Copy mask register
    vmclr.m vd     => vmxor.mm vd, vd, vd   # Clear mask register
    vmset.m vd     => vmxnor.mm vd, vd, vd  # Set mask register
    vmnot.m vd, vs => vmnand.mm vd, vs, vs  # Invert bits

Note: vmmv.m は以前は vmcpy.m と呼ばれていましたが、新しいレイアウトでは、 ビットが解釈無しにコピーされるため "mv"と読んだ方が整合性があります。 vmcpy.m アセンブラ疑似命令は互換性のために残されています。

8つのマスク論理命令は2つの入力マスクに対する任意の16個のバイナリ論理演算を実行することができます。

inputs
0 0 1 1 src1
0 1 0 1 src2
output instruction pseudoinstruction
0 0 0 0 vmxor.mm vd, vd, vd vmclr.m vd
1 0 0 0 vmnor.mm vd, src1, src2
0 1 0 0 vmandnot.mm vd, src2, src1
1 1 0 0 vmnand.mm vd, src1, src1 vmnot.m vd, src1
0 0 1 0 vmandnot.mm vd, src1, src2
1 0 1 0 vmnand.mm vd, src2, src2 vmnot.m vd, src2
0 1 1 0 vmxor.mm vd, src1, src2
1 1 1 0 vmnand.mm vd, src1, src2
0 0 0 1 vmand.mm vd, src1, src2
1 0 0 1 vmxnor.mm vd, src1, src2
0 1 0 1 vmand.mm vd, src2, src2 vmmv.m vd, src2
1 1 0 1 vmornot.mm vd, src2, src1
0 0 1 1 vmand.mm vd, src1, src1 vmmv.m vd, src1
1 0 1 1 vmornot.mm vd, src1, src2
1 1 1 1 vmxnor.mm vd, vd, vd vmset.m vd

ベクトルマスク論理命令は、使用前に値をv0に移すことで、プレディケートレジスタの数を効果的に拡張するために、 次のマスクされたベクトル演算と簡単に融合できるように設計されています。

15.2. ベクトルマスクPopカウント命令 vpopc

    vpopc.m rd, vs2, vm

ソースオペランドは、 マスクレジスタのレイアウト 節で説明されているように、マスクレジスタの値を保持する単一のベクトルレジスタです。

vpopc.m命令は,ベクトルソースマスクレジスタのアクティブ要素のうち、値が1であるマスク要素の数を数え、その結果をスカラのxレジスタに書き込む。

この操作はマスク下で行うことができ、その場合はマスクされた要素のみがカウントされます。

 vpopc.m rd, vs2, v0.t # x[rd] = sum__i ( vs2.mask[i] && v0.mask[i] )

vpopc.m 上の例外は、常に vstart が 0 で通知されます。 vpopc 命令は、vstart が0でない場合、不正命令例外を発生させます。

15.3. vfirst find-first-set マスクビット命令

    vfirst.m rd, vs2, vm

vfirst 命令は,ソースマスクベクトルの中から、値1を持つ最も低い番号のアクティブな要素を見つけ、その要素のインデックスをGPRに書き込みます。 値が1のアクティブな要素がない場合は,-1が書き込まれます。

ベクトルの長さはどのような実装でも2(XLEN-1) を超えることはありませんので、ソフトウェアは負の値(最上位ビットの設定)があれば、 要素が見つからないと仮定することができます。

vfirst の例外は常に 0 の vstart で報告されます。vstart が 0 でない場合、vfirst 命令は不正命令例外を発生させます。