dynasm\arch\x64/
mod.rs

1use syn::parse;
2use proc_macro_error2::emit_error;
3
4mod ast;
5mod compiler;
6mod parser;
7mod debug;
8mod x64data;
9
10use crate::State;
11use crate::arch::Arch;
12
13#[cfg(feature = "dynasm_opmap")]
14pub use debug::create_opmap;
15
16#[derive(Debug, Clone, Copy, PartialEq, Eq)]
17pub enum X86Mode {
18    Long,
19    Protected
20}
21
22struct Context<'a, 'b: 'a> {
23    pub state: &'a mut State<'b>,
24    pub mode: X86Mode,
25    pub features: x64data::Features
26}
27
28#[derive(Clone, Debug)]
29pub struct Archx64 {
30    features: x64data::Features
31}
32
33impl Default for Archx64 {
34    fn default() -> Archx64 {
35        Archx64 { features: x64data::Features::all() }
36    }
37}
38
39impl Arch for Archx64 {
40    fn set_features(&mut self, features: &[syn::Ident]) {
41        let mut new_features = x64data::Features::empty();
42        for ident in features {
43            new_features |= match x64data::Features::from_str(&ident.to_string()) {
44                Some(feature) => feature,
45                None => {
46                    emit_error!(ident, "Architecture x64 does not support feature '{}'", ident);
47                    continue;
48                }
49            }
50        }
51        self.features = new_features;
52    }
53
54    fn default_align(&self) -> u8 {
55        0x90
56    }
57
58    fn compile_instruction(&self, state: &mut State, input: parse::ParseStream) -> parse::Result<()> {
59        let mut ctx = Context {
60            state,
61            mode: X86Mode::Long,
62            features: self.features
63        };
64        let (instruction, args) = parser::parse_instruction(&mut ctx, input)?;
65        let span = instruction.span;
66
67        if let Err(Some(e)) = compiler::compile_instruction(&mut ctx, instruction, args) {
68            emit_error!(span, e);
69        }
70        Ok(())
71    }
72}
73
74#[derive(Clone, Debug)]
75pub struct Archx86 {
76    features: x64data::Features
77}
78
79impl Default for Archx86 {
80    fn default() -> Archx86 {
81        Archx86 { features: x64data::Features::all() }
82    }
83}
84
85impl Arch for Archx86 {
86    fn set_features(&mut self, features: &[syn::Ident]) {
87        let mut new_features = x64data::Features::empty();
88        for ident in features {
89            new_features |= match x64data::Features::from_str(&ident.to_string()) {
90                Some(feature) => feature,
91                None => {
92                    emit_error!(ident, "Architecture x86 does not support feature '{}'", ident);
93                    continue;
94                }
95            }
96        }
97        self.features = new_features;
98    }
99
100    fn default_align(&self) -> u8 {
101        0x90
102    }
103
104    fn compile_instruction(&self, state: &mut State, input: parse::ParseStream) -> parse::Result<()> {
105        let mut ctx = Context {
106            state,
107            mode: X86Mode::Protected,
108            features: self.features
109        };
110        let (instruction, args) = parser::parse_instruction(&mut ctx, input)?;
111        let span = instruction.span;
112
113        if let Err(Some(e)) = compiler::compile_instruction(&mut ctx, instruction, args) {
114            emit_error!(span, e);
115        }
116        Ok(())
117    }
118}