use crate::arch::x86::{DecodedInsn, Mnemonic, format_intel};
use crate::ast::Stmt;
use super::{Candidate, Pattern, PatternCtx};
pub struct Arith;
impl Pattern for Arith {
fn name(&self) -> &'static str {
"arith"
}
fn tentative(
&self,
ctx: &PatternCtx,
insns: &[DecodedInsn],
start: usize,
) -> Option<Candidate> {
let ins = insns.get(start)?;
let (prefix, op) = match ins.iced.mnemonic() {
Mnemonic::Add => ("add ", "+"),
Mnemonic::Sub => ("sub ", "-"),
Mnemonic::And => ("and ", "&"),
Mnemonic::Or => ("or ", "|"),
Mnemonic::Xor => ("xor ", "^"),
Mnemonic::Shl => ("shl ", "<<"),
Mnemonic::Shr => ("shr ", ">>"),
Mnemonic::Sar => ("sar ", ">>"), Mnemonic::Rol => ("rol ", "<<<"),
Mnemonic::Ror => ("ror ", ">>>"),
_ => return None,
};
let (dst_raw, src_raw) = 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_raw, sp);
let src = crate::arch::x86::rename_operand_in_ctx(&src_raw, sp);
let new_src = format!("{dst} {op} {src}");
Some(Candidate {
pattern: self.name(),
start,
consumed: 1,
priority: 40,
stmts: vec![Stmt::Move {
dst,
src: new_src,
bytes: ins.original_bytes.clone(),
}],
})
}
}