1pub mod b;
4pub mod c;
5pub mod m;
6#[cfg(test)]
7pub(crate) mod test_utils;
8#[cfg(test)]
9mod tests;
10pub mod zce;
11pub mod zk;
12
13use crate::{
14 ExecutableInstruction, ExecutableInstructionCsr, ExecutableInstructionOperands, ExecutionError,
15 ProgramCounter, RegisterFile, Rs1Rs2OperandValues, Rs1Rs2Operands, SystemInstructionHandler,
16 VirtualMemory,
17};
18use ab_riscv_macros::instruction_execution;
19use ab_riscv_primitives::prelude::*;
20use core::ops::ControlFlow;
21
22#[instruction_execution]
23impl<Reg> ExecutableInstructionOperands for Rv64Instruction<Reg> where Reg: Register<Type = u64> {}
24
25#[instruction_execution]
26impl<Reg, ExtState, CustomError> ExecutableInstructionCsr<ExtState, CustomError>
27 for Rv64Instruction<Reg>
28where
29 Reg: Register<Type = u64>,
30{
31}
32
33#[instruction_execution]
34impl<Reg, Regs, ExtState, Memory, PC, InstructionHandler, CustomError>
35 ExecutableInstruction<Regs, ExtState, Memory, PC, InstructionHandler, CustomError>
36 for Rv64Instruction<Reg>
37where
38 Reg: Register<Type = u64>,
39 Regs: RegisterFile<Reg>,
40 Memory: VirtualMemory,
41 PC: ProgramCounter<Reg::Type, Memory, CustomError>,
42 InstructionHandler: SystemInstructionHandler<Reg, Regs, Memory, PC, CustomError>,
43{
44 #[inline(always)]
45 fn execute(
46 self,
47 Rs1Rs2OperandValues {
48 rs1_value,
49 rs2_value,
50 }: Rs1Rs2OperandValues<<Self::Reg as Register>::Type>,
51 regs: &mut Regs,
52 _ext_state: &mut ExtState,
53 memory: &mut Memory,
54 program_counter: &mut PC,
55 system_instruction_handler: &mut InstructionHandler,
56 ) -> Result<
57 ControlFlow<(), (Self::Reg, <Self::Reg as Register>::Type)>,
58 ExecutionError<Reg::Type, CustomError>,
59 > {
60 match self {
61 Self::Add { rd, rs1: _, rs2: _ } => {
62 let value = rs1_value.wrapping_add(rs2_value);
63 Ok(ControlFlow::Continue((rd, value)))
64 }
65 Self::Sub { rd, rs1: _, rs2: _ } => {
66 let value = rs1_value.wrapping_sub(rs2_value);
67 Ok(ControlFlow::Continue((rd, value)))
68 }
69 Self::Sll { rd, rs1: _, rs2: _ } => {
70 let shamt = rs2_value & 0x3f;
71 let value = rs1_value << shamt;
72 Ok(ControlFlow::Continue((rd, value)))
73 }
74 Self::Slt { rd, rs1: _, rs2: _ } => {
75 let value = rs1_value.cast_signed() < rs2_value.cast_signed();
76 Ok(ControlFlow::Continue((rd, value as u64)))
77 }
78 Self::Sltu { rd, rs1: _, rs2: _ } => {
79 let value = rs1_value < rs2_value;
80 Ok(ControlFlow::Continue((rd, value as u64)))
81 }
82 Self::Xor { rd, rs1: _, rs2: _ } => {
83 let value = rs1_value ^ rs2_value;
84 Ok(ControlFlow::Continue((rd, value)))
85 }
86 Self::Srl { rd, rs1: _, rs2: _ } => {
87 let shamt = rs2_value & 0x3f;
88 let value = rs1_value >> shamt;
89 Ok(ControlFlow::Continue((rd, value)))
90 }
91 Self::Sra { rd, rs1: _, rs2: _ } => {
92 let shamt = rs2_value & 0x3f;
93 let value = rs1_value.cast_signed() >> shamt;
94 Ok(ControlFlow::Continue((rd, value.cast_unsigned())))
95 }
96 Self::Or { rd, rs1: _, rs2: _ } => {
97 let value = rs1_value | rs2_value;
98 Ok(ControlFlow::Continue((rd, value)))
99 }
100 Self::And { rd, rs1: _, rs2: _ } => {
101 let value = rs1_value & rs2_value;
102 Ok(ControlFlow::Continue((rd, value)))
103 }
104
105 Self::Addw { rd, rs1: _, rs2: _ } => {
106 let sum = (rs1_value as i32).wrapping_add(rs2_value as i32);
107 Ok(ControlFlow::Continue((rd, i64::from(sum).cast_unsigned())))
108 }
109 Self::Subw { rd, rs1: _, rs2: _ } => {
110 let diff = (rs1_value as i32).wrapping_sub(rs2_value as i32);
111 Ok(ControlFlow::Continue((rd, i64::from(diff).cast_unsigned())))
112 }
113 Self::Sllw { rd, rs1: _, rs2: _ } => {
114 let shamt = rs2_value & 0x1f;
115 let shifted = (rs1_value as u32) << shamt;
116 Ok(ControlFlow::Continue((
117 rd,
118 i64::from(shifted.cast_signed()).cast_unsigned(),
119 )))
120 }
121 Self::Srlw { rd, rs1: _, rs2: _ } => {
122 let shamt = rs2_value & 0x1f;
123 let shifted = (rs1_value as u32) >> shamt;
124 Ok(ControlFlow::Continue((
125 rd,
126 i64::from(shifted.cast_signed()).cast_unsigned(),
127 )))
128 }
129 Self::Sraw { rd, rs1: _, rs2: _ } => {
130 let shamt = rs2_value & 0x1f;
131 let shifted = (rs1_value as i32) >> shamt;
132 Ok(ControlFlow::Continue((
133 rd,
134 i64::from(shifted).cast_unsigned(),
135 )))
136 }
137
138 Self::Addi { rd, rs1: _, imm } => {
139 let value = rs1_value.wrapping_add(i64::from(imm).cast_unsigned());
140 Ok(ControlFlow::Continue((rd, value)))
141 }
142 Self::Slti { rd, rs1: _, imm } => {
143 let value = rs1_value.cast_signed() < i64::from(imm);
144 Ok(ControlFlow::Continue((rd, value as u64)))
145 }
146 Self::Sltiu { rd, rs1: _, imm } => {
147 let value = rs1_value < i64::from(imm).cast_unsigned();
148 Ok(ControlFlow::Continue((rd, value as u64)))
149 }
150 Self::Xori { rd, rs1: _, imm } => {
151 let value = rs1_value ^ i64::from(imm).cast_unsigned();
152 Ok(ControlFlow::Continue((rd, value)))
153 }
154 Self::Ori { rd, rs1: _, imm } => {
155 let value = rs1_value | i64::from(imm).cast_unsigned();
156 Ok(ControlFlow::Continue((rd, value)))
157 }
158 Self::Andi { rd, rs1: _, imm } => {
159 let value = rs1_value & i64::from(imm).cast_unsigned();
160 Ok(ControlFlow::Continue((rd, value)))
161 }
162 Self::Slli { rd, rs1: _, shamt } => {
163 let value = rs1_value << shamt;
164 Ok(ControlFlow::Continue((rd, value)))
165 }
166 Self::Srli { rd, rs1: _, shamt } => {
167 let value = rs1_value >> shamt;
168 Ok(ControlFlow::Continue((rd, value)))
169 }
170 Self::Srai { rd, rs1: _, shamt } => {
171 let value = rs1_value.cast_signed() >> shamt;
172 Ok(ControlFlow::Continue((rd, value.cast_unsigned())))
173 }
174
175 Self::Addiw { rd, rs1: _, imm } => {
176 let sum = (rs1_value as i32).wrapping_add(i32::from(imm));
177 Ok(ControlFlow::Continue((rd, i64::from(sum).cast_unsigned())))
178 }
179 Self::Slliw { rd, rs1: _, shamt } => {
180 let shifted = (rs1_value as u32) << shamt;
181 Ok(ControlFlow::Continue((
182 rd,
183 i64::from(shifted.cast_signed()).cast_unsigned(),
184 )))
185 }
186 Self::Srliw { rd, rs1: _, shamt } => {
187 let shifted = (rs1_value as u32) >> shamt;
188 Ok(ControlFlow::Continue((
189 rd,
190 i64::from(shifted.cast_signed()).cast_unsigned(),
191 )))
192 }
193 Self::Sraiw { rd, rs1: _, shamt } => {
194 let shifted = (rs1_value as i32) >> shamt;
195 Ok(ControlFlow::Continue((
196 rd,
197 i64::from(shifted).cast_unsigned(),
198 )))
199 }
200
201 Self::Lb { rd, rs1: _, imm } => {
202 let addr = rs1_value.wrapping_add(i64::from(imm).cast_unsigned());
203 let value = i64::from(memory.read::<i8>(addr)?);
204 Ok(ControlFlow::Continue((rd, value.cast_unsigned())))
205 }
206 Self::Lh { rd, rs1: _, imm } => {
207 let addr = rs1_value.wrapping_add(i64::from(imm).cast_unsigned());
208 let value = i64::from(memory.read::<i16>(addr)?);
209 Ok(ControlFlow::Continue((rd, value.cast_unsigned())))
210 }
211 Self::Lw { rd, rs1: _, imm } => {
212 let addr = rs1_value.wrapping_add(i64::from(imm).cast_unsigned());
213 let value = i64::from(memory.read::<i32>(addr)?);
214 Ok(ControlFlow::Continue((rd, value.cast_unsigned())))
215 }
216 Self::Ld { rd, rs1: _, imm } => {
217 let addr = rs1_value.wrapping_add(i64::from(imm).cast_unsigned());
218 let value = memory.read::<u64>(addr)?;
219 Ok(ControlFlow::Continue((rd, value)))
220 }
221 Self::Lbu { rd, rs1: _, imm } => {
222 let addr = rs1_value.wrapping_add(i64::from(imm).cast_unsigned());
223 let value = memory.read::<u8>(addr)?;
224 Ok(ControlFlow::Continue((rd, value as u64)))
225 }
226 Self::Lhu { rd, rs1: _, imm } => {
227 let addr = rs1_value.wrapping_add(i64::from(imm).cast_unsigned());
228 let value = memory.read::<u16>(addr)?;
229 Ok(ControlFlow::Continue((rd, value as u64)))
230 }
231 Self::Lwu { rd, rs1: _, imm } => {
232 let addr = rs1_value.wrapping_add(i64::from(imm).cast_unsigned());
233 let value = memory.read::<u32>(addr)?;
234 Ok(ControlFlow::Continue((rd, value as u64)))
235 }
236
237 Self::Jalr { rd, rs1: _, imm } => {
238 let target = (rs1_value.wrapping_add(i64::from(imm).cast_unsigned())) & !1u64;
239 regs.write(rd, program_counter.get_pc());
240 return program_counter
241 .set_pc(memory, target)
242 .map(|control_flow| control_flow.map_continue(|()| Default::default()))
243 .map_err(ExecutionError::from);
244 }
245
246 Self::Sb {
247 rs2: _,
248 rs1: _,
249 imm,
250 } => {
251 let addr = rs1_value.wrapping_add(i64::from(imm).cast_unsigned());
252 memory.write(addr, rs2_value as u8)?;
253 Ok(ControlFlow::Continue(Default::default()))
254 }
255 Self::Sh {
256 rs2: _,
257 rs1: _,
258 imm,
259 } => {
260 let addr = rs1_value.wrapping_add(i64::from(imm).cast_unsigned());
261 memory.write(addr, rs2_value as u16)?;
262 Ok(ControlFlow::Continue(Default::default()))
263 }
264 Self::Sw {
265 rs2: _,
266 rs1: _,
267 imm,
268 } => {
269 let addr = rs1_value.wrapping_add(i64::from(imm).cast_unsigned());
270 memory.write(addr, rs2_value as u32)?;
271 Ok(ControlFlow::Continue(Default::default()))
272 }
273 Self::Sd {
274 rs2: _,
275 rs1: _,
276 imm,
277 } => {
278 let addr = rs1_value.wrapping_add(i64::from(imm).cast_unsigned());
279 memory.write(addr, rs2_value)?;
280 Ok(ControlFlow::Continue(Default::default()))
281 }
282
283 Self::Beq {
284 rs1: _,
285 rs2: _,
286 imm,
287 } => {
288 if rs1_value == rs2_value {
289 let old_pc = program_counter.old_pc(size_of::<u32>() as u8);
290 return program_counter
291 .set_pc(memory, old_pc.wrapping_add(i64::from(imm).cast_unsigned()))
292 .map(|control_flow| control_flow.map_continue(|()| Default::default()))
293 .map_err(ExecutionError::from);
294 }
295
296 Ok(ControlFlow::Continue(Default::default()))
297 }
298 Self::Bne {
299 rs1: _,
300 rs2: _,
301 imm,
302 } => {
303 if rs1_value != rs2_value {
304 let old_pc = program_counter.old_pc(size_of::<u32>() as u8);
305 return program_counter
306 .set_pc(memory, old_pc.wrapping_add(i64::from(imm).cast_unsigned()))
307 .map(|control_flow| control_flow.map_continue(|()| Default::default()))
308 .map_err(ExecutionError::from);
309 }
310
311 Ok(ControlFlow::Continue(Default::default()))
312 }
313 Self::Blt {
314 rs1: _,
315 rs2: _,
316 imm,
317 } => {
318 if rs1_value.cast_signed() < rs2_value.cast_signed() {
319 let old_pc = program_counter.old_pc(size_of::<u32>() as u8);
320 return program_counter
321 .set_pc(memory, old_pc.wrapping_add(i64::from(imm).cast_unsigned()))
322 .map(|control_flow| control_flow.map_continue(|()| Default::default()))
323 .map_err(ExecutionError::from);
324 }
325
326 Ok(ControlFlow::Continue(Default::default()))
327 }
328 Self::Bge {
329 rs1: _,
330 rs2: _,
331 imm,
332 } => {
333 if rs1_value.cast_signed() >= rs2_value.cast_signed() {
334 let old_pc = program_counter.old_pc(size_of::<u32>() as u8);
335 return program_counter
336 .set_pc(memory, old_pc.wrapping_add(i64::from(imm).cast_unsigned()))
337 .map(|control_flow| control_flow.map_continue(|()| Default::default()))
338 .map_err(ExecutionError::from);
339 }
340
341 Ok(ControlFlow::Continue(Default::default()))
342 }
343 Self::Bltu {
344 rs1: _,
345 rs2: _,
346 imm,
347 } => {
348 if rs1_value < rs2_value {
349 let old_pc = program_counter.old_pc(size_of::<u32>() as u8);
350 return program_counter
351 .set_pc(memory, old_pc.wrapping_add(i64::from(imm).cast_unsigned()))
352 .map(|control_flow| control_flow.map_continue(|()| Default::default()))
353 .map_err(ExecutionError::from);
354 }
355
356 Ok(ControlFlow::Continue(Default::default()))
357 }
358 Self::Bgeu {
359 rs1: _,
360 rs2: _,
361 imm,
362 } => {
363 if rs1_value >= rs2_value {
364 let old_pc = program_counter.old_pc(size_of::<u32>() as u8);
365 return program_counter
366 .set_pc(memory, old_pc.wrapping_add(i64::from(imm).cast_unsigned()))
367 .map(|control_flow| control_flow.map_continue(|()| Default::default()))
368 .map_err(ExecutionError::from);
369 }
370
371 Ok(ControlFlow::Continue(Default::default()))
372 }
373
374 Self::Lui { rd, imm } => {
375 Ok(ControlFlow::Continue((rd, i64::from(imm).cast_unsigned())))
376 }
377
378 Self::Auipc { rd, imm } => {
379 let old_pc = program_counter.old_pc(size_of::<u32>() as u8);
380 Ok(ControlFlow::Continue((
381 rd,
382 old_pc.wrapping_add(i64::from(imm).cast_unsigned()),
383 )))
384 }
385
386 Self::Jal { rd, imm } => {
387 let pc = program_counter.get_pc();
388 let old_pc = program_counter.old_pc(size_of::<u32>() as u8);
389 regs.write(rd, pc);
390 return program_counter
391 .set_pc(memory, old_pc.wrapping_add(i64::from(imm).cast_unsigned()))
392 .map(|control_flow| control_flow.map_continue(|()| Default::default()))
393 .map_err(ExecutionError::from);
394 }
395
396 Self::Fence { pred, succ } => {
397 system_instruction_handler.handle_fence(pred, succ);
398 Ok(ControlFlow::Continue(Default::default()))
399 }
400 Self::FenceTso => {
401 system_instruction_handler.handle_fence_tso();
402 Ok(ControlFlow::Continue(Default::default()))
403 }
404
405 Self::Ecall => {
406 return system_instruction_handler
407 .handle_ecall(regs, memory, program_counter)
408 .map(|control_flow| control_flow.map_continue(|()| Default::default()));
409 }
410 Self::Ebreak => {
411 system_instruction_handler.handle_ebreak(regs, memory, program_counter.get_pc());
412 Ok(ControlFlow::Continue(Default::default()))
413 }
414
415 Self::Unimp => {
416 let old_pc = program_counter.old_pc(size_of::<u32>() as u8);
417 return Err(ExecutionError::IllegalInstruction { address: old_pc });
418 }
419 }
420 }
421}