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
318229Snate@binkert.org#include "arch/mips/dsp.hh"
3211793Sbrandon.potter@amd.com
334661Sksewell@umich.edu#include "arch/mips/isa_traits.hh"
348229Snate@binkert.org#include "base/bitfield.hh"
3512334Sgabeblack@google.com#include "base/logging.hh"
364661Sksewell@umich.edu#include "cpu/static_inst.hh"
374661Sksewell@umich.edu#include "sim/serialize.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
4666712Snate@binkert.org    memset(c_values, 0, sizeof(c_values));
4676712Snate@binkert.org
4685558Snate@binkert.org    simdUnpack(a, a_values, SIMD_FMT_PH, SIGNED);
4695558Snate@binkert.org    simdUnpack(b, b_values, SIMD_FMT_PH, SIGNED);
4704661Sksewell@umich.edu
4715563Snate@binkert.org    switch (mode) {
4724661Sksewell@umich.edu      case MODE_L:
4735558Snate@binkert.org        for (int i = 0; i < nvals; i++)
4745558Snate@binkert.org            c_values[i] = dspSaturate(a_values[i + 1] * b_values[i + 1] << 1,
4755558Snate@binkert.org                                       SIMD_FMT_W, SIGNED, &ouflag);
4764661Sksewell@umich.edu        break;
4774661Sksewell@umich.edu      case MODE_R:
4785558Snate@binkert.org        for (int i = 0; i < nvals; i++)
4795558Snate@binkert.org            c_values[i] = dspSaturate(a_values[i] * b_values[i] << 1,
4805558Snate@binkert.org                                       SIMD_FMT_W, SIGNED, &ouflag);
4814661Sksewell@umich.edu        break;
4824661Sksewell@umich.edu    }
4834661Sksewell@umich.edu
4845558Snate@binkert.org    simdPack(c_values, &result, SIMD_FMT_W);
4854661Sksewell@umich.edu
4865558Snate@binkert.org    if (ouflag)
4875558Snate@binkert.org        writeDSPControl(dspctl, (ouflag << 5) << DSP_CTL_POS[DSP_OUFLAG],
4885558Snate@binkert.org                        1 << DSP_OUFLAG);
4894661Sksewell@umich.edu
4905558Snate@binkert.org    return result;
4914661Sksewell@umich.edu}
4924661Sksewell@umich.edu
4934661Sksewell@umich.eduint64_t
4945558Snate@binkert.orgMipsISA::dspDpaq(int64_t dspac, int32_t a, int32_t b, int32_t ac,
4955558Snate@binkert.org    int32_t infmt, int32_t outfmt, int32_t postsat, int32_t mode,
4965558Snate@binkert.org    uint32_t *dspctl)
4974661Sksewell@umich.edu{
4984661Sksewell@umich.edu    int nvals = SIMD_NVALS[infmt];
4994661Sksewell@umich.edu    int64_t result = 0;
5004661Sksewell@umich.edu    int64_t temp = 0;
5014661Sksewell@umich.edu    uint32_t ouflag = 0;
5024661Sksewell@umich.edu    uint64_t a_values[SIMD_MAX_VALS];
5034661Sksewell@umich.edu    uint64_t b_values[SIMD_MAX_VALS];
5044661Sksewell@umich.edu
5055558Snate@binkert.org    simdUnpack(a, a_values, infmt, SIGNED);
5065558Snate@binkert.org    simdUnpack(b, b_values, infmt, SIGNED);
5074661Sksewell@umich.edu
5085558Snate@binkert.org    for (int i = 0; i < nvals; i++) {
5095563Snate@binkert.org        switch (mode) {
5104661Sksewell@umich.edu          case MODE_X:
5115558Snate@binkert.org            if (a_values[nvals - 1 - i] == FIXED_SMIN[infmt] &&
5125558Snate@binkert.org                b_values[i] == FIXED_SMIN[infmt]) {
5134661Sksewell@umich.edu                result += FIXED_SMAX[outfmt];
5144661Sksewell@umich.edu                ouflag = 1;
5154661Sksewell@umich.edu            }
5164661Sksewell@umich.edu            else
5175558Snate@binkert.org                result += a_values[nvals - 1 - i] * b_values[i] << 1;
5184661Sksewell@umich.edu            break;
5194661Sksewell@umich.edu          default:
5205558Snate@binkert.org            if (a_values[i] == FIXED_SMIN[infmt] &&
5215558Snate@binkert.org                b_values[i] == FIXED_SMIN[infmt]) {
5224661Sksewell@umich.edu                result += FIXED_SMAX[outfmt];
5234661Sksewell@umich.edu                ouflag = 1;
5245558Snate@binkert.org            } else {
5255558Snate@binkert.org                result += a_values[i] * b_values[i] << 1;
5264661Sksewell@umich.edu            }
5274661Sksewell@umich.edu            break;
5284661Sksewell@umich.edu        }
5294661Sksewell@umich.edu    }
5304661Sksewell@umich.edu
5315558Snate@binkert.org    if (postsat) {
5325558Snate@binkert.org        if (outfmt == SIMD_FMT_L) {
5335558Snate@binkert.org            int signa = bits(dspac, 63, 63);
5345558Snate@binkert.org            int signb = bits(result, 63, 63);
5354661Sksewell@umich.edu
5364661Sksewell@umich.edu            temp = dspac + result;
5374661Sksewell@umich.edu
5385558Snate@binkert.org            if (signa == signb && bits(temp, 63, 63) != signa) {
5394661Sksewell@umich.edu                ouflag = 1;
5405558Snate@binkert.org                if (signa)
5414661Sksewell@umich.edu                    dspac = FIXED_SMIN[outfmt];
5424661Sksewell@umich.edu                else
5434661Sksewell@umich.edu                    dspac = FIXED_SMAX[outfmt];
5445558Snate@binkert.org            } else {
5455558Snate@binkert.org                dspac = temp;
5464661Sksewell@umich.edu            }
5475558Snate@binkert.org        } else {
5485558Snate@binkert.org            dspac = dspSaturate(dspac + result, outfmt, SIGNED, &ouflag);
5494661Sksewell@umich.edu        }
5505558Snate@binkert.org    } else {
5515558Snate@binkert.org        dspac += result;
5524661Sksewell@umich.edu    }
5534661Sksewell@umich.edu
5545558Snate@binkert.org    if (ouflag)
5555558Snate@binkert.org        *dspctl = insertBits(*dspctl, 16 + ac, 16 + ac, 1);
5564661Sksewell@umich.edu
5575558Snate@binkert.org    return dspac;
5584661Sksewell@umich.edu}
5594661Sksewell@umich.edu
5604661Sksewell@umich.eduint64_t
5615558Snate@binkert.orgMipsISA::dspDpsq(int64_t dspac, int32_t a, int32_t b, int32_t ac,
5625558Snate@binkert.org    int32_t infmt, int32_t outfmt, int32_t postsat, int32_t mode,
5635558Snate@binkert.org    uint32_t *dspctl)
5644661Sksewell@umich.edu{
5654661Sksewell@umich.edu    int nvals = SIMD_NVALS[infmt];
5664661Sksewell@umich.edu    int64_t result = 0;
5674661Sksewell@umich.edu    int64_t temp = 0;
5684661Sksewell@umich.edu    uint32_t ouflag = 0;
5694661Sksewell@umich.edu    uint64_t a_values[SIMD_MAX_VALS];
5704661Sksewell@umich.edu    uint64_t b_values[SIMD_MAX_VALS];
5714661Sksewell@umich.edu
5725558Snate@binkert.org    simdUnpack(a, a_values, infmt, SIGNED);
5735558Snate@binkert.org    simdUnpack(b, b_values, infmt, SIGNED);
5744661Sksewell@umich.edu
5755558Snate@binkert.org    for (int i = 0; i < nvals; i++) {
5765563Snate@binkert.org        switch (mode) {
5774661Sksewell@umich.edu          case MODE_X:
5785558Snate@binkert.org            if (a_values[nvals - 1 - i] == FIXED_SMIN[infmt] &&
5795558Snate@binkert.org                b_values[i] == FIXED_SMIN[infmt]) {
5804661Sksewell@umich.edu                result += FIXED_SMAX[outfmt];
5814661Sksewell@umich.edu                ouflag = 1;
5825558Snate@binkert.org            } else {
5835558Snate@binkert.org                result += a_values[nvals - 1 - i] * b_values[i] << 1;
5844661Sksewell@umich.edu            }
5854661Sksewell@umich.edu            break;
5864661Sksewell@umich.edu          default:
5875558Snate@binkert.org            if (a_values[i] == FIXED_SMIN[infmt] &&
5885558Snate@binkert.org                b_values[i] == FIXED_SMIN[infmt]) {
5894661Sksewell@umich.edu                result += FIXED_SMAX[outfmt];
5904661Sksewell@umich.edu                ouflag = 1;
5915558Snate@binkert.org            } else {
5925558Snate@binkert.org                result += a_values[i] * b_values[i] << 1;
5934661Sksewell@umich.edu            }
5944661Sksewell@umich.edu            break;
5954661Sksewell@umich.edu        }
5964661Sksewell@umich.edu    }
5974661Sksewell@umich.edu
5985558Snate@binkert.org    if (postsat) {
5995558Snate@binkert.org        if (outfmt == SIMD_FMT_L) {
6005558Snate@binkert.org            int signa = bits(dspac, 63, 63);
6015558Snate@binkert.org            int signb = bits(-result, 63, 63);
6024661Sksewell@umich.edu
6034661Sksewell@umich.edu            temp = dspac - result;
6044661Sksewell@umich.edu
6055558Snate@binkert.org            if (signa == signb && bits(temp, 63, 63) != signa) {
6064661Sksewell@umich.edu                ouflag = 1;
6075558Snate@binkert.org                if (signa)
6084661Sksewell@umich.edu                    dspac = FIXED_SMIN[outfmt];
6094661Sksewell@umich.edu                else
6104661Sksewell@umich.edu                    dspac = FIXED_SMAX[outfmt];
6115558Snate@binkert.org            } else {
6125558Snate@binkert.org                dspac = temp;
6134661Sksewell@umich.edu            }
6145558Snate@binkert.org        } else {
6155558Snate@binkert.org            dspac = dspSaturate(dspac - result, outfmt, SIGNED, &ouflag);
6164661Sksewell@umich.edu        }
6175558Snate@binkert.org    } else {
6185558Snate@binkert.org        dspac -= result;
6194661Sksewell@umich.edu    }
6204661Sksewell@umich.edu
6215558Snate@binkert.org    if (ouflag)
6225558Snate@binkert.org        *dspctl = insertBits(*dspctl, 16 + ac, 16 + ac, 1);
6234661Sksewell@umich.edu
6245558Snate@binkert.org    return dspac;
6254661Sksewell@umich.edu}
6264661Sksewell@umich.edu
6274661Sksewell@umich.eduint64_t
6285558Snate@binkert.orgMipsISA::dspDpa(int64_t dspac, int32_t a, int32_t b, int32_t ac,
6295558Snate@binkert.org                int32_t fmt, int32_t sign, int32_t mode)
6304661Sksewell@umich.edu{
6314661Sksewell@umich.edu    int nvals = SIMD_NVALS[fmt];
6324661Sksewell@umich.edu    uint64_t a_values[SIMD_MAX_VALS];
6334661Sksewell@umich.edu    uint64_t b_values[SIMD_MAX_VALS];
6344661Sksewell@umich.edu
6355558Snate@binkert.org    simdUnpack(a, a_values, fmt, sign);
6365558Snate@binkert.org    simdUnpack(b, b_values, fmt, sign);
6374661Sksewell@umich.edu
6385558Snate@binkert.org    for (int i = 0; i < 2; i++) {
6395563Snate@binkert.org        switch (mode) {
6404661Sksewell@umich.edu          case MODE_L:
6415558Snate@binkert.org            dspac += a_values[nvals - 1 - i] * b_values[nvals - 1 - i];
6424661Sksewell@umich.edu            break;
6434661Sksewell@umich.edu          case MODE_R:
6445558Snate@binkert.org            dspac += a_values[nvals - 3 - i] * b_values[nvals - 3 - i];
6454661Sksewell@umich.edu            break;
6464661Sksewell@umich.edu          case MODE_X:
6475558Snate@binkert.org            dspac += a_values[nvals - 1 - i] * b_values[i];
6484661Sksewell@umich.edu            break;
6494661Sksewell@umich.edu        }
6504661Sksewell@umich.edu    }
6514661Sksewell@umich.edu
6524661Sksewell@umich.edu    return dspac;
6534661Sksewell@umich.edu}
6544661Sksewell@umich.edu
6554661Sksewell@umich.eduint64_t
6565558Snate@binkert.orgMipsISA::dspDps(int64_t dspac, int32_t a, int32_t b, int32_t ac,
6575558Snate@binkert.org                int32_t fmt, int32_t sign, int32_t mode)
6584661Sksewell@umich.edu{
6594661Sksewell@umich.edu    int nvals = SIMD_NVALS[fmt];
6604661Sksewell@umich.edu    uint64_t a_values[SIMD_MAX_VALS];
6614661Sksewell@umich.edu    uint64_t b_values[SIMD_MAX_VALS];
6624661Sksewell@umich.edu
6635558Snate@binkert.org    simdUnpack(a, a_values, fmt, sign);
6645558Snate@binkert.org    simdUnpack(b, b_values, fmt, sign);
6654661Sksewell@umich.edu
6665558Snate@binkert.org    for (int i = 0; i < 2; i++) {
6675563Snate@binkert.org        switch (mode) {
6684661Sksewell@umich.edu          case MODE_L:
6695558Snate@binkert.org            dspac -= a_values[nvals - 1 - i] * b_values[nvals - 1 - i];
6704661Sksewell@umich.edu            break;
6714661Sksewell@umich.edu          case MODE_R:
6725558Snate@binkert.org            dspac -= a_values[nvals - 3 - i] * b_values[nvals - 3 - i];
6734661Sksewell@umich.edu            break;
6744661Sksewell@umich.edu          case MODE_X:
6755558Snate@binkert.org            dspac -= a_values[nvals - 1 - i] * b_values[i];
6764661Sksewell@umich.edu            break;
6774661Sksewell@umich.edu        }
6784661Sksewell@umich.edu    }
6794661Sksewell@umich.edu
6804661Sksewell@umich.edu    return dspac;
6814661Sksewell@umich.edu}
6824661Sksewell@umich.edu
6834661Sksewell@umich.eduint64_t
6845558Snate@binkert.orgMipsISA::dspMaq(int64_t dspac, int32_t a, int32_t b, int32_t ac,
6855558Snate@binkert.org                 int32_t fmt, int32_t mode, int32_t saturate, uint32_t *dspctl)
6864661Sksewell@umich.edu{
6875558Snate@binkert.org    int nvals = SIMD_NVALS[fmt - 1];
6884661Sksewell@umich.edu    uint64_t a_values[SIMD_MAX_VALS];
6894661Sksewell@umich.edu    uint64_t b_values[SIMD_MAX_VALS];
6904661Sksewell@umich.edu    int64_t temp = 0;
6914661Sksewell@umich.edu    uint32_t ouflag = 0;
6924661Sksewell@umich.edu
6935558Snate@binkert.org    simdUnpack(a, a_values, fmt, SIGNED);
6945558Snate@binkert.org    simdUnpack(b, b_values, fmt, SIGNED);
6954661Sksewell@umich.edu
6965558Snate@binkert.org    for (int i = 0; i < nvals; i++) {
6975563Snate@binkert.org        switch (mode) {
6984661Sksewell@umich.edu          case MODE_L:
6995558Snate@binkert.org            temp = a_values[i + 1] * b_values[i + 1] << 1;
7005558Snate@binkert.org            if (a_values[i + 1] == FIXED_SMIN[fmt] &&
7015558Snate@binkert.org                b_values[i + 1] == FIXED_SMIN[fmt]) {
7025558Snate@binkert.org                temp = (int64_t)FIXED_SMAX[fmt - 1];
7034661Sksewell@umich.edu                ouflag = 1;
7044661Sksewell@umich.edu            }
7054661Sksewell@umich.edu            break;
7064661Sksewell@umich.edu          case MODE_R:
7074661Sksewell@umich.edu            temp = a_values[i] * b_values[i] << 1;
7085558Snate@binkert.org            if (a_values[i] == FIXED_SMIN[fmt] &&
7095558Snate@binkert.org                b_values[i] == FIXED_SMIN[fmt]) {
7105558Snate@binkert.org                temp = (int64_t)FIXED_SMAX[fmt - 1];
7114661Sksewell@umich.edu                ouflag = 1;
7124661Sksewell@umich.edu            }
7134661Sksewell@umich.edu            break;
7144661Sksewell@umich.edu        }
7154661Sksewell@umich.edu
7164661Sksewell@umich.edu        temp += dspac;
7174661Sksewell@umich.edu
7185558Snate@binkert.org        if (saturate)
7195558Snate@binkert.org            temp = dspSaturate(temp, fmt - 1, SIGNED, &ouflag);
7205558Snate@binkert.org        if (ouflag)
7215558Snate@binkert.org            *dspctl = insertBits(*dspctl, 16 + ac, 16 + ac, 1);
7224661Sksewell@umich.edu    }
7234661Sksewell@umich.edu
7244661Sksewell@umich.edu    return temp;
7254661Sksewell@umich.edu}
7264661Sksewell@umich.edu
7274661Sksewell@umich.eduint64_t
7285558Snate@binkert.orgMipsISA::dspMulsa(int64_t dspac, int32_t a, int32_t b, int32_t ac, int32_t fmt)
7294661Sksewell@umich.edu{
7304661Sksewell@umich.edu    uint64_t a_values[SIMD_MAX_VALS];
7314661Sksewell@umich.edu    uint64_t b_values[SIMD_MAX_VALS];
7324661Sksewell@umich.edu
7335558Snate@binkert.org    simdUnpack(a, a_values, fmt, SIGNED);
7345558Snate@binkert.org    simdUnpack(b, b_values, fmt, SIGNED);
7354661Sksewell@umich.edu
7364661Sksewell@umich.edu    dspac += a_values[1] * b_values[1] - a_values[0] * b_values[0];
7374661Sksewell@umich.edu
7384661Sksewell@umich.edu    return dspac;
7394661Sksewell@umich.edu}
7404661Sksewell@umich.edu
7414661Sksewell@umich.eduint64_t
7425558Snate@binkert.orgMipsISA::dspMulsaq(int64_t dspac, int32_t a, int32_t b, int32_t ac,
7435558Snate@binkert.org    int32_t fmt, uint32_t *dspctl)
7444661Sksewell@umich.edu{
7454661Sksewell@umich.edu    int nvals = SIMD_NVALS[fmt];
7464661Sksewell@umich.edu    uint64_t a_values[SIMD_MAX_VALS];
7474661Sksewell@umich.edu    uint64_t b_values[SIMD_MAX_VALS];
7486712Snate@binkert.org    int64_t temp[2] = {0, 0};
7494661Sksewell@umich.edu    uint32_t ouflag = 0;
7504661Sksewell@umich.edu
7515558Snate@binkert.org    simdUnpack(a, a_values, fmt, SIGNED);
7525558Snate@binkert.org    simdUnpack(b, b_values, fmt, SIGNED);
7534661Sksewell@umich.edu
7545558Snate@binkert.org    for (int i = nvals - 1; i > -1; i--) {
7554661Sksewell@umich.edu        temp[i] = a_values[i] * b_values[i] << 1;
7565558Snate@binkert.org        if (a_values[i] == FIXED_SMIN[fmt] && b_values[i] == FIXED_SMIN[fmt]) {
7575558Snate@binkert.org            temp[i] = FIXED_SMAX[fmt - 1];
7584661Sksewell@umich.edu            ouflag = 1;
7594661Sksewell@umich.edu        }
7604661Sksewell@umich.edu    }
7614661Sksewell@umich.edu
7624661Sksewell@umich.edu    dspac += temp[1] - temp[0];
7634661Sksewell@umich.edu
7645558Snate@binkert.org    if (ouflag)
7655558Snate@binkert.org        *dspctl = insertBits(*dspctl, 16 + ac, 16 + ac, 1);
7664661Sksewell@umich.edu
7674661Sksewell@umich.edu    return dspac;
7684661Sksewell@umich.edu}
7694661Sksewell@umich.edu
7704661Sksewell@umich.eduvoid
7715558Snate@binkert.orgMipsISA::dspCmp(int32_t a, int32_t b, int32_t fmt, int32_t sign, int32_t op,
7725558Snate@binkert.org    uint32_t *dspctl)
7734661Sksewell@umich.edu{
7744661Sksewell@umich.edu    int nvals = SIMD_NVALS[fmt];
7754661Sksewell@umich.edu    int ccond = 0;
7764661Sksewell@umich.edu    uint64_t a_values[SIMD_MAX_VALS];
7774661Sksewell@umich.edu    uint64_t b_values[SIMD_MAX_VALS];
7784661Sksewell@umich.edu
7795558Snate@binkert.org    simdUnpack(a, a_values, fmt, sign);
7805558Snate@binkert.org    simdUnpack(b, b_values, fmt, sign);
7814661Sksewell@umich.edu
7825558Snate@binkert.org    for (int i = 0; i < nvals; i++) {
7834661Sksewell@umich.edu        int cc = 0;
7844661Sksewell@umich.edu
7855563Snate@binkert.org        switch (op) {
7865558Snate@binkert.org          case CMP_EQ:
7875558Snate@binkert.org            cc = (a_values[i] == b_values[i]);
7885558Snate@binkert.org            break;
7895558Snate@binkert.org          case CMP_LT:
7905558Snate@binkert.org            cc = (a_values[i] < b_values[i]);
7915558Snate@binkert.org            break;
7925558Snate@binkert.org          case CMP_LE:
7935558Snate@binkert.org            cc = (a_values[i] <= b_values[i]);
7945558Snate@binkert.org            break;
7954661Sksewell@umich.edu        }
7964661Sksewell@umich.edu
7975558Snate@binkert.org        ccond |= cc << (DSP_CTL_POS[DSP_CCOND] + i);
7984661Sksewell@umich.edu    }
7994661Sksewell@umich.edu
8005558Snate@binkert.org    writeDSPControl(dspctl, ccond, 1 << DSP_CCOND);
8014661Sksewell@umich.edu}
8024661Sksewell@umich.edu
8034661Sksewell@umich.eduint32_t
8045558Snate@binkert.orgMipsISA::dspCmpg(int32_t a, int32_t b, int32_t fmt, int32_t sign, int32_t op)
8054661Sksewell@umich.edu{
8064661Sksewell@umich.edu    int nvals = SIMD_NVALS[fmt];
8074661Sksewell@umich.edu    int32_t result = 0;
8084661Sksewell@umich.edu    uint64_t a_values[SIMD_MAX_VALS];
8094661Sksewell@umich.edu    uint64_t b_values[SIMD_MAX_VALS];
8104661Sksewell@umich.edu
8115558Snate@binkert.org    simdUnpack(a, a_values, fmt, sign);
8125558Snate@binkert.org    simdUnpack(b, b_values, fmt, sign);
8134661Sksewell@umich.edu
8145558Snate@binkert.org    for (int i = 0; i < nvals; i++) {
8154661Sksewell@umich.edu        int cc = 0;
8164661Sksewell@umich.edu
8175563Snate@binkert.org        switch (op) {
8185558Snate@binkert.org          case CMP_EQ:
8195558Snate@binkert.org            cc = (a_values[i] == b_values[i]);
8205558Snate@binkert.org            break;
8215558Snate@binkert.org          case CMP_LT:
8225558Snate@binkert.org            cc = (a_values[i] < b_values[i]);
8235558Snate@binkert.org            break;
8245558Snate@binkert.org          case CMP_LE:
8255558Snate@binkert.org            cc = (a_values[i] <= b_values[i]);
8265558Snate@binkert.org            break;
8274661Sksewell@umich.edu        }
8284661Sksewell@umich.edu
8294661Sksewell@umich.edu        result |= cc << i;
8304661Sksewell@umich.edu    }
8314661Sksewell@umich.edu
8325558Snate@binkert.org    return result;
8334661Sksewell@umich.edu}
8344661Sksewell@umich.edu
8354661Sksewell@umich.eduint32_t
8365558Snate@binkert.orgMipsISA::dspCmpgd(int32_t a, int32_t b, int32_t fmt, int32_t sign, int32_t op,
8375558Snate@binkert.org    uint32_t *dspctl)
8384661Sksewell@umich.edu{
8394661Sksewell@umich.edu    int nvals = SIMD_NVALS[fmt];
8404661Sksewell@umich.edu    int32_t result = 0;
8414661Sksewell@umich.edu    int ccond = 0;
8424661Sksewell@umich.edu    uint64_t a_values[SIMD_MAX_VALS];
8434661Sksewell@umich.edu    uint64_t b_values[SIMD_MAX_VALS];
8444661Sksewell@umich.edu
8455558Snate@binkert.org    simdUnpack(a, a_values, fmt, sign);
8465558Snate@binkert.org    simdUnpack(b, b_values, fmt, sign);
8474661Sksewell@umich.edu
8485558Snate@binkert.org    for (int i = 0; i < nvals; i++) {
8495558Snate@binkert.org        int cc = 0;
8504661Sksewell@umich.edu
8515563Snate@binkert.org        switch (op) {
8525558Snate@binkert.org          case CMP_EQ:
8535558Snate@binkert.org            cc = (a_values[i] == b_values[i]);
8545558Snate@binkert.org            break;
8555558Snate@binkert.org          case CMP_LT:
8565558Snate@binkert.org            cc = (a_values[i] < b_values[i]);
8575558Snate@binkert.org            break;
8585558Snate@binkert.org          case CMP_LE:
8595558Snate@binkert.org            cc = (a_values[i] <= b_values[i]);
8605558Snate@binkert.org            break;
8614661Sksewell@umich.edu        }
8624661Sksewell@umich.edu
8634661Sksewell@umich.edu        result |= cc << i;
8645558Snate@binkert.org        ccond |= cc << (DSP_CTL_POS[DSP_CCOND] + i);
8654661Sksewell@umich.edu    }
8664661Sksewell@umich.edu
8675558Snate@binkert.org    writeDSPControl(dspctl, ccond, 1 << DSP_CCOND);
8684661Sksewell@umich.edu
8695558Snate@binkert.org    return result;
8704661Sksewell@umich.edu}
8714661Sksewell@umich.edu
8724661Sksewell@umich.eduint32_t
8735558Snate@binkert.orgMipsISA::dspPrece(int32_t a, int32_t infmt, int32_t insign, int32_t outfmt,
8745558Snate@binkert.org    int32_t outsign, int32_t mode)
8754661Sksewell@umich.edu{
8764661Sksewell@umich.edu    int sa = 0;
8774661Sksewell@umich.edu    int ninvals = SIMD_NVALS[infmt];
8784661Sksewell@umich.edu    int noutvals = SIMD_NVALS[outfmt];
8794661Sksewell@umich.edu    int32_t result;
8804661Sksewell@umich.edu    uint64_t in_values[SIMD_MAX_VALS];
8814661Sksewell@umich.edu    uint64_t out_values[SIMD_MAX_VALS];
8824661Sksewell@umich.edu
8835558Snate@binkert.org    if (insign == SIGNED && outsign == SIGNED)
8844661Sksewell@umich.edu      sa = SIMD_NBITS[infmt];
8855558Snate@binkert.org    else if (insign == UNSIGNED && outsign == SIGNED)
8864661Sksewell@umich.edu      sa = SIMD_NBITS[infmt] - 1;
8875558Snate@binkert.org    else if (insign == UNSIGNED && outsign == UNSIGNED)
8884661Sksewell@umich.edu      sa = 0;
8894661Sksewell@umich.edu
8905558Snate@binkert.org    simdUnpack(a, in_values, infmt, insign);
8914661Sksewell@umich.edu
8925558Snate@binkert.org    for (int i = 0; i<noutvals; i++) {
8935563Snate@binkert.org        switch (mode) {
8945558Snate@binkert.org          case MODE_L:
8955558Snate@binkert.org            out_values[i] = in_values[i + (ninvals >> 1)] << sa;
8965558Snate@binkert.org            break;
8975558Snate@binkert.org          case MODE_R:
8985558Snate@binkert.org            out_values[i] = in_values[i] << sa;
8995558Snate@binkert.org            break;
9005558Snate@binkert.org          case MODE_LA:
9015558Snate@binkert.org            out_values[i] = in_values[(i << 1) + 1] << sa;
9025558Snate@binkert.org            break;
9035558Snate@binkert.org          case MODE_RA:
9045558Snate@binkert.org            out_values[i] = in_values[i << 1] << sa;
9055558Snate@binkert.org            break;
9064661Sksewell@umich.edu        }
9074661Sksewell@umich.edu    }
9084661Sksewell@umich.edu
9095558Snate@binkert.org    simdPack(out_values, &result, outfmt);
9104661Sksewell@umich.edu
9115558Snate@binkert.org    return result;
9124661Sksewell@umich.edu}
9134661Sksewell@umich.edu
9144661Sksewell@umich.eduint32_t
9155558Snate@binkert.orgMipsISA::dspPrecrqu(int32_t a, int32_t b, uint32_t *dspctl)
9164661Sksewell@umich.edu{
9174661Sksewell@umich.edu    uint64_t a_values[SIMD_MAX_VALS];
9184661Sksewell@umich.edu    uint64_t b_values[SIMD_MAX_VALS];
9194661Sksewell@umich.edu    uint64_t r_values[SIMD_MAX_VALS];
9204661Sksewell@umich.edu    uint32_t ouflag = 0;
9214661Sksewell@umich.edu    int32_t result = 0;
9224661Sksewell@umich.edu
9235558Snate@binkert.org    simdUnpack(a, a_values, SIMD_FMT_PH, SIGNED);
9245558Snate@binkert.org    simdUnpack(b, b_values, SIMD_FMT_PH, SIGNED);
9254661Sksewell@umich.edu
9265558Snate@binkert.org    for (int i = 0; i<2; i++) {
9275558Snate@binkert.org        r_values[i] =
9285570Snate@binkert.org            dspSaturate((int64_t)b_values[i] >> (SIMD_NBITS[SIMD_FMT_QB] - 1),
9295558Snate@binkert.org                        SIMD_FMT_QB, UNSIGNED, &ouflag);
9305558Snate@binkert.org        r_values[i + 2] =
9315570Snate@binkert.org            dspSaturate((int64_t)a_values[i] >> (SIMD_NBITS[SIMD_FMT_QB] - 1),
9325558Snate@binkert.org                        SIMD_FMT_QB, UNSIGNED, &ouflag);
9334661Sksewell@umich.edu    }
9344661Sksewell@umich.edu
9355558Snate@binkert.org    simdPack(r_values, &result, SIMD_FMT_QB);
9364661Sksewell@umich.edu
9375558Snate@binkert.org    if (ouflag)
9385558Snate@binkert.org        *dspctl = insertBits(*dspctl, 22, 22, 1);
9394661Sksewell@umich.edu
9404661Sksewell@umich.edu    return result;
9414661Sksewell@umich.edu}
9424661Sksewell@umich.edu
9434661Sksewell@umich.eduint32_t
9445558Snate@binkert.orgMipsISA::dspPrecrq(int32_t a, int32_t b, int32_t fmt, uint32_t *dspctl)
9454661Sksewell@umich.edu{
9464661Sksewell@umich.edu    uint64_t a_values[SIMD_MAX_VALS];
9474661Sksewell@umich.edu    uint64_t b_values[SIMD_MAX_VALS];
9484661Sksewell@umich.edu    uint64_t r_values[SIMD_MAX_VALS];
9494661Sksewell@umich.edu    uint32_t ouflag = 0;
9504661Sksewell@umich.edu    int32_t result;
9514661Sksewell@umich.edu
9525558Snate@binkert.org    simdUnpack(a, a_values, fmt, SIGNED);
9535558Snate@binkert.org    simdUnpack(b, b_values, fmt, SIGNED);
9544661Sksewell@umich.edu
9555558Snate@binkert.org    r_values[1] = dspSaturate((int64_t)addHalfLsb(a_values[0], 16) >> 16,
9565558Snate@binkert.org                              fmt + 1, SIGNED, &ouflag);
9575558Snate@binkert.org    r_values[0] = dspSaturate((int64_t)addHalfLsb(b_values[0], 16) >> 16,
9585558Snate@binkert.org                              fmt + 1, SIGNED, &ouflag);
9594661Sksewell@umich.edu
9605558Snate@binkert.org    simdPack(r_values, &result, fmt + 1);
9614661Sksewell@umich.edu
9625558Snate@binkert.org    if (ouflag)
9635558Snate@binkert.org        *dspctl = insertBits(*dspctl, 22, 22, 1);
9644661Sksewell@umich.edu
9654661Sksewell@umich.edu    return result;
9664661Sksewell@umich.edu}
9674661Sksewell@umich.edu
9684661Sksewell@umich.eduint32_t
9695558Snate@binkert.orgMipsISA::dspPrecrSra(int32_t a, int32_t b, int32_t sa, int32_t fmt,
9705558Snate@binkert.org    int32_t round)
9714661Sksewell@umich.edu{
9724661Sksewell@umich.edu    int nvals = SIMD_NVALS[fmt];
9734661Sksewell@umich.edu    uint64_t a_values[SIMD_MAX_VALS];
9744661Sksewell@umich.edu    uint64_t b_values[SIMD_MAX_VALS];
9754661Sksewell@umich.edu    uint64_t c_values[SIMD_MAX_VALS];
9764661Sksewell@umich.edu    int32_t result = 0;
9774661Sksewell@umich.edu
9785558Snate@binkert.org    simdUnpack(a, a_values, fmt, SIGNED);
9795558Snate@binkert.org    simdUnpack(b, b_values, fmt, SIGNED);
9804661Sksewell@umich.edu
9815558Snate@binkert.org    for (int i = 0; i < nvals; i++) {
9825558Snate@binkert.org        if (round) {
9835558Snate@binkert.org            c_values[i] = addHalfLsb(b_values[i], sa) >> sa;
9845558Snate@binkert.org            c_values[i + 1] = addHalfLsb(a_values[i], sa) >> sa;
9855558Snate@binkert.org        } else {
9864661Sksewell@umich.edu            c_values[i] = b_values[i] >> sa;
9875558Snate@binkert.org            c_values[i + 1] = a_values[i] >> sa;
9884661Sksewell@umich.edu        }
9894661Sksewell@umich.edu    }
9904661Sksewell@umich.edu
9915558Snate@binkert.org    simdPack(c_values, &result, fmt + 1);
9924661Sksewell@umich.edu
9934661Sksewell@umich.edu    return result;
9944661Sksewell@umich.edu}
9954661Sksewell@umich.edu
9964661Sksewell@umich.eduint32_t
9975558Snate@binkert.orgMipsISA::dspPick(int32_t a, int32_t b, int32_t fmt, uint32_t *dspctl)
9984661Sksewell@umich.edu{
9994661Sksewell@umich.edu    int nvals = SIMD_NVALS[fmt];
10004661Sksewell@umich.edu    int32_t result;
10014661Sksewell@umich.edu    uint64_t a_values[SIMD_MAX_VALS];
10024661Sksewell@umich.edu    uint64_t b_values[SIMD_MAX_VALS];
10034661Sksewell@umich.edu    uint64_t c_values[SIMD_MAX_VALS];
10044661Sksewell@umich.edu
10055558Snate@binkert.org    simdUnpack(a, a_values, fmt, UNSIGNED);
10065558Snate@binkert.org    simdUnpack(b, b_values, fmt, UNSIGNED);
10074661Sksewell@umich.edu
10085558Snate@binkert.org    for (int i = 0; i < nvals; i++) {
10094661Sksewell@umich.edu        int condbit = DSP_CTL_POS[DSP_CCOND] + i;
10105558Snate@binkert.org        if (bits(*dspctl, condbit, condbit) == 1)
10114661Sksewell@umich.edu            c_values[i] = a_values[i];
10124661Sksewell@umich.edu        else
10134661Sksewell@umich.edu            c_values[i] = b_values[i];
10144661Sksewell@umich.edu    }
10154661Sksewell@umich.edu
10165558Snate@binkert.org    simdPack(c_values, &result, fmt);
10174661Sksewell@umich.edu
10185558Snate@binkert.org    return result;
10194661Sksewell@umich.edu}
10204661Sksewell@umich.edu
10214661Sksewell@umich.eduint32_t
10225558Snate@binkert.orgMipsISA::dspPack(int32_t a, int32_t b, int32_t fmt)
10234661Sksewell@umich.edu{
10244661Sksewell@umich.edu    int32_t result;
10254661Sksewell@umich.edu    uint64_t a_values[SIMD_MAX_VALS];
10264661Sksewell@umich.edu    uint64_t b_values[SIMD_MAX_VALS];
10274661Sksewell@umich.edu    uint64_t c_values[SIMD_MAX_VALS];
10284661Sksewell@umich.edu
10295558Snate@binkert.org    simdUnpack(a, a_values, fmt, UNSIGNED);
10305558Snate@binkert.org    simdUnpack(b, b_values, fmt, UNSIGNED);
10314661Sksewell@umich.edu
10324661Sksewell@umich.edu    c_values[0] = b_values[1];
10334661Sksewell@umich.edu    c_values[1] = a_values[0];
10344661Sksewell@umich.edu
10355558Snate@binkert.org    simdPack(c_values, &result, fmt);
10364661Sksewell@umich.edu
10375558Snate@binkert.org    return result;
10384661Sksewell@umich.edu}
10394661Sksewell@umich.edu
10404661Sksewell@umich.eduint32_t
10415558Snate@binkert.orgMipsISA::dspExtr(int64_t dspac, int32_t fmt, int32_t sa, int32_t round,
10425558Snate@binkert.org    int32_t saturate, uint32_t *dspctl)
10434661Sksewell@umich.edu{
10444661Sksewell@umich.edu    int32_t result = 0;
10454661Sksewell@umich.edu    uint32_t ouflag = 0;
10464661Sksewell@umich.edu    int64_t temp = 0;
10474661Sksewell@umich.edu
10485558Snate@binkert.org    sa = bits(sa, 4, 0);
10494661Sksewell@umich.edu
10505558Snate@binkert.org    if (sa > 0) {
10515558Snate@binkert.org        if (round) {
10525558Snate@binkert.org            temp = (int64_t)addHalfLsb(dspac, sa);
10534661Sksewell@umich.edu
10545558Snate@binkert.org            if (dspac > 0 && temp < 0) {
10554661Sksewell@umich.edu                ouflag = 1;
10565558Snate@binkert.org                if (saturate)
10574661Sksewell@umich.edu                    temp = FIXED_SMAX[SIMD_FMT_L];
10584661Sksewell@umich.edu            }
10594661Sksewell@umich.edu            temp = temp >> sa;
10605558Snate@binkert.org        } else {
10615558Snate@binkert.org            temp = dspac >> sa;
10624661Sksewell@umich.edu        }
10635558Snate@binkert.org    } else {
10645558Snate@binkert.org        temp = dspac;
10654661Sksewell@umich.edu    }
10664661Sksewell@umich.edu
10675558Snate@binkert.org    dspac = checkOverflow(dspac, fmt, SIGNED, &ouflag);
10684661Sksewell@umich.edu
10695558Snate@binkert.org    if (ouflag) {
10705558Snate@binkert.org        *dspctl = insertBits(*dspctl, 23, 23, ouflag);
10714661Sksewell@umich.edu
10725558Snate@binkert.org        if (saturate)
10735558Snate@binkert.org            result = (int32_t)dspSaturate(temp, fmt, SIGNED, &ouflag);
10744661Sksewell@umich.edu        else
10754661Sksewell@umich.edu            result = (int32_t)temp;
10765558Snate@binkert.org    } else {
10775558Snate@binkert.org        result = (int32_t)temp;
10784661Sksewell@umich.edu    }
10794661Sksewell@umich.edu
10805558Snate@binkert.org    return result;
10814661Sksewell@umich.edu}
10824661Sksewell@umich.edu
10834661Sksewell@umich.eduint32_t
10845558Snate@binkert.orgMipsISA::dspExtp(int64_t dspac, int32_t size, uint32_t *dspctl)
10854661Sksewell@umich.edu{
10864661Sksewell@umich.edu    int32_t pos = 0;
10874661Sksewell@umich.edu    int32_t result = 0;
10884661Sksewell@umich.edu
10895558Snate@binkert.org    pos = bits(*dspctl, 5, 0);
10905558Snate@binkert.org    size = bits(size, 4, 0);
10914661Sksewell@umich.edu
10925558Snate@binkert.org    if (pos - (size + 1) >= -1) {
10935558Snate@binkert.org        result = bits(dspac, pos, pos - size);
10945558Snate@binkert.org        *dspctl = insertBits(*dspctl, 14, 14, 0);
10955558Snate@binkert.org    } else {
10964661Sksewell@umich.edu        result = 0;
10975558Snate@binkert.org        *dspctl = insertBits(*dspctl, 14, 14, 1);
10984661Sksewell@umich.edu    }
10994661Sksewell@umich.edu
11005558Snate@binkert.org    return result;
11014661Sksewell@umich.edu}
11024661Sksewell@umich.edu
11034661Sksewell@umich.eduint32_t
11045558Snate@binkert.orgMipsISA::dspExtpd(int64_t dspac, int32_t size, uint32_t *dspctl)
11054661Sksewell@umich.edu{
11064661Sksewell@umich.edu    int32_t pos = 0;
11074661Sksewell@umich.edu    int32_t result = 0;
11084661Sksewell@umich.edu
11095558Snate@binkert.org    pos = bits(*dspctl, 5, 0);
11105558Snate@binkert.org    size = bits(size, 4, 0);
11114661Sksewell@umich.edu
11125558Snate@binkert.org    if (pos - (size + 1) >= -1) {
11135558Snate@binkert.org        result = bits(dspac, pos, pos - size);
11145558Snate@binkert.org        *dspctl = insertBits(*dspctl, 14, 14, 0);
11155558Snate@binkert.org        if (pos - (size + 1) >= 0)
11165558Snate@binkert.org            *dspctl = insertBits(*dspctl, 5, 0, pos - (size + 1));
11175558Snate@binkert.org        else if ((pos - (size + 1)) == -1)
11185558Snate@binkert.org            *dspctl = insertBits(*dspctl, 5, 0, 63);
11195558Snate@binkert.org    } else {
11204661Sksewell@umich.edu        result = 0;
11215558Snate@binkert.org        *dspctl = insertBits(*dspctl, 14, 14, 1);
11224661Sksewell@umich.edu    }
11234661Sksewell@umich.edu
11245558Snate@binkert.org    return result;
11254661Sksewell@umich.edu}
11264661Sksewell@umich.edu
11274661Sksewell@umich.eduvoid
11285558Snate@binkert.orgMipsISA::simdPack(uint64_t *values_ptr, int32_t *reg, int32_t fmt)
11294661Sksewell@umich.edu{
11304661Sksewell@umich.edu    int nvals = SIMD_NVALS[fmt];
11314661Sksewell@umich.edu    int nbits = SIMD_NBITS[fmt];
11324661Sksewell@umich.edu
11334661Sksewell@umich.edu    *reg = 0;
11344661Sksewell@umich.edu
11355558Snate@binkert.org    for (int i = 0; i < nvals; i++)
11365558Snate@binkert.org        *reg |= (int32_t)bits(values_ptr[i], nbits - 1, 0) << nbits * i;
11374661Sksewell@umich.edu}
11384661Sksewell@umich.edu
11394661Sksewell@umich.eduvoid
11405558Snate@binkert.orgMipsISA::simdUnpack(int32_t reg, uint64_t *values_ptr, int32_t fmt, int32_t sign)
11414661Sksewell@umich.edu{
11424661Sksewell@umich.edu    int nvals = SIMD_NVALS[fmt];
11434661Sksewell@umich.edu    int nbits = SIMD_NBITS[fmt];
11444661Sksewell@umich.edu
11455563Snate@binkert.org    switch (sign) {
11465558Snate@binkert.org      case SIGNED:
11475558Snate@binkert.org        for (int i = 0; i < nvals; i++) {
11485558Snate@binkert.org            uint64_t tmp = (uint64_t)bits(reg, nbits * (i + 1) - 1, nbits * i);
11495558Snate@binkert.org            values_ptr[i] = signExtend(tmp, fmt);
11504661Sksewell@umich.edu        }
11514661Sksewell@umich.edu        break;
11525558Snate@binkert.org      case UNSIGNED:
11535558Snate@binkert.org        for (int i = 0; i < nvals; i++) {
11545558Snate@binkert.org            values_ptr[i] =
11555558Snate@binkert.org                (uint64_t)bits(reg, nbits * (i + 1) - 1, nbits * i);
11564661Sksewell@umich.edu        }
11574661Sksewell@umich.edu        break;
11584661Sksewell@umich.edu    }
11594661Sksewell@umich.edu}
11604661Sksewell@umich.edu
11614661Sksewell@umich.eduvoid
11625558Snate@binkert.orgMipsISA::writeDSPControl(uint32_t *dspctl, uint32_t value, uint32_t mask)
11634661Sksewell@umich.edu{
11644661Sksewell@umich.edu    uint32_t fmask = 0;
11654661Sksewell@umich.edu
11665558Snate@binkert.org    if (mask & 0x01) fmask |= DSP_CTL_MASK[DSP_POS];
11675558Snate@binkert.org    if (mask & 0x02) fmask |= DSP_CTL_MASK[DSP_SCOUNT];
11685558Snate@binkert.org    if (mask & 0x04) fmask |= DSP_CTL_MASK[DSP_C];
11695558Snate@binkert.org    if (mask & 0x08) fmask |= DSP_CTL_MASK[DSP_OUFLAG];
11705558Snate@binkert.org    if (mask & 0x10) fmask |= DSP_CTL_MASK[DSP_CCOND];
11715558Snate@binkert.org    if (mask & 0x20) fmask |= DSP_CTL_MASK[DSP_EFI];
11724661Sksewell@umich.edu
11734661Sksewell@umich.edu    *dspctl &= ~fmask;
11744661Sksewell@umich.edu    value &= fmask;
11754661Sksewell@umich.edu    *dspctl |= value;
11764661Sksewell@umich.edu}
11774661Sksewell@umich.edu
11784661Sksewell@umich.eduuint32_t
11795558Snate@binkert.orgMipsISA::readDSPControl(uint32_t *dspctl, uint32_t mask)
11804661Sksewell@umich.edu{
11814661Sksewell@umich.edu    uint32_t fmask = 0;
11824661Sksewell@umich.edu
11835558Snate@binkert.org    if (mask & 0x01) fmask |= DSP_CTL_MASK[DSP_POS];
11845558Snate@binkert.org    if (mask & 0x02) fmask |= DSP_CTL_MASK[DSP_SCOUNT];
11855558Snate@binkert.org    if (mask & 0x04) fmask |= DSP_CTL_MASK[DSP_C];
11865558Snate@binkert.org    if (mask & 0x08) fmask |= DSP_CTL_MASK[DSP_OUFLAG];
11875558Snate@binkert.org    if (mask & 0x10) fmask |= DSP_CTL_MASK[DSP_CCOND];
11885558Snate@binkert.org    if (mask & 0x20) fmask |= DSP_CTL_MASK[DSP_EFI];
11894661Sksewell@umich.edu
11905558Snate@binkert.org    return *dspctl & fmask;
11914661Sksewell@umich.edu}
1192