1*15dc779aSAndroid Build Coastguard Worker /******************************************************************************
2*15dc779aSAndroid Build Coastguard Worker * *
3*15dc779aSAndroid Build Coastguard Worker * Copyright (C) 2018 The Android Open Source Project
4*15dc779aSAndroid Build Coastguard Worker *
5*15dc779aSAndroid Build Coastguard Worker * Licensed under the Apache License, Version 2.0 (the "License");
6*15dc779aSAndroid Build Coastguard Worker * you may not use this file except in compliance with the License.
7*15dc779aSAndroid Build Coastguard Worker * You may obtain a copy of the License at:
8*15dc779aSAndroid Build Coastguard Worker *
9*15dc779aSAndroid Build Coastguard Worker * http://www.apache.org/licenses/LICENSE-2.0
10*15dc779aSAndroid Build Coastguard Worker *
11*15dc779aSAndroid Build Coastguard Worker * Unless required by applicable law or agreed to in writing, software
12*15dc779aSAndroid Build Coastguard Worker * distributed under the License is distributed on an "AS IS" BASIS,
13*15dc779aSAndroid Build Coastguard Worker * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14*15dc779aSAndroid Build Coastguard Worker * See the License for the specific language governing permissions and
15*15dc779aSAndroid Build Coastguard Worker * limitations under the License.
16*15dc779aSAndroid Build Coastguard Worker *
17*15dc779aSAndroid Build Coastguard Worker *****************************************************************************
18*15dc779aSAndroid Build Coastguard Worker * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
19*15dc779aSAndroid Build Coastguard Worker */
20*15dc779aSAndroid Build Coastguard Worker #ifndef IXHEAAC_BASIC_OPS40_H
21*15dc779aSAndroid Build Coastguard Worker #define IXHEAAC_BASIC_OPS40_H
22*15dc779aSAndroid Build Coastguard Worker
ixheaac_mult32x16in32_shl(WORD32 a,WORD16 b)23*15dc779aSAndroid Build Coastguard Worker static PLATFORM_INLINE WORD32 ixheaac_mult32x16in32_shl(WORD32 a, WORD16 b) {
24*15dc779aSAndroid Build Coastguard Worker WORD32 result;
25*15dc779aSAndroid Build Coastguard Worker WORD64 temp_result;
26*15dc779aSAndroid Build Coastguard Worker
27*15dc779aSAndroid Build Coastguard Worker temp_result = (WORD64)a * (WORD64)b;
28*15dc779aSAndroid Build Coastguard Worker
29*15dc779aSAndroid Build Coastguard Worker result = (WORD32)(temp_result >> 16);
30*15dc779aSAndroid Build Coastguard Worker
31*15dc779aSAndroid Build Coastguard Worker return (result << 1);
32*15dc779aSAndroid Build Coastguard Worker }
33*15dc779aSAndroid Build Coastguard Worker
ixheaac_mult32x16in32(WORD32 a,WORD16 b)34*15dc779aSAndroid Build Coastguard Worker static PLATFORM_INLINE WORD32 ixheaac_mult32x16in32(WORD32 a, WORD16 b) {
35*15dc779aSAndroid Build Coastguard Worker WORD32 result;
36*15dc779aSAndroid Build Coastguard Worker WORD64 temp_result;
37*15dc779aSAndroid Build Coastguard Worker
38*15dc779aSAndroid Build Coastguard Worker temp_result = (WORD64)a * (WORD64)b;
39*15dc779aSAndroid Build Coastguard Worker
40*15dc779aSAndroid Build Coastguard Worker result = (WORD32)(temp_result >> 16);
41*15dc779aSAndroid Build Coastguard Worker
42*15dc779aSAndroid Build Coastguard Worker return (result);
43*15dc779aSAndroid Build Coastguard Worker }
44*15dc779aSAndroid Build Coastguard Worker
ixheaac_mult32x32in32(WORD32 a,WORD32 b)45*15dc779aSAndroid Build Coastguard Worker static PLATFORM_INLINE WORD32 ixheaac_mult32x32in32(WORD32 a, WORD32 b) {
46*15dc779aSAndroid Build Coastguard Worker WORD32 result;
47*15dc779aSAndroid Build Coastguard Worker WORD64 temp_result;
48*15dc779aSAndroid Build Coastguard Worker
49*15dc779aSAndroid Build Coastguard Worker temp_result = (WORD64)a * (WORD64)b;
50*15dc779aSAndroid Build Coastguard Worker
51*15dc779aSAndroid Build Coastguard Worker result = (WORD32)(temp_result >> 16);
52*15dc779aSAndroid Build Coastguard Worker
53*15dc779aSAndroid Build Coastguard Worker return (result);
54*15dc779aSAndroid Build Coastguard Worker }
55*15dc779aSAndroid Build Coastguard Worker
ixheaac_mult32x16in32_shl_sat(WORD32 a,WORD16 b)56*15dc779aSAndroid Build Coastguard Worker static PLATFORM_INLINE WORD32 ixheaac_mult32x16in32_shl_sat(WORD32 a, WORD16 b) {
57*15dc779aSAndroid Build Coastguard Worker WORD32 result;
58*15dc779aSAndroid Build Coastguard Worker
59*15dc779aSAndroid Build Coastguard Worker if (a == (WORD32)0x80000000 && b == (WORD16)0x8000) {
60*15dc779aSAndroid Build Coastguard Worker result = (WORD32)0x7fffffff;
61*15dc779aSAndroid Build Coastguard Worker } else {
62*15dc779aSAndroid Build Coastguard Worker result = ixheaac_mult32x16in32_shl(a, b);
63*15dc779aSAndroid Build Coastguard Worker }
64*15dc779aSAndroid Build Coastguard Worker
65*15dc779aSAndroid Build Coastguard Worker return (result);
66*15dc779aSAndroid Build Coastguard Worker }
67*15dc779aSAndroid Build Coastguard Worker
ixheaac_mult32_shl(WORD32 a,WORD32 b)68*15dc779aSAndroid Build Coastguard Worker static PLATFORM_INLINE WORD32 ixheaac_mult32_shl(WORD32 a, WORD32 b) {
69*15dc779aSAndroid Build Coastguard Worker WORD32 result;
70*15dc779aSAndroid Build Coastguard Worker WORD64 temp_result;
71*15dc779aSAndroid Build Coastguard Worker
72*15dc779aSAndroid Build Coastguard Worker temp_result = (WORD64)a * (WORD64)b;
73*15dc779aSAndroid Build Coastguard Worker result = (WORD32)(temp_result >> 32);
74*15dc779aSAndroid Build Coastguard Worker
75*15dc779aSAndroid Build Coastguard Worker return (result << 1);
76*15dc779aSAndroid Build Coastguard Worker }
77*15dc779aSAndroid Build Coastguard Worker
ixheaac_mult32(WORD32 a,WORD32 b)78*15dc779aSAndroid Build Coastguard Worker static PLATFORM_INLINE WORD32 ixheaac_mult32(WORD32 a, WORD32 b) {
79*15dc779aSAndroid Build Coastguard Worker WORD32 result;
80*15dc779aSAndroid Build Coastguard Worker WORD64 temp_result;
81*15dc779aSAndroid Build Coastguard Worker
82*15dc779aSAndroid Build Coastguard Worker temp_result = (WORD64)a * (WORD64)b;
83*15dc779aSAndroid Build Coastguard Worker result = (WORD32)(temp_result >> 32);
84*15dc779aSAndroid Build Coastguard Worker
85*15dc779aSAndroid Build Coastguard Worker return (result);
86*15dc779aSAndroid Build Coastguard Worker }
87*15dc779aSAndroid Build Coastguard Worker
ixheaac_mult32_shl_sat(WORD32 a,WORD32 b)88*15dc779aSAndroid Build Coastguard Worker static PLATFORM_INLINE WORD32 ixheaac_mult32_shl_sat(WORD32 a, WORD32 b) {
89*15dc779aSAndroid Build Coastguard Worker WORD32 result;
90*15dc779aSAndroid Build Coastguard Worker
91*15dc779aSAndroid Build Coastguard Worker if (a == (WORD32)0x80000000 && b == (WORD32)0x80000000) {
92*15dc779aSAndroid Build Coastguard Worker result = 0x7fffffff;
93*15dc779aSAndroid Build Coastguard Worker } else {
94*15dc779aSAndroid Build Coastguard Worker result = ixheaac_mult32_shl(a, b);
95*15dc779aSAndroid Build Coastguard Worker }
96*15dc779aSAndroid Build Coastguard Worker
97*15dc779aSAndroid Build Coastguard Worker return (result);
98*15dc779aSAndroid Build Coastguard Worker }
99*15dc779aSAndroid Build Coastguard Worker
ixheaac_mac32x16in32(WORD32 a,WORD32 b,WORD16 c)100*15dc779aSAndroid Build Coastguard Worker static PLATFORM_INLINE WORD32 ixheaac_mac32x16in32(WORD32 a, WORD32 b, WORD16 c) {
101*15dc779aSAndroid Build Coastguard Worker WORD32 result;
102*15dc779aSAndroid Build Coastguard Worker
103*15dc779aSAndroid Build Coastguard Worker result = a + ixheaac_mult32x16in32(b, c);
104*15dc779aSAndroid Build Coastguard Worker
105*15dc779aSAndroid Build Coastguard Worker return (result);
106*15dc779aSAndroid Build Coastguard Worker }
107*15dc779aSAndroid Build Coastguard Worker
ixheaac_mac32x16in32_shl(WORD32 a,WORD32 b,WORD16 c)108*15dc779aSAndroid Build Coastguard Worker static PLATFORM_INLINE WORD32 ixheaac_mac32x16in32_shl(WORD32 a, WORD32 b, WORD16 c) {
109*15dc779aSAndroid Build Coastguard Worker WORD32 result;
110*15dc779aSAndroid Build Coastguard Worker
111*15dc779aSAndroid Build Coastguard Worker result = a + ixheaac_mult32x16in32_shl(b, c);
112*15dc779aSAndroid Build Coastguard Worker
113*15dc779aSAndroid Build Coastguard Worker return (result);
114*15dc779aSAndroid Build Coastguard Worker }
115*15dc779aSAndroid Build Coastguard Worker
ixheaac_mac32x16in32_shl_sat(WORD32 a,WORD32 b,WORD16 c)116*15dc779aSAndroid Build Coastguard Worker static PLATFORM_INLINE WORD32 ixheaac_mac32x16in32_shl_sat(WORD32 a, WORD32 b, WORD16 c) {
117*15dc779aSAndroid Build Coastguard Worker WORD32 result;
118*15dc779aSAndroid Build Coastguard Worker
119*15dc779aSAndroid Build Coastguard Worker result = ixheaac_add32_sat(a, ixheaac_mult32x16in32_shl_sat(b, c));
120*15dc779aSAndroid Build Coastguard Worker
121*15dc779aSAndroid Build Coastguard Worker return (result);
122*15dc779aSAndroid Build Coastguard Worker }
123*15dc779aSAndroid Build Coastguard Worker
ixheaac_mac32(WORD32 a,WORD32 b,WORD32 c)124*15dc779aSAndroid Build Coastguard Worker static PLATFORM_INLINE WORD32 ixheaac_mac32(WORD32 a, WORD32 b, WORD32 c) {
125*15dc779aSAndroid Build Coastguard Worker WORD32 result;
126*15dc779aSAndroid Build Coastguard Worker
127*15dc779aSAndroid Build Coastguard Worker result = a + ixheaac_mult32(b, c);
128*15dc779aSAndroid Build Coastguard Worker
129*15dc779aSAndroid Build Coastguard Worker return (result);
130*15dc779aSAndroid Build Coastguard Worker }
131*15dc779aSAndroid Build Coastguard Worker
ixheaac_mult32x32in64(WORD32 a,WORD32 b)132*15dc779aSAndroid Build Coastguard Worker static PLATFORM_INLINE WORD64 ixheaac_mult32x32in64(WORD32 a, WORD32 b) {
133*15dc779aSAndroid Build Coastguard Worker WORD64 result;
134*15dc779aSAndroid Build Coastguard Worker
135*15dc779aSAndroid Build Coastguard Worker result = (WORD64)a * (WORD64)b;
136*15dc779aSAndroid Build Coastguard Worker
137*15dc779aSAndroid Build Coastguard Worker return (result);
138*15dc779aSAndroid Build Coastguard Worker }
139*15dc779aSAndroid Build Coastguard Worker
ixheaac_mac32x32in64(WORD64 sum,WORD32 a,WORD32 b)140*15dc779aSAndroid Build Coastguard Worker static PLATFORM_INLINE WORD64 ixheaac_mac32x32in64(WORD64 sum, WORD32 a, WORD32 b) {
141*15dc779aSAndroid Build Coastguard Worker sum += (WORD64)a * (WORD64)b;
142*15dc779aSAndroid Build Coastguard Worker
143*15dc779aSAndroid Build Coastguard Worker return (sum);
144*15dc779aSAndroid Build Coastguard Worker }
145*15dc779aSAndroid Build Coastguard Worker
ixheaac_mac32x32in64_7(const WORD32 * a,const WORD16 * b)146*15dc779aSAndroid Build Coastguard Worker static PLATFORM_INLINE WORD64 ixheaac_mac32x32in64_7(const WORD32 *a, const WORD16 *b) {
147*15dc779aSAndroid Build Coastguard Worker WORD64 sum;
148*15dc779aSAndroid Build Coastguard Worker sum = (WORD64)a[0] * (WORD64)b[0];
149*15dc779aSAndroid Build Coastguard Worker sum += (WORD64)a[1] * (WORD64)b[1];
150*15dc779aSAndroid Build Coastguard Worker sum += (WORD64)a[2] * (WORD64)b[2];
151*15dc779aSAndroid Build Coastguard Worker sum += (WORD64)a[3] * (WORD64)b[3];
152*15dc779aSAndroid Build Coastguard Worker sum += (WORD64)a[4] * (WORD64)b[4];
153*15dc779aSAndroid Build Coastguard Worker sum += (WORD64)a[5] * (WORD64)b[5];
154*15dc779aSAndroid Build Coastguard Worker sum += (WORD64)a[6] * (WORD64)b[6];
155*15dc779aSAndroid Build Coastguard Worker
156*15dc779aSAndroid Build Coastguard Worker return (sum);
157*15dc779aSAndroid Build Coastguard Worker }
158*15dc779aSAndroid Build Coastguard Worker
ixheaac_mac32x32in64_n(WORD64 sum,const WORD32 * a,const WORD16 * b,WORD32 n)159*15dc779aSAndroid Build Coastguard Worker static PLATFORM_INLINE WORD64 ixheaac_mac32x32in64_n(WORD64 sum, const WORD32 *a, const WORD16 *b,
160*15dc779aSAndroid Build Coastguard Worker WORD32 n) {
161*15dc779aSAndroid Build Coastguard Worker WORD32 k;
162*15dc779aSAndroid Build Coastguard Worker
163*15dc779aSAndroid Build Coastguard Worker sum += (WORD64)a[0] * (WORD64)b[0];
164*15dc779aSAndroid Build Coastguard Worker for (k = 1; k < n; k++) sum += (WORD64)a[k] * (WORD64)b[k];
165*15dc779aSAndroid Build Coastguard Worker return (sum);
166*15dc779aSAndroid Build Coastguard Worker }
167*15dc779aSAndroid Build Coastguard Worker
ixheaac_mult64(WORD32 a,WORD32 b)168*15dc779aSAndroid Build Coastguard Worker static PLATFORM_INLINE WORD64 ixheaac_mult64(WORD32 a, WORD32 b) {
169*15dc779aSAndroid Build Coastguard Worker WORD64 result;
170*15dc779aSAndroid Build Coastguard Worker result = (WORD64)a * (WORD64)b;
171*15dc779aSAndroid Build Coastguard Worker return (result);
172*15dc779aSAndroid Build Coastguard Worker }
173*15dc779aSAndroid Build Coastguard Worker
ixheaac_mult64_sat(WORD64 a,WORD64 b)174*15dc779aSAndroid Build Coastguard Worker static PLATFORM_INLINE WORD64 ixheaac_mult64_sat(WORD64 a, WORD64 b) {
175*15dc779aSAndroid Build Coastguard Worker WORD64 result;
176*15dc779aSAndroid Build Coastguard Worker
177*15dc779aSAndroid Build Coastguard Worker if (a > 0 && b > 0 && a > MAX_64 / b) return MAX_64;
178*15dc779aSAndroid Build Coastguard Worker if (a < 0 && b > 0 && a < MIN_64 / b) return MIN_64;
179*15dc779aSAndroid Build Coastguard Worker if (a > 0 && b < 0 && b < MIN_64 / a) return MIN_64;
180*15dc779aSAndroid Build Coastguard Worker if (a < 0 && b < 0 && a < MAX_64 / b) return MAX_64;
181*15dc779aSAndroid Build Coastguard Worker
182*15dc779aSAndroid Build Coastguard Worker result = a * b;
183*15dc779aSAndroid Build Coastguard Worker return (result);
184*15dc779aSAndroid Build Coastguard Worker }
185*15dc779aSAndroid Build Coastguard Worker
ixheaac_add64_sat(WORD64 a,WORD64 b)186*15dc779aSAndroid Build Coastguard Worker static PLATFORM_INLINE WORD64 ixheaac_add64_sat(WORD64 a, WORD64 b) {
187*15dc779aSAndroid Build Coastguard Worker WORD64 result, comp;
188*15dc779aSAndroid Build Coastguard Worker result = (a < 0) ? MIN_64 : MAX_64;
189*15dc779aSAndroid Build Coastguard Worker comp = result - a;
190*15dc779aSAndroid Build Coastguard Worker if ((a < 0) == (b > comp)) result = a + b;
191*15dc779aSAndroid Build Coastguard Worker
192*15dc779aSAndroid Build Coastguard Worker return (result);
193*15dc779aSAndroid Build Coastguard Worker }
194*15dc779aSAndroid Build Coastguard Worker
ixheaac_sat64_32(WORD64 a)195*15dc779aSAndroid Build Coastguard Worker static PLATFORM_INLINE WORD32 ixheaac_sat64_32(WORD64 a) {
196*15dc779aSAndroid Build Coastguard Worker WORD32 result;
197*15dc779aSAndroid Build Coastguard Worker if (a >= MAX_32) {
198*15dc779aSAndroid Build Coastguard Worker result = MAX_32;
199*15dc779aSAndroid Build Coastguard Worker } else if (a <= MIN_32) {
200*15dc779aSAndroid Build Coastguard Worker result = MIN_32;
201*15dc779aSAndroid Build Coastguard Worker } else {
202*15dc779aSAndroid Build Coastguard Worker result = (WORD32)a;
203*15dc779aSAndroid Build Coastguard Worker }
204*15dc779aSAndroid Build Coastguard Worker return (result);
205*15dc779aSAndroid Build Coastguard Worker }
206*15dc779aSAndroid Build Coastguard Worker
ixheaac_add64(WORD64 a,WORD64 b)207*15dc779aSAndroid Build Coastguard Worker static PLATFORM_INLINE WORD64 ixheaac_add64(WORD64 a, WORD64 b) {
208*15dc779aSAndroid Build Coastguard Worker WORD64 result;
209*15dc779aSAndroid Build Coastguard Worker result = a + b;
210*15dc779aSAndroid Build Coastguard Worker return (result);
211*15dc779aSAndroid Build Coastguard Worker }
212*15dc779aSAndroid Build Coastguard Worker
ixheaac_sub64(WORD64 a,WORD64 b)213*15dc779aSAndroid Build Coastguard Worker static PLATFORM_INLINE WORD64 ixheaac_sub64(WORD64 a, WORD64 b) {
214*15dc779aSAndroid Build Coastguard Worker WORD64 diff;
215*15dc779aSAndroid Build Coastguard Worker
216*15dc779aSAndroid Build Coastguard Worker diff = (WORD64)a - (WORD64)b;
217*15dc779aSAndroid Build Coastguard Worker
218*15dc779aSAndroid Build Coastguard Worker return diff;
219*15dc779aSAndroid Build Coastguard Worker }
220*15dc779aSAndroid Build Coastguard Worker
ixheaac_sub64_sat(WORD64 a,WORD64 b)221*15dc779aSAndroid Build Coastguard Worker static PLATFORM_INLINE WORD64 ixheaac_sub64_sat(WORD64 a, WORD64 b) {
222*15dc779aSAndroid Build Coastguard Worker WORD64 diff;
223*15dc779aSAndroid Build Coastguard Worker
224*15dc779aSAndroid Build Coastguard Worker diff = ixheaac_sub64(a, b);
225*15dc779aSAndroid Build Coastguard Worker
226*15dc779aSAndroid Build Coastguard Worker if ((((WORD64)a ^ (WORD64)b) & (WORD64)MIN_64) != 0) {
227*15dc779aSAndroid Build Coastguard Worker if (((WORD64)diff ^ (WORD64)a) & (WORD64)MIN_64) {
228*15dc779aSAndroid Build Coastguard Worker diff = (a < 0L) ? MIN_64 : MAX_64;
229*15dc779aSAndroid Build Coastguard Worker }
230*15dc779aSAndroid Build Coastguard Worker }
231*15dc779aSAndroid Build Coastguard Worker
232*15dc779aSAndroid Build Coastguard Worker return (diff);
233*15dc779aSAndroid Build Coastguard Worker }
234*15dc779aSAndroid Build Coastguard Worker
ixheaac_mul32_sh(WORD32 a,WORD32 b,WORD8 shift)235*15dc779aSAndroid Build Coastguard Worker static PLATFORM_INLINE WORD32 ixheaac_mul32_sh(WORD32 a, WORD32 b, WORD8 shift) {
236*15dc779aSAndroid Build Coastguard Worker WORD32 result;
237*15dc779aSAndroid Build Coastguard Worker WORD64 temp_result;
238*15dc779aSAndroid Build Coastguard Worker
239*15dc779aSAndroid Build Coastguard Worker temp_result = (WORD64)a * (WORD64)b;
240*15dc779aSAndroid Build Coastguard Worker result = (WORD32)(temp_result >> shift);
241*15dc779aSAndroid Build Coastguard Worker
242*15dc779aSAndroid Build Coastguard Worker return (result);
243*15dc779aSAndroid Build Coastguard Worker }
244*15dc779aSAndroid Build Coastguard Worker
ixheaac_mult32x16hin32_shl(WORD32 a,WORD32 b)245*15dc779aSAndroid Build Coastguard Worker static PLATFORM_INLINE WORD32 ixheaac_mult32x16hin32_shl(WORD32 a, WORD32 b) {
246*15dc779aSAndroid Build Coastguard Worker WORD32 product;
247*15dc779aSAndroid Build Coastguard Worker WORD64 temp_product;
248*15dc779aSAndroid Build Coastguard Worker
249*15dc779aSAndroid Build Coastguard Worker temp_product = (WORD64)a * (WORD64)(b >> 16);
250*15dc779aSAndroid Build Coastguard Worker product = (WORD32)(temp_product >> 16);
251*15dc779aSAndroid Build Coastguard Worker
252*15dc779aSAndroid Build Coastguard Worker return (product << 1);
253*15dc779aSAndroid Build Coastguard Worker }
254*15dc779aSAndroid Build Coastguard Worker
255*15dc779aSAndroid Build Coastguard Worker #endif /* IXHEAAC_BASIC_OPS40_H */
256