1
Fork 0

Rollup merge of #131664 - taiki-e:s390x-asm-vreg-inout, r=Amanieu

Support input/output in vector registers of s390x inline assembly (under asm_experimental_reg feature)

This extends currently clobber-only vector registers (`vreg`) support to allow passing `#[repr(simd)]` types, floats (f32/f64/f128), and integers (i32/i64/i128) as input/output.

This is unstable and gated under new `#![feature(asm_experimental_reg)]` (tracking issue: https://github.com/rust-lang/rust/issues/133416). If the feature is not enabled, only clober is supported as before.

| Architecture | Register class | Target feature | Allowed types |
| ------------ | -------------- | -------------- | -------------- |
| s390x | `vreg` | `vector` | `i32`, `f32`, `i64`, `f64`, `i128`, `f128`, `i8x16`, `i16x8`, `i32x4`, `i64x2`, `f32x4`, `f64x2` |

This matches the list of types that are supported by the vector registers in LLVM:
https://github.com/llvm/llvm-project/blob/llvmorg-19.1.0/llvm/lib/Target/SystemZ/SystemZRegisterInfo.td#L301-L313

In addition to `core::simd` types and floats listed above, custom `#[repr(simd)]` types of the same size and type are also allowed. All allowed types other than i32/f32/i64/f64/i128, and relevant target features are currently unstable.

Currently there is no SIMD type for s390x in `core::arch`, but this is tracked in https://github.com/rust-lang/rust/issues/130869.

cc https://github.com/rust-lang/rust/issues/130869 about vector facility support in s390x
cc https://github.com/rust-lang/rust/issues/125398 & https://github.com/rust-lang/rust/issues/116909 about f128 support in asm

`@rustbot` label +O-SystemZ +A-inline-assembly
This commit is contained in:
Matthias Krüger 2024-11-25 07:01:37 +01:00 committed by GitHub
commit 3f86eddf83
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
22 changed files with 1382 additions and 146 deletions

View file

@ -604,9 +604,13 @@ impl InlineAsmRegClass {
/// Returns a list of supported types for this register class, each with an
/// options target feature required to use this type.
///
/// At the codegen stage, it is fine to always pass true for `allow_experimental_reg`,
/// since all the stability checking will have been done in prior stages.
pub fn supported_types(
self,
arch: InlineAsmArch,
allow_experimental_reg: bool,
) -> &'static [(InlineAsmType, Option<Symbol>)] {
match self {
Self::X86(r) => r.supported_types(arch),
@ -618,7 +622,7 @@ impl InlineAsmRegClass {
Self::Hexagon(r) => r.supported_types(arch),
Self::LoongArch(r) => r.supported_types(arch),
Self::Mips(r) => r.supported_types(arch),
Self::S390x(r) => r.supported_types(arch),
Self::S390x(r) => r.supported_types(arch, allow_experimental_reg),
Self::Sparc(r) => r.supported_types(arch),
Self::SpirV(r) => r.supported_types(arch),
Self::Wasm(r) => r.supported_types(arch),
@ -696,8 +700,11 @@ impl InlineAsmRegClass {
/// Returns whether registers in this class can only be used as clobbers
/// and not as inputs/outputs.
pub fn is_clobber_only(self, arch: InlineAsmArch) -> bool {
self.supported_types(arch).is_empty()
///
/// At the codegen stage, it is fine to always pass true for `allow_experimental_reg`,
/// since all the stability checking will have been done in prior stages.
pub fn is_clobber_only(self, arch: InlineAsmArch, allow_experimental_reg: bool) -> bool {
self.supported_types(arch, allow_experimental_reg).is_empty()
}
}

View file

@ -38,11 +38,22 @@ impl S390xInlineAsmRegClass {
pub fn supported_types(
self,
_arch: InlineAsmArch,
allow_experimental_reg: bool,
) -> &'static [(InlineAsmType, Option<Symbol>)] {
match self {
Self::reg | Self::reg_addr => types! { _: I8, I16, I32, I64; },
Self::freg => types! { _: F32, F64; },
Self::vreg => &[],
Self::vreg => {
if allow_experimental_reg {
// non-clobber-only vector register support is unstable.
types! {
vector: I32, F32, I64, F64, I128, F128,
VecI8(16), VecI16(8), VecI32(4), VecI64(2), VecF32(4), VecF64(2);
}
} else {
&[]
}
}
Self::areg => &[],
}
}