Replace special-case swap_{AB,CD} methods with general shuffles

This commit is contained in:
Henry de Valence 2018-06-14 11:13:46 -07:00
parent 02296fafb5
commit eea3eadf5b
2 changed files with 7 additions and 30 deletions

View file

@ -177,9 +177,8 @@ impl<'a> Neg for &'a CachedPoint {
type Output = CachedPoint;
fn neg(self) -> CachedPoint {
let mut coords = self.0;
coords.swap_AB();
CachedPoint(coords.blend(coords.negate_lazy(), Lanes::D))
let swapped = self.0.shuffle(Shuffle::BACD);
CachedPoint(swapped.blend(swapped.negate_lazy(), Lanes::D))
}
}
@ -197,7 +196,7 @@ impl<'a, 'b> Add<&'b CachedPoint> for &'a ExtendedPoint {
tmp = &tmp * &other.0;
// tmp = (S8 S9 S11 S10)
tmp.swap_CD();
tmp = tmp.shuffle(Shuffle::ABDC);
// tmp = (S9-S8 S9+S8 S10-S11 S10+S11) = (S12 S13 S14 S15)
tmp.diff_sum(Lanes::ABCD);

View file

@ -106,6 +106,8 @@ pub enum Shuffle {
CBCB,
ABAB,
BADC,
BACD,
ABDC,
}
/// A vector of four `FieldElements`, implemented using AVX2.
@ -174,6 +176,8 @@ impl FieldElement32x4 {
Shuffle::CBCB => u32x8::new(4, 1, 6, 3, 4, 1, 6, 3),
Shuffle::ABAB => u32x8::new(0, 1, 2, 3, 0, 1, 2, 3),
Shuffle::BADC => u32x8::new(1, 0, 3, 2, 5, 4, 7, 6),
Shuffle::BACD => u32x8::new(1, 0, 3, 2, 4, 5, 6, 7),
Shuffle::ABDC => u32x8::new(0, 1, 2, 3, 5, 4, 7, 6),
};
// Note that this gets turned into a generic LLVM
// shuffle-by-constants, which can be lowered to a simpler
@ -241,32 +245,6 @@ impl FieldElement32x4 {
])
}
/// Given `self = (A,B,C,D)`, set `self = (B,A,C,D)`
pub fn swap_AB(&mut self) {
unsafe {
use core::arch::x86_64::_mm256_blend_epi32;
use core::arch::x86_64::_mm256_shuffle_epi32;
for i in 0..5 {
let swapped = _mm256_shuffle_epi32(self.0[i].into_bits(), 0b10_11_00_01);
self.0[i] =
_mm256_blend_epi32(self.0[i].into_bits(), swapped, 0b00001111).into_bits();
}
}
}
/// Given `self = (A,B,C,D)`, set `self = (A,B,D,C)`
pub fn swap_CD(&mut self) {
unsafe {
use core::arch::x86_64::_mm256_blend_epi32;
use core::arch::x86_64::_mm256_shuffle_epi32;
for i in 0..5 {
let swapped = _mm256_shuffle_epi32(self.0[i].into_bits(), 0b10_11_00_01);
self.0[i] =
_mm256_blend_epi32(self.0[i].into_bits(), swapped, 0b11110000).into_bits();
}
}
}
/// Given `self = (A,B,C,D)`, set `self = (B - A, B + A, D - C, D + C)` according to `mask`.
///
/// This is `#[inline(always)]` because the `mask` parameter should be an immediate.