Implement ECALL and EBREAK, the final RV64I instructions!

This commit is contained in:
2025-12-27 21:47:22 +01:00
parent 5c008bfc04
commit 8024af6b13
4 changed files with 29 additions and 1 deletions

View File

@@ -4,6 +4,8 @@ taitep's RISC-V Emulator.
The goal is to support at least RV64GC and be able to run Linux,
potentially more. No plans for RV32I or RV32/64E.
Currently implemented RISC-V ISA: `RV64I`
## Current Use
Currently, the emulator is nowhere near complete,
its not even at rv64i, but it does work for a subset of it.

View File

@@ -93,4 +93,9 @@ impl Instruction {
pub fn funct6(self) -> u8 {
(self.0 >> 26 & 0x3f) as u8
}
/// Mostly/only used for the SYSTEM opcode
pub fn funct12(self) -> u16 {
(self.0 >> 20) as u16
}
}

View File

@@ -31,6 +31,15 @@ pub enum ExceptionType {
HardwareError = 19,
}
impl ExceptionType {
pub fn with_no_value(self) -> Exception {
Exception {
type_: self,
value: 0,
}
}
}
#[derive(Debug, Clone, Copy)]
pub struct Exception {
pub type_: ExceptionType,

View File

@@ -13,7 +13,10 @@ use crate::{
consts::DWord,
core::Core,
decode::Instruction,
exceptions::{Exception, ExceptionType::IllegalInstruction},
exceptions::{
Exception,
ExceptionType::{self, IllegalInstruction},
},
};
fn illegal(instr: Instruction) -> Result<(), Exception> {
@@ -130,6 +133,15 @@ pub(crate) fn find_and_exec(instr: Instruction, core: &mut Core) -> Result<(), E
}
_ => illegal(instr),
},
0b11100 => match (instr.funct3(), instr.funct12(), instr.rs1(), instr.rd()) {
(0b000, 0b000000000000, 0, 0) => {
// TODO: When privilege modes are added, make the exception raised by ecall
// depend on privilege mode
Err(ExceptionType::EnvironmentCallFromMMode.with_no_value())
}
(0b000, 0b000000000001, 0, 0) => Err(ExceptionType::Breakpoint.with_no_value()),
_ => illegal(instr),
},
_ => illegal(instr),
}
}