Skip to content

Commit f8d17d1

Browse files
committed
Support floats in input/output in vector registers of PowerPC inline assembly
1 parent 0f8ebba commit f8d17d1

File tree

4 files changed

+111
-3
lines changed

4 files changed

+111
-3
lines changed

compiler/rustc_codegen_llvm/src/asm.rs

+42
Original file line numberDiff line numberDiff line change
@@ -1040,6 +1040,26 @@ fn llvm_fixup_input<'ll, 'tcx>(
10401040
let value = bx.or(value, bx.const_u32(0xFFFF_0000));
10411041
bx.bitcast(value, bx.type_f32())
10421042
}
1043+
(PowerPC(PowerPCInlineAsmRegClass::vreg), BackendRepr::Scalar(s))
1044+
if s.primitive() == Primitive::Float(Float::F32) =>
1045+
{
1046+
let value = bx.insert_element(
1047+
bx.const_undef(bx.type_vector(bx.type_f32(), 4)),
1048+
value,
1049+
bx.const_usize(0),
1050+
);
1051+
bx.bitcast(value, bx.type_vector(bx.type_f32(), 4))
1052+
}
1053+
(PowerPC(PowerPCInlineAsmRegClass::vreg), BackendRepr::Scalar(s))
1054+
if s.primitive() == Primitive::Float(Float::F64) =>
1055+
{
1056+
let value = bx.insert_element(
1057+
bx.const_undef(bx.type_vector(bx.type_f64(), 2)),
1058+
value,
1059+
bx.const_usize(0),
1060+
);
1061+
bx.bitcast(value, bx.type_vector(bx.type_f64(), 2))
1062+
}
10431063
_ => value,
10441064
}
10451065
}
@@ -1175,6 +1195,18 @@ fn llvm_fixup_output<'ll, 'tcx>(
11751195
let value = bx.trunc(value, bx.type_i16());
11761196
bx.bitcast(value, bx.type_f16())
11771197
}
1198+
(PowerPC(PowerPCInlineAsmRegClass::vreg), BackendRepr::Scalar(s))
1199+
if s.primitive() == Primitive::Float(Float::F32) =>
1200+
{
1201+
let value = bx.bitcast(value, bx.type_vector(bx.type_f32(), 4));
1202+
bx.extract_element(value, bx.const_usize(0))
1203+
}
1204+
(PowerPC(PowerPCInlineAsmRegClass::vreg), BackendRepr::Scalar(s))
1205+
if s.primitive() == Primitive::Float(Float::F64) =>
1206+
{
1207+
let value = bx.bitcast(value, bx.type_vector(bx.type_f64(), 2));
1208+
bx.extract_element(value, bx.const_usize(0))
1209+
}
11781210
_ => value,
11791211
}
11801212
}
@@ -1299,6 +1331,16 @@ fn llvm_fixup_output_type<'ll, 'tcx>(
12991331
{
13001332
cx.type_f32()
13011333
}
1334+
(PowerPC(PowerPCInlineAsmRegClass::vreg), BackendRepr::Scalar(s))
1335+
if s.primitive() == Primitive::Float(Float::F32) =>
1336+
{
1337+
cx.type_vector(cx.type_f32(), 4)
1338+
}
1339+
(PowerPC(PowerPCInlineAsmRegClass::vreg), BackendRepr::Scalar(s))
1340+
if s.primitive() == Primitive::Float(Float::F64) =>
1341+
{
1342+
cx.type_vector(cx.type_f64(), 2)
1343+
}
13021344
_ => layout.llvm_type(cx),
13031345
}
13041346
}

compiler/rustc_target/src/asm/powerpc.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -51,10 +51,10 @@ impl PowerPCInlineAsmRegClass {
5151
}
5252
}
5353
Self::freg => types! { _: F32, F64; },
54-
// FIXME: vsx also supports integers and floats: https://github.com/rust-lang/rust/pull/131551#discussion_r1797651773
54+
// FIXME: vsx also supports integers?: https://github.com/rust-lang/rust/pull/131551#discussion_r1862535963
5555
Self::vreg => types! {
5656
altivec: VecI8(16), VecI16(8), VecI32(4), VecF32(4);
57-
vsx: VecI64(2), VecF64(2);
57+
vsx: F32, F64, VecI64(2), VecF64(2);
5858
},
5959
Self::cr | Self::xer => &[],
6060
}

src/doc/unstable-book/src/language-features/asm-experimental-arch.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@ This feature tracks `asm!` and `global_asm!` support for the following architect
7676
| PowerPC | `reg_nonzero` | None | `i8`, `i16`, `i32`, `i64` (powerpc64 only) |
7777
| PowerPC | `freg` | None | `f32`, `f64` |
7878
| PowerPC | `vreg` | `altivec` | `i8x16`, `i16x8`, `i32x4`, `f32x4` |
79-
| PowerPC | `vreg` | `vsx` | `i64x2`, `f64x2` |
79+
| PowerPC | `vreg` | `vsx` | `f32`, `f64`, `i64x2`, `f64x2` |
8080
| PowerPC | `cr` | N/A | Only clobbers |
8181
| PowerPC | `xer` | N/A | Only clobbers |
8282
| wasm32 | `local` | None | `i8` `i16` `i32` `i64` `f32` `f64` |

