diff --git a/backend/src/cpu/interpreter/interpreter.rs b/backend/src/cpu/interpreter/interpreter.rs new file mode 100644 index 0000000..e69de29 diff --git a/backend/src/cpu/interpreter/mod.rs b/backend/src/cpu/interpreter/mod.rs new file mode 100644 index 0000000..e69de29 diff --git a/backend/src/cpu/registers.rs b/backend/src/cpu/registers.rs index 4b9b6a9..5c8070f 100644 --- a/backend/src/cpu/registers.rs +++ b/backend/src/cpu/registers.rs @@ -1,3 +1,31 @@ +pub trait RegisterValue: Sized { + fn read_from(raw: i64) -> Self; + fn write_to(value: Self) -> i64; +} + +macro_rules! impl_register_value { + ($ty:ty) => { + impl RegisterValue for $ty { + fn read_from(raw: i64) -> Self { + raw as $ty + } + + fn write_to(value: Self) -> i64 { + value as i64 + } + } + }; +} + +impl_register_value!(u8); +impl_register_value!(i8); +impl_register_value!(u16); +impl_register_value!(i16); +impl_register_value!(u32); +impl_register_value!(i32); +impl_register_value!(u64); +impl_register_value!(i64); + pub struct Registers { delay_slot: bool, prev_delay_slot: bool, @@ -37,81 +65,16 @@ impl Registers { self.next_pc = self.pc + 4; } - pub fn read_u8(&self, idx: usize) -> u8 { - self.gpr[idx] as u8 + pub fn read(&self, idx: usize) -> T { + T::read_from(self.gpr[idx]) } - pub fn read_i8(&self, idx: usize) -> i8 { - self.gpr[idx] as i8 - } - - pub fn read_u16(&self, idx: usize) -> u16 { - self.gpr[idx] as u16 - } - - pub fn read_u32(&self, idx: usize) -> u32 { - self.gpr[idx] as u32 - } - - pub fn read_i16(&self, idx: usize) -> i16 { - self.gpr[idx] as i16 - } - - pub fn read_i32(&self, idx: usize) -> i32 { - self.gpr[idx] as i32 - } - - pub fn write_u8(&mut self, idx: usize, val: u8) { + pub fn write(&mut self, idx: usize, val: T) { if idx == 0 { return; } self.constant_regs |= 1 << idx; - self.gpr[idx] = val as i64; - } - - pub fn write_i8(&mut self, idx: usize, val: i8) { - if idx == 0 { - return; - } - - self.constant_regs |= 1 << idx; - self.gpr[idx] = val as i64; - } - - pub fn write_u16(&mut self, idx: usize, val: u16) { - if idx == 0 { - return; - } - - self.constant_regs |= 1 << idx; - self.gpr[idx] = val as i64; - } - - pub fn write_u32(&mut self, idx: usize, val: u32) { - if idx == 0 { - return; - } - - self.constant_regs |= 1 << idx; - self.gpr[idx] = val as i64; - } - - pub fn write_i16(&mut self, idx: usize, val: i16) { - if idx == 0 { - return; - } - - self.constant_regs |= 1 << idx; - self.gpr[idx] = val as i64; - } - - pub fn write_i32(&mut self, idx: usize, val: i32) { - if idx == 0 { - return; - } - - self.constant_regs |= 1 << idx; - self.gpr[idx] = val as i64; + self.gpr[idx] = T::write_to(val); } }