1use derive_more::{Add, AddAssign, Debug, Sub};
16
17use crate::{PAGE_BYTES, PAGE_WORDS, WORD_SIZE};
18
19#[derive(Add, AddAssign, Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd, Sub)]
21#[debug("{_0:#010x}")]
22pub struct ByteAddr(pub u32);
23
24#[derive(Add, AddAssign, Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd, Sub)]
28#[debug("${_0:#010x}")]
29pub struct WordAddr(pub u32);
30
31impl ByteAddr {
32 pub const fn waddr(self) -> WordAddr {
36 WordAddr(self.0 / WORD_SIZE as u32)
37 }
38
39 pub const fn page_idx(&self) -> u32 {
41 self.0 / PAGE_BYTES as u32
42 }
43
44 pub const fn page_subaddr(&self) -> ByteAddr {
49 Self(self.0 % PAGE_BYTES as u32)
50 }
51
52 pub fn waddr_aligned(self) -> Option<WordAddr> {
56 self.is_aligned().then(|| self.waddr())
57 }
58
59 pub const fn is_aligned(&self) -> bool {
63 self.0.is_multiple_of(WORD_SIZE as u32)
64 }
65
66 pub const fn is_null(&self) -> bool {
70 self.0 == 0
71 }
72
73 pub const fn checked_add(self, rhs: u32) -> Option<Self> {
75 match self.0.checked_add(rhs) {
76 None => None,
77 Some(x) => Some(Self(x)),
78 }
79 }
80
81 pub const fn saturating_add(self, rhs: u32) -> Self {
83 Self(self.0.saturating_add(rhs))
84 }
85
86 pub const fn wrapping_add(self, rhs: u32) -> Self {
90 Self(self.0.wrapping_add(rhs))
91 }
92
93 pub const fn subaddr(&self) -> u32 {
97 self.0 % WORD_SIZE as u32
98 }
99}
100
101impl WordAddr {
102 pub const fn baddr(self) -> ByteAddr {
104 ByteAddr(self.0 * WORD_SIZE as u32)
105 }
106
107 pub const fn page_idx(&self) -> u32 {
109 self.0 / PAGE_WORDS as u32
110 }
111
112 pub const fn page_subaddr(&self) -> WordAddr {
116 Self(self.0 % PAGE_WORDS as u32)
117 }
118
119 pub const fn inc(&mut self) {
123 self.0 += 1;
124 }
125
126 pub const fn postfix_inc(&mut self) -> Self {
130 let cur = *self;
131 self.0 += 1;
132 cur
133 }
134
135 pub const fn is_null(&self) -> bool {
139 self.0 == 0
140 }
141}
142
143impl core::ops::Add<usize> for WordAddr {
144 type Output = WordAddr;
145
146 fn add(self, rhs: usize) -> Self::Output {
147 Self(self.0 + rhs as u32)
148 }
149}
150
151impl core::ops::Add<u32> for WordAddr {
152 type Output = WordAddr;
153
154 fn add(self, rhs: u32) -> Self::Output {
155 Self(self.0 + rhs)
156 }
157}
158
159impl core::ops::Add<i32> for WordAddr {
160 type Output = WordAddr;
161
162 fn add(self, rhs: i32) -> Self::Output {
163 Self(self.0.checked_add_signed(rhs).unwrap())
164 }
165}
166
167impl core::ops::Sub<u32> for WordAddr {
168 type Output = WordAddr;
169
170 fn sub(self, rhs: u32) -> Self::Output {
171 Self(self.0 - rhs)
172 }
173}
174
175impl core::ops::AddAssign<usize> for WordAddr {
176 fn add_assign(&mut self, rhs: usize) {
177 self.0 += rhs as u32;
178 }
179}
180
181impl core::ops::AddAssign<u32> for WordAddr {
182 fn add_assign(&mut self, rhs: u32) {
183 self.0 += rhs;
184 }
185}
186
187impl core::ops::Add<usize> for ByteAddr {
188 type Output = ByteAddr;
189
190 fn add(self, rhs: usize) -> Self::Output {
191 Self(self.0 + rhs as u32)
192 }
193}
194
195impl core::ops::Add<u32> for ByteAddr {
196 type Output = ByteAddr;
197
198 fn add(self, rhs: u32) -> Self::Output {
199 Self(self.0 + rhs)
200 }
201}
202
203impl core::ops::Add<i32> for ByteAddr {
204 type Output = ByteAddr;
205
206 fn add(self, rhs: i32) -> Self::Output {
207 Self(self.0.checked_add_signed(rhs).unwrap())
208 }
209}
210
211impl core::ops::AddAssign<usize> for ByteAddr {
212 fn add_assign(&mut self, rhs: usize) {
213 self.0 += rhs as u32;
214 }
215}
216
217impl core::ops::AddAssign<u32> for ByteAddr {
218 fn add_assign(&mut self, rhs: u32) {
219 self.0 += rhs;
220 }
221}
222
223impl From<ByteAddr> for WordAddr {
224 fn from(addr: ByteAddr) -> Self {
225 addr.waddr()
226 }
227}
228
229impl From<WordAddr> for ByteAddr {
230 fn from(addr: WordAddr) -> Self {
231 addr.baddr()
232 }
233}