RV64GBでOp fusionできそうな命令列

最近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