about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--compiler/rustc_target/src/asm/loongarch.rs2
-rw-r--r--tests/ui/asm/loongarch/bad-reg.loongarch64_lp64d.stderr38
-rw-r--r--tests/ui/asm/loongarch/bad-reg.loongarch64_lp64s.stderr62
-rw-r--r--tests/ui/asm/loongarch/bad-reg.rs45
4 files changed, 146 insertions, 1 deletions
diff --git a/compiler/rustc_target/src/asm/loongarch.rs b/compiler/rustc_target/src/asm/loongarch.rs
index b1c01d27cad..b4ea6fc592a 100644
--- a/compiler/rustc_target/src/asm/loongarch.rs
+++ b/compiler/rustc_target/src/asm/loongarch.rs
@@ -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; },
         }
     }
 }
diff --git a/tests/ui/asm/loongarch/bad-reg.loongarch64_lp64d.stderr b/tests/ui/asm/loongarch/bad-reg.loongarch64_lp64d.stderr
new file mode 100644
index 00000000000..0e544119650
--- /dev/null
+++ b/tests/ui/asm/loongarch/bad-reg.loongarch64_lp64d.stderr
@@ -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
+
diff --git a/tests/ui/asm/loongarch/bad-reg.loongarch64_lp64s.stderr b/tests/ui/asm/loongarch/bad-reg.loongarch64_lp64s.stderr
new file mode 100644
index 00000000000..6d0410dc6a1
--- /dev/null
+++ b/tests/ui/asm/loongarch/bad-reg.loongarch64_lp64s.stderr
@@ -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
+
diff --git a/tests/ui/asm/loongarch/bad-reg.rs b/tests/ui/asm/loongarch/bad-reg.rs
new file mode 100644
index 00000000000..c5288cc78b7
--- /dev/null
+++ b/tests/ui/asm/loongarch/bad-reg.rs
@@ -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
+    }
+}