From b10e027fef0d21d5d02b9444f833fcc559f6eb39 Mon Sep 17 00:00:00 2001 From: Yury Delendik Date: Thu, 22 Oct 2020 14:52:42 -0500 Subject: [PATCH] Refactor UnwindInfo codes and frame_register (#2307) * Refactor UnwindInfo codes and frame_register * use isa word_size * fix filetests * Add comment about UnwindCode::PushRegister --- cranelift/codegen/src/isa/unwind.rs | 7 +- cranelift/codegen/src/isa/unwind/systemv.rs | 127 +++++++++--------- cranelift/codegen/src/isa/unwind/winx64.rs | 64 ++++++--- cranelift/codegen/src/isa/x86/abi.rs | 3 +- cranelift/codegen/src/isa/x86/unwind.rs | 98 +++++++++++--- .../codegen/src/isa/x86/unwind/systemv.rs | 15 +-- .../codegen/src/isa/x86/unwind/winx64.rs | 10 +- .../filetests/isa/x86/systemv_x64_unwind.clif | 23 +++- 8 files changed, 219 insertions(+), 128 deletions(-) diff --git a/cranelift/codegen/src/isa/unwind.rs b/cranelift/codegen/src/isa/unwind.rs index 0f957d631b..cc53fb6a3d 100644 --- a/cranelift/codegen/src/isa/unwind.rs +++ b/cranelift/codegen/src/isa/unwind.rs @@ -27,16 +27,12 @@ pub(crate) mod input { SaveRegister { offset: CodeOffset, reg: Reg, + stack_offset: u32, }, RestoreRegister { offset: CodeOffset, reg: Reg, }, - SaveXmmRegister { - offset: CodeOffset, - reg: Reg, - stack_offset: u32, - }, StackAlloc { offset: CodeOffset, size: u32, @@ -64,5 +60,6 @@ pub(crate) mod input { pub(crate) prologue_unwind_codes: Vec>, pub(crate) epilogues_unwind_codes: Vec>>, pub(crate) function_size: CodeOffset, + pub(crate) word_size: u8, } } diff --git a/cranelift/codegen/src/isa/unwind/systemv.rs b/cranelift/codegen/src/isa/unwind/systemv.rs index c3070fe1c2..70bac9fe4d 100644 --- a/cranelift/codegen/src/isa/unwind/systemv.rs +++ b/cranelift/codegen/src/isa/unwind/systemv.rs @@ -115,12 +115,10 @@ pub struct UnwindInfo { impl UnwindInfo { pub(crate) fn build<'b>( unwind: input::UnwindInfo, - word_size: u8, - frame_register: Option, map_reg: &'b dyn RegisterMapper, ) -> CodegenResult { use input::UnwindCode; - let mut builder = InstructionBuilder::new(word_size, frame_register, map_reg); + let mut builder = InstructionBuilder::new(unwind.word_size, map_reg); for c in unwind.prologue_unwind_codes.iter().chain( unwind @@ -130,9 +128,13 @@ impl UnwindInfo { .flatten(), ) { match c { - UnwindCode::SaveRegister { offset, reg } => { + UnwindCode::SaveRegister { + offset, + reg, + stack_offset: 0, + } => { builder - .push_reg(*offset, *reg) + .save_reg(*offset, *reg) .map_err(CodegenError::RegisterMappingError)?; } UnwindCode::StackAlloc { offset, size } => { @@ -143,7 +145,7 @@ impl UnwindInfo { } UnwindCode::RestoreRegister { offset, reg } => { builder - .pop_reg(*offset, *reg) + .restore_reg(*offset, *reg) .map_err(CodegenError::RegisterMappingError)?; } UnwindCode::SetFramePointer { offset, reg } => { @@ -180,46 +182,29 @@ impl UnwindInfo { } struct InstructionBuilder<'a> { - word_size: u8, - cfa_offset: i32, - saved_state: Option, + sp_offset: i32, frame_register: Option, + saved_state: Option<(i32, Option)>, map_reg: &'a dyn RegisterMapper, instructions: Vec<(u32, CallFrameInstruction)>, } impl<'a> InstructionBuilder<'a> { - fn new( - word_size: u8, - frame_register: Option, - map_reg: &'a (dyn RegisterMapper + 'a), - ) -> Self { + fn new(word_size: u8, map_reg: &'a (dyn RegisterMapper + 'a)) -> Self { Self { - word_size, - cfa_offset: word_size as i32, // CFA offset starts at word size offset to account for the return address on stack + sp_offset: word_size as i32, // CFA offset starts at word size offset to account for the return address on stack saved_state: None, - frame_register, + frame_register: None, map_reg, instructions: Vec::new(), } } - fn push_reg(&mut self, offset: u32, reg: RegUnit) -> Result<(), RegisterMappingError> { - self.cfa_offset += self.word_size as i32; - // Update the CFA if this is the save of the frame pointer register or if a frame pointer isn't being used - // When using a frame pointer, we only need to update the CFA to account for the push of the frame pointer itself - if match self.frame_register { - Some(fp) => reg == fp, - None => true, - } { - self.instructions - .push((offset, CallFrameInstruction::CfaOffset(self.cfa_offset))); - } - + fn save_reg(&mut self, offset: u32, reg: RegUnit) -> Result<(), RegisterMappingError> { // Pushes in the prologue are register saves, so record an offset of the save self.instructions.push(( offset, - CallFrameInstruction::Offset(self.map_reg.map(reg)?, -self.cfa_offset), + CallFrameInstruction::Offset(self.map_reg.map(reg)?, -self.sp_offset), )); Ok(()) @@ -228,27 +213,52 @@ impl<'a> InstructionBuilder<'a> { fn adjust_sp_down_imm(&mut self, offset: u32, imm: i64) { assert!(imm <= core::u32::MAX as i64); + self.sp_offset += imm as i32; + // Don't adjust the CFA if we're using a frame pointer if self.frame_register.is_some() { return; } - self.cfa_offset += imm as i32; self.instructions - .push((offset, CallFrameInstruction::CfaOffset(self.cfa_offset))); + .push((offset, CallFrameInstruction::CfaOffset(self.sp_offset))); } fn adjust_sp_up_imm(&mut self, offset: u32, imm: i64) { assert!(imm <= core::u32::MAX as i64); + self.sp_offset -= imm as i32; + // Don't adjust the CFA if we're using a frame pointer if self.frame_register.is_some() { return; } - self.cfa_offset -= imm as i32; - self.instructions - .push((offset, CallFrameInstruction::CfaOffset(self.cfa_offset))); + let cfa_inst_ofs = { + // Scan to find and merge with CFA instruction with the same offset. + let mut it = self.instructions.iter_mut(); + loop { + match it.next_back() { + Some((i_offset, i)) if *i_offset == offset => { + if let CallFrameInstruction::Cfa(_, o) = i { + break Some(o); + } + } + _ => { + break None; + } + } + } + }; + + if let Some(o) = cfa_inst_ofs { + // Update previous CFA instruction. + *o = self.sp_offset; + } else { + // Add just CFA offset instruction. + self.instructions + .push((offset, CallFrameInstruction::CfaOffset(self.sp_offset))); + } } fn set_cfa_reg(&mut self, offset: u32, reg: RegUnit) -> Result<(), RegisterMappingError> { @@ -256,48 +266,39 @@ impl<'a> InstructionBuilder<'a> { offset, CallFrameInstruction::CfaRegister(self.map_reg.map(reg)?), )); + self.frame_register = Some(reg); Ok(()) } - fn pop_reg(&mut self, offset: u32, reg: RegUnit) -> Result<(), RegisterMappingError> { - self.cfa_offset -= self.word_size as i32; - - // Update the CFA if this is the restore of the frame pointer register or if a frame pointer isn't being used - match self.frame_register { - Some(fp) => { - if reg == fp { - self.instructions.push(( - offset, - CallFrameInstruction::Cfa(self.map_reg.rsp(), self.cfa_offset), - )); - } - } - None => { - self.instructions - .push((offset, CallFrameInstruction::CfaOffset(self.cfa_offset))); - - // Pops in the epilogue are register restores, so record a "same value" for the register - // This isn't necessary when using a frame pointer as the CFA doesn't change for CSR restores - self.instructions.push(( - offset, - CallFrameInstruction::SameValue(self.map_reg.map(reg)?), - )); - } - }; + fn restore_reg(&mut self, offset: u32, reg: RegUnit) -> Result<(), RegisterMappingError> { + // Update the CFA if this is the restore of the frame pointer register. + if Some(reg) == self.frame_register { + self.frame_register = None; + self.instructions.push(( + offset, + CallFrameInstruction::Cfa(self.map_reg.rsp(), self.sp_offset), + )); + } + // Pops in the epilogue are register restores, so record a "same value" for the register + self.instructions.push(( + offset, + CallFrameInstruction::SameValue(self.map_reg.map(reg)?), + )); Ok(()) } fn remember_state(&mut self, offset: u32) { - self.saved_state = Some(self.cfa_offset); + self.saved_state = Some((self.sp_offset, self.frame_register)); self.instructions .push((offset, CallFrameInstruction::RememberState)); } fn restore_state(&mut self, offset: u32) { - let cfa_offset = self.saved_state.take().unwrap(); - self.cfa_offset = cfa_offset; + let (sp_offset, frame_register) = self.saved_state.take().unwrap(); + self.sp_offset = sp_offset; + self.frame_register = frame_register; self.instructions .push((offset, CallFrameInstruction::RestoreState)); diff --git a/cranelift/codegen/src/isa/unwind/winx64.rs b/cranelift/codegen/src/isa/unwind/winx64.rs index f7d4d94c72..3d01982745 100644 --- a/cranelift/codegen/src/isa/unwind/winx64.rs +++ b/cranelift/codegen/src/isa/unwind/winx64.rs @@ -137,10 +137,15 @@ impl UnwindCode { } } +pub(crate) enum MappedRegister { + Int(u8), + Xmm(u8), +} + /// Maps UnwindInfo register to Windows x64 unwind data. pub(crate) trait RegisterMapper { /// Maps RegUnit. - fn map(reg: RegUnit) -> u8; + fn map(reg: RegUnit) -> MappedRegister; } /// Represents Windows x64 unwind information. @@ -219,14 +224,50 @@ impl UnwindInfo { ) -> CodegenResult { use crate::isa::unwind::input::UnwindCode as InputUnwindCode; + let word_size: u32 = unwind.word_size.into(); let mut unwind_codes = Vec::new(); for c in unwind.prologue_unwind_codes.iter() { match c { - InputUnwindCode::SaveRegister { offset, reg } => { - unwind_codes.push(UnwindCode::PushRegister { - offset: ensure_unwind_offset(*offset)?, - reg: MR::map(*reg), - }); + InputUnwindCode::SaveRegister { + offset, + reg, + stack_offset, + } => { + let reg = MR::map(*reg); + let offset = ensure_unwind_offset(*offset)?; + match reg { + MappedRegister::Int(reg) => { + // Attempt to convert sequence of the `InputUnwindCode`: + // `StackAlloc { size = word_size }`, `SaveRegister { stack_offset: 0 }` + // to the shorter `UnwindCode::PushRegister`. + let push_reg_sequence = if let Some(UnwindCode::StackAlloc { + offset: alloc_offset, + size, + }) = unwind_codes.last() + { + *size == word_size && offset == *alloc_offset && *stack_offset == 0 + } else { + false + }; + if push_reg_sequence { + *unwind_codes.last_mut().unwrap() = + UnwindCode::PushRegister { offset, reg }; + } else { + // TODO add `UnwindCode::SaveRegister` to handle multiple register + // pushes with single `UnwindCode::StackAlloc`. + return Err(CodegenError::Unsupported( + "Unsupported UnwindCode::PushRegister sequence".into(), + )); + } + } + MappedRegister::Xmm(reg) => { + unwind_codes.push(UnwindCode::SaveXmm { + offset, + reg, + stack_offset: *stack_offset, + }); + } + } } InputUnwindCode::StackAlloc { offset, size } => { unwind_codes.push(UnwindCode::StackAlloc { @@ -234,17 +275,6 @@ impl UnwindInfo { size: *size, }); } - InputUnwindCode::SaveXmmRegister { - offset, - reg, - stack_offset, - } => { - unwind_codes.push(UnwindCode::SaveXmm { - offset: ensure_unwind_offset(*offset)?, - reg: MR::map(*reg), - stack_offset: *stack_offset, - }); - } _ => {} } } diff --git a/cranelift/codegen/src/isa/x86/abi.rs b/cranelift/codegen/src/isa/x86/abi.rs index 227e2a8ee7..5119bb3241 100644 --- a/cranelift/codegen/src/isa/x86/abi.rs +++ b/cranelift/codegen/src/isa/x86/abi.rs @@ -1083,8 +1083,7 @@ pub fn create_unwind_info( // In the future, we should be omitting frame pointer as an optimization, so this will change Ok(match func.signature.call_conv { CallConv::Fast | CallConv::Cold | CallConv::SystemV => { - super::unwind::systemv::create_unwind_info(func, isa, Some(RU::rbp.into()))? - .map(|u| UnwindInfo::SystemV(u)) + super::unwind::systemv::create_unwind_info(func, isa)?.map(|u| UnwindInfo::SystemV(u)) } CallConv::WindowsFastcall => { super::unwind::winx64::create_unwind_info(func, isa)?.map(|u| UnwindInfo::WindowsX64(u)) diff --git a/cranelift/codegen/src/isa/x86/unwind.rs b/cranelift/codegen/src/isa/x86/unwind.rs index e458111b37..3168cc49be 100644 --- a/cranelift/codegen/src/isa/x86/unwind.rs +++ b/cranelift/codegen/src/isa/x86/unwind.rs @@ -15,7 +15,6 @@ use crate::isa::unwind::input::{UnwindCode, UnwindInfo}; pub(crate) fn create_unwind_info( func: &Function, isa: &dyn TargetIsa, - frame_register: Option, ) -> CodegenResult>> { // Find last block based on max offset. let last_block = func @@ -36,10 +35,13 @@ pub(crate) fn create_unwind_info( .map(|(i, b)| (*b, *i)) .collect::>(); + let word_size = isa.pointer_bytes(); + let mut stack_size = None; let mut prologue_size = 0; let mut prologue_unwind_codes = Vec::new(); let mut epilogues_unwind_codes = Vec::new(); + let mut frame_register: Option = None; // Process only entry block and blocks with epilogues. let mut blocks = func @@ -93,7 +95,15 @@ pub(crate) fn create_unwind_info( match opcode { Opcode::X86Push => { let reg = func.locations[arg].unwrap_reg(); - unwind_codes.push(UnwindCode::SaveRegister { offset, reg }); + unwind_codes.push(UnwindCode::StackAlloc { + offset, + size: word_size.into(), + }); + unwind_codes.push(UnwindCode::SaveRegister { + offset, + reg, + stack_offset: 0, + }); } Opcode::AdjustSpDown => { let stack_size = @@ -160,7 +170,7 @@ pub(crate) fn create_unwind_info( // Note: the stack_offset here is relative to an adjusted SP if dst == (RU::rsp as RegUnit) && FPR.contains(src) { let stack_offset: i32 = stack_offset.into(); - unwind_codes.push(UnwindCode::SaveXmmRegister { + unwind_codes.push(UnwindCode::SaveRegister { offset, reg: src, stack_offset: stack_offset as u32, @@ -168,12 +178,11 @@ pub(crate) fn create_unwind_info( } } } - InstructionData::CopySpecial { src, dst, .. } => { - if let Some(fp) = frame_register { - // Check for change in CFA register (RSP is always the starting CFA) - if src == (RU::rsp as RegUnit) && dst == fp { - unwind_codes.push(UnwindCode::SetFramePointer { offset, reg: dst }); - } + InstructionData::CopySpecial { src, dst, .. } if frame_register.is_none() => { + // Check for change in CFA register (RSP is always the starting CFA) + if src == (RU::rsp as RegUnit) { + unwind_codes.push(UnwindCode::SetFramePointer { offset, reg: dst }); + frame_register = Some(dst); } } InstructionData::NullAry { opcode } => match opcode { @@ -195,9 +204,15 @@ pub(crate) fn create_unwind_info( let reg = func.locations[*arg].unwrap_reg(); unwind_codes.push(UnwindCode::RestoreRegister { offset, reg }); + unwind_codes.push(UnwindCode::StackDealloc { + offset, + size: word_size.into(), + }); } epilogue_pop_offsets.clear(); + // TODO ensure unwind codes sorted by offsets ? + if !is_last_block { unwind_codes.push(UnwindCode::RestoreState { offset }); } @@ -216,6 +231,7 @@ pub(crate) fn create_unwind_info( prologue_unwind_codes, epilogues_unwind_codes, function_size, + word_size, })) } @@ -246,7 +262,7 @@ mod tests { context.compile(&*isa).expect("expected compilation"); - let unwind = create_unwind_info(&context.func, &*isa, None) + let unwind = create_unwind_info(&context.func, &*isa) .expect("can create unwind info") .expect("expected unwind info"); @@ -255,9 +271,15 @@ mod tests { UnwindInfo { prologue_size: 9, prologue_unwind_codes: vec![ + UnwindCode::StackAlloc { offset: 2, size: 8 }, UnwindCode::SaveRegister { offset: 2, reg: RU::rbp.into(), + stack_offset: 0, + }, + UnwindCode::SetFramePointer { + offset: 5, + reg: RU::rbp.into(), }, UnwindCode::StackAlloc { offset: 9, @@ -272,9 +294,14 @@ mod tests { UnwindCode::RestoreRegister { offset: 15, reg: RU::rbp.into() + }, + UnwindCode::StackDealloc { + offset: 15, + size: 8 } ]], function_size: 16, + word_size: 8, } ); } @@ -293,7 +320,7 @@ mod tests { context.compile(&*isa).expect("expected compilation"); - let unwind = create_unwind_info(&context.func, &*isa, None) + let unwind = create_unwind_info(&context.func, &*isa) .expect("can create unwind info") .expect("expected unwind info"); @@ -302,9 +329,15 @@ mod tests { UnwindInfo { prologue_size: 27, prologue_unwind_codes: vec![ + UnwindCode::StackAlloc { offset: 2, size: 8 }, UnwindCode::SaveRegister { offset: 2, reg: RU::rbp.into(), + stack_offset: 0, + }, + UnwindCode::SetFramePointer { + offset: 5, + reg: RU::rbp.into(), }, UnwindCode::StackAlloc { offset: 27, @@ -319,9 +352,14 @@ mod tests { UnwindCode::RestoreRegister { offset: 36, reg: RU::rbp.into() + }, + UnwindCode::StackDealloc { + offset: 36, + size: 8 } ]], function_size: 37, + word_size: 8, } ); } @@ -340,7 +378,7 @@ mod tests { context.compile(&*isa).expect("expected compilation"); - let unwind = create_unwind_info(&context.func, &*isa, None) + let unwind = create_unwind_info(&context.func, &*isa) .expect("can create unwind info") .expect("expected unwind info"); @@ -349,9 +387,15 @@ mod tests { UnwindInfo { prologue_size: 27, prologue_unwind_codes: vec![ + UnwindCode::StackAlloc { offset: 2, size: 8 }, UnwindCode::SaveRegister { offset: 2, reg: RU::rbp.into(), + stack_offset: 0, + }, + UnwindCode::SetFramePointer { + offset: 5, + reg: RU::rbp.into(), }, UnwindCode::StackAlloc { offset: 27, @@ -366,9 +410,14 @@ mod tests { UnwindCode::RestoreRegister { offset: 36, reg: RU::rbp.into() + }, + UnwindCode::StackDealloc { + offset: 36, + size: 8 } ]], function_size: 37, + word_size: 8, } ); } @@ -400,7 +449,7 @@ mod tests { context.compile(&*isa).expect("expected compilation"); - let unwind = create_unwind_info(&context.func, &*isa, Some(RU::rbp.into())) + let unwind = create_unwind_info(&context.func, &*isa) .expect("can create unwind info") .expect("expected unwind info"); @@ -409,9 +458,11 @@ mod tests { UnwindInfo { prologue_size: 5, prologue_unwind_codes: vec![ + UnwindCode::StackAlloc { offset: 2, size: 8 }, UnwindCode::SaveRegister { offset: 2, - reg: RU::rbp.into() + reg: RU::rbp.into(), + stack_offset: 0, }, UnwindCode::SetFramePointer { offset: 5, @@ -425,14 +476,25 @@ mod tests { offset: 12, reg: RU::rbp.into() }, + UnwindCode::StackDealloc { + offset: 12, + size: 8 + }, UnwindCode::RestoreState { offset: 13 } ], - vec![UnwindCode::RestoreRegister { - offset: 15, - reg: RU::rbp.into() - }] + vec![ + UnwindCode::RestoreRegister { + offset: 15, + reg: RU::rbp.into() + }, + UnwindCode::StackDealloc { + offset: 15, + size: 8 + } + ] ], function_size: 16, + word_size: 8, } ); } diff --git a/cranelift/codegen/src/isa/x86/unwind/systemv.rs b/cranelift/codegen/src/isa/x86/unwind/systemv.rs index 7bc5b283ac..b08628e6fd 100644 --- a/cranelift/codegen/src/isa/x86/unwind/systemv.rs +++ b/cranelift/codegen/src/isa/x86/unwind/systemv.rs @@ -95,7 +95,6 @@ pub fn map_reg(isa: &dyn TargetIsa, reg: RegUnit) -> Result, ) -> CodegenResult> { // Only System V-like calling conventions are supported match func.signature.call_conv { @@ -106,9 +105,8 @@ pub(crate) fn create_unwind_info( if func.prologue_end.is_none() || isa.name() != "x86" || isa.pointer_bits() != 64 { return Ok(None); } - const WORD_SIZE: u8 = 8; // bytes - let unwind = match super::create_unwind_info(func, isa, frame_register)? { + let unwind = match super::create_unwind_info(func, isa)? { Some(u) => u, None => { return Ok(None); @@ -126,12 +124,7 @@ pub(crate) fn create_unwind_info( } let map = RegisterMapper(isa); - Ok(Some(UnwindInfo::build( - unwind, - WORD_SIZE, - frame_register, - &map, - )?)) + Ok(Some(UnwindInfo::build(unwind, &map)?)) } #[cfg(test)] @@ -172,7 +165,7 @@ mod tests { _ => panic!("expected unwind information"), }; - assert_eq!(format!("{:?}", fde), "FrameDescriptionEntry { address: Constant(1234), length: 16, lsda: None, instructions: [(2, CfaOffset(16)), (2, Offset(Register(6), -16)), (5, CfaRegister(Register(6))), (15, Cfa(Register(7), 8))] }"); + assert_eq!(format!("{:?}", fde), "FrameDescriptionEntry { address: Constant(1234), length: 16, lsda: None, instructions: [(2, CfaOffset(16)), (2, Offset(Register(6), -16)), (5, CfaRegister(Register(6))), (15, Cfa(Register(7), 8)), (15, SameValue(Register(6)))] }"); } fn create_function(call_conv: CallConv, stack_slot: Option) -> Function { @@ -212,7 +205,7 @@ mod tests { _ => panic!("expected unwind information"), }; - assert_eq!(format!("{:?}", fde), "FrameDescriptionEntry { address: Constant(4321), length: 16, lsda: None, instructions: [(2, CfaOffset(16)), (2, Offset(Register(6), -16)), (5, CfaRegister(Register(6))), (12, RememberState), (12, Cfa(Register(7), 8)), (13, RestoreState), (15, Cfa(Register(7), 8))] }"); + assert_eq!(format!("{:?}", fde), "FrameDescriptionEntry { address: Constant(4321), length: 16, lsda: None, instructions: [(2, CfaOffset(16)), (2, Offset(Register(6), -16)), (5, CfaRegister(Register(6))), (12, RememberState), (12, Cfa(Register(7), 8)), (12, SameValue(Register(6))), (13, RestoreState), (15, Cfa(Register(7), 8)), (15, SameValue(Register(6)))] }"); } fn create_multi_return_function(call_conv: CallConv) -> Function { diff --git a/cranelift/codegen/src/isa/x86/unwind/winx64.rs b/cranelift/codegen/src/isa/x86/unwind/winx64.rs index 98c07949a2..ed046f9a87 100644 --- a/cranelift/codegen/src/isa/x86/unwind/winx64.rs +++ b/cranelift/codegen/src/isa/x86/unwind/winx64.rs @@ -14,7 +14,7 @@ pub(crate) fn create_unwind_info( return Ok(None); } - let unwind = match super::create_unwind_info(func, isa, None)? { + let unwind = match super::create_unwind_info(func, isa)? { Some(u) => u, None => { return Ok(None); @@ -27,12 +27,12 @@ pub(crate) fn create_unwind_info( struct RegisterMapper; impl crate::isa::unwind::winx64::RegisterMapper for RegisterMapper { - fn map(reg: RegUnit) -> u8 { + fn map(reg: RegUnit) -> crate::isa::unwind::winx64::MappedRegister { + use crate::isa::unwind::winx64::MappedRegister; if GPR.contains(reg) { - GPR.index_of(reg) as u8 + MappedRegister::Int(GPR.index_of(reg) as u8) } else if FPR.contains(reg) { - // XMM register - reg as u8 + MappedRegister::Xmm(reg as u8) } else { panic!() } diff --git a/cranelift/filetests/filetests/isa/x86/systemv_x64_unwind.clif b/cranelift/filetests/filetests/isa/x86/systemv_x64_unwind.clif index 7ff0ea8615..cf0da2f4db 100644 --- a/cranelift/filetests/filetests/isa/x86/systemv_x64_unwind.clif +++ b/cranelift/filetests/filetests/isa/x86/systemv_x64_unwind.clif @@ -38,7 +38,7 @@ block0: ; nextln: DW_CFA_def_cfa_register (r6) ; nextln: DW_CFA_advance_loc (1) ; nextln: DW_CFA_def_cfa (r7, 8) -; nextln: DW_CFA_nop +; nextln: DW_CFA_same_value (r6) ; nextln: DW_CFA_nop ; check a function with medium-sized stack alloc @@ -77,7 +77,7 @@ block0: ; nextln: DW_CFA_def_cfa_register (r6) ; nextln: DW_CFA_advance_loc (21) ; nextln: DW_CFA_def_cfa (r7, 8) -; nextln: DW_CFA_nop +; nextln: DW_CFA_same_value (r6) ; nextln: DW_CFA_nop ; check a function with large-sized stack alloc @@ -116,7 +116,7 @@ block0: ; nextln: DW_CFA_def_cfa_register (r6) ; nextln: DW_CFA_advance_loc (21) ; nextln: DW_CFA_def_cfa (r7, 8) -; nextln: DW_CFA_nop +; nextln: DW_CFA_same_value (r6) ; nextln: DW_CFA_nop ; nextln: @@ -169,7 +169,7 @@ block0(v0: i64, v1: i64): ; nextln: ; nextln: ; nextln: 0x00000018: FDE -; nextln: length: 0x00000034 +; nextln: length: 0x00000044 ; nextln: CIE_pointer: 0x00000000 ; nextln: start_addr: 0x0000000000000000 ; nextln: range_size: 0x0000000000000074 (end_addr = 0x0000000000000074) @@ -189,9 +189,18 @@ block0(v0: i64, v1: i64): ; nextln: DW_CFA_offset (r14, 6) ; nextln: DW_CFA_advance_loc (2) ; nextln: DW_CFA_offset (r15, 7) -; nextln: DW_CFA_advance_loc (102) +; nextln: DW_CFA_advance_loc (94) +; nextln: DW_CFA_same_value (r15) +; nextln: DW_CFA_advance_loc (2) +; nextln: DW_CFA_same_value (r14) +; nextln: DW_CFA_advance_loc (2) +; nextln: DW_CFA_same_value (r13) +; nextln: DW_CFA_advance_loc (2) +; nextln: DW_CFA_same_value (r12) +; nextln: DW_CFA_advance_loc (1) +; nextln: DW_CFA_same_value (r3) +; nextln: DW_CFA_advance_loc (1) ; nextln: DW_CFA_def_cfa (r7, 8) -; nextln: DW_CFA_nop -; nextln: DW_CFA_nop +; nextln: DW_CFA_same_value (r6) ; nextln: DW_CFA_nop ; nextln: DW_CFA_nop