Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
53 changes: 37 additions & 16 deletions compiler/rustc_ast_lowering/src/asm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -261,24 +261,45 @@ impl<'hir> LoweringContext<'_, 'hir> {
if class == asm::InlineAsmRegClass::Err {
continue;
}
let valid_modifiers = class.valid_modifiers(asm_arch.unwrap());
let valid_modifiers =
class.valid_modifiers(asm_arch.unwrap(), allow_experimental_reg);
if !valid_modifiers.contains(&modifier) {
let sub = if valid_modifiers.is_empty() {
InvalidAsmTemplateModifierRegClassSub::DoesNotSupportModifier {
class_name: class.name(),
}
// First check if the requested modifier is missing from the valid
// values because experimental registers are disabled.
let unstable_modifiers = class.valid_modifiers(asm_arch.unwrap(), true);
if !allow_experimental_reg && unstable_modifiers.contains(&modifier) {
self.tcx.sess.create_feature_err(
InvalidAsmTemplateModifierRegClass {
placeholder_span,
op_span: op_sp,
modifier: modifier.to_string(),
sub: InvalidAsmTemplateModifierRegClassSub::ModifierIsGated {
class_name: class.name(),
feature: sym::asm_experimental_reg,
stable_modifiers: valid_modifiers.to_vec().into(),
all_modifiers: unstable_modifiers.to_vec().into(),
},
},
sym::asm_experimental_reg,
).emit();
} else {
InvalidAsmTemplateModifierRegClassSub::SupportModifier {
class_name: class.name(),
modifiers: valid_modifiers.to_vec().into(),
}
};
self.dcx().emit_err(InvalidAsmTemplateModifierRegClass {
placeholder_span,
op_span: op_sp,
modifier: modifier.to_string(),
sub,
});
let sub = if valid_modifiers.is_empty() {
InvalidAsmTemplateModifierRegClassSub::DoesNotSupportModifier {
class_name: class.name(),
}
} else {
InvalidAsmTemplateModifierRegClassSub::SupportModifier {
class_name: class.name(),
modifiers: valid_modifiers.to_vec().into(),
}
};
self.dcx().emit_err(InvalidAsmTemplateModifierRegClass {
placeholder_span,
op_span: op_sp,
modifier: modifier.to_string(),
sub,
});
}
}
}
hir::InlineAsmOperand::Const { .. } => {
Expand Down
12 changes: 12 additions & 0 deletions compiler/rustc_ast_lowering/src/diagnostics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -266,6 +266,18 @@ pub(crate) enum InvalidAsmTemplateModifierRegClassSub {
SupportModifier { class_name: Symbol, modifiers: DiagSymbolList<char> },
#[note("the `{$class_name}` register class does not support template modifiers")]
DoesNotSupportModifier { class_name: Symbol },

/// Enabling a feature is needed to use the requested modifier.
#[note(
"the `{$class_name}` register class only supports the following template modifiers on stable: {$stable_modifiers}"
)]
#[note("enabling the `{$feature}` feature will allow using: {$all_modifiers}")]
ModifierIsGated {
class_name: Symbol,
feature: Symbol,
stable_modifiers: DiagSymbolList<char>,
all_modifiers: DiagSymbolList<char>,
},
}

#[derive(Diagnostic)]
Expand Down
15 changes: 13 additions & 2 deletions compiler/rustc_target/src/asm/aarch64.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,21 @@ def_reg_class! {
}

impl AArch64InlineAsmRegClass {
pub fn valid_modifiers(self, _arch: super::InlineAsmArch) -> &'static [char] {
pub fn valid_modifiers(
self,
_arch: super::InlineAsmArch,
allow_experimental_reg: bool,
) -> &'static [char] {
match self {
Self::reg => &['w', 'x'],
Self::vreg | Self::vreg_low16 => &['b', 'h', 's', 'd', 'q', 'v', 'z'],
Self::vreg | Self::vreg_low16 => {
if allow_experimental_reg {
&['b', 'h', 's', 'd', 'q', 'v', 'z']
} else {
&['b', 'h', 's', 'd', 'q', 'v']
}
}

Self::preg | Self::ffr => &[],
}
}
Expand Down
14 changes: 10 additions & 4 deletions compiler/rustc_target/src/asm/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -711,13 +711,19 @@ impl InlineAsmRegClass {
})
}

