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