about summary refs log tree commit diff
diff options
context:
space:
mode:
authorTaiki Endo <te316e89@gmail.com>2024-11-29 03:10:07 +0900
committerTaiki Endo <te316e89@gmail.com>2024-11-29 03:10:07 +0900
commitdf8feb5067f99e20059c7ee8021d9ba5273bfe68 (patch)
tree16d97d2a36a20201eef685877ec32ef984150d59
parent0f8ebba54a8e41a9daccbbedae88e8798f4557c3 (diff)
downloadrust-df8feb5067f99e20059c7ee8021d9ba5273bfe68.tar.gz
rust-df8feb5067f99e20059c7ee8021d9ba5273bfe68.zip
Support floats in input/output in vector registers of PowerPC inline assembly
-rw-r--r--compiler/rustc_codegen_llvm/src/asm.rs42
-rw-r--r--compiler/rustc_target/src/asm/powerpc.rs4
-rw-r--r--src/doc/unstable-book/src/language-features/asm-experimental-arch.md2
-rw-r--r--tests/assembly/asm/powerpc-types.rs66
-rw-r--r--tests/ui/asm/powerpc/bad-reg.aix64.stderr6
-rw-r--r--tests/ui/asm/powerpc/bad-reg.powerpc64.stderr6
-rw-r--r--tests/ui/asm/powerpc/bad-reg.powerpc64le.stderr6
7 files changed, 120 insertions, 12 deletions
diff --git a/compiler/rustc_codegen_llvm/src/asm.rs b/compiler/rustc_codegen_llvm/src/asm.rs
index 1483d576362..d1804cb49ad 100644
--- a/compiler/rustc_codegen_llvm/src/asm.rs
+++ b/compiler/rustc_codegen_llvm/src/asm.rs
@@ -1040,6 +1040,26 @@ fn llvm_fixup_input<'ll, 'tcx>(
             let value = bx.or(value, bx.const_u32(0xFFFF_0000));
             bx.bitcast(value, bx.type_f32())
         }
+        (PowerPC(PowerPCInlineAsmRegClass::vreg), BackendRepr::Scalar(s))
+            if s.primitive() == Primitive::Float(Float::F32) =>
+        {
+            let value = bx.insert_element(
+                bx.const_undef(bx.type_vector(bx.type_f32(), 4)),
+                value,
+                bx.const_usize(0),
+            );
+            bx.bitcast(value, bx.type_vector(bx.type_f32(), 4))
+        }
+        (PowerPC(PowerPCInlineAsmRegClass::vreg), BackendRepr::Scalar(s))
+            if s.primitive() == Primitive::Float(Float::F64) =>
+        {
+            let value = bx.insert_element(
+                bx.const_undef(bx.type_vector(bx.type_f64(), 2)),
+                value,
+                bx.const_usize(0),
+            );
+            bx.bitcast(value, bx.type_vector(bx.type_f64(), 2))
+        }
         _ => value,
     }
 }
@@ -1175,6 +1195,18 @@ fn llvm_fixup_output<'ll, 'tcx>(
             let value = bx.trunc(value, bx.type_i16());
             bx.bitcast(value, bx.type_f16())
         }
+        (PowerPC(PowerPCInlineAsmRegClass::vreg), BackendRepr::Scalar(s))
+            if s.primitive() == Primitive::Float(Float::F32) =>
+        {
+            let value = bx.bitcast(value, bx.type_vector(bx.type_f32(), 4));
+            bx.extract_element(value, bx.const_usize(0))
+        }
+        (PowerPC(PowerPCInlineAsmRegClass::vreg), BackendRepr::Scalar(s))
+            if s.primitive() == Primitive::Float(Float::F64) =>
+        {
+            let value = bx.bitcast(value, bx.type_vector(bx.type_f64(), 2));
+            bx.extract_element(value, bx.const_usize(0))
+        }
         _ => value,
     }
 }
@@ -1299,6 +1331,16 @@ fn llvm_fixup_output_type<'ll, 'tcx>(
         {
             cx.type_f32()
         }
+        (PowerPC(PowerPCInlineAsmRegClass::vreg), BackendRepr::Scalar(s))
+            if s.primitive() == Primitive::Float(Float::F32) =>
+        {
+            cx.type_vector(cx.type_f32(), 4)
+        }
+        (PowerPC(PowerPCInlineAsmRegClass::vreg), BackendRepr::Scalar(s))
+            if s.primitive() == Primitive::Float(Float::F64) =>
+        {
+            cx.type_vector(cx.type_f64(), 2)
+        }
         _ => layout.llvm_type(cx),
     }
 }
