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}