Skip to content
Open
4 changes: 2 additions & 2 deletions crates/base64-simd/src/decode.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ use crate::{Config, Error, Extra, Kind};
use crate::{STANDARD_CHARSET, URL_SAFE_CHARSET};

use vsimd::alsw::AlswLut;
use vsimd::isa::{NEON, SSSE3, WASM128};
use vsimd::isa::{NEON, SSSE3, VSX, WASM128};
use vsimd::mask::u8x32_highbit_any;
use vsimd::matches_isa;
use vsimd::tools::{read, write};
Expand Down Expand Up @@ -249,7 +249,7 @@ fn merge_bits_x2<S: SIMD256>(s: S, x: V256) -> V256 {
let m2 = s.u32x8_splat(u32::from_le_bytes([0x00, 0x10, 0x01, 0x00]));
s.i16x16_madd(x1, m2)
// {ccdddddd|bbbbcccc|aaaaaabb|00000000} x8
} else if matches_isa!(S, NEON | WASM128) {
} else if matches_isa!(S, NEON | WASM128 | VSX) {
let m1 = s.u32x8_splat(u32::from_le_bytes([0x3f, 0x00, 0x3f, 0x00]));
let x1 = s.v256_and(x, m1);
// x1: {00aaaaaa|00000000|00cccccc|00000000} x8
Expand Down
6 changes: 3 additions & 3 deletions crates/base64-simd/src/encode.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use crate::{Config, Kind};
use crate::{STANDARD_CHARSET, URL_SAFE_CHARSET};

use vsimd::isa::{NEON, SSE2, WASM128};
use vsimd::isa::{NEON, SSE2, VSX, WASM128};
use vsimd::tools::{read, write};
use vsimd::vector::{V128, V256};
use vsimd::{matches_isa, POD};
Expand Down Expand Up @@ -200,7 +200,7 @@ fn split_bits_x2<S: SIMD256>(s: S, x: V256) -> V256 {
// {00aaaaaa|00bbbbbb|00cccccc|00dddddd} x8
}

if matches_isa!(S, NEON | WASM128) {
if matches_isa!(S, NEON | WASM128 | VSX) {
let m1 = s.u32x8_splat(u32::from_le_bytes([0x00, 0xfc, 0x00, 0x00]));
let x1 = s.u16x16_shr::<10>(s.v256_and(x0, m1));
// x1: {00aaaaaa|000000000|00000000|00000000} x8
Expand Down Expand Up @@ -248,7 +248,7 @@ fn split_bits_x1<S: SIMD128>(s: S, x: V128) -> V128 {
return s.v128_or(x3, x4);
}

if matches_isa!(S, NEON | WASM128) {
if matches_isa!(S, NEON | WASM128 | VSX) {
let m1 = s.u32x4_splat(u32::from_le_bytes([0x00, 0xfc, 0x00, 0x00]));
let x1 = s.u16x8_shr::<10>(s.v128_and(x0, m1));

Expand Down
4 changes: 4 additions & 0 deletions crates/base64-simd/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,10 @@
//
#![cfg_attr(not(any(feature = "std", test)), no_std)]
#![cfg_attr(feature = "unstable", feature(arm_target_feature))]
#![cfg_attr(
all(feature = "unstable", target_arch = "powerpc64"),
feature(powerpc_target_feature)
)]
#![cfg_attr(docsrs, feature(doc_cfg))]
#![cfg_attr(test, deny(warnings))]
//
Expand Down
16 changes: 8 additions & 8 deletions crates/base64-simd/src/multiversion.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,33 +5,33 @@ vsimd::dispatch!(
signature = {pub(crate) unsafe fn(src: *const u8, len: usize, dst: *mut u8, config: Config) -> ()},
fallback = {crate::encode::encode_fallback},
simd = {crate::encode::encode_simd},
targets = {"avx2", "ssse3", "neon", "simd128"},
fastest = {"avx2", "neon", "simd128"},
targets = {"avx2", "ssse3", "neon", "simd128", "vsx"},
fastest = {"avx2", "neon", "simd128", "vsx"},
);

vsimd::dispatch!(
name = {decode},
signature = {pub(crate) unsafe fn(src: *const u8, dst: *mut u8, n: usize, config: Config) -> Result<(), Error>},
fallback = {crate::decode::decode_fallback},
simd = {crate::decode::decode_simd},
targets = {"avx2", "ssse3", "neon", "simd128"},
fastest = {"avx2", "neon", "simd128"},
targets = {"avx2", "ssse3", "neon", "simd128", "vsx"},
fastest = {"avx2", "neon", "simd128", "vsx"},
);

vsimd::dispatch!(
name = {check},
signature = {pub(crate) unsafe fn(src: *const u8, n: usize, config: Config) -> Result<(), Error>},
fallback = {crate::check::check_fallback},
simd = {crate::check::check_simd},
targets = {"avx2", "ssse3", "neon", "simd128"},
fastest = {"avx2", "neon", "simd128"},
targets = {"avx2", "ssse3", "neon", "simd128", "vsx"},
fastest = {"avx2", "neon", "simd128", "vsx"},
);

vsimd::dispatch!(
name = {find_non_ascii_whitespace},
signature = {pub unsafe fn(src: *const u8, len: usize) -> usize},
fallback = {crate::ascii::find_non_ascii_whitespace_fallback},
simd = {crate::ascii::find_non_ascii_whitespace_simd},
targets = {"avx2", "sse2", "neon", "simd128"},
fastest = {"avx2", "neon", "simd128"},
targets = {"avx2", "sse2", "neon", "simd128", "vsx"},
fastest = {"avx2", "neon", "simd128", "vsx"},
);
45 changes: 44 additions & 1 deletion crates/vsimd/src/isa.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ pub enum InstructionSetTypeId {
AVX2,
NEON,
WASM128,
VSX,
}

#[doc(hidden)]
Expand All @@ -46,6 +47,7 @@ where
AVX2 => matches!(super_ty, Fallback | SSE2 | SSSE3 | SSE41 | AVX2),
NEON => matches!(super_ty, Fallback | NEON),
WASM128 => matches!(super_ty, Fallback | WASM128),
VSX => matches!(super_ty, Fallback | VSX),
};

S::ARCH && U::ARCH && inherits
Expand Down Expand Up @@ -115,11 +117,16 @@ macro_rules! is_feature_detected {
{
std::arch::is_aarch64_feature_detected!($feature)
}
#[cfg(all(feature = "unstable", target_arch = "powerpc64"))]
{
std::arch::is_powerpc64_feature_detected!($feature)
}
#[cfg(not(any(
target_arch = "x86",
target_arch = "x86_64",
target_arch = "arm",
target_arch = "aarch64"
target_arch = "aarch64",
all(feature = "unstable", target_arch = "powerpc64"),
)))]
{
false
Expand Down Expand Up @@ -303,3 +310,39 @@ unsafe impl InstructionSet for WASM128 {
unsafe impl SIMD64 for WASM128 {}
unsafe impl SIMD128 for WASM128 {}
unsafe impl SIMD256 for WASM128 {}

macro_rules! ppc64_is_enabled {
($feature:tt) => {{
#[cfg(all(feature = "unstable", target_arch = "powerpc64"))]
{
is_feature_detected!($feature)
}
#[cfg(not(all(feature = "unstable", target_arch = "powerpc64")))]
{
false
}
}};
}

#[allow(clippy::upper_case_acronyms)]
#[derive(Debug, Clone, Copy)]
pub struct VSX(());

unsafe impl InstructionSet for VSX {
const ID: InstructionSetTypeId = InstructionSetTypeId::VSX;
const ARCH: bool = cfg!(all(feature = "unstable", target_arch = "powerpc64"));

#[inline(always)]
unsafe fn new() -> Self {
Self(())
}

#[inline(always)]
fn is_enabled() -> bool {
ppc64_is_enabled!("vsx")
}
}

unsafe impl SIMD64 for VSX {}
unsafe impl SIMD128 for VSX {}
unsafe impl SIMD256 for VSX {}
13 changes: 11 additions & 2 deletions crates/vsimd/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,12 +1,21 @@
//! ⚠️ This crate contains shared implementation details. Do not directly depend on it.
#![cfg_attr(not(any(test, feature = "std")), no_std)]
#![cfg_attr(feature = "unstable", feature(portable_simd))]
#![cfg_attr(all(feature = "unstable", not(target_arch = "powerpc64")), feature(portable_simd))]
#![cfg_attr(
all(feature = "unstable", target_arch = "arm"),
feature(arm_target_feature),
feature(stdarch_arm_feature_detection),
feature(stdarch_arm_neon_intrinsics)
)]
#![cfg_attr(
all(feature = "unstable", target_arch = "powerpc64"),
feature(stdarch_powerpc),
feature(powerpc_target_feature)
)]
#![cfg_attr(
all(feature = "unstable", feature = "detect", target_arch = "powerpc64"),
feature(stdarch_powerpc_feature_detection)
)]
#![cfg_attr(docsrs, feature(doc_cfg))]
#![cfg_attr(test, deny(warnings))]
//
Expand Down Expand Up @@ -81,5 +90,5 @@ pub mod mask;
pub mod native;
pub mod table;

