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