Skip to content

Commit

Permalink
Rollup merge of #131551 - taiki-e:ppc-asm-vreg-inout, r=Amanieu
Browse files Browse the repository at this point in the history
Support input/output in vector registers of PowerPC inline assembly

This extends currently clobber-only vector registers (`vreg`) support to allow passing `#[repr(simd)]` types as input/output.

| Architecture | Register class | Target feature | Allowed types |
| ------------ | -------------- | -------------- | -------------- |
| PowerPC      | `vreg` | `altivec` | `i8x16`, `i16x8`, `i32x4`, `f32x4` |
| PowerPC      | `vreg` | `vsx` | `f32`, `f64`, `i64x2`, `f64x2` |

In addition to floats and `core::simd` types listed above, `core::arch` types and custom `#[repr(simd)]` types of the same size and type are also allowed. All allowed types and relevant target features are currently unstable.

r? `@Amanieu`

`@rustbot` label +O-PowerPC +A-inline-assembly
jieyouxu authored Nov 30, 2024
2 parents 76f3ff6 + df8feb5 commit 1aa0192
Showing 12 changed files with 703 additions and 352 deletions.
10 changes: 6 additions & 4 deletions compiler/rustc_codegen_gcc/src/asm.rs
Original file line number Diff line number Diff line change
@@ -656,9 +656,9 @@ fn reg_to_gcc(reg: InlineAsmRegOrRegClass) -> ConstraintOrRegister {
InlineAsmRegClass::PowerPC(PowerPCInlineAsmRegClass::reg) => "r",
InlineAsmRegClass::PowerPC(PowerPCInlineAsmRegClass::reg_nonzero) => "b",
InlineAsmRegClass::PowerPC(PowerPCInlineAsmRegClass::freg) => "f",
InlineAsmRegClass::PowerPC(PowerPCInlineAsmRegClass::vreg) => "v",
InlineAsmRegClass::PowerPC(PowerPCInlineAsmRegClass::cr)
| InlineAsmRegClass::PowerPC(PowerPCInlineAsmRegClass::xer)
| InlineAsmRegClass::PowerPC(PowerPCInlineAsmRegClass::vreg) => {
| InlineAsmRegClass::PowerPC(PowerPCInlineAsmRegClass::xer) => {
unreachable!("clobber-only")
}
InlineAsmRegClass::RiscV(RiscVInlineAsmRegClass::reg) => "r",
@@ -736,9 +736,11 @@ fn dummy_output_type<'gcc, 'tcx>(cx: &CodegenCx<'gcc, 'tcx>, reg: InlineAsmRegCl
InlineAsmRegClass::PowerPC(PowerPCInlineAsmRegClass::reg) => cx.type_i32(),
InlineAsmRegClass::PowerPC(PowerPCInlineAsmRegClass::reg_nonzero) => cx.type_i32(),
InlineAsmRegClass::PowerPC(PowerPCInlineAsmRegClass::freg) => cx.type_f64(),
InlineAsmRegClass::PowerPC(PowerPCInlineAsmRegClass::vreg) => {
cx.type_vector(cx.type_i32(), 4)
}
InlineAsmRegClass::PowerPC(PowerPCInlineAsmRegClass::cr)
| InlineAsmRegClass::PowerPC(PowerPCInlineAsmRegClass::xer)
| InlineAsmRegClass::PowerPC(PowerPCInlineAsmRegClass::vreg) => {
| InlineAsmRegClass::PowerPC(PowerPCInlineAsmRegClass::xer) => {
unreachable!("clobber-only")
}
InlineAsmRegClass::RiscV(RiscVInlineAsmRegClass::reg) => cx.type_i32(),
52 changes: 46 additions & 6 deletions compiler/rustc_codegen_llvm/src/asm.rs
Original file line number Diff line number Diff line change
@@ -656,9 +656,8 @@ fn reg_to_llvm(reg: InlineAsmRegOrRegClass, layout: Option<&TyAndLayout<'_>>) ->
PowerPC(PowerPCInlineAsmRegClass::reg) => "r",
PowerPC(PowerPCInlineAsmRegClass::reg_nonzero) => "b",
PowerPC(PowerPCInlineAsmRegClass::freg) => "f",
PowerPC(PowerPCInlineAsmRegClass::cr)
| PowerPC(PowerPCInlineAsmRegClass::xer)
| PowerPC(PowerPCInlineAsmRegClass::vreg) => {
PowerPC(PowerPCInlineAsmRegClass::vreg) => "v",
PowerPC(PowerPCInlineAsmRegClass::cr) | PowerPC(PowerPCInlineAsmRegClass::xer) => {
unreachable!("clobber-only")
}
RiscV(RiscVInlineAsmRegClass::reg) => "r",
@@ -825,9 +824,8 @@ fn dummy_output_type<'ll>(cx: &CodegenCx<'ll, '_>, reg: InlineAsmRegClass) -> &'
PowerPC(PowerPCInlineAsmRegClass::reg) => cx.type_i32(),
PowerPC(PowerPCInlineAsmRegClass::reg_nonzero) => cx.type_i32(),
PowerPC(PowerPCInlineAsmRegClass::freg) => cx.type_f64(),
PowerPC(PowerPCInlineAsmRegClass::cr)
| PowerPC(PowerPCInlineAsmRegClass::xer)
| PowerPC(PowerPCInlineAsmRegClass::vreg) => {
PowerPC(PowerPCInlineAsmRegClass::vreg) => cx.type_vector(cx.type_i32(), 4),
PowerPC(PowerPCInlineAsmRegClass::cr) | PowerPC(PowerPCInlineAsmRegClass::xer) => {
unreachable!("clobber-only")
}
RiscV(RiscVInlineAsmRegClass::reg) => cx.type_i32(),
@@ -1042,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,
}
}
@@ -1177,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,
}
}
@@ -1301,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),
}
}
2 changes: 2 additions & 0 deletions compiler/rustc_span/src/symbol.rs
Original file line number Diff line number Diff line change
@@ -392,6 +392,7 @@ symbols! {
allow_fail,
allow_internal_unsafe,
allow_internal_unstable,
altivec,
alu32,
always,
and,
@@ -2154,6 +2155,7 @@ symbols! {
volatile_store,
vreg,
vreg_low16,
vsx,
vtable_align,
vtable_size,
warn,
6 changes: 5 additions & 1 deletion compiler/rustc_target/src/asm/powerpc.rs
Original file line number Diff line number Diff line change
@@ -51,7 +51,11 @@ impl PowerPCInlineAsmRegClass {
}
}
Self::freg => types! { _: F32, F64; },
Self::vreg => &[],
// 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: F32, F64, VecI64(2), VecF64(2);
},
Self::cr | Self::xer => &[],
}
}
Original file line number Diff line number Diff line change
@@ -34,7 +34,7 @@ This feature tracks `asm!` and `global_asm!` support for the following architect
| PowerPC | `reg` | `r0`, `r[3-12]`, `r[14-28]` | `r` |
| PowerPC | `reg_nonzero` | `r[3-12]`, `r[14-28]` | `b` |
| PowerPC | `freg` | `f[0-31]` | `f` |
| PowerPC | `vreg` | `v[0-31]` | Only clobbers |
| PowerPC | `vreg` | `v[0-31]` | `v` |
| PowerPC | `cr` | `cr[0-7]`, `cr` | Only clobbers |
| PowerPC | `xer` | `xer` | Only clobbers |
| wasm32 | `local` | None\* | `r` |
@@ -75,7 +75,8 @@ This feature tracks `asm!` and `global_asm!` support for the following architect
| PowerPC | `reg` | None | `i8`, `i16`, `i32`, `i64` (powerpc64 only) |
| PowerPC | `reg_nonzero` | None | `i8`, `i16`, `i32`, `i64` (powerpc64 only) |
| PowerPC | `freg` | None | `f32`, `f64` |
| PowerPC | `vreg` | N/A | Only clobbers |
| PowerPC | `vreg` | `altivec` | `i8x16`, `i16x8`, `i32x4`, `f32x4` |
| 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` |
@@ -181,6 +182,7 @@ This feature tracks `asm!` and `global_asm!` support for the following architect
| PowerPC | `reg` | None | `0` | None |
| PowerPC | `reg_nonzero` | None | `3` | None |
| PowerPC | `freg` | None | `0` | None |
| PowerPC | `vreg` | None | `0` | None |
| SPARC | `reg` | None | `%o0` | None |
| CSKY | `reg` | None | `r0` | None |
| CSKY | `freg` | None | `f0` | None |
303 changes: 301 additions & 2 deletions tests/assembly/asm/powerpc-types.rs
Original file line number Diff line number Diff line change
@@ -1,16 +1,29 @@
//@ revisions: powerpc powerpc64
//@ revisions: powerpc powerpc_altivec powerpc_vsx powerpc64 powerpc64_vsx
//@ assembly-output: emit-asm
//@[powerpc] compile-flags: --target powerpc-unknown-linux-gnu
//@[powerpc] needs-llvm-components: powerpc
//@[powerpc64] compile-flags: --target powerpc64-unknown-linux-gnu
//@[powerpc_altivec] compile-flags: --target powerpc-unknown-linux-gnu -C target-feature=+altivec --cfg altivec
//@[powerpc_altivec] needs-llvm-components: powerpc
//@[powerpc_vsx] compile-flags: --target powerpc-unknown-linux-gnu -C target-feature=+altivec,+vsx --cfg altivec --cfg vsx
//@[powerpc_vsx] needs-llvm-components: powerpc
//@[powerpc64] compile-flags: --target powerpc64-unknown-linux-gnu --cfg altivec
//@[powerpc64] needs-llvm-components: powerpc
//@[powerpc64_vsx] compile-flags: --target powerpc64-unknown-linux-gnu -C target-feature=+vsx --cfg altivec --cfg vsx
//@[powerpc64_vsx] needs-llvm-components: powerpc
//@ compile-flags: -Zmerge-functions=disabled

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

#[cfg_attr(altivec, cfg(not(target_feature = "altivec")))]
#[cfg_attr(not(altivec), cfg(target_feature = "altivec"))]
compile_error!("altivec cfg and target feature mismatch");
#[cfg_attr(vsx, cfg(not(target_feature = "vsx")))]
#[cfg_attr(not(vsx), cfg(target_feature = "vsx"))]
compile_error!("vsx cfg and target feature mismatch");

#[rustc_builtin_macro]
macro_rules! asm {
() => {};
@@ -29,8 +42,23 @@ trait Sized {}
#[lang = "copy"]
trait Copy {}

impl<T: Copy, const N: usize> Copy for [T; N] {}

type ptr = *const i32;

#[repr(simd)]
pub struct i8x16([i8; 16]);
#[repr(simd)]
pub struct i16x8([i16; 8]);
#[repr(simd)]
pub struct i32x4([i32; 4]);
#[repr(simd)]
pub struct i64x2([i64; 2]);
#[repr(simd)]
pub struct f32x4([f32; 4]);
#[repr(simd)]
pub struct f64x2([f64; 2]);

impl Copy for i8 {}
impl Copy for u8 {}
impl Copy for i16 {}
@@ -39,6 +67,13 @@ impl Copy for i64 {}
impl Copy for f32 {}
impl Copy for f64 {}
impl Copy for ptr {}
impl Copy for i8x16 {}
impl Copy for i16x8 {}
impl Copy for i32x4 {}
impl Copy for i64x2 {}
impl Copy for f32x4 {}
impl Copy for f64x2 {}

extern "C" {
fn extern_func();
static extern_static: u8;
@@ -124,6 +159,94 @@ check!(reg_f32, f32, freg, "fmr");
// CHECK: #NO_APP
check!(reg_f64, f64, freg, "fmr");

// powerpc_altivec-LABEL: vreg_i8x16:
// powerpc_altivec: #APP
// powerpc_altivec: vmr {{[0-9]+}}, {{[0-9]+}}
// powerpc_altivec: #NO_APP
// powerpc64-LABEL: vreg_i8x16:
// powerpc64: #APP
// powerpc64: vmr {{[0-9]+}}, {{[0-9]+}}
// powerpc64: #NO_APP
#[cfg(altivec)]
check!(vreg_i8x16, i8x16, vreg, "vmr");

// powerpc_altivec-LABEL: vreg_i16x8:
// powerpc_altivec: #APP
// powerpc_altivec: vmr {{[0-9]+}}, {{[0-9]+}}
// powerpc_altivec: #NO_APP
// powerpc64-LABEL: vreg_i16x8:
// powerpc64: #APP
// powerpc64: vmr {{[0-9]+}}, {{[0-9]+}}
// powerpc64: #NO_APP
#[cfg(altivec)]
check!(vreg_i16x8, i16x8, vreg, "vmr");

// powerpc_altivec-LABEL: vreg_i32x4:
// powerpc_altivec: #APP
// powerpc_altivec: vmr {{[0-9]+}}, {{[0-9]+}}
// powerpc_altivec: #NO_APP
// powerpc64-LABEL: vreg_i32x4:
// powerpc64: #APP
// powerpc64: vmr {{[0-9]+}}, {{[0-9]+}}
// powerpc64: #NO_APP
#[cfg(altivec)]
check!(vreg_i32x4, i32x4, vreg, "vmr");

// powerpc_vsx-LABEL: vreg_i64x2:
// powerpc_vsx: #APP
// powerpc_vsx: vmr {{[0-9]+}}, {{[0-9]+}}
// powerpc_vsx: #NO_APP
// powerpc64_vsx-LABEL: vreg_i64x2:
// powerpc64_vsx: #APP
// powerpc64_vsx: vmr {{[0-9]+}}, {{[0-9]+}}
// powerpc64_vsx: #NO_APP
#[cfg(vsx)]
check!(vreg_i64x2, i64x2, vreg, "vmr");

// powerpc_altivec-LABEL: vreg_f32x4:
// powerpc_altivec: #APP
// powerpc_altivec: vmr {{[0-9]+}}, {{[0-9]+}}
// powerpc_altivec: #NO_APP
// powerpc64-LABEL: vreg_f32x4:
// powerpc64: #APP
// powerpc64: vmr {{[0-9]+}}, {{[0-9]+}}
// powerpc64: #NO_APP
#[cfg(altivec)]
check!(vreg_f32x4, f32x4, vreg, "vmr");

// powerpc_vsx-LABEL: vreg_f64x2:
// powerpc_vsx: #APP
// powerpc_vsx: vmr {{[0-9]+}}, {{[0-9]+}}
// powerpc_vsx: #NO_APP
// powerpc64_vsx-LABEL: vreg_f64x2:
// powerpc64_vsx: #APP
// powerpc64_vsx: vmr {{[0-9]+}}, {{[0-9]+}}
// powerpc64_vsx: #NO_APP
#[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
@@ -197,3 +320,179 @@ check_reg!(reg_f32_f18, f32, "18", "f18", "fmr");
// CHECK: fmr 18, 18
// CHECK: #NO_APP
check_reg!(reg_f64_f18, f64, "18", "f18", "fmr");

// powerpc_altivec-LABEL: vreg_i8x16_v0:
// powerpc_altivec: #APP
// powerpc_altivec: vmr 0, 0
// powerpc_altivec: #NO_APP
// powerpc64-LABEL: vreg_i8x16_v0:
// powerpc64: #APP
// powerpc64: vmr 0, 0
// powerpc64: #NO_APP
#[cfg(altivec)]
check_reg!(vreg_i8x16_v0, i8x16, "0", "v0", "vmr");

// powerpc_altivec-LABEL: vreg_i16x8_v0:
// powerpc_altivec: #APP
// powerpc_altivec: vmr 0, 0
// powerpc_altivec: #NO_APP
// powerpc64-LABEL: vreg_i16x8_v0:
// powerpc64: #APP
// powerpc64: vmr 0, 0
// powerpc64: #NO_APP
#[cfg(altivec)]
check_reg!(vreg_i16x8_v0, i16x8, "0", "v0", "vmr");

// powerpc_altivec-LABEL: vreg_i32x4_v0:
// powerpc_altivec: #APP
// powerpc_altivec: vmr 0, 0
// powerpc_altivec: #NO_APP
// powerpc64-LABEL: vreg_i32x4_v0:
// powerpc64: #APP
// powerpc64: vmr 0, 0
// powerpc64: #NO_APP
#[cfg(altivec)]
check_reg!(vreg_i32x4_v0, i32x4, "0", "v0", "vmr");

// powerpc_vsx-LABEL: vreg_i64x2_v0:
// powerpc_vsx: #APP
// powerpc_vsx: vmr 0, 0
// powerpc_vsx: #NO_APP
// powerpc64_vsx-LABEL: vreg_i64x2_v0:
// powerpc64_vsx: #APP
// powerpc64_vsx: vmr 0, 0
// powerpc64_vsx: #NO_APP
#[cfg(vsx)]
check_reg!(vreg_i64x2_v0, i64x2, "0", "v0", "vmr");

// powerpc_altivec-LABEL: vreg_f32x4_v0:
// powerpc_altivec: #APP
// powerpc_altivec: vmr 0, 0
// powerpc_altivec: #NO_APP
// powerpc64-LABEL: vreg_f32x4_v0:
// powerpc64: #APP
// powerpc64: vmr 0, 0
// powerpc64: #NO_APP
#[cfg(altivec)]
check_reg!(vreg_f32x4_v0, f32x4, "0", "v0", "vmr");

// powerpc_vsx-LABEL: vreg_f64x2_v0:
// powerpc_vsx: #APP
// powerpc_vsx: vmr 0, 0
// powerpc_vsx: #NO_APP
// powerpc64_vsx-LABEL: vreg_f64x2_v0:
// powerpc64_vsx: #APP
// powerpc64_vsx: vmr 0, 0
// powerpc64_vsx: #NO_APP
#[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
// powerpc_altivec: #NO_APP
// powerpc64-LABEL: vreg_i8x16_v18:
// powerpc64: #APP
// powerpc64: vmr 18, 18
// powerpc64: #NO_APP
#[cfg(altivec)]
check_reg!(vreg_i8x16_v18, i8x16, "18", "v18", "vmr");

// powerpc_altivec-LABEL: vreg_i16x8_v18:
// powerpc_altivec: #APP
// powerpc_altivec: vmr 18, 18
// powerpc_altivec: #NO_APP
// powerpc64-LABEL: vreg_i16x8_v18:
// powerpc64: #APP
// powerpc64: vmr 18, 18
// powerpc64: #NO_APP
#[cfg(altivec)]
check_reg!(vreg_i16x8_v18, i16x8, "18", "v18", "vmr");

// powerpc_altivec-LABEL: vreg_i32x4_v18:
// powerpc_altivec: #APP
// powerpc_altivec: vmr 18, 18
// powerpc_altivec: #NO_APP
// powerpc64-LABEL: vreg_i32x4_v18:
// powerpc64: #APP
// powerpc64: vmr 18, 18
// powerpc64: #NO_APP
#[cfg(altivec)]
check_reg!(vreg_i32x4_v18, i32x4, "18", "v18", "vmr");

// powerpc_vsx-LABEL: vreg_i64x2_v18:
// powerpc_vsx: #APP
// powerpc_vsx: vmr 18, 18
// powerpc_vsx: #NO_APP
// powerpc64_vsx-LABEL: vreg_i64x2_v18:
// powerpc64_vsx: #APP
// powerpc64_vsx: vmr 18, 18
// powerpc64_vsx: #NO_APP
#[cfg(vsx)]
check_reg!(vreg_i64x2_v18, i64x2, "18", "v18", "vmr");

// powerpc_altivec-LABEL: vreg_f32x4_v18:
// powerpc_altivec: #APP
// powerpc_altivec: vmr 18, 18
// powerpc_altivec: #NO_APP
// powerpc64-LABEL: vreg_f32x4_v18:
// powerpc64: #APP
// powerpc64: vmr 18, 18
// powerpc64: #NO_APP
#[cfg(altivec)]
check_reg!(vreg_f32x4_v18, f32x4, "18", "v18", "vmr");

// powerpc_vsx-LABEL: vreg_f64x2_v18:
// powerpc_vsx: #APP
// powerpc_vsx: vmr 18, 18
// powerpc_vsx: #NO_APP
// powerpc64_vsx-LABEL: vreg_f64x2_v18:
// powerpc64_vsx: #APP
// powerpc64_vsx: vmr 18, 18
// 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");
13 changes: 11 additions & 2 deletions tests/codegen/asm/powerpc-clobbers.rs
Original file line number Diff line number Diff line change
@@ -7,6 +7,7 @@
//@[powerpc64le] needs-llvm-components: powerpc
//@[aix64] compile-flags: --target powerpc64-ibm-aix
//@[aix64] needs-llvm-components: powerpc
// ignore-tidy-linelength

#![crate_type = "rlib"]
#![feature(no_core, rustc_attrs, lang_items, asm_experimental_arch)]
@@ -48,15 +49,23 @@ pub unsafe fn xer_clobber() {
asm!("", out("xer") _, options(nostack, nomem, preserves_flags));
}

// Output format depends on the availability of altivec.
// CHECK-LABEL: @v0_clobber
// CHECK: call void asm sideeffect "", "~{v0}"()
// powerpc: call void asm sideeffect "", "~{v0}"()
// powerpc64: call <4 x i32> asm sideeffect "", "=&{v0}"()
// powerpc64le: call <4 x i32> asm sideeffect "", "=&{v0}"()
// aix64: call <4 x i32> asm sideeffect "", "=&{v0}"()
#[no_mangle]
pub unsafe fn v0_clobber() {
asm!("", out("v0") _, options(nostack, nomem, preserves_flags));
}

// Output format depends on the availability of altivec.
// CHECK-LABEL: @clobber_abi
// CHECK: asm sideeffect "", "={r0},={r3},={r4},={r5},={r6},={r7},={r8},={r9},={r10},={r11},={r12},={f0},={f1},={f2},={f3},={f4},={f5},={f6},={f7},={f8},={f9},={f10},={f11},={f12},={f13},~{v0},~{v1},~{v2},~{v3},~{v4},~{v5},~{v6},~{v7},~{v8},~{v9},~{v10},~{v11},~{v12},~{v13},~{v14},~{v15},~{v16},~{v17},~{v18},~{v19},~{cr0},~{cr1},~{cr5},~{cr6},~{cr7},~{xer}"()
// powerpc: asm sideeffect "", "={r0},={r3},={r4},={r5},={r6},={r7},={r8},={r9},={r10},={r11},={r12},={f0},={f1},={f2},={f3},={f4},={f5},={f6},={f7},={f8},={f9},={f10},={f11},={f12},={f13},~{v0},~{v1},~{v2},~{v3},~{v4},~{v5},~{v6},~{v7},~{v8},~{v9},~{v10},~{v11},~{v12},~{v13},~{v14},~{v15},~{v16},~{v17},~{v18},~{v19},~{cr0},~{cr1},~{cr5},~{cr6},~{cr7},~{xer}"()
// powerpc64: asm sideeffect "", "={r0},={r3},={r4},={r5},={r6},={r7},={r8},={r9},={r10},={r11},={r12},={f0},={f1},={f2},={f3},={f4},={f5},={f6},={f7},={f8},={f9},={f10},={f11},={f12},={f13},={v0},={v1},={v2},={v3},={v4},={v5},={v6},={v7},={v8},={v9},={v10},={v11},={v12},={v13},={v14},={v15},={v16},={v17},={v18},={v19},~{cr0},~{cr1},~{cr5},~{cr6},~{cr7},~{xer}"()
// powerpc64le: asm sideeffect "", "={r0},={r3},={r4},={r5},={r6},={r7},={r8},={r9},={r10},={r11},={r12},={f0},={f1},={f2},={f3},={f4},={f5},={f6},={f7},={f8},={f9},={f10},={f11},={f12},={f13},={v0},={v1},={v2},={v3},={v4},={v5},={v6},={v7},={v8},={v9},={v10},={v11},={v12},={v13},={v14},={v15},={v16},={v17},={v18},={v19},~{cr0},~{cr1},~{cr5},~{cr6},~{cr7},~{xer}"()
// aix64: asm sideeffect "", "={r0},={r3},={r4},={r5},={r6},={r7},={r8},={r9},={r10},={r11},={r12},={f0},={f1},={f2},={f3},={f4},={f5},={f6},={f7},={f8},={f9},={f10},={f11},={f12},={f13},={v0},={v1},={v2},={v3},={v4},={v5},={v6},={v7},={v8},={v9},={v10},={v11},={v12},={v13},={v14},={v15},={v16},={v17},={v18},={v19},~{cr0},~{cr1},~{cr5},~{cr6},~{cr7},~{xer}"()
#[no_mangle]
pub unsafe fn clobber_abi() {
asm!("", clobber_abi("C"), options(nostack, nomem, preserves_flags));
136 changes: 56 additions & 80 deletions tests/ui/asm/powerpc/bad-reg.aix64.stderr
Original file line number Diff line number Diff line change
@@ -1,264 +1,240 @@
error: invalid register `sp`: the stack pointer cannot be used as an operand for inline asm
--> $DIR/bad-reg.rs:32:18
--> $DIR/bad-reg.rs:45:18
|
LL | asm!("", out("sp") _);
| ^^^^^^^^^^^

error: invalid register `r2`: r2 is a system reserved register and cannot be used as an operand for inline asm
--> $DIR/bad-reg.rs:34:18
--> $DIR/bad-reg.rs:47:18
|
LL | asm!("", out("r2") _);
| ^^^^^^^^^^^

error: invalid register `r29`: r29 is used internally by LLVM and cannot be used as an operand for inline asm
--> $DIR/bad-reg.rs:38:18
--> $DIR/bad-reg.rs:51:18
|
LL | asm!("", out("r29") _);
| ^^^^^^^^^^^^

error: invalid register `r30`: r30 is used internally by LLVM and cannot be used as an operand for inline asm
--> $DIR/bad-reg.rs:40:18
--> $DIR/bad-reg.rs:53:18
|
LL | asm!("", out("r30") _);
| ^^^^^^^^^^^^

error: invalid register `fp`: the frame pointer cannot be used as an operand for inline asm
--> $DIR/bad-reg.rs:42:18
--> $DIR/bad-reg.rs:55:18
|
LL | asm!("", out("fp") _);
| ^^^^^^^^^^^

error: invalid register `lr`: the link register cannot be used as an operand for inline asm
--> $DIR/bad-reg.rs:44:18
--> $DIR/bad-reg.rs:57:18
|
LL | asm!("", out("lr") _);
| ^^^^^^^^^^^

error: invalid register `ctr`: the counter register cannot be used as an operand for inline asm
--> $DIR/bad-reg.rs:46:18
--> $DIR/bad-reg.rs:59:18
|
LL | asm!("", out("ctr") _);
| ^^^^^^^^^^^^

error: invalid register `vrsave`: the vrsave register cannot be used as an operand for inline asm
--> $DIR/bad-reg.rs:48:18
--> $DIR/bad-reg.rs:61:18
|
LL | asm!("", out("vrsave") _);
| ^^^^^^^^^^^^^^^

error: register class `cr` can only be used as a clobber, not as an input or output
--> $DIR/bad-reg.rs:66:18
--> $DIR/bad-reg.rs:109:18
|
LL | asm!("", in("cr") x);
| ^^^^^^^^^^

error: register class `cr` can only be used as a clobber, not as an input or output
--> $DIR/bad-reg.rs:69:18
--> $DIR/bad-reg.rs:112:18
|
LL | asm!("", out("cr") x);
| ^^^^^^^^^^^

error: register class `cr` can only be used as a clobber, not as an input or output
--> $DIR/bad-reg.rs:72:26
--> $DIR/bad-reg.rs:115:26
|
LL | asm!("/* {} */", in(cr) x);
| ^^^^^^^^

error: register class `cr` can only be used as a clobber, not as an input or output
--> $DIR/bad-reg.rs:75:26
--> $DIR/bad-reg.rs:118:26
|
LL | asm!("/* {} */", out(cr) _);
| ^^^^^^^^^

error: register class `xer` can only be used as a clobber, not as an input or output
--> $DIR/bad-reg.rs:79:18
--> $DIR/bad-reg.rs:122:18
|
LL | asm!("", in("xer") x);
| ^^^^^^^^^^^

error: register class `xer` can only be used as a clobber, not as an input or output
--> $DIR/bad-reg.rs:82:18
--> $DIR/bad-reg.rs:125:18
|
LL | asm!("", out("xer") x);
| ^^^^^^^^^^^^

error: register class `xer` can only be used as a clobber, not as an input or output
--> $DIR/bad-reg.rs:85:26
--> $DIR/bad-reg.rs:128:26
|
LL | asm!("/* {} */", in(xer) x);
| ^^^^^^^^^

error: register class `xer` can only be used as a clobber, not as an input or output
--> $DIR/bad-reg.rs:88:26
--> $DIR/bad-reg.rs:131:26
|
LL | asm!("/* {} */", out(xer) _);
| ^^^^^^^^^^

error: register class `vreg` can only be used as a clobber, not as an input or output
--> $DIR/bad-reg.rs:93:18
|
LL | asm!("", in("v0") x);
| ^^^^^^^^^^

error: register class `vreg` can only be used as a clobber, not as an input or output
--> $DIR/bad-reg.rs:96:18
|
LL | asm!("", out("v0") x);
| ^^^^^^^^^^^

error: register class `vreg` can only be used as a clobber, not as an input or output
--> $DIR/bad-reg.rs:99:26
|
LL | asm!("/* {} */", in(vreg) x);
| ^^^^^^^^^^

error: register class `vreg` can only be used as a clobber, not as an input or output
--> $DIR/bad-reg.rs:102:26
|
LL | asm!("/* {} */", out(vreg) _);
| ^^^^^^^^^^^

error: register `cr0` conflicts with register `cr`
--> $DIR/bad-reg.rs:106:31
--> $DIR/bad-reg.rs:135:31
|
LL | asm!("", out("cr") _, out("cr0") _);
| ----------- ^^^^^^^^^^^^ register `cr0`
| |
| register `cr`

error: register `cr1` conflicts with register `cr`
--> $DIR/bad-reg.rs:108:31
--> $DIR/bad-reg.rs:137:31
|
LL | asm!("", out("cr") _, out("cr1") _);
| ----------- ^^^^^^^^^^^^ register `cr1`
| |
| register `cr`

error: register `cr2` conflicts with register `cr`
--> $DIR/bad-reg.rs:110:31
--> $DIR/bad-reg.rs:139:31
|
LL | asm!("", out("cr") _, out("cr2") _);
| ----------- ^^^^^^^^^^^^ register `cr2`
| |
| register `cr`

error: register `cr3` conflicts with register `cr`
--> $DIR/bad-reg.rs:112:31
--> $DIR/bad-reg.rs:141:31
|
LL | asm!("", out("cr") _, out("cr3") _);
| ----------- ^^^^^^^^^^^^ register `cr3`
| |
| register `cr`

error: register `cr4` conflicts with register `cr`
--> $DIR/bad-reg.rs:114:31
--> $DIR/bad-reg.rs:143:31
|
LL | asm!("", out("cr") _, out("cr4") _);
| ----------- ^^^^^^^^^^^^ register `cr4`
| |
| register `cr`

error: register `cr5` conflicts with register `cr`
--> $DIR/bad-reg.rs:116:31
--> $DIR/bad-reg.rs:145:31
|
LL | asm!("", out("cr") _, out("cr5") _);
| ----------- ^^^^^^^^^^^^ register `cr5`
| |
| register `cr`

error: register `cr6` conflicts with register `cr`
--> $DIR/bad-reg.rs:118:31
--> $DIR/bad-reg.rs:147:31
|
LL | asm!("", out("cr") _, out("cr6") _);
| ----------- ^^^^^^^^^^^^ register `cr6`
| |
| register `cr`

error: register `cr7` conflicts with register `cr`
--> $DIR/bad-reg.rs:120:31
--> $DIR/bad-reg.rs:149:31
|
LL | asm!("", out("cr") _, out("cr7") _);
| ----------- ^^^^^^^^^^^^ register `cr7`
| |
| register `cr`

error: cannot use register `r13`: r13 is a reserved register on this target
--> $DIR/bad-reg.rs:36:18
--> $DIR/bad-reg.rs:49:18
|
LL | asm!("", out("r13") _);
| ^^^^^^^^^^^^

error: type `i32` cannot be used with this register class
--> $DIR/bad-reg.rs:66:27
--> $DIR/bad-reg.rs:76:27
|
LL | asm!("", in("v0") x); // FIXME: should be ok if vsx is available
| ^
|
= 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
|
LL | asm!("", out("v0") x); // FIXME: should be ok if vsx is available
| ^
|
= 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
|
LL | asm!("/* {} */", in(vreg) x); // FIXME: should be ok if vsx is available
| ^
|
= 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
|
LL | asm!("", in("cr") x);
| ^
|
= note: register class `cr` supports these types:

error: type `i32` cannot be used with this register class
--> $DIR/bad-reg.rs:69:28
--> $DIR/bad-reg.rs:112:28
|
LL | asm!("", out("cr") x);
| ^
|
= note: register class `cr` supports these types:

error: type `i32` cannot be used with this register class
--> $DIR/bad-reg.rs:72:33
--> $DIR/bad-reg.rs:115:33
|
LL | asm!("/* {} */", in(cr) x);
| ^
|
= note: register class `cr` supports these types:

error: type `i32` cannot be used with this register class
--> $DIR/bad-reg.rs:79:28
--> $DIR/bad-reg.rs:122:28
|
LL | asm!("", in("xer") x);
| ^
|
= note: register class `xer` supports these types:

error: type `i32` cannot be used with this register class
--> $DIR/bad-reg.rs:82:29
--> $DIR/bad-reg.rs:125:29
|
LL | asm!("", out("xer") x);
| ^
|
= note: register class `xer` supports these types:

error: type `i32` cannot be used with this register class
--> $DIR/bad-reg.rs:85:34
--> $DIR/bad-reg.rs:128:34
|
LL | asm!("/* {} */", in(xer) x);
| ^
|
= note: register class `xer` supports these types:

error: type `i32` cannot be used with this register class
--> $DIR/bad-reg.rs:93:27
|
LL | asm!("", in("v0") x);
| ^
|
= note: register class `vreg` supports these types:

error: type `i32` cannot be used with this register class
--> $DIR/bad-reg.rs:96:28
|
LL | asm!("", out("v0") x);
| ^
|
= note: register class `vreg` supports these types:

error: type `i32` cannot be used with this register class
--> $DIR/bad-reg.rs:99:35
|
LL | asm!("/* {} */", in(vreg) x);
| ^
|
= note: register class `vreg` supports these types:

error: aborting due to 38 previous errors
error: aborting due to 34 previous errors

172 changes: 92 additions & 80 deletions tests/ui/asm/powerpc/bad-reg.powerpc.stderr
Original file line number Diff line number Diff line change
@@ -1,264 +1,276 @@
error: invalid register `sp`: the stack pointer cannot be used as an operand for inline asm
--> $DIR/bad-reg.rs:32:18
--> $DIR/bad-reg.rs:45:18
|
LL | asm!("", out("sp") _);
| ^^^^^^^^^^^

error: invalid register `r2`: r2 is a system reserved register and cannot be used as an operand for inline asm
--> $DIR/bad-reg.rs:34:18
--> $DIR/bad-reg.rs:47:18
|
LL | asm!("", out("r2") _);
| ^^^^^^^^^^^

error: invalid register `r29`: r29 is used internally by LLVM and cannot be used as an operand for inline asm
--> $DIR/bad-reg.rs:38:18
--> $DIR/bad-reg.rs:51:18
|
LL | asm!("", out("r29") _);
| ^^^^^^^^^^^^

error: invalid register `r30`: r30 is used internally by LLVM and cannot be used as an operand for inline asm
--> $DIR/bad-reg.rs:40:18
--> $DIR/bad-reg.rs:53:18
|
LL | asm!("", out("r30") _);
| ^^^^^^^^^^^^

error: invalid register `fp`: the frame pointer cannot be used as an operand for inline asm
--> $DIR/bad-reg.rs:42:18
--> $DIR/bad-reg.rs:55:18
|
LL | asm!("", out("fp") _);
| ^^^^^^^^^^^

error: invalid register `lr`: the link register cannot be used as an operand for inline asm
--> $DIR/bad-reg.rs:44:18
--> $DIR/bad-reg.rs:57:18
|
LL | asm!("", out("lr") _);
| ^^^^^^^^^^^

error: invalid register `ctr`: the counter register cannot be used as an operand for inline asm
--> $DIR/bad-reg.rs:46:18
--> $DIR/bad-reg.rs:59:18
|
LL | asm!("", out("ctr") _);
| ^^^^^^^^^^^^

error: invalid register `vrsave`: the vrsave register cannot be used as an operand for inline asm
--> $DIR/bad-reg.rs:48:18
--> $DIR/bad-reg.rs:61:18
|
LL | asm!("", out("vrsave") _);
| ^^^^^^^^^^^^^^^

error: register class `cr` can only be used as a clobber, not as an input or output
--> $DIR/bad-reg.rs:66:18
--> $DIR/bad-reg.rs:109:18
|
LL | asm!("", in("cr") x);
| ^^^^^^^^^^

error: register class `cr` can only be used as a clobber, not as an input or output
--> $DIR/bad-reg.rs:69:18
--> $DIR/bad-reg.rs:112:18
|
LL | asm!("", out("cr") x);
| ^^^^^^^^^^^

error: register class `cr` can only be used as a clobber, not as an input or output
--> $DIR/bad-reg.rs:72:26
--> $DIR/bad-reg.rs:115:26
|
LL | asm!("/* {} */", in(cr) x);
| ^^^^^^^^

error: register class `cr` can only be used as a clobber, not as an input or output
--> $DIR/bad-reg.rs:75:26
--> $DIR/bad-reg.rs:118:26
|
LL | asm!("/* {} */", out(cr) _);
| ^^^^^^^^^

error: register class `xer` can only be used as a clobber, not as an input or output
--> $DIR/bad-reg.rs:79:18
--> $DIR/bad-reg.rs:122:18
|
LL | asm!("", in("xer") x);
| ^^^^^^^^^^^

error: register class `xer` can only be used as a clobber, not as an input or output
--> $DIR/bad-reg.rs:82:18
--> $DIR/bad-reg.rs:125:18
|
LL | asm!("", out("xer") x);
| ^^^^^^^^^^^^

error: register class `xer` can only be used as a clobber, not as an input or output
--> $DIR/bad-reg.rs:85:26
--> $DIR/bad-reg.rs:128:26
|
LL | asm!("/* {} */", in(xer) x);
| ^^^^^^^^^

error: register class `xer` can only be used as a clobber, not as an input or output
--> $DIR/bad-reg.rs:88:26
--> $DIR/bad-reg.rs:131:26
|
LL | asm!("/* {} */", out(xer) _);
| ^^^^^^^^^^

error: register class `vreg` can only be used as a clobber, not as an input or output
--> $DIR/bad-reg.rs:93:18
|
LL | asm!("", in("v0") x);
| ^^^^^^^^^^

error: register class `vreg` can only be used as a clobber, not as an input or output
--> $DIR/bad-reg.rs:96:18
|
LL | asm!("", out("v0") x);
| ^^^^^^^^^^^

error: register class `vreg` can only be used as a clobber, not as an input or output
--> $DIR/bad-reg.rs:99:26
|
LL | asm!("/* {} */", in(vreg) x);
| ^^^^^^^^^^

error: register class `vreg` can only be used as a clobber, not as an input or output
--> $DIR/bad-reg.rs:102:26
|
LL | asm!("/* {} */", out(vreg) _);
| ^^^^^^^^^^^

error: register `cr0` conflicts with register `cr`
--> $DIR/bad-reg.rs:106:31
--> $DIR/bad-reg.rs:135:31
|
LL | asm!("", out("cr") _, out("cr0") _);
| ----------- ^^^^^^^^^^^^ register `cr0`
| |
| register `cr`

error: register `cr1` conflicts with register `cr`
--> $DIR/bad-reg.rs:108:31
--> $DIR/bad-reg.rs:137:31
|
LL | asm!("", out("cr") _, out("cr1") _);
| ----------- ^^^^^^^^^^^^ register `cr1`
| |
| register `cr`

error: register `cr2` conflicts with register `cr`
--> $DIR/bad-reg.rs:110:31
--> $DIR/bad-reg.rs:139:31
|
LL | asm!("", out("cr") _, out("cr2") _);
| ----------- ^^^^^^^^^^^^ register `cr2`
| |
| register `cr`

error: register `cr3` conflicts with register `cr`
--> $DIR/bad-reg.rs:112:31
--> $DIR/bad-reg.rs:141:31
|
LL | asm!("", out("cr") _, out("cr3") _);
| ----------- ^^^^^^^^^^^^ register `cr3`
| |
| register `cr`

error: register `cr4` conflicts with register `cr`
--> $DIR/bad-reg.rs:114:31
--> $DIR/bad-reg.rs:143:31
|
LL | asm!("", out("cr") _, out("cr4") _);
| ----------- ^^^^^^^^^^^^ register `cr4`
| |
| register `cr`

error: register `cr5` conflicts with register `cr`
--> $DIR/bad-reg.rs:116:31
--> $DIR/bad-reg.rs:145:31
|
LL | asm!("", out("cr") _, out("cr5") _);
| ----------- ^^^^^^^^^^^^ register `cr5`
| |
| register `cr`

error: register `cr6` conflicts with register `cr`
--> $DIR/bad-reg.rs:118:31
--> $DIR/bad-reg.rs:147:31
|
LL | asm!("", out("cr") _, out("cr6") _);
| ----------- ^^^^^^^^^^^^ register `cr6`
| |
| register `cr`

error: register `cr7` conflicts with register `cr`
--> $DIR/bad-reg.rs:120:31
--> $DIR/bad-reg.rs:149:31
|
LL | asm!("", out("cr") _, out("cr7") _);
| ----------- ^^^^^^^^^^^^ register `cr7`
| |
| register `cr`

error: cannot use register `r13`: r13 is a reserved register on this target
--> $DIR/bad-reg.rs:36:18
--> $DIR/bad-reg.rs:49:18
|
LL | asm!("", out("r13") _);
| ^^^^^^^^^^^^

error: register class `vreg` requires at least one of the following target features: altivec, vsx
--> $DIR/bad-reg.rs:66:18
|
LL | asm!("", in("v0") v32x4); // requires altivec
| ^^^^^^^^^^^^^^

error: register class `vreg` requires at least one of the following target features: altivec, vsx
--> $DIR/bad-reg.rs:68:18
|
LL | asm!("", out("v0") v32x4); // requires altivec
| ^^^^^^^^^^^^^^^

error: register class `vreg` requires at least one of the following target features: altivec, vsx
--> $DIR/bad-reg.rs:70:18
|
LL | asm!("", in("v0") v64x2); // requires vsx
| ^^^^^^^^^^^^^^

error: register class `vreg` requires at least one of the following target features: altivec, vsx
--> $DIR/bad-reg.rs:73:18
|
LL | asm!("", out("v0") v64x2); // requires vsx
| ^^^^^^^^^^^^^^^

error: register class `vreg` requires at least one of the following target features: altivec, vsx
--> $DIR/bad-reg.rs:76:18
|
LL | asm!("", in("v0") x); // FIXME: should be ok if vsx is available
| ^^^^^^^^^^

error: register class `vreg` requires at least one of the following target features: altivec, vsx
--> $DIR/bad-reg.rs:79:18
|
LL | asm!("", out("v0") x); // FIXME: should be ok if vsx is available
| ^^^^^^^^^^^

error: register class `vreg` requires at least one of the following target features: altivec, vsx
--> $DIR/bad-reg.rs:82:26
|
LL | asm!("/* {} */", in(vreg) v32x4); // requires altivec
| ^^^^^^^^^^^^^^

error: register class `vreg` requires at least one of the following target features: altivec, vsx
--> $DIR/bad-reg.rs:84:26
|
LL | asm!("/* {} */", in(vreg) v64x2); // requires vsx
| ^^^^^^^^^^^^^^

error: register class `vreg` requires at least one of the following target features: altivec, vsx
--> $DIR/bad-reg.rs:87:26
|
LL | asm!("/* {} */", in(vreg) x); // FIXME: should be ok if vsx is available
| ^^^^^^^^^^

error: register class `vreg` requires at least one of the following target features: altivec, vsx
--> $DIR/bad-reg.rs:90:26
|
LL | asm!("/* {} */", out(vreg) _); // requires altivec
| ^^^^^^^^^^^

error: type `i32` cannot be used with this register class
--> $DIR/bad-reg.rs:66:27
--> $DIR/bad-reg.rs:109:27
|
LL | asm!("", in("cr") x);
| ^
|
= note: register class `cr` supports these types:

error: type `i32` cannot be used with this register class
--> $DIR/bad-reg.rs:69:28
--> $DIR/bad-reg.rs:112:28
|
LL | asm!("", out("cr") x);
| ^
|
= note: register class `cr` supports these types:

error: type `i32` cannot be used with this register class
--> $DIR/bad-reg.rs:72:33
--> $DIR/bad-reg.rs:115:33
|
LL | asm!("/* {} */", in(cr) x);
| ^
|
= note: register class `cr` supports these types:

error: type `i32` cannot be used with this register class
--> $DIR/bad-reg.rs:79:28
--> $DIR/bad-reg.rs:122:28
|
LL | asm!("", in("xer") x);
| ^
|
= note: register class `xer` supports these types:

error: type `i32` cannot be used with this register class
--> $DIR/bad-reg.rs:82:29
--> $DIR/bad-reg.rs:125:29
|
LL | asm!("", out("xer") x);
| ^
|
= note: register class `xer` supports these types:

error: type `i32` cannot be used with this register class
--> $DIR/bad-reg.rs:85:34
--> $DIR/bad-reg.rs:128:34
|
LL | asm!("/* {} */", in(xer) x);
| ^
|
= note: register class `xer` supports these types:

error: type `i32` cannot be used with this register class
--> $DIR/bad-reg.rs:93:27
|
LL | asm!("", in("v0") x);
| ^
|
= note: register class `vreg` supports these types:

error: type `i32` cannot be used with this register class
--> $DIR/bad-reg.rs:96:28
|
LL | asm!("", out("v0") x);
| ^
|
= note: register class `vreg` supports these types:

error: type `i32` cannot be used with this register class
--> $DIR/bad-reg.rs:99:35
|
LL | asm!("/* {} */", in(vreg) x);
| ^
|
= note: register class `vreg` supports these types:

error: aborting due to 38 previous errors
error: aborting due to 41 previous errors

160 changes: 80 additions & 80 deletions tests/ui/asm/powerpc/bad-reg.powerpc64.stderr
Original file line number Diff line number Diff line change
@@ -1,264 +1,264 @@
error: invalid register `sp`: the stack pointer cannot be used as an operand for inline asm
--> $DIR/bad-reg.rs:32:18
--> $DIR/bad-reg.rs:45:18
|
LL | asm!("", out("sp") _);
| ^^^^^^^^^^^

error: invalid register `r2`: r2 is a system reserved register and cannot be used as an operand for inline asm
--> $DIR/bad-reg.rs:34:18
--> $DIR/bad-reg.rs:47:18
|
LL | asm!("", out("r2") _);
| ^^^^^^^^^^^

error: invalid register `r29`: r29 is used internally by LLVM and cannot be used as an operand for inline asm
--> $DIR/bad-reg.rs:38:18
--> $DIR/bad-reg.rs:51:18
|
LL | asm!("", out("r29") _);
| ^^^^^^^^^^^^

error: invalid register `r30`: r30 is used internally by LLVM and cannot be used as an operand for inline asm
--> $DIR/bad-reg.rs:40:18
--> $DIR/bad-reg.rs:53:18
|
LL | asm!("", out("r30") _);
| ^^^^^^^^^^^^

error: invalid register `fp`: the frame pointer cannot be used as an operand for inline asm
--> $DIR/bad-reg.rs:42:18
--> $DIR/bad-reg.rs:55:18
|
LL | asm!("", out("fp") _);
| ^^^^^^^^^^^

error: invalid register `lr`: the link register cannot be used as an operand for inline asm
--> $DIR/bad-reg.rs:44:18
--> $DIR/bad-reg.rs:57:18
|
LL | asm!("", out("lr") _);
| ^^^^^^^^^^^

error: invalid register `ctr`: the counter register cannot be used as an operand for inline asm
--> $DIR/bad-reg.rs:46:18
--> $DIR/bad-reg.rs:59:18
|
LL | asm!("", out("ctr") _);
| ^^^^^^^^^^^^

error: invalid register `vrsave`: the vrsave register cannot be used as an operand for inline asm
--> $DIR/bad-reg.rs:48:18
--> $DIR/bad-reg.rs:61:18
|
LL | asm!("", out("vrsave") _);
| ^^^^^^^^^^^^^^^

error: register class `cr` can only be used as a clobber, not as an input or output
--> $DIR/bad-reg.rs:66:18
--> $DIR/bad-reg.rs:109:18
|
LL | asm!("", in("cr") x);
| ^^^^^^^^^^

error: register class `cr` can only be used as a clobber, not as an input or output
--> $DIR/bad-reg.rs:69:18
--> $DIR/bad-reg.rs:112:18
|
LL | asm!("", out("cr") x);
| ^^^^^^^^^^^

error: register class `cr` can only be used as a clobber, not as an input or output
--> $DIR/bad-reg.rs:72:26
--> $DIR/bad-reg.rs:115:26
|
LL | asm!("/* {} */", in(cr) x);
| ^^^^^^^^

error: register class `cr` can only be used as a clobber, not as an input or output
--> $DIR/bad-reg.rs:75:26
--> $DIR/bad-reg.rs:118:26
|
LL | asm!("/* {} */", out(cr) _);
| ^^^^^^^^^

error: register class `xer` can only be used as a clobber, not as an input or output
--> $DIR/bad-reg.rs:79:18
--> $DIR/bad-reg.rs:122:18
|
LL | asm!("", in("xer") x);
| ^^^^^^^^^^^

error: register class `xer` can only be used as a clobber, not as an input or output
--> $DIR/bad-reg.rs:82:18
--> $DIR/bad-reg.rs:125:18
|
LL | asm!("", out("xer") x);
| ^^^^^^^^^^^^

error: register class `xer` can only be used as a clobber, not as an input or output
--> $DIR/bad-reg.rs:85:26
--> $DIR/bad-reg.rs:128:26
|
LL | asm!("/* {} */", in(xer) x);
| ^^^^^^^^^

error: register class `xer` can only be used as a clobber, not as an input or output
--> $DIR/bad-reg.rs:88:26
--> $DIR/bad-reg.rs:131:26
|
LL | asm!("/* {} */", out(xer) _);
| ^^^^^^^^^^

error: register class `vreg` can only be used as a clobber, not as an input or output
--> $DIR/bad-reg.rs:93:18
|
LL | asm!("", in("v0") x);
| ^^^^^^^^^^

error: register class `vreg` can only be used as a clobber, not as an input or output
--> $DIR/bad-reg.rs:96:18
|
LL | asm!("", out("v0") x);
| ^^^^^^^^^^^

error: register class `vreg` can only be used as a clobber, not as an input or output
--> $DIR/bad-reg.rs:99:26
|
LL | asm!("/* {} */", in(vreg) x);
| ^^^^^^^^^^

error: register class `vreg` can only be used as a clobber, not as an input or output
--> $DIR/bad-reg.rs:102:26
|
LL | asm!("/* {} */", out(vreg) _);
| ^^^^^^^^^^^

error: register `cr0` conflicts with register `cr`
--> $DIR/bad-reg.rs:106:31
--> $DIR/bad-reg.rs:135:31
|
LL | asm!("", out("cr") _, out("cr0") _);
| ----------- ^^^^^^^^^^^^ register `cr0`
| |
| register `cr`

error: register `cr1` conflicts with register `cr`
--> $DIR/bad-reg.rs:108:31
--> $DIR/bad-reg.rs:137:31
|
LL | asm!("", out("cr") _, out("cr1") _);
| ----------- ^^^^^^^^^^^^ register `cr1`
| |
| register `cr`

error: register `cr2` conflicts with register `cr`
--> $DIR/bad-reg.rs:110:31
--> $DIR/bad-reg.rs:139:31
|
LL | asm!("", out("cr") _, out("cr2") _);
| ----------- ^^^^^^^^^^^^ register `cr2`
| |
| register `cr`

error: register `cr3` conflicts with register `cr`
--> $DIR/bad-reg.rs:112:31
--> $DIR/bad-reg.rs:141:31
|
LL | asm!("", out("cr") _, out("cr3") _);
| ----------- ^^^^^^^^^^^^ register `cr3`
| |
| register `cr`

error: register `cr4` conflicts with register `cr`
--> $DIR/bad-reg.rs:114:31
--> $DIR/bad-reg.rs:143:31
|
LL | asm!("", out("cr") _, out("cr4") _);
| ----------- ^^^^^^^^^^^^ register `cr4`
| |
| register `cr`

error: register `cr5` conflicts with register `cr`
--> $DIR/bad-reg.rs:116:31
--> $DIR/bad-reg.rs:145:31
|
LL | asm!("", out("cr") _, out("cr5") _);
| ----------- ^^^^^^^^^^^^ register `cr5`
| |
| register `cr`

error: register `cr6` conflicts with register `cr`
--> $DIR/bad-reg.rs:118:31
--> $DIR/bad-reg.rs:147:31
|
LL | asm!("", out("cr") _, out("cr6") _);
| ----------- ^^^^^^^^^^^^ register `cr6`
| |
| register `cr`

error: register `cr7` conflicts with register `cr`
--> $DIR/bad-reg.rs:120:31
--> $DIR/bad-reg.rs:149:31
|
LL | asm!("", out("cr") _, out("cr7") _);
| ----------- ^^^^^^^^^^^^ register `cr7`
| |
| register `cr`

error: cannot use register `r13`: r13 is a reserved register on this target
--> $DIR/bad-reg.rs:36:18
--> $DIR/bad-reg.rs:49:18
|
LL | asm!("", out("r13") _);
| ^^^^^^^^^^^^

error: `vsx` target feature is not enabled
--> $DIR/bad-reg.rs:70:27
|
LL | asm!("", in("v0") v64x2); // requires vsx
| ^^^^^
|
= note: this is required to use type `i64x2` with register class `vreg`

error: `vsx` target feature is not enabled
--> $DIR/bad-reg.rs:73:28
|
LL | asm!("", out("v0") v64x2); // requires vsx
| ^^^^^
|
= note: this is required to use type `i64x2` with register class `vreg`

error: type `i32` cannot be used with this register class
--> $DIR/bad-reg.rs:76:27
|
LL | asm!("", in("v0") x); // FIXME: should be ok if vsx is available
| ^
|
= 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
|
LL | asm!("", out("v0") x); // FIXME: should be ok if vsx is available
| ^
|
= 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
|
LL | asm!("/* {} */", in(vreg) v64x2); // requires vsx
| ^^^^^
|
= note: this is required to use type `i64x2` with register class `vreg`

error: type `i32` cannot be used with this register class
--> $DIR/bad-reg.rs:66:27
--> $DIR/bad-reg.rs:87:35
|
LL | asm!("/* {} */", in(vreg) x); // FIXME: should be ok if vsx is available
| ^
|
= 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
|
LL | asm!("", in("cr") x);
| ^
|
= note: register class `cr` supports these types:

error: type `i32` cannot be used with this register class
--> $DIR/bad-reg.rs:69:28
--> $DIR/bad-reg.rs:112:28
|
LL | asm!("", out("cr") x);
| ^
|
= note: register class `cr` supports these types:

error: type `i32` cannot be used with this register class
--> $DIR/bad-reg.rs:72:33
--> $DIR/bad-reg.rs:115:33
|
LL | asm!("/* {} */", in(cr) x);
| ^
|
= note: register class `cr` supports these types:

error: type `i32` cannot be used with this register class
--> $DIR/bad-reg.rs:79:28
--> $DIR/bad-reg.rs:122:28
|
LL | asm!("", in("xer") x);
| ^
|
= note: register class `xer` supports these types:

error: type `i32` cannot be used with this register class
--> $DIR/bad-reg.rs:82:29
--> $DIR/bad-reg.rs:125:29
|
LL | asm!("", out("xer") x);
| ^
|
= note: register class `xer` supports these types:

error: type `i32` cannot be used with this register class
--> $DIR/bad-reg.rs:85:34
--> $DIR/bad-reg.rs:128:34
|
LL | asm!("/* {} */", in(xer) x);
| ^
|
= note: register class `xer` supports these types:

error: type `i32` cannot be used with this register class
--> $DIR/bad-reg.rs:93:27
|
LL | asm!("", in("v0") x);
| ^
|
= note: register class `vreg` supports these types:

error: type `i32` cannot be used with this register class
--> $DIR/bad-reg.rs:96:28
|
LL | asm!("", out("v0") x);
| ^
|
= note: register class `vreg` supports these types:

error: type `i32` cannot be used with this register class
--> $DIR/bad-reg.rs:99:35
|
LL | asm!("/* {} */", in(vreg) x);
| ^
|
= note: register class `vreg` supports these types:

error: aborting due to 38 previous errors
error: aborting due to 37 previous errors

136 changes: 56 additions & 80 deletions tests/ui/asm/powerpc/bad-reg.powerpc64le.stderr
Original file line number Diff line number Diff line change
@@ -1,264 +1,240 @@
error: invalid register `sp`: the stack pointer cannot be used as an operand for inline asm
--> $DIR/bad-reg.rs:32:18
--> $DIR/bad-reg.rs:45:18
|
LL | asm!("", out("sp") _);
| ^^^^^^^^^^^

error: invalid register `r2`: r2 is a system reserved register and cannot be used as an operand for inline asm
--> $DIR/bad-reg.rs:34:18
--> $DIR/bad-reg.rs:47:18
|
LL | asm!("", out("r2") _);
| ^^^^^^^^^^^

error: invalid register `r29`: r29 is used internally by LLVM and cannot be used as an operand for inline asm
--> $DIR/bad-reg.rs:38:18
--> $DIR/bad-reg.rs:51:18
|
LL | asm!("", out("r29") _);
| ^^^^^^^^^^^^

error: invalid register `r30`: r30 is used internally by LLVM and cannot be used as an operand for inline asm
--> $DIR/bad-reg.rs:40:18
--> $DIR/bad-reg.rs:53:18
|
LL | asm!("", out("r30") _);
| ^^^^^^^^^^^^

error: invalid register `fp`: the frame pointer cannot be used as an operand for inline asm
--> $DIR/bad-reg.rs:42:18
--> $DIR/bad-reg.rs:55:18
|
LL | asm!("", out("fp") _);
| ^^^^^^^^^^^

error: invalid register `lr`: the link register cannot be used as an operand for inline asm
--> $DIR/bad-reg.rs:44:18
--> $DIR/bad-reg.rs:57:18
|
LL | asm!("", out("lr") _);
| ^^^^^^^^^^^

error: invalid register `ctr`: the counter register cannot be used as an operand for inline asm
--> $DIR/bad-reg.rs:46:18
--> $DIR/bad-reg.rs:59:18
|
LL | asm!("", out("ctr") _);
| ^^^^^^^^^^^^

error: invalid register `vrsave`: the vrsave register cannot be used as an operand for inline asm
--> $DIR/bad-reg.rs:48:18
--> $DIR/bad-reg.rs:61:18
|
LL | asm!("", out("vrsave") _);
| ^^^^^^^^^^^^^^^

error: register class `cr` can only be used as a clobber, not as an input or output
--> $DIR/bad-reg.rs:66:18
--> $DIR/bad-reg.rs:109:18
|
LL | asm!("", in("cr") x);
| ^^^^^^^^^^

error: register class `cr` can only be used as a clobber, not as an input or output
--> $DIR/bad-reg.rs:69:18
--> $DIR/bad-reg.rs:112:18
|
LL | asm!("", out("cr") x);
| ^^^^^^^^^^^

error: register class `cr` can only be used as a clobber, not as an input or output
--> $DIR/bad-reg.rs:72:26
--> $DIR/bad-reg.rs:115:26
|
LL | asm!("/* {} */", in(cr) x);
| ^^^^^^^^

error: register class `cr` can only be used as a clobber, not as an input or output
--> $DIR/bad-reg.rs:75:26
--> $DIR/bad-reg.rs:118:26
|
LL | asm!("/* {} */", out(cr) _);
| ^^^^^^^^^

error: register class `xer` can only be used as a clobber, not as an input or output
--> $DIR/bad-reg.rs:79:18
--> $DIR/bad-reg.rs:122:18
|
LL | asm!("", in("xer") x);
| ^^^^^^^^^^^

error: register class `xer` can only be used as a clobber, not as an input or output
--> $DIR/bad-reg.rs:82:18
--> $DIR/bad-reg.rs:125:18
|
LL | asm!("", out("xer") x);
| ^^^^^^^^^^^^

error: register class `xer` can only be used as a clobber, not as an input or output
--> $DIR/bad-reg.rs:85:26
--> $DIR/bad-reg.rs:128:26
|
LL | asm!("/* {} */", in(xer) x);
| ^^^^^^^^^

error: register class `xer` can only be used as a clobber, not as an input or output
--> $DIR/bad-reg.rs:88:26
--> $DIR/bad-reg.rs:131:26
|
LL | asm!("/* {} */", out(xer) _);
| ^^^^^^^^^^

error: register class `vreg` can only be used as a clobber, not as an input or output
--> $DIR/bad-reg.rs:93:18
|
LL | asm!("", in("v0") x);
| ^^^^^^^^^^

error: register class `vreg` can only be used as a clobber, not as an input or output
--> $DIR/bad-reg.rs:96:18
|
LL | asm!("", out("v0") x);
| ^^^^^^^^^^^

error: register class `vreg` can only be used as a clobber, not as an input or output
--> $DIR/bad-reg.rs:99:26
|
LL | asm!("/* {} */", in(vreg) x);
| ^^^^^^^^^^

error: register class `vreg` can only be used as a clobber, not as an input or output
--> $DIR/bad-reg.rs:102:26
|
LL | asm!("/* {} */", out(vreg) _);
| ^^^^^^^^^^^

error: register `cr0` conflicts with register `cr`
--> $DIR/bad-reg.rs:106:31
--> $DIR/bad-reg.rs:135:31
|
LL | asm!("", out("cr") _, out("cr0") _);
| ----------- ^^^^^^^^^^^^ register `cr0`
| |
| register `cr`

error: register `cr1` conflicts with register `cr`
--> $DIR/bad-reg.rs:108:31
--> $DIR/bad-reg.rs:137:31
|
LL | asm!("", out("cr") _, out("cr1") _);
| ----------- ^^^^^^^^^^^^ register `cr1`
| |
| register `cr`

error: register `cr2` conflicts with register `cr`
--> $DIR/bad-reg.rs:110:31
--> $DIR/bad-reg.rs:139:31
|
LL | asm!("", out("cr") _, out("cr2") _);
| ----------- ^^^^^^^^^^^^ register `cr2`
| |
| register `cr`

error: register `cr3` conflicts with register `cr`
--> $DIR/bad-reg.rs:112:31
--> $DIR/bad-reg.rs:141:31
|
LL | asm!("", out("cr") _, out("cr3") _);
| ----------- ^^^^^^^^^^^^ register `cr3`
| |
| register `cr`

error: register `cr4` conflicts with register `cr`
--> $DIR/bad-reg.rs:114:31
--> $DIR/bad-reg.rs:143:31
|
LL | asm!("", out("cr") _, out("cr4") _);
| ----------- ^^^^^^^^^^^^ register `cr4`
| |
| register `cr`

error: register `cr5` conflicts with register `cr`
--> $DIR/bad-reg.rs:116:31
--> $DIR/bad-reg.rs:145:31
|
LL | asm!("", out("cr") _, out("cr5") _);
| ----------- ^^^^^^^^^^^^ register `cr5`
| |
| register `cr`

error: register `cr6` conflicts with register `cr`
--> $DIR/bad-reg.rs:118:31
--> $DIR/bad-reg.rs:147:31
|
LL | asm!("", out("cr") _, out("cr6") _);
| ----------- ^^^^^^^^^^^^ register `cr6`
| |
| register `cr`

error: register `cr7` conflicts with register `cr`
--> $DIR/bad-reg.rs:120:31
--> $DIR/bad-reg.rs:149:31
|
LL | asm!("", out("cr") _, out("cr7") _);
| ----------- ^^^^^^^^^^^^ register `cr7`
| |
| register `cr`

error: cannot use register `r13`: r13 is a reserved register on this target
--> $DIR/bad-reg.rs:36:18
--> $DIR/bad-reg.rs:49:18
|
LL | asm!("", out("r13") _);
| ^^^^^^^^^^^^

error: type `i32` cannot be used with this register class
--> $DIR/bad-reg.rs:66:27
--> $DIR/bad-reg.rs:76:27
|
LL | asm!("", in("v0") x); // FIXME: should be ok if vsx is available
| ^
|
= 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
|
LL | asm!("", out("v0") x); // FIXME: should be ok if vsx is available
| ^
|
= 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
|
LL | asm!("/* {} */", in(vreg) x); // FIXME: should be ok if vsx is available
| ^
|
= 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
|
LL | asm!("", in("cr") x);
| ^
|
= note: register class `cr` supports these types:

error: type `i32` cannot be used with this register class
--> $DIR/bad-reg.rs:69:28
--> $DIR/bad-reg.rs:112:28
|
LL | asm!("", out("cr") x);
| ^
|
= note: register class `cr` supports these types:

error: type `i32` cannot be used with this register class
--> $DIR/bad-reg.rs:72:33
--> $DIR/bad-reg.rs:115:33
|
LL | asm!("/* {} */", in(cr) x);
| ^
|
= note: register class `cr` supports these types:

error: type `i32` cannot be used with this register class
--> $DIR/bad-reg.rs:79:28
--> $DIR/bad-reg.rs:122:28
|
LL | asm!("", in("xer") x);
| ^
|
= note: register class `xer` supports these types:

error: type `i32` cannot be used with this register class
--> $DIR/bad-reg.rs:82:29
--> $DIR/bad-reg.rs:125:29
|
LL | asm!("", out("xer") x);
| ^
|
= note: register class `xer` supports these types:

error: type `i32` cannot be used with this register class
--> $DIR/bad-reg.rs:85:34
--> $DIR/bad-reg.rs:128:34
|
LL | asm!("/* {} */", in(xer) x);
| ^
|
= note: register class `xer` supports these types:

error: type `i32` cannot be used with this register class
--> $DIR/bad-reg.rs:93:27
|
LL | asm!("", in("v0") x);
| ^
|
= note: register class `vreg` supports these types:

error: type `i32` cannot be used with this register class
--> $DIR/bad-reg.rs:96:28
|
LL | asm!("", out("v0") x);
| ^
|
= note: register class `vreg` supports these types:

error: type `i32` cannot be used with this register class
--> $DIR/bad-reg.rs:99:35
|
LL | asm!("/* {} */", in(vreg) x);
| ^
|
= note: register class `vreg` supports these types:

error: aborting due to 38 previous errors
error: aborting due to 34 previous errors

59 changes: 44 additions & 15 deletions tests/ui/asm/powerpc/bad-reg.rs
Original file line number Diff line number Diff line change
@@ -8,17 +8,28 @@
//@[aix64] compile-flags: --target powerpc64-ibm-aix
//@[aix64] needs-llvm-components: powerpc
//@ needs-asm-support
// ignore-tidy-linelength

#![crate_type = "rlib"]
#![feature(no_core, rustc_attrs, lang_items, asm_experimental_arch)]
#![feature(no_core, rustc_attrs, lang_items, repr_simd, asm_experimental_arch)]
#![no_core]
#![allow(non_camel_case_types)]

#[lang = "sized"]
trait Sized {}
#[lang = "copy"]
trait Copy {}

#[repr(simd)]
pub struct i32x4([i32; 4]);
#[repr(simd)]
pub struct i64x2([i64; 2]);

impl<T: Copy, const N: usize> Copy for [T; N] {}
impl Copy for i32 {}
impl Copy for i64 {}
impl Copy for i32x4 {}
impl Copy for i64x2 {}

#[rustc_builtin_macro]
macro_rules! asm {
@@ -27,6 +38,8 @@ macro_rules! asm {

fn f() {
let mut x = 0;
let mut v32x4 = i32x4([0; 4]);
let mut v64x2 = i64x2([0; 2]);
unsafe {
// Unsupported registers
asm!("", out("sp") _);
@@ -47,6 +60,36 @@ fn f() {
//~^ ERROR invalid register `ctr`: the counter register cannot be used as an operand for inline asm
asm!("", out("vrsave") _);
//~^ ERROR invalid register `vrsave`: the vrsave register cannot be used as an operand for inline asm

// vreg
asm!("", out("v0") _); // always ok
asm!("", in("v0") v32x4); // requires altivec
//[powerpc]~^ ERROR register class `vreg` requires at least one of the following target features: altivec, vsx
asm!("", out("v0") v32x4); // requires altivec
//[powerpc]~^ ERROR register class `vreg` requires at least one of the following target features: altivec, vsx
asm!("", in("v0") v64x2); // requires vsx
//[powerpc]~^ ERROR register class `vreg` requires at least one of the following target features: altivec, vsx
//[powerpc64]~^^ ERROR `vsx` target feature is not enabled
asm!("", out("v0") v64x2); // requires vsx
//[powerpc]~^ ERROR register class `vreg` requires at least one of the following target features: altivec, vsx
//[powerpc64]~^^ ERROR `vsx` target feature is not enabled
asm!("", in("v0") x); // FIXME: should be ok if vsx is available
//[powerpc]~^ ERROR register class `vreg` requires at least one of the following target features: altivec, vsx
//[powerpc64,powerpc64le,aix64]~^^ ERROR type `i32` cannot be used with this register class
asm!("", out("v0") x); // FIXME: should be ok if vsx is available
//[powerpc]~^ ERROR register class `vreg` requires at least one of the following target features: altivec, vsx
//[powerpc64,powerpc64le,aix64]~^^ ERROR type `i32` cannot be used with this register class
asm!("/* {} */", in(vreg) v32x4); // requires altivec
//[powerpc]~^ ERROR register class `vreg` requires at least one of the following target features: altivec, vsx
asm!("/* {} */", in(vreg) v64x2); // requires vsx
//[powerpc]~^ ERROR register class `vreg` requires at least one of the following target features: altivec, vsx
//[powerpc64]~^^ ERROR `vsx` target feature is not enabled
asm!("/* {} */", in(vreg) x); // FIXME: should be ok if vsx is available
//[powerpc]~^ ERROR register class `vreg` requires at least one of the following target features: altivec, vsx
//[powerpc64,powerpc64le,aix64]~^^ ERROR type `i32` cannot be used with this register class
asm!("/* {} */", out(vreg) _); // requires altivec
//[powerpc]~^ ERROR register class `vreg` requires at least one of the following target features: altivec, vsx
// v20-v31 are reserved on AIX with vec-default ABI (this ABI is not currently used in Rust's builtin AIX targets).
asm!("", out("v20") _);
asm!("", out("v21") _);
asm!("", out("v22") _);
@@ -87,20 +130,6 @@ fn f() {
//~| ERROR type `i32` cannot be used with this register class
asm!("/* {} */", out(xer) _);
//~^ ERROR can only be used as a clobber
// vreg
asm!("", out("v0") _); // ok
// FIXME: will be supported in the subsequent patch: https://github.com/rust-lang/rust/pull/131551
asm!("", in("v0") x);
//~^ ERROR can only be used as a clobber
//~| ERROR type `i32` cannot be used with this register class
asm!("", out("v0") x);
//~^ ERROR can only be used as a clobber
//~| ERROR type `i32` cannot be used with this register class
asm!("/* {} */", in(vreg) x);
//~^ ERROR can only be used as a clobber
//~| ERROR type `i32` cannot be used with this register class
asm!("/* {} */", out(vreg) _);
//~^ ERROR can only be used as a clobber

// Overlapping-only registers
asm!("", out("cr") _, out("cr0") _);

0 comments on commit 1aa0192

Please sign in to comment.