archmage/lib.rs
1//! # archmage
2//!
3//! > Safely invoke your intrinsic power, using the tokens granted to you by the CPU.
4//! > Cast primitive magics faster than any mage alive.
5//!
6//! archmage provides capability tokens that prove CPU feature availability at runtime,
7//! making raw SIMD intrinsics safe to call via the `#[arcane]` macro.
8//!
9//! ## Quick Example
10//!
11//! ```rust,ignore
12//! use archmage::{Desktop64, Has256BitSimd, SimdToken, arcane};
13//! use std::arch::x86_64::*;
14//!
15//! #[arcane]
16//! fn multiply_add(_token: impl Has256BitSimd, a: &[f32; 8], b: &[f32; 8]) -> [f32; 8] {
17//! // safe_unaligned_simd calls are SAFE inside #[arcane] - no unsafe needed!
18//! let va = safe_unaligned_simd::x86_64::_mm256_loadu_ps(a);
19//! let vb = safe_unaligned_simd::x86_64::_mm256_loadu_ps(b);
20//!
21//! // Value-based intrinsics are also SAFE inside #[arcane]!
22//! let result = _mm256_add_ps(va, vb);
23//! let result = _mm256_mul_ps(result, result);
24//!
25//! let mut out = [0.0f32; 8];
26//! safe_unaligned_simd::x86_64::_mm256_storeu_ps(&mut out, result);
27//! out
28//! }
29//!
30//! fn main() {
31//! // Desktop64: AVX2 + FMA + BMI2 (Haswell 2013+, Zen 1+)
32//! // CPUID check elided if compiled with -C target-cpu=native
33//! if let Some(token) = Desktop64::summon() {
34//! let result = multiply_add(token, &[1.0; 8], &[2.0; 8]);
35//! }
36//! }
37//! ```
38//!
39//! ## How It Works
40//!
41//! **Capability Tokens** are zero-sized proof types created via `summon()`, which
42//! checks CPUID at runtime (elided if compiled with target features enabled).
43//!
44//! **The `#[arcane]` macro** generates an inner function with `#[target_feature]`,
45//! making intrinsics safe inside. The token parameter proves CPU support was verified.
46//!
47//! **Generic bounds** like `impl Has256BitSimd` let functions accept any token that
48//! provides 256-bit SIMD (e.g., `X64V3Token`, `Desktop64`, `X64V4Token`).
49//!
50//! ## Feature Flags
51//!
52//! - `std` (default): Enable std library support
53//! - `macros` (default): Enable `#[arcane]` attribute macro (alias: `#[simd_fn]`)
54//! - `avx512`: AVX-512 token support
55
56#![cfg_attr(not(feature = "std"), no_std)]
57#![cfg_attr(docsrs, feature(doc_cfg))]
58#![deny(unsafe_op_in_unsafe_fn)]
59#![warn(missing_docs)]
60
61#[cfg(feature = "std")]
62extern crate std;
63
64extern crate alloc;
65
66// Re-export arcane macro (and simd_fn alias) from archmage-macros
67#[cfg(feature = "macros")]
68#[cfg_attr(docsrs, doc(cfg(feature = "macros")))]
69pub use archmage_macros::{arcane, multiwidth, simd_fn};
70
71// Optimized feature detection
72#[cfg(any(target_arch = "x86_64", target_arch = "x86", target_arch = "aarch64"))]
73pub mod detect;
74
75// Core token types and traits
76pub mod tokens;
77
78// SIMD types moved to magetypes crate
79// Use `magetypes::simd` for f32x8, i32x4, etc.
80
81// ============================================================================
82// Re-exports at crate root for convenience
83// ============================================================================
84
85// Core trait
86pub use tokens::SimdToken;
87
88// Width marker traits
89pub use tokens::{Has128BitSimd, Has256BitSimd, Has512BitSimd};
90
91// x86 tier marker traits (based on LLVM x86-64 microarchitecture levels)
92pub use tokens::HasX64V2;
93#[cfg(feature = "avx512")]
94pub use tokens::HasX64V4;
95
96// AArch64 tier marker traits
97pub use tokens::{HasNeon, HasNeonAes, HasNeonSha3};
98
99// All tokens available on all architectures (summon() returns None on wrong arch)
100pub use tokens::{
101 // ARM tokens
102 Arm64,
103 // x86 tier tokens
104 Avx2FmaToken,
105 Desktop64,
106 NeonAesToken,
107 NeonCrcToken,
108 NeonSha3Token,
109 NeonToken,
110 // WASM tokens
111 Simd128Token,
112 X64V2Token,
113 X64V3Token,
114};
115
116// AVX-512 tokens (requires "avx512" feature)
117#[cfg(feature = "avx512")]
118pub use tokens::{Avx512Fp16Token, Avx512ModernToken, Avx512Token, Server64, X64V4Token};