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