Binary Translation型のエミュレータをRustで自作する話、徐々にテストパタンが安定して動作するようになっている。64ビット整数命令のパタンはすべてPassできるようになりたい。
これに伴っていくつかの実装変更を行った。これまではCSRRW命令などは専用のTCGを持っていたがこれを汎用的なCALL_HELPERに置き換えた。これにより独自のTCGを持つ必要性が減ってより汎用的な実装となっている。
pub fn translate_csrrw(inst: &InstrInfo) -> Vec<TCGOp> { let rs1_addr: usize = get_rs1_addr!(inst.inst) as usize; let rd_addr: usize = get_rd_addr!(inst.inst) as usize; let csr_const: u64 = get_imm12!(inst.inst); let rs1 = Box::new(TCGv::new_reg(rs1_addr as u64)); let rd = Box::new(TCGv::new_reg(rd_addr as u64)); let csr = Box::new(TCGv::new_imm(csr_const)); let csr_op = TCGOp::new_helper_call_arg3(CALL_HELPER_IDX::CALL_CSRRW_IDX as usize, *rd, *rs1, *csr); vec![csr_op] }
そのほか、TCGを簡単に記述できるようにいくつかWrapperの実装も行った。例えばRAXにGPRの値をロードするための専用関数tcg_gen_load_gpr_64bit()
や、RAXの値をGPRにストアするための専用関数tcg_gen_store_gpr_64bit
など。
fn tcg_gen_load_gpr_64bit( emu: &EmuEnv, dest: X86TargetRM, source: u64, mc: &mut Vec<u8>, ) -> usize { let mut gen_size = 0; gen_size += Self::tcg_modrm_64bit_out(X86Opcode::MOV_GV_EV, X86ModRM::MOD_10_DISP_RBP, dest, mc); gen_size += Self::tcg_out(emu.calc_gpr_relat_address(source) as u64, 4, mc); return gen_size; }
fn tcg_gen_store_gpr_64bit( emu: &EmuEnv, source: X86TargetRM, dest: u64, mc: &mut Vec<u8>, ) -> usize { let mut gen_size = 0; gen_size += Self::tcg_modrm_64bit_out(X86Opcode::MOV_EV_GV, X86ModRM::MOD_10_DISP_RBP, source, mc); gen_size += Self::tcg_out(emu.calc_gpr_relat_address(dest) as u64, 4, mc); return gen_size; }
バグをいくつか潰していって現在は殆どすべてのパタンをPassさせることができるようになった。
test rv64ui_p_andi ... ok test rv64ui_p_add ... ok test rv64ui_p_addi ... ok test rv64ui_p_addiw ... ok test rv64ui_p_auipc ... ok test rv64ui_p_beq ... ok test rv64ui_p_addw ... ok test rv64ui_p_and ... ok ... test rv64ui_p_sraiw ... ok test rv64ui_p_sraw ... ok test rv64ui_p_srl ... ok test rv64ui_p_srli ... ok test rv64ui_p_srliw ... ok test rv64ui_p_srlw ... ok test rv64ui_p_sub ... ok test rv64ui_p_subw ... ok test rv64ui_p_sw ... ok test rv64ui_p_xor ... ok test rv64ui_p_xori ... ok
次はどっちの方向に進もうか。。。乗除算命令系を実装しなければならないとして、その後は浮動小数点の方向へ行くか、仮想アドレスのサポートへ進むか。。。