diff --git a/compiler/rustc_target/src/asm/powerpc.rs b/compiler/rustc_target/src/asm/powerpc.rs
index a5a96b87e36..f3934afa6d9 100644
--- a/compiler/rustc_target/src/asm/powerpc.rs
+++ b/compiler/rustc_target/src/asm/powerpc.rs
@@ -51,10 +51,10 @@ impl PowerPCInlineAsmRegClass {
                 }
             }
             Self::freg => types! { _: F32, F64; },
-            // FIXME: vsx also supports integers and floats: https://github.com/rust-lang/rust/pull/131551#discussion_r1797651773
+            // FIXME: vsx also supports integers?: https://github.com/rust-lang/rust/pull/131551#discussion_r1862535963
             Self::vreg => types! {
                 altivec: VecI8(16), VecI16(8), VecI32(4), VecF32(4);
-                vsx: VecI64(2), VecF64(2);
+                vsx: F32, F64, VecI64(2), VecF64(2);
             },
             Self::cr | Self::xer => &[],
         }
diff --git a/src/doc/unstable-book/src/language-features/asm-experimental-arch.md b/src/doc/unstable-book/src/language-features/asm-experimental-arch.md
index f2d0caa5e37..c2f4170d7d2 100644
--- a/src/doc/unstable-book/src/language-features/asm-experimental-arch.md
+++ b/src/doc/unstable-book/src/language-features/asm-experimental-arch.md
@@ -76,7 +76,7 @@ This feature tracks `asm!` and `global_asm!` support for the following architect
 | PowerPC      | `reg_nonzero`                   | None           | `i8`, `i16`, `i32`, `i64` (powerpc64 only) |
 | PowerPC      | `freg`                          | None           | `f32`, `f64`                            |
 | PowerPC      | `vreg`                          | `altivec`      | `i8x16`, `i16x8`, `i32x4`, `f32x4`      |
-| PowerPC      | `vreg`                          | `vsx`          | `i64x2`, `f64x2`                        |
+| PowerPC      | `vreg`                          | `vsx`          | `f32`, `f64`, `i64x2`, `f64x2`          |
 | PowerPC      | `cr`                            | N/A            | Only clobbers                           |
 | PowerPC      | `xer`                           | N/A            | Only clobbers                           |
 | wasm32       | `local`                         | None           | `i8` `i16` `i32` `i64` `f32` `f64`      |
diff --git a/tests/assembly/asm/powerpc-types.rs b/tests/assembly/asm/powerpc-types.rs
index d67e0f66f66..aa35c4d8865 100644
--- a/tests/assembly/asm/powerpc-types.rs
+++ b/tests/assembly/asm/powerpc-types.rs
@@ -225,6 +225,28 @@ check!(vreg_f32x4, f32x4, vreg, "vmr");
 #[cfg(vsx)]
 check!(vreg_f64x2, f64x2, vreg, "vmr");
 
+// powerpc_vsx-LABEL: vreg_f32:
+// powerpc_vsx: #APP
+// powerpc_vsx: vmr {{[0-9]+}}, {{[0-9]+}}
+// powerpc_vsx: #NO_APP
+// powerpc64_vsx-LABEL: vreg_f32:
+// powerpc64_vsx: #APP
+// powerpc64_vsx: vmr {{[0-9]+}}, {{[0-9]+}}
+// powerpc64_vsx: #NO_APP
+#[cfg(vsx)]
+check!(vreg_f32, f32, vreg, "vmr");
+
+// powerpc_vsx-LABEL: vreg_f64:
+// powerpc_vsx: #APP
+// powerpc_vsx: vmr {{[0-9]+}}, {{[0-9]+}}
+// powerpc_vsx: #NO_APP
+// powerpc64_vsx-LABEL: vreg_f64:
+// powerpc64_vsx: #APP
+// powerpc64_vsx: vmr {{[0-9]+}}, {{[0-9]+}}
+// powerpc64_vsx: #NO_APP
+#[cfg(vsx)]
+check!(vreg_f64, f64, vreg, "vmr");
+
 // CHECK-LABEL: reg_i8_r0:
 // CHECK: #APP
 // CHECK: mr 0, 0
