Skip to content

Commit 2f14414

Browse files
committed
Support #[repr(simd)] types in input/output of PowerPC inline assembly
1 parent 9b4d7c6 commit 2f14414

File tree

12 files changed

+595
-352
lines changed

12 files changed

+595
-352
lines changed

compiler/rustc_codegen_gcc/src/asm.rs

+6-4
Original file line numberDiff line numberDiff line change
@@ -656,9 +656,9 @@ fn reg_to_gcc(reg: InlineAsmRegOrRegClass) -> ConstraintOrRegister {
656656
InlineAsmRegClass::PowerPC(PowerPCInlineAsmRegClass::reg) => "r",
657657
InlineAsmRegClass::PowerPC(PowerPCInlineAsmRegClass::reg_nonzero) => "b",
658658
InlineAsmRegClass::PowerPC(PowerPCInlineAsmRegClass::freg) => "f",
659+
InlineAsmRegClass::PowerPC(PowerPCInlineAsmRegClass::vreg) => "v",
659660
InlineAsmRegClass::PowerPC(PowerPCInlineAsmRegClass::cr)
660-
| InlineAsmRegClass::PowerPC(PowerPCInlineAsmRegClass::xer)
661-
| InlineAsmRegClass::PowerPC(PowerPCInlineAsmRegClass::vreg) => {
661+
| InlineAsmRegClass::PowerPC(PowerPCInlineAsmRegClass::xer) => {
662662
unreachable!("clobber-only")
663663
}
664664
InlineAsmRegClass::RiscV(RiscVInlineAsmRegClass::reg) => "r",
@@ -736,9 +736,11 @@ fn dummy_output_type<'gcc, 'tcx>(cx: &CodegenCx<'gcc, 'tcx>, reg: InlineAsmRegCl
736736
InlineAsmRegClass::PowerPC(PowerPCInlineAsmRegClass::reg) => cx.type_i32(),
737737
InlineAsmRegClass::PowerPC(PowerPCInlineAsmRegClass::reg_nonzero) => cx.type_i32(),
738738
InlineAsmRegClass::PowerPC(PowerPCInlineAsmRegClass::freg) => cx.type_f64(),
739+
InlineAsmRegClass::PowerPC(PowerPCInlineAsmRegClass::vreg) => {
740+
cx.type_vector(cx.type_i32(), 4)
741+
}
739742
InlineAsmRegClass::PowerPC(PowerPCInlineAsmRegClass::cr)
740-
| InlineAsmRegClass::PowerPC(PowerPCInlineAsmRegClass::xer)
741-
| InlineAsmRegClass::PowerPC(PowerPCInlineAsmRegClass::vreg) => {
743+
| InlineAsmRegClass::PowerPC(PowerPCInlineAsmRegClass::xer) => {
742744
unreachable!("clobber-only")
743745
}
744746
InlineAsmRegClass::RiscV(RiscVInlineAsmRegClass::reg) => cx.type_i32(),

compiler/rustc_codegen_llvm/src/asm.rs

+4-6
Original file line numberDiff line numberDiff line change
@@ -656,9 +656,8 @@ fn reg_to_llvm(reg: InlineAsmRegOrRegClass, layout: Option<&TyAndLayout<'_>>) ->
656656
PowerPC(PowerPCInlineAsmRegClass::reg) => "r",
657657
PowerPC(PowerPCInlineAsmRegClass::reg_nonzero) => "b",
658658
PowerPC(PowerPCInlineAsmRegClass::freg) => "f",
659-
PowerPC(PowerPCInlineAsmRegClass::cr)
660-
| PowerPC(PowerPCInlineAsmRegClass::xer)
661-
| PowerPC(PowerPCInlineAsmRegClass::vreg) => {
659+
PowerPC(PowerPCInlineAsmRegClass::vreg) => "v",
660+
PowerPC(PowerPCInlineAsmRegClass::cr) | PowerPC(PowerPCInlineAsmRegClass::xer) => {
662661
unreachable!("clobber-only")
663662
}
664663
RiscV(RiscVInlineAsmRegClass::reg) => "r",
@@ -825,9 +824,8 @@ fn dummy_output_type<'ll>(cx: &CodegenCx<'ll, '_>, reg: InlineAsmRegClass) -> &'
825824
PowerPC(PowerPCInlineAsmRegClass::reg) => cx.type_i32(),
826825
PowerPC(PowerPCInlineAsmRegClass::reg_nonzero) => cx.type_i32(),
827826
PowerPC(PowerPCInlineAsmRegClass::freg) => cx.type_f64(),
828-
PowerPC(PowerPCInlineAsmRegClass::cr)
829-
| PowerPC(PowerPCInlineAsmRegClass::xer)
830-
| PowerPC(PowerPCInlineAsmRegClass::vreg) => {
827+
PowerPC(PowerPCInlineAsmRegClass::vreg) => cx.type_vector(cx.type_i32(), 4),
828+
PowerPC(PowerPCInlineAsmRegClass::cr) | PowerPC(PowerPCInlineAsmRegClass::xer) => {
831829
unreachable!("clobber-only")
832830
}
833831
RiscV(RiscVInlineAsmRegClass::reg) => cx.type_i32(),

compiler/rustc_span/src/symbol.rs

+2
Original file line numberDiff line numberDiff line change
@@ -392,6 +392,7 @@ symbols! {
392392
allow_fail,
393393
allow_internal_unsafe,
394394
allow_internal_unstable,
395+
altivec,
395396
alu32,
396397
always,
397398
and,
@@ -2154,6 +2155,7 @@ symbols! {
21542155
volatile_store,
21552156
vreg,
21562157
vreg_low16,
2158+
vsx,
21572159
vtable_align,
21582160
vtable_size,
21592161
warn,

compiler/rustc_target/src/asm/powerpc.rs

+5-1
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,11 @@ impl PowerPCInlineAsmRegClass {
5151
}
5252
}
5353
Self::freg => types! { _: F32, F64; },
54-
Self::vreg => &[],
54+
// FIXME: vsx also supports integers and floats: https://github.com/rust-lang/rust/pull/131551#discussion_r1797651773
55+
Self::vreg => types! {
56+
altivec: VecI8(16), VecI16(8), VecI32(4), VecF32(4);
57+
vsx: VecI64(2), VecF64(2);
58+
},
5559
Self::cr | Self::xer => &[],
5660
}
5761
}

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

+4-2
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ This feature tracks `asm!` and `global_asm!` support for the following architect
3434
| PowerPC | `reg` | `r0`, `r[3-12]`, `r[14-28]` | `r` |
3535
| PowerPC | `reg_nonzero` | `r[3-12]`, `r[14-28]` | `b` |
3636
| PowerPC | `freg` | `f[0-31]` | `f` |
37-
| PowerPC | `vreg` | `v[0-31]` | Only clobbers |
37+
| PowerPC | `vreg` | `v[0-31]` | `v` |
3838
| PowerPC | `cr` | `cr[0-7]`, `cr` | Only clobbers |
3939
| PowerPC | `xer` | `xer` | Only clobbers |
4040
| wasm32 | `local` | None\* | `r` |
@@ -75,7 +75,8 @@ This feature tracks `asm!` and `global_asm!` support for the following architect
7575
| PowerPC | `reg` | None | `i8`, `i16`, `i32`, `i64` (powerpc64 only) |
7676
| PowerPC | `reg_nonzero` | None | `i8`, `i16`, `i32`, `i64` (powerpc64 only) |
7777
| PowerPC | `freg` | None | `f32`, `f64` |
78-
| PowerPC | `vreg` | N/A | Only clobbers |
78+
| PowerPC | `vreg` | `altivec` | `i8x16`, `i16x8`, `i32x4`, `f32x4` |
79+
| PowerPC | `vreg` | `vsx` | `f32`, `f64`, `i64x2`, `f64x2` |
7980
| PowerPC | `cr` | N/A | Only clobbers |
8081
| PowerPC | `xer` | N/A | Only clobbers |
8182
| wasm32 | `local` | None | `i8` `i16` `i32` `i64` `f32` `f64` |
@@ -181,6 +182,7 @@ This feature tracks `asm!` and `global_asm!` support for the following architect
181182
| PowerPC | `reg` | None | `0` | None |
182183
| PowerPC | `reg_nonzero` | None | `3` | None |
183184
| PowerPC | `freg` | None | `0` | None |
185+
| PowerPC | `vreg` | None | `0` | None |
184186
| SPARC | `reg` | None | `%o0` | None |
185187
| CSKY | `reg` | None | `r0` | None |
186188
| CSKY | `freg` | None | `f0` | None |

tests/assembly/asm/powerpc-types.rs

+235-2
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,29 @@
1-
//@ revisions: powerpc powerpc64
1+
//@ revisions: powerpc powerpc_altivec powerpc_vsx powerpc64 powerpc64_vsx
22
//@ assembly-output: emit-asm
33
//@[powerpc] compile-flags: --target powerpc-unknown-linux-gnu
44
//@[powerpc] needs-llvm-components: powerpc
5-
//@[powerpc64] compile-flags: --target powerpc64-unknown-linux-gnu
5+
//@[powerpc_altivec] compile-flags: --target powerpc-unknown-linux-gnu -C target-feature=+altivec --cfg altivec
6+
//@[powerpc_altivec] needs-llvm-components: powerpc
7+
//@[powerpc_vsx] compile-flags: --target powerpc-unknown-linux-gnu -C target-feature=+altivec,+vsx --cfg altivec --cfg vsx
8+
//@[powerpc_vsx] needs-llvm-components: powerpc
9+
//@[powerpc64] compile-flags: --target powerpc64-unknown-linux-gnu --cfg altivec
610
//@[powerpc64] needs-llvm-components: powerpc
11+
//@[powerpc64_vsx] compile-flags: --target powerpc64-unknown-linux-gnu -C target-feature=+vsx --cfg altivec --cfg vsx
12+
//@[powerpc64_vsx] needs-llvm-components: powerpc
713
//@ compile-flags: -Zmerge-functions=disabled
814

915
#![feature(no_core, lang_items, rustc_attrs, repr_simd, asm_experimental_arch)]
1016
#![crate_type = "rlib"]
1117
#![no_core]
1218
#![allow(asm_sub_register, non_camel_case_types)]
1319

20+
#[cfg_attr(altivec, cfg(not(target_feature = "altivec")))]
21+
#[cfg_attr(not(altivec), cfg(target_feature = "altivec"))]
22+
compile_error!("altivec cfg and target feature mismatch");
23+
#[cfg_attr(vsx, cfg(not(target_feature = "vsx")))]
24+
#[cfg_attr(not(vsx), cfg(target_feature = "vsx"))]
25+
compile_error!("vsx cfg and target feature mismatch");
26+
1427
#[rustc_builtin_macro]
1528
macro_rules! asm {
1629
() => {};
@@ -29,8 +42,23 @@ trait Sized {}
2942
#[lang = "copy"]
3043
trait Copy {}
3144

45+
impl<T: Copy, const N: usize> Copy for [T; N] {}
46+
3247
type ptr = *const i32;
3348

49+
#[repr(simd)]
50+
pub struct i8x16([i8; 16]);
51+
#[repr(simd)]
52+
pub struct i16x8([i16; 8]);
53+
#[repr(simd)]
54+
pub struct i32x4([i32; 4]);
55+
#[repr(simd)]
56+
pub struct i64x2([i64; 2]);
57+
#[repr(simd)]
58+
pub struct f32x4([f32; 4]);
59+
#[repr(simd)]
60+
pub struct f64x2([f64; 2]);
61+
3462
impl Copy for i8 {}
3563
impl Copy for u8 {}
3664
impl Copy for i16 {}
@@ -39,6 +67,13 @@ impl Copy for i64 {}
3967
impl Copy for f32 {}
4068
impl Copy for f64 {}
4169
impl Copy for ptr {}
70+
impl Copy for i8x16 {}
71+
impl Copy for i16x8 {}
72+
impl Copy for i32x4 {}
73+
impl Copy for i64x2 {}
74+
impl Copy for f32x4 {}
75+
impl Copy for f64x2 {}
76+
4277
extern "C" {
4378
fn extern_func();
4479
static extern_static: u8;
@@ -124,6 +159,72 @@ check!(reg_f32, f32, freg, "fmr");
124159
// CHECK: #NO_APP
125160
check!(reg_f64, f64, freg, "fmr");
126161

162+
// powerpc_altivec-LABEL: vreg_i8x16:
163+
// powerpc_altivec: #APP
164+
// powerpc_altivec: vmr {{[0-9]+}}, {{[0-9]+}}
165+
// powerpc_altivec: #NO_APP
166+
// powerpc64-LABEL: vreg_i8x16:
167+
// powerpc64: #APP
168+
// powerpc64: vmr {{[0-9]+}}, {{[0-9]+}}
169+
// powerpc64: #NO_APP
170+
#[cfg(altivec)]
171+
check!(vreg_i8x16, i8x16, vreg, "vmr");
172+
173+
// powerpc_altivec-LABEL: vreg_i16x8:
174+
// powerpc_altivec: #APP
175+
// powerpc_altivec: vmr {{[0-9]+}}, {{[0-9]+}}
176+
// powerpc_altivec: #NO_APP
177+
// powerpc64-LABEL: vreg_i16x8:
178+
// powerpc64: #APP
179+
// powerpc64: vmr {{[0-9]+}}, {{[0-9]+}}
180+
// powerpc64: #NO_APP
181+
#[cfg(altivec)]
182+
check!(vreg_i16x8, i16x8, vreg, "vmr");
183+
184+
// powerpc_altivec-LABEL: vreg_i32x4:
185+
// powerpc_altivec: #APP
186+
// powerpc_altivec: vmr {{[0-9]+}}, {{[0-9]+}}
187+
// powerpc_altivec: #NO_APP
188+
// powerpc64-LABEL: vreg_i32x4:
189+
// powerpc64: #APP
190+
// powerpc64: vmr {{[0-9]+}}, {{[0-9]+}}
191+
// powerpc64: #NO_APP
192+
#[cfg(altivec)]
193+
check!(vreg_i32x4, i32x4, vreg, "vmr");
194+
195+
// powerpc_vsx-LABEL: vreg_i64x2:
196+
// powerpc_vsx: #APP
197+
// powerpc_vsx: vmr {{[0-9]+}}, {{[0-9]+}}
198+
// powerpc_vsx: #NO_APP
199+
// powerpc64_vsx-LABEL: vreg_i64x2:
200+
// powerpc64_vsx: #APP
201+
// powerpc64_vsx: vmr {{[0-9]+}}, {{[0-9]+}}
202+
// powerpc64_vsx: #NO_APP
203+
#[cfg(vsx)]
204+
check!(vreg_i64x2, i64x2, vreg, "vmr");
205+
206+
// powerpc_altivec-LABEL: vreg_f32x4:
207+
// powerpc_altivec: #APP
208+
// powerpc_altivec: vmr {{[0-9]+}}, {{[0-9]+}}
209+
// powerpc_altivec: #NO_APP
210+
// powerpc64-LABEL: vreg_f32x4:
211+
// powerpc64: #APP
212+
// powerpc64: vmr {{[0-9]+}}, {{[0-9]+}}
213+
// powerpc64: #NO_APP
214+
#[cfg(altivec)]
215+
check!(vreg_f32x4, f32x4, vreg, "vmr");
216+
217+
// powerpc_vsx-LABEL: vreg_f64x2:
218+
// powerpc_vsx: #APP
219+
// powerpc_vsx: vmr {{[0-9]+}}, {{[0-9]+}}
220+
// powerpc_vsx: #NO_APP
221+
// powerpc64_vsx-LABEL: vreg_f64x2:
222+
// powerpc64_vsx: #APP
223+
// powerpc64_vsx: vmr {{[0-9]+}}, {{[0-9]+}}
224+
// powerpc64_vsx: #NO_APP
225+
#[cfg(vsx)]
226+
check!(vreg_f64x2, f64x2, vreg, "vmr");
227+
127228
// CHECK-LABEL: reg_i8_r0:
128229
// CHECK: #APP
129230
// CHECK: mr 0, 0
@@ -197,3 +298,135 @@ check_reg!(reg_f32_f18, f32, "18", "f18", "fmr");
197298
// CHECK: fmr 18, 18
198299
// CHECK: #NO_APP
199300
check_reg!(reg_f64_f18, f64, "18", "f18", "fmr");
301+
302+
// powerpc_altivec-LABEL: vreg_i8x16_v0:
303+
// powerpc_altivec: #APP
304+
// powerpc_altivec: vmr 0, 0
305+
// powerpc_altivec: #NO_APP
306+
// powerpc64-LABEL: vreg_i8x16_v0:
307+
// powerpc64: #APP
308+
// powerpc64: vmr 0, 0
309+
// powerpc64: #NO_APP
310+
#[cfg(altivec)]
311+
check_reg!(vreg_i8x16_v0, i8x16, "0", "v0", "vmr");
312+
313+
// powerpc_altivec-LABEL: vreg_i16x8_v0:
314+
// powerpc_altivec: #APP
315+
// powerpc_altivec: vmr 0, 0
316+
// powerpc_altivec: #NO_APP
317+
// powerpc64-LABEL: vreg_i16x8_v0:
318+
// powerpc64: #APP
319+
// powerpc64: vmr 0, 0
320+
// powerpc64: #NO_APP
321+
#[cfg(altivec)]
322+
check_reg!(vreg_i16x8_v0, i16x8, "0", "v0", "vmr");
323+
324+
// powerpc_altivec-LABEL: vreg_i32x4_v0:
325+
// powerpc_altivec: #APP
326+
// powerpc_altivec: vmr 0, 0
327+
// powerpc_altivec: #NO_APP
328+
// powerpc64-LABEL: vreg_i32x4_v0:
329+
// powerpc64: #APP
330+
// powerpc64: vmr 0, 0
331+
// powerpc64: #NO_APP
332+
#[cfg(altivec)]
333+
check_reg!(vreg_i32x4_v0, i32x4, "0", "v0", "vmr");
334+
335+
// powerpc_vsx-LABEL: vreg_i64x2_v0:
336+
// powerpc_vsx: #APP
337+
// powerpc_vsx: vmr 0, 0
338+
// powerpc_vsx: #NO_APP
339+
// powerpc64_vsx-LABEL: vreg_i64x2_v0:
340+
// powerpc64_vsx: #APP
341+
// powerpc64_vsx: vmr 0, 0
342+
// powerpc64_vsx: #NO_APP
343+
#[cfg(vsx)]
344+
check_reg!(vreg_i64x2_v0, i64x2, "0", "v0", "vmr");
345+
346+
// powerpc_altivec-LABEL: vreg_f32x4_v0:
347+
// powerpc_altivec: #APP
348+
// powerpc_altivec: vmr 0, 0
349+
// powerpc_altivec: #NO_APP
350+
// powerpc64-LABEL: vreg_f32x4_v0:
351+
// powerpc64: #APP
352+
// powerpc64: vmr 0, 0
353+
// powerpc64: #NO_APP
354+
#[cfg(altivec)]
355+
check_reg!(vreg_f32x4_v0, f32x4, "0", "v0", "vmr");
356+
357+
// powerpc_vsx-LABEL: vreg_f64x2_v0:
358+
// powerpc_vsx: #APP
359+
// powerpc_vsx: vmr 0, 0
360+
// powerpc_vsx: #NO_APP
361+
// powerpc64_vsx-LABEL: vreg_f64x2_v0:
362+
// powerpc64_vsx: #APP
363+
// powerpc64_vsx: vmr 0, 0
364+
// powerpc64_vsx: #NO_APP
365+
#[cfg(vsx)]
366+
check_reg!(vreg_f64x2_v0, f64x2, "0", "v0", "vmr");
367+
368+
// powerpc_altivec-LABEL: vreg_i8x16_v18:
369+
// powerpc_altivec: #APP
370+
// powerpc_altivec: vmr 18, 18
371+
// powerpc_altivec: #NO_APP
372+
// powerpc64-LABEL: vreg_i8x16_v18:
373+
// powerpc64: #APP
374+
// powerpc64: vmr 18, 18
375+
// powerpc64: #NO_APP
376+
#[cfg(altivec)]
377+
check_reg!(vreg_i8x16_v18, i8x16, "18", "v18", "vmr");
378+
379+
// powerpc_altivec-LABEL: vreg_i16x8_v18:
380+
// powerpc_altivec: #APP
381+
// powerpc_altivec: vmr 18, 18
382+
// powerpc_altivec: #NO_APP
383+
// powerpc64-LABEL: vreg_i16x8_v18:
384+
// powerpc64: #APP
385+
// powerpc64: vmr 18, 18
386+
// powerpc64: #NO_APP
387+
#[cfg(altivec)]
388+
check_reg!(vreg_i16x8_v18, i16x8, "18", "v18", "vmr");
389+
390+
// powerpc_altivec-LABEL: vreg_i32x4_v18:
391+
// powerpc_altivec: #APP
392+
// powerpc_altivec: vmr 18, 18
393+
// powerpc_altivec: #NO_APP
394+
// powerpc64-LABEL: vreg_i32x4_v18:
395+
// powerpc64: #APP
396+
// powerpc64: vmr 18, 18
397+
// powerpc64: #NO_APP
398+
#[cfg(altivec)]
399+
check_reg!(vreg_i32x4_v18, i32x4, "18", "v18", "vmr");
400+
401+
// powerpc_vsx-LABEL: vreg_i64x2_v18:
402+
// powerpc_vsx: #APP
403+
// powerpc_vsx: vmr 18, 18
404+
// powerpc_vsx: #NO_APP
405+
// powerpc64_vsx-LABEL: vreg_i64x2_v18:
406+
// powerpc64_vsx: #APP
407+
// powerpc64_vsx: vmr 18, 18
408+
// powerpc64_vsx: #NO_APP
409+
#[cfg(vsx)]
410+
check_reg!(vreg_i64x2_v18, i64x2, "18", "v18", "vmr");
411+
412+
// powerpc_altivec-LABEL: vreg_f32x4_v18:
413+
// powerpc_altivec: #APP
414+
// powerpc_altivec: vmr 18, 18
415+
// powerpc_altivec: #NO_APP
416+
// powerpc64-LABEL: vreg_f32x4_v18:
417+
// powerpc64: #APP
418+
// powerpc64: vmr 18, 18
419+
// powerpc64: #NO_APP
420+
#[cfg(altivec)]
421+
check_reg!(vreg_f32x4_v18, f32x4, "18", "v18", "vmr");
422+
423+
// powerpc_vsx-LABEL: vreg_f64x2_v18:
424+
// powerpc_vsx: #APP
425+
// powerpc_vsx: vmr 18, 18
426+
// powerpc_vsx: #NO_APP
427+
// powerpc64_vsx-LABEL: vreg_f64x2_v18:
428+
// powerpc64_vsx: #APP
429+
// powerpc64_vsx: vmr 18, 18
430+
// powerpc64_vsx: #NO_APP
431+
#[cfg(vsx)]
432+
check_reg!(vreg_f64x2_v18, f64x2, "18", "v18", "vmr");

0 commit comments

Comments
 (0)