use super::*;
pub fn mac(a: S<8>, b: S<8>, c: S<32>) -> S<OUTPUT_BITS> {
let a = u32::from(U::from(a.sext::<32>())) as i32;
let b = u32::from(U::from(b.sext::<32>())) as i32;
let c = u32::from(U::from(c)) as i32;
S::from((a * b + c).into_u())
}
pub fn rounding_shift(val: S<32>, shamt: U<5>) -> S<32> {
let val = U::from(val);
let val_i32 = u32::from(val) as i32; let shamt_usize = u32::from(shamt) as usize;
let round_down_shifted = val_i32 >> u32::from(shamt);
let nonzero_shamt = shamt.any(|x| x);
let zeros = if shamt_usize < 2 {
false
} else {
let mask = (1 << (shamt_usize - 1)) - 1;
(val_i32 & mask) != 0
};
let r = (nonzero_shamt & val[shamt_usize - 1] & (zeros | val[shamt_usize])) as i32;
S::from((round_down_shifted + r).into_u())
}
pub fn clip_with_saturation<const N: usize, const M: usize>(val: S<N>) -> S<M>
where
[(); M - 1]:,
[(); (M - 1) + 1]:,
{
let val = u32::from(U::from(val)) as i32;
let sat_max = u32::from(U::from(S::<M>::signed_max())) as i32;
let sat_min = u32::from(U::from(S::<M>::signed_min().resize::<20>().sext::<32>())) as i32;
let clipped = if val > sat_max {
sat_max
} else if val < sat_min {
sat_min
} else {
val
};
S::from(clipped.into_u())
}