asm: Add a kreg0 register class on x86 which includes k0

Previously we only exposed a kreg register class which excludes the k0
register since it can't be used in many instructions. However k0 is a
valid register and we need to have a way of marking it as clobbered for
clobber_abi.

Fixes #94977
This commit is contained in:
Amanieu d'Antras 2022-04-06 20:41:12 +01:00
parent 634770c0a7
commit b2bc46938c
8 changed files with 40 additions and 25 deletions

View File

@ -581,6 +581,7 @@ fn reg_to_gcc(reg: InlineAsmRegOrRegClass) -> ConstraintOrRegister {
| InlineAsmRegClass::X86(X86InlineAsmRegClass::ymm_reg) => "x", | InlineAsmRegClass::X86(X86InlineAsmRegClass::ymm_reg) => "x",
InlineAsmRegClass::X86(X86InlineAsmRegClass::zmm_reg) => "v", InlineAsmRegClass::X86(X86InlineAsmRegClass::zmm_reg) => "v",
InlineAsmRegClass::X86(X86InlineAsmRegClass::kreg) => unimplemented!(), InlineAsmRegClass::X86(X86InlineAsmRegClass::kreg) => unimplemented!(),
InlineAsmRegClass::X86(X86InlineAsmRegClass::kreg0) => unimplemented!(),
InlineAsmRegClass::Wasm(WasmInlineAsmRegClass::local) => unimplemented!(), InlineAsmRegClass::Wasm(WasmInlineAsmRegClass::local) => unimplemented!(),
InlineAsmRegClass::X86( InlineAsmRegClass::X86(
X86InlineAsmRegClass::x87_reg | X86InlineAsmRegClass::mmx_reg, X86InlineAsmRegClass::x87_reg | X86InlineAsmRegClass::mmx_reg,
@ -646,6 +647,7 @@ fn dummy_output_type<'gcc, 'tcx>(cx: &CodegenCx<'gcc, 'tcx>, reg: InlineAsmRegCl
| InlineAsmRegClass::X86(X86InlineAsmRegClass::zmm_reg) => cx.type_f32(), | InlineAsmRegClass::X86(X86InlineAsmRegClass::zmm_reg) => cx.type_f32(),
InlineAsmRegClass::X86(X86InlineAsmRegClass::x87_reg) => unimplemented!(), InlineAsmRegClass::X86(X86InlineAsmRegClass::x87_reg) => unimplemented!(),
InlineAsmRegClass::X86(X86InlineAsmRegClass::kreg) => cx.type_i16(), InlineAsmRegClass::X86(X86InlineAsmRegClass::kreg) => cx.type_i16(),
InlineAsmRegClass::X86(X86InlineAsmRegClass::kreg0) => cx.type_i16(),
InlineAsmRegClass::Wasm(WasmInlineAsmRegClass::local) => cx.type_i32(), InlineAsmRegClass::Wasm(WasmInlineAsmRegClass::local) => cx.type_i32(),
InlineAsmRegClass::SpirV(SpirVInlineAsmRegClass::reg) => { InlineAsmRegClass::SpirV(SpirVInlineAsmRegClass::reg) => {
bug!("LLVM backend does not support SPIR-V") bug!("LLVM backend does not support SPIR-V")
@ -760,6 +762,7 @@ fn modifier_to_gcc(arch: InlineAsmArch, reg: InlineAsmRegClass, modifier: Option
_ => unreachable!(), _ => unreachable!(),
}, },
InlineAsmRegClass::X86(X86InlineAsmRegClass::kreg) => None, InlineAsmRegClass::X86(X86InlineAsmRegClass::kreg) => None,
InlineAsmRegClass::X86(X86InlineAsmRegClass::kreg0) => None,
InlineAsmRegClass::X86(X86InlineAsmRegClass::x87_reg | X86InlineAsmRegClass::mmx_reg) => { InlineAsmRegClass::X86(X86InlineAsmRegClass::x87_reg | X86InlineAsmRegClass::mmx_reg) => {
unreachable!("clobber-only") unreachable!("clobber-only")
} }

View File

@ -574,7 +574,9 @@ fn reg_to_llvm(reg: InlineAsmRegOrRegClass, layout: Option<&TyAndLayout<'_>>) ->
InlineAsmRegClass::X86(X86InlineAsmRegClass::zmm_reg) => "v", InlineAsmRegClass::X86(X86InlineAsmRegClass::zmm_reg) => "v",
InlineAsmRegClass::X86(X86InlineAsmRegClass::kreg) => "^Yk", InlineAsmRegClass::X86(X86InlineAsmRegClass::kreg) => "^Yk",
InlineAsmRegClass::X86( InlineAsmRegClass::X86(
X86InlineAsmRegClass::x87_reg | X86InlineAsmRegClass::mmx_reg, X86InlineAsmRegClass::x87_reg
| X86InlineAsmRegClass::mmx_reg
| X86InlineAsmRegClass::kreg0,
) => unreachable!("clobber-only"), ) => unreachable!("clobber-only"),
InlineAsmRegClass::Wasm(WasmInlineAsmRegClass::local) => "r", InlineAsmRegClass::Wasm(WasmInlineAsmRegClass::local) => "r",
InlineAsmRegClass::Bpf(BpfInlineAsmRegClass::reg) => "r", InlineAsmRegClass::Bpf(BpfInlineAsmRegClass::reg) => "r",
@ -659,7 +661,11 @@ fn modifier_to_llvm(
_ => unreachable!(), _ => unreachable!(),
}, },
InlineAsmRegClass::X86(X86InlineAsmRegClass::kreg) => None, InlineAsmRegClass::X86(X86InlineAsmRegClass::kreg) => None,
InlineAsmRegClass::X86(X86InlineAsmRegClass::x87_reg | X86InlineAsmRegClass::mmx_reg) => { InlineAsmRegClass::X86(
X86InlineAsmRegClass::x87_reg
| X86InlineAsmRegClass::mmx_reg
| X86InlineAsmRegClass::kreg0,
) => {
unreachable!("clobber-only") unreachable!("clobber-only")
} }
InlineAsmRegClass::Wasm(WasmInlineAsmRegClass::local) => None, InlineAsmRegClass::Wasm(WasmInlineAsmRegClass::local) => None,
@ -729,7 +735,11 @@ fn dummy_output_type<'ll>(cx: &CodegenCx<'ll, '_>, reg: InlineAsmRegClass) -> &'
| InlineAsmRegClass::X86(X86InlineAsmRegClass::ymm_reg) | InlineAsmRegClass::X86(X86InlineAsmRegClass::ymm_reg)
| InlineAsmRegClass::X86(X86InlineAsmRegClass::zmm_reg) => cx.type_f32(), | InlineAsmRegClass::X86(X86InlineAsmRegClass::zmm_reg) => cx.type_f32(),
InlineAsmRegClass::X86(X86InlineAsmRegClass::kreg) => cx.type_i16(), InlineAsmRegClass::X86(X86InlineAsmRegClass::kreg) => cx.type_i16(),
InlineAsmRegClass::X86(X86InlineAsmRegClass::x87_reg | X86InlineAsmRegClass::mmx_reg) => { InlineAsmRegClass::X86(
X86InlineAsmRegClass::x87_reg
| X86InlineAsmRegClass::mmx_reg
| X86InlineAsmRegClass::kreg0,
) => {
unreachable!("clobber-only") unreachable!("clobber-only")
} }
InlineAsmRegClass::Wasm(WasmInlineAsmRegClass::local) => cx.type_i32(), InlineAsmRegClass::Wasm(WasmInlineAsmRegClass::local) => cx.type_i32(),

View File

@ -803,6 +803,7 @@
keyword, keyword,
kind, kind,
kreg, kreg,
kreg0,
label, label,
label_break_value, label_break_value,
lang, lang,

View File

@ -893,7 +893,7 @@ macro_rules! clobbered_regs {
xmm0, xmm1, xmm2, xmm3, xmm4, xmm5, xmm6, xmm7, xmm0, xmm1, xmm2, xmm3, xmm4, xmm5, xmm6, xmm7,
k1, k2, k3, k4, k5, k6, k7, k0, k1, k2, k3, k4, k5, k6, k7,
mm0, mm1, mm2, mm3, mm4, mm5, mm6, mm7, mm0, mm1, mm2, mm3, mm4, mm5, mm6, mm7,
st0, st1, st2, st3, st4, st5, st6, st7, st0, st1, st2, st3, st4, st5, st6, st7,
@ -908,7 +908,7 @@ macro_rules! clobbered_regs {
zmm16, zmm17, zmm18, zmm19, zmm20, zmm21, zmm22, zmm23, zmm16, zmm17, zmm18, zmm19, zmm20, zmm21, zmm22, zmm23,
zmm24, zmm25, zmm26, zmm27, zmm28, zmm29, zmm30, zmm31, zmm24, zmm25, zmm26, zmm27, zmm28, zmm29, zmm30, zmm31,
k1, k2, k3, k4, k5, k6, k7, k0, k1, k2, k3, k4, k5, k6, k7,
mm0, mm1, mm2, mm3, mm4, mm5, mm6, mm7, mm0, mm1, mm2, mm3, mm4, mm5, mm6, mm7,
st0, st1, st2, st3, st4, st5, st6, st7, st0, st1, st2, st3, st4, st5, st6, st7,
@ -927,7 +927,7 @@ macro_rules! clobbered_regs {
zmm16, zmm17, zmm18, zmm19, zmm20, zmm21, zmm22, zmm23, zmm16, zmm17, zmm18, zmm19, zmm20, zmm21, zmm22, zmm23,
zmm24, zmm25, zmm26, zmm27, zmm28, zmm29, zmm30, zmm31, zmm24, zmm25, zmm26, zmm27, zmm28, zmm29, zmm30, zmm31,
k1, k2, k3, k4, k5, k6, k7, k0, k1, k2, k3, k4, k5, k6, k7,
mm0, mm1, mm2, mm3, mm4, mm5, mm6, mm7, mm0, mm1, mm2, mm3, mm4, mm5, mm6, mm7,
st0, st1, st2, st3, st4, st5, st6, st7, st0, st1, st2, st3, st4, st5, st6, st7,

View File

@ -14,6 +14,7 @@
ymm_reg, ymm_reg,
zmm_reg, zmm_reg,
kreg, kreg,
kreg0,
mmx_reg, mmx_reg,
x87_reg, x87_reg,
} }
@ -38,7 +39,7 @@ pub fn valid_modifiers(self, arch: super::InlineAsmArch) -> &'static [char] {
} }
Self::reg_byte => &[], Self::reg_byte => &[],
Self::xmm_reg | Self::ymm_reg | Self::zmm_reg => &['x', 'y', 'z'], Self::xmm_reg | Self::ymm_reg | Self::zmm_reg => &['x', 'y', 'z'],
Self::kreg => &[], Self::kreg | Self::kreg0 => &[],
Self::mmx_reg | Self::x87_reg => &[], Self::mmx_reg | Self::x87_reg => &[],
} }
} }
@ -77,7 +78,7 @@ pub fn suggest_modifier(
256 => Some(('y', "ymm0")), 256 => Some(('y', "ymm0")),
_ => Some(('x', "xmm0")), _ => Some(('x', "xmm0")),
}, },
Self::kreg => None, Self::kreg | Self::kreg0 => None,
Self::mmx_reg | Self::x87_reg => None, Self::mmx_reg | Self::x87_reg => None,
} }
} }
@ -95,7 +96,7 @@ pub fn default_modifier(self, arch: InlineAsmArch) -> Option<(char, &'static str
Self::xmm_reg => Some(('x', "xmm0")), Self::xmm_reg => Some(('x', "xmm0")),
Self::ymm_reg => Some(('y', "ymm0")), Self::ymm_reg => Some(('y', "ymm0")),
Self::zmm_reg => Some(('z', "zmm0")), Self::zmm_reg => Some(('z', "zmm0")),
Self::kreg => None, Self::kreg | Self::kreg0 => None,
Self::mmx_reg | Self::x87_reg => None, Self::mmx_reg | Self::x87_reg => None,
} }
} }
@ -132,6 +133,7 @@ pub fn supported_types(
avx512f: I8, I16; avx512f: I8, I16;
avx512bw: I32, I64; avx512bw: I32, I64;
}, },
Self::kreg0 => &[],
Self::mmx_reg | Self::x87_reg => &[], Self::mmx_reg | Self::x87_reg => &[],
} }
} }
@ -294,6 +296,7 @@ fn esi_reserved(
zmm29: zmm_reg = ["zmm29", "xmm29", "ymm29"] % x86_64_only, zmm29: zmm_reg = ["zmm29", "xmm29", "ymm29"] % x86_64_only,
zmm30: zmm_reg = ["zmm30", "xmm30", "ymm30"] % x86_64_only, zmm30: zmm_reg = ["zmm30", "xmm30", "ymm30"] % x86_64_only,
zmm31: zmm_reg = ["zmm31", "xmm31", "ymm31"] % x86_64_only, zmm31: zmm_reg = ["zmm31", "xmm31", "ymm31"] % x86_64_only,
k0: kreg0 = ["k0"],
k1: kreg = ["k1"], k1: kreg = ["k1"],
k2: kreg = ["k2"], k2: kreg = ["k2"],
k3: kreg = ["k3"], k3: kreg = ["k3"],
@ -323,8 +326,6 @@ fn esi_reserved(
"the stack pointer cannot be used as an operand for inline asm", "the stack pointer cannot be used as an operand for inline asm",
#error = ["ip", "eip", "rip"] => #error = ["ip", "eip", "rip"] =>
"the instruction pointer cannot be used as an operand for inline asm", "the instruction pointer cannot be used as an operand for inline asm",
#error = ["k0"] =>
"the k0 AVX mask register cannot be used as an operand for inline asm",
} }
} }

