diff --git a/ext/crates/fp/src/limb.rs b/ext/crates/fp/src/limb.rs index 0a362e465..11dff98b4 100644 --- a/ext/crates/fp/src/limb.rs +++ b/ext/crates/fp/src/limb.rs @@ -1,7 +1,7 @@ use std::ops::Range; pub(crate) use crate::constants::Limb; -use crate::{constants::BITS_PER_LIMB, prime::ValidPrime}; +use crate::{constants::BITS_PER_LIMB, prime::ValidPrime, simd}; /// A struct containing the information required to access a specific entry in an array of `Limb`s. #[derive(Copy, Clone)] @@ -231,6 +231,19 @@ pub(crate) const fn add(limb_a: Limb, limb_b: Limb, coeff: u32) -> } } +/// Add (`c` times) all of the limbs in `rhs` to the limbs in `lhs`. This is optimized to use SIMD +/// when `P == 2`. +pub(crate) fn add_all(lhs: &mut [Limb], rhs: &[Limb], c: u32) { + if P == 2 { + simd::add_simd(lhs, rhs, 0); + } else { + for (left, right) in lhs.iter_mut().zip(rhs) { + *left = add::

(*left, *right, c); + *left = reduce::

(*left); + } + } +} + /// Return the `Limb` whose entries are the entries of `limb` reduced modulo `P`. /// /// Contributed by Robert Burklund. diff --git a/ext/crates/fp/src/vector/internal/mod.rs b/ext/crates/fp/src/vector/internal/mod.rs index b78c9334a..330e751e4 100644 --- a/ext/crates/fp/src/vector/internal/mod.rs +++ b/ext/crates/fp/src/vector/internal/mod.rs @@ -205,13 +205,11 @@ pub trait InternalBaseVectorMutP: InternalBaseVectorP

{ let target_inner_range = self._len().limb_range_inner(); let source_inner_range = other._len().limb_range_inner(); if !source_inner_range.is_empty() { - for (left, right) in self._limbs_mut()[target_inner_range] - .iter_mut() - .zip(&other_limbs[source_inner_range]) - { - *left = limb::add::

(*left, *right, c); - *left = limb::reduce::

(*left); - } + limb::add_all::

( + &mut self._limbs_mut()[target_inner_range], + &other_limbs[source_inner_range], + c, + ); } if source_range.len() > 1 { // The first and last limbs are distinct, so we process the last.