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 {
fn new() -> Self;
fn get_type() -> CpuType;
fn get_regs(&mut self) -> &mut Registers;
fn fetch(&self, _: &Memory, _: u64) -> Option<Instruction> {
@@ -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);
+15 -14
View File
@@ -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;
}
}
+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 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,
}
}