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

📄 dspfns.h

📁 Keil for ARM.rar
💻 H
📖 第 1 页 / 共 2 页
字号:
/* dspfns.h
 *
 * Copyright 2001 ARM Limited. All rights reserved.
 *
 * RCS $Revision: 1.1.2.2 $
 * Checkin $Date: 2001/07/31 16:10:40 $
 * Revising $Author: statham $
 */

/* ----------------------------------------------------------------------
 * This header file provides a set of DSP-type primitive
 * operations, such as 16-bit and 32-bit saturating arithmetic. The
 * operations it provides are similar to the ones used by the ITU
 * for publishing specifications of DSP algorithms.
 * 
 * This header file is intended as an example implementation. It
 * demonstrates how to use the inline assembly feature in the ARM
 * compilers, to construct intrinsic functions that provide
 * C-language access to the ARM9E's DSP capability.
 * 
 * This header file is NOT SUFFICIENT to be used alone - you need
 * to include "dspfns.c" from the examples\dsp directory as well.
 */

#ifndef ARMDSP_DSPFNS_H
#define ARMDSP_DSPFNS_H

#include <assert.h>

#ifndef ARMDSP_WORD32_DEFINED
#define ARMDSP_WORD32_DEFINED
typedef signed int Word32;
typedef signed short Word16;
#define ARMDSP_WORD32_MAX ((Word32)0x7FFFFFFF)
#define ARMDSP_WORD32_MIN ((Word32)-0x80000000)
#define ARMDSP_WORD16_MAX ((Word16)0x7FFF)
#define ARMDSP_WORD16_MIN ((Word16)-0x8000)
#endif

typedef int Flag;

/*
 * This global variable needs to exist somewhere in the compiled
 * program in order for the flag-using functions to work. You can
 * either include the declaration
 * 
 *   armdsp_flagdata_union armdsp_flagdata;
 * 
 * in at least one of your source files (that includes this
 * header), or compile in "dspfns.c" from the examples\dsp
 * directory.
 */
typedef union {
    unsigned int armdsp_flags_word;
    struct {
#ifdef __BIG_ENDIAN
        Flag armdsp_n:1, armdsp_z:1, armdsp_c:1, armdsp_v:1, armdsp_q:1, armdsp_unused:27;
#else
        Flag armdsp_unused:27, armdsp_q:1, armdsp_v:1, armdsp_c:1, armdsp_z:1, armdsp_n:1;
#endif
    } armdsp_bitfields;
} armdsp_flagdata_union;
extern armdsp_flagdata_union armdsp_flagdata;

#define Carry ( armdsp_flagdata.armdsp_bitfields.armdsp_c )
#define Overflow ( armdsp_flagdata.armdsp_bitfields.armdsp_q )

#ifdef __cplusplus
extern "C" {
#endif
#if 0
}
#endif

/*
 * Convert a 32-bit signed integer into a 16-bit signed integer by
 * saturation.
 */
__inline Word16 saturate(Word32 x)
{
    if (x > ARMDSP_WORD16_MAX)
        Overflow = 1, x = ARMDSP_WORD16_MAX;
    else if (x < ARMDSP_WORD16_MIN)
        Overflow = 1, x = ARMDSP_WORD16_MIN;
    return (Word16) x;
}

/*
 * Add two 16-bit signed integers with saturation.
 */
__inline Word16 add(Word16 x, Word16 y)
{
    Word32 xs, ys, rs;
    __asm {
        mov xs, x, lsl #16;
        mov ys, y, lsl #16;
        qadd rs, xs, ys;
    }
    return (Word16) (rs >> 16);
}

/*
 * Subtract one 16-bit signed integer from another with saturation.
 */
__inline Word16 sub(Word16 x, Word16 y)
{
    Word32 xs, ys, rs;
    __asm {
        mov xs, x, lsl #16;
        mov ys, y, lsl #16;
        qsub rs, xs, ys;
    }
    return (Word16) (rs >> 16);
}

/*
 * Absolute value of a 16-bit signed integer. Saturating, so
 * abs(-0x8000) becomes +0x7FFF.
 */
__inline Word16 abs_s(Word16 x)
{
    if (x >= 0)
        return x;
    else if (x == ARMDSP_WORD16_MIN)
        return ARMDSP_WORD16_MAX;
    else
        return (Word16) -x;
}

/*
 * Shift a 16-bit signed integer left (or right, if the shift count
 * is negative). Saturate on overflow.
 */
