prjunnamed_pattern/
shift.rs

1use prjunnamed_netlist::{Cell, Value};
2
3use crate::{DesignDyn, Pattern};
4
5macro_rules! shift_patterns {
6    {} => {};
7
8    { $name:ident(_,_,_) => $cstr:ident; $($rest:tt)* } => {
9        pub struct $name<P1, P2, P3>(P1, P2, P3);
10
11        impl<P1, P2, P3> $name<P1, P2, P3> {
12            pub fn new(pat1: P1, pat2: P2, pat3: P3) -> $name<P1, P2, P3> {
13                $name(pat1, pat2, pat3)
14            }
15        }
16
17        impl<P1: Pattern<Value>, P2: Pattern<Value>, P3: Pattern<u32>> Pattern<Value> for $name<P1, P2, P3> {
18            type Capture = (Value, P1::Capture, P2::Capture, P3::Capture);
19
20            #[inline]
21            fn execute(&self, design: &dyn DesignDyn, target: &Value) -> Option<Self::Capture> {
22                if target.is_empty() {
23                    return None;
24                }
25                let (cap1, cap2, cap3);
26                if let Ok((cell_ref, _offset)) = design.find_cell(target.iter().next().unwrap()) {
27                    if let Cell::$cstr(arg1, arg2, arg3) = &*cell_ref.get() {
28                        if *target == cell_ref.output() {
29                            cap1 = arg1.clone();
30                            cap2 = arg2.clone();
31                            cap3 = *arg3;
32                        } else {
33                            return None;
34                        }
35                    } else {
36                        return None;
37                    }
38                } else {
39                    return None;
40                }
41                self.0.execute(design, &cap1).and_then(|cap1|
42                    self.1.execute(design, &cap2).and_then(|cap2|
43                        self.2.execute(design, &cap3).and_then(|cap3|
44                            Some((target.clone(), cap1, cap2, cap3)))))
45            }
46        }
47
48        shift_patterns!{ $($rest)* }
49    };
50}
51
52shift_patterns! {
53    PShl(_,_,_) => Shl;
54    PUShr(_,_,_) => UShr;
55    PSShr(_,_,_) => SShr;
56    PXShr(_,_,_) => XShr;
57}