RISC-Vベクトル拡張仕様書の読み直し。次はマスクを操作するための命令。論理命令など。
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 命令は不正命令例外を発生させます。