Skip to content

Commit

Permalink
Support s390x z13 vector ABI
Browse files Browse the repository at this point in the history
  • Loading branch information
taiki-e committed Nov 10, 2024
1 parent 7660aed commit 730ecfe
Show file tree
Hide file tree
Showing 9 changed files with 844 additions and 16 deletions.
46 changes: 36 additions & 10 deletions compiler/rustc_target/src/callconv/s390x.rs
Original file line number Diff line number Diff line change
@@ -1,16 +1,36 @@
// FIXME: The assumes we're using the non-vector ABI, i.e., compiling
// for a pre-z13 machine or using -mno-vx.
use rustc_abi::{BackendRepr, HasDataLayout, Size, TyAbiInterface, TyAndLayout};

use crate::abi::call::{ArgAbi, FnAbi, Reg};
use crate::abi::{HasDataLayout, TyAbiInterface};
use crate::abi::call::{ArgAbi, FnAbi, Reg, RegKind};
use crate::spec::HasTargetSpec;

fn contains_vector<'a, Ty, C>(cx: &C, layout: TyAndLayout<'a, Ty>, expected_size: Size) -> bool
where
Ty: TyAbiInterface<'a, C> + Copy,
{
match layout.backend_repr {
BackendRepr::Uninhabited | BackendRepr::Scalar(_) | BackendRepr::ScalarPair(..) => false,
BackendRepr::Vector { .. } => layout.size == expected_size,
BackendRepr::Memory { .. } => {
for i in 0..layout.fields.count() {
if contains_vector(cx, layout.field(cx, i), expected_size) {
return true;
}
}
false
}
}
}

fn classify_ret<Ty>(ret: &mut ArgAbi<'_, Ty>) {
if !ret.layout.is_aggregate() && ret.layout.size.bits() <= 64 {
let size = ret.layout.size;
if size.bits() <= 128 && matches!(ret.layout.backend_repr, BackendRepr::Vector { .. }) {
return;
}
if !ret.layout.is_aggregate() && size.bits() <= 64 {
ret.extend_integer_width_to(64);
} else {
ret.make_indirect();
return;
}
ret.make_indirect();
}

fn classify_arg<'a, Ty, C>(cx: &C, arg: &mut ArgAbi<'a, Ty>)
Expand All @@ -32,19 +52,25 @@ where
}
return;
}
if !arg.layout.is_aggregate() && arg.layout.size.bits() <= 64 {

let size = arg.layout.size;
if size.bits() <= 128 && contains_vector(cx, arg.layout, size) {
arg.cast_to(Reg { kind: RegKind::Vector, size });
return;
}
if !arg.layout.is_aggregate() && size.bits() <= 64 {
arg.extend_integer_width_to(64);
return;
}

if arg.layout.is_single_fp_element(cx) {
match arg.layout.size.bytes() {
match size.bytes() {
4 => arg.cast_to(Reg::f32()),
8 => arg.cast_to(Reg::f64()),
_ => arg.make_indirect(),
}
} else {
match arg.layout.size.bytes() {
match size.bytes() {
1 => arg.cast_to(Reg::i8()),
2 => arg.cast_to(Reg::i16()),
4 => arg.cast_to(Reg::i32()),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,6 @@ pub(crate) fn target() -> Target {
base.endian = Endian::Big;
// z10 is the oldest CPU supported by LLVM
base.cpu = "z10".into();
// FIXME: The ABI implementation in abi/call/s390x.rs is for now hard-coded to assume the no-vector
// ABI. Pass the -vector feature string to LLVM to respect this assumption.
base.features = "-vector".into();
base.max_atomic_width = Some(128);
base.min_global_align = Some(16);
base.stack_probes = StackProbeType::Inline;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,6 @@ pub(crate) fn target() -> Target {
base.endian = Endian::Big;
// z10 is the oldest CPU supported by LLVM
base.cpu = "z10".into();
// FIXME: The ABI implementation in abi/call/s390x.rs is for now hard-coded to assume the no-vector
// ABI. Pass the -vector feature string to LLVM to respect this assumption.
base.features = "-vector".into();
base.max_atomic_width = Some(128);
base.min_global_align = Some(16);
base.static_position_independent_executables = true;
Expand Down
2 changes: 2 additions & 0 deletions compiler/rustc_target/src/target_features.rs
Original file line number Diff line number Diff line change
Expand Up @@ -582,6 +582,7 @@ pub fn all_rust_features() -> impl Iterator<Item = (&'static str, Stability)> {
const X86_FEATURES_FOR_CORRECT_VECTOR_ABI: &'static [(u64, &'static str)] =
&[(128, "sse"), (256, "avx"), (512, "avx512f")];
const AARCH64_FEATURES_FOR_CORRECT_VECTOR_ABI: &'static [(u64, &'static str)] = &[(128, "neon")];
const S390X_FEATURES_FOR_CORRECT_VECTOR_ABI: &'static [(u64, &'static str)] = &[(128, "vector")];

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

0 comments on commit 730ecfe

Please sign in to comment.