📄 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 + -