⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 dspfns.h

📁 Keil for ARM.rar
💻 H
📖 第 1 页 / 共 2 页
字号:
    __asm {
        msr CPSR_f, armdsp_flagdata.armdsp_flags_word;
        adcs result, x, y;
        mrs flags, CPSR;
        orrvs flags, flags, #0x08000000; // set Q if V is set
        mov armdsp_flagdata.armdsp_flags_word, flags;
    }
    return result;
}

/*
 * Subtract one 32-bit signed integer, together with the Carry
 * variable, from another 32-bit signed integer, without
 * saturation.
 */
__inline Word32 L_sub_c(Word32 x, Word32 y)
{
    Word32 result, flags;

    __asm {
        msr CPSR_f, armdsp_flagdata.armdsp_flags_word;
        sbcs result, x, y;
        mrs flags, CPSR;
        orrvs flags, flags, #0x08000000; // set Q if V is set
        mov armdsp_flagdata.armdsp_flags_word, flags;
    }
    return result;
}

/*
 * Multiply two 16-bit signed integers together to give a 32-bit
 * signed integer, shift left by one _with_ saturation, and add
 * with carry to another 32-bit integer _without_ saturation.
 */
__inline Word32 L_macNs(Word32 accumulator, Word16 x, Word16 y)
{
    return L_add_c(accumulator, L_mult(x, y));
}

/*
 * Multiply two 16-bit signed integers together to give a 32-bit
 * signed integer, shift left by one _with_ saturation, and
 * subtract with carry from another 32-bit integer _without_
 * saturation.
 */
__inline Word32 L_msuNs(Word32 accumulator, Word16 x, Word16 y)
{
    return L_sub_c(accumulator, L_mult(x, y));
}

/*
 * Negate a 32-bit signed integer, with saturation. (Saturation is
 * only necessary when the input is -0x80000000.)
 */
__inline Word32 L_negate(Word32 x)
{
    if (x == ARMDSP_WORD32_MIN)
        return ARMDSP_WORD32_MAX;
    return -x;
}

/*
 * Multiply two 16-bit signed integers, shift the result right by
 * 15 with rounding, and saturate it. (Saturation is only necessary
 * if both inputs were -0x8000, in which case the result "should"
 * be 0x8000 and is saturated to 0x7FFF.)
 */
__inline Word16 mult_r(Word16 x, Word16 y)
{
    Word32 product;
    __asm {
        smulbb product, x, y;
        qdadd product, 0x8000, product;
    }
    return (Word16) (product >> 16);   /* qdadd adds one to the 15 */
}

/*
 * Shift a 32-bit signed integer left (or right, if the shift count
 * is negative). Saturate on overflow.
 */
__inline Word32 L_shl(Word32 x, Word16 shift)
{
    int lz;
    int absx;
    if (shift <= 0)
        return x >> (-shift);
    absx = (x < 0 ? -x : x);
    __asm {
        clz lz, absx;
    }
    if (shift < lz || x == 0)
        return x << shift;
    if (x < 0)
        return ARMDSP_WORD32_MIN;
    else
        return ARMDSP_WORD32_MAX;
}

/*
 * Shift a 32-bit signed integer right (or left, if the shift count
 * is negative). Saturate on overflow.
 */
__inline Word32 L_shr(Word32 x, Word16 shift)
{
    int lz;
    int absx;
    if (shift >= 0)
        return x >> shift;
    absx = (x < 0 ? -x : x);
    __asm {
        clz lz, absx;
    }
    if (-shift < lz || x == 0)
        return x << (-shift);
    if (x < 0)
        return ARMDSP_WORD32_MIN;
    else
        return ARMDSP_WORD32_MAX;
}

/*
 * Shift a 16-bit signed integer right, with rounding. Shift left
 * with saturation if the shift count is negative.
 */
__inline Word16 shr_r(Word16 x, Word16 shift)
{
    if (shift == 0 || x == 0)
        return (Word16) (x >> shift);
    if (shift > 0)
        return (Word16) (((x >> (shift-1)) + 1) >> 1);
    if (shift < -15)
        shift = -16;
    return saturate(x << (-shift));
}

/*
 * Multiply two 16-bit signed integers together to give a 32-bit
 * signed integer, shift left by one with saturation, and add to
 * another 32-bit integer with saturation (like L_mac). Then shift
 * the result right by 15 bits with rounding (like round).
 */
__inline Word16 mac_r(Word32 accumulator, Word16 x, Word16 y)
{
    return round(L_mac(accumulator, x, y));
}

