Skip to content

Commit b1bcff0

Browse files
committed
Disallow the use of high byte registes as operands on x86_64
They are still allowed on x86 though. Fixes #83495
1 parent cbd6ec7 commit b1bcff0

File tree

8 files changed

+25
-24
lines changed

8 files changed

+25
-24
lines changed

compiler/rustc_target/src/asm/arm.rs

-2
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,6 @@ fn frame_pointer_r11(
6868
_arch: InlineAsmArch,
6969
has_feature: impl FnMut(&str) -> bool,
7070
target: &Target,
71-
_allocating: bool,
7271
) -> Result<(), &'static str> {
7372
if !frame_pointer_is_r7(has_feature, target) {
7473
Err("the frame pointer (r11) cannot be used as an operand for inline asm")
@@ -81,7 +80,6 @@ fn frame_pointer_r7(
8180
_arch: InlineAsmArch,
8281
has_feature: impl FnMut(&str) -> bool,
8382
target: &Target,
84-
_allocating: bool,
8583
) -> Result<(), &'static str> {
8684
if frame_pointer_is_r7(has_feature, target) {
8785
Err("the frame pointer (r7) cannot be used as an operand for inline asm")

compiler/rustc_target/src/asm/mod.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,7 @@ macro_rules! def_regs {
9090
match name {
9191
$(
9292
$($alias)|* | $reg_name => {
93-
$($filter(_arch, &mut _has_feature, _target, false)?;)?
93+
$($filter(_arch, &mut _has_feature, _target)?;)?
9494
Ok(Self::$reg)
9595
}
9696
)*
@@ -114,7 +114,7 @@ macro_rules! def_regs {
114114
#[allow(unused_imports)]
115115
use super::{InlineAsmReg, InlineAsmRegClass};
116116
$(
117-
if $($filter(_arch, &mut _has_feature, _target, true).is_ok() &&)? true {
117+
if $($filter(_arch, &mut _has_feature, _target).is_ok() &&)? true {
118118
if let Some(set) = _map.get_mut(&InlineAsmRegClass::$arch($arch_regclass::$class)) {
119119
set.insert(InlineAsmReg::$arch($arch_reg::$reg));
120120
}

compiler/rustc_target/src/asm/riscv.rs

-1
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,6 @@ fn not_e(
5252
_arch: InlineAsmArch,
5353
mut has_feature: impl FnMut(&str) -> bool,
5454
_target: &Target,
55-
_allocating: bool,
5655
) -> Result<(), &'static str> {
5756
if has_feature("e") {
5857
Err("register can't be used with the `e` target feature")

compiler/rustc_target/src/asm/x86.rs

+1-6
Original file line numberDiff line numberDiff line change
@@ -133,7 +133,6 @@ fn x86_64_only(
133133
arch: InlineAsmArch,
134134
_has_feature: impl FnMut(&str) -> bool,
135135
_target: &Target,
136-
_allocating: bool,
137136
) -> Result<(), &'static str> {
138137
match arch {
139138
InlineAsmArch::X86 => Err("register is only available on x86_64"),
@@ -146,13 +145,9 @@ fn high_byte(
146145
arch: InlineAsmArch,
147146
_has_feature: impl FnMut(&str) -> bool,
148147
_target: &Target,
149-
allocating: bool,
150148
) -> Result<(), &'static str> {
151149
match arch {
152-
InlineAsmArch::X86_64 if allocating => {
153-
// The error message isn't actually used...
154-
Err("high byte registers are not allocated by reg_byte")
155-
}
150+
InlineAsmArch::X86_64 => Err("high byte registers cannot be used as an operand on x86_64"),
156151
_ => Ok(()),
157152
}
158153
}

src/doc/unstable-book/src/library-features/asm.md

+2-2
Original file line numberDiff line numberDiff line change
@@ -495,7 +495,7 @@ Here is the list of currently supported register classes:
495495
| x86 | `reg` | `ax`, `bx`, `cx`, `dx`, `si`, `di`, `r[8-15]` (x86-64 only) | `r` |
496496
| x86 | `reg_abcd` | `ax`, `bx`, `cx`, `dx` | `Q` |
497497
| x86-32 | `reg_byte` | `al`, `bl`, `cl`, `dl`, `ah`, `bh`, `ch`, `dh` | `q` |
498-
| x86-64 | `reg_byte` | `al`, `bl`, `cl`, `dl`, `sil`, `dil`, `r[8-15]b`, `ah`\*, `bh`\*, `ch`\*, `dh`\* | `q` |
498+
| x86-64 | `reg_byte`\* | `al`, `bl`, `cl`, `dl`, `sil`, `dil`, `r[8-15]b` | `q` |
499499
| x86 | `xmm_reg` | `xmm[0-7]` (x86) `xmm[0-15]` (x86-64) | `x` |
500500
| x86 | `ymm_reg` | `ymm[0-7]` (x86) `ymm[0-15]` (x86-64) | `x` |
501501
| x86 | `zmm_reg` | `zmm[0-7]` (x86) `zmm[0-31]` (x86-64) | `v` |
@@ -526,7 +526,7 @@ Here is the list of currently supported register classes:
526526

527527
> **Note**: On x86 we treat `reg_byte` differently from `reg` because the compiler can allocate `al` and `ah` separately whereas `reg` reserves the whole register.
528528
>
529-
> Note #2: On x86-64 the high byte registers (e.g. `ah`) are only available when used as an explicit register. Specifying the `reg_byte` register class for an operand will always allocate a low byte register.
529+
> Note #2: On x86-64 the high byte registers (e.g. `ah`) are not available in the `reg_byte` register class.
530530
>
531531
> Note #3: NVPTX doesn't have a fixed register set, so named registers are not supported.
532532
>

src/test/assembly/asm/x86-types.rs

+5-4
Original file line numberDiff line numberDiff line change
@@ -748,10 +748,11 @@ check_reg!(eax_f64 f64 "eax" "mov");
748748
// CHECK: #NO_APP
749749
check_reg!(eax_ptr ptr "eax" "mov");
750750

751-
// CHECK-LABEL: ah_byte:
752-
// CHECK: #APP
753-
// CHECK: mov ah, ah
754-
// CHECK: #NO_APP
751+
// i686-LABEL: ah_byte:
752+
// i686: #APP
753+
// i686: mov ah, ah
754+
// i686: #NO_APP
755+
#[cfg(i686)]
755756
check_reg!(ah_byte i8 "ah" "mov");
756757

757758
// CHECK-LABEL: xmm0_i32:

src/test/ui/asm/bad-reg.rs

+2
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,8 @@ fn main() {
3737
//~^ ERROR invalid register `mm0`: MMX registers are not currently supported as operands
3838
asm!("", in("k0") foo);
3939
//~^ ERROR invalid register `k0`: the k0 AVX mask register cannot be used as an operand
40+
asm!("", in("ah") foo);
41+
//~^ ERROR invalid register `ah`: high byte registers cannot be used as an operand
4042

4143
// Explicit register conflicts
4244
// (except in/lateout which don't conflict)

src/test/ui/asm/bad-reg.stderr

+13-7
Original file line numberDiff line numberDiff line change
@@ -94,49 +94,55 @@ error: invalid register `k0`: the k0 AVX mask register cannot be used as an oper
9494
LL | asm!("", in("k0") foo);
9595
| ^^^^^^^^^^^^
9696

97+
error: invalid register `ah`: high byte registers cannot be used as an operand on x86_64
98+
--> $DIR/bad-reg.rs:40:18
99+
|
100+
LL | asm!("", in("ah") foo);
101+
| ^^^^^^^^^^^^
102+
97103
error: register `al` conflicts with register `ax`
98-
--> $DIR/bad-reg.rs:44:33
104+
--> $DIR/bad-reg.rs:46:33
99105
|
100106
LL | asm!("", in("eax") foo, in("al") bar);
101107
| ------------- ^^^^^^^^^^^^ register `al`
102108
| |
103109
| register `ax`
104110

105111
error: register `ax` conflicts with register `ax`
106-
--> $DIR/bad-reg.rs:46:33
112+
--> $DIR/bad-reg.rs:48:33
107113
|
108114
LL | asm!("", in("rax") foo, out("rax") bar);
109115
| ------------- ^^^^^^^^^^^^^^ register `ax`
110116
| |
111117
| register `ax`
112118
|
113119
help: use `lateout` instead of `out` to avoid conflict
114-
--> $DIR/bad-reg.rs:46:18
120+
--> $DIR/bad-reg.rs:48:18
115121
|
116122
LL | asm!("", in("rax") foo, out("rax") bar);
117123
| ^^^^^^^^^^^^^
118124

119125
error: register `ymm0` conflicts with register `xmm0`
120-
--> $DIR/bad-reg.rs:49:34
126+
--> $DIR/bad-reg.rs:51:34
121127
|
122128
LL | asm!("", in("xmm0") foo, in("ymm0") bar);
123129
| -------------- ^^^^^^^^^^^^^^ register `ymm0`
124130
| |
125131
| register `xmm0`
126132

127133
error: register `ymm0` conflicts with register `xmm0`
128-
--> $DIR/bad-reg.rs:51:34
134+
--> $DIR/bad-reg.rs:53:34
129135
|
130136
LL | asm!("", in("xmm0") foo, out("ymm0") bar);
131137
| -------------- ^^^^^^^^^^^^^^^ register `ymm0`
132138
| |
133139
| register `xmm0`
134140
|
135141
help: use `lateout` instead of `out` to avoid conflict
136-
--> $DIR/bad-reg.rs:51:18
142+
--> $DIR/bad-reg.rs:53:18
137143
|
138144
LL | asm!("", in("xmm0") foo, out("ymm0") bar);
139145
| ^^^^^^^^^^^^^^
140146

141-
error: aborting due to 18 previous errors
147+
error: aborting due to 19 previous errors
142148

0 commit comments

Comments
 (0)