xref: /aosp_15_r20/external/libxaac/common/ixheaac_basic_ops32.h (revision 15dc779a375ca8b5125643b829a8aa4b70d7f451)
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 IXHEAAC_BASIC_OPS32_H
21 #define IXHEAAC_BASIC_OPS32_H
22 
ixheaac_min32(WORD32 a,WORD32 b)23 static PLATFORM_INLINE WORD32 ixheaac_min32(WORD32 a, WORD32 b) {
24   WORD32 min_val;
25 
26   min_val = (a < b) ? a : b;
27 
28   return min_val;
29 }
30 
ixheaac_max32(WORD32 a,WORD32 b)31 static PLATFORM_INLINE WORD32 ixheaac_max32(WORD32 a, WORD32 b) {
32   WORD32 max_val;
33 
34   max_val = (a > b) ? a : b;
35 
36   return max_val;
37 }
38 
ixheaac_shl32(WORD32 a,WORD b)39 static PLATFORM_INLINE WORD32 ixheaac_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 
ixheaac_shr32(WORD32 a,WORD b)51 static PLATFORM_INLINE WORD32 ixheaac_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 
ixheaac_shl32_sat(WORD32 a,WORD b)67 static PLATFORM_INLINE WORD32 ixheaac_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 
ixheaac_shl32_dir(WORD32 a,WORD b)78 static PLATFORM_INLINE WORD32 ixheaac_shl32_dir(WORD32 a, WORD b) {
79   WORD32 out_val;
80 
81   if (b < 0) {
82     out_val = ixheaac_shr32(a, -b);
83   } else {
84     out_val = ixheaac_shl32(a, b);
85   }
86 
87   return out_val;
88 }
89 
ixheaac_shl32_dir_sat(WORD32 a,WORD b)90 static PLATFORM_INLINE WORD32 ixheaac_shl32_dir_sat(WORD32 a, WORD b) {
91   WORD32 out_val;
92 
93   if (b < 0) {
94     out_val = ixheaac_shr32(a, -b);
95   } else {
96     out_val = ixheaac_shl32_sat(a, b);
97   }
98 
99   return out_val;
100 }
101 
ixheaac_shr32_dir(WORD32 a,WORD b)102 static PLATFORM_INLINE WORD32 ixheaac_shr32_dir(WORD32 a, WORD b) {
103   WORD32 out_val;
104 
105   if (b < 0) {
106     out_val = ixheaac_shl32(a, -b);
107   } else {
108     out_val = ixheaac_shr32(a, b);
109   }
110 
111   return out_val;
112 }
113 
ixheaac_shr32_dir_sat(WORD32 a,WORD b)114 static PLATFORM_INLINE WORD32 ixheaac_shr32_dir_sat(WORD32 a, WORD b) {
115   WORD32 out_val;
116 
117   if (b < 0) {
118     out_val = ixheaac_shl32_sat(a, -b);
119   } else {
120     out_val = ixheaac_shr32(a, b);
121   }
122 
123   return out_val;
124 }
125 
ixheaac_mult16x16in32(WORD16 a,WORD16 b)126 static PLATFORM_INLINE WORD32 ixheaac_mult16x16in32(WORD16 a, WORD16 b) {
127   WORD32 product;
128 
129   product = (WORD32)a * (WORD32)b;
130 
131   return product;
132 }
133 
ixheaac_mult32x16hin32(WORD32 a,WORD32 b)134 static PLATFORM_INLINE WORD32 ixheaac_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 
ixheaac_mult32x16in32_sat(WORD32 a,WORD16 b)144 static PLATFORM_INLINE WORD32 ixheaac_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 
ixheaac_mult16x16in32_shl(WORD16 a,WORD16 b)162 static PLATFORM_INLINE WORD32 ixheaac_mult16x16in32_shl(WORD16 a, WORD16 b) {
163   WORD32 product;
164 
165   product = ixheaac_shl32(ixheaac_mult16x16in32(a, b), 1);
166 
167   return product;
168 }
169 
ixheaac_mult16x16in32_shl_sat(WORD16 a,WORD16 b)170 static PLATFORM_INLINE WORD32 ixheaac_mult16x16in32_shl_sat(WORD16 a, WORD16 b) {
171   WORD32 product;
172   product = (WORD32)a * (WORD32)b;
173   if (product != (WORD32)0x40000000L) {
174     product = ixheaac_shl32(product, 1);
175   } else {
176     product = MAX_32;
177   }
178   return product;
179 }
180 
ixheaac_add32(WORD32 a,WORD32 b)181 static PLATFORM_INLINE WORD32 ixheaac_add32(WORD32 a, WORD32 b) {
182   WORD32 sum;
183 
184   sum = (WORD32)a + (WORD32)b;
185 
186   return sum;
187 }
188 
ixheaac_sub32(WORD32 a,WORD32 b)189 static PLATFORM_INLINE WORD32 ixheaac_sub32(WORD32 a, WORD32 b) {
190   WORD32 diff;
191 
192   diff = (WORD32)a - (WORD32)b;
193 
194   return diff;
195 }
196 
ixheaac_add32_sat(WORD32 a,WORD32 b)197 static PLATFORM_INLINE WORD32 ixheaac_add32_sat(WORD32 a, WORD32 b) {
198   WORD64 sum;
199 
200   sum = (WORD64)a + (WORD64)b;
201 
202   if (sum >= MAX_32) return MAX_32;
203   if (sum <= MIN_32) return MIN_32;
204 
205   return (WORD32)sum;
206 }
207 
ixheaac_add32_sat3(WORD32 a,WORD32 b,WORD32 c)208 static PLATFORM_INLINE WORD32 ixheaac_add32_sat3(WORD32 a, WORD32 b, WORD32 c) {
209   WORD64 sum;
210 
211   sum = (WORD64)a + (WORD64)b;
212 
213   sum = (WORD64)sum + (WORD64)c;
214 
215   if (sum > MAX_32) {
216     sum = MAX_32;
217   }
218   if (sum < MIN_32) {
219     sum = MIN_32;
220   }
221 
222   return (WORD32)sum;
223 }
224 
ixheaac_sub32_sat(WORD32 a,WORD32 b)225 static PLATFORM_INLINE WORD32 ixheaac_sub32_sat(WORD32 a, WORD32 b) {
226   WORD64 diff;
227 
228   diff = (WORD64)a - (WORD64)b;
229 
230   if (diff >= MAX_32) return MAX_32;
231   if (diff <= MIN_32) return MIN_32;
232 
233   return (WORD32)diff;
234 }
235 
ixheaac_norm32(WORD32 a)236 static PLATFORM_INLINE WORD ixheaac_norm32(WORD32 a) {
237   WORD norm_val;
238 
239   if (a == 0) {
240     norm_val = 31;
241   } else {
242     if (a == (WORD32)0xffffffffL) {
243       norm_val = 31;
244     } else {
245       if (a < 0) {
246         a = ~a;
247       }
248       for (norm_val = 0; a < (WORD32)0x40000000L; norm_val++) {
249         a <<= 1;
250       }
251     }
252   }
253 
254   return norm_val;
255 }
256 
ixheaac_pnorm32(WORD32 a)257 static PLATFORM_INLINE WORD ixheaac_pnorm32(WORD32 a) {
258   WORD norm_val;
259 
260   if (a == 0) {
261     norm_val = 31;
262   } else {
263     for (norm_val = 0; a < (WORD32)0x40000000L; norm_val++) {
264       a <<= 1;
265     }
266   }
267 
268   return norm_val;
269 }
270 
ixheaac_abs32(WORD32 a)271 static PLATFORM_INLINE WORD32 ixheaac_abs32(WORD32 a) {
272   WORD32 abs_val;
273 
274   abs_val = a;
275 
276   if (a < 0) {
277     abs_val = -a;
278   }
279 
280   return abs_val;
281 }
282 
ixheaac_abs32_nrm(WORD32 a)283 static PLATFORM_INLINE WORD32 ixheaac_abs32_nrm(WORD32 a) {
284   WORD32 abs_val;
285 
286   abs_val = a;
287 
288   if (a < 0) {
289     abs_val = ~a;
290   }
291 
292   return abs_val;
293 }
294 
ixheaac_abs32_sat(WORD32 a)295 static PLATFORM_INLINE WORD32 ixheaac_abs32_sat(WORD32 a) {
296   WORD32 abs_val;
297 
298   abs_val = a;
299 
300   if (a == MIN_32) {
301     abs_val = MAX_32;
302   } else if (a < 0) {
303     abs_val = -a;
304   }
305 
306   return abs_val;
307 }
308 
ixheaac_negate32(WORD32 a)309 static PLATFORM_INLINE WORD32 ixheaac_negate32(WORD32 a) {
310   WORD32 neg_val;
311 
312   neg_val = -a;
313 
314   return neg_val;
315 }
316 
ixheaac_negate32_sat(WORD32 a)317 static PLATFORM_INLINE WORD32 ixheaac_negate32_sat(WORD32 a) {
318   WORD32 neg_val;
319 
320   if (a == MIN_32) {
321     neg_val = MAX_32;
322   } else {
323     neg_val = -a;
324   }
325   return neg_val;
326 }
327 
ixheaac_div32(WORD32 a,WORD32 b,WORD * q_format)328 static PLATFORM_INLINE WORD32 ixheaac_div32(WORD32 a, WORD32 b, WORD *q_format) {
329   WORD32 quotient;
330   UWORD32 mantissa_nr, mantissa_dr;
331   WORD16 sign = 0;
332 
333   LOOPINDEX i;
334   WORD q_nr, q_dr;
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 = ixheaac_norm32(a);
354   mantissa_nr = (UWORD32)a << (q_nr);
355   q_dr = ixheaac_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 
ixheaac_shr32_sat(WORD32 a,WORD32 b)377 static PLATFORM_INLINE WORD32 ixheaac_shr32_sat(WORD32 a, WORD32 b) {
378   WORD32 out_val;
379 
380   b = ((UWORD32)(b << 24) >> 24);
381   if (b >= 31) {
382     if (a < 0)
383       out_val = -1;
384     else
385       out_val = 0;
386   } else if (b <= 0) {
387     return a;
388   } else {
389     a = ixheaac_add32_sat(a, (1 << (b - 1)));
390     out_val = (WORD32)a >> b;
391   }
392 
393   return out_val;
394 }
395 
ixheaac_mac16x16in32_sat(WORD32 a,WORD16 b,WORD16 c)396 static PLATFORM_INLINE WORD32 ixheaac_mac16x16in32_sat(WORD32 a, WORD16 b, WORD16 c) {
397   WORD32 acc;
398 
399   acc = ixheaac_mult16x16in32(b, c);
400 
401   acc = ixheaac_add32_sat(a, acc);
402 
403   return acc;
404 }
405 
ixheaac_mac16x16in32_shl(WORD32 a,WORD16 b,WORD16 c)406 static PLATFORM_INLINE WORD32 ixheaac_mac16x16in32_shl(WORD32 a, WORD16 b, WORD16 c) {
407   WORD32 acc;
408 
409   acc = ixheaac_mult16x16in32_shl(b, c);
410 
411   acc = ixheaac_add32(a, acc);
412 
413   return acc;
414 }
415 
ixheaac_mac16x16in32_shl_sat(WORD32 a,WORD16 b,WORD16 c)416 static PLATFORM_INLINE WORD32 ixheaac_mac16x16in32_shl_sat(WORD32 a, WORD16 b, WORD16 c) {
417   WORD32 acc;
418 
419   acc = ixheaac_mult16x16in32_shl_sat(b, c);
420 
421   acc = ixheaac_add32_sat(a, acc);
422 
423   return acc;
424 }
425 
ixheaac_msu16x16in32(WORD32 a,WORD16 b,WORD16 c)426 static PLATFORM_INLINE WORD32 ixheaac_msu16x16in32(WORD32 a, WORD16 b, WORD16 c) {
427   WORD32 acc;
428 
429   acc = ixheaac_mult16x16in32(b, c);
430 
431   acc = ixheaac_sub32(a, acc);
432 
433   return acc;
434 }
435 
436 #endif /* IXHEAAC_BASIC_OPS32_H */
437