Skip to main content

core/stdarch/crates/core_arch/src/
mod.rs

1//! `core_arch`
2
3#![allow(unknown_lints, unnecessary_transmutes)]
4
5#[macro_use]
6mod macros;
7
8#[cfg(test)]
9mod test;
10#[cfg(test)]
11use test::assert_eq_const;
12
13#[cfg(any(target_arch = "riscv32", target_arch = "riscv64", doc))]
14mod riscv_shared;
15
16#[cfg(any(
17    target_arch = "arm",
18    target_arch = "aarch64",
19    target_arch = "arm64ec",
20    doc
21))]
22mod arm_shared;
23
24#[cfg(any(target_arch = "loongarch32", target_arch = "loongarch64", doc))]
25mod loongarch_shared;
26
27mod simd;
28
29#[doc = "SIMD and vendor intrinsics module.\n\nThis module is intended to be the gateway to architecture-specific\nintrinsic functions, typically related to SIMD (but not always!). Each\narchitecture that Rust compiles to may contain a submodule here, which\nmeans that this is not a portable module! If you\'re writing a portable\nlibrary take care when using these APIs!\n\nUnder this module you\'ll find an architecture-named module, such as\n`x86_64`. Each `#[cfg(target_arch)]` that Rust can compile to may have a\nmodule entry here, only present on that particular target. For example the\n`i686-pc-windows-msvc` target will have an `x86` module here, whereas\n`x86_64-pc-windows-msvc` has `x86_64`.\n\n[rfc]: https://github.com/rust-lang/rfcs/pull/2325\n[tracked]: https://github.com/rust-lang/rust/issues/48556\n\n# Overview\n\nThis module exposes vendor-specific intrinsics that typically correspond to\na single machine instruction. These intrinsics are not portable: their\navailability is architecture-dependent, and not all machines of that\narchitecture might provide the intrinsic.\n\nThe `arch` module is intended to be a low-level implementation detail for\nhigher-level APIs. Using it correctly can be quite tricky as you need to\nensure at least a few guarantees are upheld:\n\n* The correct architecture\'s module is used. For example the `arm` module\n  isn\'t available on the `x86_64-unknown-linux-gnu` target. This is\n  typically done by ensuring that `#[cfg]` is used appropriately when using\n  this module.\n* The CPU the program is currently running on supports the function being\n  called. For example it is unsafe to call an AVX2 function on a CPU that\n  doesn\'t actually support AVX2.\n\nAs a result of the latter of these guarantees all intrinsics in this module\nare `unsafe` and extra care needs to be taken when calling them!\n\n# CPU Feature Detection\n\nIn order to call these APIs in a safe fashion there\'s a number of\nmechanisms available to ensure that the correct CPU feature is available\nto call an intrinsic. Let\'s consider, for example, the `_mm256_add_epi64`\nintrinsics on the `x86` and `x86_64` architectures. This function requires\nthe AVX2 feature as [documented by Intel][intel-dox] so to correctly call\nthis function we need to (a) guarantee we only call it on `x86`/`x86_64`\nand (b) ensure that the CPU feature is available\n\n[intel-dox]: https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm256_add_epi64&expand=100\n\n## Static CPU Feature Detection\n\nThe first option available to us is to conditionally compile code via the\n`#[cfg]` attribute. CPU features correspond to the `target_feature` cfg\navailable, and can be used like so:\n\n```ignore\n#[cfg(\n    all(\n        any(target_arch = \"x86\", target_arch = \"x86_64\"),\n        target_feature = \"avx2\"\n    )\n)]\nfn foo() {\n    #[cfg(target_arch = \"x86\")]\n    use std::arch::x86::_mm256_add_epi64;\n    #[cfg(target_arch = \"x86_64\")]\n    use std::arch::x86_64::_mm256_add_epi64;\n\n    unsafe {\n        _mm256_add_epi64(...);\n    }\n}\n```\n\nHere we\'re using `#[cfg(target_feature = \"avx2\")]` to conditionally compile\nthis function into our module. This means that if the `avx2` feature is\n*enabled statically* then we\'ll use the `_mm256_add_epi64` function at\nruntime. The `unsafe` block here can be justified through the usage of\n`#[cfg]` to only compile the code in situations where the safety guarantees\nare upheld.\n\nStatically enabling a feature is typically done with the `-C\ntarget-feature` or `-C target-cpu` flags to the compiler. For example if\nyour local CPU supports AVX2 then you can compile the above function with:\n\n```sh\n$ RUSTFLAGS=\'-C target-cpu=native\' cargo build\n```\n\nOr otherwise you can specifically enable just the AVX2 feature:\n\n```sh\n$ RUSTFLAGS=\'-C target-feature=+avx2\' cargo build\n```\n\nNote that when you compile a binary with a particular feature enabled it\'s\nimportant to ensure that you only run the binary on systems which satisfy\nthe required feature set.\n\n## Dynamic CPU Feature Detection\n\nSometimes statically dispatching isn\'t quite what you want. Instead you\nmight want to build a portable binary that runs across a variety of CPUs,\nbut at runtime it selects the most optimized implementation available. This\nallows you to build a \"least common denominator\" binary which has certain\nsections more optimized for different CPUs.\n\nTaking our previous example from before, we\'re going to compile our binary\n*without* AVX2 support, but we\'d like to enable it for just one function.\nWe can do that in a manner like:\n\n```ignore\nfn foo() {\n    #[cfg(any(target_arch = \"x86\", target_arch = \"x86_64\"))]\n    {\n        if is_x86_feature_detected!(\"avx2\") {\n            return unsafe { foo_avx2() };\n        }\n    }\n\n    // fallback implementation without using AVX2\n}\n\n#[cfg(any(target_arch = \"x86\", target_arch = \"x86_64\"))]\n#[target_feature(enable = \"avx2\")]\nunsafe fn foo_avx2() {\n    #[cfg(target_arch = \"x86\")]\n    use std::arch::x86::_mm256_add_epi64;\n    #[cfg(target_arch = \"x86_64\")]\n    use std::arch::x86_64::_mm256_add_epi64;\n\n    unsafe { _mm256_add_epi64(...); }\n}\n```\n\nThere\'s a couple of components in play here, so let\'s go through them in\ndetail!\n\n* First up we notice the `is_x86_feature_detected!` macro. Provided by\n  the standard library, this macro will perform necessary runtime detection\n  to determine whether the CPU the program is running on supports the\n  specified feature. In this case the macro will expand to a boolean\n  expression evaluating to whether the local CPU has the AVX2 feature or\n  not.\n\n  Note that this macro, like the `arch` module, is platform-specific. For\n  example calling `is_x86_feature_detected!(\"avx2\")` on ARM will be a\n  compile time error. To ensure we don\'t hit this error a statement level\n  `#[cfg]` is used to only compile usage of the macro on `x86`/`x86_64`.\n\n* Next up we see our AVX2-enabled function, `foo_avx2`. This function is\n  decorated with the `#[target_feature]` attribute which enables a CPU\n  feature for just this one function. Using a compiler flag like `-C\n  target-feature=+avx2` will enable AVX2 for the entire program, but using\n  an attribute will only enable it for the one function. Usage of the\n  `#[target_feature]` attribute currently requires the function to also be\n  `unsafe`, as we see here. This is because the function can only be\n  correctly called on systems which have the AVX2 (like the intrinsics\n  themselves).\n\nAnd with all that we should have a working program! This program will run\nacross all machines and it\'ll use the optimized AVX2 implementation on\nmachines where support is detected.\n\n# Ergonomics\n\nIt\'s important to note that using the `arch` module is not the easiest\nthing in the world, so if you\'re curious to try it out you may want to\nbrace yourself for some wordiness!\n\nThe primary purpose of this module is to enable stable crates on crates.io\nto build up much more ergonomic abstractions which end up using SIMD under\nthe hood. Over time these abstractions may also move into the standard\nlibrary itself, but for now this module is tasked with providing the bare\nminimum necessary to use vendor intrinsics on stable Rust.\n\n# Other architectures\n\nThis documentation is only for one particular architecture, you can find\nothers at:\n\n* [`x86`]\n* [`x86_64`]\n* [`arm`]\n* [`aarch64`]\n* [`amdgpu`]\n* [`hexagon`]\n* [`riscv32`]\n* [`riscv64`]\n* [`mips`]\n* [`mips64`]\n* [`powerpc`]\n* [`powerpc64`]\n* [`nvptx`]\n* [`wasm32`]\n* [`loongarch32`]\n* [`loongarch64`]\n* [`s390x`]\n\n[`x86`]: ../../core/arch/x86/index.html\n[`x86_64`]: ../../core/arch/x86_64/index.html\n[`arm`]: ../../core/arch/arm/index.html\n[`aarch64`]: ../../core/arch/aarch64/index.html\n[`amdgpu`]: ../../core/arch/amdgpu/index.html\n[`hexagon`]: ../../core/arch/hexagon/index.html\n[`riscv32`]: ../../core/arch/riscv32/index.html\n[`riscv64`]: ../../core/arch/riscv64/index.html\n[`mips`]: ../../core/arch/mips/index.html\n[`mips64`]: ../../core/arch/mips64/index.html\n[`powerpc`]: ../../core/arch/powerpc/index.html\n[`powerpc64`]: ../../core/arch/powerpc64/index.html\n[`nvptx`]: ../../core/arch/nvptx/index.html\n[`wasm32`]: ../../core/arch/wasm32/index.html\n[`loongarch32`]: ../../core/arch/loongarch32/index.html\n[`loongarch64`]: ../../core/arch/loongarch64/index.html\n[`s390x`]: ../../core/arch/s390x/index.html\n\n# Examples\n\nFirst let\'s take a look at not actually using any intrinsics but instead\nusing LLVM\'s auto-vectorization to produce optimized vectorized code for\nAVX2 and also for the default platform.\n\n```rust\nfn main() {\n    let mut dst = [0];\n    add_quickly(&[1], &[2], &mut dst);\n    assert_eq!(dst[0], 3);\n}\n\nfn add_quickly(a: &[u8], b: &[u8], c: &mut [u8]) {\n    #[cfg(any(target_arch = \"x86\", target_arch = \"x86_64\"))]\n    {\n        // Note that this `unsafe` block is safe because we\'re testing\n        // that the `avx2` feature is indeed available on our CPU.\n        if is_x86_feature_detected!(\"avx2\") {\n            return unsafe { add_quickly_avx2(a, b, c) };\n        }\n    }\n\n    add_quickly_fallback(a, b, c)\n}\n\n#[cfg(any(target_arch = \"x86\", target_arch = \"x86_64\"))]\n#[target_feature(enable = \"avx2\")]\nunsafe fn add_quickly_avx2(a: &[u8], b: &[u8], c: &mut [u8]) {\n    add_quickly_fallback(a, b, c) // the function below is inlined here\n}\n\nfn add_quickly_fallback(a: &[u8], b: &[u8], c: &mut [u8]) {\n    for ((a, b), c) in a.iter().zip(b).zip(c) {\n        *c = *a + *b;\n    }\n}\n```\n\nNext up let\'s take a look at an example of manually using intrinsics. Here\nwe\'ll be using SSE4.1 features to implement hex encoding.\n\n```\nfn main() {\n    let mut dst = [0; 32];\n    hex_encode(b\"\\x01\\x02\\x03\", &mut dst);\n    assert_eq!(&dst[..6], b\"010203\");\n\n    let mut src = [0; 16];\n    for i in 0..16 {\n        src[i] = (i + 1) as u8;\n    }\n    hex_encode(&src, &mut dst);\n    assert_eq!(&dst, b\"0102030405060708090a0b0c0d0e0f10\");\n}\n\npub fn hex_encode(src: &[u8], dst: &mut [u8]) {\n    let len = src.len().checked_mul(2).unwrap();\n    assert!(dst.len() >= len);\n\n    #[cfg(any(target_arch = \"x86\", target_arch = \"x86_64\"))]\n    {\n        if is_x86_feature_detected!(\"sse4.1\") {\n            return unsafe { hex_encode_sse41(src, dst) };\n        }\n    }\n\n    hex_encode_fallback(src, dst)\n}\n\n// translated from\n// <https://github.com/Matherunner/bin2hex-sse/blob/master/base16_sse4.cpp>\n#[target_feature(enable = \"sse4.1\")]\n#[cfg(any(target_arch = \"x86\", target_arch = \"x86_64\"))]\nunsafe fn hex_encode_sse41(mut src: &[u8], dst: &mut [u8]) {\n    #[cfg(target_arch = \"x86\")]\n    use std::arch::x86::*;\n    #[cfg(target_arch = \"x86_64\")]\n    use std::arch::x86_64::*;\n\n    unsafe {\n        let ascii_zero = _mm_set1_epi8(b\'0\' as i8);\n        let nines = _mm_set1_epi8(9);\n        let ascii_a = _mm_set1_epi8((b\'a\' - 9 - 1) as i8);\n        let and4bits = _mm_set1_epi8(0xf);\n\n        let mut i = 0_isize;\n        while src.len() >= 16 {\n            let invec = _mm_loadu_si128(src.as_ptr() as *const _);\n\n            let masked1 = _mm_and_si128(invec, and4bits);\n            let masked2 = _mm_and_si128(_mm_srli_epi64(invec, 4), and4bits);\n\n            // return 0xff corresponding to the elements > 9, or 0x00 otherwise\n            let cmpmask1 = _mm_cmpgt_epi8(masked1, nines);\n            let cmpmask2 = _mm_cmpgt_epi8(masked2, nines);\n\n            // add \'0\' or the offset depending on the masks\n            let masked1 = _mm_add_epi8(\n                masked1,\n                _mm_blendv_epi8(ascii_zero, ascii_a, cmpmask1),\n            );\n            let masked2 = _mm_add_epi8(\n                masked2,\n                _mm_blendv_epi8(ascii_zero, ascii_a, cmpmask2),\n            );\n\n            // interleave masked1 and masked2 bytes\n            let res1 = _mm_unpacklo_epi8(masked2, masked1);\n            let res2 = _mm_unpackhi_epi8(masked2, masked1);\n\n            _mm_storeu_si128(dst.as_mut_ptr().offset(i * 2) as *mut _, res1);\n            _mm_storeu_si128(\n                dst.as_mut_ptr().offset(i * 2 + 16) as *mut _,\n                res2,\n            );\n            src = &src[16..];\n            i += 16;\n        }\n\n        let i = i as usize;\n        hex_encode_fallback(src, &mut dst[i * 2..]);\n    }\n}\n\nfn hex_encode_fallback(src: &[u8], dst: &mut [u8]) {\n    fn hex(byte: u8) -> u8 {\n        static TABLE: &[u8] = b\"0123456789abcdef\";\n        TABLE[byte as usize]\n    }\n\n    for (byte, slots) in src.iter().zip(dst.chunks_mut(2)) {\n        slots[0] = hex((*byte >> 4) & 0xf);\n        slots[1] = hex(*byte & 0xf);\n    }\n}\n```\n"include_str!("core_arch_docs.md")]
30#[stable(feature = "simd_arch", since = "1.27.0")]
31pub mod arch {
32    /// Platform-specific intrinsics for the `x86` platform.
33    ///
34    /// See the [module documentation](../index.html) for more details.
35    #[cfg(any(target_arch = "x86", doc))]
36//     #[doc(cfg(target_arch = "x86"))] // commented out for std.noratrieb.dev
37    #[stable(feature = "simd_x86", since = "1.27.0")]
38    pub mod x86 {
39        #[stable(feature = "simd_x86", since = "1.27.0")]
40        pub use crate::core_arch::x86::*;
41    }
42
43    /// Platform-specific intrinsics for the `x86_64` platform.
44    ///
45    /// See the [module documentation](../index.html) for more details.
46    #[cfg(any(target_arch = "x86_64", doc))]
47//     #[doc(cfg(target_arch = "x86_64"))] // commented out for std.noratrieb.dev
48    #[stable(feature = "simd_x86", since = "1.27.0")]
49    pub mod x86_64 {
50        #[stable(feature = "simd_x86", since = "1.27.0")]
51        pub use crate::core_arch::x86::*;
52        #[stable(feature = "simd_x86", since = "1.27.0")]
53        pub use crate::core_arch::x86_64::*;
54    }
55
56    /// Platform-specific intrinsics for the `arm` platform.
57    ///
58    /// See the [module documentation](../index.html) for more details.
59    #[cfg(any(target_arch = "arm", doc))]
60//     #[doc(cfg(target_arch = "arm"))] // commented out for std.noratrieb.dev
61    #[unstable(feature = "stdarch_arm_neon_intrinsics", issue = "111800")]
62    pub mod arm {
63        #[unstable(feature = "stdarch_arm_neon_intrinsics", issue = "111800")]
64        pub use crate::core_arch::arm::*;
65    }
66
67    /// Platform-specific intrinsics for the `aarch64` platform.
68    ///
69    /// See the [module documentation](../index.html) for more details.
70    #[cfg(any(target_arch = "aarch64", target_arch = "arm64ec", doc))]
71//     #[doc(cfg(any(target_arch = "aarch64", target_arch = "arm64ec")))] // commented out for std.noratrieb.dev
72    #[stable(feature = "neon_intrinsics", since = "1.59.0")]
73    pub mod aarch64 {
74        #[stable(feature = "neon_intrinsics", since = "1.59.0")]
75        pub use crate::core_arch::aarch64::*;
76    }
77
78    /// Platform-specific intrinsics for the `riscv32` platform.
79    ///
80    /// See the [module documentation](../index.html) for more details.
81    #[cfg(any(target_arch = "riscv32", doc))]
82//     #[doc(cfg(any(target_arch = "riscv32")))] // commented out for std.noratrieb.dev
83    #[unstable(feature = "riscv_ext_intrinsics", issue = "114544")]
84    pub mod riscv32 {
85        pub use crate::core_arch::riscv_shared::*;
86        pub use crate::core_arch::riscv32::*;
87    }
88
89    /// Platform-specific intrinsics for the `riscv64` platform.
90    ///
91    /// See the [module documentation](../index.html) for more details.
92    #[cfg(any(target_arch = "riscv64", doc))]
93//     #[doc(cfg(any(target_arch = "riscv64")))] // commented out for std.noratrieb.dev
94    #[unstable(feature = "riscv_ext_intrinsics", issue = "114544")]
95    pub mod riscv64 {
96        pub use crate::core_arch::riscv64::*;
97        // RISC-V RV64 supports all RV32 instructions as well in current specifications (2022-01-05).
98        // Module `riscv_shared` includes instructions available under all RISC-V platforms,
99        // i.e. RISC-V RV32 instructions.
100        pub use crate::core_arch::riscv_shared::*;
101    }
102
103    /// Platform-specific intrinsics for the `wasm32` platform.
104    ///
105    /// This module provides intrinsics specific to the WebAssembly
106    /// architecture. Here you'll find intrinsics specific to WebAssembly that
107    /// aren't otherwise surfaced somewhere in a cross-platform abstraction of
108    /// `std`, and you'll also find functions for leveraging WebAssembly
109    /// proposals such as [atomics] and [simd].
110    ///
111    /// Intrinsics in the `wasm32` module are modeled after the WebAssembly
112    /// instructions that they represent. Most functions are named after the
113    /// instruction they intend to correspond to, and the arguments/results
114    /// correspond to the type signature of the instruction itself. Stable
115    /// WebAssembly instructions are [documented online][instrdoc].
116    ///
117    /// [instrdoc]: https://webassembly.github.io/spec/core/valid/instructions.html
118    ///
119    /// If a proposal is not yet stable in WebAssembly itself then the functions
120    /// within this function may be unstable and require the nightly channel of
121    /// Rust to use. As the proposal itself stabilizes the intrinsics in this
122    /// module should stabilize as well.
123    ///
124    /// [atomics]: https://github.com/webassembly/threads
125    /// [simd]: https://github.com/webassembly/simd
126    ///
127    /// See the [module documentation](../index.html) for general information
128    /// about the `arch` module and platform intrinsics.
129    ///
130    /// ## Atomics
131    ///
132    /// The [threads proposal][atomics] for WebAssembly adds a number of
133    /// instructions for dealing with multithreaded programs. Most instructions
134    /// added in the [atomics] proposal are exposed in Rust through the
135    /// `std::sync::atomic` module. Some instructions, however, don't have
136    /// direct equivalents in Rust so they're exposed here instead.
137    ///
138    /// Note that the instructions added in the [atomics] proposal can work in
139    /// either a context with a shared wasm memory and without. These intrinsics
140    /// are always available in the standard library, but you likely won't be
141    /// able to use them too productively unless you recompile the standard
142    /// library (and all your code) with `-Ctarget-feature=+atomics`.
143    ///
144    /// It's also worth pointing out that multi-threaded WebAssembly and its
145    /// story in Rust is still in a somewhat "early days" phase as of the time
146    /// of this writing. Pieces should mostly work but it generally requires a
147    /// good deal of manual setup. At this time it's not as simple as "just call
148    /// `std::thread::spawn`", but it will hopefully get there one day!
149    ///
150    /// ## SIMD
151    ///
152    /// The [simd proposal][simd] for WebAssembly added a new `v128` type for a
153    /// 128-bit SIMD register. It also added a large array of instructions to
154    /// operate on the `v128` type to perform data processing. Using SIMD on
155    /// wasm is intended to be similar to as you would on `x86_64`, for example.
156    /// You'd write a function such as:
157    ///
158    /// ```rust,ignore
159    /// #[cfg(target_arch = "wasm32")]
160    /// #[target_feature(enable = "simd128")]
161    /// unsafe fn uses_simd() {
162    ///     use std::arch::wasm32::*;
163    ///     // ...
164    /// }
165    /// ```
166    ///
167    /// Unlike `x86_64`, however, WebAssembly does not currently have dynamic
168    /// detection at runtime as to whether SIMD is supported (this is one of the
169    /// motivators for the [conditional sections][condsections] and [feature
170    /// detection] proposals, but that is still pretty early days). This means
171    /// that your binary will either have SIMD and can only run on engines
172    /// which support SIMD, or it will not have SIMD at all. For compatibility
173    /// the standard library itself does not use any SIMD internally.
174    /// Determining how best to ship your WebAssembly binary with SIMD is
175    /// largely left up to you as it can be pretty nuanced depending on
176    /// your situation.
177    ///
178    /// [condsections]: https://github.com/webassembly/conditional-sections
179    /// [feature detection]: https://github.com/WebAssembly/feature-detection
180    ///
181    /// To enable SIMD support at compile time you need to do one of two things:
182    ///
183    /// * First you can annotate functions with `#[target_feature(enable =
184    ///   "simd128")]`. This causes just that one function to have SIMD support
185    ///   available to it, and intrinsics will get inlined as usual in this
186    ///   situation.
187    ///
188    /// * Second you can compile your program with `-Ctarget-feature=+simd128`.
189    ///   This compilation flag blanket enables SIMD support for your entire
190    ///   compilation. Note that this does not include the standard library
191    ///   unless you [recompile the standard library][buildstd].
192    ///
193    /// [buildstd]: https://doc.rust-lang.org/nightly/cargo/reference/unstable.html#build-std
194    ///
195    /// If you enable SIMD via either of these routes then you'll have a
196    /// WebAssembly binary that uses SIMD instructions, and you'll need to ship
197    /// that accordingly. Also note that if you call SIMD intrinsics but don't
198    /// enable SIMD via either of these mechanisms, you'll still have SIMD
199    /// generated in your program. This means to generate a binary without SIMD
200    /// you'll need to avoid both options above plus calling into any intrinsics
201    /// in this module.
202    #[cfg(any(target_arch = "wasm32", doc))]
203//     #[doc(cfg(target_arch = "wasm32"))] // commented out for std.noratrieb.dev
204    #[stable(feature = "simd_wasm32", since = "1.33.0")]
205    pub mod wasm32 {
206        #[stable(feature = "simd_wasm32", since = "1.33.0")]
207        pub use crate::core_arch::wasm32::*;
208    }
209
210    /// Platform-specific intrinsics for the `wasm64` platform.
211    ///
212    /// See the [module documentation](../index.html) for more details.
213    #[cfg(any(target_arch = "wasm64", doc))]
214//     #[doc(cfg(target_arch = "wasm64"))] // commented out for std.noratrieb.dev
215    #[unstable(feature = "simd_wasm64", issue = "90599")]
216    pub mod wasm64 {
217        #[unstable(feature = "simd_wasm64", issue = "90599")]
218        pub use crate::core_arch::wasm32::*;
219    }
220
221    /// Platform-specific intrinsics for the `wasm` target family.
222    ///
223    /// See the [module documentation](../index.html) for more details.
224    #[cfg(any(target_family = "wasm", doc))]
225//     #[doc(cfg(target_family = "wasm"))] // commented out for std.noratrieb.dev
226    #[unstable(feature = "simd_wasm64", issue = "90599")]
227    pub mod wasm {
228        #[unstable(feature = "simd_wasm64", issue = "90599")]
229        pub use crate::core_arch::wasm32::*;
230    }
231
232    /// Platform-specific intrinsics for the `mips` platform.
233    ///
234    /// See the [module documentation](../index.html) for more details.
235    #[cfg(any(target_arch = "mips", doc))]
236//     #[doc(cfg(target_arch = "mips"))] // commented out for std.noratrieb.dev
237    #[unstable(feature = "stdarch_mips", issue = "111198")]
238    pub mod mips {
239        pub use crate::core_arch::mips::*;
240    }
241
242    /// Platform-specific intrinsics for the `mips64` platform.
243    ///
244    /// See the [module documentation](../index.html) for more details.
245    #[cfg(any(target_arch = "mips64", doc))]
246//     #[doc(cfg(target_arch = "mips64"))] // commented out for std.noratrieb.dev
247    #[unstable(feature = "stdarch_mips", issue = "111198")]
248    pub mod mips64 {
249        pub use crate::core_arch::mips::*;
250    }
251
252    /// Platform-specific intrinsics for the `PowerPC` platform.
253    ///
254    /// See the [module documentation](../index.html) for more details.
255    #[cfg(any(target_arch = "powerpc", doc))]
256//     #[doc(cfg(target_arch = "powerpc"))] // commented out for std.noratrieb.dev
257    #[unstable(feature = "stdarch_powerpc", issue = "111145")]
258    pub mod powerpc {
259        pub use crate::core_arch::powerpc::*;
260    }
261
262    /// Platform-specific intrinsics for the `PowerPC64` platform.
263    ///
264    /// See the [module documentation](../index.html) for more details.
265    #[cfg(any(target_arch = "powerpc64", doc))]
266//     #[doc(cfg(target_arch = "powerpc64"))] // commented out for std.noratrieb.dev
267    #[unstable(feature = "stdarch_powerpc", issue = "111145")]
268    pub mod powerpc64 {
269        pub use crate::core_arch::powerpc64::*;
270    }
271
272    /// Platform-specific intrinsics for the `NVPTX` platform.
273    ///
274    /// See the [module documentation](../index.html) for more details.
275    #[cfg(any(target_arch = "nvptx64", doc))]
276//     #[doc(cfg(target_arch = "nvptx64"))] // commented out for std.noratrieb.dev
277    #[unstable(feature = "stdarch_nvptx", issue = "111199")]
278    pub mod nvptx {
279        pub use crate::core_arch::nvptx::*;
280    }
281
282    /// Platform-specific intrinsics for the `amdgpu` platform.
283    ///
284    /// See the [module documentation](../index.html) for more details.
285    #[cfg(any(target_arch = "amdgpu", doc))]
286//     #[doc(cfg(target_arch = "amdgpu"))] // commented out for std.noratrieb.dev
287    #[unstable(feature = "stdarch_amdgpu", issue = "149988")]
288    pub mod amdgpu {
289        pub use crate::core_arch::amdgpu::*;
290    }
291
292    /// Platform-specific intrinsics for the `loongarch32` platform.
293    ///
294    /// See the [module documentation](../index.html) for more details.
295    #[cfg(any(target_arch = "loongarch32", doc))]
296//     #[doc(cfg(target_arch = "loongarch32"))] // commented out for std.noratrieb.dev
297    #[unstable(feature = "stdarch_loongarch", issue = "117427")]
298    pub mod loongarch32 {
299        pub use crate::core_arch::loongarch_shared::*;
300        pub use crate::core_arch::loongarch32::*;
301    }
302
303    /// Platform-specific intrinsics for the `loongarch64` platform.
304    ///
305    /// See the [module documentation](../index.html) for more details.
306    #[cfg(any(target_arch = "loongarch64", doc))]
307//     #[doc(cfg(target_arch = "loongarch64"))] // commented out for std.noratrieb.dev
308    #[unstable(feature = "stdarch_loongarch", issue = "117427")]
309    pub mod loongarch64 {
310        pub use crate::core_arch::loongarch_shared::*;
311        pub use crate::core_arch::loongarch64::*;
312    }
313
314    /// Platform-specific intrinsics for the `s390x` platform.
315    ///
316    /// See the [module documentation](../index.html) for more details.
317    #[cfg(any(target_arch = "s390x", doc))]
318//     #[doc(cfg(target_arch = "s390x"))] // commented out for std.noratrieb.dev
319    #[unstable(feature = "stdarch_s390x", issue = "135681")]
320    pub mod s390x {
321        pub use crate::core_arch::s390x::*;
322    }
323
324    /// Platform-specific intrinsics for the `hexagon` platform.
325    ///
326    /// This module provides intrinsics for the Qualcomm Hexagon DSP architecture,
327    /// including the Hexagon Vector Extensions (HVX).
328    ///
329    /// See the [module documentation](../index.html) for more details.
330    #[cfg(any(target_arch = "hexagon", doc))]
331//     #[doc(cfg(target_arch = "hexagon"))] // commented out for std.noratrieb.dev
332    #[unstable(feature = "stdarch_hexagon", issue = "151523")]
333    pub mod hexagon {
334        pub use crate::core_arch::hexagon::*;
335    }
336}
337
338#[cfg(any(target_arch = "x86", target_arch = "x86_64", doc))]
339// #[doc(cfg(any(target_arch = "x86", target_arch = "x86_64")))] // commented out for std.noratrieb.dev
340mod x86;
341#[cfg(any(target_arch = "x86_64", doc))]
342// #[doc(cfg(target_arch = "x86_64"))] // commented out for std.noratrieb.dev
343mod x86_64;
344
345#[cfg(any(target_arch = "aarch64", target_arch = "arm64ec", doc))]
346// #[doc(cfg(any(target_arch = "aarch64", target_arch = "arm64ec")))] // commented out for std.noratrieb.dev
347mod aarch64;
348#[cfg(any(target_arch = "arm", doc))]
349// #[doc(cfg(any(target_arch = "arm")))] // commented out for std.noratrieb.dev
350mod arm;
351
352#[cfg(any(target_arch = "riscv32", doc))]
353// #[doc(cfg(any(target_arch = "riscv32")))] // commented out for std.noratrieb.dev
354mod riscv32;
355
356#[cfg(any(target_arch = "riscv64", doc))]
357// #[doc(cfg(any(target_arch = "riscv64")))] // commented out for std.noratrieb.dev
358mod riscv64;
359
360#[cfg(any(target_family = "wasm", doc))]
361// #[doc(cfg(target_family = "wasm"))] // commented out for std.noratrieb.dev
362mod wasm32;
363
364#[cfg(any(target_arch = "mips", target_arch = "mips64", doc))]
365// #[doc(cfg(any(target_arch = "mips", target_arch = "mips64")))] // commented out for std.noratrieb.dev
366mod mips;
367
368#[cfg(any(target_arch = "powerpc", target_arch = "powerpc64", doc))]
369// #[doc(cfg(any(target_arch = "powerpc", target_arch = "powerpc64")))] // commented out for std.noratrieb.dev
370mod powerpc;
371
372#[cfg(any(target_arch = "powerpc64", doc))]
373// #[doc(cfg(target_arch = "powerpc64"))] // commented out for std.noratrieb.dev
374mod powerpc64;
375
376#[cfg(any(target_arch = "nvptx64", doc))]
377// #[doc(cfg(target_arch = "nvptx64"))] // commented out for std.noratrieb.dev
378mod nvptx;
379
380#[cfg(any(target_arch = "amdgpu", doc))]
381// #[doc(cfg(target_arch = "amdgpu"))] // commented out for std.noratrieb.dev
382mod amdgpu;
383
384#[cfg(any(target_arch = "loongarch32", doc))]
385// #[doc(cfg(target_arch = "loongarch32"))] // commented out for std.noratrieb.dev
386mod loongarch32;
387
388#[cfg(any(target_arch = "loongarch64", doc))]
389// #[doc(cfg(target_arch = "loongarch64"))] // commented out for std.noratrieb.dev
390mod loongarch64;
391
392#[cfg(any(target_arch = "s390x", doc))]
393// #[doc(cfg(target_arch = "s390x"))] // commented out for std.noratrieb.dev
394mod s390x;
395
396#[cfg(any(target_arch = "hexagon", doc))]
397// #[doc(cfg(target_arch = "hexagon"))] // commented out for std.noratrieb.dev
398mod hexagon;