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 + -
显示快捷键?