arch_ops/x86/
printer.rs

1use super::{
2    insn::{ModRM, X86Instruction, X86Mode},
3    X86RegisterClass,
4};
5use core::ops::{Deref, DerefMut};
6
7#[derive(Copy, Clone, Debug, Hash, PartialEq, Eq)]
8pub enum Syntax {
9    Intel,
10    Att(bool),
11}
12
13pub struct InsnPrinter<W> {
14    syntax: Syntax,
15    mode: X86Mode,
16    writer: W,
17}
18
19impl<W> InsnPrinter<W> {
20    pub const fn new(writer: W, mode: X86Mode, syntax: Syntax) -> Self {
21        Self {
22            writer,
23            mode,
24            syntax,
25        }
26    }
27
28    pub fn into_inner(self) -> W {
29        self.writer
30    }
31
32    pub fn set_mode(&mut self, mode: X86Mode) {
33        self.mode = mode;
34    }
35
36    pub fn mode(&self) -> X86Mode {
37        self.mode
38    }
39
40    pub fn set_syntax(&mut self, syntax: Syntax) {
41        self.syntax = syntax
42    }
43
44    pub fn syntax(&self) -> Syntax {
45        self.syntax
46    }
47}
48
49impl<W> Deref for InsnPrinter<W> {
50    type Target = W;
51    fn deref(&self) -> &W {
52        &self.writer
53    }
54}
55
56impl<W> DerefMut for InsnPrinter<W> {
57    fn deref_mut(&mut self) -> &mut W {
58        &mut self.writer
59    }
60}
61
62impl<W: core::fmt::Write> InsnPrinter<W> {
63    pub fn write_insn(&mut self, insn: &X86Instruction) -> core::fmt::Result {
64        let mode = insn.mode_override().unwrap_or(self.mode);
65
66        match self.syntax {
67            Syntax::Intel => {
68                let mut addr_mode = mode.largest_gpr();
69                for op in insn.operands() {
70                    match op {
71                        super::insn::X86Operand::ModRM(modrm)
72                        | super::insn::X86Operand::FarModRM { modrm, .. } => match modrm {
73                            ModRM::Indirect { mode, .. }
74                            | ModRM::IndirectDisp8 { mode, .. }
75                            | ModRM::IndirectDisp32 { mode, .. } => match mode {
76                                super::insn::ModRMRegOrSib::Reg(r) => addr_mode = r.class(),
77                                super::insn::ModRMRegOrSib::Abs(_) => todo!(),
78                                super::insn::ModRMRegOrSib::RipRel(_) => todo!(),
79                                super::insn::ModRMRegOrSib::Sib { base, .. } => {
80                                    addr_mode = base.class()
81                                }
82                                super::insn::ModRMRegOrSib::Index16 { .. } => {
83                                    addr_mode = X86RegisterClass::Word
84                                }
85                            },
86                            _ => {}
87                        },
88                        _ => {}
89                    }
90                }
91
92                if addr_mode != mode.largest_gpr() {
93                    self.writer
94                        .write_fmt(format_args!("addr{} ", addr_mode.size(mode) * 8))?;
95                }
96                self.writer.write_fmt(format_args!("{} ", insn.opcode()))?;
97            }
98            Syntax::Att(_) => todo!("att_syntax"),
99        }
100        Ok(())
101    }
102}