machine_check/types/
signed.rs1use std::{
2 fmt::Debug,
3 ops::{Add, BitAnd, BitOr, BitXor, Div, Mul, Not, Rem, Shl, Shr, Sub},
4};
5
6use machine_check_common::{PANIC_MSG_DIV_BY_ZERO, PANIC_MSG_REM_BY_ZERO};
7use mck::{
8 concr::{self, IntoMck},
9 forward::{Bitwise, HwArith, HwShift},
10};
11
12use crate::{traits::Ext, Bitvector, Unsigned};
13
14#[derive(Clone, Copy, Hash, PartialEq, Eq)]
23pub struct Signed<const L: u32>(pub(super) concr::Bitvector<L>);
24
25impl<const L: u32> Not for Signed<L> {
28 type Output = Self;
29
30 fn not(self) -> Self::Output {
32 Self(self.0.bit_not())
33 }
34}
35
36impl<const L: u32> BitAnd<Signed<L>> for Signed<L> {
37 type Output = Self;
38
39 fn bitand(self, rhs: Signed<L>) -> Self::Output {
41 Self(self.0.bit_and(rhs.0))
42 }
43}
44impl<const L: u32> BitOr<Signed<L>> for Signed<L> {
45 type Output = Self;
46
47 fn bitor(self, rhs: Signed<L>) -> Self::Output {
49 Self(self.0.bit_or(rhs.0))
50 }
51}
52impl<const L: u32> BitXor<Signed<L>> for Signed<L> {
53 type Output = Self;
54
55 fn bitxor(self, rhs: Signed<L>) -> Self::Output {
57 Self(self.0.bit_xor(rhs.0))
58 }
59}
60
61impl<const L: u32> Add<Signed<L>> for Signed<L> {
64 type Output = Self;
65
66 fn add(self, rhs: Signed<L>) -> Self::Output {
68 Self(self.0.add(rhs.0))
69 }
70}
71
72impl<const L: u32> Sub<Signed<L>> for Signed<L> {
73 type Output = Self;
74
75 fn sub(self, rhs: Signed<L>) -> Self::Output {
77 Self(self.0.sub(rhs.0))
78 }
79}
80
81impl<const L: u32> Mul<Signed<L>> for Signed<L> {
82 type Output = Self;
83
84 fn mul(self, rhs: Signed<L>) -> Self::Output {
86 Self(self.0.mul(rhs.0))
87 }
88}
89
90impl<const L: u32> Div<Signed<L>> for Signed<L> {
91 type Output = Self;
92
93 fn div(self, rhs: Signed<L>) -> Self::Output {
102 let panic_result = self.0.sdiv(rhs.0);
103 if panic_result.panic.is_nonzero() {
104 panic!("{}", PANIC_MSG_DIV_BY_ZERO)
105 }
106 Self(panic_result.result)
107 }
108}
109
110impl<const L: u32> Rem<Signed<L>> for Signed<L> {
111 type Output = Self;
112
113 fn rem(self, rhs: Signed<L>) -> Self::Output {
122 let panic_result = self.0.srem(rhs.0);
123 if panic_result.panic.is_nonzero() {
124 panic!("{}", PANIC_MSG_REM_BY_ZERO)
125 }
126 Self(panic_result.result)
127 }
128}
129
130impl<const L: u32> Shl<Signed<L>> for Signed<L> {
131 type Output = Self;
132
133 fn shl(self, rhs: Signed<L>) -> Self::Output {
147 Self(self.0.logic_shl(rhs.0))
148 }
149}
150
151impl<const L: u32> Shr<Signed<L>> for Signed<L> {
152 type Output = Self;
153
154 fn shr(self, rhs: Signed<L>) -> Self::Output {
166 Self(self.0.arith_shr(rhs.0))
167 }
168}
169
170impl<const L: u32, const X: u32> Ext<X> for Signed<L> {
172 type Output = Signed<X>;
173
174 fn ext(self) -> Self::Output {
179 Signed::<X>(mck::forward::Ext::sext(self.0))
180 }
181}
182
183impl<const L: u32> PartialOrd for Signed<L> {
186 fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
187 Some(self.cmp(other))
188 }
189}
190
191impl<const L: u32> Ord for Signed<L> {
192 fn cmp(&self, other: &Self) -> std::cmp::Ordering {
193 self.0.signed_cmp(&other.0)
194 }
195}
196
197impl<const L: u32> From<Unsigned<L>> for Signed<L> {
199 fn from(value: Unsigned<L>) -> Self {
201 Self(value.0)
202 }
203}
204
205impl<const L: u32> From<Bitvector<L>> for Signed<L> {
206 fn from(value: Bitvector<L>) -> Self {
208 Self(value.0)
209 }
210}
211
212impl<const L: u32> Debug for Signed<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 Signed<L> {
224 type Type = mck::concr::Bitvector<L>;
225
226 fn into_mck(self) -> Self::Type {
227 self.0
228 }
229}