RISC-Vのビット操作系拡張(B拡張)のまとめ(その4)

ビットフィールドやビットベクトルの操作系命令をまとめます。

bfp

rs1offビット目からlenビットをrs2の下lenビットに置き換えます。 ここで、offlenは(オペランド数の都合上)rs2の上位ビットを使って指定します。

offは、RV32であればrs2の16ビット目から20ビット目、RV64であればrs2の32ビット目から37ビット目または48ビット目から53ビット目を使います。 lenは、RV32であればrs2の24ビット目から27ビット目、RV64であればrs2の40ビット目から44ビット目または56ビット目から60ビット目を使います。

「または」と書いてある部分は、rs2の62ビット目から63ビット目が2であれば後者を、そうでなければ前者を使います。

lenは1から16/32になるはずです。そこで、4/5bitのフィールドは、すべてが0の時に16/32と解釈する工夫がなされます。

offlenを指定する定数をrs2の上位ビットに送り込むには、pack命令が有用です。 RV32の場合、addiで作った12ビットの定数をpack命令で上位ビットに送り込めば、任意のlenoffを実現できます。 RV64の場合、luiで作った32ビットの定数をpack命令で上位ビットに送り込めば、任意のlenoffを実現できます(「または」と書いてある部分を後者で使うモードを利用します)。

bext, bdep

bext命令は、rs1のうち、rs2の中で1がたっているビットの部分だけを下位ビットに集約します。 bdep命令は、その逆操作を行います。つまり、rs2の中で1がたっているビットの位置に、rs1の各ビットを展開します。

bext命令を使うと、Magic Bitboardみたいなことが簡単にできます。

また、bdep命令を使うと簡潔データ構造で用いられるようなselect1(rank)演算が実現可能です。先頭から10ビット目の1の位置を知りたい場合、bdep a0, 1ull<<10, a0; ctz a0, a0のようにすることで求まります。