brotli/enc/
compat.rs

1#![cfg_attr(feature = "simd", allow(unused))]
2use core::ops::{Add, AddAssign, BitAnd, Index, IndexMut, Mul, Shr, Sub};
3
4#[derive(Default, Copy, Clone, Debug)]
5pub struct Compat16x16([i16; 16]);
6impl Compat16x16 {
7    #[inline(always)]
8    pub fn splat(a: i16) -> Compat16x16 {
9        Compat16x16([a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a])
10    }
11    #[inline(always)]
12    pub fn to_int(&self) -> Self {
13        *self
14    }
15    #[inline(always)]
16    pub fn simd_gt(&self, rhs: Compat16x16) -> Compat16x16 {
17        Self([
18            -((self[0] > rhs[0]) as i16),
19            -((self[1] > rhs[1]) as i16),
20            -((self[2] > rhs[2]) as i16),
21            -((self[3] > rhs[3]) as i16),
22            -((self[4] > rhs[4]) as i16),
23            -((self[5] > rhs[5]) as i16),
24            -((self[6] > rhs[6]) as i16),
25            -((self[7] > rhs[7]) as i16),
26            -((self[8] > rhs[8]) as i16),
27            -((self[9] > rhs[9]) as i16),
28            -((self[10] > rhs[10]) as i16),
29            -((self[11] > rhs[11]) as i16),
30            -((self[12] > rhs[12]) as i16),
31            -((self[13] > rhs[13]) as i16),
32            -((self[14] > rhs[14]) as i16),
33            -((self[15] > rhs[15]) as i16),
34        ])
35    }
36}
37
38macro_rules! op16 {
39    ($a: expr, $b: expr, $op: expr) => {
40        Compat16x16([
41            $op($a[0], $b[0]),
42            $op($a[1], $b[1]),
43            $op($a[2], $b[2]),
44            $op($a[3], $b[3]),
45            $op($a[4], $b[4]),
46            $op($a[5], $b[5]),
47            $op($a[6], $b[6]),
48            $op($a[7], $b[7]),
49            $op($a[8], $b[8]),
50            $op($a[9], $b[9]),
51            $op($a[10], $b[10]),
52            $op($a[11], $b[11]),
53            $op($a[12], $b[12]),
54            $op($a[13], $b[13]),
55            $op($a[14], $b[14]),
56            $op($a[15], $b[15]),
57        ])
58    };
59}
60macro_rules! scalar_op16 {
61    ($a: expr, $b: expr, $op: expr) => {
62        Compat16x16([
63            $op($a[0], $b),
64            $op($a[1], $b),
65            $op($a[2], $b),
66            $op($a[3], $b),
67            $op($a[4], $b),
68            $op($a[5], $b),
69            $op($a[6], $b),
70            $op($a[7], $b),
71            $op($a[8], $b),
72            $op($a[9], $b),
73            $op($a[10], $b),
74            $op($a[11], $b),
75            $op($a[12], $b),
76            $op($a[13], $b),
77            $op($a[14], $b),
78            $op($a[15], $b),
79        ])
80    };
81}
82#[inline(always)]
83fn wrapping_i16_add(a: i16, b: i16) -> i16 {
84    a.wrapping_add(b)
85}
86#[inline(always)]
87fn wrapping_i16_sub(a: i16, b: i16) -> i16 {
88    a.wrapping_sub(b)
89}
90#[inline(always)]
91fn i16_bitand(a: i16, b: i16) -> i16 {
92    a & b
93}
94#[inline(always)]
95fn shift16<Scalar>(a: i16, b: Scalar) -> i16
96where
97    i64: From<Scalar>,
98{
99    a >> i64::from(b)
100}
101impl Add for Compat16x16 {
102    type Output = Compat16x16;
103    #[inline(always)]
104    fn add(self, other: Compat16x16) -> Compat16x16 {
105        op16!(self.0, other.0, wrapping_i16_add)
106    }
107}
108impl Sub for Compat16x16 {
109    type Output = Compat16x16;
110    #[inline(always)]
111    fn sub(self, other: Compat16x16) -> Compat16x16 {
112        op16!(self.0, other.0, wrapping_i16_sub)
113    }
114}
115impl BitAnd for Compat16x16 {
116    type Output = Compat16x16;
117    #[inline(always)]
118    fn bitand(self, other: Compat16x16) -> Compat16x16 {
119        op16!(self.0, other.0, i16_bitand)
120    }
121}
122impl From<[i16; 16]> for Compat16x16 {
123    fn from(value: [i16; 16]) -> Self {
124        Self(value)
125    }
126}
127impl<I> Index<I> for Compat16x16
128where
129    I: core::slice::SliceIndex<[i16]>,
130{
131    type Output = I::Output;
132
133    fn index(&self, index: I) -> &Self::Output {
134        &self.0[index]
135    }
136}
137impl<I> IndexMut<I> for Compat16x16
138where
139    I: core::slice::SliceIndex<[i16]>,
140{
141    fn index_mut(&mut self, index: I) -> &mut Self::Output {
142        &mut self.0[index]
143    }
144}
145impl<Scalar: Clone> Shr<Scalar> for Compat16x16
146where
147    i64: From<Scalar>,
148{
149    type Output = Compat16x16;
150    #[inline(always)]
151    fn shr(self, other: Scalar) -> Compat16x16 {
152        scalar_op16!(self.0, other.clone(), shift16)
153    }
154}
155
156#[derive(Default, Copy, Clone, Debug)]
157pub struct Compat32x8([i32; 8]);
158impl Compat32x8 {
159    #[inline(always)]
160    pub fn splat(a: i32) -> Compat32x8 {
161        Compat32x8([a, a, a, a, a, a, a, a])
162    }
163    #[inline(always)]
164    pub fn simd_gt(&self, rhs: Compat32x8) -> Compat32x8 {
165        Self([
166            -((self[0] > rhs[0]) as i32),
167            -((self[1] > rhs[1]) as i32),
168            -((self[2] > rhs[2]) as i32),
169            -((self[3] > rhs[3]) as i32),
170            -((self[4] > rhs[4]) as i32),
171            -((self[5] > rhs[5]) as i32),
172            -((self[6] > rhs[6]) as i32),
173            -((self[7] > rhs[7]) as i32),
174        ])
175    }
176    #[inline(always)]
177    pub fn simd_ge(&self, rhs: Compat32x8) -> Compat32x8 {
178        Self([
179            -((self[0] >= rhs[0]) as i32),
180            -((self[1] >= rhs[1]) as i32),
181            -((self[2] >= rhs[2]) as i32),
182            -((self[3] >= rhs[3]) as i32),
183            -((self[4] >= rhs[4]) as i32),
184            -((self[5] >= rhs[5]) as i32),
185            -((self[6] >= rhs[6]) as i32),
186            -((self[7] >= rhs[7]) as i32),
187        ])
188    }
189    pub fn to_int(&self) -> Self {
190        *self
191    }
192}
193
194#[inline(always)]
195fn fmin(a: f32, b: f32) -> f32 {
196    if a < b {
197        a
198    } else {
199        b
200    }
201}
202#[derive(Default, Copy, Clone, Debug)]
203pub struct CompatF8([f32; 8]);
204impl CompatF8 {
205    #[inline(always)]
206    pub fn splat(a: f32) -> CompatF8 {
207        CompatF8([a, a, a, a, a, a, a, a])
208    }
209    #[inline(always)]
210    pub fn simd_ge(&self, rhs: CompatF8) -> Compat32x8 {
211        Compat32x8([
212            -((self[0] >= rhs[0]) as i32),
213            -((self[1] >= rhs[1]) as i32),
214            -((self[2] >= rhs[2]) as i32),
215            -((self[3] >= rhs[3]) as i32),
216            -((self[4] >= rhs[4]) as i32),
217            -((self[5] >= rhs[5]) as i32),
218            -((self[6] >= rhs[6]) as i32),
219            -((self[7] >= rhs[7]) as i32),
220        ])
221    }
222    #[inline(always)]
223    pub fn simd_min(&self, rhs: CompatF8) -> CompatF8 {
224        Self([
225            fmin(self[0], rhs[0]),
226            fmin(self[1], rhs[1]),
227            fmin(self[2], rhs[2]),
228            fmin(self[3], rhs[3]),
229            fmin(self[4], rhs[4]),
230            fmin(self[5], rhs[5]),
231            fmin(self[6], rhs[6]),
232            fmin(self[7], rhs[7]),
233        ])
234    }
235}
236impl Add for Compat32x8 {
237    type Output = Compat32x8;
238    #[inline(always)]
239    fn add(self, other: Compat32x8) -> Compat32x8 {
240        Compat32x8([
241            self.0[0].wrapping_add(other.0[0]),
242            self.0[1].wrapping_add(other.0[1]),
243            self.0[2].wrapping_add(other.0[2]),
244            self.0[3].wrapping_add(other.0[3]),
245            self.0[4].wrapping_add(other.0[4]),
246            self.0[5].wrapping_add(other.0[5]),
247            self.0[6].wrapping_add(other.0[6]),
248            self.0[7].wrapping_add(other.0[7]),
249        ])
250    }
251}
252
253impl BitAnd for Compat32x8 {
254    type Output = Compat32x8;
255    #[inline(always)]
256    fn bitand(self, other: Compat32x8) -> Compat32x8 {
257        Compat32x8([
258            self.0[0] & other.0[0],
259            self.0[1] & other.0[1],
260            self.0[2] & other.0[2],
261            self.0[3] & other.0[3],
262            self.0[4] & other.0[4],
263            self.0[5] & other.0[5],
264            self.0[6] & other.0[6],
265            self.0[7] & other.0[7],
266        ])
267    }
268}
269impl Mul for Compat32x8 {
270    type Output = Compat32x8;
271    #[inline(always)]
272    fn mul(self, other: Compat32x8) -> Compat32x8 {
273        Compat32x8([
274            self.0[0].wrapping_mul(other.0[0]),
275            self.0[1].wrapping_mul(other.0[1]),
276            self.0[2].wrapping_mul(other.0[2]),
277            self.0[3].wrapping_mul(other.0[3]),
278            self.0[4].wrapping_mul(other.0[4]),
279            self.0[5].wrapping_mul(other.0[5]),
280            self.0[6].wrapping_mul(other.0[6]),
281            self.0[7].wrapping_mul(other.0[7]),
282        ])
283    }
284}
285impl From<[i32; 8]> for Compat32x8 {
286    fn from(value: [i32; 8]) -> Self {
287        Self(value)
288    }
289}
290impl<I> Index<I> for Compat32x8
291where
292    I: core::slice::SliceIndex<[i32]>,
293{
294    type Output = I::Output;
295
296    fn index(&self, index: I) -> &Self::Output {
297        &self.0[index]
298    }
299}
300impl<I> IndexMut<I> for Compat32x8
301where
302    I: core::slice::SliceIndex<[i32]>,
303{
304    fn index_mut(&mut self, index: I) -> &mut Self::Output {
305        &mut self.0[index]
306    }
307}
308impl Add for CompatF8 {
309    type Output = CompatF8;
310    #[inline(always)]
311    fn add(self, other: CompatF8) -> CompatF8 {
312        CompatF8([
313            self.0[0] + other.0[0],
314            self.0[1] + other.0[1],
315            self.0[2] + other.0[2],
316            self.0[3] + other.0[3],
317            self.0[4] + other.0[4],
318            self.0[5] + other.0[5],
319            self.0[6] + other.0[6],
320            self.0[7] + other.0[7],
321        ])
322    }
323}
324impl Sub for CompatF8 {
325    type Output = CompatF8;
326    #[inline(always)]
327    fn sub(self, other: CompatF8) -> CompatF8 {
328        CompatF8([
329            self.0[0] - other.0[0],
330            self.0[1] - other.0[1],
331            self.0[2] - other.0[2],
332            self.0[3] - other.0[3],
333            self.0[4] - other.0[4],
334            self.0[5] - other.0[5],
335            self.0[6] - other.0[6],
336            self.0[7] - other.0[7],
337        ])
338    }
339}
340impl Mul for CompatF8 {
341    type Output = CompatF8;
342    #[inline(always)]
343    fn mul(self, other: CompatF8) -> CompatF8 {
344        CompatF8([
345            self.0[0] * other.0[0],
346            self.0[1] * other.0[1],
347            self.0[2] * other.0[2],
348            self.0[3] * other.0[3],
349            self.0[4] * other.0[4],
350            self.0[5] * other.0[5],
351            self.0[6] * other.0[6],
352            self.0[7] * other.0[7],
353        ])
354    }
355}
356impl AddAssign for CompatF8 {
357    #[inline(always)]
358    fn add_assign(&mut self, other: CompatF8) {
359        self.0[0] += other.0[0];
360        self.0[1] += other.0[1];
361        self.0[2] += other.0[2];
362        self.0[3] += other.0[3];
363        self.0[4] += other.0[4];
364        self.0[5] += other.0[5];
365        self.0[6] += other.0[6];
366        self.0[7] += other.0[7];
367    }
368}
369impl From<[f32; 8]> for CompatF8 {
370    fn from(value: [f32; 8]) -> Self {
371        Self(value)
372    }
373}
374impl<I> Index<I> for CompatF8
375where
376    I: core::slice::SliceIndex<[f32]>,
377{
378    type Output = I::Output;
379
380    fn index(&self, index: I) -> &Self::Output {
381        &self.0[index]
382    }
383}
384impl<I> IndexMut<I> for CompatF8
385where
386    I: core::slice::SliceIndex<[f32]>,
387{
388    fn index_mut(&mut self, index: I) -> &mut Self::Output {
389        &mut self.0[index]
390    }
391}