#[cfg(feature = "unstable")]
#[cfg(all(feature = "unstable", not(target_arch = "powerpc64")))]
pub mod unstable;
33 changes: 33 additions & 0 deletions crates/vsimd/src/macros.rs
Original file line number Diff line number Diff line change
Expand Up @@ -209,6 +209,17 @@ macro_rules! dispatch {
}
};

(@resolve_static, "vsx", $($arg_name: ident),*) => {
#[cfg(all(
feature = "unstable",
target_arch = "powerpc64",
target_feature = "vsx",
))]
{
return unsafe { vsx($($arg_name),*) }
}
};

(
@iter_resolve_dynamic,
targets = {$x:tt, $($xs:tt),+},
Expand Down Expand Up @@ -266,6 +277,13 @@ macro_rules! dispatch {
}
};

(@resolve_dynamic, "vsx") => {
#[cfg(all(feature = "unstable", target_arch = "powerpc64"))]
if $crate::isa::VSX::is_enabled() {
return vsx;
}
};

(
@iter_compile,
signature = {$vis:vis unsafe fn($($arg_name: ident: $arg_type: ty),*) -> $ret:ty},
Expand Down Expand Up @@ -389,5 +407,20 @@ macro_rules! dispatch {
use $crate::isa::{WASM128, InstructionSet as _};
$simd_fn(WASM128::new() $(,$arg_name)*)
}
};

