From 536969427154f8ffc71e3dd515af3bf85e43a50e Mon Sep 17 00:00:00 2001 From: iris Date: Tue, 18 Aug 2026 11:30:28 +0200 Subject: [PATCH] start implementing instructions --- backend/src/core/cpu.rs | 3 +- backend/src/core/interpreter.rs | 29 ++++++++-------- backend/src/core/interpreter/decode.rs | 36 ++++++++++++++++++++ backend/src/core/interpreter/instructions.rs | 34 ++++++++++++++++++ utils/src/instruction.rs | 6 ++-- 5 files changed, 90 insertions(+), 18 deletions(-) create mode 100644 backend/src/core/interpreter/decode.rs create mode 100644 backend/src/core/interpreter/instructions.rs diff --git a/backend/src/core/cpu.rs b/backend/src/core/cpu.rs index 3ddcc1b..f8021fe 100644 --- a/backend/src/core/cpu.rs +++ b/backend/src/core/cpu.rs @@ -8,6 +8,7 @@ pub enum CpuType { } pub trait Cpu { + fn new() -> Self; fn get_type() -> CpuType; fn get_regs(&mut self) -> &mut Registers; fn fetch(&self, _: &Memory, _: u64) -> Option { @@ -21,7 +22,7 @@ pub trait Cpu { fn advance(&mut self) -> bool { false } - fn decode_execute(&mut self, instr: Instruction) -> Result<(), Error>; + fn reset(&mut self); fn should_service_interrupt(&self) -> bool; fn update_compare_interrupt(&mut self); diff --git a/backend/src/core/interpreter.rs b/backend/src/core/interpreter.rs index edf5cfe..536cc31 100644 --- a/backend/src/core/interpreter.rs +++ b/backend/src/core/interpreter.rs @@ -3,10 +3,10 @@ use crate::core::{ mem::Memory, registers::Registers, }; -use utils::{ - error::{Error, Severity, Type::UnhandledInstruction}, - instruction::Instruction, -}; +use utils::{error::Error, instruction::Instruction}; + +pub mod decode; +pub mod instructions; pub struct Interpreter { regs: Registers, @@ -15,6 +15,14 @@ pub struct Interpreter { } impl Cpu for Interpreter { + fn new() -> Self { + Self { + regs: Registers::new(), + delay_slot: false, + prev_delay_slot: false, + } + } + fn get_type() -> super::cpu::CpuType { Interpreter } @@ -65,16 +73,9 @@ impl Cpu for Interpreter { Ok(1) } - fn decode_execute(&mut self, instr: Instruction) -> Result<(), Error> { - match instr.opcode() { - _ => Err(Error { - severity: Severity::Error, - err_type: UnhandledInstruction(instr), - }), - } - } - fn reset(&mut self) { - todo!("reset") + self.regs = Registers::new(); + self.delay_slot = false; + self.prev_delay_slot = false; } } diff --git a/backend/src/core/interpreter/decode.rs b/backend/src/core/interpreter/decode.rs new file mode 100644 index 0000000..88990d3 --- /dev/null +++ b/backend/src/core/interpreter/decode.rs @@ -0,0 +1,36 @@ +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 => { + if instr.0 == 0 { + Ok(()) // nop + } else { + Ok(self.sll(instr)) + } + } + Instruction::ADD => Ok(self.add(instr)), + Instruction::ADDU => Ok(self.addu(instr)), + _ => Err(Error { + severity: Severity::Fatal, + err_type: UnhandledInstruction(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(instr), + }), + } + } +} diff --git a/backend/src/core/interpreter/instructions.rs b/backend/src/core/interpreter/instructions.rs new file mode 100644 index 0000000..df4659e --- /dev/null +++ b/backend/src/core/interpreter/instructions.rs @@ -0,0 +1,34 @@ +#![allow(dead_code)] +#![allow(unused)] + +use utils::{ + error::{Error, Severity, Type::UnhandledInstruction}, + instruction::Instruction, +}; + +use crate::core::interpreter::Interpreter; + +impl Interpreter { + pub 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); + if overflow { + todo!("add overflow!") + } + + self.regs.write(instr.rd(), rd as i32); + } + + pub fn addu(&mut self, instr: Instruction) { + let rs = self.regs.read::(instr.rs()) as i32; + let rt = self.regs.read::(instr.rt()) as i32; + let rd = rs + rt; + self.regs.write(instr.rd(), rd); + } + + pub fn sll(&mut self, instr: Instruction) { + let rd = self.regs.read::(instr.rt()) << instr.sa(); + self.regs.write(instr.rd(), rd); + } +} diff --git a/utils/src/instruction.rs b/utils/src/instruction.rs index dea63d6..6f05e68 100644 --- a/utils/src/instruction.rs +++ b/utils/src/instruction.rs @@ -5,16 +5,16 @@ bitfield! { pub struct Instruction(pub u32): FromStorage, IntoStorage, DerefStorage { pub special: u8 @ 0..6, pub regimm: u8 @ 16..21, - pub rt: u8 @ 16..21, + pub rt: usize @ 16..21, pub cop_rt: u8 @ 16..21, - pub rs: u8 @ 21..26, + pub rs: usize @ 21..26, pub cop_rs: u8 @ 21..26, pub opcode: u8 @ 26..32, pub imm: u16 @ 0..16, pub target: u32 @ 0..26, pub funct: u8 @ 0..6, pub sa: u8 @ 6..11, - pub rd: u8 @ 11..16, + pub rd: usize @ 11..16, } }