#![allow(unsafe_code)]
#[cfg(all(target_arch = "x86_64", feature = "simd-avx2"))]
use core::arch::x86_64::*;
#[cfg(all(target_arch = "x86_64", feature = "simd-avx2"))]
pub fn generate_syndrome_avx2(syndrome: &mut [u8], vector: &[u8], parity: &[u8]) {
unsafe {
let chunks = syndrome.len() / 32;
for i in 0..chunks {
let offset = i * 32;
let vec_chunk = _mm256_loadu_si256(vector.as_ptr().add(offset) as *const __m256i);
let parity_chunk = _mm256_loadu_si256(parity.as_ptr().add(offset) as *const __m256i);
let syndrome_chunk = compute_syndrome_chunk(vec_chunk, parity_chunk);
_mm256_storeu_si256(
syndrome.as_mut_ptr().add(offset) as *mut __m256i,
syndrome_chunk,
);
}
let remaining = syndrome.len() % 32;
if remaining > 0 {
let offset = chunks * 32;
super::super::portable::generate_syndrome_portable(
&mut syndrome[offset..],
&vector[offset..],
&parity[offset..],
);
}
}
}
#[cfg(all(target_arch = "x86_64", feature = "simd-avx2"))]
unsafe fn compute_syndrome_chunk(vector: __m256i, parity: __m256i) -> __m256i {
unsafe { _mm256_xor_si256(vector, parity) }
}
#[cfg(all(target_arch = "x86_64", feature = "simd-avx2"))]
pub fn correct_errors_avx2(corrected: &mut [u8], received: &[u8], syndrome: &[u8]) -> bool {
unsafe {
let chunks = corrected.len() / 32;
for i in 0..chunks {
let offset = i * 32;
let recv_chunk = _mm256_loadu_si256(received.as_ptr().add(offset) as *const __m256i);
let synd_chunk = _mm256_loadu_si256(syndrome.as_ptr().add(offset) as *const __m256i);
let corrected_chunk = _mm256_xor_si256(recv_chunk, synd_chunk);
_mm256_storeu_si256(
corrected.as_mut_ptr().add(offset) as *mut __m256i,
corrected_chunk,
);
}
let remaining = corrected.len() % 32;
if remaining > 0 {
let offset = chunks * 32;
for j in 0..remaining {
corrected[offset + j] = received[offset + j] ^ syndrome[offset + j];
}
}
true
}
}
#[cfg(not(all(target_arch = "x86_64", feature = "simd-avx2")))]
pub fn generate_syndrome_avx2(syndrome: &mut [u8], vector: &[u8], parity: &[u8]) {
super::super::portable::generate_syndrome_portable(syndrome, vector, parity);
}
#[cfg(not(all(target_arch = "x86_64", feature = "simd-avx2")))]
pub fn correct_errors_avx2(corrected: &mut [u8], received: &[u8], syndrome: &[u8]) -> bool {
super::super::portable::correct_errors_portable(corrected, received, syndrome)
}