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