Skip to content

Commit 1f59a4a

Browse files
Rollup merge of #151154 - fneddy:s390x_softfloat_abi, r=workingjubilee
Add `s390x-unknown-none-softfloat` with `RustcAbi::Softfloat` followup on #150766 add an `s390x-unknown-none-softfloat` target to use for kernel compilation, as the Linux kernel does not wish to pay the overhead of saving float registers by default on kernel switch. this target's `extern "C"` ABI is unspecified, so it is unstable and subject to change between versions, just like the Linux intrakernel ABI and `extern "Rust"` ABIs are unstable. enforce target feature incompatibility by adding `RustcAbi::Softfloat`. this is itself just a rename of `RustcAbi::X86Softfloat`, accepting both "x86-softfloat" and "softfloat" as valid strings in the target.json format. the target-features of `"soft-float"` and `"vector"` are incompatible for s390x, so issue a compatibility warning if they are combined.
2 parents af70d82 + 83dba5b commit 1f59a4a

23 files changed

+350
-22
lines changed

compiler/rustc_target/src/callconv/x86_win64.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ where
2828
BackendRepr::ScalableVector { .. } => panic!("scalable vectors are unsupported"),
2929
BackendRepr::Scalar(scalar) => {
3030
if is_ret && matches!(scalar.primitive(), Primitive::Int(Integer::I128, _)) {
31-
if cx.target_spec().rustc_abi == Some(RustcAbi::X86Softfloat) {
31+
if cx.target_spec().rustc_abi == Some(RustcAbi::Softfloat) {
3232
// Use the native `i128` LLVM type for the softfloat ABI -- in other words, adjust nothing.
3333
} else {
3434
// `i128` is returned in xmm0 by Clang and GCC

compiler/rustc_target/src/lib.rs

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@ macro_rules! target_spec_enum {
7676
pub enum $Name:ident {
7777
$(
7878
$( #[$variant_attr:meta] )*
79-
$Variant:ident = $string:literal,
79+
$Variant:ident = $string:literal $(,$alias:literal)* ,
8080
)*
8181
}
8282
parse_error_type = $parse_error_type:literal;
@@ -88,6 +88,7 @@ macro_rules! target_spec_enum {
8888
$(
8989
$( #[$variant_attr] )*
9090
#[serde(rename = $string)] // for JSON schema generation only
91+
$( #[serde(alias = $alias)] )*
9192
$Variant,
9293
)*
9394
}
@@ -97,7 +98,10 @@ macro_rules! target_spec_enum {
9798

9899
fn from_str(s: &str) -> Result<Self, Self::Err> {
99100
Ok(match s {
100-
$( $string => Self::$Variant, )*
101+
$(
102+
$string => Self::$Variant,
103+
$($alias => Self::$Variant,)*
104+
)*
101105
_ => {
102106
let all = [$( concat!("'", $string, "'") ),*].join(", ");
103107
return Err(format!("invalid {}: '{s}'. allowed values: {all}", $parse_error_type));
@@ -123,7 +127,7 @@ macro_rules! target_spec_enum {
123127
pub enum $Name:ident {
124128
$(
125129
$( #[$variant_attr:meta] )*
126-
$Variant:ident = $string:literal,
130+
$Variant:ident = $string:literal $(,$alias:literal)* ,
127131
)*
128132
}
129133
$( #[$other_variant_attr:meta] )*
@@ -134,6 +138,7 @@ macro_rules! target_spec_enum {
134138
pub enum $Name {
135139
$(
136140
$( #[$variant_attr:meta] )*
141+
$( #[serde(alias = $alias)] )*
137142
$Variant,
138143
)*
139144
/// The vast majority of the time, the compiler deals with a fixed
@@ -165,7 +170,10 @@ macro_rules! target_spec_enum {
165170

166171
fn from_str(s: &str) -> Result<Self, Self::Err> {
167172
Ok(match s {
168-
$( $string => Self::$Variant, )*
173+
$(
174+
$string => Self::$Variant,
175+
$($alias => Self::$Variant,)*
176+
)*
169177
_ => Self::$OtherVariant(s.to_owned().into()),
170178
})
171179
}

compiler/rustc_target/src/spec/mod.rs

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1005,8 +1005,8 @@ crate::target_spec_enum! {
10051005
pub enum RustcAbi {
10061006
/// On x86-32 only: make use of SSE and SSE2 for ABI purposes.
10071007
X86Sse2 = "x86-sse2",
1008-
/// On x86-32/64 only: do not use any FPU or SIMD registers for the ABI.
1009-
X86Softfloat = "x86-softfloat",
1008+
/// On x86-32/64 and S390x: do not use any FPU or SIMD registers for the ABI.
1009+
Softfloat = "softfloat", "x86-softfloat",
10101010
}
10111011

10121012
parse_error_type = "rustc abi";
@@ -1460,6 +1460,7 @@ supported_targets! {
14601460
("powerpc64le-unknown-linux-gnu", powerpc64le_unknown_linux_gnu),
14611461
("powerpc64le-unknown-linux-musl", powerpc64le_unknown_linux_musl),
14621462
("s390x-unknown-linux-gnu", s390x_unknown_linux_gnu),
1463+
("s390x-unknown-none-softfloat", s390x_unknown_none_softfloat),
14631464
("s390x-unknown-linux-musl", s390x_unknown_linux_musl),
14641465
("sparc-unknown-linux-gnu", sparc_unknown_linux_gnu),
14651466
("sparc64-unknown-linux-gnu", sparc64_unknown_linux_gnu),
@@ -3204,10 +3205,10 @@ impl Target {
32043205
Arch::X86,
32053206
"`x86-sse2` ABI is only valid for x86-32 targets"
32063207
),
3207-
RustcAbi::X86Softfloat => check_matches!(
3208+
RustcAbi::Softfloat => check_matches!(
32083209
self.arch,
3209-
Arch::X86 | Arch::X86_64,
3210-
"`x86-softfloat` ABI is only valid for x86 targets"
3210+
Arch::X86 | Arch::X86_64 | Arch::S390x,
3211+
"`softfloat` ABI is only valid for x86 and s390x targets"
32113212
),
32123213
}
32133214
}

compiler/rustc_target/src/spec/targets/i686_unknown_uefi.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ pub(crate) fn target() -> Target {
2222
// If you initialize FP units yourself, you can override these flags with custom linker
2323
// arguments, thus giving you access to full MMX/SSE acceleration.
2424
base.features = "-mmx,-sse,+soft-float".into();
25-
base.rustc_abi = Some(RustcAbi::X86Softfloat);
25+
base.rustc_abi = Some(RustcAbi::Softfloat);
2626

2727
// Turn off DWARF. This fixes an lld warning, "section name .debug_frame is longer than 8
2828
// characters and will use a non-standard string table". That section will not be created if
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
use rustc_abi::{Align, Endian};
2+
3+
use crate::spec::{
4+
Abi, Arch, Cc, LinkerFlavor, Lld, PanicStrategy, RelocModel, RustcAbi, SanitizerSet,
5+
StackProbeType, Target, TargetMetadata, TargetOptions,
6+
};
7+
8+
pub(crate) fn target() -> Target {
9+
let opts = TargetOptions {
10+
abi: Abi::SoftFloat,
11+
cpu: "z10".into(),
12+
endian: Endian::Big,
13+
features: "+soft-float,-vector".into(),
14+
linker_flavor: LinkerFlavor::Gnu(Cc::No, Lld::Yes),
15+
linker: Some("rust-lld".into()),
16+
max_atomic_width: Some(128),
17+
min_global_align: Some(Align::from_bits(16).unwrap()),
18+
panic_strategy: PanicStrategy::Abort,
19+
relocation_model: RelocModel::Static,
20+
rustc_abi: Some(RustcAbi::Softfloat),
21+
stack_probes: StackProbeType::Inline,
22+
supported_sanitizers: SanitizerSet::KERNELADDRESS,
23+
..Default::default()
24+
};
25+
26+
Target {
27+
llvm_target: "s390x-unknown-linux-gnu".into(),
28+
metadata: TargetMetadata {
29+
description: Some("S390x Linux".into()),
30+
host_tools: Some(false),
31+
std: Some(false),
32+
tier: Some(2),
33+
},
34+
arch: Arch::S390x,
35+
data_layout: "E-S64-m:e-i1:8:16-i8:8:16-i64:64-f128:64-v128:64-a:8:16-n32:64".into(),
36+
options: opts,
37+
pointer_width: 64,
38+
}
39+
}

compiler/rustc_target/src/spec/targets/x86_64_unknown_none.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ pub(crate) fn target() -> Target {
2020
relro_level: RelroLevel::Full,
2121
linker_flavor: LinkerFlavor::Gnu(Cc::No, Lld::Yes),
2222
linker: Some("rust-lld".into()),
23-
rustc_abi: Some(RustcAbi::X86Softfloat),
23+
rustc_abi: Some(RustcAbi::Softfloat),
2424
features: "-mmx,-sse,-sse2,-sse3,-ssse3,-sse4.1,-sse4.2,-avx,-avx2,+soft-float".into(),
2525
supported_sanitizers: SanitizerSet::KCFI | SanitizerSet::KERNELADDRESS,
2626
disable_redzone: true,

compiler/rustc_target/src/spec/targets/x86_64_unknown_uefi.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ pub(crate) fn target() -> Target {
2727
// If you initialize FP units yourself, you can override these flags with custom linker
2828
// arguments, thus giving you access to full MMX/SSE acceleration.
2929
base.features = "-mmx,-sse,+soft-float".into();
30-
base.rustc_abi = Some(RustcAbi::X86Softfloat);
30+
base.rustc_abi = Some(RustcAbi::Softfloat);
3131

3232
Target {
3333
llvm_target: "x86_64-unknown-windows".into(),

compiler/rustc_target/src/target_features.rs

Lines changed: 24 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -863,7 +863,7 @@ const IBMZ_FEATURES: &[(&str, Stability, ImpliedFeatures)] = &[
863863
("miscellaneous-extensions-3", Stable, &[]),
864864
("miscellaneous-extensions-4", Stable, &[]),
865865
("nnp-assist", Stable, &["vector"]),
866-
("soft-float", Forbidden { reason: "currently unsupported ABI-configuration feature" }, &[]),
866+
("soft-float", Forbidden { reason: "unsupported ABI-configuration feature" }, &[]),
867867
("transactional-execution", Unstable(sym::s390x_target_feature), &[]),
868868
("vector", Stable, &[]),
869869
("vector-enhancements-1", Stable, &["vector"]),
@@ -1117,7 +1117,7 @@ impl Target {
11171117
incompatible: &["soft-float"],
11181118
}
11191119
}
1120-
Some(RustcAbi::X86Softfloat) => {
1120+
Some(RustcAbi::Softfloat) => {
11211121
// Softfloat ABI, requires corresponding target feature. That feature trumps
11221122
// `x87` and all other FPU features so those do not matter.
11231123
// Note that this one requirement is the entire implementation of the ABI!
@@ -1137,7 +1137,7 @@ impl Target {
11371137
incompatible: &["soft-float"],
11381138
}
11391139
}
1140-
Some(RustcAbi::X86Softfloat) => {
1140+
Some(RustcAbi::Softfloat) => {
11411141
// Softfloat ABI, requires corresponding target feature. That feature trumps
11421142
// `x87` and all other FPU features so those do not matter.
11431143
// Note that this one requirement is the entire implementation of the ABI!
@@ -1237,11 +1237,27 @@ impl Target {
12371237
}
12381238
}
12391239
Arch::S390x => {
1240-
// We don't currently support a softfloat target on this architecture.
1241-
// As usual, we have to reject swapping the `soft-float` target feature.
1242-
// The "vector" target feature does not affect the ABI for floats
1243-
// because the vector and float registers overlap.
1244-
FeatureConstraints { required: &[], incompatible: &["soft-float"] }
1240+
// Same as x86, We use our own ABI indicator here;
1241+
// LLVM does not have anything native and will switch ABI based
1242+
// on the soft-float target feature.
1243+
// Every case should require or forbid `soft-float`!
1244+
// The "vector" target feature may only be used without soft-float
1245+
// because the float and vector registers overlap and the
1246+
// standard s390x C ABI may pass vectors via these registers.
1247+
match self.rustc_abi {
1248+
None => {
1249+
// Default hardfloat ABI.
1250+
FeatureConstraints { required: &[], incompatible: &["soft-float"] }
1251+
}
1252+
Some(RustcAbi::Softfloat) => {
1253+
// Softfloat ABI, requires corresponding target feature.
1254+
// llvm will switch to soft-float ABI just based on this feature.
1255+
FeatureConstraints { required: &["soft-float"], incompatible: &["vector"] }
1256+
}
1257+
Some(r) => {
1258+
panic!("invalid Rust ABI for s390x: {r:?}");
1259+
}
1260+
}
12451261
}
12461262
Arch::Avr => {
12471263
// SRAM is minimum requirement for C/C++ in both avr-gcc and Clang,

src/bootstrap/src/core/sanity.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ const STAGE0_MISSING_TARGETS: &[&str] = &[
4848
"thumbv6-none-eabi",
4949
"aarch64v8r-unknown-none",
5050
"aarch64v8r-unknown-none-softfloat",
51+
"s390x-unknown-none-softfloat",
5152
];
5253

5354
/// Minimum version threshold for libstdc++ required when using prebuilt LLVM

src/doc/rustc/src/SUMMARY.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -120,6 +120,7 @@
120120
- [riscv64a23-unknown-linux-gnu](platform-support/riscv64a23-unknown-linux-gnu.md)
121121
- [s390x-unknown-linux-gnu](platform-support/s390x-unknown-linux-gnu.md)
122122
- [s390x-unknown-linux-musl](platform-support/s390x-unknown-linux-musl.md)
123+
- [s390x-unknown-none-softfloat](platform-support/s390x-unknown-none-softfloat.md)
123124
- [sparc-unknown-none-elf](./platform-support/sparc-unknown-none-elf.md)
124125
- [solaris](platform-support/solaris.md)
125126
- [\*-nto-qnx-\*](platform-support/nto-qnx.md)

0 commit comments

Comments
 (0)