14661Sksewell@umich.edu/*
25268Sksewell@umich.edu * Copyright (c) 2007 MIPS Technologies, Inc.
35268Sksewell@umich.edu * All rights reserved.
44661Sksewell@umich.edu *
55268Sksewell@umich.edu * Redistribution and use in source and binary forms, with or without
65268Sksewell@umich.edu * modification, are permitted provided that the following conditions are
75268Sksewell@umich.edu * met: redistributions of source code must retain the above copyright
85268Sksewell@umich.edu * notice, this list of conditions and the following disclaimer;
95268Sksewell@umich.edu * redistributions in binary form must reproduce the above copyright
105268Sksewell@umich.edu * notice, this list of conditions and the following disclaimer in the
115268Sksewell@umich.edu * documentation and/or other materials provided with the distribution;
125268Sksewell@umich.edu * neither the name of the copyright holders nor the names of its
135268Sksewell@umich.edu * contributors may be used to endorse or promote products derived from
145268Sksewell@umich.edu * this software without specific prior written permission.
154661Sksewell@umich.edu *
165268Sksewell@umich.edu * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
175268Sksewell@umich.edu * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
185268Sksewell@umich.edu * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
195268Sksewell@umich.edu * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
205268Sksewell@umich.edu * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
215268Sksewell@umich.edu * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
225268Sksewell@umich.edu * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
235268Sksewell@umich.edu * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
245268Sksewell@umich.edu * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
255268Sksewell@umich.edu * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
265268Sksewell@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#ifndef __ARCH_MIPS_DSP_HH__
324661Sksewell@umich.edu#define __ARCH_MIPS_DSP_HH__
334661Sksewell@umich.edu
348229Snate@binkert.org#include "arch/mips/isa_traits.hh"
354661Sksewell@umich.edu#include "arch/mips/types.hh"
3612334Sgabeblack@google.com#include "base/logging.hh"
376216Snate@binkert.org#include "base/types.hh"
384661Sksewell@umich.edu
394661Sksewell@umich.educlass ThreadContext;
404661Sksewell@umich.edu
414661Sksewell@umich.edunamespace MipsISA {
424661Sksewell@umich.edu
435558Snate@binkert.org// SIMD formats
445558Snate@binkert.orgenum {
455558Snate@binkert.org    SIMD_FMT_L,    // long word
465558Snate@binkert.org    SIMD_FMT_W,    // word
475558Snate@binkert.org    SIMD_FMT_PH,   // paired halfword
485558Snate@binkert.org    SIMD_FMT_QB,   // quad byte
495558Snate@binkert.org    SIMD_NUM_FMTS
504661Sksewell@umich.edu};
514661Sksewell@umich.edu
525558Snate@binkert.org// DSPControl Fields
535558Snate@binkert.orgenum {
545558Snate@binkert.org    DSP_POS,       // insertion bitfield position
555558Snate@binkert.org    DSP_SCOUNT,    // insertion bitfield size
565558Snate@binkert.org    DSP_C,         // carry bit
575558Snate@binkert.org    DSP_OUFLAG,    // overflow-underflow flag
585558Snate@binkert.org    DSP_CCOND,     // condition code
595558Snate@binkert.org    DSP_EFI,       // extract fail indicator bit
605558Snate@binkert.org    DSP_NUM_FIELDS
615558Snate@binkert.org};
625558Snate@binkert.org
635558Snate@binkert.org// compare instruction operations
645558Snate@binkert.orgenum {
655558Snate@binkert.org    CMP_EQ,        // equal
665558Snate@binkert.org    CMP_LT,        // less than
675558Snate@binkert.org    CMP_LE         // less than or equal
685558Snate@binkert.org};
695558Snate@binkert.org
705558Snate@binkert.org// SIMD operation order modes
715558Snate@binkert.orgenum {
725558Snate@binkert.org    MODE_L,        // left
735558Snate@binkert.org    MODE_R,        // right
745558Snate@binkert.org    MODE_LA,       // left-alternate
755558Snate@binkert.org    MODE_RA,       // right-alternate
765558Snate@binkert.org    MODE_X         // cross
775558Snate@binkert.org};
785558Snate@binkert.org
795558Snate@binkert.org// dsp operation parameters
805558Snate@binkert.orgenum { UNSIGNED, SIGNED };
815558Snate@binkert.orgenum { NOSATURATE, SATURATE };
825558Snate@binkert.orgenum { NOROUND, ROUND };
835558Snate@binkert.org
845558Snate@binkert.org// DSPControl field positions and masks
855558Snate@binkert.orgconst uint32_t DSP_CTL_POS[DSP_NUM_FIELDS] = { 0, 7, 13, 16, 24, 14 };
865558Snate@binkert.orgconst uint32_t DSP_CTL_MASK[DSP_NUM_FIELDS] =
875558Snate@binkert.org{ 0x0000003f, 0x00001f80, 0x00002000,
885558Snate@binkert.org  0x00ff0000, 0x0f000000, 0x00004000 };
895558Snate@binkert.org
905558Snate@binkert.org/*
915558Snate@binkert.org * SIMD format constants
925558Snate@binkert.org */
935558Snate@binkert.org
945558Snate@binkert.org// maximum values per register
955558Snate@binkert.orgconst uint32_t SIMD_MAX_VALS = 4;
965558Snate@binkert.org// number of values in fmt
975558Snate@binkert.orgconst uint32_t SIMD_NVALS[SIMD_NUM_FMTS] = { 1, 1, 2, 4 };
985558Snate@binkert.org// number of bits per value
995558Snate@binkert.orgconst uint32_t SIMD_NBITS[SIMD_NUM_FMTS] = { 64, 32, 16, 8 };
1005558Snate@binkert.org// log2(bits per value)
1015558Snate@binkert.orgconst uint32_t SIMD_LOG2N[SIMD_NUM_FMTS] = { 6, 5, 4, 3 };
1025558Snate@binkert.org
1035558Snate@binkert.org
1045558Snate@binkert.org// DSP maximum values
1055558Snate@binkert.orgconst uint64_t FIXED_L_SMAX = ULL(0x7fffffffffffffff);
1065558Snate@binkert.orgconst uint64_t FIXED_W_SMAX = ULL(0x000000007fffffff);
1075558Snate@binkert.orgconst uint64_t FIXED_H_SMAX = ULL(0x0000000000007fff);
1085558Snate@binkert.orgconst uint64_t FIXED_B_SMAX = ULL(0x000000000000007f);
1095558Snate@binkert.orgconst uint64_t FIXED_L_UMAX = ULL(0xffffffffffffffff);
1105558Snate@binkert.orgconst uint64_t FIXED_W_UMAX = ULL(0x00000000ffffffff);
1115558Snate@binkert.orgconst uint64_t FIXED_H_UMAX = ULL(0x000000000000ffff);
1125558Snate@binkert.orgconst uint64_t FIXED_B_UMAX = ULL(0x00000000000000ff);
1135558Snate@binkert.orgconst uint64_t FIXED_SMAX[SIMD_NUM_FMTS] =
1145558Snate@binkert.org{ FIXED_L_SMAX, FIXED_W_SMAX, FIXED_H_SMAX, FIXED_B_SMAX };
1155558Snate@binkert.orgconst uint64_t FIXED_UMAX[SIMD_NUM_FMTS] =
1165558Snate@binkert.org{ FIXED_L_UMAX, FIXED_W_UMAX, FIXED_H_UMAX, FIXED_B_UMAX };
1175558Snate@binkert.org
1185558Snate@binkert.org// DSP minimum values
1195558Snate@binkert.orgconst uint64_t FIXED_L_SMIN = ULL(0x8000000000000000);
1205558Snate@binkert.orgconst uint64_t FIXED_W_SMIN = ULL(0xffffffff80000000);
1215558Snate@binkert.orgconst uint64_t FIXED_H_SMIN = ULL(0xffffffffffff8000);
1225558Snate@binkert.orgconst uint64_t FIXED_B_SMIN = ULL(0xffffffffffffff80);
1235558Snate@binkert.orgconst uint64_t FIXED_L_UMIN = ULL(0x0000000000000000);
1245558Snate@binkert.orgconst uint64_t FIXED_W_UMIN = ULL(0x0000000000000000);
1255558Snate@binkert.orgconst uint64_t FIXED_H_UMIN = ULL(0x0000000000000000);
1265558Snate@binkert.orgconst uint64_t FIXED_B_UMIN = ULL(0x0000000000000000);
1275558Snate@binkert.orgconst uint64_t FIXED_SMIN[SIMD_NUM_FMTS] =
1285558Snate@binkert.org{ FIXED_L_SMIN, FIXED_W_SMIN, FIXED_H_SMIN, FIXED_B_SMIN };
1295558Snate@binkert.orgconst uint64_t FIXED_UMIN[SIMD_NUM_FMTS] =
1305558Snate@binkert.org{ FIXED_L_UMIN, FIXED_W_UMIN, FIXED_H_UMIN, FIXED_B_UMIN };
1315558Snate@binkert.org
1325558Snate@binkert.org// DSP utility functions
1335558Snate@binkert.orgint32_t bitrev(int32_t value);
1345558Snate@binkert.orguint64_t dspSaturate(uint64_t value, int32_t fmt, int32_t sign,
1355558Snate@binkert.org                     uint32_t *overflow);
1365558Snate@binkert.orguint64_t checkOverflow(uint64_t value, int32_t fmt, int32_t sign,
1375558Snate@binkert.org                       uint32_t *overflow);
1385558Snate@binkert.orguint64_t signExtend(uint64_t value, int32_t signpos);
1395558Snate@binkert.orguint64_t addHalfLsb(uint64_t value, int32_t lsbpos);
1405558Snate@binkert.orgint32_t dspAbs(int32_t a, int32_t fmt, uint32_t *dspctl);
1415558Snate@binkert.orgint32_t dspAdd(int32_t a, int32_t b, int32_t fmt, int32_t saturate,
1425558Snate@binkert.org               int32_t sign, uint32_t *dspctl);
1435558Snate@binkert.orgint32_t dspAddh(int32_t a, int32_t b, int32_t fmt, int32_t round,
1445558Snate@binkert.org                int32_t sign);
1455558Snate@binkert.orgint32_t dspSub(int32_t a, int32_t b, int32_t fmt, int32_t saturate,
1465558Snate@binkert.org               int32_t sign, uint32_t *dspctl);
1475558Snate@binkert.orgint32_t dspSubh(int32_t a, int32_t b, int32_t fmt, int32_t round,
1485558Snate@binkert.org                int32_t sign);
1495558Snate@binkert.orgint32_t dspShll(int32_t a, uint32_t sa, int32_t fmt, int32_t saturate,
1505558Snate@binkert.org                int32_t sign, uint32_t *dspctl);
1515558Snate@binkert.orgint32_t dspShrl(int32_t a, uint32_t sa, int32_t fmt, int32_t sign);
1525558Snate@binkert.orgint32_t dspShra(int32_t a, uint32_t sa, int32_t fmt, int32_t round,
1535558Snate@binkert.org                int32_t sign, uint32_t *dspctl);
1545558Snate@binkert.orgint32_t dspMul(int32_t a, int32_t b, int32_t fmt, int32_t saturate,
1555558Snate@binkert.org               uint32_t *dspctl);
1565558Snate@binkert.orgint32_t dspMulq(int32_t a, int32_t b, int32_t fmt, int32_t saturate,
1575558Snate@binkert.org                int32_t round, uint32_t *dspctl);
1585558Snate@binkert.orgint32_t dspMuleu(int32_t a, int32_t b, int32_t mode, uint32_t *dspctl);
1595558Snate@binkert.orgint32_t dspMuleq(int32_t a, int32_t b, int32_t mode, uint32_t *dspctl);
1605558Snate@binkert.orgint64_t dspDpaq(int64_t dspac, int32_t a, int32_t b, int32_t ac,
1615558Snate@binkert.org                int32_t infmt, int32_t outfmt, int32_t postsat, int32_t mode,
1625558Snate@binkert.org                uint32_t *dspctl);
1635558Snate@binkert.orgint64_t dspDpsq(int64_t dspac, int32_t a, int32_t b, int32_t ac,
1645558Snate@binkert.org                int32_t infmt, int32_t outfmt, int32_t postsat, int32_t mode,
1655558Snate@binkert.org                uint32_t *dspctl);
1665558Snate@binkert.orgint64_t dspDpa(int64_t dspac, int32_t a, int32_t b, int32_t ac, int32_t fmt,
1675558Snate@binkert.org               int32_t sign, int32_t mode);
1685558Snate@binkert.orgint64_t dspDps(int64_t dspac, int32_t a, int32_t b, int32_t ac, int32_t fmt,
1695558Snate@binkert.org               int32_t sign, int32_t mode);
1705558Snate@binkert.orgint64_t dspMaq(int64_t dspac, int32_t a, int32_t b, int32_t ac,
1715558Snate@binkert.org               int32_t fmt, int32_t mode, int32_t saturate, uint32_t *dspctl);
1725558Snate@binkert.orgint64_t dspMulsa(int64_t dspac, int32_t a, int32_t b, int32_t ac, int32_t fmt);
1735558Snate@binkert.orgint64_t dspMulsaq(int64_t dspac, int32_t a, int32_t b, int32_t ac, int32_t fmt,
1745558Snate@binkert.org                  uint32_t *dspctl);
1755558Snate@binkert.orgvoid dspCmp(int32_t a, int32_t b, int32_t fmt, int32_t sign, int32_t op,
1765558Snate@binkert.org            uint32_t *dspctl);
1775558Snate@binkert.orgint32_t dspCmpg(int32_t a, int32_t b, int32_t fmt, int32_t sign, int32_t op);
1785558Snate@binkert.orgint32_t dspCmpgd(int32_t a, int32_t b, int32_t fmt, int32_t sign, int32_t op,
1795558Snate@binkert.org                 uint32_t *dspctl);
1805558Snate@binkert.orgint32_t dspPrece(int32_t a, int32_t infmt, int32_t insign, int32_t outfmt,
1815558Snate@binkert.org                 int32_t outsign, int32_t mode);
1825558Snate@binkert.orgint32_t dspPrecrqu(int32_t a, int32_t b, uint32_t *dspctl);
1835558Snate@binkert.orgint32_t dspPrecrq(int32_t a, int32_t b, int32_t fmt, uint32_t *dspctl);
1845558Snate@binkert.orgint32_t dspPrecrSra(int32_t a, int32_t b, int32_t sa, int32_t fmt,
1855558Snate@binkert.org                    int32_t round);
1865558Snate@binkert.orgint32_t dspPick(int32_t a, int32_t b, int32_t fmt, uint32_t *dspctl);
1875558Snate@binkert.orgint32_t dspPack(int32_t a, int32_t b, int32_t fmt);
1885558Snate@binkert.orgint32_t dspExtr(int64_t dspac, int32_t fmt, int32_t sa, int32_t round,
1895558Snate@binkert.org                int32_t saturate, uint32_t *dspctl);
1905558Snate@binkert.orgint32_t dspExtp(int64_t dspac, int32_t size, uint32_t *dspctl);
1915558Snate@binkert.orgint32_t dspExtpd(int64_t dspac, int32_t size, uint32_t *dspctl);
1925558Snate@binkert.org
1935558Snate@binkert.org// SIMD pack/unpack utility functions
1945558Snate@binkert.orgvoid simdPack(uint64_t *values_ptr, int32_t *reg, int32_t fmt);
1955558Snate@binkert.orgvoid simdUnpack(int32_t reg, uint64_t *values_ptr, int32_t fmt, int32_t sign);
1965558Snate@binkert.org
1975558Snate@binkert.org// DSPControl r/w utility functions
1985558Snate@binkert.orgvoid writeDSPControl(uint32_t *dspctl, uint32_t value, uint32_t mask);
1995558Snate@binkert.orguint32_t readDSPControl(uint32_t *dspctl, uint32_t mask);
2005558Snate@binkert.org
2017811Ssteve.reinhardt@amd.com} // namespace MipsISA
2025558Snate@binkert.org
2035558Snate@binkert.org#endif // __ARCH_MIPS_DSP_HH__
204