ab_riscv_interpreter/rv64/zce/
zcmp.rs1pub mod rv64_zcmp_helpers;
4#[cfg(test)]
5mod tests;
6
7use crate::{
8 ExecutableInstruction, ExecutionError, ProgramCounter, RegisterFile, SystemInstructionHandler,
9 VirtualMemory,
10};
11use ab_riscv_macros::instruction_execution;
12use ab_riscv_primitives::prelude::*;
13use core::ops::ControlFlow;
14
15#[instruction_execution]
16impl<Reg, Regs, ExtState, Memory, PC, InstructionHandler, CustomError>
17 ExecutableInstruction<Regs, ExtState, Memory, PC, InstructionHandler, CustomError>
18 for Rv64ZcmpInstruction<Reg>
19where
20 Reg: ZcmpRegister<Type = u64>,
21 Regs: RegisterFile<Reg>,
22 Memory: VirtualMemory,
23 PC: ProgramCounter<Reg::Type, Memory, CustomError>,
24 InstructionHandler: SystemInstructionHandler<Reg, Regs, Memory, PC, CustomError>,
25{
26 #[inline(always)]
27 fn execute(
28 self,
29 regs: &mut Regs,
30 _ext_state: &mut ExtState,
31 memory: &mut Memory,
32 program_counter: &mut PC,
33 _system_instruction_handler: &mut InstructionHandler,
34 ) -> Result<ControlFlow<()>, ExecutionError<Reg::Type, CustomError>> {
35 match self {
36 Self::CmPush { urlist, stack_adj } => {
37 rv64_zcmp_helpers::do_push(regs, memory, urlist, stack_adj)?;
38 }
39 Self::CmPop { urlist, stack_adj } => {
40 rv64_zcmp_helpers::do_pop(regs, memory, urlist, stack_adj)?;
41 }
42 Self::CmPopretz { urlist, stack_adj } => {
43 let ra_val = rv64_zcmp_helpers::do_pop(regs, memory, urlist, stack_adj)?;
44 regs.write(Reg::A0, 0);
46 let target = ra_val & !1;
48 return program_counter
49 .set_pc(memory, target)
50 .map_err(ExecutionError::from);
51 }
52 Self::CmPopret { urlist, stack_adj } => {
53 let ra_val = rv64_zcmp_helpers::do_pop(regs, memory, urlist, stack_adj)?;
54 let target = ra_val & !1;
56 return program_counter
57 .set_pc(memory, target)
58 .map_err(ExecutionError::from);
59 }
60 Self::CmMva01s { r1s, r2s } => {
61 let v1 = regs.read(r1s);
63 let v2 = regs.read(r2s);
64 regs.write(Reg::A0, v1);
65 regs.write(Reg::A1, v2);
66 }
67 Self::CmMvsa01 { r1s, r2s } => {
68 let a0_val = regs.read(Reg::A0);
70 let a1_val = regs.read(Reg::A1);
71 regs.write(r1s, a0_val);
72 regs.write(r2s, a1_val);
73 }
74 }
75
76 Ok(ControlFlow::Continue(()))
77 }
78}