diff --git a/src/attributes.md b/src/attributes.md index 313320815..16aaa4ba0 100644 --- a/src/attributes.md +++ b/src/attributes.md @@ -216,6 +216,7 @@ The following is an index of all built-in attributes. - [`inline`] — Hint to inline code. - [`cold`] — Hint that a function is unlikely to be called. - [`no_builtins`] — Disables use of certain built-in functions. + - [`target_feature`] — Configure platform-specific code generation. - Documentation - `doc` — Specifies documentation. See [The Rustdoc Book] for more information. [Doc comments] are transformed into `doc` attributes. @@ -282,6 +283,7 @@ The following is an index of all built-in attributes. [`recursion_limit`]: attributes/limits.html#the-recursion_limit-attribute [`repr`]: type-layout.html#representations [`should_panic`]: attributes/testing.html#the-should_panic-attribute +[`target_feature`]: attributes/codegen.html#the-target_feature-attribute [`test`]: attributes/testing.html#the-test-attribute [`used`]: abi.html#the-used-attribute [`warn`]: attributes/diagnostics.html#lint-check-attributes diff --git a/src/attributes/codegen.md b/src/attributes/codegen.md index 384cbc013..a7f79c20d 100644 --- a/src/attributes/codegen.md +++ b/src/attributes/codegen.md @@ -42,7 +42,112 @@ The *`no_builtins` [attribute]* may be applied at the crate level to disable optimizing certain code patterns to invocations of library functions that are assumed to exist. +## The `target_feature` attribute + +The *`target_feature` [attribute]* may be applied to an [unsafe function] to +enable code generation of that function for specific platform architecture +features. It uses the [_MetaListNameValueStr_] syntax with a single key of +`enable` whose value is a string of comma-separated feature names to enable. + +```rust,ignore +#[target_feature(enable = "avx2")] +unsafe fn foo_avx2() {} +``` + +Each [target architecture] has a set of features that may be enabled. It is an +error to specify a feature for a target architecture that the crate is not +being compiled for. + +It is [undefined behavior] to call a function that is compiled with a feature +that is not supported on the current platform the code is running on. + +Functions marked with `target_feature` are not inlined into a context that +does not support the given features. The `#[inline(always)]` attribute may not +be used with a `target_feature` attribute. + +### Available features + +The following is a list of the available feature names. + +#### `x86` or `x86_64` + +Feature | Implicitly Enables | Description +------------|--------------------|------------------- +`aes` | `sse2` | [AES] — Advanced Encryption Standard +`avx` | `sse4.2` | [AVX] — Advanced Vector Extensions +`avx2` | `avx` | [AVX2] — Advanced Vector Extensions 2 +`bmi1` | | [BMI1] — Bit Manipulation Instruction Sets +`bmi2` | | [BMI2] — Bit Manipulation Instruction Sets 2 +`fma` | `avx` | [FMA3] — Three-operand fused multiply-add +`fxsr` | | [`fxsave`] and [`fxrstor`] — Save and restore x87 FPU, MMX Technology, and SSE State +`lzcnt` | | [`lzcnt`] — Leading zeros count +`pclmulqdq` | `sse2` | [`pclmulqdq`] — Packed carry-less multiplication quadword +`popcnt` | | [`popcnt`] — Count of bits set to 1 +`rdrand` | | [`rdrand`] — Read random number +`rdseed` | | [`rdseed`] — Read random seed +`sha` | `sse2` | [SHA] — Secure Hash Algorithm +`sse` | | [SSE] — Streaming SIMD Extensions +`sse2` | `sse` | [SSE2] — Streaming SIMD Extensions 2 +`sse3` | `sse2` | [SSE3] — Streaming SIMD Extensions 3 +`sse4.1` | `sse3` | [SSE4.1] — Streaming SIMD Extensions 4.1 +`sse4.2` | `sse4.1` | [SSE4.2] — Streaming SIMD Extensions 4.2 +`ssse3` | `sse3` | [SSSE3] — Supplemental Streaming SIMD Extensions 3 +`xsave` | | [`xsave`] — Save processor extended states +`xsavec` | | [`xsavec`] — Save processor extended states with compaction +`xsaveopt` | | [`xsaveopt`] — Save processor extended states optimized +`xsaves` | | [`xsaves`] — Save processor extended states supervisor + + + +[AES]: https://en.wikipedia.org/wiki/AES_instruction_set +[AVX]: https://en.wikipedia.org/wiki/Advanced_Vector_Extensions +[AVX2]: https://en.wikipedia.org/wiki/Advanced_Vector_Extensions#AVX2 +[BMI1]: https://en.wikipedia.org/wiki/Bit_Manipulation_Instruction_Sets +[BMI2]: https://en.wikipedia.org/wiki/Bit_Manipulation_Instruction_Sets#BMI2 +[FMA3]: https://en.wikipedia.org/wiki/FMA_instruction_set +[`fxsave`]: https://www.felixcloutier.com/x86/fxsave +[`fxrstor`]: https://www.felixcloutier.com/x86/fxrstor +[`lzcnt`]: https://www.felixcloutier.com/x86/lzcnt +[`pclmulqdq`]: https://www.felixcloutier.com/x86/pclmulqdq +[`popcnt`]: https://www.felixcloutier.com/x86/popcnt +[`rdrand`]: https://en.wikipedia.org/wiki/RdRand +[`rdseed`]: https://en.wikipedia.org/wiki/RdRand +[SHA]: https://en.wikipedia.org/wiki/Intel_SHA_extensions +[SSE]: https://en.wikipedia.org/wiki/Streaming_SIMD_Extensions +[SSE2]: https://en.wikipedia.org/wiki/SSE2 +[SSE3]: https://en.wikipedia.org/wiki/SSE3 +[SSE4.1]: https://en.wikipedia.org/wiki/SSE4#SSE4.1 +[SSE4.2]: https://en.wikipedia.org/wiki/SSE4#SSE4.2 +[SSSE3]: https://en.wikipedia.org/wiki/SSSE3 +[`xsave`]: https://www.felixcloutier.com/x86/xsave +[`xsavec`]: https://www.felixcloutier.com/x86/xsavec +[`xsaveopt`]: https://www.felixcloutier.com/x86/xsaveopt +[`xsaves`]: https://www.felixcloutier.com/x86/xsaves + +### Additional information + +See the [`target_feature` conditional compilation option] for selectively +enabling or disabling compilation of code based on compile-time settings. Note +that this option is not affected by the `target_feature` attribute, and is +only driven by the features enabled for the entire crate. + +See the [`is_x86_feature_detected`] macro in the standard library for runtime +feature detection on the x86 platforms. + +> Note: `rustc` has a default set of features enabled for each target and CPU. +> The CPU may be chosen with the [`-C target-cpu`] flag. Individual features +> may be enabled or disabled for an entire crate with the +> [`-C target-feature`] flag. + +[_MetaListNameValueStr_]: attributes.html#meta-item-attribute-syntax +[`-C target-cpu`]: ../rustc/codegen-options/index.html#target-cpu +[`-C target-feature`]: ../rustc/codegen-options/index.html#target-feature +[`is_x86_feature_detected`]: ../std/macro.is_x86_feature_detected.html +[`target_feature` conditional compilation option]: conditional-compilation.html#target_feature [attribute]: attributes.html [attributes]: attributes.html [functions]: items/functions.html +[target architecture]: conditional-compilation.html#target_arch [trait]: items/traits.html +[undefined behavior]: behavior-considered-undefined.html +[unsafe function]: unsafe-functions.html diff --git a/src/behavior-considered-undefined.md b/src/behavior-considered-undefined.md index 5dca31d0b..2a895d194 100644 --- a/src/behavior-considered-undefined.md +++ b/src/behavior-considered-undefined.md @@ -38,6 +38,8 @@ code. * A discriminant in an `enum` not included in the type definition. * A value in a `char` which is a surrogate or above `char::MAX`. * Non-UTF-8 byte sequences in a `str`. +* Executing code compiled with platform features that the current platform + does not support (see [`target_feature`]). > **Note**: Undefined behavior affects the entire program. For example, calling > a function in C that exhibits undefined behavior of C means your entire @@ -48,9 +50,10 @@ code. [noalias]: http://llvm.org/docs/LangRef.html#noalias [pointer aliasing rules]: http://llvm.org/docs/LangRef.html#pointer-aliasing-rules [undef]: http://llvm.org/docs/LangRef.html#undefined-values -[`offset`]: https://doc.rust-lang.org/std/primitive.pointer.html#method.offset -[`std::ptr::copy_nonoverlapping_memory`]: https://doc.rust-lang.org/std/ptr/fn.copy_nonoverlapping.html -[`UnsafeCell`]: https://doc.rust-lang.org/std/cell/struct.UnsafeCell.html -[`read_unaligned`]: https://doc.rust-lang.org/std/ptr/fn.read_unaligned.html -[`write_unaligned`]: https://doc.rust-lang.org/std/ptr/fn.write_unaligned.html +[`offset`]: ../std/primitive.pointer.html#method.offset +[`std::ptr::copy_nonoverlapping_memory`]: ../std/ptr/fn.copy_nonoverlapping.html +[`target_feature`]: attributes/codegen.html#the-target_feature-attribute +[`UnsafeCell`]: ../std/cell/struct.UnsafeCell.html +[`read_unaligned`]: ../std/ptr/fn.read_unaligned.html +[`write_unaligned`]: ../std/ptr/fn.write_unaligned.html [Rustonomicon]: ../nomicon/index.html diff --git a/src/conditional-compilation.md b/src/conditional-compilation.md index 5c3d6fd4f..4f402e3ea 100644 --- a/src/conditional-compilation.md +++ b/src/conditional-compilation.md @@ -90,6 +90,25 @@ Example values: * `"arm"` * `"aarch64"` +### `target_feature` + +Key-value option set for each platform feature available for the current +compilation target. + +Example values: + +* `"avx"` +* `"avx2"` +* `"crt-static"` +* `"rdrand"` +* `"sse"` +* `"sse2"` +* `"sse4.1"` + +See the [`target_feature` attribute] for more details on the available +features. An additional feature of `crt-static` is available to the +`target_feature` option to indicate that a [static C runtime] is available. + ### `target_os` Key-value option set once with the target's operating system. This value is @@ -305,6 +324,8 @@ println!("I'm running on a {} machine!", machine_kind); [`cfg` macro]: #the-cfg-macro [`cfg_attr`]: #the-cfg_attr-attribute [`debug_assert!`]: ../std/macro.debug_assert.html +[`target_feature` attribute]: attributes/codegen.html#the-target_feature-attribute [attribute]: attributes.html [attributes]: attributes.html [crate type]: linkage.html +[static C runtime]: linkage.html#static-and-dynamic-c-runtimes diff --git a/src/linkage.md b/src/linkage.md index 691e46584..1f27f80f8 100644 --- a/src/linkage.md +++ b/src/linkage.md @@ -168,7 +168,7 @@ that it's linked as you would expect after the compiler succeeds. Crates may also learn about how the C runtime is being linked. Code on MSVC, for example, needs to be compiled differently (e.g. with `/MT` or `/MD`) depending on the runtime being linked. This is exported currently through the -`target_feature` attribute (note this is a nightly feature): +[`cfg` attribute `target_feature` option]: ```rust,ignore #[cfg(target_feature = "crt-static")] @@ -210,5 +210,6 @@ a statically linked binary on MSVC you would execute: RUSTFLAGS='-C target-feature=+crt-static' cargo build --target x86_64-pc-windows-msvc ``` +[`cfg` attribute `target_feature` option]: conditional-compilation.html#target_feature [configuration option]: conditional-compilation.html -[procedural macros]: procedural-macros.html \ No newline at end of file +[procedural macros]: procedural-macros.html