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