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