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:
Yury Delendik
2020-10-22 14:52:42 -05:00
committed by GitHub
parent 4f104d3a4e
commit b10e027fef
8 changed files with 219 additions and 128 deletions

View File

@@ -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,
});
}
_ => {}
}
}