📄 mathhalf.c
字号:
* 0x8000 0000 <= L_var1 <= 0x7fff ffff.
* OUTPUTS:
*
* none
*
* RETURN VALUE:
*
* L_Out
* 32 bit long signed integer (Longword) whose value
* falls in the range
* 0x8000 0000 <= L_var1 <= 0x7fff ffff.
*
*
* IMPLEMENTATION:
*
* Arithmetically shift the input right by var2. This
* operation maintains the sign of the input number. If var2 is
* negative then an arithmetic shift left (shl) of L_var1 by
* -var2 is performed. See description of L_shl for details.
*
* The input is a 32 bit number, as is the output.
*
* Equivalent to the Full-Rate GSM ">> n" operation. Note that
* ANSI-C does not guarantee operation of the C ">>" or "<<"
* operator for negative numbers.
*
* KEYWORDS: shift, arithmetic shift right,
*
*************************************************************************/
Longword L_shr(Longword L_var1, Shortword var2)
{
Longword L_Mask,
L_Out;
if (var2 == 0 || L_var1 == 0)
{
L_Out = L_var1;
}
else if (var2 < 0)
{
/* perform a left shift */
/*----------------------*/
if (var2 <= -31)
{
/* saturate */
if (L_var1 > 0)
L_Out = LW_MAX;
else
L_Out = LW_MIN;
}
else
L_Out = L_shl(L_var1, -var2);
}
else
{
if (var2 >= 31)
{
if (L_var1 > 0)
L_Out = 0;
else
L_Out = 0xffffffffL;
}
else
{
L_Mask = 0;
if (L_var1 < 0)
{
L_Mask = ~L_Mask << (32 - var2);
}
L_var1 >>= var2;
L_Out = L_Mask | L_var1;
}
}
return (L_Out);
}
/***************************************************************************
*
* FUNCTION NAME: L_sub
*
* PURPOSE:
*
* Perform the subtraction of the two 32 bit input variables with
* saturation.
*
* INPUTS:
*
* L_var1
* 32 bit long signed integer (Longword) whose value
* falls in the range
* 0x8000 0000 <= L_var1 <= 0x7fff ffff.
* L_var2
* 32 bit long signed integer (Longword) whose value
* falls in the range
* 0x8000 0000 <= L_var2 <= 0x7fff ffff.
*
* OUTPUTS:
*
* none
*
* RETURN VALUE:
*
* L_Out
* 32 bit long signed integer (Longword) whose value
* falls in the range
* 0x8000 0000 <= L_var1 <= 0x7fff ffff.
*
* IMPLEMENTATION:
*
* Perform the subtraction of the two 32 bit input variables with
* saturation.
*
* L_Out = L_var1 - L_var2
*
* L_Out is set to 0x7fff ffff if the operation results in an
* overflow. L_Out is set to 0x8000 0000 if the operation
* results in an underflow.
*
* KEYWORDS: sub, subtraction
*
*************************************************************************/
Longword L_sub(Longword L_var1, Longword L_var2)
{
Longword L_Sum;
/* check for overflow */
if ((L_var1 > 0 && L_var2 < 0) || (L_var1 < 0 && L_var2 > 0))
{
if (L_var2 == LW_MIN)
{
L_Sum = L_add(L_var1, LW_MAX);
L_Sum = L_add(L_Sum, 1);
}
else
L_Sum = L_add(L_var1, -L_var2);
}
else
{ /* no overflow possible */
L_Sum = L_var1 - L_var2;
}
return (L_Sum);
}
/***************************************************************************
*
* FUNCTION NAME:mac_r
*
* PURPOSE:
*
* Multiply accumulate and round. Fractionally multiply two 16
* bit numbers together with saturation. Add that result to
* the 32 bit input with saturation. Finally round the result
* into a 16 bit number.
*
*
* INPUTS:
*
* var1
* 16 bit short signed integer (Shortword) whose value
* falls in the range 0xffff 8000 <= var1 <= 0x0000 7fff.
* var2
* 16 bit short signed integer (Shortword) whose value
* falls in the range 0xffff 8000 <= var2 <= 0x0000 7fff.
* L_var3
* 32 bit long signed integer (Longword) whose value
* falls in the range
* 0x8000 0000 <= L_var2 <= 0x7fff ffff.
*
* OUTPUTS:
*
* none
*
* RETURN VALUE:
*
* swOut
* 16 bit short signed integer (Shortword) whose value
* falls in the range
* 0xffff 8000 <= swOut <= 0x0000 7fff.
*
* IMPLEMENTATION:
*
* Fractionally multiply two 16 bit numbers together with
* saturation. The only numbers which will cause saturation on
* the multiply are 0x8000 * 0x8000.
*
* Add that result to the 32 bit input with saturation.
* Round the 32 bit result by adding 0x0000 8000 to the input.
* The result may overflow due to the add. If so, the result
* is saturated. The 32 bit rounded number is then shifted
* down 16 bits and returned as a Shortword.
*
* Please note that this is not a true multiply accumulate as
* most processors would implement it. The 0x8000*0x8000
* causes and overflow for this instruction. On most
* processors this would cause an overflow only if the 32 bit
* input added to it were positive or zero.
*
* KEYWORDS: mac, multiply accumulate, macr
*
*************************************************************************/
Shortword mac_r(Longword L_var3, Shortword var1, Shortword var2)
{
return (round(L_add(L_var3, L_mult(var1, var2))));
}
/***************************************************************************
*
* FUNCTION NAME: msu_r
*
* PURPOSE:
*
* Multiply subtract and round. Fractionally multiply two 16
* bit numbers together with saturation. Subtract that result from
* the 32 bit input with saturation. Finally round the result
* into a 16 bit number.
*
*
* INPUTS:
*
* var1
* 16 bit short signed integer (Shortword) whose value
* falls in the range 0xffff 8000 <= var1 <= 0x0000 7fff.
* var2
* 16 bit short signed integer (Shortword) whose value
* falls in the range 0xffff 8000 <= var2 <= 0x0000 7fff.
* L_var3
* 32 bit long signed integer (Longword) whose value
* falls in the range
* 0x8000 0000 <= L_var2 <= 0x7fff ffff.
*
* OUTPUTS:
*
* none
*
* RETURN VALUE:
*
* swOut
* 16 bit short signed integer (Shortword) whose value
* falls in the range
* 0xffff 8000 <= swOut <= 0x0000 7fff.
*
* IMPLEMENTATION:
*
* Fractionally multiply two 16 bit numbers together with
* saturation. The only numbers which will cause saturation on
* the multiply are 0x8000 * 0x8000.
*
* Subtract that result from the 32 bit input with saturation.
* Round the 32 bit result by adding 0x0000 8000 to the input.
* The result may overflow due to the add. If so, the result
* is saturated. The 32 bit rounded number is then shifted
* down 16 bits and returned as a Shortword.
*
* Please note that this is not a true multiply accumulate as
* most processors would implement it. The 0x8000*0x8000
* causes and overflow for this instruction. On most
* processors this would cause an overflow only if the 32 bit
* input added to it were positive or zero.
*
* KEYWORDS: mac, multiply accumulate, macr
*
*************************************************************************/
Shortword msu_r(Longword L_var3, Shortword var1, Shortword var2)
{
return (round(L_sub(L_var3, L_mult(var1, var2))));
}
/***************************************************************************
*
* FUNCTION NAME: mult
*
* PURPOSE:
*
* Perform a fractional multipy of the two 16 bit input numbers
* with saturation and truncation.
*
* INPUTS:
*
* var1
* 16 bit short signed integer (Shortword) whose value
* falls in the range 0xffff 8000 <= var1 <= 0x0000 7fff.
* var2
* 16 bit short signed integer (Shortword) whose value
* falls in the range 0xffff 8000 <= var2 <= 0x0000 7fff.
*
* OUTPUTS:
*
* none
*
* RETURN VALUE:
*
* swOut
* 16 bit short signed integer (Shortword) whose value
* falls in the range
* 0xffff 8000 <= swOut <= 0x0000 7fff.
*
* IMPLEMENTATION:
*
* Perform a fractional multipy of the two 16 bit input
* numbers. If var1 == var2 == -0x8000, output 0x7fff.
* Otherwise output var1*var2 >> 15. The output is a
* 16 bit number.
*
* KEYWORDS: mult, mulitply, mpy
*
*************************************************************************/
Shortword mult(Shortword var1, Shortword var2)
{
Longword L_product;
Shortword swOut;
L_product = L_mult(var1, var2);
swOut = extract_h(L_product);
return (swOut);
}
/***************************************************************************
*
* FUNCTION NAME: mult_r
*
* PURPOSE:
*
* Perform a fractional multipy and round of the two 16 bit
* input numbers with saturation.
*
* INPUTS:
*
* var1
* 16 bit short signed integer (Shortword) whose value
* falls in the range 0xffff 8000 <= var1 <= 0x0000 7fff.
* var2
* 16 bit short signed integer (Shortword) whose value
* falls in the range 0xffff 8000 <= var2 <= 0x0000 7fff.
*
* OUTPUTS:
*
* none
*
* RETURN VALUE:
*
* swOut
* 16 bit short signed integer (Shortword) whose value
* falls in the range
* 0xffff 8000 <= swOut <= 0x0000 7fff.
*
* IMPLEMENTATION:
*
* This routine is defined as the concatenation of the multiply
* operation and the round operation.
*
* The fractional multiply (L_mult) produces a saturated 32 bit
* output. This is followed by a an add of 0x0000 8000 to the
* 32 bit result. The result may overflow due to the add. If
* so, the result is saturated. The 32 bit rounded number is
* then shifted down 16 bits and returned as a Shortword.
*
*
* KEYWORDS: multiply and round, round, mult_r, mpyr
*
*************************************************************************/
Shortword mult_r(Shortword var1, Shortword var2)
{
Shortword swOut;
swOut = round(L_mult(var1, var2));
return (swOut);
}
/***************************************************************************
*
* FUNCTION NAME: negate
*
* PURPOSE:
*
* Negate the 16 bit input. 0x8000's negated value is 0x7fff.
*
* INPUTS:
*
* var1
* 16 bit short signed integer (Shortword) whose value
* falls in the range 0xffff 8000 <= var1 <= 0x0000 7fff.
*
* OUTPUTS:
*
* none
*
* RETURN VALUE:
*
* swOut
* 16 bit short signed integer (Shortword) whose value
* falls in the range
* 0xffff 8001 <= swOut <= 0x0000 7fff.
*
* KEYWORDS: negate, negative, invert
*
*************************************************************************/
Shortword negate(Shortword var1)
{
Shortword swOut;
if (var1 == SW_MIN)
swOut = SW_MAX;
else
swOut = -var1;
return (swOut);
}
/***************************************************************************
*
* FUNCTION NAME: norm_l
*
* PURPOSE:
*
* Get normalize shift count:
*
* A 32 bit number is input (possiblly unnormalized). Output
* the positive (or zero) shift count required to normalize the
* input.
*
* INPUTS:
*
* L_var1
* 32 bit long signed integer (Longword) whose value
* falls in the range
* 0x8000 0000 <= L_var1 <= 0x7fff ffff.
*
* OUTPUTS:
*
* none
*
* RETURN VALUE:
*
* swOut
* 16 bit short signed integer (Shortword) whose value
* falls in the range
* 0 <= swOut <= 31
*
*
*
* IMPLEMENTATION:
*
* Get normalize shift count:
*
* A 32 bit number is input (possiblly unnormalized). Output
* the positive (or zero) shift count required to normalize the
* input.
*
* If zero in input, return 0 as the shift count.
*
* For non-zero numbers, count the number of left shift
* required to get the number to fall into the range:
*
* 0x4000 0000 >= normlzd number >= 0x7fff ffff (positive number)
* or
* 0x8000 0000 <= normlzd number < 0xc000 0000 (negative number)
*
* Return the number of shifts.
*
* This instruction corresponds exactly to the Full-Rate "norm"
* instruction.
*
* KEYWORDS: norm, normalization
*
*************************************************************************/
Shortword norm_l(Longword L_var1)
{
Shortword swShiftCnt;
if (L_var1 != 0)
{
if (!(L_var1 & LW_SIGN))
{
/* positive input */
for (swShiftCnt = 0; !(L_var1 <= LW_MAX && L_var1 >= 0x40000000L);
swShiftCnt++)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -