@@ -5,7 +5,7 @@ use rustc_data_structures::fx::{FxHashMap, FxHashSet};
55use rustc_data_structures:: stable_hasher:: { HashStable , StableHasher } ;
66use rustc_span:: { Symbol , sym} ;
77
8- use crate :: spec:: Target ;
8+ use crate :: spec:: { FloatAbi , Target } ;
99
1010/// Features that control behaviour of rustc, rather than the codegen.
1111/// These exist globally and are not in the target-specific lists below.
@@ -148,7 +148,6 @@ const ARM_FEATURES: &[(&str, Stability, ImpliedFeatures)] = &[
148148 ( "neon" , Unstable ( sym:: arm_target_feature) , & [ "vfp3" ] ) ,
149149 ( "rclass" , Unstable ( sym:: arm_target_feature) , & [ ] ) ,
150150 ( "sha2" , Unstable ( sym:: arm_target_feature) , & [ "neon" ] ) ,
151- ( "soft-float" , Stability :: Forbidden { reason : "unsound because it changes float ABI" } , & [ ] ) ,
152151 // This is needed for inline assembly, but shouldn't be stabilized as-is
153152 // since it should be enabled per-function using #[instruction_set], not
154153 // #[target_feature].
@@ -204,6 +203,7 @@ const AARCH64_FEATURES: &[(&str, Stability, ImpliedFeatures)] = &[
204203 ( "flagm" , Stable , & [ ] ) ,
205204 // FEAT_FLAGM2
206205 ( "flagm2" , Unstable ( sym:: aarch64_unstable_target_feature) , & [ ] ) ,
206+ // We forbid directly toggling just `fp-armv8`; it must be toggled with `neon`.
207207 ( "fp-armv8" , Stability :: Forbidden { reason : "Rust ties `fp-armv8` to `neon`" } , & [ ] ) ,
208208 // FEAT_FP16
209209 // Rust ties FP and Neon: https://github.com/rust-lang/rust/pull/91608
@@ -758,6 +758,7 @@ impl Target {
758758 match & * self . arch {
759759 "x86" => {
760760 // We support 2 ABIs, hardfloat (default) and softfloat.
761+ // x86 has no sane ABI indicator so we have to use the target feature.
761762 if self . has_feature ( "soft-float" ) {
762763 NOTHING
763764 } else {
@@ -767,6 +768,7 @@ impl Target {
767768 }
768769 "x86_64" => {
769770 // We support 2 ABIs, hardfloat (default) and softfloat.
771+ // x86 has no sane ABI indicator so we have to use the target feature.
770772 if self . has_feature ( "soft-float" ) {
771773 NOTHING
772774 } else {
@@ -775,20 +777,27 @@ impl Target {
775777 }
776778 }
777779 "arm" => {
778- // We support 2 ABIs, hardfloat (default) and softfloat.
779- if self . has_feature ( "soft-float" ) {
780- NOTHING
781- } else {
782- // Hardfloat ABI. x87 must be enabled.
783- ( & [ "fpregs" ] , & [ ] )
780+ // On ARM, ABI handling is reasonably sane; we use `llvm_floatabi` to indicate
781+ // to LLVM which ABI we are going for.
782+ match self . llvm_floatabi . unwrap ( ) {
783+ FloatAbi :: Soft => {
784+ // Nothing special required, will use soft-float ABI throughout.
785+ NOTHING
786+ }
787+ FloatAbi :: Hard => {
788+ // Must have `fpregs` and must not have `soft-float`.
789+ ( & [ "fpregs" ] , & [ "soft-float" ] )
790+ }
784791 }
785792 }
786793 "aarch64" | "arm64ec" => {
794+ // Aarch64 has no sane ABI specifier, and LLVM doesn't even have a way to force
795+ // the use of soft-float, so all we can do here is some crude hacks.
787796 match & * self . abi {
788797 "softfloat" => {
789798 // This is not fully correct, LLVM actually doesn't let us enforce the softfloat
790799 // ABI properly... see <https://github.com/rust-lang/rust/issues/134375>.
791- // FIXME: should be forbid "neon" here? But that would be a breaking change.
800+ // FIXME: should we forbid "neon" here? But that would be a breaking change.
792801 NOTHING
793802 }
794803 _ => {
@@ -799,6 +808,8 @@ impl Target {
799808 }
800809 }
801810 "riscv32" | "riscv64" => {
811+ // RISC-V handles ABI in a very sane way, being fully explicit via `llvm_abiname`
812+ // about what the intended ABI is.
802813 match & * self . llvm_abiname {
803814 "ilp32d" | "lp64d" => {
804815 // Requires d (which implies f), incompatible with e.
0 commit comments