start implementing instructions

This commit is contained in:
2026-08-18 11:30:28 +02:00
parent 08d1e9c797
commit 5369694271
5 changed files with 90 additions and 18 deletions
+2 -1
View File
@@ -8,6 +8,7 @@ pub enum CpuType {
} }
pub trait Cpu { pub trait Cpu {
fn new() -> Self;
fn get_type() -> CpuType; fn get_type() -> CpuType;
fn get_regs(&mut self) -> &mut Registers; fn get_regs(&mut self) -> &mut Registers;
fn fetch(&self, _: &Memory, _: u64) -> Option<Instruction> { fn fetch(&self, _: &Memory, _: u64) -> Option<Instruction> {
@@ -21,7 +22,7 @@ pub trait Cpu {
fn advance(&mut self) -> bool { fn advance(&mut self) -> bool {
false false
} }
fn decode_execute(&mut self, instr: Instruction) -> Result<(), Error>;
fn reset(&mut self); fn reset(&mut self);
fn should_service_interrupt(&self) -> bool; fn should_service_interrupt(&self) -> bool;
fn update_compare_interrupt(&mut self); fn update_compare_interrupt(&mut self);
+15 -14
View File
@@ -3,10 +3,10 @@ use crate::core::{
mem::Memory, mem::Memory,
registers::Registers, registers::Registers,
}; };
use utils::{ use utils::{error::Error, instruction::Instruction};
error::{Error, Severity, Type::UnhandledInstruction},
instruction::Instruction, pub mod decode;
}; pub mod instructions;
pub struct Interpreter { pub struct Interpreter {
regs: Registers, regs: Registers,
@@ -15,6 +15,14 @@ pub struct Interpreter {
} }
impl Cpu for 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 { fn get_type() -> super::cpu::CpuType {
Interpreter Interpreter
} }
@@ -65,16 +73,9 @@ impl Cpu for Interpreter {
Ok(1) 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) { fn reset(&mut self) {
todo!("reset") self.regs = Registers::new();
self.delay_slot = false;
self.prev_delay_slot = false;
} }
} }
+36
View File
@@ -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),
}),
}
}
}
@@ -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::<i64>(instr.rs()) as u32;
let rt = self.regs.read::<i64>(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::<i64>(instr.rs()) as i32;
let rt = self.regs.read::<i64>(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::<i64>(instr.rt()) << instr.sa();
self.regs.write(instr.rd(), rd);
}
}
+3 -3
View File
@@ -5,16 +5,16 @@ bitfield! {
pub struct Instruction(pub u32): FromStorage, IntoStorage, DerefStorage { pub struct Instruction(pub u32): FromStorage, IntoStorage, DerefStorage {
pub special: u8 @ 0..6, pub special: u8 @ 0..6,
pub regimm: u8 @ 16..21, pub regimm: u8 @ 16..21,
pub rt: u8 @ 16..21, pub rt: usize @ 16..21,
pub cop_rt: u8 @ 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 cop_rs: u8 @ 21..26,
pub opcode: u8 @ 26..32, pub opcode: u8 @ 26..32,
pub imm: u16 @ 0..16, pub imm: u16 @ 0..16,
pub target: u32 @ 0..26, pub target: u32 @ 0..26,
pub funct: u8 @ 0..6, pub funct: u8 @ 0..6,
pub sa: u8 @ 6..11, pub sa: u8 @ 6..11,
pub rd: u8 @ 11..16, pub rd: usize @ 11..16,
} }
} }