ab_riscv_interpreter/rv32/zce/zcmp/
rv32_zcmp_helpers.rs1use crate::{ExecutionError, RegisterFile, VirtualMemory};
4use ab_riscv_primitives::prelude::*;
5use core::ops::ControlFlow;
6
7#[inline]
9#[doc(hidden)]
10#[expect(clippy::type_complexity, reason = "Internal helper")]
11#[cfg_attr(feature = "no-panic", no_panic_const::no_panic)]
12pub fn do_push<Reg, Regs, Memory, CustomError>(
13 regs: &mut Regs,
14 memory: &mut Memory,
15 urlist: ZcmpUrlist<Reg>,
16 stack_adj: u8,
17) -> Result<ControlFlow<(), (Reg, u32)>, ExecutionError<Reg::Type, CustomError>>
18where
19 Reg: ZcmpRegister<Type = u32>,
20 Regs: RegisterFile<Reg>,
21 Memory: VirtualMemory,
22{
23 let sp = regs.read(Reg::SP);
24 let mut store_addr = u64::from(sp.wrapping_sub(size_of::<Reg::Type>() as u32));
26 for reg in urlist.reg_list() {
27 memory.write(store_addr, regs.read(reg))?;
28 store_addr = store_addr.wrapping_sub(size_of::<Reg::Type>() as u64);
29 }
30 Ok(ControlFlow::Continue((
31 Reg::SP,
32 sp.wrapping_sub(u32::from(stack_adj)),
33 )))
34}
35
36#[inline]
39#[doc(hidden)]
40#[cfg_attr(feature = "no-panic", no_panic_const::no_panic)]
41pub fn do_pop<Reg, Regs, Memory, CustomError>(
42 regs: &mut Regs,
43 memory: &mut Memory,
44 urlist: ZcmpUrlist<Reg>,
45 stack_adj: u8,
46) -> Result<u32, ExecutionError<Reg::Type, CustomError>>
47where
48 Reg: ZcmpRegister<Type = u32>,
49 Regs: RegisterFile<Reg>,
50 Memory: VirtualMemory,
51{
52 let sp = regs.read(Reg::SP);
53 let new_sp = sp.wrapping_add(u32::from(stack_adj));
54 let mut load_addr = u64::from(new_sp.wrapping_sub(size_of::<Reg::Type>() as u32));
56 for reg in urlist.reg_list() {
57 let value = memory.read::<u32>(load_addr)?;
58 regs.write(reg, value);
59 load_addr = load_addr.wrapping_sub(size_of::<Reg::Type>() as u64);
60 }
61 regs.write(Reg::SP, new_sp);
62 Ok(regs.read(Reg::RA))
63}