sleigh_rs/semantic/inner/pattern/
constraint.rs1use crate::pattern::BitConstraint;
2use crate::semantic::pattern::{CmpOp, ConstraintValue};
3use crate::FieldBits;
4
5impl BitConstraint {
6 pub fn define(self, bit: bool) -> Option<Self> {
7 match self {
8 Self::Unrestrained => Some(Self::Defined(bit)),
9 Self::Defined(old_bit) if old_bit == bit => Some(self),
10 Self::Defined(_old_bit) => None,
11 Self::Restrained => Some(Self::Defined(bit)),
13 }
14 }
15 pub fn most_restrictive(self, other: Self) -> Option<Self> {
17 match (self, other) {
18 (Self::Unrestrained, other) | (other, Self::Unrestrained) => {
20 Some(other)
21 }
22 (Self::Restrained, Self::Restrained) => Some(self),
24 (Self::Defined(self_value), Self::Defined(other_value))
25 if self_value == other_value =>
26 {
27 Some(self)
28 }
29 (Self::Defined(_), Self::Defined(_)) => None,
31 (other @ Self::Defined(_), Self::Restrained)
33 | (Self::Restrained, other @ Self::Defined(_)) => Some(other),
34 }
35 }
36 pub fn least_restrictive(self, other: Self) -> Self {
38 match (self, other) {
39 (Self::Unrestrained, _other) | (_other, Self::Unrestrained) => {
40 Self::Unrestrained
41 }
42 (Self::Defined(self_value), Self::Defined(other_value))
43 if self_value != other_value =>
44 {
45 Self::Restrained
46 }
47 (Self::Defined(_), Self::Defined(_)) => self,
49 (Self::Restrained, Self::Restrained)
50 | (Self::Defined(_), Self::Restrained)
51 | (Self::Restrained, Self::Defined(_)) => Self::Restrained,
52 }
53 }
54}
55
56pub fn apply_value(
57 constraint: &mut [BitConstraint],
58 field_order: fn(usize, usize) -> usize,
59 value_order: fn(usize, usize) -> usize,
60 field_bits: FieldBits,
61 op: CmpOp,
62 value: &ConstraintValue,
63) -> Option<()> {
64 use crate::semantic::disassembly::{ExprElement, ReadScope};
66 let value = match (op, value.expr().elements()) {
67 (
68 CmpOp::Eq,
69 [ExprElement::Value {
70 value: ReadScope::Integer(value),
71 location: _,
72 }],
73 ) => Some(value.signed_super()),
74 _ => None,
75 };
76
77 let field_bits_len = field_bits.len().get().try_into().unwrap();
78 for (value_bit, field_bit) in field_bits.0.into_iter().enumerate() {
79 let field_bit = field_bit.try_into().unwrap();
80 let field_bit = field_order(field_bit, constraint.len());
81 let bit = &mut constraint[field_bit as usize];
82 if let Some(value) = value {
83 let value_bit = value_order(value_bit, field_bits_len);
84 let value_bit = (value >> value_bit) & 1 != 0;
85 *bit = bit.define(value_bit)?;
86 } else {
87 *bit = bit.most_restrictive(BitConstraint::Restrained).unwrap();
89 }
90 }
91 Some(())
92}