brotli/enc/
compat.rs

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