use crate::ir::stackslot::{StackOffset, StackSlotKind, StackSlots};
use crate::ir::StackSlot;
#[derive(Clone, Copy, Debug)]
pub struct StackRef {
pub base: StackBase,
pub offset: StackOffset,
}
impl StackRef {
pub fn masked(ss: StackSlot, mask: StackBaseMask, frame: &StackSlots) -> Option<Self> {
if mask.contains(StackBase::SP) {
return Some(Self::sp(ss, frame));
}
None
}
pub fn sp(ss: StackSlot, frame: &StackSlots) -> Self {
let size = frame
.layout_info
.expect("Stack layout must be computed before referencing stack slots")
.frame_size;
let slot = &frame[ss];
let offset = if slot.kind == StackSlotKind::OutgoingArg {
slot.offset.unwrap()
} else {
let sp_offset = -(size as StackOffset);
slot.offset.unwrap() - sp_offset
};
Self {
base: StackBase::SP,
offset,
}
}
}
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub enum StackBase {
SP = 0,
FP = 1,
Zone = 2,
}
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub struct StackBaseMask(pub u8);
impl StackBaseMask {
pub fn contains(self, base: StackBase) -> bool {
self.0 & (1 << base as usize) != 0
}
}