From dac08cde0aa5848bc14831bfc046c2c879da8362 Mon Sep 17 00:00:00 2001 From: Clo91eaf Date: Mon, 11 Mar 2024 19:43:47 +0800 Subject: [PATCH] Refactor pc --- src/cpu.rs | 67 ++-- src/cpu/instruction.rs | 105 ++++- src/cpu/utils.rs | 98 ----- src/monitor/sdb.rs | 20 +- tests/am-tests.rs | 2 +- tests/riscv-tests.rs | 861 ++++------------------------------------- 6 files changed, 211 insertions(+), 942 deletions(-) diff --git a/src/cpu.rs b/src/cpu.rs index 8000c42..478bb19 100644 --- a/src/cpu.rs +++ b/src/cpu.rs @@ -8,8 +8,8 @@ use ansi_term::Colour::{Green, Red}; use csr::*; use instruction::BranchType as B; use instruction::ImmediateType as I; -use instruction::Instruction as Insn; use instruction::Inst; +use instruction::Instruction as Insn; use instruction::JumpType as J; use instruction::RegisterType as R; use instruction::StoreType as S; @@ -22,7 +22,7 @@ use memory::{read_data, read_inst, write_data}; use utils::{bits, sext}; #[derive(PartialEq, Debug)] -pub enum CpuState { +pub enum State { Running, // Stopped, Ended, @@ -45,10 +45,8 @@ pub struct Cpu { pub gpr: [u64; 32], pub csr: Csr, pub pc: u64, - snpc: u64, - dnpc: u64, inst: Inst, - pub state: CpuState, + pub state: State, pub halt: Halt, statistic: statistic::Statistic, diff: Option>, @@ -65,10 +63,8 @@ impl Cpu { gpr: [0; 32], csr: Csr::new(), pc: 0x80000000, - snpc: 0x80000000, - dnpc: 0x80000000, inst: Inst::new(), - state: CpuState::Running, + state: State::Running, halt: Halt::new(), statistic: statistic::Statistic::new(), diff, @@ -76,7 +72,7 @@ impl Cpu { } fn hemu_trap(&mut self) { - self.state = CpuState::Ended; + self.state = State::Ended; self.halt.pc = self.pc as u32; self.halt.ret = self.gpr[10] as u32; @@ -84,15 +80,13 @@ impl Cpu { } pub fn fetch(&mut self) { - let bits = read_inst(self.snpc) as u32; + let bits = read_inst(self.pc) as u32; self.inst.set_bits(bits); - self.snpc += 4; } #[rustfmt::skip] pub fn execute(&mut self) { let (rd, rs1, rs2, imm) = (self.inst.rd, self.inst.rs1, self.inst.rs2, self.inst.imm); - self.dnpc = self.snpc; let csr = bits(self.inst.bits, 20, 31) as u16; match self.inst.typ { Insn::Register(R::ADD) => {self.gpr[rd] = (self.gpr[rs1] as i64).wrapping_add(self.gpr[rs2] as i64) as u64;} @@ -138,15 +132,15 @@ impl Cpu { Insn::Store(S::SW) => {write_data((self.gpr[rs1] as i64).wrapping_add(imm) as u64, 4, self.gpr[rs2]);} Insn::Store(S::SD) => {write_data((self.gpr[rs1] as i64).wrapping_add(imm) as u64, 8, self.gpr[rs2]);} - Insn::Branch(B::BEQ) => {if self.gpr[rs1] == self.gpr[rs2] {self.dnpc = (self.pc as i64).wrapping_add(imm) as u64;}} - Insn::Branch(B::BNE) => {if self.gpr[rs1] != self.gpr[rs2] {self.dnpc = (self.pc as i64).wrapping_add(imm) as u64;}} - Insn::Branch(B::BLT) => {if (self.gpr[rs1] as i64) < (self.gpr[rs2] as i64) {self.dnpc = (self.pc as i64).wrapping_add(imm) as u64;}} - Insn::Branch(B::BGE) => {if (self.gpr[rs1] as i64) >= (self.gpr[rs2] as i64) {self.dnpc = (self.pc as i64).wrapping_add(imm) as u64;}} - Insn::Branch(B::BLTU) => {if self.gpr[rs1] < self.gpr[rs2] {self.dnpc = (self.pc as i64).wrapping_add(imm) as u64;}} - Insn::Branch(B::BGEU) => {if self.gpr[rs1] >= self.gpr[rs2] {self.dnpc = (self.pc as i64).wrapping_add(imm) as u64;}} + Insn::Branch(B::BEQ) => {if self.gpr[rs1] == self.gpr[rs2] {self.pc = (self.pc as i64).wrapping_add(imm).wrapping_sub(4) as u64;}} + Insn::Branch(B::BNE) => {if self.gpr[rs1] != self.gpr[rs2] {self.pc = (self.pc as i64).wrapping_add(imm).wrapping_sub(4) as u64;}} + Insn::Branch(B::BLT) => {if (self.gpr[rs1] as i64) < (self.gpr[rs2] as i64) {self.pc = (self.pc as i64).wrapping_add(imm).wrapping_sub(4) as u64;}} + Insn::Branch(B::BGE) => {if (self.gpr[rs1] as i64) >= (self.gpr[rs2] as i64) {self.pc = (self.pc as i64).wrapping_add(imm).wrapping_sub(4) as u64;}} + Insn::Branch(B::BLTU) => {if self.gpr[rs1] < self.gpr[rs2] {self.pc = (self.pc as i64).wrapping_add(imm).wrapping_sub(4) as u64;}} + Insn::Branch(B::BGEU) => {if self.gpr[rs1] >= self.gpr[rs2] {self.pc = (self.pc as i64).wrapping_add(imm).wrapping_sub(4) as u64;}} - Insn::Jump(J::JAL) => {self.gpr[rd] = self.pc + 4; self.dnpc = (self.pc as i64).wrapping_add(imm) as u64;} - Insn::Immediate(I::JALR) => {self.gpr[rd] = self.pc + 4; self.dnpc = (self.gpr[rs1] as i64).wrapping_add(imm) as u64;} + Insn::Jump(J::JAL) => {self.gpr[rd] = self.pc + 4; self.pc = (self.pc as i64).wrapping_add(imm).wrapping_sub(4) as u64;} + Insn::Immediate(I::JALR) => {self.gpr[rd] = self.pc + 4; self.pc = (self.gpr[rs1] as i64).wrapping_add(imm).wrapping_sub(4) as u64;} Insn::Upper(U::LUI) => {self.gpr[rd] = imm as u64;} Insn::Upper(U::AUIPC) => {self.gpr[rd] = (self.pc as i64).wrapping_add(imm) as u64;} @@ -165,7 +159,7 @@ impl Cpu { Insn::Register(R::REMUW) => {self.gpr[rd] = sext((self.gpr[rs1] as u32 % self.gpr[rs2] as u32) as usize, 64);} Insn::Register(R::REMW) => {self.gpr[rd] = sext((self.gpr[rs1] as i32 % self.gpr[rs2] as i32) as usize, 32);} - Insn::Register(R::MRET) => {self.dnpc = self.csr.read(MEPC).wrapping_add(4);} + Insn::Register(R::MRET) => {self.pc = self.csr.read(MEPC);} Insn::Immediate(I::ECALL) => {todo!();} Insn::Immediate(I::EBREAK) => {self.hemu_trap();} @@ -184,29 +178,24 @@ impl Cpu { } fn exec_once(&mut self) { - // pipeline start - self.snpc = self.pc; // fetch stage self.fetch(); + //disassemble + log::info!("{:08x}: {:08x}\t{}", self.pc, &self.inst.bits, self.inst.disassemble(self.pc)); + let pc = self.pc; // execute stage (including memory stage and write back stage) self.execute(); // print disassemble - log::info!( - "{:08x}: {:08x}\t{}", - self.pc, - &self.inst.bits, - self.inst.disassemble(self.pc) - ); - self.difftest().unwrap(); + self.difftest(pc).unwrap(); // update pc - self.pc = self.dnpc; + self.pc += 4; } fn exec_ntimes(&mut self, n: usize) { for _ in 0..n { self.exec_once(); self.statistic.inc_count(); - if self.state != CpuState::Running { + if self.state != State::Running { break; } } @@ -229,7 +218,7 @@ impl Cpu { self.statistic.stop_timer(start_time); match self.state { - CpuState::Ended => { + State::Ended => { if self.halt.ret == 0 { println!("{}", Green.bold().paint("HIT GOOD TRAP")); self.statistic(); @@ -239,8 +228,8 @@ impl Cpu { -1 } } - CpuState::Running => 0, - CpuState::Quit => { + State::Running => 0, + State::Quit => { self.statistic(); 0 } @@ -266,7 +255,7 @@ impl Cpu { todo!("watch points not implemented!"); } - fn difftest(&mut self) -> anyhow::Result<()> { + fn difftest(&mut self, pc: u64) -> anyhow::Result<()> { // get numbers from diff file let mut line = String::new(); @@ -287,12 +276,12 @@ impl Cpu { } // difftest check - if numbers[0] != self.pc { - panic!("pc = {:x}, ref = {:x}", self.pc, numbers[0]); + if numbers[0] != pc { + panic!("pc = {:x}, ref = {:x}", pc, numbers[0]); } (0..32).for_each(|i| { if numbers[i + 1] != self.gpr[i] { - panic!("x{:02} = {:x}, ref = {:x}", i, self.gpr[i], numbers[i + 1]); + panic!("pc = {:x}, x{:02} = {:x}, ref = {:x}", pc, i, self.gpr[i], numbers[i + 1]); } }); diff --git a/src/cpu/instruction.rs b/src/cpu/instruction.rs index 9fb51a8..18cad7e 100644 --- a/src/cpu/instruction.rs +++ b/src/cpu/instruction.rs @@ -1,7 +1,4 @@ -use crate::cpu::utils; - use super::utils::{bits, sext}; -use std::fmt; #[derive(Copy, Clone, Debug)] pub enum Instruction { @@ -149,7 +146,7 @@ impl Inst { rd: 0, rs1: 0, rs2: 0, - imm: 0 + imm: 0, } } @@ -179,7 +176,7 @@ impl Inst { } pub fn disassemble(&self, pc: u64) -> String { - utils::disassemble(self, pc) + disassemble(self, pc) } fn match_inst(&self, pattern: &str) -> bool { @@ -217,10 +214,6 @@ impl InstPattern { } } -pub struct InstPatternTable { - pub patterns: Vec, -} - #[rustfmt::skip] pub fn new_ipt() -> Vec { vec![ @@ -321,3 +314,97 @@ pub fn new_ipt() -> Vec { InstPattern::new("??????? ????? ????? ??? ????? 01101 11", Instruction::Upper(UpperType::LUI)), InstPattern::new("??????? ????? ????? ??? ????? 00101 11", Instruction::Upper(UpperType::AUIPC)),] } + +#[rustfmt::skip] +/// Decode operands from instruction +pub fn disassemble(inst: &Inst, pc: u64) -> String { + let (rd, rs1, rs2, imm) = (inst.rd, inst.rs1, inst.rs2, inst.imm); + let gpr = vec!["zero", "ra", "sp", "gp", "tp", "t0", "t1", "t2", "s0", "s1", "a0", "a1", "a2", "a3", "a4", "a5", "a6", "a7", "s2", "s3", "s4", "s5", "s6", "s7", "s8", "s9", "s10", "s11", "t3", "t4", "t5", "t6"]; + match inst.typ { + Instruction::Register(RegisterType::ADD) => format!("add {}, {}, {}", gpr[rd], gpr[rs1], gpr[rs2]), + Instruction::Register(RegisterType::ADDW) => format!("addw {}, {}, {}", gpr[rd], gpr[rs1], gpr[rs2]), + Instruction::Register(RegisterType::SUB) => format!("sub {}, {}, {}", gpr[rd], gpr[rs1], gpr[rs2]), + Instruction::Register(RegisterType::SUBW) => format!("subw {}, {}, {}", gpr[rd], gpr[rs1], gpr[rs2]), + Instruction::Register(RegisterType::XOR) => format!("xor {}, {}, {}", gpr[rd], gpr[rs1], gpr[rs2]), + Instruction::Register(RegisterType::OR) => format!("or {}, {}, {}", gpr[rd], gpr[rs1], gpr[rs2]), + Instruction::Register(RegisterType::AND) => format!("and {}, {}, {}", gpr[rd], gpr[rs1], gpr[rs2]), + Instruction::Register(RegisterType::SLL) => format!("sll {}, {}, {}", gpr[rd], gpr[rs1], gpr[rs2]), + Instruction::Register(RegisterType::SLLW) => format!("sllw {}, {}, {}", gpr[rd], gpr[rs1], gpr[rs2]), + Instruction::Register(RegisterType::SRL) => format!("srl {}, {}, {}", gpr[rd], gpr[rs1], gpr[rs2]), + Instruction::Register(RegisterType::SRA) => format!("sra {}, {}, {}", gpr[rd], gpr[rs1], gpr[rs2]), + Instruction::Register(RegisterType::SRLW) => format!("srlw {}, {}, {}", gpr[rd], gpr[rs1], gpr[rs2]), + Instruction::Register(RegisterType::SRAW) => format!("sraw {}, {}, {}", gpr[rd], gpr[rs1], gpr[rs2]), + Instruction::Register(RegisterType::SLT) => format!("slt {}, {}, {}", gpr[rd], gpr[rs1], gpr[rs2]), + Instruction::Register(RegisterType::SLTU) => format!("sltu {}, {}, {}", gpr[rd], gpr[rs1], gpr[rs2]), + + Instruction::Immediate(ImmediateType::ADDI) => format!("addi {}, {}, {}", gpr[rd], gpr[rs1], imm), + Instruction::Immediate(ImmediateType::ADDIW) => format!("addiw {}, {}, {}", gpr[rd], gpr[rs1], imm), + Instruction::Immediate(ImmediateType::XORI) => format!("xori {}, {}, {}", gpr[rd], gpr[rs1], imm), + Instruction::Immediate(ImmediateType::ORI) => format!("ori {}, {}, {}", gpr[rd], gpr[rs1], imm), + Instruction::Immediate(ImmediateType::ANDI) => format!("andi {}, {}, {}", gpr[rd], gpr[rs1], imm), + Instruction::Immediate(ImmediateType::SLLI) => format!("slli {}, {}, {}", gpr[rd], gpr[rs1], imm), + Instruction::Immediate(ImmediateType::SLLIW) => format!("slliw {}, {}, {}", gpr[rd], gpr[rs1], imm), + Instruction::Immediate(ImmediateType::SRLI) => format!("srli {}, {}, {}", gpr[rd], gpr[rs1], imm), + Instruction::Immediate(ImmediateType::SRLIW) => format!("srliw {}, {}, {}", gpr[rd], gpr[rs1], imm), + Instruction::Immediate(ImmediateType::SRAI) => format!("srai {}, {}, {}", gpr[rd], gpr[rs1], imm), + Instruction::Immediate(ImmediateType::SRAIW) => format!("sraiw {}, {}, {}", gpr[rd], gpr[rs1], imm), + Instruction::Immediate(ImmediateType::SLTI) => format!("slti {}, {}, {}", gpr[rd], gpr[rs1], imm), + Instruction::Immediate(ImmediateType::SLTIU) => format!("sltiu {}, {}, {}", gpr[rd], gpr[rs1], imm), + + Instruction::Immediate(ImmediateType::LB) => format!("lb {}, {:x}({})", gpr[rd], imm, gpr[rs1]), + Instruction::Immediate(ImmediateType::LBU) => format!("lbu {}, {:x}({})", gpr[rd], imm, gpr[rs1]), + Instruction::Immediate(ImmediateType::LH) => format!("lh {}, {:x}({})", gpr[rd], imm, gpr[rs1]), + Instruction::Immediate(ImmediateType::LHU) => format!("lhu {}, {:x}({})", gpr[rd], imm, gpr[rs1]), + Instruction::Immediate(ImmediateType::LW) => format!("lw {}, {:x}({})", gpr[rd], imm, gpr[rs1]), + Instruction::Immediate(ImmediateType::LWU) => format!("lwu {}, {:x}({})", gpr[rd], imm, gpr[rs1]), + Instruction::Immediate(ImmediateType::LD) => format!("ld {}, {:x}({})", gpr[rd], imm, gpr[rs1]), + + Instruction::Store(StoreType::SB) => format!("sb {}, {}({})", gpr[rs2], imm, gpr[rs1]), + Instruction::Store(StoreType::SH) => format!("sh {}, {}({})", gpr[rs2], imm, gpr[rs1]), + Instruction::Store(StoreType::SW) => format!("sw {}, {}({})", gpr[rs2], imm, gpr[rs1]), + Instruction::Store(StoreType::SD) => format!("sd {}, {}({})", gpr[rs2], imm, gpr[rs1]), + + Instruction::Branch(BranchType::BEQ) => format!("beq {}, {}, {:x}", gpr[rs1], gpr[rs2], (pc as i64).wrapping_add(imm)), + Instruction::Branch(BranchType::BNE) => format!("bne {}, {}, {:x}", gpr[rs1], gpr[rs2], (pc as i64).wrapping_add(imm)), + Instruction::Branch(BranchType::BLT) => format!("blt {}, {}, {:x}", gpr[rs1], gpr[rs2], (pc as i64).wrapping_add(imm)), + Instruction::Branch(BranchType::BGE) => format!("bge {}, {}, {:x}", gpr[rs1], gpr[rs2], (pc as i64).wrapping_add(imm)), + Instruction::Branch(BranchType::BLTU) => format!("bltu {}, {}, {:x}", gpr[rs1], gpr[rs2], (pc as i64).wrapping_add(imm)), + Instruction::Branch(BranchType::BGEU) => format!("bgeu {}, {}, {:x}", gpr[rs1], gpr[rs2], (pc as i64).wrapping_add(imm)), + + Instruction::Jump(JumpType::JAL) => format!("jal {}, {:x}", gpr[rd], (imm as u64).wrapping_add(pc)), + Instruction::Immediate(ImmediateType::JALR) => format!("jalr {}, {}, {:x}", gpr[rd], gpr[rs1], imm), + + Instruction::Upper(UpperType::LUI) => format!("lui {}, {:x}", gpr[rd], imm), + Instruction::Upper(UpperType::AUIPC) => format!("auipc {}, {:x}", gpr[rd], (pc as i64).wrapping_add(imm)), + + Instruction::Register(RegisterType::MUL) => format!("mul {}, {}, {}", gpr[rd], gpr[rs1], gpr[rs2]), + Instruction::Register(RegisterType::MULH) => format!("mulh {}, {}, {}", gpr[rd], gpr[rs1], gpr[rs2]), + Instruction::Register(RegisterType::MULHU) => format!("mulhu {}, {}, {}", gpr[rd], gpr[rs1], gpr[rs2]), + Instruction::Register(RegisterType::MULHSU) => format!("mulhsu {}, {}, {}", gpr[rd], gpr[rs1], gpr[rs2]), + Instruction::Register(RegisterType::MULW) => format!("mulw {}, {}, {}", gpr[rd], gpr[rs1], gpr[rs2]), + Instruction::Register(RegisterType::DIV) => format!("div {}, {}, {}", gpr[rd], gpr[rs1], gpr[rs2]), + Instruction::Register(RegisterType::DIVU) => format!("divu {}, {}, {}", gpr[rd], gpr[rs1], gpr[rs2]), + Instruction::Register(RegisterType::DIVUW) => format!("divuw {}, {}, {}", gpr[rd], gpr[rs1], gpr[rs2]), + Instruction::Register(RegisterType::DIVW) => format!("divw {}, {}, {}", gpr[rd], gpr[rs1], gpr[rs2]), + Instruction::Register(RegisterType::REM) => format!("rem {}, {}, {}", gpr[rd], gpr[rs1], gpr[rs2]), + Instruction::Register(RegisterType::REMU) => format!("remu {}, {}, {}", gpr[rd], gpr[rs1], gpr[rs2]), + Instruction::Register(RegisterType::REMUW) => format!("remuw {}, {}, {}", gpr[rd], gpr[rs1], gpr[rs2]), + Instruction::Register(RegisterType::REMW) => format!("remw {}, {}, {}", gpr[rd], gpr[rs1], gpr[rs2]), + + Instruction::Register(RegisterType::MRET) => format!("mret"), + + Instruction::Immediate(ImmediateType::ECALL) => format!("ecall"), + Instruction::Immediate(ImmediateType::EBREAK) => format!("ebreak"), + + Instruction::Immediate(ImmediateType::FENCE) => format!("fence"), + + Instruction::Immediate(ImmediateType::CSRRW) => format!("csrrw {}, {}", gpr[rd], gpr[rs1]), + Instruction::Immediate(ImmediateType::CSRRS) => format!("csrrs {}, {}", gpr[rd], gpr[rs1]), + Instruction::Immediate(ImmediateType::CSRRC) => format!("csrrc {}, {}", gpr[rd], gpr[rs1]), + Instruction::Immediate(ImmediateType::CSRRWI) => format!("csrrwi {}, 0x{:x}, {}", gpr[rd], imm, rs1), + Instruction::Immediate(ImmediateType::CSRRSI) => format!("csrrsi {}, 0x{:x}, {}", gpr[rd], imm, rs1), + Instruction::Immediate(ImmediateType::CSRRCI) => format!("csrrci {}, 0x{:x}, {}", gpr[rd], imm, rs1), + + _ => format!("Unknown instruction") + } +} diff --git a/src/cpu/utils.rs b/src/cpu/utils.rs index 2d9ff9e..593e1b1 100644 --- a/src/cpu/utils.rs +++ b/src/cpu/utils.rs @@ -1,6 +1,3 @@ -use crate::cpu::instruction::Inst; -use crate::cpu::instruction::*; - fn bitmask(bits: u32) -> u32 { (1u32 << bits) - 1 } @@ -16,98 +13,3 @@ pub fn sext(x: usize, len: u32) -> u64 { let extend_bits = 64 - len; (((x as i64) << extend_bits) >> extend_bits) as u64 } - - -#[rustfmt::skip] -/// Decode operands from instruction -pub fn disassemble(inst: &Inst, pc: u64) -> String { - let (rd, rs1, rs2, imm) = (inst.rd, inst.rs1, inst.rs2, inst.imm); - let gpr = vec!["zero", "ra", "sp", "gp", "tp", "t0", "t1", "t2", "s0", "s1", "a0", "a1", "a2", "a3", "a4", "a5", "a6", "a7", "s2", "s3", "s4", "s5", "s6", "s7", "s8", "s9", "s10", "s11", "t3", "t4", "t5", "t6"]; - match inst.typ { - Instruction::Register(RegisterType::ADD) => format!("add {}, {}, {}", gpr[rd], gpr[rs1], gpr[rs2]), - Instruction::Register(RegisterType::ADDW) => format!("addw {}, {}, {}", gpr[rd], gpr[rs1], gpr[rs2]), - Instruction::Register(RegisterType::SUB) => format!("sub {}, {}, {}", gpr[rd], gpr[rs1], gpr[rs2]), - Instruction::Register(RegisterType::SUBW) => format!("subw {}, {}, {}", gpr[rd], gpr[rs1], gpr[rs2]), - Instruction::Register(RegisterType::XOR) => format!("xor {}, {}, {}", gpr[rd], gpr[rs1], gpr[rs2]), - Instruction::Register(RegisterType::OR) => format!("or {}, {}, {}", gpr[rd], gpr[rs1], gpr[rs2]), - Instruction::Register(RegisterType::AND) => format!("and {}, {}, {}", gpr[rd], gpr[rs1], gpr[rs2]), - Instruction::Register(RegisterType::SLL) => format!("sll {}, {}, {}", gpr[rd], gpr[rs1], gpr[rs2]), - Instruction::Register(RegisterType::SLLW) => format!("sllw {}, {}, {}", gpr[rd], gpr[rs1], gpr[rs2]), - Instruction::Register(RegisterType::SRL) => format!("srl {}, {}, {}", gpr[rd], gpr[rs1], gpr[rs2]), - Instruction::Register(RegisterType::SRA) => format!("sra {}, {}, {}", gpr[rd], gpr[rs1], gpr[rs2]), - Instruction::Register(RegisterType::SRLW) => format!("srlw {}, {}, {}", gpr[rd], gpr[rs1], gpr[rs2]), - Instruction::Register(RegisterType::SRAW) => format!("sraw {}, {}, {}", gpr[rd], gpr[rs1], gpr[rs2]), - Instruction::Register(RegisterType::SLT) => format!("slt {}, {}, {}", gpr[rd], gpr[rs1], gpr[rs2]), - Instruction::Register(RegisterType::SLTU) => format!("sltu {}, {}, {}", gpr[rd], gpr[rs1], gpr[rs2]), - - Instruction::Immediate(ImmediateType::ADDI) => format!("addi {}, {}, {}", gpr[rd], gpr[rs1], imm), - Instruction::Immediate(ImmediateType::ADDIW) => format!("addiw {}, {}, {}", gpr[rd], gpr[rs1], imm), - Instruction::Immediate(ImmediateType::XORI) => format!("xori {}, {}, {}", gpr[rd], gpr[rs1], imm), - Instruction::Immediate(ImmediateType::ORI) => format!("ori {}, {}, {}", gpr[rd], gpr[rs1], imm), - Instruction::Immediate(ImmediateType::ANDI) => format!("andi {}, {}, {}", gpr[rd], gpr[rs1], imm), - Instruction::Immediate(ImmediateType::SLLI) => format!("slli {}, {}, {}", gpr[rd], gpr[rs1], imm), - Instruction::Immediate(ImmediateType::SLLIW) => format!("slliw {}, {}, {}", gpr[rd], gpr[rs1], imm), - Instruction::Immediate(ImmediateType::SRLI) => format!("srli {}, {}, {}", gpr[rd], gpr[rs1], imm), - Instruction::Immediate(ImmediateType::SRLIW) => format!("srliw {}, {}, {}", gpr[rd], gpr[rs1], imm), - Instruction::Immediate(ImmediateType::SRAI) => format!("srai {}, {}, {}", gpr[rd], gpr[rs1], imm), - Instruction::Immediate(ImmediateType::SRAIW) => format!("sraiw {}, {}, {}", gpr[rd], gpr[rs1], imm), - Instruction::Immediate(ImmediateType::SLTI) => format!("slti {}, {}, {}", gpr[rd], gpr[rs1], imm), - Instruction::Immediate(ImmediateType::SLTIU) => format!("sltiu {}, {}, {}", gpr[rd], gpr[rs1], imm), - - Instruction::Immediate(ImmediateType::LB) => format!("lb {}, {:x}({})", gpr[rd], imm, gpr[rs1]), - Instruction::Immediate(ImmediateType::LBU) => format!("lbu {}, {:x}({})", gpr[rd], imm, gpr[rs1]), - Instruction::Immediate(ImmediateType::LH) => format!("lh {}, {:x}({})", gpr[rd], imm, gpr[rs1]), - Instruction::Immediate(ImmediateType::LHU) => format!("lhu {}, {:x}({})", gpr[rd], imm, gpr[rs1]), - Instruction::Immediate(ImmediateType::LW) => format!("lw {}, {:x}({})", gpr[rd], imm, gpr[rs1]), - Instruction::Immediate(ImmediateType::LWU) => format!("lwu {}, {:x}({})", gpr[rd], imm, gpr[rs1]), - Instruction::Immediate(ImmediateType::LD) => format!("ld {}, {:x}({})", gpr[rd], imm, gpr[rs1]), - - Instruction::Store(StoreType::SB) => format!("sb {}, {}({})", gpr[rs2], imm, gpr[rs1]), - Instruction::Store(StoreType::SH) => format!("sh {}, {}({})", gpr[rs2], imm, gpr[rs1]), - Instruction::Store(StoreType::SW) => format!("sw {}, {}({})", gpr[rs2], imm, gpr[rs1]), - Instruction::Store(StoreType::SD) => format!("sd {}, {}({})", gpr[rs2], imm, gpr[rs1]), - - Instruction::Branch(BranchType::BEQ) => format!("beq {}, {}, {:x}", gpr[rs1], gpr[rs2], (pc as i64).wrapping_add(imm)), - Instruction::Branch(BranchType::BNE) => format!("bne {}, {}, {:x}", gpr[rs1], gpr[rs2], (pc as i64).wrapping_add(imm)), - Instruction::Branch(BranchType::BLT) => format!("blt {}, {}, {:x}", gpr[rs1], gpr[rs2], (pc as i64).wrapping_add(imm)), - Instruction::Branch(BranchType::BGE) => format!("bge {}, {}, {:x}", gpr[rs1], gpr[rs2], (pc as i64).wrapping_add(imm)), - Instruction::Branch(BranchType::BLTU) => format!("bltu {}, {}, {:x}", gpr[rs1], gpr[rs2], (pc as i64).wrapping_add(imm)), - Instruction::Branch(BranchType::BGEU) => format!("bgeu {}, {}, {:x}", gpr[rs1], gpr[rs2], (pc as i64).wrapping_add(imm)), - - Instruction::Jump(JumpType::JAL) => format!("jal {}, {:x}", gpr[rd], (imm as u64).wrapping_add(pc)), - Instruction::Immediate(ImmediateType::JALR) => format!("jalr {}, {}, {:x}", gpr[rd], gpr[rs1], imm), - - Instruction::Upper(UpperType::LUI) => format!("lui {}, {:x}", gpr[rd], imm), - Instruction::Upper(UpperType::AUIPC) => format!("auipc {}, {:x}", gpr[rd], (pc as i64).wrapping_add(imm)), - - Instruction::Register(RegisterType::MUL) => format!("mul {}, {}, {}", gpr[rd], gpr[rs1], gpr[rs2]), - Instruction::Register(RegisterType::MULH) => format!("mulh {}, {}, {}", gpr[rd], gpr[rs1], gpr[rs2]), - Instruction::Register(RegisterType::MULHU) => format!("mulhu {}, {}, {}", gpr[rd], gpr[rs1], gpr[rs2]), - Instruction::Register(RegisterType::MULHSU) => format!("mulhsu {}, {}, {}", gpr[rd], gpr[rs1], gpr[rs2]), - Instruction::Register(RegisterType::MULW) => format!("mulw {}, {}, {}", gpr[rd], gpr[rs1], gpr[rs2]), - Instruction::Register(RegisterType::DIV) => format!("div {}, {}, {}", gpr[rd], gpr[rs1], gpr[rs2]), - Instruction::Register(RegisterType::DIVU) => format!("divu {}, {}, {}", gpr[rd], gpr[rs1], gpr[rs2]), - Instruction::Register(RegisterType::DIVUW) => format!("divuw {}, {}, {}", gpr[rd], gpr[rs1], gpr[rs2]), - Instruction::Register(RegisterType::DIVW) => format!("divw {}, {}, {}", gpr[rd], gpr[rs1], gpr[rs2]), - Instruction::Register(RegisterType::REM) => format!("rem {}, {}, {}", gpr[rd], gpr[rs1], gpr[rs2]), - Instruction::Register(RegisterType::REMU) => format!("remu {}, {}, {}", gpr[rd], gpr[rs1], gpr[rs2]), - Instruction::Register(RegisterType::REMUW) => format!("remuw {}, {}, {}", gpr[rd], gpr[rs1], gpr[rs2]), - Instruction::Register(RegisterType::REMW) => format!("remw {}, {}, {}", gpr[rd], gpr[rs1], gpr[rs2]), - - Instruction::Register(RegisterType::MRET) => format!("mret"), - - Instruction::Immediate(ImmediateType::ECALL) => format!("ecall"), - Instruction::Immediate(ImmediateType::EBREAK) => format!("ebreak"), - - Instruction::Immediate(ImmediateType::FENCE) => format!("fence"), - - Instruction::Immediate(ImmediateType::CSRRW) => format!("csrrw {}, {}", gpr[rd], gpr[rs1]), - Instruction::Immediate(ImmediateType::CSRRS) => format!("csrrs {}, {}", gpr[rd], gpr[rs1]), - Instruction::Immediate(ImmediateType::CSRRC) => format!("csrrc {}, {}", gpr[rd], gpr[rs1]), - Instruction::Immediate(ImmediateType::CSRRWI) => format!("csrrwi {}, 0x{:x}, {}", gpr[rd], imm, rs1), - Instruction::Immediate(ImmediateType::CSRRSI) => format!("csrrsi {}, 0x{:x}, {}", gpr[rd], imm, rs1), - Instruction::Immediate(ImmediateType::CSRRCI) => format!("csrrci {}, 0x{:x}, {}", gpr[rd], imm, rs1), - - _ => format!("Unknown instruction") - } -} diff --git a/src/monitor/sdb.rs b/src/monitor/sdb.rs index 0150643..7cb7d1f 100644 --- a/src/monitor/sdb.rs +++ b/src/monitor/sdb.rs @@ -1,5 +1,5 @@ use crate::cpu::memory::read_data; -use crate::cpu::{Cpu, CpuState}; +use crate::cpu::{Cpu, State}; use crate::monitor::expr; use atoi::atoi; use rustyline::Editor; @@ -25,20 +25,14 @@ impl CommandTable { fn help(&self, args: &str) -> i32 { if args == "" { for i in 0..self.commands.len() { - println!( - "{} - {}", - self.commands[i].name, self.commands[i].description - ); + println!("{} - {}", self.commands[i].name, self.commands[i].description); } return 0; } for i in 0..self.commands.len() { if args == self.commands[i].name { - println!( - "{} - {}", - self.commands[i].name, self.commands[i].description - ); + println!("{} - {}", self.commands[i].name, self.commands[i].description); return 0; } } @@ -56,11 +50,7 @@ struct Command { } impl Command { - fn new( - name: &'static str, - description: &'static str, - handler: fn(&str, &mut Cpu) -> i32, - ) -> Command { + fn new(name: &'static str, description: &'static str, handler: fn(&str, &mut Cpu) -> i32) -> Command { Command { name, description, @@ -93,7 +83,7 @@ impl Command { #[allow(unused_variables)] fn quit(args: &str, cpu: &mut Cpu) -> i32 { - cpu.state = CpuState::Quit; + cpu.state = State::Quit; -1 } diff --git a/tests/am-tests.rs b/tests/am-tests.rs index 4f10d19..a7e7528 100644 --- a/tests/am-tests.rs +++ b/tests/am-tests.rs @@ -26,7 +26,7 @@ macro_rules! add_test { sdb::sdb_mainloop(cpu, true); // check the result - assert_eq!(cpu.state, cpu::CpuState::Ended); + assert_eq!(cpu.state, cpu::State::Ended); assert_eq!(cpu.halt.ret, 0); } }; diff --git a/tests/riscv-tests.rs b/tests/riscv-tests.rs index 4319a36..85d857e 100644 --- a/tests/riscv-tests.rs +++ b/tests/riscv-tests.rs @@ -2,783 +2,84 @@ use hemu::cpu; use hemu::monitor::*; use std::path::PathBuf; -#[test] -fn test_add() { - // prepare the img file - let img = PathBuf::from("./resources/riscv-tests/rv64ui/rv64ui-p-add.bin"); - - // start the monitor - let _ = load_img(img).unwrap(); - let cpu = &mut cpu::Cpu::new(None); - sdb::sdb_mainloop(cpu, true); - - // check the result - assert_eq!(cpu.state, cpu::CpuState::Ended); - assert_eq!(cpu.halt.ret, 0); -} - -#[test] -fn test_addi() { - // prepare the img file - let img = PathBuf::from("./resources/riscv-tests/rv64ui/rv64ui-p-addi.bin"); - - // start the monitor - let _ = load_img(img).unwrap(); - let cpu = &mut cpu::Cpu::new(None); - sdb::sdb_mainloop(cpu, true); - - // check the result - assert_eq!(cpu.state, cpu::CpuState::Ended); - assert_eq!(cpu.halt.ret, 0); -} - -#[test] -fn test_addiw() { - // prepare the img file - let img = PathBuf::from("./resources/riscv-tests/rv64ui/rv64ui-p-addiw.bin"); - - // start the monitor - let _ = load_img(img).unwrap(); - let cpu = &mut cpu::Cpu::new(None); - sdb::sdb_mainloop(cpu, true); - - // check the result - assert_eq!(cpu.state, cpu::CpuState::Ended); - assert_eq!(cpu.halt.ret, 0); -} - -#[test] -fn test_addw() { - // prepare the img file - let img = PathBuf::from("./resources/riscv-tests/rv64ui/rv64ui-p-addw.bin"); - - // start the monitor - let _ = load_img(img).unwrap(); - let cpu = &mut cpu::Cpu::new(None); - sdb::sdb_mainloop(cpu, true); - - // check the result - assert_eq!(cpu.state, cpu::CpuState::Ended); - assert_eq!(cpu.halt.ret, 0); -} - -#[test] -fn test_and() { - // prepare the img file - let img = PathBuf::from("./resources/riscv-tests/rv64ui/rv64ui-p-and.bin"); - - // start the monitor - let _ = load_img(img).unwrap(); - let cpu = &mut cpu::Cpu::new(None); - sdb::sdb_mainloop(cpu, true); - - // check the result - assert_eq!(cpu.state, cpu::CpuState::Ended); - assert_eq!(cpu.halt.ret, 0); -} - -#[test] -fn test_andi() { - // prepare the img file - let img = PathBuf::from("./resources/riscv-tests/rv64ui/rv64ui-p-andi.bin"); - - // start the monitor - let _ = load_img(img).unwrap(); - let cpu = &mut cpu::Cpu::new(None); - sdb::sdb_mainloop(cpu, true); - - // check the result - assert_eq!(cpu.state, cpu::CpuState::Ended); - assert_eq!(cpu.halt.ret, 0); -} - -#[test] -fn test_auipc() { - // prepare the img file - let img = PathBuf::from("./resources/riscv-tests/rv64ui/rv64ui-p-auipc.bin"); - - // start the monitor - let _ = load_img(img).unwrap(); - let cpu = &mut cpu::Cpu::new(None); - sdb::sdb_mainloop(cpu, true); - - // check the result - assert_eq!(cpu.state, cpu::CpuState::Ended); - assert_eq!(cpu.halt.ret, 0); -} - -#[test] -fn test_beq() { - // prepare the img file - let img = PathBuf::from("./resources/riscv-tests/rv64ui/rv64ui-p-beq.bin"); - - // start the monitor - let _ = load_img(img).unwrap(); - let cpu = &mut cpu::Cpu::new(None); - sdb::sdb_mainloop(cpu, true); - - // check the result - assert_eq!(cpu.state, cpu::CpuState::Ended); - assert_eq!(cpu.halt.ret, 0); -} - -#[test] -fn test_bge() { - // prepare the img file - let img = PathBuf::from("./resources/riscv-tests/rv64ui/rv64ui-p-bge.bin"); - - // start the monitor - let _ = load_img(img).unwrap(); - let cpu = &mut cpu::Cpu::new(None); - sdb::sdb_mainloop(cpu, true); - - // check the result - assert_eq!(cpu.state, cpu::CpuState::Ended); - assert_eq!(cpu.halt.ret, 0); -} - -#[test] -fn test_bgeu() { - // prepare the img file - let img = PathBuf::from("./resources/riscv-tests/rv64ui/rv64ui-p-bgeu.bin"); - - // start the monitor - let _ = load_img(img).unwrap(); - let cpu = &mut cpu::Cpu::new(None); - sdb::sdb_mainloop(cpu, true); - - // check the result - assert_eq!(cpu.state, cpu::CpuState::Ended); - assert_eq!(cpu.halt.ret, 0); -} - -#[test] -fn test_blt() { - // prepare the img file - let img = PathBuf::from("./resources/riscv-tests/rv64ui/rv64ui-p-blt.bin"); - - // start the monitor - let _ = load_img(img).unwrap(); - let cpu = &mut cpu::Cpu::new(None); - sdb::sdb_mainloop(cpu, true); - - // check the result - assert_eq!(cpu.state, cpu::CpuState::Ended); - assert_eq!(cpu.halt.ret, 0); -} - -#[test] -fn test_bltu() { - // prepare the img file - let img = PathBuf::from("./resources/riscv-tests/rv64ui/rv64ui-p-bltu.bin"); - - // start the monitor - let _ = load_img(img).unwrap(); - let cpu = &mut cpu::Cpu::new(None); - sdb::sdb_mainloop(cpu, true); - - // check the result - assert_eq!(cpu.state, cpu::CpuState::Ended); - assert_eq!(cpu.halt.ret, 0); -} - -#[test] -fn test_bne() { - // prepare the img file - let img = PathBuf::from("./resources/riscv-tests/rv64ui/rv64ui-p-bne.bin"); - - // start the monitor - let _ = load_img(img).unwrap(); - let cpu = &mut cpu::Cpu::new(None); - sdb::sdb_mainloop(cpu, true); - - // check the result - assert_eq!(cpu.state, cpu::CpuState::Ended); - assert_eq!(cpu.halt.ret, 0); -} - -#[test] -fn test_fence_i() { - // prepare the img file - let img = PathBuf::from("./resources/riscv-tests/rv64ui/rv64ui-p-fence_i.bin"); - - // start the monitor - let _ = load_img(img).unwrap(); - let cpu = &mut cpu::Cpu::new(None); - sdb::sdb_mainloop(cpu, true); - - // check the result - assert_eq!(cpu.state, cpu::CpuState::Ended); - assert_eq!(cpu.halt.ret, 0); -} - -#[test] -fn test_jal() { - // prepare the img file - let img = PathBuf::from("./resources/riscv-tests/rv64ui/rv64ui-p-jal.bin"); - - // start the monitor - let _ = load_img(img).unwrap(); - let cpu = &mut cpu::Cpu::new(None); - sdb::sdb_mainloop(cpu, true); - - // check the result - assert_eq!(cpu.state, cpu::CpuState::Ended); - assert_eq!(cpu.halt.ret, 0); -} - -#[test] -fn test_jalr() { - // prepare the img file - let img = PathBuf::from("./resources/riscv-tests/rv64ui/rv64ui-p-jalr.bin"); - - // start the monitor - let _ = load_img(img).unwrap(); - let cpu = &mut cpu::Cpu::new(None); - sdb::sdb_mainloop(cpu, true); - - // check the result - assert_eq!(cpu.state, cpu::CpuState::Ended); - assert_eq!(cpu.halt.ret, 0); -} - -#[test] -fn test_lb() { - // prepare the img file - let img = PathBuf::from("./resources/riscv-tests/rv64ui/rv64ui-p-lb.bin"); - - // start the monitor - let _ = load_img(img).unwrap(); - let cpu = &mut cpu::Cpu::new(None); - sdb::sdb_mainloop(cpu, true); - - // check the result - assert_eq!(cpu.state, cpu::CpuState::Ended); - assert_eq!(cpu.halt.ret, 0); -} - -#[test] -fn test_lbu() { - // prepare the img file - let img = PathBuf::from("./resources/riscv-tests/rv64ui/rv64ui-p-lbu.bin"); - - // start the monitor - let _ = load_img(img).unwrap(); - let cpu = &mut cpu::Cpu::new(None); - sdb::sdb_mainloop(cpu, true); - - // check the result - assert_eq!(cpu.state, cpu::CpuState::Ended); - assert_eq!(cpu.halt.ret, 0); -} - -#[test] -fn test_ld() { - // prepare the img file - let img = PathBuf::from("./resources/riscv-tests/rv64ui/rv64ui-p-ld.bin"); - - // start the monitor - let _ = load_img(img).unwrap(); - let cpu = &mut cpu::Cpu::new(None); - sdb::sdb_mainloop(cpu, true); - - // check the result - assert_eq!(cpu.state, cpu::CpuState::Ended); - assert_eq!(cpu.halt.ret, 0); -} - -#[test] -fn test_lh() { - // prepare the img file - let img = PathBuf::from("./resources/riscv-tests/rv64ui/rv64ui-p-lh.bin"); - - // start the monitor - let _ = load_img(img).unwrap(); - let cpu = &mut cpu::Cpu::new(None); - sdb::sdb_mainloop(cpu, true); - - // check the result - assert_eq!(cpu.state, cpu::CpuState::Ended); - assert_eq!(cpu.halt.ret, 0); -} - -#[test] -fn test_lhu() { - // prepare the img file - let img = PathBuf::from("./resources/riscv-tests/rv64ui/rv64ui-p-lhu.bin"); - - // start the monitor - let _ = load_img(img).unwrap(); - let cpu = &mut cpu::Cpu::new(None); - sdb::sdb_mainloop(cpu, true); - - // check the result - assert_eq!(cpu.state, cpu::CpuState::Ended); - assert_eq!(cpu.halt.ret, 0); -} - -#[test] -fn test_lui() { - // prepare the img file - let img = PathBuf::from("./resources/riscv-tests/rv64ui/rv64ui-p-lui.bin"); - - // start the monitor - let _ = load_img(img).unwrap(); - let cpu = &mut cpu::Cpu::new(None); - sdb::sdb_mainloop(cpu, true); - - // check the result - assert_eq!(cpu.state, cpu::CpuState::Ended); - assert_eq!(cpu.halt.ret, 0); -} - -#[test] -fn test_lw() { - // prepare the img file - let img = PathBuf::from("./resources/riscv-tests/rv64ui/rv64ui-p-lw.bin"); - - // start the monitor - let _ = load_img(img).unwrap(); - let cpu = &mut cpu::Cpu::new(None); - sdb::sdb_mainloop(cpu, true); - - // check the result - assert_eq!(cpu.state, cpu::CpuState::Ended); - assert_eq!(cpu.halt.ret, 0); -} - -#[test] -fn test_lwu() { - // prepare the img file - let img = PathBuf::from("./resources/riscv-tests/rv64ui/rv64ui-p-lwu.bin"); - - // start the monitor - let _ = load_img(img).unwrap(); - let cpu = &mut cpu::Cpu::new(None); - sdb::sdb_mainloop(cpu, true); - - // check the result - assert_eq!(cpu.state, cpu::CpuState::Ended); - assert_eq!(cpu.halt.ret, 0); -} - -#[test] -fn test_ma_data() { - // prepare the img file - let img = PathBuf::from("./resources/riscv-tests/rv64ui/rv64ui-p-ma_data.bin"); - - // start the monitor - let _ = load_img(img).unwrap(); - let cpu = &mut cpu::Cpu::new(None); - sdb::sdb_mainloop(cpu, true); - - // check the result - assert_eq!(cpu.state, cpu::CpuState::Ended); - assert_eq!(cpu.halt.ret, 0); -} - -#[test] -fn test_or() { - // prepare the img file - let img = PathBuf::from("./resources/riscv-tests/rv64ui/rv64ui-p-or.bin"); - - // start the monitor - let _ = load_img(img).unwrap(); - let cpu = &mut cpu::Cpu::new(None); - sdb::sdb_mainloop(cpu, true); - - // check the result - assert_eq!(cpu.state, cpu::CpuState::Ended); - assert_eq!(cpu.halt.ret, 0); -} - -#[test] -fn test_ori() { - // prepare the img file - let img = PathBuf::from("./resources/riscv-tests/rv64ui/rv64ui-p-ori.bin"); - - // start the monitor - let _ = load_img(img).unwrap(); - let cpu = &mut cpu::Cpu::new(None); - sdb::sdb_mainloop(cpu, true); - - // check the result - assert_eq!(cpu.state, cpu::CpuState::Ended); - assert_eq!(cpu.halt.ret, 0); -} - -#[test] -fn test_sb() { - // prepare the img file - let img = PathBuf::from("./resources/riscv-tests/rv64ui/rv64ui-p-sb.bin"); - - // start the monitor - let _ = load_img(img).unwrap(); - let cpu = &mut cpu::Cpu::new(None); - sdb::sdb_mainloop(cpu, true); - - // check the result - assert_eq!(cpu.state, cpu::CpuState::Ended); - assert_eq!(cpu.halt.ret, 0); -} - -#[test] -fn test_sd() { - // prepare the img file - let img = PathBuf::from("./resources/riscv-tests/rv64ui/rv64ui-p-sd.bin"); - - // start the monitor - let _ = load_img(img).unwrap(); - let cpu = &mut cpu::Cpu::new(None); - sdb::sdb_mainloop(cpu, true); - - // check the result - assert_eq!(cpu.state, cpu::CpuState::Ended); - assert_eq!(cpu.halt.ret, 0); -} - -#[test] -fn test_sh() { - // prepare the img file - let img = PathBuf::from("./resources/riscv-tests/rv64ui/rv64ui-p-sh.bin"); - - // start the monitor - let _ = load_img(img).unwrap(); - let cpu = &mut cpu::Cpu::new(None); - sdb::sdb_mainloop(cpu, true); - - // check the result - assert_eq!(cpu.state, cpu::CpuState::Ended); - assert_eq!(cpu.halt.ret, 0); -} - -#[test] -fn test_simple() { - // prepare the img file - let img = PathBuf::from("./resources/riscv-tests/rv64ui/rv64ui-p-simple.bin"); - - // start the monitor - let _ = load_img(img).unwrap(); - let cpu = &mut cpu::Cpu::new(None); - sdb::sdb_mainloop(cpu, true); - - // check the result - assert_eq!(cpu.state, cpu::CpuState::Ended); - assert_eq!(cpu.halt.ret, 0); -} - -#[test] -fn test_sll() { - // prepare the img file - let img = PathBuf::from("./resources/riscv-tests/rv64ui/rv64ui-p-sll.bin"); - - // start the monitor - let _ = load_img(img).unwrap(); - let cpu = &mut cpu::Cpu::new(None); - sdb::sdb_mainloop(cpu, true); - - // check the result - assert_eq!(cpu.state, cpu::CpuState::Ended); - assert_eq!(cpu.halt.ret, 0); -} - -#[test] -fn test_slli() { - // prepare the img file - let img = PathBuf::from("./resources/riscv-tests/rv64ui/rv64ui-p-slli.bin"); - - // start the monitor - let _ = load_img(img).unwrap(); - let cpu = &mut cpu::Cpu::new(None); - sdb::sdb_mainloop(cpu, true); - - // check the result - assert_eq!(cpu.state, cpu::CpuState::Ended); - assert_eq!(cpu.halt.ret, 0); -} - -#[test] -fn test_slliw() { - // prepare the img file - let img = PathBuf::from("./resources/riscv-tests/rv64ui/rv64ui-p-slliw.bin"); - - // start the monitor - let _ = load_img(img).unwrap(); - let cpu = &mut cpu::Cpu::new(None); - sdb::sdb_mainloop(cpu, true); - - // check the result - assert_eq!(cpu.state, cpu::CpuState::Ended); - assert_eq!(cpu.halt.ret, 0); -} - -#[test] -fn test_sllw() { - // prepare the img file - let img = PathBuf::from("./resources/riscv-tests/rv64ui/rv64ui-p-sllw.bin"); - - // start the monitor - let _ = load_img(img).unwrap(); - let cpu = &mut cpu::Cpu::new(None); - sdb::sdb_mainloop(cpu, true); - - // check the result - assert_eq!(cpu.state, cpu::CpuState::Ended); - assert_eq!(cpu.halt.ret, 0); -} - -#[test] -fn test_slt() { - // prepare the img file - let img = PathBuf::from("./resources/riscv-tests/rv64ui/rv64ui-p-slt.bin"); - - // start the monitor - let _ = load_img(img).unwrap(); - let cpu = &mut cpu::Cpu::new(None); - sdb::sdb_mainloop(cpu, true); - - // check the result - assert_eq!(cpu.state, cpu::CpuState::Ended); - assert_eq!(cpu.halt.ret, 0); -} - -#[test] -fn test_slti() { - // prepare the img file - let img = PathBuf::from("./resources/riscv-tests/rv64ui/rv64ui-p-slti.bin"); - - // start the monitor - let _ = load_img(img).unwrap(); - let cpu = &mut cpu::Cpu::new(None); - sdb::sdb_mainloop(cpu, true); - - // check the result - assert_eq!(cpu.state, cpu::CpuState::Ended); - assert_eq!(cpu.halt.ret, 0); -} - -#[test] -fn test_sltiu() { - // prepare the img file - let img = PathBuf::from("./resources/riscv-tests/rv64ui/rv64ui-p-sltiu.bin"); - - // start the monitor - let _ = load_img(img).unwrap(); - let cpu = &mut cpu::Cpu::new(None); - sdb::sdb_mainloop(cpu, true); - - // check the result - assert_eq!(cpu.state, cpu::CpuState::Ended); - assert_eq!(cpu.halt.ret, 0); -} - -#[test] -fn test_sltu() { - // prepare the img file - let img = PathBuf::from("./resources/riscv-tests/rv64ui/rv64ui-p-sltu.bin"); - - // start the monitor - let _ = load_img(img).unwrap(); - let cpu = &mut cpu::Cpu::new(None); - sdb::sdb_mainloop(cpu, true); - - // check the result - assert_eq!(cpu.state, cpu::CpuState::Ended); - assert_eq!(cpu.halt.ret, 0); -} - -#[test] -fn test_sra() { - // prepare the img file - let img = PathBuf::from("./resources/riscv-tests/rv64ui/rv64ui-p-sra.bin"); - - // start the monitor - let _ = load_img(img).unwrap(); - let cpu = &mut cpu::Cpu::new(None); - sdb::sdb_mainloop(cpu, true); - - // check the result - assert_eq!(cpu.state, cpu::CpuState::Ended); - assert_eq!(cpu.halt.ret, 0); -} - -#[test] -fn test_srai() { - // prepare the img file - let img = PathBuf::from("./resources/riscv-tests/rv64ui/rv64ui-p-srai.bin"); - - // start the monitor - let _ = load_img(img).unwrap(); - let cpu = &mut cpu::Cpu::new(None); - sdb::sdb_mainloop(cpu, true); - - // check the result - assert_eq!(cpu.state, cpu::CpuState::Ended); - assert_eq!(cpu.halt.ret, 0); -} - -#[test] -fn test_sraiw() { - // prepare the img file - let img = PathBuf::from("./resources/riscv-tests/rv64ui/rv64ui-p-sraiw.bin"); - - // start the monitor - let _ = load_img(img).unwrap(); - let cpu = &mut cpu::Cpu::new(None); - sdb::sdb_mainloop(cpu, true); - - // check the result - assert_eq!(cpu.state, cpu::CpuState::Ended); - assert_eq!(cpu.halt.ret, 0); -} - -#[test] -fn test_sraw() { - // prepare the img file - let img = PathBuf::from("./resources/riscv-tests/rv64ui/rv64ui-p-sraw.bin"); - - // start the monitor - let _ = load_img(img).unwrap(); - let cpu = &mut cpu::Cpu::new(None); - sdb::sdb_mainloop(cpu, true); - - // check the result - assert_eq!(cpu.state, cpu::CpuState::Ended); - assert_eq!(cpu.halt.ret, 0); -} - -#[test] -fn test_srl() { - // prepare the img file - let img = PathBuf::from("./resources/riscv-tests/rv64ui/rv64ui-p-srl.bin"); - - // start the monitor - let _ = load_img(img).unwrap(); - let cpu = &mut cpu::Cpu::new(None); - sdb::sdb_mainloop(cpu, true); - - // check the result - assert_eq!(cpu.state, cpu::CpuState::Ended); - assert_eq!(cpu.halt.ret, 0); -} - -#[test] -fn test_srli() { - // prepare the img file - let img = PathBuf::from("./resources/riscv-tests/rv64ui/rv64ui-p-srli.bin"); - - // start the monitor - let _ = load_img(img).unwrap(); - let cpu = &mut cpu::Cpu::new(None); - sdb::sdb_mainloop(cpu, true); - - // check the result - assert_eq!(cpu.state, cpu::CpuState::Ended); - assert_eq!(cpu.halt.ret, 0); -} - -#[test] -fn test_srliw() { - // prepare the img file - let img = PathBuf::from("./resources/riscv-tests/rv64ui/rv64ui-p-srliw.bin"); - - // start the monitor - let _ = load_img(img).unwrap(); - let cpu = &mut cpu::Cpu::new(None); - sdb::sdb_mainloop(cpu, true); - - // check the result - assert_eq!(cpu.state, cpu::CpuState::Ended); - assert_eq!(cpu.halt.ret, 0); -} - -#[test] -fn test_srlw() { - // prepare the img file - let img = PathBuf::from("./resources/riscv-tests/rv64ui/rv64ui-p-srlw.bin"); - - // start the monitor - let _ = load_img(img).unwrap(); - let cpu = &mut cpu::Cpu::new(None); - sdb::sdb_mainloop(cpu, true); - - // check the result - assert_eq!(cpu.state, cpu::CpuState::Ended); - assert_eq!(cpu.halt.ret, 0); -} - -#[test] -fn test_sub() { - // prepare the img file - let img = PathBuf::from("./resources/riscv-tests/rv64ui/rv64ui-p-sub.bin"); - - // start the monitor - let _ = load_img(img).unwrap(); - let cpu = &mut cpu::Cpu::new(None); - sdb::sdb_mainloop(cpu, true); - - // check the result - assert_eq!(cpu.state, cpu::CpuState::Ended); - assert_eq!(cpu.halt.ret, 0); -} - -#[test] -fn test_subw() { - // prepare the img file - let img = PathBuf::from("./resources/riscv-tests/rv64ui/rv64ui-p-subw.bin"); - - // start the monitor - let _ = load_img(img).unwrap(); - let cpu = &mut cpu::Cpu::new(None); - sdb::sdb_mainloop(cpu, true); - - // check the result - assert_eq!(cpu.state, cpu::CpuState::Ended); - assert_eq!(cpu.halt.ret, 0); -} - -#[test] -fn test_sw() { - // prepare the img file - let img = PathBuf::from("./resources/riscv-tests/rv64ui/rv64ui-p-sw.bin"); - - // start the monitor - let _ = load_img(img).unwrap(); - let cpu = &mut cpu::Cpu::new(None); - sdb::sdb_mainloop(cpu, true); - - // check the result - assert_eq!(cpu.state, cpu::CpuState::Ended); - assert_eq!(cpu.halt.ret, 0); -} - -#[test] -fn test_xor() { - // prepare the img file - let img = PathBuf::from("./resources/riscv-tests/rv64ui/rv64ui-p-xor.bin"); - - // start the monitor - let _ = load_img(img).unwrap(); - let cpu = &mut cpu::Cpu::new(None); - sdb::sdb_mainloop(cpu, true); - - // check the result - assert_eq!(cpu.state, cpu::CpuState::Ended); - assert_eq!(cpu.halt.ret, 0); -} - -#[test] -fn test_xori() { - // prepare the img file - let img = PathBuf::from("./resources/riscv-tests/rv64ui/rv64ui-p-xori.bin"); - - // start the monitor - let _ = load_img(img).unwrap(); - let cpu = &mut cpu::Cpu::new(None); - sdb::sdb_mainloop(cpu, true); - - // check the result - assert_eq!(cpu.state, cpu::CpuState::Ended); - assert_eq!(cpu.halt.ret, 0); -} - +#[macro_export] +macro_rules! add_test { + ($name: ident) => { + #[test] + fn $name() { + let mut root = String::from(env!("CARGO_MANIFEST_DIR")); + root.push_str("/tests/resources/riscv-tests/rv64ui/rv64ui-p-"); + root.push_str(&stringify!($name).replace("_", "-")); + + // prepare the diff file + let diff = None; + + // prepare the img file + let img = PathBuf::from(root.to_string() + ".bin"); + + println!("img:{:?}", img); + + // start the monitor + let _ = load_img(img).unwrap(); + let cpu = &mut cpu::Cpu::new(diff); + sdb::sdb_mainloop(cpu, true); + + // check the result + assert_eq!(cpu.state, cpu::State::Ended); + assert_eq!(cpu.halt.ret, 0); + } + }; +} + +add_test!(add); +add_test!(addi); +add_test!(addiw); +add_test!(addw); +add_test!(and); +add_test!(andi); +add_test!(auipc); +add_test!(beq); +add_test!(bge); +add_test!(bgeu); +add_test!(blt); +add_test!(bltu); +add_test!(bne); +add_test!(fence_i); +add_test!(jal); +add_test!(jalr); +add_test!(lb); +add_test!(lbu); +add_test!(ld); +add_test!(lh); +add_test!(lhu); +add_test!(lui); +add_test!(lw); +add_test!(lwu); +add_test!(ma_data); +add_test!(or); +add_test!(ori); +add_test!(sb); +add_test!(sd); +add_test!(sh); +add_test!(simple); +add_test!(sll); +add_test!(slli); +add_test!(slliw); +add_test!(sllw); +add_test!(slt); +add_test!(slti); +add_test!(sltiu); +add_test!(sltu); +add_test!(sra); +add_test!(srai); +add_test!(sraiw); +add_test!(sraw); +add_test!(srl); +add_test!(srli); +add_test!(srliw); +add_test!(srlw); +add_test!(sub); +add_test!(subw); +add_test!(sw); +add_test!(xor); +add_test!(xori);