|
1 | 1 | //! Declares Rust's target feature names for each target. |
2 | 2 | //! Note that these are similar to but not always identical to LLVM's feature names, |
3 | 3 | //! and Rust adds some features that do not correspond to LLVM features at all. |
| 4 | +//! |
| 5 | +//! The target features listed here can be used in `#[target_feature]` and `#[cfg(target_feature)]`. |
| 6 | +//! They also do not trigger any warnings when used with `-Ctarget-feature`. |
| 7 | +//! |
| 8 | +//! Note that even unstable (and even entirely unlisted) features can be used with `-Ctarget-feature` |
| 9 | +//! on stable. Using a feature not on the list of Rust target features only emits a warning. |
| 10 | +//! Only `cfg(target_feature)` and `#[target_feature]` actually do any stability gating. |
| 11 | +//! `cfg(target_feature)` for unstable features just works on nightly without any feature gate. |
| 12 | +//! `#[target_feature]` requires a feature gate. |
| 13 | +//! |
| 14 | +//! When adding features to the below lists |
| 15 | +//! check whether they're named already elsewhere in rust |
| 16 | +//! e.g. in stdarch and whether the given name matches LLVM's |
| 17 | +//! if it doesn't, to_llvm_feature in llvm_util in rustc_codegen_llvm needs to be adapted. |
| 18 | +//! Additionally, if the feature is not available in older version of LLVM supported by the current |
| 19 | +//! rust, the same function must be updated to filter out these features to avoid triggering |
| 20 | +//! warnings. |
| 21 | +//! |
| 22 | +//! Also note that all target features listed here must be purely additive: for target_feature 1.1 to |
| 23 | +//! be sound, we can never allow features like `+soft-float` (on x86) to be controlled on a |
| 24 | +//! per-function level, since we would then allow safe calls from functions with `+soft-float` to |
| 25 | +//! functions without that feature! |
| 26 | +//! |
| 27 | +//! It is important for soundness to consider the interaction of target features and the function |
| 28 | +//! call ABI. For example, disabling the `x87` feature on x86 changes how scalar floats are passed as |
| 29 | +//! arguments, so letting people toggle that feature would be unsound. To this end, the |
| 30 | +//! [`Target::abi_required_features`] function computes which target features must and must not be |
| 31 | +//! enabled for any given target, and individual features can also be marked as [`Forbidden`]. See |
| 32 | +//! <https://github.com/rust-lang/rust/issues/116344> for some more context. |
| 33 | +//! |
| 34 | +//! The one exception to features that change the ABI is features that enable larger vector |
| 35 | +//! registers. Those are permitted to be listed here. The `*_FOR_CORRECT_VECTOR_ABI` arrays store |
| 36 | +//! information about which target feature is ABI-required for which vector size; this is used to |
| 37 | +//! ensure that vectors can only be passed via `extern "C"` when the right feature is enabled. (For |
| 38 | +//! the "Rust" ABI we generally pass vectors by-ref exactly to avoid these issues.) |
| 39 | +//! Also see <https://github.com/rust-lang/rust/issues/116558>. |
| 40 | +//! |
| 41 | +//! Stabilizing a target feature requires t-lang approval. |
4 | 42 | use rustc_data_structures::fx::{FxHashMap, FxHashSet}; |
5 | 43 | use rustc_macros::StableHash; |
6 | 44 | use rustc_span::{Symbol, sym}; |
@@ -32,9 +70,12 @@ pub enum Stability { |
32 | 70 | Symbol, |
33 | 71 | ), |
34 | 72 | /// This feature can not be set via `-Ctarget-feature` or `#[target_feature]`, it can only be |
35 | | - /// set in the target spec. It is never set in `cfg(target_feature)`. Used in |
36 | | - /// particular for features are actually ABI configuration flags (not all targets are as nice as |
37 | | - /// RISC-V and have an explicit way to set the ABI separate from target features). |
| 73 | + /// set in the target spec. It is never set in `cfg(target_feature)`. Used in particular for |
| 74 | + /// features are actually ABI configuration flags (such as "soft-float" on many targets). |
| 75 | + /// However, "forbidden" target features can still sometimes be enabled via `-Ctarget-cpu` or |
| 76 | + /// target feature implications (on the Rust/LLVM level). To prevent that, ABI-relevant target |
| 77 | + /// features are ideally pinned down (required or forbidden) in |
| 78 | + /// [`Target::abi_required_features`]. |
38 | 79 | Forbidden { |
39 | 80 | reason: &'static str, |
40 | 81 | /// True if this is always an error, false if this can be reported as a warning when set via |
@@ -102,50 +143,11 @@ impl Stability { |
102 | 143 | } |
103 | 144 | } |
104 | 145 |
|
105 | | -// Here we list target features that rustc "understands": they can be used in `#[target_feature]` |
106 | | -// and `#[cfg(target_feature)]`. They also do not trigger any warnings when used with |
107 | | -// `-Ctarget-feature`. |
108 | | -// |
109 | | -// Note that even unstable (and even entirely unlisted) features can be used with `-Ctarget-feature` |
110 | | -// on stable. Using a feature not on the list of Rust target features only emits a warning. |
111 | | -// Only `cfg(target_feature)` and `#[target_feature]` actually do any stability gating. |
112 | | -// `cfg(target_feature)` for unstable features just works on nightly without any feature gate. |
113 | | -// `#[target_feature]` requires a feature gate. |
114 | | -// |
115 | | -// When adding features to the below lists |
116 | | -// check whether they're named already elsewhere in rust |
117 | | -// e.g. in stdarch and whether the given name matches LLVM's |
118 | | -// if it doesn't, to_llvm_feature in llvm_util in rustc_codegen_llvm needs to be adapted. |
119 | | -// Additionally, if the feature is not available in older version of LLVM supported by the current |
120 | | -// rust, the same function must be updated to filter out these features to avoid triggering |
121 | | -// warnings. |
122 | | -// |
123 | | -// Also note that all target features listed here must be purely additive: for target_feature 1.1 to |
124 | | -// be sound, we can never allow features like `+soft-float` (on x86) to be controlled on a |
125 | | -// per-function level, since we would then allow safe calls from functions with `+soft-float` to |
126 | | -// functions without that feature! |
127 | | -// |
128 | | -// It is important for soundness to consider the interaction of targets features and the function |
129 | | -// call ABI. For example, disabling the `x87` feature on x86 changes how scalar floats are passed as |
130 | | -// arguments, so letting people toggle that feature would be unsound. To this end, the |
131 | | -// `abi_required_features` function computes which target features must and must not be enabled for |
132 | | -// any given target, and individual features can also be marked as `Forbidden`. |
133 | | -// See https://github.com/rust-lang/rust/issues/116344 for some more context. |
134 | | -// |
135 | | -// The one exception to features that change the ABI is features that enable larger vector |
136 | | -// registers. Those are permitted to be listed here. The `*_FOR_CORRECT_VECTOR_ABI` arrays store |
137 | | -// information about which target feature is ABI-required for which vector size; this is used to |
138 | | -// ensure that vectors can only be passed via `extern "C"` when the right feature is enabled. (For |
139 | | -// the "Rust" ABI we generally pass vectors by-ref exactly to avoid these issues.) |
140 | | -// Also see https://github.com/rust-lang/rust/issues/116558. |
141 | | -// |
142 | | -// Stabilizing a target feature requires t-lang approval. |
143 | | - |
144 | | -// If feature A "implies" feature B, then: |
145 | | -// - when A gets enabled (via `-Ctarget-feature` or `#[target_feature]`), we also enable B |
146 | | -// - when B gets disabled (via `-Ctarget-feature`), we also disable A |
147 | | -// |
148 | | -// Both of these are also applied transitively. |
| 146 | +/// If feature A "implies" feature B, then: |
| 147 | +/// - when A gets enabled (via `-Ctarget-feature` or `#[target_feature]`), we also enable B |
| 148 | +/// - when B gets disabled (via `-Ctarget-feature`), we also disable A |
| 149 | +/// |
| 150 | +/// Both of these are also applied transitively. |
149 | 151 | type ImpliedFeatures = &'static [&'static str]; |
150 | 152 |
|
151 | 153 | static ARM_FEATURES: &[(&str, Stability, ImpliedFeatures)] = &[ |
|
0 commit comments