/*
 * Multiply two 16-bit signed integers together to give a 32-bit
 * signed integer, shift left by one with saturation, and subtract
 * from another 32-bit integer with saturation (like L_msu). Then
 * shift the result right by 15 bits with rounding (like round).
 */
__inline Word16 msu_r(Word32 accumulator, Word16 x, Word16 y)
{
    return round(L_msu(accumulator, x, y));
}

/*
 * Shift a 16-bit signed integer left by 16 bits to generate a
 * 32-bit signed integer. The bottom 16 bits are zeroed.
 */
__inline Word32 L_deposit_h(Word16 x)
{
    return ((Word32)x) << 16;
}

/*
 * Sign-extend a 16-bit signed integer by 16 bits to generate a
 * 32-bit signed integer.
 */
__inline Word32 L_deposit_l(Word16 x)
{
    return (Word32)x;
}

/*
 * Shift a 32-bit signed integer right, with rounding. Shift left
 * with saturation if the shift count is negative.
 */
__inline Word32 L_shr_r(Word32 x, Word16 shift)
{
    int lz;
    int absx;
    if (shift == 0 || x == 0)
        return x >> shift;
    if (shift > 0) {
        Word32 x2 = x >> (shift-1);
        return (x2 >> 1) + (x2 & 1);
    }
    absx = (x < 0 ? -x : x);
    __asm {
        clz lz, absx;
    }
    if (-shift < lz || x == 0)
        return x << (-shift);
    if (x < 0)
        return ARMDSP_WORD32_MIN;
    else
        return ARMDSP_WORD32_MAX;
}

/*
 * Absolute value of a 32-bit signed integer. Saturating, so
 * abs(-0x80000000) becomes +0x7FFFFFFF.
 */
__inline Word32 L_abs(Word32 x)
{
    if (x >= 0)
        return x;
    else if (x == ARMDSP_WORD32_MIN)
        return ARMDSP_WORD32_MAX;
    else
        return -x;
}

/*
 * Return a saturated value appropriate to the most recent carry-
 * affecting operation (L_add_c, L_macNs, L_sub_c, L_msuNs).
 * 
 * In other words: return the argument if the Q flag is clear.
 * Otherwise, return -0x80000000 or +0x7FFFFFFF depending on
 * whether the Carry flag is set or clear (respectively).
 */
__inline Word32 L_sat(Word32 x)
{
    int qflag;
    __asm {
        mrs qflag, CPSR;
    }
    if (!(qflag & 0x08000000))
        return x;
    if (Carry)
        return ARMDSP_WORD32_MIN;
    else
        return ARMDSP_WORD32_MAX;
}

/*
 * Return the number of bits of left shift needed to arrange for a
 * 16-bit signed integer to have value >= 0x4000 or <= -0x4001.
 * 
 * Returns zero if x is zero.
 */
__inline Word16 norm_s(Word16 x)
{
    int lz;
    if (x == 0)
        return 0;                      /* 0 is a special case */
    x = (Word16) (x ^ (x >> 15));      /* invert x if it's negative */
    __asm {
        clz lz, x;
    }
    return (Word16) (lz - 17);
}

/*
 * Divide one 16-bit signed integer by another, and produce a
 * 15-bit fixed point fractional result (by multiplying the true
 * mathematical result by 0x8000). The divisor (denominator) is
 * assumed to be non-zero and also assumed to be greater or equal
 * to the dividend (numerator). Hence the (unscaled) result is
 * necessarily within the range [0,1].
 * 
 * Both operands are assumed to be positive.
 * 
 * After division, the result is saturated to fit into a 16-bit
 * signed integer. (The only way this can happen is if the operands
 * are equal, so that the result would be 1, i.e. +0x8000 in 15-bit
 * fixed point.)
 */
__inline Word16 div_s(Word16 x, Word16 y)
{
    Word32 quot;
    assert(y > 0);
    assert(x >= 0);
    assert(x <= y);
    quot = 0x8000 * x;
    quot /= y;
    if (quot > ARMDSP_WORD16_MAX)
        return ARMDSP_WORD16_MAX;
    else
        return (Word16)quot;
}

/*
 * Return the number of bits of left shift needed to arrange for a
 * 32-bit signed integer to have value >= 0x40000000 (if 
 * 
 * Returns zero if x is zero.
 */
__inline Word16 norm_l(Word32 x)
{
    int lz;
    if (x == 0)
        return 0;                      /* 0 is a special case */
    x ^= (x >> 31);                    /* invert x if it's negative */
    __asm {
        clz lz, x;
    }
    return (Word16) (lz - 1);
}

#ifdef __cplusplus
}
#endif

#endif /* ARMDSP_DSPFNS_H */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -