use crate::arch::x86::{DecodedInsn, Mnemonic, format_intel};
use crate::ast::Stmt;
use super::{Candidate, Pattern, PatternCtx};
pub struct Unary;
impl Pattern for Unary {
fn name(&self) -> &'static str {
"unary"
}
fn tentative(
&self,
ctx: &PatternCtx,
insns: &[DecodedInsn],
start: usize,
) -> Option<Candidate> {
let ins = insns.get(start)?;
let (prefix, render): (&str, fn(&str) -> String) = match ins.iced.mnemonic() {
Mnemonic::Inc => ("inc ", |d| format!("{d} + 1")),
Mnemonic::Dec => ("dec ", |d| format!("{d} - 1")),
Mnemonic::Neg => ("neg ", |d| format!("-{d}")),
Mnemonic::Not => ("not ", |d| format!("~{d}")),
_ => return None,
};
let full = format_intel(&ins.iced);
let dst_raw = full.strip_prefix(prefix)?.trim().to_string();
if dst_raw.is_empty() {
return None;
}
let sp = ctx.sp_delta_at.get(&ins.iced.ip()).copied();
let dst = crate::arch::x86::rename_operand_in_ctx(&dst_raw, sp);
let src = render(&dst);
Some(Candidate {
pattern: self.name(),
start,
consumed: 1,
priority: 50,
stmts: vec![Stmt::Move {
dst,
src,
bytes: ins.original_bytes.clone(),
}],
})
}
}