/// Returns the list of template modifiers that can be used with this
/// register class.
pub fn valid_modifiers(self, arch: InlineAsmArch) -> &'static [char] {
/// Returns the list of template modifiers that can be used with this register class, as well as
/// whether the `asm_experimental_reg` feature is enabled: there can be template modifiers that
/// apply to currently unstable registers, and we don't want to make these modifiers usable
/// without the feature gate.
pub fn valid_modifiers(
self,
arch: InlineAsmArch,
allow_experimental_reg: bool,
) -> &'static [char] {
match self {
Self::X86(r) => r.valid_modifiers(arch),
Self::Arm(r) => r.valid_modifiers(arch),
Self::AArch64(r) => r.valid_modifiers(arch),
Self::AArch64(r) => r.valid_modifiers(arch, allow_experimental_reg),
Self::Amdgpu(r) => r.valid_modifiers(arch),
Self::RiscV(r) => r.valid_modifiers(arch),
Self::Nvptx(r) => r.valid_modifiers(arch),
Expand Down
2 changes: 1 addition & 1 deletion tests/assembly-llvm/asm/aarch64-modifiers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
//@ compile-flags: -Zmerge-functions=disabled
//@ needs-llvm-components: aarch64

#![feature(no_core)]
#![feature(asm_experimental_reg, no_core)]
#![crate_type = "rlib"]
#![no_core]
#![allow(asm_sub_register)]
Expand Down
4 changes: 2 additions & 2 deletions tests/ui/asm/aarch64/bad-reg.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ LL | asm!("{:r}", in(vreg) foo);
| |
| template modifier
|
= note: the `vreg` register class supports the following template modifiers: `b`, `h`, `s`, `d`, `q`, `v`, and `z`
= note: the `vreg` register class supports the following template modifiers: `b`, `h`, `s`, `d`, `q`, and `v`

error: invalid asm template modifier `r` for this register class
--> $DIR/bad-reg.rs:26:15
Expand All @@ -40,7 +40,7 @@ LL | asm!("{:r}", in(vreg_low16) foo);
| |
| template modifier
|
= note: the `vreg_low16` register class supports the following template modifiers: `b`, `h`, `s`, `d`, `q`, `v`, and `z`
= note: the `vreg_low16` register class supports the following template modifiers: `b`, `h`, `s`, `d`, `q`, and `v`

error: asm template modifiers are not allowed for `const` arguments
--> $DIR/bad-reg.rs:28:15
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,32 @@ LL | asm!("/* {0} */", in(preg) p);
= help: add `#![feature(asm_experimental_reg)]` to the crate attributes to enable
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date

error[E0658]: invalid asm template modifier `z` for this register class
--> $DIR/feature-gate-asm_experimental_reg.rs:53:24
|
LL | unsafe { asm!("mov {1:z}.d, {0:z}.d", in(vreg) x, out(vreg) y) };
| ^^^^^ template modifier ----------- argument
|
= note: the `vreg` register class only supports the following template modifiers on stable: `b`, `h`, `s`, `d`, `q`, and `v`
= note: enabling the `asm_experimental_reg` feature will allow using: `b`, `h`, `s`, `d`, `q`, `v`, and `z`
= note: see issue #133416 <https://github.com/rust-lang/rust/issues/133416> for more information
= help: add `#![feature(asm_experimental_reg)]` to the crate attributes to enable
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date

error[E0658]: invalid asm template modifier `z` for this register class
--> $DIR/feature-gate-asm_experimental_reg.rs:53:33
|
LL | unsafe { asm!("mov {1:z}.d, {0:z}.d", in(vreg) x, out(vreg) y) };
| ^^^^^ ---------- argument
| |
| template modifier
|
= note: the `vreg` register class only supports the following template modifiers on stable: `b`, `h`, `s`, `d`, `q`, and `v`
= note: enabling the `asm_experimental_reg` feature will allow using: `b`, `h`, `s`, `d`, `q`, `v`, and `z`
= note: see issue #133416 <https://github.com/rust-lang/rust/issues/133416> for more information
= help: add `#![feature(asm_experimental_reg)]` to the crate attributes to enable
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date

error[E0658]: type `svint32_t` cannot be used with this register class in stable
--> $DIR/feature-gate-asm_experimental_reg.rs:33:32
|
Expand Down Expand Up @@ -48,6 +74,6 @@ LL | asm!("/* {0} */", in(preg) p);
= help: add `#![feature(asm_experimental_reg)]` to the crate attributes to enable
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date

error: aborting due to 5 previous errors
error: aborting due to 7 previous errors

For more information about this error, try `rustc --explain E0658`.
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
error[E0658]: register class `vreg` can only be used as a clobber in stable
--> $DIR/feature-gate-asm_experimental_reg.rs:60:41
--> $DIR/feature-gate-asm_experimental_reg.rs:69:41
|
LL | asm!("xvadd.h {1:u}, {0:u}, {0:u}", out(vreg) y, in(vreg) x);
| ^^^^^^^^^^^
Expand All @@ -9,7 +9,7 @@ LL | asm!("xvadd.h {1:u}, {0:u}, {0:u}", out(vreg) y, in(vreg) x);
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date

error[E0658]: register class `vreg` can only be used as a clobber in stable
--> $DIR/feature-gate-asm_experimental_reg.rs:60:54
--> $DIR/feature-gate-asm_experimental_reg.rs:69:54
|
LL | asm!("xvadd.h {1:u}, {0:u}, {0:u}", out(vreg) y, in(vreg) x);
| ^^^^^^^^^^
Expand All @@ -19,7 +19,7 @@ LL | asm!("xvadd.h {1:u}, {0:u}, {0:u}", out(vreg) y, in(vreg) x);
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date

error[E0658]: type `i8x16` cannot be used with this register class in stable
--> $DIR/feature-gate-asm_experimental_reg.rs:60:51
--> $DIR/feature-gate-asm_experimental_reg.rs:69:51
|
LL | asm!("xvadd.h {1:u}, {0:u}, {0:u}", out(vreg) y, in(vreg) x);
| ^
Expand All @@ -29,7 +29,7 @@ LL | asm!("xvadd.h {1:u}, {0:u}, {0:u}", out(vreg) y, in(vreg) x);
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date

error[E0658]: type `i8x16` cannot be used with this register class in stable
--> $DIR/feature-gate-asm_experimental_reg.rs:60:63
--> $DIR/feature-gate-asm_experimental_reg.rs:69:63
|
LL | asm!("xvadd.h {1:u}, {0:u}, {0:u}", out(vreg) y, in(vreg) x);
| ^
Expand Down
9 changes: 9 additions & 0 deletions tests/ui/feature-gates/feature-gate-asm_experimental_reg.rs
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,15 @@ unsafe fn predicate(p: svbool_t) {
//[aarch64]~| ERROR type `svbool_t` cannot be used with this register class in stable
}

#[cfg(aarch64)]
unsafe fn modifier(x: f64) -> f64 {
let y: f64;
unsafe { asm!("mov {1:z}.d, {0:z}.d", in(vreg) x, out(vreg) y) };
//[aarch64]~^ ERROR invalid asm template modifier `z` for this register class
//[aarch64]~| ERROR invalid asm template modifier `z` for this register class
y
}

#[cfg(loongarch)]
#[repr(simd)]
pub struct i8x16([i8; 16]);
Expand Down
Loading