eeric_core/rv_core/registers/
integer.rs

1use crate::{prelude::Snapshotable, rv_core::memory::Memory};
2
3use super::aliases::integer::SP;
4
5#[derive(Clone, PartialEq, Debug)]
6pub struct IntegerRegisters([u64; 31]);
7
8impl IntegerRegisters {
9    pub fn new(mem: &Memory) -> Self {
10        let mut regs: [u64; 31] = Default::default();
11
12        regs[SP - 1] = mem.len() as u64 - 1;
13
14        Self(regs)
15    }
16}
17
18impl Snapshotable for IntegerRegisters {
19    type Snapshot = [u64; 32];
20
21    fn snapshot(&self) -> Self::Snapshot {
22        let mut regs = [0; 32];
23        regs[1..].copy_from_slice(&self.0);
24        regs
25    }
26}
27
28impl std::ops::Index<usize> for IntegerRegisters {
29    type Output = u64;
30
31    fn index(&self, index: usize) -> &Self::Output {
32        match index {
33            0 => &0,
34            _ => &self.0[index - 1],
35        }
36    }
37}
38
39impl std::ops::IndexMut<usize> for IntegerRegisters {
40    fn index_mut(&mut self, index: usize) -> &mut Self::Output {
41        // Rust prohibits returning &mut 0 because reference would outlive the value on the stack.
42        // Small static variables are basically free so IMO it's the best second choice
43        static mut DISCARD_VALUE: u64 = 0;
44
45        match index {
46            0 => unsafe { &mut DISCARD_VALUE },
47            _ => &mut self.0[index - 1],
48        }
49    }
50}