diff --git a/lib/cretonne/src/isa/intel/abi.rs b/lib/cretonne/src/isa/intel/abi.rs index 2aa83703cd..0257c66586 100644 --- a/lib/cretonne/src/isa/intel/abi.rs +++ b/lib/cretonne/src/isa/intel/abi.rs @@ -15,9 +15,6 @@ static ARG_GPRS: [RU; 6] = [RU::rdi, RU::rsi, RU::rdx, RU::rcx, RU::r8, RU::r9]; /// Return value registers. 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 { pointer_bytes: u32, pointer_bits: u16, @@ -156,3 +153,11 @@ pub fn allocatable_registers( regs } + +pub fn callee_saved_registers(flags: &shared_settings::Flags) -> Vec { + if flags.is_64bit() { + return vec![RU::rbx, RU::r12, RU::r13, RU::r14, RU::r15]; + } else { + return vec![RU::rbx, RU::rsi, RU::rdi]; + } +} diff --git a/lib/cretonne/src/isa/intel/mod.rs b/lib/cretonne/src/isa/intel/mod.rs index 0d63a15220..3e90acc933 100644 --- a/lib/cretonne/src/isa/intel/mod.rs +++ b/lib/cretonne/src/isa/intel/mod.rs @@ -120,9 +120,15 @@ impl TargetIsa for Isa { fn prologue_epilogue(&self, func: &mut ir::Function) -> result::CtonResult { let word_size = if self.flags().is_64bit() { 8 } else { 4 }; + let csr_type = if self.flags().is_64bit() { + ir::types::I64 + } else { + ir::types::I32 + }; + let csrs = abi::callee_saved_registers(&self.shared_flags); let mut csr_stack_size = word_size; // Size of RBP to start with - for _reg in abi::CSR_GPRS.iter() { + for _reg in &csrs { csr_stack_size += word_size; } @@ -139,16 +145,16 @@ impl TargetIsa for Isa { // Append frame pointer to function signature let rbp_arg = ir::AbiParam::special_reg( - ir::types::I64, + csr_type, ir::ArgumentPurpose::FramePointer, RU::rbp as RegUnit, ); func.signature.params.push(rbp_arg); func.signature.returns.push(rbp_arg); - for reg in abi::CSR_GPRS.iter() { + for reg in &csrs { let csr_arg = ir::AbiParam::special_reg( - ir::types::I64, + csr_type, ir::ArgumentPurpose::CalleeSaved, *reg as RegUnit, ); @@ -158,7 +164,7 @@ impl TargetIsa for Isa { // Append param to entry EBB 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, csr_type); // Find our frame pointer parameter Value let fp = func.special_param(ir::ArgumentPurpose::FramePointer) @@ -168,9 +174,9 @@ impl TargetIsa for Isa { func.locations[fp] = ir::ValueLoc::Reg(RU::rbp as RegUnit); let mut csr_vals = Vec::new(); - for reg in abi::CSR_GPRS.iter() { + for reg in &csrs { // Append param to entry EBB - func.dfg.append_ebb_param(entry_ebb, ir::types::I64); + func.dfg.append_ebb_param(entry_ebb, csr_type); let csr_arg = func.dfg.ebb_params(entry_ebb).last().expect( "no last argument", @@ -216,7 +222,7 @@ impl TargetIsa for Isa { // Insert an epilogue directly before every 'return' for inst in return_insts { - self.insert_epilogue(inst, local_stack_size as i32, func); + self.insert_epilogue(inst, local_stack_size as i32, func, &csrs, csr_type); } @@ -225,18 +231,25 @@ impl TargetIsa for Isa { } impl Isa { - fn insert_epilogue(&self, inst: ir::Inst, stack_size: i32, func: &mut ir::Function) { + fn insert_epilogue( + &self, + inst: ir::Inst, + stack_size: i32, + func: &mut ir::Function, + csrs: &Vec, + csr_type: ir::types::Type, + ) { let mut return_values = Vec::new(); let mut pos = EncCursor::new(func, self).at_inst(inst); if stack_size > 0 { pos.ins().adjust_sp_imm(stack_size); } - for reg in abi::CSR_GPRS.iter().rev() { - let csr_ret = pos.ins().x86_pop(ir::types::I64); + for reg in csrs.iter().rev() { + let csr_ret = pos.ins().x86_pop(csr_type); return_values.push((csr_ret, *reg)); } - let fp_ret = pos.ins().x86_pop(ir::types::I64); + let fp_ret = pos.ins().x86_pop(csr_type); return_values.push((fp_ret, RU::rbp)); let func = pos.func;