📄 enh40.c
字号:
/* =========================================================================== File: ENH40.C v.2.0 - 15.Nov.2004 =========================================================================== ITU-T STL BASIC OPERATORS 40-BIT ARITHMETIC OPERATORS History: 07 Nov 04 v2.0 Incorporation of new 32-bit / 40-bit / control operators for the ITU-T Standard Tool Library as described in Geneva, 20-30 January 2004 WP 3/16 Q10/16 TD 11 document and subsequent discussions on the wp3audio@yahoogroups.com email reflector. ============================================================================*//***************************************************************************** * * Enhanced 40 bit operators : * * L40_add() * L40_sub() * L40_abs() * L40_negate() * L40_max() * L40_min() * L40_shr() * L40_shr_r() * L40_shl() * L40_shl_r() * norm_L40() * L40_mult() * L40_mac() * L40_msu() * mac_r40() * msu_r40() * Mpy_32_16_ss() * Mpy_32_32_ss() * L40_lshl() * L40_lshr() * L40_round() * L_saturate40() * L40_set() * Extract40_H() * Extract40_L() * L_Extract40() * L40_deposit_h() * L40_deposit_l() * L40_deposit32() * *****************************************************************************//***************************************************************************** * * Include-Files * *****************************************************************************/#include <stdio.h>#include <stdlib.h>#include "stl.h"#if (WMOPS)extern BASIC_OP multiCounter[MAXCOUNTERS];extern int currCounter;#endif /* ifdef WMOPS *//***************************************************************************** * * Local Functions * *****************************************************************************//***************************************************************************** * * Constants and Globals * *****************************************************************************//***************************************************************************** * * Functions * *****************************************************************************//***************************************************************************** * * Function Name : L40_shl * * Purpose : * * Arithmetically shifts left L40_var1 by var2 positions. * - If var2 is negative, L40_var1 is shifted to the LSBits by (-var2) * positions with extension of the sign bit. * - If var2 is positive, L40_var1 is shifted to the MSBits by (var2) * positions. * 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 : 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_shl( Word40 L40_var1, Word16 var2) { Word40 L40_var_out; Word40 L40_constant = L40_set( 0xc000000000); if( var2 < 0) { var2 = -var2; L40_var_out = L40_shr( L40_var1, var2); #if (WMOPS) multiCounter[currCounter].L40_shr--; #endif /* ifdef WMOPS */ } else { L40_var_out = L40_var1; for ( ; var2 > 0; var2--) { if( L40_var_out > 0x003fffffffff) { L40_var_out = L40_OVERFLOW_OCCURED( L40_var_out); break; } else if ( L40_var_out < L40_constant) { L40_var_out = L40_UNDERFLOW_OCCURED( L40_var_out); break; } else { L40_var_out = L40_var_out << 1; } } } #if (WMOPS) multiCounter[currCounter].L40_set--; multiCounter[currCounter].L40_shl++; #endif /* ifdef WMOPS */ return( L40_var_out);}/***************************************************************************** * * Function Name : L40_shr * * Purpose : * * Arithmetically shifts right L40_var1 by var2 positions. * - If var2 is positive, L40_var1 is shifted to the LSBits by (var2) * positions with extension of the sign bit. * - If var2 is negative, L40_var1 is shifted to the MSBits by (-var2) * positions. * 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 : 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_shr( Word40 L40_var1, Word16 var2) { Word40 L40_var_out; if( var2 < 0) { var2 = -var2; L40_var_out = L40_shl ( L40_var1, var2); #if (WMOPS) multiCounter[currCounter].L40_shl--; #endif /* ifdef WMOPS */ } else { L40_var_out = L40_var1 >> var2; } #if (WMOPS) multiCounter[currCounter].L40_shr++; #endif /* ifdef WMOPS */ return( L40_var_out);}/***************************************************************************** * * Function Name : L40_negate * * Purpose : * * Negates L40_var1. * 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 : 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 : * * L40_var_out 40 bit long signed integer (Word40) whose value falls in * the range : MIN_40 <= L40_var_out <= MAX_40. * *****************************************************************************/Word40 L40_negate( Word40 L40_var1) { Word40 L40_var_out; L40_var_out = L40_add( ~L40_var1, 0x01); #if (WMOPS) multiCounter[currCounter].L40_add--; multiCounter[currCounter].L40_negate++; #endif /* ifdef WMOPS */ return( L40_var_out);}/***************************************************************************** * * Function Name : L40_add * * Purpose : * * Adds L40_var1 and L40_var2 and returns the 40-bit result. * 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 : 1 * * Inputs : * * L40_var1 40 bit long signed integer (Word40) whose value falls in the * range : MIN_40 <= L40_var1 <= MAX_40. * * L40_var2 40 bit long signed integer (Word40) whose value falls in the * range : MIN_40 <= L40_var2 <= MAX_40. * * 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_add( Word40 L40_var1, Word40 L40_var2) { Word40 L40_var_out; L40_var_out = L40_var1 + L40_var2; if( ((( L40_var1 & 0x8000000000) >> 39) != 0) && ((( L40_var2 & 0x8000000000) >> 39) != 0) && ((( L40_var_out & 0x8000000000) >> 39) == 0)) { L40_var_out = L40_UNDERFLOW_OCCURED( L40_var_out); } else if( (((L40_var1 & 0x8000000000) >> 39) == 0) && (((L40_var2 & 0x8000000000) >> 39) == 0) && (((L40_var_out & 0x8000000000) >> 39) != 0)) { L40_var_out = L40_OVERFLOW_OCCURED( L40_var_out); } #if (WMOPS) multiCounter[currCounter].L40_add++; #endif /* ifdef WMOPS */ return( L40_var_out);}/***************************************************************************** * * Function Name : L40_sub * * Purpose : * * Subtracts L40_var2 from L40_var1. * 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 : 1 * * Inputs : * * L40_var1 40 bit long signed integer (Word40) whose value falls in the * range : MIN_40 <= L40_var1 <= MAX_40. * * L40_var2 40 bit long signed integer (Word40) whose value falls in the * range : MIN_40 <= L40_var2 <= MAX_40. * * 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_sub( Word40 L40_var1, Word40 L40_var2) { Word40 L40_var_out; L40_var_out = L40_var1 - L40_var2; if( (((L40_var1 & 0x8000000000) >> 39) != 0) && (((L40_var2 & 0x8000000000) >> 39) == 0) && (((L40_var_out & 0x8000000000) >> 39) == 0)) { L40_var_out = L40_UNDERFLOW_OCCURED( L40_var_out); } else if( (((L40_var1 & 0x8000000000) >> 39) == 0) && (((L40_var2 & 0x8000000000) >> 39) != 0) && (((L40_var_out & 0x8000000000) >> 39) != 0)) { L40_var_out = L40_OVERFLOW_OCCURED( L40_var_out); } #if (WMOPS) multiCounter[currCounter].L40_sub++; #endif /* ifdef WMOPS */ return( L40_var_out);}/***************************************************************************** * * Function Name : L40_abs * * Purpose : * * Returns the absolute value of L40_var1. * 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 : 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 : * * L40_var_out 40 bit long signed integer (Word40) whose value falls in * the range : 0x00 0000 0000 <= L40_var_out <= MAX_40. * *****************************************************************************/Word40 L40_abs( Word40 L40_var1) { Word40 L40_var_out; if( L40_var1 < 0) { L40_var_out = L40_negate ( L40_var1); #if (WMOPS) multiCounter[currCounter].L40_negate--; #endif /* ifdef WMOPS */ } else { L40_var_out = L40_var1; } #if (WMOPS) multiCounter[currCounter].L40_abs++; #endif /* ifdef WMOPS */ return( L40_var_out);}/***************************************************************************** * * Function Name : L40_max * * Purpose : * * Compares L40_var1 and L40_var2 and returns the maximum value. * * * Complexity weight : 1 * * Inputs : * * L40_var1 40 bit long signed integer (Word40) whose value falls in the * range : MIN_40 <= L40_var1 <= MAX_40. * * L40_var2 40 bit long signed integer (Word40) whose value falls in the * range : MIN_40 <= L40_var2 <= MAX_40. * * 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_max( Word40 L40_var1, Word40 L40_var2) { Word40 L40_var_out; if( L40_var1 < L40_var2) L40_var_out = L40_var2; else L40_var_out = L40_var1; #if (WMOPS) multiCounter[currCounter].L40_max++; #endif /* ifdef WMOPS */ return( L40_var_out);}/***************************************************************************** * * Function Name : L40_min * * Purpose : * * Compares L40_var1 and L40_var2 and returns the minimum value. * * * Complexity weight : 1 * * Inputs : * * L40_var1 40 bit long signed integer (Word40) whose value falls in the * range : MIN_40 <= L40_var1 <= MAX_40. * * L40_var2 40 bit long signed integer (Word40) whose value falls in the * range : MIN_40 <= L40_var2 <= MAX_40. * * 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_min( Word40 L40_var1, Word40 L40_var2) { Word40 L40_var_out; if( L40_var1 < L40_var2) L40_var_out = L40_var1; else L40_var_out = L40_var2; #if (WMOPS) multiCounter[currCounter].L40_min++; #endif /* ifdef WMOPS */ return( L40_var_out);}/***************************************************************************** * * Function Name : L_saturate40 * * Purpose : * * If L40_var1 is greater than MAX_32, returns MAX_32. * If L40_var1 is lower than MIN_32, returns MIN_32. * If not, returns L_Extract40( L40_var1). * * Complexity weight : 1
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -