Restructure crate as core module
Aligns module with rust-lang/library/core, creating an... unusual architecture that is easier to pull in as a module, as core itself can have no dependencies (as we haven't built core yet).
This commit is contained in:
parent
8cf7a62e5d
commit
b25ed7f86d
26 changed files with 159 additions and 130 deletions
|
|
@ -1,4 +1,5 @@
|
|||
use crate::{LaneCount, Mask, Simd, SimdElement, SupportedLaneCount};
|
||||
use crate::simd::intrinsics;
|
||||
use crate::simd::{LaneCount, Mask, Simd, SimdElement, SupportedLaneCount};
|
||||
|
||||
impl<T, const LANES: usize> Simd<T, LANES>
|
||||
where
|
||||
|
|
@ -8,13 +9,13 @@ where
|
|||
/// Test if each lane is equal to the corresponding lane in `other`.
|
||||
#[inline]
|
||||
pub fn lanes_eq(self, other: Self) -> Mask<T::Mask, LANES> {
|
||||
unsafe { Mask::from_int_unchecked(crate::intrinsics::simd_eq(self, other)) }
|
||||
unsafe { Mask::from_int_unchecked(intrinsics::simd_eq(self, other)) }
|
||||
}
|
||||
|
||||
/// Test if each lane is not equal to the corresponding lane in `other`.
|
||||
#[inline]
|
||||
pub fn lanes_ne(self, other: Self) -> Mask<T::Mask, LANES> {
|
||||
unsafe { Mask::from_int_unchecked(crate::intrinsics::simd_ne(self, other)) }
|
||||
unsafe { Mask::from_int_unchecked(intrinsics::simd_ne(self, other)) }
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -26,24 +27,24 @@ where
|
|||
/// Test if each lane is less than the corresponding lane in `other`.
|
||||
#[inline]
|
||||
pub fn lanes_lt(self, other: Self) -> Mask<T::Mask, LANES> {
|
||||
unsafe { Mask::from_int_unchecked(crate::intrinsics::simd_lt(self, other)) }
|
||||
unsafe { Mask::from_int_unchecked(intrinsics::simd_lt(self, other)) }
|
||||
}
|
||||
|
||||
/// Test if each lane is greater than the corresponding lane in `other`.
|
||||
#[inline]
|
||||
pub fn lanes_gt(self, other: Self) -> Mask<T::Mask, LANES> {
|
||||
unsafe { Mask::from_int_unchecked(crate::intrinsics::simd_gt(self, other)) }
|
||||
unsafe { Mask::from_int_unchecked(intrinsics::simd_gt(self, other)) }
|
||||
}
|
||||
|
||||
/// Test if each lane is less than or equal to the corresponding lane in `other`.
|
||||
#[inline]
|
||||
pub fn lanes_le(self, other: Self) -> Mask<T::Mask, LANES> {
|
||||
unsafe { Mask::from_int_unchecked(crate::intrinsics::simd_le(self, other)) }
|
||||
unsafe { Mask::from_int_unchecked(intrinsics::simd_le(self, other)) }
|
||||
}
|
||||
|
||||
/// Test if each lane is greater than or equal to the corresponding lane in `other`.
|
||||
#[inline]
|
||||
pub fn lanes_ge(self, other: Self) -> Mask<T::Mask, LANES> {
|
||||
unsafe { Mask::from_int_unchecked(crate::intrinsics::simd_ge(self, other)) }
|
||||
unsafe { Mask::from_int_unchecked(intrinsics::simd_ge(self, other)) }
|
||||
}
|
||||
}
|
||||
|
|
|
|||
4
crates/core_simd/src/core_simd_docs.md
Normal file
4
crates/core_simd/src/core_simd_docs.md
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
Portable SIMD module.
|
||||
|
||||
This module offers a portable abstraction for SIMD operations
|
||||
that is not bound to any particular hardware architecture.
|
||||
|
|
@ -1,17 +1,20 @@
|
|||
use crate::simd::{LaneCount, Simd, SimdElement, SupportedLaneCount};
|
||||
use core::fmt;
|
||||
|
||||
macro_rules! impl_fmt_trait {
|
||||
{ $($trait:ident,)* } => {
|
||||
$(
|
||||
impl<T, const LANES: usize> core::fmt::$trait for crate::Simd<T, LANES>
|
||||
impl<T, const LANES: usize> fmt::$trait for Simd<T, LANES>
|
||||
where
|
||||
crate::LaneCount<LANES>: crate::SupportedLaneCount,
|
||||
T: crate::SimdElement + core::fmt::$trait,
|
||||
LaneCount<LANES>: SupportedLaneCount,
|
||||
T: SimdElement + fmt::$trait,
|
||||
{
|
||||
fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
#[repr(transparent)]
|
||||
struct Wrapper<'a, T: core::fmt::$trait>(&'a T);
|
||||
struct Wrapper<'a, T: fmt::$trait>(&'a T);
|
||||
|
||||
impl<T: core::fmt::$trait> core::fmt::Debug for Wrapper<'_, T> {
|
||||
fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {
|
||||
impl<T: fmt::$trait> fmt::Debug for Wrapper<'_, T> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
self.0.fmt(f)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -91,9 +91,9 @@ extern "platform-intrinsic" {
|
|||
pub(crate) fn simd_bitmask<T, U>(x: T) -> U;
|
||||
|
||||
// select
|
||||
pub(crate) fn simd_select<T, U>(m: T, a: U, b: U) -> U;
|
||||
pub(crate) fn simd_select<M, T>(m: M, a: T, b: T) -> T;
|
||||
#[allow(unused)]
|
||||
pub(crate) fn simd_select_bitmask<T, U>(m: T, a: U, b: U) -> U;
|
||||
pub(crate) fn simd_select_bitmask<M, T>(m: M, a: T, b: T) -> T;
|
||||
}
|
||||
|
||||
#[cfg(feature = "std")]
|
||||
|
|
@ -114,4 +114,4 @@ mod std {
|
|||
}
|
||||
|
||||
#[cfg(feature = "std")]
|
||||
pub(crate) use crate::intrinsics::std::*;
|
||||
pub(crate) use crate::simd::intrinsics::std::*;
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
use crate::{LaneCount, Simd, SupportedLaneCount};
|
||||
use crate::simd::{LaneCount, Simd, SupportedLaneCount};
|
||||
use core::{
|
||||
iter::{Product, Sum},
|
||||
ops::{Add, Mul},
|
||||
|
|
@ -15,7 +15,7 @@ macro_rules! impl_traits {
|
|||
}
|
||||
}
|
||||
|
||||
impl<const LANES: usize> core::iter::Product<Self> for Simd<$type, LANES>
|
||||
impl<const LANES: usize> Product<Self> for Simd<$type, LANES>
|
||||
where
|
||||
LaneCount<LANES>: SupportedLaneCount,
|
||||
{
|
||||
|
|
|
|||
|
|
@ -14,31 +14,6 @@
|
|||
#![unstable(feature = "portable_simd", issue = "86656")]
|
||||
//! Portable SIMD module.
|
||||
|
||||
#[macro_use]
|
||||
mod permute;
|
||||
#[macro_use]
|
||||
mod reduction;
|
||||
|
||||
mod select;
|
||||
pub use select::Select;
|
||||
|
||||
#[cfg(feature = "generic_const_exprs")]
|
||||
mod to_bytes;
|
||||
|
||||
mod comparisons;
|
||||
mod fmt;
|
||||
mod intrinsics;
|
||||
mod iter;
|
||||
mod math;
|
||||
mod ops;
|
||||
mod round;
|
||||
mod vendor;
|
||||
|
||||
mod lane_count;
|
||||
pub use lane_count::*;
|
||||
|
||||
mod masks;
|
||||
pub use masks::*;
|
||||
|
||||
mod vector;
|
||||
pub use vector::*;
|
||||
#[path = "mod.rs"]
|
||||
mod core_simd;
|
||||
pub use self::core_simd::simd::*;
|
||||
|
|
|
|||
|
|
@ -12,7 +12,9 @@
|
|||
)]
|
||||
mod mask_impl;
|
||||
|
||||
use crate::{LaneCount, Simd, SimdElement, SupportedLaneCount};
|
||||
use crate::simd::{LaneCount, Simd, SimdElement, SupportedLaneCount};
|
||||
use core::cmp::Ordering;
|
||||
use core::fmt;
|
||||
|
||||
/// Marker trait for types that may be used as SIMD mask elements.
|
||||
pub unsafe trait MaskElement: SimdElement {
|
||||
|
|
@ -251,17 +253,17 @@ where
|
|||
LaneCount<LANES>: SupportedLaneCount,
|
||||
{
|
||||
#[inline]
|
||||
fn partial_cmp(&self, other: &Self) -> Option<core::cmp::Ordering> {
|
||||
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
|
||||
self.0.partial_cmp(&other.0)
|
||||
}
|
||||
}
|
||||
|
||||
impl<T, const LANES: usize> core::fmt::Debug for Mask<T, LANES>
|
||||
impl<T, const LANES: usize> fmt::Debug for Mask<T, LANES>
|
||||
where
|
||||
T: MaskElement + core::fmt::Debug,
|
||||
T: MaskElement + fmt::Debug,
|
||||
LaneCount<LANES>: SupportedLaneCount,
|
||||
{
|
||||
fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
f.debug_list()
|
||||
.entries((0..LANES).map(|lane| self.test(lane)))
|
||||
.finish()
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
use crate::{LaneCount, MaskElement, Simd, SupportedLaneCount};
|
||||
use crate::simd::intrinsics;
|
||||
use crate::simd::{LaneCount, Simd, SupportedLaneCount};
|
||||
use core::marker::PhantomData;
|
||||
|
||||
/// A mask where each lane is represented by a single bit.
|
||||
|
|
@ -99,11 +100,7 @@ where
|
|||
unsafe {
|
||||
let mask: <LaneCount<LANES> as SupportedLaneCount>::IntBitMask =
|
||||
core::mem::transmute_copy(&self);
|
||||
crate::intrinsics::simd_select_bitmask(
|
||||
mask,
|
||||
Simd::splat(T::TRUE),
|
||||
Simd::splat(T::FALSE),
|
||||
)
|
||||
intrinsics::simd_select_bitmask(mask, Simd::splat(T::TRUE), Simd::splat(T::FALSE))
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -115,7 +112,7 @@ where
|
|||
core::mem::size_of::<<LaneCount::<LANES> as SupportedLaneCount>::IntBitMask>(),
|
||||
);
|
||||
let mask: <LaneCount<LANES> as SupportedLaneCount>::IntBitMask =
|
||||
crate::intrinsics::simd_bitmask(value);
|
||||
intrinsics::simd_bitmask(value);
|
||||
Self(core::mem::transmute_copy(&mask), PhantomData)
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,7 +1,8 @@
|
|||
//! Masks that take up full SIMD vector registers.
|
||||
|
||||
use super::MaskElement;
|
||||
use crate::{LaneCount, Simd, SupportedLaneCount};
|
||||
use crate::simd::intrinsics;
|
||||
use crate::simd::{LaneCount, Simd, SupportedLaneCount};
|
||||
|
||||
#[repr(transparent)]
|
||||
pub struct Mask<T, const LANES: usize>(Simd<T, LANES>)
|
||||
|
|
@ -98,7 +99,7 @@ where
|
|||
where
|
||||
U: MaskElement,
|
||||
{
|
||||
unsafe { Mask(crate::intrinsics::simd_cast(self.0)) }
|
||||
unsafe { Mask(intrinsics::simd_cast(self.0)) }
|
||||
}
|
||||
|
||||
#[cfg(feature = "generic_const_exprs")]
|
||||
|
|
@ -111,7 +112,7 @@ where
|
|||
LaneCount::<LANES>::BITMASK_LEN,
|
||||
);
|
||||
let bitmask: <LaneCount<LANES> as SupportedLaneCount>::IntBitMask =
|
||||
crate::intrinsics::simd_bitmask(self.0);
|
||||
intrinsics::simd_bitmask(self.0);
|
||||
let mut bitmask: [u8; LaneCount::<LANES>::BITMASK_LEN] =
|
||||
core::mem::transmute_copy(&bitmask);
|
||||
|
||||
|
|
@ -149,7 +150,7 @@ where
|
|||
let bitmask: <LaneCount<LANES> as SupportedLaneCount>::IntBitMask =
|
||||
core::mem::transmute_copy(&bitmask);
|
||||
|
||||
Self::from_int_unchecked(crate::intrinsics::simd_select_bitmask(
|
||||
Self::from_int_unchecked(intrinsics::simd_select_bitmask(
|
||||
bitmask,
|
||||
Self::splat(true).to_int(),
|
||||
Self::splat(false).to_int(),
|
||||
|
|
@ -159,12 +160,12 @@ where
|
|||
|
||||
#[inline]
|
||||
pub fn any(self) -> bool {
|
||||
unsafe { crate::intrinsics::simd_reduce_any(self.to_int()) }
|
||||
unsafe { intrinsics::simd_reduce_any(self.to_int()) }
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn all(self) -> bool {
|
||||
unsafe { crate::intrinsics::simd_reduce_all(self.to_int()) }
|
||||
unsafe { intrinsics::simd_reduce_all(self.to_int()) }
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -186,7 +187,7 @@ where
|
|||
type Output = Self;
|
||||
#[inline]
|
||||
fn bitand(self, rhs: Self) -> Self {
|
||||
unsafe { Self(crate::intrinsics::simd_and(self.0, rhs.0)) }
|
||||
unsafe { Self(intrinsics::simd_and(self.0, rhs.0)) }
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -198,7 +199,7 @@ where
|
|||
type Output = Self;
|
||||
#[inline]
|
||||
fn bitor(self, rhs: Self) -> Self {
|
||||
unsafe { Self(crate::intrinsics::simd_or(self.0, rhs.0)) }
|
||||
unsafe { Self(intrinsics::simd_or(self.0, rhs.0)) }
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -210,7 +211,7 @@ where
|
|||
type Output = Self;
|
||||
#[inline]
|
||||
fn bitxor(self, rhs: Self) -> Self {
|
||||
unsafe { Self(crate::intrinsics::simd_xor(self.0, rhs.0)) }
|
||||
unsafe { Self(intrinsics::simd_xor(self.0, rhs.0)) }
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
use crate::{LaneCount, Simd, SupportedLaneCount};
|
||||
use crate::simd::intrinsics::{simd_saturating_add, simd_saturating_sub};
|
||||
use crate::simd::{LaneCount, Simd, SupportedLaneCount};
|
||||
|
||||
macro_rules! impl_uint_arith {
|
||||
($($ty:ty),+) => {
|
||||
|
|
@ -20,7 +21,7 @@ macro_rules! impl_uint_arith {
|
|||
/// ```
|
||||
#[inline]
|
||||
pub fn saturating_add(self, second: Self) -> Self {
|
||||
unsafe { crate::intrinsics::simd_saturating_add(self, second) }
|
||||
unsafe { simd_saturating_add(self, second) }
|
||||
}
|
||||
|
||||
/// Lanewise saturating subtract.
|
||||
|
|
@ -38,7 +39,7 @@ macro_rules! impl_uint_arith {
|
|||
/// assert_eq!(sat, Simd::splat(0));
|
||||
#[inline]
|
||||
pub fn saturating_sub(self, second: Self) -> Self {
|
||||
unsafe { crate::intrinsics::simd_saturating_sub(self, second) }
|
||||
unsafe { simd_saturating_sub(self, second) }
|
||||
}
|
||||
})+
|
||||
}
|
||||
|
|
@ -64,7 +65,7 @@ macro_rules! impl_int_arith {
|
|||
/// ```
|
||||
#[inline]
|
||||
pub fn saturating_add(self, second: Self) -> Self {
|
||||
unsafe { crate::intrinsics::simd_saturating_add(self, second) }
|
||||
unsafe { simd_saturating_add(self, second) }
|
||||
}
|
||||
|
||||
/// Lanewise saturating subtract.
|
||||
|
|
@ -82,7 +83,7 @@ macro_rules! impl_int_arith {
|
|||
/// assert_eq!(sat, Simd::from_array([MIN, MIN, MIN, 0]));
|
||||
#[inline]
|
||||
pub fn saturating_sub(self, second: Self) -> Self {
|
||||
unsafe { crate::intrinsics::simd_saturating_sub(self, second) }
|
||||
unsafe { simd_saturating_sub(self, second) }
|
||||
}
|
||||
|
||||
/// Lanewise absolute value, implemented in Rust.
|
||||
|
|
|
|||
33
crates/core_simd/src/mod.rs
Normal file
33
crates/core_simd/src/mod.rs
Normal file
|
|
@ -0,0 +1,33 @@
|
|||
#[macro_use]
|
||||
mod permute;
|
||||
#[macro_use]
|
||||
mod reduction;
|
||||
|
||||
mod select;
|
||||
|
||||
#[cfg(feature = "generic_const_exprs")]
|
||||
mod to_bytes;
|
||||
|
||||
mod comparisons;
|
||||
mod fmt;
|
||||
mod intrinsics;
|
||||
mod iter;
|
||||
mod math;
|
||||
mod ops;
|
||||
mod round;
|
||||
mod vendor;
|
||||
|
||||
mod lane_count;
|
||||
|
||||
mod masks;
|
||||
|
||||
mod vector;
|
||||
|
||||
#[doc = include_str!("core_simd_docs.md")]
|
||||
pub mod simd {
|
||||
pub use crate::core_simd::lane_count::*;
|
||||
pub use crate::core_simd::masks::*;
|
||||
pub use crate::core_simd::select::Select;
|
||||
pub use crate::core_simd::vector::*;
|
||||
pub(crate) use crate::core_simd::*;
|
||||
}
|
||||
|
|
@ -1,4 +1,5 @@
|
|||
use crate::{LaneCount, Simd, SimdElement, SupportedLaneCount};
|
||||
use crate::simd::intrinsics;
|
||||
use crate::simd::{LaneCount, Simd, SimdElement, SupportedLaneCount};
|
||||
|
||||
impl<I, T, const LANES: usize> core::ops::Index<I> for Simd<T, LANES>
|
||||
where
|
||||
|
|
@ -208,7 +209,7 @@ macro_rules! impl_op {
|
|||
{
|
||||
type Output = Self;
|
||||
fn neg(self) -> Self::Output {
|
||||
unsafe { crate::intrinsics::simd_neg(self) }
|
||||
unsafe { intrinsics::simd_neg(self) }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -226,7 +227,7 @@ macro_rules! impl_op {
|
|||
#[inline]
|
||||
fn $trait_fn(self, rhs: Self) -> Self::Output {
|
||||
unsafe {
|
||||
crate::intrinsics::$intrinsic(self, rhs)
|
||||
intrinsics::$intrinsic(self, rhs)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -268,7 +269,7 @@ macro_rules! impl_op {
|
|||
#[inline]
|
||||
fn $assign_trait_fn(&mut self, rhs: Self) {
|
||||
unsafe {
|
||||
*self = crate::intrinsics::$intrinsic(*self, rhs);
|
||||
*self = intrinsics::$intrinsic(*self, rhs);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -338,7 +339,7 @@ macro_rules! impl_unsigned_int_ops {
|
|||
.any(|(x,y)| *x == <$scalar>::MIN && *y == -1 as _) {
|
||||
panic!("attempt to divide with overflow");
|
||||
}
|
||||
unsafe { crate::intrinsics::simd_div(self, rhs) }
|
||||
unsafe { intrinsics::simd_div(self, rhs) }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -361,7 +362,7 @@ macro_rules! impl_unsigned_int_ops {
|
|||
panic!("attempt to divide with overflow");
|
||||
}
|
||||
let rhs = Self::splat(rhs);
|
||||
unsafe { crate::intrinsics::simd_div(self, rhs) }
|
||||
unsafe { intrinsics::simd_div(self, rhs) }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -428,7 +429,7 @@ macro_rules! impl_unsigned_int_ops {
|
|||
.any(|(x,y)| *x == <$scalar>::MIN && *y == -1 as _) {
|
||||
panic!("attempt to calculate the remainder with overflow");
|
||||
}
|
||||
unsafe { crate::intrinsics::simd_rem(self, rhs) }
|
||||
unsafe { intrinsics::simd_rem(self, rhs) }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -451,7 +452,7 @@ macro_rules! impl_unsigned_int_ops {
|
|||
panic!("attempt to calculate the remainder with overflow");
|
||||
}
|
||||
let rhs = Self::splat(rhs);
|
||||
unsafe { crate::intrinsics::simd_rem(self, rhs) }
|
||||
unsafe { intrinsics::simd_rem(self, rhs) }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -512,7 +513,7 @@ macro_rules! impl_unsigned_int_ops {
|
|||
{
|
||||
panic!("attempt to shift left with overflow");
|
||||
}
|
||||
unsafe { crate::intrinsics::simd_shl(self, rhs) }
|
||||
unsafe { intrinsics::simd_shl(self, rhs) }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -530,7 +531,7 @@ macro_rules! impl_unsigned_int_ops {
|
|||
panic!("attempt to shift left with overflow");
|
||||
}
|
||||
let rhs = Self::splat(rhs);
|
||||
unsafe { crate::intrinsics::simd_shl(self, rhs) }
|
||||
unsafe { intrinsics::simd_shl(self, rhs) }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -577,7 +578,7 @@ macro_rules! impl_unsigned_int_ops {
|
|||
{
|
||||
panic!("attempt to shift with overflow");
|
||||
}
|
||||
unsafe { crate::intrinsics::simd_shr(self, rhs) }
|
||||
unsafe { intrinsics::simd_shr(self, rhs) }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -595,7 +596,7 @@ macro_rules! impl_unsigned_int_ops {
|
|||
panic!("attempt to shift with overflow");
|
||||
}
|
||||
let rhs = Self::splat(rhs);
|
||||
unsafe { crate::intrinsics::simd_shr(self, rhs) }
|
||||
unsafe { intrinsics::simd_shr(self, rhs) }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,8 +1,11 @@
|
|||
use crate::simd::intrinsics;
|
||||
use crate::simd::{Simd, SimdElement};
|
||||
|
||||
macro_rules! impl_shuffle_lane {
|
||||
{ $fn:ident, $n:literal } => {
|
||||
impl<T> crate::Simd<T, $n>
|
||||
impl<T> Simd<T, $n>
|
||||
where
|
||||
T: crate::SimdElement,
|
||||
T: SimdElement,
|
||||
{
|
||||
/// A const SIMD shuffle that takes 2 SIMD vectors and produces another vector, using
|
||||
/// the indices in the const parameter. The first or "self" vector will have its lanes
|
||||
|
|
@ -24,7 +27,7 @@ macro_rules! impl_shuffle_lane {
|
|||
/// ```
|
||||
#[inline]
|
||||
pub fn shuffle<const IDX: [u32; $n]>(self, second: Self) -> Self {
|
||||
unsafe { crate::intrinsics::$fn(self, second, IDX) }
|
||||
unsafe { intrinsics::$fn(self, second, IDX) }
|
||||
}
|
||||
|
||||
/// Reverse the order of the lanes in the vector.
|
||||
|
|
|
|||
|
|
@ -1,4 +1,8 @@
|
|||
use crate::{LaneCount, Simd, SupportedLaneCount};
|
||||
use crate::simd::intrinsics::{
|
||||
simd_reduce_add_ordered, simd_reduce_and, simd_reduce_max, simd_reduce_min,
|
||||
simd_reduce_mul_ordered, simd_reduce_or, simd_reduce_xor,
|
||||
};
|
||||
use crate::simd::{LaneCount, Simd, SupportedLaneCount};
|
||||
|
||||
macro_rules! impl_integer_reductions {
|
||||
{ $scalar:ty } => {
|
||||
|
|
@ -9,46 +13,46 @@ macro_rules! impl_integer_reductions {
|
|||
/// Horizontal wrapping add. Returns the sum of the lanes of the vector, with wrapping addition.
|
||||
#[inline]
|
||||
pub fn horizontal_sum(self) -> $scalar {
|
||||
unsafe { crate::intrinsics::simd_reduce_add_ordered(self, 0) }
|
||||
unsafe { simd_reduce_add_ordered(self, 0) }
|
||||
}
|
||||
|
||||
/// Horizontal wrapping multiply. Returns the product of the lanes of the vector, with wrapping multiplication.
|
||||
#[inline]
|
||||
pub fn horizontal_product(self) -> $scalar {
|
||||
unsafe { crate::intrinsics::simd_reduce_mul_ordered(self, 1) }
|
||||
unsafe { simd_reduce_mul_ordered(self, 1) }
|
||||
}
|
||||
|
||||
/// Horizontal bitwise "and". Returns the cumulative bitwise "and" across the lanes of
|
||||
/// the vector.
|
||||
#[inline]
|
||||
pub fn horizontal_and(self) -> $scalar {
|
||||
unsafe { crate::intrinsics::simd_reduce_and(self) }
|
||||
unsafe { simd_reduce_and(self) }
|
||||
}
|
||||
|
||||
/// Horizontal bitwise "or". Returns the cumulative bitwise "or" across the lanes of
|
||||
/// the vector.
|
||||
#[inline]
|
||||
pub fn horizontal_or(self) -> $scalar {
|
||||
unsafe { crate::intrinsics::simd_reduce_or(self) }
|
||||
unsafe { simd_reduce_or(self) }
|
||||
}
|
||||
|
||||
/// Horizontal bitwise "xor". Returns the cumulative bitwise "xor" across the lanes of
|
||||
/// the vector.
|
||||
#[inline]
|
||||
pub fn horizontal_xor(self) -> $scalar {
|
||||
unsafe { crate::intrinsics::simd_reduce_xor(self) }
|
||||
unsafe { simd_reduce_xor(self) }
|
||||
}
|
||||
|
||||
/// Horizontal maximum. Returns the maximum lane in the vector.
|
||||
#[inline]
|
||||
pub fn horizontal_max(self) -> $scalar {
|
||||
unsafe { crate::intrinsics::simd_reduce_max(self) }
|
||||
unsafe { simd_reduce_max(self) }
|
||||
}
|
||||
|
||||
/// Horizontal minimum. Returns the minimum lane in the vector.
|
||||
#[inline]
|
||||
pub fn horizontal_min(self) -> $scalar {
|
||||
unsafe { crate::intrinsics::simd_reduce_min(self) }
|
||||
unsafe { simd_reduce_min(self) }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -79,7 +83,7 @@ macro_rules! impl_float_reductions {
|
|||
if cfg!(all(target_arch = "x86", not(target_feature = "sse2"))) {
|
||||
self.as_array().iter().sum()
|
||||
} else {
|
||||
unsafe { crate::intrinsics::simd_reduce_add_ordered(self, 0.) }
|
||||
unsafe { simd_reduce_add_ordered(self, 0.) }
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -90,7 +94,7 @@ macro_rules! impl_float_reductions {
|
|||
if cfg!(all(target_arch = "x86", not(target_feature = "sse2"))) {
|
||||
self.as_array().iter().product()
|
||||
} else {
|
||||
unsafe { crate::intrinsics::simd_reduce_mul_ordered(self, 1.) }
|
||||
unsafe { simd_reduce_mul_ordered(self, 1.) }
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -100,7 +104,7 @@ macro_rules! impl_float_reductions {
|
|||
/// return either. This function will not return `NaN` unless all lanes are `NaN`.
|
||||
#[inline]
|
||||
pub fn horizontal_max(self) -> $scalar {
|
||||
unsafe { crate::intrinsics::simd_reduce_max(self) }
|
||||
unsafe { simd_reduce_max(self) }
|
||||
}
|
||||
|
||||
/// Horizontal minimum. Returns the minimum lane in the vector.
|
||||
|
|
@ -109,7 +113,7 @@ macro_rules! impl_float_reductions {
|
|||
/// return either. This function will not return `NaN` unless all lanes are `NaN`.
|
||||
#[inline]
|
||||
pub fn horizontal_min(self) -> $scalar {
|
||||
unsafe { crate::intrinsics::simd_reduce_min(self) }
|
||||
unsafe { simd_reduce_min(self) }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
use crate::{LaneCount, Simd, SupportedLaneCount};
|
||||
use crate::simd::intrinsics;
|
||||
use crate::simd::{LaneCount, Simd, SupportedLaneCount};
|
||||
|
||||
macro_rules! implement {
|
||||
{
|
||||
|
|
@ -13,28 +14,28 @@ macro_rules! implement {
|
|||
#[must_use = "method returns a new vector and does not mutate the original value"]
|
||||
#[inline]
|
||||
pub fn ceil(self) -> Self {
|
||||
unsafe { crate::intrinsics::simd_ceil(self) }
|
||||
unsafe { intrinsics::simd_ceil(self) }
|
||||
}
|
||||
|
||||
/// Returns the largest integer value less than or equal to each lane.
|
||||
#[must_use = "method returns a new vector and does not mutate the original value"]
|
||||
#[inline]
|
||||
pub fn floor(self) -> Self {
|
||||
unsafe { crate::intrinsics::simd_floor(self) }
|
||||
unsafe { intrinsics::simd_floor(self) }
|
||||
}
|
||||
|
||||
/// Rounds to the nearest integer value. Ties round toward zero.
|
||||
#[must_use = "method returns a new vector and does not mutate the original value"]
|
||||
#[inline]
|
||||
pub fn round(self) -> Self {
|
||||
unsafe { crate::intrinsics::simd_round(self) }
|
||||
unsafe { intrinsics::simd_round(self) }
|
||||
}
|
||||
|
||||
/// Returns the floating point's integer value, with its fractional part removed.
|
||||
#[must_use = "method returns a new vector and does not mutate the original value"]
|
||||
#[inline]
|
||||
pub fn trunc(self) -> Self {
|
||||
unsafe { crate::intrinsics::simd_trunc(self) }
|
||||
unsafe { intrinsics::simd_trunc(self) }
|
||||
}
|
||||
|
||||
/// Returns the floating point's fractional value, with its integer part removed.
|
||||
|
|
@ -60,14 +61,14 @@ macro_rules! implement {
|
|||
/// * Be representable in the return type, after truncating off its fractional part
|
||||
#[inline]
|
||||
pub unsafe fn to_int_unchecked(self) -> Simd<$int_type, LANES> {
|
||||
crate::intrinsics::simd_cast(self)
|
||||
intrinsics::simd_cast(self)
|
||||
}
|
||||
|
||||
/// Creates a floating-point vector from an integer vector. Rounds values that are
|
||||
/// not exactly representable.
|
||||
#[inline]
|
||||
pub fn round_from_int(value: Simd<$int_type, LANES>) -> Self {
|
||||
unsafe { crate::intrinsics::simd_cast(value) }
|
||||
unsafe { intrinsics::simd_cast(value) }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
use crate::{LaneCount, Mask, MaskElement, Simd, SimdElement, SupportedLaneCount};
|
||||
use crate::simd::intrinsics;
|
||||
use crate::simd::{LaneCount, Mask, MaskElement, Simd, SimdElement, SupportedLaneCount};
|
||||
|
||||
mod sealed {
|
||||
pub trait Sealed {}
|
||||
|
|
@ -25,7 +26,7 @@ where
|
|||
{
|
||||
#[inline]
|
||||
fn select(mask: Mask<T::Mask, LANES>, true_values: Self, false_values: Self) -> Self {
|
||||
unsafe { crate::intrinsics::simd_select(mask.to_int(), true_values, false_values) }
|
||||
unsafe { intrinsics::simd_select(mask.to_int(), true_values, false_values) }
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,19 +1,19 @@
|
|||
macro_rules! impl_to_bytes {
|
||||
{ $ty:ty, $size:literal } => {
|
||||
impl<const LANES: usize> crate::Simd<$ty, LANES>
|
||||
impl<const LANES: usize> crate::simd::Simd<$ty, LANES>
|
||||
where
|
||||
crate::LaneCount<LANES>: crate::SupportedLaneCount,
|
||||
crate::LaneCount<{{ $size * LANES }}>: crate::SupportedLaneCount,
|
||||
crate::simd::LaneCount<LANES>: crate::simd::SupportedLaneCount,
|
||||
crate::simd::LaneCount<{{ $size * LANES }}>: crate::simd::SupportedLaneCount,
|
||||
{
|
||||
/// Return the memory representation of this integer as a byte array in native byte
|
||||
/// order.
|
||||
pub fn to_ne_bytes(self) -> crate::Simd<u8, {{ $size * LANES }}> {
|
||||
pub fn to_ne_bytes(self) -> crate::simd::Simd<u8, {{ $size * LANES }}> {
|
||||
unsafe { core::mem::transmute_copy(&self) }
|
||||
}
|
||||
|
||||
/// Create a native endian integer value from its memory representation as a byte array
|
||||
/// in native endianness.
|
||||
pub fn from_ne_bytes(bytes: crate::Simd<u8, {{ $size * LANES }}>) -> Self {
|
||||
pub fn from_ne_bytes(bytes: crate::simd::Simd<u8, {{ $size * LANES }}>) -> Self {
|
||||
unsafe { core::mem::transmute_copy(&bytes) }
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -9,7 +9,8 @@ pub use uint::*;
|
|||
// Vectors of pointers are not for public use at the current time.
|
||||
pub(crate) mod ptr;
|
||||
|
||||
use crate::{LaneCount, Mask, MaskElement, SupportedLaneCount};
|
||||
use crate::simd::intrinsics;
|
||||
use crate::simd::{LaneCount, Mask, MaskElement, SupportedLaneCount};
|
||||
|
||||
/// A SIMD vector of `LANES` elements of type `T`.
|
||||
#[repr(simd)]
|
||||
|
|
@ -108,11 +109,11 @@ where
|
|||
or: Self,
|
||||
) -> Self {
|
||||
let mask = (mask & idxs.lanes_lt(Simd::splat(slice.len()))).to_int();
|
||||
let base_ptr = crate::vector::ptr::SimdConstPtr::splat(slice.as_ptr());
|
||||
let base_ptr = crate::simd::ptr::SimdConstPtr::splat(slice.as_ptr());
|
||||
// Ferris forgive me, I have done pointer arithmetic here.
|
||||
let ptrs = base_ptr.wrapping_add(idxs);
|
||||
// SAFETY: The ptrs have been bounds-masked to prevent memory-unsafe reads insha'allah
|
||||
unsafe { crate::intrinsics::simd_gather(or, ptrs, mask) }
|
||||
unsafe { intrinsics::simd_gather(or, ptrs, mask) }
|
||||
}
|
||||
|
||||
/// SIMD scatter: write a SIMD vector's values into a slice, using potentially discontiguous indices.
|
||||
|
|
@ -168,11 +169,11 @@ where
|
|||
// 3. &mut [T] which will become our base ptr.
|
||||
unsafe {
|
||||
// Now Entering ☢️ *mut T Zone
|
||||
let base_ptr = crate::vector::ptr::SimdMutPtr::splat(slice.as_mut_ptr());
|
||||
let base_ptr = crate::simd::ptr::SimdMutPtr::splat(slice.as_mut_ptr());
|
||||
// Ferris forgive me, I have done pointer arithmetic here.
|
||||
let ptrs = base_ptr.wrapping_add(idxs);
|
||||
// The ptrs have been bounds-masked to prevent memory-unsafe writes insha'allah
|
||||
crate::intrinsics::simd_scatter(self, ptrs, mask)
|
||||
intrinsics::simd_scatter(self, ptrs, mask)
|
||||
// Cleared ☢️ *mut T Zone
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
#![allow(non_camel_case_types)]
|
||||
|
||||
use crate::{LaneCount, Mask, Simd, SupportedLaneCount};
|
||||
use crate::simd::intrinsics;
|
||||
use crate::simd::{LaneCount, Mask, Simd, SupportedLaneCount};
|
||||
|
||||
/// Implements inherent methods for a float vector containing multiple
|
||||
/// `$lanes` of float `$type`, which uses `$bits_ty` as its binary
|
||||
|
|
@ -31,7 +32,7 @@ macro_rules! impl_float_vector {
|
|||
/// equivalently-indexed lane in `self`.
|
||||
#[inline]
|
||||
pub fn abs(self) -> Self {
|
||||
unsafe { crate::intrinsics::simd_fabs(self) }
|
||||
unsafe { intrinsics::simd_fabs(self) }
|
||||
}
|
||||
|
||||
/// Fused multiply-add. Computes `(self * a) + b` with only one rounding error,
|
||||
|
|
@ -43,7 +44,7 @@ macro_rules! impl_float_vector {
|
|||
/// hardware in mind.
|
||||
#[inline]
|
||||
pub fn mul_add(self, a: Self, b: Self) -> Self {
|
||||
unsafe { crate::intrinsics::simd_fma(self, a, b) }
|
||||
unsafe { intrinsics::simd_fma(self, a, b) }
|
||||
}
|
||||
|
||||
/// Produces a vector where every lane has the square root value
|
||||
|
|
@ -51,7 +52,7 @@ macro_rules! impl_float_vector {
|
|||
#[inline]
|
||||
#[cfg(feature = "std")]
|
||||
pub fn sqrt(self) -> Self {
|
||||
unsafe { crate::intrinsics::simd_fsqrt(self) }
|
||||
unsafe { intrinsics::simd_fsqrt(self) }
|
||||
}
|
||||
|
||||
/// Takes the reciprocal (inverse) of each lane, `1/x`.
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
#![allow(non_camel_case_types)]
|
||||
|
||||
use crate::{LaneCount, Mask, Simd, SupportedLaneCount};
|
||||
use crate::simd::{LaneCount, Mask, Simd, SupportedLaneCount};
|
||||
|
||||
/// Implements additional integer traits (Eq, Ord, Hash) on the specified vector `$name`, holding multiple `$lanes` of `$type`.
|
||||
macro_rules! impl_integer_vector {
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
//! Private implementation details of public gather/scatter APIs.
|
||||
use crate::{LaneCount, Simd, SupportedLaneCount};
|
||||
use crate::simd::{LaneCount, Simd, SupportedLaneCount};
|
||||
use core::mem;
|
||||
|
||||
/// A vector of *const T.
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
#![allow(non_camel_case_types)]
|
||||
|
||||
use crate::Simd;
|
||||
use crate::simd::Simd;
|
||||
|
||||
/// Vector of two `usize` values
|
||||
pub type usizex2 = Simd<usize, 2>;
|
||||
|
|
|
|||
2
crates/core_simd/src/vendor/arm.rs
vendored
2
crates/core_simd/src/vendor/arm.rs
vendored
|
|
@ -1,4 +1,4 @@
|
|||
use crate::*;
|
||||
use crate::simd::*;
|
||||
|
||||
#[cfg(target_arch = "arm")]
|
||||
use core::arch::arm::*;
|
||||
|
|
|
|||
2
crates/core_simd/src/vendor/powerpc.rs
vendored
2
crates/core_simd/src/vendor/powerpc.rs
vendored
|
|
@ -1,4 +1,4 @@
|
|||
use crate::*;
|
||||
use crate::simd::*;
|
||||
|
||||
#[cfg(target_arch = "powerpc")]
|
||||
use core::arch::powerpc::*;
|
||||
|
|
|
|||
2
crates/core_simd/src/vendor/wasm32.rs
vendored
2
crates/core_simd/src/vendor/wasm32.rs
vendored
|
|
@ -1,4 +1,4 @@
|
|||
use crate::*;
|
||||
use crate::simd::*;
|
||||
use core::arch::wasm32::v128;
|
||||
|
||||
from_transmute! { unsafe u8x16 => v128 }
|
||||
|
|
|
|||
2
crates/core_simd/src/vendor/x86.rs
vendored
2
crates/core_simd/src/vendor/x86.rs
vendored
|
|
@ -1,4 +1,4 @@
|
|||
use crate::*;
|
||||
use crate::simd::*;
|
||||
|
||||
#[cfg(any(target_arch = "x86"))]
|
||||
use core::arch::x86::*;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue