forked from rust-lang/rust
-
Notifications
You must be signed in to change notification settings - Fork 6
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Rollup merge of rust-lang#133587 - taiki-e:loongarch-asm-freg, r=Amanieu Fix target_feature handling in freg of LoongArch inline assembly In LoongArch inline assembly, freg currently always accepts f32/f64 as input/output. https://github.com/rust-lang/rust/blob/9b4d7c6a40b328d212095c28670c629facf1557d/compiler/rustc_target/src/asm/loongarch.rs#L41 However, these types actually require f/d target features as in RISC-V. Otherwise, an (ugly) compile error will occur: https://godbolt.org/z/K61Gq1E9E f32/f64 without f: ``` error: couldn't allocate output register for constraint '{$f1}' --> <source>:12:11 | 12 | asm!("", in("$f1") x, lateout("$f1") y); | ^ ``` f64 with f but without d: ``` error: scalar-to-vector conversion failed, possible invalid constraint for vector type --> <source>:19:11 | 19 | asm!("", in("$f1") x, lateout("$f1") y); | ^ ``` cc ``@heiher`` r? ``@Amanieu`` ``@rustbot`` label +O-LoongArch +A-inline-assembly
- Loading branch information
Showing
4 changed files
with
146 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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 | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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 | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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 | ||
} | ||
} |