ab_riscv_interpreter/rv64/zce/zcmp/
rv64_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")]
11pub fn do_push<Reg, Regs, Memory, CustomError>(
12 regs: &mut Regs,
13 memory: &mut Memory,
14 urlist: ZcmpUrlist<Reg>,
15 stack_adj: u8,
16) -> Result<ControlFlow<(), (Reg, u64)>, ExecutionError<Reg::Type, CustomError>>
17where
18 Reg: ZcmpRegister<Type = u64>,
19 Regs: RegisterFile<Reg>,
20 Memory: VirtualMemory,
21{
22 let sp = regs.read(Reg::SP);
23 let mut store_addr = sp.wrapping_sub(size_of::<Reg::Type>() as u64);
25 for reg in urlist.reg_list() {
26 memory.write(store_addr, regs.read(reg))?;
27 store_addr = store_addr.wrapping_sub(size_of::<Reg::Type>() as u64);
28 }
29 Ok(ControlFlow::Continue((
30 Reg::SP,
31 sp.wrapping_sub(u64::from(stack_adj)),
32 )))
33}
34
35#[inline]
38#[doc(hidden)]
39pub fn do_pop<Reg, Regs, Memory, CustomError>(
40 regs: &mut Regs,
41 memory: &mut Memory,
42 urlist: ZcmpUrlist<Reg>,
43 stack_adj: u8,
44) -> Result<u64, ExecutionError<Reg::Type, CustomError>>
45where
46 Reg: ZcmpRegister<Type = u64>,
47 Regs: RegisterFile<Reg>,
48 Memory: VirtualMemory,
49{
50 let sp = regs.read(Reg::SP);
51 let new_sp = sp.wrapping_add(u64::from(stack_adj));
52 let mut load_addr = new_sp.wrapping_sub(size_of::<Reg::Type>() as u64);
54 for reg in urlist.reg_list() {
55 let value = memory.read::<u64>(load_addr)?;
56 regs.write(reg, value);
57 load_addr = load_addr.wrapping_sub(size_of::<Reg::Type>() as u64);
58 }
59 regs.write(Reg::SP, new_sp);
60 Ok(regs.read(Reg::RA))
61}