Skip to main content

zksync_vm2/
predication.rs

1const LT_BIT: u8 = 1;
2const EQ_BIT: u8 = 1 << 1;
3const GT_BIT: u8 = 1 << 2;
4const ALWAYS_BIT: u8 = 1 << 3;
5
6#[derive(Debug, Clone, PartialEq)]
7pub(crate) struct Flags(u8);
8
9impl Flags {
10    pub(crate) fn new(lt_of: bool, eq: bool, gt: bool) -> Self {
11        Flags(u8::from(lt_of) | (u8::from(eq) << 1) | (u8::from(gt) << 2) | ALWAYS_BIT)
12    }
13}
14
15/// Predicate for an instruction. Encoded so that comparing it to flags is efficient.
16#[derive(Copy, Clone, Debug, Default, Hash)]
17#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
18#[repr(u8)]
19pub enum Predicate {
20    /// Always execute the associated instruction.
21    #[default]
22    Always = ALWAYS_BIT,
23    /// Execute the associated instruction if the "greater than" execution flag is set.
24    IfGT = GT_BIT,
25    /// Execute the associated instruction if the "equal" execution flag is set.
26    IfEQ = EQ_BIT,
27    /// Execute the associated instruction if the "less than" execution flag is set.
28    IfLT = LT_BIT,
29    /// Execute the associated instruction if either of "greater than" or "equal" execution flags are set.
30    IfGE = GT_BIT | EQ_BIT,
31    /// Execute the associated instruction if either of "less than" or "equal" execution flags are set.
32    IfLE = LT_BIT | EQ_BIT,
33    /// Execute the associated instruction if the "equal" execution flag is not set.
34    IfNotEQ = (EQ_BIT << 4) | ALWAYS_BIT,
35    /// Execute the associated instruction if either of "less than" or "greater than" execution flags are set.
36    IfGTOrLT = GT_BIT | LT_BIT,
37}
38
39impl Predicate {
40    #[inline(always)]
41    pub(crate) fn satisfied(self, flags: &Flags) -> bool {
42        let bits = self as u8;
43        bits & flags.0 != 0 && (bits >> 4) & flags.0 == 0
44    }
45}
46
47#[cfg(feature = "single_instruction_test")]
48impl From<&Flags> for zk_evm::flags::Flags {
49    fn from(flags: &Flags) -> Self {
50        zk_evm::flags::Flags {
51            overflow_or_less_than_flag: flags.0 & LT_BIT != 0,
52            equality_flag: flags.0 & EQ_BIT != 0,
53            greater_than_flag: flags.0 & GT_BIT != 0,
54        }
55    }
56}