dsp.cc revision 5570
14661Sksewell@umich.edu/*
25222Sksewell@umich.edu * Copyright (c) 2007 MIPS Technologies, Inc.
34661Sksewell@umich.edu * All rights reserved.
44661Sksewell@umich.edu *
54661Sksewell@umich.edu * Redistribution and use in source and binary forms, with or without
64661Sksewell@umich.edu * modification, are permitted provided that the following conditions are
74661Sksewell@umich.edu * met: redistributions of source code must retain the above copyright
84661Sksewell@umich.edu * notice, this list of conditions and the following disclaimer;
94661Sksewell@umich.edu * redistributions in binary form must reproduce the above copyright
104661Sksewell@umich.edu * notice, this list of conditions and the following disclaimer in the
114661Sksewell@umich.edu * documentation and/or other materials provided with the distribution;
124661Sksewell@umich.edu * neither the name of the copyright holders nor the names of its
134661Sksewell@umich.edu * contributors may be used to endorse or promote products derived from
144661Sksewell@umich.edu * this software without specific prior written permission.
154661Sksewell@umich.edu *
164661Sksewell@umich.edu * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
174661Sksewell@umich.edu * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
184661Sksewell@umich.edu * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
194661Sksewell@umich.edu * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
204661Sksewell@umich.edu * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
214661Sksewell@umich.edu * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
224661Sksewell@umich.edu * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
234661Sksewell@umich.edu * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
244661Sksewell@umich.edu * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
254661Sksewell@umich.edu * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
264661Sksewell@umich.edu * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
274661Sksewell@umich.edu *
284661Sksewell@umich.edu * Authors: Brett Miller
294661Sksewell@umich.edu */
304661Sksewell@umich.edu
314661Sksewell@umich.edu#include "arch/mips/isa_traits.hh"
324661Sksewell@umich.edu#include "arch/mips/dsp.hh"
334661Sksewell@umich.edu#include "config/full_system.hh"
344661Sksewell@umich.edu#include "cpu/static_inst.hh"
354661Sksewell@umich.edu#include "sim/serialize.hh"
364661Sksewell@umich.edu#include "base/bitfield.hh"
374661Sksewell@umich.edu#include "base/misc.hh"
384661Sksewell@umich.edu
394661Sksewell@umich.eduusing namespace MipsISA;
404661Sksewell@umich.eduusing namespace std;
414661Sksewell@umich.edu
424661Sksewell@umich.eduint32_t
435558Snate@binkert.orgMipsISA::bitrev(int32_t value)
444661Sksewell@umich.edu{
454661Sksewell@umich.edu    int32_t result = 0;
465558Snate@binkert.org    int shift;
474661Sksewell@umich.edu
485558Snate@binkert.org    for (int i = 0; i < 16; i++) {
495558Snate@binkert.org        shift = 2 * i - 15;
504661Sksewell@umich.edu
515558Snate@binkert.org        if (shift < 0)
525558Snate@binkert.org            result |= (value & 1 << i) << -shift;
534661Sksewell@umich.edu        else
545558Snate@binkert.org            result |= (value & 1 << i) >> shift;
554661Sksewell@umich.edu    }
564661Sksewell@umich.edu
574661Sksewell@umich.edu    return result;
584661Sksewell@umich.edu}
594661Sksewell@umich.edu
604661Sksewell@umich.eduuint64_t
615558Snate@binkert.orgMipsISA::dspSaturate(uint64_t value, int32_t fmt, int32_t sign,
625558Snate@binkert.org    uint32_t *overflow)
634661Sksewell@umich.edu{
645558Snate@binkert.org    int64_t svalue = (int64_t)value;
654661Sksewell@umich.edu
665563Snate@binkert.org    switch (sign) {
674661Sksewell@umich.edu      case SIGNED:
685558Snate@binkert.org        if (svalue > (int64_t)FIXED_SMAX[fmt]) {
694661Sksewell@umich.edu            *overflow = 1;
704661Sksewell@umich.edu            svalue = (int64_t)FIXED_SMAX[fmt];
715558Snate@binkert.org        } else if (svalue < (int64_t)FIXED_SMIN[fmt]) {
724661Sksewell@umich.edu            *overflow = 1;
734661Sksewell@umich.edu            svalue = (int64_t)FIXED_SMIN[fmt];
744661Sksewell@umich.edu        }
754661Sksewell@umich.edu        break;
764661Sksewell@umich.edu      case UNSIGNED:
775558Snate@binkert.org        if (svalue > (int64_t)FIXED_UMAX[fmt]) {
784661Sksewell@umich.edu            *overflow = 1;
794661Sksewell@umich.edu            svalue = FIXED_UMAX[fmt];
805558Snate@binkert.org        } else if (svalue < (int64_t)FIXED_UMIN[fmt]) {
814661Sksewell@umich.edu            *overflow = 1;
824661Sksewell@umich.edu            svalue = FIXED_UMIN[fmt];
834661Sksewell@umich.edu        }
844661Sksewell@umich.edu        break;
854661Sksewell@umich.edu    }
864661Sksewell@umich.edu
875558Snate@binkert.org    return (uint64_t)svalue;
884661Sksewell@umich.edu}
894661Sksewell@umich.edu
904661Sksewell@umich.eduuint64_t
915558Snate@binkert.orgMipsISA::checkOverflow(uint64_t value, int32_t fmt, int32_t sign,
925558Snate@binkert.org    uint32_t *overflow)
934661Sksewell@umich.edu{
945558Snate@binkert.org    int64_t svalue = (int64_t)value;
954661Sksewell@umich.edu
965563Snate@binkert.org    switch (sign)
974661Sksewell@umich.edu    {
984661Sksewell@umich.edu      case SIGNED:
995558Snate@binkert.org        if (svalue > (int64_t)FIXED_SMAX[fmt] ||
1005558Snate@binkert.org            svalue < (int64_t)FIXED_SMIN[fmt])
1014661Sksewell@umich.edu            *overflow = 1;
1024661Sksewell@umich.edu        break;
1034661Sksewell@umich.edu      case UNSIGNED:
1045558Snate@binkert.org        if (svalue > (int64_t)FIXED_UMAX[fmt] ||
1055558Snate@binkert.org            svalue < (int64_t)FIXED_UMIN[fmt])
1064661Sksewell@umich.edu            *overflow = 1;
1074661Sksewell@umich.edu        break;
1084661Sksewell@umich.edu    }
1094661Sksewell@umich.edu
1105558Snate@binkert.org    return (uint64_t)svalue;
1114661Sksewell@umich.edu}
1124661Sksewell@umich.edu
1134661Sksewell@umich.eduuint64_t
1145558Snate@binkert.orgMipsISA::signExtend(uint64_t value, int32_t fmt)
1154661Sksewell@umich.edu{
1164661Sksewell@umich.edu    int32_t signpos = SIMD_NBITS[fmt];
1175558Snate@binkert.org    uint64_t sign = uint64_t(1) << (signpos - 1);
1184661Sksewell@umich.edu    uint64_t ones = ~(0ULL);
1194661Sksewell@umich.edu
1205558Snate@binkert.org    if (value & sign)
1214661Sksewell@umich.edu        value |= (ones << signpos); // extend with ones
1224661Sksewell@umich.edu    else
1234661Sksewell@umich.edu        value &= (ones >> (64 - signpos)); // extend with zeros
1244661Sksewell@umich.edu
1254661Sksewell@umich.edu    return value;
1264661Sksewell@umich.edu}
1274661Sksewell@umich.edu
1284661Sksewell@umich.eduuint64_t
1295558Snate@binkert.orgMipsISA::addHalfLsb(uint64_t value, int32_t lsbpos)
1304661Sksewell@umich.edu{
1315558Snate@binkert.org    return value += ULL(1) << (lsbpos - 1);
1324661Sksewell@umich.edu}
1334661Sksewell@umich.edu
1344661Sksewell@umich.eduint32_t
1355558Snate@binkert.orgMipsISA::dspAbs(int32_t a, int32_t fmt, uint32_t *dspctl)
1364661Sksewell@umich.edu{
1374661Sksewell@umich.edu    int nvals = SIMD_NVALS[fmt];
1384661Sksewell@umich.edu    int32_t result;
1394661Sksewell@umich.edu    int64_t svalue;
1404661Sksewell@umich.edu    uint32_t ouflag = 0;
1414661Sksewell@umich.edu    uint64_t a_values[SIMD_MAX_VALS];
1424661Sksewell@umich.edu
1435558Snate@binkert.org    simdUnpack(a, a_values, fmt, SIGNED);
1444661Sksewell@umich.edu
1455558Snate@binkert.org    for (int i = 0; i < nvals; i++) {
1464661Sksewell@umich.edu        svalue = (int64_t)a_values[i];
1474661Sksewell@umich.edu
1485558Snate@binkert.org        if (a_values[i] == FIXED_SMIN[fmt]) {
1494661Sksewell@umich.edu            a_values[i] = FIXED_SMAX[fmt];
1504661Sksewell@umich.edu            ouflag = 1;
1515558Snate@binkert.org        } else if (svalue < 0) {
1525558Snate@binkert.org            a_values[i] = uint64_t(0 - svalue);
1534661Sksewell@umich.edu        }
1544661Sksewell@umich.edu    }
1554661Sksewell@umich.edu
1565558Snate@binkert.org    simdPack(a_values, &result, fmt);
1574661Sksewell@umich.edu
1585558Snate@binkert.org    if (ouflag)
1595558Snate@binkert.org        writeDSPControl(dspctl, (ouflag << 4) << DSP_CTL_POS[DSP_OUFLAG],
1605558Snate@binkert.org                        1 << DSP_OUFLAG);
1614661Sksewell@umich.edu
1625558Snate@binkert.org    return result;
1634661Sksewell@umich.edu}
1644661Sksewell@umich.edu
1654661Sksewell@umich.eduint32_t
1665558Snate@binkert.orgMipsISA::dspAdd(int32_t a, int32_t b, int32_t fmt, int32_t saturate,
1675558Snate@binkert.org    int32_t sign, uint32_t *dspctl)
1684661Sksewell@umich.edu{
1694661Sksewell@umich.edu    int nvals = SIMD_NVALS[fmt];
1704661Sksewell@umich.edu    int32_t result;
1714661Sksewell@umich.edu    uint32_t ouflag = 0;
1724661Sksewell@umich.edu    uint64_t a_values[SIMD_MAX_VALS];
1734661Sksewell@umich.edu    uint64_t b_values[SIMD_MAX_VALS];
1744661Sksewell@umich.edu
1755558Snate@binkert.org    simdUnpack(a, a_values, fmt, sign);
1765558Snate@binkert.org    simdUnpack(b, b_values, fmt, sign);
1774661Sksewell@umich.edu
1785558Snate@binkert.org    for (int i = 0; i < nvals; i++)
1794661Sksewell@umich.edu    {
1805558Snate@binkert.org        if (saturate)
1815558Snate@binkert.org            a_values[i] = dspSaturate(a_values[i] + b_values[i], fmt, sign,
1825558Snate@binkert.org                                      &ouflag);
1834661Sksewell@umich.edu        else
1845558Snate@binkert.org            a_values[i] = checkOverflow(a_values[i] + b_values[i], fmt, sign,
1855558Snate@binkert.org                                        &ouflag);
1864661Sksewell@umich.edu    }
1874661Sksewell@umich.edu
1885558Snate@binkert.org    simdPack(a_values, &result, fmt);
1894661Sksewell@umich.edu
1905558Snate@binkert.org    if (ouflag)
1915558Snate@binkert.org        writeDSPControl(dspctl, (ouflag << 4) << DSP_CTL_POS[DSP_OUFLAG],
1925558Snate@binkert.org                        1 << DSP_OUFLAG);
1934661Sksewell@umich.edu
1945558Snate@binkert.org    return result;
1954661Sksewell@umich.edu}
1964661Sksewell@umich.edu
1974661Sksewell@umich.eduint32_t
1985558Snate@binkert.orgMipsISA::dspAddh(int32_t a, int32_t b, int32_t fmt, int32_t round,
1995558Snate@binkert.org    int32_t sign)
2004661Sksewell@umich.edu{
2014661Sksewell@umich.edu    int nvals = SIMD_NVALS[fmt];
2024661Sksewell@umich.edu    int32_t result;
2034661Sksewell@umich.edu    uint64_t a_values[SIMD_MAX_VALS];
2044661Sksewell@umich.edu    uint64_t b_values[SIMD_MAX_VALS];
2054661Sksewell@umich.edu
2065558Snate@binkert.org    simdUnpack(a, a_values, fmt, sign);
2075558Snate@binkert.org    simdUnpack(b, b_values, fmt, sign);
2084661Sksewell@umich.edu
2095558Snate@binkert.org    for (int i = 0; i < nvals; i++) {
2105558Snate@binkert.org        if (round)
2115558Snate@binkert.org            a_values[i] = addHalfLsb(a_values[i] + b_values[i], 1) >> 1;
2124661Sksewell@umich.edu        else
2135558Snate@binkert.org            a_values[i] = (a_values[i] + b_values[i]) >> 1;
2144661Sksewell@umich.edu    }
2154661Sksewell@umich.edu
2165558Snate@binkert.org    simdPack(a_values, &result, fmt);
2174661Sksewell@umich.edu
2185558Snate@binkert.org    return result;
2194661Sksewell@umich.edu}
2204661Sksewell@umich.edu
2214661Sksewell@umich.eduint32_t
2225558Snate@binkert.orgMipsISA::dspSub(int32_t a, int32_t b, int32_t fmt, int32_t saturate,
2235558Snate@binkert.org    int32_t sign, uint32_t *dspctl)
2244661Sksewell@umich.edu{
2254661Sksewell@umich.edu    int nvals = SIMD_NVALS[fmt];
2264661Sksewell@umich.edu    int32_t result;
2274661Sksewell@umich.edu    uint32_t ouflag = 0;
2284661Sksewell@umich.edu    uint64_t a_values[SIMD_MAX_VALS];
2294661Sksewell@umich.edu    uint64_t b_values[SIMD_MAX_VALS];
2304661Sksewell@umich.edu
2315558Snate@binkert.org    simdUnpack(a, a_values, fmt, sign);
2325558Snate@binkert.org    simdUnpack(b, b_values, fmt, sign);
2334661Sksewell@umich.edu
2345558Snate@binkert.org    for (int i = 0; i < nvals; i++) {
2355558Snate@binkert.org        if (saturate)
2365558Snate@binkert.org            a_values[i] = dspSaturate(a_values[i] - b_values[i], fmt, sign,
2375558Snate@binkert.org                                      &ouflag);
2384661Sksewell@umich.edu        else
2395558Snate@binkert.org            a_values[i] = checkOverflow(a_values[i] - b_values[i], fmt, sign,
2405558Snate@binkert.org                                        &ouflag);
2414661Sksewell@umich.edu    }
2424661Sksewell@umich.edu
2435558Snate@binkert.org    simdPack(a_values, &result, fmt);
2444661Sksewell@umich.edu
2455558Snate@binkert.org    if (ouflag)
2465558Snate@binkert.org        writeDSPControl(dspctl, (ouflag << 4) << DSP_CTL_POS[DSP_OUFLAG],
2475558Snate@binkert.org                        1 << DSP_OUFLAG);
2484661Sksewell@umich.edu
2495558Snate@binkert.org    return result;
2504661Sksewell@umich.edu}
2514661Sksewell@umich.edu
2524661Sksewell@umich.eduint32_t
2535558Snate@binkert.orgMipsISA::dspSubh(int32_t a, int32_t b, int32_t fmt, int32_t round,
2545558Snate@binkert.org    int32_t sign)
2554661Sksewell@umich.edu{
2564661Sksewell@umich.edu    int nvals = SIMD_NVALS[fmt];
2574661Sksewell@umich.edu    int32_t result;
2584661Sksewell@umich.edu    uint64_t a_values[SIMD_MAX_VALS];
2594661Sksewell@umich.edu    uint64_t b_values[SIMD_MAX_VALS];
2604661Sksewell@umich.edu
2615558Snate@binkert.org    simdUnpack(a, a_values, fmt, sign);
2625558Snate@binkert.org    simdUnpack(b, b_values, fmt, sign);
2634661Sksewell@umich.edu
2645558Snate@binkert.org    for (int i = 0; i < nvals; i++)
2654661Sksewell@umich.edu    {
2665558Snate@binkert.org        if (round)
2675558Snate@binkert.org            a_values[i] = addHalfLsb(a_values[i] - b_values[i], 1) >> 1;
2684661Sksewell@umich.edu        else
2695558Snate@binkert.org            a_values[i] = (a_values[i] - b_values[i]) >> 1;
2704661Sksewell@umich.edu    }
2714661Sksewell@umich.edu
2725558Snate@binkert.org    simdPack(a_values, &result, fmt);
2734661Sksewell@umich.edu
2745558Snate@binkert.org    return result;
2754661Sksewell@umich.edu}
2764661Sksewell@umich.edu
2774661Sksewell@umich.eduint32_t
2785558Snate@binkert.orgMipsISA::dspShll(int32_t a, uint32_t sa, int32_t fmt, int32_t saturate,
2795558Snate@binkert.org    int32_t sign, uint32_t *dspctl)
2804661Sksewell@umich.edu{
2814661Sksewell@umich.edu    int nvals = SIMD_NVALS[fmt];
2824661Sksewell@umich.edu    int32_t result;
2834661Sksewell@umich.edu    uint32_t ouflag = 0;
2844661Sksewell@umich.edu    uint64_t a_values[SIMD_MAX_VALS];
2854661Sksewell@umich.edu
2865558Snate@binkert.org    sa = bits(sa, SIMD_LOG2N[fmt] - 1, 0);
2875558Snate@binkert.org    simdUnpack(a, a_values, fmt, sign);
2884661Sksewell@umich.edu
2895558Snate@binkert.org    for (int i = 0; i < nvals; i++)
2904661Sksewell@umich.edu    {
2915558Snate@binkert.org        if (saturate)
2925558Snate@binkert.org            a_values[i] = dspSaturate(a_values[i] << sa, fmt, sign, &ouflag);
2934661Sksewell@umich.edu        else
2945558Snate@binkert.org            a_values[i] = checkOverflow(a_values[i] << sa, fmt, sign, &ouflag);
2954661Sksewell@umich.edu    }
2964661Sksewell@umich.edu
2975558Snate@binkert.org    simdPack(a_values, &result, fmt);
2984661Sksewell@umich.edu
2995558Snate@binkert.org    if (ouflag)
3005558Snate@binkert.org        writeDSPControl(dspctl, (ouflag << 6) << DSP_CTL_POS[DSP_OUFLAG],
3015558Snate@binkert.org                        1 << DSP_OUFLAG);
3024661Sksewell@umich.edu
3035558Snate@binkert.org    return result;
3044661Sksewell@umich.edu}
3054661Sksewell@umich.edu
3064661Sksewell@umich.eduint32_t
3075558Snate@binkert.orgMipsISA::dspShrl(int32_t a, uint32_t sa, int32_t fmt, int32_t sign)
3084661Sksewell@umich.edu{
3094661Sksewell@umich.edu    int nvals = SIMD_NVALS[fmt];
3104661Sksewell@umich.edu    int32_t result;
3114661Sksewell@umich.edu    uint64_t a_values[SIMD_MAX_VALS];
3124661Sksewell@umich.edu
3135558Snate@binkert.org    sa = bits(sa, SIMD_LOG2N[fmt] - 1, 0);
3144661Sksewell@umich.edu
3155558Snate@binkert.org    simdUnpack(a, a_values, fmt, UNSIGNED);
3164661Sksewell@umich.edu
3175558Snate@binkert.org    for (int i = 0; i < nvals; i++)
3184661Sksewell@umich.edu        a_values[i] = a_values[i] >> sa;
3194661Sksewell@umich.edu
3205558Snate@binkert.org    simdPack(a_values, &result, fmt);
3214661Sksewell@umich.edu
3225558Snate@binkert.org    return result;
3234661Sksewell@umich.edu}
3244661Sksewell@umich.edu
3254661Sksewell@umich.eduint32_t
3265558Snate@binkert.orgMipsISA::dspShra(int32_t a, uint32_t sa, int32_t fmt, int32_t round,
3275558Snate@binkert.org    int32_t sign, uint32_t *dspctl)
3284661Sksewell@umich.edu{
3294661Sksewell@umich.edu    int nvals = SIMD_NVALS[fmt];
3304661Sksewell@umich.edu    int32_t result;
3314661Sksewell@umich.edu    uint64_t a_values[SIMD_MAX_VALS];
3324661Sksewell@umich.edu
3335558Snate@binkert.org    sa = bits(sa, SIMD_LOG2N[fmt] - 1, 0);
3344661Sksewell@umich.edu
3355558Snate@binkert.org    simdUnpack(a, a_values, fmt, SIGNED);
3364661Sksewell@umich.edu
3375558Snate@binkert.org    for (int i = 0; i < nvals; i++) {
3385558Snate@binkert.org        if (round)
3395558Snate@binkert.org            a_values[i] = addHalfLsb(a_values[i], sa) >> sa;
3404661Sksewell@umich.edu        else
3414661Sksewell@umich.edu            a_values[i] = a_values[i] >> sa;
3424661Sksewell@umich.edu    }
3434661Sksewell@umich.edu
3445558Snate@binkert.org    simdPack(a_values, &result, fmt);
3454661Sksewell@umich.edu
3465558Snate@binkert.org    return result;
3474661Sksewell@umich.edu}
3484661Sksewell@umich.edu
3494661Sksewell@umich.eduint32_t
3505558Snate@binkert.orgMipsISA::dspMulq(int32_t a, int32_t b, int32_t fmt, int32_t saturate,
3515558Snate@binkert.org    int32_t round, uint32_t *dspctl)
3524661Sksewell@umich.edu{
3534661Sksewell@umich.edu    int nvals = SIMD_NVALS[fmt];
3544661Sksewell@umich.edu    int sa = SIMD_NBITS[fmt];
3554661Sksewell@umich.edu    int32_t result;
3564661Sksewell@umich.edu    uint32_t ouflag = 0;
3574661Sksewell@umich.edu    uint64_t a_values[SIMD_MAX_VALS];
3584661Sksewell@umich.edu    uint64_t b_values[SIMD_MAX_VALS];
3594661Sksewell@umich.edu    int64_t temp;
3604661Sksewell@umich.edu
3615558Snate@binkert.org    simdUnpack(a, a_values, fmt, SIGNED);
3625558Snate@binkert.org    simdUnpack(b, b_values, fmt, SIGNED);
3634661Sksewell@umich.edu
3645558Snate@binkert.org    for (int i = 0; i < nvals; i++) {
3655558Snate@binkert.org        if (round)
3665558Snate@binkert.org            temp =
3675558Snate@binkert.org                (int64_t)addHalfLsb(a_values[i] * b_values[i] << 1, sa) >> sa;
3684661Sksewell@umich.edu        else
3694661Sksewell@umich.edu            temp = (int64_t)(a_values[i] * b_values[i]) >> (sa - 1);
3704661Sksewell@umich.edu
3715558Snate@binkert.org        if (a_values[i] == FIXED_SMIN[fmt] && b_values[i] == FIXED_SMIN[fmt]) {
3724661Sksewell@umich.edu            ouflag = 1;
3734661Sksewell@umich.edu
3745558Snate@binkert.org            if (saturate)
3754661Sksewell@umich.edu                temp = FIXED_SMAX[fmt];
3764661Sksewell@umich.edu        }
3774661Sksewell@umich.edu
3784661Sksewell@umich.edu        a_values[i] = temp;
3794661Sksewell@umich.edu    }
3804661Sksewell@umich.edu
3815558Snate@binkert.org    simdPack(a_values, &result, fmt);
3824661Sksewell@umich.edu
3835558Snate@binkert.org    if (ouflag)
3845558Snate@binkert.org        writeDSPControl(dspctl, (ouflag << 5) << DSP_CTL_POS[DSP_OUFLAG],
3855558Snate@binkert.org                        1 << DSP_OUFLAG);
3864661Sksewell@umich.edu
3875558Snate@binkert.org    return result;
3884661Sksewell@umich.edu}
3894661Sksewell@umich.edu
3904661Sksewell@umich.eduint32_t
3915558Snate@binkert.orgMipsISA::dspMul(int32_t a, int32_t b, int32_t fmt, int32_t saturate,
3925558Snate@binkert.org    uint32_t *dspctl)
3934661Sksewell@umich.edu{
3944661Sksewell@umich.edu    int nvals = SIMD_NVALS[fmt];
3954661Sksewell@umich.edu    int32_t result;
3964661Sksewell@umich.edu    uint32_t ouflag = 0;
3974661Sksewell@umich.edu    uint64_t a_values[SIMD_MAX_VALS];
3984661Sksewell@umich.edu    uint64_t b_values[SIMD_MAX_VALS];
3994661Sksewell@umich.edu
4005558Snate@binkert.org    simdUnpack(a, a_values, fmt, SIGNED);
4015558Snate@binkert.org    simdUnpack(b, b_values, fmt, SIGNED);
4024661Sksewell@umich.edu
4035558Snate@binkert.org    for (int i = 0; i < nvals; i++)
4044661Sksewell@umich.edu    {
4055558Snate@binkert.org        if (saturate)
4065558Snate@binkert.org            a_values[i] = dspSaturate(a_values[i] * b_values[i], fmt, SIGNED,
4075558Snate@binkert.org                                      &ouflag);
4084661Sksewell@umich.edu        else
4095558Snate@binkert.org            a_values[i] = checkOverflow(a_values[i] * b_values[i], fmt, SIGNED,
4105558Snate@binkert.org                                        &ouflag);
4114661Sksewell@umich.edu    }
4124661Sksewell@umich.edu
4135558Snate@binkert.org    simdPack(a_values, &result, fmt);
4144661Sksewell@umich.edu
4155558Snate@binkert.org    if (ouflag)
4165558Snate@binkert.org        writeDSPControl(dspctl, (ouflag << 5) << DSP_CTL_POS[DSP_OUFLAG],
4175558Snate@binkert.org                        1 << DSP_OUFLAG);
4184661Sksewell@umich.edu
4195558Snate@binkert.org    return result;
4204661Sksewell@umich.edu}
4214661Sksewell@umich.edu
4224661Sksewell@umich.eduint32_t
4235558Snate@binkert.orgMipsISA::dspMuleu(int32_t a, int32_t b, int32_t mode, uint32_t *dspctl)
4244661Sksewell@umich.edu{
4254661Sksewell@umich.edu    int nvals = SIMD_NVALS[SIMD_FMT_PH];
4264661Sksewell@umich.edu    int32_t result;
4274661Sksewell@umich.edu    uint32_t ouflag = 0;
4284661Sksewell@umich.edu    uint64_t a_values[SIMD_MAX_VALS];
4294661Sksewell@umich.edu    uint64_t b_values[SIMD_MAX_VALS];
4304661Sksewell@umich.edu
4315558Snate@binkert.org    simdUnpack(a, a_values, SIMD_FMT_QB, UNSIGNED);
4325558Snate@binkert.org    simdUnpack(b, b_values, SIMD_FMT_PH, UNSIGNED);
4334661Sksewell@umich.edu
4345563Snate@binkert.org    switch (mode) {
4354661Sksewell@umich.edu      case MODE_L:
4365558Snate@binkert.org        for (int i = 0; i < nvals; i++)
4375558Snate@binkert.org            b_values[i] = dspSaturate(a_values[i + 2] * b_values[i],
4385558Snate@binkert.org                                      SIMD_FMT_PH, UNSIGNED, &ouflag);
4394661Sksewell@umich.edu        break;
4404661Sksewell@umich.edu      case MODE_R:
4415558Snate@binkert.org        for (int i = 0; i < nvals; i++)
4425558Snate@binkert.org            b_values[i] = dspSaturate(a_values[i] * b_values[i], SIMD_FMT_PH,
4435558Snate@binkert.org                                      UNSIGNED, &ouflag);
4444661Sksewell@umich.edu        break;
4454661Sksewell@umich.edu    }
4464661Sksewell@umich.edu
4475558Snate@binkert.org    simdPack(b_values, &result, SIMD_FMT_PH);
4484661Sksewell@umich.edu
4495558Snate@binkert.org    if (ouflag)
4505558Snate@binkert.org        writeDSPControl(dspctl, (ouflag << 5) << DSP_CTL_POS[DSP_OUFLAG],
4515558Snate@binkert.org                        1 << DSP_OUFLAG);
4524661Sksewell@umich.edu
4535558Snate@binkert.org    return result;
4544661Sksewell@umich.edu}
4554661Sksewell@umich.edu
4564661Sksewell@umich.eduint32_t
4575558Snate@binkert.orgMipsISA::dspMuleq(int32_t a, int32_t b, int32_t mode, uint32_t *dspctl)
4584661Sksewell@umich.edu{
4594661Sksewell@umich.edu    int nvals = SIMD_NVALS[SIMD_FMT_W];
4604661Sksewell@umich.edu    int32_t result;
4614661Sksewell@umich.edu    uint32_t ouflag = 0;
4624661Sksewell@umich.edu    uint64_t a_values[SIMD_MAX_VALS];
4634661Sksewell@umich.edu    uint64_t b_values[SIMD_MAX_VALS];
4644661Sksewell@umich.edu    uint64_t c_values[SIMD_MAX_VALS];
4654661Sksewell@umich.edu
4665558Snate@binkert.org    simdUnpack(a, a_values, SIMD_FMT_PH, SIGNED);
4675558Snate@binkert.org    simdUnpack(b, b_values, SIMD_FMT_PH, SIGNED);
4684661Sksewell@umich.edu
4695563Snate@binkert.org    switch (mode) {
4704661Sksewell@umich.edu      case MODE_L:
4715558Snate@binkert.org        for (int i = 0; i < nvals; i++)
4725558Snate@binkert.org            c_values[i] = dspSaturate(a_values[i + 1] * b_values[i + 1] << 1,
4735558Snate@binkert.org                                       SIMD_FMT_W, SIGNED, &ouflag);
4744661Sksewell@umich.edu        break;
4754661Sksewell@umich.edu      case MODE_R:
4765558Snate@binkert.org        for (int i = 0; i < nvals; i++)
4775558Snate@binkert.org            c_values[i] = dspSaturate(a_values[i] * b_values[i] << 1,
4785558Snate@binkert.org                                       SIMD_FMT_W, SIGNED, &ouflag);
4794661Sksewell@umich.edu        break;
4804661Sksewell@umich.edu    }
4814661Sksewell@umich.edu
4825558Snate@binkert.org    simdPack(c_values, &result, SIMD_FMT_W);
4834661Sksewell@umich.edu
4845558Snate@binkert.org    if (ouflag)
4855558Snate@binkert.org        writeDSPControl(dspctl, (ouflag << 5) << DSP_CTL_POS[DSP_OUFLAG],
4865558Snate@binkert.org                        1 << DSP_OUFLAG);
4874661Sksewell@umich.edu
4885558Snate@binkert.org    return result;
4894661Sksewell@umich.edu}
4904661Sksewell@umich.edu
4914661Sksewell@umich.eduint64_t
4925558Snate@binkert.orgMipsISA::dspDpaq(int64_t dspac, int32_t a, int32_t b, int32_t ac,
4935558Snate@binkert.org    int32_t infmt, int32_t outfmt, int32_t postsat, int32_t mode,
4945558Snate@binkert.org    uint32_t *dspctl)
4954661Sksewell@umich.edu{
4964661Sksewell@umich.edu    int nvals = SIMD_NVALS[infmt];
4974661Sksewell@umich.edu    int64_t result = 0;
4984661Sksewell@umich.edu    int64_t temp = 0;
4994661Sksewell@umich.edu    uint32_t ouflag = 0;
5004661Sksewell@umich.edu    uint64_t a_values[SIMD_MAX_VALS];
5014661Sksewell@umich.edu    uint64_t b_values[SIMD_MAX_VALS];
5024661Sksewell@umich.edu
5035558Snate@binkert.org    simdUnpack(a, a_values, infmt, SIGNED);
5045558Snate@binkert.org    simdUnpack(b, b_values, infmt, SIGNED);
5054661Sksewell@umich.edu
5065558Snate@binkert.org    for (int i = 0; i < nvals; i++) {
5075563Snate@binkert.org        switch (mode) {
5084661Sksewell@umich.edu          case MODE_X:
5095558Snate@binkert.org            if (a_values[nvals - 1 - i] == FIXED_SMIN[infmt] &&
5105558Snate@binkert.org                b_values[i] == FIXED_SMIN[infmt]) {
5114661Sksewell@umich.edu                result += FIXED_SMAX[outfmt];
5124661Sksewell@umich.edu                ouflag = 1;
5134661Sksewell@umich.edu            }
5144661Sksewell@umich.edu            else
5155558Snate@binkert.org                result += a_values[nvals - 1 - i] * b_values[i] << 1;
5164661Sksewell@umich.edu            break;
5174661Sksewell@umich.edu          default:
5185558Snate@binkert.org            if (a_values[i] == FIXED_SMIN[infmt] &&
5195558Snate@binkert.org                b_values[i] == FIXED_SMIN[infmt]) {
5204661Sksewell@umich.edu                result += FIXED_SMAX[outfmt];
5214661Sksewell@umich.edu                ouflag = 1;
5225558Snate@binkert.org            } else {
5235558Snate@binkert.org                result += a_values[i] * b_values[i] << 1;
5244661Sksewell@umich.edu            }
5254661Sksewell@umich.edu            break;
5264661Sksewell@umich.edu        }
5274661Sksewell@umich.edu    }
5284661Sksewell@umich.edu
5295558Snate@binkert.org    if (postsat) {
5305558Snate@binkert.org        if (outfmt == SIMD_FMT_L) {
5315558Snate@binkert.org            int signa = bits(dspac, 63, 63);
5325558Snate@binkert.org            int signb = bits(result, 63, 63);
5334661Sksewell@umich.edu
5344661Sksewell@umich.edu            temp = dspac + result;
5354661Sksewell@umich.edu
5365558Snate@binkert.org            if (signa == signb && bits(temp, 63, 63) != signa) {
5374661Sksewell@umich.edu                ouflag = 1;
5385558Snate@binkert.org                if (signa)
5394661Sksewell@umich.edu                    dspac = FIXED_SMIN[outfmt];
5404661Sksewell@umich.edu                else
5414661Sksewell@umich.edu                    dspac = FIXED_SMAX[outfmt];
5425558Snate@binkert.org            } else {
5435558Snate@binkert.org                dspac = temp;
5444661Sksewell@umich.edu            }
5455558Snate@binkert.org        } else {
5465558Snate@binkert.org            dspac = dspSaturate(dspac + result, outfmt, SIGNED, &ouflag);
5474661Sksewell@umich.edu        }
5485558Snate@binkert.org    } else {
5495558Snate@binkert.org        dspac += result;
5504661Sksewell@umich.edu    }
5514661Sksewell@umich.edu
5525558Snate@binkert.org    if (ouflag)
5535558Snate@binkert.org        *dspctl = insertBits(*dspctl, 16 + ac, 16 + ac, 1);
5544661Sksewell@umich.edu
5555558Snate@binkert.org    return dspac;
5564661Sksewell@umich.edu}
5574661Sksewell@umich.edu
5584661Sksewell@umich.eduint64_t
5595558Snate@binkert.orgMipsISA::dspDpsq(int64_t dspac, int32_t a, int32_t b, int32_t ac,
5605558Snate@binkert.org    int32_t infmt, int32_t outfmt, int32_t postsat, int32_t mode,
5615558Snate@binkert.org    uint32_t *dspctl)
5624661Sksewell@umich.edu{
5634661Sksewell@umich.edu    int nvals = SIMD_NVALS[infmt];
5644661Sksewell@umich.edu    int64_t result = 0;
5654661Sksewell@umich.edu    int64_t temp = 0;
5664661Sksewell@umich.edu    uint32_t ouflag = 0;
5674661Sksewell@umich.edu    uint64_t a_values[SIMD_MAX_VALS];
5684661Sksewell@umich.edu    uint64_t b_values[SIMD_MAX_VALS];
5694661Sksewell@umich.edu
5705558Snate@binkert.org    simdUnpack(a, a_values, infmt, SIGNED);
5715558Snate@binkert.org    simdUnpack(b, b_values, infmt, SIGNED);
5724661Sksewell@umich.edu
5735558Snate@binkert.org    for (int i = 0; i < nvals; i++) {
5745563Snate@binkert.org        switch (mode) {
5754661Sksewell@umich.edu          case MODE_X:
5765558Snate@binkert.org            if (a_values[nvals - 1 - i] == FIXED_SMIN[infmt] &&
5775558Snate@binkert.org                b_values[i] == FIXED_SMIN[infmt]) {
5784661Sksewell@umich.edu                result += FIXED_SMAX[outfmt];
5794661Sksewell@umich.edu                ouflag = 1;
5805558Snate@binkert.org            } else {
5815558Snate@binkert.org                result += a_values[nvals - 1 - i] * b_values[i] << 1;
5824661Sksewell@umich.edu            }
5834661Sksewell@umich.edu            break;
5844661Sksewell@umich.edu          default:
5855558Snate@binkert.org            if (a_values[i] == FIXED_SMIN[infmt] &&
5865558Snate@binkert.org                b_values[i] == FIXED_SMIN[infmt]) {
5874661Sksewell@umich.edu                result += FIXED_SMAX[outfmt];
5884661Sksewell@umich.edu                ouflag = 1;
5895558Snate@binkert.org            } else {
5905558Snate@binkert.org                result += a_values[i] * b_values[i] << 1;
5914661Sksewell@umich.edu            }
5924661Sksewell@umich.edu            break;
5934661Sksewell@umich.edu        }
5944661Sksewell@umich.edu    }
5954661Sksewell@umich.edu
5965558Snate@binkert.org    if (postsat) {
5975558Snate@binkert.org        if (outfmt == SIMD_FMT_L) {
5985558Snate@binkert.org            int signa = bits(dspac, 63, 63);
5995558Snate@binkert.org            int signb = bits(-result, 63, 63);
6004661Sksewell@umich.edu
6014661Sksewell@umich.edu            temp = dspac - result;
6024661Sksewell@umich.edu
6035558Snate@binkert.org            if (signa == signb && bits(temp, 63, 63) != signa) {
6044661Sksewell@umich.edu                ouflag = 1;
6055558Snate@binkert.org                if (signa)
6064661Sksewell@umich.edu                    dspac = FIXED_SMIN[outfmt];
6074661Sksewell@umich.edu                else
6084661Sksewell@umich.edu                    dspac = FIXED_SMAX[outfmt];
6095558Snate@binkert.org            } else {
6105558Snate@binkert.org                dspac = temp;
6114661Sksewell@umich.edu            }
6125558Snate@binkert.org        } else {
6135558Snate@binkert.org            dspac = dspSaturate(dspac - result, outfmt, SIGNED, &ouflag);
6144661Sksewell@umich.edu        }
6155558Snate@binkert.org    } else {
6165558Snate@binkert.org        dspac -= result;
6174661Sksewell@umich.edu    }
6184661Sksewell@umich.edu
6195558Snate@binkert.org    if (ouflag)
6205558Snate@binkert.org        *dspctl = insertBits(*dspctl, 16 + ac, 16 + ac, 1);
6214661Sksewell@umich.edu
6225558Snate@binkert.org    return dspac;
6234661Sksewell@umich.edu}
6244661Sksewell@umich.edu
6254661Sksewell@umich.eduint64_t
6265558Snate@binkert.orgMipsISA::dspDpa(int64_t dspac, int32_t a, int32_t b, int32_t ac,
6275558Snate@binkert.org                int32_t fmt, int32_t sign, int32_t mode)
6284661Sksewell@umich.edu{
6294661Sksewell@umich.edu    int nvals = SIMD_NVALS[fmt];
6304661Sksewell@umich.edu    uint64_t a_values[SIMD_MAX_VALS];
6314661Sksewell@umich.edu    uint64_t b_values[SIMD_MAX_VALS];
6324661Sksewell@umich.edu
6335558Snate@binkert.org    simdUnpack(a, a_values, fmt, sign);
6345558Snate@binkert.org    simdUnpack(b, b_values, fmt, sign);
6354661Sksewell@umich.edu
6365558Snate@binkert.org    for (int i = 0; i < 2; i++) {
6375563Snate@binkert.org        switch (mode) {
6384661Sksewell@umich.edu          case MODE_L:
6395558Snate@binkert.org            dspac += a_values[nvals - 1 - i] * b_values[nvals - 1 - i];
6404661Sksewell@umich.edu            break;
6414661Sksewell@umich.edu          case MODE_R:
6425558Snate@binkert.org            dspac += a_values[nvals - 3 - i] * b_values[nvals - 3 - i];
6434661Sksewell@umich.edu            break;
6444661Sksewell@umich.edu          case MODE_X:
6455558Snate@binkert.org            dspac += a_values[nvals - 1 - i] * b_values[i];
6464661Sksewell@umich.edu            break;
6474661Sksewell@umich.edu        }
6484661Sksewell@umich.edu    }
6494661Sksewell@umich.edu
6504661Sksewell@umich.edu    return dspac;
6514661Sksewell@umich.edu}
6524661Sksewell@umich.edu
6534661Sksewell@umich.eduint64_t
6545558Snate@binkert.orgMipsISA::dspDps(int64_t dspac, int32_t a, int32_t b, int32_t ac,
6555558Snate@binkert.org                int32_t fmt, int32_t sign, int32_t mode)
6564661Sksewell@umich.edu{
6574661Sksewell@umich.edu    int nvals = SIMD_NVALS[fmt];
6584661Sksewell@umich.edu    uint64_t a_values[SIMD_MAX_VALS];
6594661Sksewell@umich.edu    uint64_t b_values[SIMD_MAX_VALS];
6604661Sksewell@umich.edu
6615558Snate@binkert.org    simdUnpack(a, a_values, fmt, sign);
6625558Snate@binkert.org    simdUnpack(b, b_values, fmt, sign);
6634661Sksewell@umich.edu
6645558Snate@binkert.org    for (int i = 0; i < 2; i++) {
6655563Snate@binkert.org        switch (mode) {
6664661Sksewell@umich.edu          case MODE_L:
6675558Snate@binkert.org            dspac -= a_values[nvals - 1 - i] * b_values[nvals - 1 - i];
6684661Sksewell@umich.edu            break;
6694661Sksewell@umich.edu          case MODE_R:
6705558Snate@binkert.org            dspac -= a_values[nvals - 3 - i] * b_values[nvals - 3 - i];
6714661Sksewell@umich.edu            break;
6724661Sksewell@umich.edu          case MODE_X:
6735558Snate@binkert.org            dspac -= a_values[nvals - 1 - i] * b_values[i];
6744661Sksewell@umich.edu            break;
6754661Sksewell@umich.edu        }
6764661Sksewell@umich.edu    }
6774661Sksewell@umich.edu
6784661Sksewell@umich.edu    return dspac;
6794661Sksewell@umich.edu}
6804661Sksewell@umich.edu
6814661Sksewell@umich.eduint64_t
6825558Snate@binkert.orgMipsISA::dspMaq(int64_t dspac, int32_t a, int32_t b, int32_t ac,
6835558Snate@binkert.org                 int32_t fmt, int32_t mode, int32_t saturate, uint32_t *dspctl)
6844661Sksewell@umich.edu{
6855558Snate@binkert.org    int nvals = SIMD_NVALS[fmt - 1];
6864661Sksewell@umich.edu    uint64_t a_values[SIMD_MAX_VALS];
6874661Sksewell@umich.edu    uint64_t b_values[SIMD_MAX_VALS];
6884661Sksewell@umich.edu    int64_t temp = 0;
6894661Sksewell@umich.edu    uint32_t ouflag = 0;
6904661Sksewell@umich.edu
6915558Snate@binkert.org    simdUnpack(a, a_values, fmt, SIGNED);
6925558Snate@binkert.org    simdUnpack(b, b_values, fmt, SIGNED);
6934661Sksewell@umich.edu
6945558Snate@binkert.org    for (int i = 0; i < nvals; i++) {
6955563Snate@binkert.org        switch (mode) {
6964661Sksewell@umich.edu          case MODE_L:
6975558Snate@binkert.org            temp = a_values[i + 1] * b_values[i + 1] << 1;
6985558Snate@binkert.org            if (a_values[i + 1] == FIXED_SMIN[fmt] &&
6995558Snate@binkert.org                b_values[i + 1] == FIXED_SMIN[fmt]) {
7005558Snate@binkert.org                temp = (int64_t)FIXED_SMAX[fmt - 1];
7014661Sksewell@umich.edu                ouflag = 1;
7024661Sksewell@umich.edu            }
7034661Sksewell@umich.edu            break;
7044661Sksewell@umich.edu          case MODE_R:
7054661Sksewell@umich.edu            temp = a_values[i] * b_values[i] << 1;
7065558Snate@binkert.org            if (a_values[i] == FIXED_SMIN[fmt] &&
7075558Snate@binkert.org                b_values[i] == FIXED_SMIN[fmt]) {
7085558Snate@binkert.org                temp = (int64_t)FIXED_SMAX[fmt - 1];
7094661Sksewell@umich.edu                ouflag = 1;
7104661Sksewell@umich.edu            }
7114661Sksewell@umich.edu            break;
7124661Sksewell@umich.edu        }
7134661Sksewell@umich.edu
7144661Sksewell@umich.edu        temp += dspac;
7154661Sksewell@umich.edu
7165558Snate@binkert.org        if (saturate)
7175558Snate@binkert.org            temp = dspSaturate(temp, fmt - 1, SIGNED, &ouflag);
7185558Snate@binkert.org        if (ouflag)
7195558Snate@binkert.org            *dspctl = insertBits(*dspctl, 16 + ac, 16 + ac, 1);
7204661Sksewell@umich.edu    }
7214661Sksewell@umich.edu
7224661Sksewell@umich.edu    return temp;
7234661Sksewell@umich.edu}
7244661Sksewell@umich.edu
7254661Sksewell@umich.eduint64_t
7265558Snate@binkert.orgMipsISA::dspMulsa(int64_t dspac, int32_t a, int32_t b, int32_t ac, int32_t fmt)
7274661Sksewell@umich.edu{
7284661Sksewell@umich.edu    uint64_t a_values[SIMD_MAX_VALS];
7294661Sksewell@umich.edu    uint64_t b_values[SIMD_MAX_VALS];
7304661Sksewell@umich.edu
7315558Snate@binkert.org    simdUnpack(a, a_values, fmt, SIGNED);
7325558Snate@binkert.org    simdUnpack(b, b_values, fmt, SIGNED);
7334661Sksewell@umich.edu
7344661Sksewell@umich.edu    dspac += a_values[1] * b_values[1] - a_values[0] * b_values[0];
7354661Sksewell@umich.edu
7364661Sksewell@umich.edu    return dspac;
7374661Sksewell@umich.edu}
7384661Sksewell@umich.edu
7394661Sksewell@umich.eduint64_t
7405558Snate@binkert.orgMipsISA::dspMulsaq(int64_t dspac, int32_t a, int32_t b, int32_t ac,
7415558Snate@binkert.org    int32_t fmt, uint32_t *dspctl)
7424661Sksewell@umich.edu{
7434661Sksewell@umich.edu    int nvals = SIMD_NVALS[fmt];
7444661Sksewell@umich.edu    uint64_t a_values[SIMD_MAX_VALS];
7454661Sksewell@umich.edu    uint64_t b_values[SIMD_MAX_VALS];
7464661Sksewell@umich.edu    int64_t temp[2];
7474661Sksewell@umich.edu    uint32_t ouflag = 0;
7484661Sksewell@umich.edu
7495558Snate@binkert.org    simdUnpack(a, a_values, fmt, SIGNED);
7505558Snate@binkert.org    simdUnpack(b, b_values, fmt, SIGNED);
7514661Sksewell@umich.edu
7525558Snate@binkert.org    for (int i = nvals - 1; i > -1; i--) {
7534661Sksewell@umich.edu        temp[i] = a_values[i] * b_values[i] << 1;
7545558Snate@binkert.org        if (a_values[i] == FIXED_SMIN[fmt] && b_values[i] == FIXED_SMIN[fmt]) {
7555558Snate@binkert.org            temp[i] = FIXED_SMAX[fmt - 1];
7564661Sksewell@umich.edu            ouflag = 1;
7574661Sksewell@umich.edu        }
7584661Sksewell@umich.edu    }
7594661Sksewell@umich.edu
7604661Sksewell@umich.edu    dspac += temp[1] - temp[0];
7614661Sksewell@umich.edu
7625558Snate@binkert.org    if (ouflag)
7635558Snate@binkert.org        *dspctl = insertBits(*dspctl, 16 + ac, 16 + ac, 1);
7644661Sksewell@umich.edu
7654661Sksewell@umich.edu    return dspac;
7664661Sksewell@umich.edu}
7674661Sksewell@umich.edu
7684661Sksewell@umich.eduvoid
7695558Snate@binkert.orgMipsISA::dspCmp(int32_t a, int32_t b, int32_t fmt, int32_t sign, int32_t op,
7705558Snate@binkert.org    uint32_t *dspctl)
7714661Sksewell@umich.edu{
7724661Sksewell@umich.edu    int nvals = SIMD_NVALS[fmt];
7734661Sksewell@umich.edu    int ccond = 0;
7744661Sksewell@umich.edu    uint64_t a_values[SIMD_MAX_VALS];
7754661Sksewell@umich.edu    uint64_t b_values[SIMD_MAX_VALS];
7764661Sksewell@umich.edu
7775558Snate@binkert.org    simdUnpack(a, a_values, fmt, sign);
7785558Snate@binkert.org    simdUnpack(b, b_values, fmt, sign);
7794661Sksewell@umich.edu
7805558Snate@binkert.org    for (int i = 0; i < nvals; i++) {
7814661Sksewell@umich.edu        int cc = 0;
7824661Sksewell@umich.edu
7835563Snate@binkert.org        switch (op) {
7845558Snate@binkert.org          case CMP_EQ:
7855558Snate@binkert.org            cc = (a_values[i] == b_values[i]);
7865558Snate@binkert.org            break;
7875558Snate@binkert.org          case CMP_LT:
7885558Snate@binkert.org            cc = (a_values[i] < b_values[i]);
7895558Snate@binkert.org            break;
7905558Snate@binkert.org          case CMP_LE:
7915558Snate@binkert.org            cc = (a_values[i] <= b_values[i]);
7925558Snate@binkert.org            break;
7934661Sksewell@umich.edu        }
7944661Sksewell@umich.edu
7955558Snate@binkert.org        ccond |= cc << (DSP_CTL_POS[DSP_CCOND] + i);
7964661Sksewell@umich.edu    }
7974661Sksewell@umich.edu
7985558Snate@binkert.org    writeDSPControl(dspctl, ccond, 1 << DSP_CCOND);
7994661Sksewell@umich.edu}
8004661Sksewell@umich.edu
8014661Sksewell@umich.eduint32_t
8025558Snate@binkert.orgMipsISA::dspCmpg(int32_t a, int32_t b, int32_t fmt, int32_t sign, int32_t op)
8034661Sksewell@umich.edu{
8044661Sksewell@umich.edu    int nvals = SIMD_NVALS[fmt];
8054661Sksewell@umich.edu    int32_t result = 0;
8064661Sksewell@umich.edu    uint64_t a_values[SIMD_MAX_VALS];
8074661Sksewell@umich.edu    uint64_t b_values[SIMD_MAX_VALS];
8084661Sksewell@umich.edu
8095558Snate@binkert.org    simdUnpack(a, a_values, fmt, sign);
8105558Snate@binkert.org    simdUnpack(b, b_values, fmt, sign);
8114661Sksewell@umich.edu
8125558Snate@binkert.org    for (int i = 0; i < nvals; i++) {
8134661Sksewell@umich.edu        int cc = 0;
8144661Sksewell@umich.edu
8155563Snate@binkert.org        switch (op) {
8165558Snate@binkert.org          case CMP_EQ:
8175558Snate@binkert.org            cc = (a_values[i] == b_values[i]);
8185558Snate@binkert.org            break;
8195558Snate@binkert.org          case CMP_LT:
8205558Snate@binkert.org            cc = (a_values[i] < b_values[i]);
8215558Snate@binkert.org            break;
8225558Snate@binkert.org          case CMP_LE:
8235558Snate@binkert.org            cc = (a_values[i] <= b_values[i]);
8245558Snate@binkert.org            break;
8254661Sksewell@umich.edu        }
8264661Sksewell@umich.edu
8274661Sksewell@umich.edu        result |= cc << i;
8284661Sksewell@umich.edu    }
8294661Sksewell@umich.edu
8305558Snate@binkert.org    return result;
8314661Sksewell@umich.edu}
8324661Sksewell@umich.edu
8334661Sksewell@umich.eduint32_t
8345558Snate@binkert.orgMipsISA::dspCmpgd(int32_t a, int32_t b, int32_t fmt, int32_t sign, int32_t op,
8355558Snate@binkert.org    uint32_t *dspctl)
8364661Sksewell@umich.edu{
8374661Sksewell@umich.edu    int nvals = SIMD_NVALS[fmt];
8384661Sksewell@umich.edu    int32_t result = 0;
8394661Sksewell@umich.edu    int ccond = 0;
8404661Sksewell@umich.edu    uint64_t a_values[SIMD_MAX_VALS];
8414661Sksewell@umich.edu    uint64_t b_values[SIMD_MAX_VALS];
8424661Sksewell@umich.edu
8435558Snate@binkert.org    simdUnpack(a, a_values, fmt, sign);
8445558Snate@binkert.org    simdUnpack(b, b_values, fmt, sign);
8454661Sksewell@umich.edu
8465558Snate@binkert.org    for (int i = 0; i < nvals; i++) {
8475558Snate@binkert.org        int cc = 0;
8484661Sksewell@umich.edu
8495563Snate@binkert.org        switch (op) {
8505558Snate@binkert.org          case CMP_EQ:
8515558Snate@binkert.org            cc = (a_values[i] == b_values[i]);
8525558Snate@binkert.org            break;
8535558Snate@binkert.org          case CMP_LT:
8545558Snate@binkert.org            cc = (a_values[i] < b_values[i]);
8555558Snate@binkert.org            break;
8565558Snate@binkert.org          case CMP_LE:
8575558Snate@binkert.org            cc = (a_values[i] <= b_values[i]);
8585558Snate@binkert.org            break;
8594661Sksewell@umich.edu        }
8604661Sksewell@umich.edu
8614661Sksewell@umich.edu        result |= cc << i;
8625558Snate@binkert.org        ccond |= cc << (DSP_CTL_POS[DSP_CCOND] + i);
8634661Sksewell@umich.edu    }
8644661Sksewell@umich.edu
8655558Snate@binkert.org    writeDSPControl(dspctl, ccond, 1 << DSP_CCOND);
8664661Sksewell@umich.edu
8675558Snate@binkert.org    return result;
8684661Sksewell@umich.edu}
8694661Sksewell@umich.edu
8704661Sksewell@umich.eduint32_t
8715558Snate@binkert.orgMipsISA::dspPrece(int32_t a, int32_t infmt, int32_t insign, int32_t outfmt,
8725558Snate@binkert.org    int32_t outsign, int32_t mode)
8734661Sksewell@umich.edu{
8744661Sksewell@umich.edu    int sa = 0;
8754661Sksewell@umich.edu    int ninvals = SIMD_NVALS[infmt];
8764661Sksewell@umich.edu    int noutvals = SIMD_NVALS[outfmt];
8774661Sksewell@umich.edu    int32_t result;
8784661Sksewell@umich.edu    uint64_t in_values[SIMD_MAX_VALS];
8794661Sksewell@umich.edu    uint64_t out_values[SIMD_MAX_VALS];
8804661Sksewell@umich.edu
8815558Snate@binkert.org    if (insign == SIGNED && outsign == SIGNED)
8824661Sksewell@umich.edu      sa = SIMD_NBITS[infmt];
8835558Snate@binkert.org    else if (insign == UNSIGNED && outsign == SIGNED)
8844661Sksewell@umich.edu      sa = SIMD_NBITS[infmt] - 1;
8855558Snate@binkert.org    else if (insign == UNSIGNED && outsign == UNSIGNED)
8864661Sksewell@umich.edu      sa = 0;
8874661Sksewell@umich.edu
8885558Snate@binkert.org    simdUnpack(a, in_values, infmt, insign);
8894661Sksewell@umich.edu
8905558Snate@binkert.org    for (int i = 0; i<noutvals; i++) {
8915563Snate@binkert.org        switch (mode) {
8925558Snate@binkert.org          case MODE_L:
8935558Snate@binkert.org            out_values[i] = in_values[i + (ninvals >> 1)] << sa;
8945558Snate@binkert.org            break;
8955558Snate@binkert.org          case MODE_R:
8965558Snate@binkert.org            out_values[i] = in_values[i] << sa;
8975558Snate@binkert.org            break;
8985558Snate@binkert.org          case MODE_LA:
8995558Snate@binkert.org            out_values[i] = in_values[(i << 1) + 1] << sa;
9005558Snate@binkert.org            break;
9015558Snate@binkert.org          case MODE_RA:
9025558Snate@binkert.org            out_values[i] = in_values[i << 1] << sa;
9035558Snate@binkert.org            break;
9044661Sksewell@umich.edu        }
9054661Sksewell@umich.edu    }
9064661Sksewell@umich.edu
9075558Snate@binkert.org    simdPack(out_values, &result, outfmt);
9084661Sksewell@umich.edu
9095558Snate@binkert.org    return result;
9104661Sksewell@umich.edu}
9114661Sksewell@umich.edu
9124661Sksewell@umich.eduint32_t
9135558Snate@binkert.orgMipsISA::dspPrecrqu(int32_t a, int32_t b, uint32_t *dspctl)
9144661Sksewell@umich.edu{
9154661Sksewell@umich.edu    uint64_t a_values[SIMD_MAX_VALS];
9164661Sksewell@umich.edu    uint64_t b_values[SIMD_MAX_VALS];
9174661Sksewell@umich.edu    uint64_t r_values[SIMD_MAX_VALS];
9184661Sksewell@umich.edu    uint32_t ouflag = 0;
9194661Sksewell@umich.edu    int32_t result = 0;
9204661Sksewell@umich.edu
9215558Snate@binkert.org    simdUnpack(a, a_values, SIMD_FMT_PH, SIGNED);
9225558Snate@binkert.org    simdUnpack(b, b_values, SIMD_FMT_PH, SIGNED);
9234661Sksewell@umich.edu
9245558Snate@binkert.org    for (int i = 0; i<2; i++) {
9255558Snate@binkert.org        r_values[i] =
9265570Snate@binkert.org            dspSaturate((int64_t)b_values[i] >> (SIMD_NBITS[SIMD_FMT_QB] - 1),
9275558Snate@binkert.org                        SIMD_FMT_QB, UNSIGNED, &ouflag);
9285558Snate@binkert.org        r_values[i + 2] =
9295570Snate@binkert.org            dspSaturate((int64_t)a_values[i] >> (SIMD_NBITS[SIMD_FMT_QB] - 1),
9305558Snate@binkert.org                        SIMD_FMT_QB, UNSIGNED, &ouflag);
9314661Sksewell@umich.edu    }
9324661Sksewell@umich.edu
9335558Snate@binkert.org    simdPack(r_values, &result, SIMD_FMT_QB);
9344661Sksewell@umich.edu
9355558Snate@binkert.org    if (ouflag)
9365558Snate@binkert.org        *dspctl = insertBits(*dspctl, 22, 22, 1);
9374661Sksewell@umich.edu
9384661Sksewell@umich.edu    return result;
9394661Sksewell@umich.edu}
9404661Sksewell@umich.edu
9414661Sksewell@umich.eduint32_t
9425558Snate@binkert.orgMipsISA::dspPrecrq(int32_t a, int32_t b, int32_t fmt, uint32_t *dspctl)
9434661Sksewell@umich.edu{
9444661Sksewell@umich.edu    uint64_t a_values[SIMD_MAX_VALS];
9454661Sksewell@umich.edu    uint64_t b_values[SIMD_MAX_VALS];
9464661Sksewell@umich.edu    uint64_t r_values[SIMD_MAX_VALS];
9474661Sksewell@umich.edu    uint32_t ouflag = 0;
9484661Sksewell@umich.edu    int32_t result;
9494661Sksewell@umich.edu
9505558Snate@binkert.org    simdUnpack(a, a_values, fmt, SIGNED);
9515558Snate@binkert.org    simdUnpack(b, b_values, fmt, SIGNED);
9524661Sksewell@umich.edu
9535558Snate@binkert.org    r_values[1] = dspSaturate((int64_t)addHalfLsb(a_values[0], 16) >> 16,
9545558Snate@binkert.org                              fmt + 1, SIGNED, &ouflag);
9555558Snate@binkert.org    r_values[0] = dspSaturate((int64_t)addHalfLsb(b_values[0], 16) >> 16,
9565558Snate@binkert.org                              fmt + 1, SIGNED, &ouflag);
9574661Sksewell@umich.edu
9585558Snate@binkert.org    simdPack(r_values, &result, fmt + 1);
9594661Sksewell@umich.edu
9605558Snate@binkert.org    if (ouflag)
9615558Snate@binkert.org        *dspctl = insertBits(*dspctl, 22, 22, 1);
9624661Sksewell@umich.edu
9634661Sksewell@umich.edu    return result;
9644661Sksewell@umich.edu}
9654661Sksewell@umich.edu
9664661Sksewell@umich.eduint32_t
9675558Snate@binkert.orgMipsISA::dspPrecrSra(int32_t a, int32_t b, int32_t sa, int32_t fmt,
9685558Snate@binkert.org    int32_t round)
9694661Sksewell@umich.edu{
9704661Sksewell@umich.edu    int nvals = SIMD_NVALS[fmt];
9714661Sksewell@umich.edu    uint64_t a_values[SIMD_MAX_VALS];
9724661Sksewell@umich.edu    uint64_t b_values[SIMD_MAX_VALS];
9734661Sksewell@umich.edu    uint64_t c_values[SIMD_MAX_VALS];
9744661Sksewell@umich.edu    int32_t result = 0;
9754661Sksewell@umich.edu
9765558Snate@binkert.org    simdUnpack(a, a_values, fmt, SIGNED);
9775558Snate@binkert.org    simdUnpack(b, b_values, fmt, SIGNED);
9784661Sksewell@umich.edu
9795558Snate@binkert.org    for (int i = 0; i < nvals; i++) {
9805558Snate@binkert.org        if (round) {
9815558Snate@binkert.org            c_values[i] = addHalfLsb(b_values[i], sa) >> sa;
9825558Snate@binkert.org            c_values[i + 1] = addHalfLsb(a_values[i], sa) >> sa;
9835558Snate@binkert.org        } else {
9844661Sksewell@umich.edu            c_values[i] = b_values[i] >> sa;
9855558Snate@binkert.org            c_values[i + 1] = a_values[i] >> sa;
9864661Sksewell@umich.edu        }
9874661Sksewell@umich.edu    }
9884661Sksewell@umich.edu
9895558Snate@binkert.org    simdPack(c_values, &result, fmt + 1);
9904661Sksewell@umich.edu
9914661Sksewell@umich.edu    return result;
9924661Sksewell@umich.edu}
9934661Sksewell@umich.edu
9944661Sksewell@umich.eduint32_t
9955558Snate@binkert.orgMipsISA::dspPick(int32_t a, int32_t b, int32_t fmt, uint32_t *dspctl)
9964661Sksewell@umich.edu{
9974661Sksewell@umich.edu    int nvals = SIMD_NVALS[fmt];
9984661Sksewell@umich.edu    int32_t result;
9994661Sksewell@umich.edu    uint64_t a_values[SIMD_MAX_VALS];
10004661Sksewell@umich.edu    uint64_t b_values[SIMD_MAX_VALS];
10014661Sksewell@umich.edu    uint64_t c_values[SIMD_MAX_VALS];
10024661Sksewell@umich.edu
10035558Snate@binkert.org    simdUnpack(a, a_values, fmt, UNSIGNED);
10045558Snate@binkert.org    simdUnpack(b, b_values, fmt, UNSIGNED);
10054661Sksewell@umich.edu
10065558Snate@binkert.org    for (int i = 0; i < nvals; i++) {
10074661Sksewell@umich.edu        int condbit = DSP_CTL_POS[DSP_CCOND] + i;
10085558Snate@binkert.org        if (bits(*dspctl, condbit, condbit) == 1)
10094661Sksewell@umich.edu            c_values[i] = a_values[i];
10104661Sksewell@umich.edu        else
10114661Sksewell@umich.edu            c_values[i] = b_values[i];
10124661Sksewell@umich.edu    }
10134661Sksewell@umich.edu
10145558Snate@binkert.org    simdPack(c_values, &result, fmt);
10154661Sksewell@umich.edu
10165558Snate@binkert.org    return result;
10174661Sksewell@umich.edu}
10184661Sksewell@umich.edu
10194661Sksewell@umich.eduint32_t
10205558Snate@binkert.orgMipsISA::dspPack(int32_t a, int32_t b, int32_t fmt)
10214661Sksewell@umich.edu{
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
10275558Snate@binkert.org    simdUnpack(a, a_values, fmt, UNSIGNED);
10285558Snate@binkert.org    simdUnpack(b, b_values, fmt, UNSIGNED);
10294661Sksewell@umich.edu
10304661Sksewell@umich.edu    c_values[0] = b_values[1];
10314661Sksewell@umich.edu    c_values[1] = a_values[0];
10324661Sksewell@umich.edu
10335558Snate@binkert.org    simdPack(c_values, &result, fmt);
10344661Sksewell@umich.edu
10355558Snate@binkert.org    return result;
10364661Sksewell@umich.edu}
10374661Sksewell@umich.edu
10384661Sksewell@umich.eduint32_t
10395558Snate@binkert.orgMipsISA::dspExtr(int64_t dspac, int32_t fmt, int32_t sa, int32_t round,
10405558Snate@binkert.org    int32_t saturate, uint32_t *dspctl)
10414661Sksewell@umich.edu{
10424661Sksewell@umich.edu    int32_t result = 0;
10434661Sksewell@umich.edu    uint32_t ouflag = 0;
10444661Sksewell@umich.edu    int64_t temp = 0;
10454661Sksewell@umich.edu
10465558Snate@binkert.org    sa = bits(sa, 4, 0);
10474661Sksewell@umich.edu
10485558Snate@binkert.org    if (sa > 0) {
10495558Snate@binkert.org        if (round) {
10505558Snate@binkert.org            temp = (int64_t)addHalfLsb(dspac, sa);
10514661Sksewell@umich.edu
10525558Snate@binkert.org            if (dspac > 0 && temp < 0) {
10534661Sksewell@umich.edu                ouflag = 1;
10545558Snate@binkert.org                if (saturate)
10554661Sksewell@umich.edu                    temp = FIXED_SMAX[SIMD_FMT_L];
10564661Sksewell@umich.edu            }
10574661Sksewell@umich.edu            temp = temp >> sa;
10585558Snate@binkert.org        } else {
10595558Snate@binkert.org            temp = dspac >> sa;
10604661Sksewell@umich.edu        }
10615558Snate@binkert.org    } else {
10625558Snate@binkert.org        temp = dspac;
10634661Sksewell@umich.edu    }
10644661Sksewell@umich.edu
10655558Snate@binkert.org    dspac = checkOverflow(dspac, fmt, SIGNED, &ouflag);
10664661Sksewell@umich.edu
10675558Snate@binkert.org    if (ouflag) {
10685558Snate@binkert.org        *dspctl = insertBits(*dspctl, 23, 23, ouflag);
10694661Sksewell@umich.edu
10705558Snate@binkert.org        if (saturate)
10715558Snate@binkert.org            result = (int32_t)dspSaturate(temp, fmt, SIGNED, &ouflag);
10724661Sksewell@umich.edu        else
10734661Sksewell@umich.edu            result = (int32_t)temp;
10745558Snate@binkert.org    } else {
10755558Snate@binkert.org        result = (int32_t)temp;
10764661Sksewell@umich.edu    }
10774661Sksewell@umich.edu
10785558Snate@binkert.org    return result;
10794661Sksewell@umich.edu}
10804661Sksewell@umich.edu
10814661Sksewell@umich.eduint32_t
10825558Snate@binkert.orgMipsISA::dspExtp(int64_t dspac, int32_t size, uint32_t *dspctl)
10834661Sksewell@umich.edu{
10844661Sksewell@umich.edu    int32_t pos = 0;
10854661Sksewell@umich.edu    int32_t result = 0;
10864661Sksewell@umich.edu
10875558Snate@binkert.org    pos = bits(*dspctl, 5, 0);
10885558Snate@binkert.org    size = bits(size, 4, 0);
10894661Sksewell@umich.edu
10905558Snate@binkert.org    if (pos - (size + 1) >= -1) {
10915558Snate@binkert.org        result = bits(dspac, pos, pos - size);
10925558Snate@binkert.org        *dspctl = insertBits(*dspctl, 14, 14, 0);
10935558Snate@binkert.org    } else {
10944661Sksewell@umich.edu        result = 0;
10955558Snate@binkert.org        *dspctl = insertBits(*dspctl, 14, 14, 1);
10964661Sksewell@umich.edu    }
10974661Sksewell@umich.edu
10985558Snate@binkert.org    return result;
10994661Sksewell@umich.edu}
11004661Sksewell@umich.edu
11014661Sksewell@umich.eduint32_t
11025558Snate@binkert.orgMipsISA::dspExtpd(int64_t dspac, int32_t size, uint32_t *dspctl)
11034661Sksewell@umich.edu{
11044661Sksewell@umich.edu    int32_t pos = 0;
11054661Sksewell@umich.edu    int32_t result = 0;
11064661Sksewell@umich.edu
11075558Snate@binkert.org    pos = bits(*dspctl, 5, 0);
11085558Snate@binkert.org    size = bits(size, 4, 0);
11094661Sksewell@umich.edu
11105558Snate@binkert.org    if (pos - (size + 1) >= -1) {
11115558Snate@binkert.org        result = bits(dspac, pos, pos - size);
11125558Snate@binkert.org        *dspctl = insertBits(*dspctl, 14, 14, 0);
11135558Snate@binkert.org        if (pos - (size + 1) >= 0)
11145558Snate@binkert.org            *dspctl = insertBits(*dspctl, 5, 0, pos - (size + 1));
11155558Snate@binkert.org        else if ((pos - (size + 1)) == -1)
11165558Snate@binkert.org            *dspctl = insertBits(*dspctl, 5, 0, 63);
11175558Snate@binkert.org    } else {
11184661Sksewell@umich.edu        result = 0;
11195558Snate@binkert.org        *dspctl = insertBits(*dspctl, 14, 14, 1);
11204661Sksewell@umich.edu    }
11214661Sksewell@umich.edu
11225558Snate@binkert.org    return result;
11234661Sksewell@umich.edu}
11244661Sksewell@umich.edu
11254661Sksewell@umich.eduvoid
11265558Snate@binkert.orgMipsISA::simdPack(uint64_t *values_ptr, int32_t *reg, int32_t fmt)
11274661Sksewell@umich.edu{
11284661Sksewell@umich.edu    int nvals = SIMD_NVALS[fmt];
11294661Sksewell@umich.edu    int nbits = SIMD_NBITS[fmt];
11304661Sksewell@umich.edu
11314661Sksewell@umich.edu    *reg = 0;
11324661Sksewell@umich.edu
11335558Snate@binkert.org    for (int i = 0; i < nvals; i++)
11345558Snate@binkert.org        *reg |= (int32_t)bits(values_ptr[i], nbits - 1, 0) << nbits * i;
11354661Sksewell@umich.edu}
11364661Sksewell@umich.edu
11374661Sksewell@umich.eduvoid
11385558Snate@binkert.orgMipsISA::simdUnpack(int32_t reg, uint64_t *values_ptr, int32_t fmt, int32_t sign)
11394661Sksewell@umich.edu{
11404661Sksewell@umich.edu    int nvals = SIMD_NVALS[fmt];
11414661Sksewell@umich.edu    int nbits = SIMD_NBITS[fmt];
11424661Sksewell@umich.edu
11435563Snate@binkert.org    switch (sign) {
11445558Snate@binkert.org      case SIGNED:
11455558Snate@binkert.org        for (int i = 0; i < nvals; i++) {
11465558Snate@binkert.org            uint64_t tmp = (uint64_t)bits(reg, nbits * (i + 1) - 1, nbits * i);
11475558Snate@binkert.org            values_ptr[i] = signExtend(tmp, fmt);
11484661Sksewell@umich.edu        }
11494661Sksewell@umich.edu        break;
11505558Snate@binkert.org      case UNSIGNED:
11515558Snate@binkert.org        for (int i = 0; i < nvals; i++) {
11525558Snate@binkert.org            values_ptr[i] =
11535558Snate@binkert.org                (uint64_t)bits(reg, nbits * (i + 1) - 1, nbits * i);
11544661Sksewell@umich.edu        }
11554661Sksewell@umich.edu        break;
11564661Sksewell@umich.edu    }
11574661Sksewell@umich.edu}
11584661Sksewell@umich.edu
11594661Sksewell@umich.eduvoid
11605558Snate@binkert.orgMipsISA::writeDSPControl(uint32_t *dspctl, uint32_t value, uint32_t mask)
11614661Sksewell@umich.edu{
11624661Sksewell@umich.edu    uint32_t fmask = 0;
11634661Sksewell@umich.edu
11645558Snate@binkert.org    if (mask & 0x01) fmask |= DSP_CTL_MASK[DSP_POS];
11655558Snate@binkert.org    if (mask & 0x02) fmask |= DSP_CTL_MASK[DSP_SCOUNT];
11665558Snate@binkert.org    if (mask & 0x04) fmask |= DSP_CTL_MASK[DSP_C];
11675558Snate@binkert.org    if (mask & 0x08) fmask |= DSP_CTL_MASK[DSP_OUFLAG];
11685558Snate@binkert.org    if (mask & 0x10) fmask |= DSP_CTL_MASK[DSP_CCOND];
11695558Snate@binkert.org    if (mask & 0x20) fmask |= DSP_CTL_MASK[DSP_EFI];
11704661Sksewell@umich.edu
11714661Sksewell@umich.edu    *dspctl &= ~fmask;
11724661Sksewell@umich.edu    value &= fmask;
11734661Sksewell@umich.edu    *dspctl |= value;
11744661Sksewell@umich.edu}
11754661Sksewell@umich.edu
11764661Sksewell@umich.eduuint32_t
11775558Snate@binkert.orgMipsISA::readDSPControl(uint32_t *dspctl, uint32_t mask)
11784661Sksewell@umich.edu{
11794661Sksewell@umich.edu    uint32_t fmask = 0;
11804661Sksewell@umich.edu
11815558Snate@binkert.org    if (mask & 0x01) fmask |= DSP_CTL_MASK[DSP_POS];
11825558Snate@binkert.org    if (mask & 0x02) fmask |= DSP_CTL_MASK[DSP_SCOUNT];
11835558Snate@binkert.org    if (mask & 0x04) fmask |= DSP_CTL_MASK[DSP_C];
11845558Snate@binkert.org    if (mask & 0x08) fmask |= DSP_CTL_MASK[DSP_OUFLAG];
11855558Snate@binkert.org    if (mask & 0x10) fmask |= DSP_CTL_MASK[DSP_CCOND];
11865558Snate@binkert.org    if (mask & 0x20) fmask |= DSP_CTL_MASK[DSP_EFI];
11874661Sksewell@umich.edu
11885558Snate@binkert.org    return *dspctl & fmask;
11894661Sksewell@umich.edu}
1190