summaryrefslogtreecommitdiffstats
path: root/vendor/ppv-lite86/src/types.rs
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/ppv-lite86/src/types.rs')
-rw-r--r--vendor/ppv-lite86/src/types.rs279
1 files changed, 279 insertions, 0 deletions
diff --git a/vendor/ppv-lite86/src/types.rs b/vendor/ppv-lite86/src/types.rs
new file mode 100644
index 000000000..119b6bb8d
--- /dev/null
+++ b/vendor/ppv-lite86/src/types.rs
@@ -0,0 +1,279 @@
+use core::ops::{Add, AddAssign, BitAnd, BitOr, BitXor, BitXorAssign, Not};
+
+pub trait AndNot {
+ type Output;
+ fn andnot(self, rhs: Self) -> Self::Output;
+}
+pub trait BSwap {
+ fn bswap(self) -> Self;
+}
+/// Ops that depend on word size
+pub trait ArithOps: Add<Output = Self> + AddAssign + Sized + Copy + Clone + BSwap {}
+/// Ops that are independent of word size and endian
+pub trait BitOps0:
+ BitAnd<Output = Self>
+ + BitOr<Output = Self>
+ + BitXor<Output = Self>
+ + BitXorAssign
+ + Not<Output = Self>
+ + AndNot<Output = Self>
+ + Sized
+ + Copy
+ + Clone
+{
+}
+
+pub trait BitOps32: BitOps0 + RotateEachWord32 {}
+pub trait BitOps64: BitOps32 + RotateEachWord64 {}
+pub trait BitOps128: BitOps64 + RotateEachWord128 {}
+
+pub trait RotateEachWord32 {
+ fn rotate_each_word_right7(self) -> Self;
+ fn rotate_each_word_right8(self) -> Self;
+ fn rotate_each_word_right11(self) -> Self;
+ fn rotate_each_word_right12(self) -> Self;
+ fn rotate_each_word_right16(self) -> Self;
+ fn rotate_each_word_right20(self) -> Self;
+ fn rotate_each_word_right24(self) -> Self;
+ fn rotate_each_word_right25(self) -> Self;
+}
+
+pub trait RotateEachWord64 {
+ fn rotate_each_word_right32(self) -> Self;
+}
+
+pub trait RotateEachWord128 {}
+
+#[allow(non_camel_case_types)]
+mod types {
+ //! Vector type naming scheme:
+ //! uN[xP]xL
+ //! Unsigned; N-bit words * P bits per lane * L lanes
+ //!
+ //! A lane is always 128-bits, chosen because common SIMD architectures treat 128-bit units of
+ //! wide vectors specially (supporting e.g. intra-lane shuffles), and tend to have limited and
+ //! slow inter-lane operations.
+
+ use crate::arch::{vec128_storage, vec256_storage, vec512_storage};
+ use crate::{ArithOps, BitOps128, BitOps32, BitOps64, Machine, Store, StoreBytes};
+
+ pub trait UnsafeFrom<T> {
+ unsafe fn unsafe_from(t: T) -> Self;
+ }
+
+ /// A vector composed of two elements, which may be words or themselves vectors.
+ pub trait Vec2<W> {
+ fn extract(self, i: u32) -> W;
+ fn insert(self, w: W, i: u32) -> Self;
+ }
+
+ /// A vector composed of four elements, which may be words or themselves vectors.
+ pub trait Vec4<W> {
+ fn extract(self, i: u32) -> W;
+ fn insert(self, w: W, i: u32) -> Self;
+ }
+
+ // TODO: multiples of 4 should inherit this
+ /// A vector composed of four words; depending on their size, operations may cross lanes.
+ pub trait Words4 {
+ fn shuffle1230(self) -> Self;
+ fn shuffle2301(self) -> Self;
+ fn shuffle3012(self) -> Self;
+ }
+
+ /// A vector composed one or more lanes each composed of four words.
+ pub trait LaneWords4 {
+ fn shuffle_lane_words1230(self) -> Self;
+ fn shuffle_lane_words2301(self) -> Self;
+ fn shuffle_lane_words3012(self) -> Self;
+ }
+
+ // TODO: make this a part of BitOps
+ /// Exchange neigboring ranges of bits of the specified size
+ pub trait Swap64 {
+ fn swap1(self) -> Self;
+ fn swap2(self) -> Self;
+ fn swap4(self) -> Self;
+ fn swap8(self) -> Self;
+ fn swap16(self) -> Self;
+ fn swap32(self) -> Self;
+ fn swap64(self) -> Self;
+ }
+
+ pub trait u32x4<M: Machine>:
+ BitOps32
+ + Store<vec128_storage>
+ + ArithOps
+ + Vec4<u32>
+ + Words4
+ + LaneWords4
+ + StoreBytes
+ + MultiLane<[u32; 4]>
+ + Into<vec128_storage>
+ {
+}
+ pub trait u64x2<M: Machine>:
+ BitOps64
+ + Store<vec128_storage>
+ + ArithOps
+ + Vec2<u64>
+ + MultiLane<[u64; 2]>
+ + Into<vec128_storage>
+ {
+}
+ pub trait u128x1<M: Machine>:
+ BitOps128 + Store<vec128_storage> + Swap64 + MultiLane<[u128; 1]> + Into<vec128_storage>
+ {
+}
+
+ pub trait u32x4x2<M: Machine>:
+ BitOps32
+ + Store<vec256_storage>
+ + Vec2<M::u32x4>
+ + MultiLane<[M::u32x4; 2]>
+ + ArithOps
+ + Into<vec256_storage>
+ {
+}
+ pub trait u64x2x2<M: Machine>:
+ BitOps64
+ + Store<vec256_storage>
+ + Vec2<M::u64x2>
+ + MultiLane<[M::u64x2; 2]>
+ + ArithOps
+ + StoreBytes
+ + Into<vec256_storage>
+ {
+}
+ pub trait u64x4<M: Machine>:
+ BitOps64
+ + Store<vec256_storage>
+ + Vec4<u64>
+ + MultiLane<[u64; 4]>
+ + ArithOps
+ + Words4
+ + StoreBytes
+ + Into<vec256_storage>
+ {
+}
+ pub trait u128x2<M: Machine>:
+ BitOps128
+ + Store<vec256_storage>
+ + Vec2<M::u128x1>
+ + MultiLane<[M::u128x1; 2]>
+ + Swap64
+ + Into<vec256_storage>
+ {
+}
+
+ pub trait u32x4x4<M: Machine>:
+ BitOps32
+ + Store<vec512_storage>
+ + Vec4<M::u32x4>
+ + MultiLane<[M::u32x4; 4]>
+ + ArithOps
+ + LaneWords4
+ + Into<vec512_storage>
+ {
+}
+ pub trait u64x2x4<M: Machine>:
+ BitOps64
+ + Store<vec512_storage>
+ + Vec4<M::u64x2>
+ + MultiLane<[M::u64x2; 4]>
+ + ArithOps
+ + Into<vec512_storage>
+ {
+}
+ // TODO: Words4
+ pub trait u128x4<M: Machine>:
+ BitOps128
+ + Store<vec512_storage>
+ + Vec4<M::u128x1>
+ + MultiLane<[M::u128x1; 4]>
+ + Swap64
+ + Into<vec512_storage>
+ {
+}
+
+ /// A vector composed of multiple 128-bit lanes.
+ pub trait MultiLane<Lanes> {
+ /// Split a multi-lane vector into single-lane vectors.
+ fn to_lanes(self) -> Lanes;
+ /// Build a multi-lane vector from individual lanes.
+ fn from_lanes(lanes: Lanes) -> Self;
+ }
+
+ /// Combine single vectors into a multi-lane vector.
+ pub trait VZip<V> {
+ fn vzip(self) -> V;
+ }
+
+ impl<V, T> VZip<V> for T
+ where
+ V: MultiLane<T>,
+ {
+ #[inline(always)]
+ fn vzip(self) -> V {
+ V::from_lanes(self)
+ }
+ }
+}
+pub use self::types::*;
+
+pub trait Machine: Sized + Copy {
+ type u32x4: u32x4<Self>;
+ type u64x2: u64x2<Self>;
+ type u128x1: u128x1<Self>;
+
+ type u32x4x2: u32x4x2<Self>;
+ type u64x2x2: u64x2x2<Self>;
+ type u64x4: u64x4<Self>;
+ type u128x2: u128x2<Self>;
+
+ type u32x4x4: u32x4x4<Self>;
+ type u64x2x4: u64x2x4<Self>;
+ type u128x4: u128x4<Self>;
+
+ #[inline(always)]
+ fn unpack<S, V: Store<S>>(self, s: S) -> V {
+ unsafe { V::unpack(s) }
+ }
+
+ #[inline(always)]
+ fn vec<V, A>(self, a: A) -> V
+ where
+ V: MultiLane<A>,
+ {
+ V::from_lanes(a)
+ }
+
+ #[inline(always)]
+ fn read_le<V>(self, input: &[u8]) -> V
+ where
+ V: StoreBytes,
+ {
+ unsafe { V::unsafe_read_le(input) }
+ }
+
+ #[inline(always)]
+ fn read_be<V>(self, input: &[u8]) -> V
+ where
+ V: StoreBytes,
+ {
+ unsafe { V::unsafe_read_be(input) }
+ }
+
+ unsafe fn instance() -> Self;
+}
+
+pub trait Store<S> {
+ unsafe fn unpack(p: S) -> Self;
+}
+
+pub trait StoreBytes {
+ unsafe fn unsafe_read_le(input: &[u8]) -> Self;
+ unsafe fn unsafe_read_be(input: &[u8]) -> Self;
+ fn write_le(self, out: &mut [u8]);
+ fn write_be(self, out: &mut [u8]);
+}