• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /******************************************************************************
2  *                                                                            *
3  * Copyright (C) 2018 The Android Open Source Project
4  *
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at:
8  *
9  * http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  *
17  *****************************************************************************
18  * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
19 */
20 #ifndef IXHEAACD_BASIC_OPS40_H
21 #define IXHEAACD_BASIC_OPS40_H
22 #define lo64(a) (((unsigned *)&a)[0])
23 #define hi64(a) (((WORD32 *)&a)[1])
24 
norm40(WORD40 * in)25 static PLATFORM_INLINE WORD16 norm40(WORD40 *in) {
26   WORD16 expo;
27   WORD32 tempo;
28 
29   if (0 == (*in)) return 31;
30 
31   if (((*in) <= 0x7fffffff) && ((WORD40)(*in) >= (WORD40)0xFFFFFFFF80000000)) {
32     tempo = (WORD32)(*in);
33     expo = ixheaacd_norm32(tempo);
34     *in = tempo << expo;
35 
36     return (expo);
37   }
38 
39   tempo = (WORD32)((*in) >> 31);
40   expo = 31 - (ixheaacd_norm32(tempo));
41   *in = (*in) >> expo;
42 
43   return (-expo);
44 }
45 
add32_shr40(WORD32 a,WORD32 b)46 static PLATFORM_INLINE WORD32 add32_shr40(WORD32 a, WORD32 b) {
47   WORD40 sum;
48 
49   sum = (WORD40)a + (WORD40)b;
50   sum = sum >> 1;
51 
52   return ((WORD32)sum);
53 }
54 
sub32_shr40(WORD32 a,WORD32 b)55 static PLATFORM_INLINE WORD32 sub32_shr40(WORD32 a, WORD32 b) {
56   WORD40 sum;
57 
58   sum = (WORD40)a - (WORD40)b;
59   sum = sum >> 1;
60 
61   return ((WORD32)sum);
62 }
63 
ixheaacd_mult32x16in32_shl(WORD32 a,WORD16 b)64 static PLATFORM_INLINE WORD32 ixheaacd_mult32x16in32_shl(WORD32 a, WORD16 b) {
65   WORD32 result;
66   WORD64 temp_result;
67 
68   temp_result = (WORD64)a * (WORD64)b;
69 
70   result = (WORD32)(temp_result >> 16);
71 
72   return (result << 1);
73 }
74 
mult32x16hin32_shl(WORD32 a,WORD32 b)75 static PLATFORM_INLINE WORD32 mult32x16hin32_shl(WORD32 a, WORD32 b) {
76   WORD32 product;
77   WORD64 temp_product;
78 
79   temp_product = (WORD64)a * (WORD64)(b >> 16);
80   product = (WORD32)(temp_product >> 16);
81 
82   return (product << 1);
83 }
84 
ixheaacd_mult32x16in32(WORD32 a,WORD16 b)85 static PLATFORM_INLINE WORD32 ixheaacd_mult32x16in32(WORD32 a, WORD16 b) {
86   WORD32 result;
87   WORD64 temp_result;
88 
89   temp_result = (WORD64)a * (WORD64)b;
90 
91   result = (WORD32)(temp_result >> 16);
92 
93   return (result);
94 }
95 
ixheaacd_mult32x16in32_shl_sat(WORD32 a,WORD16 b)96 static PLATFORM_INLINE WORD32 ixheaacd_mult32x16in32_shl_sat(WORD32 a,
97                                                              WORD16 b) {
98   WORD32 result;
99 
100   if (a == (WORD32)0x80000000 && b == (WORD16)0x8000) {
101     result = (WORD32)0x7fffffff;
102   } else {
103     result = ixheaacd_mult32x16in32_shl(a, b);
104   }
105 
106   return (result);
107 }
108 
ixheaacd_mult32_shl(WORD32 a,WORD32 b)109 static PLATFORM_INLINE WORD32 ixheaacd_mult32_shl(WORD32 a, WORD32 b) {
110   WORD32 result;
111   WORD64 temp_result;
112 
113   temp_result = (WORD64)a * (WORD64)b;
114   result = (WORD32)(temp_result >> 32);
115 
116   return (result << 1);
117 }
118 
ixheaacd_mult32(WORD32 a,WORD32 b)119 static PLATFORM_INLINE WORD32 ixheaacd_mult32(WORD32 a, WORD32 b) {
120   WORD32 result;
121   WORD64 temp_result;
122 
123   temp_result = (WORD64)a * (WORD64)b;
124   result = (WORD32)(temp_result >> 32);
125 
126   return (result);
127 }
128 
ixheaacd_mult32_shl_sat(WORD32 a,WORD32 b)129 static PLATFORM_INLINE WORD32 ixheaacd_mult32_shl_sat(WORD32 a, WORD32 b) {
130   WORD32 result;
131 
132   if (a == (WORD32)0x80000000 && b == (WORD32)0x80000000) {
133     result = 0x7fffffff;
134   } else {
135     result = ixheaacd_mult32_shl(a, b);
136   }
137 
138   return (result);
139 }
140 
ixheaacd_mac32x16in32(WORD32 a,WORD32 b,WORD16 c)141 static PLATFORM_INLINE WORD32 ixheaacd_mac32x16in32(WORD32 a, WORD32 b,
142                                                     WORD16 c) {
143   WORD32 result;
144 
145   result = a + ixheaacd_mult32x16in32(b, c);
146 
147   return (result);
148 }
149 
ixheaacd_mac32x16in32_shl(WORD32 a,WORD32 b,WORD16 c)150 static PLATFORM_INLINE WORD32 ixheaacd_mac32x16in32_shl(WORD32 a, WORD32 b,
151                                                         WORD16 c) {
152   WORD32 result;
153 
154   result = a + ixheaacd_mult32x16in32_shl(b, c);
155 
156   return (result);
157 }
158 
ixheaacd_mac32x16in32_shl_sat(WORD32 a,WORD32 b,WORD16 c)159 static PLATFORM_INLINE WORD32 ixheaacd_mac32x16in32_shl_sat(WORD32 a, WORD32 b,
160                                                             WORD16 c) {
161   return (ixheaacd_add32_sat(a, ixheaacd_mult32x16in32_shl_sat(b, c)));
162 }
163 
ixheaacd_mac32(WORD32 a,WORD32 b,WORD32 c)164 static PLATFORM_INLINE WORD32 ixheaacd_mac32(WORD32 a, WORD32 b, WORD32 c) {
165   WORD32 result;
166 
167   result = a + ixheaacd_mult32(b, c);
168 
169   return (result);
170 }
171 
mac32_shl(WORD32 a,WORD32 b,WORD32 c)172 static PLATFORM_INLINE WORD32 mac32_shl(WORD32 a, WORD32 b, WORD32 c) {
173   WORD32 result;
174 
175   result = a + ixheaacd_mult32_shl(b, c);
176 
177   return (result);
178 }
179 
mac32_shl_sat(WORD32 a,WORD32 b,WORD32 c)180 static PLATFORM_INLINE WORD32 mac32_shl_sat(WORD32 a, WORD32 b, WORD32 c) {
181   return (ixheaacd_add32_sat(a, ixheaacd_mult32_shl_sat(b, c)));
182 }
183 
msu32x16in32(WORD32 a,WORD32 b,WORD16 c)184 static PLATFORM_INLINE WORD32 msu32x16in32(WORD32 a, WORD32 b, WORD16 c) {
185   WORD32 result;
186 
187   result = a - ixheaacd_mult32x16in32(b, c);
188 
189   return (result);
190 }
191 
msu32x16in32_shl(WORD32 a,WORD32 b,WORD16 c)192 static PLATFORM_INLINE WORD32 msu32x16in32_shl(WORD32 a, WORD32 b, WORD16 c) {
193   WORD32 result;
194 
195   result = a - ixheaacd_mult32x16in32_shl(b, c);
196 
197   return (result);
198 }
199 
msu32x16in32_shl_sat(WORD32 a,WORD32 b,WORD16 c)200 static PLATFORM_INLINE WORD32 msu32x16in32_shl_sat(WORD32 a, WORD32 b,
201                                                    WORD16 c) {
202   return (ixheaacd_sub32_sat(a, ixheaacd_mult32x16in32_shl_sat(b, c)));
203 }
204 
msu32(WORD32 a,WORD32 b,WORD32 c)205 static PLATFORM_INLINE WORD32 msu32(WORD32 a, WORD32 b, WORD32 c) {
206   WORD32 result;
207 
208   result = a - ixheaacd_mult32(b, c);
209 
210   return (result);
211 }
212 
msu32_shl(WORD32 a,WORD32 b,WORD32 c)213 static PLATFORM_INLINE WORD32 msu32_shl(WORD32 a, WORD32 b, WORD32 c) {
214   WORD32 result;
215 
216   result = a - ixheaacd_mult32_shl(b, c);
217 
218   return (result);
219 }
220 
msu32_shl_sat(WORD32 a,WORD32 b,WORD32 c)221 static PLATFORM_INLINE WORD32 msu32_shl_sat(WORD32 a, WORD32 b, WORD32 c) {
222   return (ixheaacd_sub32_sat(a, ixheaacd_mult32_shl_sat(b, c)));
223 }
224 
mac3216_arr40(WORD32 * x,WORD16 * y,LOOPINDEX length,WORD16 * q_val)225 static PLATFORM_INLINE WORD32 mac3216_arr40(WORD32 *x, WORD16 *y,
226                                             LOOPINDEX length, WORD16 *q_val) {
227   LOOPINDEX i;
228   WORD40 sum = 0;
229 
230   for (i = 0; i < length; i++) {
231     sum += (WORD40)(ixheaacd_mult32x16in32(x[i], y[i]));
232   }
233 
234   *q_val = norm40(&sum);
235 
236   return (WORD32)sum;
237 }
238 
mac32_arr40(WORD32 * x,WORD32 * y,LOOPINDEX length,WORD16 * q_val)239 static PLATFORM_INLINE WORD32 mac32_arr40(WORD32 *x, WORD32 *y,
240                                           LOOPINDEX length, WORD16 *q_val) {
241   LOOPINDEX i;
242   WORD40 sum = 0;
243 
244   for (i = 0; i < length; i++) {
245     sum += (WORD40)(ixheaacd_mult32(x[i], y[i]));
246   }
247 
248   *q_val = norm40(&sum);
249 
250   return ((WORD32)sum);
251 }
252 
mac16_arr40(WORD16 * x,WORD16 * y,LOOPINDEX length,WORD16 * q_val)253 static PLATFORM_INLINE WORD32 mac16_arr40(WORD16 *x, WORD16 *y,
254                                           LOOPINDEX length, WORD16 *q_val) {
255   LOOPINDEX i;
256   WORD40 sum = 0;
257 
258   for (i = 0; i < length; i++) {
259     sum += (WORD40)((WORD32)x[i] * (WORD32)y[i]);
260   }
261 
262   *q_val = norm40(&sum);
263 
264   return ((WORD32)sum);
265 }
266 
add32_arr40(WORD32 * in_arr,LOOPINDEX length,WORD16 * q_val)267 static PLATFORM_INLINE WORD32 add32_arr40(WORD32 *in_arr, LOOPINDEX length,
268                                           WORD16 *q_val) {
269   LOOPINDEX i;
270   WORD40 sum = 0;
271 
272   for (i = 0; i < length; i++) {
273     sum += (WORD40)in_arr[i];
274   }
275 
276   *q_val = norm40(&sum);
277 
278   return ((WORD32)sum);
279 }
280 
ixheaacd_mult32x32in64(WORD32 a,WORD32 b)281 static PLATFORM_INLINE WORD64 ixheaacd_mult32x32in64(WORD32 a, WORD32 b) {
282   WORD64 result;
283 
284   result = (WORD64)a * (WORD64)b;
285 
286   return (result);
287 }
288 
ixheaacd_mac32x32in64(WORD64 sum,WORD32 a,WORD32 b)289 static PLATFORM_INLINE WORD64 ixheaacd_mac32x32in64(WORD64 sum, WORD32 a,
290                                                     WORD32 b) {
291   sum += (WORD64)a * (WORD64)b;
292 
293   return (sum);
294 }
295 
ixheaacd_mac32x32in64_7(const WORD32 * a,const WORD16 * b)296 static PLATFORM_INLINE WORD64 ixheaacd_mac32x32in64_7(const WORD32 *a,
297                                                       const WORD16 *b) {
298   WORD64 sum;
299   sum = (WORD64)a[0] * (WORD64)b[0];
300   sum += (WORD64)a[1] * (WORD64)b[1];
301   sum += (WORD64)a[2] * (WORD64)b[2];
302   sum += (WORD64)a[3] * (WORD64)b[3];
303   sum += (WORD64)a[4] * (WORD64)b[4];
304   sum += (WORD64)a[5] * (WORD64)b[5];
305   sum += (WORD64)a[6] * (WORD64)b[6];
306 
307   return (sum);
308 }
309 
ixheaacd_mac32x32in64_n(WORD64 sum,const WORD32 * a,const WORD16 * b,WORD32 n)310 static PLATFORM_INLINE WORD64 ixheaacd_mac32x32in64_n(WORD64 sum,
311                                                       const WORD32 *a,
312                                                       const WORD16 *b,
313                                                       WORD32 n) {
314   WORD32 k;
315 
316   sum += (WORD64)a[0] * (WORD64)b[0];
317   for (k = 1; k < n; k++) sum += (WORD64)a[k] * (WORD64)b[k];
318   return (sum);
319 }
320 
ixheaacd_mult64(WORD32 a,WORD32 b)321 static PLATFORM_INLINE WORD64 ixheaacd_mult64(WORD32 a, WORD32 b) {
322   WORD64 result;
323   result = (WORD64)a * (WORD64)b;
324   return (result);
325 }
326 
ixheaacd_mult64_sat(WORD64 a,WORD64 b)327 static PLATFORM_INLINE WORD64 ixheaacd_mult64_sat(WORD64 a, WORD64 b) {
328   WORD64 result;
329 
330   if (a > 0 && b > 0 && a > MAX_64 / b) return MAX_64;
331   if (a < 0 && b > 0 && a < MIN_64 / b) return MIN_64;
332   if (a > 0 && b < 0 && b < MIN_64 / a) return MIN_64;
333   if (a < 0 && b < 0 && a < MAX_64 / b) return MAX_64;
334 
335   result = a * b;
336   return (result);
337 }
338 
ixheaacd_add64_sat(WORD64 a,WORD64 b)339 static PLATFORM_INLINE WORD64 ixheaacd_add64_sat(WORD64 a, WORD64 b) {
340   WORD64 result, comp;
341   result = (a < 0) ? MIN_64 : MAX_64;
342   comp = result - a;
343   if ((a < 0) == (b > comp)) result = a + b;
344 
345   return (result);
346 }
347 
ixheaacd_sat64_32(WORD64 a)348 static PLATFORM_INLINE WORD32 ixheaacd_sat64_32(WORD64 a) {
349   WORD32 result;
350   if (a >= MAX_32) {
351     result = MAX_32;
352   } else if (a <= MIN_32) {
353     result = MIN_32;
354   } else
355     result = (WORD32)a;
356 
357   return (result);
358 }
359 
ixheaacd_add64(WORD64 a,WORD64 b)360 static PLATFORM_INLINE WORD64 ixheaacd_add64(WORD64 a, WORD64 b) {
361   WORD64 result;
362   result = a + b;
363   return (result);
364 }
365 
ixheaacd_sub64(WORD64 a,WORD64 b)366 static PLATFORM_INLINE WORD64 ixheaacd_sub64(WORD64 a, WORD64 b) {
367   WORD64 diff;
368 
369   diff = (WORD64)a - (WORD64)b;
370 
371   return diff;
372 }
373 
ixheaacd_sub64_sat(WORD64 a,WORD64 b)374 static PLATFORM_INLINE WORD64 ixheaacd_sub64_sat(WORD64 a, WORD64 b) {
375   WORD64 diff;
376 
377   diff = ixheaacd_sub64(a, b);
378 
379   if ((((WORD64)a ^ (WORD64)b) & (WORD64)MIN_64) != 0) {
380     if (((WORD64)diff ^ (WORD64)a) & (WORD64)MIN_64) {
381       diff = (a < 0L) ? MIN_64 : MAX_64;
382     }
383   }
384 
385   return (diff);
386 }
387 
ixheaacd_mul32_sh(WORD32 a,WORD32 b,WORD8 shift)388 static PLATFORM_INLINE WORD32 ixheaacd_mul32_sh(WORD32 a, WORD32 b,
389                                                 WORD8 shift) {
390   WORD32 result;
391   WORD64 temp_result;
392 
393   temp_result = (WORD64)a * (WORD64)b;
394   result = (WORD32)(temp_result >> shift);
395 
396   return (result);
397 }
398 
399 #endif
400