1use crate::ContractRegister;
2#[cfg(any(miri, not(all(target_arch = "riscv64", target_feature = "zbc"))))]
3use ab_riscv_interpreter::rv64::b::zbc::clmul_internal;
4use ab_riscv_interpreter::rv64::{Rv64InterpreterState, Rv64SystemInstructionHandler};
5use ab_riscv_interpreter::{ExecutableInstruction, ExecutionError, ProgramCounter, VirtualMemory};
6use ab_riscv_macros::{instruction, instruction_execution};
7use ab_riscv_primitives::instructions::Instruction;
8use ab_riscv_primitives::instructions::rv64::Rv64Instruction;
9use ab_riscv_primitives::instructions::rv64::b::zba::Rv64ZbaInstruction;
10use ab_riscv_primitives::instructions::rv64::b::zbb::Rv64ZbbInstruction;
11use ab_riscv_primitives::instructions::rv64::b::zbc::Rv64ZbcInstruction;
12use ab_riscv_primitives::instructions::rv64::b::zbs::Rv64ZbsInstruction;
13use ab_riscv_primitives::instructions::rv64::m::Rv64MInstruction;
14use ab_riscv_primitives::instructions::rv64::zk::zkn::zknh::Rv64ZknhInstruction;
15use ab_riscv_primitives::registers::general_purpose::Register;
16use core::fmt;
17use core::ops::ControlFlow;
18
19#[instruction(
21 reorder = [
22 Ld,
23 Sd,
24 Add,
25 Addi,
26 Xor,
27 Rori,
28 Srli,
29 Or,
30 And,
31 Slli,
32 Lbu,
33 Auipc,
34 Jalr,
35 Sb,
36 Roriw,
37 Sub,
38 Sltu,
39 Mulhu,
40 Mul,
41 Sh1add,
42 ],
43 ignore = [
44 Rv64Instruction,
45 Rv64MInstruction,
46 Rv64BInstruction,
47 Rv64ZbcInstruction,
48 ],
49 inherit = [
50 Rv64Instruction,
51 Rv64MInstruction,
52 Rv64BInstruction,
53 Rv64ZbcInstruction,
54 ],
55)]
56#[derive(Debug, Clone, Copy, PartialEq, Eq)]
57pub enum PopularInstruction<Reg> {}
58
59#[instruction]
60impl<Reg> const Instruction for PopularInstruction<Reg>
61where
62 Reg: [const] Register<Type = u64>,
63{
64 type Reg = ContractRegister;
65
66 #[inline(always)]
67 fn try_decode(instruction: u32) -> Option<Self> {
68 None
69 }
70
71 #[inline(always)]
72 fn alignment() -> u8 {
73 size_of::<u32>() as u8
74 }
75
76 #[inline(always)]
77 fn size(&self) -> u8 {
78 size_of::<u32>() as u8
79 }
80}
81
82#[instruction]
83impl<Reg> fmt::Display for PopularInstruction<Reg>
84where
85 Reg: fmt::Display + Copy,
86{
87 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
88 match self {}
89 }
90}
91
92#[instruction_execution]
93impl<Reg, Memory, PC, InstructionHandler, CustomError>
94 ExecutableInstruction<
95 Rv64InterpreterState<Reg, Memory, PC, InstructionHandler, CustomError>,
96 CustomError,
97 > for PopularInstruction<Reg>
98where
99 Reg: Register<Type = u64>,
100 [(); Reg::N]:,
101 Memory: VirtualMemory,
102 PC: ProgramCounter<Reg::Type, Memory, CustomError>,
103 InstructionHandler: Rv64SystemInstructionHandler<Reg, Memory, PC, CustomError>,
104{
105 #[inline(always)]
106 fn execute(
107 self,
108 state: &mut Rv64InterpreterState<Reg, Memory, PC, InstructionHandler, CustomError>,
109 ) -> Result<ControlFlow<()>, ExecutionError<Reg::Type, Self, CustomError>> {
110 Ok(ControlFlow::Continue(()))
111 }
112}
113
114#[instruction(
116 ignore = [PopularInstruction, Fence, Ecall],
117 inherit = [
118 Rv64Instruction,
119 Rv64MInstruction,
120 Rv64BInstruction,
121 Rv64ZbcInstruction,
122 Rv64ZknhInstruction,
123 ],
124)]
125#[derive(Debug, Clone, Copy, PartialEq, Eq)]
126pub enum NotPopularInstruction<Reg> {}
127
128#[instruction]
129impl<Reg> const Instruction for NotPopularInstruction<Reg>
130where
131 Reg: [const] Register<Type = u64>,
132{
133 type Reg = ContractRegister;
134
135 #[inline(always)]
136 fn try_decode(instruction: u32) -> Option<Self> {
137 None
138 }
139
140 #[inline(always)]
141 fn alignment() -> u8 {
142 size_of::<u32>() as u8
143 }
144
145 #[inline(always)]
146 fn size(&self) -> u8 {
147 size_of::<u32>() as u8
148 }
149}
150
151#[instruction]
152impl<Reg> fmt::Display for NotPopularInstruction<Reg>
153where
154 Reg: fmt::Display + Copy,
155{
156 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
157 match self {}
158 }
159}
160
161#[instruction_execution]
162impl<Reg, Memory, PC, InstructionHandler, CustomError>
163 ExecutableInstruction<
164 Rv64InterpreterState<Reg, Memory, PC, InstructionHandler, CustomError>,
165 CustomError,
166 > for NotPopularInstruction<Reg>
167where
168 Reg: Register<Type = u64>,
169 [(); Reg::N]:,
170 Memory: VirtualMemory,
171 PC: ProgramCounter<Reg::Type, Memory, CustomError>,
172 InstructionHandler: Rv64SystemInstructionHandler<Reg, Memory, PC, CustomError>,
173{
174 fn execute(
175 self,
176 state: &mut Rv64InterpreterState<Reg, Memory, PC, InstructionHandler, CustomError>,
177 ) -> Result<ControlFlow<()>, ExecutionError<Reg::Type, Self, CustomError>> {
178 Ok(ControlFlow::Continue(()))
179 }
180}
181
182#[derive(Debug, Clone, Copy, PartialEq, Eq)]
184pub enum ContractInstructionPrototype<Reg> {
185 Popular(PopularInstruction<Reg>),
187 NotPopular(NotPopularInstruction<Reg>),
189}
190
191impl<Reg> const Instruction for ContractInstructionPrototype<Reg>
192where
193 Reg: [const] Register<Type = u64>,
194{
195 type Reg = ContractRegister;
196
197 #[inline(always)]
198 fn try_decode(instruction: u32) -> Option<Self> {
199 if let Some(instruction) = PopularInstruction::try_decode(instruction).map(Self::Popular) {
200 Some(instruction)
201 } else {
202 NotPopularInstruction::try_decode(instruction).map(Self::NotPopular)
203 }
204 }
205
206 #[inline(always)]
207 fn alignment() -> u8 {
208 size_of::<u32>() as u8
209 }
210
211 #[inline(always)]
212 fn size(&self) -> u8 {
213 size_of::<u32>() as u8
214 }
215}
216
217impl<Reg> fmt::Display for ContractInstructionPrototype<Reg>
218where
219 Reg: fmt::Display + Copy,
220{
221 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
222 match self {
223 Self::Popular(instructions) => fmt::Display::fmt(instructions, f),
224 Self::NotPopular(instructions) => fmt::Display::fmt(instructions, f),
225 }
226 }
227}
228
229impl<Reg, Memory, PC, InstructionHandler, CustomError>
230 ExecutableInstruction<
231 Rv64InterpreterState<Reg, Memory, PC, InstructionHandler, CustomError>,
232 CustomError,
233 > for ContractInstructionPrototype<Reg>
234where
235 Reg: Register<Type = u64>,
236 [(); Reg::N]:,
237 Memory: VirtualMemory,
238 PC: ProgramCounter<Reg::Type, Memory, CustomError>,
239 InstructionHandler: Rv64SystemInstructionHandler<Reg, Memory, PC, CustomError>,
240{
241 #[inline(always)]
242 fn execute(
243 self,
244 state: &mut Rv64InterpreterState<Reg, Memory, PC, InstructionHandler, CustomError>,
245 ) -> Result<ControlFlow<()>, ExecutionError<Reg::Type, Self, CustomError>> {
246 match self {
247 Self::Popular(instructions) => instructions
248 .execute(state)
249 .map_err(|error| error.map_instruction(Self::Popular)),
250 Self::NotPopular(instructions) => instructions
251 .execute(state)
252 .map_err(|error| error.map_instruction(Self::NotPopular)),
253 }
254 }
255}