ab_riscv_interpreter/rv32/zce/
zcmp.rs1pub mod rv32_zcmp_helpers;
4#[cfg(test)]
5mod tests;
6
7use crate::{
8 ExecutableInstruction, ExecutableInstructionCsr, ExecutableInstructionOperands, ExecutionError,
9 ProgramCounter, RegisterFile, Rs1Rs2OperandValues, Rs1Rs2Operands, SystemInstructionHandler,
10 VirtualMemory,
11};
12use ab_riscv_macros::instruction_execution;
13use ab_riscv_primitives::prelude::*;
14use core::ops::ControlFlow;
15
16#[instruction_execution]
17impl<Reg> ExecutableInstructionOperands for Rv32ZcmpInstruction<Reg> where
18 Reg: ZcmpRegister<Type = u32>
19{
20}
21
22#[instruction_execution]
23impl<Reg, ExtState, CustomError> ExecutableInstructionCsr<ExtState, CustomError>
24 for Rv32ZcmpInstruction<Reg>
25where
26 Reg: ZcmpRegister<Type = u32>,
27{
28}
29
30#[instruction_execution]
31impl<Reg, Regs, ExtState, Memory, PC, InstructionHandler, CustomError>
32 ExecutableInstruction<Regs, ExtState, Memory, PC, InstructionHandler, CustomError>
33 for Rv32ZcmpInstruction<Reg>
34where
35 Reg: ZcmpRegister<Type = u32>,
36{
37 #[inline(always)]
38 fn execute(
39 self,
40 Rs1Rs2OperandValues {
41 rs1_value,
42 rs2_value,
43 }: Rs1Rs2OperandValues<<Self::Reg as Register>::Type>,
44 regs: &mut Regs,
45 _ext_state: &mut ExtState,
46 memory: &mut Memory,
47 program_counter: &mut PC,
48 system_instruction_handler: &mut InstructionHandler,
49 ) -> Result<
50 ControlFlow<(), (Self::Reg, <Self::Reg as Register>::Type)>,
51 ExecutionError<Reg::Type, CustomError>,
52 > {
53 Ok(ControlFlow::Continue(Default::default()))
54 }
55}
56
57#[instruction_execution]
58impl<Reg> ExecutableInstructionOperands for Rv32ZcmpOnlyInstruction<Reg> where
59 Reg: ZcmpRegister<Type = u32>
60{
61}
62
63#[instruction_execution]
64impl<Reg, ExtState, CustomError> ExecutableInstructionCsr<ExtState, CustomError>
65 for Rv32ZcmpOnlyInstruction<Reg>
66where
67 Reg: ZcmpRegister<Type = u32>,
68{
69}
70
71#[instruction_execution]
72impl<Reg, Regs, ExtState, Memory, PC, InstructionHandler, CustomError>
73 ExecutableInstruction<Regs, ExtState, Memory, PC, InstructionHandler, CustomError>
74 for Rv32ZcmpOnlyInstruction<Reg>
75where
76 Reg: ZcmpRegister<Type = u32>,
77 Regs: RegisterFile<Reg>,
78 Memory: VirtualMemory,
79 PC: ProgramCounter<Reg::Type, Memory, CustomError>,
80 InstructionHandler: SystemInstructionHandler<Reg, Regs, Memory, PC, CustomError>,
81{
82 #[inline(always)]
83 fn execute(
84 self,
85 Rs1Rs2OperandValues {
86 rs1_value,
87 rs2_value,
88 }: Rs1Rs2OperandValues<<Self::Reg as Register>::Type>,
89 regs: &mut Regs,
90 _ext_state: &mut ExtState,
91 memory: &mut Memory,
92 program_counter: &mut PC,
93 _system_instruction_handler: &mut InstructionHandler,
94 ) -> Result<
95 ControlFlow<(), (Self::Reg, <Self::Reg as Register>::Type)>,
96 ExecutionError<Reg::Type, CustomError>,
97 > {
98 match self {
99 Self::CmPush { urlist, stack_adj } => {
100 rv32_zcmp_helpers::do_push(regs, memory, urlist, stack_adj)
101 }
102 Self::CmPop { urlist, stack_adj } => {
103 rv32_zcmp_helpers::do_pop(regs, memory, urlist, stack_adj)?;
104 Ok(ControlFlow::Continue(Default::default()))
105 }
106 Self::CmPopretz { urlist, stack_adj } => {
107 let ra_val = rv32_zcmp_helpers::do_pop(regs, memory, urlist, stack_adj)?;
108 regs.write(Reg::A0, 0);
110 let target = ra_val & !1;
112 program_counter
113 .set_pc(memory, target)
114 .map(|control_flow| control_flow.map_continue(|()| Default::default()))
115 .map_err(ExecutionError::from)
116 }
117 Self::CmPopret { urlist, stack_adj } => {
118 let ra_val = rv32_zcmp_helpers::do_pop(regs, memory, urlist, stack_adj)?;
119 let target = ra_val & !1;
121 program_counter
122 .set_pc(memory, target)
123 .map(|control_flow| control_flow.map_continue(|()| Default::default()))
124 .map_err(ExecutionError::from)
125 }
126 Self::CmMva01s { rs1: _, rs2: _ } => {
127 let v1 = rs1_value;
129 let v2 = rs2_value;
130 regs.write(Reg::A0, v1);
131 Ok(ControlFlow::Continue((Reg::A1, v2)))
132 }
133 Self::CmMvsa01 { rs1, rs2 } => {
134 let a0_val = regs.read(Reg::A0);
136 let a1_val = regs.read(Reg::A1);
137 regs.write(rs1, a0_val);
138 Ok(ControlFlow::Continue((rs2, a1_val)))
139 }
140 }
141 }
142}