Refactor UnwindInfo codes and frame_register (#2307)
* Refactor UnwindInfo codes and frame_register * use isa word_size * fix filetests * Add comment about UnwindCode::PushRegister
This commit is contained in:
@@ -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<Self> {
|
||||
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,
|
||||
});
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user