1use paste::paste;
5
6macro_rules! build_digit {
7 ($bits: expr, $double_bits: expr) => {
8 paste!{
9 pub const DIGITBITS: usize = $bits;
10 pub const DIGITBYTES: usize = DIGITBITS / 8;
11 pub type Digit = [<u $bits>];
12 pub type SignedDigit = [<i $bits>];
13
14 pub const DOUBLEBITS: usize = $double_bits;
15 pub const DOUBLEBYTES: usize = 2*DIGITBYTES;
16 pub type DoubleDigit = [<u $double_bits>];
17 pub type SignedDoubleDigit = [<i $double_bits>];
18
19 pub const ALLONES: Digit = (-1 as SignedDigit) as Digit;
20 pub const GREATESTBIT: Digit = 1 << (DIGITBITS - 1);
21
22 pub fn digit_from_bytes(bytes: &[u8]) -> Digit {
23 Digit::from_le_bytes(bytes.try_into().unwrap())
24 }
25
26 #[macro_export]
27 macro_rules! add {
28 ($a: expr, $b: expr, $result: expr, $carry: expr) => {
29 let res = ($a as DoubleDigit) + ($b as DoubleDigit);
30 $result = res as Digit;
31 $carry = (res >> DIGITBITS) as Digit;
32 };
33 ($a: expr, $b: expr, $result: expr) => {
34 let res = ($a as Double) + ($b as Double);
35 $result = res as Digit;
36 };
37 }
38
39 pub(crate) use add;
40
41 #[macro_export]
42 macro_rules! mul {
43 ($a: expr, $b: expr, $result: expr, $carry: expr) => {
44 let res = ($a as DoubleDigit) * ($b as DoubleDigit);
45 $result = res as Digit;
46 $carry = (res >> DIGITBITS) as Digit;
47 };
48 ($a: expr, $b: expr, $result: expr) => {
49 let res = ($a as Double) * ($b as Double);
50 $result = res as Digit;
51 };
52 }
53
54 pub(crate) use mul;
55
56 #[macro_export]
57 macro_rules! div {
58 ($dividend_high: expr, $dividend_low: expr, $divisor: expr, $quot: expr) => {
59 let dividend = (($dividend_high as DoubleDigit) << DIGITBITS) | ($dividend_low as DoubleDigit);
60 let divisor = $divisor as DoubleDigit;
61 $quot = (dividend / divisor) as Digit;
62 };
63 }
64 pub(crate) use div;
65 }
66 };
67}
68
69build_digit!(16, 32);
70
71#[macro_export]
72macro_rules! binary_formatter {
73 () => {
74 "{:#018b}" };
76}
77
78pub(crate) use binary_formatter;