Skip to content

Commit 8e56093

Browse files
committed
add vec_sub and vec_mul for s390x
1 parent 0bfb5ec commit 8e56093

File tree

1 file changed

+304
-1
lines changed

1 file changed

+304
-1
lines changed

crates/core_arch/src/s390x/vector.rs

Lines changed: 304 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -146,10 +146,146 @@ mod sealed {
146146
#[inline]
147147
#[target_feature(enable = "vector")]
148148
unsafe fn vec_add(self, other: Self) -> Self::Result {
149-
simd_add(self, other)
149+
va_float(self, other)
150150
}
151151
}
152152
}
153+
154+
#[unstable(feature = "stdarch_s390x", issue = "135681")]
155+
pub trait VectorSub<Other> {
156+
type Result;
157+
unsafe fn vec_sub(self, other: Other) -> Self::Result;
158+
}
159+
160+
macro_rules! impl_sub {
161+
($name:ident, $a:ty, $instr:ident) => {
162+
impl_sub!($name, $a, $a, $a, $instr);
163+
};
164+
($name:ident, $a:ty, $b:ty, $c:ty, $instr:ident) => {
165+
#[inline]
166+
#[target_feature(enable = "vector")]
167+
#[cfg_attr(test, assert_instr($instr))]
168+
pub unsafe fn $name(a: $a, b: $b) -> $c {
169+
transmute(simd_sub(transmute(a), b))
170+
}
171+
172+
#[unstable(feature = "stdarch_s390x", issue = "135681")]
173+
impl VectorSub<$b> for $a {
174+
type Result = $c;
175+
176+
#[inline]
177+
#[target_feature(enable = "vector")]
178+
unsafe fn vec_sub(self, other: $b) -> Self::Result {
179+
$name(self, other)
180+
}
181+
}
182+
};
183+
}
184+
185+
#[rustfmt::skip]
186+
mod impl_sub {
187+
use super::*;
188+
189+
impl_sub!(vs_sc, vector_signed_char, vsb);
190+
impl_sub!(vs_uc, vector_unsigned_char, vsb);
191+
impl_sub!(vs_sh, vector_signed_short, vsh);
192+
impl_sub!(vs_uh, vector_unsigned_short, vsh);
193+
impl_sub!(vs_sf, vector_signed_int, vsf);
194+
impl_sub!(vs_uf, vector_unsigned_int, vsf);
195+
impl_sub!(vs_sg, vector_signed_long_long, vsg);
196+
impl_sub!(vs_ug, vector_unsigned_long_long, vsg);
197+
198+
impl_sub!(vs_sc_bc, vector_signed_char, vector_bool_char, vector_signed_char, vsb);
199+
impl_sub!(vs_uc_bc, vector_unsigned_char, vector_bool_char, vector_unsigned_char, vsb);
200+
impl_sub!(vs_sh_bh, vector_signed_short, vector_bool_short, vector_signed_short, vsh);
201+
impl_sub!(vs_uh_bh, vector_unsigned_short, vector_bool_short, vector_unsigned_short, vsh);
202+
impl_sub!(vs_sf_bf, vector_signed_int, vector_bool_int, vector_signed_int, vsf);
203+
impl_sub!(vs_uf_bf, vector_unsigned_int, vector_bool_int, vector_unsigned_int, vsf);
204+
impl_sub!(vs_sg_bg, vector_signed_long_long, vector_bool_long_long, vector_signed_long_long, vsg);
205+
impl_sub!(vs_ug_bg, vector_unsigned_long_long, vector_bool_long_long, vector_unsigned_long_long, vsg);
206+
207+
impl_sub!(vs_bc_sc, vector_bool_char, vector_signed_char, vector_signed_char, vsb);
208+
impl_sub!(vs_bc_uc, vector_bool_char, vector_unsigned_char, vector_unsigned_char, vsb);
209+
impl_sub!(vs_bh_sh, vector_bool_short, vector_signed_short, vector_signed_short, vsh);
210+
impl_sub!(vs_bh_uh, vector_bool_short, vector_unsigned_short, vector_unsigned_short, vsh);
211+
impl_sub!(vs_bf_sf, vector_bool_int, vector_signed_int, vector_signed_int, vsf);
212+
impl_sub!(vs_bf_uf, vector_bool_int, vector_unsigned_int, vector_unsigned_int, vsf);
213+
impl_sub!(vs_bg_sg, vector_bool_long_long, vector_signed_long_long, vector_signed_long_long, vsg);
214+
impl_sub!(vs_bg_ug, vector_bool_long_long, vector_unsigned_long_long, vector_unsigned_long_long, vsg);
215+
216+
impl_sub!(vs_double, vector_double, vfsdb);
217+
218+
#[inline]
219+
#[target_feature(enable = "vector")]
220+
// FIXME: "vfssb" is part of vector enhancements 1, add a test for it when possible
221+
// #[cfg_attr(test, assert_instr(vfasb))]
222+
pub unsafe fn vs_float(a: vector_float, b: vector_float) -> vector_float {
223+
transmute(simd_sub(a, b))
224+
}
225+
226+
#[unstable(feature = "stdarch_s390x", issue = "135681")]
227+
impl VectorSub<Self> for vector_float {
228+
type Result = Self;
229+
230+
#[inline]
231+
#[target_feature(enable = "vector")]
232+
unsafe fn vec_sub(self, other: Self) -> Self::Result {
233+
vs_float(self, other)
234+
}
235+
}
236+
}
237+
238+
#[unstable(feature = "stdarch_s390x", issue = "135681")]
239+
pub trait VectorMul {
240+
unsafe fn vec_mul(self, b: Self) -> Self;
241+
}
242+
243+
macro_rules! impl_mul {
244+
($name:ident, $a:ty, std_simd) => {
245+
#[unstable(feature = "stdarch_s390x", issue = "135681")]
246+
impl VectorMul for $a {
247+
#[inline]
248+
#[target_feature(enable = "vector")]
249+
unsafe fn vec_mul(self, other: Self) -> Self {
250+
transmute(simd_mul(transmute(self), other))
251+
}
252+
}
253+
};
254+
($name:ident, $a:ty, $instr:ident) => {
255+
#[inline]
256+
#[target_feature(enable = "vector")]
257+
#[cfg_attr(test, assert_instr($instr))]
258+
pub unsafe fn $name(a: $a, b: $a) -> $a {
259+
transmute(simd_mul(transmute(a), b))
260+
}
261+
262+
#[unstable(feature = "stdarch_s390x", issue = "135681")]
263+
impl VectorMul for $a {
264+
#[inline]
265+
#[target_feature(enable = "vector")]
266+
unsafe fn vec_mul(self, other: Self) -> Self {
267+
$name(self, other)
268+
}
269+
}
270+
};
271+
}
272+
273+
#[rustfmt::skip]
274+
mod impl_mul {
275+
use super::*;
276+
277+
impl_mul!(vml_sc, vector_signed_char, vmlb);
278+
impl_mul!(vml_uc, vector_unsigned_char, vmlb);
279+
impl_mul!(vml_sh, vector_signed_short, vmlhw);
280+
impl_mul!(vml_uh, vector_unsigned_short, vmlhw);
281+
impl_mul!(vml_sf, vector_signed_int, vmlf);
282+
impl_mul!(vml_uf, vector_unsigned_int, vmlf);
283+
impl_mul!(vml_sg, vector_signed_long_long, std_simd);
284+
impl_mul!(vml_ug, vector_unsigned_long_long, std_simd);
285+
286+
impl_mul!(vml_float, vector_float, std_simd);
287+
impl_mul!(vml_double, vector_double, vfmdb);
288+
}
153289
}
154290

