Skip to content

Commit f5a7735

Browse files
committed
Support s390x z13 vector ABI
1 parent 6689597 commit f5a7735

9 files changed

+848
-16
lines changed

compiler/rustc_target/src/callconv/s390x.rs

+39-10
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,39 @@
1-
// FIXME: The assumes we're using the non-vector ABI, i.e., compiling
2-
// for a pre-z13 machine or using -mno-vx.
1+
// Reference: ELF Application Binary Interface s390x Supplement
2+
// https://github.com/IBM/s390x-abi
33

4-
use crate::abi::call::{ArgAbi, FnAbi, Reg};
5-
use crate::abi::{HasDataLayout, TyAbiInterface};
4+
use rustc_abi::{BackendRepr, HasDataLayout, Size, TyAbiInterface, TyAndLayout};
5+
6+
use crate::abi::call::{ArgAbi, FnAbi, Reg, RegKind};
67
use crate::spec::HasTargetSpec;
78

9+
fn contains_vector<'a, Ty, C>(cx: &C, layout: TyAndLayout<'a, Ty>, expected_size: Size) -> bool
10+
where
11+
Ty: TyAbiInterface<'a, C> + Copy,
12+
{
13+
match layout.backend_repr {
14+
BackendRepr::Uninhabited | BackendRepr::Scalar(_) | BackendRepr::ScalarPair(..) => false,
15+
BackendRepr::Vector { .. } => layout.size == expected_size,
16+
BackendRepr::Memory { .. } => {
17+
if layout.fields.count() != 1 {
18+
// Zero-sized members in C are not ignored.
19+
// See https://github.com/rust-lang/rust/pull/131586#discussion_r1836718798.
20+
return false;
21+
}
22+
contains_vector(cx, layout.field(cx, 0), expected_size)
23+
}
24+
}
25+
}
26+
827
fn classify_ret<Ty>(ret: &mut ArgAbi<'_, Ty>) {
9-
if !ret.layout.is_aggregate() && ret.layout.size.bits() <= 64 {
28+
let size = ret.layout.size;
29+
if size.bits() <= 128 && matches!(ret.layout.backend_repr, BackendRepr::Vector { .. }) {
30+
return;
31+
}
32+
if !ret.layout.is_aggregate() && size.bits() <= 64 {
1033
ret.extend_integer_width_to(64);
11-
} else {
12-
ret.make_indirect();
34+
return;
1335
}
36+
ret.make_indirect();
1437
}
1538

1639
fn classify_arg<'a, Ty, C>(cx: &C, arg: &mut ArgAbi<'a, Ty>)
@@ -32,19 +55,25 @@ where
3255
}
3356
return;
3457
}
35-
if !arg.layout.is_aggregate() && arg.layout.size.bits() <= 64 {
58+
59+
let size = arg.layout.size;
60+
if size.bits() <= 128 && contains_vector(cx, arg.layout, size) {
61+
arg.cast_to(Reg { kind: RegKind::Vector, size });
62+
return;
63+
}
64+
if !arg.layout.is_aggregate() && size.bits() <= 64 {
3665
arg.extend_integer_width_to(64);
3766
return;
3867
}
3968

4069
if arg.layout.is_single_fp_element(cx) {
41-
match arg.layout.size.bytes() {
70+
match size.bytes() {
4271
4 => arg.cast_to(Reg::f32()),
4372
8 => arg.cast_to(Reg::f64()),
4473
_ => arg.make_indirect(),
4574
}
4675
} else {
47-
match arg.layout.size.bytes() {
76+
match size.bytes() {
4877
1 => arg.cast_to(Reg::i8()),
4978
2 => arg.cast_to(Reg::i16()),
5079
4 => arg.cast_to(Reg::i32()),

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

-3
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,6 @@ pub(crate) fn target() -> Target {
66
base.endian = Endian::Big;
77
// z10 is the oldest CPU supported by LLVM
88
base.cpu = "z10".into();
9-
// FIXME: The ABI implementation in abi/call/s390x.rs is for now hard-coded to assume the no-vector
10-
// ABI. Pass the -vector feature string to LLVM to respect this assumption.
11-
base.features = "-vector".into();
129
base.max_atomic_width = Some(128);
1310
base.min_global_align = Some(16);
1411
base.stack_probes = StackProbeType::Inline;

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

-3
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,6 @@ pub(crate) fn target() -> Target {
66
base.endian = Endian::Big;
77
// z10 is the oldest CPU supported by LLVM
88
base.cpu = "z10".into();
9-
// FIXME: The ABI implementation in abi/call/s390x.rs is for now hard-coded to assume the no-vector
10-
// ABI. Pass the -vector feature string to LLVM to respect this assumption.
11-
base.features = "-vector".into();
129
base.max_atomic_width = Some(128);
1310
base.min_global_align = Some(16);
1411
base.static_position_independent_executables = true;

compiler/rustc_target/src/target_features.rs

+2
Original file line numberDiff line numberDiff line change
@@ -582,6 +582,7 @@ pub fn all_rust_features() -> impl Iterator<Item = (&'static str, Stability)> {
582582
const X86_FEATURES_FOR_CORRECT_VECTOR_ABI: &'static [(u64, &'static str)] =
583583
&[(128, "sse"), (256, "avx"), (512, "avx512f")];
584584
const AARCH64_FEATURES_FOR_CORRECT_VECTOR_ABI: &'static [(u64, &'static str)] = &[(128, "neon")];
585+
const S390X_FEATURES_FOR_CORRECT_VECTOR_ABI: &'static [(u64, &'static str)] = &[(128, "vector")];
585586

586587
impl super::spec::Target {
587588
pub fn rust_target_features(&self) -> &'static [(&'static str, Stability, ImpliedFeatures)] {
@@ -608,6 +609,7 @@ impl super::spec::Target {
608609
match &*self.arch {
609610
"x86" | "x86_64" => Some(X86_FEATURES_FOR_CORRECT_VECTOR_ABI),
610611
"aarch64" => Some(AARCH64_FEATURES_FOR_CORRECT_VECTOR_ABI),
612+
"s390x" => Some(S390X_FEATURES_FOR_CORRECT_VECTOR_ABI),
611613
// FIXME: add support for non-tier1 architectures
612614
_ => None,
613615
}

0 commit comments

Comments
 (0)