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:
@@ -17,7 +17,8 @@ use super::errors::{
|
||||
InlineAsmUnsupportedTarget, InvalidAbiClobberAbi, InvalidAsmTemplateModifierConst,
|
||||
InvalidAsmTemplateModifierLabel, InvalidAsmTemplateModifierRegClass,
|
||||
InvalidAsmTemplateModifierRegClassSub, InvalidAsmTemplateModifierSym, InvalidRegister,
|
||||
InvalidRegisterClass, RegisterClassOnlyClobber, RegisterConflict,
|
||||
InvalidRegisterClass, RegisterClassOnlyClobber, RegisterClassOnlyClobberStable,
|
||||
RegisterConflict,
|
||||
};
|
||||
use crate::{
|
||||
AllowReturnTypeNotation, ImplTraitContext, ImplTraitPosition, ParamMode,
|
||||
@@ -61,6 +62,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
||||
.emit();
|
||||
}
|
||||
}
|
||||
let allow_experimental_reg = self.tcx.features().asm_experimental_reg();
|
||||
if asm.options.contains(InlineAsmOptions::ATT_SYNTAX)
|
||||
&& !matches!(asm_arch, Some(asm::InlineAsmArch::X86 | asm::InlineAsmArch::X86_64))
|
||||
&& !self.tcx.sess.opts.actually_rustdoc
|
||||
@@ -324,11 +326,29 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
||||
// means that we disallow passing a value in/out of the asm and
|
||||
// require that the operand name an explicit register, not a
|
||||
// register class.
|
||||
if reg_class.is_clobber_only(asm_arch.unwrap()) && !op.is_clobber() {
|
||||
self.dcx().emit_err(RegisterClassOnlyClobber {
|
||||
op_span: op_sp,
|
||||
reg_class_name: reg_class.name(),
|
||||
});
|
||||
if reg_class.is_clobber_only(asm_arch.unwrap(), allow_experimental_reg)
|
||||
&& !op.is_clobber()
|
||||
{
|
||||
if allow_experimental_reg || reg_class.is_clobber_only(asm_arch.unwrap(), true)
|
||||
{
|
||||
// always clobber-only
|
||||
self.dcx().emit_err(RegisterClassOnlyClobber {
|
||||
op_span: op_sp,
|
||||
reg_class_name: reg_class.name(),
|
||||
});
|
||||
} else {
|
||||
// clobber-only in stable
|
||||
self.tcx
|
||||
.sess
|
||||
.create_feature_err(
|
||||
RegisterClassOnlyClobberStable {
|
||||
op_span: op_sp,
|
||||
reg_class_name: reg_class.name(),
|
||||
},
|
||||
sym::asm_experimental_reg,
|
||||
)
|
||||
.emit();
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user