1use std::cmp::min;
2use std::fmt::Display;
3use std::ops::{BitAnd, BitOr, BitXor, Not, Shl, Shr};
4
5pub trait Register:
6 Sized
7 + Clone
8 + Default
9 + Display
10 + Not<Output = Self>
11 + BitAnd<Output = Self>
12 + BitOr<Output = Self>
13 + BitXor<Output = Self>
14 + Shl<Self, Output = Self>
15 + Shr<Self, Output = Self>
16{
17 const BITS: u8;
18 const SHIFT_MASK: u8;
19
20 fn zero() -> Self;
21 fn one() -> Self;
22
23 fn min_value() -> Self;
24 fn max_value() -> Self;
25
26 fn eq(&self, other: &Self) -> Self;
29 fn lt(&self, other: &Self) -> Self;
30 fn lt_s(&self, other: &Self) -> Self;
31 fn logical_not(&self) -> Self;
32
33 fn cond(&self, true_value: &Self, false_value: &Self) -> Self;
38
39 fn overflowing_add(&self, rhs: &Self) -> Self;
40 fn overflowing_sub(&self, rhs: &Self) -> Self;
41 fn overflowing_mul(&self, rhs: &Self) -> Self;
42
43 fn overflowing_div(&self, rhs: &Self) -> Self;
52 fn overflowing_rem(&self, rhs: &Self) -> Self;
53 fn overflowing_div_signed(&self, rhs: &Self) -> Self;
54 fn overflowing_rem_signed(&self, rhs: &Self) -> Self;
55
56 fn overflowing_mul_high_signed(&self, rhs: &Self) -> Self;
57 fn overflowing_mul_high_unsigned(&self, rhs: &Self) -> Self;
58 fn overflowing_mul_high_signed_unsigned(&self, rhs: &Self) -> Self;
59
60 fn clz(&self) -> Self;
62 fn ctz(&self) -> Self;
64 fn cpop(&self) -> Self;
66 fn clmul(&self, rhs: &Self) -> Self;
68 fn clmulh(&self, rhs: &Self) -> Self;
70 fn clmulr(&self, rhs: &Self) -> Self;
72 fn orcb(&self) -> Self;
73 fn rev8(&self) -> Self;
74
75 fn signed_shl(&self, rhs: &Self) -> Self;
76 fn signed_shr(&self, rhs: &Self) -> Self;
77
78 fn rol(&self, rhs: &Self) -> Self;
80 fn ror(&self, rhs: &Self) -> Self;
81
82 fn zero_extend(&self, start_bit: &Self) -> Self;
85 fn sign_extend(&self, start_bit: &Self) -> Self;
88
89 fn to_i8(&self) -> i8;
98 fn to_i16(&self) -> i16;
99 fn to_i32(&self) -> i32;
100 fn to_i64(&self) -> i64;
101 fn to_u8(&self) -> u8;
102 fn to_u16(&self) -> u16;
103 fn to_u32(&self) -> u32;
104 fn to_u64(&self) -> u64;
105
106 fn from_i8(v: i8) -> Self;
107 fn from_i16(v: i16) -> Self;
108 fn from_i32(v: i32) -> Self;
109 fn from_i64(v: i64) -> Self;
110 fn from_u8(v: u8) -> Self;
111 fn from_u16(v: u16) -> Self;
112 fn from_u32(v: u32) -> Self;
113 fn from_u64(v: u64) -> Self;
114
115 fn ne(&self, rhs: &Self) -> Self {
116 self.eq(rhs).logical_not()
117 }
118
119 fn ge(&self, other: &Self) -> Self {
120 self.lt(other).logical_not()
121 }
122
123 fn ge_s(&self, other: &Self) -> Self {
124 self.lt_s(other).logical_not()
125 }
126}
127
128impl Register for u32 {
129 const BITS: u8 = 32;
130 const SHIFT_MASK: u8 = 0x1F;
131
132 fn zero() -> u32 {
133 0
134 }
135
136 fn one() -> u32 {
137 1
138 }
139
140 fn min_value() -> u32 {
141 u32::MIN
142 }
143
144 fn max_value() -> u32 {
145 u32::MAX
146 }
147
148 fn eq(&self, other: &u32) -> u32 {
149 (self == other).into()
150 }
151
152 fn lt(&self, other: &u32) -> u32 {
153 (self < other).into()
154 }
155
156 fn lt_s(&self, other: &u32) -> u32 {
157 ((*self as i32) < (*other as i32)).into()
158 }
159
160 fn logical_not(&self) -> u32 {
161 (*self != Self::one()).into()
162 }
163
164 fn cond(&self, true_value: &u32, false_value: &u32) -> u32 {
165 if *self == Self::one() {
166 *true_value
167 } else {
168 *false_value
169 }
170 }
171
172 fn overflowing_add(&self, rhs: &u32) -> u32 {
173 (*self).overflowing_add(*rhs).0
174 }
175
176 fn overflowing_sub(&self, rhs: &u32) -> u32 {
177 (*self).overflowing_sub(*rhs).0
178 }
179
180 fn overflowing_mul(&self, rhs: &u32) -> u32 {
181 (*self).overflowing_mul(*rhs).0
182 }
183
184 fn overflowing_div(&self, rhs: &u32) -> u32 {
185 if *rhs == 0 {
186 Self::MAX
187 } else {
188 (*self).overflowing_div(*rhs).0
189 }
190 }
191
192 fn overflowing_rem(&self, rhs: &u32) -> u32 {
193 if *rhs == 0 {
194 *self
195 } else {
196 (*self).overflowing_rem(*rhs).0
197 }
198 }
199
200 fn overflowing_div_signed(&self, rhs: &u32) -> u32 {
201 if *rhs == 0 {
202 (-1i32) as u32
203 } else {
204 let (v, o) = (*self as i32).overflowing_div(*rhs as i32);
205 if o {
206 ((-1i32) as u32) << (<Self as Register>::BITS - 1)
208 } else {
209 v as u32
210 }
211 }
212 }
213
214 fn overflowing_rem_signed(&self, rhs: &u32) -> u32 {
215 if *rhs == 0 {
216 *self
217 } else {
218 let (v, o) = (*self as i32).overflowing_rem(*rhs as i32);
219 if o {
220 0
221 } else {
222 v as u32
223 }
224 }
225 }
226
227 fn overflowing_mul_high_signed(&self, rhs: &u32) -> u32 {
228 let a = i64::from(*self as i32);
229 let b = i64::from(*rhs as i32);
230 let (value, _) = a.overflowing_mul(b);
231 (value >> 32) as u32
232 }
233
234 fn overflowing_mul_high_unsigned(&self, rhs: &u32) -> u32 {
235 let a = u64::from(*self);
236 let b = u64::from(*rhs);
237 let (value, _) = a.overflowing_mul(b);
238 (value >> 32) as u32
239 }
240
241 fn overflowing_mul_high_signed_unsigned(&self, rhs: &u32) -> u32 {
242 let a = i64::from(*self as i32);
243 let b = i64::from(*rhs);
244 let (value, _) = a.overflowing_mul(b);
245 (value >> 32) as u32
246 }
247
248 fn signed_shl(&self, rhs: &u32) -> u32 {
249 (*self as i32).shl(*rhs) as u32
250 }
251
252 fn signed_shr(&self, rhs: &u32) -> u32 {
253 (*self as i32).shr(*rhs) as u32
254 }
255
256 fn zero_extend(&self, start_bit: &u32) -> u32 {
257 let start_bit = min(*start_bit, 32);
258 debug_assert!(start_bit > 0);
259 (*self << (32 - start_bit)) >> (32 - start_bit)
260 }
261
262 fn sign_extend(&self, start_bit: &u32) -> u32 {
263 let start_bit = min(*start_bit, 32);
264 debug_assert!(start_bit > 0);
265 (((*self << (32 - start_bit)) as i32) >> (32 - start_bit)) as u32
266 }
267
268 fn clz(&self) -> u32 {
269 self.leading_zeros()
270 }
271
272 fn ctz(&self) -> u32 {
273 self.trailing_zeros()
274 }
275
276 fn cpop(&self) -> u32 {
277 self.count_ones()
278 }
279
280 fn clmul(&self, rhs: &u32) -> u32 {
281 let mut x: u32 = 0;
282 for i in 0..32 {
283 if ((rhs >> i) & 1) != 0 {
284 x ^= self << i;
285 }
286 }
287 x
288 }
289
290 fn clmulh(&self, rhs: &u32) -> u32 {
291 let mut x: u32 = 0;
292 for i in 1..32 {
293 if ((rhs >> i) & 1) != 0 {
294 x ^= self >> (32 - i);
295 }
296 }
297 x
298 }
299
300 fn clmulr(&self, rhs: &u32) -> u32 {
301 let mut x: u32 = 0;
302 for i in 0..32 {
303 if ((rhs >> i) & 1) != 0 {
304 x ^= self >> (31 - i);
305 }
306 }
307 x
308 }
309
310 fn orcb(&self) -> u32 {
311 let mut rr = 0;
312 if self & 0x000000ff != 0 {
313 rr |= 0x000000ff
314 }
315 if self & 0x0000ff00 != 0 {
316 rr |= 0x0000ff00
317 }
318 if self & 0x00ff0000 != 0 {
319 rr |= 0x00ff0000
320 }
321 if self & 0xff000000 != 0 {
322 rr |= 0xff000000
323 }
324 rr
325 }
326
327 fn rev8(&self) -> u32 {
328 let mut r = 0;
329 let a = self & 0x000000ff;
330 r |= a << 24;
331 let a = self & 0x0000ff00;
332 r |= a << 8;
333 let a = self & 0x00ff0000;
334 r |= a >> 8;
335 let a = self & 0xff000000;
336 r |= a >> 24;
337 r
338 }
339
340 fn rol(&self, rhs: &u32) -> u32 {
341 (*self as u32).rotate_left(*rhs) as u32
342 }
343
344 fn ror(&self, rhs: &u32) -> u32 {
345 (*self as u32).rotate_right(*rhs) as u32
346 }
347
348 fn to_i8(&self) -> i8 {
349 *self as i8
350 }
351
352 fn to_i16(&self) -> i16 {
353 *self as i16
354 }
355
356 fn to_i32(&self) -> i32 {
357 *self as i32
358 }
359
360 fn to_i64(&self) -> i64 {
361 i64::from(*self as i32)
362 }
363
364 fn to_u8(&self) -> u8 {
365 *self as u8
366 }
367
368 fn to_u16(&self) -> u16 {
369 *self as u16
370 }
371
372 fn to_u32(&self) -> u32 {
373 *self
374 }
375
376 fn to_u64(&self) -> u64 {
377 u64::from(*self)
378 }
379
380 fn from_i8(v: i8) -> u32 {
381 i32::from(v) as u32
382 }
383
384 fn from_i16(v: i16) -> u32 {
385 i32::from(v) as u32
386 }
387
388 fn from_i32(v: i32) -> u32 {
389 v as u32
390 }
391
392 fn from_i64(v: i64) -> u32 {
393 (v as i32) as u32
394 }
395
396 fn from_u8(v: u8) -> u32 {
397 u32::from(v)
398 }
399
400 fn from_u16(v: u16) -> u32 {
401 u32::from(v)
402 }
403
404 fn from_u32(v: u32) -> u32 {
405 v
406 }
407
408 fn from_u64(v: u64) -> u32 {
409 v as u32
410 }
411}
412
413impl Register for u64 {
414 const BITS: u8 = 64;
415 const SHIFT_MASK: u8 = 0x3F;
416
417 fn zero() -> u64 {
418 0
419 }
420
421 fn one() -> u64 {
422 1
423 }
424
425 fn min_value() -> u64 {
426 u64::MIN
427 }
428
429 fn max_value() -> u64 {
430 u64::MAX
431 }
432
433 fn eq(&self, other: &u64) -> u64 {
434 (self == other).into()
435 }
436
437 fn lt(&self, other: &u64) -> u64 {
438 (self < other).into()
439 }
440
441 fn lt_s(&self, other: &u64) -> u64 {
442 ((*self as i64) < (*other as i64)).into()
443 }
444
445 fn logical_not(&self) -> u64 {
446 (*self != Self::one()).into()
447 }
448
449 fn cond(&self, true_value: &u64, false_value: &u64) -> u64 {
450 if *self == Self::one() {
451 *true_value
452 } else {
453 *false_value
454 }
455 }
456
457 fn overflowing_add(&self, rhs: &u64) -> u64 {
458 (*self).overflowing_add(*rhs).0
459 }
460
461 fn overflowing_sub(&self, rhs: &u64) -> u64 {
462 (*self).overflowing_sub(*rhs).0
463 }
464
465 fn overflowing_mul(&self, rhs: &u64) -> u64 {
466 (*self).overflowing_mul(*rhs).0
467 }
468
469 fn overflowing_div(&self, rhs: &u64) -> u64 {
470 if *rhs == 0 {
471 Self::MAX
472 } else {
473 (*self).overflowing_div(*rhs).0
474 }
475 }
476
477 fn overflowing_rem(&self, rhs: &u64) -> u64 {
478 if *rhs == 0 {
479 *self
480 } else {
481 (*self).overflowing_rem(*rhs).0
482 }
483 }
484
485 fn overflowing_div_signed(&self, rhs: &u64) -> u64 {
486 if *rhs == 0 {
487 (-1i64) as u64
488 } else {
489 let (v, o) = (*self as i64).overflowing_div(*rhs as i64);
490 if o {
491 ((-1i64) as u64) << (<Self as Register>::BITS - 1)
493 } else {
494 v as u64
495 }
496 }
497 }
498
499 fn overflowing_rem_signed(&self, rhs: &u64) -> u64 {
500 if *rhs == 0 {
501 *self
502 } else {
503 let (v, o) = (*self as i64).overflowing_rem(*rhs as i64);
504 if o {
505 0
506 } else {
507 v as u64
508 }
509 }
510 }
511
512 fn overflowing_mul_high_signed(&self, rhs: &u64) -> u64 {
513 let a = i128::from(*self as i64);
514 let b = i128::from(*rhs as i64);
515 let (value, _) = a.overflowing_mul(b);
516 (value >> 64) as u64
517 }
518
519 fn overflowing_mul_high_unsigned(&self, rhs: &u64) -> u64 {
520 let a = u128::from(*self);
521 let b = u128::from(*rhs);
522 let (value, _) = a.overflowing_mul(b);
523 (value >> 64) as u64
524 }
525
526 fn overflowing_mul_high_signed_unsigned(&self, rhs: &u64) -> u64 {
527 let a = i128::from(*self as i64);
528 let b = i128::from(*rhs);
529 let (value, _) = a.overflowing_mul(b);
530 (value >> 64) as u64
531 }
532
533 fn signed_shl(&self, rhs: &u64) -> u64 {
534 (*self as i64).shl(*rhs) as u64
535 }
536
537 fn signed_shr(&self, rhs: &u64) -> u64 {
538 (*self as i64).shr(*rhs) as u64
539 }
540
541 fn zero_extend(&self, start_bit: &u64) -> u64 {
542 let start_bit = min(*start_bit, 64);
543 debug_assert!(start_bit > 0);
544 (*self << (64 - start_bit)) >> (64 - start_bit)
545 }
546
547 fn sign_extend(&self, start_bit: &u64) -> u64 {
548 let start_bit = min(*start_bit, 64);
549 debug_assert!(start_bit > 0);
550 (((*self << (64 - start_bit)) as i64) >> (64 - start_bit)) as u64
551 }
552
553 fn clz(&self) -> u64 {
554 self.leading_zeros() as u64
555 }
556
557 fn ctz(&self) -> u64 {
558 self.trailing_zeros() as u64
559 }
560
561 fn cpop(&self) -> u64 {
562 self.count_ones() as u64
563 }
564
565 fn clmul(&self, rhs: &u64) -> u64 {
566 let mut x: u64 = 0;
567 for i in 0..64 {
568 if ((rhs >> i) & 1) != 0 {
569 x ^= self << i;
570 }
571 }
572 x
573 }
574
575 fn clmulh(&self, rhs: &u64) -> u64 {
576 let mut x: u64 = 0;
577 for i in 1..64 {
578 if ((rhs >> i) & 1) != 0 {
579 x ^= self >> (64 - i);
580 }
581 }
582 x
583 }
584
585 fn clmulr(&self, rhs: &u64) -> u64 {
586 let mut x: u64 = 0;
587 for i in 0..64 {
588 if ((rhs >> i) & 1) != 0 {
589 x ^= self >> (63 - i);
590 }
591 }
592 x
593 }
594
595 fn orcb(&self) -> u64 {
596 let mut rr = 0;
597 if self & 0x00000000000000ff != 0 {
598 rr |= 0x00000000000000ff
599 }
600 if self & 0x000000000000ff00 != 0 {
601 rr |= 0x000000000000ff00
602 }
603 if self & 0x0000000000ff0000 != 0 {
604 rr |= 0x0000000000ff0000
605 }
606 if self & 0x00000000ff000000 != 0 {
607 rr |= 0x00000000ff000000
608 }
609 if self & 0x000000ff00000000 != 0 {
610 rr |= 0x000000ff00000000
611 }
612 if self & 0x0000ff0000000000 != 0 {
613 rr |= 0x0000ff0000000000
614 }
615 if self & 0x00ff000000000000 != 0 {
616 rr |= 0x00ff000000000000
617 }
618 if self & 0xff00000000000000 != 0 {
619 rr |= 0xff00000000000000
620 }
621 rr
622 }
623
624 fn rev8(&self) -> u64 {
625 let mut r = 0;
626 let a = self & 0x00000000000000ff;
627 r |= a << 56;
628 let a = self & 0x000000000000ff00;
629 r |= a << 40;
630 let a = self & 0x0000000000ff0000;
631 r |= a << 24;
632 let a = self & 0x00000000ff000000;
633 r |= a << 8;
634 let a = self & 0x000000ff00000000;
635 r |= a >> 8;
636 let a = self & 0x0000ff0000000000;
637 r |= a >> 24;
638 let a = self & 0x00ff000000000000;
639 r |= a >> 40;
640 let a = self & 0xff00000000000000;
641 r |= a >> 56;
642 r
643 }
644
645 fn rol(&self, rhs: &u64) -> u64 {
646 (*self as u64).rotate_left((*rhs) as u32) as u64
647 }
648
649 fn ror(&self, rhs: &u64) -> u64 {
650 (*self as u64).rotate_right((*rhs) as u32) as u64
651 }
652
653 fn to_i8(&self) -> i8 {
654 *self as i8
655 }
656
657 fn to_i16(&self) -> i16 {
658 *self as i16
659 }
660
661 fn to_i32(&self) -> i32 {
662 *self as i32
663 }
664
665 fn to_i64(&self) -> i64 {
666 *self as i64
667 }
668
669 fn to_u8(&self) -> u8 {
670 *self as u8
671 }
672
673 fn to_u16(&self) -> u16 {
674 *self as u16
675 }
676
677 fn to_u32(&self) -> u32 {
678 *self as u32
679 }
680
681 fn to_u64(&self) -> u64 {
682 *self
683 }
684
685 fn from_i8(v: i8) -> u64 {
686 i64::from(v) as u64
687 }
688
689 fn from_i16(v: i16) -> u64 {
690 i64::from(v) as u64
691 }
692
693 fn from_i32(v: i32) -> u64 {
694 i64::from(v) as u64
695 }
696
697 fn from_i64(v: i64) -> u64 {
698 v as u64
699 }
700
701 fn from_u8(v: u8) -> u64 {
702 u64::from(v)
703 }
704
705 fn from_u16(v: u16) -> u64 {
706 u64::from(v)
707 }
708
709 fn from_u32(v: u32) -> u64 {
710 u64::from(v)
711 }
712
713 fn from_u64(v: u64) -> u64 {
714 v
715 }
716}