machine_check/types/
unsigned.rs1use std::{
2 fmt::Debug,
3 ops::{Add, BitAnd, BitOr, BitXor, Div, Mul, Not, Rem, Shl, Shr, Sub},
4};
5
6use mck::{
7 concr::{self, IntoMck},
8 forward::{Bitwise, HwArith, HwShift},
9};
10
11use crate::{traits::Ext, Bitvector, Signed};
12
13#[derive(Clone, Copy, Hash, PartialEq, Eq)]
21pub struct Unsigned<const L: u32>(pub(super) concr::Bitvector<L>);
22
23impl<const L: u32> Unsigned<L> {
24 pub fn new(value: u64) -> Self {
29 Unsigned(concr::Bitvector::new(value))
30 }
31}
32impl<const L: u32> Not for Unsigned<L> {
35 type Output = Self;
36
37 fn not(self) -> Self::Output {
39 Self(self.0.bit_not())
40 }
41}
42
43impl<const L: u32> BitAnd<Unsigned<L>> for Unsigned<L> {
44 type Output = Self;
45
46 fn bitand(self, rhs: Unsigned<L>) -> Self::Output {
48 Self(self.0.bit_and(rhs.0))
49 }
50}
51impl<const L: u32> BitOr<Unsigned<L>> for Unsigned<L> {
52 type Output = Self;
53
54 fn bitor(self, rhs: Unsigned<L>) -> Self::Output {
56 Self(self.0.bit_or(rhs.0))
57 }
58}
59impl<const L: u32> BitXor<Unsigned<L>> for Unsigned<L> {
60 type Output = Self;
61
62 fn bitxor(self, rhs: Unsigned<L>) -> Self::Output {
64 Self(self.0.bit_xor(rhs.0))
65 }
66}
67
68impl<const L: u32> Add<Unsigned<L>> for Unsigned<L> {
71 type Output = Self;
72
73 fn add(self, rhs: Unsigned<L>) -> Self::Output {
75 Self(self.0.add(rhs.0))
76 }
77}
78
79impl<const L: u32> Sub<Unsigned<L>> for Unsigned<L> {
80 type Output = Self;
81
82 fn sub(self, rhs: Unsigned<L>) -> Self::Output {
84 Self(self.0.sub(rhs.0))
85 }
86}
87
88impl<const L: u32> Mul<Unsigned<L>> for Unsigned<L> {
89 type Output = Self;
90
91 fn mul(self, rhs: Unsigned<L>) -> Self::Output {
93 Self(self.0.mul(rhs.0))
94 }
95}
96
97impl<const L: u32> Div<Unsigned<L>> for Unsigned<L> {
98 type Output = Self;
99
100 fn div(self, rhs: Unsigned<L>) -> Self::Output {
109 let panic_result = self.0.udiv(rhs.0);
110 if panic_result.panic.is_nonzero() {
111 panic!("attempt to divide by zero")
112 }
113 Self(panic_result.result)
114 }
115}
116
117impl<const L: u32> Rem<Unsigned<L>> for Unsigned<L> {
118 type Output = Self;
119
120 fn rem(self, rhs: Unsigned<L>) -> Self::Output {
129 let panic_result = self.0.urem(rhs.0);
130 if panic_result.panic.is_nonzero() {
131 panic!("attempt to calculate the remainder with a divisor of zero")
132 }
133 Self(panic_result.result)
134 }
135}
136
137impl<const L: u32> Shl<Unsigned<L>> for Unsigned<L> {
138 type Output = Self;
139
140 fn shl(self, rhs: Unsigned<L>) -> Self::Output {
151 Self(self.0.logic_shl(rhs.0))
152 }
153}
154
155impl<const L: u32> Shr<Unsigned<L>> for Unsigned<L> {
156 type Output = Self;
157
158 fn shr(self, rhs: Unsigned<L>) -> Self::Output {
166 Self(self.0.logic_shr(rhs.0))
167 }
168}
169
170impl<const L: u32, const X: u32> Ext<X> for Unsigned<L> {
172 type Output = Unsigned<X>;
173
174 fn ext(self) -> Self::Output {
178 Unsigned::<X>(mck::forward::Ext::uext(self.0))
179 }
180}
181
182impl<const L: u32> PartialOrd for Unsigned<L> {
185 fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
186 Some(self.cmp(other))
187 }
188}
189
190impl<const L: u32> Ord for Unsigned<L> {
191 fn cmp(&self, other: &Self) -> std::cmp::Ordering {
192 self.0.unsigned_cmp(&other.0)
193 }
194}
195
196impl<const L: u32> From<Bitvector<L>> for Unsigned<L> {
199 fn from(value: Bitvector<L>) -> Self {
201 Self(value.0)
202 }
203}
204
205impl<const L: u32> From<Signed<L>> for Unsigned<L> {
206 fn from(value: Signed<L>) -> Self {
208 Self(value.0)
209 }
210}
211
212impl<const L: u32> Debug for Unsigned<L> {
215 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
216 std::fmt::Debug::fmt(&self.0, f)
217 }
218}
219
220#[doc(hidden)]
223impl<const L: u32> IntoMck for Unsigned<L> {
224 type Type = mck::concr::Bitvector<L>;
225
226 fn into_mck(self) -> Self::Type {
227 self.0
228 }
229}