about summary refs log tree commit diff
path: root/compiler
diff options
context:
space:
mode:
Diffstat (limited to 'compiler')
-rw-r--r--compiler/rustc_feature/src/unstable.rs1
-rw-r--r--compiler/rustc_span/src/symbol.rs1
-rw-r--r--compiler/rustc_target/src/spec/mod.rs12
-rw-r--r--compiler/rustc_target/src/target_features.rs36
4 files changed, 48 insertions, 2 deletions
diff --git a/compiler/rustc_feature/src/unstable.rs b/compiler/rustc_feature/src/unstable.rs
index 93a605e197c..25f6c837158 100644
--- a/compiler/rustc_feature/src/unstable.rs
+++ b/compiler/rustc_feature/src/unstable.rs
@@ -342,6 +342,7 @@ declare_features! (
     (unstable, sse4a_target_feature, "1.27.0", Some(44839)),
     (unstable, tbm_target_feature, "1.27.0", Some(44839)),
     (unstable, wasm_target_feature, "1.30.0", Some(44839)),
+    (unstable, x87_target_feature, "CURRENT_RUSTC_VERSION", Some(44839)),
     // !!!!    !!!!    !!!!    !!!!   !!!!    !!!!    !!!!    !!!!    !!!!    !!!!    !!!!
     // Features are listed in alphabetical order. Tidy will fail if you don't keep it this way.
     // !!!!    !!!!    !!!!    !!!!   !!!!    !!!!    !!!!    !!!!    !!!!    !!!!    !!!!
diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs
index d30b17c9cd8..b63575f2bb2 100644
--- a/compiler/rustc_span/src/symbol.rs
+++ b/compiler/rustc_span/src/symbol.rs
@@ -2200,6 +2200,7 @@ symbols! {
         writeln_macro,
         x86_amx_intrinsics,
         x87_reg,
+        x87_target_feature,
         xer,
         xmm_reg,
         xop_target_feature,
diff --git a/compiler/rustc_target/src/spec/mod.rs b/compiler/rustc_target/src/spec/mod.rs
index 210d67fa1aa..7d308c6c662 100644
--- a/compiler/rustc_target/src/spec/mod.rs
+++ b/compiler/rustc_target/src/spec/mod.rs
@@ -2603,6 +2603,18 @@ impl TargetOptions {
                 .collect();
         }
     }
+
+    pub(crate) fn has_feature(&self, search_feature: &str) -> bool {
+        self.features.split(',').any(|f| {
+            if let Some(f) = f.strip_prefix('+')
+                && f == search_feature
+            {
+                true
+            } else {
+                false
+            }
+        })
+    }
 }
 
 impl Default for TargetOptions {
diff --git a/compiler/rustc_target/src/target_features.rs b/compiler/rustc_target/src/target_features.rs
index 717e64fe6c8..d5da130aa6c 100644
--- a/compiler/rustc_target/src/target_features.rs
+++ b/compiler/rustc_target/src/target_features.rs
@@ -32,6 +32,8 @@ pub enum Stability<AllowToggle> {
     /// This target feature is unstable. It is only present in `#[cfg(target_feature)]` on
     /// nightly and using it in `#[target_feature]` requires enabling the given nightly feature.
     Unstable {
+        /// This must be a *language* feature, or else rustc will ICE when reporting a missing
+        /// feature gate!
         nightly_feature: Symbol,
         /// See `Stable::allow_toggle` comment above.
         allow_toggle: AllowToggle,
@@ -168,6 +170,22 @@ const ARM_FEATURES: &[(&str, StabilityUncomputed, ImpliedFeatures)] = &[
     ("dotprod", unstable(sym::arm_target_feature), &["neon"]),
     ("dsp", unstable(sym::arm_target_feature), &[]),
     ("fp-armv8", unstable(sym::arm_target_feature), &["vfp4"]),
+    (
+        "fpregs",
+        Stability::Unstable {
+            nightly_feature: sym::arm_target_feature,
+            allow_toggle: |target: &Target| {
+                // Only allow toggling this if the target has `soft-float` set. With `soft-float`,
+                // `fpregs` isn't needed so changing it cannot affect the ABI.
+                if target.has_feature("soft-float") {
+                    Ok(())
+                } else {
+                    Err("unsound on hard-float targets because it changes float ABI")
+                }
+            },
+        },
+        &[],
+    ),
     ("i8mm", unstable(sym::arm_target_feature), &["neon"]),
     ("mclass", unstable(sym::arm_target_feature), &[]),
     ("neon", unstable(sym::arm_target_feature), &["vfp3"]),
@@ -191,7 +209,6 @@ const ARM_FEATURES: &[(&str, StabilityUncomputed, ImpliedFeatures)] = &[
     ("vfp4", unstable(sym::arm_target_feature), &["vfp3"]),
     ("virtualization", unstable(sym::arm_target_feature), &[]),
     // tidy-alphabetical-end
-    // FIXME: need to also forbid turning off `fpregs` on hardfloat targets
 ];
 
 const AARCH64_FEATURES: &[(&str, StabilityUncomputed, ImpliedFeatures)] = &[
@@ -450,13 +467,28 @@ const X86_FEATURES: &[(&str, StabilityUncomputed, ImpliedFeatures)] = &[
     ("tbm", unstable(sym::tbm_target_feature), &[]),
     ("vaes", unstable(sym::avx512_target_feature), &["avx2", "aes"]),
     ("vpclmulqdq", unstable(sym::avx512_target_feature), &["avx", "pclmulqdq"]),
+    (
+        "x87",
+        Stability::Unstable {
+            nightly_feature: sym::x87_target_feature,
+            allow_toggle: |target: &Target| {
+                // Only allow toggling this if the target has `soft-float` set. With `soft-float`,
+                // `fpregs` isn't needed so changing it cannot affect the ABI.
+                if target.has_feature("soft-float") {
+                    Ok(())
+                } else {
+                    Err("unsound on hard-float targets because it changes float ABI")
+                }
+            },
+        },
+        &[],
+    ),
     ("xop", unstable(sym::xop_target_feature), &[/*"fma4", */ "avx", "sse4a"]),
     ("xsave", STABLE, &[]),
     ("xsavec", STABLE, &["xsave"]),
     ("xsaveopt", STABLE, &["xsave"]),
     ("xsaves", STABLE, &["xsave"]),
     // tidy-alphabetical-end
-    // FIXME: need to also forbid turning off `x87` on hardfloat targets
 ];
 
 const HEXAGON_FEATURES: &[(&str, StabilityUncomputed, ImpliedFeatures)] = &[