ab_riscv_interpreter/rv32/zce/
zcmp.rs1pub mod rv32_zcmp_helpers;
4use crate::PackedAddress;
5#[cfg(test)]
6mod tests;
7
8use crate::{
9 ExecutableInstruction, ExecutableInstructionCsr, ExecutableInstructionOperands, ExecutionError,
10 ExecutionResult, FetchInstructionResult, InstructionFetcher, OpaqueThreadedExecutionResult,
11 ProgramCounter, RegisterFile, Rs1Rs2OperandValues, Rs1Rs2Operands, SystemInstructionHandler,
12 ThreadedExecutableInstruction, ThreadedExecutionResult, VirtualMemory,
13};
14use ab_riscv_macros::instruction_execution;
15use ab_riscv_primitives::prelude::*;
16
17#[instruction_execution]
18const impl<Reg> ExecutableInstructionOperands for Rv32ZcmpInstruction<Reg> where
19 Reg: ZcmpRegister<Type = u32>
20{
21}
22
23#[instruction_execution]
24const impl<Reg, Env> ExecutableInstructionCsr<Env> for Rv32ZcmpInstruction<Reg> where
25 Reg: ZcmpRegister<Type = u32>
26{
27}
28
29#[instruction_execution]
30const impl<Reg, Regs, Env, Memory, PC> ExecutableInstruction<Regs, Env, Memory, PC>
31 for Rv32ZcmpInstruction<Reg>
32where
33 Reg: [const] ZcmpRegister<Type = u32>,
34{
35 #[inline(always)]
36 #[cfg_attr(feature = "no-panic", no_panic_const::no_panic(const))]
37 fn execute(
38 self,
39 Rs1Rs2OperandValues {
40 rs1_value,
41 rs2_value,
42 }: Rs1Rs2OperandValues<<Self::Reg as Register>::Type>,
43 regs: &mut Regs,
44 _env: &mut Env,
45 memory: &mut Memory,
46 program_counter: &mut PC,
47 ) -> ExecutionResult<Self::Reg> {
48 ExecutionResult::ContinueNoWrite
49 }
50}
51
52#[instruction_execution]
53const impl<Reg> ExecutableInstructionOperands for Rv32ZcmpOnlyInstruction<Reg> where
54 Reg: ZcmpRegister<Type = u32>
55{
56}
57
58#[instruction_execution]
59const impl<Reg, Env> ExecutableInstructionCsr<Env> for Rv32ZcmpOnlyInstruction<Reg> where
60 Reg: ZcmpRegister<Type = u32>
61{
62}
63
64#[instruction_execution]
65const impl<Reg, Regs, Env, Memory, PC> ExecutableInstruction<Regs, Env, Memory, PC>
66 for Rv32ZcmpOnlyInstruction<Reg>
67where
68 Reg: [const] ZcmpRegister<Type = u32>,
69 Regs: [const] RegisterFile<Reg>,
70 Memory: [const] VirtualMemory,
71 PC: [const] ProgramCounter<Reg::Type, Memory>,
72 Env: [const] SystemInstructionHandler<Reg, Regs, Memory, PC>,
73{
74 #[inline(always)]
75 #[cfg_attr(feature = "no-panic", no_panic_const::no_panic(const))]
76 fn execute(
77 self,
78 Rs1Rs2OperandValues {
79 rs1_value,
80 rs2_value,
81 }: Rs1Rs2OperandValues<<Self::Reg as Register>::Type>,
82 regs: &mut Regs,
83 _env: &mut Env,
84 memory: &mut Memory,
85 _program_counter: &mut PC,
86 ) -> ExecutionResult<Self::Reg> {
87 match self {
88 Self::CmPush { urlist, stack_adj } => {
89 rv32_zcmp_helpers::do_push(regs, memory, urlist, stack_adj)
90 }
91 Self::CmPop { urlist, stack_adj } => {
92 rv32_zcmp_helpers::do_pop(regs, memory, urlist, stack_adj)?;
93 ExecutionResult::ContinueNoWrite
94 }
95 Self::CmPopretz { urlist, stack_adj } => {
96 let ra_val = rv32_zcmp_helpers::do_pop(regs, memory, urlist, stack_adj)?;
97 regs.write(Reg::A0, 0);
99 let target = ra_val & !1;
101 ExecutionResult::Jump { target }
102 }
103 Self::CmPopret { urlist, stack_adj } => {
104 let ra_val = rv32_zcmp_helpers::do_pop(regs, memory, urlist, stack_adj)?;
105 let target = ra_val & !1;
107 ExecutionResult::Jump { target }
108 }
109 Self::CmMva01s { rs1: _, rs2: _ } => {
110 let v1 = rs1_value;
112 let v2 = rs2_value;
113 regs.write(Reg::A0, v1);
114 ExecutionResult::Continue {
115 rd: Reg::A1,
116 value: v2,
117 }
118 }
119 Self::CmMvsa01 { rs1, rs2 } => {
120 let a0_val = regs.read(Reg::A0);
122 let a1_val = regs.read(Reg::A1);
123 regs.write(rs1, a0_val);
124 ExecutionResult::Continue {
125 rd: rs2,
126 value: a1_val,
127 }
128 }
129 }
130 }
131}