use crate::arch::x86::{DecodedInsn, Mnemonic, format_intel};
use crate::ast::Stmt;
use super::{Candidate, Pattern, PatternCtx};
pub struct MovExtend;
impl Pattern for MovExtend {
fn name(&self) -> &'static str {
"mov_extend"
}
fn tentative(
&self,
ctx: &PatternCtx,
insns: &[DecodedInsn],
start: usize,
) -> Option<Candidate> {
let ins = insns.get(start)?;
let prefix = match ins.iced.mnemonic() {
Mnemonic::Movzx => "movzx ",
Mnemonic::Movsx => "movsx ",
Mnemonic::Movsxd => "movsxd ",
_ => return None,
};
let (dst, src) = super::mov::split_two_operands(&format_intel(&ins.iced), prefix)?;
let sp = ctx.sp_delta_at.get(&ins.iced.ip()).copied();
let dst = crate::arch::x86::rename_operand_in_ctx(&dst, sp);
let src = crate::arch::x86::rename_operand_in_ctx(&src, sp);
let src = format!("{} {src}", prefix.trim_end());
Some(Candidate {
pattern: self.name(),
start,
consumed: 1,
priority: 50,
stmts: vec![Stmt::Move {
dst,
src,
bytes: ins.original_bytes.clone(),
}],
})
}
}