1pub mod b;
4pub mod m;
5#[cfg(test)]
6pub(crate) mod test_utils;
7#[cfg(test)]
8mod tests;
9pub mod zk;
10
11use crate::{
12 ExecutableInstruction, ExecutionError, InterpreterState, ProgramCounter,
13 SystemInstructionHandler, VirtualMemory,
14};
15use ab_riscv_macros::instruction_execution;
16use ab_riscv_primitives::instructions::Instruction;
17use ab_riscv_primitives::instructions::rv32::Rv32Instruction;
18use ab_riscv_primitives::registers::general_purpose::Register;
19use core::ops::ControlFlow;
20
21#[instruction_execution]
22impl<Reg, ExtState, Memory, PC, InstructionHandler, CustomError>
23 ExecutableInstruction<
24 InterpreterState<Reg, ExtState, Memory, PC, InstructionHandler, CustomError>,
25 CustomError,
26 > for Rv32Instruction<Reg>
27where
28 Reg: Register<Type = u32>,
29 [(); Reg::N]:,
30 Memory: VirtualMemory,
31 PC: ProgramCounter<Reg::Type, Memory, CustomError>,
32 InstructionHandler: SystemInstructionHandler<Reg, Memory, PC, CustomError>,
33{
34 #[inline(always)]
35 fn execute(
36 self,
37 state: &mut InterpreterState<Reg, ExtState, Memory, PC, InstructionHandler, CustomError>,
38 ) -> Result<ControlFlow<()>, ExecutionError<Reg::Type, CustomError>> {
39 match self {
40 Self::Add { rd, rs1, rs2 } => {
41 let value = state.regs.read(rs1).wrapping_add(state.regs.read(rs2));
42 state.regs.write(rd, value);
43 }
44 Self::Sub { rd, rs1, rs2 } => {
45 let value = state.regs.read(rs1).wrapping_sub(state.regs.read(rs2));
46 state.regs.write(rd, value);
47 }
48 Self::Sll { rd, rs1, rs2 } => {
49 let shamt = state.regs.read(rs2) & 0x1f;
50 let value = state.regs.read(rs1) << shamt;
51 state.regs.write(rd, value);
52 }
53 Self::Slt { rd, rs1, rs2 } => {
54 let value = state.regs.read(rs1).cast_signed() < state.regs.read(rs2).cast_signed();
55 state.regs.write(rd, value as u32);
56 }
57 Self::Sltu { rd, rs1, rs2 } => {
58 let value = state.regs.read(rs1) < state.regs.read(rs2);
59 state.regs.write(rd, value as u32);
60 }
61 Self::Xor { rd, rs1, rs2 } => {
62 let value = state.regs.read(rs1) ^ state.regs.read(rs2);
63 state.regs.write(rd, value);
64 }
65 Self::Srl { rd, rs1, rs2 } => {
66 let shamt = state.regs.read(rs2) & 0x1f;
67 let value = state.regs.read(rs1) >> shamt;
68 state.regs.write(rd, value);
69 }
70 Self::Sra { rd, rs1, rs2 } => {
71 let shamt = state.regs.read(rs2) & 0x1f;
72 let value = state.regs.read(rs1).cast_signed() >> shamt;
73 state.regs.write(rd, value.cast_unsigned());
74 }
75 Self::Or { rd, rs1, rs2 } => {
76 let value = state.regs.read(rs1) | state.regs.read(rs2);
77 state.regs.write(rd, value);
78 }
79 Self::And { rd, rs1, rs2 } => {
80 let value = state.regs.read(rs1) & state.regs.read(rs2);
81 state.regs.write(rd, value);
82 }
83
84 Self::Addi { rd, rs1, imm } => {
85 let value = state
86 .regs
87 .read(rs1)
88 .wrapping_add(i32::from(imm).cast_unsigned());
89 state.regs.write(rd, value);
90 }
91 Self::Slti { rd, rs1, imm } => {
92 let value = state.regs.read(rs1).cast_signed() < i32::from(imm);
93 state.regs.write(rd, value as u32);
94 }
95 Self::Sltiu { rd, rs1, imm } => {
96 let value = state.regs.read(rs1) < i32::from(imm).cast_unsigned();
97 state.regs.write(rd, value as u32);
98 }
99 Self::Xori { rd, rs1, imm } => {
100 let value = state.regs.read(rs1) ^ i32::from(imm).cast_unsigned();
101 state.regs.write(rd, value);
102 }
103 Self::Ori { rd, rs1, imm } => {
104 let value = state.regs.read(rs1) | i32::from(imm).cast_unsigned();
105 state.regs.write(rd, value);
106 }
107 Self::Andi { rd, rs1, imm } => {
108 let value = state.regs.read(rs1) & i32::from(imm).cast_unsigned();
109 state.regs.write(rd, value);
110 }
111 Self::Slli { rd, rs1, shamt } => {
112 let value = state.regs.read(rs1) << shamt;
113 state.regs.write(rd, value);
114 }
115 Self::Srli { rd, rs1, shamt } => {
116 let value = state.regs.read(rs1) >> shamt;
117 state.regs.write(rd, value);
118 }
119 Self::Srai { rd, rs1, shamt } => {
120 let value = state.regs.read(rs1).cast_signed() >> shamt;
121 state.regs.write(rd, value.cast_unsigned());
122 }
123
124 Self::Lb { rd, rs1, imm } => {
125 let addr = state
126 .regs
127 .read(rs1)
128 .wrapping_add(i32::from(imm).cast_unsigned());
129 let value = i32::from(state.memory.read::<i8>(u64::from(addr))?);
130 state.regs.write(rd, value.cast_unsigned());
131 }
132 Self::Lh { rd, rs1, imm } => {
133 let addr = state
134 .regs
135 .read(rs1)
136 .wrapping_add(i32::from(imm).cast_unsigned());
137 let value = i32::from(state.memory.read::<i16>(u64::from(addr))?);
138 state.regs.write(rd, value.cast_unsigned());
139 }
140 Self::Lw { rd, rs1, imm } => {
141 let addr = state
142 .regs
143 .read(rs1)
144 .wrapping_add(i32::from(imm).cast_unsigned());
145 let value = state.memory.read::<u32>(u64::from(addr))?;
146 state.regs.write(rd, value);
147 }
148 Self::Lbu { rd, rs1, imm } => {
149 let addr = state
150 .regs
151 .read(rs1)
152 .wrapping_add(i32::from(imm).cast_unsigned());
153 let value = state.memory.read::<u8>(u64::from(addr))?;
154 state.regs.write(rd, value as u32);
155 }
156 Self::Lhu { rd, rs1, imm } => {
157 let addr = state
158 .regs
159 .read(rs1)
160 .wrapping_add(i32::from(imm).cast_unsigned());
161 let value = state.memory.read::<u16>(u64::from(addr))?;
162 state.regs.write(rd, value as u32);
163 }
164
165 Self::Jalr { rd, rs1, imm } => {
166 let target = (state
167 .regs
168 .read(rs1)
169 .wrapping_add(i32::from(imm).cast_unsigned()))
170 & !1u32;
171 state.regs.write(rd, state.instruction_fetcher.get_pc());
172 return state
173 .instruction_fetcher
174 .set_pc(&state.memory, target)
175 .map_err(ExecutionError::from);
176 }
177
178 Self::Sb { rs2, rs1, imm } => {
179 let addr = state
180 .regs
181 .read(rs1)
182 .wrapping_add(i32::from(imm).cast_unsigned());
183 state
184 .memory
185 .write(u64::from(addr), state.regs.read(rs2) as u8)?;
186 }
187 Self::Sh { rs2, rs1, imm } => {
188 let addr = state
189 .regs
190 .read(rs1)
191 .wrapping_add(i32::from(imm).cast_unsigned());
192 state
193 .memory
194 .write(u64::from(addr), state.regs.read(rs2) as u16)?;
195 }
196 Self::Sw { rs2, rs1, imm } => {
197 let addr = state
198 .regs
199 .read(rs1)
200 .wrapping_add(i32::from(imm).cast_unsigned());
201 state.memory.write(u64::from(addr), state.regs.read(rs2))?;
202 }
203
204 Self::Beq { rs1, rs2, imm } => {
205 if state.regs.read(rs1) == state.regs.read(rs2) {
206 let old_pc = state.instruction_fetcher.old_pc(self.size());
207 return state
208 .instruction_fetcher
209 .set_pc(&state.memory, old_pc.wrapping_add(imm.cast_unsigned()))
210 .map_err(ExecutionError::from);
211 }
212 }
213 Self::Bne { rs1, rs2, imm } => {
214 if state.regs.read(rs1) != state.regs.read(rs2) {
215 let old_pc = state.instruction_fetcher.old_pc(self.size());
216 return state
217 .instruction_fetcher
218 .set_pc(&state.memory, old_pc.wrapping_add(imm.cast_unsigned()))
219 .map_err(ExecutionError::from);
220 }
221 }
222 Self::Blt { rs1, rs2, imm } => {
223 if state.regs.read(rs1).cast_signed() < state.regs.read(rs2).cast_signed() {
224 let old_pc = state.instruction_fetcher.old_pc(self.size());
225 return state
226 .instruction_fetcher
227 .set_pc(&state.memory, old_pc.wrapping_add(imm.cast_unsigned()))
228 .map_err(ExecutionError::from);
229 }
230 }
231 Self::Bge { rs1, rs2, imm } => {
232 if state.regs.read(rs1).cast_signed() >= state.regs.read(rs2).cast_signed() {
233 let old_pc = state.instruction_fetcher.old_pc(self.size());
234 return state
235 .instruction_fetcher
236 .set_pc(&state.memory, old_pc.wrapping_add(imm.cast_unsigned()))
237 .map_err(ExecutionError::from);
238 }
239 }
240 Self::Bltu { rs1, rs2, imm } => {
241 if state.regs.read(rs1) < state.regs.read(rs2) {
242 let old_pc = state.instruction_fetcher.old_pc(self.size());
243 return state
244 .instruction_fetcher
245 .set_pc(&state.memory, old_pc.wrapping_add(imm.cast_unsigned()))
246 .map_err(ExecutionError::from);
247 }
248 }
249 Self::Bgeu { rs1, rs2, imm } => {
250 if state.regs.read(rs1) >= state.regs.read(rs2) {
251 let old_pc = state.instruction_fetcher.old_pc(self.size());
252 return state
253 .instruction_fetcher
254 .set_pc(&state.memory, old_pc.wrapping_add(imm.cast_unsigned()))
255 .map_err(ExecutionError::from);
256 }
257 }
258
259 Self::Lui { rd, imm } => {
260 state.regs.write(rd, imm.cast_unsigned());
261 }
262
263 Self::Auipc { rd, imm } => {
264 let old_pc = state.instruction_fetcher.old_pc(self.size());
265 state
266 .regs
267 .write(rd, old_pc.wrapping_add(imm.cast_unsigned()));
268 }
269
270 Self::Jal { rd, imm } => {
271 let pc = state.instruction_fetcher.get_pc();
272 let old_pc = state.instruction_fetcher.old_pc(self.size());
273 state.regs.write(rd, pc);
274 return state
275 .instruction_fetcher
276 .set_pc(&state.memory, old_pc.wrapping_add(imm.cast_unsigned()))
277 .map_err(ExecutionError::from);
278 }
279
280 Self::Fence { pred, succ } => {
281 state.system_instruction_handler.handle_fence(pred, succ);
282 }
283 Self::FenceTso => {
284 state.system_instruction_handler.handle_fence_tso();
285 }
286
287 Self::Ecall => {
288 return state.system_instruction_handler.handle_ecall(
289 &mut state.regs,
290 &mut state.memory,
291 &mut state.instruction_fetcher,
292 );
293 }
294 Self::Ebreak => {
295 state.system_instruction_handler.handle_ebreak(
296 &mut state.regs,
297 &mut state.memory,
298 state.instruction_fetcher.get_pc(),
299 );
300 }
301
302 Self::Unimp => {
303 let old_pc = state.instruction_fetcher.old_pc(self.size());
304 return Err(ExecutionError::IllegalInstruction { address: old_pc });
305 }
306 }
307
308 Ok(ControlFlow::Continue(()))
309 }
310}