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#[derive(Debug, Default, Clone, Copy)]
9pub struct ContractRegisters {
10 regs: [u64; 32],
11}
12
13impl const RegisterFile<ContractRegister> for ContractRegisters {
14 #[inline(always)]
15 fn read(&self, reg: ContractRegister) -> u64 {
16 if reg == ContractRegister::Zero {
17 return 0;
19 }
20
21 *unsafe { self.regs.get_unchecked(usize::from(reg as u8)) }
23 }
24
25 #[inline(always)]
26 fn write(&mut self, reg: ContractRegister, value: u64) {
27 *unsafe { self.regs.get_unchecked_mut(usize::from(reg as u8)) } = value;
29 }
30}
31
32#[derive(Clone, Copy)]
36#[repr(u8)]
37pub enum ContractRegister {
38 Zero = 0,
40 Ra = 1,
42 Sp = 2,
44 T0 = 5,
50 T1 = 6,
52 T2 = 7,
54 S0 = 8,
56 S1 = 9,
58 A0 = 10,
60 A1 = 11,
62 A2 = 12,
64 A3 = 13,
66 A4 = 14,
68 A5 = 15,
70 A6 = 16,
72 A7 = 17,
74 S2 = 18,
76 S3 = 19,
78 S4 = 20,
80 S5 = 21,
82 S6 = 22,
84 S7 = 23,
86 S8 = 24,
88 S9 = 25,
90 S10 = 26,
92 S11 = 27,
94 T3 = 28,
96 T4 = 29,
98 T5 = 30,
100 T6 = 31,
102}
103
104impl const Default for ContractRegister {
105 #[inline(always)]
106 fn default() -> Self {
107 Self::Zero
108 }
109}
110
111impl fmt::Display for ContractRegister {
112 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
113 match self {
114 Self::Zero => write!(f, "zero"),
115 Self::Ra => write!(f, "ra"),
116 Self::Sp => write!(f, "sp"),
117 Self::T0 => write!(f, "t0"),
118 Self::T1 => write!(f, "t1"),
119 Self::T2 => write!(f, "t2"),
120 Self::S0 => write!(f, "s0"),
121 Self::S1 => write!(f, "s1"),
122 Self::A0 => write!(f, "a0"),
123 Self::A1 => write!(f, "a1"),
124 Self::A2 => write!(f, "a2"),
125 Self::A3 => write!(f, "a3"),
126 Self::A4 => write!(f, "a4"),
127 Self::A5 => write!(f, "a5"),
128 Self::A6 => write!(f, "a6"),
129 Self::A7 => write!(f, "a7"),
130 Self::S2 => write!(f, "s2"),
131 Self::S3 => write!(f, "s3"),
132 Self::S4 => write!(f, "s4"),
133 Self::S5 => write!(f, "s5"),
134 Self::S6 => write!(f, "s6"),
135 Self::S7 => write!(f, "s7"),
136 Self::S8 => write!(f, "s8"),
137 Self::S9 => write!(f, "s9"),
138 Self::S10 => write!(f, "s10"),
139 Self::S11 => write!(f, "s11"),
140 Self::T3 => write!(f, "t3"),
141 Self::T4 => write!(f, "t4"),
142 Self::T5 => write!(f, "t5"),
143 Self::T6 => write!(f, "t6"),
144 }
145 }
146}
147
148impl fmt::Debug for ContractRegister {
149 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
150 fmt::Display::fmt(self, f)
151 }
152}
153
154impl const PartialEq for ContractRegister {
155 #[inline(always)]
156 fn eq(&self, other: &Self) -> bool {
157 matches!(
160 (self, other),
161 (Self::Zero, Self::Zero)
162 | (Self::Ra, Self::Ra)
163 | (Self::Sp, Self::Sp)
164 | (Self::T0, Self::T0)
165 | (Self::T1, Self::T1)
166 | (Self::T2, Self::T2)
167 | (Self::S0, Self::S0)
168 | (Self::S1, Self::S1)
169 | (Self::A0, Self::A0)
170 | (Self::A1, Self::A1)
171 | (Self::A2, Self::A2)
172 | (Self::A3, Self::A3)
173 | (Self::A4, Self::A4)
174 | (Self::A5, Self::A5)
175 | (Self::A6, Self::A6)
176 | (Self::A7, Self::A7)
177 | (Self::S2, Self::S2)
178 | (Self::S3, Self::S3)
179 | (Self::S4, Self::S4)
180 | (Self::S5, Self::S5)
181 | (Self::S6, Self::S6)
182 | (Self::S7, Self::S7)
183 | (Self::S8, Self::S8)
184 | (Self::S9, Self::S9)
185 | (Self::S10, Self::S10)
186 | (Self::S11, Self::S11)
187 | (Self::T3, Self::T3)
188 | (Self::T4, Self::T4)
189 | (Self::T5, Self::T5)
190 | (Self::T6, Self::T6)
191 )
192 }
193}
194
195impl const Eq for ContractRegister {}
196
197impl const Register for ContractRegister {
198 const ZERO: Self = Self::Zero;
199 const SP: Self = Self::Sp;
200 const RA: Self = Self::Ra;
201 const A0: Self = Self::A0;
202 const A1: Self = Self::A1;
203 type Type = u64;
204
205 #[inline(always)]
206 fn from_bits(bits: u8) -> Option<Self> {
207 match bits {
208 0 => Some(Self::Zero),
209 1 => Some(Self::Ra),
210 2 => Some(Self::Sp),
211 5 => Some(Self::T0),
212 6 => Some(Self::T1),
213 7 => Some(Self::T2),
214 8 => Some(Self::S0),
215 9 => Some(Self::S1),
216 10 => Some(Self::A0),
217 11 => Some(Self::A1),
218 12 => Some(Self::A2),
219 13 => Some(Self::A3),
220 14 => Some(Self::A4),
221 15 => Some(Self::A5),
222 16 => Some(Self::A6),
223 17 => Some(Self::A7),
224 18 => Some(Self::S2),
225 19 => Some(Self::S3),
226 20 => Some(Self::S4),
227 21 => Some(Self::S5),
228 22 => Some(Self::S6),
229 23 => Some(Self::S7),
230 24 => Some(Self::S8),
231 25 => Some(Self::S9),
232 26 => Some(Self::S10),
233 27 => Some(Self::S11),
234 28 => Some(Self::T3),
235 29 => Some(Self::T4),
236 30 => Some(Self::T5),
237 31 => Some(Self::T6),
238 _ => None,
239 }
240 }
241}
242
243unsafe impl const ZcmpRegister for ContractRegister {
245 const RVE: bool = false;
246}
247
248#[instruction(
250 ignore = [Fence, FenceTso, Ecall],
251 inherit = [
252 Rv64ZcaInstruction,
253 Rv64ZcbInstruction,
254 Rv64ZcmpInstruction,
255 Rv64Instruction,
256 Rv64MInstruction,
257 Rv64BInstruction,
258 Rv64ZbcInstruction,
259 Rv64ZknInstruction,
260 ZicondInstruction,
261 Rv64ZknhInstruction,
262 ],
263)]
264#[derive(Debug, Clone, Copy, PartialEq, Eq)]
265pub enum ContractInstruction<Reg = ContractRegister> {}
266
267#[instruction]
268impl<Reg> const Instruction for ContractInstruction<Reg>
269where
270 Reg: [const] Register<Type = u64>,
271{
272 type Reg = Reg;
273
274 #[inline(always)]
275 fn try_decode(instruction: u32) -> Option<Self> {
276 None
277 }
278
279 #[inline(always)]
280 fn alignment() -> u8 {
281 align_of::<u32>() as u8
282 }
283
284 #[inline(always)]
285 fn size(&self) -> u8 {
286 size_of::<u32>() as u8
287 }
288}
289
290#[instruction]
291impl<Reg> fmt::Display for ContractInstruction<Reg>
292where
293 Reg: Register,
294{
295 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
296 match self {}
297 }
298}
299
300#[instruction_execution]
301impl<Reg> ExecutableInstructionOperands for ContractInstruction<Reg> {}
302
303#[instruction_execution]
304impl<Reg, ExtState, CustomError> ExecutableInstructionCsr<ExtState, CustomError>
305 for ContractInstruction<Reg>
306{
307}
308
309#[instruction_execution]
310impl<Reg, Regs, ExtState, Memory, PC, InstructionHandler, CustomError>
311 ExecutableInstruction<Regs, ExtState, Memory, PC, InstructionHandler, CustomError>
312 for ContractInstruction<Reg>
313where
314 Reg: Register,
315{
316 #[inline(always)]
317 fn execute(
318 self,
319 Rs1Rs2OperandValues {
320 rs1_value,
321 rs2_value,
322 }: Rs1Rs2OperandValues<<Self::Reg as Register>::Type>,
323 regs: &mut Regs,
324 _ext_state: &mut ExtState,
325 memory: &mut Memory,
326 program_counter: &mut PC,
327 system_instruction_handler: &mut InstructionHandler,
328 ) -> Result<
329 ControlFlow<(), (Self::Reg, <Self::Reg as Register>::Type)>,
330 ExecutionError<Reg::Type, CustomError>,
331 > {
332 Ok(ControlFlow::Continue(Default::default()))
333 }
334}
335
336impl<Reg> ContractInstruction<Reg> {
337 #[inline]
339 pub fn is_jump(&self) -> bool {
340 matches!(
341 self,
342 Self::CJ { .. }
343 | Self::CBeqz { .. }
344 | Self::CBnez { .. }
345 | Self::CJr { .. }
346 | Self::CJalr { .. }
347 | Self::CmPopretz { .. }
348 | Self::CmPopret { .. }
349 | Self::Jalr { .. }
350 | Self::Beq { .. }
351 | Self::Bne { .. }
352 | Self::Blt { .. }
353 | Self::Bge { .. }
354 | Self::Bltu { .. }
355 | Self::Bgeu { .. }
356 | Self::Jal { .. }
357 )
358 }
359}