tests/assembly/asm/powerpc-types.rs

+66
Original file line numberDiff line numberDiff line change
@@ -225,6 +225,28 @@ check!(vreg_f32x4, f32x4, vreg, "vmr");
225225
#[cfg(vsx)]
226226
check!(vreg_f64x2, f64x2, vreg, "vmr");
227227

228+
// powerpc_vsx-LABEL: vreg_f32:
229+
// powerpc_vsx: #APP
230+
// powerpc_vsx: vmr {{[0-9]+}}, {{[0-9]+}}
231+
// powerpc_vsx: #NO_APP
232+
// powerpc64_vsx-LABEL: vreg_f32:
233+
// powerpc64_vsx: #APP
234+
// powerpc64_vsx: vmr {{[0-9]+}}, {{[0-9]+}}
235+
// powerpc64_vsx: #NO_APP
236+
#[cfg(vsx)]
237+
check!(vreg_f32, f32, vreg, "vmr");
238+
239+
// powerpc_vsx-LABEL: vreg_f64:
240+
// powerpc_vsx: #APP
241+
// powerpc_vsx: vmr {{[0-9]+}}, {{[0-9]+}}
242+
// powerpc_vsx: #NO_APP
243+
// powerpc64_vsx-LABEL: vreg_f64:
244+
// powerpc64_vsx: #APP
245+
// powerpc64_vsx: vmr {{[0-9]+}}, {{[0-9]+}}
246+
// powerpc64_vsx: #NO_APP
247+
#[cfg(vsx)]
248+
check!(vreg_f64, f64, vreg, "vmr");
249+
228250
// CHECK-LABEL: reg_i8_r0:
229251
// CHECK: #APP
230252
// CHECK: mr 0, 0
@@ -365,6 +387,28 @@ check_reg!(vreg_f32x4_v0, f32x4, "0", "v0", "vmr");
365387
#[cfg(vsx)]
366388
check_reg!(vreg_f64x2_v0, f64x2, "0", "v0", "vmr");
367389

390+
// powerpc_vsx-LABEL: vreg_f32_v0:
391+
// powerpc_vsx: #APP
392+
// powerpc_vsx: vmr 0, 0
393+
// powerpc_vsx: #NO_APP
394+
// powerpc64_vsx-LABEL: vreg_f32_v0:
395+
// powerpc64_vsx: #APP
396+
// powerpc64_vsx: vmr 0, 0
397+
// powerpc64_vsx: #NO_APP
398+
#[cfg(vsx)]
399+
check_reg!(vreg_f32_v0, f32, "0", "v0", "vmr");
400+
401+
// powerpc_vsx-LABEL: vreg_f64_v0:
402+
// powerpc_vsx: #APP
403+
// powerpc_vsx: vmr 0, 0
404+
// powerpc_vsx: #NO_APP
405+
// powerpc64_vsx-LABEL: vreg_f64_v0:
406+
// powerpc64_vsx: #APP
407+
// powerpc64_vsx: vmr 0, 0
408+
// powerpc64_vsx: #NO_APP
409+
#[cfg(vsx)]
410+
check_reg!(vreg_f64_v0, f64, "0", "v0", "vmr");
411+
368412
// powerpc_altivec-LABEL: vreg_i8x16_v18:
369413
// powerpc_altivec: #APP
370414
// powerpc_altivec: vmr 18, 18
@@ -430,3 +474,25 @@ check_reg!(vreg_f32x4_v18, f32x4, "18", "v18", "vmr");
430474
// powerpc64_vsx: #NO_APP
431475
#[cfg(vsx)]
432476
check_reg!(vreg_f64x2_v18, f64x2, "18", "v18", "vmr");
477+
478+
// powerpc_vsx-LABEL: vreg_f32_v18:
479+
// powerpc_vsx: #APP
480+
// powerpc_vsx: vmr 18, 18
481+
// powerpc_vsx: #NO_APP
482+
// powerpc64_vsx-LABEL: vreg_f32_v18:
483+
// powerpc64_vsx: #APP
484+
// powerpc64_vsx: vmr 18, 18
485+
// powerpc64_vsx: #NO_APP
486+
#[cfg(vsx)]
487+
check_reg!(vreg_f32_v18, f32, "18", "v18", "vmr");
488+
489+
// powerpc_vsx-LABEL: vreg_f64_v18:
490+
// powerpc_vsx: #APP
491+
// powerpc_vsx: vmr 18, 18
492+
// powerpc_vsx: #NO_APP
493+
// powerpc64_vsx-LABEL: vreg_f64_v18:
494+
// powerpc64_vsx: #APP
495+
// powerpc64_vsx: vmr 18, 18
496+
// powerpc64_vsx: #NO_APP
497+
#[cfg(vsx)]
498+
check_reg!(vreg_f64_v18, f64, "18", "v18", "vmr");

0 commit comments

Comments
 (0)