From c5b4d9ded465945b48ac0d9264f77efd6d6533bb Mon Sep 17 00:00:00 2001 From: Clo91eaf Date: Wed, 22 May 2024 21:03:29 +0800 Subject: [PATCH] [difftest] add new spike interfaces to support offline difftest --- .../libspike_interfaces/spike_interfaces.cc | 48 +++++++++---------- .../libspike_interfaces/spike_interfaces_c.h | 8 ++-- .../src/spike/libspike_interfaces.rs | 38 +++++++++------ 3 files changed, 50 insertions(+), 44 deletions(-) diff --git a/difftest/libspike_interfaces/spike_interfaces.cc b/difftest/libspike_interfaces/spike_interfaces.cc index 514877bab4..0b2031e4a2 100644 --- a/difftest/libspike_interfaces/spike_interfaces.cc +++ b/difftest/libspike_interfaces/spike_interfaces.cc @@ -77,8 +77,8 @@ reg_t proc_get_insn(spike_processor_t* proc) { return fetch.insn.bits(); } -uint8_t* proc_get_vreg_addr(spike_processor_t* proc) { - return &proc->p->VU.elt(0, 0); +uint8_t proc_get_vreg_data(spike_processor_t* proc, uint32_t vreg_idx, uint32_t vreg_offset) { + return proc->p->VU.elt(vreg_idx, vreg_offset); } uint32_t extract_f32(freg_t f) { return (uint32_t)f.v[0]; } @@ -89,39 +89,22 @@ inline uint32_t clip(uint32_t binary, int a, int b) { return (binary >> a) & mask; } -uint64_t proc_get_rs(spike_processor_t* proc) { +uint32_t proc_get_rs1(spike_processor_t* proc) { auto pc = proc->p->get_state()->pc; auto fetch = proc->p->get_mmu()->load_insn(pc); - return (uint64_t)fetch.insn.rs1() << 32 | (uint64_t)fetch.insn.rs2(); + return (uint32_t)fetch.insn.rs1(); } -uint32_t proc_get_rd(spike_processor_t* proc) { +uint32_t proc_get_rs2(spike_processor_t* proc) { auto pc = proc->p->get_state()->pc; auto fetch = proc->p->get_mmu()->load_insn(pc); - return fetch.insn.rd(); + return (uint32_t)fetch.insn.rs2(); } -uint64_t proc_get_rs_bits(spike_processor_t* proc) { - auto state = proc->p->get_state(); - auto &xr = state->XPR; - auto &fr = state->FPR; - auto pc = state->pc; - auto inst_bits = proc_get_insn(proc); - - uint32_t opcode = clip(inst_bits, 0, 6); - uint32_t width = clip(inst_bits, 12, 14); // also funct3 +uint32_t proc_get_rd(spike_processor_t* proc) { + auto pc = proc->p->get_state()->pc; auto fetch = proc->p->get_mmu()->load_insn(pc); - uint32_t rs1_bits, rs2_bits; - bool is_fp_operands = opcode == 0b1010111 && (width == 0b101 /* OPFVF */); - if (is_fp_operands) { - rs1_bits = extract_f32(fr[fetch.insn.rs1()]); - rs2_bits = extract_f32(fr[fetch.insn.rs2()]); - } else { - rs1_bits = xr[fetch.insn.rs1()]; - rs2_bits = xr[fetch.insn.rs2()]; - } - - return (uint64_t)rs1_bits << 32 | (uint64_t)rs2_bits; + return fetch.insn.rd(); } uint64_t proc_vu_get_vtype(spike_processor_t* proc) { @@ -189,6 +172,19 @@ void state_set_pc(spike_state_t* state, uint64_t pc) { state->s->pc = pc; } +uint32_t state_get_reg_write_size(spike_state_t* state) { + return state->s->log_reg_write.size(); +} + +uint32_t state_get_reg(spike_state_t* state, uint32_t index, bool is_fp) { + if (is_fp) { + auto &fr = state->s->FPR; + return extract_f32(fr[index]); + } + auto &xr = state->s->XPR; + return (uint32_t)xr[index]; +} + uint32_t state_get_mem_write_size(spike_state_t* state) { return state->s->log_mem_write.size(); } diff --git a/difftest/libspike_interfaces/spike_interfaces_c.h b/difftest/libspike_interfaces/spike_interfaces_c.h index 2c2a73049f..b1f93d2f7c 100644 --- a/difftest/libspike_interfaces/spike_interfaces_c.h +++ b/difftest/libspike_interfaces/spike_interfaces_c.h @@ -22,10 +22,10 @@ spike_state_t* proc_get_state(spike_processor_t* proc); uint64_t proc_func(spike_processor_t* proc); uint64_t proc_get_insn(spike_processor_t* proc); -uint8_t* proc_get_vreg_addr(spike_processor_t* proc); -uint64_t proc_get_rs(spike_processor_t* proc); +uint8_t proc_get_vreg_data(spike_processor_t* proc, uint32_t vreg_idx, uint32_t vreg_offset); +uint32_t proc_get_rs1(spike_processor_t* proc); +uint32_t proc_get_rs2(spike_processor_t* proc); uint32_t proc_get_rd(spike_processor_t* proc); -uint64_t proc_get_rs_bits(spike_processor_t* proc); uint64_t proc_vu_get_vtype(spike_processor_t* proc); uint32_t proc_vu_get_vxrm(spike_processor_t* proc); @@ -38,6 +38,8 @@ uint16_t proc_vu_get_vstart(spike_processor_t* proc); uint64_t state_get_pc(spike_state_t* state); uint64_t state_handle_pc(spike_state_t* state, uint64_t new_pc); void state_set_pc(spike_state_t* state, uint64_t pc); +uint32_t state_get_reg(spike_state_t* state, uint32_t index, bool is_fp); +uint32_t state_get_reg_write_size(spike_state_t* state); uint32_t state_get_mem_write_size(spike_state_t* state); uint32_t state_get_mem_write_addr(spike_state_t* state, uint32_t index); uint64_t state_get_mem_write_value(spike_state_t* state, uint32_t index); diff --git a/difftest/t1-simulator/src/spike/libspike_interfaces.rs b/difftest/t1-simulator/src/spike/libspike_interfaces.rs index 84d0d225cd..ea6df0d5e6 100644 --- a/difftest/t1-simulator/src/spike/libspike_interfaces.rs +++ b/difftest/t1-simulator/src/spike/libspike_interfaces.rs @@ -31,10 +31,10 @@ pub struct Processor { } impl Processor { - pub fn disassemble(&self) -> std::borrow::Cow { + pub fn disassemble(&self) -> String { let bytes = unsafe { proc_disassemble(self.processor) }; let c_str = unsafe { CStr::from_ptr(bytes as *mut c_char) }; - c_str.to_string_lossy() + format!("{}", c_str.to_string_lossy()) } pub fn reset(&self) { @@ -54,22 +54,20 @@ impl Processor { unsafe { proc_get_insn(self.processor) } } - pub fn get_vreg_addr(&self) -> *mut u8 { - unsafe { proc_get_vreg_addr(self.processor) } + pub fn get_vreg_data(&self, idx: u32, offset: u32) -> u8 { + unsafe { proc_get_vreg_data(self.processor, idx, offset) } } - pub fn get_rs(&self) -> (u32, u32) { - let rs: u64 = unsafe { proc_get_rs(self.processor) }; - ((rs >> 32) as u32, rs as u32) + pub fn get_rs1(&self) -> u32 { + unsafe { proc_get_rs1(self.processor) } } - pub fn get_rd(&self) -> u32 { - unsafe { proc_get_rd(self.processor) } + pub fn get_rs2(&self) -> u32 { + unsafe { proc_get_rs2(self.processor) } } - pub fn get_rs_bits(&self) -> (u32, u32) { - let rs_bits: u64 = unsafe { proc_get_rs_bits(self.processor) }; - ((rs_bits >> 32) as u32, rs_bits as u32) + pub fn get_rd(&self) -> u32 { + unsafe { proc_get_rd(self.processor) } } // vu @@ -128,6 +126,14 @@ impl State { } } + pub fn get_reg_write_size(&self) -> u32 { + unsafe { state_get_reg_write_size(self.state) } + } + + pub fn get_reg(&self, idx: u32, is_fp: bool) -> u32 { + unsafe { state_get_reg(self.state, idx, is_fp) } + } + pub fn get_mem_write_size(&self) -> u32 { unsafe { state_get_mem_write_size(self.state) } } @@ -177,10 +183,10 @@ extern "C" { fn proc_get_state(proc: *mut ()) -> *mut (); fn proc_func(proc: *mut ()) -> u64; fn proc_get_insn(proc: *mut ()) -> u64; - fn proc_get_vreg_addr(proc: *mut ()) -> *mut u8; - fn proc_get_rs(proc: *mut ()) -> u64; + fn proc_get_vreg_data(proc: *mut (), vreg_idx: u32, vreg_offset: u32) -> u8; + fn proc_get_rs1(proc: *mut ()) -> u32; + fn proc_get_rs2(proc: *mut ()) -> u32; fn proc_get_rd(proc: *mut ()) -> u32; - fn proc_get_rs_bits(proc: *mut ()) -> u64; fn proc_vu_get_vtype(proc: *mut ()) -> u64; fn proc_vu_get_vxrm(proc: *mut ()) -> u32; @@ -193,6 +199,8 @@ extern "C" { fn proc_destruct(proc: *mut ()); fn state_set_pc(state: *mut (), pc: u64); fn state_get_pc(state: *mut ()) -> u64; + fn state_get_reg(state: *mut (), index: u32, is_fp: bool) -> u32; + fn state_get_reg_write_size(state: *mut ()) -> u32; fn state_get_mem_write_size(state: *mut ()) -> u32; fn state_get_mem_write_addr(state: *mut (), index: u32) -> u32; fn state_get_mem_write_value(state: *mut (), index: u32) -> u64;