Rustで自作命令セットシミュレータを作っているが、RV64のテストパタンはある程度Passできるようになっている。
RV32についてだが、これまではRV32とRV64を別のクラスとして実装していた。しかしどうもこれでは冗長なコードがあってたまらないので、統一してRV64のクラスのみでRV32もサポートすることにした。
RV32をサポートするために、まずはRV64のRISC-Vコアを管理しているstruct
にXLENのパラメータを追加する。
swimmer_rust/src/riscv_core.rs
pub struct Riscv64Env { pub m_xlen: i32, ...
pub fn new(xlen: i32) -> Riscv64Env { Riscv64Env { m_xlen: xlen, m_pc: DRAM_BASE as Addr64T, ...
これに応じて、各命令の実装を変えていく。例えば、ADD命令やSUB命令ならば演算の最後に符号によるXLENビット長への丸め込みを行っておく。
swimmer_rust/src/riscv_insts.rs
RiscvInstId::ADD => { let rs1_data = self.read_reg(rs1); let rs2_data = self.read_reg(rs2); let reg_data: Xlen64T = self.sext_xlen(rs1_data.wrapping_add(rs2_data)); self.write_reg(rd, reg_data); } RiscvInstId::SUB => { let rs1_data = self.read_reg(rs1); let rs2_data = self.read_reg(rs2); let reg_data: Xlen64T = self.sext_xlen(rs1_data.wrapping_sub(rs2_data)); self.write_reg(rd, reg_data); } ...
このsext_xlen()
だが、Spikeの実装をかなりパクってしまった。
swimmer_rust/src/riscv_core.rs
pub fn sext_xlen(&mut self, hex: Xlen64T) -> Xlen64T { return (hex << (64-self.m_xlen)) >> (64-self.m_xlen) } pub fn uext_xlen(&mut self, hex: Xlen64T) -> UXlen64T { return ((hex as UXlen64T) << (64-self.m_xlen)) >> (64-self.m_xlen) }
とりあえずテストを動かしてみる。まずはPhysical Addressモードの場合でテストを行う。
cargo run -- --arch rv32 riscv-tests/isa/rv32ui-p-add.bin | tee rv32ui-p-add.log
466:M:Bare:ffffffff8000000c:03ff0a63:beq x30,x31,0x34 :x30=>000000000000000b x31=>0000000000000008 467:M:Bare:ffffffff80000010:00900f93:addi x31,x00,0x009 :x00=>0000000000000000 x31<=0000000000000009 468:M:Bare:ffffffff80000014:03ff0663:beq x30,x31,0x2c :x30=>000000000000000b x31=>0000000000000009 469:M:Bare:ffffffff80000018:00b00f93:addi x31,x00,0x00b :x00=>0000000000000000 x31<=000000000000000b 470:M:Bare:ffffffff8000001c:03ff0263:beq x30,x31,0x24 :x30=>000000000000000b x31=>000000000000000b 471:M:Bare:ffffffff80000040:00001f17:auipc x30,0x00001 :x30<=ffffffff80001040 472:M:Bare:ffffffff80000044:fc3f2023:sw x03,0x0000fc0(x30) :x03=>0000000000000001 x30=>ffffffff80001040 (ffffffff80001000)<=00000001 PASS : riscv-tests/isa/rv32ui-p-add.bin
動作自体は問題ないようだ。あとはリグレッションテストで確認していく。