o1vm/interpreters/mips/
registers.rs1use serde::{Deserialize, Serialize};
2use std::ops::{Index, IndexMut};
3
4pub const REGISTER_HI: usize = 32;
5pub const REGISTER_LO: usize = 33;
6pub const REGISTER_CURRENT_IP: usize = 34;
7pub const REGISTER_NEXT_IP: usize = 35;
8pub const REGISTER_HEAP_POINTER: usize = 36;
9pub const REGISTER_PREIMAGE_KEY_START: usize = 37;
10pub const REGISTER_PREIMAGE_KEY_END: usize = REGISTER_PREIMAGE_KEY_START + 8 ;
11pub const REGISTER_PREIMAGE_OFFSET: usize = 45;
12
13pub const NUM_REGISTERS: usize = 46;
14
15#[derive(Clone, Default, Debug, Serialize, Deserialize)]
17pub struct Registers<T> {
18 pub general_purpose: [T; 32],
19 pub hi: T,
20 pub lo: T,
21 pub current_instruction_pointer: T,
22 pub next_instruction_pointer: T,
23 pub heap_pointer: T,
24 pub preimage_key: [T; 8],
25 pub preimage_offset: T,
26}
27
28impl<T> Registers<T> {
29 pub fn iter(&self) -> impl Iterator<Item = &T> {
30 self.general_purpose
31 .iter()
32 .chain([
33 &self.hi,
34 &self.lo,
35 &self.current_instruction_pointer,
36 &self.next_instruction_pointer,
37 &self.heap_pointer,
38 ])
39 .chain(self.preimage_key.iter())
40 .chain([&self.preimage_offset])
41 }
42}
43
44impl<T: Clone> Index<usize> for Registers<T> {
45 type Output = T;
46
47 fn index(&self, index: usize) -> &Self::Output {
48 if index < 32 {
49 &self.general_purpose[index]
50 } else if index == REGISTER_HI {
51 &self.hi
52 } else if index == REGISTER_LO {
53 &self.lo
54 } else if index == REGISTER_CURRENT_IP {
55 &self.current_instruction_pointer
56 } else if index == REGISTER_NEXT_IP {
57 &self.next_instruction_pointer
58 } else if index == REGISTER_HEAP_POINTER {
59 &self.heap_pointer
60 } else if (REGISTER_PREIMAGE_KEY_START..REGISTER_PREIMAGE_KEY_END).contains(&index) {
61 &self.preimage_key[index - REGISTER_PREIMAGE_KEY_START]
62 } else if index == REGISTER_PREIMAGE_OFFSET {
63 &self.preimage_offset
64 } else {
65 panic!("Index out of bounds");
66 }
67 }
68}
69
70impl<T: Clone> IndexMut<usize> for Registers<T> {
71 fn index_mut(&mut self, index: usize) -> &mut Self::Output {
72 if index < 32 {
73 &mut self.general_purpose[index]
74 } else if index == REGISTER_HI {
75 &mut self.hi
76 } else if index == REGISTER_LO {
77 &mut self.lo
78 } else if index == REGISTER_CURRENT_IP {
79 &mut self.current_instruction_pointer
80 } else if index == REGISTER_NEXT_IP {
81 &mut self.next_instruction_pointer
82 } else if index == REGISTER_HEAP_POINTER {
83 &mut self.heap_pointer
84 } else if (REGISTER_PREIMAGE_KEY_START..REGISTER_PREIMAGE_KEY_END).contains(&index) {
85 &mut self.preimage_key[index - REGISTER_PREIMAGE_KEY_START]
86 } else if index == REGISTER_PREIMAGE_OFFSET {
87 &mut self.preimage_offset
88 } else {
89 panic!("Index out of bounds");
90 }
91 }
92}