|
|
|
use status::StatusFlags;
|
|
|
|
|
|
|
|
use crate::asm::data::literal::{Addr, Value};
|
|
|
|
|
|
|
|
pub(crate) mod status;
|
|
|
|
|
|
|
|
pub const REG_COUNT: usize = 16;
|
|
|
|
|
|
|
|
pub type CallStack = Vec<StackFrame>;
|
|
|
|
|
|
|
|
#[derive(Default, Clone, Debug)]
|
|
|
|
pub struct StackFrame {
|
|
|
|
/// Program counter, address of the executed instruction
|
|
|
|
pub pc: Addr,
|
|
|
|
/// Status flags
|
|
|
|
pub status: StatusFlags,
|
|
|
|
/// Argument registers
|
|
|
|
pub arg: [Value; REG_COUNT],
|
|
|
|
/// Result registers
|
|
|
|
pub res: [Value; REG_COUNT],
|
|
|
|
/// General purpose registers
|
|
|
|
pub gen: [Value; REG_COUNT],
|
|
|
|
}
|
|
|
|
|
|
|
|
impl StackFrame {
|
|
|
|
/// Create a new stack frame at a given address
|
|
|
|
pub fn new(addr: Addr, args: &[Value]) -> Self {
|
|
|
|
let mut sf = StackFrame::default();
|
|
|
|
sf.pc = addr;
|
|
|
|
for n in 0..(args.len().min(REG_COUNT)) {
|
|
|
|
sf.arg[n] = args[n];
|
|
|
|
}
|
|
|
|
sf
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn set_retvals(&mut self, vals: &[Value]) {
|
|
|
|
for n in 0..(vals.len().min(REG_COUNT)) {
|
|
|
|
self.res[n] = vals[n];
|
|
|
|
}
|
|
|
|
|
|
|
|
// Zero the rest
|
|
|
|
for n in vals.len()..REG_COUNT {
|
|
|
|
self.res[n] = 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|