ab_riscv_interpreter/rv64/zce/
zcmp.rs1pub mod rv64_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::*;
16use core::ops::ControlFlow;
17
18#[instruction_execution]
19const impl<Reg> ExecutableInstructionOperands for Rv64ZcmpInstruction<Reg> where
20 Reg: ZcmpRegister<Type = u64>
21{
22}
23
24#[instruction_execution]
25const impl<Reg, Env> ExecutableInstructionCsr<Env> for Rv64ZcmpInstruction<Reg> where
26 Reg: ZcmpRegister<Type = u64>
27{
28}
29
30#[instruction_execution]
31const impl<Reg, Regs, Env, Memory, PC> ExecutableInstruction<Regs, Env, Memory, PC>
32 for Rv64ZcmpInstruction<Reg>
33where
34 Reg: [const] ZcmpRegister<Type = u64>,
35{
36 #[inline(always)]
37 #[cfg_attr(feature = "no-panic", no_panic_const::no_panic(const))]
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 _env: &mut Env,
46 memory: &mut Memory,
47 program_counter: &mut PC,
48 ) -> ExecutionResult<Self::Reg> {
49 ExecutionResult::ContinueNoWrite
50 }
51}
52
53#[instruction_execution]
54const impl<Reg> ExecutableInstructionOperands for Rv64ZcmpOnlyInstruction<Reg> where
55 Reg: ZcmpRegister<Type = u64>
56{
57}
58
59#[instruction_execution]
60const impl<Reg, Env> ExecutableInstructionCsr<Env> for Rv64ZcmpOnlyInstruction<Reg> where
61 Reg: ZcmpRegister<Type = u64>
62{
63}
64
65#[instruction_execution]
66const impl<Reg, Regs, Env, Memory, PC> ExecutableInstruction<Regs, Env, Memory, PC>
67 for Rv64ZcmpOnlyInstruction<Reg>
68where
69 Reg: [const] ZcmpRegister<Type = u64>,
70 Regs: [const] RegisterFile<Reg>,
71 Memory: [const] VirtualMemory,
72 PC: [const] ProgramCounter<Reg::Type, Memory>,
73 Env: [const] SystemInstructionHandler<Reg, Regs, Memory, PC>,
74{
75 #[inline(always)]
76 #[cfg_attr(feature = "no-panic", no_panic_const::no_panic(const))]
77 fn execute(
78 self,
79 Rs1Rs2OperandValues {
80 rs1_value,
81 rs2_value,
82 }: Rs1Rs2OperandValues<<Self::Reg as Register>::Type>,
83 regs: &mut Regs,
84 _env: &mut Env,
85 memory: &mut Memory,
86 _program_counter: &mut PC,
87 ) -> ExecutionResult<Self::Reg> {
88 match self {
89 Self::CmPush { urlist, stack_adj } => {
90 rv64_zcmp_helpers::do_push(regs, memory, urlist, stack_adj)
91 }
92 Self::CmPop { urlist, stack_adj } => {
93 rv64_zcmp_helpers::do_pop(regs, memory, urlist, stack_adj)?;
94 ExecutionResult::ContinueNoWrite
95 }
96 Self::CmPopretz { urlist, stack_adj } => {
97 let ra_val = rv64_zcmp_helpers::do_pop(regs, memory, urlist, stack_adj)?;
98 regs.write(Reg::A0, 0);
100 let target = ra_val & !1;
102 ExecutionResult::Jump { target }
103 }
104 Self::CmPopret { urlist, stack_adj } => {
105 let ra_val = rv64_zcmp_helpers::do_pop(regs, memory, urlist, stack_adj)?;
106 let target = ra_val & !1;
108 ExecutionResult::Jump { target }
109 }
110 Self::CmMva01s { rs1: _, rs2: _ } => {
111 let v1 = rs1_value;
113 let v2 = rs2_value;
114 regs.write(Reg::A0, v1);
115 ExecutionResult::Continue {
116 rd: Reg::A1,
117 value: v2,
118 }
119 }
120 Self::CmMvsa01 { rs1, rs2 } => {
121 let a0_val = regs.read(Reg::A0);
123 let a1_val = regs.read(Reg::A1);
124 regs.write(rs1, a0_val);
125 ExecutionResult::Continue {
126 rd: rs2,
127 value: a1_val,
128 }
129 }
130 }
131 }
132}