Add exception values (what will go in mtval/stval)

This commit is contained in:
2025-12-27 21:33:39 +01:00
parent b5d36b7969
commit 5c008bfc04
9 changed files with 295 additions and 161 deletions

View File

@@ -10,12 +10,20 @@ mod macros;
mod rvi;
use crate::{
consts::DWord,
core::Core,
decode::Instruction,
exceptions::ExceptionType::{self, IllegalInstruction},
exceptions::{Exception, ExceptionType::IllegalInstruction},
};
pub(crate) fn find_and_exec(instr: Instruction, core: &mut Core) -> Result<(), ExceptionType> {
fn illegal(instr: Instruction) -> Result<(), Exception> {
Err(Exception {
type_: IllegalInstruction,
value: instr.0 as DWord,
})
}
pub(crate) fn find_and_exec(instr: Instruction, core: &mut Core) -> Result<(), Exception> {
match instr.opcode_noncompressed() {
0b01100 => match (instr.funct3(), instr.funct7()) {
// OP
@@ -29,7 +37,7 @@ pub(crate) fn find_and_exec(instr: Instruction, core: &mut Core) -> Result<(), E
(0b111, 0b0000000) => rvi::and(core, instr),
(0b100, 0b0000000) => rvi::xor(core, instr),
(0b110, 0b0000000) => rvi::or(core, instr),
_ => Err(IllegalInstruction),
_ => illegal(instr),
},
0b01110 => match (instr.funct3(), instr.funct7()) {
// OP_32
@@ -38,7 +46,7 @@ pub(crate) fn find_and_exec(instr: Instruction, core: &mut Core) -> Result<(), E
(0b001, 0b0000000) => rvi::sllw(core, instr),
(0b101, 0b0000000) => rvi::srlw(core, instr),
(0b101, 0b0100000) => rvi::sraw(core, instr),
_ => Err(IllegalInstruction),
_ => illegal(instr),
},
0b00100 => match instr.funct3() {
// OP_IMM
@@ -47,31 +55,31 @@ pub(crate) fn find_and_exec(instr: Instruction, core: &mut Core) -> Result<(), E
0b011 => rvi::sltiu(core, instr),
0b001 => match instr.funct6() {
0 => rvi::slli(core, instr),
_ => Err(IllegalInstruction),
_ => illegal(instr),
},
0b101 => match instr.funct6() {
0b000000 => rvi::srli(core, instr),
0b010000 => rvi::srai(core, instr),
_ => Err(IllegalInstruction),
_ => illegal(instr),
},
0b100 => rvi::xori(core, instr),
0b110 => rvi::ori(core, instr),
0b111 => rvi::andi(core, instr),
_ => Err(IllegalInstruction),
_ => illegal(instr),
},
0b00110 => match instr.funct3() {
// OP_IMM_32
0b000 => rvi::addiw(core, instr),
0b001 => match instr.funct7() {
0 => rvi::slliw(core, instr),
_ => Err(IllegalInstruction),
_ => illegal(instr),
},
0b101 => match instr.funct7() {
0b0000000 => rvi::srliw(core, instr),
0b0100000 => rvi::sraiw(core, instr),
_ => Err(IllegalInstruction),
_ => illegal(instr),
},
_ => Err(IllegalInstruction),
_ => illegal(instr),
},
0b01000 => match instr.funct3() {
// STORE
@@ -79,7 +87,7 @@ pub(crate) fn find_and_exec(instr: Instruction, core: &mut Core) -> Result<(), E
0b001 => rvi::sh(core, instr),
0b010 => rvi::sw(core, instr),
0b011 => rvi::sd(core, instr),
_ => Err(IllegalInstruction),
_ => illegal(instr),
},
0b00000 => match instr.funct3() {
// LOAD
@@ -90,7 +98,7 @@ pub(crate) fn find_and_exec(instr: Instruction, core: &mut Core) -> Result<(), E
0b010 => rvi::lw(core, instr),
0b110 => rvi::lwu(core, instr),
0b011 => rvi::ld(core, instr),
_ => Err(IllegalInstruction),
_ => illegal(instr),
},
0b11000 => match instr.funct3() {
// BRANCH
@@ -100,7 +108,7 @@ pub(crate) fn find_and_exec(instr: Instruction, core: &mut Core) -> Result<(), E
0b101 => rvi::bge(core, instr),
0b110 => rvi::bltu(core, instr),
0b111 => rvi::bgeu(core, instr),
_ => Err(IllegalInstruction),
_ => illegal(instr),
},
0b01101 => rvi::lui(core, instr),
0b00101 => rvi::auipc(core, instr),
@@ -109,7 +117,7 @@ pub(crate) fn find_and_exec(instr: Instruction, core: &mut Core) -> Result<(), E
if instr.funct3() == 0 {
rvi::jalr(core, instr)
} else {
Err(IllegalInstruction)
illegal(instr)
}
}
0b00011 => match instr.funct3() {
@@ -120,8 +128,8 @@ pub(crate) fn find_and_exec(instr: Instruction, core: &mut Core) -> Result<(), E
std::sync::atomic::fence(std::sync::atomic::Ordering::SeqCst);
Ok(())
}
_ => Err(IllegalInstruction),
_ => illegal(instr),
},
_ => Err(IllegalInstruction),
_ => illegal(instr),
}
}