(
@compile,
signature = {$vis:vis unsafe fn($($arg_name: ident: $arg_type: ty),*) -> $ret:ty},
simd = {$simd_fn:path},
target = {"vsx"},
) => {
#[cfg(all(feature = "unstable", target_arch = "powerpc64"))]
#[inline]
#[target_feature(enable = "vsx")]
$vis unsafe fn vsx($($arg_name:$arg_type),*) -> $ret {
use $crate::isa::{VSX, InstructionSet as _};
$simd_fn(VSX::new() $(,$arg_name)*)
}
}
}
22 changes: 17 additions & 5 deletions crates/vsimd/src/mask.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use crate::isa::{AVX2, NEON, SSE2, WASM128};
use crate::isa::{AVX2, NEON, SSE2, VSX, WASM128};
use crate::vector::{V128, V256};
use crate::{SIMD128, SIMD256};

Expand All @@ -17,6 +17,9 @@ pub fn mask8x16_all<S: SIMD128>(s: S, x: V128) -> bool {
return s.u8x16_reduce_min(x) != 0;
}
}
if matches_isa!(S, VSX) {
return s.u8x16_any_zero(x).not();
}
unreachable!()
}

Expand All @@ -25,7 +28,7 @@ pub fn mask8x32_all<S: SIMD256>(s: S, x: V256) -> bool {
if matches_isa!(S, AVX2) {
return s.u8x32_bitmask(x) == u32::MAX;
}
if matches_isa!(S, SSE2 | WASM128 | NEON) {
if matches_isa!(S, SSE2 | WASM128 | NEON | VSX) {
let x = x.to_v128x2();
let x = s.v128_and(x.0, x.1);
return mask8x16_all(s, x);
Expand All @@ -41,6 +44,9 @@ pub fn mask8x16_any<S: SIMD128>(s: S, x: V128) -> bool {
if matches_isa!(S, NEON) {
return s.v128_all_zero(x).not();
}
if matches_isa!(S, VSX) {
return s.v128_all_zero(x).not();
}
unreachable!()
}

Expand All @@ -49,7 +55,7 @@ pub fn mask8x32_any<S: SIMD256>(s: S, x: V256) -> bool {
if matches_isa!(S, AVX2) {
return s.u8x32_bitmask(x) != 0;
}
if matches_isa!(S, SSE2 | WASM128 | NEON) {
if matches_isa!(S, SSE2 | WASM128 | NEON | VSX) {
let x = x.to_v128x2();
let x = s.v128_or(x.0, x.1);
return mask8x16_any(s, x);
Expand All @@ -70,6 +76,9 @@ pub fn u8x16_highbit_all<S: SIMD128>(s: S, x: V128) -> bool {
return s.u8x16_reduce_min(x) >= 0x80;
}
}
if matches_isa!(S, VSX) {
return mask8x16_all(s, s.i8x16_lt(x, s.v128_create_zero()));
}
unreachable!()
}

Expand All @@ -78,7 +87,7 @@ pub fn u8x32_highbit_all<S: SIMD256>(s: S, x: V256) -> bool {
if matches_isa!(S, AVX2) {
return s.u8x32_bitmask(x) == u32::MAX;
}
if matches_isa!(S, SSE2 | WASM128 | NEON) {
if matches_isa!(S, SSE2 | WASM128 | NEON | VSX) {
let x = x.to_v128x2();
let x = s.v128_and(x.0, x.1);
return u8x16_highbit_all(s, x);
Expand All @@ -99,6 +108,9 @@ pub fn u8x16_highbit_any<S: SIMD128>(s: S, x: V128) -> bool {
return s.u8x16_reduce_max(x) >= 0x80;
}
}
if matches_isa!(S, VSX) {
return mask8x16_any(s, s.i8x16_lt(x, s.v128_create_zero()));
}
unreachable!()
}

Expand All @@ -107,7 +119,7 @@ pub fn u8x32_highbit_any<S: SIMD256>(s: S, x: V256) -> bool {
if matches_isa!(S, AVX2) {
return s.u8x32_bitmask(x) != 0;
}
if matches_isa!(S, SSE2 | WASM128 | NEON) {
if matches_isa!(S, SSE2 | WASM128 | NEON | VSX) {
let x = x.to_v128x2();
let x = s.v128_or(x.0, x.1);
return u8x16_highbit_any(s, x);
Expand Down
24 changes: 23 additions & 1 deletion crates/vsimd/src/native.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,9 @@ enum Arch {
#[cfg(target_arch = "wasm32")]
Simd128,

#[cfg(all(feature = "unstable", target_arch = "powerpc64"))]
Vsx,

Fallback,
}

Expand Down Expand Up @@ -51,6 +54,12 @@ impl Native {
return Self(Arch::Simd128);
}
}
#[cfg(all(feature = "unstable", target_arch = "powerpc64"))]
{
if is_feature_detected!("vsx") {
return Self(Arch::Vsx);
}
}
Self(Arch::Fallback)
}

Expand Down Expand Up @@ -82,10 +91,18 @@ impl Native {
Arch::Fallback => f(),
}
}
#[cfg(all(feature = "unstable", target_arch = "powerpc64"))]
{
match self.0 {
Arch::Vsx => unsafe { ppc64::vsx(f) },
Arch::Fallback => f(),
}
}
#[cfg(not(any( //
any(target_arch = "x86", target_arch = "x86_64"), //
any(all(feature = "unstable", target_arch = "arm"), target_arch = "aarch64"), //
target_arch = "wasm32" //
target_arch = "wasm32", //
all(feature = "unstable", target_arch = "powerpc64"), //
)))]
{
f()
Expand Down Expand Up @@ -123,3 +140,8 @@ mod arm {
mod wasm {
generic_dispatch!(simd128, "simd128");
}

#[cfg(all(feature = "unstable", target_arch = "powerpc64"))]
mod ppc64 {
generic_dispatch!(vsx, "vsx");
}
Loading