Fix target_feature handling in freg of LoongArch inline assembly

This commit is contained in:
Taiki Endo 2024-11-29 03:01:33 +09:00
parent 9b4d7c6a40
commit 0c8e36bb30
4 changed files with 146 additions and 1 deletions

View file

@ -38,7 +38,7 @@ impl LoongArchInlineAsmRegClass {
) -> &'static [(InlineAsmType, Option<Symbol>)] {
match self {
Self::reg => types! { _: I8, I16, I32, I64, F32, F64; },
Self::freg => types! { _: F32, F64; },
Self::freg => types! { f: F32; d: F64; },
}
}
}

View file

@ -0,0 +1,38 @@
error: invalid register `$r0`: constant zero cannot be used as an operand for inline asm
--> $DIR/bad-reg.rs:22:18
|
LL | asm!("", out("$r0") _);
| ^^^^^^^^^^^^
error: invalid register `$tp`: reserved for TLS
--> $DIR/bad-reg.rs:24:18
|
LL | asm!("", out("$tp") _);
| ^^^^^^^^^^^^
error: invalid register `$sp`: the stack pointer cannot be used as an operand for inline asm
--> $DIR/bad-reg.rs:26:18
|
LL | asm!("", out("$sp") _);
| ^^^^^^^^^^^^
error: invalid register `$r21`: reserved by the ABI
--> $DIR/bad-reg.rs:28:18
|
LL | asm!("", out("$r21") _);
| ^^^^^^^^^^^^^
error: invalid register `$fp`: the frame pointer cannot be used as an operand for inline asm
--> $DIR/bad-reg.rs:30:18
|
LL | asm!("", out("$fp") _);
| ^^^^^^^^^^^^
error: invalid register `$r31`: $r31 is used internally by LLVM and cannot be used as an operand for inline asm
--> $DIR/bad-reg.rs:32:18
|
LL | asm!("", out("$r31") _);
| ^^^^^^^^^^^^^
error: aborting due to 6 previous errors

View file

@ -0,0 +1,62 @@
error: invalid register `$r0`: constant zero cannot be used as an operand for inline asm
--> $DIR/bad-reg.rs:22:18
|
LL | asm!("", out("$r0") _);
| ^^^^^^^^^^^^
error: invalid register `$tp`: reserved for TLS
--> $DIR/bad-reg.rs:24:18
|
LL | asm!("", out("$tp") _);
| ^^^^^^^^^^^^
error: invalid register `$sp`: the stack pointer cannot be used as an operand for inline asm
--> $DIR/bad-reg.rs:26:18
|
LL | asm!("", out("$sp") _);
| ^^^^^^^^^^^^
error: invalid register `$r21`: reserved by the ABI
--> $DIR/bad-reg.rs:28:18
|
LL | asm!("", out("$r21") _);
| ^^^^^^^^^^^^^
error: invalid register `$fp`: the frame pointer cannot be used as an operand for inline asm
--> $DIR/bad-reg.rs:30:18
|
LL | asm!("", out("$fp") _);
| ^^^^^^^^^^^^
error: invalid register `$r31`: $r31 is used internally by LLVM and cannot be used as an operand for inline asm
--> $DIR/bad-reg.rs:32:18
|
LL | asm!("", out("$r31") _);
| ^^^^^^^^^^^^^
error: register class `freg` requires at least one of the following target features: d, f
--> $DIR/bad-reg.rs:36:26
|
LL | asm!("/* {} */", in(freg) f);
| ^^^^^^^^^^
error: register class `freg` requires at least one of the following target features: d, f
--> $DIR/bad-reg.rs:38:26
|
LL | asm!("/* {} */", out(freg) _);
| ^^^^^^^^^^^
error: register class `freg` requires at least one of the following target features: d, f
--> $DIR/bad-reg.rs:40:26
|
LL | asm!("/* {} */", in(freg) d);
| ^^^^^^^^^^
error: register class `freg` requires at least one of the following target features: d, f
--> $DIR/bad-reg.rs:42:26
|
LL | asm!("/* {} */", out(freg) d);
| ^^^^^^^^^^^
error: aborting due to 10 previous errors

View file

@ -0,0 +1,45 @@
//@ add-core-stubs
//@ needs-asm-support
//@ revisions: loongarch64_lp64d loongarch64_lp64s
//@[loongarch64_lp64d] compile-flags: --target loongarch64-unknown-linux-gnu
//@[loongarch64_lp64d] needs-llvm-components: loongarch
//@[loongarch64_lp64s] compile-flags: --target loongarch64-unknown-none-softfloat
//@[loongarch64_lp64s] needs-llvm-components: loongarch
#![crate_type = "lib"]
#![feature(no_core, rustc_attrs)]
#![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("$r0") _);
//~^ ERROR constant zero cannot be used as an operand for inline asm
asm!("", out("$tp") _);
//~^ ERROR invalid register `$tp`: reserved for TLS
asm!("", out("$sp") _);
//~^ ERROR invalid register `$sp`: the stack pointer cannot be used as an operand for inline asm
asm!("", out("$r21") _);
//~^ ERROR invalid register `$r21`: reserved by the ABI
asm!("", out("$fp") _);
//~^ ERROR invalid register `$fp`: the frame pointer cannot be used as an operand for inline asm
asm!("", out("$r31") _);
//~^ ERROR invalid register `$r31`: $r31 is used internally by LLVM and cannot be used as an operand for inline asm
asm!("", out("$f0") _); // ok
asm!("/* {} */", in(freg) f);
//[loongarch64_lp64s]~^ ERROR register class `freg` requires at least one of the following target features: d, f
asm!("/* {} */", out(freg) _);
//[loongarch64_lp64s]~^ ERROR register class `freg` requires at least one of the following target features: d, f
asm!("/* {} */", in(freg) d);
//[loongarch64_lp64s]~^ ERROR register class `freg` requires at least one of the following target features: d, f
asm!("/* {} */", out(freg) d);
//[loongarch64_lp64s]~^ ERROR register class `freg` requires at least one of the following target features: d, f
}
}