mirror of
https://github.com/rust-lang/rust.git
synced 2025-02-22 20:03:37 +00:00
Auto merge of #117912 - GeorgeWort:master, r=petrochenkov
Name explicit registers in conflict register errors for inline assembly
This commit is contained in:
commit
4e3dc976e7
@ -2251,6 +2251,18 @@ pub enum InlineAsmOperand {
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl InlineAsmOperand {
|
||||||
|
pub fn reg(&self) -> Option<&InlineAsmRegOrRegClass> {
|
||||||
|
match self {
|
||||||
|
Self::In { reg, .. }
|
||||||
|
| Self::Out { reg, .. }
|
||||||
|
| Self::InOut { reg, .. }
|
||||||
|
| Self::SplitInOut { reg, .. } => Some(reg),
|
||||||
|
Self::Const { .. } | Self::Sym { .. } => None,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Inline assembly.
|
/// Inline assembly.
|
||||||
///
|
///
|
||||||
/// E.g., `asm!("NOP");`.
|
/// E.g., `asm!("NOP");`.
|
||||||
|
@ -354,10 +354,6 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
|||||||
|
|
||||||
let idx2 = *o.get();
|
let idx2 = *o.get();
|
||||||
let (ref op2, op_sp2) = operands[idx2];
|
let (ref op2, op_sp2) = operands[idx2];
|
||||||
let Some(asm::InlineAsmRegOrRegClass::Reg(reg2)) = op2.reg()
|
|
||||||
else {
|
|
||||||
unreachable!();
|
|
||||||
};
|
|
||||||
|
|
||||||
let in_out = match (op, op2) {
|
let in_out = match (op, op2) {
|
||||||
(
|
(
|
||||||
@ -375,11 +371,24 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
|||||||
_ => None,
|
_ => None,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
let reg_str = |idx| -> &str {
|
||||||
|
// HIR asm doesn't preserve the original alias string of the explicit register,
|
||||||
|
// so we have to retrieve it from AST
|
||||||
|
let (op, _): &(InlineAsmOperand, Span) = &asm.operands[idx];
|
||||||
|
if let Some(ast::InlineAsmRegOrRegClass::Reg(reg_sym)) =
|
||||||
|
op.reg()
|
||||||
|
{
|
||||||
|
reg_sym.as_str()
|
||||||
|
} else {
|
||||||
|
unreachable!();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
sess.emit_err(RegisterConflict {
|
sess.emit_err(RegisterConflict {
|
||||||
op_span1: op_sp,
|
op_span1: op_sp,
|
||||||
op_span2: op_sp2,
|
op_span2: op_sp2,
|
||||||
reg1_name: reg.name(),
|
reg1_name: reg_str(idx),
|
||||||
reg2_name: reg2.name(),
|
reg2_name: reg_str(idx2),
|
||||||
in_out,
|
in_out,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -48,14 +48,14 @@ fn main() {
|
|||||||
// (except in/lateout which don't conflict)
|
// (except in/lateout which don't conflict)
|
||||||
|
|
||||||
asm!("", in("x0") foo, in("w0") bar);
|
asm!("", in("x0") foo, in("w0") bar);
|
||||||
//~^ ERROR register `x0` conflicts with register `x0`
|
//~^ ERROR register `w0` conflicts with register `x0`
|
||||||
asm!("", in("x0") foo, out("x0") bar);
|
asm!("", in("x0") foo, out("x0") bar);
|
||||||
//~^ ERROR register `x0` conflicts with register `x0`
|
//~^ ERROR register `x0` conflicts with register `x0`
|
||||||
asm!("", in("w0") foo, lateout("w0") bar);
|
asm!("", in("w0") foo, lateout("w0") bar);
|
||||||
asm!("", in("v0") foo, in("q0") bar);
|
asm!("", in("v0") foo, in("q0") bar);
|
||||||
//~^ ERROR register `v0` conflicts with register `v0`
|
//~^ ERROR register `q0` conflicts with register `v0`
|
||||||
asm!("", in("v0") foo, out("q0") bar);
|
asm!("", in("v0") foo, out("q0") bar);
|
||||||
//~^ ERROR register `v0` conflicts with register `v0`
|
//~^ ERROR register `q0` conflicts with register `v0`
|
||||||
asm!("", in("v0") foo, lateout("q0") bar);
|
asm!("", in("v0") foo, lateout("q0") bar);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -98,11 +98,11 @@ error: register class `preg` can only be used as a clobber, not as an input or o
|
|||||||
LL | asm!("{}", out(preg) _);
|
LL | asm!("{}", out(preg) _);
|
||||||
| ^^^^^^^^^^^
|
| ^^^^^^^^^^^
|
||||||
|
|
||||||
error: register `x0` conflicts with register `x0`
|
error: register `w0` conflicts with register `x0`
|
||||||
--> $DIR/bad-reg.rs:50:32
|
--> $DIR/bad-reg.rs:50:32
|
||||||
|
|
|
|
||||||
LL | asm!("", in("x0") foo, in("w0") bar);
|
LL | asm!("", in("x0") foo, in("w0") bar);
|
||||||
| ------------ ^^^^^^^^^^^^ register `x0`
|
| ------------ ^^^^^^^^^^^^ register `w0`
|
||||||
| |
|
| |
|
||||||
| register `x0`
|
| register `x0`
|
||||||
|
|
||||||
@ -120,19 +120,19 @@ help: use `lateout` instead of `out` to avoid conflict
|
|||||||
LL | asm!("", in("x0") foo, out("x0") bar);
|
LL | asm!("", in("x0") foo, out("x0") bar);
|
||||||
| ^^^^^^^^^^^^
|
| ^^^^^^^^^^^^
|
||||||
|
|
||||||
error: register `v0` conflicts with register `v0`
|
error: register `q0` conflicts with register `v0`
|
||||||
--> $DIR/bad-reg.rs:55:32
|
--> $DIR/bad-reg.rs:55:32
|
||||||
|
|
|
|
||||||
LL | asm!("", in("v0") foo, in("q0") bar);
|
LL | asm!("", in("v0") foo, in("q0") bar);
|
||||||
| ------------ ^^^^^^^^^^^^ register `v0`
|
| ------------ ^^^^^^^^^^^^ register `q0`
|
||||||
| |
|
| |
|
||||||
| register `v0`
|
| register `v0`
|
||||||
|
|
||||||
error: register `v0` conflicts with register `v0`
|
error: register `q0` conflicts with register `v0`
|
||||||
--> $DIR/bad-reg.rs:57:32
|
--> $DIR/bad-reg.rs:57:32
|
||||||
|
|
|
|
||||||
LL | asm!("", in("v0") foo, out("q0") bar);
|
LL | asm!("", in("v0") foo, out("q0") bar);
|
||||||
| ------------ ^^^^^^^^^^^^^ register `v0`
|
| ------------ ^^^^^^^^^^^^^ register `q0`
|
||||||
| |
|
| |
|
||||||
| register `v0`
|
| register `v0`
|
||||||
|
|
|
|
||||||
|
@ -56,10 +56,10 @@ fn main() {
|
|||||||
// (except in/lateout which don't conflict)
|
// (except in/lateout which don't conflict)
|
||||||
|
|
||||||
asm!("", in("eax") foo, in("al") bar);
|
asm!("", in("eax") foo, in("al") bar);
|
||||||
//~^ ERROR register `al` conflicts with register `ax`
|
//~^ ERROR register `al` conflicts with register `eax`
|
||||||
//~| ERROR `i32` cannot be used with this register class
|
//~| ERROR `i32` cannot be used with this register class
|
||||||
asm!("", in("rax") foo, out("rax") bar);
|
asm!("", in("rax") foo, out("rax") bar);
|
||||||
//~^ ERROR register `ax` conflicts with register `ax`
|
//~^ ERROR register `rax` conflicts with register `rax`
|
||||||
asm!("", in("al") foo, lateout("al") bar);
|
asm!("", in("al") foo, lateout("al") bar);
|
||||||
//~^ ERROR `i32` cannot be used with this register class
|
//~^ ERROR `i32` cannot be used with this register class
|
||||||
//~| ERROR `i32` cannot be used with this register class
|
//~| ERROR `i32` cannot be used with this register class
|
||||||
|
@ -106,21 +106,21 @@ error: register class `mmx_reg` can only be used as a clobber, not as an input o
|
|||||||
LL | asm!("{}", out(mmx_reg) _);
|
LL | asm!("{}", out(mmx_reg) _);
|
||||||
| ^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^
|
||||||
|
|
||||||
error: register `al` conflicts with register `ax`
|
error: register `al` conflicts with register `eax`
|
||||||
--> $DIR/bad-reg.rs:58:33
|
--> $DIR/bad-reg.rs:58:33
|
||||||
|
|
|
|
||||||
LL | asm!("", in("eax") foo, in("al") bar);
|
LL | asm!("", in("eax") foo, in("al") bar);
|
||||||
| ------------- ^^^^^^^^^^^^ register `al`
|
| ------------- ^^^^^^^^^^^^ register `al`
|
||||||
| |
|
| |
|
||||||
| register `ax`
|
| register `eax`
|
||||||
|
|
||||||
error: register `ax` conflicts with register `ax`
|
error: register `rax` conflicts with register `rax`
|
||||||
--> $DIR/bad-reg.rs:61:33
|
--> $DIR/bad-reg.rs:61:33
|
||||||
|
|
|
|
||||||
LL | asm!("", in("rax") foo, out("rax") bar);
|
LL | asm!("", in("rax") foo, out("rax") bar);
|
||||||
| ------------- ^^^^^^^^^^^^^^ register `ax`
|
| ------------- ^^^^^^^^^^^^^^ register `rax`
|
||||||
| |
|
| |
|
||||||
| register `ax`
|
| register `rax`
|
||||||
|
|
|
|
||||||
help: use `lateout` instead of `out` to avoid conflict
|
help: use `lateout` instead of `out` to avoid conflict
|
||||||
--> $DIR/bad-reg.rs:61:18
|
--> $DIR/bad-reg.rs:61:18
|
||||||
|
Loading…
Reference in New Issue
Block a user