@@ -365,6 +387,28 @@ check_reg!(vreg_f32x4_v0, f32x4, "0", "v0", "vmr");
 #[cfg(vsx)]
 check_reg!(vreg_f64x2_v0, f64x2, "0", "v0", "vmr");
 
+// powerpc_vsx-LABEL: vreg_f32_v0:
+// powerpc_vsx: #APP
+// powerpc_vsx: vmr 0, 0
+// powerpc_vsx: #NO_APP
+// powerpc64_vsx-LABEL: vreg_f32_v0:
+// powerpc64_vsx: #APP
+// powerpc64_vsx: vmr 0, 0
+// powerpc64_vsx: #NO_APP
+#[cfg(vsx)]
+check_reg!(vreg_f32_v0, f32, "0", "v0", "vmr");
+
+// powerpc_vsx-LABEL: vreg_f64_v0:
+// powerpc_vsx: #APP
+// powerpc_vsx: vmr 0, 0
+// powerpc_vsx: #NO_APP
+// powerpc64_vsx-LABEL: vreg_f64_v0:
+// powerpc64_vsx: #APP
+// powerpc64_vsx: vmr 0, 0
+// powerpc64_vsx: #NO_APP
+#[cfg(vsx)]
+check_reg!(vreg_f64_v0, f64, "0", "v0", "vmr");
+
 // powerpc_altivec-LABEL: vreg_i8x16_v18:
 // powerpc_altivec: #APP
 // powerpc_altivec: vmr 18, 18
@@ -430,3 +474,25 @@ check_reg!(vreg_f32x4_v18, f32x4, "18", "v18", "vmr");
 // powerpc64_vsx: #NO_APP
 #[cfg(vsx)]
 check_reg!(vreg_f64x2_v18, f64x2, "18", "v18", "vmr");
+
+// powerpc_vsx-LABEL: vreg_f32_v18:
+// powerpc_vsx: #APP
+// powerpc_vsx: vmr 18, 18
+// powerpc_vsx: #NO_APP
+// powerpc64_vsx-LABEL: vreg_f32_v18:
+// powerpc64_vsx: #APP
+// powerpc64_vsx: vmr 18, 18
+// powerpc64_vsx: #NO_APP
+#[cfg(vsx)]
+check_reg!(vreg_f32_v18, f32, "18", "v18", "vmr");
+
+// powerpc_vsx-LABEL: vreg_f64_v18:
+// powerpc_vsx: #APP
+// powerpc_vsx: vmr 18, 18
+// powerpc_vsx: #NO_APP
+// powerpc64_vsx-LABEL: vreg_f64_v18:
+// powerpc64_vsx: #APP
+// powerpc64_vsx: vmr 18, 18
+// powerpc64_vsx: #NO_APP
+#[cfg(vsx)]
+check_reg!(vreg_f64_v18, f64, "18", "v18", "vmr");
diff --git a/tests/ui/asm/powerpc/bad-reg.aix64.stderr b/tests/ui/asm/powerpc/bad-reg.aix64.stderr
index 332bdf0ff54..036641951cc 100644
--- a/tests/ui/asm/powerpc/bad-reg.aix64.stderr
+++ b/tests/ui/asm/powerpc/bad-reg.aix64.stderr
@@ -170,7 +170,7 @@ error: type `i32` cannot be used with this register class
 LL |         asm!("", in("v0") x); // FIXME: should be ok if vsx is available
    |                           ^
    |
-   = note: register class `vreg` supports these types: i8x16, i16x8, i32x4, f32x4, i64x2, f64x2
+   = note: register class `vreg` supports these types: i8x16, i16x8, i32x4, f32x4, f32, f64, i64x2, f64x2
 
 error: type `i32` cannot be used with this register class
   --> $DIR/bad-reg.rs:79:28
@@ -178,7 +178,7 @@ error: type `i32` cannot be used with this register class
 LL |         asm!("", out("v0") x); // FIXME: should be ok if vsx is available
    |                            ^
    |
-   = note: register class `vreg` supports these types: i8x16, i16x8, i32x4, f32x4, i64x2, f64x2
+   = note: register class `vreg` supports these types: i8x16, i16x8, i32x4, f32x4, f32, f64, i64x2, f64x2
 
 error: type `i32` cannot be used with this register class
   --> $DIR/bad-reg.rs:87:35
@@ -186,7 +186,7 @@ error: type `i32` cannot be used with this register class
 LL |         asm!("/* {} */", in(vreg) x); // FIXME: should be ok if vsx is available
    |                                   ^
    |
