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