0
mirror of https://github.com/Indemsys/Frequency_Inverter.git synced 2026-05-03 04:25:42 +00:00
Files
2022-01-04 12:22:53 +02:00

1179 lines
35 KiB
C

/******************************************************************************
*
* (c) Copyright 2009, Freescale & STMicroelectronics
*
***************************************************************************//*!
*
* @file SWLIBS_Inlines.h
*
* @author Andrzej Lara, Roman Filka
*
* @version 1.0.1.0
*
* @date Dec-6-2012
*
* @brief Basic inline functions definition file.
*
*******************************************************************************
* This file shall be included only after inclusion of SWLIBS_Typedefs.h
******************************************************************************/
#ifndef _SWLIBS_INLINES_H
#define _SWLIBS_INLINES_H
#ifdef __cplusplus
extern "C" {
#endif
#include "SWLIBS_Defines.h"
#if defined(__CWCC__)
#include "intrinsic_cw.h"
#undef __STATIC_INLINE
#define __STATIC_INLINE static inline
#elif defined(__IAR_SYSTEMS_ICC__)
#include <intrinsics.h>
#undef __STATIC_INLINE
#define __STATIC_INLINE static inline
#elif defined(__CC_ARM)
#include "MK40N512MD100.h" //has to be here, without this include it does not work - it is device dependent - should be change
#endif
/******************************************************************************
| defines and macros (scope: module-local)
|----------------------------------------------------------------------------*/
/******************************************************************************
| Typedefs and structures (scope: module-local)
|----------------------------------------------------------------------------*/
/******************************************************************************
| Exported variables
|----------------------------------------------------------------------------*/
/******************************************************************************
| Exported function prototypes
|----------------------------------------------------------------------------*/
/******************************************************************************
| Inline functions
|----------------------------------------------------------------------------*/
/*------------------------------------------------------------------------*//*!
@brief Absolute value of 16-bit fractional type.
@return Absolute value of the input argument.
@note Overflow is not detected.
-----------------------------------------------------------------------------*/
__STATIC_INLINE Frac16 F16Abs(register Frac16 x)
{
return (Frac16) ((x<0) ? -(x):(x));
}
/*------------------------------------------------------------------------*//*!
@brief Absolute value with overflow control of 16-bit fractional
number.
@return Absolute value of the input argument.
@note Overflow is detected and the function saturates if the result
does not fit into the return type.
-----------------------------------------------------------------------------*/
__STATIC_INLINE Frac16
F16AbsSat(register Frac16 x)
{
register Word32 y;
y = (F16TOINT32(x)<0) ? -F16TOINT32(x):F16TOINT32(x);
y = (y == -(Word32) INT16_MIN) ? (Word32) INT16_MAX:y;
return INT32TOF16(y);
}
/*------------------------------------------------------------------------*//*!
@brief Negative value of 16-bit fraction type.
@return Negative value of the input argument.
@note Overflow is not detected.
-----------------------------------------------------------------------------*/
__STATIC_INLINE Frac16
F16Neg(register Frac16 x)
{
return (Frac16) (-x);
}
/*------------------------------------------------------------------------*//*!
@brief Negative value with overflow control of 16-bit fraction type.
@return Negative value of the input argument.
@note Overflow is detected and the function saturates if the result
cannot fit in the return type.
-----------------------------------------------------------------------------*/
__STATIC_INLINE Frac16
F16NegSat(register Frac16 x)
{
register Word32 y;
y = -F16TOINT32(x);
y = (y == -(Word32) INT16_MIN) ? (Word32) INT16_MAX:y;
return INT32TOF16(y);
}
/*------------------------------------------------------------------------*//*!
@brief Add two fractional 16-bit values.
@return Sum of the input arguments.
@note Overflow is not detected.
-----------------------------------------------------------------------------*/
__STATIC_INLINE Frac16
F16Add(register Frac16 x, register Frac16 y)
{
return (Frac16) (x + y);
}
/*------------------------------------------------------------------------*//*!
@brief Add with overflow control two fractional 16-bit values.
@return Sum of the input arguments.
@note Overflow is detected. The function saturates the return
value if it cannot fit in the return type.
-----------------------------------------------------------------------------*/
__STATIC_INLINE Frac16
F16AddSat(register Frac16 x, register Frac16 y)
{
return __QADD16(x,y);
}
/*------------------------------------------------------------------------*//*!
@brief Subtraction of two fractional 16-bit values. The second
argument is subtracted from the first one.
@return The subtraction of the second argument from the first argument.
@note Overflow is not detected.
-----------------------------------------------------------------------------*/
__STATIC_INLINE Frac16
F16Sub(register Frac16 x, register Frac16 y)
{
return (Frac16) (x - y);
}
/*------------------------------------------------------------------------*//*!
@brief Subtraction with overflow control of two fractional 16-bit
numbers. The second argument is subtracted from the first one.
@return The subtraction of the second argument from the first argument.
@note Overflow is detected. The function saturates the return
value if it cannot fit in the return type.
-----------------------------------------------------------------------------*/
__STATIC_INLINE Frac16
F16SubSat(register Frac16 x, register Frac16 y)
{
return __QSUB16(x,y);
}
/*------------------------------------------------------------------------*//*!
@brief Fractional multiplication of two fractional 16-bit values.
@return 16 most significant bits of fractional multiplication of the
input arguments. The extra bits beyond the 16-bit boundary
are discarded.
@note Overflow is not detected.
-----------------------------------------------------------------------------*/
__STATIC_INLINE Frac16
F16Mul(register Frac16 x, register Frac16 y)
{
return INT32TOF16((F16TOINT32(x)*F16TOINT32(y))>>15);
}
/*------------------------------------------------------------------------*//*!
@brief Fractional multiplication of two fractional 16-bit values.
@return 16 most significant bits of fractional multiplication of the
input arguments. The extra bits beyond the 16-bit boundary
are discarded.
@note Overflow is detected. The functions saturates the return
value if it cannot fit into the return type.
-----------------------------------------------------------------------------*/
__STATIC_INLINE Frac16
F16MulSat(register Frac16 x, register Frac16 y)
{
register Word32 z;
z = (Word32) (((Word32) x)*((Word32) y)>>15);
z = (z > (Word32) INT16_MAX) ? (Word32) INT16_MAX:z;
return INT32TOF16(z);
}
/*------------------------------------------------------------------------*//*!
@brief Fractional division of two 16-bit numbers. The first argument
is the numerator and the second one is the denominator.
@return 15 most significant bits of fractional division of the first
by the second argument. The extra bits beyond the 15-bit boundary
are discarded.
@note Overflow is not detected. The first argument must be lower
in magnitude than the second argument, otherwise the result
is undefined.
If the return value cannot be represented by the 16-bit
fractional format due to finite resolution, the return value is
rounded toward zero.
-----------------------------------------------------------------------------*/
__STATIC_INLINE Frac16
F16Div(register Frac16 x, register Frac16 y)
{
register Word32 n;
register Word32 d;
register Word32 q;
n = F16TOINT32(x)<<15;
d = F16TOINT32(y);
q = n/d;
return INT32TOF16(q);
}
/*------------------------------------------------------------------------*//*!
@brief Fractional division of a 32-bit by a 16-bit numbers. The first
32-bit argument is the numerator and the second 16-bit argument
is the denominator.
@return 15 most significant bits of fractional division of the first
by the second argument. The extra bits beyond the 15-bit boundary
are discarded.
@note Overflow is not detected. The first argument must be lower
in magnitude than the second argument, otherwise the result
is undefined.
If the return value cannot be represented by the 16-bit
fractional format due to finite resolution, the return value is
rounded down (so called rounding toward minus infinity). It should
be noticed that the used rounding mode is different from the
rounding mode used in the integer division (rounding toward zero).
-----------------------------------------------------------------------------*/
__STATIC_INLINE Frac16
F16DivF32F16(register Frac32 x, register Frac16 y)
{
register Word32 n;
register Word32 d;
register Word32 q;
n = F32TOINT32(x);
d = F16TOINT32(y);
q = n/d;
q >>= 1;
return INT32TOF16(q);
}
/*------------------------------------------------------------------------*//*!
@brief Right, bidirectional shift of 16-bit fractional value (x)
by the specified shift amount (s).
@return 16-bit fractional value shifted by the shift amount, right
is the positive direction. The bits beyond the 16-bit
boundary of the results are discarded.
@note Overflow is not detected.
The shift amount cannot exceed in magnitude the bit-width of
the shift value, that means must be within the range -16...16.
Otherwise the result of the function is undefined.
-----------------------------------------------------------------------------*/
__STATIC_INLINE Frac16
F16Shr(register Frac16 x, register Word16 s)
{
return (Frac16) ((s<0) ? x<<(-s):x>>s);
}
/*------------------------------------------------------------------------*//*!
@brief Right, bidirectional shift of 16-bit fractional value with
overflow control.
@return 16-bit fractional value shifted by the shift amount, right is
the positive direction. The bits beyond the 16-bit boundary
are discarded.
@note Overflow is detected and the function saturates if the return
value cannot fit into the return type.
The shift amount cannot exceed in magnitude the bit-width of
the shift value, that means must be within the range -16...16.
Otherwise the result of the function is undefined.
-----------------------------------------------------------------------------*/
__STATIC_INLINE Frac16
F16ShrSat(register Frac16 x, register Word16 s)
{
register Word32 xl;
xl = F16TOINT32(x);
if ( s < 0 )
{
xl = xl << (-s);
xl = (xl < (Word32) INT16_MIN) ? (Word32) INT16_MIN:xl;
xl = (xl > (Word32) INT16_MAX) ? (Word32) INT16_MAX:xl;
}
else
{
xl = xl >> s;
}
return INT32TOF16(xl);
}
/*------------------------------------------------------------------------*//*!
@brief Left, bidirectional shift of 16-bit fractional value.
@return 16-bit fractional value shifted by the shift amount, left is
the positive direction. The bits beyond the 16-bit boundary
are discarded.
@note Overflow is not detected.
The shift amount cannot exceed in magnitude the bit-width of
the shift value, that means must be within the range -16...16.
Otherwise the result of the function is undefined.
-----------------------------------------------------------------------------*/
__STATIC_INLINE Frac16
F16Shl(register Frac16 x, register Word16 s)
{
return INT32TOF16((s<0) ? F16TOINT32(x)>>(-s):F16TOINT32(x)<<s);
}
/*------------------------------------------------------------------------*//*!
@brief Left, bidirectional shift of 16-bit fractional value with
overflow control.
@return 16-bit fractional value shifted by the shift amount, left is
the positive direction. The bits beyond the 16-bit boundary
are discarded.
@note Overflow is detected. The function returns a saturated
fractional value if the return value cannot fit into the return
type.
The shift amount cannot exceed in magnitude the bit-width of
the shift value, that means must be within the range -16...16.
Otherwise the result of the function is undefined.
-----------------------------------------------------------------------------*/
__STATIC_INLINE Frac16
F16ShlSat(register Frac16 x, register Word16 s)
{
register Word32 xl;
xl = F16TOINT32(x);
if ( s < 0 )
{
xl = xl >> (-s);
}
else
{
xl = xl << s;
xl = (xl < (Word32) INT16_MIN) ? (Word32) INT16_MIN:xl;
xl = (xl > (Word32) INT16_MAX) ? (Word32) INT16_MAX:xl;
}
return INT32TOF16(xl);
}
/*------------------------------------------------------------------------*//*!
@brief Right, unidirectional shift of 16-bit fractional value (x) by
the specified shift amount (s).
@return 16-bit fractional value shifted right by the shift amount.
The bits beyond the 16-bit boundary of the result are discarded.
@note This is the unidirectional right shift.
The shift amount cannot exceed in magnitude the bit-width of
the shifted value, that means it must be within the range 0...15.
Otherwise the result of the function is undefined.
@warning This function is target dependent. The shift result for the
negative value to be shifted may be undefined.
-----------------------------------------------------------------------------*/
__STATIC_INLINE Frac16
F16Shruni(register Frac16 x, register UWord16 s)
{
return (Frac16) (x>>s);
}
/*------------------------------------------------------------------------*//*!
@brief Counts the number of left shift needed for normalization of
the input 16-bit fractional value
@return The number of left shift needed to normalize the argument.
For the input 0 returns 0.
-----------------------------------------------------------------------------*/
__STATIC_INLINE Word16
F16Norm(register Frac16 x)
{
register Word32 sham;
register Word32 shdel;
register Word32 xlsh;
register Word32 xl;
register Word32 b;
if ( x == 0)
{
return 0;
}
b = (x >= 0) ? 0x00007fff:0x00008000;
sham = 0;
shdel = 8;
xl = (x<0) ? -F16TOINT32(x):F16TOINT32(x);
do
{
sham = sham + shdel;
xlsh = xl << sham;
sham = (xlsh > b) ? sham - shdel:sham;
shdel >>= 1;
} while ( shdel > 0 );
return (Word16) sham;
}
/*------------------------------------------------------------------------*//*!
@brief Rounds the input 32-bit fractional value to 16-bit fractional
value.
@return Round to 16-bit fractional value.
@note Rounding is performed by adding 0x00008000 to the 32-bit
argument (round to nearest). Overflow is not detected.
-----------------------------------------------------------------------------*/
__STATIC_INLINE Frac16
F16Roundton(register Frac32 x)
{
return INT32TOF16((F32TOINT32(x) + 0x00008000)>>16);
}
/*------------------------------------------------------------------------*//*!
@brief Rounds the input 32-bit fractional value to 16-bit fractional
value.
@return Round to 16-bit fractional value.
@note Rounding is performed by adding 0x00008000 to the 32-bit
argument (round to nearest). Overflow is detected. The function
saturates. if the return value does not fit into the return type.
-----------------------------------------------------------------------------*/
__STATIC_INLINE Frac16
F16RoundtonSat(register Frac32 x)
{
register Word32 y;
y = F32TOINT32(x) + 0x00008000;
y = (F32TOINT32(x) >= 0x7fff8000) ? F32TOINT32(x):y;
return INT32TOF16(y>>16);
}
/*------------------------------------------------------------------------*//*!
@brief Absolute value of 32-bit fractional type.
@return Absolute value of the input argument.
@note Overflow is not detected.
-----------------------------------------------------------------------------*/
__STATIC_INLINE Frac32
F32Abs(register Frac32 x)
{
return (x<0) ? -x:x;
}
/*------------------------------------------------------------------------*//*!
@brief Absolute value with overflow control of 32-bit fractional type.
@return Absolute value of the input argument.
@note Overflow is detected and the function saturates the result if
it cannot fit into the return type.
-----------------------------------------------------------------------------*/
__STATIC_INLINE Frac32
F32AbsSat(register Frac32 x)
{
register Word32 y;
y = (F32TOINT32(x)<0) ? -F32TOINT32(x):F32TOINT32(x);
y = (y == INT32_MIN) ? INT32_MAX:y;
return INT32TOF32(y);
}
/*------------------------------------------------------------------------*//*!
@brief Negative value of 32-bit fraction type.
@return Negative value of the input argument.
@note Overflow is not detected.
-----------------------------------------------------------------------------*/
__STATIC_INLINE Frac32
F32Neg(register Frac32 x)
{
return -x;
}
/*------------------------------------------------------------------------*//*!
@brief Negative value with overflow control of 32-bit fraction type.
@return Negative value of the input argument.
@note Overflow is detected and the function saturates if the result
cannot fit in the return type.
-----------------------------------------------------------------------------*/
__STATIC_INLINE Frac32
F32NegSat(register Frac32 x)
{
register Word32 y;
y = -F32TOINT32(x);
y = (y == INT32_MIN) ? INT32_MAX:y;
return INT32TOF32(y);
}
/*------------------------------------------------------------------------*//*!
@brief Add two fractional 32-bit values.
@return Sum of the input arguments.
@note Overflow is not detected.
-----------------------------------------------------------------------------*/
__STATIC_INLINE Frac32
F32Add(register Frac32 x, register Frac32 y)
{
return x + y;
}
/*------------------------------------------------------------------------*//*!
@brief Add with overflow control two fractional 32-bit values.
@return Sum of the input arguments.
@note Overflow is detected. The function saturates the return
value if it cannot fit in the return type.
-----------------------------------------------------------------------------*/
__STATIC_INLINE Frac32
F32AddSat(register Frac32 x, register Frac32 y)
{
return __QADD(x,y);
}
/*------------------------------------------------------------------------*//*!
@brief Subtraction of two fractional 32-bit values. The second
argument is subtracted from the first one.
@return The subtraction of the second argument from the first argument.
@note Overflow is not detected.
-----------------------------------------------------------------------------*/
__STATIC_INLINE Frac32
F32Sub(register Frac32 x, register Frac32 y)
{
return x - y;
}
/*------------------------------------------------------------------------*//*!
@brief Subtraction with overflow control of two fractional 32-bit
numbers. The second argument is subtracted from the first one.
@return The subtraction of the second argument from the first argument.
@note Overflow is detected. The function saturates the return
value if it cannot fit in the return type.
-----------------------------------------------------------------------------*/
__STATIC_INLINE Frac32
F32SubSat(register Frac32 x, register Frac32 y)
{
return __QSUB (x,y);
}
/*------------------------------------------------------------------------*//*!
@brief Fractional multiplication of two fractional 16-bit values.
@return All 32 bits of fractional multiplication of the two 16-bit
input arguments.
@note Overflow is not detected.
-----------------------------------------------------------------------------*/
__STATIC_INLINE Frac32
F32MulF16F16(register Frac16 x, register Frac16 y)
{
return INT32TOF32((F16TOINT32(x)*F16TOINT32(y))<<1);
}
/*------------------------------------------------------------------------*//*!
@brief Fractional multiplication of two fractional 16-bit values with
overflow detection.
@return All 32 bits of fractional multiplication of the two 16-bit
input arguments.
@note Overflow is detected. The functions saturates the return
value if it cannot fit into the return type.
-----------------------------------------------------------------------------*/
__STATIC_INLINE Frac32
F32MulSatF16F16(register Frac16 x, register Frac16 y)
{
register Word32 m;
m = (F16TOINT32(x)*F16TOINT32(y))<<1;
m = (m == INT32_MIN) ? INT32_MAX:m;
return INT32TOF32(m);
}
/*------------------------------------------------------------------------*//*!
@brief Fractional multiplication of two fractional 32-bit values.
@return 32 most significant bits of fractional multiplication of the
input arguments.
@note Overflow is not detected.
-----------------------------------------------------------------------------*/
__STATIC_INLINE Frac32
F32Mul(register Frac32 x, register Frac32 y)
{
return INT32TOF32((Word32) ((F32TOINT64(x)*F32TOINT64(y))>>31));
}
/*------------------------------------------------------------------------*//*!
@brief Fractional multiplication of two fractional 32-bit values.
@return 32 most significant bits of fractional multiplication of the
input arguments.
@note Overflow is detected. The functions saturates the return
value if it cannot fit into the return type.
-----------------------------------------------------------------------------*/
__STATIC_INLINE Frac32
F32MulSat(register Frac32 x, register Frac32 y)
{
register Word32 z;
z = (Word32) ((F32TOINT64(x)*F32TOINT64(y))>>31);
z = (z == INT32_MIN) ? INT32_MAX:z;
return INT32TOF32(z);
}
/*------------------------------------------------------------------------*//*!
@brief Multiply two 16-bit fractional values and accumulate with
a 32-bit fractional value.
@return All bits of the multiply-and-accumulate operation.
@note Overflow is not detected.
-----------------------------------------------------------------------------*/
__STATIC_INLINE Frac32
F32MacF16F16(register Frac32 a, register Frac16 x, register Frac16 y)
{
return INT32TOF32((F32TOINT32(a) + (Word32) ((F32TOINT16(x)*F32TOINT16(y))<<1)));
}
/*------------------------------------------------------------------------*//*!
@brief Multiply two 16-bit fractional values and accumulate with
a 32-bit fractional value. Perform overflow control.
@return All bits of the multiply-and-accumulate operation.
@note Overflow is detected. The functions saturates the return
value if it cannot fit into the return type.
-----------------------------------------------------------------------------*/
__STATIC_INLINE Frac32
F32MacSatF16F16(register Frac32 a, register Frac16 x, register Frac16 y)
{
register Word32 m;
m = F32TOINT32(x)*F32TOINT32(y);
m <<=1;
return __QADD(a,m);
}
/*------------------------------------------------------------------------*//*!
@brief Fractional division of two 32-bit values. The first argument is
the numerator and the second one is the denominator.
@return 31 most significant bits of the result of the fractional
division of the first by the second argument. The extra bits
beyond the 31-bit boundary are discarded.
@note Overflow is not detected. The first argument must be lower in
magnitude than the second argument, otherwise the result is
undefined.
If the return value cannot be represented by the 32-bit
fractional format due to finite resolution, the return value is
rounded toward zero.
-----------------------------------------------------------------------------*/
__STATIC_INLINE Word32 F32DivNorm(register UWord32 x)
{
register Word32 b;
register Word32 m;
register Word32 mm;
register Word32 mmp;
register Word32 mmn;
m = 15;
mmp = 8;
mmn = -8;
b = 1<<m;
mm = (x >= b) ? mmp:mmn;
m += mm;
mmp = 4;
mmn = -4;
b = 1<<m;
mm = (x >= b) ? mmp:mmn;
m += mm;
mmp = 2;
mmn = -2;
b = 1<<m;
mm = (x >= b) ? mmp:mmn;
m += mm;
mmp = 1;
mmn = -1;
b = 1<<m;
mm = (x >= b) ? mmp:mmn;
m += mm;
mmp = 0;
b = 1<<m;
mm = (x >= b) ? mmp:mmn;
m += mm;
m = 30 - m;
return m;
}
__STATIC_INLINE Frac32
F32Div(register Frac32 x, register Frac32 y)
{
register UWord32 dh;
register UWord32 dl;
register Word32 q;
register UWord32 n;
register UWord32 nlsb;
register UWord32 d;
register UWord32 qh;
register UWord32 ql;
register UWord32 r1;
register UWord32 r2;
register Word64 r;
register Word32 sign;
register Word32 m;
/* Special case for denominator at minimum.
*/
if ( y == 0x80000000 )
{
return -x;
}
/* Record the sign and make argument absolute */
sign = x^y;
n = (UWord32) ((F32TOINT32(x) < 0) ? -F32TOINT32(x):F32TOINT32(x));
d = (UWord32) ((F32TOINT32(y) < 0) ? -F32TOINT32(y):F32TOINT32(y));
/* Normalize denominator and numerator*/
m = F32DivNorm(d);
d <<= m;
n <<= m;
/* Record lsb of n*/
nlsb = (n & 0x00000001)<<15;
dh = d>>16;
dl = 0x0000ffff & d;
/* Compute tentative 15 higher bits of the quotient */
qh = n/dh;
/* Limit the quotient to avoid overflow */
qh = (qh > 0x0000ffff) ? 0x0000ffff:qh;
/* Shift down to avoid overflow, lsb of n is discarded */
qh >>= 1;
n >>= 1;
/* Compute the first remainder */
r1 = qh*dh;
r2 = qh*dl;
r1 = n-r1;
r = ((Word64) r1)<<16;
r = r - r2;
/* Retrieve lsb of n */
r += nlsb;
/* Make appropriate correction */
if ( r < 0 )
{
r = r + d;
qh = qh - 1;
}
if ( r < 0 )
{
r = r + d;
qh = qh - 1;
}
/* Compute tentative 16 lower bits of the quotient */
n = (UWord32) r;
ql = n/dh;
/* Limit the quotient to avoid overflow */
ql = (ql > 0x0000ffff) ? 0x0000ffff:ql;
/* Compute the second remainder */
r1 = ql*dh;
r2 = ql*dl;
r1 = n-r1;
r = ((Word64) r1)<<16;
r = r - r2;
/* Make appropriate correction */
if ( r < 0 )
{
ql = ql - 1;
r = r + d;
}
if ( r < 0 )
{
ql = ql - 1;
r = r + d;
}
if ( r < 0 )
{
ql = ql - 1;
r = r + d;
}
if ( r < 0 )
{
ql = ql - 1;
r = r + d;
}
/* Combine the higer and lower bits of the quotient */
q = (Word32) ((qh<<16) | ql);
/* Correct sign */
q = (sign < 0) ? -q:q;
return INT32TOF32(q);
}
/*------------------------------------------------------------------------*//*!
@brief Fractional division of a 32-bit by a 16-bit numbers. The first
32-bit argument is the numerator and the second 16-bit argument
is the denominator.
@return 31 most significant bits of the fractional division of the first
by the second argument. The extra bits beyond the 31-bit boundary
are discarded.
@note Overflow is not detected. The first argument must be lower
in magnitude than the second argument, otherwise the result
is undefined.
If the return value cannot be represented by the 32-bit
fractional format due to finite resolution, the return value
is rounded toward zero.
-----------------------------------------------------------------------------*/
__STATIC_INLINE Frac32
F32DivF32F16(register Frac32 x, register Frac16 y)
{
register UWord32 n;
register UWord32 d;
register Word32 r;
register Word32 q;
register UWord32 qh;
register UWord32 ql;
register Word32 sign;
n = (UWord32) ((x < 0) ? -F32TOINT32(x):F32TOINT32(x));
d = (UWord32) ((y < 0) ? -F16TOINT32(y):F16TOINT32(y));
sign = x^(y<<16);
qh = n/d;
r = (Word32) (n - qh*d);
r <<= 16;
ql = r/d;
ql >>= 1;
qh <<=15;
q = (Word32) (qh | ql);
q = (sign < 0) ? -q:q;
return INT32TOF32(q);
}
/*------------------------------------------------------------------------*//*!
@brief Right, bidirectional shift of 32-bit fractional value (x) by
the specified shift amount (s).
@return 32-bit fractional value shifted by the shift amount, right is
the positive direction. The bits beyond the 32-bit boundary
of the results are discarded.
@note Overflow is not detected.
The shift amount cannot exceed in magnitude the bit-width of
the shift value, that means must be within the range -32...32.
Otherwise the result of the function is undefined.
-----------------------------------------------------------------------------*/
__STATIC_INLINE Frac32
F32Shr(register Frac32 x, register Word32 s)
{
return (s<0) ? x<<(-s):x>>s;
}
/*------------------------------------------------------------------------*//*!
@brief Right, bidirectional shift of 32-bit fractional value with
overflow control.
@return 32-bit fractional value shifted by the shift amount, right is
the positive direction. The bits beyond the 32-bit boundary
are discarded.
@note Overflow is detected and the function saturates if the return
value cannot fit into the return type.
The shift amount cannot exceed in magnitude the bit-width of
the shift value, that means must be within the range -32...32
Otherwise the result of the function is undefined.
-----------------------------------------------------------------------------*/
__STATIC_INLINE Frac32
F32ShrSat(register Frac32 x, register Word32 s)
{
register Word32 y;
register Word32 xmax;
register Word32 xmin;
if(s < 0)
{
s = -s;
xmax = INT32_MAX >> s;
xmin = INT32_MIN >> s;
y = x << s;
y = (x > xmax) ? INT32_MAX:y;
y = (x <= xmin) ? INT32_MIN:y;
}
else
{
y = x >> s;
}
return INT32TOF32(y);
}
/*------------------------------------------------------------------------*//*!
@brief Left, bidirectional shift of 32-bit fractional value.
@return 32-bit fractional value shifted by the shift amount, left is
the positive direction. The bits beyond the 32-bit boundary
are discarded.
@note Overflow is not detected.
The shift amount cannot exceed in magnitude the bit-width of
the shift value, that means must be within the range -32...32.
Otherwise the result of the function is undefined.
-----------------------------------------------------------------------------*/
__STATIC_INLINE Frac32
F32Shl(register Frac32 x, register Word32 s)
{
return (s<0) ? x>>(-s):x<<s;
}
/*------------------------------------------------------------------------*//*!
@brief Left, bidirectional shift of 32-bit fractional value with
overflow control.
@return 32-bit fractional value shifted by the shift amount, left is
the positive direction. The bits beyond the 32-bit boundary
are discarded.
@note Overflow is detected. The function returns a saturated
fractional value if the return value cannot fit into the return
type.
The shift amount cannot exceed in magnitude the bit-width of
the shift value, that means must be within the range -32...32.
Otherwise the result of the function is undefined.
-----------------------------------------------------------------------------*/
__STATIC_INLINE Frac32
F32ShlSat(register Frac32 x, register Word32 s)
{
register Word32 y;
register Word32 xmax;
register Word32 xmin;
if(s > 0)
{
xmax = INT32_MAX >> s;
xmin = INT32_MIN >> s;
y = x << s;
y = (x > xmax) ? INT32_MAX:y;
y = (x <= xmin) ? INT32_MIN:y;
}
else
{
y = x >> (-s);
}
return INT32TOF32(y);
}
/*------------------------------------------------------------------------*//*!
@brief Right, unidirectional shift of 32-bit fractional value (x) by
the specified shift amount (s).
@return 32-bit fractional value shifted right by the shift amount.
The bits beyond the 32-bit boundary of the result are discarded.
@note This is the unidirectional right shift.
The shift amount cannot exceed in magnitude the bit-width of
the shifted value, that means it must be within the range 0...31.
Otherwise the result of the function is undefined.
@warning This function is target dependent. The shift result for the
negative value to be shifted may be undefined.
-----------------------------------------------------------------------------*/
__STATIC_INLINE Frac32
F32Shruni(register Frac32 x, register UWord32 s)
{
return x>>s;
}
/*------------------------------------------------------------------------*//*!
@brief Counts the number of left shift needed for normalization of
the input 32-bit fractional value
@return The number of left shift needed to normalize the argument.
For the input 0 returns 0.
-----------------------------------------------------------------------------*/
__STATIC_INLINE Word32
F32Norm(register Frac32 x)
{
register Word32 sham;
register Word32 shamd;
register Word32 shamp;
register Word32 shamn;
register Word32 shcorr;
register Word32 b;
register Word32 one;
if(x == 0)
{
return 0;
}
if(x == 0x80000000)
{
return 0;
}
shcorr = (x<0) ? 1:0;
x = (x<0) ? (-x):x;
one = 1;
sham = 15;
shamp = 8;
shamn = -8;
do
{
b = one<<sham;
shamd = (x>= b) ? shamp:shamn;
sham += shamd;
shamp >>= 1;
shamn >>= 1;
} while(shamp > 0);
shamn = -1;
b = one<<sham;
shamd = ( x>= b) ? shamp:shamn;
sham += shamd;
sham = 30 - sham + shcorr;
return sham;
}
/* NOTE:
* The next two functions are commented out because lcc (matlab compiler
* is unable to compile them). See also the note at the start of the
* file.
*/
#endif /* _SWLIBS_INLINES_H_ */