Skip to content

Commit 0c8e36b

Browse files
committed
Fix target_feature handling in freg of LoongArch inline assembly
1 parent 9b4d7c6 commit 0c8e36b

File tree

4 files changed

+146
-1
lines changed

4 files changed

+146
-1
lines changed

compiler/rustc_target/src/asm/loongarch.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ impl LoongArchInlineAsmRegClass {
3838
) -> &'static [(InlineAsmType, Option<Symbol>)] {
3939
match self {
4040
Self::reg => types! { _: I8, I16, I32, I64, F32, F64; },
41-
Self::freg => types! { _: F32, F64; },
41+
Self::freg => types! { f: F32; d: F64; },
4242
}
4343
}
4444
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
error: invalid register `$r0`: constant zero cannot be used as an operand for inline asm
2+
--> $DIR/bad-reg.rs:22:18
3+
|
4+
LL | asm!("", out("$r0") _);
5+
| ^^^^^^^^^^^^
6+
7+
error: invalid register `$tp`: reserved for TLS
8+
--> $DIR/bad-reg.rs:24:18
9+
|
10+
LL | asm!("", out("$tp") _);
11+
| ^^^^^^^^^^^^
12+
13+
error: invalid register `$sp`: the stack pointer cannot be used as an operand for inline asm
14+
--> $DIR/bad-reg.rs:26:18
15+
|
16+
LL | asm!("", out("$sp") _);
17+
| ^^^^^^^^^^^^
18+
19+
error: invalid register `$r21`: reserved by the ABI
20+
--> $DIR/bad-reg.rs:28:18
21+
|
22+
LL | asm!("", out("$r21") _);
23+
| ^^^^^^^^^^^^^
24+
25+
error: invalid register `$fp`: the frame pointer cannot be used as an operand for inline asm
26+
--> $DIR/bad-reg.rs:30:18
27+
|
28+
LL | asm!("", out("$fp") _);
29+
| ^^^^^^^^^^^^
30+
31+
error: invalid register `$r31`: $r31 is used internally by LLVM and cannot be used as an operand for inline asm
32+
--> $DIR/bad-reg.rs:32:18
33+
|
34+
LL | asm!("", out("$r31") _);
35+
| ^^^^^^^^^^^^^
36+
37+
error: aborting due to 6 previous errors
38+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
error: invalid register `$r0`: constant zero cannot be used as an operand for inline asm
2+
--> $DIR/bad-reg.rs:22:18
3+
|
4+
LL | asm!("", out("$r0") _);
5+
| ^^^^^^^^^^^^
6+
7+
error: invalid register `$tp`: reserved for TLS
8+
--> $DIR/bad-reg.rs:24:18
9+
|
10+
LL | asm!("", out("$tp") _);
11+
| ^^^^^^^^^^^^
12+
13+
error: invalid register `$sp`: the stack pointer cannot be used as an operand for inline asm
14+
--> $DIR/bad-reg.rs:26:18
15+
|
16+
LL | asm!("", out("$sp") _);
17+
| ^^^^^^^^^^^^
18+
19+
error: invalid register `$r21`: reserved by the ABI
20+
--> $DIR/bad-reg.rs:28:18
21+
|
22+
LL | asm!("", out("$r21") _);
23+
| ^^^^^^^^^^^^^
24+
25+
error: invalid register `$fp`: the frame pointer cannot be used as an operand for inline asm
26+
--> $DIR/bad-reg.rs:30:18
27+
|
28+
LL | asm!("", out("$fp") _);
29+
| ^^^^^^^^^^^^
30+
31+
error: invalid register `$r31`: $r31 is used internally by LLVM and cannot be used as an operand for inline asm
32+
--> $DIR/bad-reg.rs:32:18
33+
|
34+
LL | asm!("", out("$r31") _);
35+
| ^^^^^^^^^^^^^
36+
37+
error: register class `freg` requires at least one of the following target features: d, f
38+
--> $DIR/bad-reg.rs:36:26
39+
|
40+
LL | asm!("/* {} */", in(freg) f);
41+
| ^^^^^^^^^^
42+
43+
error: register class `freg` requires at least one of the following target features: d, f
44+
--> $DIR/bad-reg.rs:38:26
45+
|
46+
LL | asm!("/* {} */", out(freg) _);
47+
| ^^^^^^^^^^^
48+
49+
error: register class `freg` requires at least one of the following target features: d, f
50+
--> $DIR/bad-reg.rs:40:26
51+
|
52+
LL | asm!("/* {} */", in(freg) d);
53+
| ^^^^^^^^^^
54+
55+
error: register class `freg` requires at least one of the following target features: d, f
56+
--> $DIR/bad-reg.rs:42:26
57+
|
58+
LL | asm!("/* {} */", out(freg) d);
59+
| ^^^^^^^^^^^
60+
61+
error: aborting due to 10 previous errors
62+

tests/ui/asm/loongarch/bad-reg.rs

+45
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
//@ add-core-stubs
2+
//@ needs-asm-support
3+
//@ revisions: loongarch64_lp64d loongarch64_lp64s
4+
//@[loongarch64_lp64d] compile-flags: --target loongarch64-unknown-linux-gnu
5+
//@[loongarch64_lp64d] needs-llvm-components: loongarch
6+
//@[loongarch64_lp64s] compile-flags: --target loongarch64-unknown-none-softfloat
7+
//@[loongarch64_lp64s] needs-llvm-components: loongarch
8+
9+
#![crate_type = "lib"]
10+
#![feature(no_core, rustc_attrs)]
11+
#![no_core]
12+
13+
extern crate minicore;
14+
use minicore::*;
15+
16+
fn f() {
17+
let mut x = 0;
18+
let mut f = 0.0_f32;
19+
let mut d = 0.0_f64;
20+
unsafe {
21+
// Unsupported registers
22+
asm!("", out("$r0") _);
23+
//~^ ERROR constant zero cannot be used as an operand for inline asm
24+
asm!("", out("$tp") _);
25+
//~^ ERROR invalid register `$tp`: reserved for TLS
26+
asm!("", out("$sp") _);
27+
//~^ ERROR invalid register `$sp`: the stack pointer cannot be used as an operand for inline asm
28+
asm!("", out("$r21") _);
29+
//~^ ERROR invalid register `$r21`: reserved by the ABI
30+
asm!("", out("$fp") _);
31+
//~^ ERROR invalid register `$fp`: the frame pointer cannot be used as an operand for inline asm
32+
asm!("", out("$r31") _);
33+
//~^ ERROR invalid register `$r31`: $r31 is used internally by LLVM and cannot be used as an operand for inline asm
34+
35+
asm!("", out("$f0") _); // ok
36+
asm!("/* {} */", in(freg) f);
37+
//[loongarch64_lp64s]~^ ERROR register class `freg` requires at least one of the following target features: d, f
38+
asm!("/* {} */", out(freg) _);
39+
//[loongarch64_lp64s]~^ ERROR register class `freg` requires at least one of the following target features: d, f
40+
asm!("/* {} */", in(freg) d);
41+
//[loongarch64_lp64s]~^ ERROR register class `freg` requires at least one of the following target features: d, f
42+
asm!("/* {} */", out(freg) d);
43+
//[loongarch64_lp64s]~^ ERROR register class `freg` requires at least one of the following target features: d, f
44+
}
45+
}

0 commit comments

Comments
 (0)