Home | History | Annotate | Download | only in decoder
      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 
     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 
     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 
     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 
     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 
     67 static PLATFORM_INLINE WORD32 ixheaacd_shl32_sat(WORD32 a, WORD b) {
     68   WORD32 out_val = a;
     69   for (; b > 0; b--) {
     70     if (a > (WORD32)0X3fffffffL) {
     71       out_val = MAX_32;
     72       break;
     73     } else if (a < (WORD32)0xc0000000L) {
     74       out_val = MIN_32;
     75       break;
     76     }
     77 
     78     a = ixheaacd_shl32(a, 1);
     79     out_val = a;
     80   }
     81   return (out_val);
     82 }
     83 
     84 static PLATFORM_INLINE WORD32 ixheaacd_shl32_dir(WORD32 a, WORD b) {
     85   WORD32 out_val;
     86 
     87   if (b < 0) {
     88     out_val = ixheaacd_shr32(a, -b);
     89   } else {
     90     out_val = ixheaacd_shl32(a, b);
     91   }
     92 
     93   return out_val;
     94 }
     95 
     96 static PLATFORM_INLINE WORD32 ixheaacd_shl32_dir_sat(WORD32 a, WORD b) {
     97   WORD32 out_val;
     98 
     99   if (b < 0) {
    100     out_val = ixheaacd_shr32(a, -b);
    101   } else {
    102     out_val = ixheaacd_shl32_sat(a, b);
    103   }
    104 
    105   return out_val;
    106 }
    107 
    108 static PLATFORM_INLINE WORD32 ixheaacd_shr32_dir(WORD32 a, WORD b) {
    109   WORD32 out_val;
    110 
    111   if (b < 0) {
    112     out_val = ixheaacd_shl32(a, -b);
    113   } else {
    114     out_val = ixheaacd_shr32(a, b);
    115   }
    116 
    117   return out_val;
    118 }
    119 
    120 static PLATFORM_INLINE WORD32 shr32_dir_sat(WORD32 a, WORD b) {
    121   WORD32 out_val;
    122 
    123   if (b < 0) {
    124     out_val = ixheaacd_shl32_sat(a, -b);
    125   } else {
    126     out_val = ixheaacd_shr32(a, b);
    127   }
    128 
    129   return out_val;
    130 }
    131 
    132 static PLATFORM_INLINE WORD32 ixheaacd_mult16x16in32(WORD16 a, WORD16 b) {
    133   WORD32 product;
    134 
    135   product = (WORD32)a * (WORD32)b;
    136 
    137   return product;
    138 }
    139 
    140 static PLATFORM_INLINE WORD32 mult16x16in32_32(WORD32 a, WORD32 b) {
    141   WORD32 product;
    142 
    143   product = (WORD32)a * (WORD32)b;
    144 
    145   return product;
    146 }
    147 
    148 static PLATFORM_INLINE WORD32 ixheaacd_mult16x16in32_shl(WORD16 a, WORD16 b) {
    149   WORD32 product;
    150 
    151   product = ixheaacd_shl32(ixheaacd_mult16x16in32(a, b), 1);
    152 
    153   return product;
    154 }
    155 
    156 static PLATFORM_INLINE WORD32 ixheaacd_mult16x16in32_shl_sat(WORD16 a,
    157                                                              WORD16 b) {
    158   WORD32 product;
    159   product = (WORD32)a * (WORD32)b;
    160   if (product != (WORD32)0x40000000L) {
    161     product = ixheaacd_shl32(product, 1);
    162   } else {
    163     product = MAX_32;
    164   }
    165   return product;
    166 }
    167 
    168 static PLATFORM_INLINE WORD32 ixheaacd_add32(WORD32 a, WORD32 b) {
    169   WORD32 sum;
    170 
    171   sum = (WORD32)a + (WORD32)b;
    172 
    173   return sum;
    174 }
    175 
    176 static PLATFORM_INLINE WORD32 ixheaacd_sub32(WORD32 a, WORD32 b) {
    177   WORD32 diff;
    178 
    179   diff = (WORD32)a - (WORD32)b;
    180 
    181   return diff;
    182 }
    183 
    184 static PLATFORM_INLINE WORD32 ixheaacd_add32_sat(WORD32 a, WORD32 b) {
    185   WORD64 sum;
    186 
    187   sum = (WORD64)a + (WORD64)b;
    188 
    189   if ((((WORD32)a ^ (WORD32)b) & (WORD32)MIN_32) == 0) {
    190     if (((WORD32)sum ^ (WORD32)a) & (WORD32)MIN_32) {
    191       sum = (a < 0) ? MIN_32 : MAX_32;
    192     }
    193   }
    194 
    195   return (WORD32)sum;
    196 }
    197 
    198 static PLATFORM_INLINE WORD32 ixheaacd_add32_sat3(WORD32 a, WORD32 b,
    199                                                   WORD32 c) {
    200   WORD64 sum;
    201 
    202   sum = (WORD64)a + (WORD64)b;
    203 
    204   sum = (WORD64)sum + (WORD64)c;
    205 
    206   if (sum > MAX_32) {
    207     sum = MAX_32;
    208   }
    209   if (sum < MIN_32) {
    210     sum = MIN_32;
    211   }
    212 
    213   return (WORD32)sum;
    214 }
    215 
    216 static PLATFORM_INLINE WORD32 ixheaacd_sub32_sat(WORD32 a, WORD32 b) {
    217   WORD64 diff;
    218 
    219   diff = (WORD64)a - (WORD64)b;
    220 
    221   if ((((WORD32)a ^ (WORD32)b) & (WORD32)MIN_32) != 0) {
    222     if (((WORD32)diff ^ (WORD32)a) & (WORD32)MIN_32) {
    223       diff = (a < 0L) ? MIN_32 : MAX_32;
    224     }
    225   }
    226 
    227   return (WORD32)diff;
    228 }
    229 
    230 static PLATFORM_INLINE WORD ixheaacd_norm32(WORD32 a) {
    231   WORD norm_val;
    232 
    233   if (a == 0) {
    234     norm_val = 31;
    235   } else {
    236     if (a == (WORD32)0xffffffffL) {
    237       norm_val = 31;
    238     } else {
    239       if (a < 0) {
    240         a = ~a;
    241       }
    242       for (norm_val = 0; a < (WORD32)0x40000000L; norm_val++) {
    243         a <<= 1;
    244       }
    245     }
    246   }
    247 
    248   return norm_val;
    249 }
    250 
    251 static PLATFORM_INLINE WORD ixheaacd_pnorm32(WORD32 a) {
    252   WORD norm_val;
    253 
    254   if (a == 0) {
    255     norm_val = 31;
    256   } else {
    257     for (norm_val = 0; a < (WORD32)0x40000000L; norm_val++) {
    258       a <<= 1;
    259     }
    260   }
    261 
    262   return norm_val;
    263 }
    264 
    265 static PLATFORM_INLINE WORD bin_expo32(WORD32 a) {
    266   WORD bin_expo_val;
    267 
    268   bin_expo_val = 31 - ixheaacd_norm32(a);
    269 
    270   return bin_expo_val;
    271 }
    272 
    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 
    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 
    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 
    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 
    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 
    330 static PLATFORM_INLINE WORD32 div32(WORD32 a, WORD32 b, WORD *q_format) {
    331   WORD32 quotient;
    332   UWORD32 mantissa_nr, mantissa_dr;
    333   WORD16 sign = 0;
    334 
    335   LOOPINDEX i;
    336   WORD q_nr, q_dr;
    337 
    338   mantissa_nr = a;
    339   mantissa_dr = b;
    340   quotient = 0;
    341 
    342   if ((a < 0) && (0 != b)) {
    343     a = -a;
    344     sign = (WORD16)(sign ^ -1);
    345   }
    346 
    347   if (b < 0) {
    348     b = -b;
    349     sign = (WORD16)(sign ^ -1);
    350   }
    351 
    352   if (0 == b) {
    353     *q_format = 0;
    354     return (a);
    355   }
    356 
    357   quotient = 0;
    358 
    359   q_nr = ixheaacd_norm32(a);
    360   mantissa_nr = (UWORD32)a << (q_nr);
    361   q_dr = ixheaacd_norm32(b);
    362   mantissa_dr = (UWORD32)b << (q_dr);
    363   *q_format = (WORD)(30 + q_nr - q_dr);
    364 
    365   for (i = 0; i < 31; i++) {
    366     quotient = quotient << 1;
    367 
    368     if (mantissa_nr >= mantissa_dr) {
    369       mantissa_nr = mantissa_nr - mantissa_dr;
    370       quotient += 1;
    371     }
    372 
    373     mantissa_nr = (UWORD32)mantissa_nr << 1;
    374   }
    375 
    376   if (sign < 0) {
    377     quotient = -quotient;
    378   }
    379 
    380   return quotient;
    381 }
    382 
    383 static PLATFORM_INLINE WORD32 ixheaacd_mac16x16in32(WORD32 a, WORD16 b,
    384                                                     WORD16 c) {
    385   WORD32 acc;
    386 
    387   acc = ixheaacd_mult16x16in32(b, c);
    388 
    389   acc = ixheaacd_add32(a, acc);
    390 
    391   return acc;
    392 }
    393 
    394 static PLATFORM_INLINE WORD32 mac16x16hin32(WORD32 a, WORD32 b, WORD32 c) {
    395   WORD32 acc;
    396 
    397   acc = ixheaacd_mult16x16in32((WORD16)b, (WORD16)(c >> 16));
    398 
    399   acc = ixheaacd_add32(a, acc);
    400 
    401   return acc;
    402 }
    403 
    404 static PLATFORM_INLINE WORD32 ixheaacd_mac16x16in32_shl(WORD32 a, WORD16 b,
    405                                                         WORD16 c) {
    406   WORD32 acc;
    407 
    408   acc = ixheaacd_mult16x16in32_shl(b, c);
    409 
    410   acc = ixheaacd_add32(a, acc);
    411 
    412   return acc;
    413 }
    414 
    415 static PLATFORM_INLINE WORD32 ixheaacd_mac16x16in32_shl_sat(WORD32 a, WORD16 b,
    416                                                             WORD16 c) {
    417   WORD32 acc;
    418 
    419   acc = ixheaacd_mult16x16in32_shl_sat(b, c);
    420 
    421   acc = ixheaacd_add32_sat(a, acc);
    422 
    423   return acc;
    424 }
    425 
    426 static PLATFORM_INLINE WORD32 msu16x16in32(WORD32 a, WORD16 b, WORD16 c) {
    427   WORD32 acc;
    428 
    429   acc = ixheaacd_mult16x16in32(b, c);
    430 
    431   acc = ixheaacd_sub32(a, acc);
    432 
    433   return acc;
    434 }
    435 
    436 static PLATFORM_INLINE WORD32 msu16x16in32_shl(WORD32 a, WORD16 b, WORD16 c) {
    437   WORD32 acc;
    438 
    439   acc = ixheaacd_mult16x16in32_shl(b, c);
    440 
    441   acc = ixheaacd_sub32(a, acc);
    442 
    443   return acc;
    444 }
    445 
    446 static PLATFORM_INLINE WORD32 msu16x16in32_shl_sat(WORD32 a, WORD16 b,
    447                                                    WORD16 c) {
    448   WORD32 acc;
    449 
    450   acc = ixheaacd_mult16x16in32_shl_sat(b, c);
    451 
    452   acc = ixheaacd_sub32_sat(a, acc);
    453 
    454   return acc;
    455 }
    456 
    457 static PLATFORM_INLINE WORD32 add32_shr(WORD32 a, WORD32 b) {
    458   WORD32 sum;
    459 
    460   a = ixheaacd_shr32(a, 1);
    461   b = ixheaacd_shr32(b, 1);
    462 
    463   sum = ixheaacd_add32(a, b);
    464 
    465   return sum;
    466 }
    467 
    468 static PLATFORM_INLINE WORD32 sub32_shr(WORD32 a, WORD32 b) {
    469   WORD32 diff;
    470 
    471   a = ixheaacd_shr32(a, 1);
    472   b = ixheaacd_shr32(b, 1);
    473 
    474   diff = ixheaacd_sub32(a, b);
    475 
    476   return diff;
    477 }
    478 #endif
    479