swamp_code_gen/
reg_pool.rs1use std::fmt::{Debug, Display, Formatter};
6use swamp_vm_types::types::{TypedRegister, VmType};
7
8#[derive(Debug)]
9pub struct TempRegister {
10 pub(crate) register: TypedRegister,
11}
12
13impl Display for TempRegister {
14 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
15 write!(f, "{}", self.register)
16 }
17}
18
19impl TempRegister {
20 pub(crate) const fn register(&self) -> &TypedRegister {
21 &self.register
22 }
23 #[must_use]
24 pub const fn addressing(&self) -> u8 {
25 self.register.addressing()
26 }
27}
28
29#[derive(Debug)]
30pub struct RegisterInfo {
31 pub index: u8,
32}
33
34pub struct HwmTempRegisterPool {
35 start_index: u8,
36 capacity: u8,
37 num_allocated: u8,
38}
39
40impl Debug for HwmTempRegisterPool {
41 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
42 if self.num_allocated == 0 {
43 write!(f, "hwm(no protected)")
44 } else {
45 write!(
46 f,
47 "hwm({}-{})",
48 self.start_index,
49 self.start_index + self.num_allocated - 1
50 )
51 }
52 }
53}
54
55impl HwmTempRegisterPool {
56 #[must_use]
59 pub fn new(start: u8, count: usize) -> Self {
60 if count == 0 {
61 return Self {
62 start_index: start,
63 capacity: 0,
64 num_allocated: 0,
65 };
66 }
67 assert!(
68 count <= u8::MAX as usize + 1,
69 "Register count too large for u8 capacity"
70 );
71 assert!(
72 start.checked_add((count - 1) as u8).is_some(),
73 "Register index range would overflow u8"
74 );
75
76 Self {
77 start_index: start,
78 capacity: count as u8,
79 num_allocated: 0, }
81 }
82
83 pub(crate) const fn start_index_and_number_of_allocated(&self) -> (u8, u8) {
84 (self.start_index, self.num_allocated)
85 }
86
87 pub fn allocate(&mut self, ty: VmType, comment: &str) -> TempRegister {
90 assert!(
91 (self.num_allocated < self.capacity),
92 "HwmTempRegisterPool: Out of temporary registers, capacity: {}. Requested for: '{comment}'", self.capacity
93 );
94
95
96 let register_index = self.start_index + self.num_allocated;
97 self.num_allocated += 1;
98 TempRegister {
101 register: TypedRegister {
102 index: register_index,
103 ty,
104 comment: comment.to_string(),
105 },
106 }
107 }
108
109 #[must_use]
110 pub const fn save_mark(&self) -> u8 {
111 self.num_allocated
112 }
113
114 pub fn restore_to_mark(&mut self, mark: u8) {
117 assert!(
119 (mark <= self.num_allocated),
120 "HwmTempRegisterPool: Invalid mark {} provided. Current allocation count is {}.",
121 mark,
122 self.num_allocated
123 );
124
125 self.num_allocated = mark;
126 }
127}
128
129#[derive(Debug)]
130pub struct RegisterPool {
131 pub start_index: u8,
132 pub end_index: u8,
133 pub current_index: u8,
134}
135
136impl RegisterPool {
137 #[must_use]
138 pub const fn new(start: u8, count: u8) -> Self {
139 Self {
140 start_index: start,
141 end_index: start + count,
142 current_index: start,
143 }
144 }
145
146 pub fn alloc_register(&mut self, ty: VmType, comment: &str) -> TypedRegister {
149 assert!(
150 self.current_index < self.end_index,
151 "out of registers {} {}",
152 self.current_index,
153 self.end_index
154 );
155 let allocated_register = self.current_index;
156 self.current_index += 1;
157 TypedRegister {
158 index: allocated_register,
159 ty,
160 comment: comment.to_string(),
161 }
162 }
163}