use std::arch::aarch64::*;
#[target_feature(enable = "neon")]
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 = vdupq_n_s32(0);
let mut gx = 1usize;
while gx + 4 <= gw {
let left = unsafe { vld1q_s32(cur.as_ptr().add(gx - 1)) };
let top = unsafe { vld1q_s32(prev.as_ptr().add(gx)) };
let topleft = unsafe { vld1q_s32(prev.as_ptr().add(gx - 1)) };
let px = unsafe { vld1q_s32(cur.as_ptr().add(gx)) };
let ac = vsubq_s32(left, topleft);
let ab = vsubq_s32(left, top);
let bc = vsubq_s32(top, topleft);
let grad = vaddq_s32(ac, top);
let d = veorq_s32(ab, bc);
let clamp = vbslq_s32(vcltq_s32(d, zero), top, left); let s = veorq_s32(ac, bc);
let pred = vbslq_s32(vcltq_s32(s, zero), grad, clamp); let res = vsubq_s32(px, pred);
let packed = veorq_s32(vshlq_n_s32::<1>(res), vshrq_n_s32::<31>(res));
unsafe { vst1q_u32(out.as_mut_ptr().add(gx), vreinterpretq_u32_s32(packed)) };
gx += 4;
}
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;
}
}