Skip to main content

ab_contract_file/
contract_instruction_prototype.rs

1use ab_riscv_interpreter::prelude::*;
2use ab_riscv_macros::{instruction, instruction_execution};
3use ab_riscv_primitives::prelude::*;
4use core::fmt;
5use core::ops::ControlFlow;
6
7/// An instruction type used by contracts
8#[instruction(
9    ignore = [Fence, Ecall],
10    reorder = [
11        Ld,
12        Sd,
13        Add,
14        Addi,
15        Xor,
16        Rori,
17        Srli,
18        Or,
19        And,
20        Slli,
21        Lbu,
22        Auipc,
23        Jalr,
24        Sb,
25        Roriw,
26        Sub,
27        Sltu,
28        Mulhu,
29        Mul,
30        Sh1add,
31    ],
32    inherit = [
33        Rv64ZcaInstruction,
34        Rv64ZcbInstruction,
35        Rv64ZcmpInstruction,
36        Rv64Instruction,
37        Rv64MInstruction,
38        Rv64BInstruction,
39        Rv64ZbcInstruction,
40        Rv64ZknInstruction,
41        ZicondInstruction,
42        Rv64ZknhInstruction,
43    ],
44)]
45#[derive(Debug, Clone, Copy, PartialEq, Eq)]
46pub enum ContractInstructionPrototype<Reg> {}
47
48#[instruction]
49impl<Reg> const Instruction for ContractInstructionPrototype<Reg>
50where
51    Reg: [const] Register<Type = u64>,
52{
53    type Reg = Reg;
54
55    #[inline(always)]
56    fn try_decode(instruction: u32) -> Option<Self> {
57        None
58    }
59
60    #[inline(always)]
61    fn alignment() -> u8 {
62        align_of::<u32>() as u8
63    }
64
65    #[inline(always)]
66    fn size(&self) -> u8 {
67        size_of::<u32>() as u8
68    }
69}
70
71#[instruction]
72impl<Reg> fmt::Display for ContractInstructionPrototype<Reg>
73where
74    Reg: Register,
75{
76    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
77        match self {}
78    }
79}
80
81#[instruction_execution]
82impl<Reg, Regs, ExtState, Memory, PC, InstructionHandler, CustomError>
83    ExecutableInstruction<Regs, ExtState, Memory, PC, InstructionHandler, CustomError>
84    for ContractInstructionPrototype<Reg>
85where
86    Reg: Register<Type = u64>,
87{
88    #[inline(always)]
89    fn execute(
90        self,
91        regs: &mut Regs,
92        _ext_state: &mut ExtState,
93        memory: &mut Memory,
94        program_counter: &mut PC,
95        system_instruction_handler: &mut InstructionHandler,
96    ) -> Result<ControlFlow<()>, ExecutionError<Reg::Type, CustomError>> {
97        Ok(ControlFlow::Continue(()))
98    }
99}
100
101impl<Reg> ContractInstructionPrototype<Reg> {
102    /// Check if the instruction is a jump instruction of any kind (affects program counter)
103    #[inline]
104    pub fn is_jump(&self) -> bool {
105        matches!(
106            self,
107            Self::CJ { .. }
108                | Self::CBeqz { .. }
109                | Self::CBnez { .. }
110                | Self::CJr { .. }
111                | Self::CJalr { .. }
112                | Self::CmPopretz { .. }
113                | Self::CmPopret { .. }
114                | Self::Jalr { .. }
115                | Self::Beq { .. }
116                | Self::Bne { .. }
117                | Self::Blt { .. }
118                | Self::Bge { .. }
119                | Self::Bltu { .. }
120                | Self::Bgeu { .. }
121                | Self::Jal { .. }
122        )
123    }
124}