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
ixheaacd_mult32x16in32_shl(WORD32 a,WORD16 b)23 static PLATFORM_INLINE WORD32 ixheaacd_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
ixheaacd_mult32x16in32(WORD32 a,WORD16 b)34 static PLATFORM_INLINE WORD32 ixheaacd_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
ixheaacd_mult32x32in32(WORD32 a,WORD32 b)45 static PLATFORM_INLINE WORD32 ixheaacd_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
ixheaacd_mult32x16in32_shl_sat(WORD32 a,WORD16 b)56 static PLATFORM_INLINE WORD32 ixheaacd_mult32x16in32_shl_sat(WORD32 a,
57 WORD16 b) {
58 WORD32 result;
59
60 if (a == (WORD32)0x80000000 && b == (WORD16)0x8000) {
61 result = (WORD32)0x7fffffff;
62 } else {
63 result = ixheaacd_mult32x16in32_shl(a, b);
64 }
65
66 return (result);
67 }
68
ixheaacd_mult32_shl(WORD32 a,WORD32 b)69 static PLATFORM_INLINE WORD32 ixheaacd_mult32_shl(WORD32 a, WORD32 b) {
70 WORD32 result;
71 WORD64 temp_result;
72
73 temp_result = (WORD64)a * (WORD64)b;
74 result = (WORD32)(temp_result >> 32);
75
76 return (result << 1);
77 }
78
ixheaacd_mult32(WORD32 a,WORD32 b)79 static PLATFORM_INLINE WORD32 ixheaacd_mult32(WORD32 a, WORD32 b) {
80 WORD32 result;
81 WORD64 temp_result;
82
83 temp_result = (WORD64)a * (WORD64)b;
84 result = (WORD32)(temp_result >> 32);
85
86 return (result);
87 }
88
ixheaacd_mult32_shl_sat(WORD32 a,WORD32 b)89 static PLATFORM_INLINE WORD32 ixheaacd_mult32_shl_sat(WORD32 a, WORD32 b) {
90 WORD32 result;
91
92 if (a == (WORD32)0x80000000 && b == (WORD32)0x80000000) {
93 result = 0x7fffffff;
94 } else {
95 result = ixheaacd_mult32_shl(a, b);
96 }
97
98 return (result);
99 }
100
ixheaacd_mac32x16in32(WORD32 a,WORD32 b,WORD16 c)101 static PLATFORM_INLINE WORD32 ixheaacd_mac32x16in32(WORD32 a, WORD32 b,
102 WORD16 c) {
103 WORD32 result;
104
105 result = a + ixheaacd_mult32x16in32(b, c);
106
107 return (result);
108 }
109
ixheaacd_mac32x16in32_shl(WORD32 a,WORD32 b,WORD16 c)110 static PLATFORM_INLINE WORD32 ixheaacd_mac32x16in32_shl(WORD32 a, WORD32 b,
111 WORD16 c) {
112 WORD32 result;
113
114 result = a + ixheaacd_mult32x16in32_shl(b, c);
115
116 return (result);
117 }
118
ixheaacd_mac32x16in32_shl_sat(WORD32 a,WORD32 b,WORD16 c)119 static PLATFORM_INLINE WORD32 ixheaacd_mac32x16in32_shl_sat(WORD32 a, WORD32 b, WORD16 c) {
120 WORD32 result;
121
122 result = ixheaacd_add32_sat(a, ixheaacd_mult32x16in32_shl_sat(b, c));
123
124 return (result);
125 }
126
ixheaacd_mac32(WORD32 a,WORD32 b,WORD32 c)127 static PLATFORM_INLINE WORD32 ixheaacd_mac32(WORD32 a, WORD32 b, WORD32 c) {
128 WORD32 result;
129
130 result = a + ixheaacd_mult32(b, c);
131
132 return (result);
133 }
134
ixheaacd_mult32x32in64(WORD32 a,WORD32 b)135 static PLATFORM_INLINE WORD64 ixheaacd_mult32x32in64(WORD32 a, WORD32 b) {
136 WORD64 result;
137
138 result = (WORD64)a * (WORD64)b;
139
140 return (result);
141 }
142
ixheaacd_mac32x32in64(WORD64 sum,WORD32 a,WORD32 b)143 static PLATFORM_INLINE WORD64 ixheaacd_mac32x32in64(WORD64 sum, WORD32 a,
144 WORD32 b) {
145 sum += (WORD64)a * (WORD64)b;
146
147 return (sum);
148 }
149
ixheaacd_mac32x32in64_7(const WORD32 * a,const WORD16 * b)150 static PLATFORM_INLINE WORD64 ixheaacd_mac32x32in64_7(const WORD32 *a,
151 const WORD16 *b) {
152 WORD64 sum;
153 sum = (WORD64)a[0] * (WORD64)b[0];
154 sum += (WORD64)a[1] * (WORD64)b[1];
155 sum += (WORD64)a[2] * (WORD64)b[2];
156 sum += (WORD64)a[3] * (WORD64)b[3];
157 sum += (WORD64)a[4] * (WORD64)b[4];
158 sum += (WORD64)a[5] * (WORD64)b[5];
159 sum += (WORD64)a[6] * (WORD64)b[6];
160
161 return (sum);
162 }
163
ixheaacd_mac32x32in64_n(WORD64 sum,const WORD32 * a,const WORD16 * b,WORD32 n)164 static PLATFORM_INLINE WORD64 ixheaacd_mac32x32in64_n(WORD64 sum,
165 const WORD32 *a,
166 const WORD16 *b,
167 WORD32 n) {
168 WORD32 k;
169
170 sum += (WORD64)a[0] * (WORD64)b[0];
171 for (k = 1; k < n; k++) sum += (WORD64)a[k] * (WORD64)b[k];
172 return (sum);
173 }
174
ixheaacd_mult64(WORD32 a,WORD32 b)175 static PLATFORM_INLINE WORD64 ixheaacd_mult64(WORD32 a, WORD32 b) {
176 WORD64 result;
177 result = (WORD64)a * (WORD64)b;
178 return (result);
179 }
180
ixheaacd_mult64_sat(WORD64 a,WORD64 b)181 static PLATFORM_INLINE WORD64 ixheaacd_mult64_sat(WORD64 a, WORD64 b) {
182 WORD64 result;
183
184 if (a > 0 && b > 0 && a > MAX_64 / b) return MAX_64;
185 if (a < 0 && b > 0 && a < MIN_64 / b) return MIN_64;
186 if (a > 0 && b < 0 && b < MIN_64 / a) return MIN_64;
187 if (a < 0 && b < 0 && a < MAX_64 / b) return MAX_64;
188
189 result = a * b;
190 return (result);
191 }
192
ixheaacd_add64_sat(WORD64 a,WORD64 b)193 static PLATFORM_INLINE WORD64 ixheaacd_add64_sat(WORD64 a, WORD64 b) {
194 WORD64 result, comp;
195 result = (a < 0) ? MIN_64 : MAX_64;
196 comp = result - a;
197 if ((a < 0) == (b > comp)) result = a + b;
198
199 return (result);
200 }
201
ixheaacd_sat64_32(WORD64 a)202 static PLATFORM_INLINE WORD32 ixheaacd_sat64_32(WORD64 a) {
203 WORD32 result;
204 if (a >= MAX_32) {
205 result = MAX_32;
206 } else if (a <= MIN_32) {
207 result = MIN_32;
208 } else {
209 result = (WORD32)a;
210 }
211 return (result);
212 }
213
ixheaacd_add64(WORD64 a,WORD64 b)214 static PLATFORM_INLINE WORD64 ixheaacd_add64(WORD64 a, WORD64 b) {
215 WORD64 result;
216 result = a + b;
217 return (result);
218 }
219
ixheaacd_sub64(WORD64 a,WORD64 b)220 static PLATFORM_INLINE WORD64 ixheaacd_sub64(WORD64 a, WORD64 b) {
221 WORD64 diff;
222
223 diff = (WORD64)a - (WORD64)b;
224
225 return diff;
226 }
227
ixheaacd_sub64_sat(WORD64 a,WORD64 b)228 static PLATFORM_INLINE WORD64 ixheaacd_sub64_sat(WORD64 a, WORD64 b) {
229 WORD64 diff;
230
231 diff = ixheaacd_sub64(a, b);
232
233 if ((((WORD64)a ^ (WORD64)b) & (WORD64)MIN_64) != 0) {
234 if (((WORD64)diff ^ (WORD64)a) & (WORD64)MIN_64) {
235 diff = (a < 0L) ? MIN_64 : MAX_64;
236 }
237 }
238
239 return (diff);
240 }
241
ixheaacd_mul32_sh(WORD32 a,WORD32 b,WORD8 shift)242 static PLATFORM_INLINE WORD32 ixheaacd_mul32_sh(WORD32 a, WORD32 b,
243 WORD8 shift) {
244 WORD32 result;
245 WORD64 temp_result;
246
247 temp_result = (WORD64)a * (WORD64)b;
248 result = (WORD32)(temp_result >> shift);
249
250 return (result);
251 }
252
ixheaacd_mult32x16hin32_shl(WORD32 a,WORD32 b)253 static PLATFORM_INLINE WORD32 ixheaacd_mult32x16hin32_shl(WORD32 a, WORD32 b) {
254 WORD32 product;
255 WORD64 temp_product;
256
257 temp_product = (WORD64)a * (WORD64)(b >> 16);
258 product = (WORD32)(temp_product >> 16);
259
260 return (product << 1);
261 }
262
263 #endif
264