ab_riscv_interpreter/rv64/zce/zcmp/
rv64_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 = u64>,
17 Regs: RegisterFile<Reg>,
18 Memory: VirtualMemory,
19{
20 let sp = regs.read(Reg::SP);
21 let mut store_addr = sp.wrapping_sub(size_of::<Reg::Type>() as u64);
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(u64::from(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<u64, ExecutionError<Reg::Type, CustomError>>
41where
42 Reg: ZcmpRegister<Type = u64>,
43 Regs: RegisterFile<Reg>,
44 Memory: VirtualMemory,
45{
46 let sp = regs.read(Reg::SP);
47 let new_sp = sp.wrapping_add(u64::from(stack_adj));
48 let mut load_addr = new_sp.wrapping_sub(size_of::<Reg::Type>() as u64);
50 for reg in urlist.reg_list() {
51 let value = memory.read::<u64>(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}