View File

@ -6,21 +6,21 @@
use std::arch::asm; use std::arch::asm;
// CHECK-LABEL: @clobber_sysv64 // CHECK-LABEL: @clobber_sysv64
// CHECK: ={ax},={cx},={dx},={si},={di},={r8},={r9},={r10},={r11},={xmm0},={xmm1},={xmm2},={xmm3},={xmm4},={xmm5},={xmm6},={xmm7},={xmm8},={xmm9},={xmm10},={xmm11},={xmm12},={xmm13},={xmm14},={xmm15},~{xmm16},~{xmm17},~{xmm18},~{xmm19},~{xmm20},~{xmm21},~{xmm22},~{xmm23},~{xmm24},~{xmm25},~{xmm26},~{xmm27},~{xmm28},~{xmm29},~{xmm30},~{xmm31},~{k1},~{k2},~{k3},~{k4},~{k5},~{k6},~{k7},~{st},~{st(1)},~{st(2)},~{st(3)},~{st(4)},~{st(5)},~{st(6)},~{st(7)},~{dirflag},~{fpsr},~{flags},~{memory} // CHECK: ={ax},={cx},={dx},={si},={di},={r8},={r9},={r10},={r11},={xmm0},={xmm1},={xmm2},={xmm3},={xmm4},={xmm5},={xmm6},={xmm7},={xmm8},={xmm9},={xmm10},={xmm11},={xmm12},={xmm13},={xmm14},={xmm15},~{xmm16},~{xmm17},~{xmm18},~{xmm19},~{xmm20},~{xmm21},~{xmm22},~{xmm23},~{xmm24},~{xmm25},~{xmm26},~{xmm27},~{xmm28},~{xmm29},~{xmm30},~{xmm31},~{k0},~{k1},~{k2},~{k3},~{k4},~{k5},~{k6},~{k7},~{st},~{st(1)},~{st(2)},~{st(3)},~{st(4)},~{st(5)},~{st(6)},~{st(7)},~{dirflag},~{fpsr},~{flags},~{memory}
#[no_mangle] #[no_mangle]
pub unsafe fn clobber_sysv64() { pub unsafe fn clobber_sysv64() {
asm!("", clobber_abi("sysv64")); asm!("", clobber_abi("sysv64"));
} }
// CHECK-LABEL: @clobber_win64 // CHECK-LABEL: @clobber_win64
// CHECK: ={ax},={cx},={dx},={r8},={r9},={r10},={r11},={xmm0},={xmm1},={xmm2},={xmm3},={xmm4},={xmm5},={xmm6},={xmm7},={xmm8},={xmm9},={xmm10},={xmm11},={xmm12},={xmm13},={xmm14},={xmm15},~{xmm16},~{xmm17},~{xmm18},~{xmm19},~{xmm20},~{xmm21},~{xmm22},~{xmm23},~{xmm24},~{xmm25},~{xmm26},~{xmm27},~{xmm28},~{xmm29},~{xmm30},~{xmm31},~{k1},~{k2},~{k3},~{k4},~{k5},~{k6},~{k7},~{st},~{st(1)},~{st(2)},~{st(3)},~{st(4)},~{st(5)},~{st(6)},~{st(7)},~{dirflag},~{fpsr},~{flags},~{memory} // CHECK: ={ax},={cx},={dx},={r8},={r9},={r10},={r11},={xmm0},={xmm1},={xmm2},={xmm3},={xmm4},={xmm5},={xmm6},={xmm7},={xmm8},={xmm9},={xmm10},={xmm11},={xmm12},={xmm13},={xmm14},={xmm15},~{xmm16},~{xmm17},~{xmm18},~{xmm19},~{xmm20},~{xmm21},~{xmm22},~{xmm23},~{xmm24},~{xmm25},~{xmm26},~{xmm27},~{xmm28},~{xmm29},~{xmm30},~{xmm31},~{k0},~{k1},~{k2},~{k3},~{k4},~{k5},~{k6},~{k7},~{st},~{st(1)},~{st(2)},~{st(3)},~{st(4)},~{st(5)},~{st(6)},~{st(7)},~{dirflag},~{fpsr},~{flags},~{memory}
#[no_mangle] #[no_mangle]
pub unsafe fn clobber_win64() { pub unsafe fn clobber_win64() {
asm!("", clobber_abi("win64")); asm!("", clobber_abi("win64"));
} }
// CHECK-LABEL: @clobber_sysv64 // CHECK-LABEL: @clobber_sysv64
// CHECK: =&{dx},={ax},={cx},={si},={di},={r8},={r9},={r10},={r11},={xmm0},={xmm1},={xmm2},={xmm3},={xmm4},={xmm5},={xmm6},={xmm7},={xmm8},={xmm9},={xmm10},={xmm11},={xmm12},={xmm13},={xmm14},={xmm15},~{xmm16},~{xmm17},~{xmm18},~{xmm19},~{xmm20},~{xmm21},~{xmm22},~{xmm23},~{xmm24},~{xmm25},~{xmm26},~{xmm27},~{xmm28},~{xmm29},~{xmm30},~{xmm31},~{k1},~{k2},~{k3},~{k4},~{k5},~{k6},~{k7},~{st},~{st(1)},~{st(2)},~{st(3)},~{st(4)},~{st(5)},~{st(6)},~{st(7)},~{dirflag},~{fpsr},~{flags},~{memory} // CHECK: =&{dx},={ax},={cx},={si},={di},={r8},={r9},={r10},={r11},={xmm0},={xmm1},={xmm2},={xmm3},={xmm4},={xmm5},={xmm6},={xmm7},={xmm8},={xmm9},={xmm10},={xmm11},={xmm12},={xmm13},={xmm14},={xmm15},~{xmm16},~{xmm17},~{xmm18},~{xmm19},~{xmm20},~{xmm21},~{xmm22},~{xmm23},~{xmm24},~{xmm25},~{xmm26},~{xmm27},~{xmm28},~{xmm29},~{xmm30},~{xmm31},~{k0},~{k1},~{k2},~{k3},~{k4},~{k5},~{k6},~{k7},~{st},~{st(1)},~{st(2)},~{st(3)},~{st(4)},~{st(5)},~{st(6)},~{st(7)},~{dirflag},~{fpsr},~{flags},~{memory}
#[no_mangle] #[no_mangle]
pub unsafe fn clobber_sysv64_edx() { pub unsafe fn clobber_sysv64_edx() {
let foo: i32; let foo: i32;
@ -28,7 +28,7 @@ pub unsafe fn clobber_sysv64_edx() {
} }
// CHECK-LABEL: @clobber_win64 // CHECK-LABEL: @clobber_win64
// CHECK: =&{dx},={ax},={cx},={r8},={r9},={r10},={r11},={xmm0},={xmm1},={xmm2},={xmm3},={xmm4},={xmm5},={xmm6},={xmm7},={xmm8},={xmm9},={xmm10},={xmm11},={xmm12},={xmm13},={xmm14},={xmm15},~{xmm16},~{xmm17},~{xmm18},~{xmm19},~{xmm20},~{xmm21},~{xmm22},~{xmm23},~{xmm24},~{xmm25},~{xmm26},~{xmm27},~{xmm28},~{xmm29},~{xmm30},~{xmm31},~{k1},~{k2},~{k3},~{k4},~{k5},~{k6},~{k7},~{st},~{st(1)},~{st(2)},~{st(3)},~{st(4)},~{st(5)},~{st(6)},~{st(7)},~{dirflag},~{fpsr},~{flags},~{memory} // CHECK: =&{dx},={ax},={cx},={r8},={r9},={r10},={r11},={xmm0},={xmm1},={xmm2},={xmm3},={xmm4},={xmm5},={xmm6},={xmm7},={xmm8},={xmm9},={xmm10},={xmm11},={xmm12},={xmm13},={xmm14},={xmm15},~{xmm16},~{xmm17},~{xmm18},~{xmm19},~{xmm20},~{xmm21},~{xmm22},~{xmm23},~{xmm24},~{xmm25},~{xmm26},~{xmm27},~{xmm28},~{xmm29},~{xmm30},~{xmm31},~{k0},~{k1},~{k2},~{k3},~{k4},~{k5},~{k6},~{k7},~{st},~{st(1)},~{st(2)},~{st(3)},~{st(4)},~{st(5)},~{st(6)},~{st(7)},~{dirflag},~{fpsr},~{flags},~{memory}
#[no_mangle] #[no_mangle]
pub unsafe fn clobber_win64_edx() { pub unsafe fn clobber_win64_edx() {
let foo: i32; let foo: i32;

View File

@ -29,13 +29,13 @@ fn main() {
//~^ ERROR invalid register `rsp`: the stack pointer cannot be used as an operand //~^ ERROR invalid register `rsp`: the stack pointer cannot be used as an operand
asm!("", in("ip") foo); asm!("", in("ip") foo);
//~^ ERROR invalid register `ip`: the instruction pointer cannot be used as an operand //~^ ERROR invalid register `ip`: the instruction pointer cannot be used as an operand
asm!("", in("k0") foo);
//~^ ERROR invalid register `k0`: the k0 AVX mask register cannot be used as an operand
asm!("", in("st(2)") foo); asm!("", in("st(2)") foo);
//~^ ERROR register class `x87_reg` can only be used as a clobber, not as an input or output //~^ ERROR register class `x87_reg` can only be used as a clobber, not as an input or output
asm!("", in("mm0") foo); asm!("", in("mm0") foo);
//~^ ERROR register class `mmx_reg` can only be used as a clobber, not as an input or output //~^ ERROR register class `mmx_reg` can only be used as a clobber, not as an input or output
asm!("", in("k0") foo);
//~^ ERROR register class `kreg0` can only be used as a clobber, not as an input or output
asm!("", out("st(2)") _); asm!("", out("st(2)") _);
asm!("", out("mm0") _); asm!("", out("mm0") _);
asm!("{}", in(x87_reg) foo); asm!("{}", in(x87_reg) foo);

View File

@ -64,24 +64,24 @@ error: invalid register `ip`: the instruction pointer cannot be used as an opera
LL | asm!("", in("ip") foo); LL | asm!("", in("ip") foo);
| ^^^^^^^^^^^^ | ^^^^^^^^^^^^
error: invalid register `k0`: the k0 AVX mask register cannot be used as an operand for inline asm
--> $DIR/bad-reg.rs:32:18
|
LL | asm!("", in("k0") foo);
| ^^^^^^^^^^^^
error: register class `x87_reg` can only be used as a clobber, not as an input or output error: register class `x87_reg` can only be used as a clobber, not as an input or output
--> $DIR/bad-reg.rs:35:18 --> $DIR/bad-reg.rs:33:18
| |
LL | asm!("", in("st(2)") foo); LL | asm!("", in("st(2)") foo);
| ^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^
error: register class `mmx_reg` can only be used as a clobber, not as an input or output error: register class `mmx_reg` can only be used as a clobber, not as an input or output
--> $DIR/bad-reg.rs:37:18 --> $DIR/bad-reg.rs:35:18
| |
LL | asm!("", in("mm0") foo); 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:37:18
|
LL | asm!("", in("k0") foo);
| ^^^^^^^^^^^^
error: register class `x87_reg` can only be used as a clobber, not as an input or output error: register class `x87_reg` can only be used as a clobber, not as an input or output
--> $DIR/bad-reg.rs:41:20 --> $DIR/bad-reg.rs:41:20
| |