ab_riscv_interpreter/rv64/zce/zcmp/
rv64_zcmp_helpers.rs1use crate::{ExecutionError, ExecutionResult, RegisterFile, VirtualMemory};
4use ab_riscv_primitives::prelude::*;
5
6#[inline]
8#[doc(hidden)]
9#[cfg_attr(feature = "no-panic", no_panic_const::no_panic)]
10pub const fn do_push<Reg, Regs, Memory>(
11 regs: &mut Regs,
12 memory: &mut Memory,
13 urlist: ZcmpUrlist<Reg>,
14 stack_adj: u8,
15) -> ExecutionResult<Reg>
16where
17 Reg: [const] ZcmpRegister<Type = u64>,
18 Regs: [const] RegisterFile<Reg>,
19 Memory: [const] VirtualMemory,
20{
21 let sp = regs.read(Reg::SP);
22 let mut store_addr = sp.wrapping_sub(size_of::<Reg::Type>() as u64);
24 let mut reg_list = urlist.reg_list();
25 #[expect(clippy::while_let_on_iterator, reason = "Const context")]
27 while let Some(reg) = reg_list.next() {
28 memory.write(store_addr, regs.read(reg))?;
29 store_addr = store_addr.wrapping_sub(size_of::<Reg::Type>() as u64);
30 }
31 ExecutionResult::Continue {
32 rd: Reg::SP,
33 value: sp.wrapping_sub(u64::from(stack_adj)),
34 }
35}
36
37#[inline]
40#[doc(hidden)]
41#[cfg_attr(feature = "no-panic", no_panic_const::no_panic)]
42pub const fn do_pop<Reg, Regs, Memory>(
43 regs: &mut Regs,
44 memory: &mut Memory,
45 urlist: ZcmpUrlist<Reg>,
46 stack_adj: u8,
47) -> Result<u64, ExecutionError<Reg::Type>>
48where
49 Reg: [const] ZcmpRegister<Type = u64>,
50 Regs: [const] RegisterFile<Reg>,
51 Memory: [const] VirtualMemory,
52{
53 let sp = regs.read(Reg::SP);
54 let new_sp = sp.wrapping_add(u64::from(stack_adj));
55 let mut load_addr = new_sp.wrapping_sub(size_of::<Reg::Type>() as u64);
57 let mut reg_list = urlist.reg_list();
58 #[expect(clippy::while_let_on_iterator, reason = "Const context")]
60 while let Some(reg) = reg_list.next() {
61 let value = memory.read::<u64>(load_addr)?;
62 regs.write(reg, value);
63 load_addr = load_addr.wrapping_sub(size_of::<Reg::Type>() as u64);
64 }
65 regs.write(Reg::SP, new_sp);
66 Ok(regs.read(Reg::RA))
67}