prjunnamed_pattern/
shift.rs1use 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}