• 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_OPS32_H
21 #define IXHEAACD_BASIC_OPS32_H
22 
ixheaacd_min32(WORD32 a,WORD32 b)23 static PLATFORM_INLINE WORD32 ixheaacd_min32(WORD32 a, WORD32 b) {
24   WORD32 min_val;
25 
26   min_val = (a < b) ? a : b;
27 
28   return min_val;
29 }
30 
ixheaacd_max32(WORD32 a,WORD32 b)31 static PLATFORM_INLINE WORD32 ixheaacd_max32(WORD32 a, WORD32 b) {
32   WORD32 max_val;
33 
34   max_val = (a > b) ? a : b;
35 
36   return max_val;
37 }
38 
ixheaacd_shl32(WORD32 a,WORD b)39 static PLATFORM_INLINE WORD32 ixheaacd_shl32(WORD32 a, WORD b) {
40   WORD32 out_val;
41 
42   b = ((UWORD32)(b << 24) >> 24);
43   if (b > 31)
44     out_val = 0;
45   else
46     out_val = (WORD32)a << b;
47 
48   return out_val;
49 }
50 
ixheaacd_shr32(WORD32 a,WORD b)51 static PLATFORM_INLINE WORD32 ixheaacd_shr32(WORD32 a, WORD b) {
52   WORD32 out_val;
53 
54   b = ((UWORD32)(b << 24) >> 24);
55   if (b >= 31) {
56     if (a < 0)
57       out_val = -1;
58     else
59       out_val = 0;
60   } else {
61     out_val = (WORD32)a >> b;
62   }
63 
64   return out_val;
65 }
66 
ixheaacd_shl32_sat(WORD32 a,WORD b)67 static PLATFORM_INLINE WORD32 ixheaacd_shl32_sat(WORD32 a, WORD b) {
68   WORD32 out_val;
69   if (a > (MAX_32 >> b))
70     out_val = MAX_32;
71   else if (a < (MIN_32 >> b))
72     out_val = MIN_32;
73   else
74     out_val = a << b;
75   return (out_val);
76 }
77 
ixheaacd_shl32_dir(WORD32 a,WORD b)78 static PLATFORM_INLINE WORD32 ixheaacd_shl32_dir(WORD32 a, WORD b) {
79   WORD32 out_val;
80 
81   if (b < 0) {
82     out_val = ixheaacd_shr32(a, -b);
83   } else {
84     out_val = ixheaacd_shl32(a, b);
85   }
86 
87   return out_val;
88 }
89 
ixheaacd_shl32_dir_sat(WORD32 a,WORD b)90 static PLATFORM_INLINE WORD32 ixheaacd_shl32_dir_sat(WORD32 a, WORD b) {
91   WORD32 out_val;
92 
93   if (b < 0) {
94     out_val = ixheaacd_shr32(a, -b);
95   } else {
96     out_val = ixheaacd_shl32_sat(a, b);
97   }
98 
99   return out_val;
100 }
101 
ixheaacd_shr32_dir(WORD32 a,WORD b)102 static PLATFORM_INLINE WORD32 ixheaacd_shr32_dir(WORD32 a, WORD b) {
103   WORD32 out_val;
104 
105   if (b < 0) {
106     out_val = ixheaacd_shl32(a, -b);
107   } else {
108     out_val = ixheaacd_shr32(a, b);
109   }
110 
111   return out_val;
112 }
113 
shr32_dir_sat(WORD32 a,WORD b)114 static PLATFORM_INLINE WORD32 shr32_dir_sat(WORD32 a, WORD b) {
115   WORD32 out_val;
116 
117   if (b < 0) {
118     out_val = ixheaacd_shl32_sat(a, -b);
119   } else {
120     out_val = ixheaacd_shr32(a, b);
121   }
122 
123   return out_val;
124 }
125 
ixheaacd_mult16x16in32(WORD16 a,WORD16 b)126 static PLATFORM_INLINE WORD32 ixheaacd_mult16x16in32(WORD16 a, WORD16 b) {
127   WORD32 product;
128 
129   product = (WORD32)a * (WORD32)b;
130 
131   return product;
132 }
133 
mult16x16in32_32(WORD32 a,WORD32 b)134 static PLATFORM_INLINE WORD32 mult16x16in32_32(WORD32 a, WORD32 b) {
135   WORD32 product;
136 
137   product = (WORD32)a * (WORD32)b;
138 
139   return product;
140 }
141 
ixheaacd_mult16x16in32_shl(WORD16 a,WORD16 b)142 static PLATFORM_INLINE WORD32 ixheaacd_mult16x16in32_shl(WORD16 a, WORD16 b) {
143   WORD32 product;
144 
145   product = ixheaacd_shl32(ixheaacd_mult16x16in32(a, b), 1);
146 
147   return product;
148 }
149 
ixheaacd_mult16x16in32_shl_sat(WORD16 a,WORD16 b)150 static PLATFORM_INLINE WORD32 ixheaacd_mult16x16in32_shl_sat(WORD16 a,
151                                                              WORD16 b) {
152   WORD32 product;
153   product = (WORD32)a * (WORD32)b;
154   if (product != (WORD32)0x40000000L) {
155     product = ixheaacd_shl32(product, 1);
156   } else {
157     product = MAX_32;
158   }
159   return product;
160 }
161 
ixheaacd_add32(WORD32 a,WORD32 b)162 static PLATFORM_INLINE WORD32 ixheaacd_add32(WORD32 a, WORD32 b) {
163   WORD32 sum;
164 
165   sum = (WORD32)a + (WORD32)b;
166 
167   return sum;
168 }
169 
ixheaacd_sub32(WORD32 a,WORD32 b)170 static PLATFORM_INLINE WORD32 ixheaacd_sub32(WORD32 a, WORD32 b) {
171   WORD32 diff;
172 
173   diff = (WORD32)a - (WORD32)b;
174 
175   return diff;
176 }
177 
ixheaacd_add32_sat(WORD32 a,WORD32 b)178 static PLATFORM_INLINE WORD32 ixheaacd_add32_sat(WORD32 a, WORD32 b) {
179   WORD64 sum;
180 
181   sum = (WORD64)a + (WORD64)b;
182 
183   if ((((WORD32)a ^ (WORD32)b) & (WORD32)MIN_32) == 0) {
184     if (((WORD32)sum ^ (WORD32)a) & (WORD32)MIN_32) {
185       sum = (a < 0) ? MIN_32 : MAX_32;
186     }
187   }
188 
189   return (WORD32)sum;
190 }
191 
ixheaacd_add32_sat3(WORD32 a,WORD32 b,WORD32 c)192 static PLATFORM_INLINE WORD32 ixheaacd_add32_sat3(WORD32 a, WORD32 b,
193                                                   WORD32 c) {
194   WORD64 sum;
195 
196   sum = (WORD64)a + (WORD64)b;
197 
198   sum = (WORD64)sum + (WORD64)c;
199 
200   if (sum > MAX_32) {
201     sum = MAX_32;
202   }
203   if (sum < MIN_32) {
204     sum = MIN_32;
205   }
206 
207   return (WORD32)sum;
208 }
209 
ixheaacd_sub32_sat(WORD32 a,WORD32 b)210 static PLATFORM_INLINE WORD32 ixheaacd_sub32_sat(WORD32 a, WORD32 b) {
211   WORD64 diff;
212 
213   diff = (WORD64)a - (WORD64)b;
214 
215   if ((((WORD32)a ^ (WORD32)b) & (WORD32)MIN_32) != 0) {
216     if (((WORD32)diff ^ (WORD32)a) & (WORD32)MIN_32) {
217       diff = (a < 0L) ? MIN_32 : MAX_32;
218     }
219   }
220 
221   return (WORD32)diff;
222 }
223 
ixheaacd_norm32(WORD32 a)224 static PLATFORM_INLINE WORD ixheaacd_norm32(WORD32 a) {
225   WORD norm_val;
226 
227   if (a == 0) {
228     norm_val = 31;
229   } else {
230     if (a == (WORD32)0xffffffffL) {
231       norm_val = 31;
232     } else {
233       if (a < 0) {
234         a = ~a;
235       }
236       for (norm_val = 0; a < (WORD32)0x40000000L; norm_val++) {
237         a <<= 1;
238       }
239     }
240   }
241 
242   return norm_val;
243 }
244 
ixheaacd_pnorm32(WORD32 a)245 static PLATFORM_INLINE WORD ixheaacd_pnorm32(WORD32 a) {
246   WORD norm_val;
247 
248   if (a == 0) {
249     norm_val = 31;
250   } else {
251     for (norm_val = 0; a < (WORD32)0x40000000L; norm_val++) {
252       a <<= 1;
253     }
254   }
255 
256   return norm_val;
257 }
258 
bin_expo32(WORD32 a)259 static PLATFORM_INLINE WORD bin_expo32(WORD32 a) {
260   WORD bin_expo_val;
261 
262   bin_expo_val = 31 - ixheaacd_norm32(a);
263 
264   return bin_expo_val;
265 }
266 
ixheaacd_abs32(WORD32 a)267 static PLATFORM_INLINE WORD32 ixheaacd_abs32(WORD32 a) {
268   WORD32 abs_val;
269 
270   abs_val = a;
271 
272   if (a < 0) {
273     abs_val = -a;
274   }
275 
276   return abs_val;
277 }
278 
ixheaacd_abs32_nrm(WORD32 a)279 static PLATFORM_INLINE WORD32 ixheaacd_abs32_nrm(WORD32 a) {
280   WORD32 abs_val;
281 
282   abs_val = a;
283 
284   if (a < 0) {
285     abs_val = ~a;
286   }
287 
288   return abs_val;
289 }
290 
ixheaacd_abs32_sat(WORD32 a)291 static PLATFORM_INLINE WORD32 ixheaacd_abs32_sat(WORD32 a) {
292   WORD32 abs_val;
293 
294   abs_val = a;
295 
296   if (a == MIN_32) {
297     abs_val = MAX_32;
298   } else if (a < 0) {
299     abs_val = -a;
300   }
301 
302   return abs_val;
303 }
304 
ixheaacd_negate32(WORD32 a)305 static PLATFORM_INLINE WORD32 ixheaacd_negate32(WORD32 a) {
306   WORD32 neg_val;
307 
308   neg_val = -a;
309 
310   return neg_val;
311 }
312 
ixheaacd_negate32_sat(WORD32 a)313 static PLATFORM_INLINE WORD32 ixheaacd_negate32_sat(WORD32 a) {
314   WORD32 neg_val;
315 
316   if (a == MIN_32) {
317     neg_val = MAX_32;
318   } else {
319     neg_val = -a;
320   }
321   return neg_val;
322 }
323 
div32(WORD32 a,WORD32 b,WORD * q_format)324 static PLATFORM_INLINE WORD32 div32(WORD32 a, WORD32 b, WORD *q_format) {
325   WORD32 quotient;
326   UWORD32 mantissa_nr, mantissa_dr;
327   WORD16 sign = 0;
328 
329   LOOPINDEX i;
330   WORD q_nr, q_dr;
331 
332   mantissa_nr = a;
333   mantissa_dr = b;
334   quotient = 0;
335 
336   if ((a < 0) && (0 != b)) {
337     a = -a;
338     sign = (WORD16)(sign ^ -1);
339   }
340 
341   if (b < 0) {
342     b = -b;
343     sign = (WORD16)(sign ^ -1);
344   }
345 
346   if (0 == b) {
347     *q_format = 0;
348     return (a);
349   }
350 
351   quotient = 0;
352 
353   q_nr = ixheaacd_norm32(a);
354   mantissa_nr = (UWORD32)a << (q_nr);
355   q_dr = ixheaacd_norm32(b);
356   mantissa_dr = (UWORD32)b << (q_dr);
357   *q_format = (WORD)(30 + q_nr - q_dr);
358 
359   for (i = 0; i < 31; i++) {
360     quotient = quotient << 1;
361 
362     if (mantissa_nr >= mantissa_dr) {
363       mantissa_nr = mantissa_nr - mantissa_dr;
364       quotient += 1;
365     }
366 
367     mantissa_nr = (UWORD32)mantissa_nr << 1;
368   }
369 
370   if (sign < 0) {
371     quotient = -quotient;
372   }
373 
374   return quotient;
375 }
376 
ixheaacd_mac16x16in32_sat(WORD32 a,WORD16 b,WORD16 c)377 static PLATFORM_INLINE WORD32 ixheaacd_mac16x16in32_sat(WORD32 a, WORD16 b,
378                                                         WORD16 c) {
379   WORD32 acc;
380 
381   acc = ixheaacd_mult16x16in32(b, c);
382 
383   acc = ixheaacd_add32_sat(a, acc);
384 
385   return acc;
386 }
387 
mac16x16hin32(WORD32 a,WORD32 b,WORD32 c)388 static PLATFORM_INLINE WORD32 mac16x16hin32(WORD32 a, WORD32 b, WORD32 c) {
389   WORD32 acc;
390 
391   acc = ixheaacd_mult16x16in32((WORD16)b, (WORD16)(c >> 16));
392 
393   acc = ixheaacd_add32(a, acc);
394 
395   return acc;
396 }
397 
ixheaacd_mac16x16in32_shl(WORD32 a,WORD16 b,WORD16 c)398 static PLATFORM_INLINE WORD32 ixheaacd_mac16x16in32_shl(WORD32 a, WORD16 b,
399                                                         WORD16 c) {
400   WORD32 acc;
401 
402   acc = ixheaacd_mult16x16in32_shl(b, c);
403 
404   acc = ixheaacd_add32(a, acc);
405 
406   return acc;
407 }
408 
ixheaacd_mac16x16in32_shl_sat(WORD32 a,WORD16 b,WORD16 c)409 static PLATFORM_INLINE WORD32 ixheaacd_mac16x16in32_shl_sat(WORD32 a, WORD16 b,
410                                                             WORD16 c) {
411   WORD32 acc;
412 
413   acc = ixheaacd_mult16x16in32_shl_sat(b, c);
414 
415   acc = ixheaacd_add32_sat(a, acc);
416 
417   return acc;
418 }
419 
msu16x16in32(WORD32 a,WORD16 b,WORD16 c)420 static PLATFORM_INLINE WORD32 msu16x16in32(WORD32 a, WORD16 b, WORD16 c) {
421   WORD32 acc;
422 
423   acc = ixheaacd_mult16x16in32(b, c);
424 
425   acc = ixheaacd_sub32(a, acc);
426 
427   return acc;
428 }
429 
msu16x16in32_shl(WORD32 a,WORD16 b,WORD16 c)430 static PLATFORM_INLINE WORD32 msu16x16in32_shl(WORD32 a, WORD16 b, WORD16 c) {
431   WORD32 acc;
432 
433   acc = ixheaacd_mult16x16in32_shl(b, c);
434 
435   acc = ixheaacd_sub32(a, acc);
436 
437   return acc;
438 }
439 
msu16x16in32_shl_sat(WORD32 a,WORD16 b,WORD16 c)440 static PLATFORM_INLINE WORD32 msu16x16in32_shl_sat(WORD32 a, WORD16 b,
441                                                    WORD16 c) {
442   WORD32 acc;
443 
444   acc = ixheaacd_mult16x16in32_shl_sat(b, c);
445 
446   acc = ixheaacd_sub32_sat(a, acc);
447 
448   return acc;
449 }
450 
add32_shr(WORD32 a,WORD32 b)451 static PLATFORM_INLINE WORD32 add32_shr(WORD32 a, WORD32 b) {
452   WORD32 sum;
453 
454   a = ixheaacd_shr32(a, 1);
455   b = ixheaacd_shr32(b, 1);
456 
457   sum = ixheaacd_add32(a, b);
458 
459   return sum;
460 }
461 
sub32_shr(WORD32 a,WORD32 b)462 static PLATFORM_INLINE WORD32 sub32_shr(WORD32 a, WORD32 b) {
463   WORD32 diff;
464 
465   a = ixheaacd_shr32(a, 1);
466   b = ixheaacd_shr32(b, 1);
467 
468   diff = ixheaacd_sub32(a, b);
469 
470   return diff;
471 }
472 #endif