dsp.cc

来自「M5,一个功能强大的多处理器系统模拟器.很多针对处理器架构,性能的研究都使用它作」· CC 代码 · 共 1,233 行 · 第 1/3 页

CC
1,233
字号
/* * Copyright (c) 2007 MIPS Technologies, Inc.  All Rights Reserved * * This software is part of the M5 simulator. * * THIS IS A LEGAL AGREEMENT.  BY DOWNLOADING, USING, COPYING, CREATING * DERIVATIVE WORKS, AND/OR DISTRIBUTING THIS SOFTWARE YOU ARE AGREEING * TO THESE TERMS AND CONDITIONS. * * Permission is granted to use, copy, create derivative works and * distribute this software and such derivative works for any purpose, * so long as (1) the copyright notice above, this grant of permission, * and the disclaimer below appear in all copies and derivative works * made, (2) the copyright notice above is augmented as appropriate to * reflect the addition of any new copyrightable work in a derivative * work (e.g., Copyright (c) <Publication Year> Copyright Owner), and (3) * the name of MIPS Technologies, Inc. ($(B!H(BMIPS$(B!I(B) is not used in any * advertising or publicity pertaining to the use or distribution of * this software without specific, written prior authorization. * * THIS SOFTWARE IS PROVIDED $(B!H(BAS IS.$(B!I(B  MIPS MAKES NO WARRANTIES AND * DISCLAIMS ALL WARRANTIES, WHETHER EXPRESS, STATUTORY, IMPLIED OR * OTHERWISE, INCLUDING BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, AND * NON-INFRINGEMENT OF THIRD PARTY RIGHTS, REGARDING THIS SOFTWARE. * IN NO EVENT SHALL MIPS BE LIABLE FOR ANY DAMAGES, INCLUDING DIRECT, * INDIRECT, INCIDENTAL, CONSEQUENTIAL, SPECIAL, OR PUNITIVE DAMAGES OF * ANY KIND OR NATURE, ARISING OUT OF OR IN CONNECTION WITH THIS AGREEMENT, * THIS SOFTWARE AND/OR THE USE OF THIS SOFTWARE, WHETHER SUCH LIABILITY * IS ASSERTED ON THE BASIS OF CONTRACT, TORT (INCLUDING NEGLIGENCE OR * STRICT LIABILITY), OR OTHERWISE, EVEN IF MIPS HAS BEEN WARNED OF THE * POSSIBILITY OF ANY SUCH LOSS OR DAMAGE IN ADVANCE. * * Authors: Brett Miller */#include "arch/mips/isa_traits.hh"#include "arch/mips/dsp.hh"#include "config/full_system.hh"#include "cpu/static_inst.hh"#include "sim/serialize.hh"#include "base/bitfield.hh"#include "base/misc.hh"using namespace MipsISA;using namespace std;int32_tMipsISA::bitrev( int32_t value ){    int32_t result = 0;    int i, shift;    for( i=0; i<16; i++ )    {        shift = 2*i - 15;        if( shift < 0 )            result |= (value & 1L<<i) << -shift;        else            result |= (value & 1L<<i) >> shift;    }    return result;}uint64_tMipsISA::dspSaturate( uint64_t value, int32_t fmt, int32_t sign, uint32_t *overflow ){    int64_t svalue;    svalue = (int64_t)value;    switch( sign )    {      case SIGNED:        if( svalue > (int64_t)FIXED_SMAX[fmt] )        {            *overflow = 1;            svalue = (int64_t)FIXED_SMAX[fmt];        }        else if( svalue < (int64_t)FIXED_SMIN[fmt] )        {            *overflow = 1;            svalue = (int64_t)FIXED_SMIN[fmt];        }        break;      case UNSIGNED:        if( svalue > (int64_t)FIXED_UMAX[fmt] )        {            *overflow = 1;            svalue = FIXED_UMAX[fmt];        }        else if( svalue < (int64_t)FIXED_UMIN[fmt] )        {            *overflow = 1;            svalue = FIXED_UMIN[fmt];        }        break;    }    return( (uint64_t)svalue );}uint64_tMipsISA::checkOverflow( uint64_t value, int32_t fmt, int32_t sign, uint32_t *overflow ){    int64_t svalue;    svalue = (int64_t)value;    switch( sign )    {      case SIGNED:        if( svalue > (int64_t)FIXED_SMAX[fmt] || svalue < (int64_t)FIXED_SMIN[fmt] )            *overflow = 1;        break;      case UNSIGNED:        if( svalue > (int64_t)FIXED_UMAX[fmt] || svalue < (int64_t)FIXED_UMIN[fmt] )            *overflow = 1;        break;    }    return( (uint64_t)svalue );}uint64_tMipsISA::signExtend( uint64_t value, int32_t fmt ){    int32_t signpos = SIMD_NBITS[fmt];    uint64_t sign = uint64_t(1)<<(signpos-1);    uint64_t ones = ~(0ULL);    if( value & sign )        value |= (ones << signpos); // extend with ones    else        value &= (ones >> (64 - signpos)); // extend with zeros    return value;}uint64_tMipsISA::addHalfLsb( uint64_t value, int32_t lsbpos ){    return( value += ULL(1) << (lsbpos-1) );}int32_tMipsISA::dspAbs( int32_t a, int32_t fmt, uint32_t *dspctl ){    int i = 0;    int nvals = SIMD_NVALS[fmt];    int32_t result;    int64_t svalue;    uint32_t ouflag = 0;    uint64_t a_values[SIMD_MAX_VALS];    simdUnpack( a, a_values, fmt, SIGNED );    for( i=0; i<nvals; i++ )    {        svalue = (int64_t)a_values[i];        if( a_values[i] == FIXED_SMIN[fmt] )        {            a_values[i] = FIXED_SMAX[fmt];            ouflag = 1;        }        else if( svalue < 0 )        {            a_values[i] = uint64_t( 0 - svalue );        }    }    simdPack( a_values, &result, fmt );    if( ouflag )        writeDSPControl( dspctl, (ouflag<<4)<<DSP_CTL_POS[DSP_OUFLAG], 1<<DSP_OUFLAG);    return( result );}int32_tMipsISA::dspAdd( int32_t a, int32_t b, int32_t fmt, int32_t saturate, int32_t sign, uint32_t *dspctl ){    int i = 0;    int nvals = SIMD_NVALS[fmt];    int32_t result;    uint32_t ouflag = 0;    uint64_t a_values[SIMD_MAX_VALS];    uint64_t b_values[SIMD_MAX_VALS];    simdUnpack( a, a_values, fmt, sign );    simdUnpack( b, b_values, fmt, sign );    for( i=0; i<nvals; i++ )    {        if( saturate )            a_values[i] = dspSaturate( a_values[i] + b_values[i], fmt, sign, &ouflag );        else            a_values[i] = checkOverflow( a_values[i] + b_values[i], fmt, sign, &ouflag );    }    simdPack( a_values, &result, fmt );    if( ouflag )        writeDSPControl( dspctl, (ouflag<<4)<<DSP_CTL_POS[DSP_OUFLAG], 1<<DSP_OUFLAG);    return( result );}int32_tMipsISA::dspAddh( int32_t a, int32_t b, int32_t fmt, int32_t round, int32_t sign ){    int i = 0;    int nvals = SIMD_NVALS[fmt];    int32_t result;    uint64_t a_values[SIMD_MAX_VALS];    uint64_t b_values[SIMD_MAX_VALS];    simdUnpack( a, a_values, fmt, sign );    simdUnpack( b, b_values, fmt, sign );    for( i=0; i<nvals; i++ )    {        if( round )            a_values[i] = addHalfLsb( a_values[i] + b_values[i], 1 ) >> 1;        else            a_values[i] = ( a_values[i] + b_values[i] ) >> 1;    }    simdPack( a_values, &result, fmt );    return( result );}int32_tMipsISA::dspSub( int32_t a, int32_t b, int32_t fmt, int32_t saturate, int32_t sign, uint32_t *dspctl ){    int i = 0;    int nvals = SIMD_NVALS[fmt];    int32_t result;    uint32_t ouflag = 0;    uint64_t a_values[SIMD_MAX_VALS];    uint64_t b_values[SIMD_MAX_VALS];    simdUnpack( a, a_values, fmt, sign );    simdUnpack( b, b_values, fmt, sign );    for( i=0; i<nvals; i++ )    {        if( saturate )            a_values[i] = dspSaturate( a_values[i] - b_values[i], fmt, sign, &ouflag );        else            a_values[i] = checkOverflow( a_values[i] - b_values[i], fmt, sign, &ouflag );    }    simdPack( a_values, &result, fmt );    if( ouflag )        writeDSPControl( dspctl, (ouflag<<4)<<DSP_CTL_POS[DSP_OUFLAG], 1<<DSP_OUFLAG);    return( result );}int32_tMipsISA::dspSubh( int32_t a, int32_t b, int32_t fmt, int32_t round, int32_t sign ){    int i = 0;    int nvals = SIMD_NVALS[fmt];    int32_t result;    uint64_t a_values[SIMD_MAX_VALS];    uint64_t b_values[SIMD_MAX_VALS];    simdUnpack( a, a_values, fmt, sign );    simdUnpack( b, b_values, fmt, sign );    for( i=0; i<nvals; i++ )    {        if( round )            a_values[i] = addHalfLsb( a_values[i] - b_values[i], 1 ) >> 1;        else            a_values[i] = ( a_values[i] - b_values[i] ) >> 1;    }    simdPack( a_values, &result, fmt );    return( result );}int32_tMipsISA::dspShll( int32_t a, uint32_t sa, int32_t fmt, int32_t saturate, int32_t sign, uint32_t *dspctl ){    int i = 0;    int nvals = SIMD_NVALS[fmt];    int32_t result;    uint32_t ouflag = 0;    uint64_t a_values[SIMD_MAX_VALS];    sa = bits( sa, SIMD_LOG2N[fmt]-1, 0 );    simdUnpack( a, a_values, fmt, sign );    for( i=0; i<nvals; i++ )    {        if( saturate )            a_values[i] = dspSaturate( a_values[i] << sa, fmt, sign, &ouflag );        else            a_values[i] = checkOverflow( a_values[i] << sa, fmt, sign, &ouflag );    }    simdPack( a_values, &result, fmt );    if( ouflag )        writeDSPControl( dspctl, (ouflag<<6)<<DSP_CTL_POS[DSP_OUFLAG], 1<<DSP_OUFLAG);    return( result );}int32_tMipsISA::dspShrl( int32_t a, uint32_t sa, int32_t fmt, int32_t sign ){    int i = 0;    int nvals = SIMD_NVALS[fmt];    int32_t result;    uint64_t a_values[SIMD_MAX_VALS];    sa = bits( sa, SIMD_LOG2N[fmt]-1, 0 );    simdUnpack( a, a_values, fmt, UNSIGNED );    for( i=0; i<nvals; i++ )        a_values[i] = a_values[i] >> sa;    simdPack( a_values, &result, fmt );    return( result );}int32_tMipsISA::dspShra( int32_t a, uint32_t sa, int32_t fmt, int32_t round, int32_t sign, uint32_t *dspctl ){    int i = 0;    int nvals = SIMD_NVALS[fmt];    int32_t result;    uint64_t a_values[SIMD_MAX_VALS];    sa = bits( sa, SIMD_LOG2N[fmt]-1, 0 );    simdUnpack( a, a_values, fmt, SIGNED );    for( i=0; i<nvals; i++ )    {        if( round )            a_values[i] = addHalfLsb( a_values[i], sa ) >> sa;        else            a_values[i] = a_values[i] >> sa;    }    simdPack( a_values, &result, fmt );    return( result );}int32_tMipsISA::dspMulq( int32_t a, int32_t b, int32_t fmt, int32_t saturate, int32_t round, uint32_t *dspctl ){    int i = 0;    int nvals = SIMD_NVALS[fmt];    int sa = SIMD_NBITS[fmt];    int32_t result;    uint32_t ouflag = 0;    uint64_t a_values[SIMD_MAX_VALS];    uint64_t b_values[SIMD_MAX_VALS];    int64_t temp;    simdUnpack( a, a_values, fmt, SIGNED );    simdUnpack( b, b_values, fmt, SIGNED );    for( i=0; i<nvals; i++ )    {        if( round )            temp = (int64_t)addHalfLsb( a_values[i] * b_values[i] << 1, sa ) >> sa;        else            temp = (int64_t)(a_values[i] * b_values[i]) >> (sa - 1);        if( a_values[i] == FIXED_SMIN[fmt] &&            b_values[i] == FIXED_SMIN[fmt] )        {            ouflag = 1;            if( saturate )                temp = FIXED_SMAX[fmt];        }        a_values[i] = temp;    }    simdPack( a_values, &result, fmt );    if( ouflag )        writeDSPControl( dspctl, (ouflag<<5)<<DSP_CTL_POS[DSP_OUFLAG], 1<<DSP_OUFLAG);    return( result );}int32_tMipsISA::dspMul( int32_t a, int32_t b, int32_t fmt, int32_t saturate, uint32_t *dspctl ){    int i = 0;    int nvals = SIMD_NVALS[fmt];    int32_t result;

⌨️ 快捷键说明

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