Support floats in input/output in vector registers of PowerPC inline assembly
This commit is contained in:
parent
0f8ebba54a
commit
df8feb5067
7 changed files with 120 additions and 12 deletions
|
@ -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),
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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 => &[],
|
||||
}
|
||||
|
|
|
@ -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` |
|
||||
|
|
|
@ -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");
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Add table
Reference in a new issue