dsp.cc revision 5222
14661Sksewell@umich.edu/* 25222Sksewell@umich.edu * Copyright (c) 2007 MIPS Technologies, Inc. 34661Sksewell@umich.edu * All rights reserved. 44661Sksewell@umich.edu * 54661Sksewell@umich.edu * Redistribution and use in source and binary forms, with or without 64661Sksewell@umich.edu * modification, are permitted provided that the following conditions are 74661Sksewell@umich.edu * met: redistributions of source code must retain the above copyright 84661Sksewell@umich.edu * notice, this list of conditions and the following disclaimer; 94661Sksewell@umich.edu * redistributions in binary form must reproduce the above copyright 104661Sksewell@umich.edu * notice, this list of conditions and the following disclaimer in the 114661Sksewell@umich.edu * documentation and/or other materials provided with the distribution; 124661Sksewell@umich.edu * neither the name of the copyright holders nor the names of its 134661Sksewell@umich.edu * contributors may be used to endorse or promote products derived from 144661Sksewell@umich.edu * this software without specific prior written permission. 154661Sksewell@umich.edu * 164661Sksewell@umich.edu * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 174661Sksewell@umich.edu * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 184661Sksewell@umich.edu * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 194661Sksewell@umich.edu * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 204661Sksewell@umich.edu * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 214661Sksewell@umich.edu * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 224661Sksewell@umich.edu * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 234661Sksewell@umich.edu * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 244661Sksewell@umich.edu * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 254661Sksewell@umich.edu * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 264661Sksewell@umich.edu * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 274661Sksewell@umich.edu * 284661Sksewell@umich.edu * Authors: Brett Miller 294661Sksewell@umich.edu */ 304661Sksewell@umich.edu 314661Sksewell@umich.edu#include "arch/mips/isa_traits.hh" 324661Sksewell@umich.edu#include "arch/mips/dsp.hh" 334661Sksewell@umich.edu#include "config/full_system.hh" 344661Sksewell@umich.edu#include "cpu/static_inst.hh" 354661Sksewell@umich.edu#include "sim/serialize.hh" 364661Sksewell@umich.edu#include "base/bitfield.hh" 374661Sksewell@umich.edu#include "base/misc.hh" 384661Sksewell@umich.edu 394661Sksewell@umich.eduusing namespace MipsISA; 404661Sksewell@umich.eduusing namespace std; 414661Sksewell@umich.edu 424661Sksewell@umich.eduint32_t 434661Sksewell@umich.eduMipsISA::bitrev( int32_t value ) 444661Sksewell@umich.edu{ 454661Sksewell@umich.edu int32_t result = 0; 464661Sksewell@umich.edu int i, shift; 474661Sksewell@umich.edu 484661Sksewell@umich.edu for( i=0; i<16; i++ ) 494661Sksewell@umich.edu { 504661Sksewell@umich.edu shift = 2*i - 15; 514661Sksewell@umich.edu 524661Sksewell@umich.edu if( shift < 0 ) 534661Sksewell@umich.edu result |= (value & 1L<<i) << -shift; 544661Sksewell@umich.edu else 554661Sksewell@umich.edu result |= (value & 1L<<i) >> shift; 564661Sksewell@umich.edu } 574661Sksewell@umich.edu 584661Sksewell@umich.edu return result; 594661Sksewell@umich.edu} 604661Sksewell@umich.edu 614661Sksewell@umich.eduuint64_t 624661Sksewell@umich.eduMipsISA::dspSaturate( uint64_t value, int32_t fmt, int32_t sign, uint32_t *overflow ) 634661Sksewell@umich.edu{ 644661Sksewell@umich.edu int64_t svalue; 654661Sksewell@umich.edu 664661Sksewell@umich.edu svalue = (int64_t)value; 674661Sksewell@umich.edu 684661Sksewell@umich.edu switch( sign ) 694661Sksewell@umich.edu { 704661Sksewell@umich.edu case SIGNED: 714661Sksewell@umich.edu if( svalue > (int64_t)FIXED_SMAX[fmt] ) 724661Sksewell@umich.edu { 734661Sksewell@umich.edu *overflow = 1; 744661Sksewell@umich.edu svalue = (int64_t)FIXED_SMAX[fmt]; 754661Sksewell@umich.edu } 764661Sksewell@umich.edu else if( svalue < (int64_t)FIXED_SMIN[fmt] ) 774661Sksewell@umich.edu { 784661Sksewell@umich.edu *overflow = 1; 794661Sksewell@umich.edu svalue = (int64_t)FIXED_SMIN[fmt]; 804661Sksewell@umich.edu } 814661Sksewell@umich.edu break; 824661Sksewell@umich.edu case UNSIGNED: 834661Sksewell@umich.edu if( svalue > (int64_t)FIXED_UMAX[fmt] ) 844661Sksewell@umich.edu { 854661Sksewell@umich.edu *overflow = 1; 864661Sksewell@umich.edu svalue = FIXED_UMAX[fmt]; 874661Sksewell@umich.edu } 884661Sksewell@umich.edu else if( svalue < (int64_t)FIXED_UMIN[fmt] ) 894661Sksewell@umich.edu { 904661Sksewell@umich.edu *overflow = 1; 914661Sksewell@umich.edu svalue = FIXED_UMIN[fmt]; 924661Sksewell@umich.edu } 934661Sksewell@umich.edu break; 944661Sksewell@umich.edu } 954661Sksewell@umich.edu 964661Sksewell@umich.edu return( (uint64_t)svalue ); 974661Sksewell@umich.edu} 984661Sksewell@umich.edu 994661Sksewell@umich.eduuint64_t 1004661Sksewell@umich.eduMipsISA::checkOverflow( uint64_t value, int32_t fmt, int32_t sign, uint32_t *overflow ) 1014661Sksewell@umich.edu{ 1024661Sksewell@umich.edu int64_t svalue; 1034661Sksewell@umich.edu 1044661Sksewell@umich.edu svalue = (int64_t)value; 1054661Sksewell@umich.edu 1064661Sksewell@umich.edu switch( sign ) 1074661Sksewell@umich.edu { 1084661Sksewell@umich.edu case SIGNED: 1094661Sksewell@umich.edu if( svalue > (int64_t)FIXED_SMAX[fmt] || svalue < (int64_t)FIXED_SMIN[fmt] ) 1104661Sksewell@umich.edu *overflow = 1; 1114661Sksewell@umich.edu break; 1124661Sksewell@umich.edu case UNSIGNED: 1134661Sksewell@umich.edu if( svalue > (int64_t)FIXED_UMAX[fmt] || svalue < (int64_t)FIXED_UMIN[fmt] ) 1144661Sksewell@umich.edu *overflow = 1; 1154661Sksewell@umich.edu break; 1164661Sksewell@umich.edu } 1174661Sksewell@umich.edu 1184661Sksewell@umich.edu return( (uint64_t)svalue ); 1194661Sksewell@umich.edu} 1204661Sksewell@umich.edu 1214661Sksewell@umich.eduuint64_t 1224661Sksewell@umich.eduMipsISA::signExtend( uint64_t value, int32_t fmt ) 1234661Sksewell@umich.edu{ 1244661Sksewell@umich.edu int32_t signpos = SIMD_NBITS[fmt]; 1254661Sksewell@umich.edu uint64_t sign = uint64_t(1)<<(signpos-1); 1264661Sksewell@umich.edu uint64_t ones = ~(0ULL); 1274661Sksewell@umich.edu 1284661Sksewell@umich.edu if( value & sign ) 1294661Sksewell@umich.edu value |= (ones << signpos); // extend with ones 1304661Sksewell@umich.edu else 1314661Sksewell@umich.edu value &= (ones >> (64 - signpos)); // extend with zeros 1324661Sksewell@umich.edu 1334661Sksewell@umich.edu return value; 1344661Sksewell@umich.edu} 1354661Sksewell@umich.edu 1364661Sksewell@umich.eduuint64_t 1374661Sksewell@umich.eduMipsISA::addHalfLsb( uint64_t value, int32_t lsbpos ) 1384661Sksewell@umich.edu{ 1394661Sksewell@umich.edu return( value += ULL(1) << (lsbpos-1) ); 1404661Sksewell@umich.edu} 1414661Sksewell@umich.edu 1424661Sksewell@umich.eduint32_t 1434661Sksewell@umich.eduMipsISA::dspAbs( int32_t a, int32_t fmt, uint32_t *dspctl ) 1444661Sksewell@umich.edu{ 1454661Sksewell@umich.edu int i = 0; 1464661Sksewell@umich.edu int nvals = SIMD_NVALS[fmt]; 1474661Sksewell@umich.edu int32_t result; 1484661Sksewell@umich.edu int64_t svalue; 1494661Sksewell@umich.edu uint32_t ouflag = 0; 1504661Sksewell@umich.edu uint64_t a_values[SIMD_MAX_VALS]; 1514661Sksewell@umich.edu 1524661Sksewell@umich.edu simdUnpack( a, a_values, fmt, SIGNED ); 1534661Sksewell@umich.edu 1544661Sksewell@umich.edu for( i=0; i<nvals; i++ ) 1554661Sksewell@umich.edu { 1564661Sksewell@umich.edu svalue = (int64_t)a_values[i]; 1574661Sksewell@umich.edu 1584661Sksewell@umich.edu if( a_values[i] == FIXED_SMIN[fmt] ) 1594661Sksewell@umich.edu { 1604661Sksewell@umich.edu a_values[i] = FIXED_SMAX[fmt]; 1614661Sksewell@umich.edu ouflag = 1; 1624661Sksewell@umich.edu } 1634661Sksewell@umich.edu else if( svalue < 0 ) 1644661Sksewell@umich.edu { 1654661Sksewell@umich.edu a_values[i] = uint64_t( 0 - svalue ); 1664661Sksewell@umich.edu } 1674661Sksewell@umich.edu } 1684661Sksewell@umich.edu 1694661Sksewell@umich.edu simdPack( a_values, &result, fmt ); 1704661Sksewell@umich.edu 1714661Sksewell@umich.edu if( ouflag ) 1724661Sksewell@umich.edu writeDSPControl( dspctl, (ouflag<<4)<<DSP_CTL_POS[DSP_OUFLAG], 1<<DSP_OUFLAG); 1734661Sksewell@umich.edu 1744661Sksewell@umich.edu return( result ); 1754661Sksewell@umich.edu} 1764661Sksewell@umich.edu 1774661Sksewell@umich.eduint32_t 1784661Sksewell@umich.eduMipsISA::dspAdd( int32_t a, int32_t b, int32_t fmt, int32_t saturate, int32_t sign, uint32_t *dspctl ) 1794661Sksewell@umich.edu{ 1804661Sksewell@umich.edu int i = 0; 1814661Sksewell@umich.edu int nvals = SIMD_NVALS[fmt]; 1824661Sksewell@umich.edu int32_t result; 1834661Sksewell@umich.edu uint32_t ouflag = 0; 1844661Sksewell@umich.edu uint64_t a_values[SIMD_MAX_VALS]; 1854661Sksewell@umich.edu uint64_t b_values[SIMD_MAX_VALS]; 1864661Sksewell@umich.edu 1874661Sksewell@umich.edu simdUnpack( a, a_values, fmt, sign ); 1884661Sksewell@umich.edu simdUnpack( b, b_values, fmt, sign ); 1894661Sksewell@umich.edu 1904661Sksewell@umich.edu for( i=0; i<nvals; i++ ) 1914661Sksewell@umich.edu { 1924661Sksewell@umich.edu if( saturate ) 1934661Sksewell@umich.edu a_values[i] = dspSaturate( a_values[i] + b_values[i], fmt, sign, &ouflag ); 1944661Sksewell@umich.edu else 1954661Sksewell@umich.edu a_values[i] = checkOverflow( a_values[i] + b_values[i], fmt, sign, &ouflag ); 1964661Sksewell@umich.edu } 1974661Sksewell@umich.edu 1984661Sksewell@umich.edu simdPack( a_values, &result, fmt ); 1994661Sksewell@umich.edu 2004661Sksewell@umich.edu if( ouflag ) 2014661Sksewell@umich.edu writeDSPControl( dspctl, (ouflag<<4)<<DSP_CTL_POS[DSP_OUFLAG], 1<<DSP_OUFLAG); 2024661Sksewell@umich.edu 2034661Sksewell@umich.edu return( result ); 2044661Sksewell@umich.edu} 2054661Sksewell@umich.edu 2064661Sksewell@umich.eduint32_t 2074661Sksewell@umich.eduMipsISA::dspAddh( int32_t a, int32_t b, int32_t fmt, int32_t round, int32_t sign ) 2084661Sksewell@umich.edu{ 2094661Sksewell@umich.edu int i = 0; 2104661Sksewell@umich.edu int nvals = SIMD_NVALS[fmt]; 2114661Sksewell@umich.edu int32_t result; 2124661Sksewell@umich.edu uint64_t a_values[SIMD_MAX_VALS]; 2134661Sksewell@umich.edu uint64_t b_values[SIMD_MAX_VALS]; 2144661Sksewell@umich.edu 2154661Sksewell@umich.edu simdUnpack( a, a_values, fmt, sign ); 2164661Sksewell@umich.edu simdUnpack( b, b_values, fmt, sign ); 2174661Sksewell@umich.edu 2184661Sksewell@umich.edu for( i=0; i<nvals; i++ ) 2194661Sksewell@umich.edu { 2204661Sksewell@umich.edu if( round ) 2214661Sksewell@umich.edu a_values[i] = addHalfLsb( a_values[i] + b_values[i], 1 ) >> 1; 2224661Sksewell@umich.edu else 2234661Sksewell@umich.edu a_values[i] = ( a_values[i] + b_values[i] ) >> 1; 2244661Sksewell@umich.edu } 2254661Sksewell@umich.edu 2264661Sksewell@umich.edu simdPack( a_values, &result, fmt ); 2274661Sksewell@umich.edu 2284661Sksewell@umich.edu return( result ); 2294661Sksewell@umich.edu} 2304661Sksewell@umich.edu 2314661Sksewell@umich.eduint32_t 2324661Sksewell@umich.eduMipsISA::dspSub( int32_t a, int32_t b, int32_t fmt, int32_t saturate, int32_t sign, uint32_t *dspctl ) 2334661Sksewell@umich.edu{ 2344661Sksewell@umich.edu int i = 0; 2354661Sksewell@umich.edu int nvals = SIMD_NVALS[fmt]; 2364661Sksewell@umich.edu int32_t result; 2374661Sksewell@umich.edu uint32_t ouflag = 0; 2384661Sksewell@umich.edu uint64_t a_values[SIMD_MAX_VALS]; 2394661Sksewell@umich.edu uint64_t b_values[SIMD_MAX_VALS]; 2404661Sksewell@umich.edu 2414661Sksewell@umich.edu simdUnpack( a, a_values, fmt, sign ); 2424661Sksewell@umich.edu simdUnpack( b, b_values, fmt, sign ); 2434661Sksewell@umich.edu 2444661Sksewell@umich.edu for( i=0; i<nvals; i++ ) 2454661Sksewell@umich.edu { 2464661Sksewell@umich.edu if( saturate ) 2474661Sksewell@umich.edu a_values[i] = dspSaturate( a_values[i] - b_values[i], fmt, sign, &ouflag ); 2484661Sksewell@umich.edu else 2494661Sksewell@umich.edu a_values[i] = checkOverflow( a_values[i] - b_values[i], fmt, sign, &ouflag ); 2504661Sksewell@umich.edu } 2514661Sksewell@umich.edu 2524661Sksewell@umich.edu simdPack( a_values, &result, fmt ); 2534661Sksewell@umich.edu 2544661Sksewell@umich.edu if( ouflag ) 2554661Sksewell@umich.edu writeDSPControl( dspctl, (ouflag<<4)<<DSP_CTL_POS[DSP_OUFLAG], 1<<DSP_OUFLAG); 2564661Sksewell@umich.edu 2574661Sksewell@umich.edu return( result ); 2584661Sksewell@umich.edu} 2594661Sksewell@umich.edu 2604661Sksewell@umich.eduint32_t 2614661Sksewell@umich.eduMipsISA::dspSubh( int32_t a, int32_t b, int32_t fmt, int32_t round, int32_t sign ) 2624661Sksewell@umich.edu{ 2634661Sksewell@umich.edu int i = 0; 2644661Sksewell@umich.edu int nvals = SIMD_NVALS[fmt]; 2654661Sksewell@umich.edu int32_t result; 2664661Sksewell@umich.edu uint64_t a_values[SIMD_MAX_VALS]; 2674661Sksewell@umich.edu uint64_t b_values[SIMD_MAX_VALS]; 2684661Sksewell@umich.edu 2694661Sksewell@umich.edu simdUnpack( a, a_values, fmt, sign ); 2704661Sksewell@umich.edu simdUnpack( b, b_values, fmt, sign ); 2714661Sksewell@umich.edu 2724661Sksewell@umich.edu for( i=0; i<nvals; i++ ) 2734661Sksewell@umich.edu { 2744661Sksewell@umich.edu if( round ) 2754661Sksewell@umich.edu a_values[i] = addHalfLsb( a_values[i] - b_values[i], 1 ) >> 1; 2764661Sksewell@umich.edu else 2774661Sksewell@umich.edu a_values[i] = ( a_values[i] - b_values[i] ) >> 1; 2784661Sksewell@umich.edu } 2794661Sksewell@umich.edu 2804661Sksewell@umich.edu simdPack( a_values, &result, fmt ); 2814661Sksewell@umich.edu 2824661Sksewell@umich.edu return( result ); 2834661Sksewell@umich.edu} 2844661Sksewell@umich.edu 2854661Sksewell@umich.eduint32_t 2864661Sksewell@umich.eduMipsISA::dspShll( int32_t a, uint32_t sa, int32_t fmt, int32_t saturate, int32_t sign, uint32_t *dspctl ) 2874661Sksewell@umich.edu{ 2884661Sksewell@umich.edu int i = 0; 2894661Sksewell@umich.edu int nvals = SIMD_NVALS[fmt]; 2904661Sksewell@umich.edu int32_t result; 2914661Sksewell@umich.edu uint32_t ouflag = 0; 2924661Sksewell@umich.edu uint64_t a_values[SIMD_MAX_VALS]; 2934661Sksewell@umich.edu 2944661Sksewell@umich.edu sa = bits( sa, SIMD_LOG2N[fmt]-1, 0 ); 2954661Sksewell@umich.edu simdUnpack( a, a_values, fmt, sign ); 2964661Sksewell@umich.edu 2974661Sksewell@umich.edu for( i=0; i<nvals; i++ ) 2984661Sksewell@umich.edu { 2994661Sksewell@umich.edu if( saturate ) 3004661Sksewell@umich.edu a_values[i] = dspSaturate( a_values[i] << sa, fmt, sign, &ouflag ); 3014661Sksewell@umich.edu else 3024661Sksewell@umich.edu a_values[i] = checkOverflow( a_values[i] << sa, fmt, sign, &ouflag ); 3034661Sksewell@umich.edu } 3044661Sksewell@umich.edu 3054661Sksewell@umich.edu simdPack( a_values, &result, fmt ); 3064661Sksewell@umich.edu 3074661Sksewell@umich.edu if( ouflag ) 3084661Sksewell@umich.edu writeDSPControl( dspctl, (ouflag<<6)<<DSP_CTL_POS[DSP_OUFLAG], 1<<DSP_OUFLAG); 3094661Sksewell@umich.edu 3104661Sksewell@umich.edu return( result ); 3114661Sksewell@umich.edu} 3124661Sksewell@umich.edu 3134661Sksewell@umich.eduint32_t 3144661Sksewell@umich.eduMipsISA::dspShrl( int32_t a, uint32_t sa, int32_t fmt, int32_t sign ) 3154661Sksewell@umich.edu{ 3164661Sksewell@umich.edu int i = 0; 3174661Sksewell@umich.edu int nvals = SIMD_NVALS[fmt]; 3184661Sksewell@umich.edu int32_t result; 3194661Sksewell@umich.edu uint64_t a_values[SIMD_MAX_VALS]; 3204661Sksewell@umich.edu 3214661Sksewell@umich.edu sa = bits( sa, SIMD_LOG2N[fmt]-1, 0 ); 3224661Sksewell@umich.edu 3234661Sksewell@umich.edu simdUnpack( a, a_values, fmt, UNSIGNED ); 3244661Sksewell@umich.edu 3254661Sksewell@umich.edu for( i=0; i<nvals; i++ ) 3264661Sksewell@umich.edu a_values[i] = a_values[i] >> sa; 3274661Sksewell@umich.edu 3284661Sksewell@umich.edu simdPack( a_values, &result, fmt ); 3294661Sksewell@umich.edu 3304661Sksewell@umich.edu return( result ); 3314661Sksewell@umich.edu} 3324661Sksewell@umich.edu 3334661Sksewell@umich.eduint32_t 3344661Sksewell@umich.eduMipsISA::dspShra( int32_t a, uint32_t sa, int32_t fmt, int32_t round, int32_t sign, uint32_t *dspctl ) 3354661Sksewell@umich.edu{ 3364661Sksewell@umich.edu int i = 0; 3374661Sksewell@umich.edu int nvals = SIMD_NVALS[fmt]; 3384661Sksewell@umich.edu int32_t result; 3394661Sksewell@umich.edu uint64_t a_values[SIMD_MAX_VALS]; 3404661Sksewell@umich.edu 3414661Sksewell@umich.edu sa = bits( sa, SIMD_LOG2N[fmt]-1, 0 ); 3424661Sksewell@umich.edu 3434661Sksewell@umich.edu simdUnpack( a, a_values, fmt, SIGNED ); 3444661Sksewell@umich.edu 3454661Sksewell@umich.edu for( i=0; i<nvals; i++ ) 3464661Sksewell@umich.edu { 3474661Sksewell@umich.edu if( round ) 3484661Sksewell@umich.edu a_values[i] = addHalfLsb( a_values[i], sa ) >> sa; 3494661Sksewell@umich.edu else 3504661Sksewell@umich.edu a_values[i] = a_values[i] >> sa; 3514661Sksewell@umich.edu } 3524661Sksewell@umich.edu 3534661Sksewell@umich.edu simdPack( a_values, &result, fmt ); 3544661Sksewell@umich.edu 3554661Sksewell@umich.edu return( result ); 3564661Sksewell@umich.edu} 3574661Sksewell@umich.edu 3584661Sksewell@umich.eduint32_t 3594661Sksewell@umich.eduMipsISA::dspMulq( int32_t a, int32_t b, int32_t fmt, int32_t saturate, int32_t round, uint32_t *dspctl ) 3604661Sksewell@umich.edu{ 3614661Sksewell@umich.edu int i = 0; 3624661Sksewell@umich.edu int nvals = SIMD_NVALS[fmt]; 3634661Sksewell@umich.edu int sa = SIMD_NBITS[fmt]; 3644661Sksewell@umich.edu int32_t result; 3654661Sksewell@umich.edu uint32_t ouflag = 0; 3664661Sksewell@umich.edu uint64_t a_values[SIMD_MAX_VALS]; 3674661Sksewell@umich.edu uint64_t b_values[SIMD_MAX_VALS]; 3684661Sksewell@umich.edu int64_t temp; 3694661Sksewell@umich.edu 3704661Sksewell@umich.edu simdUnpack( a, a_values, fmt, SIGNED ); 3714661Sksewell@umich.edu simdUnpack( b, b_values, fmt, SIGNED ); 3724661Sksewell@umich.edu 3734661Sksewell@umich.edu for( i=0; i<nvals; i++ ) 3744661Sksewell@umich.edu { 3754661Sksewell@umich.edu if( round ) 3764661Sksewell@umich.edu temp = (int64_t)addHalfLsb( a_values[i] * b_values[i] << 1, sa ) >> sa; 3774661Sksewell@umich.edu else 3784661Sksewell@umich.edu temp = (int64_t)(a_values[i] * b_values[i]) >> (sa - 1); 3794661Sksewell@umich.edu 3804661Sksewell@umich.edu if( a_values[i] == FIXED_SMIN[fmt] && 3814661Sksewell@umich.edu b_values[i] == FIXED_SMIN[fmt] ) 3824661Sksewell@umich.edu { 3834661Sksewell@umich.edu ouflag = 1; 3844661Sksewell@umich.edu 3854661Sksewell@umich.edu if( saturate ) 3864661Sksewell@umich.edu temp = FIXED_SMAX[fmt]; 3874661Sksewell@umich.edu } 3884661Sksewell@umich.edu 3894661Sksewell@umich.edu a_values[i] = temp; 3904661Sksewell@umich.edu } 3914661Sksewell@umich.edu 3924661Sksewell@umich.edu simdPack( a_values, &result, fmt ); 3934661Sksewell@umich.edu 3944661Sksewell@umich.edu if( ouflag ) 3954661Sksewell@umich.edu writeDSPControl( dspctl, (ouflag<<5)<<DSP_CTL_POS[DSP_OUFLAG], 1<<DSP_OUFLAG); 3964661Sksewell@umich.edu 3974661Sksewell@umich.edu return( result ); 3984661Sksewell@umich.edu} 3994661Sksewell@umich.edu 4004661Sksewell@umich.eduint32_t 4014661Sksewell@umich.eduMipsISA::dspMul( int32_t a, int32_t b, int32_t fmt, int32_t saturate, uint32_t *dspctl ) 4024661Sksewell@umich.edu{ 4034661Sksewell@umich.edu int i = 0; 4044661Sksewell@umich.edu int nvals = SIMD_NVALS[fmt]; 4054661Sksewell@umich.edu int32_t result; 4064661Sksewell@umich.edu uint32_t ouflag = 0; 4074661Sksewell@umich.edu uint64_t a_values[SIMD_MAX_VALS]; 4084661Sksewell@umich.edu uint64_t b_values[SIMD_MAX_VALS]; 4094661Sksewell@umich.edu 4104661Sksewell@umich.edu simdUnpack( a, a_values, fmt, SIGNED ); 4114661Sksewell@umich.edu simdUnpack( b, b_values, fmt, SIGNED ); 4124661Sksewell@umich.edu 4134661Sksewell@umich.edu for( i=0; i<nvals; i++ ) 4144661Sksewell@umich.edu { 4154661Sksewell@umich.edu if( saturate ) 4164661Sksewell@umich.edu a_values[i] = dspSaturate( a_values[i] * b_values[i], fmt, SIGNED, &ouflag ); 4174661Sksewell@umich.edu else 4184661Sksewell@umich.edu a_values[i] = checkOverflow( a_values[i] * b_values[i], fmt, SIGNED, &ouflag ); 4194661Sksewell@umich.edu } 4204661Sksewell@umich.edu 4214661Sksewell@umich.edu simdPack( a_values, &result, fmt ); 4224661Sksewell@umich.edu 4234661Sksewell@umich.edu if( ouflag ) 4244661Sksewell@umich.edu writeDSPControl( dspctl, (ouflag<<5)<<DSP_CTL_POS[DSP_OUFLAG], 1<<DSP_OUFLAG); 4254661Sksewell@umich.edu 4264661Sksewell@umich.edu return( result ); 4274661Sksewell@umich.edu} 4284661Sksewell@umich.edu 4294661Sksewell@umich.eduint32_t 4304661Sksewell@umich.eduMipsISA::dspMuleu( int32_t a, int32_t b, int32_t mode, uint32_t *dspctl ) 4314661Sksewell@umich.edu{ 4324661Sksewell@umich.edu int i = 0; 4334661Sksewell@umich.edu int nvals = SIMD_NVALS[SIMD_FMT_PH]; 4344661Sksewell@umich.edu int32_t result; 4354661Sksewell@umich.edu uint32_t ouflag = 0; 4364661Sksewell@umich.edu uint64_t a_values[SIMD_MAX_VALS]; 4374661Sksewell@umich.edu uint64_t b_values[SIMD_MAX_VALS]; 4384661Sksewell@umich.edu 4394661Sksewell@umich.edu simdUnpack( a, a_values, SIMD_FMT_QB, UNSIGNED ); 4404661Sksewell@umich.edu simdUnpack( b, b_values, SIMD_FMT_PH, UNSIGNED ); 4414661Sksewell@umich.edu 4424661Sksewell@umich.edu switch( mode ) 4434661Sksewell@umich.edu { 4444661Sksewell@umich.edu case MODE_L: 4454661Sksewell@umich.edu for( i=0; i<nvals; i++ ) 4464661Sksewell@umich.edu b_values[i] = dspSaturate( a_values[i+2] * b_values[i], SIMD_FMT_PH, UNSIGNED, &ouflag ); 4474661Sksewell@umich.edu break; 4484661Sksewell@umich.edu case MODE_R: 4494661Sksewell@umich.edu for( i=0; i<nvals; i++ ) 4504661Sksewell@umich.edu b_values[i] = dspSaturate( a_values[i] * b_values[i], SIMD_FMT_PH, UNSIGNED, &ouflag ); 4514661Sksewell@umich.edu break; 4524661Sksewell@umich.edu } 4534661Sksewell@umich.edu 4544661Sksewell@umich.edu simdPack( b_values, &result, SIMD_FMT_PH ); 4554661Sksewell@umich.edu 4564661Sksewell@umich.edu if( ouflag ) 4574661Sksewell@umich.edu writeDSPControl( dspctl, (ouflag<<5)<<DSP_CTL_POS[DSP_OUFLAG], 1<<DSP_OUFLAG); 4584661Sksewell@umich.edu 4594661Sksewell@umich.edu return( result ); 4604661Sksewell@umich.edu} 4614661Sksewell@umich.edu 4624661Sksewell@umich.eduint32_t 4634661Sksewell@umich.eduMipsISA::dspMuleq( int32_t a, int32_t b, int32_t mode, uint32_t *dspctl ) 4644661Sksewell@umich.edu{ 4654661Sksewell@umich.edu int i = 0; 4664661Sksewell@umich.edu int nvals = SIMD_NVALS[SIMD_FMT_W]; 4674661Sksewell@umich.edu int32_t result; 4684661Sksewell@umich.edu uint32_t ouflag = 0; 4694661Sksewell@umich.edu uint64_t a_values[SIMD_MAX_VALS]; 4704661Sksewell@umich.edu uint64_t b_values[SIMD_MAX_VALS]; 4714661Sksewell@umich.edu uint64_t c_values[SIMD_MAX_VALS]; 4724661Sksewell@umich.edu 4734661Sksewell@umich.edu simdUnpack( a, a_values, SIMD_FMT_PH, SIGNED ); 4744661Sksewell@umich.edu simdUnpack( b, b_values, SIMD_FMT_PH, SIGNED ); 4754661Sksewell@umich.edu 4764661Sksewell@umich.edu switch( mode ) 4774661Sksewell@umich.edu { 4784661Sksewell@umich.edu case MODE_L: 4794661Sksewell@umich.edu for( i=0; i<nvals; i++ ) 4804661Sksewell@umich.edu c_values[i] = dspSaturate( a_values[i+1] * b_values[i+1] << 1, 4814661Sksewell@umich.edu SIMD_FMT_W, SIGNED, &ouflag ); 4824661Sksewell@umich.edu break; 4834661Sksewell@umich.edu case MODE_R: 4844661Sksewell@umich.edu for( i=0; i<nvals; i++ ) 4854661Sksewell@umich.edu c_values[i] = dspSaturate( a_values[i] * b_values[i] << 1, 4864661Sksewell@umich.edu SIMD_FMT_W, SIGNED, &ouflag ); 4874661Sksewell@umich.edu break; 4884661Sksewell@umich.edu } 4894661Sksewell@umich.edu 4904661Sksewell@umich.edu simdPack( c_values, &result, SIMD_FMT_W ); 4914661Sksewell@umich.edu 4924661Sksewell@umich.edu if( ouflag ) 4934661Sksewell@umich.edu writeDSPControl( dspctl, (ouflag<<5)<<DSP_CTL_POS[DSP_OUFLAG], 1<<DSP_OUFLAG); 4944661Sksewell@umich.edu 4954661Sksewell@umich.edu return( result ); 4964661Sksewell@umich.edu} 4974661Sksewell@umich.edu 4984661Sksewell@umich.eduint64_t 4994661Sksewell@umich.eduMipsISA::dspDpaq( int64_t dspac, int32_t a, int32_t b, int32_t ac, int32_t infmt, 5004661Sksewell@umich.edu int32_t outfmt, int32_t postsat, int32_t mode, uint32_t *dspctl ) 5014661Sksewell@umich.edu{ 5024661Sksewell@umich.edu int i = 0; 5034661Sksewell@umich.edu int nvals = SIMD_NVALS[infmt]; 5044661Sksewell@umich.edu int64_t result = 0; 5054661Sksewell@umich.edu int64_t temp = 0; 5064661Sksewell@umich.edu uint32_t ouflag = 0; 5074661Sksewell@umich.edu uint64_t a_values[SIMD_MAX_VALS]; 5084661Sksewell@umich.edu uint64_t b_values[SIMD_MAX_VALS]; 5094661Sksewell@umich.edu 5104661Sksewell@umich.edu simdUnpack( a, a_values, infmt, SIGNED ); 5114661Sksewell@umich.edu simdUnpack( b, b_values, infmt, SIGNED ); 5124661Sksewell@umich.edu 5134661Sksewell@umich.edu for( i=0; i<nvals; i++ ) 5144661Sksewell@umich.edu { 5154661Sksewell@umich.edu switch( mode ) 5164661Sksewell@umich.edu { 5174661Sksewell@umich.edu case MODE_X: 5184661Sksewell@umich.edu if( a_values[nvals-1-i] == FIXED_SMIN[infmt] && 5194661Sksewell@umich.edu b_values[i] == FIXED_SMIN[infmt] ) 5204661Sksewell@umich.edu { 5214661Sksewell@umich.edu result += FIXED_SMAX[outfmt]; 5224661Sksewell@umich.edu ouflag = 1; 5234661Sksewell@umich.edu } 5244661Sksewell@umich.edu else 5254661Sksewell@umich.edu result += a_values[nvals-1-i] * b_values[i] << 1; 5264661Sksewell@umich.edu break; 5274661Sksewell@umich.edu default: 5284661Sksewell@umich.edu if( a_values[i] == FIXED_SMIN[infmt] && 5294661Sksewell@umich.edu b_values[i] == FIXED_SMIN[infmt] ) 5304661Sksewell@umich.edu { 5314661Sksewell@umich.edu result += FIXED_SMAX[outfmt]; 5324661Sksewell@umich.edu ouflag = 1; 5334661Sksewell@umich.edu } 5344661Sksewell@umich.edu else 5354661Sksewell@umich.edu result += a_values[i] * b_values[i] << 1; 5364661Sksewell@umich.edu break; 5374661Sksewell@umich.edu } 5384661Sksewell@umich.edu } 5394661Sksewell@umich.edu 5404661Sksewell@umich.edu if( postsat ) 5414661Sksewell@umich.edu { 5424661Sksewell@umich.edu if( outfmt == SIMD_FMT_L ) 5434661Sksewell@umich.edu { 5444661Sksewell@umich.edu int signa = bits( dspac, 63, 63 ); 5454661Sksewell@umich.edu int signb = bits( result, 63, 63 ); 5464661Sksewell@umich.edu 5474661Sksewell@umich.edu temp = dspac + result; 5484661Sksewell@umich.edu 5494661Sksewell@umich.edu if( ( signa == signb ) && 5504661Sksewell@umich.edu ( bits( temp, 63, 63 ) != signa ) ) 5514661Sksewell@umich.edu { 5524661Sksewell@umich.edu ouflag = 1; 5534661Sksewell@umich.edu if( signa ) 5544661Sksewell@umich.edu dspac = FIXED_SMIN[outfmt]; 5554661Sksewell@umich.edu else 5564661Sksewell@umich.edu dspac = FIXED_SMAX[outfmt]; 5574661Sksewell@umich.edu } 5584661Sksewell@umich.edu else 5594661Sksewell@umich.edu dspac = temp; 5604661Sksewell@umich.edu } 5614661Sksewell@umich.edu else 5624661Sksewell@umich.edu dspac = dspSaturate( dspac + result, outfmt, SIGNED, &ouflag ); 5634661Sksewell@umich.edu } 5644661Sksewell@umich.edu else 5654661Sksewell@umich.edu dspac += result; 5664661Sksewell@umich.edu 5674661Sksewell@umich.edu if( ouflag ) 5684661Sksewell@umich.edu *dspctl = insertBits( *dspctl, 16+ac, 16+ac, 1 ); 5694661Sksewell@umich.edu 5704661Sksewell@umich.edu return( dspac ); 5714661Sksewell@umich.edu} 5724661Sksewell@umich.edu 5734661Sksewell@umich.eduint64_t 5744661Sksewell@umich.eduMipsISA::dspDpsq( int64_t dspac, int32_t a, int32_t b, int32_t ac, int32_t infmt, 5754661Sksewell@umich.edu int32_t outfmt, int32_t postsat, int32_t mode, uint32_t *dspctl ) 5764661Sksewell@umich.edu{ 5774661Sksewell@umich.edu int i = 0; 5784661Sksewell@umich.edu int nvals = SIMD_NVALS[infmt]; 5794661Sksewell@umich.edu int64_t result = 0; 5804661Sksewell@umich.edu int64_t temp = 0; 5814661Sksewell@umich.edu uint32_t ouflag = 0; 5824661Sksewell@umich.edu uint64_t a_values[SIMD_MAX_VALS]; 5834661Sksewell@umich.edu uint64_t b_values[SIMD_MAX_VALS]; 5844661Sksewell@umich.edu 5854661Sksewell@umich.edu simdUnpack( a, a_values, infmt, SIGNED ); 5864661Sksewell@umich.edu simdUnpack( b, b_values, infmt, SIGNED ); 5874661Sksewell@umich.edu 5884661Sksewell@umich.edu for( i=0; i<nvals; i++ ) 5894661Sksewell@umich.edu { 5904661Sksewell@umich.edu switch( mode ) 5914661Sksewell@umich.edu { 5924661Sksewell@umich.edu case MODE_X: 5934661Sksewell@umich.edu if( a_values[nvals-1-i] == FIXED_SMIN[infmt] && 5944661Sksewell@umich.edu b_values[i] == FIXED_SMIN[infmt] ) 5954661Sksewell@umich.edu { 5964661Sksewell@umich.edu result += FIXED_SMAX[outfmt]; 5974661Sksewell@umich.edu ouflag = 1; 5984661Sksewell@umich.edu } 5994661Sksewell@umich.edu else 6004661Sksewell@umich.edu result += a_values[nvals-1-i] * b_values[i] << 1; 6014661Sksewell@umich.edu break; 6024661Sksewell@umich.edu default: 6034661Sksewell@umich.edu if( a_values[i] == FIXED_SMIN[infmt] && 6044661Sksewell@umich.edu b_values[i] == FIXED_SMIN[infmt] ) 6054661Sksewell@umich.edu { 6064661Sksewell@umich.edu result += FIXED_SMAX[outfmt]; 6074661Sksewell@umich.edu ouflag = 1; 6084661Sksewell@umich.edu } 6094661Sksewell@umich.edu else 6104661Sksewell@umich.edu result += a_values[i] * b_values[i] << 1; 6114661Sksewell@umich.edu break; 6124661Sksewell@umich.edu } 6134661Sksewell@umich.edu } 6144661Sksewell@umich.edu 6154661Sksewell@umich.edu if( postsat ) 6164661Sksewell@umich.edu { 6174661Sksewell@umich.edu if( outfmt == SIMD_FMT_L ) 6184661Sksewell@umich.edu { 6194661Sksewell@umich.edu int signa = bits( dspac, 63, 63 ); 6204661Sksewell@umich.edu int signb = bits( -result, 63, 63 ); 6214661Sksewell@umich.edu 6224661Sksewell@umich.edu temp = dspac - result; 6234661Sksewell@umich.edu 6244661Sksewell@umich.edu if( ( signa == signb ) && 6254661Sksewell@umich.edu ( bits( temp, 63, 63 ) != signa ) ) 6264661Sksewell@umich.edu { 6274661Sksewell@umich.edu ouflag = 1; 6284661Sksewell@umich.edu if( signa ) 6294661Sksewell@umich.edu dspac = FIXED_SMIN[outfmt]; 6304661Sksewell@umich.edu else 6314661Sksewell@umich.edu dspac = FIXED_SMAX[outfmt]; 6324661Sksewell@umich.edu } 6334661Sksewell@umich.edu else 6344661Sksewell@umich.edu dspac = temp; 6354661Sksewell@umich.edu } 6364661Sksewell@umich.edu else 6374661Sksewell@umich.edu dspac = dspSaturate( dspac - result, outfmt, SIGNED, &ouflag ); 6384661Sksewell@umich.edu } 6394661Sksewell@umich.edu else 6404661Sksewell@umich.edu dspac -= result; 6414661Sksewell@umich.edu 6424661Sksewell@umich.edu if( ouflag ) 6434661Sksewell@umich.edu *dspctl = insertBits( *dspctl, 16+ac, 16+ac, 1 ); 6444661Sksewell@umich.edu 6454661Sksewell@umich.edu return( dspac ); 6464661Sksewell@umich.edu} 6474661Sksewell@umich.edu 6484661Sksewell@umich.eduint64_t 6494661Sksewell@umich.eduMipsISA::dspDpa( int64_t dspac, int32_t a, int32_t b, int32_t ac, 6504661Sksewell@umich.edu int32_t fmt, int32_t sign, int32_t mode ) 6514661Sksewell@umich.edu{ 6524661Sksewell@umich.edu int i = 0; 6534661Sksewell@umich.edu int nvals = SIMD_NVALS[fmt]; 6544661Sksewell@umich.edu uint64_t a_values[SIMD_MAX_VALS]; 6554661Sksewell@umich.edu uint64_t b_values[SIMD_MAX_VALS]; 6564661Sksewell@umich.edu 6574661Sksewell@umich.edu simdUnpack( a, a_values, fmt, sign ); 6584661Sksewell@umich.edu simdUnpack( b, b_values, fmt, sign ); 6594661Sksewell@umich.edu 6604661Sksewell@umich.edu for( i=0; i<2; i++ ) 6614661Sksewell@umich.edu { 6624661Sksewell@umich.edu switch( mode ) 6634661Sksewell@umich.edu { 6644661Sksewell@umich.edu case MODE_L: 6654661Sksewell@umich.edu dspac += a_values[nvals-1-i] * b_values[nvals-1-i]; 6664661Sksewell@umich.edu break; 6674661Sksewell@umich.edu case MODE_R: 6684661Sksewell@umich.edu dspac += a_values[nvals-3-i] * b_values[nvals-3-i]; 6694661Sksewell@umich.edu break; 6704661Sksewell@umich.edu case MODE_X: 6714661Sksewell@umich.edu dspac += a_values[nvals-1-i] * b_values[i]; 6724661Sksewell@umich.edu break; 6734661Sksewell@umich.edu } 6744661Sksewell@umich.edu } 6754661Sksewell@umich.edu 6764661Sksewell@umich.edu return dspac; 6774661Sksewell@umich.edu} 6784661Sksewell@umich.edu 6794661Sksewell@umich.eduint64_t 6804661Sksewell@umich.eduMipsISA::dspDps( int64_t dspac, int32_t a, int32_t b, int32_t ac, 6814661Sksewell@umich.edu int32_t fmt, int32_t sign, int32_t mode ) 6824661Sksewell@umich.edu{ 6834661Sksewell@umich.edu int i = 0; 6844661Sksewell@umich.edu int nvals = SIMD_NVALS[fmt]; 6854661Sksewell@umich.edu uint64_t a_values[SIMD_MAX_VALS]; 6864661Sksewell@umich.edu uint64_t b_values[SIMD_MAX_VALS]; 6874661Sksewell@umich.edu 6884661Sksewell@umich.edu simdUnpack( a, a_values, fmt, sign ); 6894661Sksewell@umich.edu simdUnpack( b, b_values, fmt, sign ); 6904661Sksewell@umich.edu 6914661Sksewell@umich.edu for( i=0; i<2; i++ ) 6924661Sksewell@umich.edu { 6934661Sksewell@umich.edu switch( mode ) 6944661Sksewell@umich.edu { 6954661Sksewell@umich.edu case MODE_L: 6964661Sksewell@umich.edu dspac -= a_values[nvals-1-i] * b_values[nvals-1-i]; 6974661Sksewell@umich.edu break; 6984661Sksewell@umich.edu case MODE_R: 6994661Sksewell@umich.edu dspac -= a_values[nvals-3-i] * b_values[nvals-3-i]; 7004661Sksewell@umich.edu break; 7014661Sksewell@umich.edu case MODE_X: 7024661Sksewell@umich.edu dspac -= a_values[nvals-1-i] * b_values[i]; 7034661Sksewell@umich.edu break; 7044661Sksewell@umich.edu } 7054661Sksewell@umich.edu } 7064661Sksewell@umich.edu 7074661Sksewell@umich.edu return dspac; 7084661Sksewell@umich.edu} 7094661Sksewell@umich.edu 7104661Sksewell@umich.eduint64_t 7114661Sksewell@umich.eduMipsISA::dspMaq( int64_t dspac, int32_t a, int32_t b, int32_t ac, 7124661Sksewell@umich.edu int32_t fmt, int32_t mode, int32_t saturate, uint32_t *dspctl ) 7134661Sksewell@umich.edu{ 7144661Sksewell@umich.edu int i = 0; 7154661Sksewell@umich.edu int nvals = SIMD_NVALS[fmt-1]; 7164661Sksewell@umich.edu uint64_t a_values[SIMD_MAX_VALS]; 7174661Sksewell@umich.edu uint64_t b_values[SIMD_MAX_VALS]; 7184661Sksewell@umich.edu int64_t temp = 0; 7194661Sksewell@umich.edu uint32_t ouflag = 0; 7204661Sksewell@umich.edu 7214661Sksewell@umich.edu simdUnpack( a, a_values, fmt, SIGNED ); 7224661Sksewell@umich.edu simdUnpack( b, b_values, fmt, SIGNED ); 7234661Sksewell@umich.edu 7244661Sksewell@umich.edu for( i=0; i<nvals; i++ ) 7254661Sksewell@umich.edu { 7264661Sksewell@umich.edu switch( mode ) 7274661Sksewell@umich.edu { 7284661Sksewell@umich.edu case MODE_L: 7294661Sksewell@umich.edu temp = a_values[i+1] * b_values[i+1] << 1; 7304661Sksewell@umich.edu if( a_values[i+1] == FIXED_SMIN[fmt] && b_values[i+1] == FIXED_SMIN[fmt] ) 7314661Sksewell@umich.edu { 7324661Sksewell@umich.edu temp = (int64_t)FIXED_SMAX[fmt-1]; 7334661Sksewell@umich.edu ouflag = 1; 7344661Sksewell@umich.edu } 7354661Sksewell@umich.edu break; 7364661Sksewell@umich.edu case MODE_R: 7374661Sksewell@umich.edu temp = a_values[i] * b_values[i] << 1; 7384661Sksewell@umich.edu if( a_values[i] == FIXED_SMIN[fmt] && b_values[i] == FIXED_SMIN[fmt] ) 7394661Sksewell@umich.edu { 7404661Sksewell@umich.edu temp = (int64_t)FIXED_SMAX[fmt-1]; 7414661Sksewell@umich.edu ouflag = 1; 7424661Sksewell@umich.edu } 7434661Sksewell@umich.edu break; 7444661Sksewell@umich.edu } 7454661Sksewell@umich.edu 7464661Sksewell@umich.edu temp += dspac; 7474661Sksewell@umich.edu 7484661Sksewell@umich.edu if( saturate ) 7494661Sksewell@umich.edu temp = dspSaturate( temp, fmt-1, SIGNED, &ouflag ); 7504661Sksewell@umich.edu if( ouflag ) 7514661Sksewell@umich.edu *dspctl = insertBits( *dspctl, 16+ac, 16+ac, 1 ); 7524661Sksewell@umich.edu } 7534661Sksewell@umich.edu 7544661Sksewell@umich.edu return temp; 7554661Sksewell@umich.edu} 7564661Sksewell@umich.edu 7574661Sksewell@umich.eduint64_t 7584661Sksewell@umich.eduMipsISA::dspMulsa( int64_t dspac, int32_t a, int32_t b, int32_t ac, int32_t fmt ) 7594661Sksewell@umich.edu{ 7604661Sksewell@umich.edu uint64_t a_values[SIMD_MAX_VALS]; 7614661Sksewell@umich.edu uint64_t b_values[SIMD_MAX_VALS]; 7624661Sksewell@umich.edu 7634661Sksewell@umich.edu simdUnpack( a, a_values, fmt, SIGNED ); 7644661Sksewell@umich.edu simdUnpack( b, b_values, fmt, SIGNED ); 7654661Sksewell@umich.edu 7664661Sksewell@umich.edu dspac += a_values[1] * b_values[1] - a_values[0] * b_values[0]; 7674661Sksewell@umich.edu 7684661Sksewell@umich.edu return dspac; 7694661Sksewell@umich.edu} 7704661Sksewell@umich.edu 7714661Sksewell@umich.eduint64_t 7724661Sksewell@umich.eduMipsISA::dspMulsaq( int64_t dspac, int32_t a, int32_t b, int32_t ac, int32_t fmt, uint32_t *dspctl ) 7734661Sksewell@umich.edu{ 7744661Sksewell@umich.edu int i = 0; 7754661Sksewell@umich.edu int nvals = SIMD_NVALS[fmt]; 7764661Sksewell@umich.edu uint64_t a_values[SIMD_MAX_VALS]; 7774661Sksewell@umich.edu uint64_t b_values[SIMD_MAX_VALS]; 7784661Sksewell@umich.edu int64_t temp[2]; 7794661Sksewell@umich.edu uint32_t ouflag = 0; 7804661Sksewell@umich.edu 7814661Sksewell@umich.edu simdUnpack( a, a_values, fmt, SIGNED ); 7824661Sksewell@umich.edu simdUnpack( b, b_values, fmt, SIGNED ); 7834661Sksewell@umich.edu 7844661Sksewell@umich.edu for( i=nvals-1; i>-1; i-- ) 7854661Sksewell@umich.edu { 7864661Sksewell@umich.edu temp[i] = a_values[i] * b_values[i] << 1; 7874661Sksewell@umich.edu if( a_values[i] == FIXED_SMIN[fmt] && 7884661Sksewell@umich.edu b_values[i] == FIXED_SMIN[fmt] ) 7894661Sksewell@umich.edu { 7904661Sksewell@umich.edu temp[i] = FIXED_SMAX[fmt-1]; 7914661Sksewell@umich.edu ouflag = 1; 7924661Sksewell@umich.edu } 7934661Sksewell@umich.edu } 7944661Sksewell@umich.edu 7954661Sksewell@umich.edu dspac += temp[1] - temp[0]; 7964661Sksewell@umich.edu 7974661Sksewell@umich.edu if( ouflag ) 7984661Sksewell@umich.edu *dspctl = insertBits( *dspctl, 16+ac, 16+ac, 1 ); 7994661Sksewell@umich.edu 8004661Sksewell@umich.edu return dspac; 8014661Sksewell@umich.edu} 8024661Sksewell@umich.edu 8034661Sksewell@umich.eduvoid 8044661Sksewell@umich.eduMipsISA::dspCmp( int32_t a, int32_t b, int32_t fmt, int32_t sign, int32_t op, uint32_t *dspctl ) 8054661Sksewell@umich.edu{ 8064661Sksewell@umich.edu int i = 0; 8074661Sksewell@umich.edu int nvals = SIMD_NVALS[fmt]; 8084661Sksewell@umich.edu int ccond = 0; 8094661Sksewell@umich.edu uint64_t a_values[SIMD_MAX_VALS]; 8104661Sksewell@umich.edu uint64_t b_values[SIMD_MAX_VALS]; 8114661Sksewell@umich.edu 8124661Sksewell@umich.edu simdUnpack( a, a_values, fmt, sign ); 8134661Sksewell@umich.edu simdUnpack( b, b_values, fmt, sign ); 8144661Sksewell@umich.edu 8154661Sksewell@umich.edu for( i=0; i<nvals; i++ ) 8164661Sksewell@umich.edu { 8174661Sksewell@umich.edu int cc = 0; 8184661Sksewell@umich.edu 8194661Sksewell@umich.edu switch( op ) 8204661Sksewell@umich.edu { 8214661Sksewell@umich.edu case CMP_EQ: cc = ( a_values[i] == b_values[i] ); break; 8224661Sksewell@umich.edu case CMP_LT: cc = ( a_values[i] < b_values[i] ); break; 8234661Sksewell@umich.edu case CMP_LE: cc = ( a_values[i] <= b_values[i] ); break; 8244661Sksewell@umich.edu } 8254661Sksewell@umich.edu 8264661Sksewell@umich.edu ccond |= cc << ( DSP_CTL_POS[DSP_CCOND] + i ); 8274661Sksewell@umich.edu } 8284661Sksewell@umich.edu 8294661Sksewell@umich.edu writeDSPControl( dspctl, ccond, 1<<DSP_CCOND ); 8304661Sksewell@umich.edu} 8314661Sksewell@umich.edu 8324661Sksewell@umich.eduint32_t 8334661Sksewell@umich.eduMipsISA::dspCmpg( int32_t a, int32_t b, int32_t fmt, int32_t sign, int32_t op ) 8344661Sksewell@umich.edu{ 8354661Sksewell@umich.edu int i = 0; 8364661Sksewell@umich.edu int nvals = SIMD_NVALS[fmt]; 8374661Sksewell@umich.edu int32_t result = 0; 8384661Sksewell@umich.edu uint64_t a_values[SIMD_MAX_VALS]; 8394661Sksewell@umich.edu uint64_t b_values[SIMD_MAX_VALS]; 8404661Sksewell@umich.edu 8414661Sksewell@umich.edu simdUnpack( a, a_values, fmt, sign ); 8424661Sksewell@umich.edu simdUnpack( b, b_values, fmt, sign ); 8434661Sksewell@umich.edu 8444661Sksewell@umich.edu for( i=0; i<nvals; i++ ) 8454661Sksewell@umich.edu { 8464661Sksewell@umich.edu int cc = 0; 8474661Sksewell@umich.edu 8484661Sksewell@umich.edu switch( op ) 8494661Sksewell@umich.edu { 8504661Sksewell@umich.edu case CMP_EQ: cc = ( a_values[i] == b_values[i] ); break; 8514661Sksewell@umich.edu case CMP_LT: cc = ( a_values[i] < b_values[i] ); break; 8524661Sksewell@umich.edu case CMP_LE: cc = ( a_values[i] <= b_values[i] ); break; 8534661Sksewell@umich.edu } 8544661Sksewell@umich.edu 8554661Sksewell@umich.edu result |= cc << i; 8564661Sksewell@umich.edu } 8574661Sksewell@umich.edu 8584661Sksewell@umich.edu return( result ); 8594661Sksewell@umich.edu} 8604661Sksewell@umich.edu 8614661Sksewell@umich.eduint32_t 8624661Sksewell@umich.eduMipsISA::dspCmpgd( int32_t a, int32_t b, int32_t fmt, int32_t sign, int32_t op, uint32_t *dspctl ) 8634661Sksewell@umich.edu{ 8644661Sksewell@umich.edu int i = 0;; 8654661Sksewell@umich.edu int nvals = SIMD_NVALS[fmt]; 8664661Sksewell@umich.edu int32_t result = 0; 8674661Sksewell@umich.edu int ccond = 0; 8684661Sksewell@umich.edu uint64_t a_values[SIMD_MAX_VALS]; 8694661Sksewell@umich.edu uint64_t b_values[SIMD_MAX_VALS]; 8704661Sksewell@umich.edu 8714661Sksewell@umich.edu simdUnpack( a, a_values, fmt, sign ); 8724661Sksewell@umich.edu simdUnpack( b, b_values, fmt, sign ); 8734661Sksewell@umich.edu 8744661Sksewell@umich.edu for( i=0; i<nvals; i++ ) 8754661Sksewell@umich.edu { 8764661Sksewell@umich.edu int cc = 0;; 8774661Sksewell@umich.edu 8784661Sksewell@umich.edu switch( op ) 8794661Sksewell@umich.edu { 8804661Sksewell@umich.edu case CMP_EQ: cc = ( a_values[i] == b_values[i] ); break; 8814661Sksewell@umich.edu case CMP_LT: cc = ( a_values[i] < b_values[i] ); break; 8824661Sksewell@umich.edu case CMP_LE: cc = ( a_values[i] <= b_values[i] ); break; 8834661Sksewell@umich.edu } 8844661Sksewell@umich.edu 8854661Sksewell@umich.edu result |= cc << i; 8864661Sksewell@umich.edu ccond |= cc << ( DSP_CTL_POS[DSP_CCOND] + i ); 8874661Sksewell@umich.edu } 8884661Sksewell@umich.edu 8894661Sksewell@umich.edu writeDSPControl( dspctl, ccond, 1<<DSP_CCOND ); 8904661Sksewell@umich.edu 8914661Sksewell@umich.edu return( result ); 8924661Sksewell@umich.edu} 8934661Sksewell@umich.edu 8944661Sksewell@umich.eduint32_t 8954661Sksewell@umich.eduMipsISA::dspPrece( int32_t a, int32_t infmt, int32_t insign, int32_t outfmt, int32_t outsign, int32_t mode ) 8964661Sksewell@umich.edu{ 8974661Sksewell@umich.edu int i = 0; 8984661Sksewell@umich.edu int sa = 0; 8994661Sksewell@umich.edu int ninvals = SIMD_NVALS[infmt]; 9004661Sksewell@umich.edu int noutvals = SIMD_NVALS[outfmt]; 9014661Sksewell@umich.edu int32_t result; 9024661Sksewell@umich.edu uint64_t in_values[SIMD_MAX_VALS]; 9034661Sksewell@umich.edu uint64_t out_values[SIMD_MAX_VALS]; 9044661Sksewell@umich.edu 9054661Sksewell@umich.edu if( insign == SIGNED && outsign == SIGNED ) 9064661Sksewell@umich.edu sa = SIMD_NBITS[infmt]; 9074661Sksewell@umich.edu else if( insign == UNSIGNED && outsign == SIGNED ) 9084661Sksewell@umich.edu sa = SIMD_NBITS[infmt] - 1; 9094661Sksewell@umich.edu else if( insign == UNSIGNED && outsign == UNSIGNED ) 9104661Sksewell@umich.edu sa = 0; 9114661Sksewell@umich.edu 9124661Sksewell@umich.edu simdUnpack( a, in_values, infmt, insign ); 9134661Sksewell@umich.edu 9144661Sksewell@umich.edu for( i=0; i<noutvals; i++ ) 9154661Sksewell@umich.edu { 9164661Sksewell@umich.edu switch( mode ) 9174661Sksewell@umich.edu { 9184661Sksewell@umich.edu case MODE_L: out_values[i] = in_values[i+(ninvals>>1)] << sa; break; 9194661Sksewell@umich.edu case MODE_R: out_values[i] = in_values[i] << sa; break; 9204661Sksewell@umich.edu case MODE_LA: out_values[i] = in_values[(i<<1)+1] << sa; break; 9214661Sksewell@umich.edu case MODE_RA: out_values[i] = in_values[i<<1] << sa; break; 9224661Sksewell@umich.edu } 9234661Sksewell@umich.edu } 9244661Sksewell@umich.edu 9254661Sksewell@umich.edu simdPack( out_values, &result, outfmt ); 9264661Sksewell@umich.edu 9274661Sksewell@umich.edu return( result ); 9284661Sksewell@umich.edu} 9294661Sksewell@umich.edu 9304661Sksewell@umich.eduint32_t 9314661Sksewell@umich.eduMipsISA::dspPrecrqu( int32_t a, int32_t b, uint32_t *dspctl ) 9324661Sksewell@umich.edu{ 9334661Sksewell@umich.edu int i = 0; 9344661Sksewell@umich.edu uint64_t a_values[SIMD_MAX_VALS]; 9354661Sksewell@umich.edu uint64_t b_values[SIMD_MAX_VALS]; 9364661Sksewell@umich.edu uint64_t r_values[SIMD_MAX_VALS]; 9374661Sksewell@umich.edu uint32_t ouflag = 0; 9384661Sksewell@umich.edu int32_t result = 0; 9394661Sksewell@umich.edu 9404661Sksewell@umich.edu simdUnpack( a, a_values, SIMD_FMT_PH, SIGNED ); 9414661Sksewell@umich.edu simdUnpack( b, b_values, SIMD_FMT_PH, SIGNED ); 9424661Sksewell@umich.edu 9434661Sksewell@umich.edu for( i=0; i<2; i++ ) 9444661Sksewell@umich.edu { 9454661Sksewell@umich.edu r_values[i] = dspSaturate( (int64_t)b_values[i] >> SIMD_NBITS[SIMD_FMT_QB] - 1, 9464661Sksewell@umich.edu SIMD_FMT_QB, UNSIGNED, &ouflag ); 9474661Sksewell@umich.edu r_values[i+2] = dspSaturate( (int64_t)a_values[i] >> SIMD_NBITS[SIMD_FMT_QB] - 1, 9484661Sksewell@umich.edu SIMD_FMT_QB, UNSIGNED, &ouflag ); 9494661Sksewell@umich.edu } 9504661Sksewell@umich.edu 9514661Sksewell@umich.edu simdPack( r_values, &result, SIMD_FMT_QB ); 9524661Sksewell@umich.edu 9534661Sksewell@umich.edu if( ouflag ) 9544661Sksewell@umich.edu *dspctl = insertBits( *dspctl, 22, 22, 1 ); 9554661Sksewell@umich.edu 9564661Sksewell@umich.edu return result; 9574661Sksewell@umich.edu} 9584661Sksewell@umich.edu 9594661Sksewell@umich.eduint32_t 9604661Sksewell@umich.eduMipsISA::dspPrecrq( int32_t a, int32_t b, int32_t fmt, uint32_t *dspctl ) 9614661Sksewell@umich.edu{ 9624661Sksewell@umich.edu uint64_t a_values[SIMD_MAX_VALS]; 9634661Sksewell@umich.edu uint64_t b_values[SIMD_MAX_VALS]; 9644661Sksewell@umich.edu uint64_t r_values[SIMD_MAX_VALS]; 9654661Sksewell@umich.edu uint32_t ouflag = 0; 9664661Sksewell@umich.edu int32_t result; 9674661Sksewell@umich.edu 9684661Sksewell@umich.edu simdUnpack( a, a_values, fmt, SIGNED ); 9694661Sksewell@umich.edu simdUnpack( b, b_values, fmt, SIGNED ); 9704661Sksewell@umich.edu 9714661Sksewell@umich.edu r_values[1] = dspSaturate( (int64_t)addHalfLsb( a_values[0], 16 ) >> 16, 9724661Sksewell@umich.edu fmt+1, SIGNED, &ouflag ); 9734661Sksewell@umich.edu r_values[0] = dspSaturate( (int64_t)addHalfLsb( b_values[0], 16 ) >> 16, 9744661Sksewell@umich.edu fmt+1, SIGNED, &ouflag ); 9754661Sksewell@umich.edu 9764661Sksewell@umich.edu simdPack( r_values, &result, fmt+1 ); 9774661Sksewell@umich.edu 9784661Sksewell@umich.edu if( ouflag ) 9794661Sksewell@umich.edu *dspctl = insertBits( *dspctl, 22, 22, 1 ); 9804661Sksewell@umich.edu 9814661Sksewell@umich.edu return result; 9824661Sksewell@umich.edu} 9834661Sksewell@umich.edu 9844661Sksewell@umich.eduint32_t 9854661Sksewell@umich.eduMipsISA::dspPrecrSra( int32_t a, int32_t b, int32_t sa, int32_t fmt, int32_t round ) 9864661Sksewell@umich.edu{ 9874661Sksewell@umich.edu int i = 0; 9884661Sksewell@umich.edu int nvals = SIMD_NVALS[fmt]; 9894661Sksewell@umich.edu uint64_t a_values[SIMD_MAX_VALS]; 9904661Sksewell@umich.edu uint64_t b_values[SIMD_MAX_VALS]; 9914661Sksewell@umich.edu uint64_t c_values[SIMD_MAX_VALS]; 9924661Sksewell@umich.edu int32_t result = 0; 9934661Sksewell@umich.edu 9944661Sksewell@umich.edu simdUnpack( a, a_values, fmt, SIGNED ); 9954661Sksewell@umich.edu simdUnpack( b, b_values, fmt, SIGNED ); 9964661Sksewell@umich.edu 9974661Sksewell@umich.edu for( i=0; i<nvals; i++ ) 9984661Sksewell@umich.edu { 9994661Sksewell@umich.edu if( round ) 10004661Sksewell@umich.edu { 10014661Sksewell@umich.edu c_values[i] = addHalfLsb( b_values[i], sa ) >> sa; 10024661Sksewell@umich.edu c_values[i+1] = addHalfLsb( a_values[i], sa ) >> sa; 10034661Sksewell@umich.edu } 10044661Sksewell@umich.edu else 10054661Sksewell@umich.edu { 10064661Sksewell@umich.edu c_values[i] = b_values[i] >> sa; 10074661Sksewell@umich.edu c_values[i+1] = a_values[i] >> sa; 10084661Sksewell@umich.edu } 10094661Sksewell@umich.edu } 10104661Sksewell@umich.edu 10114661Sksewell@umich.edu simdPack( c_values, &result, fmt+1 ); 10124661Sksewell@umich.edu 10134661Sksewell@umich.edu return result; 10144661Sksewell@umich.edu} 10154661Sksewell@umich.edu 10164661Sksewell@umich.eduint32_t 10174661Sksewell@umich.eduMipsISA::dspPick( int32_t a, int32_t b, int32_t fmt, uint32_t *dspctl ) 10184661Sksewell@umich.edu{ 10194661Sksewell@umich.edu int i = 0; 10204661Sksewell@umich.edu int nvals = SIMD_NVALS[fmt]; 10214661Sksewell@umich.edu int32_t result; 10224661Sksewell@umich.edu uint64_t a_values[SIMD_MAX_VALS]; 10234661Sksewell@umich.edu uint64_t b_values[SIMD_MAX_VALS]; 10244661Sksewell@umich.edu uint64_t c_values[SIMD_MAX_VALS]; 10254661Sksewell@umich.edu 10264661Sksewell@umich.edu simdUnpack( a, a_values, fmt, UNSIGNED ); 10274661Sksewell@umich.edu simdUnpack( b, b_values, fmt, UNSIGNED ); 10284661Sksewell@umich.edu 10294661Sksewell@umich.edu for( i=0; i<nvals; i++ ) 10304661Sksewell@umich.edu { 10314661Sksewell@umich.edu int condbit = DSP_CTL_POS[DSP_CCOND] + i; 10324661Sksewell@umich.edu if( bits( *dspctl, condbit, condbit ) == 1 ) 10334661Sksewell@umich.edu c_values[i] = a_values[i]; 10344661Sksewell@umich.edu else 10354661Sksewell@umich.edu c_values[i] = b_values[i]; 10364661Sksewell@umich.edu } 10374661Sksewell@umich.edu 10384661Sksewell@umich.edu simdPack( c_values, &result, fmt ); 10394661Sksewell@umich.edu 10404661Sksewell@umich.edu return( result ); 10414661Sksewell@umich.edu} 10424661Sksewell@umich.edu 10434661Sksewell@umich.eduint32_t 10444661Sksewell@umich.eduMipsISA::dspPack( int32_t a, int32_t b, int32_t fmt ) 10454661Sksewell@umich.edu{ 10464661Sksewell@umich.edu int32_t result; 10474661Sksewell@umich.edu uint64_t a_values[SIMD_MAX_VALS]; 10484661Sksewell@umich.edu uint64_t b_values[SIMD_MAX_VALS]; 10494661Sksewell@umich.edu uint64_t c_values[SIMD_MAX_VALS]; 10504661Sksewell@umich.edu 10514661Sksewell@umich.edu simdUnpack( a, a_values, fmt, UNSIGNED ); 10524661Sksewell@umich.edu simdUnpack( b, b_values, fmt, UNSIGNED ); 10534661Sksewell@umich.edu 10544661Sksewell@umich.edu c_values[0] = b_values[1]; 10554661Sksewell@umich.edu c_values[1] = a_values[0]; 10564661Sksewell@umich.edu 10574661Sksewell@umich.edu simdPack( c_values, &result, fmt ); 10584661Sksewell@umich.edu 10594661Sksewell@umich.edu return( result ); 10604661Sksewell@umich.edu} 10614661Sksewell@umich.edu 10624661Sksewell@umich.eduint32_t 10634661Sksewell@umich.eduMipsISA::dspExtr( int64_t dspac, int32_t fmt, int32_t sa, int32_t round, int32_t saturate, uint32_t *dspctl ) 10644661Sksewell@umich.edu{ 10654661Sksewell@umich.edu int32_t result = 0; 10664661Sksewell@umich.edu uint32_t ouflag = 0; 10674661Sksewell@umich.edu int64_t temp = 0; 10684661Sksewell@umich.edu 10694661Sksewell@umich.edu sa = bits( sa, 4, 0 ); 10704661Sksewell@umich.edu 10714661Sksewell@umich.edu if( sa > 0 ) 10724661Sksewell@umich.edu { 10734661Sksewell@umich.edu if( round ) 10744661Sksewell@umich.edu { 10754661Sksewell@umich.edu temp = (int64_t)addHalfLsb( dspac, sa ); 10764661Sksewell@umich.edu 10774661Sksewell@umich.edu if( dspac > 0 && temp < 0 ) 10784661Sksewell@umich.edu { 10794661Sksewell@umich.edu ouflag = 1; 10804661Sksewell@umich.edu if( saturate ) 10814661Sksewell@umich.edu temp = FIXED_SMAX[SIMD_FMT_L]; 10824661Sksewell@umich.edu } 10834661Sksewell@umich.edu temp = temp >> sa; 10844661Sksewell@umich.edu } 10854661Sksewell@umich.edu else 10864661Sksewell@umich.edu temp = dspac >> sa; 10874661Sksewell@umich.edu } 10884661Sksewell@umich.edu else 10894661Sksewell@umich.edu temp = dspac; 10904661Sksewell@umich.edu 10914661Sksewell@umich.edu dspac = checkOverflow( dspac, fmt, SIGNED, &ouflag ); 10924661Sksewell@umich.edu 10934661Sksewell@umich.edu if( ouflag ) 10944661Sksewell@umich.edu { 10954661Sksewell@umich.edu *dspctl = insertBits( *dspctl, 23, 23, ouflag ); 10964661Sksewell@umich.edu 10974661Sksewell@umich.edu if( saturate ) 10984661Sksewell@umich.edu result = (int32_t)dspSaturate( temp, fmt, SIGNED, &ouflag ); 10994661Sksewell@umich.edu else 11004661Sksewell@umich.edu result = (int32_t)temp; 11014661Sksewell@umich.edu } 11024661Sksewell@umich.edu else 11034661Sksewell@umich.edu result = (int32_t)temp; 11044661Sksewell@umich.edu 11054661Sksewell@umich.edu return( result ); 11064661Sksewell@umich.edu} 11074661Sksewell@umich.edu 11084661Sksewell@umich.eduint32_t 11094661Sksewell@umich.eduMipsISA::dspExtp( int64_t dspac, int32_t size, uint32_t *dspctl ) 11104661Sksewell@umich.edu{ 11114661Sksewell@umich.edu int32_t pos = 0; 11124661Sksewell@umich.edu int32_t result = 0; 11134661Sksewell@umich.edu 11144661Sksewell@umich.edu pos = bits( *dspctl, 5, 0 ); 11154661Sksewell@umich.edu size = bits( size, 4, 0 ); 11164661Sksewell@umich.edu 11174661Sksewell@umich.edu if( pos - (size+1) >= -1 ) 11184661Sksewell@umich.edu { 11194661Sksewell@umich.edu result = bits( dspac, pos, pos-size ); 11204661Sksewell@umich.edu *dspctl = insertBits( *dspctl, 14, 14, 0 ); 11214661Sksewell@umich.edu } 11224661Sksewell@umich.edu else 11234661Sksewell@umich.edu { 11244661Sksewell@umich.edu result = 0; 11254661Sksewell@umich.edu *dspctl = insertBits( *dspctl, 14, 14, 1 ); 11264661Sksewell@umich.edu } 11274661Sksewell@umich.edu 11284661Sksewell@umich.edu return( result ); 11294661Sksewell@umich.edu} 11304661Sksewell@umich.edu 11314661Sksewell@umich.eduint32_t 11324661Sksewell@umich.eduMipsISA::dspExtpd( int64_t dspac, int32_t size, uint32_t *dspctl ) 11334661Sksewell@umich.edu{ 11344661Sksewell@umich.edu int32_t pos = 0; 11354661Sksewell@umich.edu int32_t result = 0; 11364661Sksewell@umich.edu 11374661Sksewell@umich.edu pos = bits( *dspctl, 5, 0 ); 11384661Sksewell@umich.edu size = bits( size, 4, 0 ); 11394661Sksewell@umich.edu 11404661Sksewell@umich.edu if( pos - (size+1) >= -1 ) 11414661Sksewell@umich.edu { 11424661Sksewell@umich.edu result = bits( dspac, pos, pos-size ); 11434661Sksewell@umich.edu *dspctl = insertBits( *dspctl, 14, 14, 0 ); 11444661Sksewell@umich.edu if( pos - (size+1) >= 0 ) 11454661Sksewell@umich.edu *dspctl = insertBits( *dspctl, 5, 0, pos - (size+1) ); 11464661Sksewell@umich.edu else if( (pos - (size+1)) == -1 ) 11474661Sksewell@umich.edu *dspctl = insertBits( *dspctl, 5, 0, 63 ); 11484661Sksewell@umich.edu } 11494661Sksewell@umich.edu else 11504661Sksewell@umich.edu { 11514661Sksewell@umich.edu result = 0; 11524661Sksewell@umich.edu *dspctl = insertBits( *dspctl, 14, 14, 1 ); 11534661Sksewell@umich.edu } 11544661Sksewell@umich.edu 11554661Sksewell@umich.edu return( result ); 11564661Sksewell@umich.edu} 11574661Sksewell@umich.edu 11584661Sksewell@umich.eduvoid 11594661Sksewell@umich.eduMipsISA::simdPack( uint64_t *values_ptr, int32_t *reg, int32_t fmt ) 11604661Sksewell@umich.edu{ 11614661Sksewell@umich.edu int i = 0; 11624661Sksewell@umich.edu int nvals = SIMD_NVALS[fmt]; 11634661Sksewell@umich.edu int nbits = SIMD_NBITS[fmt]; 11644661Sksewell@umich.edu 11654661Sksewell@umich.edu *reg = 0; 11664661Sksewell@umich.edu 11674661Sksewell@umich.edu for( i=0; i<nvals; i++ ) 11684661Sksewell@umich.edu *reg |= (int32_t)bits( values_ptr[i], nbits-1, 0 ) << nbits*i; 11694661Sksewell@umich.edu} 11704661Sksewell@umich.edu 11714661Sksewell@umich.eduvoid 11724661Sksewell@umich.eduMipsISA::simdUnpack( int32_t reg, uint64_t *values_ptr, int32_t fmt, int32_t sign ) 11734661Sksewell@umich.edu{ 11744661Sksewell@umich.edu int i = 0; 11754661Sksewell@umich.edu int nvals = SIMD_NVALS[fmt]; 11764661Sksewell@umich.edu int nbits = SIMD_NBITS[fmt]; 11774661Sksewell@umich.edu 11784661Sksewell@umich.edu switch( sign ) 11794661Sksewell@umich.edu { 11804661Sksewell@umich.edu case SIGNED: 11814661Sksewell@umich.edu for( i=0; i<nvals; i++ ) 11824661Sksewell@umich.edu { 11834661Sksewell@umich.edu values_ptr[i] = (uint64_t)bits( reg, nbits*(i+1)-1, nbits*i ); 11844661Sksewell@umich.edu values_ptr[i] = signExtend( values_ptr[i], fmt ); 11854661Sksewell@umich.edu } 11864661Sksewell@umich.edu break; 11874661Sksewell@umich.edu case UNSIGNED: 11884661Sksewell@umich.edu for( i=0; i<nvals; i++ ) 11894661Sksewell@umich.edu { 11904661Sksewell@umich.edu values_ptr[i] = (uint64_t)bits( reg, nbits*(i+1)-1, nbits*i ); 11914661Sksewell@umich.edu } 11924661Sksewell@umich.edu break; 11934661Sksewell@umich.edu } 11944661Sksewell@umich.edu} 11954661Sksewell@umich.edu 11964661Sksewell@umich.eduvoid 11974661Sksewell@umich.eduMipsISA::writeDSPControl( uint32_t *dspctl, uint32_t value, uint32_t mask ) 11984661Sksewell@umich.edu{ 11994661Sksewell@umich.edu uint32_t fmask = 0; 12004661Sksewell@umich.edu 12014661Sksewell@umich.edu if( mask & 0x01 ) fmask |= DSP_CTL_MASK[DSP_POS]; 12024661Sksewell@umich.edu if( mask & 0x02 ) fmask |= DSP_CTL_MASK[DSP_SCOUNT]; 12034661Sksewell@umich.edu if( mask & 0x04 ) fmask |= DSP_CTL_MASK[DSP_C]; 12044661Sksewell@umich.edu if( mask & 0x08 ) fmask |= DSP_CTL_MASK[DSP_OUFLAG]; 12054661Sksewell@umich.edu if( mask & 0x10 ) fmask |= DSP_CTL_MASK[DSP_CCOND]; 12064661Sksewell@umich.edu if( mask & 0x20 ) fmask |= DSP_CTL_MASK[DSP_EFI]; 12074661Sksewell@umich.edu 12084661Sksewell@umich.edu *dspctl &= ~fmask; 12094661Sksewell@umich.edu value &= fmask; 12104661Sksewell@umich.edu *dspctl |= value; 12114661Sksewell@umich.edu} 12124661Sksewell@umich.edu 12134661Sksewell@umich.eduuint32_t 12144661Sksewell@umich.eduMipsISA::readDSPControl( uint32_t *dspctl, uint32_t mask ) 12154661Sksewell@umich.edu{ 12164661Sksewell@umich.edu uint32_t fmask = 0; 12174661Sksewell@umich.edu 12184661Sksewell@umich.edu if( mask & 0x01 ) fmask |= DSP_CTL_MASK[DSP_POS]; 12194661Sksewell@umich.edu if( mask & 0x02 ) fmask |= DSP_CTL_MASK[DSP_SCOUNT]; 12204661Sksewell@umich.edu if( mask & 0x04 ) fmask |= DSP_CTL_MASK[DSP_C]; 12214661Sksewell@umich.edu if( mask & 0x08 ) fmask |= DSP_CTL_MASK[DSP_OUFLAG]; 12224661Sksewell@umich.edu if( mask & 0x10 ) fmask |= DSP_CTL_MASK[DSP_CCOND]; 12234661Sksewell@umich.edu if( mask & 0x20 ) fmask |= DSP_CTL_MASK[DSP_EFI]; 12244661Sksewell@umich.edu 12254661Sksewell@umich.edu return( *dspctl & fmask ); 12264661Sksewell@umich.edu} 1227