use std::io::{Error, Write};
pub struct X86Frame;
impl X86Frame {
pub fn generate_prologue<W: Write>(
writer: &mut W,
stack_size: usize,
unwind: bool,
) -> Result<(), Error> {
writeln!(writer, " pushq %rbp")?;
if unwind {
writeln!(writer, " .cfi_def_cfa_offset 16")?;
writeln!(writer, " .cfi_offset %rbp, -16")?;
}
writeln!(writer, " movq %rsp, %rbp")?;
if unwind {
writeln!(writer, " .cfi_def_cfa_register %rbp")?;
}
let stack_size = Self::aligned_frame_size(stack_size);
if stack_size > 0 {
writeln!(writer, " subq ${stack_size}, %rsp")?;
}
Ok(())
}
pub fn aligned_frame_size(stack_size: usize) -> usize {
stack_size.div_ceil(16) * 16
}
pub fn generate_epilogue<W: Write>(
writer: &mut W,
stack_size: usize,
unwind: bool,
) -> Result<(), Error> {
let stack_size = Self::aligned_frame_size(stack_size);
if unwind {
writeln!(writer, " .cfi_remember_state")?;
}
if stack_size > 0 {
writeln!(writer, " addq ${stack_size}, %rsp")?;
}
writeln!(writer, " popq %rbp")?;
if unwind {
writeln!(writer, " .cfi_def_cfa %rsp, 8")?;
}
writeln!(writer, " ret")?;
if unwind {
writeln!(writer, " .cfi_restore_state")?;
}
Ok(())
}
pub fn calculate_stack_offset(slot_index: usize) -> i32 {
-((slot_index as i32 + 1) * 8)
}
}