Skip to content

Commit

Permalink
add vec_nand, vec_nor, vec_eqv, vec_andc and vec_orc
Browse files Browse the repository at this point in the history
  • Loading branch information
folkertdev authored and Amanieu committed Feb 13, 2025
1 parent e19ebda commit 4625b86
Show file tree
Hide file tree
Showing 2 changed files with 212 additions and 4 deletions.
30 changes: 26 additions & 4 deletions crates/core_arch/src/s390x/macros.rs
Original file line number Diff line number Diff line change
Expand Up @@ -106,18 +106,20 @@ macro_rules! impl_vec_trait {
([$Trait:ident $m:ident] ~($fn:ident)) => {
impl_vec_trait!{ [$Trait $m] ~($fn, $fn, $fn, $fn, $fn, $fn, $fn, $fn) }
};
([$Trait:ident $m:ident] 2 ($ub:ident, $sb:ident, $uh:ident, $sh:ident, $uw:ident, $sw:ident)) => {
([$Trait:ident $m:ident] 2 ($ub:ident, $sb:ident, $uh:ident, $sh:ident, $uw:ident, $sw:ident, $ug:ident, $sg:ident)) => {
impl_vec_trait!{ [$Trait $m] $ub (vector_unsigned_char, vector_unsigned_char) -> vector_unsigned_char }
impl_vec_trait!{ [$Trait $m] $sb (vector_signed_char, vector_signed_char) -> vector_signed_char }
impl_vec_trait!{ [$Trait $m] $uh (vector_unsigned_short, vector_unsigned_short) -> vector_unsigned_short }
impl_vec_trait!{ [$Trait $m] $sh (vector_signed_short, vector_signed_short) -> vector_signed_short }
impl_vec_trait!{ [$Trait $m] $uw (vector_unsigned_int, vector_unsigned_int) -> vector_unsigned_int }
impl_vec_trait!{ [$Trait $m] $sw (vector_signed_int, vector_signed_int) -> vector_signed_int }
impl_vec_trait!{ [$Trait $m] $ug (vector_unsigned_long_long, vector_unsigned_long_long) -> vector_unsigned_long_long }
impl_vec_trait!{ [$Trait $m] $sg (vector_signed_long_long, vector_signed_long_long) -> vector_signed_long_long }
};
([$Trait:ident $m:ident] 2 ($fn:ident)) => {
impl_vec_trait!{ [$Trait $m] ($fn, $fn, $fn, $fn, $fn, $fn) }
impl_vec_trait!{ [$Trait $m] ($fn, $fn, $fn, $fn, $fn, $fn, $fn, $fn) }
};
([$Trait:ident $m:ident]+ 2b ($b:ident, $h:ident, $w:ident)) => {
([$Trait:ident $m:ident]+ 2b ($b:ident, $h:ident, $w:ident, $g:ident)) => {
impl_vec_trait!{ [$Trait $m]+ $b (vector_bool_char, vector_bool_char) -> vector_bool_char }
impl_vec_trait!{ [$Trait $m]+ $b (vector_unsigned_char, vector_unsigned_char) -> vector_unsigned_char }
impl_vec_trait!{ [$Trait $m]+ $b (vector_signed_char, vector_signed_char) -> vector_signed_char }
Expand All @@ -127,9 +129,29 @@ macro_rules! impl_vec_trait {
impl_vec_trait!{ [$Trait $m]+ $w (vector_bool_int, vector_bool_int) -> vector_bool_int }
impl_vec_trait!{ [$Trait $m]+ $w (vector_unsigned_int, vector_unsigned_int) -> vector_unsigned_int }
impl_vec_trait!{ [$Trait $m]+ $w (vector_signed_int, vector_signed_int) -> vector_signed_int }
impl_vec_trait!{ [$Trait $m]+ $g (vector_unsigned_long_long, vector_unsigned_long_long) -> vector_unsigned_long_long }
impl_vec_trait!{ [$Trait $m]+ $g (vector_signed_long_long, vector_signed_long_long) -> vector_signed_long_long }
};
([$Trait:ident $m:ident]+ 2b ($fn:ident)) => {
impl_vec_trait!{ [$Trait $m]+ 2b ($fn, $fn, $fn) }
impl_vec_trait!{ [$Trait $m]+ 2b ($fn, $fn, $fn, $fn) }
};
([$Trait:ident $m:ident]+ 2c ($b:ident, $h:ident, $w:ident, $g:ident, $s:ident, $d:ident)) => {
impl_vec_trait!{ [$Trait $m]+ $b (vector_bool_char, vector_bool_char) -> vector_bool_char }
impl_vec_trait!{ [$Trait $m]+ $b (vector_unsigned_char, vector_unsigned_char) -> vector_unsigned_char }
impl_vec_trait!{ [$Trait $m]+ $b (vector_signed_char, vector_signed_char) -> vector_signed_char }
impl_vec_trait!{ [$Trait $m]+ $h (vector_bool_short, vector_bool_short) -> vector_bool_short }
impl_vec_trait!{ [$Trait $m]+ $h (vector_unsigned_short, vector_unsigned_short) -> vector_unsigned_short }
impl_vec_trait!{ [$Trait $m]+ $h (vector_signed_short, vector_signed_short) -> vector_signed_short }
impl_vec_trait!{ [$Trait $m]+ $w (vector_bool_int, vector_bool_int) -> vector_bool_int }
impl_vec_trait!{ [$Trait $m]+ $w (vector_unsigned_int, vector_unsigned_int) -> vector_unsigned_int }
impl_vec_trait!{ [$Trait $m]+ $w (vector_signed_int, vector_signed_int) -> vector_signed_int }
impl_vec_trait!{ [$Trait $m]+ $g (vector_unsigned_long_long, vector_unsigned_long_long) -> vector_unsigned_long_long }
impl_vec_trait!{ [$Trait $m]+ $g (vector_signed_long_long, vector_signed_long_long) -> vector_signed_long_long }
impl_vec_trait!{ [$Trait $m]+ $s (vector_float, vector_float) -> vector_float }
impl_vec_trait!{ [$Trait $m]+ $d (vector_double, vector_double) -> vector_double }
};
([$Trait:ident $m:ident]+ 2c ($fn:ident)) => {
impl_vec_trait!{ [$Trait $m]+ 2c ($fn, $fn, $fn, $fn, $fn, $fn) }
};
}

Expand Down
186 changes: 186 additions & 0 deletions crates/core_arch/src/s390x/vector.rs
Original file line number Diff line number Diff line change
Expand Up @@ -544,6 +544,91 @@ mod sealed {
}

impl_vec_trait! { [VectorXor vec_xor] ~(simd_xor) }

#[inline]
#[target_feature(enable = "vector")]
// FIXME(vector-enhancements-1) #[cfg_attr(test, assert_instr(vno))]
unsafe fn nor(a: vector_signed_char, b: vector_signed_char) -> vector_signed_char {
let a: u8x16 = transmute(a);
let b: u8x16 = transmute(b);
transmute(simd_xor(simd_or(a, b), u8x16::splat(0xff)))
}

#[unstable(feature = "stdarch_s390x", issue = "135681")]
pub trait VectorNor<Other> {
type Result;
unsafe fn vec_nor(self, b: Other) -> Self::Result;
}

impl_vec_trait! { [VectorNor vec_nor]+ 2c (nor) }

#[inline]
#[target_feature(enable = "vector")]
// FIXME(vector-enhancements-1) #[cfg_attr(test, assert_instr(vnn))]
unsafe fn nand(a: vector_signed_char, b: vector_signed_char) -> vector_signed_char {
let a: u8x16 = transmute(a);
let b: u8x16 = transmute(b);
transmute(simd_xor(simd_and(a, b), u8x16::splat(0xff)))
}

#[unstable(feature = "stdarch_s390x", issue = "135681")]
pub trait VectorNand<Other> {
type Result;
unsafe fn vec_nand(self, b: Other) -> Self::Result;
}

impl_vec_trait! { [VectorNand vec_nand]+ 2c (nand) }

#[inline]
#[target_feature(enable = "vector")]
// FIXME(vector-enhancements-1) #[cfg_attr(test, assert_instr(vnx))]
unsafe fn eqv(a: vector_signed_char, b: vector_signed_char) -> vector_signed_char {
let a: u8x16 = transmute(a);
let b: u8x16 = transmute(b);
transmute(simd_xor(simd_xor(a, b), u8x16::splat(0xff)))
}

#[unstable(feature = "stdarch_s390x", issue = "135681")]
pub trait VectorEqv<Other> {
type Result;
unsafe fn vec_eqv(self, b: Other) -> Self::Result;
}

impl_vec_trait! { [VectorEqv vec_eqv]+ 2c (eqv) }

#[inline]
#[target_feature(enable = "vector")]
// FIXME(vector-enhancements-1) #[cfg_attr(test, assert_instr(vnc))]
unsafe fn andc(a: vector_signed_char, b: vector_signed_char) -> vector_signed_char {
let a = transmute(a);
let b = transmute(b);
transmute(simd_and(simd_xor(u8x16::splat(0xff), b), a))
}

#[unstable(feature = "stdarch_s390x", issue = "135681")]
pub trait VectorAndc<Other> {
type Result;
unsafe fn vec_andc(self, b: Other) -> Self::Result;
}

impl_vec_trait! { [VectorAndc vec_andc]+ 2c (andc) }

#[inline]
#[target_feature(enable = "vector")]
// FIXME(vector-enhancements-1) #[cfg_attr(test, assert_instr(voc))]
unsafe fn orc(a: vector_signed_char, b: vector_signed_char) -> vector_signed_char {
let a = transmute(a);
let b = transmute(b);
transmute(simd_or(simd_xor(u8x16::splat(0xff), b), a))
}

#[unstable(feature = "stdarch_s390x", issue = "135681")]
pub trait VectorOrc<Other> {
type Result;
unsafe fn vec_orc(self, b: Other) -> Self::Result;
}

impl_vec_trait! { [VectorOrc vec_orc]+ 2c (orc) }
}

/// Vector element-wise addition.
Expand Down Expand Up @@ -697,6 +782,67 @@ where
a.vec_xor(b)
}

/// Vector nor
#[inline]
#[target_feature(enable = "vector")]
#[unstable(feature = "stdarch_s390x", issue = "135681")]
pub unsafe fn vec_nor<T, U>(a: T, b: U) -> <T as sealed::VectorNor<U>>::Result
where
T: sealed::VectorNor<U>,
{
a.vec_nor(b)
}

/// Vector nand
#[inline]
#[target_feature(enable = "vector")]
#[unstable(feature = "stdarch_s390x", issue = "135681")]
pub unsafe fn vec_nand<T, U>(a: T, b: U) -> <T as sealed::VectorNand<U>>::Result
where
T: sealed::VectorNand<U>,
{
a.vec_nand(b)
}

/// Vector xnor
#[inline]
#[target_feature(enable = "vector")]
#[unstable(feature = "stdarch_s390x", issue = "135681")]
pub unsafe fn vec_eqv<T, U>(a: T, b: U) -> <T as sealed::VectorEqv<U>>::Result
where
T: sealed::VectorEqv<U>,
{
a.vec_eqv(b)
}

/// Vector andc.
#[inline]
#[target_feature(enable = "vector")]
#[unstable(feature = "stdarch_s390x", issue = "135681")]
pub unsafe fn vec_andc<T, U>(a: T, b: U) -> <T as sealed::VectorAndc<U>>::Result
where
T: sealed::VectorAndc<U>,
{
a.vec_andc(b)
}

/// Vector OR with Complement
///
/// ## Purpose
/// Performs a bitwise OR of the first vector with the bitwise-complemented second vector.
///
/// ## Result value
/// r is the bitwise OR of a and the bitwise complement of b.
#[inline]
#[target_feature(enable = "vector")]
#[unstable(feature = "stdarch_s390x", issue = "135681")]
pub unsafe fn vec_orc<T, U>(a: T, b: U) -> <T as sealed::VectorOrc<U>>::Result
where
T: sealed::VectorOrc<U>,
{
a.vec_orc(b)
}

#[cfg(test)]
mod tests {
use super::*;
Expand Down Expand Up @@ -873,4 +1019,44 @@ mod tests {
test_vec_abs! { test_vec_abs_i64, i64x2, -42i64, 42i64 }
test_vec_abs! { test_vec_abs_f32, f32x4, -42f32, 42f32 }
test_vec_abs! { test_vec_abs_f64, f64x2, -42f64, 42f64 }

test_vec_2! { test_vec_andc, vec_andc, i32x4,
[0b11001100, 0b11001100, 0b11001100, 0b11001100],
[0b00110011, 0b11110011, 0b00001100, 0b10000000],
[0b11001100, 0b00001100, 0b11000000, 0b01001100] }

test_vec_2! { test_vec_and, vec_and, i32x4,
[0b11001100, 0b11001100, 0b11001100, 0b11001100],
[0b00110011, 0b11110011, 0b00001100, 0b00000000],
[0b00000000, 0b11000000, 0b00001100, 0b00000000] }

test_vec_2! { test_vec_nand, vec_nand, i32x4,
[0b11001100, 0b11001100, 0b11001100, 0b11001100],
[0b00110011, 0b11110011, 0b00001100, 0b00000000],
[!0b00000000, !0b11000000, !0b00001100, !0b00000000] }

test_vec_2! { test_vec_orc, vec_orc, u32x4,
[0b11001100, 0b11001100, 0b11001100, 0b11001100],
[0b00110011, 0b11110011, 0b00001100, 0b00000000],
[0b11001100 | !0b00110011, 0b11001100 | !0b11110011, 0b11001100 | !0b00001100, 0b11001100 | !0b00000000] }

test_vec_2! { test_vec_or, vec_or, i32x4,
[0b11001100, 0b11001100, 0b11001100, 0b11001100],
[0b00110011, 0b11110011, 0b00001100, 0b00000000],
[0b11111111, 0b11111111, 0b11001100, 0b11001100] }

test_vec_2! { test_vec_nor, vec_nor, i32x4,
[0b11001100, 0b11001100, 0b11001100, 0b11001100],
[0b00110011, 0b11110011, 0b00001100, 0b00000000],
[!0b11111111, !0b11111111, !0b11001100, !0b11001100] }

test_vec_2! { test_vec_xor, vec_xor, i32x4,
[0b11001100, 0b11001100, 0b11001100, 0b11001100],
[0b00110011, 0b11110011, 0b00001100, 0b00000000],
[0b11111111, 0b00111111, 0b11000000, 0b11001100] }

test_vec_2! { test_vec_eqv, vec_eqv, i32x4,
[0b11001100, 0b11001100, 0b11001100, 0b11001100],
[0b00110011, 0b11110011, 0b00001100, 0b00000000],
[!0b11111111, !0b00111111, !0b11000000, !0b11001100] }
}

0 comments on commit 4625b86

Please sign in to comment.