-   = note: register class `vreg` supports these types: i8x16, i16x8, i32x4, f32x4, i64x2, f64x2
+   = note: register class `vreg` supports these types: i8x16, i16x8, i32x4, f32x4, f32, f64, i64x2, f64x2
 
 error: type `i32` cannot be used with this register class
   --> $DIR/bad-reg.rs:109:27
diff --git a/tests/ui/asm/powerpc/bad-reg.powerpc64.stderr b/tests/ui/asm/powerpc/bad-reg.powerpc64.stderr
index 9e0dd80b3dc..6a9d552bfe2 100644
--- a/tests/ui/asm/powerpc/bad-reg.powerpc64.stderr
+++ b/tests/ui/asm/powerpc/bad-reg.powerpc64.stderr
@@ -186,7 +186,7 @@ error: type `i32` cannot be used with this register class
 LL |         asm!("", in("v0") x); // FIXME: should be ok if vsx is available
    |                           ^
    |
-   = note: register class `vreg` supports these types: i8x16, i16x8, i32x4, f32x4, i64x2, f64x2
+   = note: register class `vreg` supports these types: i8x16, i16x8, i32x4, f32x4, f32, f64, i64x2, f64x2
 
 error: type `i32` cannot be used with this register class
   --> $DIR/bad-reg.rs:79:28
@@ -194,7 +194,7 @@ error: type `i32` cannot be used with this register class
 LL |         asm!("", out("v0") x); // FIXME: should be ok if vsx is available
    |                            ^
    |
-   = note: register class `vreg` supports these types: i8x16, i16x8, i32x4, f32x4, i64x2, f64x2
+   = note: register class `vreg` supports these types: i8x16, i16x8, i32x4, f32x4, f32, f64, i64x2, f64x2
 
 error: `vsx` target feature is not enabled
   --> $DIR/bad-reg.rs:84:35
@@ -210,7 +210,7 @@ error: type `i32` cannot be used with this register class
 LL |         asm!("/* {} */", in(vreg) x); // FIXME: should be ok if vsx is available
    |                                   ^
    |
-   = note: register class `vreg` supports these types: i8x16, i16x8, i32x4, f32x4, i64x2, f64x2
+   = note: register class `vreg` supports these types: i8x16, i16x8, i32x4, f32x4, f32, f64, i64x2, f64x2
 
 error: type `i32` cannot be used with this register class
   --> $DIR/bad-reg.rs:109:27
diff --git a/tests/ui/asm/powerpc/bad-reg.powerpc64le.stderr b/tests/ui/asm/powerpc/bad-reg.powerpc64le.stderr
index 332bdf0ff54..036641951cc 100644
--- a/tests/ui/asm/powerpc/bad-reg.powerpc64le.stderr
+++ b/tests/ui/asm/powerpc/bad-reg.powerpc64le.stderr
@@ -170,7 +170,7 @@ error: type `i32` cannot be used with this register class
 LL |         asm!("", in("v0") x); // FIXME: should be ok if vsx is available
    |                           ^
    |
-   = note: register class `vreg` supports these types: i8x16, i16x8, i32x4, f32x4, i64x2, f64x2
+   = note: register class `vreg` supports these types: i8x16, i16x8, i32x4, f32x4, f32, f64, i64x2, f64x2
 
 error: type `i32` cannot be used with this register class
   --> $DIR/bad-reg.rs:79:28
@@ -178,7 +178,7 @@ error: type `i32` cannot be used with this register class
 LL |         asm!("", out("v0") x); // FIXME: should be ok if vsx is available
    |                            ^
    |
-   = note: register class `vreg` supports these types: i8x16, i16x8, i32x4, f32x4, i64x2, f64x2
+   = note: register class `vreg` supports these types: i8x16, i16x8, i32x4, f32x4, f32, f64, i64x2, f64x2
 
 error: type `i32` cannot be used with this register class
   --> $DIR/bad-reg.rs:87:35
@@ -186,7 +186,7 @@ error: type `i32` cannot be used with this register class
 LL |         asm!("/* {} */", in(vreg) x); // FIXME: should be ok if vsx is available
    |                                   ^
    |
-   = note: register class `vreg` supports these types: i8x16, i16x8, i32x4, f32x4, i64x2, f64x2
+   = note: register class `vreg` supports these types: i8x16, i16x8, i32x4, f32x4, f32, f64, i64x2, f64x2
 
 error: type `i32` cannot be used with this register class
   --> $DIR/bad-reg.rs:109:27