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