__inline Word16 shl(Word16 x, Word16 shift)
{
    if (shift <= 0 || x == 0)
        return (Word16) (x >> (-shift));
    if (shift > 15)
        shift = 16;
    return saturate(x << shift);
}

/*
 * Shift a 16-bit signed integer right (or left, if the shift count
 * is negative). Saturate on overflow.
 */
__inline Word16 shr(Word16 x, Word16 shift)
{
    if (shift >= 0 || x == 0)
        return (Word16) (x >> shift);
    if (shift < -15)
        shift = -16;
    return saturate(x << (-shift));
}

/*
 * Multiply two 16-bit signed integers, shift the result right by
 * 15 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(Word16 x, Word16 y)
{
    Word32 product;
    __asm {
        smulbb product, x, y;
        qadd product, product, product;
    }
    return (Word16) (product >> 16);   /* the qadd added one to the 15 */
}

/*
 * Multiply two 16-bit signed integers to give a 32-bit signed
 * integer. Shift left by one, and saturate the result. (Saturation
 * is only necessary if both inputs were -0x8000, in which case the
 * result "should" be 0x40000000 << 1 = +0x80000000, and is
 * saturated to +0x7FFFFFFF.)
 */
__inline Word32 L_mult(Word16 x, Word16 y)
{
    Word32 product;
    __asm {
        smulbb product, x, y;
        qadd product, product, product;
    }
    return product;
}

/*
 * Negate a 16-bit signed integer, with saturation. (Saturation is
 * only necessary when the input is -0x8000.)
 */
__inline Word16 negate(Word16 x)
{
    if (x == ARMDSP_WORD16_MIN)
        return ARMDSP_WORD16_MAX;
    return (Word16) -x;
}

/*
 * Return the top 16 bits of a 32-bit signed integer.
 */
__inline Word16 extract_h(Word32 x)
{
    return (Word16) (x >> 16);
}

/*
 * Return the bottom 16 bits of a 32-bit signed integer, with no
 * saturation, just coerced into a two's complement 16 bit
 * representation.
 */
__inline Word16 extract_l(Word32 x)
{
    return (Word16) x;
}

/*
 * Divide a 32-bit signed integer by 2^16, rounding to the nearest
 * integer (round up on a tie). Equivalent to adding 0x8000 with
 * saturation, then shifting right by 16.
 */
__inline Word16 round(Word32 x)
{
    __asm {
        qadd x, x, 0x8000;
    }
    return extract_h(x);
}

/*
 * 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.
 * 
 * Note the intermediate saturation operation in the definition:
 * 
 *    L_mac(-1, -0x8000, -0x8000)
 * 
 * will give 0x7FFFFFFE and not 0x7FFFFFFF:
 *    the unshifted product is:   0x40000000
 *    shift left with saturation: 0x7FFFFFFF
 *    add to -1 with saturation:  0x7FFFFFFE
 */
__inline Word32 L_mac(Word32 accumulator, Word16 x, Word16 y)
{
    Word32 product;
    __asm {
        smulbb product, x, y;
        qdadd accumulator, accumulator, product;
    }
    return accumulator;
}

/*
 * 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.
 * 
 * Note the intermediate saturation operation in the definition:
 * 
 *    L_msu(1, -0x8000, -0x8000)
 * 
 * will give 0x80000002 and not 0x80000001:
 *    the unshifted product is:         0x40000000
 *    shift left with saturation:       0x7FFFFFFF
 *    subtract from 1 with saturation:  0x80000002
 */
__inline Word32 L_msu(Word32 accumulator, Word16 x, Word16 y)
{
    Word32 product;
    __asm {
        smulbb product, x, y;
        qdsub accumulator, accumulator, product;
    }
    return accumulator;
}

/*
 * Add two 32-bit signed integers with saturation.
 */
__inline Word32 L_add(Word32 x, Word32 y)
{
    Word32 result;
    __asm {
        qadd result, x, y;
    }
    return result;
}

/*
 * Subtract one 32-bit signed integer from another with saturation.
 */
__inline Word32 L_sub(Word32 x, Word32 y)
{
    Word32 result;
    __asm {
        qsub result, x, y;
    }
    return result;
}

/*
 * Add together the Carry variable and two 32-bit signed integers,
 * without saturation.
 */
__inline Word32 L_add_c(Word32 x, Word32 y)
{
    Word32 result, flags;

⌨️ 快捷键说明

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