From eea3eadf5b5b10249c77cdc0e351f5803bd6b68b Mon Sep 17 00:00:00 2001 From: Henry de Valence Date: Thu, 14 Jun 2018 11:13:46 -0700 Subject: [PATCH] Replace special-case `swap_{AB,CD}` methods with general shuffles --- src/backend/avx2/edwards.rs | 7 +++---- src/backend/avx2/field.rs | 30 ++++-------------------------- 2 files changed, 7 insertions(+), 30 deletions(-) diff --git a/src/backend/avx2/edwards.rs b/src/backend/avx2/edwards.rs index a04c785..df446b7 100644 --- a/src/backend/avx2/edwards.rs +++ b/src/backend/avx2/edwards.rs @@ -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); diff --git a/src/backend/avx2/field.rs b/src/backend/avx2/field.rs index 082287d..ea6e6cb 100644 --- a/src/backend/avx2/field.rs +++ b/src/backend/avx2/field.rs @@ -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.