diff options
| author | Taiki Endo <te316e89@gmail.com> | 2024-11-29 03:10:07 +0900 |
|---|---|---|
| committer | Taiki Endo <te316e89@gmail.com> | 2024-11-29 03:10:07 +0900 |
| commit | df8feb5067f99e20059c7ee8021d9ba5273bfe68 (patch) | |
| tree | 16d97d2a36a20201eef685877ec32ef984150d59 | |
| parent | 0f8ebba54a8e41a9daccbbedae88e8798f4557c3 (diff) | |
| download | rust-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.rs | 42 | ||||
| -rw-r--r-- | compiler/rustc_target/src/asm/powerpc.rs | 4 | ||||
| -rw-r--r-- | src/doc/unstable-book/src/language-features/asm-experimental-arch.md | 2 | ||||
| -rw-r--r-- | tests/assembly/asm/powerpc-types.rs | 66 | ||||
| -rw-r--r-- | tests/ui/asm/powerpc/bad-reg.aix64.stderr | 6 | ||||
| -rw-r--r-- | tests/ui/asm/powerpc/bad-reg.powerpc64.stderr | 6 | ||||
| -rw-r--r-- | tests/ui/asm/powerpc/bad-reg.powerpc64le.stderr | 6 |
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 |
