• 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 
ixheaacd_shr32_dir_sat(WORD32 a,WORD b)114 static PLATFORM_INLINE WORD32 ixheaacd_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 
ixheaacd_mult32x16hin32(WORD32 a,WORD32 b)134 static PLATFORM_INLINE WORD32 ixheaacd_mult32x16hin32(WORD32 a, WORD32 b) {
135   WORD32 result;
136   WORD64 temp_result;
137 
138   temp_result = (WORD64)(a) * (WORD64)(b >> 16);
139   result = (WORD32)(temp_result >> 16);
140 
141   return (result);
142 }
143 
ixheaacd_mult32x16in32_sat(WORD32 a,WORD16 b)144 static PLATFORM_INLINE WORD32 ixheaacd_mult32x16in32_sat(WORD32 a, WORD16 b) {
145   WORD32 result;
146   WORD64 temp_result;
147 
148   temp_result = (WORD64)a * (WORD64)b;
149 
150   if (temp_result < (WORD64)MIN_32)
151     result = MIN_32;
152 
153   else if (temp_result > (WORD64)MAX_32)
154     result = MAX_32;
155 
156   else
157     result = (WORD32)(temp_result);
158 
159   return(result);
160 }
161 
ixheaacd_mult16x16in32_shl(WORD16 a,WORD16 b)162 static PLATFORM_INLINE WORD32 ixheaacd_mult16x16in32_shl(WORD16 a, WORD16 b) {
163   WORD32 product;
164 
165   product = ixheaacd_shl32(ixheaacd_mult16x16in32(a, b), 1);
166 
167   return product;
168 }
169 
ixheaacd_mult16x16in32_shl_sat(WORD16 a,WORD16 b)170 static PLATFORM_INLINE WORD32 ixheaacd_mult16x16in32_shl_sat(WORD16 a,
171                                                              WORD16 b) {
172   WORD32 product;
173   product = (WORD32)a * (WORD32)b;
174   if (product != (WORD32)0x40000000L) {
175     product = ixheaacd_shl32(product, 1);
176   } else {
177     product = MAX_32;
178   }
179   return product;
180 }
181 
ixheaacd_add32(WORD32 a,WORD32 b)182 static PLATFORM_INLINE WORD32 ixheaacd_add32(WORD32 a, WORD32 b) {
183   WORD32 sum;
184 
185   sum = (WORD32)a + (WORD32)b;
186 
187   return sum;
188 }
189 
ixheaacd_sub32(WORD32 a,WORD32 b)190 static PLATFORM_INLINE WORD32 ixheaacd_sub32(WORD32 a, WORD32 b) {
191   WORD32 diff;
192 
193   diff = (WORD32)a - (WORD32)b;
194 
195   return diff;
196 }
197 
ixheaacd_add32_sat(WORD32 a,WORD32 b)198 static PLATFORM_INLINE WORD32 ixheaacd_add32_sat(WORD32 a, WORD32 b) {
199   WORD64 sum;
200 
201   sum = (WORD64)a + (WORD64)b;
202 
203   if (sum >= MAX_32) return MAX_32;
204   if (sum <= MIN_32) return MIN_32;
205 
206   return (WORD32)sum;
207 }
208 
ixheaacd_add32_sat3(WORD32 a,WORD32 b,WORD32 c)209 static PLATFORM_INLINE WORD32 ixheaacd_add32_sat3(WORD32 a, WORD32 b,
210                                                   WORD32 c) {
211   WORD64 sum;
212 
213   sum = (WORD64)a + (WORD64)b;
214 
215   sum = (WORD64)sum + (WORD64)c;
216 
217   if (sum > MAX_32) {
218     sum = MAX_32;
219   }
220   if (sum < MIN_32) {
221     sum = MIN_32;
222   }
223 
224   return (WORD32)sum;
225 }
226 
ixheaacd_sub32_sat(WORD32 a,WORD32 b)227 static PLATFORM_INLINE WORD32 ixheaacd_sub32_sat(WORD32 a, WORD32 b) {
228   WORD64 diff;
229 
230   diff = (WORD64)a - (WORD64)b;
231 
232   if (diff >= MAX_32) return MAX_32;
233   if (diff <= MIN_32) return MIN_32;
234 
235   return (WORD32)diff;
236 }
237 
ixheaacd_norm32(WORD32 a)238 static PLATFORM_INLINE WORD ixheaacd_norm32(WORD32 a) {
239   WORD norm_val;
240 
241   if (a == 0) {
242     norm_val = 31;
243   } else {
244     if (a == (WORD32)0xffffffffL) {
245       norm_val = 31;
246     } else {
247       if (a < 0) {
248         a = ~a;
249       }
250       for (norm_val = 0; a < (WORD32)0x40000000L; norm_val++) {
251         a <<= 1;
252       }
253     }
254   }
255 
256   return norm_val;
257 }
258 
ixheaacd_pnorm32(WORD32 a)259 static PLATFORM_INLINE WORD ixheaacd_pnorm32(WORD32 a) {
260   WORD norm_val;
261 
262   if (a == 0) {
263     norm_val = 31;
264   } else {
265     for (norm_val = 0; a < (WORD32)0x40000000L; norm_val++) {
266       a <<= 1;
267     }
268   }
269 
270   return norm_val;
271 }
272 
ixheaacd_abs32(WORD32 a)273 static PLATFORM_INLINE WORD32 ixheaacd_abs32(WORD32 a) {
274   WORD32 abs_val;
275 
276   abs_val = a;
277 
278   if (a < 0) {
279     abs_val = -a;
280   }
281 
282   return abs_val;
283 }
284 
ixheaacd_abs32_nrm(WORD32 a)285 static PLATFORM_INLINE WORD32 ixheaacd_abs32_nrm(WORD32 a) {
286   WORD32 abs_val;
287 
288   abs_val = a;
289 
290   if (a < 0) {
291     abs_val = ~a;
292   }
293 
294   return abs_val;
295 }
296 
ixheaacd_abs32_sat(WORD32 a)297 static PLATFORM_INLINE WORD32 ixheaacd_abs32_sat(WORD32 a) {
298   WORD32 abs_val;
299 
300   abs_val = a;
301 
302   if (a == MIN_32) {
303     abs_val = MAX_32;
304   } else if (a < 0) {
305     abs_val = -a;
306   }
307 
308   return abs_val;
309 }
310 
ixheaacd_negate32(WORD32 a)311 static PLATFORM_INLINE WORD32 ixheaacd_negate32(WORD32 a) {
312   WORD32 neg_val;
313 
314   neg_val = -a;
315 
316   return neg_val;
317 }
318 
ixheaacd_negate32_sat(WORD32 a)319 static PLATFORM_INLINE WORD32 ixheaacd_negate32_sat(WORD32 a) {
320   WORD32 neg_val;
321 
322   if (a == MIN_32) {
323     neg_val = MAX_32;
324   } else {
325     neg_val = -a;
326   }
327   return neg_val;
328 }
329 
ixheaacd_div32(WORD32 a,WORD32 b,WORD * q_format)330 static PLATFORM_INLINE WORD32 ixheaacd_div32(WORD32 a, WORD32 b,
331                                              WORD *q_format) {
332   WORD32 quotient;
333   UWORD32 mantissa_nr, mantissa_dr;
334   WORD16 sign = 0;
335 
336   LOOPINDEX i;
337   WORD q_nr, q_dr;
338 
339   mantissa_nr = a;
340   mantissa_dr = b;
341   quotient = 0;
342 
343   if ((a < 0) && (0 != b)) {
344     a = -a;
345     sign = (WORD16)(sign ^ -1);
346   }
347 
348   if (b < 0) {
349     b = -b;
350     sign = (WORD16)(sign ^ -1);
351   }
352 
353   if (0 == b) {
354     *q_format = 0;
355     return (a);
356   }
357 
358   quotient = 0;
359 
360   q_nr = ixheaacd_norm32(a);
361   mantissa_nr = (UWORD32)a << (q_nr);
362   q_dr = ixheaacd_norm32(b);
363   mantissa_dr = (UWORD32)b << (q_dr);
364   *q_format = (WORD)(30 + q_nr - q_dr);
365 
366   for (i = 0; i < 31; i++) {
367     quotient = quotient << 1;
368 
369     if (mantissa_nr >= mantissa_dr) {
370       mantissa_nr = mantissa_nr - mantissa_dr;
371       quotient += 1;
372     }
373 
374     mantissa_nr = (UWORD32)mantissa_nr << 1;
375   }
376 
377   if (sign < 0) {
378     quotient = -quotient;
379   }
380 
381   return quotient;
382 }
383 
ixheaacd_shr32_sat(WORD32 a,WORD32 b)384 static PLATFORM_INLINE WORD32 ixheaacd_shr32_sat(WORD32 a, WORD32 b) {
385   WORD32 out_val;
386 
387   b = ((UWORD32)(b << 24) >> 24);
388   if (b >= 31) {
389     if (a < 0)
390       out_val = -1;
391     else
392       out_val = 0;
393   }
394   else if (b <= 0) {
395     return a;
396   }
397   else {
398     a = ixheaacd_add32_sat(a, (1 << (b - 1)));
399     out_val = (WORD32)a >> b;
400   }
401 
402   return out_val;
403 }
404 
ixheaacd_mac16x16in32_sat(WORD32 a,WORD16 b,WORD16 c)405 static PLATFORM_INLINE WORD32 ixheaacd_mac16x16in32_sat(WORD32 a, WORD16 b,
406                                                         WORD16 c) {
407   WORD32 acc;
408 
409   acc = ixheaacd_mult16x16in32(b, c);
410 
411   acc = ixheaacd_add32_sat(a, acc);
412 
413   return acc;
414 }
415 
ixheaacd_mac16x16in32_shl(WORD32 a,WORD16 b,WORD16 c)416 static PLATFORM_INLINE WORD32 ixheaacd_mac16x16in32_shl(WORD32 a, WORD16 b,
417                                                         WORD16 c) {
418   WORD32 acc;
419 
420   acc = ixheaacd_mult16x16in32_shl(b, c);
421 
422   acc = ixheaacd_add32(a, acc);
423 
424   return acc;
425 }
426 
ixheaacd_mac16x16in32_shl_sat(WORD32 a,WORD16 b,WORD16 c)427 static PLATFORM_INLINE WORD32 ixheaacd_mac16x16in32_shl_sat(WORD32 a, WORD16 b,
428                                                             WORD16 c) {
429   WORD32 acc;
430 
431   acc = ixheaacd_mult16x16in32_shl_sat(b, c);
432 
433   acc = ixheaacd_add32_sat(a, acc);
434 
435   return acc;
436 }
437 
ixheaacd_msu16x16in32(WORD32 a,WORD16 b,WORD16 c)438 static PLATFORM_INLINE WORD32 ixheaacd_msu16x16in32(WORD32 a, WORD16 b, WORD16 c) {
439   WORD32 acc;
440 
441   acc = ixheaacd_mult16x16in32(b, c);
442 
443   acc = ixheaacd_sub32(a, acc);
444 
445   return acc;
446 }
447 
448 #endif
449