1use derive_more::{Add, AddAssign, Debug, Sub};
16
17use crate::{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 fn waddr_aligned(self) -> Option<WordAddr> {
43 self.is_aligned().then(|| self.waddr())
44 }
45
46 pub const fn is_aligned(&self) -> bool {
50 self.0 % WORD_SIZE as u32 == 0
51 }
52
53 pub const fn is_null(&self) -> bool {
57 self.0 == 0
58 }
59
60 pub fn wrapping_add(self, rhs: u32) -> Self {
64 Self(self.0.wrapping_add(rhs))
65 }
66
67 pub fn subaddr(&self) -> u32 {
71 self.0 % WORD_SIZE as u32
72 }
73}
74
75impl WordAddr {
76 pub const fn baddr(self) -> ByteAddr {
78 ByteAddr(self.0 * WORD_SIZE as u32)
79 }
80
81 pub fn page_idx(&self) -> u32 {
83 self.0 / PAGE_WORDS as u32
84 }
85
86 pub fn page_subaddr(&self) -> WordAddr {
90 Self(self.0 % PAGE_WORDS as u32)
91 }
92
93 pub fn inc(&mut self) {
97 self.0 += 1;
98 }
99
100 pub fn postfix_inc(&mut self) -> Self {
104 let cur = *self;
105 self.0 += 1;
106 cur
107 }
108
109 pub const fn is_null(&self) -> bool {
113 self.0 == 0
114 }
115}
116
117impl core::ops::Add<usize> for WordAddr {
118 type Output = WordAddr;
119
120 fn add(self, rhs: usize) -> Self::Output {
121 Self(self.0 + rhs as u32)
122 }
123}
124
125impl core::ops::Add<u32> for WordAddr {
126 type Output = WordAddr;
127
128 fn add(self, rhs: u32) -> Self::Output {
129 Self(self.0 + rhs)
130 }
131}
132
133impl core::ops::Add<i32> for WordAddr {
134 type Output = WordAddr;
135
136 fn add(self, rhs: i32) -> Self::Output {
137 Self(self.0.checked_add_signed(rhs).unwrap())
138 }
139}
140
141impl core::ops::Sub<u32> for WordAddr {
142 type Output = WordAddr;
143
144 fn sub(self, rhs: u32) -> Self::Output {
145 Self(self.0 - rhs)
146 }
147}
148
149impl core::ops::AddAssign<usize> for WordAddr {
150 fn add_assign(&mut self, rhs: usize) {
151 self.0 += rhs as u32;
152 }
153}
154
155impl core::ops::AddAssign<u32> for WordAddr {
156 fn add_assign(&mut self, rhs: u32) {
157 self.0 += rhs;
158 }
159}
160
161impl core::ops::Add<usize> for ByteAddr {
162 type Output = ByteAddr;
163
164 fn add(self, rhs: usize) -> Self::Output {
165 Self(self.0 + rhs as u32)
166 }
167}
168
169impl core::ops::Add<u32> for ByteAddr {
170 type Output = ByteAddr;
171
172 fn add(self, rhs: u32) -> Self::Output {
173 Self(self.0 + rhs)
174 }
175}
176
177impl core::ops::Add<i32> for ByteAddr {
178 type Output = ByteAddr;
179
180 fn add(self, rhs: i32) -> Self::Output {
181 Self(self.0.checked_add_signed(rhs).unwrap())
182 }
183}
184
185impl core::ops::AddAssign<usize> for ByteAddr {
186 fn add_assign(&mut self, rhs: usize) {
187 self.0 += rhs as u32;
188 }
189}
190
191impl core::ops::AddAssign<u32> for ByteAddr {
192 fn add_assign(&mut self, rhs: u32) {
193 self.0 += rhs;
194 }
195}
196
197impl From<ByteAddr> for WordAddr {
198 fn from(addr: ByteAddr) -> Self {
199 addr.waddr()
200 }
201}
202
203impl From<WordAddr> for ByteAddr {
204 fn from(addr: WordAddr) -> Self {
205 addr.baddr()
206 }
207}