📄 enh40.c
字号:
* * Inputs : * * L40_var1 40 bit long signed integer (Word40) whose value falls in the * range : MIN_40 <= L40_var1 <= MAX_40. * * Outputs : * * none * * Return Value : * * L_var_out 32 bit long signed integer (Word32) whose value falls in * the range : 0x8000 0000 <= L_var_out <= 0x7fff ffff. * *****************************************************************************/Word32 L_saturate40( Word40 L40_var1) { Word32 L_var_out; Word40 UNDER_L40_var2 = ( Word40) ~(((( Word40) 1) << 31) - ( Word40) 1 ); Word40 OVER_L40_var2 = ( Word40) (((( Word40) 1) << 31) - ( Word40) 1 ); if( L40_var1 < UNDER_L40_var2) { L40_var1 = UNDER_L40_var2; Overflow = 1; } if( L40_var1 > OVER_L40_var2) { L40_var1 = OVER_L40_var2; Overflow = 1; } L_var_out = L_Extract40( L40_var1); #if (WMOPS) multiCounter[currCounter].L_Extract40--; multiCounter[currCounter].L_saturate40++; #endif /* ifdef WMOPS */ return( L_var_out);}/***************************************************************************** * * Function Name : Mpy_32_16_ss * * Purpose : * * Multiplies the 2 signed values L_var1 and var2 with saturation control * on 48-bit. The operation is performed in fractional mode : * - L_var1 is supposed to be in 1Q31 format. * - var2 is supposed to be in 1Q15 format. * - The result is produced in 1Q47 format : L_varout_h points to the * 32 MSBits while varout_l points to the 16 LSBits. * * Complexity weight : 2 * * Inputs : * * L_var1 32 bit long signed integer (Word32) whose value falls in * the range : 0x8000 0000 <= L_var1 <= 0x7fff ffff. * * var2 16 bit short signed integer (Word16) whose value falls in * the range : 0xffff 8000 <= var2 <= 0x0000 7fff. * * Outputs : * * *L_varout_h 32 bit long signed integer (Word32) whose value falls in * the range : 0x8000 0000 <= L_varout_h <= 0x7fff ffff. * * *varout_l 16 bit short unsigned integer (UWord16) whose value falls in * the range : 0x0000 0000 <= varout_l <= 0x0000 ffff. * * Return Value : * * none * *****************************************************************************/void Mpy_32_16_ss( Word32 L_var1, Word16 var2, Word32 *L_varout_h, UWord16 *varout_l) { Word16 var1_h; UWord16 uvar1_l; Word40 L40_var1; if( (L_var1 == ( Word32) 0x80000000) && (var2 == ( Word16) 0x8000)) { *L_varout_h = 0x7fffffff; *varout_l = ( UWord16) 0xffff; } else { uvar1_l = extract_l( L_var1); var1_h = extract_h( L_var1); /* Below line can not overflow, so we can use << instead of L40_shl. */ L40_var1 = (( Word40) (( Word32) var2 * ( Word32) uvar1_l)) << 1; *varout_l = Extract40_L( L40_var1); L40_var1 = L40_shr( L40_var1, 16); L40_var1 = L40_mac( L40_var1, var2, var1_h); *L_varout_h = L_Extract40( L40_var1); #if(WMOPS) multiCounter[currCounter].extract_l--; multiCounter[currCounter].extract_h--; multiCounter[currCounter].Extract40_L--; multiCounter[currCounter].L40_shr--; multiCounter[currCounter].L40_mac--; multiCounter[currCounter].L_Extract40--; #endif /* ifdef WMOPS */ } #if (WMOPS) multiCounter[currCounter].Mpy_32_16_ss++; #endif /* ifdef WMOPS */ return;}/***************************************************************************** * * Function Name : Mpy_32_32_ss * * Purpose : * * Multiplies the 2 signed values L_var1 and L_var2 with saturation control * on 64-bit. The operation is performed in fractional mode : * - L_var1 and L_var2 are supposed to be in 1Q31 format. * - The result is produced in 1Q63 format : L_varout_h points to the * 32 MSBits while L_varout_l points to the 32 LSBits. * * Complexity weight : 4 * * Inputs : * * L_var1 32 bit long signed integer (Word32) whose value falls in the * range : 0x8000 0000 <= L_var1 <= 0x7fff ffff. * * L_var2 32 bit long signed integer (Word32) whose value falls in the * range : 0x8000 0000 <= L_var2 <= 0x7fff ffff. * * Outputs : * * *L_varout_h 32 bit long signed integer (Word32) whose value falls in * the range : 0x8000 0000 <= L_varout_h <= 0x7fff ffff. * * *L_varout_l 32 bit short unsigned integer (UWord32) whose value falls in * the range : 0x0000 0000 <= L_varout_l <= 0xffff ffff. * * * Return Value : * * none * *****************************************************************************/void Mpy_32_32_ss( Word32 L_var1, Word32 L_var2, Word32 *L_varout_h, UWord32 *L_varout_l) { UWord16 uvar1_l, uvar2_l; Word16 var1_h, var2_h; Word40 L40_var1; if( (L_var1 == ( Word32)0x80000000) && (L_var2 == ( Word32)0x80000000)) { *L_varout_h = 0x7fffffff; *L_varout_l = ( UWord32)0xffffffff; } else { uvar1_l = extract_l( L_var1); var1_h = extract_h( L_var1); uvar2_l = extract_l( L_var2); var2_h = extract_h( L_var2); /* Below line can not overflow, so we can use << instead of L40_shl. */ L40_var1 = (( Word40) (( UWord32) uvar2_l * ( UWord32) uvar1_l)) << 1; *L_varout_l = 0x0000ffff & L_Extract40( L40_var1); L40_var1 = L40_shr( L40_var1, 16); L40_var1 = L40_add( L40_var1, (( Word40) (( Word32) var2_h * ( Word32) uvar1_l)) << 1); L40_var1 = L40_add( L40_var1, (( Word40) (( Word32) var1_h * ( Word32) uvar2_l)) << 1); *L_varout_l |= (L_Extract40( L40_var1)) << 16; L40_var1 = L40_shr( L40_var1, 16); L40_var1 = L40_mac( L40_var1, var1_h, var2_h); *L_varout_h = L_Extract40( L40_var1); #if (WMOPS) multiCounter[currCounter].extract_l-=2; multiCounter[currCounter].extract_h-=2; multiCounter[currCounter].L_Extract40-=3; multiCounter[currCounter].L40_shr-=2; multiCounter[currCounter].L40_add-=2; multiCounter[currCounter].L40_mac--; #endif /* ifdef WMOPS */ } #if (WMOPS) multiCounter[currCounter].Mpy_32_32_ss++; #endif /* ifdef WMOPS */ return;}/***************************************************************************** * * Function Name : L40_lshl * * Purpose : * * Logically shifts left L40_var1 by var2 positions. * - If var2 is negative, L40_var1 is shifted to the LSBits by (-var2) * positions with insertion of 0 at the MSBit. * - If var2 is positive, L40_var1 is shifted to the MSBits by (var2) * positions. * * Complexity weight : 1 * * Inputs : * * L40_var1 40 bit long signed integer (Word40) whose value falls in the * range : MIN_40 <= L40_var1 <= MAX_40. * * var2 16 bit short signed integer (Word16) whose value falls in * the range : MIN_16 <= var2 <= MAX_16. * * Outputs : * * none * * Return Value : * * L40_var_out 40 bit long signed integer (Word40) whose value falls in * the range : MIN_40 <= L40_var_out <= MAX_40. * *****************************************************************************/Word40 L40_lshl( Word40 L40_var1, Word16 var2) { Word40 L40_var_out; if( var2 <= 0) { var2 = -var2; L40_var_out = L40_lshr ( L40_var1, var2); #if (WMOPS) multiCounter[currCounter].L40_lshr--; #endif /* ifdef WMOPS */ } else { if( var2 >= 40) L40_var_out = 0x0000000000; else L40_var_out = L40_var1 << var2; L40_var_out = L40_set( L40_var_out); #if (WMOPS) multiCounter[currCounter].L40_set--; #endif /* ifdef WMOPS */ } #if (WMOPS) multiCounter[currCounter].L40_lshl++; #endif /* ifdef WMOPS */ return( L40_var_out);}/***************************************************************************** * * Function Name : L40_lshr * * Purpose : * * Logically shifts right L40_var1 by var2 positions. * - If var2 is positive, L40_var1 is shifted to the LSBits by (var2) * positions with insertion of 0 at the MSBit. * - If var2 is negative, L40_var1 is shifted to the MSBits by (-var2) * positions. * * Complexity weight : 1 * * Inputs : * * L40_var1 40 bit long signed integer (Word40) whose value falls in the * range : MIN_40 <= L40_var1 <= MAX_40. * * var2 16 bit short signed integer (Word16) whose value falls in * the range : MIN_16 <= var2 <= MAX_16.* * Outputs : * * none * * Return Value : * * L40_var_out 40 bit long signed integer (Word40) whose value falls in * the range : MIN_40 <= L40_var_out <= MAX_40. * *****************************************************************************/Word40 L40_lshr( Word40 L40_var1, Word16 var2) { Word40 L40_var_out; if( var2 < 0) { var2 = -var2; L40_var_out = L40_lshl ( L40_var1, var2); #if (WMOPS) multiCounter[currCounter].L40_lshl--; #endif /* ifdef WMOPS */ } else { if( var2 >= 40) L40_var_out = 0x0000000000; else L40_var_out = (L40_var1 & 0xffffffffff) >> var2; } #if (WMOPS) multiCounter[currCounter].L40_lshr++; #endif /* ifdef WMOPS */ return( L40_var_out);}/***************************************************************************** * * Function Name : norm_L40 * * Purpose : * * Produces the number of left shifts needed to normalize in 32 bit format * the 40 bit variable L40_var1. This returned value can be used to scale * L_40_var1 into the following intervals : * - [(MAX_32+1)/2 .. MAX_32 ] for positive values. * - [ MIN_32 .. (MIN_32/2)+1 ] for negative values. * - [ 0 .. 0 ] for null values. * In order to normalize the result, the following operation must be done : * normelized_L40_var1 = L40_shl( L40_var1, norm_L40( L40_var1)) * * Complexity weight : 1 * * Inputs : * * L40_var1 40 bit long signed integer (Word40) whose value falls in the * range : MIN_40 <= L40_var1 <= MAX_40. * * Outputs : * * none * * Return Value : * * var_out 16 bit short signed integer (Word16) whose value falls in * the range : -8 <= var_out <= 31. * *****************************************************************************/Word16 norm_L40( Word40 L40_var1) { Word16 var_out; var_out = 0; if( L40_var1 != 0) { while( (L40_var1 > ( Word32)0x80000000L) && (L40_var1 < ( Word32)0x7fffffffL)) { L40_var1 = L40_shl( L40_var1, 1); var_out++; #ifdef WMOPS multiCounter[currCounter].L40_shl--; #endif /* ifdef WMOPS */ } while( (L40_var1 < ( Word32)0x80000000L) || (L40_var1 > ( Word32)0x7fffffffL)) { L40_var1 = L40_shl( L40_var1, -1); var_out--; #ifdef WMOPS multiCounter[currCounter].L40_shl--; #endif /* ifdef WMOPS */ } } #ifdef WMOPS multiCounter[currCounter].norm_L40++; #endif /* ifdef WMOPS */ return( var_out); }/***************************************************************************** * * Function Name : L40_shr_r * * Purpose : * * Arithmetically shifts right L40_var1 by var2 positions and rounds the * result. It is equivalent to L40_shr( L40_var1, var2) except that if the * last bit shifted out to the LSBit is 1, then the shifted result is * incremented by 1. * Calls the macro L40_UNDERFLOW_OCCURED() in case of underflow on 40-bit. * Calls the macro L40_OVERFLOW_OCCURED() in case of overflow on 40-bit. * * Complexity weight : 3 * * Inputs : * * L40_var1 40 bit long signed integer (Word40) whose value falls in the * range : MIN_40 <= L40_var1 <= MAX_40. * * var2 16 bit short signed integer (Word16) whose value falls in * the range : 0xffff 8000 <= var2 <= 0x0000 7fff. * * Outputs : * * none * * Return Value : * * L40_var_out 40 bit long signed integer (Word40) whose value falls in * the range : MIN_40 <= L40_var_out <= MAX_40. * *****************************************************************************/Word40 L40_shr_r( Word40 L40_var1, Word16 var2) { Word40 L40_var_out; if( var2 > 39) { L40_var_out = 0; } else { L40_var_out = L40_shr( L40_var1, var2); #if (WMOPS) multiCounter[currCounter].L40_shr--; #endif /* ifdef WMOPS */ if( var2 > 0) { if( ( L40_var1 & (( Word40) 1 << (var2 - 1))) != 0) { /* below line can not generate overflows on 40-bit */ L40_var_out++; } } } #if (WMOPS) multiCounter[currCounter].L40_shr_r++; #endif /* ifdef WMOPS */ return( L40_var_out);}/***************************************************************************** * * Function Name : L40_shl_r * * Purpose : * * Arithmetically shifts left L40_var1 by var2 positions and rounds the * result. It is equivalent to L40_shl( L40_var1, var2) except if var2 is * negative. In that case, it does the same as * L40_shr_r( L40_var1, (-var2)). * Calls the macro L40_UNDERFLOW_OCCURED() in case of underflow on 40-bit. * Calls the macro L40_OVERFLOW_OCCURED() in case of overflow on 40-bit. * * Complexity weight : 3 * * Inputs : * * L40_var1 40 bit long signed integer (Word40) whose value falls in the * range : MIN_40 <= L40_var1 <= MAX_40. * * var2 16 bit short signed integer (Word16) whose value falls in * the range : 0xffff 8000 <= var2 <= 0x0000 7fff. * * Outputs : * * none * * Return Value : * * L40_var_out 40 bit long signed integer (Word40) whose value falls in * the range : MIN_40 <= L40_var_out <= MAX_40. * *****************************************************************************/Word40 L40_shl_r( Word40 L40_var1, Word16 var2) { Word40 L40_var_out; if( var2 >= 0) { L40_var_out = L40_shl( L40_var1, var2); #if (WMOPS) multiCounter[currCounter].L40_shl--; #endif /* ifdef WMOPS */ } else { var2 = -var2; L40_var_out = L40_shr_r ( L40_var1, var2); #if (WMOPS) multiCounter[currCounter].L40_shr_r--; #endif /* ifdef WMOPS */ } #if (WMOPS) multiCounter[currCounter].L40_shl_r++; #endif /* ifdef WMOPS */ return( L40_var_out);}/* end of file */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -