wasmtime_asm_macros/lib.rs
1//! This crate defines a macro named `asm_func!` which is suitable for
2//! generating a single `global_asm!`-defined function.
3//!
4//! This macro takes care of platform-specific directives to get the symbol
5//! attributes correct (e.g. ELF symbols get a size and are flagged as a
6//! function) and additionally handles visibility across platforms. All symbols
7//! should be visible to Rust but not visible externally outside of a `*.so`.
8
9cfg_if::cfg_if! {
10 if #[cfg(target_os = "macos")] {
11 #[macro_export]
12 macro_rules! asm_func {
13 ($name:expr, $body:expr $(, $($args:tt)*)?) => {
14 std::arch::global_asm!(
15 concat!(
16 ".p2align 4\n",
17 ".private_extern _", $name, "\n",
18 ".global _", $name, "\n",
19 "_", $name, ":\n",
20 $body,
21 ),
22 $($($args)*)?
23 );
24 };
25 }
26 } else if #[cfg(target_os = "windows")] {
27 #[macro_export]
28 macro_rules! asm_func {
29 ($name:expr, $body:expr $(, $($args:tt)*)?) => {
30 std::arch::global_asm!(
31 concat!(
32 ".def ", $name, "\n",
33 ".scl 2\n",
34 ".type 32\n",
35 ".endef\n",
36 ".global ", $name, "\n",
37 ".p2align 4\n",
38 $name, ":\n",
39 $body
40 ),
41 $($($args)*)?
42 );
43 };
44 }
45 } else {
46 // Note that for now this "else" clause just assumes that everything
47 // other than macOS is ELF and has the various directives here for
48 // that.
49 cfg_if::cfg_if! {
50 if #[cfg(target_arch = "arm")] {
51 #[macro_export]
52 macro_rules! elf_func_type_header {
53 ($name:tt) => (concat!(".type ", $name, ",%function\n"))
54 }
55 } else {
56 #[macro_export]
57 macro_rules! elf_func_type_header {
58 ($name:tt) => (concat!(".type ", $name, ",@function\n"))
59 }
60 }
61 }
62
63 #[macro_export]
64 macro_rules! asm_func {
65 ($name:expr, $body:expr $(, $($args:tt)*)?) => {
66 std::arch::global_asm!(
67 concat!(
68 ".p2align 4\n",
69 ".hidden ", $name, "\n",
70 ".global ", $name, "\n",
71 $crate::elf_func_type_header!($name),
72 $name, ":\n",
73 $body,
74 ".size ", $name, ",.-", $name,
75 )
76 $(, $($args)*)?
77 );
78 };
79 }
80 }
81}