From 753adb38d5471d23315d1bcfc6a744d1c6e03975 Mon Sep 17 00:00:00 2001 From: Korey Sewell Date: Fri, 22 Jun 2007 19:03:42 -0400 Subject: mips import pt. 1 src/arch/mips/SConscript: "mips import pt.1". --HG-- extra : convert_revision : 2e393341938bebf32fb638a209262d074fad4cc1 --- src/arch/mips/dsp.cc | 1227 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 1227 insertions(+) create mode 100755 src/arch/mips/dsp.cc (limited to 'src/arch/mips/dsp.cc') diff --git a/src/arch/mips/dsp.cc b/src/arch/mips/dsp.cc new file mode 100755 index 000000000..059c15a32 --- /dev/null +++ b/src/arch/mips/dsp.cc @@ -0,0 +1,1227 @@ +/* + * Copyright (c) 2003-2006 The Regents of The University of Michigan + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer; + * redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution; + * neither the name of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * Authors: Brett Miller + */ + +#include "arch/mips/isa_traits.hh" +#include "arch/mips/dsp.hh" +#include "arch/mips/constants.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_t +MipsISA::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<> shift; + } + + return result; +} + +uint64_t +MipsISA::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_t +MipsISA::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_t +MipsISA::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_t +MipsISA::addHalfLsb( uint64_t value, int32_t lsbpos ) +{ + return( value += ULL(1) << (lsbpos-1) ); +} + +int32_t +MipsISA::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> 1; + else + a_values[i] = ( a_values[i] + b_values[i] ) >> 1; + } + + simdPack( a_values, &result, fmt ); + + return( result ); +} + +int32_t +MipsISA::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> 1; + else + a_values[i] = ( a_values[i] - b_values[i] ) >> 1; + } + + simdPack( a_values, &result, fmt ); + + return( result ); +} + +int32_t +MipsISA::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> sa; + + simdPack( a_values, &result, fmt ); + + return( result ); +} + +int32_t +MipsISA::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> sa; + else + a_values[i] = a_values[i] >> sa; + } + + simdPack( a_values, &result, fmt ); + + return( result ); +} + +int32_t +MipsISA::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> 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)<-1; i-- ) + { + temp[i] = a_values[i] * b_values[i] << 1; + if( a_values[i] == FIXED_SMIN[fmt] && + b_values[i] == FIXED_SMIN[fmt] ) + { + temp[i] = FIXED_SMAX[fmt-1]; + ouflag = 1; + } + } + + dspac += temp[1] - temp[0]; + + if( ouflag ) + *dspctl = insertBits( *dspctl, 16+ac, 16+ac, 1 ); + + return dspac; +} + +void +MipsISA::dspCmp( int32_t a, int32_t b, int32_t fmt, int32_t sign, int32_t op, uint32_t *dspctl ) +{ + int i = 0; + int nvals = SIMD_NVALS[fmt]; + int ccond = 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>1)] << sa; break; + case MODE_R: out_values[i] = in_values[i] << sa; break; + case MODE_LA: out_values[i] = in_values[(i<<1)+1] << sa; break; + case MODE_RA: out_values[i] = in_values[i<<1] << sa; break; + } + } + + simdPack( out_values, &result, outfmt ); + + return( result ); +} + +int32_t +MipsISA::dspPrecrqu( int32_t a, int32_t b, uint32_t *dspctl ) +{ + int i = 0; + uint64_t a_values[SIMD_MAX_VALS]; + uint64_t b_values[SIMD_MAX_VALS]; + uint64_t r_values[SIMD_MAX_VALS]; + uint32_t ouflag = 0; + int32_t result = 0; + + simdUnpack( a, a_values, SIMD_FMT_PH, SIGNED ); + simdUnpack( b, b_values, SIMD_FMT_PH, SIGNED ); + + for( i=0; i<2; i++ ) + { + r_values[i] = dspSaturate( (int64_t)b_values[i] >> SIMD_NBITS[SIMD_FMT_QB] - 1, + SIMD_FMT_QB, UNSIGNED, &ouflag ); + r_values[i+2] = dspSaturate( (int64_t)a_values[i] >> SIMD_NBITS[SIMD_FMT_QB] - 1, + SIMD_FMT_QB, UNSIGNED, &ouflag ); + } + + simdPack( r_values, &result, SIMD_FMT_QB ); + + if( ouflag ) + *dspctl = insertBits( *dspctl, 22, 22, 1 ); + + return result; +} + +int32_t +MipsISA::dspPrecrq( int32_t a, int32_t b, int32_t fmt, uint32_t *dspctl ) +{ + uint64_t a_values[SIMD_MAX_VALS]; + uint64_t b_values[SIMD_MAX_VALS]; + uint64_t r_values[SIMD_MAX_VALS]; + uint32_t ouflag = 0; + int32_t result; + + simdUnpack( a, a_values, fmt, SIGNED ); + simdUnpack( b, b_values, fmt, SIGNED ); + + r_values[1] = dspSaturate( (int64_t)addHalfLsb( a_values[0], 16 ) >> 16, + fmt+1, SIGNED, &ouflag ); + r_values[0] = dspSaturate( (int64_t)addHalfLsb( b_values[0], 16 ) >> 16, + fmt+1, SIGNED, &ouflag ); + + simdPack( r_values, &result, fmt+1 ); + + if( ouflag ) + *dspctl = insertBits( *dspctl, 22, 22, 1 ); + + return result; +} + +int32_t +MipsISA::dspPrecrSra( int32_t a, int32_t b, int32_t sa, int32_t fmt, int32_t round ) +{ + int i = 0; + int nvals = SIMD_NVALS[fmt]; + uint64_t a_values[SIMD_MAX_VALS]; + uint64_t b_values[SIMD_MAX_VALS]; + uint64_t c_values[SIMD_MAX_VALS]; + int32_t result = 0; + + simdUnpack( a, a_values, fmt, SIGNED ); + simdUnpack( b, b_values, fmt, SIGNED ); + + for( i=0; i> sa; + c_values[i+1] = addHalfLsb( a_values[i], sa ) >> sa; + } + else + { + c_values[i] = b_values[i] >> sa; + c_values[i+1] = a_values[i] >> sa; + } + } + + simdPack( c_values, &result, fmt+1 ); + + return result; +} + +int32_t +MipsISA::dspPick( int32_t a, int32_t b, int32_t fmt, uint32_t *dspctl ) +{ + 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]; + uint64_t c_values[SIMD_MAX_VALS]; + + simdUnpack( a, a_values, fmt, UNSIGNED ); + simdUnpack( b, b_values, fmt, UNSIGNED ); + + for( i=0; i 0 ) + { + if( round ) + { + temp = (int64_t)addHalfLsb( dspac, sa ); + + if( dspac > 0 && temp < 0 ) + { + ouflag = 1; + if( saturate ) + temp = FIXED_SMAX[SIMD_FMT_L]; + } + temp = temp >> sa; + } + else + temp = dspac >> sa; + } + else + temp = dspac; + + dspac = checkOverflow( dspac, fmt, SIGNED, &ouflag ); + + if( ouflag ) + { + *dspctl = insertBits( *dspctl, 23, 23, ouflag ); + + if( saturate ) + result = (int32_t)dspSaturate( temp, fmt, SIGNED, &ouflag ); + else + result = (int32_t)temp; + } + else + result = (int32_t)temp; + + return( result ); +} + +int32_t +MipsISA::dspExtp( int64_t dspac, int32_t size, uint32_t *dspctl ) +{ + int32_t pos = 0; + int32_t result = 0; + + pos = bits( *dspctl, 5, 0 ); + size = bits( size, 4, 0 ); + + if( pos - (size+1) >= -1 ) + { + result = bits( dspac, pos, pos-size ); + *dspctl = insertBits( *dspctl, 14, 14, 0 ); + } + else + { + result = 0; + *dspctl = insertBits( *dspctl, 14, 14, 1 ); + } + + return( result ); +} + +int32_t +MipsISA::dspExtpd( int64_t dspac, int32_t size, uint32_t *dspctl ) +{ + int32_t pos = 0; + int32_t result = 0; + + pos = bits( *dspctl, 5, 0 ); + size = bits( size, 4, 0 ); + + if( pos - (size+1) >= -1 ) + { + result = bits( dspac, pos, pos-size ); + *dspctl = insertBits( *dspctl, 14, 14, 0 ); + if( pos - (size+1) >= 0 ) + *dspctl = insertBits( *dspctl, 5, 0, pos - (size+1) ); + else if( (pos - (size+1)) == -1 ) + *dspctl = insertBits( *dspctl, 5, 0, 63 ); + } + else + { + result = 0; + *dspctl = insertBits( *dspctl, 14, 14, 1 ); + } + + return( result ); +} + +void +MipsISA::simdPack( uint64_t *values_ptr, int32_t *reg, int32_t fmt ) +{ + int i = 0; + int nvals = SIMD_NVALS[fmt]; + int nbits = SIMD_NBITS[fmt]; + + *reg = 0; + + for( i=0; i