ビットフィールドやビットベクトルの操作系命令をまとめます。
bfp
rs1
のoff
ビット目からlen
ビットをrs2
の下len
ビットに置き換えます。
ここで、off
とlen
は(オペランド数の都合上)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と解釈する工夫がなされます。
off
やlen
を指定する定数をrs2
の上位ビットに送り込むには、pack
命令が有用です。
RV32の場合、addi
で作った12ビットの定数をpack
命令で上位ビットに送り込めば、任意のlen
とoff
を実現できます。
RV64の場合、lui
で作った32ビットの定数をpack
命令で上位ビットに送り込めば、任意のlen
とoff
を実現できます(「または」と書いてある部分を後者で使うモードを利用します)。
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
のようにすることで求まります。