Begin changing vectors to const generics

This commit is contained in:
Caleb Zulawski
2020-12-05 00:03:20 -05:00
parent 35b9ab9f5c
commit 27e944231c
17 changed files with 241 additions and 405 deletions

View File

@@ -30,10 +30,10 @@ debug_wrapper! {
}
macro_rules! impl_fmt_trait {
{ $($type:ty => $(($trait:ident, $format:ident)),*;)* } => {
{ $($type:ident => $(($trait:ident, $format:ident)),*;)* } => {
$( // repeat type
$( // repeat trait
impl core::fmt::$trait for $type {
impl<const LANES: usize> core::fmt::$trait for crate::$type<LANES> {
fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {
$format(self.as_ref(), f)
}
@@ -41,7 +41,7 @@ macro_rules! impl_fmt_trait {
)*
)*
};
{ integers: $($type:ty,)* } => {
{ integers: $($type:ident,)* } => {
impl_fmt_trait! {
$($type =>
(Debug, format),
@@ -54,7 +54,7 @@ macro_rules! impl_fmt_trait {
)*
}
};
{ floats: $($type:ty,)* } => {
{ floats: $($type:ident,)* } => {
impl_fmt_trait! {
$($type =>
(Debug, format),
@@ -63,7 +63,7 @@ macro_rules! impl_fmt_trait {
)*
}
};
{ masks: $($type:ty,)* } => {
{ masks: $($type:ident,)* } => {
impl_fmt_trait! {
$($type =>
(Debug, format);
@@ -74,32 +74,12 @@ macro_rules! impl_fmt_trait {
impl_fmt_trait! {
integers:
crate::u8x8, crate::u8x16, crate::u8x32, crate::u8x64,
crate::i8x8, crate::i8x16, crate::i8x32, crate::i8x64,
crate::u16x4, crate::u16x8, crate::u16x16, crate::u16x32,
crate::i16x4, crate::i16x8, crate::i16x16, crate::i16x32,
crate::u32x2, crate::u32x4, crate::u32x8, crate::u32x16,
crate::i32x2, crate::i32x4, crate::i32x8, crate::i32x16,
crate::u64x2, crate::u64x4, crate::u64x8,
crate::i64x2, crate::i64x4, crate::i64x8,
crate::u128x2, crate::u128x4,
crate::i128x2, crate::i128x4,
crate::usizex2, crate::usizex4, crate::usizex8,
crate::isizex2, crate::isizex4, crate::isizex8,
SimdU8, SimdU16, SimdU32, SimdU64, SimdU128,
SimdI8, SimdI16, SimdI32, SimdI64, SimdI128,
SimdUsize, SimdIsize,
}
impl_fmt_trait! {
floats:
crate::f32x2, crate::f32x4, crate::f32x8, crate::f32x16,
crate::f64x2, crate::f64x4, crate::f64x8,
}
impl_fmt_trait! {
masks:
crate::masks::wide::m8x8, crate::masks::wide::m8x16, crate::masks::wide::m8x32, crate::masks::wide::m8x64,
crate::masks::wide::m16x4, crate::masks::wide::m16x8, crate::masks::wide::m16x16, crate::masks::wide::m16x32,
crate::masks::wide::m32x2, crate::masks::wide::m32x4, crate::masks::wide::m32x8, crate::masks::wide::m32x16,
crate::masks::wide::m64x2, crate::masks::wide::m64x4, crate::masks::wide::m64x8,
crate::masks::wide::m128x2, crate::masks::wide::m128x4,
crate::masks::wide::msizex2, crate::masks::wide::msizex4, crate::masks::wide::msizex8,
SimdF32, SimdF64,
}

View File

@@ -1,5 +1,5 @@
#![no_std]
#![feature(repr_simd, platform_intrinsics, link_llvm_intrinsics, simd_ffi)]
#![feature(repr_simd, platform_intrinsics, link_llvm_intrinsics, simd_ffi, min_const_generics)]
#![warn(missing_docs)]
//! Portable SIMD module.
@@ -8,10 +8,11 @@ mod macros;
mod fmt;
mod intrinsics;
mod ops;
//mod ops;
//mod round;
pub mod masks;
pub use masks::opaque::*;
//pub mod masks;
//pub use masks::opaque::*;
mod vectors_u8;
pub use vectors_u8::*;
@@ -44,4 +45,15 @@ pub use vectors_f32::*;
mod vectors_f64;
pub use vectors_f64::*;
mod round;
//mod vectors_mask8;
//pub use vectors_mask8::*;
//mod vectors_mask16;
//pub use vectors_mask16::*;
//mod vectors_mask32;
//pub use vectors_mask32::*;
//mod vectors_mask64;
//pub use vectors_mask64::*;
//mod vectors_mask128;
//pub use vectors_mask128::*;
//mod vectors_masksize;
//pub use vectors_masksize::*;

View File

@@ -136,73 +136,110 @@ macro_rules! call_counting_args {
}
/// Implements common traits on the specified vector `$name`, holding multiple `$lanes` of `$type`.
macro_rules! base_vector_traits {
{ $name:path => [$type:ty; $lanes:literal] } => {
impl Copy for $name {}
macro_rules! impl_vector {
{ $name:ident, $type:ty } => {
impl<const LANES: usize> $name<LANES> {
/// Construct a vector by setting all lanes to the given value.
pub const fn splat(value: $type) -> Self {
Self([value; LANES])
}
impl Clone for $name {
pub const fn as_slice(&self) -> &[$type] {
&self.0
}
pub fn as_mut_slice(&mut self) -> &mut [$type] {
&mut self.0
}
pub const fn as_ptr(&self) -> *const $type {
self.0.as_ptr()
}
pub fn as_mut_ptr(&mut self) -> *mut $type {
self.0.as_mut_ptr()
}
pub const fn from_array(array: [$type; LANES]) -> Self {
Self(array)
}
pub const fn to_array(self) -> [$type; LANES] {
self.0
}
}
impl<const LANES: usize> Copy for $name<LANES> {}
impl<const LANES: usize> Clone for $name<LANES> {
#[inline]
fn clone(&self) -> Self {
*self
}
}
impl Default for $name {
impl<const LANES: usize> Default for $name<LANES> {
#[inline]
fn default() -> Self {
Self::splat(<$type>::default())
}
}
impl PartialEq for $name {
impl<const LANES: usize> PartialEq for $name<LANES> {
#[inline]
fn eq(&self, other: &Self) -> bool {
AsRef::<[$type]>::as_ref(self) == AsRef::<[$type]>::as_ref(other)
// TODO use SIMD equality
self.to_array() == other.to_array()
}
}
impl PartialOrd for $name {
impl<const LANES: usize> PartialOrd for $name<LANES> {
#[inline]
fn partial_cmp(&self, other: &Self) -> Option<core::cmp::Ordering> {
AsRef::<[$type]>::as_ref(self).partial_cmp(AsRef::<[$type]>::as_ref(other))
// TODO use SIMD equalitya
self.to_array().partial_cmp(other.as_ref())
}
}
// array references
impl AsRef<[$type; $lanes]> for $name {
impl<const LANES: usize> AsRef<[$type; LANES]> for $name<LANES> {
#[inline]
fn as_ref(&self) -> &[$type; $lanes] {
unsafe { &*(self as *const _ as *const _) }
fn as_ref(&self) -> &[$type; LANES] {
&self.0
}
}
impl AsMut<[$type; $lanes]> for $name {
impl<const LANES: usize> AsMut<[$type; LANES]> for $name<LANES> {
#[inline]
fn as_mut(&mut self) -> &mut [$type; $lanes] {
unsafe { &mut *(self as *mut _ as *mut _) }
fn as_mut(&mut self) -> &mut [$type; LANES] {
&mut self.0
}
}
// slice references
impl AsRef<[$type]> for $name {
impl<const LANES: usize> AsRef<[$type]> for $name<LANES> {
#[inline]
fn as_ref(&self) -> &[$type] {
AsRef::<[$type; $lanes]>::as_ref(self)
&self.0
}
}
impl AsMut<[$type]> for $name {
impl<const LANES: usize> AsMut<[$type]> for $name<LANES> {
#[inline]
fn as_mut(&mut self) -> &mut [$type] {
AsMut::<[$type; $lanes]>::as_mut(self)
&mut self.0
}
}
// vector/array conversion
from_transmute! { unsafe $name => [$type; $lanes] }
impl<const LANES: usize> From<[$type; LANES]> for $name<LANES> {
fn from(array: [$type; LANES]) -> Self {
Self(array)
}
}
// splat
impl From<$type> for $name {
impl<const LANES: usize> From<$type> for $name<LANES> {
#[inline]
fn from(value: $type) -> Self {
Self::splat(value)
@@ -212,181 +249,59 @@ macro_rules! base_vector_traits {
}
/// Implements additional integer traits (Eq, Ord, Hash) on the specified vector `$name`, holding multiple `$lanes` of `$type`.
macro_rules! integer_vector_traits {
{ $name:path => [$type:ty; $lanes:literal] } => {
impl Eq for $name {}
macro_rules! impl_integer_vector {
{ $name:path, $type:ty } => {
impl_vector! { $name, $type }
impl Ord for $name {
impl<const LANES: usize> Eq for $name<LANES> {}
impl<const LANES: usize> Ord for $name<LANES> {
#[inline]
fn cmp(&self, other: &Self) -> core::cmp::Ordering {
AsRef::<[$type]>::as_ref(self).cmp(AsRef::<[$type]>::as_ref(other))
// TODO use SIMD cmp
self.to_array().cmp(other.as_ref())
}
}
impl core::hash::Hash for $name {
impl<const LANES: usize> core::hash::Hash for $name<LANES> {
#[inline]
fn hash<H>(&self, state: &mut H)
where
H: core::hash::Hasher
{
AsRef::<[$type]>::as_ref(self).hash(state)
self.as_slice().hash(state)
}
}
}
}
/// Defines a vector `$name` containing multiple `$lanes` of `$type`.
macro_rules! define_vector {
{ $(#[$attr:meta])* struct $name:ident([$type:ty; $lanes:tt]); } => {
call_repeat! { $lanes => define_vector [$type] def $(#[$attr])* | $name | }
impl $name {
call_repeat! { $lanes => define_vector [$type] splat $type | }
call_counting_args! { $lanes => define_vector => new $type | }
}
base_vector_traits! { $name => [$type; $lanes] }
};
{ def $(#[$attr:meta])* | $name:ident | $($itype:ty)* } => {
$(#[$attr])*
#[allow(non_camel_case_types)]
#[repr(simd)]
pub struct $name($($itype),*);
};
{ splat $type:ty | $($itype:ty)* } => {
/// Construct a vector by setting all lanes to the given value.
#[inline]
pub const fn splat(value: $type) -> Self {
Self($(value as $itype),*)
}
};
{ new $type:ty | $($var:ident)* } => {
/// Construct a vector by setting each lane to the given values.
#[allow(clippy::too_many_arguments)]
#[inline]
pub const fn new($($var: $type),*) -> Self {
Self($($var),*)
}
}
}
/// Implements inherent methods for a float vector `$name` containing multiple
/// `$lanes` of float `$type`, which uses `$bits_ty` as its binary
/// representation. Called from `define_float_vector!`.
macro_rules! impl_float_vector {
{ $name:path => [$type:ty; $lanes:literal]; bits $bits_ty:ty; } => {
impl $name {
/// Raw transmutation to an unsigned integer vector type with the
/// same size and number of lanes.
#[inline]
pub fn to_bits(self) -> $bits_ty {
unsafe { core::mem::transmute(self) }
}
/// Raw transmutation from an unsigned integer vector type with the
/// same size and number of lanes.
#[inline]
pub fn from_bits(bits: $bits_ty) -> Self {
unsafe { core::mem::transmute(bits) }
}
/// Produces a vector where every lane has the absolute value of the
/// equivalently-indexed lane in `self`.
#[inline]
pub fn abs(self) -> Self {
let no_sign = <$bits_ty>::splat(!0 >> 1);
Self::from_bits(self.to_bits() & no_sign)
}
// /// Raw transmutation to an unsigned integer vector type with the
// /// same size and number of lanes.
// #[inline]
// pub fn to_bits(self) -> $bits_ty {
// unsafe { core::mem::transmute(self) }
// }
//
// /// Raw transmutation from an unsigned integer vector type with the
// /// same size and number of lanes.
// #[inline]
// pub fn from_bits(bits: $bits_ty) -> Self {
// unsafe { core::mem::transmute(bits) }
// }
//
// /// Produces a vector where every lane has the absolute value of the
// /// equivalently-indexed lane in `self`.
// #[inline]
// pub fn abs(self) -> Self {
// let no_sign = <$bits_ty>::splat(!0 >> 1);
// Self::from_bits(self.to_bits() & no_sign)
// }
}
};
}
/// Defines a float vector `$name` containing multiple `$lanes` of float
/// `$type`, which uses `$bits_ty` as its binary representation.
macro_rules! define_float_vector {
{ $(#[$attr:meta])* struct $name:ident([$type:ty; $lanes:tt]); bits $bits_ty:ty; } => {
define_vector! {
$(#[$attr])*
struct $name([$type; $lanes]);
}
impl_float_vector! { $name => [$type; $lanes]; bits $bits_ty; }
}
}
/// Defines an integer vector `$name` containing multiple `$lanes` of integer `$type`.
macro_rules! define_integer_vector {
{ $(#[$attr:meta])* struct $name:ident([$type:ty; $lanes:tt]); } => {
define_vector! {
$(#[$attr])*
struct $name([$type; $lanes]);
}
integer_vector_traits! { $name => [$type; $lanes] }
}
}
/// Defines a mask vector `$name` containing multiple `$lanes` of `$type`, represented by the
/// underlying type `$impl_type`.
macro_rules! define_mask_vector {
{ $(#[$attr:meta])* struct $name:ident([$impl_type:ty as $type:ty; $lanes:tt]); } => {
call_repeat! { $lanes => define_mask_vector [$impl_type] def $(#[$attr])* | $name | }
impl $name {
call_repeat! { $lanes => define_mask_vector [$impl_type] splat $type | }
call_counting_args! { $lanes => define_mask_vector => new $type | }
call_counting_args! { $lanes => define_mask_vector => new_from_bool $type | }
/// Tests the value of the specified lane.
///
/// # Panics
/// Panics if `lane` is greater than or equal to the number of lanes in the vector.
#[inline]
pub fn test(&self, lane: usize) -> bool {
self[lane].test()
}
/// Sets the value of the specified lane.
///
/// # Panics
/// Panics if `lane` is greater than or equal to the number of lanes in the vector.
#[inline]
pub fn set(&mut self, lane: usize, value: bool) {
self[lane] = value.into();
}
}
base_vector_traits! { $name => [$type; $lanes] }
integer_vector_traits! { $name => [$type; $lanes] }
};
{ def $(#[$attr:meta])* | $name:ident | $($itype:ty)* } => {
$(#[$attr])*
#[allow(non_camel_case_types)]
#[repr(simd)]
pub struct $name($($itype),*);
};
{ splat $type:ty | $($itype:ty)* } => {
/// Construct a vector by setting all lanes to the given value.
#[inline]
pub const fn splat(value: $type) -> Self {
Self($(value.0 as $itype),*)
}
};
{ new $type:ty | $($var:ident)* } => {
/// Construct a vector by setting each lane to the given values.
#[allow(clippy::too_many_arguments)]
#[inline]
pub const fn new($($var: $type),*) -> Self {
Self($($var.0),*)
}
};
{ new_from_bool $type:ty | $($var:ident)* } => {
/// Used internally (since we can't use the Into trait in `const fn`s)
#[allow(clippy::too_many_arguments)]
#[allow(unused)]
#[inline]
pub(crate) const fn new_from_bool($($var: bool),*) -> Self {
Self($(<$type>::new($var).0),*)
}
}
}

View File

@@ -1,29 +1,16 @@
define_float_vector! {
/// Vector of two `f32` values
struct f32x2([f32; 2]);
bits crate::u32x2;
}
#![allow(non_camel_case_types)]
define_float_vector! {
/// Vector of four `f32` values
struct f32x4([f32; 4]);
bits crate::u32x4;
}
/// A SIMD vector of containing `LANES` lanes of `f32`.
#[repr(simd)]
pub struct SimdF32<const LANES: usize>([f32; LANES]);
define_float_vector! {
/// Vector of eight `f32` values
struct f32x8([f32; 8]);
bits crate::u32x8;
}
impl_vector! { SimdF32, f32 }
define_float_vector! {
/// Vector of 16 `f32` values
struct f32x16([f32; 16]);
bits crate::u32x16;
}
pub type f32x2 = SimdF32<2>;
pub type f32x4 = SimdF32<4>;
pub type f32x8 = SimdF32<8>;
pub type f32x16 = SimdF32<16>;
from_transmute_x86! { unsafe f32x4 => __m128 }
from_transmute_x86! { unsafe f32x8 => __m256 }
//from_transmute_x86! { unsafe f32x16 => __m512 }

View File

@@ -1,20 +1,14 @@
define_float_vector! {
/// Vector of two `f64` values
struct f64x2([f64; 2]);
bits crate::u64x2;
}
#![allow(non_camel_case_types)]
define_float_vector! {
/// Vector of four `f64` values
struct f64x4([f64; 4]);
bits crate::u64x4;
}
/// A SIMD vector of containing `LANES` lanes of `f64`.
#[repr(simd)]
pub struct SimdF64<const LANES: usize>([f64; LANES]);
define_float_vector! {
/// Vector of eight `f64` values
struct f64x8([f64; 8]);
bits crate::u64x8;
}
impl_vector! { SimdF64, f64 }
pub type f64x2 = SimdF64<2>;
pub type f64x4 = SimdF64<4>;
pub type f64x8 = SimdF64<8>;
from_transmute_x86! { unsafe f64x2 => __m128d }
from_transmute_x86! { unsafe f64x4 => __m256d }

View File

@@ -1,12 +1,13 @@
define_integer_vector! {
/// Vector of two `i128` values
struct i128x2([i128; 2]);
}
#![allow(non_camel_case_types)]
define_integer_vector! {
/// Vector of four `i128` values
struct i128x4([i128; 4]);
}
/// A SIMD vector of containing `LANES` lanes of `i128`.
#[repr(simd)]
pub struct SimdI128<const LANES: usize>([i128; LANES]);
impl_vector! { SimdI128, i128 }
pub type i128x2 = SimdI128<2>;
pub type i128x4 = SimdI128<4>;
from_transmute_x86! { unsafe i128x2 => __m256i }
//from_transmute_x86! { unsafe i128x4 => __m512i }

View File

@@ -1,22 +1,15 @@
define_integer_vector! {
/// Vector of four `i16` values
struct i16x4([i16; 4]);
}
#![allow(non_camel_case_types)]
define_integer_vector! {
/// Vector of eight `i16` values
struct i16x8([i16; 8]);
}
/// A SIMD vector of containing `LANES` lanes of `i16`.
#[repr(simd)]
pub struct SimdI16<const LANES: usize>([i16; LANES]);
define_integer_vector! {
/// Vector of 16 `i16` values
struct i16x16([i16; 16]);
}
impl_vector! { SimdI16, i16 }
define_integer_vector! {
/// Vector of 32 `i16` values
struct i16x32([i16; 32]);
}
pub type i16x4 = SimdI16<4>;
pub type i16x8 = SimdI16<8>;
pub type i16x16 = SimdI16<16>;
pub type i16x32 = SimdI16<32>;
from_transmute_x86! { unsafe i16x8 => __m128i }
from_transmute_x86! { unsafe i16x16 => __m256i }

View File

@@ -1,22 +1,15 @@
define_integer_vector! {
/// Vector of two `i32` values
struct i32x2([i32; 2]);
}
#![allow(non_camel_case_types)]
define_integer_vector! {
/// Vector of four `i32` values
struct i32x4([i32; 4]);
}
/// A SIMD vector of containing `LANES` lanes of `i32`.
#[repr(simd)]
pub struct SimdI32<const LANES: usize>([i32; LANES]);
define_integer_vector! {
/// Vector of eight `i32` values
struct i32x8([i32; 8]);
}
impl_vector! { SimdI32, i32 }
define_integer_vector! {
/// Vector of 16 `i32` values
struct i32x16([i32; 16]);
}
pub type i32x2 = SimdI32<2>;
pub type i32x4 = SimdI32<4>;
pub type i32x8 = SimdI32<8>;
pub type i32x16 = SimdI32<16>;
from_transmute_x86! { unsafe i32x4 => __m128i }
from_transmute_x86! { unsafe i32x8 => __m256i }

View File

@@ -1,17 +1,14 @@
define_integer_vector! {
/// Vector of two `i64` values
struct i64x2([i64; 2]);
}
#![allow(non_camel_case_types)]
define_integer_vector! {
/// Vector of four `i64` values
struct i64x4([i64; 4]);
}
/// A SIMD vector of containing `LANES` lanes of `i64`.
#[repr(simd)]
pub struct SimdI64<const LANES: usize>([i64; LANES]);
define_integer_vector! {
/// Vector of eight `i64` values
struct i64x8([i64; 8]);
}
impl_vector! { SimdI64, i64 }
pub type i64x2 = SimdI64<2>;
pub type i64x4 = SimdI64<4>;
pub type i64x8 = SimdI64<8>;
from_transmute_x86! { unsafe i64x2 => __m128i }
from_transmute_x86! { unsafe i64x4 => __m256i }

View File

@@ -1,22 +1,15 @@
define_integer_vector! {
/// Vector of eight `i8` values
struct i8x8([i8; 8]);
}
#![allow(non_camel_case_types)]
define_integer_vector! {
/// Vector of 16 `i8` values
struct i8x16([i8; 16]);
}
/// A SIMD vector of containing `LANES` lanes of `i8`.
#[repr(simd)]
pub struct SimdI8<const LANES: usize>([i8; LANES]);
define_integer_vector! {
/// Vector of 32 `i8` values
struct i8x32([i8; 32]);
}
impl_vector! { SimdI8, i8 }
define_integer_vector! {
/// Vector of 64 `i8` values
struct i8x64([i8; 64]);
}
pub type i8x8 = SimdI8<8>;
pub type i8x16 = SimdI8<16>;
pub type i8x32 = SimdI8<32>;
pub type i8x64 = SimdI8<64>;
from_transmute_x86! { unsafe i8x16 => __m128i }
from_transmute_x86! { unsafe i8x32 => __m256i }

View File

@@ -1,17 +1,14 @@
define_integer_vector! {
/// Vector of two `isize` values
struct isizex2([isize; 2]);
}
#![allow(non_camel_case_types)]
define_integer_vector! {
/// Vector of four `isize` values
struct isizex4([isize; 4]);
}
/// A SIMD vector of containing `LANES` lanes of `isize`.
#[repr(simd)]
pub struct SimdIsize<const LANES: usize>([isize; LANES]);
define_integer_vector! {
/// Vector of eight `isize` values
struct isizex8([isize; 8]);
}
impl_vector! { SimdIsize, isize }
pub type isizex2 = SimdIsize<2>;
pub type isizex4 = SimdIsize<4>;
pub type isizex8 = SimdIsize<8>;
#[cfg(target_pointer_width = "32")]
from_transmute_x86! { unsafe isizex4 => __m128i }

View File

@@ -1,12 +1,13 @@
define_integer_vector! {
/// Vector of two `u128` values
struct u128x2([u128; 2]);
}
#![allow(non_camel_case_types)]
define_integer_vector! {
/// Vector of four `u128` values
struct u128x4([u128; 4]);
}
/// A SIMD vector of containing `LANES` lanes of `u128`.
#[repr(simd)]
pub struct SimdU128<const LANES: usize>([u128; LANES]);
impl_vector! { SimdU128, u128 }
pub type u128x2 = SimdU128<2>;
pub type u128x4 = SimdU128<4>;
from_transmute_x86! { unsafe u128x2 => __m256i }
//from_transmute_x86! { unsafe u128x4 => __m512i }

View File

@@ -1,22 +1,15 @@
define_integer_vector! {
/// Vector of four `u16` values
struct u16x4([u16; 4]);
}
#![allow(non_camel_case_types)]
define_integer_vector! {
/// Vector of eight `u16` values
struct u16x8([u16; 8]);
}
/// A SIMD vector of containing `LANES` lanes of `u16`.
#[repr(simd)]
pub struct SimdU16<const LANES: usize>([u16; LANES]);
define_integer_vector! {
/// Vector of 16 `u16` values
struct u16x16([u16; 16]);
}
impl_vector! { SimdU16, u16 }
define_integer_vector! {
/// Vector of 32 `u16` values
struct u16x32([u16; 32]);
}
pub type u16x4 = SimdU16<4>;
pub type u16x8 = SimdU16<8>;
pub type u16x16 = SimdU16<16>;
pub type u16x32 = SimdU16<32>;
from_transmute_x86! { unsafe u16x8 => __m128i }
from_transmute_x86! { unsafe u16x16 => __m256i }

View File

@@ -1,22 +1,15 @@
define_integer_vector! {
/// Vector of two `u32` values
struct u32x2([u32; 2]);
}
#![allow(non_camel_case_types)]
define_integer_vector! {
/// Vector of four `u32` values
struct u32x4([u32; 4]);
}
/// A SIMD vector of containing `LANES` lanes of `u32`.
#[repr(simd)]
pub struct SimdU32<const LANES: usize>([u32; LANES]);
define_integer_vector! {
/// Vector of eight `u32` values
struct u32x8([u32; 8]);
}
impl_vector! { SimdU32, u32 }
define_integer_vector! {
/// Vector of 16 `u32` values
struct u32x16([u32; 16]);
}
pub type u32x2 = SimdU32<2>;
pub type u32x4 = SimdU32<4>;
pub type u32x8 = SimdU32<8>;
pub type u32x16 = SimdU32<16>;
from_transmute_x86! { unsafe u32x4 => __m128i }
from_transmute_x86! { unsafe u32x8 => __m256i }

View File

@@ -1,17 +1,14 @@
define_integer_vector! {
/// Vector of two `u64` values
struct u64x2([u64; 2]);
}
#![allow(non_camel_case_types)]
define_integer_vector! {
/// Vector of four `u64` values
struct u64x4([u64; 4]);
}
/// A SIMD vector of containing `LANES` lanes of `u64`.
#[repr(simd)]
pub struct SimdU64<const LANES: usize>([u64; LANES]);
define_integer_vector! {
/// Vector of eight `u64` values
struct u64x8([u64; 8]);
}
impl_vector! { SimdU64, u64 }
pub type u64x2 = SimdU64<2>;
pub type u64x4 = SimdU64<4>;
pub type u64x8 = SimdU64<8>;
from_transmute_x86! { unsafe u64x2 => __m128i }
from_transmute_x86! { unsafe u64x4 => __m256i }

View File

@@ -1,22 +1,15 @@
define_integer_vector! {
/// Vector of eight `u8` values
struct u8x8([u8; 8]);
}
#![allow(non_camel_case_types)]
define_integer_vector! {
/// Vector of 16 `u8` values
struct u8x16([u8; 16]);
}
/// A SIMD vector of containing `LANES` lanes of `u8`.
#[repr(simd)]
pub struct SimdU8<const LANES: usize>([u8; LANES]);
define_integer_vector! {
/// Vector of 32 `u8` values
struct u8x32([u8; 32]);
}
impl_vector! { SimdU8, u8 }
define_integer_vector! {
/// Vector of 64 `u8` values
struct u8x64([u8; 64]);
}
pub type u8x8 = SimdU8<8>;
pub type u8x16 = SimdU8<16>;
pub type u8x32 = SimdU8<32>;
pub type u8x64 = SimdU8<64>;
from_transmute_x86! { unsafe u8x16 => __m128i }
from_transmute_x86! { unsafe u8x32 => __m256i }

View File

@@ -1,17 +1,14 @@
define_integer_vector! {
/// Vector of two `usize` values
struct usizex2([usize; 2]);
}
#![allow(non_camel_case_types)]
define_integer_vector! {
/// Vector of four `usize` values
struct usizex4([usize; 4]);
}
/// A SIMD vector of containing `LANES` lanes of `usize`.
#[repr(simd)]
pub struct SimdUsize<const LANES: usize>([usize; LANES]);
define_integer_vector! {
/// Vector of eight `usize` values
struct usizex8([usize; 8]);
}
impl_vector! { SimdUsize, usize }
pub type usizex2 = SimdUsize<2>;
pub type usizex4 = SimdUsize<4>;
pub type usizex8 = SimdUsize<8>;
#[cfg(target_pointer_width = "32")]
from_transmute_x86! { unsafe usizex4 => __m128i }