最近RV64GBの命令列を見ていてOp fusionできそうな命令が結構あったので、抜き出してみた。
rs1をrs2の整数倍になるように切り捨て
div rd, rs1, rs2 mul rd, rd, rs2
実装は以下のようになりレイテンシをmulからsubへ置き換えることができる
rem rd, rs1, rs2 sub rd, rs1, rd
比較
rs1 == -imm
immは-1か-2が多い
addi rd, rs1, imm seqz rd, rd
rs1 != -imm
addi rd, rs1, imm snez rd, rd
(rs1&rs2) == 0
and rd, rs1, rs2 seqz rd, rd
(rs1^rs2) == 0
xor rd, rs1, rs2 seqz rd, rd
(rs1|rs2) == 0
or rd, rs1, rs2 seqz rd, rd
rs1 >= imm
slti rd, rs1, imm not rd, rd
即値より上という命令はないのでよく出てくる
アドレス計算
&rs2[rs1+imm]
addi rd, rs1, imm sh2add rd, rd, rs2
&(rs2[rs1])+imm
sh2add rd, rs1, rs2 addi rd, rd, imm
rs2[rs1]
sh3add rd, rs1, rs2 ld rd, 0(rd)
std::distance(rs1, rd)
2の累乗の大きさの要素を持つiteratorの距離を、アドレスから計算する
sub rd, rd, rs1 srai rd, rd, imm
浮動小数の絶対値との加減算
fabs.d rd, rd fsub.d rd, rd, rs1
fsub.d rd, rs1, rs2 fabs.d rd, rd
符号ビットを0にするだけなので実装が簡単
ハードウェア的に簡単に実装できないor構造の大規模変更が必要なもの
浮動小数の+0との比較
浮動小数レジスタと整数レジスタに書き戻しが必要
fmv.d.x ft0, zero flt.d rd,rs1,ft0