ab_riscv_interpreter/rv32/zce/zcmp/
rv32_zcmp_helpers.rs1use crate::{ExecutionError, RegisterFile, VirtualMemory};
4use ab_riscv_primitives::prelude::*;
5
6#[inline(always)]
8#[doc(hidden)]
9pub fn do_push<Reg, Regs, Memory, CustomError>(
10 regs: &mut Regs,
11 memory: &mut Memory,
12 urlist: ZcmpUrlist<Reg>,
13 stack_adj: u32,
14) -> Result<(), ExecutionError<Reg::Type, CustomError>>
15where
16 Reg: ZcmpRegister<Type = u32>,
17 Regs: RegisterFile<Reg>,
18 Memory: VirtualMemory,
19{
20 let sp = regs.read(Reg::SP);
21 let mut store_addr = u64::from(sp.wrapping_sub(size_of::<Reg::Type>() as u32));
23 for reg in urlist.reg_list() {
24 memory.write(store_addr, regs.read(reg))?;
25 store_addr = store_addr.wrapping_sub(size_of::<Reg::Type>() as u64);
26 }
27 regs.write(Reg::SP, sp.wrapping_sub(stack_adj));
28 Ok(())
29}
30
31#[inline(always)]
34#[doc(hidden)]
35pub fn do_pop<Reg, Regs, Memory, CustomError>(
36 regs: &mut Regs,
37 memory: &mut Memory,
38 urlist: ZcmpUrlist<Reg>,
39 stack_adj: u32,
40) -> Result<u32, ExecutionError<Reg::Type, CustomError>>
41where
42 Reg: ZcmpRegister<Type = u32>,
43 Regs: RegisterFile<Reg>,
44 Memory: VirtualMemory,
45{
46 let sp = regs.read(Reg::SP);
47 let new_sp = sp.wrapping_add(stack_adj);
48 let mut load_addr = u64::from(new_sp.wrapping_sub(size_of::<Reg::Type>() as u32));
50 for reg in urlist.reg_list() {
51 let value = memory.read::<u32>(load_addr)?;
52 regs.write(reg, value);
53 load_addr = load_addr.wrapping_sub(size_of::<Reg::Type>() as u64);
54 }
55 regs.write(Reg::SP, new_sp);
56 Ok(regs.read(Reg::RA))
57}