rust/tests/ui/asm/riscv/bad-reg.rs
Taiki Endo b07232d95d Move tests/ui/abi/riscv32e-registers.rs to tests/ui/asm/riscv
This also adds comments explaining the difference to bad-reg.rs.
2024-11-03 18:32:04 +09:00

110 lines
5.3 KiB
Rust

//@ add-core-stubs
//@ needs-asm-support
//@ revisions: riscv32i riscv32imafc riscv32gc riscv32e riscv64imac riscv64gc
//@[riscv32i] compile-flags: --target riscv32i-unknown-none-elf
//@[riscv32i] needs-llvm-components: riscv
//@[riscv32imafc] compile-flags: --target riscv32imafc-unknown-none-elf
//@[riscv32imafc] needs-llvm-components: riscv
//@[riscv32gc] compile-flags: --target riscv32gc-unknown-linux-gnu
//@[riscv32gc] needs-llvm-components: riscv
//@[riscv32e] compile-flags: --target riscv32e-unknown-none-elf
//@[riscv32e] needs-llvm-components: riscv
//@[riscv64imac] compile-flags: --target riscv64imac-unknown-none-elf
//@[riscv64imac] needs-llvm-components: riscv
//@[riscv64gc] compile-flags: --target riscv64gc-unknown-linux-gnu
//@[riscv64gc] needs-llvm-components: riscv
// Unlike riscv32e-registers.rs, this tests if the rustc can reject invalid registers
// usage in the asm! API (in, out, inout, etc.).
#![crate_type = "lib"]
#![feature(no_core, rustc_attrs)]
#![feature(asm_experimental_arch)]
#![no_core]
extern crate minicore;
use minicore::*;
fn f() {
let mut x = 0;
let mut f = 0.0_f32;
let mut d = 0.0_f64;
unsafe {
// Unsupported registers
asm!("", out("s1") _);
//~^ ERROR invalid register `s1`: s1 is used internally by LLVM and cannot be used as an operand for inline asm
asm!("", out("fp") _);
//~^ ERROR invalid register `fp`: the frame pointer cannot be used as an operand for inline asm
asm!("", out("sp") _);
//~^ ERROR invalid register `sp`: the stack pointer cannot be used as an operand for inline asm
asm!("", out("gp") _);
//~^ ERROR invalid register `gp`: the global pointer cannot be used as an operand for inline asm
asm!("", out("gp") _);
//~^ ERROR invalid register `gp`: the global pointer cannot be used as an operand for inline asm
asm!("", out("tp") _);
//~^ ERROR invalid register `tp`: the thread pointer cannot be used as an operand for inline asm
asm!("", out("zero") _);
//~^ ERROR invalid register `zero`: the zero register cannot be used as an operand for inline asm
asm!("", out("x16") _);
//[riscv32e]~^ ERROR register can't be used with the `e` target feature
asm!("", out("x17") _);
//[riscv32e]~^ ERROR register can't be used with the `e` target feature
asm!("", out("x18") _);
//[riscv32e]~^ ERROR register can't be used with the `e` target feature
asm!("", out("x19") _);
//[riscv32e]~^ ERROR register can't be used with the `e` target feature
asm!("", out("x20") _);
//[riscv32e]~^ ERROR register can't be used with the `e` target feature
asm!("", out("x21") _);
//[riscv32e]~^ ERROR register can't be used with the `e` target feature
asm!("", out("x22") _);
//[riscv32e]~^ ERROR register can't be used with the `e` target feature
asm!("", out("x23") _);
//[riscv32e]~^ ERROR register can't be used with the `e` target feature
asm!("", out("x24") _);
//[riscv32e]~^ ERROR register can't be used with the `e` target feature
asm!("", out("x25") _);
//[riscv32e]~^ ERROR register can't be used with the `e` target feature
asm!("", out("x26") _);
//[riscv32e]~^ ERROR register can't be used with the `e` target feature
asm!("", out("x27") _);
//[riscv32e]~^ ERROR register can't be used with the `e` target feature
asm!("", out("x28") _);
//[riscv32e]~^ ERROR register can't be used with the `e` target feature
asm!("", out("x29") _);
//[riscv32e]~^ ERROR register can't be used with the `e` target feature
asm!("", out("x30") _);
//[riscv32e]~^ ERROR register can't be used with the `e` target feature
asm!("", out("x31") _);
//[riscv32e]~^ ERROR register can't be used with the `e` target feature
asm!("", out("f0") _); // ok
asm!("/* {} */", in(freg) f);
//[riscv32i,riscv32e,riscv64imac]~^ ERROR register class `freg` requires at least one of the following target features: d, f
asm!("/* {} */", out(freg) _);
//[riscv32i,riscv32e,riscv64imac]~^ ERROR register class `freg` requires at least one of the following target features: d, f
asm!("/* {} */", in(freg) d);
//[riscv32i,riscv32e,riscv64imac]~^ ERROR register class `freg` requires at least one of the following target features: d, f
//[riscv32imafc]~^^ ERROR `d` target feature is not enabled
asm!("/* {} */", out(freg) d);
//[riscv32i,riscv32e,riscv64imac]~^ ERROR register class `freg` requires at least one of the following target features: d, f
//[riscv32imafc]~^^ ERROR `d` target feature is not enabled
// Clobber-only registers
// vreg
asm!("", out("v0") _); // ok
asm!("", in("v0") x);
//~^ ERROR can only be used as a clobber
//~| ERROR type `i32` cannot be used with this register class
asm!("", out("v0") x);
//~^ ERROR can only be used as a clobber
//~| ERROR type `i32` cannot be used with this register class
asm!("/* {} */", in(vreg) x);
//~^ ERROR can only be used as a clobber
//~| ERROR type `i32` cannot be used with this register class
asm!("/* {} */", out(vreg) _);
//~^ ERROR can only be used as a clobber
}
}