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_OPS40_H
21 #define IXHEAAC_BASIC_OPS40_H
22
ixheaac_mult32x16in32_shl(WORD32 a,WORD16 b)23 static PLATFORM_INLINE WORD32 ixheaac_mult32x16in32_shl(WORD32 a, WORD16 b) {
24 WORD32 result;
25 WORD64 temp_result;
26
27 temp_result = (WORD64)a * (WORD64)b;
28
29 result = (WORD32)(temp_result >> 16);
30
31 return (result << 1);
32 }
33
ixheaac_mult32x16in32(WORD32 a,WORD16 b)34 static PLATFORM_INLINE WORD32 ixheaac_mult32x16in32(WORD32 a, WORD16 b) {
35 WORD32 result;
36 WORD64 temp_result;
37
38 temp_result = (WORD64)a * (WORD64)b;
39
40 result = (WORD32)(temp_result >> 16);
41
42 return (result);
43 }
44
ixheaac_mult32x32in32(WORD32 a,WORD32 b)45 static PLATFORM_INLINE WORD32 ixheaac_mult32x32in32(WORD32 a, WORD32 b) {
46 WORD32 result;
47 WORD64 temp_result;
48
49 temp_result = (WORD64)a * (WORD64)b;
50
51 result = (WORD32)(temp_result >> 16);
52
53 return (result);
54 }
55
ixheaac_mult32x16in32_shl_sat(WORD32 a,WORD16 b)56 static PLATFORM_INLINE WORD32 ixheaac_mult32x16in32_shl_sat(WORD32 a, WORD16 b) {
57 WORD32 result;
58
59 if (a == (WORD32)0x80000000 && b == (WORD16)0x8000) {
60 result = (WORD32)0x7fffffff;
61 } else {
62 result = ixheaac_mult32x16in32_shl(a, b);
63 }
64
65 return (result);
66 }
67
ixheaac_mult32_shl(WORD32 a,WORD32 b)68 static PLATFORM_INLINE WORD32 ixheaac_mult32_shl(WORD32 a, WORD32 b) {
69 WORD32 result;
70 WORD64 temp_result;
71
72 temp_result = (WORD64)a * (WORD64)b;
73 result = (WORD32)(temp_result >> 32);
74
75 return (result << 1);
76 }
77
ixheaac_mult32(WORD32 a,WORD32 b)78 static PLATFORM_INLINE WORD32 ixheaac_mult32(WORD32 a, WORD32 b) {
79 WORD32 result;
80 WORD64 temp_result;
81
82 temp_result = (WORD64)a * (WORD64)b;
83 result = (WORD32)(temp_result >> 32);
84
85 return (result);
86 }
87
ixheaac_mult32_shl_sat(WORD32 a,WORD32 b)88 static PLATFORM_INLINE WORD32 ixheaac_mult32_shl_sat(WORD32 a, WORD32 b) {
89 WORD32 result;
90
91 if (a == (WORD32)0x80000000 && b == (WORD32)0x80000000) {
92 result = 0x7fffffff;
93 } else {
94 result = ixheaac_mult32_shl(a, b);
95 }
96
97 return (result);
98 }
99
ixheaac_mac32x16in32(WORD32 a,WORD32 b,WORD16 c)100 static PLATFORM_INLINE WORD32 ixheaac_mac32x16in32(WORD32 a, WORD32 b, WORD16 c) {
101 WORD32 result;
102
103 result = a + ixheaac_mult32x16in32(b, c);
104
105 return (result);
106 }
107
ixheaac_mac32x16in32_shl(WORD32 a,WORD32 b,WORD16 c)108 static PLATFORM_INLINE WORD32 ixheaac_mac32x16in32_shl(WORD32 a, WORD32 b, WORD16 c) {
109 WORD32 result;
110
111 result = a + ixheaac_mult32x16in32_shl(b, c);
112
113 return (result);
114 }
115
ixheaac_mac32x16in32_shl_sat(WORD32 a,WORD32 b,WORD16 c)116 static PLATFORM_INLINE WORD32 ixheaac_mac32x16in32_shl_sat(WORD32 a, WORD32 b, WORD16 c) {
117 WORD32 result;
118
119 result = ixheaac_add32_sat(a, ixheaac_mult32x16in32_shl_sat(b, c));
120
121 return (result);
122 }
123
ixheaac_mac32(WORD32 a,WORD32 b,WORD32 c)124 static PLATFORM_INLINE WORD32 ixheaac_mac32(WORD32 a, WORD32 b, WORD32 c) {
125 WORD32 result;
126
127 result = a + ixheaac_mult32(b, c);
128
129 return (result);
130 }
131
ixheaac_mult32x32in64(WORD32 a,WORD32 b)132 static PLATFORM_INLINE WORD64 ixheaac_mult32x32in64(WORD32 a, WORD32 b) {
133 WORD64 result;
134
135 result = (WORD64)a * (WORD64)b;
136
137 return (result);
138 }
139
ixheaac_mac32x32in64(WORD64 sum,WORD32 a,WORD32 b)140 static PLATFORM_INLINE WORD64 ixheaac_mac32x32in64(WORD64 sum, WORD32 a, WORD32 b) {
141 sum += (WORD64)a * (WORD64)b;
142
143 return (sum);
144 }
145
ixheaac_mac32x32in64_7(const WORD32 * a,const WORD16 * b)146 static PLATFORM_INLINE WORD64 ixheaac_mac32x32in64_7(const WORD32 *a, const WORD16 *b) {
147 WORD64 sum;
148 sum = (WORD64)a[0] * (WORD64)b[0];
149 sum += (WORD64)a[1] * (WORD64)b[1];
150 sum += (WORD64)a[2] * (WORD64)b[2];
151 sum += (WORD64)a[3] * (WORD64)b[3];
152 sum += (WORD64)a[4] * (WORD64)b[4];
153 sum += (WORD64)a[5] * (WORD64)b[5];
154 sum += (WORD64)a[6] * (WORD64)b[6];
155
156 return (sum);
157 }
158
ixheaac_mac32x32in64_n(WORD64 sum,const WORD32 * a,const WORD16 * b,WORD32 n)159 static PLATFORM_INLINE WORD64 ixheaac_mac32x32in64_n(WORD64 sum, const WORD32 *a, const WORD16 *b,
160 WORD32 n) {
161 WORD32 k;
162
163 sum += (WORD64)a[0] * (WORD64)b[0];
164 for (k = 1; k < n; k++) sum += (WORD64)a[k] * (WORD64)b[k];
165 return (sum);
166 }
167
ixheaac_mult64(WORD32 a,WORD32 b)168 static PLATFORM_INLINE WORD64 ixheaac_mult64(WORD32 a, WORD32 b) {
169 WORD64 result;
170 result = (WORD64)a * (WORD64)b;
171 return (result);
172 }
173
ixheaac_mult64_sat(WORD64 a,WORD64 b)174 static PLATFORM_INLINE WORD64 ixheaac_mult64_sat(WORD64 a, WORD64 b) {
175 WORD64 result;
176
177 if (a > 0 && b > 0 && a > MAX_64 / b) return MAX_64;
178 if (a < 0 && b > 0 && a < MIN_64 / b) return MIN_64;
179 if (a > 0 && b < 0 && b < MIN_64 / a) return MIN_64;
180 if (a < 0 && b < 0 && a < MAX_64 / b) return MAX_64;
181
182 result = a * b;
183 return (result);
184 }
185
ixheaac_add64_sat(WORD64 a,WORD64 b)186 static PLATFORM_INLINE WORD64 ixheaac_add64_sat(WORD64 a, WORD64 b) {
187 WORD64 result, comp;
188 result = (a < 0) ? MIN_64 : MAX_64;
189 comp = result - a;
190 if ((a < 0) == (b > comp)) result = a + b;
191
192 return (result);
193 }
194
ixheaac_sat64_32(WORD64 a)195 static PLATFORM_INLINE WORD32 ixheaac_sat64_32(WORD64 a) {
196 WORD32 result;
197 if (a >= MAX_32) {
198 result = MAX_32;
199 } else if (a <= MIN_32) {
200 result = MIN_32;
201 } else {
202 result = (WORD32)a;
203 }
204 return (result);
205 }
206
ixheaac_add64(WORD64 a,WORD64 b)207 static PLATFORM_INLINE WORD64 ixheaac_add64(WORD64 a, WORD64 b) {
208 WORD64 result;
209 result = a + b;
210 return (result);
211 }
212
ixheaac_sub64(WORD64 a,WORD64 b)213 static PLATFORM_INLINE WORD64 ixheaac_sub64(WORD64 a, WORD64 b) {
214 WORD64 diff;
215
216 diff = (WORD64)a - (WORD64)b;
217
218 return diff;
219 }
220
ixheaac_sub64_sat(WORD64 a,WORD64 b)221 static PLATFORM_INLINE WORD64 ixheaac_sub64_sat(WORD64 a, WORD64 b) {
222 WORD64 diff;
223
224 diff = ixheaac_sub64(a, b);
225
226 if ((((WORD64)a ^ (WORD64)b) & (WORD64)MIN_64) != 0) {
227 if (((WORD64)diff ^ (WORD64)a) & (WORD64)MIN_64) {
228 diff = (a < 0L) ? MIN_64 : MAX_64;
229 }
230 }
231
232 return (diff);
233 }
234
ixheaac_mul32_sh(WORD32 a,WORD32 b,WORD8 shift)235 static PLATFORM_INLINE WORD32 ixheaac_mul32_sh(WORD32 a, WORD32 b, WORD8 shift) {
236 WORD32 result;
237 WORD64 temp_result;
238
239 temp_result = (WORD64)a * (WORD64)b;
240 result = (WORD32)(temp_result >> shift);
241
242 return (result);
243 }
244
ixheaac_mult32x16hin32_shl(WORD32 a,WORD32 b)245 static PLATFORM_INLINE WORD32 ixheaac_mult32x16hin32_shl(WORD32 a, WORD32 b) {
246 WORD32 product;
247 WORD64 temp_product;
248
249 temp_product = (WORD64)a * (WORD64)(b >> 16);
250 product = (WORD32)(temp_product >> 16);
251
252 return (product << 1);
253 }
254
255 #endif /* IXHEAAC_BASIC_OPS40_H */
256