#[arcane]macros only.Expand description
Mark a function as an arcane SIMD function.
This macro generates a safe wrapper around a #[target_feature] function.
The token parameter type determines which CPU features are enabled.
§Expansion Modes
§Sibling (default)
Generates two functions at the same scope: a safe #[target_feature] sibling
and a safe wrapper. self/Self work naturally since both functions share scope.
Compatible with #![forbid(unsafe_code)].
#[arcane]
fn process(token: X64V3Token, data: &[f32; 8]) -> [f32; 8] { /* body */ }
// Expands to (x86_64 only):
#[cfg(target_arch = "x86_64")]
#[doc(hidden)]
#[target_feature(enable = "avx2,fma,...")]
fn __arcane_process(token: X64V3Token, data: &[f32; 8]) -> [f32; 8] { /* body */ }
#[cfg(target_arch = "x86_64")]
fn process(token: X64V3Token, data: &[f32; 8]) -> [f32; 8] {
unsafe { __arcane_process(token, data) }
}Methods work naturally:
impl MyType {
#[arcane]
fn compute(&self, token: X64V3Token) -> f32 {
self.data.iter().sum() // self/Self just work!
}
}§Nested (nested or _self = Type)
Generates a nested inner function inside the original. Required for trait impls
(where sibling functions would fail) and when _self = Type is used.
impl SimdOps for MyType {
#[arcane(_self = MyType)]
fn compute(&self, token: X64V3Token) -> Self {
// Use _self instead of self, Self replaced with MyType
_self.data.iter().sum()
}
}§Cross-Architecture Behavior
Default (cfg-out): On the wrong architecture, the function is not emitted at all — no stub, no dead code. Code that references it must be cfg-gated.
With stub: Generates an unreachable!() stub on wrong architectures.
Use when cross-arch dispatch references the function without cfg guards.
#[arcane(stub)] // generates stub on wrong arch
fn process_neon(token: NeonToken, data: &[f32]) -> f32 { ... }incant! is unaffected — it already cfg-gates dispatch calls by architecture.
§Token Parameter Forms
// Concrete token
#[arcane]
fn process(token: X64V3Token, data: &[f32; 8]) -> [f32; 8] { ... }
// impl Trait bound
#[arcane]
fn process(token: impl HasX64V2, data: &[f32; 8]) -> [f32; 8] { ... }
// Generic with inline or where-clause bounds
#[arcane]
fn process<T: HasX64V2>(token: T, data: &[f32; 8]) -> [f32; 8] { ... }
// Wildcard
#[arcane]
fn process(_: X64V3Token, data: &[f32; 8]) -> [f32; 8] { ... }§Options
| Option | Effect |
|---|---|
stub | Generate unreachable!() stub on wrong architecture |
nested | Use nested inner function instead of sibling |
_self = Type | Implies nested, transforms self receiver, replaces Self |
inline_always | Use #[inline(always)] (requires nightly) |
import_intrinsics | Auto-import archmage::intrinsics::{arch}::* (includes safe memory ops) |
import_magetypes | Auto-import magetypes::simd::{ns}::* and magetypes::simd::backends::* |
§Auto-Imports
import_intrinsics and import_magetypes inject use statements into the
function body, eliminating boilerplate. The macro derives the architecture and
namespace from the token type:
// Without auto-imports — lots of boilerplate:
use std::arch::x86_64::*;
use magetypes::simd::v3::*;
#[arcane]
fn process(token: X64V3Token, data: &[f32; 8]) -> f32 {
let v = f32x8::load(token, data);
let zero = _mm256_setzero_ps();
// ...
}
// With auto-imports — clean:
#[arcane(import_intrinsics, import_magetypes)]
fn process(token: X64V3Token, data: &[f32; 8]) -> f32 {
let v = f32x8::load(token, data);
let zero = _mm256_setzero_ps();
// ...
}The namespace mapping is token-driven:
| Token | import_intrinsics | import_magetypes |
|---|---|---|
X64V1..V3Token | archmage::intrinsics::x86_64::* | magetypes::simd::v3::* |
X64V4Token | archmage::intrinsics::x86_64::* | magetypes::simd::v4::* |
X64V4xToken | archmage::intrinsics::x86_64::* | magetypes::simd::v4x::* |
NeonToken / ARM | archmage::intrinsics::aarch64::* | magetypes::simd::neon::* |
Wasm128Token | archmage::intrinsics::wasm32::* | magetypes::simd::wasm128::* |
Works with concrete tokens, impl Trait bounds, and generic parameters.
§Supported Tokens
- x86_64:
X64V2Token,X64V3Token/Desktop64,X64V4Token/Avx512Token/Server64,X64V4xToken,Avx512Fp16Token,X64CryptoToken,X64V3CryptoToken - ARM:
NeonToken/Arm64,Arm64V2Token,Arm64V3Token,NeonAesToken,NeonSha3Token,NeonCrcToken - WASM:
Wasm128Token
§Supported Trait Bounds
HasX64V2, HasX64V4, HasNeon, HasNeonAes, HasNeonSha3, HasArm64V2, HasArm64V3
#![feature(target_feature_inline_always)]
#[arcane(inline_always)]
fn fast_kernel(token: Avx2Token, data: &mut [f32]) {
// Inner function will use #[inline(always)]
}