Skip to content

Commit b6b9f79

Browse files
committed
Support input/output in vector registers in s390x inline assembly
1 parent 75703c1 commit b6b9f79

File tree

9 files changed

+677
-118
lines changed

9 files changed

+677
-118
lines changed

compiler/rustc_codegen_gcc/src/asm.rs

+4-4
Original file line numberDiff line numberDiff line change
@@ -683,9 +683,8 @@ fn reg_to_gcc(reg: InlineAsmRegOrRegClass) -> ConstraintOrRegister {
683683
InlineAsmRegClass::S390x(S390xInlineAsmRegClass::reg) => "r",
684684
InlineAsmRegClass::S390x(S390xInlineAsmRegClass::reg_addr) => "a",
685685
InlineAsmRegClass::S390x(S390xInlineAsmRegClass::freg) => "f",
686-
InlineAsmRegClass::S390x(
687-
S390xInlineAsmRegClass::vreg | S390xInlineAsmRegClass::areg,
688-
) => {
686+
InlineAsmRegClass::S390x(S390xInlineAsmRegClass::vreg) => "v",
687+
InlineAsmRegClass::S390x(S390xInlineAsmRegClass::areg) => {
689688
unreachable!("clobber-only")
690689
}
691690
InlineAsmRegClass::Sparc(SparcInlineAsmRegClass::reg) => "r",
@@ -766,7 +765,8 @@ fn dummy_output_type<'gcc, 'tcx>(cx: &CodegenCx<'gcc, 'tcx>, reg: InlineAsmRegCl
766765
S390xInlineAsmRegClass::reg | S390xInlineAsmRegClass::reg_addr,
767766
) => cx.type_i32(),
768767
InlineAsmRegClass::S390x(S390xInlineAsmRegClass::freg) => cx.type_f64(),
769-
InlineAsmRegClass::S390x(S390xInlineAsmRegClass::vreg | S390xInlineAsmRegClass::areg) => {
768+
InlineAsmRegClass::S390x(S390xInlineAsmRegClass::vreg) => cx.type_vector(cx.type_i64(), 2),
769+
InlineAsmRegClass::S390x(S390xInlineAsmRegClass::areg) => {
770770
unreachable!("clobber-only")
771771
}
772772
InlineAsmRegClass::Sparc(SparcInlineAsmRegClass::reg) => cx.type_i32(),

compiler/rustc_codegen_llvm/src/asm.rs

+4-2
Original file line numberDiff line numberDiff line change
@@ -678,7 +678,8 @@ fn reg_to_llvm(reg: InlineAsmRegOrRegClass, layout: Option<&TyAndLayout<'_>>) ->
678678
S390x(S390xInlineAsmRegClass::reg) => "r",
679679
S390x(S390xInlineAsmRegClass::reg_addr) => "a",
680680
S390x(S390xInlineAsmRegClass::freg) => "f",
681-
S390x(S390xInlineAsmRegClass::vreg | S390xInlineAsmRegClass::areg) => {
681+
S390x(S390xInlineAsmRegClass::vreg) => "v",
682+
S390x(S390xInlineAsmRegClass::areg) => {
682683
unreachable!("clobber-only")
683684
}
684685
Sparc(SparcInlineAsmRegClass::reg) => "r",
@@ -844,7 +845,8 @@ fn dummy_output_type<'ll>(cx: &CodegenCx<'ll, '_>, reg: InlineAsmRegClass) -> &'
844845
Avr(AvrInlineAsmRegClass::reg_ptr) => cx.type_i16(),
845846
S390x(S390xInlineAsmRegClass::reg | S390xInlineAsmRegClass::reg_addr) => cx.type_i32(),
846847
S390x(S390xInlineAsmRegClass::freg) => cx.type_f64(),
847-
S390x(S390xInlineAsmRegClass::vreg | S390xInlineAsmRegClass::areg) => {
848+
S390x(S390xInlineAsmRegClass::vreg) => cx.type_vector(cx.type_i64(), 2),
849+
S390x(S390xInlineAsmRegClass::areg) => {
848850
unreachable!("clobber-only")
849851
}
850852
Sparc(SparcInlineAsmRegClass::reg) => cx.type_i32(),

compiler/rustc_span/src/symbol.rs

+1
Original file line numberDiff line numberDiff line change
@@ -2137,6 +2137,7 @@ symbols! {
21372137
vec_pop,
21382138
vec_with_capacity,
21392139
vecdeque_iter,
2140+
vector,
21402141
version,
21412142
vfp2,
21422143
vis,

compiler/rustc_target/src/asm/s390x.rs

+4-1
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,10 @@ impl S390xInlineAsmRegClass {
4242
match self {
4343
Self::reg | Self::reg_addr => types! { _: I8, I16, I32, I64; },
4444
Self::freg => types! { _: F32, F64; },
45-
Self::vreg => &[],
45+
Self::vreg => types! {
46+
vector: I32, F32, I64, F64, I128, F128,
47+
VecI8(16), VecI16(8), VecI32(4), VecI64(2), VecF32(4), VecF64(2);
48+
},
4649
Self::areg => &[],
4750
}
4851
}

tests/assembly/asm/s390x-types.rs

+195-3
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,12 @@
1-
//@ revisions: s390x
1+
//@ revisions: s390x s390x_vector
22
//@ assembly-output: emit-asm
33
//@[s390x] compile-flags: --target s390x-unknown-linux-gnu
44
//@[s390x] needs-llvm-components: systemz
5+
//@[s390x_vector] compile-flags: --target s390x-unknown-linux-gnu -C target-feature=+vector
6+
//@[s390x_vector] needs-llvm-components: systemz
57
//@ compile-flags: -Zmerge-functions=disabled
68

7-
#![feature(no_core, lang_items, rustc_attrs, repr_simd)]
9+
#![feature(no_core, lang_items, rustc_attrs, repr_simd, f128)]
810
#![crate_type = "rlib"]
911
#![no_core]
1012
#![allow(asm_sub_register, non_camel_case_types)]
@@ -27,16 +29,39 @@ trait Sized {}
2729
#[lang = "copy"]
2830
trait Copy {}
2931

32+
impl<T: Copy, const N: usize> Copy for [T; N] {}
33+
3034
type ptr = *const i32;
3135

36+
#[repr(simd)]
37+
pub struct i8x16([i8; 16]);
38+
#[repr(simd)]
39+
pub struct i16x8([i16; 8]);
40+
#[repr(simd)]
41+
pub struct i32x4([i32; 4]);
42+
#[repr(simd)]
43+
pub struct i64x2([i64; 2]);
44+
#[repr(simd)]
45+
pub struct f32x4([f32; 4]);
46+
#[repr(simd)]
47+
pub struct f64x2([f64; 2]);
48+
3249
impl Copy for i8 {}
3350
impl Copy for u8 {}
3451
impl Copy for i16 {}
3552
impl Copy for i32 {}
3653
impl Copy for i64 {}
54+
impl Copy for i128 {}
3755
impl Copy for f32 {}
3856
impl Copy for f64 {}
57+
impl Copy for f128 {}
3958
impl Copy for ptr {}
59+
impl Copy for i8x16 {}
60+
impl Copy for i16x8 {}
61+
impl Copy for i32x4 {}
62+
impl Copy for i64x2 {}
63+
impl Copy for f32x4 {}
64+
impl Copy for f64x2 {}
4065

4166
extern "C" {
4267
fn extern_func();
@@ -65,7 +90,6 @@ macro_rules! check_reg { ($func:ident, $ty:ty, $reg:tt, $mov:literal) => {
6590
// CHECK: #APP
6691
// CHECK: brasl %r14, extern_func
6792
// CHECK: #NO_APP
68-
#[cfg(s390x)]
6993
#[no_mangle]
7094
pub unsafe fn sym_fn_32() {
7195
asm!("brasl %r14, {}", sym extern_func);
@@ -146,6 +170,90 @@ check!(reg_f64, f64, freg, "ldr");
146170
// CHECK: #NO_APP
147171
check!(reg_ptr, ptr, reg, "lgr");
148172

173+
// s390x_vector-LABEL: vreg_i8x16:
174+
// s390x_vector: #APP
175+
// s390x_vector: vlr %v{{[0-9]+}}, %v{{[0-9]+}}
176+
// s390x_vector: #NO_APP
177+
#[cfg(s390x_vector)]
178+
check!(vreg_i8x16, i8x16, vreg, "vlr");
179+
180+
// s390x_vector-LABEL: vreg_i16x8:
181+
// s390x_vector: #APP
182+
// s390x_vector: vlr %v{{[0-9]+}}, %v{{[0-9]+}}
183+
// s390x_vector: #NO_APP
184+
#[cfg(s390x_vector)]
185+
check!(vreg_i16x8, i16x8, vreg, "vlr");
186+
187+
// s390x_vector-LABEL: vreg_i32x4:
188+
// s390x_vector: #APP
189+
// s390x_vector: vlr %v{{[0-9]+}}, %v{{[0-9]+}}
190+
// s390x_vector: #NO_APP
191+
#[cfg(s390x_vector)]
192+
check!(vreg_i32x4, i32x4, vreg, "vlr");
193+
194+
// s390x_vector-LABEL: vreg_i64x2:
195+
// s390x_vector: #APP
196+
// s390x_vector: vlr %v{{[0-9]+}}, %v{{[0-9]+}}
197+
// s390x_vector: #NO_APP
198+
#[cfg(s390x_vector)]
199+
check!(vreg_i64x2, i64x2, vreg, "vlr");
200+
201+
// s390x_vector-LABEL: vreg_f32x4:
202+
// s390x_vector: #APP
203+
// s390x_vector: vlr %v{{[0-9]+}}, %v{{[0-9]+}}
204+
// s390x_vector: #NO_APP
205+
#[cfg(s390x_vector)]
206+
check!(vreg_f32x4, f32x4, vreg, "vlr");
207+
208+
// s390x_vector-LABEL: vreg_f64x2:
209+
// s390x_vector: #APP
210+
// s390x_vector: vlr %v{{[0-9]+}}, %v{{[0-9]+}}
211+
// s390x_vector: #NO_APP
212+
#[cfg(s390x_vector)]
213+
check!(vreg_f64x2, f64x2, vreg, "vlr");
214+
215+
// s390x_vector-LABEL: vreg_i32:
216+
// s390x_vector: #APP
217+
// s390x_vector: vlr %v{{[0-9]+}}, %v{{[0-9]+}}
218+
// s390x_vector: #NO_APP
219+
#[cfg(s390x_vector)]
220+
check!(vreg_i32, i32, vreg, "vlr");
221+
222+
// s390x_vector-LABEL: vreg_i64:
223+
// s390x_vector: #APP
224+
// s390x_vector: vlr %v{{[0-9]+}}, %v{{[0-9]+}}
225+
// s390x_vector: #NO_APP
226+
#[cfg(s390x_vector)]
227+
check!(vreg_i64, i64, vreg, "vlr");
228+
229+
// s390x_vector-LABEL: vreg_i128:
230+
// s390x_vector: #APP
231+
// s390x_vector: vlr %v{{[0-9]+}}, %v{{[0-9]+}}
232+
// s390x_vector: #NO_APP
233+
#[cfg(s390x_vector)]
234+
check!(vreg_i128, i128, vreg, "vlr");
235+
236+
// s390x_vector-LABEL: vreg_f32:
237+
// s390x_vector: #APP
238+
// s390x_vector: vlr %v{{[0-9]+}}, %v{{[0-9]+}}
239+
// s390x_vector: #NO_APP
240+
#[cfg(s390x_vector)]
241+
check!(vreg_f32, f32, vreg, "vlr");
242+
243+
// s390x_vector-LABEL: vreg_f64:
244+
// s390x_vector: #APP
245+
// s390x_vector: vlr %v{{[0-9]+}}, %v{{[0-9]+}}
246+
// s390x_vector: #NO_APP
247+
#[cfg(s390x_vector)]
248+
check!(vreg_f64, f64, vreg, "vlr");
249+
250+
// s390x_vector-LABEL: vreg_f128:
251+
// s390x_vector: #APP
252+
// s390x_vector: vlr %v{{[0-9]+}}, %v{{[0-9]+}}
253+
// s390x_vector: #NO_APP
254+
#[cfg(s390x_vector)]
255+
check!(vreg_f128, f128, vreg, "vlr");
256+
149257
// CHECK-LABEL: r0_i8:
150258
// CHECK: #APP
151259
// CHECK: lr %r0, %r0
@@ -181,3 +289,87 @@ check_reg!(f0_f32, f32, "f0", "ler");
181289
// CHECK: ldr %f0, %f0
182290
// CHECK: #NO_APP
183291
check_reg!(f0_f64, f64, "f0", "ldr");
292+
293+
// s390x_vector-LABEL: v0_i8x16:
294+
// s390x_vector: #APP
295+
// s390x_vector: vlr %v0, %v0
296+
// s390x_vector: #NO_APP
297+
#[cfg(s390x_vector)]
298+
check_reg!(v0_i8x16, i8x16, "v0", "vlr");
299+
300+
// s390x_vector-LABEL: v0_i16x8:
301+
// s390x_vector: #APP
302+
// s390x_vector: vlr %v0, %v0
303+
// s390x_vector: #NO_APP
304+
#[cfg(s390x_vector)]
305+
check_reg!(v0_i16x8, i16x8, "v0", "vlr");
306+
307+
// s390x_vector-LABEL: v0_i32x4:
308+
// s390x_vector: #APP
309+
// s390x_vector: vlr %v0, %v0
310+
// s390x_vector: #NO_APP
311+
#[cfg(s390x_vector)]
312+
check_reg!(v0_i32x4, i32x4, "v0", "vlr");
313+
314+
// s390x_vector-LABEL: v0_i64x2:
315+
// s390x_vector: #APP
316+
// s390x_vector: vlr %v0, %v0
317+
// s390x_vector: #NO_APP
318+
#[cfg(s390x_vector)]
319+
check_reg!(v0_i64x2, i64x2, "v0", "vlr");
320+
321+
// s390x_vector-LABEL: v0_f32x4:
322+
// s390x_vector: #APP
323+
// s390x_vector: vlr %v0, %v0
324+
// s390x_vector: #NO_APP
325+
#[cfg(s390x_vector)]
326+
check_reg!(v0_f32x4, f32x4, "v0", "vlr");
327+
328+
// s390x_vector-LABEL: v0_f64x2:
329+
// s390x_vector: #APP
330+
// s390x_vector: vlr %v0, %v0
331+
// s390x_vector: #NO_APP
332+
#[cfg(s390x_vector)]
333+
check_reg!(v0_f64x2, f64x2, "v0", "vlr");
334+
335+
// s390x_vector-LABEL: v0_i32:
336+
// s390x_vector: #APP
337+
// s390x_vector: vlr %v0, %v0
338+
// s390x_vector: #NO_APP
339+
#[cfg(s390x_vector)]
340+
check_reg!(v0_i32, i32, "v0", "vlr");
341+
342+
// s390x_vector-LABEL: v0_i64:
343+
// s390x_vector: #APP
344+
// s390x_vector: vlr %v0, %v0
345+
// s390x_vector: #NO_APP
346+
#[cfg(s390x_vector)]
347+
check_reg!(v0_i64, i64, "v0", "vlr");
348+
349+
// s390x_vector-LABEL: v0_i128:
350+
// s390x_vector: #APP
351+
// s390x_vector: vlr %v0, %v0
352+
// s390x_vector: #NO_APP
353+
#[cfg(s390x_vector)]
354+
check_reg!(v0_i128, i128, "v0", "vlr");
355+
356+
// s390x_vector-LABEL: v0_f32:
357+
// s390x_vector: #APP
358+
// s390x_vector: vlr %v0, %v0
359+
// s390x_vector: #NO_APP
360+
#[cfg(s390x_vector)]
361+
check_reg!(v0_f32, f32, "v0", "vlr");
362+
363+
// s390x_vector-LABEL: v0_f64:
364+
// s390x_vector: #APP
365+
// s390x_vector: vlr %v0, %v0
366+
// s390x_vector: #NO_APP
367+
#[cfg(s390x_vector)]
368+
check_reg!(v0_f64, f64, "v0", "vlr");
369+
370+
// s390x_vector-LABEL: v0_f128:
371+
// s390x_vector: #APP
372+
// s390x_vector: vlr %v0, %v0
373+
// s390x_vector: #NO_APP
374+
#[cfg(s390x_vector)]
375+
check_reg!(v0_f128, f128, "v0", "vlr");

tests/auxiliary/minicore.rs

+1
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ impl_marker_trait!(
4545
impl<'a, T: ?Sized> Copy for &'a T {}
4646
impl<T: ?Sized> Copy for *const T {}
4747
impl<T: ?Sized> Copy for *mut T {}
48+
impl<T: Copy, const N: usize> Copy for [T; N] {}
4849

4950
#[lang = "phantom_data"]
5051
pub struct PhantomData<T: ?Sized>;

tests/ui/asm/s390x/bad-reg.rs

+38-18
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,28 @@
11
//@ add-core-stubs
22
//@ needs-asm-support
3-
//@ revisions: s390x
3+
//@ revisions: s390x s390x_vector
44
//@[s390x] compile-flags: --target s390x-unknown-linux-gnu
55
//@[s390x] needs-llvm-components: systemz
6+
//@[s390x_vector] compile-flags: --target s390x-unknown-linux-gnu -C target-feature=+vector
7+
//@[s390x_vector] needs-llvm-components: systemz
68

79
#![crate_type = "rlib"]
8-
#![feature(no_core, rustc_attrs)]
9-
#![feature(asm_experimental_arch)]
10+
#![feature(no_core, rustc_attrs, repr_simd)]
1011
#![no_core]
12+
#![allow(non_camel_case_types)]
1113

1214
extern crate minicore;
1315
use minicore::*;
1416

17+
#[repr(simd)]
18+
pub struct i64x2([i64; 2]);
19+
20+
impl Copy for i64x2 {}
21+
1522
fn f() {
1623
let mut x = 0;
24+
let mut b = 0u8;
25+
let mut v = i64x2([0; 2]);
1726
unsafe {
1827
// Unsupported registers
1928
asm!("", out("r11") _);
@@ -57,6 +66,32 @@ fn f() {
5766
asm!("", out("a1") _);
5867
//~^ ERROR invalid register `a1`: a0 and a1 are reserved for system use and cannot be used as operands for inline asm
5968

69+
// vreg
70+
asm!("", out("v0") _); // always ok
71+
asm!("", in("v0") v); // requires vector
72+
//[s390x]~^ ERROR register class `vreg` requires the `vector` target feature
73+
asm!("", out("v0") v); // requires vector
74+
//[s390x]~^ ERROR register class `vreg` requires the `vector` target feature
75+
asm!("", in("v0") x); // requires vector
76+
//[s390x]~^ ERROR register class `vreg` requires the `vector` target feature
77+
asm!("", out("v0") x); // requires vector
78+
//[s390x]~^ ERROR register class `vreg` requires the `vector` target feature
79+
asm!("", in("v0") b);
80+
//[s390x]~^ ERROR register class `vreg` requires the `vector` target feature
81+
//[s390x_vector]~^^ ERROR type `u8` cannot be used with this register class
82+
asm!("", out("v0") b);
83+
//[s390x]~^ ERROR register class `vreg` requires the `vector` target feature
84+
//[s390x_vector]~^^ ERROR type `u8` cannot be used with this register class
85+
asm!("/* {} */", in(vreg) v); // requires vector
86+
//[s390x]~^ ERROR register class `vreg` requires the `vector` target feature
87+
asm!("/* {} */", in(vreg) x); // requires vector
88+
//[s390x]~^ ERROR register class `vreg` requires the `vector` target feature
89+
asm!("/* {} */", in(vreg) b);
90+
//[s390x]~^ ERROR register class `vreg` requires the `vector` target feature
91+
//[s390x_vector]~^^ ERROR type `u8` cannot be used with this register class
92+
asm!("/* {} */", out(vreg) _); // requires vector
93+
//[s390x]~^ ERROR register class `vreg` requires the `vector` target feature
94+
6095
// Clobber-only registers
6196
// areg
6297
asm!("", out("a2") _); // ok
@@ -72,21 +107,6 @@ fn f() {
72107
asm!("/* {} */", out(areg) _);
73108
//~^ ERROR can only be used as a clobber
74109

75-
// vreg
76-
asm!("", out("v0") _); // ok
77-
// FIXME: will be supported in https://github.com/rust-lang/rust/pull/131664
78-
asm!("", in("v0") x);
79-
//~^ ERROR can only be used as a clobber
80-
//~| ERROR type `i32` cannot be used with this register class
81-
asm!("", out("v0") x);
82-
//~^ ERROR can only be used as a clobber
83-
//~| ERROR type `i32` cannot be used with this register class
84-
asm!("/* {} */", in(vreg) x);
85-
//~^ ERROR can only be used as a clobber
86-
//~| ERROR type `i32` cannot be used with this register class
87-
asm!("/* {} */", out(vreg) _);
88-
//~^ ERROR can only be used as a clobber
89-
90110
// Overlapping registers
91111
// vreg/freg
92112
asm!("", out("v0") _, out("f0") _);

0 commit comments

Comments
 (0)