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     Word32 L_var_out = 0L;
    522 
    523     if (var2 <= 0)
    524     {
    525         L_var1 = L_shr(L_var1, (Word16)-var2);
    526     }
    527     else
    528     {
    529         for (; var2 > 0; var2--)
    530         {
    531             if (L_var1 > (Word32) 0X3fffffffL)
    532             {
    533                 return MAX_32;
    534             }
    535             else
    536             {
    537                 if (L_var1 < (Word32) 0xc0000000L)
    538                 {
    539                     return MIN_32;
    540                 }
    541             }
    542             L_var1 <<= 1;
    543             L_var_out = L_var1;
    544         }
    545     }
    546     return (L_var1);
    547 #endif
    548 }
    549 #endif
    550 
    551 #if (L_SHR_IS_INLINE)
    552 __inline Word32 L_shr (Word32 L_var1, Word16 var2)
    553 {
    554 #if ARMV5TE_L_SHR
    555 	if(var2>=0)
    556 	{
    557 		return ASM_L_shr( L_var1, var2);
    558 	}
    559 	else
    560 	{
    561 		return ASM_L_shl( L_var1, -var2);
    562 	}
    563 #else
    564     Word32 L_var_out;
    565 
    566     if (var2 < 0)
    567     {
    568         L_var_out = L_shl (L_var1, (Word16)-var2);
    569     }
    570     else
    571     {
    572         if (var2 >= 31)
    573         {
    574             L_var_out = (L_var1 < 0L) ? -1 : 0;
    575         }
    576         else
    577         {
    578             if (L_var1 < 0)
    579             {
    580                 L_var_out = ~((~L_var1) >> var2);
    581             }
    582             else
    583             {
    584                 L_var_out = L_var1 >> var2;
    585             }
    586         }
    587     }
    588     return (L_var_out);
    589 #endif
    590 }
    591 #endif
    592 
    593 /* Short add,           1   */
    594 #if (ADD_IS_INLINE)
    595 __inline Word16 add (Word16 var1, Word16 var2)
    596 {
    597 #if ARMV5TE_ADD
    598 	Word32 result;
    599 	Word32 tmp;
    600 	asm (
    601 		"ADD  %[result], %[var1], %[var2] \n"
    602 		"MOV  %[tmp], %[result], ASR #15 \n"
    603 		"TEQ  %[tmp], %[result], ASR #31 \n"
    604 		"EORNE %[result], %[mask], %[result], ASR #31"
    605 		:[result]"=&r"(result), [tmp]"=&r"(tmp)
    606 		:[var1]"r"(var1), [var2]"r"(var2), [mask]"r"(0x7fff)
    607 		);
    608 	return result;
    609 #else
    610     Word16 var_out;
    611     Word32 L_sum;
    612 
    613     L_sum = (Word32) var1 + var2;
    614     var_out = saturate(L_sum);
    615 
    616     return (var_out);
    617 #endif
    618 }
    619 #endif
    620 
    621 /* Short sub,           1   */
    622 #if (SUB_IS_INLINE)
    623 __inline Word16 sub(Word16 var1, Word16 var2)
    624 {
    625 #if ARMV5TE_SUB
    626 	Word32 result;
    627 	Word32 tmp;
    628 	asm (
    629 		"SUB   %[result], %[var1], %[var2] \n"
    630 		"MOV   %[tmp], %[var1], ASR #15 \n"
    631 		"TEQ   %[tmp], %[var1], ASR #31 \n"
    632 		"EORNE %[result], %[mask], %[result], ASR #31 \n"
    633 		:[result]"=&r"(result), [tmp]"=&r"(tmp)
    634 		:[var1]"r"(var1), [var2]"r"(var2), [mask]"r"(0x7fff)
    635 		);
    636 	return result;
    637 #else
    638     Word16 var_out;
    639     Word32 L_diff;
    640 
    641     L_diff = (Word32) var1 - var2;
    642     var_out = saturate(L_diff);
    643 
    644     return (var_out);
    645 #endif
    646 }
    647 #endif
    648 
    649 /* Short division,       18  */
    650 #if (DIV_S_IS_INLINE)
    651 __inline Word16 div_s (Word16 var1, Word16 var2)
    652 {
    653     Word16 var_out = 0;
    654     Word16 iteration;
    655     Word32 L_num;
    656     Word32 L_denom;
    657 
    658     var_out = MAX_16;
    659     if (var1!= var2)//var1!= var2
    660     {
    661     	var_out = 0;
    662     	L_num = (Word32) var1;
    663 
    664     	L_denom = (Word32) var2;
    665 
    666 		//return (L_num<<15)/var2;
    667 
    668     	for (iteration = 0; iteration < 15; iteration++)
    669     	{
    670     		var_out <<= 1;
    671     		L_num <<= 1;
    672 
    673     		if (L_num >= L_denom)
    674     		{
    675     			L_num -= L_denom;
    676     			var_out++;
    677     		}
    678     	}
    679     }
    680     return (var_out);
    681 }
    682 #endif
    683 
    684 /* Short mult,          1   */
    685 #if (MULT_IS_INLINE)
    686 __inline Word16 mult (Word16 var1, Word16 var2)
    687 {
    688 #if ARMV5TE_MULT && ARMV6_SAT
    689 	Word32 result;
    690 	asm (
    691 		"SMULBB %[result], %[var1], %[var2] \n"
    692 		"SSAT   %[result], #16, %[result], ASR #15 \n"
    693 		:[result]"=r"(result)
    694 		:[var1]"r"(var1), [var2]"r"(var2)
    695 		);
    696 	return result;
    697 #elif ARMV5TE_MULT
    698 	Word32 result, tmp;
    699 	asm (
    700 		"SMULBB %[tmp], %[var1], %[var2] \n"
    701 		"MOV	%[result], %[tmp], ASR #15\n"
    702 		"MOV	%[tmp], %[result], ASR #15\n"
    703 		"TEQ	%[tmp], %[result], ASR #31\n"
    704 		"EORNE  %[result], %[mask], %[result], ASR #31 \n"
    705 		:[result]"=&r"(result), [tmp]"=&r"(tmp)
    706 		:[var1]"r"(var1), [var2]"r"(var2), [mask]"r"(0x7fff)
    707 		);
    708 	return result;
    709 #else
    710     Word16 var_out;
    711     Word32 L_product;
    712 
    713     L_product = (Word32) var1 *(Word32) var2;
    714     L_product = (L_product & (Word32) 0xffff8000L) >> 15;
    715     if (L_product & (Word32) 0x00010000L)
    716         L_product = L_product | (Word32) 0xffff0000L;
    717     var_out = saturate(L_product);
    718 
    719     return (var_out);
    720 #endif
    721 }
    722 #endif
    723 
    724 
    725 /* Short norm,           15  */
    726 #if (NORM_S_IS_INLINE)
    727 __inline Word16 norm_s (Word16 var1)
    728 {
    729 #if ARMV5TE_NORM_S
    730 	Word16 result;
    731 	Word32 tmp;
    732 	asm (
    733 		"RSBS  %[tmp], %[var1], #0 \n"
    734 		"CLZLT %[result], %[var1]\n"
    735 		"CLZGT %[result], %[tmp]\n"
    736 		"SUBNE %[result], %[result], #17\n"
    737 		"MOVEQ %[result], #0\n"
    738 		"CMP   %[var1], #-1\n"
    739 		"MOVEQ %[result], #15\n"
    740 		:[result]"=&r"(result), [tmp]"=&r"(tmp)
    741 		:[var1]"r"(var1)
    742 		);
    743 	return result;
    744 #else
    745     Word16 var_out;
    746 
    747     if (var1 == 0)
    748     {
    749         var_out = 0;
    750     }
    751     else
    752     {
    753         if (var1 == -1)
    754         {
    755             var_out = 15;
    756         }
    757         else
    758         {
    759             if (var1 < 0)
    760             {
    761                 var1 = (Word16)~var1;
    762             }
    763             for (var_out = 0; var1 < 0x4000; var_out++)
    764             {
    765                 var1 <<= 1;
    766             }
    767         }
    768     }
    769     return (var_out);
    770 #endif
    771 }
    772 #endif
    773 
    774 /* Long norm,            30  */
    775 #if (NORM_L_IS_INLINE)
    776 __inline Word16 norm_l (Word32 L_var1)
    777 {
    778 #if ARMV5TE_NORM_L
    779 	Word16 result;
    780 	asm volatile(
    781 		"CMP    %[L_var1], #0\n"
    782 		"CLZNE  %[result], %[L_var1]\n"
    783 		"SUBNE  %[result], %[result], #1\n"
    784 		"MOVEQ  %[result], #0\n"
    785 		:[result]"=r"(result)
    786 		:[L_var1]"r"(L_var1)
    787 		);
    788 	return result;
    789 #else
    790     //Word16 var_out;
    791 
    792     //if (L_var1 == 0)
    793     //{
    794     //    var_out = 0;
    795     //}
    796     //else
    797     //{
    798     //    if (L_var1 == (Word32) 0xffffffffL)
    799     //    {
    800     //        var_out = 31;
    801     //    }
    802     //    else
    803     //    {
    804     //        if (L_var1 < 0)
    805     //        {
    806     //            L_var1 = ~L_var1;
    807     //        }
    808     //        for (var_out = 0; L_var1 < (Word32) 0x40000000L; var_out++)
    809     //        {
    810     //            L_var1 <<= 1;
    811     //        }
    812     //    }
    813     //}
    814     //return (var_out);
    815   Word16 a16;
    816   Word16 r = 0 ;
    817 
    818 
    819   if ( L_var1 < 0 ) {
    820     L_var1 = ~L_var1;
    821   }
    822 
    823   if (0 == (L_var1 & 0x7fff8000)) {
    824     a16 = extract_l(L_var1);
    825     r += 16;
    826 
    827     if (0 == (a16 & 0x7f80)) {
    828       r += 8;
    829 
    830       if (0 == (a16 & 0x0078)) {
    831         r += 4;
    832 
    833         if (0 == (a16 & 0x0006)) {
    834           r += 2;
    835 
    836           if (0 == (a16 & 0x0001)) {
    837             r += 1;
    838           }
    839         }
    840         else {
    841 
    842           if (0 == (a16 & 0x0004)) {
    843             r += 1;
    844           }
    845         }
    846       }
    847       else {
    848 
    849         if (0 == (a16 & 0x0060)) {
    850           r += 2;
    851 
    852           if (0 == (a16 & 0x0010)) {
    853             r += 1;
    854           }
    855         }
    856         else {
    857 
    858           if (0 == (a16 & 0x0040)) {
    859             r += 1;
    860           }
    861         }
    862       }
    863     }
    864     else {
    865 
    866       if (0 == (a16 & 0x7800)) {
    867         r += 4;
    868 
    869         if (0 == (a16 & 0x0600)) {
    870           r += 2;
    871 
    872           if (0 == (a16 & 0x0100)) {
    873             r += 1;
    874           }
    875         }
    876         else {
    877 
    878           if (0 == (a16 & 0x0400)) {
    879             r += 1;
    880           }
    881         }
    882       }
    883       else {
    884 
    885         if (0 == (a16 & 0x6000)) {
    886           r += 2;
    887 
    888           if (0 == (a16 & 0x1000)) {
    889             r += 1;
    890           }
    891         }
    892         else {
    893 
    894           if (0 == (a16 & 0x4000)) {
    895             r += 1;
    896           }
    897         }
    898       }
    899     }
    900   }
    901   else {
    902     a16 = extract_h(L_var1);
    903 
    904     if (0 == (a16 & 0x7f80)) {
    905       r += 8;
    906 
    907       if (0 == (a16 & 0x0078)) {
    908         r += 4 ;
    909 
    910         if (0 == (a16 & 0x0006)) {
    911           r += 2;
    912 
    913           if (0 == (a16 & 0x0001)) {
    914             r += 1;
    915           }
    916         }
    917         else {
    918 
    919           if (0 == (a16 & 0x0004)) {
    920             r += 1;
    921           }
    922         }
    923       }
    924       else {
    925 
    926         if (0 == (a16 & 0x0060)) {
    927           r += 2;
    928 
    929           if (0 == (a16 & 0x0010)) {
    930             r += 1;
    931           }
    932         }
    933         else {
    934 
    935           if (0 == (a16 & 0x0040)) {
    936             r += 1;
    937           }
    938         }
    939       }
    940     }
    941     else {
    942 
    943       if (0 == (a16 & 0x7800)) {
    944         r += 4;
    945 
    946         if (0 == (a16 & 0x0600)) {
    947           r += 2;
    948 
    949           if (0 == (a16 & 0x0100)) {
    950             r += 1;
    951           }
    952         }
    953         else {
    954 
    955           if (0 == (a16 & 0x0400)) {
    956             r += 1;
    957           }
    958         }
    959       }
    960       else {
    961 
    962         if (0 == (a16 & 0x6000)) {
    963           r += 2;
    964 
    965           if (0 == (a16 & 0x1000)) {
    966             r += 1;
    967           }
    968         }
    969         else {
    970 
    971           if (0 == (a16 & 0x4000)) {
    972             return 1;
    973           }
    974         }
    975       }
    976     }
    977   }
    978 
    979   return r ;
    980 #endif
    981 }
    982 #endif
    983 
    984 /* Round,               1   */
    985 #if (ROUND_IS_INLINE)
    986 __inline Word16 round16(Word32 L_var1)
    987 {
    988 #if ARMV5TE_ROUND
    989 	Word16 result;
    990 	asm (
    991 		"QADD  %[result], %[L_var1], %[bias]\n"
    992 		"MOV   %[result], %[result], ASR #16 \n"
    993 		:[result]"=r"(result)
    994 		:[L_var1]"r"(L_var1), [bias]"r"(0x8000)
    995 		);
    996 	return result;
    997 #else
    998     Word16 var_out;
    999     Word32 L_rounded;
   1000 
   1001     L_rounded = L_add (L_var1, (Word32) 0x00008000L);
   1002     var_out = extract_h (L_rounded);
   1003     return (var_out);
   1004 #endif
   1005 }
   1006 #endif
   1007 
   1008 /* Mac,  1  */
   1009 #if (L_MAC_IS_INLINE)
   1010 __inline Word32 L_mac (Word32 L_var3, Word16 var1, Word16 var2)
   1011 {
   1012 #if ARMV5TE_L_MAC
   1013 	Word32 result;
   1014 	asm (
   1015 		"SMULBB %[result], %[var1], %[var2]\n"
   1016 		"QDADD  %[result], %[L_var3], %[result]\n"
   1017 		:[result]"=&r"(result)
   1018 		: [L_var3]"r"(L_var3), [var1]"r"(var1), [var2]"r"(var2)
   1019 		);
   1020 	return result;
   1021 #else
   1022     Word32 L_var_out;
   1023     Word32 L_product;
   1024 
   1025     L_product = L_mult(var1, var2);
   1026     L_var_out = L_add (L_var3, L_product);
   1027     return (L_var_out);
   1028 #endif
   1029 }
   1030 #endif
   1031 
   1032 #if (L_ADD_IS_INLINE)
   1033 __inline Word32 L_add (Word32 L_var1, Word32 L_var2)
   1034 {
   1035 #if ARMV5TE_L_ADD
   1036 	Word32 result;
   1037 	asm (
   1038 		"QADD %[result], %[L_var1], %[L_var2]\n"
   1039 		:[result]"=r"(result)
   1040 		:[L_var1]"r"(L_var1), [L_var2]"r"(L_var2)
   1041 		);
   1042 	return result;
   1043 #else
   1044     Word32 L_var_out;
   1045 
   1046     L_var_out = L_var1 + L_var2;
   1047     if (((L_var1 ^ L_var2) & MIN_32) == 0)
   1048     {
   1049         if ((L_var_out ^ L_var1) & MIN_32)
   1050         {
   1051             L_var_out = (L_var1 < 0) ? MIN_32 : MAX_32;
   1052         }
   1053     }
   1054     return (L_var_out);
   1055 #endif
   1056 }
   1057 #endif
   1058 
   1059 
   1060 
   1061 #if (MULT_R_IS_INLINE)
   1062 __inline Word16 mult_r (Word16 var1, Word16 var2)
   1063 {
   1064     Word16 var_out;
   1065     Word32 L_product_arr;
   1066 
   1067     L_product_arr = (Word32)var1 *(Word32)var2;       /* product */
   1068     L_product_arr += (Word32)0x00004000L;      /* round */
   1069     L_product_arr >>= 15;       /* shift */
   1070 
   1071     var_out = saturate(L_product_arr);
   1072 
   1073     return (var_out);
   1074 }
   1075 #endif
   1076 
   1077 #if (SHR_R_IS_INLINE)
   1078 __inline Word16 shr_r (Word16 var1, Word16 var2)
   1079 {
   1080     Word16 var_out;
   1081 
   1082     if (var2 > 15)
   1083     {
   1084         var_out = 0;
   1085     }
   1086     else
   1087     {
   1088         var_out = shr(var1, var2);
   1089 
   1090         if (var2 > 0)
   1091         {
   1092             if ((var1 & ((Word16) 1 << (var2 - 1))) != 0)
   1093             {
   1094                 var_out++;
   1095             }
   1096         }
   1097     }
   1098 
   1099     return (var_out);
   1100 }
   1101 #endif
   1102 
   1103 #if (MAC_R_IS_INLINE)
   1104 __inline Word16 mac_r (Word32 L_var3, Word16 var1, Word16 var2)
   1105 {
   1106     Word16 var_out;
   1107 
   1108     L_var3 = L_mac (L_var3, var1, var2);
   1109     var_out = (Word16)((L_var3 + 0x8000L) >> 16);
   1110 
   1111     return (var_out);
   1112 }
   1113 #endif
   1114 
   1115 #if (MSU_R_IS_INLINE)
   1116 __inline Word16 msu_r (Word32 L_var3, Word16 var1, Word16 var2)
   1117 {
   1118     Word16 var_out;
   1119 
   1120     L_var3 = L_msu (L_var3, var1, var2);
   1121     var_out = (Word16)((L_var3 + 0x8000L) >> 16);
   1122 
   1123     return (var_out);
   1124 }
   1125 #endif
   1126 
   1127 #if (L_SHR_R_IS_INLINE)
   1128 __inline Word32 L_shr_r (Word32 L_var1, Word16 var2)
   1129 {
   1130     Word32 L_var_out;
   1131 
   1132     if (var2 > 31)
   1133     {
   1134         L_var_out = 0;
   1135     }
   1136     else
   1137     {
   1138         L_var_out = L_shr(L_var1, var2);
   1139 
   1140         if (var2 > 0)
   1141         {
   1142             if ((L_var1 & ((Word32) 1 << (var2 - 1))) != 0)
   1143             {
   1144                 L_var_out++;
   1145             }
   1146         }
   1147     }
   1148 
   1149     return (L_var_out);
   1150 }
   1151 #endif
   1152 
   1153 #if (EXTRACT_H_IS_INLINE)
   1154 __inline Word16 extract_h (Word32 L_var1)
   1155 {
   1156     Word16 var_out;
   1157 
   1158     var_out = (Word16) (L_var1 >> 16);
   1159 
   1160     return (var_out);
   1161 }
   1162 #endif
   1163 
   1164 #if (EXTRACT_L_IS_INLINE)
   1165 __inline Word16 extract_l(Word32 L_var1)
   1166 {
   1167 	return (Word16) L_var1;
   1168 }
   1169 #endif
   1170 
   1171 #endif
   1172