Skip to content

Commit 255da5e

Browse files
folkertdevAmanieu
authored andcommitted
s390x vector: add vec_cntlz, vec_cnttz and vec_popcnt
1 parent a4ecfd4 commit 255da5e

File tree

2 files changed

+114
-0
lines changed

2 files changed

+114
-0
lines changed

Diff for: crates/core_arch/src/s390x/macros.rs

+8
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,14 @@
22
#![allow(unused_imports)] // FIXME remove when more tests are added
33

44
macro_rules! test_impl {
5+
($fun:ident +($($v:ident : $ty:ty),*) -> $r:ty [$call:ident, $instr:ident]) => {
6+
#[inline]
7+
#[target_feature(enable = "vector")]
8+
#[cfg_attr(test, assert_instr($instr))]
9+
pub unsafe fn $fun ($($v : $ty),*) -> $r {
10+
transmute($call ($($v),*))
11+
}
12+
};
513
($fun:ident ($($v:ident : $ty:ty),*) -> $r:ty [$call:ident, $instr:ident]) => {
614
#[inline]
715
#[target_feature(enable = "vector")]

Diff for: crates/core_arch/src/s390x/vector.rs

+106
Original file line numberDiff line numberDiff line change
@@ -450,8 +450,79 @@ mod sealed {
450450
(u64, u64x2, vector_bool_long_long),
451451
(i64, i64x2, vector_bool_long_long)
452452
}
453+
454+
#[unstable(feature = "stdarch_s390x", issue = "135681")]
455+
pub trait CountBits {
456+
type Result;
457+
458+
unsafe fn vec_cntlz(self) -> Self::Result;
459+
unsafe fn vec_cnttz(self) -> Self::Result;
460+
unsafe fn vec_popcnt(self) -> Self::Result;
461+
}
462+
463+
macro_rules! impl_count_bits {
464+
($ty:tt) => {
465+
#[unstable(feature = "stdarch_s390x", issue = "135681")]
466+
impl CountBits for $ty {
467+
type Result = t_u!($ty);
468+
469+
#[inline]
470+
#[target_feature(enable = "vector")]
471+
unsafe fn vec_cntlz(self) -> Self::Result {
472+
transmute(simd_ctlz(self))
473+
}
474+
475+
#[inline]
476+
#[target_feature(enable = "vector")]
477+
unsafe fn vec_cnttz(self) -> Self::Result {
478+
transmute(simd_cttz(self))
479+
}
480+
481+
#[inline]
482+
#[target_feature(enable = "vector")]
483+
unsafe fn vec_popcnt(self) -> Self::Result {
484+
transmute(simd_ctpop(self))
485+
}
486+
}
487+
};
488+
}
489+
490+
impl_count_bits!(vector_signed_char);
491+
impl_count_bits!(vector_unsigned_char);
492+
impl_count_bits!(vector_signed_short);
493+
impl_count_bits!(vector_unsigned_short);
494+
impl_count_bits!(vector_signed_int);
495+
impl_count_bits!(vector_unsigned_int);
496+
impl_count_bits!(vector_signed_long_long);
497+
impl_count_bits!(vector_unsigned_long_long);
498+
499+
test_impl! { vec_clzb_signed +(a: vector_signed_char) -> vector_unsigned_char [simd_ctlz, vclzb] }
500+
test_impl! { vec_clzh_signed +(a: vector_signed_short) -> vector_unsigned_short [simd_ctlz, vclzh] }
501+
test_impl! { vec_clzf_signed +(a: vector_signed_int) -> vector_unsigned_int [simd_ctlz, vclzf] }
502+
test_impl! { vec_clzg_signed +(a: vector_signed_long_long) -> vector_unsigned_long_long [simd_ctlz, vclzg] }
503+
504+
test_impl! { vec_clzb_unsigned +(a: vector_unsigned_char) -> vector_unsigned_char [simd_ctlz, vclzb] }
505+
test_impl! { vec_clzh_unsigned +(a: vector_unsigned_short) -> vector_unsigned_short [simd_ctlz, vclzh] }
506+
test_impl! { vec_clzf_unsigned +(a: vector_unsigned_int) -> vector_unsigned_int [simd_ctlz, vclzf] }
507+
test_impl! { vec_clzg_unsigned +(a: vector_unsigned_long_long) -> vector_unsigned_long_long [simd_ctlz, vclzg] }
508+
509+
test_impl! { vec_ctzb_signed +(a: vector_signed_char) -> vector_unsigned_char [simd_cttz, vctzb] }
510+
test_impl! { vec_ctzh_signed +(a: vector_signed_short) -> vector_unsigned_short [simd_cttz, vctzh] }
511+
test_impl! { vec_ctzf_signed +(a: vector_signed_int) -> vector_unsigned_int [simd_cttz, vctzf] }
512+
test_impl! { vec_ctzg_signed +(a: vector_signed_long_long) -> vector_unsigned_long_long [simd_cttz, vctzg] }
513+
514+
test_impl! { vec_ctzb_unsigned +(a: vector_unsigned_char) -> vector_unsigned_char [simd_cttz, vctzb] }
515+
test_impl! { vec_ctzh_unsigned +(a: vector_unsigned_short) -> vector_unsigned_short [simd_cttz, vctzh] }
516+
test_impl! { vec_ctzf_unsigned +(a: vector_unsigned_int) -> vector_unsigned_int [simd_cttz, vctzf] }
517+
test_impl! { vec_ctzg_unsigned +(a: vector_unsigned_long_long) -> vector_unsigned_long_long [simd_cttz, vctzg] }
518+
519+
// FIXME(vector-enhancements-1) other integer types are emulated, but get their own
520+
// instructions in later facilities. Add tests when possible.
521+
test_impl! { vec_popcnt_signed +(a: vector_signed_char) -> vector_signed_char [simd_ctpop, vpopctb] }
522+
test_impl! { vec_popcnt_unsigned +(a: vector_unsigned_char) -> vector_unsigned_char [simd_ctpop, vpopctb] }
453523
}
454524

525+
455526
/// Vector element-wise addition.
456527
#[inline]
457528
#[target_feature(enable = "vector")]
@@ -491,6 +562,41 @@ where
491562
a.vec_mul(b)
492563
}
493564

