x86: reserve bl and bh registers to match rbx

This commit is contained in:
Cathal Mullan
2026-03-02 17:41:57 +00:00
parent 8ddf4ef064
commit 6696649c47
5 changed files with 83 additions and 55 deletions
+3 -3
View File
@@ -67,7 +67,7 @@ pub(super) fn regclass_map() -> rustc_data_structures::fx::FxHashMap<
macro_rules! def_regs {
($arch:ident $arch_reg:ident $arch_regclass:ident {
$(
$reg:ident: $class:ident $(, $extra_class:ident)* = [$reg_name:literal $(, $alias:literal)*] $(% $filter:ident)?,
$reg:ident: $class:ident $(, $extra_class:ident)* = [$reg_name:literal $(, $alias:literal)*] $(% $filter:ident)*,
)*
$(
#error = [$($bad_reg:literal),+] => $error:literal,
@@ -121,7 +121,7 @@ pub fn validate(self,
_target_features,
_target,
_is_clobber
)?;)?
)?;)*
Ok(())
}
)*
@@ -142,7 +142,7 @@ pub(super) fn fill_reg_map(
#[allow(unused_imports)]
use super::{InlineAsmReg, InlineAsmRegClass};
$(
if $($filter(_arch, _reloc_model, _target_features, _target, false).is_ok() &&)? true {
if $($filter(_arch, _reloc_model, _target_features, _target, false).is_ok() &&)* true {
if let Some(set) = _map.get_mut(&InlineAsmRegClass::$arch($arch_regclass::$class)) {
set.insert(InlineAsmReg::$arch($arch_reg::$reg));
}
+2 -2
View File
@@ -250,8 +250,8 @@ fn esi_reserved(
r15: reg = ["r15", "r15w", "r15d"] % x86_64_only,
al: reg_byte = ["al"],
ah: reg_byte = ["ah"] % high_byte,
bl: reg_byte = ["bl"],
bh: reg_byte = ["bh"] % high_byte,
bl: reg_byte = ["bl"] % rbx_reserved,
bh: reg_byte = ["bh"] % rbx_reserved % high_byte,
cl: reg_byte = ["cl"],
ch: reg_byte = ["ch"] % high_byte,
dl: reg_byte = ["dl"],
@@ -67,49 +67,49 @@ LL | asm!("", in("ip") foo);
| ^^^^^^^^^^^^
error: register class `x87_reg` can only be used as a clobber, not as an input or output
--> $DIR/bad-reg.rs:39:18
--> $DIR/bad-reg.rs:43:18
|
LL | asm!("", in("st(2)") foo);
| ^^^^^^^^^^^^^^^
error: register class `mmx_reg` can only be used as a clobber, not as an input or output
--> $DIR/bad-reg.rs:42:18
--> $DIR/bad-reg.rs:46:18
|
LL | asm!("", in("mm0") foo);
| ^^^^^^^^^^^^^
error: register class `kreg0` can only be used as a clobber, not as an input or output
--> $DIR/bad-reg.rs:45:18
--> $DIR/bad-reg.rs:49:18
|
LL | asm!("", in("k0") foo);
| ^^^^^^^^^^^^
error: register class `x87_reg` can only be used as a clobber, not as an input or output
--> $DIR/bad-reg.rs:50:20
--> $DIR/bad-reg.rs:54:20
|
LL | asm!("{}", in(x87_reg) foo);
| ^^^^^^^^^^^^^^^
error: register class `mmx_reg` can only be used as a clobber, not as an input or output
--> $DIR/bad-reg.rs:53:20
--> $DIR/bad-reg.rs:57:20
|
LL | asm!("{}", in(mmx_reg) foo);
| ^^^^^^^^^^^^^^^
error: register class `x87_reg` can only be used as a clobber, not as an input or output
--> $DIR/bad-reg.rs:56:20
--> $DIR/bad-reg.rs:60:20
|
LL | asm!("{}", out(x87_reg) _);
| ^^^^^^^^^^^^^^
error: register class `mmx_reg` can only be used as a clobber, not as an input or output
--> $DIR/bad-reg.rs:58:20
--> $DIR/bad-reg.rs:62:20
|
LL | asm!("{}", out(mmx_reg) _);
| ^^^^^^^^^^^^^^
error: register `al` conflicts with register `eax`
--> $DIR/bad-reg.rs:64:33
--> $DIR/bad-reg.rs:68:33
|
LL | asm!("", in("eax") foo, in("al") bar);
| ------------- ^^^^^^^^^^^^ register `al`
@@ -117,7 +117,7 @@ LL | asm!("", in("eax") foo, in("al") bar);
| register `eax`
error: register `rax` conflicts with register `rax`
--> $DIR/bad-reg.rs:67:33
--> $DIR/bad-reg.rs:71:33
|
LL | asm!("", in("rax") foo, out("rax") bar);
| ------------- ^^^^^^^^^^^^^^ register `rax`
@@ -125,13 +125,13 @@ LL | asm!("", in("rax") foo, out("rax") bar);
| register `rax`
|
help: use `lateout` instead of `out` to avoid conflict
--> $DIR/bad-reg.rs:67:18
--> $DIR/bad-reg.rs:71:18
|
LL | asm!("", in("rax") foo, out("rax") bar);
| ^^^^^^^^^^^^^
error: register `ymm0` conflicts with register `xmm0`
--> $DIR/bad-reg.rs:72:34
--> $DIR/bad-reg.rs:76:34
|
LL | asm!("", in("xmm0") foo, in("ymm0") bar);
| -------------- ^^^^^^^^^^^^^^ register `ymm0`
@@ -139,7 +139,7 @@ LL | asm!("", in("xmm0") foo, in("ymm0") bar);
| register `xmm0`
error: register `ymm0` conflicts with register `xmm0`
--> $DIR/bad-reg.rs:74:34
--> $DIR/bad-reg.rs:78:34
|
LL | asm!("", in("xmm0") foo, out("ymm0") bar);
| -------------- ^^^^^^^^^^^^^^^ register `ymm0`
@@ -147,13 +147,25 @@ LL | asm!("", in("xmm0") foo, out("ymm0") bar);
| register `xmm0`
|
help: use `lateout` instead of `out` to avoid conflict
--> $DIR/bad-reg.rs:74:18
--> $DIR/bad-reg.rs:78:18
|
LL | asm!("", in("xmm0") foo, out("ymm0") bar);
| ^^^^^^^^^^^^^^
error: cannot use register `bl`: rbx is used internally by LLVM and cannot be used as an operand for inline asm
--> $DIR/bad-reg.rs:38:18
|
LL | asm!("", in("bl") foo);
| ^^^^^^^^^^^^
error: cannot use register `bh`: rbx is used internally by LLVM and cannot be used as an operand for inline asm
--> $DIR/bad-reg.rs:40:18
|
LL | asm!("", in("bh") foo);
| ^^^^^^^^^^^^
error: type `i32` cannot be used with this register class
--> $DIR/bad-reg.rs:39:30
--> $DIR/bad-reg.rs:43:30
|
LL | asm!("", in("st(2)") foo);
| ^^^
@@ -161,7 +173,7 @@ LL | asm!("", in("st(2)") foo);
= note: register class `x87_reg` supports these types:
error: type `i32` cannot be used with this register class
--> $DIR/bad-reg.rs:42:28
--> $DIR/bad-reg.rs:46:28
|
LL | asm!("", in("mm0") foo);
| ^^^
@@ -169,7 +181,7 @@ LL | asm!("", in("mm0") foo);
= note: register class `mmx_reg` supports these types:
error: type `i32` cannot be used with this register class
--> $DIR/bad-reg.rs:45:27
--> $DIR/bad-reg.rs:49:27
|
LL | asm!("", in("k0") foo);
| ^^^
@@ -177,7 +189,7 @@ LL | asm!("", in("k0") foo);
= note: register class `kreg0` supports these types:
error: type `i32` cannot be used with this register class
--> $DIR/bad-reg.rs:50:32
--> $DIR/bad-reg.rs:54:32
|
LL | asm!("{}", in(x87_reg) foo);
| ^^^
@@ -185,7 +197,7 @@ LL | asm!("{}", in(x87_reg) foo);
= note: register class `x87_reg` supports these types:
error: type `i32` cannot be used with this register class
--> $DIR/bad-reg.rs:53:32
--> $DIR/bad-reg.rs:57:32
|
LL | asm!("{}", in(mmx_reg) foo);
| ^^^
@@ -193,7 +205,7 @@ LL | asm!("{}", in(mmx_reg) foo);
= note: register class `mmx_reg` supports these types:
error: type `i32` cannot be used with this register class
--> $DIR/bad-reg.rs:64:42
--> $DIR/bad-reg.rs:68:42
|
LL | asm!("", in("eax") foo, in("al") bar);
| ^^^
@@ -201,7 +213,7 @@ LL | asm!("", in("eax") foo, in("al") bar);
= note: register class `reg_byte` supports these types: i8
error: type `i32` cannot be used with this register class
--> $DIR/bad-reg.rs:69:27
--> $DIR/bad-reg.rs:73:27
|
LL | asm!("", in("al") foo, lateout("al") bar);
| ^^^
@@ -209,12 +221,12 @@ LL | asm!("", in("al") foo, lateout("al") bar);
= note: register class `reg_byte` supports these types: i8
error: type `i32` cannot be used with this register class
--> $DIR/bad-reg.rs:69:46
--> $DIR/bad-reg.rs:73:46
|
LL | asm!("", in("al") foo, lateout("al") bar);
| ^^^
|
= note: register class `reg_byte` supports these types: i8
error: aborting due to 28 previous errors
error: aborting due to 30 previous errors
+4
View File
@@ -35,6 +35,10 @@ fn main() {
//~^ ERROR invalid register `rsp`: the stack pointer cannot be used as an operand
asm!("", in("ip") foo);
//~^ ERROR invalid register `ip`: the instruction pointer cannot be used as an operand
asm!("", in("bl") foo);
//~^ ERROR cannot use register `bl`: rbx is used internally by LLVM and cannot be used as an operand for inline asm
asm!("", in("bh") foo);
//~^ ERROR cannot use register `bh`: rbx is used internally by LLVM and cannot be used as an operand for inline asm
asm!("", in("st(2)") foo);
//~^ ERROR register class `x87_reg` can only be used as a clobber, not as an input or output
+40 -28
View File
@@ -67,49 +67,49 @@ LL | asm!("", in("ip") foo);
| ^^^^^^^^^^^^
error: register class `x87_reg` can only be used as a clobber, not as an input or output
--> $DIR/bad-reg.rs:39:18
--> $DIR/bad-reg.rs:43:18
|
LL | asm!("", in("st(2)") foo);
| ^^^^^^^^^^^^^^^
error: register class `mmx_reg` can only be used as a clobber, not as an input or output
--> $DIR/bad-reg.rs:42:18
--> $DIR/bad-reg.rs:46:18
|
LL | asm!("", in("mm0") foo);
| ^^^^^^^^^^^^^
error: register class `kreg0` can only be used as a clobber, not as an input or output
--> $DIR/bad-reg.rs:45:18
--> $DIR/bad-reg.rs:49:18
|
LL | asm!("", in("k0") foo);
| ^^^^^^^^^^^^
error: register class `x87_reg` can only be used as a clobber, not as an input or output
--> $DIR/bad-reg.rs:50:20
--> $DIR/bad-reg.rs:54:20
|
LL | asm!("{}", in(x87_reg) foo);
| ^^^^^^^^^^^^^^^
error: register class `mmx_reg` can only be used as a clobber, not as an input or output
--> $DIR/bad-reg.rs:53:20
--> $DIR/bad-reg.rs:57:20
|
LL | asm!("{}", in(mmx_reg) foo);
| ^^^^^^^^^^^^^^^
error: register class `x87_reg` can only be used as a clobber, not as an input or output
--> $DIR/bad-reg.rs:56:20
--> $DIR/bad-reg.rs:60:20
|
LL | asm!("{}", out(x87_reg) _);
| ^^^^^^^^^^^^^^
error: register class `mmx_reg` can only be used as a clobber, not as an input or output
--> $DIR/bad-reg.rs:58:20
--> $DIR/bad-reg.rs:62:20
|
LL | asm!("{}", out(mmx_reg) _);
| ^^^^^^^^^^^^^^
error: register `al` conflicts with register `eax`
--> $DIR/bad-reg.rs:64:33
--> $DIR/bad-reg.rs:68:33
|
LL | asm!("", in("eax") foo, in("al") bar);
| ------------- ^^^^^^^^^^^^ register `al`
@@ -117,7 +117,7 @@ LL | asm!("", in("eax") foo, in("al") bar);
| register `eax`
error: register `rax` conflicts with register `rax`
--> $DIR/bad-reg.rs:67:33
--> $DIR/bad-reg.rs:71:33
|
LL | asm!("", in("rax") foo, out("rax") bar);
| ------------- ^^^^^^^^^^^^^^ register `rax`
@@ -125,13 +125,13 @@ LL | asm!("", in("rax") foo, out("rax") bar);
| register `rax`
|
help: use `lateout` instead of `out` to avoid conflict
--> $DIR/bad-reg.rs:67:18
--> $DIR/bad-reg.rs:71:18
|
LL | asm!("", in("rax") foo, out("rax") bar);
| ^^^^^^^^^^^^^
error: register `ymm0` conflicts with register `xmm0`
--> $DIR/bad-reg.rs:72:34
--> $DIR/bad-reg.rs:76:34
|
LL | asm!("", in("xmm0") foo, in("ymm0") bar);
| -------------- ^^^^^^^^^^^^^^ register `ymm0`
@@ -139,7 +139,7 @@ LL | asm!("", in("xmm0") foo, in("ymm0") bar);
| register `xmm0`
error: register `ymm0` conflicts with register `xmm0`
--> $DIR/bad-reg.rs:74:34
--> $DIR/bad-reg.rs:78:34
|
LL | asm!("", in("xmm0") foo, out("ymm0") bar);
| -------------- ^^^^^^^^^^^^^^^ register `ymm0`
@@ -147,13 +147,25 @@ LL | asm!("", in("xmm0") foo, out("ymm0") bar);
| register `xmm0`
|
help: use `lateout` instead of `out` to avoid conflict
--> $DIR/bad-reg.rs:74:18
--> $DIR/bad-reg.rs:78:18
|
LL | asm!("", in("xmm0") foo, out("ymm0") bar);
| ^^^^^^^^^^^^^^
error: cannot use register `bl`: rbx is used internally by LLVM and cannot be used as an operand for inline asm
--> $DIR/bad-reg.rs:38:18
|
LL | asm!("", in("bl") foo);
| ^^^^^^^^^^^^
error: cannot use register `bh`: rbx is used internally by LLVM and cannot be used as an operand for inline asm
--> $DIR/bad-reg.rs:40:18
|
LL | asm!("", in("bh") foo);
| ^^^^^^^^^^^^
error: type `i32` cannot be used with this register class
--> $DIR/bad-reg.rs:39:30
--> $DIR/bad-reg.rs:43:30
|
LL | asm!("", in("st(2)") foo);
| ^^^
@@ -161,7 +173,7 @@ LL | asm!("", in("st(2)") foo);
= note: register class `x87_reg` supports these types:
error: type `i32` cannot be used with this register class
--> $DIR/bad-reg.rs:42:28
--> $DIR/bad-reg.rs:46:28
|
LL | asm!("", in("mm0") foo);
| ^^^
@@ -169,7 +181,7 @@ LL | asm!("", in("mm0") foo);
= note: register class `mmx_reg` supports these types:
error: type `i32` cannot be used with this register class
--> $DIR/bad-reg.rs:45:27
--> $DIR/bad-reg.rs:49:27
|
LL | asm!("", in("k0") foo);
| ^^^
@@ -177,7 +189,7 @@ LL | asm!("", in("k0") foo);
= note: register class `kreg0` supports these types:
error: type `i32` cannot be used with this register class
--> $DIR/bad-reg.rs:50:32
--> $DIR/bad-reg.rs:54:32
|
LL | asm!("{}", in(x87_reg) foo);
| ^^^
@@ -185,7 +197,7 @@ LL | asm!("{}", in(x87_reg) foo);
= note: register class `x87_reg` supports these types:
error: type `i32` cannot be used with this register class
--> $DIR/bad-reg.rs:53:32
--> $DIR/bad-reg.rs:57:32
|
LL | asm!("{}", in(mmx_reg) foo);
| ^^^
@@ -193,7 +205,7 @@ LL | asm!("{}", in(mmx_reg) foo);
= note: register class `mmx_reg` supports these types:
error: type `i32` cannot be used with this register class
--> $DIR/bad-reg.rs:64:42
--> $DIR/bad-reg.rs:68:42
|
LL | asm!("", in("eax") foo, in("al") bar);
| ^^^
@@ -201,7 +213,7 @@ LL | asm!("", in("eax") foo, in("al") bar);
= note: register class `reg_byte` supports these types: i8
error: type `i32` cannot be used with this register class
--> $DIR/bad-reg.rs:69:27
--> $DIR/bad-reg.rs:73:27
|
LL | asm!("", in("al") foo, lateout("al") bar);
| ^^^
@@ -209,7 +221,7 @@ LL | asm!("", in("al") foo, lateout("al") bar);
= note: register class `reg_byte` supports these types: i8
error: type `i32` cannot be used with this register class
--> $DIR/bad-reg.rs:69:46
--> $DIR/bad-reg.rs:73:46
|
LL | asm!("", in("al") foo, lateout("al") bar);
| ^^^
@@ -217,7 +229,7 @@ LL | asm!("", in("al") foo, lateout("al") bar);
= note: register class `reg_byte` supports these types: i8
error[E0658]: type `u128` cannot be used with this register class in stable
--> $DIR/bad-reg.rs:81:40
--> $DIR/bad-reg.rs:85:40
|
LL | asm!("/* {:x} */", in(xmm_reg) xmmword); // requires asm_experimental_reg
| ^^^^^^^
@@ -227,7 +239,7 @@ LL | asm!("/* {:x} */", in(xmm_reg) xmmword); // requires asm_experiment
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
error[E0658]: type `u128` cannot be used with this register class in stable
--> $DIR/bad-reg.rs:83:41
--> $DIR/bad-reg.rs:87:41
|
LL | asm!("/* {:x} */", out(xmm_reg) xmmword); // requires asm_experimental_reg
| ^^^^^^^
@@ -237,7 +249,7 @@ LL | asm!("/* {:x} */", out(xmm_reg) xmmword); // requires asm_experimen
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
error[E0658]: type `u128` cannot be used with this register class in stable
--> $DIR/bad-reg.rs:86:40
--> $DIR/bad-reg.rs:90:40
|
LL | asm!("/* {:y} */", in(ymm_reg) xmmword); // requires asm_experimental_reg
| ^^^^^^^
@@ -247,7 +259,7 @@ LL | asm!("/* {:y} */", in(ymm_reg) xmmword); // requires asm_experiment
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
error[E0658]: type `u128` cannot be used with this register class in stable
--> $DIR/bad-reg.rs:88:41
--> $DIR/bad-reg.rs:92:41
|
LL | asm!("/* {:y} */", out(ymm_reg) xmmword); // requires asm_experimental_reg
| ^^^^^^^
@@ -257,7 +269,7 @@ LL | asm!("/* {:y} */", out(ymm_reg) xmmword); // requires asm_experimen
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
error[E0658]: type `u128` cannot be used with this register class in stable
--> $DIR/bad-reg.rs:91:40
--> $DIR/bad-reg.rs:95:40
|
LL | asm!("/* {:z} */", in(zmm_reg) xmmword); // requires asm_experimental_reg
| ^^^^^^^
@@ -267,7 +279,7 @@ LL | asm!("/* {:z} */", in(zmm_reg) xmmword); // requires asm_experiment
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
error[E0658]: type `u128` cannot be used with this register class in stable
--> $DIR/bad-reg.rs:93:41
--> $DIR/bad-reg.rs:97:41
|
LL | asm!("/* {:z} */", out(zmm_reg) xmmword); // requires asm_experimental_reg
| ^^^^^^^
@@ -276,6 +288,6 @@ LL | asm!("/* {:z} */", out(zmm_reg) xmmword); // requires asm_experimen
= 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 34 previous errors
error: aborting due to 36 previous errors
For more information about this error, try `rustc --explain E0658`.