1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70
//! Frame layout item changes. use crate::ir::entities::Inst; use crate::isa::RegUnit; use std::boxed::Box; use crate::HashMap; /// Change in the frame layout information. #[derive(Clone, Copy, Debug, Eq, PartialEq, Hash)] pub enum FrameLayoutChange { /// Base CallFrameAddress (CFA) pointer moved to different register/offset. CallFrameAddressAt { /// CFA register. reg: RegUnit, /// CFA offset. offset: isize, }, /// Register saved at. RegAt { /// Saved register. reg: RegUnit, /// Offset in the frame (offset from CFA). cfa_offset: isize, }, /// Return address saved at. ReturnAddressAt { /// Offset in the frame (offset from CFA). cfa_offset: isize, }, /// The entire frame layout must be preserved somewhere to be restored at a corresponding /// `Restore` change. /// /// This likely maps to the DWARF call frame instruction `.cfa_remember_state`. Preserve, /// Restore the entire frame layout from a corresponding prior `Preserve` frame change. /// /// This likely maps to the DWARF call frame instruction `.cfa_restore_state`. Restore, } /// Set of frame layout changes. pub type FrameLayoutChanges = Box<[FrameLayoutChange]>; /// Frame items layout for (prologue/epilogue) instructions. #[derive(Debug, Clone)] pub struct FrameLayout { /// Initial frame layout. pub initial: FrameLayoutChanges, /// Instruction frame layout (changes). Because the map will not be dense, /// a HashMap is used instead of a SecondaryMap. pub instructions: HashMap<Inst, FrameLayoutChanges>, } impl FrameLayout { /// Create instance of FrameLayout. pub fn new() -> Self { FrameLayout { initial: vec![].into_boxed_slice(), instructions: HashMap::new(), } } /// Clear the structure. pub fn clear(&mut self) { self.initial = vec![].into_boxed_slice(); self.instructions.clear(); } }