diff --git a/compiler/rustc_target/src/spec/mod.rs b/compiler/rustc_target/src/spec/mod.rs index ab52a7d63301a..ea52031e1cfd8 100644 --- a/compiler/rustc_target/src/spec/mod.rs +++ b/compiler/rustc_target/src/spec/mod.rs @@ -1007,6 +1007,8 @@ crate::target_spec_enum! { X86Sse2 = "x86-sse2", /// On x86-32/64 only: do not use any FPU or SIMD registers for the ABI. X86Softfloat = "x86-softfloat", + // On S390x only: do not use any FPU or Vector registers for the ABI. + S390xSoftFloat = "s390x-softfloat", } parse_error_type = "rustc abi"; @@ -3198,6 +3200,11 @@ impl Target { Arch::X86 | Arch::X86_64, "`x86-softfloat` ABI is only valid for x86 targets" ), + RustcAbi::S390xSoftFloat => check_matches!( + self.arch, + Arch::S390x, + "`s390x-softfloat` ABI is only valid for s390x targets" + ), } } diff --git a/compiler/rustc_target/src/target_features.rs b/compiler/rustc_target/src/target_features.rs index 40cc4f40a3336..e3265ae0622ad 100644 --- a/compiler/rustc_target/src/target_features.rs +++ b/compiler/rustc_target/src/target_features.rs @@ -1098,6 +1098,7 @@ impl Target { // LLVM handles the rest. FeatureConstraints { required: &["soft-float"], incompatible: &[] } } + Some(r) => panic!("invalid Rust ABI for x86: {r:?}"), } } Arch::X86_64 => { @@ -1211,11 +1212,26 @@ impl Target { } } Arch::S390x => { - // We don't currently support a softfloat target on this architecture. - // As usual, we have to reject swapping the `soft-float` target feature. + // Same as x86, We use our own ABI indicator here; + // LLVM does not have anything native and will switch ABI based + // on the soft-float target feature. + // Every case should require or forbid `soft-float`! // The "vector" target feature does not affect the ABI for floats // because the vector and float registers overlap. - FeatureConstraints { required: &[], incompatible: &["soft-float"] } + match self.rustc_abi { + None => { + // Default hardfloat ABI. + FeatureConstraints { required: &[], incompatible: &["soft-float"] } + } + Some(RustcAbi::S390xSoftFloat) => { + // Softfloat ABI, requires corresponding target feature. + // llvm will switch to soft-float ABI just based on this feature. + FeatureConstraints { required: &["soft-float"], incompatible: &[] } + } + Some(r) => { + panic!("invalid Rust ABI for s390x: {r:?}"); + } + } } _ => NOTHING, }