Save all callee-saved registers in prologue.
This commit is contained in:
committed by
Jakob Stoklund Olesen
parent
b049916d35
commit
f31a764fc8
@@ -15,6 +15,9 @@ static ARG_GPRS: [RU; 6] = [RU::rdi, RU::rsi, RU::rdx, RU::rcx, RU::r8, RU::r9];
|
|||||||
/// Return value registers.
|
/// Return value registers.
|
||||||
static RET_GPRS: [RU; 3] = [RU::rax, RU::rdx, RU::rcx];
|
static RET_GPRS: [RU; 3] = [RU::rax, RU::rdx, RU::rcx];
|
||||||
|
|
||||||
|
/// Callee-saved registers
|
||||||
|
pub static CSR_GPRS: [RU; 5] = [RU::rbx, RU::r12, RU::r13, RU::r14, RU::r15];
|
||||||
|
|
||||||
struct Args {
|
struct Args {
|
||||||
pointer_bytes: u32,
|
pointer_bytes: u32,
|
||||||
pointer_bits: u16,
|
pointer_bits: u16,
|
||||||
|
|||||||
@@ -121,18 +121,21 @@ impl TargetIsa for Isa {
|
|||||||
fn prologue_epilogue(&self, func: &mut ir::Function) -> result::CtonResult {
|
fn prologue_epilogue(&self, func: &mut ir::Function) -> result::CtonResult {
|
||||||
let word_size = if self.flags().is_64bit() { 8 } else { 4 };
|
let word_size = if self.flags().is_64bit() { 8 } else { 4 };
|
||||||
|
|
||||||
// TODO: Insert stack slot for FP and CSRs we will push
|
let mut csr_stack_size = word_size; // Size of RBP to start with
|
||||||
let meta_stack_size = word_size; // TODO: this needs to change depending on CSRs
|
for _reg in abi::CSR_GPRS.iter() {
|
||||||
let stack_offset = -(meta_stack_size as i32);
|
csr_stack_size += word_size;
|
||||||
|
}
|
||||||
|
|
||||||
|
let stack_offset = -(csr_stack_size as i32);
|
||||||
let slot = ir::StackSlotData {
|
let slot = ir::StackSlotData {
|
||||||
kind: ir::StackSlotKind::IncomingArg,
|
kind: ir::StackSlotKind::IncomingArg,
|
||||||
size: meta_stack_size,
|
size: csr_stack_size,
|
||||||
offset: stack_offset,
|
offset: stack_offset,
|
||||||
};
|
};
|
||||||
func.create_stack_slot(slot);
|
func.create_stack_slot(slot);
|
||||||
|
|
||||||
let total_stack_size = layout_stack(&mut func.stack_slots, word_size)?;
|
let total_stack_size = layout_stack(&mut func.stack_slots, word_size)?;
|
||||||
let local_stack_size = total_stack_size - meta_stack_size;
|
let local_stack_size = total_stack_size - csr_stack_size;
|
||||||
|
|
||||||
// Append frame pointer to function signature
|
// Append frame pointer to function signature
|
||||||
let rbp_arg = ir::AbiParam::special_reg(
|
let rbp_arg = ir::AbiParam::special_reg(
|
||||||
@@ -143,6 +146,16 @@ impl TargetIsa for Isa {
|
|||||||
func.signature.params.push(rbp_arg);
|
func.signature.params.push(rbp_arg);
|
||||||
func.signature.returns.push(rbp_arg);
|
func.signature.returns.push(rbp_arg);
|
||||||
|
|
||||||
|
for reg in abi::CSR_GPRS.iter() {
|
||||||
|
let csr_arg = ir::AbiParam::special_reg(
|
||||||
|
ir::types::I64,
|
||||||
|
ir::ArgumentPurpose::CalleeSaved,
|
||||||
|
*reg as RegUnit,
|
||||||
|
);
|
||||||
|
func.signature.params.push(csr_arg);
|
||||||
|
func.signature.returns.push(csr_arg);
|
||||||
|
}
|
||||||
|
|
||||||
// Append param to entry EBB
|
// Append param to entry EBB
|
||||||
let entry_ebb = func.layout.entry_block().expect("missing entry block");
|
let entry_ebb = func.layout.entry_block().expect("missing entry block");
|
||||||
func.dfg.append_ebb_param(entry_ebb, ir::types::I64);
|
func.dfg.append_ebb_param(entry_ebb, ir::types::I64);
|
||||||
@@ -154,6 +167,23 @@ impl TargetIsa for Isa {
|
|||||||
// Assign it a location
|
// Assign it a location
|
||||||
func.locations[fp] = ir::ValueLoc::Reg(RU::rbp as RegUnit);
|
func.locations[fp] = ir::ValueLoc::Reg(RU::rbp as RegUnit);
|
||||||
|
|
||||||
|
let mut csr_vals = Vec::new();
|
||||||
|
for reg in abi::CSR_GPRS.iter() {
|
||||||
|
// Append param to entry EBB
|
||||||
|
func.dfg.append_ebb_param(entry_ebb, ir::types::I64);
|
||||||
|
|
||||||
|
let csr_arg = func.dfg.ebb_params(entry_ebb).last().expect(
|
||||||
|
"no last argument",
|
||||||
|
);
|
||||||
|
|
||||||
|
// Assign it a location
|
||||||
|
func.locations[*csr_arg] = ir::ValueLoc::Reg(*reg as RegUnit);
|
||||||
|
|
||||||
|
// Remember it so we can push it momentarily
|
||||||
|
csr_vals.push(*csr_arg);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// Insert prologue
|
// Insert prologue
|
||||||
{
|
{
|
||||||
let mut pos = EncCursor::new(func, self).at_first_insertion_point(entry_ebb);
|
let mut pos = EncCursor::new(func, self).at_first_insertion_point(entry_ebb);
|
||||||
@@ -165,6 +195,10 @@ impl TargetIsa for Isa {
|
|||||||
if local_stack_size > 0 {
|
if local_stack_size > 0 {
|
||||||
pos.ins().adjust_sp_imm(-(local_stack_size as i32));
|
pos.ins().adjust_sp_imm(-(local_stack_size as i32));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for csr_arg in csr_vals {
|
||||||
|
pos.ins().x86_push(csr_arg);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Find all 'return' instructions
|
// Find all 'return' instructions
|
||||||
@@ -187,6 +221,7 @@ impl TargetIsa for Isa {
|
|||||||
func.dfg.append_inst_arg(inst, fp_ret);
|
func.dfg.append_inst_arg(inst, fp_ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user