1#[inline]
5pub const fn clamp(x: i32, min: i32, max: i32) -> i32 {
6 if x < min {
7 min
8 } else if x > max {
9 max
10 } else {
11 x
12 }
13}
14
15#[inline]
20pub fn doubling_high_mult_no_sat(m1: i32, m2: i32) -> i32 {
21 let mult = (m1 as i64) * (m2 as i64) + (1i64 << 30);
22 (mult >> 31) as i32
23}
24
25#[inline]
29pub fn divide_by_power_of_two(dividend: i32, exponent: i32) -> i32 {
30 if exponent <= 0 {
31 return dividend;
32 }
33 if exponent >= 31 {
34 return 0;
35 }
36
37 let remainder_mask = (1i32 << exponent) - 1;
38 let remainder = remainder_mask & dividend;
39
40 let mut result = dividend >> exponent;
41 let mut threshold = remainder_mask >> 1;
42 if dividend < 0 {
43 threshold += 1;
44 }
45 if remainder > threshold {
46 result += 1;
47 }
48 result
49}
50
51#[inline]
55pub fn requantize(val: i32, multiplier: i32, shift: i32) -> i32 {
56 if shift >= 0 {
57 let val_shifted = val.wrapping_shl(shift as u32);
58 doubling_high_mult_no_sat(val_shifted, multiplier)
59 } else {
60 let right_shift = -shift;
61 let mult = doubling_high_mult_no_sat(val, multiplier);
62 divide_by_power_of_two(mult, right_shift)
63 }
64}
65
66#[inline]
70pub fn requantize_s64(val: i64, reduced_multiplier: i32, shift: i32) -> i32 {
71 let new_val = val * (reduced_multiplier as i64);
72 let shift_amt = 14 - shift;
73 let mut result = (new_val >> (shift_amt - 1)) as i32;
74 result = (result + 1) >> 1;
75 result
76}
77
78#[inline]
80pub const fn pack_s8x4_32x1(v0: i8, v1: i8, v2: i8, v3: i8) -> i32 {
81 ((v0 as u8 as i32) & 0xFF)
82 | (((v1 as u8 as i32) << 8) & 0xFF00)
83 | (((v2 as u8 as i32) << 16) & 0xFF0000)
84 | (((v3 as u8 as i32) << 24) as i32)
85}
86
87#[inline]
89pub const fn pack_q15x2_32x1(v0: i16, v1: i16) -> i32 {
90 ((v0 as u16 as i32) & 0xFFFF) | ((v1 as u16 as i32) << 16)
91}
92
93#[cfg(test)]
94mod tests {
95 use super::*;
96
97 #[test]
98 fn test_clamp() {
99 assert_eq!(clamp(10, 0, 5), 5);
100 assert_eq!(clamp(-5, 0, 5), 0);
101 assert_eq!(clamp(3, 0, 5), 3);
102 }
103
104 #[test]
105 fn test_doubling_high_mult() {
106 let res = doubling_high_mult_no_sat(1073741824, 1073741824); assert!((res - 536870912).abs() <= 1);
108 }
109
110 #[test]
111 fn test_divide_by_power_of_two() {
112 assert_eq!(divide_by_power_of_two(16, 2), 4);
113 assert_eq!(divide_by_power_of_two(18, 2), 5); }
115
116 #[test]
117 fn test_requantize() {
118 let val = 1000;
119 let mult = 1073741824; let shift = -1;
121 let res = requantize(val, mult, shift);
122 assert_eq!(res, 250);
123 }
124}