155291
/// Vector pointwise addition.
@@ -163,6 +299,34 @@ where
163299
a.vec_add(b)
164300
}
165301

302+
/// Vector pointwise subtraction.
303+
#[inline]
304+
#[target_feature(enable = "vector")]
305+
#[unstable(feature = "stdarch_s390x", issue = "135681")]
306+
pub unsafe fn vec_sub<T, U>(a: T, b: U) -> <T as sealed::VectorSub<U>>::Result
307+
where
308+
T: sealed::VectorSub<U>,
309+
{
310+
a.vec_sub(b)
311+
}
312+
313+
/// Vector Multiply
314+
///
315+
/// ## Purpose
316+
/// Compute the products of corresponding elements of two vectors.
317+
///
318+
/// ## Result value
319+
/// Each element of r receives the product of the corresponding elements of a and b.
320+
#[inline]
321+
#[target_feature(enable = "vector")]
322+
#[unstable(feature = "stdarch_s390x", issue = "135681")]
323+
pub unsafe fn vec_mul<T>(a: T, b: T) -> T
324+
where
325+
T: sealed::VectorMul,
326+
{
327+
a.vec_mul(b)
328+
}
329+
166330
#[cfg(test)]
167331
mod tests {
168332
use super::*;
@@ -172,6 +336,33 @@ mod tests {
172336
use crate::core_arch::simd::*;
173337
use stdarch_test::simd_test;
174338

339+
macro_rules! test_vec_2 {
340+
{ $name: ident, $fn:ident, $ty: ident, [$($a:expr),+], [$($b:expr),+], [$($d:expr),+] } => {
341+
test_vec_2! { $name, $fn, $ty -> $ty, [$($a),+], [$($b),+], [$($d),+] }
342+
};
343+
{ $name: ident, $fn:ident, $ty: ident -> $ty_out: ident, [$($a:expr),+], [$($b:expr),+], [$($d:expr),+] } => {
344+
#[simd_test(enable = "vector")]
345+
unsafe fn $name() {
346+
let a: s_t_l!($ty) = transmute($ty::new($($a),+));
347+
let b: s_t_l!($ty) = transmute($ty::new($($b),+));
348+
349+
let d = $ty_out::new($($d),+);
350+
let r : $ty_out = transmute($fn(a, b));
351+
assert_eq!(d, r);
352+
}
353+
};
354+
{ $name: ident, $fn:ident, $ty: ident -> $ty_out: ident, [$($a:expr),+], [$($b:expr),+], $d:expr } => {
355+
#[simd_test(enable = "vector")]
356+
unsafe fn $name() {
357+
let a: s_t_l!($ty) = transmute($ty::new($($a),+));
358+
let b: s_t_l!($ty) = transmute($ty::new($($b),+));
359+
360+
let r : $ty_out = transmute($fn(a, b));
361+
assert_eq!($d, r);
362+
}
363+
}
364+
}
365+
175366
#[simd_test(enable = "vector")]
176367
unsafe fn vec_add_i32x4_i32x4() {
177368
let x = i32x4::new(1, 2, 3, 4);
@@ -181,4 +372,116 @@ mod tests {
181372
let z = vec_add(x, y);
182373
assert_eq!(i32x4::splat(5), transmute(z));
183374
}
375+
376+
macro_rules! test_vec_sub {
377+
{ $name: ident, $ty: ident, [$($a:expr),+], [$($b:expr),+], [$($d:expr),+] } => {
378+
test_vec_2! {$name, vec_sub, $ty, [$($a),+], [$($b),+], [$($d),+] }
379+
}
380+
}
381+
382+
test_vec_sub! { test_vec_sub_f32x4, f32x4,
383+
[-1.0, 0.0, 1.0, 2.0],
384+
[2.0, 1.0, -1.0, -2.0],
385+
[-3.0, -1.0, 2.0, 4.0] }
386+
387+
test_vec_sub! { test_vec_sub_f64x2, f64x2,
388+
[-1.0, 0.0],
389+
[2.0, 1.0],
390+
[-3.0, -1.0] }
391+
392+
test_vec_sub! { test_vec_sub_i64x2, i64x2,
393+
[-1, 0],
394+
[2, 1],
395+
[-3, -1] }
396+
397+
test_vec_sub! { test_vec_sub_u64x2, u64x2,
398+
[0, 1],
399+
[1, 0],
400+
[u64::MAX, 1] }
401+
402+
test_vec_sub! { test_vec_sub_i32x4, i32x4,
403+
[-1, 0, 1, 2],
404+
[2, 1, -1, -2],
405+
[-3, -1, 2, 4] }
406+
407+
test_vec_sub! { test_vec_sub_u32x4, u32x4,
408+
[0, 0, 1, 2],
409+
[2, 1, 0, 0],
410+
[4294967294, 4294967295, 1, 2] }
411+
412+
test_vec_sub! { test_vec_sub_i16x8, i16x8,
413+
[-1, 0, 1, 2, -1, 0, 1, 2],
414+
[2, 1, -1, -2, 2, 1, -1, -2],
415+
[-3, -1, 2, 4, -3, -1, 2, 4] }
416+
417+
test_vec_sub! { test_vec_sub_u16x8, u16x8,
418+
[0, 0, 1, 2, 0, 0, 1, 2],
419+
[2, 1, 0, 0, 2, 1, 0, 0],
420+
[65534, 65535, 1, 2, 65534, 65535, 1, 2] }
421+
422+
test_vec_sub! { test_vec_sub_i8x16, i8x16,
423+
[-1, 0, 1, 2, -1, 0, 1, 2, -1, 0, 1, 2, -1, 0, 1, 2],
424+
[2, 1, -1, -2, 2, 1, -1, -2, 2, 1, -1, -2, 2, 1, -1, -2],
425+
[-3, -1, 2, 4, -3, -1, 2, 4, -3, -1, 2, 4, -3, -1, 2, 4] }
426+
427+
test_vec_sub! { test_vec_sub_u8x16, u8x16,
428+
[0, 0, 1, 2, 0, 0, 1, 2, 0, 0, 1, 2, 0, 0, 1, 2],
429+
[2, 1, 0, 0, 2, 1, 0, 0, 2, 1, 0, 0, 2, 1, 0, 0],
430+
[254, 255, 1, 2, 254, 255, 1, 2, 254, 255, 1, 2, 254, 255, 1, 2] }
431+
432+
macro_rules! test_vec_mul {
433+
{ $name: ident, $ty: ident, [$($a:expr),+], [$($b:expr),+], [$($d:expr),+] } => {
434+
test_vec_2! {$name, vec_mul, $ty, [$($a),+], [$($b),+], [$($d),+] }
435+
}
436+
}
437+
438+
test_vec_mul! { test_vec_mul_f32x4, f32x4,
439+
[-1.0, 0.0, 1.0, 2.0],
440+
[2.0, 1.0, -1.0, -2.0],
441+
[-2.0, 0.0, -1.0, -4.0] }
442+
443+
test_vec_mul! { test_vec_mul_f64x2, f64x2,
444+
[-1.0, 0.0],
445+
[2.0, 1.0],
446+
[-2.0, 0.0] }
447+
448+
test_vec_mul! { test_vec_mul_i64x2, i64x2,
449+
[i64::MAX, -4],
450+
[2, 3],
451+
[i64::MAX.wrapping_mul(2), -12] }
452+
453+
test_vec_mul! { test_vec_mul_u64x2, u64x2,
454+
[u64::MAX, 4],
455+
[2, 3],
456+
[u64::MAX.wrapping_mul(2), 12] }
457+
458+
test_vec_mul! { test_vec_mul_i32x4, i32x4,
459+
[-1, 0, 1, 2],
460+
[2, 1, -1, -2],
461+
[-2, 0, -1, -4] }
462+
463+
test_vec_mul! { test_vec_mul_u32x4, u32x4,
464+
[0, u32::MAX - 1, 1, 2],
465+
[5, 6, 7, 8],
466+
[0, 4294967284, 7, 16] }
467+
468+
test_vec_mul! { test_vec_mul_i16x8, i16x8,
469+
[-1, 0, 1, 2, -1, 0, 1, 2],
470+
[2, 1, -1, -2, 2, 1, -1, -2],
471+
[-2, 0, -1, -4, -2, 0, -1, -4] }
472+
473+
test_vec_mul! { test_vec_mul_u16x8, u16x8,
474+
[0, u16::MAX - 1, 1, 2, 3, 4, 5, 6],
475+
[5, 6, 7, 8, 9, 8, 7, 6],
476+
[0, 65524, 7, 16, 27, 32, 35, 36] }
477+
478+
test_vec_mul! { test_vec_mul_i8x16, i8x16,
479+
[-1, 0, 1, 2, -1, 0, 1, 2, -1, 0, 1, 2, -1, 0, 1, 2],
480+
[2, 1, -1, -2, 2, 1, -1, -2, 2, 1, -1, -2, 2, 1, -1, -2],
481+
[-2, 0, -1, -4, -2, 0, -1, -4, -2, 0, -1, -4, -2, 0, -1, -4] }
482+
483+
test_vec_mul! { test_vec_mul_u8x16, u8x16,
484+
[0, u8::MAX - 1, 1, 2, 3, 4, 5, 6, 7, 8, 9, 8, 7, 6, 5, 4],
485+
[5, 6, 7, 8, 9, 8, 7, 6, 5, 4, 0, u8::MAX, 1, 2, 3, 4],
486+
[0, 244, 7, 16, 27, 32, 35, 36, 35, 32, 0, 248, 7, 12, 15, 16] }
184487
}

0 commit comments

Comments
 (0)