| 1 | //! `core_arch` |
| 2 | |
| 3 | #![allow (unknown_lints, unnecessary_transmutes)] |
| 4 | |
| 5 | #[macro_use ] |
| 6 | mod macros; |
| 7 | |
| 8 | #[cfg (any(target_arch = "riscv32" , target_arch = "riscv64" , doc))] |
| 9 | mod riscv_shared; |
| 10 | |
| 11 | #[cfg (any( |
| 12 | target_arch = "arm" , |
| 13 | target_arch = "aarch64" , |
| 14 | target_arch = "arm64ec" , |
| 15 | doc |
| 16 | ))] |
| 17 | mod arm_shared; |
| 18 | |
| 19 | mod simd; |
| 20 | |
| 21 | #[doc = include_str!("core_arch_docs.md" )] |
| 22 | #[stable (feature = "simd_arch" , since = "1.27.0" )] |
| 23 | pub mod arch { |
| 24 | /// Platform-specific intrinsics for the `x86` platform. |
| 25 | /// |
| 26 | /// See the [module documentation](../index.html) for more details. |
| 27 | #[cfg (any(target_arch = "x86" , doc))] |
| 28 | #[doc (cfg(target_arch = "x86" ))] |
| 29 | #[stable (feature = "simd_x86" , since = "1.27.0" )] |
| 30 | pub mod x86 { |
| 31 | #[stable (feature = "simd_x86" , since = "1.27.0" )] |
| 32 | pub use crate::core_arch::x86::*; |
| 33 | } |
| 34 | |
| 35 | /// Platform-specific intrinsics for the `x86_64` platform. |
| 36 | /// |
| 37 | /// See the [module documentation](../index.html) for more details. |
| 38 | #[cfg (any(target_arch = "x86_64" , doc))] |
| 39 | #[doc (cfg(target_arch = "x86_64" ))] |
| 40 | #[stable (feature = "simd_x86" , since = "1.27.0" )] |
| 41 | pub mod x86_64 { |
| 42 | #[stable (feature = "simd_x86" , since = "1.27.0" )] |
| 43 | pub use crate::core_arch::x86::*; |
| 44 | #[stable (feature = "simd_x86" , since = "1.27.0" )] |
| 45 | pub use crate::core_arch::x86_64::*; |
| 46 | } |
| 47 | |
| 48 | /// Platform-specific intrinsics for the `arm` platform. |
| 49 | /// |
| 50 | /// See the [module documentation](../index.html) for more details. |
| 51 | #[cfg (any(target_arch = "arm" , doc))] |
| 52 | #[doc (cfg(target_arch = "arm" ))] |
| 53 | #[unstable (feature = "stdarch_arm_neon_intrinsics" , issue = "111800" )] |
| 54 | pub mod arm { |
| 55 | #[unstable (feature = "stdarch_arm_neon_intrinsics" , issue = "111800" )] |
| 56 | pub use crate::core_arch::arm::*; |
| 57 | } |
| 58 | |
| 59 | /// Platform-specific intrinsics for the `aarch64` platform. |
| 60 | /// |
| 61 | /// See the [module documentation](../index.html) for more details. |
| 62 | #[cfg (any(target_arch = "aarch64" , target_arch = "arm64ec" , doc))] |
| 63 | #[doc (cfg(any(target_arch = "aarch64" , target_arch = "arm64ec" )))] |
| 64 | #[stable (feature = "neon_intrinsics" , since = "1.59.0" )] |
| 65 | pub mod aarch64 { |
| 66 | #[stable (feature = "neon_intrinsics" , since = "1.59.0" )] |
| 67 | pub use crate::core_arch::aarch64::*; |
| 68 | } |
| 69 | |
| 70 | /// Platform-specific intrinsics for the `riscv32` platform. |
| 71 | /// |
| 72 | /// See the [module documentation](../index.html) for more details. |
| 73 | #[cfg (any(target_arch = "riscv32" , doc))] |
| 74 | #[doc (cfg(any(target_arch = "riscv32" )))] |
| 75 | #[unstable (feature = "riscv_ext_intrinsics" , issue = "114544" )] |
| 76 | pub mod riscv32 { |
| 77 | pub use crate::core_arch::riscv_shared::*; |
| 78 | pub use crate::core_arch::riscv32::*; |
| 79 | } |
| 80 | |
| 81 | /// Platform-specific intrinsics for the `riscv64` platform. |
| 82 | /// |
| 83 | /// See the [module documentation](../index.html) for more details. |
| 84 | #[cfg (any(target_arch = "riscv64" , doc))] |
| 85 | #[doc (cfg(any(target_arch = "riscv64" )))] |
| 86 | #[unstable (feature = "riscv_ext_intrinsics" , issue = "114544" )] |
| 87 | pub mod riscv64 { |
| 88 | pub use crate::core_arch::riscv64::*; |
| 89 | // RISC-V RV64 supports all RV32 instructions as well in current specifications (2022-01-05). |
| 90 | // Module `riscv_shared` includes instructions available under all RISC-V platforms, |
| 91 | // i.e. RISC-V RV32 instructions. |
| 92 | pub use crate::core_arch::riscv_shared::*; |
| 93 | } |
| 94 | |
| 95 | /// Platform-specific intrinsics for the `wasm32` platform. |
| 96 | /// |
| 97 | /// This module provides intrinsics specific to the WebAssembly |
| 98 | /// architecture. Here you'll find intrinsics specific to WebAssembly that |
| 99 | /// aren't otherwise surfaced somewhere in a cross-platform abstraction of |
| 100 | /// `std`, and you'll also find functions for leveraging WebAssembly |
| 101 | /// proposals such as [atomics] and [simd]. |
| 102 | /// |
| 103 | /// Intrinsics in the `wasm32` module are modeled after the WebAssembly |
| 104 | /// instructions that they represent. Most functions are named after the |
| 105 | /// instruction they intend to correspond to, and the arguments/results |
| 106 | /// correspond to the type signature of the instruction itself. Stable |
| 107 | /// WebAssembly instructions are [documented online][instrdoc]. |
| 108 | /// |
| 109 | /// [instrdoc]: https://webassembly.github.io/spec/core/valid/instructions.html |
| 110 | /// |
| 111 | /// If a proposal is not yet stable in WebAssembly itself then the functions |
| 112 | /// within this function may be unstable and require the nightly channel of |
| 113 | /// Rust to use. As the proposal itself stabilizes the intrinsics in this |
| 114 | /// module should stabilize as well. |
| 115 | /// |
| 116 | /// [atomics]: https://github.com/webassembly/threads |
| 117 | /// [simd]: https://github.com/webassembly/simd |
| 118 | /// |
| 119 | /// See the [module documentation](../index.html) for general information |
| 120 | /// about the `arch` module and platform intrinsics. |
| 121 | /// |
| 122 | /// ## Atomics |
| 123 | /// |
| 124 | /// The [threads proposal][atomics] for WebAssembly adds a number of |
| 125 | /// instructions for dealing with multithreaded programs. Most instructions |
| 126 | /// added in the [atomics] proposal are exposed in Rust through the |
| 127 | /// `std::sync::atomic` module. Some instructions, however, don't have |
| 128 | /// direct equivalents in Rust so they're exposed here instead. |
| 129 | /// |
| 130 | /// Note that the instructions added in the [atomics] proposal can work in |
| 131 | /// either a context with a shared wasm memory and without. These intrinsics |
| 132 | /// are always available in the standard library, but you likely won't be |
| 133 | /// able to use them too productively unless you recompile the standard |
| 134 | /// library (and all your code) with `-Ctarget-feature=+atomics`. |
| 135 | /// |
| 136 | /// It's also worth pointing out that multi-threaded WebAssembly and its |
| 137 | /// story in Rust is still in a somewhat "early days" phase as of the time |
| 138 | /// of this writing. Pieces should mostly work but it generally requires a |
| 139 | /// good deal of manual setup. At this time it's not as simple as "just call |
| 140 | /// `std::thread::spawn`", but it will hopefully get there one day! |
| 141 | /// |
| 142 | /// ## SIMD |
| 143 | /// |
| 144 | /// The [simd proposal][simd] for WebAssembly added a new `v128` type for a |
| 145 | /// 128-bit SIMD register. It also added a large array of instructions to |
| 146 | /// operate on the `v128` type to perform data processing. Using SIMD on |
| 147 | /// wasm is intended to be similar to as you would on `x86_64`, for example. |
| 148 | /// You'd write a function such as: |
| 149 | /// |
| 150 | /// ```rust,ignore |
| 151 | /// #[cfg(target_arch = "wasm32")] |
| 152 | /// #[target_feature(enable = "simd128")] |
| 153 | /// unsafe fn uses_simd() { |
| 154 | /// use std::arch::wasm32::*; |
| 155 | /// // ... |
| 156 | /// } |
| 157 | /// ``` |
| 158 | /// |
| 159 | /// Unlike `x86_64`, however, WebAssembly does not currently have dynamic |
| 160 | /// detection at runtime as to whether SIMD is supported (this is one of the |
| 161 | /// motivators for the [conditional sections][condsections] and [feature |
| 162 | /// detection] proposals, but that is still pretty early days). This means |
| 163 | /// that your binary will either have SIMD and can only run on engines |
| 164 | /// which support SIMD, or it will not have SIMD at all. For compatibility |
| 165 | /// the standard library itself does not use any SIMD internally. |
| 166 | /// Determining how best to ship your WebAssembly binary with SIMD is |
| 167 | /// largely left up to you as it can be pretty nuanced depending on |
| 168 | /// your situation. |
| 169 | /// |
| 170 | /// [condsections]: https://github.com/webassembly/conditional-sections |
| 171 | /// [feature detection]: https://github.com/WebAssembly/feature-detection |
| 172 | /// |
| 173 | /// To enable SIMD support at compile time you need to do one of two things: |
| 174 | /// |
| 175 | /// * First you can annotate functions with `#[target_feature(enable = |
| 176 | /// "simd128")]`. This causes just that one function to have SIMD support |
| 177 | /// available to it, and intrinsics will get inlined as usual in this |
| 178 | /// situation. |
| 179 | /// |
| 180 | /// * Second you can compile your program with `-Ctarget-feature=+simd128`. |
| 181 | /// This compilation flag blanket enables SIMD support for your entire |
| 182 | /// compilation. Note that this does not include the standard library |
| 183 | /// unless you [recompile the standard library][buildstd]. |
| 184 | /// |
| 185 | /// [buildstd]: https://doc.rust-lang.org/nightly/cargo/reference/unstable.html#build-std |
| 186 | /// |
| 187 | /// If you enable SIMD via either of these routes then you'll have a |
| 188 | /// WebAssembly binary that uses SIMD instructions, and you'll need to ship |
| 189 | /// that accordingly. Also note that if you call SIMD intrinsics but don't |
| 190 | /// enable SIMD via either of these mechanisms, you'll still have SIMD |
| 191 | /// generated in your program. This means to generate a binary without SIMD |
| 192 | /// you'll need to avoid both options above plus calling into any intrinsics |
| 193 | /// in this module. |
| 194 | #[cfg (any(target_arch = "wasm32" , doc))] |
| 195 | #[doc (cfg(target_arch = "wasm32" ))] |
| 196 | #[stable (feature = "simd_wasm32" , since = "1.33.0" )] |
| 197 | pub mod wasm32 { |
| 198 | #[stable (feature = "simd_wasm32" , since = "1.33.0" )] |
| 199 | pub use crate::core_arch::wasm32::*; |
| 200 | } |
| 201 | |
| 202 | /// Platform-specific intrinsics for the `wasm64` platform. |
| 203 | /// |
| 204 | /// See the [module documentation](../index.html) for more details. |
| 205 | #[cfg (any(target_arch = "wasm64" , doc))] |
| 206 | #[doc (cfg(target_arch = "wasm64" ))] |
| 207 | #[unstable (feature = "simd_wasm64" , issue = "90599" )] |
| 208 | pub mod wasm64 { |
| 209 | #[unstable (feature = "simd_wasm64" , issue = "90599" )] |
| 210 | pub use crate::core_arch::wasm32::*; |
| 211 | } |
| 212 | |
| 213 | /// Platform-specific intrinsics for the `wasm` target family. |
| 214 | /// |
| 215 | /// See the [module documentation](../index.html) for more details. |
| 216 | #[cfg (any(target_family = "wasm" , doc))] |
| 217 | #[doc (cfg(target_family = "wasm" ))] |
| 218 | #[unstable (feature = "simd_wasm64" , issue = "90599" )] |
| 219 | pub mod wasm { |
| 220 | #[unstable (feature = "simd_wasm64" , issue = "90599" )] |
| 221 | pub use crate::core_arch::wasm32::*; |
| 222 | } |
| 223 | |
| 224 | /// Platform-specific intrinsics for the `mips` platform. |
| 225 | /// |
| 226 | /// See the [module documentation](../index.html) for more details. |
| 227 | #[cfg (any(target_arch = "mips" , doc))] |
| 228 | #[doc (cfg(target_arch = "mips" ))] |
| 229 | #[unstable (feature = "stdarch_mips" , issue = "111198" )] |
| 230 | pub mod mips { |
| 231 | pub use crate::core_arch::mips::*; |
| 232 | } |
| 233 | |
| 234 | /// Platform-specific intrinsics for the `mips64` platform. |
| 235 | /// |
| 236 | /// See the [module documentation](../index.html) for more details. |
| 237 | #[cfg (any(target_arch = "mips64" , doc))] |
| 238 | #[doc (cfg(target_arch = "mips64" ))] |
| 239 | #[unstable (feature = "stdarch_mips" , issue = "111198" )] |
| 240 | pub mod mips64 { |
| 241 | pub use crate::core_arch::mips::*; |
| 242 | } |
| 243 | |
| 244 | /// Platform-specific intrinsics for the `PowerPC` platform. |
| 245 | /// |
| 246 | /// See the [module documentation](../index.html) for more details. |
| 247 | #[cfg (any(target_arch = "powerpc" , doc))] |
| 248 | #[doc (cfg(target_arch = "powerpc" ))] |
| 249 | #[unstable (feature = "stdarch_powerpc" , issue = "111145" )] |
| 250 | pub mod powerpc { |
| 251 | pub use crate::core_arch::powerpc::*; |
| 252 | } |
| 253 | |
| 254 | /// Platform-specific intrinsics for the `PowerPC64` platform. |
| 255 | /// |
| 256 | /// See the [module documentation](../index.html) for more details. |
| 257 | #[cfg (any(target_arch = "powerpc64" , doc))] |
| 258 | #[doc (cfg(target_arch = "powerpc64" ))] |
| 259 | #[unstable (feature = "stdarch_powerpc" , issue = "111145" )] |
| 260 | pub mod powerpc64 { |
| 261 | pub use crate::core_arch::powerpc64::*; |
| 262 | } |
| 263 | |
| 264 | /// Platform-specific intrinsics for the `NVPTX` platform. |
| 265 | /// |
| 266 | /// See the [module documentation](../index.html) for more details. |
| 267 | #[cfg (any(target_arch = "nvptx64" , doc))] |
| 268 | #[doc (cfg(target_arch = "nvptx64" ))] |
| 269 | #[unstable (feature = "stdarch_nvptx" , issue = "111199" )] |
| 270 | pub mod nvptx { |
| 271 | pub use crate::core_arch::nvptx::*; |
| 272 | } |
| 273 | |
| 274 | /// Platform-specific intrinsics for the `loongarch` platform. |
| 275 | /// |
| 276 | /// See the [module documentation](../index.html) for more details. |
| 277 | #[cfg (any(target_arch = "loongarch64" , doc))] |
| 278 | #[doc (cfg(target_arch = "loongarch64" ))] |
| 279 | #[unstable (feature = "stdarch_loongarch" , issue = "117427" )] |
| 280 | pub mod loongarch64 { |
| 281 | pub use crate::core_arch::loongarch64::*; |
| 282 | } |
| 283 | |
| 284 | /// Platform-specific intrinsics for the `s390x` platform. |
| 285 | /// |
| 286 | /// See the [module documentation](../index.html) for more details. |
| 287 | #[cfg (any(target_arch = "s390x" , doc))] |
| 288 | #[doc (cfg(target_arch = "s390x" ))] |
| 289 | #[unstable (feature = "stdarch_s390x" , issue = "135681" )] |
| 290 | pub mod s390x { |
| 291 | pub use crate::core_arch::s390x::*; |
| 292 | } |
| 293 | } |
| 294 | |
| 295 | #[cfg (any(target_arch = "x86" , target_arch = "x86_64" , doc))] |
| 296 | #[doc (cfg(any(target_arch = "x86" , target_arch = "x86_64" )))] |
| 297 | mod x86; |
| 298 | #[cfg (any(target_arch = "x86_64" , doc))] |
| 299 | #[doc (cfg(target_arch = "x86_64" ))] |
| 300 | mod x86_64; |
| 301 | |
| 302 | #[cfg (any(target_arch = "aarch64" , target_arch = "arm64ec" , doc))] |
| 303 | #[doc (cfg(any(target_arch = "aarch64" , target_arch = "arm64ec" )))] |
| 304 | mod aarch64; |
| 305 | #[cfg (any(target_arch = "arm" , doc))] |
| 306 | #[doc (cfg(any(target_arch = "arm" )))] |
| 307 | mod arm; |
| 308 | |
| 309 | #[cfg (any(target_arch = "riscv32" , doc))] |
| 310 | #[doc (cfg(any(target_arch = "riscv32" )))] |
| 311 | mod riscv32; |
| 312 | |
| 313 | #[cfg (any(target_arch = "riscv64" , doc))] |
| 314 | #[doc (cfg(any(target_arch = "riscv64" )))] |
| 315 | mod riscv64; |
| 316 | |
| 317 | #[cfg (any(target_family = "wasm" , doc))] |
| 318 | #[doc (cfg(target_family = "wasm" ))] |
| 319 | mod wasm32; |
| 320 | |
| 321 | #[cfg (any(target_arch = "mips" , target_arch = "mips64" , doc))] |
| 322 | #[doc (cfg(any(target_arch = "mips" , target_arch = "mips64" )))] |
| 323 | mod mips; |
| 324 | |
| 325 | #[cfg (any(target_arch = "powerpc" , target_arch = "powerpc64" , doc))] |
| 326 | #[doc (cfg(any(target_arch = "powerpc" , target_arch = "powerpc64" )))] |
| 327 | mod powerpc; |
| 328 | |
| 329 | #[cfg (any(target_arch = "powerpc64" , doc))] |
| 330 | #[doc (cfg(target_arch = "powerpc64" ))] |
| 331 | mod powerpc64; |
| 332 | |
| 333 | #[cfg (any(target_arch = "nvptx64" , doc))] |
| 334 | #[doc (cfg(target_arch = "nvptx64" ))] |
| 335 | mod nvptx; |
| 336 | |
| 337 | #[cfg (any(target_arch = "loongarch64" , doc))] |
| 338 | #[doc (cfg(target_arch = "loongarch64" ))] |
| 339 | mod loongarch64; |
| 340 | |
| 341 | #[cfg (any(target_arch = "s390x" , doc))] |
| 342 | #[doc (cfg(target_arch = "s390x" ))] |
| 343 | mod s390x; |
| 344 | |