os/mm/address/
operations.rs1use crate::config::PAGE_SIZE;
7use core::ops::{
8 Add, AddAssign, BitAnd, BitAndAssign, BitOr, BitOrAssign, BitXor, BitXorAssign, Shl, ShlAssign,
9 Shr, ShrAssign, Sub, SubAssign,
10};
11
12pub trait UsizeConvert: Copy + Clone + PartialEq + PartialOrd + Eq + Ord {
18 fn as_usize(&self) -> usize;
20 fn from_usize(value: usize) -> Self;
22}
23
24pub trait CalcOps:
29 UsizeConvert
30 + Add<usize>
31 + Add<Self>
32 + AddAssign<usize>
33 + AddAssign<Self>
34 + Sub<usize>
35 + Sub<Self>
36 + SubAssign<usize>
37 + SubAssign<Self>
38 + BitAnd<usize>
39 + BitAnd<Self>
40 + BitAndAssign<usize>
41 + BitAndAssign<Self>
42 + BitOr<usize>
43 + BitOr<Self>
44 + BitOrAssign<usize>
45 + BitOrAssign<Self>
46 + BitXor<usize>
47 + BitXor<Self>
48 + BitXorAssign<usize>
49 + BitXorAssign<Self>
50 + Shl<usize>
51 + ShlAssign<usize>
52 + Shr<usize>
53 + ShrAssign<usize>
54{
55}
56
57#[macro_export]
68macro_rules! impl_calc_ops {
69 ($type:ty) => {
70 impl core::ops::Add<usize> for $type {
72 type Output = Self;
73 fn add(self, rhs: usize) -> Self::Output {
74 $crate::mm::address::operations::UsizeConvert::from_usize(self.as_usize() + rhs)
75 }
76 }
77 impl core::ops::Add<Self> for $type {
78 type Output = Self;
79 fn add(self, rhs: Self) -> Self::Output {
80 $crate::mm::address::operations::UsizeConvert::from_usize(
81 self.as_usize() + rhs.as_usize(),
82 )
83 }
84 }
85 impl core::ops::AddAssign<usize> for $type {
86 fn add_assign(&mut self, rhs: usize) {
87 *self =
88 $crate::mm::address::operations::UsizeConvert::from_usize(self.as_usize() + rhs)
89 }
90 }
91 impl core::ops::AddAssign<Self> for $type {
92 fn add_assign(&mut self, rhs: Self) {
93 *self = $crate::mm::address::operations::UsizeConvert::from_usize(
94 self.as_usize() + rhs.as_usize(),
95 )
96 }
97 }
98 impl core::ops::Sub<usize> for $type {
100 type Output = Self;
101 fn sub(self, rhs: usize) -> Self::Output {
102 $crate::mm::address::operations::UsizeConvert::from_usize(self.as_usize() - rhs)
103 }
104 }
105 impl core::ops::Sub<Self> for $type {
106 type Output = Self;
107 fn sub(self, rhs: Self) -> Self::Output {
108 $crate::mm::address::operations::UsizeConvert::from_usize(
109 self.as_usize() - rhs.as_usize(),
110 )
111 }
112 }
113 impl core::ops::SubAssign<usize> for $type {
114 fn sub_assign(&mut self, rhs: usize) {
115 *self =
116 $crate::mm::address::operations::UsizeConvert::from_usize(self.as_usize() - rhs)
117 }
118 }
119 impl core::ops::SubAssign<Self> for $type {
120 fn sub_assign(&mut self, rhs: Self) {
121 *self = $crate::mm::address::operations::UsizeConvert::from_usize(
122 self.as_usize() - rhs.as_usize(),
123 )
124 }
125 }
126 impl core::ops::BitAnd<usize> for $type {
128 type Output = Self;
129 fn bitand(self, rhs: usize) -> Self::Output {
130 $crate::mm::address::operations::UsizeConvert::from_usize(self.as_usize() & rhs)
131 }
132 }
133 impl core::ops::BitAnd<Self> for $type {
134 type Output = Self;
135 fn bitand(self, rhs: Self) -> Self::Output {
136 $crate::mm::address::operations::UsizeConvert::from_usize(
137 self.as_usize() & rhs.as_usize(),
138 )
139 }
140 }
141 impl core::ops::BitAndAssign<usize> for $type {
142 fn bitand_assign(&mut self, rhs: usize) {
143 *self =
144 $crate::mm::address::operations::UsizeConvert::from_usize(self.as_usize() & rhs)
145 }
146 }
147 impl core::ops::BitAndAssign<Self> for $type {
148 fn bitand_assign(&mut self, rhs: Self) {
149 *self = $crate::mm::address::operations::UsizeConvert::from_usize(
150 self.as_usize() & rhs.as_usize(),
151 )
152 }
153 }
154 impl core::ops::BitOr<usize> for $type {
156 type Output = Self;
157 fn bitor(self, rhs: usize) -> Self::Output {
158 $crate::mm::address::operations::UsizeConvert::from_usize(self.as_usize() | rhs)
159 }
160 }
161 impl core::ops::BitOr<Self> for $type {
162 type Output = Self;
163 fn bitor(self, rhs: Self) -> Self::Output {
164 $crate::mm::address::operations::UsizeConvert::from_usize(
165 self.as_usize() | rhs.as_usize(),
166 )
167 }
168 }
169 impl core::ops::BitOrAssign<usize> for $type {
170 fn bitor_assign(&mut self, rhs: usize) {
171 *self =
172 $crate::mm::address::operations::UsizeConvert::from_usize(self.as_usize() | rhs)
173 }
174 }
175 impl core::ops::BitOrAssign<Self> for $type {
176 fn bitor_assign(&mut self, rhs: Self) {
177 *self = $crate::mm::address::operations::UsizeConvert::from_usize(
178 self.as_usize() | rhs.as_usize(),
179 )
180 }
181 }
182 impl core::ops::BitXor<usize> for $type {
184 type Output = Self;
185 fn bitxor(self, rhs: usize) -> Self::Output {
186 $crate::mm::address::operations::UsizeConvert::from_usize(self.as_usize() ^ rhs)
187 }
188 }
189 impl core::ops::BitXor<Self> for $type {
190 type Output = Self;
191 fn bitxor(self, rhs: Self) -> Self::Output {
192 $crate::mm::address::operations::UsizeConvert::from_usize(
193 self.as_usize() ^ rhs.as_usize(),
194 )
195 }
196 }
197 impl core::ops::BitXorAssign<usize> for $type {
198 fn bitxor_assign(&mut self, rhs: usize) {
199 *self =
200 $crate::mm::address::operations::UsizeConvert::from_usize(self.as_usize() ^ rhs)
201 }
202 }
203 impl core::ops::BitXorAssign<Self> for $type {
204 fn bitxor_assign(&mut self, rhs: Self) {
205 *self = $crate::mm::address::operations::UsizeConvert::from_usize(
206 self.as_usize() ^ rhs.as_usize(),
207 )
208 }
209 }
210 impl core::ops::Shl<usize> for $type {
212 type Output = Self;
213 fn shl(self, rhs: usize) -> Self::Output {
214 $crate::mm::address::operations::UsizeConvert::from_usize(self.as_usize() << rhs)
215 }
216 }
217 impl core::ops::ShlAssign<usize> for $type {
218 fn shl_assign(&mut self, rhs: usize) {
219 *self = $crate::mm::address::operations::UsizeConvert::from_usize(
220 self.as_usize() << rhs,
221 )
222 }
223 }
224 impl core::ops::Shr<usize> for $type {
225 type Output = Self;
226 fn shr(self, rhs: usize) -> Self::Output {
227 $crate::mm::address::operations::UsizeConvert::from_usize(self.as_usize() >> rhs)
228 }
229 }
230 impl core::ops::ShrAssign<usize> for $type {
231 fn shr_assign(&mut self, rhs: usize) {
232 *self = $crate::mm::address::operations::UsizeConvert::from_usize(
233 self.as_usize() >> rhs,
234 )
235 }
236 }
237 impl $crate::mm::address::operations::CalcOps for $type {}
239 };
240}
241
242#[allow(dead_code)]
248pub trait AlignOps: UsizeConvert {
249 fn is_aligned(self, alignment: usize) -> bool {
254 debug_assert!(
255 alignment.is_power_of_two(),
256 "alignment must be a power of two"
257 );
258 let mask = alignment - 1;
259 self.as_usize() & mask == 0
261 }
262 fn is_page_aligned(self) -> bool {
264 self.is_aligned(PAGE_SIZE)
265 }
266 fn align_up(self, alignment: usize) -> Self {
271 debug_assert!(
272 alignment.is_power_of_two(),
273 "alignment must be a power of two"
274 );
275 let mask = alignment - 1;
276 Self::from_usize((self.as_usize() + mask) & !mask)
278 }
279 fn align_down(self, alignment: usize) -> Self {
284 debug_assert!(
285 alignment.is_power_of_two(),
286 "alignment must be a power of two"
287 );
288 let mask = alignment - 1;
289 Self::from_usize(self.as_usize() & !mask)
291 }
292 fn align_up_to_page(self) -> Self {
294 self.align_up(PAGE_SIZE)
295 }
296 fn align_down_to_page(self) -> Self {
298 self.align_down(PAGE_SIZE)
299 }
300}