use std::arch::x86_64::*;
#[target_feature(enable = "avx2")]
pub(crate) fn grad_pack_interior(cur: &[i32], prev: &[i32], out: &mut [u32], gw: usize) {
assert!(cur.len() >= gw && prev.len() >= gw && out.len() >= gw);
let zero = _mm256_setzero_si256();
let mut gx = 1usize;
while gx + 8 <= gw {
let left = unsafe { _mm256_loadu_si256(cur.as_ptr().add(gx - 1) as *const __m256i) };
let top = unsafe { _mm256_loadu_si256(prev.as_ptr().add(gx) as *const __m256i) };
let topleft = unsafe { _mm256_loadu_si256(prev.as_ptr().add(gx - 1) as *const __m256i) };
let px = unsafe { _mm256_loadu_si256(cur.as_ptr().add(gx) as *const __m256i) };
let ac = _mm256_sub_epi32(left, topleft);
let ab = _mm256_sub_epi32(left, top);
let bc = _mm256_sub_epi32(top, topleft);
let grad = _mm256_add_epi32(ac, top);
let d = _mm256_xor_si256(ab, bc);
let clamp = _mm256_blendv_epi8(left, top, _mm256_cmpgt_epi32(zero, d)); let s = _mm256_xor_si256(ac, bc);
let pred = _mm256_blendv_epi8(clamp, grad, _mm256_cmpgt_epi32(zero, s)); let res = _mm256_sub_epi32(px, pred);
let packed = _mm256_xor_si256(_mm256_slli_epi32::<1>(res), _mm256_srai_epi32::<31>(res));
unsafe { _mm256_storeu_si256(out.as_mut_ptr().add(gx) as *mut __m256i, packed) };
gx += 8;
}
while gx < gw {
let w = cur[gx - 1];
let n = prev[gx];
let nw = prev[gx - 1];
let ac = w.wrapping_sub(nw);
let bc = n.wrapping_sub(nw);
let grad = ac.wrapping_add(n);
let clamp = if (w.wrapping_sub(n) ^ bc) < 0 { n } else { w };
let pred = if (ac ^ bc) < 0 { grad } else { clamp };
let r = cur[gx].wrapping_sub(pred) as i64;
out[gx] = ((r << 1) ^ (r >> 63)) as u32;
gx += 1;
}
}