1use syn::parse;
2use proc_macro_error2::emit_error;
3
4use crate::State;
5
6use std::fmt::Debug;
7
8pub mod x64;
9pub mod aarch64;
10pub mod riscv;
11
12pub(crate) trait Arch : Debug + Send {
13 fn set_features(&mut self, features: &[syn::Ident]);
16 fn default_align(&self) -> u8;
18 fn compile_instruction(&self, state: &mut State, input: parse::ParseStream) -> parse::Result<()>;
21}
22
23#[derive(Clone, Debug)]
24pub struct DummyArch {}
25
26impl DummyArch {
27 fn new() -> DummyArch {
28 DummyArch{}
29 }
30}
31
32impl Arch for DummyArch {
33 fn set_features(&mut self, features: &[syn::Ident]) {
34 if let Some(feature) = features.first() {
35 emit_error!(feature, "Cannot set features when the assembling architecture is undefined. Define it using a .arch directive");
36 }
37 }
38
39 fn default_align(&self) -> u8 {
40 0
41 }
42
43 fn compile_instruction(&self, _state: &mut State, input: parse::ParseStream) -> parse::Result<()> {
44 emit_error!(input.cursor().span(), "Current assembling architecture is undefined. Define it using a .arch directive");
45 Ok(())
46 }
47}
48
49pub(crate) fn from_str(s: &str) -> Option<Box<dyn Arch>> {
50 match s {
51 "x64" => Some(Box::new(x64::Archx64::default())),
52 "x86" => Some(Box::new(x64::Archx86::default())),
53 "aarch64" => Some(Box::new(aarch64::ArchAarch64::default())),
54 "riscv64i" | "riscv64" => Some(Box::new(riscv::ArchRiscV64I::default())),
55 "riscv64e" => Some(Box::new(riscv::ArchRiscV64E::default())),
56 "riscv32i" | "riscv32" => Some(Box::new(riscv::ArchRiscV32I::default())),
57 "riscv32e" => Some(Box::new(riscv::ArchRiscV32E::default())),
58 "unknown" => Some(Box::new(DummyArch::new())),
59 _ => None
60 }
61}
62
63#[cfg(target_arch="x86_64")]
64pub const CURRENT_ARCH: &str = "x64";
65#[cfg(target_arch="x86")]
66pub const CURRENT_ARCH: &str = "x86";
67#[cfg(target_arch="aarch64")]
68pub const CURRENT_ARCH: &str = "aarch64";
69#[cfg(target_arch="riscv64")]
72pub const CURRENT_ARCH: &str = "riscv64i";
73#[cfg(target_arch="riscv32")]
74pub const CURRENT_ARCH: &str = "riscv32i";
75#[cfg(not(any(
76 target_arch="x86",
77 target_arch="x86_64",
78 target_arch="aarch64",
79 target_arch="riscv64",
80 target_arch="riscv32"
81)))]
82pub const CURRENT_ARCH: &str = "unknown";