565+
/// Vector Count Leading Zeros
566+
#[inline]
567+
#[target_feature(enable = "vector")]
568+
#[unstable(feature = "stdarch_s390x", issue = "135681")]
569+
pub unsafe fn vec_cntlz<T>(a: T) -> <T as sealed::CountBits>::Result
570+
where
571+
T: sealed::CountBits,
572+
{
573+
a.vec_cntlz()
574+
}
575+
576+
/// Vector Count Trailing Zeros
577+
#[inline]
578+
#[target_feature(enable = "vector")]
579+
#[unstable(feature = "stdarch_s390x", issue = "135681")]
580+
pub unsafe fn vec_cnttz<T>(a: T) -> <T as sealed::CountBits>::Result
581+
where
582+
T: sealed::CountBits,
583+
{
584+
a.vec_cnttz()
585+
}
586+
587+
/// Vector Population Count
588+
///
589+
/// Computes the population count (number of set bits) in each element of the input.
590+
#[inline]
591+
#[target_feature(enable = "vector")]
592+
#[unstable(feature = "stdarch_s390x", issue = "135681")]
593+
pub unsafe fn vec_popcnt<T>(a: T) -> <T as sealed::CountBits>::Result
594+
where
595+
T: sealed::CountBits,
596+
{
597+
a.vec_popcnt()
598+
}
599+
494600
/// Vector element-wise maximum.
495601
#[inline]
496602
#[target_feature(enable = "vector")]

0 commit comments

Comments
 (0)