Skip to main content

shift_left_avx2

Function shift_left_avx2 

Source
pub unsafe fn shift_left_avx2<const OR_ASSIGN: bool>(
    bits: &mut [u64],
    rhs: usize,
)
Examples found in repository?
crates/competitive/src/data_structure/bitset.rs (line 391)
366    fn shift_left<const OR_ASSIGN: bool>(&mut self, rhs: usize) {
367        if rhs == 0 {
368            return;
369        }
370        if rhs >= self.size {
371            if !OR_ASSIGN {
372                self.reset();
373            }
374            return;
375        }
376        #[cfg(target_arch = "x86_64")]
377        if self.bits.len() >= SIMD_MIN_BLOCKS {
378            if avx512_enabled()
379                && is_x86_feature_detected!("avx512f")
380                && is_x86_feature_detected!("avx512vbmi2")
381            {
382                // SAFETY: blocks are aligned and feature detection checked AVX-512F and VBMI2.
383                unsafe { simd::shift_left_avx512::<OR_ASSIGN>(&mut self.bits, rhs) };
384                if self.size & 511 != 0 {
385                    self.trim();
386                }
387                return;
388            }
389            if is_x86_feature_detected!("avx2") {
390                // SAFETY: feature detection checked AVX2 support.
391                unsafe { simd::shift_left_avx2::<OR_ASSIGN>(self.words_mut(), rhs) };
392                if self.size & 63 != 0 {
393                    self.trim();
394                }
395                return;
396            }
397        }
398
399        let bits = self.words_mut();
400        let word_shift = rhs >> 6;
401        let bit_shift = rhs & 63;
402        if bit_shift == 0 {
403            for i in (0..bits.len() - word_shift).rev() {
404                if OR_ASSIGN {
405                    bits[i + word_shift] |= bits[i];
406                } else {
407                    bits[i + word_shift] = bits[i];
408                }
409            }
410        } else {
411            for i in (1..bits.len() - word_shift).rev() {
412                let value = (bits[i] << bit_shift) | (bits[i - 1] >> (64 - bit_shift));
413                if OR_ASSIGN {
414                    bits[i + word_shift] |= value;
415                } else {
416                    bits[i + word_shift] = value;
417                }
418            }
419            if OR_ASSIGN {
420                bits[word_shift] |= bits[0] << bit_shift;
421            } else {
422                bits[word_shift] = bits[0] << bit_shift;
423            }
424        }
425        if !OR_ASSIGN {
426            bits[..word_shift].fill(0);
427        }
428        if self.size & 63 != 0 {
429            self.trim();
430        }
431    }