Struct vectoreyes::U64x2
source · [−]#[repr(transparent)]pub struct U64x2(_);
Expand description
[u64; 2]
as a vector.
Implementations
sourceimpl U64x2
impl U64x2
sourcepub fn carryless_mul<const HI_OTHER: bool, const HI_SELF: bool>(
&self,
other: U64x2
) -> U64x2
pub fn carryless_mul<const HI_OTHER: bool, const HI_SELF: bool>(
&self,
other: U64x2
) -> U64x2
Scalar Equivalent:
let x = if HI_SELF { self.as_array()[1] } else { self.as_array()[0] };
let y = if HI_OTHER { other.as_array()[1] } else { other.as_array()[0] };
// This software carryless-multplication implementation is from https://github.com/RustCrypto/universal-hashes/blob/2e8a948dbb25bc2ac6c712b4bdc21b158527ca70/polyval/src/backend/soft64.rs
// That code is MIT/Apache dual-licensed.
#[inline(always)]
fn bmul64(x: u64, y: u64) -> u64 {
use std::num::Wrapping;
let x0 = Wrapping(x & 0x1111_1111_1111_1111);
let x1 = Wrapping(x & 0x2222_2222_2222_2222);
let x2 = Wrapping(x & 0x4444_4444_4444_4444);
let x3 = Wrapping(x & 0x8888_8888_8888_8888);
let y0 = Wrapping(y & 0x1111_1111_1111_1111);
let y1 = Wrapping(y & 0x2222_2222_2222_2222);
let y2 = Wrapping(y & 0x4444_4444_4444_4444);
let y3 = Wrapping(y & 0x8888_8888_8888_8888);
let mut z0 = ((x0 * y0) ^ (x1 * y3) ^ (x2 * y2) ^ (x3 * y1)).0;
let mut z1 = ((x0 * y1) ^ (x1 * y0) ^ (x2 * y3) ^ (x3 * y2)).0;
let mut z2 = ((x0 * y2) ^ (x1 * y1) ^ (x2 * y0) ^ (x3 * y3)).0;
let mut z3 = ((x0 * y3) ^ (x1 * y2) ^ (x2 * y1) ^ (x3 * y0)).0;
z0 &= 0x1111_1111_1111_1111;
z1 &= 0x2222_2222_2222_2222;
z2 &= 0x4444_4444_4444_4444;
z3 &= 0x8888_8888_8888_8888;
z0 | z1 | z2 | z3
}
#[inline(always)]
fn rev64(mut x: u64) -> u64 {
x = ((x & 0x5555_5555_5555_5555) << 1) | ((x >> 1) & 0x5555_5555_5555_5555);
x = ((x & 0x3333_3333_3333_3333) << 2) | ((x >> 2) & 0x3333_3333_3333_3333);
x = ((x & 0x0f0f_0f0f_0f0f_0f0f) << 4) | ((x >> 4) & 0x0f0f_0f0f_0f0f_0f0f);
x = ((x & 0x00ff_00ff_00ff_00ff) << 8) | ((x >> 8) & 0x00ff_00ff_00ff_00ff);
x = ((x & 0xffff_0000_ffff) << 16) | ((x >> 16) & 0xffff_0000_ffff);
(x << 32) | (x >> 32)
}
U64x2::from([
bmul64(x, y),
rev64(bmul64(rev64(x), rev64(y))) >> 1,
])
Avx2
-
PCLMULQDQ xmm, xmm, imm8
Trait Implementations
sourceimpl Add<U64x2> for U64x2
impl Add<U64x2> for U64x2
sourceimpl AddAssign<U64x2> for U64x2
impl AddAssign<U64x2> for U64x2
sourcefn add_assign(&mut self, rhs: Self)
fn add_assign(&mut self, rhs: Self)
+=
operation. Read moresourceimpl BitAnd<U64x2> for U64x2
impl BitAnd<U64x2> for U64x2
sourceimpl BitAndAssign<U64x2> for U64x2
impl BitAndAssign<U64x2> for U64x2
sourcefn bitand_assign(&mut self, rhs: Self)
fn bitand_assign(&mut self, rhs: Self)
&=
operation. Read moresourceimpl BitOr<U64x2> for U64x2
impl BitOr<U64x2> for U64x2
sourceimpl BitOrAssign<U64x2> for U64x2
impl BitOrAssign<U64x2> for U64x2
sourcefn bitor_assign(&mut self, rhs: Self)
fn bitor_assign(&mut self, rhs: Self)
|=
operation. Read moresourceimpl BitXor<U64x2> for U64x2
impl BitXor<U64x2> for U64x2
sourceimpl BitXorAssign<U64x2> for U64x2
impl BitXorAssign<U64x2> for U64x2
sourcefn bitxor_assign(&mut self, rhs: Self)
fn bitxor_assign(&mut self, rhs: Self)
^=
operation. Read moresourceimpl ConditionallySelectable for U64x2
impl ConditionallySelectable for U64x2
sourcefn conditional_select(a: &Self, b: &Self, choice: Choice) -> Self
fn conditional_select(a: &Self, b: &Self, choice: Choice) -> Self
sourcefn conditional_assign(&mut self, other: &Self, choice: Choice)
fn conditional_assign(&mut self, other: &Self, choice: Choice)
sourceimpl ConstantTimeEq for U64x2
impl ConstantTimeEq for U64x2
sourceimpl ExtendingCast<U16x8> for U64x2
impl ExtendingCast<U16x8> for U64x2
sourcefn extending_cast_from(vector: U16x8) -> U64x2
fn extending_cast_from(vector: U16x8) -> U64x2
Scalar Equivalent:
U64x2::from([
u64::from(vector.as_array()[0]),
u64::from(vector.as_array()[1]),
])
Avx2
-
PMOVZXWQ xmm, xmm
sourceimpl ExtendingCast<U32x4> for U64x2
impl ExtendingCast<U32x4> for U64x2
sourcefn extending_cast_from(vector: U32x4) -> U64x2
fn extending_cast_from(vector: U32x4) -> U64x2
Scalar Equivalent:
U64x2::from([
u64::from(vector.as_array()[0]),
u64::from(vector.as_array()[1]),
])
Avx2
-
PMOVZXDQ xmm, xmm
sourceimpl ExtendingCast<U8x16> for U64x2
impl ExtendingCast<U8x16> for U64x2
sourcefn extending_cast_from(vector: U8x16) -> U64x2
fn extending_cast_from(vector: U8x16) -> U64x2
Scalar Equivalent:
U64x2::from([
u64::from(vector.as_array()[0]),
u64::from(vector.as_array()[1]),
])
Avx2
-
PMOVZXBQ xmm, xmm
sourceimpl From<U64x2> for U64x4
impl From<U64x2> for U64x4
sourcefn from(vector: U64x2) -> U64x4
fn from(vector: U64x2) -> U64x4
NOTE: this will zero the upper bits of the destination. Other intrinsics are more effcient, but leave the upper bits undefined. At present, these more effcient intrinsics are not exposed.
Scalar Equivalent:
let mut out = [0; 4];
out[0..2].copy_from_slice(&vector.as_array());
U64x4::from(out)
Avx2
sourceimpl Shl<U64x2> for U64x2
impl Shl<U64x2> for U64x2
sourceimpl Shl<u64> for U64x2
impl Shl<u64> for U64x2
sourceimpl ShlAssign<U64x2> for U64x2
impl ShlAssign<U64x2> for U64x2
sourcefn shl_assign(&mut self, amount: U64x2)
fn shl_assign(&mut self, amount: U64x2)
<<=
operation. Read moresourceimpl ShlAssign<u64> for U64x2
impl ShlAssign<u64> for U64x2
sourcefn shl_assign(&mut self, amount: u64)
fn shl_assign(&mut self, amount: u64)
<<=
operation. Read moresourceimpl Shr<U64x2> for U64x2
impl Shr<U64x2> for U64x2
sourceimpl Shr<u64> for U64x2
impl Shr<u64> for U64x2
sourceimpl ShrAssign<U64x2> for U64x2
impl ShrAssign<U64x2> for U64x2
sourcefn shr_assign(&mut self, amount: U64x2)
fn shr_assign(&mut self, amount: U64x2)
>>=
operation. Read moresourceimpl ShrAssign<u64> for U64x2
impl ShrAssign<u64> for U64x2
sourcefn shr_assign(&mut self, amount: u64)
fn shr_assign(&mut self, amount: u64)
>>=
operation. Read moresourceimpl SimdBase for U64x2
impl SimdBase for U64x2
sourcefn set_lo(scalar: u64) -> U64x2
fn set_lo(scalar: u64) -> U64x2
Scalar Equivalent:
let mut out = [0; 2];
out[0] = scalar;
U64x2::from(out)
Avx2
-
Instruction sequence.
sourcefn broadcast_lo(vector: U64x2) -> U64x2
fn broadcast_lo(vector: U64x2) -> U64x2
sourcefn cmp_eq(&self, other: U64x2) -> U64x2
fn cmp_eq(&self, other: U64x2) -> U64x2
Scalar Equivalent:
U64x2::from([
if self.as_array()[0] == other.as_array()[0] { u64::MAX } else { 0 },
if self.as_array()[1] == other.as_array()[1] { u64::MAX } else { 0 },
])
Avx2
-
PCMPEQQ xmm, xmm
sourcefn and_not(&self, other: U64x2) -> U64x2
fn and_not(&self, other: U64x2) -> U64x2
Scalar Equivalent:
U64x2::from([
self.as_array()[0] & (!other.as_array()[0]),
self.as_array()[1] & (!other.as_array()[1]),
])
Avx2
-
PANDN xmm, xmm
sourcefn cmp_gt(&self, other: U64x2) -> U64x2
fn cmp_gt(&self, other: U64x2) -> U64x2
Scalar Equivalent:
U64x2::from([
if self.as_array()[0] > other.as_array()[0] { u64::MAX } else { 0 },
if self.as_array()[1] > other.as_array()[1] { u64::MAX } else { 0 },
])
Avx2
NOTE: this implementation uses an efficient vector polyfill, though this operation is not natively supported.
// Based on https://stackoverflow.com/a/33173643 and https://git.io/JmghK
let sign_bit = Self::broadcast(1 << 63);
Self::from(I64x2::from(*self ^ sign_bit).cmp_gt(
I64x2::from(other ^ sign_bit)
))
sourcefn shift_left<const BITS: usize>(&self) -> U64x2
fn shift_left<const BITS: usize>(&self) -> U64x2
Scalar Equivalent:
let mut out = self.as_array();
for x in out.iter_mut() {
*x <<= BITS;
}
U64x2::from(out)
Avx2
-
PSLLQ xmm, imm8
sourcefn shift_right<const BITS: usize>(&self) -> U64x2
fn shift_right<const BITS: usize>(&self) -> U64x2
Scalar Equivalent:
let mut out = self.as_array();
for x in out.iter_mut() {
*x >>= BITS;
}
U64x2::from(out)
Avx2
-
PSRLQ xmm, imm8
sourcefn unpack_lo(&self, other: U64x2) -> U64x2
fn unpack_lo(&self, other: U64x2) -> U64x2
Scalar Equivalent:
U64x2::from([
// Lane# 0
self.as_array()[0],
other.as_array()[0],
])
Avx2
-
PUNPCKLQDQ xmm, xmm
sourcefn unpack_hi(&self, other: U64x2) -> U64x2
fn unpack_hi(&self, other: U64x2) -> U64x2
Scalar Equivalent:
U64x2::from([
// Lane# 0
self.as_array()[1],
other.as_array()[1],
])
Avx2
-
PUNPCKHQDQ xmm, xmm
sourcefn max(&self, other: U64x2) -> U64x2
fn max(&self, other: U64x2) -> U64x2
Scalar Equivalent:
U64x2::from([
self.as_array()[0].max(other.as_array()[0]),
self.as_array()[1].max(other.as_array()[1]),
])
Avx2
WARNING: this implementation is a polyfill which executes the scalar implemenation.
sourcefn min(&self, other: U64x2) -> U64x2
fn min(&self, other: U64x2) -> U64x2
Scalar Equivalent:
U64x2::from([
self.as_array()[0].min(other.as_array()[0]),
self.as_array()[1].min(other.as_array()[1]),
])
Avx2
WARNING: this implementation is a polyfill which executes the scalar implemenation.
const ZERO: Self = _
type BroadcastLoInput = U64x2
sourceimpl SimdBase64 for U64x2
impl SimdBase64 for U64x2
sourceimpl SimdBaseGatherable<I64x2> for U64x2
impl SimdBaseGatherable<I64x2> for U64x2
Safety
base
does not need to be aligned. Forall i
, base + indices[i]
must meet
the safety requirements of std::ptr::read_unaligned
sourceunsafe fn gather(base: *const u64, indices: I64x2) -> U64x2
unsafe fn gather(base: *const u64, indices: I64x2) -> U64x2
Scalar Equivalent:
U64x2::from([
base.offset(indices.as_array()[0] as isize).read_unaligned(),
base.offset(indices.as_array()[1] as isize).read_unaligned(),
])
Avx2
-
VPGATHERQQ xmm, vm64x, xmm
sourceunsafe fn gather_masked(
base: *const u64,
indices: I64x2,
mask: U64x2,
src: U64x2
) -> U64x2
unsafe fn gather_masked(
base: *const u64,
indices: I64x2,
mask: U64x2,
src: U64x2
) -> U64x2
Scalar Equivalent:
U64x2::from([
if (mask.as_array()[0] >> 63) == 1 {
base.offset(indices.as_array()[0] as isize).read_unaligned()
} else {
src.as_array()[0]
},
if (mask.as_array()[1] >> 63) == 1 {
base.offset(indices.as_array()[1] as isize).read_unaligned()
} else {
src.as_array()[1]
},
])
Avx2
-
VPGATHERQQ xmm, vm64x, xmm
sourceimpl SimdBaseGatherable<U64x2> for I64x2
impl SimdBaseGatherable<U64x2> for I64x2
Safety
base
does not need to be aligned. Forall i
, base + indices[i]
must meet
the safety requirements of std::ptr::read_unaligned
sourceunsafe fn gather(base: *const i64, indices: U64x2) -> I64x2
unsafe fn gather(base: *const i64, indices: U64x2) -> I64x2
Scalar Equivalent:
I64x2::from([
base.offset(indices.as_array()[0] as isize).read_unaligned(),
base.offset(indices.as_array()[1] as isize).read_unaligned(),
])
Avx2
-
VPGATHERQQ xmm, vm64x, xmm
sourceunsafe fn gather_masked(
base: *const i64,
indices: U64x2,
mask: I64x2,
src: I64x2
) -> I64x2
unsafe fn gather_masked(
base: *const i64,
indices: U64x2,
mask: I64x2,
src: I64x2
) -> I64x2
Scalar Equivalent:
I64x2::from([
if ((mask.as_array()[0] as u64) >> 63) == 1 {
base.offset(indices.as_array()[0] as isize).read_unaligned()
} else {
src.as_array()[0]
},
if ((mask.as_array()[1] as u64) >> 63) == 1 {
base.offset(indices.as_array()[1] as isize).read_unaligned()
} else {
src.as_array()[1]
},
])
Avx2
-
VPGATHERQQ xmm, vm64x, xmm
sourceimpl SimdBaseGatherable<U64x2> for U64x2
impl SimdBaseGatherable<U64x2> for U64x2
Safety
base
does not need to be aligned. Forall i
, base + indices[i]
must meet
the safety requirements of std::ptr::read_unaligned
sourceunsafe fn gather(base: *const u64, indices: U64x2) -> U64x2
unsafe fn gather(base: *const u64, indices: U64x2) -> U64x2
Scalar Equivalent:
U64x2::from([
base.offset(indices.as_array()[0] as isize).read_unaligned(),
base.offset(indices.as_array()[1] as isize).read_unaligned(),
])
Avx2
-
VPGATHERQQ xmm, vm64x, xmm
sourceunsafe fn gather_masked(
base: *const u64,
indices: U64x2,
mask: U64x2,
src: U64x2
) -> U64x2
unsafe fn gather_masked(
base: *const u64,
indices: U64x2,
mask: U64x2,
src: U64x2
) -> U64x2
Scalar Equivalent:
U64x2::from([
if (mask.as_array()[0] >> 63) == 1 {
base.offset(indices.as_array()[0] as isize).read_unaligned()
} else {
src.as_array()[0]
},
if (mask.as_array()[1] >> 63) == 1 {
base.offset(indices.as_array()[1] as isize).read_unaligned()
} else {
src.as_array()[1]
},
])
Avx2
-
VPGATHERQQ xmm, vm64x, xmm
sourceimpl Sub<U64x2> for U64x2
impl Sub<U64x2> for U64x2
sourceimpl SubAssign<U64x2> for U64x2
impl SubAssign<U64x2> for U64x2
sourcefn sub_assign(&mut self, rhs: Self)
fn sub_assign(&mut self, rhs: Self)
-=
operation. Read moreimpl Copy for U64x2
impl Eq for U64x2
impl Pod for U64x2
Auto Trait Implementations
impl RefUnwindSafe for U64x2
impl Send for U64x2
impl Sync for U64x2
impl Unpin for U64x2
impl UnwindSafe for U64x2
Blanket Implementations
sourceimpl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
const: unstable · sourcefn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
impl<T> CheckedBitPattern for Twhere
T: AnyBitPattern,
impl<T> CheckedBitPattern for Twhere
T: AnyBitPattern,
type Bits = T
type Bits = T
Self
must have the same layout as the specified Bits
except for
the possible invalid bit patterns being checked during
is_valid_bit_pattern
. Read more