Home | History | Annotate | Download | only in basic_op
      1 /*
      2  ** Copyright 2003-2010, VisualOn, Inc.
      3  **
      4  ** Licensed under the Apache License, Version 2.0 (the "License");
      5  ** you may not use this file except in compliance with the License.
      6  ** You may obtain a copy of the License at
      7  **
      8  **     http://www.apache.org/licenses/LICENSE-2.0
      9  **
     10  ** Unless required by applicable law or agreed to in writing, software
     11  ** distributed under the License is distributed on an "AS IS" BASIS,
     12  ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  ** See the License for the specific language governing permissions and
     14  ** limitations under the License.
     15  */
     16 /*******************************************************************************
     17 	File:		basicop2.h
     18 
     19 	Content:	Constants , Globals and Basic arithmetic operators.
     20 
     21 *******************************************************************************/
     22 
     23 #ifndef __BASIC_OP_H
     24 #define __BASIC_OP_H
     25 
     26 #include "typedef.h"
     27 
     28 #define MAX_32 (Word32)0x7fffffffL
     29 #define MIN_32 (Word32)0x80000000L
     30 
     31 #define MAX_16 (Word16)0x7fff
     32 #define MIN_16 (Word16)0x8000
     33 #define ABS(a)	((a) >= 0) ? (a) : (-(a))
     34 
     35 /* Short abs,           1   */
     36 #define abs_s(x)       ((Word16)(((x) != MIN_16) ? (((x) >= 0) ? (x) : (-(x))) : MAX_16))
     37 
     38 /* 16 bit var1 -> MSB,     2 */
     39 #define L_deposit_h(x) (((Word32)(x)) << 16)
     40 
     41 
     42 /* 16 bit var1 -> LSB,     2 */
     43 #define L_deposit_l(x) ((Word32)(x))
     44 
     45 
     46 /* Long abs,              3  */
     47 #define L_abs(x) (((x) != MIN_32) ? (((x) >= 0) ? (x) : (-(x))) : MAX_32)
     48 
     49 
     50 /* Short negate,        1   */
     51 #define negate(var1) ((Word16)(((var1) == MIN_16) ? MAX_16 : (-(var1))))
     52 
     53 
     54 /* Long negate,     2 */
     55 #define L_negate(L_var1) (((L_var1) == (MIN_32)) ? (MAX_32) : (-(L_var1)))
     56 
     57 
     58 #define MULHIGH(A,B) (int)(((Word64)(A)*(Word64)(B)) >> 32)
     59 #define fixmul(a, b) (int)((((Word64)(a)*(Word64)(b)) >> 32) << 1)
     60 
     61 
     62 #if  (SATRUATE_IS_INLINE)
     63 __inline Word16 saturate(Word32 L_var1);
     64 #else
     65 Word16 saturate(Word32 L_var1);
     66 #endif
     67 
     68 /* Short shift left,    1   */
     69 #if (SHL_IS_INLINE)
     70 __inline Word16 shl (Word16 var1, Word16 var2);
     71 #else
     72 Word16 shl (Word16 var1, Word16 var2);
     73 #endif
     74 
     75 /* Short shift right,   1   */
     76 #if (SHR_IS_INLINE)
     77 __inline Word16 shr (Word16 var1, Word16 var2);
     78 #else
     79 Word16 shr (Word16 var1, Word16 var2);
     80 #endif
     81 
     82 #if (L_MULT_IS_INLINE)
     83 __inline Word32 L_mult(Word16 var1, Word16 var2);
     84 #else
     85 Word32 L_mult(Word16 var1, Word16 var2);
     86 #endif
     87 
     88 /* Msu,  1  */
     89 #if (L_MSU_IS_INLINE)
     90 __inline Word32 L_msu (Word32 L_var3, Word16 var1, Word16 var2);
     91 #else
     92 Word32 L_msu (Word32 L_var3, Word16 var1, Word16 var2);
     93 #endif
     94 
     95 /* Long sub,        2 */
     96 #if (L_SUB_IS_INLINE)
     97 __inline Word32 L_sub(Word32 L_var1, Word32 L_var2);
     98 #else
     99 Word32 L_sub(Word32 L_var1, Word32 L_var2);
    100 #endif
    101 
    102 /* Long shift left, 2 */
    103 #if (L_SHL_IS_INLINE)
    104 __inline Word32 L_shl (Word32 L_var1, Word16 var2);
    105 #else
    106 Word32 L_shl (Word32 L_var1, Word16 var2);
    107 #endif
    108 
    109 /* Long shift right, 2*/
    110 #if (L_SHR_IS_INLINE)
    111 __inline Word32 L_shr (Word32 L_var1, Word16 var2);
    112 #else
    113 Word32 L_shr (Word32 L_var1, Word16 var2);
    114 #endif
    115 
    116 /* Short add,           1   */
    117 #if (ADD_IS_INLINE)
    118 __inline Word16 add (Word16 var1, Word16 var2);
    119 #else
    120 Word16 add (Word16 var1, Word16 var2);
    121 #endif
    122 
    123 /* Short sub,           1   */
    124 #if (SUB_IS_INLINE)
    125 __inline Word16 sub(Word16 var1, Word16 var2);
    126 #else
    127 Word16 sub(Word16 var1, Word16 var2);
    128 #endif
    129 
    130 /* Short division,       18  */
    131 #if (DIV_S_IS_INLINE)
    132 __inline Word16 div_s (Word16 var1, Word16 var2);
    133 #else
    134 Word16 div_s (Word16 var1, Word16 var2);
    135 #endif
    136 
    137 /* Short mult,          1   */
    138 #if (MULT_IS_INLINE)
    139 __inline Word16 mult (Word16 var1, Word16 var2);
    140 #else
    141 Word16 mult (Word16 var1, Word16 var2);
    142 #endif
    143 
    144 /* Short norm,           15  */
    145 #if (NORM_S_IS_INLINE)
    146 __inline Word16 norm_s (Word16 var1);
    147 #else
    148 Word16 norm_s (Word16 var1);
    149 #endif
    150 
    151 /* Long norm,            30  */
    152 #if (NORM_L_IS_INLINE)
    153 __inline Word16 norm_l (Word32 L_var1);
    154 #else
    155 Word16 norm_l (Word32 L_var1);
    156 #endif
    157 
    158 /* Round,               1   */
    159 #if (ROUND_IS_INLINE)
    160 __inline Word16 round16(Word32 L_var1);
    161 #else
    162 Word16 round16(Word32 L_var1);
    163 #endif
    164 
    165 /* Mac,  1  */
    166 #if (L_MAC_IS_INLINE)
    167 __inline Word32 L_mac (Word32 L_var3, Word16 var1, Word16 var2);
    168 #else
    169 Word32 L_mac (Word32 L_var3, Word16 var1, Word16 var2);
    170 #endif
    171 
    172 #if (L_ADD_IS_INLINE)
    173 __inline Word32 L_add (Word32 L_var1, Word32 L_var2);
    174 #else
    175 Word32 L_add (Word32 L_var1, Word32 L_var2);
    176 #endif
    177 
    178 /* Extract high,        1   */
    179 #if (EXTRACT_H_IS_INLINE)
    180 __inline Word16 extract_h (Word32 L_var1);
    181 #else
    182 Word16 extract_h (Word32 L_var1);
    183 #endif
    184 
    185 /* Extract low,         1   */
    186 #if (EXTRACT_L_IS_INLINE)
    187 __inline Word16 extract_l(Word32 L_var1);
    188 #else
    189 Word16 extract_l(Word32 L_var1);
    190 #endif
    191 
    192 /* Mult with round, 2 */
    193 #if (MULT_R_IS_INLINE)
    194 __inline Word16 mult_r(Word16 var1, Word16 var2);
    195 #else
    196 Word16 mult_r(Word16 var1, Word16 var2);
    197 #endif
    198 
    199 /* Shift right with round, 2           */
    200 #if (SHR_R_IS_INLINE)
    201 __inline Word16 shr_r (Word16 var1, Word16 var2);
    202 #else
    203 Word16 shr_r (Word16 var1, Word16 var2);
    204 #endif
    205 
    206 /* Mac with rounding,2 */
    207 #if (MAC_R_IS_INLINE)
    208 __inline Word16 mac_r (Word32 L_var3, Word16 var1, Word16 var2);
    209 #else
    210 Word16 mac_r (Word32 L_var3, Word16 var1, Word16 var2);
    211 #endif
    212 
    213 /* Msu with rounding,2 */
    214 #if (MSU_R_IS_INLINE)
    215 __inline Word16 msu_r (Word32 L_var3, Word16 var1, Word16 var2);
    216 #else
    217 Word16 msu_r (Word32 L_var3, Word16 var1, Word16 var2);
    218 #endif
    219 
    220 /* Long shift right with round,  3             */
    221 #if (L_SHR_R_IS_INLINE)
    222 __inline Word32 L_shr_r (Word32 L_var1, Word16 var2);
    223 #else
    224 Word32 L_shr_r (Word32 L_var1, Word16 var2);
    225 #endif
    226 
    227 #if ARMV4_INASM
    228 __inline Word32 ASM_L_shr(Word32 L_var1, Word16 var2)
    229 {
    230 	return L_var1 >> var2;
    231 }
    232 
    233 __inline Word32 ASM_L_shl(Word32 L_var1, Word16 var2)
    234 {
    235 	Word32 result;
    236 	asm (
    237 		"MOV	%[result], %[L_var1], ASL %[var2] \n"
    238 		"TEQ	%[L_var1], %[result], ASR %[var2]\n"
    239 		"EORNE  %[result], %[mask], %[L_var1], ASR #31\n"
    240 		:[result]"=&r"(result)
    241 		:[L_var1]"r"(L_var1), [var2]"r"(var2), [mask]"r"(0x7fffffff)
    242 		);
    243 	return result;
    244 }
    245 
    246 __inline Word32 ASM_shr(Word32 L_var1, Word16 var2)
    247 {
    248 	Word32 result;
    249 	asm (
    250 		"CMP	%[var2], #15\n"
    251 		"MOVLT	%[result], %[L_var1], ASR %[var2]\n"
    252 		"MOVGE	%[result], %[L_var1], ASR #15\n"
    253 		:[result]"=r"(result)
    254 		:[L_var1]"r"(L_var1), [var2]"r"(var2)
    255 		);
    256 	return result;
    257 }
    258 
    259 __inline Word32 ASM_shl(Word32 L_var1, Word16 var2)
    260 {
    261 #if ARMV6_SAT
    262 	Word32 result;
    263 	asm (
    264 		"CMP	%[var2], #16\n"
    265 		"MOVLT  %[result], %[L_var1], ASL %[var2]\n"
    266 		"MOVGE  %[result], %[L_var1], ASL #16\n"
    267 		"SSAT   %[result], #16, %[result]\n"
    268 		:[result]"=r"(result)
    269 		:[L_var1]"r"(L_var1), [var2]"r"(var2)
    270 		);
    271 	return result;
    272 #else
    273 	Word32 result;
    274 	Word32 tmp;
    275 	asm (
    276 		"CMP	%[var2], #16\n"
    277 		"MOVLT  %[result], %[L_var1], ASL %[var2]\n"
    278 		"MOVGE  %[result], %[L_var1], ASL #16\n"
    279         "MOV    %[tmp], %[result], ASR #15\n"
    280         "TEQ    %[tmp], %[result], ASR #31 \n"
    281         "EORNE  %[result], %[mask], %[result],ASR #31"
    282 		:[result]"=&r"(result), [tmp]"=&r"(tmp)
    283 		:[L_var1]"r"(L_var1), [var2]"r"(var2), [mask]"r"(0x7fff)
    284 		);
    285 	return result;
    286 #endif
    287 }
    288 #endif
    289 
    290 /*___________________________________________________________________________
    291  |                                                                           |
    292  |   definitions for inline basic arithmetic operators                       |
    293  |___________________________________________________________________________|
    294 */
    295 #if (SATRUATE_IS_INLINE)
    296 __inline Word16 saturate(Word32 L_var1)
    297 {
    298 #if ARMV6_SAT
    299     Word16 result;
    300 	asm (
    301 		"SSAT %[result], #16, %[L_var1]"
    302 		: [result]"=r"(result)
    303 		: [L_var1]"r"(L_var1)
    304 		);
    305 	return result;
    306 #elif ARMV5TE_SAT
    307 	Word16 result;
    308 	Word32 tmp;
    309 	asm volatile (
    310 		"MOV	%[tmp], %[L_var1],ASR#15\n"
    311 		"TEQ	%[tmp], %[L_var1],ASR#31\n"
    312 		"EORNE	%[result], %[mask],%[L_var1],ASR#31\n"
    313 		"MOVEQ	%[result], %[L_var1]\n"
    314 		:[result]"=&r"(result), [tmp]"=&r"(tmp)
    315 		:[L_var1]"r"(L_var1), [mask]"r"(0x7fff)
    316 	);
    317 
    318 	return result;
    319 #else
    320     Word16 var_out;
    321 
    322     //var_out = (L_var1 > (Word32)0X00007fffL) ? (MAX_16) : ((L_var1 < (Word32)0xffff8000L) ? (MIN_16) : ((Word16)L_var1));
    323 
    324     if (L_var1 > 0X00007fffL)
    325     {
    326         var_out = MAX_16;
    327     }
    328     else if (L_var1 < (Word32) 0xffff8000L)
    329     {
    330         var_out = MIN_16;
    331     }
    332     else
    333     {
    334         var_out = extract_l(L_var1);
    335     }
    336 
    337     return (var_out);
    338 #endif
    339 }
    340 #endif
    341 
    342 /* Short shift left,    1   */
    343 #if (SHL_IS_INLINE)
    344 __inline Word16 shl (Word16 var1, Word16 var2)
    345 {
    346 #if ARMV5TE_SHL
    347 	if(var2>=0)
    348 	{
    349 		return ASM_shl( var1, var2);
    350 	}
    351 	else
    352 	{
    353 		return ASM_shr( var1, -var2);
    354 	}
    355 #else
    356     Word16 var_out;
    357     Word32 result;
    358 
    359     if (var2 < 0)
    360     {
    361         var_out = shr (var1, (Word16)-var2);
    362     }
    363     else
    364     {
    365         result = (Word32) var1 *((Word32) 1 << var2);
    366 
    367         if ((var2 > 15 && var1 != 0) || (result != (Word32) ((Word16) result)))
    368         {
    369             var_out = (Word16)((var1 > 0) ? MAX_16 : MIN_16);
    370         }
    371         else
    372         {
    373             var_out = extract_l(result);
    374         }
    375     }
    376     return (var_out);
    377 #endif
    378 }
    379 #endif
    380 
    381 /* Short shift right,   1   */
    382 #if (SHR_IS_INLINE)
    383 __inline Word16 shr (Word16 var1, Word16 var2)
    384 {
    385 #if ARMV5TE_SHR
    386 	if(var2>=0)
    387 	{
    388 		return  ASM_shr( var1, var2);
    389 	}
    390 	else
    391 	{
    392 		return  ASM_shl( var1, -var2);
    393 	}
    394 #else
    395     Word16 var_out;
    396 
    397     if (var2 < 0)
    398     {
    399         var_out = shl (var1, (Word16)-var2);
    400     }
    401     else
    402     {
    403         if (var2 >= 15)
    404         {
    405             var_out = (Word16)((var1 < 0) ? -1 : 0);
    406         }
    407         else
    408         {
    409             if (var1 < 0)
    410             {
    411                 var_out = (Word16)(~((~var1) >> var2));
    412             }
    413             else
    414             {
    415                 var_out = (Word16)(var1 >> var2);
    416             }
    417         }
    418     }
    419 
    420     return (var_out);
    421 #endif
    422 }
    423 #endif
    424 
    425 
    426 #if (L_MULT_IS_INLINE)
    427 __inline Word32 L_mult(Word16 var1, Word16 var2)
    428 {
    429 #if ARMV5TE_L_MULT
    430 	Word32 result;
    431 	asm (
    432 		"SMULBB %[result], %[var1], %[var2] \n"
    433 		"QADD %[result], %[result], %[result] \n"
    434 		:[result]"=r"(result)
    435 		:[var1]"r"(var1), [var2]"r"(var2)
    436 		);
    437 	return result;
    438 #else
    439     Word32 L_var_out;
    440 
    441     L_var_out = (Word32) var1 *(Word32) var2;
    442 
    443     if (L_var_out != (Word32) 0x40000000L)
    444     {
    445         L_var_out <<= 1;
    446     }
    447     else
    448     {
    449         L_var_out = MAX_32;
    450     }
    451     return (L_var_out);
    452 #endif
    453 }
    454 #endif
    455 
    456 #if (L_MSU_IS_INLINE)
    457 __inline Word32 L_msu (Word32 L_var3, Word16 var1, Word16 var2)
    458 {
    459 #if ARMV5TE_L_MSU
    460 	Word32 result;
    461 	asm (
    462 		"SMULBB %[result], %[var1], %[var2] \n"
    463 		"QDSUB %[result], %[L_var3], %[result]\n"
    464 		:[result]"=&r"(result)
    465 		:[L_var3]"r"(L_var3), [var1]"r"(var1), [var2]"r"(var2)
    466 		);
    467 	return result;
    468 #else
    469     Word32 L_var_out;
    470     Word32 L_product;
    471 
    472     L_product = L_mult(var1, var2);
    473     L_var_out = L_sub(L_var3, L_product);
    474     return (L_var_out);
    475 #endif
    476 }
    477 #endif
    478 
    479 #if (L_SUB_IS_INLINE)
    480 __inline Word32 L_sub(Word32 L_var1, Word32 L_var2)
    481 {
    482 #if ARMV5TE_L_SUB
    483 	Word32 result;
    484 	asm (
    485 		"QSUB %[result], %[L_var1], %[L_var2]\n"
    486 		:[result]"=r"(result)
    487 		:[L_var1]"r"(L_var1), [L_var2]"r"(L_var2)
    488 		);
    489 	return result;
    490 #else
    491     Word32 L_var_out;
    492 
    493     L_var_out = L_var1 - L_var2;
    494 
    495     if (((L_var1 ^ L_var2) & MIN_32) != 0)
    496     {
    497         if ((L_var_out ^ L_var1) & MIN_32)
    498         {
    499             L_var_out = (L_var1 < 0L) ? MIN_32 : MAX_32;
    500         }
    501     }
    502 
    503     return (L_var_out);
    504 #endif
    505 }
    506 #endif
    507 
    508 #if (L_SHL_IS_INLINE)
    509 __inline Word32 L_shl(Word32 L_var1, Word16 var2)
    510 {
    511 #if ARMV5TE_L_SHL
    512     if(var2>=0)
    513     {
    514         return  ASM_L_shl( L_var1, var2);
    515     }
    516     else
    517     {
    518         return  ASM_L_shr( L_var1, -var2);
    519     }
    520 #else
    521     if (var2 <= 0)
    522     {
    523         L_var1 = L_shr(L_var1, (Word16)-var2);
    524     }
    525     else
    526     {
    527         for (; var2 > 0; var2--)
    528         {
    529             if (L_var1 > (Word32) 0X3fffffffL)
    530             {
    531                 return MAX_32;
    532             }
    533             else
    534             {
    535                 if (L_var1 < (Word32) 0xc0000000L)
    536                 {
    537                     return MIN_32;
    538                 }
    539             }
    540             L_var1 <<= 1;
    541         }
    542     }
    543     return (L_var1);
    544 #endif
    545 }
    546 #endif
    547 
    548 #if (L_SHR_IS_INLINE)
    549 __inline Word32 L_shr (Word32 L_var1, Word16 var2)
    550 {
    551 #if ARMV5TE_L_SHR
    552 	if(var2>=0)
    553 	{
    554 		return ASM_L_shr( L_var1, var2);
    555 	}
    556 	else
    557 	{
    558 		return ASM_L_shl( L_var1, -var2);
    559 	}
    560 #else
    561     Word32 L_var_out;
    562 
    563     if (var2 < 0)
    564     {
    565         L_var_out = L_shl (L_var1, (Word16)-var2);
    566     }
    567     else
    568     {
    569         if (var2 >= 31)
    570         {
    571             L_var_out = (L_var1 < 0L) ? -1 : 0;
    572         }
    573         else
    574         {
    575             if (L_var1 < 0)
    576             {
    577                 L_var_out = ~((~L_var1) >> var2);
    578             }
    579             else
    580             {
    581                 L_var_out = L_var1 >> var2;
    582             }
    583         }
    584     }
    585     return (L_var_out);
    586 #endif
    587 }
    588 #endif
    589 
    590 /* Short add,           1   */
    591 #if (ADD_IS_INLINE)
    592 __inline Word16 add (Word16 var1, Word16 var2)
    593 {
    594 #if ARMV5TE_ADD
    595 	Word32 result;
    596 	Word32 tmp;
    597 	asm (
    598 		"ADD  %[result], %[var1], %[var2] \n"
    599 		"MOV  %[tmp], %[result], ASR #15 \n"
    600 		"TEQ  %[tmp], %[result], ASR #31 \n"
    601 		"EORNE %[result], %[mask], %[result], ASR #31"
    602 		:[result]"=&r"(result), [tmp]"=&r"(tmp)
    603 		:[var1]"r"(var1), [var2]"r"(var2), [mask]"r"(0x7fff)
    604 		);
    605 	return result;
    606 #else
    607     Word16 var_out;
    608     Word32 L_sum;
    609 
    610     L_sum = (Word32) var1 + var2;
    611     var_out = saturate(L_sum);
    612 
    613     return (var_out);
    614 #endif
    615 }
    616 #endif
    617 
    618 /* Short sub,           1   */
    619 #if (SUB_IS_INLINE)
    620 __inline Word16 sub(Word16 var1, Word16 var2)
    621 {
    622 #if ARMV5TE_SUB
    623 	Word32 result;
    624 	Word32 tmp;
    625 	asm (
    626 		"SUB   %[result], %[var1], %[var2] \n"
    627 		"MOV   %[tmp], %[var1], ASR #15 \n"
    628 		"TEQ   %[tmp], %[var1], ASR #31 \n"
    629 		"EORNE %[result], %[mask], %[result], ASR #31 \n"
    630 		:[result]"=&r"(result), [tmp]"=&r"(tmp)
    631 		:[var1]"r"(var1), [var2]"r"(var2), [mask]"r"(0x7fff)
    632 		);
    633 	return result;
    634 #else
    635     Word16 var_out;
    636     Word32 L_diff;
    637 
    638     L_diff = (Word32) var1 - var2;
    639     var_out = saturate(L_diff);
    640 
    641     return (var_out);
    642 #endif
    643 }
    644 #endif
    645 
    646 /* Short division,       18  */
    647 #if (DIV_S_IS_INLINE)
    648 __inline Word16 div_s (Word16 var1, Word16 var2)
    649 {
    650     Word16 var_out = 0;
    651     Word16 iteration;
    652     Word32 L_num;
    653     Word32 L_denom;
    654 
    655     var_out = MAX_16;
    656     if (var1!= var2)//var1!= var2
    657     {
    658     	var_out = 0;
    659     	L_num = (Word32) var1;
    660 
    661     	L_denom = (Word32) var2;
    662 
    663 		//return (L_num<<15)/var2;
    664 
    665     	for (iteration = 0; iteration < 15; iteration++)
    666     	{
    667     		var_out <<= 1;
    668     		L_num <<= 1;
    669 
    670     		if (L_num >= L_denom)
    671     		{
    672     			L_num -= L_denom;
    673     			var_out++;
    674     		}
    675     	}
    676     }
    677     return (var_out);
    678 }
    679 #endif
    680 
    681 /* Short mult,          1   */
    682 #if (MULT_IS_INLINE)
    683 __inline Word16 mult (Word16 var1, Word16 var2)
    684 {
    685 #if ARMV5TE_MULT && ARMV6_SAT
    686 	Word32 result;
    687 	asm (
    688 		"SMULBB %[result], %[var1], %[var2] \n"
    689 		"SSAT   %[result], #16, %[result], ASR #15 \n"
    690 		:[result]"=r"(result)
    691 		:[var1]"r"(var1), [var2]"r"(var2)
    692 		);
    693 	return result;
    694 #elif ARMV5TE_MULT
    695 	Word32 result, tmp;
    696 	asm (
    697 		"SMULBB %[tmp], %[var1], %[var2] \n"
    698 		"MOV	%[result], %[tmp], ASR #15\n"
    699 		"MOV	%[tmp], %[result], ASR #15\n"
    700 		"TEQ	%[tmp], %[result], ASR #31\n"
    701 		"EORNE  %[result], %[mask], %[result], ASR #31 \n"
    702 		:[result]"=&r"(result), [tmp]"=&r"(tmp)
    703 		:[var1]"r"(var1), [var2]"r"(var2), [mask]"r"(0x7fff)
    704 		);
    705 	return result;
    706 #else
    707     Word16 var_out;
    708     Word32 L_product;
    709 
    710     L_product = (Word32) var1 *(Word32) var2;
    711     L_product = (L_product & (Word32) 0xffff8000L) >> 15;
    712     if (L_product & (Word32) 0x00010000L)
    713         L_product = L_product | (Word32) 0xffff0000L;
    714     var_out = saturate(L_product);
    715 
    716     return (var_out);
    717 #endif
    718 }
    719 #endif
    720 
    721 
    722 /* Short norm,           15  */
    723 #if (NORM_S_IS_INLINE)
    724 __inline Word16 norm_s (Word16 var1)
    725 {
    726 #if ARMV5TE_NORM_S
    727 	Word16 result;
    728 	Word32 tmp;
    729 	asm (
    730 		"RSBS  %[tmp], %[var1], #0 \n"
    731 		"CLZLT %[result], %[var1]\n"
    732 		"CLZGT %[result], %[tmp]\n"
    733 		"SUBNE %[result], %[result], #17\n"
    734 		"MOVEQ %[result], #0\n"
    735 		"CMP   %[var1], #-1\n"
    736 		"MOVEQ %[result], #15\n"
    737 		:[result]"=&r"(result), [tmp]"=&r"(tmp)
    738 		:[var1]"r"(var1)
    739 		);
    740 	return result;
    741 #else
    742     Word16 var_out;
    743 
    744     if (var1 == 0)
    745     {
    746         var_out = 0;
    747     }
    748     else
    749     {
    750         if (var1 == -1)
    751         {
    752             var_out = 15;
    753         }
    754         else
    755         {
    756             if (var1 < 0)
    757             {
    758                 var1 = (Word16)~var1;
    759             }
    760             for (var_out = 0; var1 < 0x4000; var_out++)
    761             {
    762                 var1 <<= 1;
    763             }
    764         }
    765     }
    766     return (var_out);
    767 #endif
    768 }
    769 #endif
    770 
    771 /* Long norm,            30  */
    772 #if (NORM_L_IS_INLINE)
    773 __inline Word16 norm_l (Word32 L_var1)
    774 {
    775 #if ARMV5TE_NORM_L
    776 	Word16 result;
    777 	asm volatile(
    778 		"CMP    %[L_var1], #0\n"
    779 		"CLZNE  %[result], %[L_var1]\n"
    780 		"SUBNE  %[result], %[result], #1\n"
    781 		"MOVEQ  %[result], #0\n"
    782 		:[result]"=r"(result)
    783 		:[L_var1]"r"(L_var1)
    784 		);
    785 	return result;
    786 #else
    787     //Word16 var_out;
    788 
    789     //if (L_var1 == 0)
    790     //{
    791     //    var_out = 0;
    792     //}
    793     //else
    794     //{
    795     //    if (L_var1 == (Word32) 0xffffffffL)
    796     //    {
    797     //        var_out = 31;
    798     //    }
    799     //    else
    800     //    {
    801     //        if (L_var1 < 0)
    802     //        {
    803     //            L_var1 = ~L_var1;
    804     //        }
    805     //        for (var_out = 0; L_var1 < (Word32) 0x40000000L; var_out++)
    806     //        {
    807     //            L_var1 <<= 1;
    808     //        }
    809     //    }
    810     //}
    811     //return (var_out);
    812   Word16 a16;
    813   Word16 r = 0 ;
    814 
    815 
    816   if ( L_var1 < 0 ) {
    817     L_var1 = ~L_var1;
    818   }
    819 
    820   if (0 == (L_var1 & 0x7fff8000)) {
    821     a16 = extract_l(L_var1);
    822     r += 16;
    823 
    824     if (0 == (a16 & 0x7f80)) {
    825       r += 8;
    826 
    827       if (0 == (a16 & 0x0078)) {
    828         r += 4;
    829 
    830         if (0 == (a16 & 0x0006)) {
    831           r += 2;
    832 
    833           if (0 == (a16 & 0x0001)) {
    834             r += 1;
    835           }
    836         }
    837         else {
    838 
    839           if (0 == (a16 & 0x0004)) {
    840             r += 1;
    841           }
    842         }
    843       }
    844       else {
    845 
    846         if (0 == (a16 & 0x0060)) {
    847           r += 2;
    848 
    849           if (0 == (a16 & 0x0010)) {
    850             r += 1;
    851           }
    852         }
    853         else {
    854 
    855           if (0 == (a16 & 0x0040)) {
    856             r += 1;
    857           }
    858         }
    859       }
    860     }
    861     else {
    862 
    863       if (0 == (a16 & 0x7800)) {
    864         r += 4;
    865 
    866         if (0 == (a16 & 0x0600)) {
    867           r += 2;
    868 
    869           if (0 == (a16 & 0x0100)) {
    870             r += 1;
    871           }
    872         }
    873         else {
    874 
    875           if (0 == (a16 & 0x0400)) {
    876             r += 1;
    877           }
    878         }
    879       }
    880       else {
    881 
    882         if (0 == (a16 & 0x6000)) {
    883           r += 2;
    884 
    885           if (0 == (a16 & 0x1000)) {
    886             r += 1;
    887           }
    888         }
    889         else {
    890 
    891           if (0 == (a16 & 0x4000)) {
    892             r += 1;
    893           }
    894         }
    895       }
    896     }
    897   }
    898   else {
    899     a16 = extract_h(L_var1);
    900 
    901     if (0 == (a16 & 0x7f80)) {
    902       r += 8;
    903 
    904       if (0 == (a16 & 0x0078)) {
    905         r += 4 ;
    906 
    907         if (0 == (a16 & 0x0006)) {
    908           r += 2;
    909 
    910           if (0 == (a16 & 0x0001)) {
    911             r += 1;
    912           }
    913         }
    914         else {
    915 
    916           if (0 == (a16 & 0x0004)) {
    917             r += 1;
    918           }
    919         }
    920       }
    921       else {
    922 
    923         if (0 == (a16 & 0x0060)) {
    924           r += 2;
    925 
    926           if (0 == (a16 & 0x0010)) {
    927             r += 1;
    928           }
    929         }
    930         else {
    931 
    932           if (0 == (a16 & 0x0040)) {
    933             r += 1;
    934           }
    935         }
    936       }
    937     }
    938     else {
    939 
    940       if (0 == (a16 & 0x7800)) {
    941         r += 4;
    942 
    943         if (0 == (a16 & 0x0600)) {
    944           r += 2;
    945 
    946           if (0 == (a16 & 0x0100)) {
    947             r += 1;
    948           }
    949         }
    950         else {
    951 
    952           if (0 == (a16 & 0x0400)) {
    953             r += 1;
    954           }
    955         }
    956       }
    957       else {
    958 
    959         if (0 == (a16 & 0x6000)) {
    960           r += 2;
    961 
    962           if (0 == (a16 & 0x1000)) {
    963             r += 1;
    964           }
    965         }
    966         else {
    967 
    968           if (0 == (a16 & 0x4000)) {
    969             return 1;
    970           }
    971         }
    972       }
    973     }
    974   }
    975 
    976   return r ;
    977 #endif
    978 }
    979 #endif
    980 
    981 /* Round,               1   */
    982 #if (ROUND_IS_INLINE)
    983 __inline Word16 round16(Word32 L_var1)
    984 {
    985 #if ARMV5TE_ROUND
    986 	Word16 result;
    987 	asm (
    988 		"QADD  %[result], %[L_var1], %[bias]\n"
    989 		"MOV   %[result], %[result], ASR #16 \n"
    990 		:[result]"=r"(result)
    991 		:[L_var1]"r"(L_var1), [bias]"r"(0x8000)
    992 		);
    993 	return result;
    994 #else
    995     Word16 var_out;
    996     Word32 L_rounded;
    997 
    998     L_rounded = L_add (L_var1, (Word32) 0x00008000L);
    999     var_out = extract_h (L_rounded);
   1000     return (var_out);
   1001 #endif
   1002 }
   1003 #endif
   1004 
   1005 /* Mac,  1  */
   1006 #if (L_MAC_IS_INLINE)
   1007 __inline Word32 L_mac (Word32 L_var3, Word16 var1, Word16 var2)
   1008 {
   1009 #if ARMV5TE_L_MAC
   1010 	Word32 result;
   1011 	asm (
   1012 		"SMULBB %[result], %[var1], %[var2]\n"
   1013 		"QDADD  %[result], %[L_var3], %[result]\n"
   1014 		:[result]"=&r"(result)
   1015 		: [L_var3]"r"(L_var3), [var1]"r"(var1), [var2]"r"(var2)
   1016 		);
   1017 	return result;
   1018 #else
   1019     Word32 L_var_out;
   1020     Word32 L_product;
   1021 
   1022     L_product = L_mult(var1, var2);
   1023     L_var_out = L_add (L_var3, L_product);
   1024     return (L_var_out);
   1025 #endif
   1026 }
   1027 #endif
   1028 
   1029 #if (L_ADD_IS_INLINE)
   1030 __inline Word32 L_add (Word32 L_var1, Word32 L_var2)
   1031 {
   1032 #if ARMV5TE_L_ADD
   1033 	Word32 result;
   1034 	asm (
   1035 		"QADD %[result], %[L_var1], %[L_var2]\n"
   1036 		:[result]"=r"(result)
   1037 		:[L_var1]"r"(L_var1), [L_var2]"r"(L_var2)
   1038 		);
   1039 	return result;
   1040 #else
   1041     Word32 L_var_out;
   1042 
   1043     L_var_out = L_var1 + L_var2;
   1044     if (((L_var1 ^ L_var2) & MIN_32) == 0)
   1045     {
   1046         if ((L_var_out ^ L_var1) & MIN_32)
   1047         {
   1048             L_var_out = (L_var1 < 0) ? MIN_32 : MAX_32;
   1049         }
   1050     }
   1051     return (L_var_out);
   1052 #endif
   1053 }
   1054 #endif
   1055 
   1056 
   1057 
   1058 #if (MULT_R_IS_INLINE)
   1059 __inline Word16 mult_r (Word16 var1, Word16 var2)
   1060 {
   1061     Word16 var_out;
   1062     Word32 L_product_arr;
   1063 
   1064     L_product_arr = (Word32)var1 *(Word32)var2;       /* product */
   1065     L_product_arr += (Word32)0x00004000L;      /* round */
   1066     L_product_arr >>= 15;       /* shift */
   1067 
   1068     var_out = saturate(L_product_arr);
   1069 
   1070     return (var_out);
   1071 }
   1072 #endif
   1073 
   1074 #if (SHR_R_IS_INLINE)
   1075 __inline Word16 shr_r (Word16 var1, Word16 var2)
   1076 {
   1077     Word16 var_out;
   1078 
   1079     if (var2 > 15)
   1080     {
   1081         var_out = 0;
   1082     }
   1083     else
   1084     {
   1085         var_out = shr(var1, var2);
   1086 
   1087         if (var2 > 0)
   1088         {
   1089             if ((var1 & ((Word16) 1 << (var2 - 1))) != 0)
   1090             {
   1091                 var_out++;
   1092             }
   1093         }
   1094     }
   1095 
   1096     return (var_out);
   1097 }
   1098 #endif
   1099 
   1100 #if (MAC_R_IS_INLINE)
   1101 __inline Word16 mac_r (Word32 L_var3, Word16 var1, Word16 var2)
   1102 {
   1103     Word16 var_out;
   1104 
   1105     L_var3 = L_mac (L_var3, var1, var2);
   1106     var_out = (Word16)((L_var3 + 0x8000L) >> 16);
   1107 
   1108     return (var_out);
   1109 }
   1110 #endif
   1111 
   1112 #if (MSU_R_IS_INLINE)
   1113 __inline Word16 msu_r (Word32 L_var3, Word16 var1, Word16 var2)
   1114 {
   1115     Word16 var_out;
   1116 
   1117     L_var3 = L_msu (L_var3, var1, var2);
   1118     var_out = (Word16)((L_var3 + 0x8000L) >> 16);
   1119 
   1120     return (var_out);
   1121 }
   1122 #endif
   1123 
   1124 #if (L_SHR_R_IS_INLINE)
   1125 __inline Word32 L_shr_r (Word32 L_var1, Word16 var2)
   1126 {
   1127     Word32 L_var_out;
   1128 
   1129     if (var2 > 31)
   1130     {
   1131         L_var_out = 0;
   1132     }
   1133     else
   1134     {
   1135         L_var_out = L_shr(L_var1, var2);
   1136 
   1137         if (var2 > 0)
   1138         {
   1139             if ((L_var1 & ((Word32) 1 << (var2 - 1))) != 0)
   1140             {
   1141                 L_var_out++;
   1142             }
   1143         }
   1144     }
   1145 
   1146     return (L_var_out);
   1147 }
   1148 #endif
   1149 
   1150 #if (EXTRACT_H_IS_INLINE)
   1151 __inline Word16 extract_h (Word32 L_var1)
   1152 {
   1153     Word16 var_out;
   1154 
   1155     var_out = (Word16) (L_var1 >> 16);
   1156 
   1157     return (var_out);
   1158 }
   1159 #endif
   1160 
   1161 #if (EXTRACT_L_IS_INLINE)
   1162 __inline Word16 extract_l(Word32 L_var1)
   1163 {
   1164 	return (Word16) L_var1;
   1165 }
   1166 #endif
   1167 
   1168 #endif
   1169