From 81590e5f83b9f5b5b5d2fc8b04b0511376af17e3 Mon Sep 17 00:00:00 2001 From: iris Date: Wed, 19 Aug 2026 22:28:21 +0200 Subject: [PATCH] better structure + no need for lifetime specifier in Error. TODO: figure out better name for aforementioned --- backend/src/core/cpu.rs | 2 +- backend/src/core/interpreter.rs | 5 +- backend/src/core/interpreter/decode.rs | 30 ----------- .../interpreter/{instructions.rs => isa.rs} | 54 ++++++++++++------- utils/src/error.rs | 12 ++--- 5 files changed, 45 insertions(+), 58 deletions(-) delete mode 100644 backend/src/core/interpreter/decode.rs rename backend/src/core/interpreter/{instructions.rs => isa.rs} (76%) diff --git a/backend/src/core/cpu.rs b/backend/src/core/cpu.rs index aea7e29..f8021fe 100644 --- a/backend/src/core/cpu.rs +++ b/backend/src/core/cpu.rs @@ -18,7 +18,7 @@ pub trait Cpu { fn fetch_then_advance(&mut self, _: &Memory) -> Option { None } - fn step(&mut self, mem: &Memory) -> Result>; + fn step(&mut self, mem: &Memory) -> Result; fn advance(&mut self) -> bool { false } diff --git a/backend/src/core/interpreter.rs b/backend/src/core/interpreter.rs index 9d0de6d..dfeb174 100644 --- a/backend/src/core/interpreter.rs +++ b/backend/src/core/interpreter.rs @@ -5,8 +5,7 @@ use crate::core::{ }; use utils::{error::Error, instruction::Instruction}; -pub mod decode; -pub mod instructions; +mod isa; pub struct Interpreter { regs: Registers, @@ -65,7 +64,7 @@ impl Cpu for Interpreter { Some(instr) } - fn step(&mut self, mem: &Memory) -> Result> { + fn step(&mut self, mem: &Memory) -> Result { if let Some(instr) = self.fetch_then_advance(mem) { self.decode_execute(instr)?; } diff --git a/backend/src/core/interpreter/decode.rs b/backend/src/core/interpreter/decode.rs deleted file mode 100644 index 61ebf7d..0000000 --- a/backend/src/core/interpreter/decode.rs +++ /dev/null @@ -1,30 +0,0 @@ -use utils::{ - error::{Error, Severity, Type::UnhandledInstruction}, - instruction::Instruction, -}; - -use crate::core::interpreter::Interpreter; - -impl Interpreter { - pub fn decode_special(&mut self, instr: Instruction) -> Result<(), Error<'_>> { - match instr.special() { - Instruction::SLL => Ok(self.sll(instr)), - Instruction::ADD => Ok(self.add(instr)), - Instruction::ADDU => Ok(self.addu(instr)), - _ => Err(Error { - severity: Severity::Fatal, - err_type: UnhandledInstruction("CPU::SpecialFunction", instr), - }), - } - } - - pub fn decode_execute(&mut self, instr: Instruction) -> Result<(), Error<'_>> { - match instr.opcode() { - Instruction::SPECIAL => self.decode_special(instr), - _ => Err(Error { - severity: Severity::Error, - err_type: UnhandledInstruction("CPU::Opcode", instr), - }), - } - } -} diff --git a/backend/src/core/interpreter/instructions.rs b/backend/src/core/interpreter/isa.rs similarity index 76% rename from backend/src/core/interpreter/instructions.rs rename to backend/src/core/interpreter/isa.rs index d4f0a23..0d75b9e 100644 --- a/backend/src/core/interpreter/instructions.rs +++ b/backend/src/core/interpreter/isa.rs @@ -1,6 +1,3 @@ -#![allow(dead_code)] -#![allow(unused)] - use utils::{ error::{Error, Severity, Type::UnhandledInstruction}, instruction::Instruction, @@ -9,7 +6,29 @@ use utils::{ use crate::core::interpreter::Interpreter; impl Interpreter { - pub fn add(&mut self, instr: Instruction) { + fn decode_special(&mut self, instr: Instruction) -> Result<(), Error> { + match instr.special() { + Instruction::SLL => Ok(self.sll(instr)), + Instruction::ADD => Ok(self.add(instr)), + Instruction::ADDU => Ok(self.addu(instr)), + _ => Err(Error { + severity: Severity::Fatal, + err_type: UnhandledInstruction("CPU::SpecialFunction", instr), + }), + } + } + + pub fn decode_execute(&mut self, instr: Instruction) -> Result<(), Error> { + match instr.opcode() { + Instruction::SPECIAL => self.decode_special(instr), + _ => Err(Error { + severity: Severity::Error, + err_type: UnhandledInstruction("CPU::Opcode", instr), + }), + } + } + + fn add(&mut self, instr: Instruction) { let rs = self.regs.read(instr.rs()) as u32; let rt = self.regs.read(instr.rt()) as u32; let (rd, overflow) = rs.overflowing_add(rt); @@ -20,13 +39,13 @@ impl Interpreter { self.regs.write(instr.rd(), rd as i32); } - pub fn addu(&mut self, instr: Instruction) { + fn addu(&mut self, instr: Instruction) { let rs = self.regs.read(instr.rs()) as i32; let rt = self.regs.read(instr.rt()) as i32; self.regs.write(instr.rd(), rs + rt); } - pub fn addi(&mut self, instr: Instruction) { + fn addi(&mut self, instr: Instruction) { let rs = self.regs.read(instr.rs()) as u32; let imm = instr.imm() as i16 as i32 as u32; let (rt, overflow) = rs.overflowing_add(imm); @@ -36,14 +55,13 @@ impl Interpreter { self.regs.write(instr.rt(), rt as i32); } - - pub fn addiu(&mut self, instr: Instruction) { + fn addiu(&mut self, instr: Instruction) { let rs = self.regs.read(instr.rs()) as i32; let imm = instr.imm() as i16 as i32; self.regs.write(instr.rt(), rs + imm); } - pub fn dadd(&mut self, instr: Instruction) { + fn dadd(&mut self, instr: Instruction) { let rs = self.regs.read(instr.rs()) as u64; let rt = self.regs.read(instr.rt()) as u64; let (rd, overflow) = rs.overflowing_add(rt); @@ -54,13 +72,13 @@ impl Interpreter { self.regs.write(instr.rd(), rd as i64); } - pub fn daddu(&mut self, instr: Instruction) { + fn daddu(&mut self, instr: Instruction) { let rs = self.regs.read(instr.rs()) as i64; let rt = self.regs.read(instr.rt()) as i64; self.regs.write(instr.rd(), rs + rt); } - pub fn daddi(&mut self, instr: Instruction) { + fn daddi(&mut self, instr: Instruction) { let rs = self.regs.read(instr.rs()) as u64; let imm = instr.imm() as i16 as i64 as u64; let (rt, overflow) = rs.overflowing_add(imm); @@ -71,7 +89,7 @@ impl Interpreter { self.regs.write(instr.rt(), rt as i64); } - pub fn daddiu(&mut self, instr: Instruction) { + fn daddiu(&mut self, instr: Instruction) { let rs = self.regs.read(instr.rs()); let imm = instr.imm() as i16 as i64; self.regs.write(instr.rt(), rs + imm); @@ -156,14 +174,14 @@ impl Interpreter { self.regs.next_pc = addr; } - pub fn b(&mut self, instr: Instruction, cond: bool) { + fn b(&mut self, instr: Instruction, cond: bool) { let imm = instr.imm() as i16; let offset = (imm as i64) << 2; let address = self.regs.curr_pc + offset; self.branch(cond, address); } - pub fn blink(&mut self, instr: Instruction, cond: bool) { + fn blink(&mut self, instr: Instruction, cond: bool) { self.regs.write(31, self.regs.next_pc); let imm = instr.imm() as i16; let offset = (imm as i64) << 2; @@ -171,14 +189,14 @@ impl Interpreter { self.branch(cond, address); } - pub fn bl(&mut self, instr: Instruction, cond: bool) { + fn bl(&mut self, instr: Instruction, cond: bool) { let imm = instr.imm() as i16; let offset = (imm as i64) << 2; let address = self.regs.curr_pc + offset; self.branch_likely(cond, address); } - pub fn bllink(&mut self, instr: Instruction, cond: bool) { + fn bllink(&mut self, instr: Instruction, cond: bool) { self.regs.write(31, self.regs.next_pc); let imm = instr.imm() as i16; let offset = (imm as i64) << 2; @@ -186,12 +204,12 @@ impl Interpreter { self.branch_likely(cond, address); } - pub fn lui(&mut self, instr: Instruction) { + fn lui(&mut self, instr: Instruction) { let imm = (instr.imm() as i16 as i64) << 16; self.regs.write(instr.rt(), imm); } - pub fn sll(&mut self, instr: Instruction) { + fn sll(&mut self, instr: Instruction) { if instr.0 == 0 { return; } diff --git a/utils/src/error.rs b/utils/src/error.rs index 082b23e..e9721bf 100644 --- a/utils/src/error.rs +++ b/utils/src/error.rs @@ -63,12 +63,12 @@ impl fmt::Display for AccessType { } #[derive(Debug, Clone, Copy)] -pub enum Type<'a> { - UnhandledInstruction(&'a str, Instruction), +pub enum Type { + UnhandledInstruction(&'static str, Instruction), UnhandledMemoryAccess(u32, AccessType), } -impl<'a> fmt::Display for Type<'a> { +impl<'a> fmt::Display for Type { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { let err_type = match self { Type::UnhandledInstruction(which_type, instr) => { @@ -84,12 +84,12 @@ impl<'a> fmt::Display for Type<'a> { } #[derive(Debug, Clone, Copy)] -pub struct Error<'a> { +pub struct Error { pub severity: Severity, - pub err_type: Type<'a>, + pub err_type: Type, } -impl<'a> fmt::Display for Error<'a> { +impl<'a> fmt::Display for Error { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { write!(f, "[{}]: {}", self.severity, self.err_type) }