Rustで作るRISC-Vシミュレータ。基本的な形が出来上がったので、次に命令を追加してテストパタンをパスさせていく。 次に追加するのは乗除算命令だ。RV32には以下のテストパタンが用意されているので、それぞれ実装していく。
- rv32um-x-mulhsu
- rv32um-x-mulh
- rv32um-x-rem
- rv32um-x-mulhu
- rv32um-x-mul
- rv32um-x-remu
- rv32um-x-div
- rv32um-x-divu
それぞれで実装していくうえで気を付けなければならないのはWrappingだ。いろんな実装を見ていると、Wrappingした演算を実現するためにはもう少しきれいな記法があることが分かった。
RiscvInst::ADD => { let rs1_data = self.read_reg(rs1); let rs2_data = self.read_reg(rs2); - let reg_data:XlenType = (Wrapping(rs1_data) + Wrapping(rs2_data)).0; + let reg_data:XlenType = rs1_data.wrapping_add(rs2_data); self.write_reg(rd, reg_data); }
これでテストパタンを書き直す。MUL,DIV,REMについてもWrappingした演算が定義されているのでとても便利だ。
- DIV
let reg_data: XlenType = rs1_data.wrapping_mul(rs2_data);
- MUL
reg_data = rs1_data.wrapping_div(rs2_data);
- REM
reg_data = rs1_data.wrapping_rem(rs2_data);
これでテストパタンを実行した。無事にPASSすることが確認できたぞ。
PASS : ./riscv-tests/isa/rv32ui-p-sll.bin PASS : ./riscv-tests/isa/rv32ui-p-jal.bin PASS : ./riscv-tests/isa/rv32ui-p-lhu.bin PASS : ./riscv-tests/isa/rv32ui-p-slti.bin PASS : ./riscv-tests/isa/rv32ui-p-sra.bin PASS : ./riscv-tests/isa/rv32ui-p-sh.bin PASS : ./riscv-tests/isa/rv32ui-p-blt.bin PASS : ./riscv-tests/isa/rv32ui-p-and.bin PASS : ./riscv-tests/isa/rv32ui-p-andi.bin PASS : ./riscv-tests/isa/rv32ui-p-xor.bin PASS : ./riscv-tests/isa/rv32ui-p-sltu.bin PASS : ./riscv-tests/isa/rv32ui-p-bge.bin PASS : ./riscv-tests/isa/rv32ui-p-jalr.bin PASS : ./riscv-tests/isa/rv32ui-p-bne.bin PASS : ./riscv-tests/isa/rv32ui-p-srai.bin PASS : ./riscv-tests/isa/rv32ui-p-lw.bin PASS : ./riscv-tests/isa/rv32ui-p-bltu.bin PASS : ./riscv-tests/isa/rv32ui-p-lbu.bin PASS : ./riscv-tests/isa/rv32ui-p-beq.bin PASS : ./riscv-tests/isa/rv32ui-p-ori.bin PASS : ./riscv-tests/isa/rv32ui-p-lui.bin PASS : ./riscv-tests/isa/rv32ui-p-sltiu.bin PASS : ./riscv-tests/isa/rv32ui-p-srli.bin PASS : ./riscv-tests/isa/rv32ui-p-add.bin PASS : ./riscv-tests/isa/rv32ui-p-slt.bin PASS : ./riscv-tests/isa/rv32ui-p-lh.bin PASS : ./riscv-tests/isa/rv32ui-p-fence_i.bin PASS : ./riscv-tests/isa/rv32ui-p-slli.bin PASS : ./riscv-tests/isa/rv32ui-p-xori.bin PASS : ./riscv-tests/isa/rv32ui-p-addi.bin PASS : ./riscv-tests/isa/rv32ui-p-bgeu.bin PASS : ./riscv-tests/isa/rv32ui-p-srl.bin PASS : ./riscv-tests/isa/rv32ui-p-sw.bin PASS : ./riscv-tests/isa/rv32ui-p-simple.bin PASS : ./riscv-tests/isa/rv32ui-p-auipc.bin PASS : ./riscv-tests/isa/rv32ui-p-sb.bin PASS : ./riscv-tests/isa/rv32ui-p-or.bin PASS : ./riscv-tests/isa/rv32ui-p-lb.bin PASS : ./riscv-tests/isa/rv32ui-p-sub.bin PASS : ./riscv-tests/isa/rv32um-p-mulhsu.bin PASS : ./riscv-tests/isa/rv32um-p-mulh.bin PASS : ./riscv-tests/isa/rv32um-p-rem.bin PASS : ./riscv-tests/isa/rv32um-p-mulhu.bin PASS : ./riscv-tests/isa/rv32um-p-mul.bin PASS : ./riscv-tests/isa/rv32um-p-remu.bin PASS : ./riscv-tests/isa/rv32um-p-div.bin PASS : ./riscv-tests/isa/rv32um-p-divu.bin