generic_simd_macros/
lib.rs1extern crate proc_macro;
2use proc_macro::TokenStream;
3use quote::quote;
4use syn::{parse_macro_input, Ident, ItemFn};
5
6#[proc_macro_attribute]
7pub fn dispatch(args: TokenStream, input: TokenStream) -> TokenStream {
8 let ItemFn {
9 attrs,
10 vis,
11 sig,
12 block,
13 } = parse_macro_input!(input as ItemFn);
14 let feature = parse_macro_input!(args as Ident);
15
16 let build_fn = |wasm| {
17 let nightly = cfg!(feature = "nightly");
18 let clone_wasm = if nightly && wasm {
19 Some(quote! { #[clone(target = "wasm32+simd128")] })
20 } else {
21 None
22 };
23 let clone_arm = if nightly {
24 Some(quote! { #[clone(target = "aarch64+neon")] })
25 } else {
26 None
27 };
28 quote! {
29 #[generic_simd::multiversion::multiversion]
30 #[clone(target = "[x86|x86_64]+avx")]
31 #[clone(target = "[x86|x86_64]+sse4.1")]
32 #clone_wasm
33 #clone_arm
34 #[crate_path(path = "generic_simd::multiversion")]
35 #(#attrs)*
36 #vis
37 #sig
38 {
39 #[target_cfg(target = "[x86|x86_64]+sse4.1")]
40 let #feature = unsafe { <generic_simd::arch::x86::Sse as generic_simd::arch::Token>::new_unchecked() };
41
42 #[target_cfg(target = "[x86|x86_64]+avx")]
43 let #feature = unsafe { <generic_simd::arch::x86::Avx as generic_simd::arch::Token>::new_unchecked() };
44
45 #[target_cfg(target = "wasm32+simd128")]
46 let #feature = unsafe { <generic_simd::arch::wasm::Simd128 as generic_simd::arch::Token>::new_unchecked() };
47
48 #[target_cfg(target = "[arm|aarch64]+neon")]
49 let #feature = unsafe { <generic_simd::arch::arm::Neon as generic_simd::arch::Token>::new_unchecked() };
50
51 #[target_cfg(not(any(
52 target = "[x86|x86_64]+sse4.1",
53 target = "[x86|x86_64]+avx",
54 target = "[arm|aarch64]+neon",
55 target = "wasm32+simd128",
56 )))]
57 let #feature = <generic_simd::arch::generic::Generic as generic_simd::arch::Token>::new().unwrap();
58
59 #block
60 }
61 }
62 };
63 let normal = build_fn(false);
64 let with_wasm = build_fn(true);
65 let output = quote! {
66 #[cfg(all(target_arch = "wasm32", target_feature = "simd128"))]
67 #with_wasm
68
69 #[cfg(not(all(target_arch = "wasm32", target_feature = "simd128"),))]
70 #normal
71 };
72 output.into()
73}