mips import pt. 1
authorKorey Sewell <ksewell@umich.edu>
Fri, 22 Jun 2007 23:03:42 +0000 (19:03 -0400)
committerKorey Sewell <ksewell@umich.edu>
Fri, 22 Jun 2007 23:03:42 +0000 (19:03 -0400)
src/arch/mips/SConscript:
    "mips import pt.1".

--HG--
extra : convert_revision : 2e393341938bebf32fb638a209262d074fad4cc1

44 files changed:
src/arch/mips/SConscript
src/arch/mips/constants.hh [new file with mode: 0755]
src/arch/mips/dsp.cc [new file with mode: 0755]
src/arch/mips/dsp.hh [new file with mode: 0755]
src/arch/mips/dt_constants.hh [new file with mode: 0755]
src/arch/mips/faults.cc
src/arch/mips/faults.hh
src/arch/mips/isa/bitfields.isa
src/arch/mips/isa/decoder.isa
src/arch/mips/isa/formats/branch.isa
src/arch/mips/isa/formats/control.isa
src/arch/mips/isa/formats/dsp.isa [new file with mode: 0755]
src/arch/mips/isa/formats/formats.isa
src/arch/mips/isa/formats/fp.isa
src/arch/mips/isa/formats/int.isa
src/arch/mips/isa/formats/mem.isa
src/arch/mips/isa/formats/mt.isa
src/arch/mips/isa/formats/tlbop.isa
src/arch/mips/isa/formats/util.isa
src/arch/mips/isa/includes.isa
src/arch/mips/isa/operands.isa
src/arch/mips/isa_traits.cc
src/arch/mips/isa_traits.hh
src/arch/mips/linux/linux.cc
src/arch/mips/linux/linux.hh
src/arch/mips/linux/process.cc
src/arch/mips/linux/process.hh
src/arch/mips/locked_mem.hh
src/arch/mips/mt.hh [new file with mode: 0755]
src/arch/mips/mt_constants.hh [new file with mode: 0755]
src/arch/mips/pra_constants.hh [new file with mode: 0755]
src/arch/mips/process.hh
src/arch/mips/regfile/float_regfile.hh
src/arch/mips/regfile/int_regfile.hh
src/arch/mips/regfile/misc_regfile.cc [new file with mode: 0755]
src/arch/mips/regfile/misc_regfile.hh
src/arch/mips/regfile/regfile.hh
src/arch/mips/utility.cc
src/arch/mips/utility.hh
src/base/bitfield.hh
src/base/traceflags.py
src/cpu/simple/base.hh
src/cpu/simple_thread.hh
src/cpu/thread_context.hh

index f959951b3c778ed68078a07085b44734dfcef5b9..de209348a6b9494cd5919e4e681e093cacc31f76 100644 (file)
@@ -35,7 +35,9 @@ Import('*')
 if env['TARGET_ISA'] == 'mips':
     Source('faults.cc')
     Source('isa_traits.cc')
+    Source('regfile/misc_regfile.cc')
     Source('utility.cc')
+    Source('dsp.cc')
 
     if env['FULL_SYSTEM']:
         #Insert Full-System Files Here
diff --git a/src/arch/mips/constants.hh b/src/arch/mips/constants.hh
new file mode 100755 (executable)
index 0000000..7e1739b
--- /dev/null
@@ -0,0 +1,41 @@
+/*
+ * Copyright (c) 2006 The Regents of The University of Michigan
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met: redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer;
+ * redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution;
+ * neither the name of the copyright holders nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * Authors: Korey Sewell
+ */
+
+#ifndef __ARCH_MIPS_CONSTANTS_HH__
+#define __ARCH_MIPS_CONSTANTS_HH__
+
+#include "arch/mips/types.hh"
+//#include "config/full_system.hh"
+
+namespace MipsISA
+{
+} // namespace MipsISA
+
+#endif
diff --git a/src/arch/mips/dsp.cc b/src/arch/mips/dsp.cc
new file mode 100755 (executable)
index 0000000..059c15a
--- /dev/null
@@ -0,0 +1,1227 @@
+/*
+ * Copyright (c) 2003-2006 The Regents of The University of Michigan
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met: redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer;
+ * redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution;
+ * neither the name of the copyright holders nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * Authors: Brett Miller
+ */
+
+#include "arch/mips/isa_traits.hh"
+#include "arch/mips/dsp.hh"
+#include "arch/mips/constants.hh"
+#include "config/full_system.hh"
+#include "cpu/static_inst.hh"
+#include "sim/serialize.hh"
+#include "base/bitfield.hh"
+#include "base/misc.hh"
+
+using namespace MipsISA;
+using namespace std;
+
+int32_t
+MipsISA::bitrev( int32_t value )
+{
+    int32_t result = 0;
+    int i, shift;
+
+    for( i=0; i<16; i++ )
+    {
+        shift = 2*i - 15;
+
+        if( shift < 0 )
+            result |= (value & 1L<<i) << -shift;
+        else
+            result |= (value & 1L<<i) >> shift;
+    }
+
+    return result;
+}
+
+uint64_t
+MipsISA::dspSaturate( uint64_t value, int32_t fmt, int32_t sign, uint32_t *overflow )
+{
+    int64_t svalue;
+
+    svalue = (int64_t)value;
+
+    switch( sign )
+    {
+      case SIGNED:
+        if( svalue > (int64_t)FIXED_SMAX[fmt] )
+        {
+            *overflow = 1;
+            svalue = (int64_t)FIXED_SMAX[fmt];
+        }
+        else if( svalue < (int64_t)FIXED_SMIN[fmt] )
+        {
+            *overflow = 1;
+            svalue = (int64_t)FIXED_SMIN[fmt];
+        }
+        break;
+      case UNSIGNED:
+        if( svalue > (int64_t)FIXED_UMAX[fmt] )
+        {
+            *overflow = 1;
+            svalue = FIXED_UMAX[fmt];
+        }
+        else if( svalue < (int64_t)FIXED_UMIN[fmt] )
+        {
+            *overflow = 1;
+            svalue = FIXED_UMIN[fmt];
+        }
+        break;
+    }
+
+    return( (uint64_t)svalue );
+}
+
+uint64_t
+MipsISA::checkOverflow( uint64_t value, int32_t fmt, int32_t sign, uint32_t *overflow )
+{
+    int64_t svalue;
+
+    svalue = (int64_t)value;
+
+    switch( sign )
+    {
+      case SIGNED:
+        if( svalue > (int64_t)FIXED_SMAX[fmt] || svalue < (int64_t)FIXED_SMIN[fmt] )
+            *overflow = 1;
+        break;
+      case UNSIGNED:
+        if( svalue > (int64_t)FIXED_UMAX[fmt] || svalue < (int64_t)FIXED_UMIN[fmt] )
+            *overflow = 1;
+        break;
+    }
+
+    return( (uint64_t)svalue );
+}
+
+uint64_t
+MipsISA::signExtend( uint64_t value, int32_t fmt )
+{
+    int32_t signpos = SIMD_NBITS[fmt];
+    uint64_t sign = uint64_t(1)<<(signpos-1);
+    uint64_t ones = ~(0ULL);
+
+    if( value & sign )
+        value |= (ones << signpos); // extend with ones
+    else
+        value &= (ones >> (64 - signpos)); // extend with zeros
+
+    return value;
+}
+
+uint64_t
+MipsISA::addHalfLsb( uint64_t value, int32_t lsbpos )
+{
+    return( value += ULL(1) << (lsbpos-1) );
+}
+
+int32_t
+MipsISA::dspAbs( int32_t a, int32_t fmt, uint32_t *dspctl )
+{
+    int i = 0;
+    int nvals = SIMD_NVALS[fmt];
+    int32_t result;
+    int64_t svalue;
+    uint32_t ouflag = 0;
+    uint64_t a_values[SIMD_MAX_VALS];
+
+    simdUnpack( a, a_values, fmt, SIGNED );
+
+    for( i=0; i<nvals; i++ )
+    {
+        svalue = (int64_t)a_values[i];
+
+        if( a_values[i] == FIXED_SMIN[fmt] )
+        {
+            a_values[i] = FIXED_SMAX[fmt];
+            ouflag = 1;
+        }
+        else if( svalue < 0 )
+        {
+            a_values[i] = uint64_t( 0 - svalue );
+        }
+    }
+
+    simdPack( a_values, &result, fmt );
+
+    if( ouflag )
+        writeDSPControl( dspctl, (ouflag<<4)<<DSP_CTL_POS[DSP_OUFLAG], 1<<DSP_OUFLAG);
+
+    return( result );
+}
+
+int32_t
+MipsISA::dspAdd( int32_t a, int32_t b, int32_t fmt, int32_t saturate, int32_t sign, uint32_t *dspctl )
+{
+    int i = 0;
+    int nvals = SIMD_NVALS[fmt];
+    int32_t result;
+    uint32_t ouflag = 0;
+    uint64_t a_values[SIMD_MAX_VALS];
+    uint64_t b_values[SIMD_MAX_VALS];
+
+    simdUnpack( a, a_values, fmt, sign );
+    simdUnpack( b, b_values, fmt, sign );
+
+    for( i=0; i<nvals; i++ )
+    {
+        if( saturate )
+            a_values[i] = dspSaturate( a_values[i] + b_values[i], fmt, sign, &ouflag );
+        else
+            a_values[i] = checkOverflow( a_values[i] + b_values[i], fmt, sign, &ouflag );
+    }
+
+    simdPack( a_values, &result, fmt );
+
+    if( ouflag )
+        writeDSPControl( dspctl, (ouflag<<4)<<DSP_CTL_POS[DSP_OUFLAG], 1<<DSP_OUFLAG);
+
+    return( result );
+}
+
+int32_t
+MipsISA::dspAddh( int32_t a, int32_t b, int32_t fmt, int32_t round, int32_t sign )
+{
+    int i = 0;
+    int nvals = SIMD_NVALS[fmt];
+    int32_t result;
+    uint64_t a_values[SIMD_MAX_VALS];
+    uint64_t b_values[SIMD_MAX_VALS];
+
+    simdUnpack( a, a_values, fmt, sign );
+    simdUnpack( b, b_values, fmt, sign );
+
+    for( i=0; i<nvals; i++ )
+    {
+        if( round )
+            a_values[i] = addHalfLsb( a_values[i] + b_values[i], 1 ) >> 1;
+        else
+            a_values[i] = ( a_values[i] + b_values[i] ) >> 1;
+    }
+
+    simdPack( a_values, &result, fmt );
+
+    return( result );
+}
+
+int32_t
+MipsISA::dspSub( int32_t a, int32_t b, int32_t fmt, int32_t saturate, int32_t sign, uint32_t *dspctl )
+{
+    int i = 0;
+    int nvals = SIMD_NVALS[fmt];
+    int32_t result;
+    uint32_t ouflag = 0;
+    uint64_t a_values[SIMD_MAX_VALS];
+    uint64_t b_values[SIMD_MAX_VALS];
+
+    simdUnpack( a, a_values, fmt, sign );
+    simdUnpack( b, b_values, fmt, sign );
+
+    for( i=0; i<nvals; i++ )
+    {
+        if( saturate )
+            a_values[i] = dspSaturate( a_values[i] - b_values[i], fmt, sign, &ouflag );
+        else
+            a_values[i] = checkOverflow( a_values[i] - b_values[i], fmt, sign, &ouflag );
+    }
+
+    simdPack( a_values, &result, fmt );
+
+    if( ouflag )
+        writeDSPControl( dspctl, (ouflag<<4)<<DSP_CTL_POS[DSP_OUFLAG], 1<<DSP_OUFLAG);
+
+    return( result );
+}
+
+int32_t
+MipsISA::dspSubh( int32_t a, int32_t b, int32_t fmt, int32_t round, int32_t sign )
+{
+    int i = 0;
+    int nvals = SIMD_NVALS[fmt];
+    int32_t result;
+    uint64_t a_values[SIMD_MAX_VALS];
+    uint64_t b_values[SIMD_MAX_VALS];
+
+    simdUnpack( a, a_values, fmt, sign );
+    simdUnpack( b, b_values, fmt, sign );
+
+    for( i=0; i<nvals; i++ )
+    {
+        if( round )
+            a_values[i] = addHalfLsb( a_values[i] - b_values[i], 1 ) >> 1;
+        else
+            a_values[i] = ( a_values[i] - b_values[i] ) >> 1;
+    }
+
+    simdPack( a_values, &result, fmt );
+
+    return( result );
+}
+
+int32_t
+MipsISA::dspShll( int32_t a, uint32_t sa, int32_t fmt, int32_t saturate, int32_t sign, uint32_t *dspctl )
+{
+    int i = 0;
+    int nvals = SIMD_NVALS[fmt];
+    int32_t result;
+    uint32_t ouflag = 0;
+    uint64_t a_values[SIMD_MAX_VALS];
+
+    sa = bits( sa, SIMD_LOG2N[fmt]-1, 0 );
+    simdUnpack( a, a_values, fmt, sign );
+
+    for( i=0; i<nvals; i++ )
+    {
+        if( saturate )
+            a_values[i] = dspSaturate( a_values[i] << sa, fmt, sign, &ouflag );
+        else
+            a_values[i] = checkOverflow( a_values[i] << sa, fmt, sign, &ouflag );
+    }
+
+    simdPack( a_values, &result, fmt );
+
+    if( ouflag )
+        writeDSPControl( dspctl, (ouflag<<6)<<DSP_CTL_POS[DSP_OUFLAG], 1<<DSP_OUFLAG);
+
+    return( result );
+}
+
+int32_t
+MipsISA::dspShrl( int32_t a, uint32_t sa, int32_t fmt, int32_t sign )
+{
+    int i = 0;
+    int nvals = SIMD_NVALS[fmt];
+    int32_t result;
+    uint64_t a_values[SIMD_MAX_VALS];
+
+    sa = bits( sa, SIMD_LOG2N[fmt]-1, 0 );
+
+    simdUnpack( a, a_values, fmt, UNSIGNED );
+
+    for( i=0; i<nvals; i++ )
+        a_values[i] = a_values[i] >> sa;
+
+    simdPack( a_values, &result, fmt );
+
+    return( result );
+}
+
+int32_t
+MipsISA::dspShra( int32_t a, uint32_t sa, int32_t fmt, int32_t round, int32_t sign, uint32_t *dspctl )
+{
+    int i = 0;
+    int nvals = SIMD_NVALS[fmt];
+    int32_t result;
+    uint64_t a_values[SIMD_MAX_VALS];
+
+    sa = bits( sa, SIMD_LOG2N[fmt]-1, 0 );
+
+    simdUnpack( a, a_values, fmt, SIGNED );
+
+    for( i=0; i<nvals; i++ )
+    {
+        if( round )
+            a_values[i] = addHalfLsb( a_values[i], sa ) >> sa;
+        else
+            a_values[i] = a_values[i] >> sa;
+    }
+
+    simdPack( a_values, &result, fmt );
+
+    return( result );
+}
+
+int32_t
+MipsISA::dspMulq( int32_t a, int32_t b, int32_t fmt, int32_t saturate, int32_t round, uint32_t *dspctl )
+{
+    int i = 0;
+    int nvals = SIMD_NVALS[fmt];
+    int sa = SIMD_NBITS[fmt];
+    int32_t result;
+    uint32_t ouflag = 0;
+    uint64_t a_values[SIMD_MAX_VALS];
+    uint64_t b_values[SIMD_MAX_VALS];
+    int64_t temp;
+
+    simdUnpack( a, a_values, fmt, SIGNED );
+    simdUnpack( b, b_values, fmt, SIGNED );
+
+    for( i=0; i<nvals; i++ )
+    {
+        if( round )
+            temp = (int64_t)addHalfLsb( a_values[i] * b_values[i] << 1, sa ) >> sa;
+        else
+            temp = (int64_t)(a_values[i] * b_values[i]) >> (sa - 1);
+
+        if( a_values[i] == FIXED_SMIN[fmt] &&
+            b_values[i] == FIXED_SMIN[fmt] )
+        {
+            ouflag = 1;
+
+            if( saturate )
+                temp = FIXED_SMAX[fmt];
+        }
+
+        a_values[i] = temp;
+    }
+
+    simdPack( a_values, &result, fmt );
+
+    if( ouflag )
+        writeDSPControl( dspctl, (ouflag<<5)<<DSP_CTL_POS[DSP_OUFLAG], 1<<DSP_OUFLAG);
+
+    return( result );
+}
+
+int32_t
+MipsISA::dspMul( int32_t a, int32_t b, int32_t fmt, int32_t saturate, uint32_t *dspctl )
+{
+    int i = 0;
+    int nvals = SIMD_NVALS[fmt];
+    int32_t result;
+    uint32_t ouflag = 0;
+    uint64_t a_values[SIMD_MAX_VALS];
+    uint64_t b_values[SIMD_MAX_VALS];
+
+    simdUnpack( a, a_values, fmt, SIGNED );
+    simdUnpack( b, b_values, fmt, SIGNED );
+
+    for( i=0; i<nvals; i++ )
+    {
+        if( saturate )
+            a_values[i] = dspSaturate( a_values[i] * b_values[i], fmt, SIGNED, &ouflag );
+        else
+            a_values[i] = checkOverflow( a_values[i] * b_values[i], fmt, SIGNED, &ouflag );
+    }
+
+    simdPack( a_values, &result, fmt );
+
+    if( ouflag )
+        writeDSPControl( dspctl, (ouflag<<5)<<DSP_CTL_POS[DSP_OUFLAG], 1<<DSP_OUFLAG);
+
+    return( result );
+}
+
+int32_t
+MipsISA::dspMuleu( int32_t a, int32_t b, int32_t mode, uint32_t *dspctl )
+{
+    int i = 0;
+    int nvals = SIMD_NVALS[SIMD_FMT_PH];
+    int32_t result;
+    uint32_t ouflag = 0;
+    uint64_t a_values[SIMD_MAX_VALS];
+    uint64_t b_values[SIMD_MAX_VALS];
+
+    simdUnpack( a, a_values, SIMD_FMT_QB, UNSIGNED );
+    simdUnpack( b, b_values, SIMD_FMT_PH, UNSIGNED );
+
+    switch( mode )
+    {
+      case MODE_L:
+        for( i=0; i<nvals; i++ )
+            b_values[i] = dspSaturate( a_values[i+2] * b_values[i], SIMD_FMT_PH, UNSIGNED, &ouflag );
+        break;
+      case MODE_R:
+        for( i=0; i<nvals; i++ )
+            b_values[i] = dspSaturate( a_values[i] * b_values[i], SIMD_FMT_PH, UNSIGNED, &ouflag );
+        break;
+    }
+
+    simdPack( b_values, &result, SIMD_FMT_PH );
+
+    if( ouflag )
+        writeDSPControl( dspctl, (ouflag<<5)<<DSP_CTL_POS[DSP_OUFLAG], 1<<DSP_OUFLAG);
+
+    return( result );
+}
+
+int32_t
+MipsISA::dspMuleq( int32_t a, int32_t b, int32_t mode, uint32_t *dspctl )
+{
+    int i = 0;
+    int nvals = SIMD_NVALS[SIMD_FMT_W];
+    int32_t result;
+    uint32_t ouflag = 0;
+    uint64_t a_values[SIMD_MAX_VALS];
+    uint64_t b_values[SIMD_MAX_VALS];
+    uint64_t c_values[SIMD_MAX_VALS];
+
+    simdUnpack( a, a_values, SIMD_FMT_PH, SIGNED );
+    simdUnpack( b, b_values, SIMD_FMT_PH, SIGNED );
+
+    switch( mode )
+    {
+      case MODE_L:
+        for( i=0; i<nvals; i++ )
+            c_values[i] = dspSaturate( a_values[i+1] * b_values[i+1] << 1,
+                                       SIMD_FMT_W, SIGNED, &ouflag );
+        break;
+      case MODE_R:
+        for( i=0; i<nvals; i++ )
+            c_values[i] = dspSaturate( a_values[i] * b_values[i] << 1,
+                                       SIMD_FMT_W, SIGNED, &ouflag );
+        break;
+    }
+
+    simdPack( c_values, &result, SIMD_FMT_W );
+
+    if( ouflag )
+        writeDSPControl( dspctl, (ouflag<<5)<<DSP_CTL_POS[DSP_OUFLAG], 1<<DSP_OUFLAG);
+
+    return( result );
+}
+
+int64_t
+MipsISA::dspDpaq( int64_t dspac, int32_t a, int32_t b, int32_t ac, int32_t infmt,
+                  int32_t outfmt, int32_t postsat, int32_t mode, uint32_t *dspctl )
+{
+    int i = 0;
+    int nvals = SIMD_NVALS[infmt];
+    int64_t result = 0;
+    int64_t temp = 0;
+    uint32_t ouflag = 0;
+    uint64_t a_values[SIMD_MAX_VALS];
+    uint64_t b_values[SIMD_MAX_VALS];
+
+    simdUnpack( a, a_values, infmt, SIGNED );
+    simdUnpack( b, b_values, infmt, SIGNED );
+
+    for( i=0; i<nvals; i++ )
+    {
+        switch( mode )
+        {
+          case MODE_X:
+            if( a_values[nvals-1-i] == FIXED_SMIN[infmt] &&
+                b_values[i] == FIXED_SMIN[infmt] )
+            {
+                result += FIXED_SMAX[outfmt];
+                ouflag = 1;
+            }
+            else
+                result += a_values[nvals-1-i] * b_values[i] << 1;
+            break;
+          default:
+            if( a_values[i] == FIXED_SMIN[infmt] &&
+                b_values[i] == FIXED_SMIN[infmt] )
+            {
+                result += FIXED_SMAX[outfmt];
+                ouflag = 1;
+            }
+            else
+                result += a_values[i] * b_values[i] << 1;
+            break;
+        }
+    }
+
+    if( postsat )
+    {
+        if( outfmt == SIMD_FMT_L )
+        {
+            int signa = bits( dspac, 63, 63 );
+            int signb = bits( result, 63, 63 );
+
+            temp = dspac + result;
+
+            if( ( signa == signb ) &&
+                ( bits( temp, 63, 63 ) != signa ) )
+            {
+                ouflag = 1;
+                if( signa )
+                    dspac = FIXED_SMIN[outfmt];
+                else
+                    dspac = FIXED_SMAX[outfmt];
+            }
+            else
+                dspac = temp;
+        }
+        else
+            dspac = dspSaturate( dspac + result, outfmt, SIGNED, &ouflag );
+    }
+    else
+        dspac += result;
+
+    if( ouflag )
+        *dspctl = insertBits( *dspctl, 16+ac, 16+ac, 1 );
+
+    return( dspac );
+}
+
+int64_t
+MipsISA::dspDpsq( int64_t dspac, int32_t a, int32_t b, int32_t ac, int32_t infmt,
+                  int32_t outfmt, int32_t postsat, int32_t mode, uint32_t *dspctl )
+{
+    int i = 0;
+    int nvals = SIMD_NVALS[infmt];
+    int64_t result = 0;
+    int64_t temp = 0;
+    uint32_t ouflag = 0;
+    uint64_t a_values[SIMD_MAX_VALS];
+    uint64_t b_values[SIMD_MAX_VALS];
+
+    simdUnpack( a, a_values, infmt, SIGNED );
+    simdUnpack( b, b_values, infmt, SIGNED );
+
+    for( i=0; i<nvals; i++ )
+    {
+        switch( mode )
+        {
+          case MODE_X:
+            if( a_values[nvals-1-i] == FIXED_SMIN[infmt] &&
+                b_values[i] == FIXED_SMIN[infmt] )
+            {
+                result += FIXED_SMAX[outfmt];
+                ouflag = 1;
+            }
+            else
+                result += a_values[nvals-1-i] * b_values[i] << 1;
+            break;
+          default:
+            if( a_values[i] == FIXED_SMIN[infmt] &&
+                b_values[i] == FIXED_SMIN[infmt] )
+            {
+                result += FIXED_SMAX[outfmt];
+                ouflag = 1;
+            }
+            else
+                result += a_values[i] * b_values[i] << 1;
+            break;
+        }
+    }
+
+    if( postsat )
+    {
+        if( outfmt == SIMD_FMT_L )
+        {
+            int signa = bits( dspac, 63, 63 );
+            int signb = bits( -result, 63, 63 );
+
+            temp = dspac - result;
+
+            if( ( signa == signb ) &&
+                ( bits( temp, 63, 63 ) != signa ) )
+            {
+                ouflag = 1;
+                if( signa )
+                    dspac = FIXED_SMIN[outfmt];
+                else
+                    dspac = FIXED_SMAX[outfmt];
+            }
+            else
+                dspac = temp;
+        }
+        else
+            dspac = dspSaturate( dspac - result, outfmt, SIGNED, &ouflag );
+    }
+    else
+        dspac -= result;
+
+    if( ouflag )
+        *dspctl = insertBits( *dspctl, 16+ac, 16+ac, 1 );
+
+    return( dspac );
+}
+
+int64_t
+MipsISA::dspDpa( int64_t dspac, int32_t a, int32_t b, int32_t ac,
+                 int32_t fmt, int32_t sign, int32_t mode )
+{
+    int i = 0;
+    int nvals = SIMD_NVALS[fmt];
+    uint64_t a_values[SIMD_MAX_VALS];
+    uint64_t b_values[SIMD_MAX_VALS];
+
+    simdUnpack( a, a_values, fmt, sign );
+    simdUnpack( b, b_values, fmt, sign );
+
+    for( i=0; i<2; i++ )
+    {
+        switch( mode )
+        {
+          case MODE_L:
+            dspac += a_values[nvals-1-i] * b_values[nvals-1-i];
+            break;
+          case MODE_R:
+            dspac += a_values[nvals-3-i] * b_values[nvals-3-i];
+            break;
+          case MODE_X:
+            dspac += a_values[nvals-1-i] * b_values[i];
+            break;
+        }
+    }
+
+    return dspac;
+}
+
+int64_t
+MipsISA::dspDps( int64_t dspac, int32_t a, int32_t b, int32_t ac,
+                 int32_t fmt, int32_t sign, int32_t mode )
+{
+    int i = 0;
+    int nvals = SIMD_NVALS[fmt];
+    uint64_t a_values[SIMD_MAX_VALS];
+    uint64_t b_values[SIMD_MAX_VALS];
+
+    simdUnpack( a, a_values, fmt, sign );
+    simdUnpack( b, b_values, fmt, sign );
+
+    for( i=0; i<2; i++ )
+    {
+        switch( mode )
+        {
+          case MODE_L:
+            dspac -= a_values[nvals-1-i] * b_values[nvals-1-i];
+            break;
+          case MODE_R:
+            dspac -= a_values[nvals-3-i] * b_values[nvals-3-i];
+            break;
+          case MODE_X:
+            dspac -= a_values[nvals-1-i] * b_values[i];
+            break;
+        }
+    }
+
+    return dspac;
+}
+
+int64_t
+MipsISA::dspMaq( int64_t dspac, int32_t a, int32_t b, int32_t ac,
+                 int32_t fmt, int32_t mode, int32_t saturate, uint32_t *dspctl )
+{
+    int i = 0;
+    int nvals = SIMD_NVALS[fmt-1];
+    uint64_t a_values[SIMD_MAX_VALS];
+    uint64_t b_values[SIMD_MAX_VALS];
+    int64_t temp = 0;
+    uint32_t ouflag = 0;
+
+    simdUnpack( a, a_values, fmt, SIGNED );
+    simdUnpack( b, b_values, fmt, SIGNED );
+
+    for( i=0; i<nvals; i++ )
+    {
+        switch( mode )
+        {
+          case MODE_L:
+            temp = a_values[i+1] * b_values[i+1] << 1;
+            if( a_values[i+1] == FIXED_SMIN[fmt] && b_values[i+1] == FIXED_SMIN[fmt] )
+            {
+                temp = (int64_t)FIXED_SMAX[fmt-1];
+                ouflag = 1;
+            }
+            break;
+          case MODE_R:
+            temp = a_values[i] * b_values[i] << 1;
+            if( a_values[i] == FIXED_SMIN[fmt] && b_values[i] == FIXED_SMIN[fmt] )
+            {
+                temp = (int64_t)FIXED_SMAX[fmt-1];
+                ouflag = 1;
+            }
+            break;
+        }
+
+        temp += dspac;
+
+        if( saturate )
+            temp = dspSaturate( temp, fmt-1, SIGNED, &ouflag );
+        if( ouflag )
+            *dspctl = insertBits( *dspctl, 16+ac, 16+ac, 1 );
+    }
+
+    return temp;
+}
+
+int64_t
+MipsISA::dspMulsa( int64_t dspac, int32_t a, int32_t b, int32_t ac, int32_t fmt )
+{
+    uint64_t a_values[SIMD_MAX_VALS];
+    uint64_t b_values[SIMD_MAX_VALS];
+
+    simdUnpack( a, a_values, fmt, SIGNED );
+    simdUnpack( b, b_values, fmt, SIGNED );
+
+    dspac += a_values[1] * b_values[1] - a_values[0] * b_values[0];
+
+    return dspac;
+}
+
+int64_t
+MipsISA::dspMulsaq( int64_t dspac, int32_t a, int32_t b, int32_t ac, int32_t fmt, uint32_t *dspctl )
+{
+    int i = 0;
+    int nvals = SIMD_NVALS[fmt];
+    uint64_t a_values[SIMD_MAX_VALS];
+    uint64_t b_values[SIMD_MAX_VALS];
+    int64_t temp[2];
+    uint32_t ouflag = 0;
+
+    simdUnpack( a, a_values, fmt, SIGNED );
+    simdUnpack( b, b_values, fmt, SIGNED );
+
+    for( i=nvals-1; i>-1; i-- )
+    {
+        temp[i] = a_values[i] * b_values[i] << 1;
+        if( a_values[i] == FIXED_SMIN[fmt] &&
+            b_values[i] == FIXED_SMIN[fmt] )
+        {
+            temp[i] = FIXED_SMAX[fmt-1];
+            ouflag = 1;
+        }
+    }
+
+    dspac += temp[1] - temp[0];
+
+    if( ouflag )
+        *dspctl = insertBits( *dspctl, 16+ac, 16+ac, 1 );
+
+    return dspac;
+}
+
+void
+MipsISA::dspCmp( int32_t a, int32_t b, int32_t fmt, int32_t sign, int32_t op, uint32_t *dspctl )
+{
+    int i = 0;
+    int nvals = SIMD_NVALS[fmt];
+    int ccond = 0;
+    uint64_t a_values[SIMD_MAX_VALS];
+    uint64_t b_values[SIMD_MAX_VALS];
+
+    simdUnpack( a, a_values, fmt, sign );
+    simdUnpack( b, b_values, fmt, sign );
+
+    for( i=0; i<nvals; i++ )
+    {
+        int cc = 0;
+
+        switch( op )
+        {
+          case CMP_EQ: cc = ( a_values[i] == b_values[i] ); break;
+          case CMP_LT: cc = ( a_values[i] < b_values[i] ); break;
+          case CMP_LE: cc = ( a_values[i] <= b_values[i] ); break;
+        }
+
+        ccond |= cc << ( DSP_CTL_POS[DSP_CCOND] + i );
+    }
+
+    writeDSPControl( dspctl, ccond, 1<<DSP_CCOND );
+}
+
+int32_t
+MipsISA::dspCmpg( int32_t a, int32_t b, int32_t fmt, int32_t sign, int32_t op )
+{
+    int i = 0;
+    int nvals = SIMD_NVALS[fmt];
+    int32_t result = 0;
+    uint64_t a_values[SIMD_MAX_VALS];
+    uint64_t b_values[SIMD_MAX_VALS];
+
+    simdUnpack( a, a_values, fmt, sign );
+    simdUnpack( b, b_values, fmt, sign );
+
+    for( i=0; i<nvals; i++ )
+    {
+        int cc = 0;
+
+        switch( op )
+        {
+          case CMP_EQ: cc = ( a_values[i] == b_values[i] ); break;
+          case CMP_LT: cc = ( a_values[i] < b_values[i] ); break;
+          case CMP_LE: cc = ( a_values[i] <= b_values[i] ); break;
+        }
+
+        result |= cc << i;
+    }
+
+    return( result );
+}
+
+int32_t
+MipsISA::dspCmpgd( int32_t a, int32_t b, int32_t fmt, int32_t sign, int32_t op, uint32_t *dspctl )
+{
+    int i = 0;;
+    int nvals = SIMD_NVALS[fmt];
+    int32_t result = 0;
+    int ccond = 0;
+    uint64_t a_values[SIMD_MAX_VALS];
+    uint64_t b_values[SIMD_MAX_VALS];
+
+    simdUnpack( a, a_values, fmt, sign );
+    simdUnpack( b, b_values, fmt, sign );
+
+    for( i=0; i<nvals; i++ )
+    {
+        int cc = 0;;
+
+        switch( op )
+        {
+          case CMP_EQ: cc = ( a_values[i] == b_values[i] ); break;
+          case CMP_LT: cc = ( a_values[i] < b_values[i] ); break;
+          case CMP_LE: cc = ( a_values[i] <= b_values[i] ); break;
+        }
+
+        result |= cc << i;
+        ccond |= cc << ( DSP_CTL_POS[DSP_CCOND] + i );
+    }
+
+    writeDSPControl( dspctl, ccond, 1<<DSP_CCOND );
+
+    return( result );
+}
+
+int32_t
+MipsISA::dspPrece( int32_t a, int32_t infmt, int32_t insign, int32_t outfmt, int32_t outsign, int32_t mode )
+{
+    int i = 0;
+    int sa = 0;
+    int ninvals = SIMD_NVALS[infmt];
+    int noutvals = SIMD_NVALS[outfmt];
+    int32_t result;
+    uint64_t in_values[SIMD_MAX_VALS];
+    uint64_t out_values[SIMD_MAX_VALS];
+
+    if( insign == SIGNED && outsign == SIGNED )
+      sa = SIMD_NBITS[infmt];
+    else if( insign == UNSIGNED && outsign == SIGNED )
+      sa = SIMD_NBITS[infmt] - 1;
+    else if( insign == UNSIGNED && outsign == UNSIGNED )
+      sa = 0;
+
+    simdUnpack( a, in_values, infmt, insign );
+
+    for( i=0; i<noutvals; i++ )
+    {
+        switch( mode )
+        {
+          case MODE_L: out_values[i] = in_values[i+(ninvals>>1)] << sa; break;
+          case MODE_R: out_values[i] = in_values[i] << sa; break;
+          case MODE_LA: out_values[i] = in_values[(i<<1)+1] << sa; break;
+          case MODE_RA: out_values[i] = in_values[i<<1] << sa; break;
+        }
+    }
+
+    simdPack( out_values, &result, outfmt );
+
+    return( result );
+}
+
+int32_t
+MipsISA::dspPrecrqu( int32_t a, int32_t b, uint32_t *dspctl )
+{
+    int i = 0;
+    uint64_t a_values[SIMD_MAX_VALS];
+    uint64_t b_values[SIMD_MAX_VALS];
+    uint64_t r_values[SIMD_MAX_VALS];
+    uint32_t ouflag = 0;
+    int32_t result = 0;
+
+    simdUnpack( a, a_values, SIMD_FMT_PH, SIGNED );
+    simdUnpack( b, b_values, SIMD_FMT_PH, SIGNED );
+
+    for( i=0; i<2; i++ )
+    {
+        r_values[i] = dspSaturate( (int64_t)b_values[i] >> SIMD_NBITS[SIMD_FMT_QB] - 1,
+                                   SIMD_FMT_QB, UNSIGNED, &ouflag );
+        r_values[i+2] = dspSaturate( (int64_t)a_values[i] >> SIMD_NBITS[SIMD_FMT_QB] - 1,
+                                     SIMD_FMT_QB, UNSIGNED, &ouflag );
+    }
+
+    simdPack( r_values, &result, SIMD_FMT_QB );
+
+    if( ouflag )
+        *dspctl = insertBits( *dspctl, 22, 22, 1 );
+
+    return result;
+}
+
+int32_t
+MipsISA::dspPrecrq( int32_t a, int32_t b, int32_t fmt, uint32_t *dspctl )
+{
+    uint64_t a_values[SIMD_MAX_VALS];
+    uint64_t b_values[SIMD_MAX_VALS];
+    uint64_t r_values[SIMD_MAX_VALS];
+    uint32_t ouflag = 0;
+    int32_t result;
+
+    simdUnpack( a, a_values, fmt, SIGNED );
+    simdUnpack( b, b_values, fmt, SIGNED );
+
+    r_values[1] = dspSaturate( (int64_t)addHalfLsb( a_values[0], 16 ) >> 16,
+                                   fmt+1, SIGNED, &ouflag );
+    r_values[0] = dspSaturate( (int64_t)addHalfLsb( b_values[0], 16 ) >> 16,
+                                   fmt+1, SIGNED, &ouflag );
+
+    simdPack( r_values, &result, fmt+1 );
+
+    if( ouflag )
+        *dspctl = insertBits( *dspctl, 22, 22, 1 );
+
+    return result;
+}
+
+int32_t
+MipsISA::dspPrecrSra( int32_t a, int32_t b, int32_t sa, int32_t fmt, int32_t round )
+{
+    int i = 0;
+    int nvals = SIMD_NVALS[fmt];
+    uint64_t a_values[SIMD_MAX_VALS];
+    uint64_t b_values[SIMD_MAX_VALS];
+    uint64_t c_values[SIMD_MAX_VALS];
+    int32_t result = 0;
+
+    simdUnpack( a, a_values, fmt, SIGNED );
+    simdUnpack( b, b_values, fmt, SIGNED );
+
+    for( i=0; i<nvals; i++ )
+    {
+        if( round )
+        {
+            c_values[i] = addHalfLsb( b_values[i], sa ) >> sa;
+            c_values[i+1] = addHalfLsb( a_values[i], sa ) >> sa;
+        }
+        else
+        {
+            c_values[i] = b_values[i] >> sa;
+            c_values[i+1] = a_values[i] >> sa;
+        }
+    }
+
+    simdPack( c_values, &result, fmt+1 );
+
+    return result;
+}
+
+int32_t
+MipsISA::dspPick( int32_t a, int32_t b, int32_t fmt, uint32_t *dspctl )
+{
+    int i = 0;
+    int nvals = SIMD_NVALS[fmt];
+    int32_t result;
+    uint64_t a_values[SIMD_MAX_VALS];
+    uint64_t b_values[SIMD_MAX_VALS];
+    uint64_t c_values[SIMD_MAX_VALS];
+
+    simdUnpack( a, a_values, fmt, UNSIGNED );
+    simdUnpack( b, b_values, fmt, UNSIGNED );
+
+    for( i=0; i<nvals; i++ )
+    {
+        int condbit = DSP_CTL_POS[DSP_CCOND] + i;
+        if( bits( *dspctl, condbit, condbit ) == 1 )
+            c_values[i] = a_values[i];
+        else
+            c_values[i] = b_values[i];
+    }
+
+    simdPack( c_values, &result, fmt );
+
+    return( result );
+}
+
+int32_t
+MipsISA::dspPack( int32_t a, int32_t b, int32_t fmt )
+{
+    int32_t result;
+    uint64_t a_values[SIMD_MAX_VALS];
+    uint64_t b_values[SIMD_MAX_VALS];
+    uint64_t c_values[SIMD_MAX_VALS];
+
+    simdUnpack( a, a_values, fmt, UNSIGNED );
+    simdUnpack( b, b_values, fmt, UNSIGNED );
+
+    c_values[0] = b_values[1];
+    c_values[1] = a_values[0];
+
+    simdPack( c_values, &result, fmt );
+
+    return( result );
+}
+
+int32_t
+MipsISA::dspExtr( int64_t dspac, int32_t fmt, int32_t sa, int32_t round, int32_t saturate, uint32_t *dspctl )
+{
+    int32_t result = 0;
+    uint32_t ouflag = 0;
+    int64_t temp = 0;
+
+    sa = bits( sa, 4, 0 );
+
+    if( sa > 0 )
+    {
+        if( round )
+        {
+            temp = (int64_t)addHalfLsb( dspac, sa );
+
+            if( dspac > 0 && temp < 0 )
+            {
+                ouflag = 1;
+                if( saturate )
+                    temp = FIXED_SMAX[SIMD_FMT_L];
+            }
+            temp = temp >> sa;
+        }
+        else
+            temp = dspac >> sa;
+    }
+    else
+        temp = dspac;
+
+    dspac = checkOverflow( dspac, fmt, SIGNED, &ouflag );
+
+    if( ouflag )
+    {
+        *dspctl = insertBits( *dspctl, 23, 23, ouflag );
+
+        if( saturate )
+            result = (int32_t)dspSaturate( temp, fmt, SIGNED, &ouflag );
+        else
+            result = (int32_t)temp;
+    }
+    else
+        result = (int32_t)temp;
+
+    return( result );
+}
+
+int32_t
+MipsISA::dspExtp( int64_t dspac, int32_t size, uint32_t *dspctl )
+{
+    int32_t pos = 0;
+    int32_t result = 0;
+
+    pos = bits( *dspctl, 5, 0 );
+    size = bits( size, 4, 0 );
+
+    if( pos - (size+1) >= -1 )
+    {
+        result = bits( dspac, pos, pos-size );
+        *dspctl = insertBits( *dspctl, 14, 14, 0 );
+    }
+    else
+    {
+        result = 0;
+        *dspctl = insertBits( *dspctl, 14, 14, 1 );
+    }
+
+    return( result );
+}
+
+int32_t
+MipsISA::dspExtpd( int64_t dspac, int32_t size, uint32_t *dspctl )
+{
+    int32_t pos = 0;
+    int32_t result = 0;
+
+    pos = bits( *dspctl, 5, 0 );
+    size = bits( size, 4, 0 );
+
+    if( pos - (size+1) >= -1 )
+    {
+        result = bits( dspac, pos, pos-size );
+        *dspctl = insertBits( *dspctl, 14, 14, 0 );
+        if( pos - (size+1) >= 0 )
+            *dspctl = insertBits( *dspctl, 5, 0, pos - (size+1) );
+        else if( (pos - (size+1)) == -1 )
+            *dspctl = insertBits( *dspctl, 5, 0, 63 );
+    }
+    else
+    {
+        result = 0;
+        *dspctl = insertBits( *dspctl, 14, 14, 1 );
+    }
+
+    return( result );
+}
+
+void
+MipsISA::simdPack( uint64_t *values_ptr, int32_t *reg, int32_t fmt )
+{
+    int i = 0;
+    int nvals = SIMD_NVALS[fmt];
+    int nbits = SIMD_NBITS[fmt];
+
+    *reg = 0;
+
+    for( i=0; i<nvals; i++ )
+        *reg |= (int32_t)bits( values_ptr[i], nbits-1, 0 ) << nbits*i;
+}
+
+void
+MipsISA::simdUnpack( int32_t reg, uint64_t *values_ptr, int32_t fmt, int32_t sign )
+{
+    int i = 0;
+    int nvals = SIMD_NVALS[fmt];
+    int nbits = SIMD_NBITS[fmt];
+
+    switch( sign )
+    {
+    case SIGNED:
+        for( i=0; i<nvals; i++ )
+        {
+            values_ptr[i] = (uint64_t)bits( reg, nbits*(i+1)-1, nbits*i );
+            values_ptr[i] = signExtend( values_ptr[i], fmt );
+        }
+        break;
+    case UNSIGNED:
+        for( i=0; i<nvals; i++ )
+        {
+            values_ptr[i] = (uint64_t)bits( reg, nbits*(i+1)-1, nbits*i );
+        }
+        break;
+    }
+}
+
+void
+MipsISA::writeDSPControl( uint32_t *dspctl, uint32_t value, uint32_t mask )
+{
+    uint32_t fmask = 0;
+
+    if( mask & 0x01 ) fmask |= DSP_CTL_MASK[DSP_POS];
+    if( mask & 0x02 ) fmask |= DSP_CTL_MASK[DSP_SCOUNT];
+    if( mask & 0x04 ) fmask |= DSP_CTL_MASK[DSP_C];
+    if( mask & 0x08 ) fmask |= DSP_CTL_MASK[DSP_OUFLAG];
+    if( mask & 0x10 ) fmask |= DSP_CTL_MASK[DSP_CCOND];
+    if( mask & 0x20 ) fmask |= DSP_CTL_MASK[DSP_EFI];
+
+    *dspctl &= ~fmask;
+    value &= fmask;
+    *dspctl |= value;
+}
+
+uint32_t
+MipsISA::readDSPControl( uint32_t *dspctl, uint32_t mask )
+{
+    uint32_t fmask = 0;
+
+    if( mask & 0x01 ) fmask |= DSP_CTL_MASK[DSP_POS];
+    if( mask & 0x02 ) fmask |= DSP_CTL_MASK[DSP_SCOUNT];
+    if( mask & 0x04 ) fmask |= DSP_CTL_MASK[DSP_C];
+    if( mask & 0x08 ) fmask |= DSP_CTL_MASK[DSP_OUFLAG];
+    if( mask & 0x10 ) fmask |= DSP_CTL_MASK[DSP_CCOND];
+    if( mask & 0x20 ) fmask |= DSP_CTL_MASK[DSP_EFI];
+
+    return( *dspctl & fmask );
+}
diff --git a/src/arch/mips/dsp.hh b/src/arch/mips/dsp.hh
new file mode 100755 (executable)
index 0000000..03ee333
--- /dev/null
@@ -0,0 +1,171 @@
+/*
+ * Copyright (c) 2003-2005 The Regents of The University of Michigan
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met: redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer;
+ * redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution;
+ * neither the name of the copyright holders nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * Authors: Brett Miller
+ */
+
+#ifndef __ARCH_MIPS_DSP_HH__
+#define __ARCH_MIPS_DSP_HH__
+
+#include "arch/mips/types.hh"
+#include "arch/mips/isa_traits.hh"
+#include "base/misc.hh"
+#include "config/full_system.hh"
+#include "sim/host.hh"
+
+class ThreadContext;
+
+namespace MipsISA {
+
+    // SIMD formats
+    enum {
+        SIMD_FMT_L,    // long word
+        SIMD_FMT_W,    // word
+        SIMD_FMT_PH,   // paired halfword
+        SIMD_FMT_QB,   // quad byte
+        SIMD_NUM_FMTS
+    };
+
+    // DSPControl Fields
+    enum {
+        DSP_POS,       // insertion bitfield position
+        DSP_SCOUNT,    // insertion bitfield size
+        DSP_C,         // carry bit
+        DSP_OUFLAG,    // overflow-underflow flag
+        DSP_CCOND,     // condition code
+        DSP_EFI,       // extract fail indicator bit
+        DSP_NUM_FIELDS
+    };
+
+    // compare instruction operations
+    enum {
+        CMP_EQ,        // equal
+        CMP_LT,        // less than
+        CMP_LE         // less than or equal
+    };
+
+    // SIMD operation order modes
+    enum {
+        MODE_L,        // left
+        MODE_R,        // right
+        MODE_LA,       // left-alternate
+        MODE_RA,       // right-alternate
+        MODE_X         // cross
+    };
+
+    // dsp operation parameters
+    enum { UNSIGNED, SIGNED };
+    enum { NOSATURATE, SATURATE };
+    enum { NOROUND, ROUND };
+
+    // DSPControl field positions and masks
+    const uint32_t DSP_CTL_POS[DSP_NUM_FIELDS] = { 0, 7, 13, 16, 24, 14 };
+    const uint32_t DSP_CTL_MASK[DSP_NUM_FIELDS] = { 0x0000003f, 0x00001f80, 0x00002000,
+                                                    0x00ff0000, 0x0f000000, 0x00004000 };
+
+    // SIMD format constants
+    const uint32_t SIMD_MAX_VALS = 4; // maximum values per register
+    const uint32_t SIMD_NVALS[SIMD_NUM_FMTS] = { 1, 1, 2, 4 }; // number of values in fmt
+    const uint32_t SIMD_NBITS[SIMD_NUM_FMTS] = { 64, 32, 16, 8 }; // number of bits per value
+    const uint32_t SIMD_LOG2N[SIMD_NUM_FMTS] = { 6, 5, 4, 3 }; // log2( bits per value )
+
+    // DSP maximum values
+    const uint64_t FIXED_L_SMAX = ULL(0x7fffffffffffffff);
+    const uint64_t FIXED_W_SMAX = ULL(0x000000007fffffff);
+    const uint64_t FIXED_H_SMAX = ULL(0x0000000000007fff);
+    const uint64_t FIXED_B_SMAX = ULL(0x000000000000007f);
+    const uint64_t FIXED_L_UMAX = ULL(0xffffffffffffffff);
+    const uint64_t FIXED_W_UMAX = ULL(0x00000000ffffffff);
+    const uint64_t FIXED_H_UMAX = ULL(0x000000000000ffff);
+    const uint64_t FIXED_B_UMAX = ULL(0x00000000000000ff);
+    const uint64_t FIXED_SMAX[SIMD_NUM_FMTS] = { FIXED_L_SMAX, FIXED_W_SMAX, FIXED_H_SMAX, FIXED_B_SMAX };
+    const uint64_t FIXED_UMAX[SIMD_NUM_FMTS] = { FIXED_L_UMAX, FIXED_W_UMAX, FIXED_H_UMAX, FIXED_B_UMAX };
+
+    // DSP minimum values
+    const uint64_t FIXED_L_SMIN = ULL(0x8000000000000000);
+    const uint64_t FIXED_W_SMIN = ULL(0xffffffff80000000);
+    const uint64_t FIXED_H_SMIN = ULL(0xffffffffffff8000);
+    const uint64_t FIXED_B_SMIN = ULL(0xffffffffffffff80);
+    const uint64_t FIXED_L_UMIN = ULL(0x0000000000000000);
+    const uint64_t FIXED_W_UMIN = ULL(0x0000000000000000);
+    const uint64_t FIXED_H_UMIN = ULL(0x0000000000000000);
+    const uint64_t FIXED_B_UMIN = ULL(0x0000000000000000);
+    const uint64_t FIXED_SMIN[SIMD_NUM_FMTS] = { FIXED_L_SMIN, FIXED_W_SMIN, FIXED_H_SMIN, FIXED_B_SMIN };
+    const uint64_t FIXED_UMIN[SIMD_NUM_FMTS] = { FIXED_L_UMIN, FIXED_W_UMIN, FIXED_H_UMIN, FIXED_B_UMIN };
+
+    // DSP utility functions
+    int32_t bitrev( int32_t value );
+    uint64_t dspSaturate( uint64_t value, int32_t fmt, int32_t sign, uint32_t *overflow );
+    uint64_t checkOverflow( uint64_t value, int32_t fmt, int32_t sign, uint32_t *overflow );
+    uint64_t signExtend( uint64_t value, int32_t signpos );
+    uint64_t addHalfLsb( uint64_t value, int32_t lsbpos );
+    int32_t dspAbs( int32_t a, int32_t fmt, uint32_t *dspctl );
+    int32_t dspAdd( int32_t a, int32_t b, int32_t fmt, int32_t saturate, int32_t sign, uint32_t *dspctl );
+    int32_t dspAddh( int32_t a, int32_t b, int32_t fmt, int32_t round, int32_t sign );
+    int32_t dspSub( int32_t a, int32_t b, int32_t fmt, int32_t saturate, int32_t sign, uint32_t *dspctl );
+    int32_t dspSubh( int32_t a, int32_t b, int32_t fmt, int32_t round, int32_t sign );
+    int32_t dspShll( int32_t a, uint32_t sa, int32_t fmt, int32_t saturate, int32_t sign, uint32_t *dspctl );
+    int32_t dspShrl( int32_t a, uint32_t sa, int32_t fmt, int32_t sign );
+    int32_t dspShra( int32_t a, uint32_t sa, int32_t fmt, int32_t round, int32_t sign, uint32_t *dspctl );
+    int32_t dspMul( int32_t a, int32_t b, int32_t fmt, int32_t saturate, uint32_t *dspctl );
+    int32_t dspMulq( int32_t a, int32_t b, int32_t fmt, int32_t saturate, int32_t round, uint32_t *dspctl );
+    int32_t dspMuleu( int32_t a, int32_t b, int32_t mode, uint32_t *dspctl );
+    int32_t dspMuleq( int32_t a, int32_t b, int32_t mode, uint32_t *dspctl );
+    int64_t dspDpaq( int64_t dspac, int32_t a, int32_t b, int32_t ac, int32_t infmt,
+                     int32_t outfmt, int32_t postsat, int32_t mode, uint32_t *dspctl );
+    int64_t dspDpsq( int64_t dspac, int32_t a, int32_t b, int32_t ac, int32_t infmt,
+                     int32_t outfmt, int32_t postsat, int32_t mode, uint32_t *dspctl );
+    int64_t dspDpa( int64_t dspac, int32_t a, int32_t b, int32_t ac, int32_t fmt, int32_t sign, int32_t mode );
+    int64_t dspDps( int64_t dspac, int32_t a, int32_t b, int32_t ac, int32_t fmt, int32_t sign, int32_t mode );
+    int64_t dspMaq( int64_t dspac, int32_t a, int32_t b, int32_t ac,
+                    int32_t fmt, int32_t mode, int32_t saturate, uint32_t *dspctl );
+    int64_t dspMulsa( int64_t dspac, int32_t a, int32_t b, int32_t ac, int32_t fmt );
+    int64_t dspMulsaq( int64_t dspac, int32_t a, int32_t b, int32_t ac, int32_t fmt, uint32_t *dspctl );
+    void dspCmp( int32_t a, int32_t b, int32_t fmt, int32_t sign, int32_t op, uint32_t *dspctl );
+    int32_t dspCmpg( int32_t a, int32_t b, int32_t fmt, int32_t sign, int32_t op );
+    int32_t dspCmpgd( int32_t a, int32_t b, int32_t fmt, int32_t sign, int32_t op, uint32_t *dspctl );
+    int32_t dspPrece( int32_t a, int32_t infmt, int32_t insign, int32_t outfmt, int32_t outsign, int32_t mode );
+    int32_t dspPrecrqu( int32_t a, int32_t b, uint32_t *dspctl );
+    int32_t dspPrecrq( int32_t a, int32_t b, int32_t fmt, uint32_t *dspctl );
+    int32_t dspPrecrSra( int32_t a, int32_t b, int32_t sa, int32_t fmt, int32_t round );
+    int32_t dspPick( int32_t a, int32_t b, int32_t fmt, uint32_t *dspctl );
+    int32_t dspPack( int32_t a, int32_t b, int32_t fmt );
+    int32_t dspExtr( int64_t dspac, int32_t fmt, int32_t sa, int32_t round,
+                     int32_t saturate, uint32_t *dspctl );
+    int32_t dspExtp( int64_t dspac, int32_t size, uint32_t *dspctl );
+    int32_t dspExtpd( int64_t dspac, int32_t size, uint32_t *dspctl );
+
+    // SIMD pack/unpack utility functions
+    void simdPack( uint64_t *values_ptr, int32_t *reg, int32_t fmt );
+    void simdUnpack( int32_t reg, uint64_t *values_ptr, int32_t fmt, int32_t sign );
+
+    // DSPControl r/w utility functions
+    void writeDSPControl( uint32_t *dspctl, uint32_t value, uint32_t mask );
+    uint32_t readDSPControl( uint32_t *dspctl, uint32_t mask );
+};
+
+#endif
diff --git a/src/arch/mips/dt_constants.hh b/src/arch/mips/dt_constants.hh
new file mode 100755 (executable)
index 0000000..bad1d7b
--- /dev/null
@@ -0,0 +1,216 @@
+/*
+ * Copyright (c) 2006 The Regents of The University of Michigan
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met: redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer;
+ * redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution;
+ * neither the name of the copyright holders nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * Authors: Jaidev Patwardhan
+ */
+
+#ifndef __ARCH_MIPS_DT_CONSTANTS_HH__
+#define __ARCH_MIPS_DT_CONSTANTS_HH__
+
+#include "arch/mips/types.hh"
+//#include "config/full_system.hh"
+
+namespace MipsISA
+{
+  // See the EJTAG Specification - Revision 4.10
+  // Also see PDTrace Specification - Revision 4.30
+
+  // Debug Register - CP0 Reg 23, Sel 0
+  const unsigned Debug_DBD = 31;
+  const unsigned Debug_DM_HI = 30;
+  const unsigned Debug_DM_LO = 30;
+  const unsigned Debug_NODCR = 29;
+  const unsigned Debug_LSNM = 28;
+  const unsigned Debug_DOZE = 27;
+  const unsigned Debug_HALT = 26;
+  const unsigned Debug_COUNTDM = 25;
+  const unsigned Debug_IBUSEP = 24;
+  const unsigned Debug_MCHECKEP = 23;
+  const unsigned Debug_CACHEEP = 22;
+  const unsigned Debug_DBUSEP = 21;
+  const unsigned Debug_IEXI_HI = 20;
+  const unsigned Debug_IEXI_LO = 20;
+  const unsigned Debug_DDBS_IMPR = 19;
+  const unsigned Debug_DDBL_IMPR = 18;
+  const unsigned Debug_EJTAGVER_2 =17;
+  const unsigned Debug_EJTAGVER_1 =16;
+  const unsigned Debug_EJTAGVER_0 =15;
+  const unsigned Debug_EJTAGVER_HI = 17;
+  const unsigned Debug_EJTAGVER_LO = 15;
+  const unsigned Debug_DEXC_CODE_HI = 14;
+  const unsigned Debug_DEXC_CODE_LO = 10;
+  const unsigned Debug_NOSST = 9;
+  const unsigned Debug_SST = 8;
+  const unsigned Debug_OFFLINE = 7;
+  const unsigned Debug_DIBIMPR = 6;
+  const unsigned Debug_DINT = 5;
+  const unsigned Debug_DIB = 4;
+  const unsigned Debug_DDBS = 3;
+  const unsigned Debug_DDBL = 2;
+  const unsigned Debug_DBp = 1;
+  const unsigned Debug_DSS = 0;
+
+
+  // TraceControl Register - CP0 Reg 23, Sel 1
+  const unsigned TraceControl_TS = 31;
+  const unsigned TraceControl_UT = 30;
+  const unsigned TraceControl_TB = 27;
+  const unsigned TraceControl_IO = 26;
+  const unsigned TraceControl_D = 25;
+  const unsigned TraceControl_E = 24;
+  const unsigned TraceControl_K = 23;
+  const unsigned TraceControl_S = 22;
+  const unsigned TraceControl_U = 21;
+  const unsigned TraceControl_ASID_M_HI = 20;
+  const unsigned TraceControl_ASID_M_LO = 13;
+  const unsigned TraceControl_ASID_HI = 12;
+  const unsigned TraceControl_ASID_LO = 5;
+  const unsigned TraceControl_G = 4;
+  const unsigned TraceControl_TFCR = 3;
+  const unsigned TraceControl_TLSM = 2;
+  const unsigned TraceControl_TIM = 1;
+  const unsigned TraceControl_ON = 0;
+
+  // TraceControl2 Register - CP0 Reg 23, Sel 2
+  const unsigned TraceControl2_CPUIDV = 29;
+  const unsigned TraceControl2_CPUID_HI = 28;
+  const unsigned TraceControl2_CPUID_LO = 21;
+  const unsigned TraceControl2_TCV = 20;
+  const unsigned TraceControl2_TCNUM_HI = 19;
+  const unsigned TraceControl2_TCNUM_LO = 12;
+  const unsigned TraceControl2_MODE_HI = 11;
+  const unsigned TraceControl2_MODE_LO = 7;
+  const unsigned TraceControl2_VALIDMODES_HI = 6;
+  const unsigned TraceControl2_VALIDMODES_LO = 5;
+  const unsigned TraceControl2_TBI = 4;
+  const unsigned TraceControl2_TBU = 3;
+  const unsigned TraceControl2_SYP_HI = 2;
+  const unsigned TraceControl2_SYP_LO = 0;
+
+  // UserTraceData Register - CP0 Reg 23, Sel 3
+  // Just holds 32-bits (or 64-bits) of data
+
+  // TraceIBPC Register - CP0 Reg 23, Sel 4
+  const unsigned TraceIBPC_MB = 31;
+  const unsigned TraceIBPC_IE = 28;
+  const unsigned TraceIBPC_ATE = 27;
+  const unsigned TraceIBPC_IBPC8_HI = 26;
+  const unsigned TraceIBPC_IBPC8_LO = 24;
+  const unsigned TraceIBPC_IBPC7_HI = 23;
+  const unsigned TraceIBPC_IBPC7_LO = 21;
+  const unsigned TraceIBPC_IBPC6_HI = 20;
+  const unsigned TraceIBPC_IBPC6_LO = 18;
+  const unsigned TraceIBPC_IBPC5_HI = 17;
+  const unsigned TraceIBPC_IBPC5_LO = 15;
+  const unsigned TraceIBPC_IBPC4_HI = 14;
+  const unsigned TraceIBPC_IBPC4_LO = 12;
+  const unsigned TraceIBPC_IBPC3_HI = 11;
+  const unsigned TraceIBPC_IBPC3_LO = 9;
+  const unsigned TraceIBPC_IBPC2_HI = 8;
+  const unsigned TraceIBPC_IBPC2_LO = 6;
+  const unsigned TraceIBPC_IBPC1_HI = 5;
+  const unsigned TraceIBPC_IBPC1_LO = 3;
+  const unsigned TraceIBPC_IBPC0_HI = 2;
+  const unsigned TraceIBPC_IBPC0_LO = 0;
+
+
+  // TraceDBPC Register - CP0 Reg 23, Sel 5
+  const unsigned TRACEDBPC_MB = 31;
+  const unsigned TRACEDBPC_DE = 28;
+  const unsigned TRACEDBPC_ATE = 27;
+  const unsigned TRACEDBPC_DBPC8_HI = 26;
+  const unsigned TRACEDBPC_DBPC8_LO = 24;
+  const unsigned TRACEDBPC_DBPC7_HI = 23;
+  const unsigned TRACEDBPC_DBPC7_LO = 21;
+  const unsigned TRACEDBPC_DBPC6_HI = 20;
+  const unsigned TRACEDBPC_DBPC6_LO = 18;
+  const unsigned TRACEDBPC_DBPC5_HI = 17;
+  const unsigned TRACEDBPC_DBPC5_LO = 15;
+  const unsigned TRACEDBPC_DBPC4_HI = 14;
+  const unsigned TRACEDBPC_DBPC4_LO = 12;
+  const unsigned TRACEDBPC_DBPC3_HI = 11;
+  const unsigned TRACEDBPC_DBPC3_LO = 9;
+  const unsigned TRACEDBPC_DBPC2_HI = 8;
+  const unsigned TRACEDBPC_DBPC2_LO = 6;
+  const unsigned TRACEDBPC_DBPC1_HI = 5;
+  const unsigned TRACEDBPC_DBPC1_LO = 3;
+  const unsigned TRACEDBPC_DBPC0_HI = 2;
+  const unsigned TRACEDBPC_DBPC0_LO = 0;
+
+  // TraceIBPC2 - Not part of CP0, but part of TRACE
+  const unsigned TraceIBPC_IBPC14_HI = 17;
+  const unsigned TraceIBPC_IBPC14_LO = 15;
+  const unsigned TraceIBPC_IBPC13_HI = 14;
+  const unsigned TraceIBPC_IBPC13_LO = 12;
+  const unsigned TraceIBPC_IBPC12_HI = 11;
+  const unsigned TraceIBPC_IBPC12_LO = 9;
+  const unsigned TraceIBPC_IBPC11_HI = 8;
+  const unsigned TraceIBPC_IBPC11_LO = 6;
+  const unsigned TraceIBPC_IBPC10_HI = 5;
+  const unsigned TraceIBPC_IBPC10_LO = 3;
+  const unsigned TraceIBPC_IBPC9_HI = 2;
+  const unsigned TraceIBPC_IBPC9_LO = 0;
+
+
+  // TraceDBPC2 - Not part of CP0, but part of TRACE
+  const unsigned TRACEDBPC_DBPC14_HI = 17;
+  const unsigned TRACEDBPC_DBPC14_LO = 15;
+  const unsigned TRACEDBPC_DBPC13_HI = 14;
+  const unsigned TRACEDBPC_DBPC13_LO = 12;
+  const unsigned TRACEDBPC_DBPC12_HI = 11;
+  const unsigned TRACEDBPC_DBPC12_LO = 9;
+  const unsigned TRACEDBPC_DBPC11_HI = 8;
+  const unsigned TRACEDBPC_DBPC11_LO = 6;
+  const unsigned TRACEDBPC_DBPC10_HI = 5;
+  const unsigned TRACEDBPC_DBPC10_LO = 3;
+  const unsigned TRACEDBPC_DBPC9_HI = 2;
+  const unsigned TRACEDBPC_DBPC9_LO = 0;
+
+
+  // Debug Register 2 - CP0 Reg 23, Sel 6
+  const unsigned DEBUG2_PRM = 3;
+  const unsigned DEBUG2_DQ = 2;
+  const unsigned DEBUG2_TUP = 1;
+  const unsigned DEBUG2_PACO = 0;
+
+  // DEPC Register - CP0 Reg 24, Sel 0
+  // Debug Exception Program Counter
+  const unsigned DEPC_HI = 31;
+  const unsigned DEPC_LO = 0;
+
+
+
+  // DESAVE - CP0 Reg 31, Sel 0
+  // Debug Exception Save Register
+  const unsigned DESAVE_HI = 31;
+  const unsigned DESAVE_LO = 0;
+
+
+
+} // namespace MipsISA
+
+#endif
index c9e6aa75bd3be548dee852ab785171f52a4af886..39a2fa997b90dbf05fc32c078f008173b7977848 100644 (file)
@@ -54,10 +54,33 @@ FaultName ResetFault::_name = "reset";
 FaultVect ResetFault::_vect = 0x0001;
 FaultStat ResetFault::_count;
 
+FaultName CoprocessorUnusableFault::_name = "Coprocessor Unusable";
+FaultVect CoprocessorUnusableFault::_vect = 0xF001;
+FaultStat CoprocessorUnusableFault::_count;
+
+FaultName ReservedInstructionFault::_name = "Reserved Instruction";
+FaultVect ReservedInstructionFault::_vect = 0x0F01;
+FaultStat ReservedInstructionFault::_count;
+
+FaultName ThreadFault::_name = "thread";
+FaultVect ThreadFault::_vect = 0x00F1;
+FaultStat ThreadFault::_count;
+
+
 FaultName ArithmeticFault::_name = "arith";
 FaultVect ArithmeticFault::_vect = 0x0501;
 FaultStat ArithmeticFault::_count;
 
+FaultName UnimplementedOpcodeFault::_name = "opdec";
+FaultVect UnimplementedOpcodeFault::_vect = 0x0481;
+FaultStat UnimplementedOpcodeFault::_count;
+
+#if !FULL_SYSTEM
+//FaultName PageTableFault::_name = "page_table_fault";
+//FaultVect PageTableFault::_vect = 0x0000;
+//FaultStat PageTableFault::_count;
+#endif
+
 FaultName InterruptFault::_name = "interrupt";
 FaultVect InterruptFault::_vect = 0x0101;
 FaultStat InterruptFault::_count;
@@ -90,21 +113,77 @@ FaultName ItbAcvFault::_name = "iaccvio";
 FaultVect ItbAcvFault::_vect = 0x0081;
 FaultStat ItbAcvFault::_count;
 
-FaultName UnimplementedOpcodeFault::_name = "opdec";
-FaultVect UnimplementedOpcodeFault::_vect = 0x0481;
-FaultStat UnimplementedOpcodeFault::_count;
-
 FaultName FloatEnableFault::_name = "fen";
 FaultVect FloatEnableFault::_vect = 0x0581;
 FaultStat FloatEnableFault::_count;
 
-FaultName PalFault::_name = "pal";
-FaultVect PalFault::_vect = 0x2001;
-FaultStat PalFault::_count;
-
 FaultName IntegerOverflowFault::_name = "intover";
 FaultVect IntegerOverflowFault::_vect = 0x0501;
 FaultStat IntegerOverflowFault::_count;
 
+FaultName DspStateDisabledFault::_name = "intover";
+FaultVect DspStateDisabledFault::_vect = 0x001a;
+FaultStat DspStateDisabledFault::_count;
+
+
+/*void PageTableFault::invoke(ThreadContext *tc)
+{
+    Process *p = tc->getProcessPtr();
+
+    Addr page_addr = p->pTable->pageAlign(vaddr);
+
+    warn("%i: [tid:%i]: %s encountered @ addr %x. Allocating new page for address range %x - %x.\n",
+         curTick, tc->getThreadNum(), name(), vaddr, page_addr, page_addr+VMPageSize);
+
+    p->pTable->allocate(page_addr, VMPageSize);
+
+    return;
+}
+*/
+    /* address is higher than the stack region or in the current stack region
+    if (vaddr > p->stack_base || vaddr > p->stack_min)
+        FaultBase::invoke(tc);
+
+    // We've accessed the next page
+    if (vaddr > p->stack_min - PageBytes) {
+        p->stack_min -= PageBytes;
+        if (p->stack_base - p->stack_min > 8*1024*1024) {
+            warn("Already allocated Over max stack size for one thread\n");
+        }
+        warn("%i: Allocating page for range %x - %x",
+             curTick, p->stack_min, p->stack_min-PageBytes);
+
+        p->pTable->allocate(p->stack_min, PageBytes);
+        warn("Increasing stack size by one page.");
+    } else {
+        FaultBase::invoke(tc);
+        }*/
+
+void ResetFault::invoke(ThreadContext *tc)
+{
+    warn("[tid:%i]: %s encountered.\n", tc->getThreadNum(), name());
+    //tc->getCpuPtr()->reset();
+}
+
+void CoprocessorUnusableFault::invoke(ThreadContext *tc)
+{
+    panic("[tid:%i]: %s encountered.\n", tc->getThreadNum(), name());
+}
+
+void ReservedInstructionFault::invoke(ThreadContext *tc)
+{
+    panic("[tid:%i]: %s encountered.\n", tc->getThreadNum(), name());
+}
+
+void ThreadFault::invoke(ThreadContext *tc)
+{
+    panic("[tid:%i]: %s encountered.\n", tc->getThreadNum(), name());
+}
+
+void DspStateDisabledFault::invoke(ThreadContext *tc)
+{
+    panic("[tid:%i]: %s encountered.\n", tc->getThreadNum(), name());
+}
+
 } // namespace MipsISA
 
index 86c74241331594f154c7198eb0f25da8105d942c..05a86acd7a3bead7db730c2f43dbf3d23ffd8e5d 100644 (file)
@@ -80,6 +80,42 @@ class AlignmentFault : public MipsFault
     bool isAlignmentFault() {return true;}
 };
 
+class UnimplementedOpcodeFault : public MipsFault
+{
+  private:
+    static FaultName _name;
+    static FaultVect _vect;
+    static FaultStat _count;
+  public:
+    FaultName name() {return _name;}
+    FaultVect vect() {return _vect;}
+    FaultStat & countStat() {return _count;}
+};
+
+#if !FULL_SYSTEM
+//class PageTableFault : public MipsFault
+//{
+//private:
+//  Addr vaddr;
+//  static FaultName _name;
+//  static FaultVect _vect;
+//  static FaultStat _count;
+//public:
+//  PageTableFault(Addr va)
+//      : vaddr(va) {}
+//  FaultName name() {return _name;}
+//  FaultVect vect() {return _vect;}
+//  FaultStat & countStat() {return _count;}
+//  void invoke(ThreadContext * tc);
+//};
+
+static inline Fault genPageTableFault(Addr va)
+{
+    return new PageTableFault(va);
+}
+#endif
+
+
 static inline Fault genMachineCheckFault()
 {
     return new MachineCheckFault;
@@ -100,8 +136,49 @@ class ResetFault : public MipsFault
     FaultName name() {return _name;}
     FaultVect vect() {return _vect;}
     FaultStat & countStat() {return _count;}
+    void invoke(ThreadContext * tc);
 };
 
+class CoprocessorUnusableFault : public MipsFault
+{
+  private:
+    static FaultName _name;
+    static FaultVect _vect;
+    static FaultStat _count;
+  public:
+    FaultName name() {return _name;}
+    FaultVect vect() {return _vect;}
+    FaultStat & countStat() {return _count;}
+    void invoke(ThreadContext * tc);
+};
+
+class ReservedInstructionFault : public MipsFault
+{
+  private:
+    static FaultName _name;
+    static FaultVect _vect;
+    static FaultStat _count;
+  public:
+    FaultName name() {return _name;}
+    FaultVect vect() {return _vect;}
+    FaultStat & countStat() {return _count;}
+    void invoke(ThreadContext * tc);
+};
+
+class ThreadFault : public MipsFault
+{
+  private:
+    static FaultName _name;
+    static FaultVect _vect;
+    static FaultStat _count;
+  public:
+    FaultName name() {return _name;}
+    FaultVect vect() {return _vect;}
+    FaultStat & countStat() {return _count;}
+    void invoke(ThreadContext * tc);
+};
+
+
 class ArithmeticFault : public MipsFault
 {
   protected:
@@ -217,18 +294,6 @@ class ItbAcvFault : public MipsFault
     FaultStat & countStat() {return _count;}
 };
 
-class UnimplementedOpcodeFault : public MipsFault
-{
-  private:
-    static FaultName _name;
-    static FaultVect _vect;
-    static FaultStat _count;
-  public:
-    FaultName name() {return _name;}
-    FaultVect vect() {return _vect;}
-    FaultStat & countStat() {return _count;}
-};
-
 class FloatEnableFault : public MipsFault
 {
   private:
@@ -241,10 +306,8 @@ class FloatEnableFault : public MipsFault
     FaultStat & countStat() {return _count;}
 };
 
-class PalFault : public MipsFault
+class IntegerOverflowFault : public MipsFault
 {
-  protected:
-    bool skipFaultingInstruction() {return true;}
   private:
     static FaultName _name;
     static FaultVect _vect;
@@ -255,7 +318,7 @@ class PalFault : public MipsFault
     FaultStat & countStat() {return _count;}
 };
 
-class IntegerOverflowFault : public MipsFault
+class DspStateDisabledFault : public MipsFault
 {
   private:
     static FaultName _name;
@@ -265,6 +328,7 @@ class IntegerOverflowFault : public MipsFault
     FaultName name() {return _name;}
     FaultVect vect() {return _vect;}
     FaultStat & countStat() {return _count;}
+    void invoke(ThreadContext * tc);
 };
 
 } // MipsISA namespace
index 35815bf1f823b84a8ff16ce8433ba0c6a974e2ef..87be5ad13f7e2c7eafb2781e73f4138bf487e2e8 100644 (file)
@@ -28,6 +28,7 @@
 //
 // Authors: Korey Sewell
 
+//@TODO: Make sure the naming convention is consistent here.
 ////////////////////////////////////////////////////////////////////
 //
 // Bitfield definitions.
@@ -58,6 +59,7 @@ def bitfield RT_RD    <20:11>;
 def bitfield RD              <15:11>;
 
 def bitfield INTIMM      <15: 0>;
+def bitfield RS_RT_INTIMM <25: 0>;
 
 // Floating-point operate format
 def bitfield FMT      <25:21>;
@@ -81,7 +83,7 @@ def bitfield BRANCH_CC <20:18>;
 // CP0 Register Select
 def bitfield SEL       < 2: 0>;
 
-// Interrupts
+// INTERRUPTS
 def bitfield SC       < 5: 5>;
 
 // Branch format
@@ -100,3 +102,20 @@ def bitfield LSB   <10: 6>;
 
 // M5 instructions
 def bitfield M5FUNC <7:0>;
+
+// DSP instructions
+def bitfield OP        <10:6>;
+def bitfield OP_HI     <10:9>;
+def bitfield OP_LO     <8:6>;
+def bitfield DSPSA     <23:21>;
+def bitfield HILOSA    <25:20>;
+def bitfield RDDSPMASK <21:16>;
+def bitfield WRDSPMASK <16:11>;
+def bitfield ACSRC     <22:21>;
+def bitfield ACDST     <12:11>;
+def bitfield BP        <12:11>;
+
+// MT Instructions
+def bitfield POS   <10: 6>;
+def bitfield MT_U     <5:5>;
+def bitfield MT_H     <4:4>;
index b5d1df4fc2a0cf35c5f49bd89b261520a02fd542..0af84e36bf5f07b8e3d83f96be000ede12a11582 100644 (file)
@@ -35,7 +35,7 @@
 // The following instructions are specified in the MIPS32 ISA
 // Specification. Decoding closely follows the style specified
 // in the MIPS32 ISA specification document starting with Table
-// A-2 (document available @ www.mips.com)
+// A-2 (document available @ http://www.mips.com)
 //
 decode OPCODE_HI default Unknown::unknown() {
     //Table A-2
@@ -55,7 +55,7 @@ decode OPCODE_HI default Unknown::unknown() {
                     //functions
                     0x0: decode RS  {
                         0x0: decode RT_RD {
-                            0x0: decode SA default Nop::nop(){
+                            0x0: decode SA default Nop::nop() {
                                 0x1: WarnUnimpl::ssnop();
                                 0x3: WarnUnimpl::ehb();
                             }
@@ -123,10 +123,9 @@ decode OPCODE_HI default Unknown::unknown() {
                     }
 
                     0x1: decode HINT {
-                        0x1: jalr_hb({{ Rd = NNPC; NNPC = Rs; }}, IsCall, Link
+                        0x1: jalr_hb({{ Rd = NNPC; NNPC = Rs; }}, IsCall
                                      , ClearHazards);
-                        default: jalr({{ Rd = NNPC; NNPC = Rs; }}, IsCall,
-                                      Link);
+                        default: jalr({{ Rd = NNPC; NNPC = Rs; }}, IsCall);
                     }
                 }
 
@@ -144,34 +143,29 @@ decode OPCODE_HI default Unknown::unknown() {
             }
 
             0x2: decode FUNCTION_LO {
-                format HiLoMiscOp {
-                    0x0: mfhi({{ Rd = HI; }});
-                    0x1: mthi({{ HI = Rs; }});
-                    0x2: mflo({{ Rd = LO; }});
-                    0x3: mtlo({{ LO = Rs; }});
-                }
+                0x0: HiLoRsSelOp::mfhi({{ Rd = HI_RS_SEL; }});
+                0x1: HiLoRdSelOp::mthi({{ HI_RD_SEL = Rs; }});
+                0x2: HiLoRsSelOp::mflo({{ Rd = LO_RS_SEL; }});
+                0x3: HiLoRdSelOp::mtlo({{ LO_RD_SEL = Rs; }});
             }
 
             0x3: decode FUNCTION_LO {
+                format HiLoRdSelValOp {
+                    0x0: mult({{ val = Rs.sd * Rt.sd; }});
+                    0x1: multu({{ val = Rs.ud * Rt.ud; }});
+                }
+
                 format HiLoOp {
-                    0x0: mult({{ int64_t val = Rs.sd * Rt.sd; }});
-                    0x1: multu({{ uint64_t val = Rs.ud * Rt.ud; }});
-                    0x2: div({{ //Initialized to placate g++
-                                int64_t val = 0;
-                                if (Rt.sd != 0) {
-                                    int64_t hi = Rs.sd % Rt.sd;
-                                    int64_t lo = Rs.sd / Rt.sd;
-                                    val = (hi << 32) | lo;
-                                }
-                             }});
-                    0x3: divu({{ //Initialized to placate g++
-                                 uint64_t val = 0;
-                                 if (Rt.ud != 0) {
-                                     uint64_t hi = Rs.ud % Rt.ud;
-                                     uint64_t lo = Rs.ud / Rt.ud;
-                                     val = (hi << 32) | lo;
-                                 }
-                              }});
+                    0x2: div({{ if (Rt.sd != 0) {
+                        HI0 = Rs.sd % Rt.sd;
+                        LO0 = Rs.sd / Rt.sd;
+                    }
+                    }});
+                    0x3: divu({{ if (Rt.ud != 0) {
+                        HI0 = Rs.ud % Rt.ud;
+                        LO0 = Rs.ud / Rt.ud;
+                    }
+                    }});
                 }
             }
 
@@ -245,6 +239,8 @@ decode OPCODE_HI default Unknown::unknown() {
             }
 
             0x3: decode REGIMM_LO {
+                // from Table 5-4 MIPS32 REGIMM Encoding of rt Field (DSP ASE MANUAL)
+                0x4: DspBranch::bposge32({{ cond = (dspctl<5:0> >= 32); }});
                 format WarnUnimpl {
                     0x7: synci();
                 }
@@ -273,7 +269,15 @@ decode OPCODE_HI default Unknown::unknown() {
             0x0: addi({{ Rt.sw = Rs.sw + imm; /*Trap If Overflow*/}});
             0x1: addiu({{ Rt.sw = Rs.sw + imm;}});
             0x2: slti({{ Rt.sw = ( Rs.sw < imm) ? 1 : 0 }});
-            0x3: sltiu({{ Rt.uw = ( Rs.uw < (uint32_t)sextImm ) ? 1 : 0 }});
+
+            //Edited to include MIPS AVP Pass/Fail instructions and
+            //default to the sltiu instruction
+            0x3: decode RS_RT_INTIMM {
+                0xabc1: BasicOp::fail({{ exitSimLoop("AVP/SRVP Test Failed"); }});
+                0xabc2: BasicOp::pass({{ exitSimLoop("AVP/SRVP Test Passed"); }});
+              default: sltiu({{ Rt.uw = ( Rs.uw < (uint32_t)sextImm ) ? 1 : 0 }});
+            }
+
             0x4: andi({{ Rt.sw = Rs.sw & zextImm;}});
             0x5: ori({{ Rt.sw = Rs.sw | zextImm;}});
             0x6: xori({{ Rt.sw = Rs.sw ^ zextImm;}});
@@ -289,47 +293,296 @@ decode OPCODE_HI default Unknown::unknown() {
         0x0: decode RS_MSB {
             0x0: decode RS {
                 format CP0Control {
-                    0x0: mfc0({{ Rt = xc->readMiscRegNoEffect(RD << 5 | SEL); }});
-                    0x4: mtc0({{ xc->setMiscRegNoEffect(RD << 5 | SEL, Rt); }});
+                    0x0: mfc0({{  Rt = CP0_RD_SEL; }});
+                    0x4: mtc0({{  CP0_RD_SEL = Rt; }});
                 }
 
-                format MipsMT {
-                    0x8: mftr();
-                    0xC: mttr();
-                    0xB: decode RD {
-                        0x0: decode SC {
-                            0x0: dvpe();
-                            0x1: evpe();
-                        }
-                        0x1: decode SC {
-                            0x0: dmt();
-                            0x1: emt();
-                            0xC: decode SC {
-                                0x0: di();
-                                0x1: ei();
+
+                format MT_MFTR { // Decode MIPS MT MFTR instruction into sub-instructions
+                    0x8: decode MT_U {
+                        0x0: mftc0({{ data = xc->readRegOtherThread((RT << 3 | SEL) +
+                                                                    Ctrl_Base_DepTag);
+                                   }});
+                        0x1: decode SEL {
+                            0x0: mftgpr({{ data = xc->readRegOtherThread(RT); }});
+                            0x1: decode RT {
+                                0x0: mftlo_dsp0({{ data = xc->readRegOtherThread(MipsISA::DSPLo0); }});
+                                0x1: mfthi_dsp0({{ data = xc->readRegOtherThread(MipsISA::DSPHi0); }});
+                                0x2: mftacx_dsp0({{ data = xc->readRegOtherThread(MipsISA::DSPACX0); }});
+                                0x4: mftlo_dsp1({{ data = xc->readRegOtherThread(MipsISA::DSPLo1); }});
+                                0x5: mfthi_dsp1({{ data = xc->readRegOtherThread(MipsISA::DSPHi1); }});
+                                0x6: mftacx_dsp1({{ data = xc->readRegOtherThread(MipsISA::DSPACX1); }});
+                                0x8: mftlo_dsp2({{ data = xc->readRegOtherThread(MipsISA::DSPLo2); }});
+                                0x9: mfthi_dsp2({{ data = xc->readRegOtherThread(MipsISA::DSPHi2); }});
+                                0x10: mftacx_dsp2({{ data = xc->readRegOtherThread(MipsISA::DSPACX2); }});
+                                0x12: mftlo_dsp3({{ data = xc->readRegOtherThread(MipsISA::DSPLo3); }});
+                                0x13: mfthi_dsp3({{ data = xc->readRegOtherThread(MipsISA::DSPHi3); }});
+                                0x14: mftacx_dsp3({{ data = xc->readRegOtherThread(MipsISA::DSPACX3); }});
+                                0x16: mftdsp({{ data = xc->readRegOtherThread(MipsISA::DSPControl); }});
                             }
+                            0x2: decode MT_H {
+                                0x0: mftc1({{ data = xc->readRegOtherThread(RT +
+                                                                            FP_Base_DepTag);
+                                           }});
+                                0x1: mfthc1({{ data = xc->readRegOtherThread(RT +
+                                                                             FP_Base_DepTag);
+                                           }});
+                            }
+                            0x3: cftc1({{ uint32_t fcsr_val = xc->readRegOtherThread(MipsISA::FCSR +
+                                                                            FP_Base_DepTag);
+                                          switch (RT)
+                                          {
+                                               case 0:
+                                                 data = xc->readRegOtherThread(MipsISA::FIR +
+                                                                               Ctrl_Base_DepTag);
+                                                 break;
+                                               case 25:
+                                                 data = 0 | fcsr_val & 0xFE000000 >> 24
+                                                          | fcsr_val & 0x00800000 >> 23;
+                                                 break;
+                                               case 26:
+                                                 data = 0 | fcsr_val & 0x0003F07C;
+                                                 break;
+                                               case 28:
+                                                 data = 0 | fcsr_val & 0x00000F80
+                                                          | fcsr_val & 0x01000000 >> 21
+                                                          | fcsr_val & 0x00000003;
+                                                 break;
+                                               case 31:
+                                                 data = fcsr_val;
+                                                 break;
+                                               default:
+                                                 fatal("FP Control Value (%d) Not Valid");
+                                          }
+                                        }});
                         }
                     }
                 }
 
-                format FailUnimpl {
-                    0xA: rdpgpr();
-                    0xE: wrpgpr();
+                format MT_MTTR { // Decode MIPS MT MTTR instruction into sub-instructions
+                    0xC: decode MT_U {
+                        0x0: mttc0({{ xc->setRegOtherThread((RD << 3 | SEL) + Ctrl_Base_DepTag,
+                                                            Rt);
+                                   }});
+                        0x1: decode SEL {
+                            0x0: mttgpr({{ xc->setRegOtherThread(RD, Rt); }});
+                            0x1: decode RT {
+                                0x0: mttlo_dsp0({{ xc->setRegOtherThread(MipsISA::DSPLo0, Rt);
+                                                }});
+                                0x1: mtthi_dsp0({{ xc->setRegOtherThread(MipsISA::DSPHi0,
+                                                                         Rt);
+                                                }});
+                                0x2: mttacx_dsp0({{ xc->setRegOtherThread(MipsISA::DSPACX0,
+                                                                          Rt);
+                                                 }});
+                                0x4: mttlo_dsp1({{ xc->setRegOtherThread(MipsISA::DSPLo1,
+                                                                         Rt);
+                                                }});
+                                0x5: mtthi_dsp1({{ xc->setRegOtherThread(MipsISA::DSPHi1,
+                                                                         Rt);
+                                                }});
+                                0x6: mttacx_dsp1({{ xc->setRegOtherThread(MipsISA::DSPACX1,
+                                                                          Rt);
+                                                 }});
+                                0x8: mttlo_dsp2({{ xc->setRegOtherThread(MipsISA::DSPLo2,
+                                                                         Rt);
+                                                }});
+                                0x9: mtthi_dsp2({{ xc->setRegOtherThread(MipsISA::DSPHi2,
+                                                                         Rt);
+                                                }});
+                                0x10: mttacx_dsp2({{ xc->setRegOtherThread(MipsISA::DSPACX2,
+                                                                           Rt);
+                                                  }});
+                                0x12: mttlo_dsp3({{ xc->setRegOtherThread(MipsISA::DSPLo3,
+                                                                          Rt);
+                                                 }});
+                                0x13: mtthi_dsp3({{ xc->setRegOtherThread(MipsISA::DSPHi3,
+                                                                          Rt);
+                                                 }});
+                                0x14: mttacx_dsp3({{ xc->setRegOtherThread(MipsISA::DSPACX3, Rt);
+                                                  }});
+                                0x16: mttdsp({{ xc->setRegOtherThread(MipsISA::DSPControl, Rt); }});
+                            }
+                            0x2: mttc1({{ uint64_t data = xc->readRegOtherThread(RD +
+                                                                                FP_Base_DepTag);
+                                          data = insertBits(data, top_bit, bottom_bit, Rt);
+                                          xc->setRegOtherThread(RD + FP_Base_DepTag, data);
+                                       }});
+                            0x3: cttc1({{ uint32_t data;
+                                          switch (RD)
+                                          {
+                                            case 25:
+                                              data = 0 | (Rt.uw<7:1> << 25) // move 31...25
+                                                  | (FCSR & 0x01000000) // bit 24
+                                                  | (FCSR & 0x004FFFFF);// bit 22...0
+                                              break;
+
+                                            case 26:
+                                              data = 0 | (FCSR & 0xFFFC0000) // move 31...18
+                                                  | Rt.uw<17:12> << 12           // bit 17...12
+                                                  | (FCSR & 0x00000F80) << 7// bit 11...7
+                                                  | Rt.uw<6:2> << 2              // bit 6...2
+                                                  | (FCSR & 0x00000002);     // bit 1...0
+                                              break;
+
+                                            case 28:
+                                              data = 0 | (FCSR & 0xFE000000) // move 31...25
+                                                  | Rt.uw<2:2> << 24       // bit 24
+                                                  | (FCSR & 0x00FFF000) << 23// bit 23...12
+                                                  | Rt.uw<11:7> << 7       // bit 24
+                                                  | (FCSR & 0x000007E)
+                                                  | Rt.uw<1:0>;// bit 22...0
+                                              break;
+
+                                            case 31:
+                                              data  = Rt.uw;
+                                              break;
+
+                                            default:
+                                              panic("FP Control Value (%d) Not Available. Ignoring Access to"
+                                                    "Floating Control Status Register", FS);
+                                          }
+                                          xc->setRegOtherThread(FCSR, data);
+                                       }});
+                        }
+                    }
+                }
+
+
+                0xB: decode RD {
+                    format MT_Control {
+                        0x0: decode POS {
+                            0x0: decode SEL {
+                                0x1: decode SC {
+                                    0x0: dvpe({{ Rt = MVPControl;
+                                                 if (VPEConf0<VPEC0_MVP:> == 1) {
+                                                     MVPControl = insertBits(MVPControl, MVPC_EVP, 0);
+                                                 }
+                                              }});
+                                    0x1: evpe({{ Rt = MVPControl;
+                                                 if (VPEConf0<VPEC0_MVP:> == 1) {
+                                                     MVPControl = insertBits(MVPControl, MVPC_EVP, 1);
+                                                 }
+                                              }});
+                                }
+                            }
+                        }
+
+                        0x1: decode POS {
+                            0xF: decode SEL {
+                                0x1: decode SC {
+                                    0x0: dmt({{ Rt = VPEControl;
+                                                VPEControl = insertBits(VPEControl, VPEC_TE, 0);
+                                         }});
+                                    0x1: emt({{ Rt = VPEControl;
+                                                VPEControl = insertBits(VPEControl, VPEC_TE, 1);
+                                         }});
+
+                                }
+                            }
+                        }
+                    }
+                    0xC: decode POS {
+                      0x0: decode SC {
+                        0x0: CP0Control::di({{
+                            if(Config_AR >= 1) // Rev 2.0 or beyond?
+                                {
+                                  Rt = Status;
+                                  Status_IE = 0;
+                                }
+                            else // Enable this else branch once we actually set values for Config on init
+                              {
+                                fault = new ReservedInstructionFault();
+                              }
+                          }});
+                        0x1: CP0Control::ei({{
+                            if(Config_AR >= 1)
+                              {
+                                Rt = Status;
+                                Status_IE = 1;
+                              }
+                            else
+                              {
+                                fault = new ReservedInstructionFault();
+                              }
+                          }});
+                      }
+                    }
+                }
+
+                format CP0Control {
+                    0xA: rdpgpr({{
+                      if(Config_AR >= 1)
+                        { // Rev 2 of the architecture
+                          Rd = xc->tcBase()->readIntReg(Rt + NumIntRegs * SRSCtl_PSS);
+                        }
+                      else
+                        {
+                          fault = new ReservedInstructionFault();
+                        }
+                         }});
+                    0xE: wrpgpr({{
+                      if(Config_AR >= 1)
+                        { // Rev 2 of the architecture
+                          xc->tcBase()->setIntReg(Rd + NumIntRegs * SRSCtl_PSS,Rt);
+                        }
+                      else
+                        {
+                          fault = new ReservedInstructionFault();
+                        }
+
+                         }});
+
                 }
+
             }
 
             //Table A-12 MIPS32 COP0 Encoding of Function Field When rs=CO
             0x1: decode FUNCTION {
-                format FailUnimpl {
-                    0x01: tlbr();
-                    0x02: tlbwi();
-                    0x06: tlbwr();
-                    0x08: tlbp();
+              format CP0Control {
+                0x18: eret({{
+                  if(Status_ERL == 1){
+                    Status_ERL = 0;
+                    NPC = ErrorEPC;
+                  }
+                  else{
+                    NPC = EPC;
+                    Status_EXL = 0;
+                    if(Config_AR >= 1 && SRSCtl_HSS > 0 && Status_BEV == 0){
+                      SRSCtl_CSS = SRSCtl_PSS;
+                    }
+                  }
+                  //             LLFlag = 0;
+                  // ClearHazards(); ?
+                }});
+
+                0x1F: deret({{
+                  // if(EJTagImplemented()) {
+                  if(Debug_DM == 1){
+                    Debug_DM = 1;
+                    Debug_IEXI = 0;
+                    NPC = DEPC;
+                  }
+                  else
+                    {
+                      // Undefined;
+                    }
+                  //} // EJTag Implemented
+                  //else {
+                  // Reserved Instruction Exception
+                  //}
+                }});
+              }
+
+              format FailUnimpl {
+                  0x01: tlbr(); // Need to hook up to TLB
+                  0x02: tlbwi(); // Need to hook up to TLB
+                    0x06: tlbwr();// Need to hook up to TLB
+                    0x08: tlbp();// Need to hook up to TLB
 
-                    0x18: eret();
-                    0x1F: deret();
                     0x20: wait();
                 }
+
             }
         }
 
@@ -949,45 +1202,37 @@ decode OPCODE_HI default Unknown::unknown() {
         0x4: decode FUNCTION_HI {
             0x0: decode FUNCTION_LO {
                 0x2: IntOp::mul({{ int64_t temp1 = Rs.sd * Rt.sd;
-                                   Rd.sw = temp1<31:0>
+                                   Rd.sw = temp1<31:0>;
                                 }});
 
-                format HiLoOp {
-                    0x0: madd({{ int64_t val = ((int64_t) HI << 32 | LO) +
-                                          (Rs.sd * Rt.sd);
-                              }});
-                    0x1: maddu({{ uint64_t val = ((uint64_t) HI << 32 | LO) +
-                                           (Rs.ud * Rt.ud);
-                               }});
-                    0x4: msub({{ int64_t val = ((int64_t) HI << 32 | LO) -
-                                          (Rs.sd * Rt.sd);
-                              }});
-                    0x5: msubu({{ uint64_t val = ((uint64_t) HI << 32 | LO) -
-                                           (Rs.ud * Rt.ud);
-                               }});
+                format HiLoRdSelValOp {
+                    0x0: madd({{ val = ((int64_t)HI_RD_SEL << 32 | LO_RD_SEL) + (Rs.sd * Rt.sd); }});
+                    0x1: maddu({{ val = ((uint64_t)HI_RD_SEL << 32 | LO_RD_SEL) + (Rs.ud * Rt.ud); }});
+                    0x4: msub({{ val = ((int64_t)HI_RD_SEL << 32 | LO_RD_SEL) - (Rs.sd * Rt.sd); }});
+                    0x5: msubu({{ val = ((uint64_t)HI_RD_SEL << 32 | LO_RD_SEL) - (Rs.ud * Rt.ud); }});
                 }
             }
 
             0x4: decode FUNCTION_LO {
                 format BasicOp {
                     0x0: clz({{ int cnt = 32;
-                                for (int idx = 31; idx >= 0; idx--) {
-                                    if( Rs<idx:idx> == 1) {
-                                        cnt = 31 - idx;
-                                        break;
-                                    }
-                                }
-                                Rd.uw = cnt;
-                             }});
+                          for (int idx = 31; idx >= 0; idx--) {
+                              if( Rs<idx:idx> == 1) {
+                                  cnt = 31 - idx;
+                                  break;
+                              }
+                          }
+                          Rd.uw = cnt;
+                       }});
                     0x1: clo({{ int cnt = 32;
-                                for (int idx = 31; idx >= 0; idx--) {
-                                    if( Rs<idx:idx> == 0) {
-                                        cnt = 31 - idx;
-                                        break;
-                                    }
-                                }
-                                Rd.uw = cnt;
-                             }});
+                          for (int idx = 31; idx >= 0; idx--) {
+                              if( Rs<idx:idx> == 0) {
+                                  cnt = 31 - idx;
+                                  break;
+                              }
+                          }
+                          Rd.uw = cnt;
+                        }});
                 }
             }
 
@@ -1010,9 +1255,337 @@ decode OPCODE_HI default Unknown::unknown() {
             }
 
             0x1: decode FUNCTION_LO {
-                format MipsMT {
-                    0x0: fork();
-                    0x1: yield();
+                format MT_Control {
+                    0x0: fork({{ forkThread(xc->tcBase(), fault, RD, Rs, Rt); }},
+                              UserMode);
+                    0x1: yield({{ Rd.sw = yieldThread(xc->tcBase(), fault, Rs.sw, YQMask); }},
+                               UserMode);
+                }
+
+                //Table 5-9 MIPS32 LX Encoding of the op Field (DSP ASE MANUAL)
+                0x2: decode OP_HI {
+                    0x0: decode OP_LO {
+                        format LoadIndexedMemory {
+                            0x0: lwx({{ Rd.sw = Mem.sw; }});
+                            0x4: lhx({{ Rd.sw = Mem.sh; }});
+                            0x6: lbux({{ Rd.uw = Mem.ub; }});
+                        }
+                    }
+                }
+                0x4: DspIntOp::insv({{ int pos = dspctl<5:0>;
+                                       int size = dspctl<12:7>-1;
+                                       Rt.uw = insertBits( Rt.uw, pos+size, pos, Rs.uw<size:0> ); }});
+            }
+
+            0x2: decode FUNCTION_LO {
+
+                //Table 5-5 MIPS32 ADDU.QB Encoding of the op Field (DSP ASE MANUAL)
+                0x0: decode OP_HI {
+                    0x0: decode OP_LO {
+                        format DspIntOp {
+                            0x0: addu_qb({{ Rd.uw = dspAdd( Rs.uw, Rt.uw, SIMD_FMT_QB,
+                                                            NOSATURATE, UNSIGNED, &dspctl ); }});
+                            0x1: subu_qb({{ Rd.uw = dspSub( Rs.uw, Rt.uw, SIMD_FMT_QB,
+                                                            NOSATURATE, UNSIGNED, &dspctl ); }});
+                            0x4: addu_s_qb({{ Rd.uw = dspAdd( Rs.uw, Rt.uw, SIMD_FMT_QB,
+                                                              SATURATE, UNSIGNED, &dspctl ); }});
+                            0x5: subu_s_qb({{ Rd.uw = dspSub( Rs.uw, Rt.uw, SIMD_FMT_QB,
+                                                              SATURATE, UNSIGNED, &dspctl ); }});
+                            0x6: muleu_s_ph_qbl({{ Rd.uw = dspMuleu( Rs.uw, Rt.uw,
+                                                                     MODE_L, &dspctl ); }});
+                            0x7: muleu_s_ph_qbr({{ Rd.uw = dspMuleu( Rs.uw, Rt.uw,
+                                                                     MODE_R, &dspctl ); }});
+                        }
+                    }
+                    0x1: decode OP_LO {
+                        format DspIntOp {
+                            0x0: addu_ph({{ Rd.uw = dspAdd( Rs.uw, Rt.uw, SIMD_FMT_PH,
+                                                            NOSATURATE, UNSIGNED, &dspctl ); }});
+                            0x1: subu_ph({{ Rd.uw = dspSub( Rs.uw, Rt.uw, SIMD_FMT_PH,
+                                                            NOSATURATE, UNSIGNED, &dspctl ); }});
+                            0x2: addq_ph({{ Rd.uw = dspAdd( Rs.uw, Rt.uw, SIMD_FMT_PH,
+                                                            NOSATURATE, SIGNED, &dspctl ); }});
+                            0x3: subq_ph({{ Rd.uw = dspSub( Rs.uw, Rt.uw, SIMD_FMT_PH,
+                                                            NOSATURATE, SIGNED, &dspctl ); }});
+                            0x4: addu_s_ph({{ Rd.uw = dspAdd( Rs.uw, Rt.uw, SIMD_FMT_PH,
+                                                              SATURATE, UNSIGNED, &dspctl ); }});
+                            0x5: subu_s_ph({{ Rd.uw = dspSub( Rs.uw, Rt.uw, SIMD_FMT_PH,
+                                                              SATURATE, UNSIGNED, &dspctl ); }});
+                            0x6: addq_s_ph({{ Rd.uw = dspAdd( Rs.uw, Rt.uw, SIMD_FMT_PH,
+                                                              SATURATE, SIGNED, &dspctl ); }});
+                            0x7: subq_s_ph({{ Rd.uw = dspSub( Rs.uw, Rt.uw, SIMD_FMT_PH,
+                                                              SATURATE, SIGNED, &dspctl ); }});
+                        }
+                    }
+                    0x2: decode OP_LO {
+                        format DspIntOp {
+                            0x0: addsc({{ int64_t dresult;
+                                          dresult = Rs.ud + Rt.ud;
+                                          Rd.sw = dresult<31:0>;
+                                          dspctl = insertBits( dspctl, 13, 13,
+                                                               dresult<32:32> ); }});
+                            0x1: addwc({{ int64_t dresult;
+                                          dresult = Rs.sd + Rt.sd + dspctl<13:13>;
+                                          Rd.sw = dresult<31:0>;
+                                          if( dresult<32:32> != dresult<31:31> )
+                                              dspctl = insertBits( dspctl, 20, 20, 1 ); }});
+                            0x2: modsub({{ Rd.sw = (Rs.sw == 0) ? Rt.sw<23:8> : Rs.sw - Rt.sw<7:0>; }});
+                            0x4: raddu_w_qb({{ Rd.uw = Rs.uw<31:24> + Rs.uw<23:16> +
+                                                   Rs.uw<15:8> + Rs.uw<7:0>; }});
+                            0x6: addq_s_w({{ Rd.sw = dspAdd( Rs.sw, Rt.sw, SIMD_FMT_W,
+                                                             SATURATE, SIGNED, &dspctl ); }});
+                            0x7: subq_s_w({{ Rd.sw = dspSub( Rs.sw, Rt.sw, SIMD_FMT_W,
+                                                             SATURATE, SIGNED, &dspctl ); }});
+                        }
+                    }
+                    0x3: decode OP_LO {
+                        format DspIntOp {
+                            0x4: muleq_s_w_phl({{ Rd.sw = dspMuleq( Rs.sw, Rt.sw,
+                                                                    MODE_L, &dspctl ); }});
+                            0x5: muleq_s_w_phr({{ Rd.sw = dspMuleq( Rs.sw, Rt.sw,
+                                                                    MODE_R, &dspctl ); }});
+                            0x6: mulq_s_ph({{ Rd.sw = dspMulq( Rs.sw, Rt.sw, SIMD_FMT_PH,
+                                                               SATURATE, NOROUND, &dspctl ); }});
+                            0x7: mulq_rs_ph({{ Rd.sw = dspMulq( Rs.sw, Rt.sw, SIMD_FMT_PH,
+                                                                SATURATE, ROUND, &dspctl ); }});
+                        }
+                    }
+                }
+
+                //Table 5-6 MIPS32 CMPU_EQ_QB Encoding of the op Field (DSP ASE MANUAL)
+                0x1: decode OP_HI {
+                    0x0: decode OP_LO {
+                        format DspIntOp {
+                            0x0: cmpu_eq_qb({{ dspCmp( Rs.uw, Rt.uw, SIMD_FMT_QB,
+                                                       UNSIGNED, CMP_EQ, &dspctl ); }});
+                            0x1: cmpu_lt_qb({{ dspCmp( Rs.uw, Rt.uw, SIMD_FMT_QB,
+                                                       UNSIGNED, CMP_LT, &dspctl ); }});
+                            0x2: cmpu_le_qb({{ dspCmp( Rs.uw, Rt.uw, SIMD_FMT_QB,
+                                                       UNSIGNED, CMP_LE, &dspctl ); }});
+                            0x3: pick_qb({{ Rd.uw = dspPick( Rs.uw, Rt.uw,
+                                                             SIMD_FMT_QB, &dspctl ); }});
+                            0x4: cmpgu_eq_qb({{ Rd.uw = dspCmpg( Rs.uw, Rt.uw, SIMD_FMT_QB,
+                                                                 UNSIGNED, CMP_EQ ); }});
+                            0x5: cmpgu_lt_qb({{ Rd.uw = dspCmpg( Rs.uw, Rt.uw, SIMD_FMT_QB,
+                                                                 UNSIGNED, CMP_LT ); }});
+                            0x6: cmpgu_le_qb({{ Rd.uw = dspCmpg( Rs.uw, Rt.uw, SIMD_FMT_QB,
+                                                                 UNSIGNED, CMP_LE ); }});
+                        }
+                    }
+                    0x1: decode OP_LO {
+                        format DspIntOp {
+                            0x0: cmp_eq_ph({{ dspCmp( Rs.uw, Rt.uw, SIMD_FMT_PH,
+                                                      SIGNED, CMP_EQ, &dspctl ); }});
+                            0x1: cmp_lt_ph({{ dspCmp( Rs.uw, Rt.uw, SIMD_FMT_PH,
+                                                      SIGNED, CMP_LT, &dspctl ); }});
+                            0x2: cmp_le_ph({{ dspCmp( Rs.uw, Rt.uw, SIMD_FMT_PH,
+                                                      SIGNED, CMP_LE, &dspctl ); }});
+                            0x3: pick_ph({{ Rd.uw = dspPick( Rs.uw, Rt.uw,
+                                                             SIMD_FMT_PH, &dspctl ); }});
+                            0x4: precrq_qb_ph({{ Rd.uw = Rs.uw<31:24> << 24 |
+                                                         Rs.uw<15:8> << 16 |
+                                                         Rt.uw<31:24> << 8 |
+                                                         Rt.uw<15:8>; }});
+                            0x5: precr_qb_ph({{ Rd.uw = Rs.uw<23:16> << 24 |
+                                                         Rs.uw<7:0> << 16 |
+                                                         Rt.uw<23:16> << 8 |
+                                                         Rt.uw<7:0>; }});
+                            0x6: packrl_ph({{ Rd.uw = dspPack( Rs.uw, Rt.uw,
+                                                               SIMD_FMT_PH ); }});
+                            0x7: precrqu_s_qb_ph({{ Rd.uw = dspPrecrqu( Rs.uw, Rt.uw, &dspctl ); }});
+                        }
+                    }
+                    0x2: decode OP_LO {
+                        format DspIntOp {
+                            0x4: precrq_ph_w({{ Rd.uw = Rs.uw<31:16> << 16 | Rt.uw<31:16>; }});
+                            0x5: precrq_rs_ph_w({{ Rd.uw = dspPrecrq( Rs.uw, Rt.uw, SIMD_FMT_W, &dspctl ); }});
+                        }
+                    }
+                    0x3: decode OP_LO {
+                        format DspIntOp {
+                            0x0: cmpgdu_eq_qb({{ Rd.uw = dspCmpgd( Rs.uw, Rt.uw, SIMD_FMT_QB,
+                                                                   UNSIGNED, CMP_EQ, &dspctl ); }});
+                            0x1: cmpgdu_lt_qb({{ Rd.uw = dspCmpgd( Rs.uw, Rt.uw, SIMD_FMT_QB,
+                                                                   UNSIGNED, CMP_LT, &dspctl  ); }});
+                            0x2: cmpgdu_le_qb({{ Rd.uw = dspCmpgd( Rs.uw, Rt.uw, SIMD_FMT_QB,
+                                                                   UNSIGNED, CMP_LE, &dspctl ); }});
+                            0x6: precr_sra_ph_w({{ Rt.uw = dspPrecrSra( Rt.uw, Rs.uw, RD,
+                                                                        SIMD_FMT_W, NOROUND ); }});
+                            0x7: precr_sra_r_ph_w({{ Rt.uw = dspPrecrSra( Rt.uw, Rs.uw, RD,
+                                                                        SIMD_FMT_W, ROUND ); }});
+                        }
+                    }
+                }
+
+                //Table 5-7 MIPS32 ABSQ_S.PH Encoding of the op Field (DSP ASE MANUAL)
+                0x2: decode OP_HI {
+                    0x0: decode OP_LO {
+                        format DspIntOp {
+                            0x1: absq_s_qb({{ Rd.sw = dspAbs( Rt.sw, SIMD_FMT_QB, &dspctl );}});
+                            0x2: repl_qb({{ Rd.uw = RS_RT<7:0> << 24 |
+                                                    RS_RT<7:0> << 16 |
+                                                    RS_RT<7:0> << 8 |
+                                                    RS_RT<7:0>; }});
+                            0x3: replv_qb({{ Rd.sw = Rt.uw<7:0> << 24 |
+                                                     Rt.uw<7:0> << 16 |
+                                                     Rt.uw<7:0> << 8 |
+                                                     Rt.uw<7:0>; }});
+                            0x4: precequ_ph_qbl({{ Rd.uw = dspPrece( Rt.uw, SIMD_FMT_QB, UNSIGNED,
+                                                                     SIMD_FMT_PH, SIGNED, MODE_L ); }});
+                            0x5: precequ_ph_qbr({{ Rd.uw = dspPrece( Rt.uw, SIMD_FMT_QB, UNSIGNED,
+                                                                     SIMD_FMT_PH, SIGNED, MODE_R ); }});
+                            0x6: precequ_ph_qbla({{ Rd.uw = dspPrece( Rt.uw, SIMD_FMT_QB, UNSIGNED,
+                                                                      SIMD_FMT_PH, SIGNED, MODE_LA ); }});
+                            0x7: precequ_ph_qbra({{ Rd.uw = dspPrece( Rt.uw, SIMD_FMT_QB, UNSIGNED,
+                                                                      SIMD_FMT_PH, SIGNED, MODE_RA ); }});
+                        }
+                    }
+                    0x1: decode OP_LO {
+                        format DspIntOp {
+                            0x1: absq_s_ph({{ Rd.sw = dspAbs( Rt.sw, SIMD_FMT_PH, &dspctl ); }});
+                            0x2: repl_ph({{ Rd.uw = (sext<10>(RS_RT))<15:0> << 16 |
+                                                    (sext<10>(RS_RT))<15:0>; }});
+                            0x3: replv_ph({{ Rd.uw = Rt.uw<15:0> << 16 |
+                                                     Rt.uw<15:0>; }});
+                            0x4: preceq_w_phl({{ Rd.uw = dspPrece( Rt.uw, SIMD_FMT_PH, SIGNED,
+                                                                   SIMD_FMT_W, SIGNED, MODE_L ); }});
+                            0x5: preceq_w_phr({{ Rd.uw = dspPrece( Rt.uw, SIMD_FMT_PH, SIGNED,
+                                                                   SIMD_FMT_W, SIGNED, MODE_R ); }});
+                        }
+                    }
+                    0x2: decode OP_LO {
+                        format DspIntOp {
+                            0x1: absq_s_w({{ Rd.sw = dspAbs( Rt.sw, SIMD_FMT_W, &dspctl ); }});
+                        }
+                    }
+                    0x3: decode OP_LO {
+                        0x3: IntOp::bitrev({{ Rd.uw = bitrev( Rt.uw<15:0> ); }});
+                        format DspIntOp {
+                            0x4: preceu_ph_qbl({{ Rd.uw = dspPrece( Rt.uw, SIMD_FMT_QB, UNSIGNED,
+                                                                    SIMD_FMT_PH, UNSIGNED, MODE_L ); }});
+                            0x5: preceu_ph_qbr({{ Rd.uw = dspPrece( Rt.uw, SIMD_FMT_QB, UNSIGNED,
+                                                                    SIMD_FMT_PH, UNSIGNED, MODE_R ); }});
+                            0x6: preceu_ph_qbla({{ Rd.uw = dspPrece( Rt.uw, SIMD_FMT_QB, UNSIGNED,
+                                                                     SIMD_FMT_PH, UNSIGNED, MODE_LA ); }});
+                            0x7: preceu_ph_qbra({{ Rd.uw = dspPrece( Rt.uw, SIMD_FMT_QB, UNSIGNED,
+                                                                     SIMD_FMT_PH, UNSIGNED, MODE_RA ); }});
+                        }
+                    }
+                }
+
+                //Table 5-8 MIPS32 SHLL.QB Encoding of the op Field (DSP ASE MANUAL)
+                0x3: decode OP_HI {
+                    0x0: decode OP_LO {
+                        format DspIntOp {
+                            0x0: shll_qb({{ Rd.sw = dspShll( Rt.sw, RS, SIMD_FMT_QB,
+                                                             NOSATURATE, UNSIGNED, &dspctl ); }});
+                            0x1: shrl_qb({{ Rd.sw = dspShrl( Rt.sw, RS, SIMD_FMT_QB,
+                                                             UNSIGNED ); }});
+                            0x2: shllv_qb({{ Rd.sw = dspShll( Rt.sw, Rs.sw, SIMD_FMT_QB,
+                                                              NOSATURATE, UNSIGNED, &dspctl ); }});
+                            0x3: shrlv_qb({{ Rd.sw = dspShrl( Rt.sw, Rs.sw, SIMD_FMT_QB,
+                                                              UNSIGNED ); }});
+                            0x4: shra_qb({{ Rd.sw = dspShra( Rt.sw, RS, SIMD_FMT_QB,
+                                                             NOROUND, SIGNED, &dspctl ); }});
+                            0x5: shra_r_qb({{ Rd.sw = dspShra( Rt.sw, RS, SIMD_FMT_QB,
+                                                               ROUND, SIGNED, &dspctl ); }});
+                            0x6: shrav_qb({{ Rd.sw = dspShra( Rt.sw, Rs.sw, SIMD_FMT_QB,
+                                                              NOROUND, SIGNED, &dspctl ); }});
+                            0x7: shrav_r_qb({{ Rd.sw = dspShra( Rt.sw, Rs.sw, SIMD_FMT_QB,
+                                                                ROUND, SIGNED, &dspctl ); }});
+                        }
+                    }
+                    0x1: decode OP_LO {
+                        format DspIntOp {
+                            0x0: shll_ph({{ Rd.uw = dspShll( Rt.uw, RS, SIMD_FMT_PH,
+                                                             NOSATURATE, SIGNED, &dspctl ); }});
+                            0x1: shra_ph({{ Rd.sw = dspShra( Rt.sw, RS, SIMD_FMT_PH,
+                                                             NOROUND, SIGNED, &dspctl ); }});
+                            0x2: shllv_ph({{ Rd.sw = dspShll( Rt.sw, Rs.sw, SIMD_FMT_PH,
+                                                              NOSATURATE, SIGNED, &dspctl ); }});
+                            0x3: shrav_ph({{ Rd.sw = dspShra( Rt.sw, Rs.sw, SIMD_FMT_PH,
+                                                              NOROUND, SIGNED, &dspctl ); }});
+                            0x4: shll_s_ph({{ Rd.sw = dspShll( Rt.sw, RS, SIMD_FMT_PH,
+                                                               SATURATE, SIGNED, &dspctl ); }});
+                            0x5: shra_r_ph({{ Rd.sw = dspShra( Rt.sw, RS, SIMD_FMT_PH,
+                                                               ROUND, SIGNED, &dspctl ); }});
+                            0x6: shllv_s_ph({{ Rd.sw = dspShll( Rt.sw, Rs.sw, SIMD_FMT_PH,
+                                                                SATURATE, SIGNED, &dspctl ); }});
+                            0x7: shrav_r_ph({{ Rd.sw = dspShra( Rt.sw, Rs.sw, SIMD_FMT_PH,
+                                                                ROUND, SIGNED, &dspctl ); }});
+                        }
+                    }
+                    0x2: decode OP_LO {
+                        format DspIntOp {
+                            0x4: shll_s_w({{ Rd.sw = dspShll( Rt.sw, RS, SIMD_FMT_W,
+                                                              SATURATE, SIGNED, &dspctl ); }});
+                            0x5: shra_r_w({{ Rd.sw = dspShra( Rt.sw, RS, SIMD_FMT_W,
+                                                              ROUND, SIGNED, &dspctl ); }});
+                            0x6: shllv_s_w({{ Rd.sw = dspShll( Rt.sw, Rs.sw, SIMD_FMT_W,
+                                                               SATURATE, SIGNED, &dspctl ); }});
+                            0x7: shrav_r_w({{ Rd.sw = dspShra( Rt.sw, Rs.sw, SIMD_FMT_W,
+                                                               ROUND, SIGNED, &dspctl ); }});
+                        }
+                    }
+                    0x3: decode OP_LO {
+                        format DspIntOp {
+                            0x1: shrl_ph({{ Rd.sw = dspShrl( Rt.sw, RS, SIMD_FMT_PH,
+                                                             UNSIGNED ); }});
+                            0x3: shrlv_ph({{ Rd.sw = dspShrl( Rt.sw, Rs.sw, SIMD_FMT_PH,
+                                                              UNSIGNED ); }});
+                        }
+                    }
+                }
+            }
+
+            0x3: decode FUNCTION_LO {
+
+                //Table 3.12 MIPS32 ADDUH.QB Encoding of the op Field (DSP ASE Rev2 Manual)
+                0x0: decode OP_HI {
+                    0x0: decode OP_LO {
+                        format DspIntOp {
+                            0x0: adduh_qb({{ Rd.uw = dspAddh( Rs.sw, Rt.sw, SIMD_FMT_QB,
+                                                              NOROUND, UNSIGNED ); }});
+                            0x1: subuh_qb({{ Rd.uw = dspSubh( Rs.sw, Rt.sw, SIMD_FMT_QB,
+                                                              NOROUND, UNSIGNED ); }});
+                            0x2: adduh_r_qb({{ Rd.uw = dspAddh( Rs.sw, Rt.sw, SIMD_FMT_QB,
+                                                                ROUND, UNSIGNED ); }});
+                            0x3: subuh_r_qb({{ Rd.uw = dspSubh( Rs.sw, Rt.sw, SIMD_FMT_QB,
+                                                                ROUND, UNSIGNED ); }});
+                        }
+                    }
+                    0x1: decode OP_LO {
+                        format DspIntOp {
+                            0x0: addqh_ph({{ Rd.uw = dspAddh( Rs.sw, Rt.sw, SIMD_FMT_PH,
+                                                              NOROUND, SIGNED ); }});
+                            0x1: subqh_ph({{ Rd.uw = dspSubh( Rs.sw, Rt.sw, SIMD_FMT_PH,
+                                                              NOROUND, SIGNED ); }});
+                            0x2: addqh_r_ph({{ Rd.uw = dspAddh( Rs.sw, Rt.sw, SIMD_FMT_PH,
+                                                                ROUND, SIGNED ); }});
+                            0x3: subqh_r_ph({{ Rd.uw = dspSubh( Rs.sw, Rt.sw, SIMD_FMT_PH,
+                                                                ROUND, SIGNED ); }});
+                            0x4: mul_ph({{ Rd.sw = dspMul( Rs.sw, Rt.sw, SIMD_FMT_PH,
+                                                           NOSATURATE, &dspctl ); }});
+                            0x6: mul_s_ph({{ Rd.sw = dspMul( Rs.sw, Rt.sw, SIMD_FMT_PH,
+                                                             SATURATE, &dspctl ); }});
+                        }
+                    }
+                    0x2: decode OP_LO {
+                        format DspIntOp {
+                            0x0: addqh_w({{ Rd.uw = dspAddh( Rs.sw, Rt.sw, SIMD_FMT_W,
+                                                             NOROUND, SIGNED ); }});
+                            0x1: subqh_w({{ Rd.uw = dspSubh( Rs.sw, Rt.sw, SIMD_FMT_W,
+                                                             NOROUND, SIGNED ); }});
+                            0x2: addqh_r_w({{ Rd.uw = dspAddh( Rs.sw, Rt.sw, SIMD_FMT_W,
+                                                               ROUND, SIGNED ); }});
+                            0x3: subqh_r_w({{ Rd.uw = dspSubh( Rs.sw, Rt.sw, SIMD_FMT_W,
+                                                               ROUND, SIGNED ); }});
+                            0x6: mulq_s_w({{ Rd.sw = dspMulq( Rs.sw, Rt.sw, SIMD_FMT_W,
+                                                              SATURATE, NOROUND, &dspctl ); }});
+                            0x7: mulq_rs_w({{ Rd.sw = dspMulq( Rs.sw, Rt.sw, SIMD_FMT_W,
+                                                               SATURATE, ROUND, &dspctl ); }});
+                        }
+                    }
                 }
             }
 
@@ -1020,9 +1593,9 @@ decode OPCODE_HI default Unknown::unknown() {
             0x4: decode SA {
                 format BasicOp {
                     0x02: wsbh({{ Rd.uw = Rt.uw<23:16> << 24 |
-                                          Rt.uw<31:24> << 16 |
-                                          Rt.uw<7:0>   << 8  |
-                                          Rt.uw<15:8>;
+                                      Rt.uw<31:24> << 16 |
+                                      Rt.uw<7:0>   << 8  |
+                                      Rt.uw<15:8>;
                     }});
                     0x10: seb({{ Rd.sw = Rt.sb; }});
                     0x18: seh({{ Rd.sw = Rt.sh; }});
@@ -1030,8 +1603,145 @@ decode OPCODE_HI default Unknown::unknown() {
             }
 
             0x6: decode FUNCTION_LO {
+
+                //Table 5-10 MIPS32 DPAQ.W.PH Encoding of the op Field (DSP ASE MANUAL)
+                0x0: decode OP_HI {
+                    0x0: decode OP_LO {
+                        format DspHiLoOp {
+                            0x0: dpa_w_ph({{ dspac = dspDpa( dspac, Rs.sw, Rt.sw, ACDST,
+                                                             SIMD_FMT_PH, SIGNED, MODE_L ); }});
+                            0x1: dps_w_ph({{ dspac = dspDps( dspac, Rs.sw, Rt.sw, ACDST,
+                                                             SIMD_FMT_PH, SIGNED, MODE_L ); }});
+                            0x2: mulsa_w_ph({{ dspac = dspMulsa( dspac, Rs.sw, Rt.sw,
+                                                                 ACDST, SIMD_FMT_PH ); }});
+                            0x3: dpau_h_qbl({{ dspac = dspDpa( dspac, Rs.sw, Rt.sw, ACDST,
+                                                               SIMD_FMT_QB, UNSIGNED, MODE_L ); }});
+                            0x4: dpaq_s_w_ph({{ dspac = dspDpaq( dspac, Rs.sw, Rt.sw, ACDST, SIMD_FMT_PH,
+                                                                 SIMD_FMT_W, NOSATURATE, MODE_L, &dspctl ); }});
+                            0x5: dpsq_s_w_ph({{ dspac = dspDpsq( dspac, Rs.sw, Rt.sw, ACDST, SIMD_FMT_PH,
+                                                                 SIMD_FMT_W, NOSATURATE, MODE_L, &dspctl ); }});
+                            0x6: mulsaq_s_w_ph({{ dspac = dspMulsaq( dspac, Rs.sw, Rt.sw,
+                                                                     ACDST, SIMD_FMT_PH, &dspctl ); }});
+                            0x7: dpau_h_qbr({{ dspac = dspDpa( dspac, Rs.sw, Rt.sw, ACDST,
+                                                               SIMD_FMT_QB, UNSIGNED, MODE_R ); }});
+                        }
+                    }
+                    0x1: decode OP_LO {
+                        format DspHiLoOp {
+                            0x0: dpax_w_ph({{ dspac = dspDpa( dspac, Rs.sw, Rt.sw, ACDST,
+                                                              SIMD_FMT_PH, SIGNED, MODE_X ); }});
+                            0x1: dpsx_w_ph({{ dspac = dspDps( dspac, Rs.sw, Rt.sw, ACDST,
+                                                              SIMD_FMT_PH, SIGNED, MODE_X ); }});
+                            0x3: dpsu_h_qbl({{ dspac = dspDps( dspac, Rs.sw, Rt.sw, ACDST,
+                                                               SIMD_FMT_QB, UNSIGNED, MODE_L ); }});
+                            0x4: dpaq_sa_l_w({{ dspac = dspDpaq( dspac, Rs.sw, Rt.sw, ACDST, SIMD_FMT_W,
+                                                                 SIMD_FMT_L, SATURATE, MODE_L, &dspctl ); }});
+                            0x5: dpsq_sa_l_w({{ dspac = dspDpsq( dspac, Rs.sw, Rt.sw, ACDST, SIMD_FMT_W,
+                                                                 SIMD_FMT_L, SATURATE, MODE_L, &dspctl ); }});
+                            0x7: dpsu_h_qbr({{ dspac = dspDps( dspac, Rs.sw, Rt.sw, ACDST,
+                                                               SIMD_FMT_QB, UNSIGNED, MODE_R ); }});
+                        }
+                    }
+                    0x2: decode OP_LO {
+                        format DspHiLoOp {
+                            0x0: maq_sa_w_phl({{ dspac = dspMaq( dspac, Rs.uw, Rt.uw, ACDST, SIMD_FMT_PH,
+                                                                 MODE_L, SATURATE, &dspctl ); }});
+                            0x2: maq_sa_w_phr({{ dspac = dspMaq( dspac, Rs.uw, Rt.uw, ACDST, SIMD_FMT_PH,
+                                                                 MODE_R, SATURATE, &dspctl ); }});
+                            0x4: maq_s_w_phl({{ dspac = dspMaq( dspac, Rs.uw, Rt.uw, ACDST, SIMD_FMT_PH,
+                                                                 MODE_L, NOSATURATE, &dspctl ); }});
+                            0x6: maq_s_w_phr({{ dspac = dspMaq( dspac, Rs.uw, Rt.uw, ACDST, SIMD_FMT_PH,
+                                                                 MODE_R, NOSATURATE, &dspctl ); }});
+                        }
+                    }
+                    0x3: decode OP_LO {
+                        format DspHiLoOp {
+                            0x0: dpaqx_s_w_ph({{ dspac = dspDpaq( dspac, Rs.sw, Rt.sw, ACDST, SIMD_FMT_PH,
+                                                                  SIMD_FMT_W, NOSATURATE, MODE_X, &dspctl ); }});
+                            0x1: dpsqx_s_w_ph({{ dspac = dspDpsq( dspac, Rs.sw, Rt.sw, ACDST, SIMD_FMT_PH,
+                                                                  SIMD_FMT_W, NOSATURATE, MODE_X, &dspctl ); }});
+                            0x2: dpaqx_sa_w_ph({{ dspac = dspDpaq( dspac, Rs.sw, Rt.sw, ACDST, SIMD_FMT_PH,
+                                                                   SIMD_FMT_W, SATURATE, MODE_X, &dspctl ); }});
+                            0x3: dpsqx_sa_w_ph({{ dspac = dspDpsq( dspac, Rs.sw, Rt.sw, ACDST, SIMD_FMT_PH,
+                                                                   SIMD_FMT_W, SATURATE, MODE_X, &dspctl ); }});
+                        }
+                    }
+                }
+
+                //Table 3.3 MIPS32 APPEND Encoding of the op Field
+                0x1: decode OP_HI {
+                    0x0: decode OP_LO {
+                        format IntOp {
+                            0x0: append({{ Rt.uw = (Rt.uw << RD) | bits(Rs.uw,RD-1,0); }});
+                            0x1: prepend({{ Rt.uw = (Rt.uw >> RD) | (bits(Rs.uw,RD-1,0) << 32-RD); }});
+                        }
+                    }
+                    0x2: decode OP_LO {
+                        format IntOp {
+                            0x0: balign({{ Rt.uw = (Rt.uw << (8*BP)) | (Rs.uw >> (8*(4-BP))); }});
+                        }
+                    }
+                }
+
                 0x7: FailUnimpl::rdhwr();
             }
+
+            0x7: decode FUNCTION_LO {
+
+                //Table 5-11 MIPS32 EXTR.W Encoding of the op Field (DSP ASE MANUAL)
+                0x0: decode OP_HI {
+                    0x0: decode OP_LO {
+                        format DspHiLoOp {
+                            0x0: extr_w({{ Rt.uw = dspExtr( dspac, SIMD_FMT_W, RS,
+                                                            NOROUND, NOSATURATE, &dspctl ); }});
+                            0x1: extrv_w({{ Rt.uw = dspExtr( dspac, SIMD_FMT_W, Rs.uw,
+                                                             NOROUND, NOSATURATE, &dspctl ); }});
+                            0x2: extp({{ Rt.uw = dspExtp( dspac, RS, &dspctl ); }});
+                            0x3: extpv({{ Rt.uw = dspExtp( dspac, Rs.uw, &dspctl ); }});
+                            0x4: extr_r_w({{ Rt.uw = dspExtr( dspac, SIMD_FMT_W, RS,
+                                                              ROUND, NOSATURATE, &dspctl ); }});
+                            0x5: extrv_r_w({{ Rt.uw = dspExtr( dspac, SIMD_FMT_W, Rs.uw,
+                                                               ROUND, NOSATURATE, &dspctl ); }});
+                            0x6: extr_rs_w({{ Rt.uw = dspExtr( dspac, SIMD_FMT_W, RS,
+                                                               ROUND, SATURATE, &dspctl ); }});
+                            0x7: extrv_rs_w({{ Rt.uw = dspExtr( dspac, SIMD_FMT_W, Rs.uw,
+                                                                ROUND, SATURATE, &dspctl ); }});
+                        }
+                    }
+                    0x1: decode OP_LO {
+                        format DspHiLoOp {
+                            0x2: extpdp({{ Rt.uw = dspExtpd( dspac, RS, &dspctl ); }});
+                            0x3: extpdpv({{ Rt.uw = dspExtpd( dspac, Rs.uw, &dspctl ); }});
+                            0x6: extr_s_h({{ Rt.uw = dspExtr( dspac, SIMD_FMT_PH, RS,
+                                                              NOROUND, SATURATE, &dspctl ); }});
+                            0x7: extrv_s_h({{ Rt.uw = dspExtr( dspac, SIMD_FMT_PH, Rs.uw,
+                                                               NOROUND, SATURATE, &dspctl ); }});
+                        }
+                    }
+                    0x2: decode OP_LO {
+                        format DspIntOp {
+                            0x2: rddsp({{ Rd.uw = readDSPControl( &dspctl, RDDSPMASK ); }});
+                            0x3: wrdsp({{ writeDSPControl( &dspctl, Rs.uw, WRDSPMASK ); }});
+                        }
+                    }
+                    0x3: decode OP_LO {
+                        format DspHiLoOp {
+                            0x2: shilo({{ if( sext<6>(HILOSA) < 0 )
+                                              dspac = (uint64_t)dspac << -sext<6>(HILOSA);
+                                          else
+                                              dspac = (uint64_t)dspac >> sext<6>(HILOSA); }});
+                            0x3: shilov({{ if( sext<6>(Rs.sw<5:0>) < 0 )
+                                              dspac = (uint64_t)dspac << -sext<6>(Rs.sw<5:0>);
+                                           else
+                                              dspac = (uint64_t)dspac >> sext<6>(Rs.sw<5:0>); }});
+                            0x7: mthlip({{ dspac = dspac << 32;
+                                           dspac |= Rs.uw;
+                                           dspctl = insertBits( dspctl, 5, 0,
+                                                                dspctl<5:0>+32 ); }});
+                        }
+                    }
+                }
+            }
         }
     }
 
@@ -1047,13 +1757,13 @@ decode OPCODE_HI default Unknown::unknown() {
         format LoadUnalignedMemory {
             0x2: lwl({{ uint32_t mem_shift = 24 - (8 * byte_offset);
                         Rt.uw = mem_word << mem_shift |
-                                Rt.uw & mask(mem_shift);
+                            Rt.uw & mask(mem_shift);
                      }});
             0x6: lwr({{ uint32_t mem_shift = 8 * byte_offset;
                         Rt.uw = Rt.uw & (mask(mem_shift) << (32 - mem_shift)) |
-                                mem_word >> mem_shift;
+                            mem_word >> mem_shift;
                      }});
-        }
+      }
     }
 
     0x5: decode OPCODE_LO {
@@ -1093,9 +1803,6 @@ decode OPCODE_HI default Unknown::unknown() {
         0x0: StoreCond::sc({{ Mem.uw = Rt.uw;}},
                            {{ uint64_t tmp = write_result;
                               Rt.uw = (tmp == 0 || tmp == 1) ? tmp : Rt.uw;
-                              if (tmp == 1) {
-                                  xc->setStCondFailures(0);
-                              }
                            }}, mem_flags=LOCKED, inst_flags = IsStoreConditional);
 
         format StoreMemory {
index a67f04dca84fb6613a2b9cbc1ee7b8d6dbcb8599..e959e4c1bea0e5cae4b7521e894a3e281bc30e78 100644 (file)
@@ -36,6 +36,7 @@
 output header {{
 
 #include <iostream>
+    using namespace std;
 
     /**
      * Base class for instructions whose disassembly is not purely a
@@ -216,7 +217,7 @@ output decoder {{
     }
 }};
 
-def format Branch(code,*opt_flags) {{
+def format Branch(code, *opt_flags) {{
     not_taken_code = '  NNPC = NNPC;\n'
     not_taken_code += '} \n'
 
@@ -230,13 +231,13 @@ def format Branch(code,*opt_flags) {{
             not_taken_code = '  NPC = NNPC;\n'
             not_taken_code += '  NNPC = NNPC + 4;\n'
             not_taken_code += '} \n'
-            inst_flags = ('IsCondDelaySlot', )
+            inst_flags += ('IsCondDelaySlot', )
         else:
             inst_flags += (x, )
 
     #Take into account uncond. branch instruction
-    if 'cond == 1' in code:
-         inst_flags += ('IsUnCondControl', )
+    if 'cond = 1' in code:
+         inst_flags += ('IsUncondControl', )
     else:
          inst_flags += ('IsCondControl', )
 
@@ -254,6 +255,51 @@ def format Branch(code,*opt_flags) {{
     exec_output = BasicExecute.subst(iop)
 }};
 
+def format DspBranch(code, *opt_flags) {{
+    not_taken_code = '  NNPC = NNPC;\n'
+    not_taken_code += '} \n'
+
+    #Build Instruction Flags
+    #Use Link & Likely Flags to Add Link/Condition Code
+    inst_flags = ('IsDirectControl', )
+    for x in opt_flags:
+        if x == 'Link':
+            code += 'R31 = NNPC;\n'
+        elif x == 'Likely':
+            not_taken_code = '  NPC = NNPC;\n'
+            not_taken_code += '  NNPC = NNPC + 4;\n'
+            not_taken_code += '} \n'
+            inst_flags += ('IsCondDelaySlot', )
+        else:
+            inst_flags += (x, )
+
+    #Take into account uncond. branch instruction
+    if 'cond = 1' in code:
+         inst_flags += ('IsUncondControl', )
+    else:
+         inst_flags += ('IsCondControl', )
+
+    #Declaration code
+    decl_code = 'bool cond;\n'
+    decl_code += 'uint32_t dspctl;\n'
+
+    #Fetch code
+    fetch_code = 'dspctl = DSPControl;\n'
+
+    #Condition code
+    code = decl_code + fetch_code + code
+    code += 'if (cond) {\n'
+    code += '  NNPC = NPC + disp;\n'
+    code += '} else {\n'
+    code += not_taken_code
+
+    iop = InstObjParams(name, Name, 'Branch', code, inst_flags)
+    header_output = BasicDeclare.subst(iop)
+    decoder_output = BasicConstructor.subst(iop)
+    decode_block = BasicDecode.subst(iop)
+    exec_output = BasicExecute.subst(iop)
+}};
+
 def format Jump(code, *opt_flags) {{
     #Build Instruction Flags
     #Use Link Flag to Add Link Code
index 1c63a6e22ee68ac5d5a63bca25d23940d5bae798..1de2948be7d7541c9f8fb56007d2ed09b8ea4b35 100644 (file)
 
 ////////////////////////////////////////////////////////////////////
 //
-// Integer operate instructions
+// Coprocessor instructions
 //
 
 //Outputs to decoder.hh
 output header {{
 
-        class Control : public MipsStaticInst
-        {
-                protected:
-
-                /// Constructor
-                Control(const char *mnem, MachInst _machInst, OpClass __opClass) :
-                           MipsStaticInst(mnem, _machInst, __opClass)
-                {
-                }
-
-                std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const;
-        };
-
-        class CP0Control : public Control
+        class CP0Control : public MipsStaticInst
         {
                 protected:
 
                 /// Constructor
                 CP0Control(const char *mnem, MachInst _machInst, OpClass __opClass) :
-                           Control(mnem, _machInst, __opClass)
+                           MipsStaticInst(mnem, _machInst, __opClass)
                 {
                 }
 
                 std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const;
         };
 
-        class CP1Control : public Control
+        class CP1Control : public MipsStaticInst
         {
                 protected:
 
                 /// Constructor
                 CP1Control(const char *mnem, MachInst _machInst, OpClass __opClass) :
-                           Control(mnem, _machInst, __opClass)
+                           MipsStaticInst(mnem, _machInst, __opClass)
                 {
                 }
 
@@ -77,46 +64,34 @@ output header {{
 
 }};
 
-//Outputs to decoder.cc
-output decoder {{
-        std::string Control::generateDisassembly(Addr pc, const SymbolTable *symtab) const
+// Basic instruction class execute method template.
+def template ControlExecute {{
+        Fault %(class_name)s::execute(%(CPU_exec_context)s *xc, Trace::InstRecord *traceData) const
         {
-            std::stringstream ss;
-
-            ccprintf(ss, "%-10s ", mnemonic);
-
-            if (mnemonic == "mfc0" || mnemonic == "mtc0") {
-                ccprintf(ss, "%-10s %d,%d,%d", mnemonic,RT,RD,SEL);
-            } else {
-
-                // just print the first dest... if there's a second one,
-                // it's generally implicit
-                if (_numDestRegs > 0) {
-                    printReg(ss, _destRegIdx[0]);
-                }
-
-                ss << ", ";
-
-                // just print the first two source regs... if there's
-                // a third one, it's a read-modify-write dest (Rc),
-                // e.g. for CMOVxx
-                if (_numSrcRegs > 0) {
-                    printReg(ss, _srcRegIdx[0]);
+                Fault fault = NoFault;
+                %(op_decl)s;
+                %(op_rd)s;
+
+                if (isCoprocessorEnabled(xc, 0)) {
+                    %(code)s;
+                } else {
+                    fault = new CoprocessorUnusableFault();
                 }
 
-                if (_numSrcRegs > 1) {
-                    ss << ", ";
-                    printReg(ss, _srcRegIdx[1]);
+                if(fault == NoFault)
+                {
+                    %(op_wb)s;
                 }
-            }
-
-            return ss.str();
+                return fault;
         }
+}};
 
+//Outputs to decoder.cc
+output decoder {{
         std::string CP0Control::generateDisassembly(Addr pc, const SymbolTable *symtab) const
         {
             std::stringstream ss;
-            ccprintf(ss, "%-10s r%d, r%d, %d", mnemonic, RT, RD, SEL);
+            ccprintf(ss, "%-10s r%d, %d, %d", mnemonic, RT, RD, SEL);
             return ss.str();
         }
 
@@ -129,28 +104,50 @@ output decoder {{
 
 }};
 
-def format System(code, *flags) {{
-        iop = InstObjParams(name, Name, 'Control', code, flags)
-        header_output = BasicDeclare.subst(iop)
-        decoder_output = BasicConstructor.subst(iop)
-        decode_block = BasicDecode.subst(iop)
-        exec_output = BasicExecute.subst(iop)
+output exec {{
+        bool isCoprocessorEnabled(%(CPU_exec_context)s *xc, unsigned cop_num)
+        {
+          switch(cop_num)
+            {
+            case 0:
+#if FULL_SYSTEM
+              if((xc->readMiscReg(MipsISA::Status) & 0x10000006) == 0 && (xc->readMiscReg(MipsISA::Debug) & 0x40000000 ) == 0) {
+                  // Unable to use Status_CU0, etc directly, using bitfields & masks
+                  return false;
+              }
+#else
+              //printf("Syscall Emulation Mode: CP0 Enable Check defaults to TRUE\n");
+#endif
+              break;
+            case 1:
+              break;
+            case 2:
+              break;
+            case 3:
+              break;
+            default: panic("Invalid Coprocessor Number Specified");
+              break;
+            }
+            return true;
+        }
 }};
 
 def format CP0Control(code, *flags) {{
-        iop = InstObjParams(name, Name, 'CP0Control', code, flags)
-        header_output = BasicDeclare.subst(iop)
-        decoder_output = BasicConstructor.subst(iop)
-        decode_block = BasicDecode.subst(iop)
-        exec_output = BasicExecute.subst(iop)
+    flags += ('IsNonSpeculative', )
+    iop = InstObjParams(name, Name, 'CP0Control', code, flags)
+    header_output = BasicDeclare.subst(iop)
+    decoder_output = BasicConstructor.subst(iop)
+    decode_block = BasicDecode.subst(iop)
+    exec_output = ControlExecute.subst(iop)
 }};
 
 def format CP1Control(code, *flags) {{
-        iop = InstObjParams(name, Name, 'CP1Control', code, flags)
-        header_output = BasicDeclare.subst(iop)
-        decoder_output = BasicConstructor.subst(iop)
-        decode_block = BasicDecode.subst(iop)
-        exec_output = BasicExecute.subst(iop)
+    flags += ('IsNonSpeculative', )
+    iop = InstObjParams(name, Name, 'CP1Control', code, flags)
+    header_output = BasicDeclare.subst(iop)
+    decoder_output = BasicConstructor.subst(iop)
+    decode_block = BasicDecode.subst(iop)
+    exec_output = ControlExecute.subst(iop)
 }};
 
 
diff --git a/src/arch/mips/isa/formats/dsp.isa b/src/arch/mips/isa/formats/dsp.isa
new file mode 100755 (executable)
index 0000000..768f3dd
--- /dev/null
@@ -0,0 +1,218 @@
+// -*- mode:c++ -*-
+
+// Copyright (c) 2006 The Regents of The University of Michigan
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met: redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer;
+// redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution;
+// neither the name of the copyright holders nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+// Authors: Korey Sewell
+
+////////////////////////////////////////////////////////////////////
+//
+// DSP integer operate instructions
+//
+output header {{
+#include <iostream>
+    using namespace std;
+    /**
+     * Base class for integer operations.
+     */
+    class DspIntOp : public MipsStaticInst
+    {
+      protected:
+
+        /// Constructor
+        DspIntOp(const char *mnem, MachInst _machInst, OpClass __opClass) :
+            MipsStaticInst(mnem, _machInst, __opClass)
+        {
+        }
+    };
+
+    class DspHiLoOp : public MipsStaticInst
+    {
+      protected:
+
+        /// Constructor
+        DspHiLoOp(const char *mnem, MachInst _machInst, OpClass __opClass) :
+            MipsStaticInst(mnem, _machInst, __opClass)
+        {
+        }
+    };
+}};
+
+// Dsp instruction class execute method template.
+def template DspExecute {{
+        Fault %(class_name)s::execute(%(CPU_exec_context)s *xc, Trace::InstRecord *traceData) const
+        {
+                Fault fault = NoFault;
+
+                %(op_decl)s;
+
+                if (isDspPresent(xc))
+                {
+                    if (isDspEnabled(xc))
+                    {
+                        %(op_rd)s;
+                        %(code)s;
+                    }
+                    else
+                    {
+                        fault = new DspStateDisabledFault();
+                    }
+                }
+                else
+                {
+                    fault = new ReservedInstructionFault();
+                }
+
+                if(fault == NoFault)
+                {
+                    %(op_wb)s;
+                }
+                return fault;
+        }
+}};
+
+// DspHiLo instruction class execute method template.
+def template DspHiLoExecute {{
+        Fault %(class_name)s::execute(%(CPU_exec_context)s *xc, Trace::InstRecord *traceData) const
+        {
+                Fault fault = NoFault;
+
+                %(op_decl)s;
+
+                if (isDspPresent(xc))
+                {
+                    if (isDspEnabled(xc))
+                    {
+                        %(op_rd)s;
+                        %(code)s;
+                    }
+                    else
+                    {
+                        fault = new DspStateDisabledFault();
+                    }
+                }
+                else
+                {
+                    fault = new ReservedInstructionFault();
+                }
+
+                if(fault == NoFault)
+                {
+                    %(op_wb)s;
+                    //If there are 2 Destination Registers then
+                    //concatenate the values for the traceData
+                    if(traceData && _numDestRegs == 2) {
+                        // FIXME - set the trace value correctly here
+                        //uint64_t hilo_final_val = (uint64_t)HI_RD_SEL << 32 | LO_RD_SEL;
+                        //traceData->setData(hilo_final_val);
+                    }
+                }
+                return fault;
+        }
+}};
+
+//Outputs to decoder.cc
+output decoder {{
+}};
+
+output exec {{
+    bool isDspEnabled(%(CPU_exec_context)s *xc)
+    {
+#if FULL_SYSTEM
+        if( bits( xc->readMiscReg(MipsISA::Status), 24, 24 ) == 0 )
+            return false;
+#else
+        //printf("Syscall Emulation Mode: isDspEnabled() check defaults to TRUE\n");
+#endif
+        return true;
+    }
+}};
+
+output exec {{
+    bool isDspPresent(%(CPU_exec_context)s *xc)
+    {
+#if FULL_SYSTEM
+        if( bits( xc->readMiscReg(MipsISA::Config3), 10, 10 ) == 0 )
+            return false;
+#else
+        //printf("Syscall Emulation Mode: isDspPresent() check defaults to TRUE\n");
+#endif
+        return true;
+    }
+}};
+
+// add code to fetch the DSPControl register
+// and write it back after execution, giving
+// the instruction the opportunity to modify
+// it if necessary
+def format DspIntOp(code, *opt_flags) {{
+
+    decl_code = 'uint32_t dspctl;\n'
+    decl_code += 'dspctl = DSPControl;\n'
+
+    write_code = 'DSPControl = dspctl;\n'
+
+    code = decl_code + code + write_code
+
+    iop = InstObjParams(name, Name, 'DspIntOp', code, opt_flags)
+    header_output = BasicDeclare.subst(iop)
+    decoder_output = BasicConstructor.subst(iop)
+    decode_block = BasicDecode.subst(iop)
+    exec_output = DspExecute.subst(iop)
+}};
+
+// add code to fetch the DSPControl register
+// and write it back after execution, giving
+// the instruction the opportunity to modify
+// it if necessary; also, fetch the appropriate
+// HI/LO register pair, based on the AC
+// instruction field.
+
+def format DspHiLoOp(code, *opt_flags) {{
+
+    decl_code = 'int64_t dspac;\n'
+    decl_code += 'uint32_t dspctl;\n'
+
+    fetch_code = 'dspctl = DSPControl;\n'
+    fetch_code += 'dspac = HI_RD_SEL;\n'
+    fetch_code += 'dspac = dspac << 32 | LO_RD_SEL;\n'
+
+    write_code = 'DSPControl = dspctl;\n'
+    write_code += 'HI_RD_SEL = dspac<63:32>;\n'
+    write_code += 'LO_RD_SEL = dspac<31:0>;\n'
+
+    code = decl_code + fetch_code + code + write_code
+
+    iop = InstObjParams(name, Name, 'DspHiLoOp', code, opt_flags)
+    header_output = BasicDeclare.subst(iop)
+    decoder_output = BasicConstructor.subst(iop)
+    decode_block = BasicDecode.subst(iop)
+    exec_output = DspHiLoExecute.subst(iop)
+
+}};
+
+
+
index 4c3eec13258979bba5f7b0d218eb859148f90ca2..1cff9732fb3282f8dc2170ee604c70be1bbf89ae 100644 (file)
@@ -44,6 +44,9 @@
 //Include the integer formats
 ##include "int.isa"
 
+//Include the DSP integer format
+##include "dsp.isa"
+
 //Include the floatOp format
 ##include "fp.isa"
 
index ac6805cc736fd70904629455d053532dba993ec9..4b340e2e62a96805f671a9f11f6e708acca2c0cb 100644 (file)
@@ -87,6 +87,12 @@ output decoder {{
 }};
 
 output exec {{
+        inline Fault checkFpEnableFault(%(CPU_exec_context)s *xc)
+        {
+            //@TODO: Implement correct CP0 checks to see if the CP1
+            // unit is enable or not
+            return NoFault;
+        }
 
         //If any operand is Nan return the appropriate QNaN
         template <class T>
@@ -145,7 +151,7 @@ output exec {{
                 uint32_t fcsr_bits = cpu->tcBase()->readFloatRegBits(FCSR);
 
                 //Write FCSR from FloatRegFile
-                cpu->tcBase()->setFloatRegBits(FCSR, genInvalidVector(fcsr_bits));
+                cpu->tcBase()->setFloatRegOperandBits(FCSR, genInvalidVector(fcsr_bits));
 
                 if (traceData) { traceData->setData(mips_nan); }
                 return true;
@@ -160,6 +166,7 @@ output exec {{
             //Read FCSR from FloatRegFile
             uint32_t fcsr = cpu->tcBase()->readFloatRegBits(FCSR);
 
+            // TODO: Use utility function here
             fcsr = bits(fcsr, 31, 18) << 18 | bits(fcsr, 11, 0);
 
             //Write FCSR from FloatRegFile
index 2f131f6d9676ff5d9fa6dde3f40f4fcc3d767a87..7fa8e481764ec2b2bd17b68b2a0298b36389572a 100644 (file)
@@ -34,6 +34,7 @@
 //
 output header {{
 #include <iostream>
+    using namespace std;
         /**
          * Base class for integer operations.
          */
@@ -64,12 +65,12 @@ output header {{
                 std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const;
         };
 
-        class HiLoMiscOp: public HiLoOp
+        class HiLoRsSelOp: public HiLoOp
         {
                 protected:
 
                 /// Constructor
-                HiLoMiscOp(const char *mnem, MachInst _machInst, OpClass __opClass) :
+                HiLoRsSelOp(const char *mnem, MachInst _machInst, OpClass __opClass) :
                                 HiLoOp(mnem, _machInst, __opClass)
                 {
                 }
@@ -77,6 +78,31 @@ output header {{
                 std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const;
         };
 
+        class HiLoRdSelOp: public HiLoOp
+        {
+                protected:
+
+                /// Constructor
+                HiLoRdSelOp(const char *mnem, MachInst _machInst, OpClass __opClass) :
+                                HiLoOp(mnem, _machInst, __opClass)
+                {
+                }
+
+                std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const;
+        };
+
+        class HiLoRdSelValOp: public HiLoOp
+        {
+                protected:
+
+                /// Constructor
+                HiLoRdSelValOp(const char *mnem, MachInst _machInst, OpClass __opClass) :
+                                HiLoOp(mnem, _machInst, __opClass)
+                {
+                }
+
+                std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const;
+        };
 
         class IntImmOp : public MipsStaticInst
         {
@@ -105,9 +131,7 @@ output header {{
 
 }};
 
-// HiLo<Misc> instruction class execute method template.
-// Mainly to get instruction trace data to print out
-// correctly
+// HiLo instruction class execute method template.
 def template HiLoExecute {{
         Fault %(class_name)s::execute(%(CPU_exec_context)s *xc, Trace::InstRecord *traceData) const
         {
@@ -121,12 +145,58 @@ def template HiLoExecute {{
                 if(fault == NoFault)
                 {
                     %(op_wb)s;
-                    //If there are 2 Destination Registers then
-                    //concatenate the values for the traceData
-                    if(traceData && _numDestRegs == 2) {
-                        uint64_t hilo_final_val = (uint64_t)HI << 32 | LO;
-                        traceData->setData(hilo_final_val);
-                    }
+                }
+                return fault;
+        }
+}};
+
+// HiLoRsSel instruction class execute method template.
+def template HiLoRsSelExecute {{
+        Fault %(class_name)s::execute(%(CPU_exec_context)s *xc, Trace::InstRecord *traceData) const
+        {
+                Fault fault = NoFault;
+
+                %(op_decl)s;
+
+                if( ACSRC > 0 && !isDspEnabled(xc) )
+                {
+                    fault = new DspStateDisabledFault();
+                }
+                else
+                {
+                    %(op_rd)s;
+                    %(code)s;
+                }
+
+                if(fault == NoFault)
+                {
+                    %(op_wb)s;
+                }
+                return fault;
+        }
+}};
+
+// HiLoRdSel instruction class execute method template.
+def template HiLoRdSelExecute {{
+        Fault %(class_name)s::execute(%(CPU_exec_context)s *xc, Trace::InstRecord *traceData) const
+        {
+                Fault fault = NoFault;
+
+                %(op_decl)s;
+
+                if( ACDST > 0 && !isDspEnabled(xc) )
+                {
+                    fault = new DspStateDisabledFault();
+                }
+                else
+                {
+                    %(op_rd)s;
+                    %(code)s;
+                }
+
+                if(fault == NoFault)
+                {
+                    %(op_wb)s;
                 }
                 return fault;
         }
@@ -181,7 +251,37 @@ output decoder {{
             return ss.str();
         }
 
-        std::string HiLoMiscOp::generateDisassembly(Addr pc, const SymbolTable *symtab) const
+        std::string HiLoRsSelOp::generateDisassembly(Addr pc, const SymbolTable *symtab) const
+        {
+            std::stringstream ss;
+
+            ccprintf(ss, "%-10s ", mnemonic);
+
+            if (_numDestRegs > 0 && _destRegIdx[0] < 32) {
+                printReg(ss, _destRegIdx[0]);
+            } else if (_numSrcRegs > 0 && _srcRegIdx[0] < 32) {
+                printReg(ss, _srcRegIdx[0]);
+            }
+
+            return ss.str();
+        }
+
+        std::string HiLoRdSelOp::generateDisassembly(Addr pc, const SymbolTable *symtab) const
+        {
+            std::stringstream ss;
+
+            ccprintf(ss, "%-10s ", mnemonic);
+
+            if (_numDestRegs > 0 && _destRegIdx[0] < 32) {
+                printReg(ss, _destRegIdx[0]);
+            } else if (_numSrcRegs > 0 && _srcRegIdx[0] < 32) {
+                printReg(ss, _srcRegIdx[0]);
+            }
+
+            return ss.str();
+        }
+
+        std::string HiLoRdSelValOp::generateDisassembly(Addr pc, const SymbolTable *symtab) const
         {
             std::stringstream ss;
 
@@ -239,26 +339,43 @@ def format IntImmOp(code, *opt_flags) {{
     exec_output = BasicExecute.subst(iop)
 }};
 
-def format HiLoOp(code, *opt_flags) {{
-    code += 'HI = val<63:32>;\n'
-    code += 'LO = val<31:0>;\n'
-
-    iop = InstObjParams(name, Name, 'HiLoOp', code, opt_flags)
+def format HiLoRsSelOp(code, *opt_flags) {{
+    iop = InstObjParams(name, Name, 'HiLoRsSelOp', code, opt_flags)
     header_output = BasicDeclare.subst(iop)
     decoder_output = BasicConstructor.subst(iop)
     decode_block = BasicDecode.subst(iop)
-    exec_output = HiLoExecute.subst(iop)
+    exec_output = HiLoRsSelExecute.subst(iop)
 }};
 
-def format HiLoMiscOp(code, *opt_flags) {{
-    iop = InstObjParams(name, Name, 'HiLoMiscOp', code, opt_flags)
+def format HiLoRdSelOp(code, *opt_flags) {{
+    iop = InstObjParams(name, Name, 'HiLoRdSelOp', code, opt_flags)
     header_output = BasicDeclare.subst(iop)
     decoder_output = BasicConstructor.subst(iop)
     decode_block = BasicDecode.subst(iop)
-    exec_output = BasicExecute.subst(iop)
+    exec_output = HiLoRdSelExecute.subst(iop)
 }};
 
+def format HiLoRdSelValOp(code, *opt_flags) {{
 
+    if '.sd' in code:
+        code = 'int64_t ' + code
+    elif '.ud' in code:
+        code = 'uint64_t ' + code
 
+    code += 'HI_RD_SEL = val<63:32>;\n'
+    code += 'LO_RD_SEL = val<31:0>;\n'
 
+    iop = InstObjParams(name, Name, 'HiLoRdSelOp', code, opt_flags)
+    header_output = BasicDeclare.subst(iop)
+    decoder_output = BasicConstructor.subst(iop)
+    decode_block = BasicDecode.subst(iop)
+    exec_output = HiLoRdSelExecute.subst(iop)
+}};
 
+def format HiLoOp(code, *opt_flags) {{
+    iop = InstObjParams(name, Name, 'HiLoOp', code, opt_flags)
+    header_output = BasicDeclare.subst(iop)
+    decoder_output = BasicConstructor.subst(iop)
+    decode_block = BasicDecode.subst(iop)
+    exec_output = HiLoExecute.subst(iop)
+}};
index df80e7a1fe87df2744b33b456946f7745520b74f..c8e85a7543448411584f3b61dbd793213b6df605 100644 (file)
@@ -69,6 +69,8 @@ output header {{
 
         const StaticInstPtr &eaCompInst() const { return eaCompPtr; }
         const StaticInstPtr &memAccInst() const { return memAccPtr; }
+
+        unsigned memAccFlags() { return memAccessFlags; }
     };
 
      /**
@@ -108,6 +110,37 @@ output decoder {{
                         flags[IsFloating] ? FD : RD,
                         RS, RT);
     }
+
+}};
+
+output exec {{
+    /** return data in cases where there the size of data is only
+        known in the packet
+    */
+    uint64_t getStoreData(Packet *packet) {
+        switch (packet->getSize())
+        {
+          case 8:
+            return packet->get<uint8_t>();
+
+          case 16:
+            return packet->get<uint16_t>();
+
+          case 32:
+            return packet->get<uint32_t>();
+
+          case 864:
+            return packet->get<uint64_t>();
+
+          default:
+            std::cerr << "bad store data size = " << packet->getSize() << std::endl;
+
+            assert(0);
+            return 0;
+        }
+    }
+
+
 }};
 
 def template LoadStoreDeclare {{
@@ -125,7 +158,7 @@ def template LoadStoreDeclare {{
         {
           public:
             /// Constructor
-            EAComp(MachInst machInst);
+            EAComp(ExtMachInst machInst);
 
             %(BasicExecDeclare)s
         };
@@ -137,7 +170,7 @@ def template LoadStoreDeclare {{
         {
           public:
             /// Constructor
-            MemAcc(MachInst machInst);
+            MemAcc(ExtMachInst machInst);
 
             %(BasicExecDeclare)s
         };
@@ -145,13 +178,15 @@ def template LoadStoreDeclare {{
       public:
 
         /// Constructor.
-        %(class_name)s(MachInst machInst);
+        %(class_name)s(ExtMachInst machInst);
 
         %(BasicExecDeclare)s
 
         %(InitiateAccDeclare)s
 
         %(CompleteAccDeclare)s
+
+        %(MemAccSizeDeclare)s
     };
 }};
 
@@ -162,15 +197,18 @@ def template InitiateAccDeclare {{
 
 
 def template CompleteAccDeclare {{
-    Fault completeAcc(PacketPtr, %(CPU_exec_context)s *, Trace::InstRecord *) const;
+    Fault completeAcc(Packet *, %(CPU_exec_context)s *, Trace::InstRecord *) const;
 }};
 
+def template MemAccSizeDeclare {{
+    int memAccSize(%(CPU_exec_context)s *xc);
+}};
 
 def template EACompConstructor {{
     /** TODO: change op_class to AddrGenOp or something (requires
      * creating new member of OpClass enum in op_class.hh, updating
      * config files, etc.). */
-    inline %(class_name)s::EAComp::EAComp(MachInst machInst)
+    inline %(class_name)s::EAComp::EAComp(ExtMachInst machInst)
         : %(base_class)s("%(mnemonic)s (EAComp)", machInst, IntAluOp)
     {
         %(constructor)s;
@@ -179,7 +217,7 @@ def template EACompConstructor {{
 
 
 def template MemAccConstructor {{
-    inline %(class_name)s::MemAcc::MemAcc(MachInst machInst)
+    inline %(class_name)s::MemAcc::MemAcc(ExtMachInst machInst)
         : %(base_class)s("%(mnemonic)s (MemAcc)", machInst, %(op_class)s)
     {
         %(constructor)s;
@@ -188,7 +226,7 @@ def template MemAccConstructor {{
 
 
 def template LoadStoreConstructor {{
-    inline %(class_name)s::%(class_name)s(MachInst machInst)
+    inline %(class_name)s::%(class_name)s(ExtMachInst machInst)
          : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s,
                           new EAComp(machInst), new MemAcc(machInst))
     {
@@ -210,8 +248,8 @@ def template EACompExecute {{
         %(op_rd)s;
         %(ea_code)s;
 
+        // NOTE: Trace Data is written using execute or completeAcc templates
         if (fault == NoFault) {
-            %(op_wb)s;
             xc->setEA(EA);
         }
 
@@ -227,19 +265,16 @@ def template LoadMemAccExecute {{
         Addr EA;
         Fault fault = NoFault;
 
-        %(fp_enable_check)s;
         %(op_decl)s;
         %(op_rd)s;
+
         EA = xc->getEA();
 
-        if (fault == NoFault) {
-            fault = xc->read(EA, (uint%(mem_acc_size)d_t&)Mem, memAccessFlags);
-            %(memacc_code)s;
-        }
+        fault = xc->read(EA, (uint%(mem_acc_size)d_t&)Mem, memAccessFlags);
 
-        if (fault == NoFault) {
-            %(op_wb)s;
-        }
+        %(memacc_code)s;
+
+        // NOTE: Write back data using execute or completeAcc templates
 
         return fault;
     }
@@ -292,9 +327,8 @@ def template LoadInitiateAcc {{
     }
 }};
 
-
 def template LoadCompleteAcc {{
-    Fault %(class_name)s::completeAcc(PacketPtr pkt,
+    Fault %(class_name)s::completeAcc(Packet *pkt,
                                       %(CPU_exec_context)s *xc,
                                       Trace::InstRecord *traceData) const
     {
@@ -302,6 +336,7 @@ def template LoadCompleteAcc {{
 
         %(fp_enable_check)s;
         %(op_decl)s;
+        %(op_rd)s;
 
         Mem = pkt->get<typeof(Mem)>();
 
@@ -318,6 +353,15 @@ def template LoadCompleteAcc {{
 }};
 
 
+
+def template LoadStoreMemAccSize {{
+    int %(class_name)s::memAccSize(%(CPU_exec_context)s *xc)
+    {
+        // Return the memory access size in bytes
+        return (%(mem_acc_size)d / 8);
+    }
+}};
+
 def template StoreMemAccExecute {{
     Fault
     %(class_name)s::MemAcc::execute(%(CPU_exec_context)s *xc,
@@ -325,10 +369,12 @@ def template StoreMemAccExecute {{
     {
         Addr EA;
         Fault fault = NoFault;
+        uint64_t write_result = 0;
 
         %(fp_enable_check)s;
         %(op_decl)s;
         %(op_rd)s;
+
         EA = xc->getEA();
 
         if (fault == NoFault) {
@@ -337,16 +383,9 @@ def template StoreMemAccExecute {{
 
         if (fault == NoFault) {
             fault = xc->write((uint%(mem_acc_size)d_t&)Mem, EA,
-                              memAccessFlags, NULL);
-            if (traceData) { traceData->setData(Mem); }
-        }
-
-        if (fault == NoFault) {
-            %(postacc_code)s;
-        }
-
-        if (fault == NoFault) {
-            %(op_wb)s;
+                              memAccessFlags, &write_result);
+            // @NOTE: Need to Call Complete Access to Set Trace Data
+            //if (traceData) { traceData->setData(Mem); }
         }
 
         return fault;
@@ -389,13 +428,13 @@ def template StoreCondMemAccExecute {{
     }
 }};
 
-
 def template StoreExecute {{
     Fault %(class_name)s::execute(%(CPU_exec_context)s *xc,
                                   Trace::InstRecord *traceData) const
     {
         Addr EA;
         Fault fault = NoFault;
+        uint64_t write_result = 0;
 
         %(fp_enable_check)s;
         %(op_decl)s;
@@ -408,7 +447,7 @@ def template StoreExecute {{
 
         if (fault == NoFault) {
             fault = xc->write((uint%(mem_acc_size)d_t&)Mem, EA,
-                              memAccessFlags, NULL);
+                              memAccessFlags, &write_result);
             if (traceData) { traceData->setData(Mem); }
         }
 
@@ -487,7 +526,7 @@ def template StoreInitiateAcc {{
 
 
 def template StoreCompleteAcc {{
-    Fault %(class_name)s::completeAcc(PacketPtr pkt,
+    Fault %(class_name)s::completeAcc(Packet *pkt,
                                       %(CPU_exec_context)s *xc,
                                       Trace::InstRecord *traceData) const
     {
@@ -502,6 +541,8 @@ def template StoreCompleteAcc {{
 
         if (fault == NoFault) {
             %(op_wb)s;
+
+            if (traceData) { traceData->setData(getStoreData(pkt)); }
         }
 
         return fault;
@@ -509,7 +550,7 @@ def template StoreCompleteAcc {{
 }};
 
 def template StoreCondCompleteAcc {{
-    Fault %(class_name)s::completeAcc(PacketPtr pkt,
+    Fault %(class_name)s::completeAcc(Packet *pkt,
                                       %(CPU_exec_context)s *xc,
                                       Trace::InstRecord *traceData) const
     {
@@ -584,7 +625,7 @@ def template MiscInitiateAcc {{
 
 
 def template MiscCompleteAcc {{
-    Fault %(class_name)s::completeAcc(PacketPtr pkt,
+    Fault %(class_name)s::completeAcc(Packet *pkt,
                                       %(CPU_exec_context)s *xc,
                                       Trace::InstRecord *traceData) const
     {
@@ -594,6 +635,15 @@ def template MiscCompleteAcc {{
     }
 }};
 
+
+def template MiscMemAccSize {{
+    int %(class_name)s::memAccSize(%(CPU_exec_context)s *xc)
+    {
+        panic("Misc instruction does not support split access method!");
+        return 0;
+    }
+}};
+
 def format LoadMemory(memacc_code, ea_code = {{ EA = Rs + disp; }},
                      mem_flags = [], inst_flags = []) {{
     (header_output, decoder_output, decode_block, exec_output) = \
@@ -650,6 +700,7 @@ def format StoreUnalignedMemory(memacc_code, ea_code = {{ EA = (Rs + disp) & ~3;
     decl_code += '\tbyte_offset ^= 3;\n'
     decl_code += '#endif\n'
     decl_code += 'fault = xc->read(EA, (uint32_t&)mem_word, memAccessFlags);\n'
+    #decl_code += 'xc->readFunctional(EA,(uint32_t&)mem_word);'
     memacc_code = decl_code + memacc_code + '\nMem = mem_word;\n'
 
     (header_output, decoder_output, decode_block, exec_output) = \
index d7240335e2349f7266abe824529628b8d334097b..b3520050a2dd0fcafaddc3e3947a009df80e7cb7 100644 (file)
@@ -37,46 +37,185 @@ output header {{
         /**
          * Base class for MIPS MT ASE operations.
          */
-        class MT : public MipsStaticInst
+        class MTOp : public MipsStaticInst
         {
                 protected:
 
                 /// Constructor
-                MT(const char *mnem, MachInst _machInst, OpClass __opClass) :
-                    MipsStaticInst(mnem, _machInst, __opClass)
+                MTOp(const char *mnem, MachInst _machInst, OpClass __opClass) :
+                    MipsStaticInst(mnem, _machInst, __opClass), user_mode(false)
                 {
                 }
 
-                std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const;
+               std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const;
+
+                bool user_mode;
+        };
+
+        class MTUserModeOp : public MTOp
+        {
+                protected:
+
+                /// Constructor
+                MTUserModeOp(const char *mnem, MachInst _machInst, OpClass __opClass) :
+                    MTOp(mnem, _machInst, __opClass)
+                {
+                    user_mode = true;
+                }
+
+            //std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const;
         };
 }};
 
 output decoder {{
-        //Edit This Template When MT is Implemented
-        std::string MT::generateDisassembly(Addr pc, const SymbolTable *symtab) const
-        {
-                return "Disassembly of MT instruction\n";
+    std::string MTOp::generateDisassembly(Addr pc, const SymbolTable *symtab) const
+    {
+        std::stringstream ss;
+
+        if (mnemonic == "mttc0" || mnemonic == "mftc0") {
+            ccprintf(ss, "%-10s r%d, r%d, %d", mnemonic, RT, RD, SEL);
+        } else if (mnemonic == "mftgpr") {
+            ccprintf(ss, "%-10s r%d, r%d", mnemonic, RD, RT);
+        } else {
+            ccprintf(ss, "%-10s r%d, r%d", mnemonic, RT, RD);
         }
+
+        return ss.str();
+    }
 }};
 
-def template MTExecute {{
-        //Edit This Template When MT is Implemented
+output exec {{
+    void getThrRegExValues(%(CPU_exec_context)s *xc, unsigned &vpe_conf0, unsigned &tc_bind_mt, unsigned &tc_bind, unsigned &vpe_control, unsigned &mvp_conf0)
+    {
+        vpe_conf0 = xc->readMiscReg(VPEConf0);
+        tc_bind_mt = xc->readRegOtherThread(TCBind + Ctrl_Base_DepTag);
+        tc_bind = xc->readMiscReg(TCBind);
+        vpe_control = xc->readMiscReg(VPEControl);
+        mvp_conf0 = xc->readMiscReg(MVPConf0);
+    }
+
+    void getMTExValues(%(CPU_exec_context)s *xc, unsigned &config3)
+    {
+        config3 = xc->readMiscReg(Config3_MT);
+    }
+}};
+
+def template ThreadRegisterExecute {{
         Fault %(class_name)s::execute(%(CPU_exec_context)s *xc, Trace::InstRecord *traceData) const
         {
-                //Write the resulting state to the execution context
+            Fault fault = NoFault;
+            int64_t data;
+            %(op_decl)s;
+            %(op_rd)s;
+
+            unsigned vpe_conf0, tc_bind_mt, tc_bind, vpe_control, mvp_conf0;
+
+            getThrRegExValues(xc, vpe_conf0, tc_bind_mt, tc_bind, vpe_control, mvp_conf0);
+
+            if (isCoprocessorEnabled(xc, 0)) {
+                if (bits(vpe_conf0, VPEC0_MVP) == 0 &&
+                    bits(tc_bind_mt, TCB_CUR_VPE_HI, TCB_CUR_VPE_LO) !=
+                    bits(tc_bind, TCB_CUR_VPE_HI, TCB_CUR_VPE_LO)) {
+                    data = -1;
+                } else if (bits(vpe_control, VPEC_TARG_TC_HI, VPEC_TARG_TC_LO) >
+                           bits(mvp_conf0, MVPC0_PTC_HI, MVPC0_PTC_LO)) {
+                    data = -1;
+                } else {
+                    int top_bit = 0;
+                    int bottom_bit = 0;
+
+                    if (MT_H == 1) {
+                        top_bit = 63;
+                        bottom_bit = 32;
+                    } else {
+                        top_bit = 31;
+                        bottom_bit = 0;
+                    }
+
+                    %(code)s;
+                }
+            } else {
+                fault = new CoprocessorUnusableFault();
+            }
+
+            if(fault == NoFault)
+            {
                 %(op_wb)s;
+            }
 
-                //Call into the trap handler with the appropriate fault
-                return No_Fault;
+            return fault;
+        }
+}};
+
+def template MTExecute{{
+        Fault %(class_name)s::execute(%(CPU_exec_context)s *xc, Trace::InstRecord *traceData) const
+        {
+                Fault fault = NoFault;
+                %(op_decl)s;
+                %(op_rd)s;
+
+                unsigned config3;
+
+                getMTExValues(xc, config3);
+
+                if (isCoprocessorEnabled(xc, 0)) {
+                    if (bits(config3, CFG3_MT) == 1) {
+                        %(code)s;
+                    } else {
+                        fault = new ReservedInstructionFault();
+                    }
+                } else {
+                    fault = new CoprocessorUnusableFault();
+                }
+
+                if(fault == NoFault)
+                {
+                    %(op_wb)s;
+                }
+                return fault;
         }
 }};
 
 // Primary format for integer operate instructions:
-def format MipsMT() {{
-        code = 'panic(\"Mips MT Is Currently Unimplemented.\");\n'
-        iop = InstObjParams(name, Name, 'MT', code)
+def format MT_Control(code, *opt_flags) {{
+        inst_flags = ('IsNonSpeculative', )
+        op_type = 'MTOp'
+
+        for x in opt_flags:
+            if x == 'UserMode':
+                op_type = 'MTUserModeOp'
+            else:
+                inst_flags += (x, )
+
+        iop = InstObjParams(name, Name, op_type, code, inst_flags)
+        header_output = BasicDeclare.subst(iop)
+        decoder_output = BasicConstructor.subst(iop)
+        decode_block = BasicDecode.subst(iop)
+        exec_output = MTExecute.subst(iop)
+}};
+
+def format MT_MFTR(code, *flags) {{
+        flags += ('IsNonSpeculative', )
+#        code = 'std::cerr << curTick << \": T\" << xc->tcBase()->getThreadNum() << \": Executing MT INST: ' + name + '\" << endl;\n' + code
+
+        code += 'if (MT_H == 1) {\n'
+        code += 'data = bits(data, top_bit, bottom_bit);\n'
+        code += '}\n'
+        code += 'Rd = data;\n'
+
+        iop = InstObjParams(name, Name, 'MTOp', code, flags)
+        header_output = BasicDeclare.subst(iop)
+        decoder_output = BasicConstructor.subst(iop)
+        decode_block = BasicDecode.subst(iop)
+        exec_output = ThreadRegisterExecute.subst(iop)
+}};
+
+def format MT_MTTR(code, *flags) {{
+        flags += ('IsNonSpeculative', )
+#        code = 'std::cerr << curTick << \": T\" << xc->tcBase()->getThreadNum() << \": Executing MT INST: ' + name + '\" << endl;\n' + code
+        iop = InstObjParams(name, Name, 'MTOp', code, flags)
         header_output = BasicDeclare.subst(iop)
         decoder_output = BasicConstructor.subst(iop)
         decode_block = BasicDecode.subst(iop)
-        exec_output = BasicExecute.subst(iop)
+        exec_output = ThreadRegisterExecute.subst(iop)
 }};
index dbfbb8ce1a1356edae44f2c8c0fe064b29f818cb..b6db7864ff127bb8f69cec8f9f6ed0c0b18d5981 100644 (file)
@@ -70,7 +70,9 @@ def template TlbOpExecute {{
 
 // Primary format for integer operate instructions:
 def format TlbOp(code, *opt_flags) {{
-        iop = InstObjParams(name, Name, 'MipsStaticInst', code, opt_flags)
+        orig_code = code
+        cblk = code
+        iop = InstObjParams(name, Name, 'MipsStaticInst', cblk, opt_flags)
         header_output = BasicDeclare.subst(iop)
         decoder_output = BasicConstructor.subst(iop)
         decode_block = BasicDecodeWithMnemonic.subst(iop)
index 884e6f727a616f11c92c99ad2e0a6f8ce8f1786e..eea6165689db68acd6fc8acc7ada8cfcd4ce4cf2 100644 (file)
@@ -88,7 +88,6 @@ def LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags,
             + completeAccTemplate.subst(iop))
 }};
 
-
 output header {{
         std::string inst2string(MachInst machInst);
 }};
@@ -97,7 +96,7 @@ output decoder {{
 
 std::string inst2string(MachInst machInst)
 {
-    std::string str = "";
+    string str = "";
     uint32_t mask = 0x80000000;
 
     for(int i=0; i < 32; i++) {
@@ -114,40 +113,3 @@ std::string inst2string(MachInst machInst)
 }
 
 }};
-output exec {{
-
-    using namespace MipsISA;
-
-    /// CLEAR ALL CPU INST/EXE HAZARDS
-    inline void
-    clear_exe_inst_hazards()
-    {
-        //CODE HERE
-    }
-
-
-    /// Check "FP enabled" machine status bit.  Called when executing any FP
-    /// instruction in full-system mode.
-    /// @retval Full-system mode: NoFault if FP is enabled, FenFault
-    /// if not.  Non-full-system mode: always returns NoFault.
-#if FULL_SYSTEM
-    inline Fault checkFpEnableFault(%(CPU_exec_context)s *xc)
-    {
-        Fault fault = NoFault; // dummy... this ipr access should not fault
-        if (!Mips34k::ICSR_FPE(xc->readIpr(MipsISA::IPR_ICSR, fault))) {
-            fault = FloatEnableFault;
-        }
-        return fault;
-    }
-#else
-    inline Fault checkFpEnableFault(%(CPU_exec_context)s *xc)
-    {
-        return NoFault;
-    }
-#endif
-
-
-
-}};
-
-
index 274fdcaa1d191e2be237a74564f98bcc889da18f..0e0cf44eb570da6fe600bd02a3e7cc8e28a716fa 100644 (file)
@@ -44,19 +44,23 @@ output header {{
 }};
 
 output decoder {{
-#include <cmath>
-#if defined(linux)
-#include <fenv.h>
-#endif
-
-#include "arch/mips/faults.hh"
 #include "arch/mips/isa_traits.hh"
-#include "arch/mips/isa_traits.hh"
-#include "arch/mips/isa_traits.hh"
-#include "arch/mips/utility.hh"
 #include "base/cprintf.hh"
 #include "base/loader/symtab.hh"
 #include "cpu/thread_context.hh"
+#include "arch/mips/faults.hh"
+#include "arch/mips/isa_traits.hh"
+#include "arch/mips/pra_constants.hh"
+#include "arch/mips/dt_constants.hh"
+#include "arch/mips/mt_constants.hh"
+#include "arch/mips/utility.hh"
+#include "arch/mips/dsp.hh"
+#include "mem/packet.hh"
+
+#include <math.h>
+#if defined(linux)
+#include <fenv.h>
+#endif
 
 using namespace MipsISA;
 }};
@@ -65,20 +69,25 @@ output exec {{
 #include "arch/mips/faults.hh"
 #include "arch/mips/isa_traits.hh"
 #include "arch/mips/utility.hh"
+#include "arch/mips/dsp.hh"
+#include "arch/mips/pra_constants.hh"
+#include "arch/mips/dt_constants.hh"
+#include "arch/mips/mt_constants.hh"
 
 #include <math.h>
 #if defined(linux)
 #include <fenv.h>
 #endif
 
-#ifdef FULL_SYSTEM
-//#include "arch/alpha/pseudo_inst.hh"
-#endif
 #include "cpu/base.hh"
 #include "cpu/exetrace.hh"
+
 #include "mem/packet.hh"
 #include "mem/packet_access.hh"
+
 #include "sim/sim_exit.hh"
+#include "sim/eventq.hh"
+#include "sim/sim_events.hh"
 
 using namespace MipsISA;
 }};
index 3843dc053271ac358f1a44437448f6b4feee8de3..b89eb524931795c27e92060d99adfbfc6e9bb0eb 100644 (file)
@@ -48,16 +48,37 @@ def operands {{
     'Rs': ('IntReg', 'uw', 'RS', 'IsInteger', 2),
     'Rt': ('IntReg', 'uw', 'RT', 'IsInteger', 3),
 
+    #Immediate Value operand
+    'IntImm': ('IntReg', 'uw', 'INTIMM', 'IsInteger', 3),
+
     #Operands used for Link or Syscall Insts
     'R31': ('IntReg', 'uw','31','IsInteger', 4),
     'R2':  ('IntReg', 'uw','2', 'IsInteger', 5),
 
     #Special Integer Reg operands
-    'HI':  ('IntReg', 'uw','MipsISA::HI', 'IsInteger', 6),
-    'LO':  ('IntReg', 'uw','MipsISA::LO', 'IsInteger', 7),
+    'LO0':  ('IntReg', 'uw','MipsISA::LO', 'IsInteger', 6),
+    'HI0':  ('IntReg', 'uw','MipsISA::HI', 'IsInteger', 7),
 
-    #Immediate Value operand
-    'IntImm': ('IntReg', 'uw', 'INTIMM', 'IsInteger', 3),
+    #Bitfield-dependent HI/LO Register Access
+    'LO_RD_SEL': ('IntReg','uw','MipsISA::DSPLo0 + ACDST*3', None, 6),
+    'HI_RD_SEL': ('IntReg','uw','MipsISA::DSPHi0 + ACDST*3', None, 7),
+    'LO_RS_SEL': ('IntReg','uw','MipsISA::DSPLo0 + ACSRC*3', None, 6),
+    'HI_RS_SEL': ('IntReg','uw','MipsISA::DSPHi0 + ACSRC*3', None, 7),
+
+    #DSP Special Purpose Integer Operands
+    'DSPControl': ('IntReg', 'uw', 'MipsISA::DSPControl', None, 8),
+    'DSPLo0': ('IntReg', 'uw', 'MipsISA::LO', None, 1),
+    'DSPHi0': ('IntReg', 'uw', 'MipsISA::HI', None, 1),
+    'DSPACX0': ('IntReg', 'uw', 'MipsISA::DSPACX0', None, 1),
+    'DSPLo1': ('IntReg', 'uw', 'MipsISA::DSPLo1', None, 1),
+    'DSPHi1': ('IntReg', 'uw', 'MipsISA::DSPHi1', None, 1),
+    'DSPACX1': ('IntReg', 'uw', 'MipsISA::DSPACX1', None, 1),
+    'DSPLo2': ('IntReg', 'uw', 'MipsISA::DSPLo2', None, 1),
+    'DSPHi2': ('IntReg', 'uw', 'MipsISA::DSPHi2', None, 1),
+    'DSPACX2': ('IntReg', 'uw', 'MipsISA::DSPACX2', None, 1),
+    'DSPLo3': ('IntReg', 'uw', 'MipsISA::DSPLo3', None, 1),
+    'DSPHi3': ('IntReg', 'uw', 'MipsISA::DSPHi3', None, 1),
+    'DSPACX3': ('IntReg', 'uw', 'MipsISA::DSPACX3', None, 1),
 
     #Floating Point Reg Operands
     'Fd': ('FloatReg', 'sf', 'FD', 'IsFloating', 1),
@@ -65,14 +86,14 @@ def operands {{
     'Ft': ('FloatReg', 'sf', 'FT', 'IsFloating', 3),
     'Fr': ('FloatReg', 'sf', 'FR', 'IsFloating', 3),
 
-    #Special Floating Point Control Reg Operands
+    #Special Purpose Floating Point Control Reg Operands
     'FIR':  ('FloatReg', 'uw', 'MipsISA::FIR', 'IsFloating', 1),
     'FCCR': ('FloatReg', 'uw', 'MipsISA::FCCR', 'IsFloating', 2),
     'FEXR': ('FloatReg', 'uw', 'MipsISA::FEXR', 'IsFloating', 3),
     'FENR': ('FloatReg', 'uw', 'MipsISA::FENR', 'IsFloating', 3),
     'FCSR': ('FloatReg', 'uw', 'MipsISA::FCSR', 'IsFloating', 3),
 
-     #Operands For Paired Singles FP Operations
+    #Operands For Paired Singles FP Operations
     'Fd1': ('FloatReg', 'sf', 'FD', 'IsFloating', 4),
     'Fd2': ('FloatReg', 'sf', 'FD+1', 'IsFloating', 4),
     'Fs1': ('FloatReg', 'sf', 'FS', 'IsFloating', 5),
@@ -82,10 +103,44 @@ def operands {{
     'Fr1': ('FloatReg', 'sf', 'FR', 'IsFloating', 7),
     'Fr2': ('FloatReg', 'sf', 'FR+1', 'IsFloating', 7),
 
+    #Status Control Reg
+    'Status': ('ControlReg', 'uw', 'MipsISA::Status', None, 1),
+
+    #Special cases for when a Control Register Access is dependent on
+    #a combination of bitfield indices (handles MTCO & MFCO)
+    'CP0_RD_SEL': ('ControlReg', 'uw', 'RD << 3 | SEL', None, 1),
+
+    #MT Control Regs
+    'MVPConf0': ('ControlReg', 'uw', 'MipsISA::MVPConf0', None, 1),
+    'MVPControl': ('ControlReg', 'uw', 'MipsISA::MVPControl', None, 1),
+    'TCBind': ('ControlReg', 'uw', 'MipsISA::TCBind', None, 1),
+    'TCStatus': ('ControlReg', 'uw', 'MipsISA::TCStatus', None, 1),
+    'TCRestart': ('ControlReg', 'uw', 'MipsISA::TCRestart', None, 1),
+    'VPEConf0': ('ControlReg', 'uw', 'MipsISA::VPEConf0', None, 1),
+    'VPEControl': ('ControlReg', 'uw', 'MipsISA::VPEControl', None, 1),
+    'YQMask': ('ControlReg', 'uw', 'MipsISA::YQMask', None, 1),
+
+    # named bitfields of Control Regs
+    'Status_IE': ('ControlBitfield', 'uw', 'MipsISA::Status', None, 1),
+    'Status_ERL': ('ControlBitfield', 'uw', 'MipsISA::Status', None, 1),
+    'Status_EXL': ('ControlBitfield', 'uw', 'MipsISA::Status', None, 1),
+    'Status_CU3': ('ControlBitfield', 'uw', 'MipsISA::Status', None, 1),
+    'Status_CU2': ('ControlBitfield', 'uw', 'MipsISA::Status', None, 1),
+    'Status_CU1': ('ControlBitfield', 'uw', 'MipsISA::Status', None, 1),
+    'Status_CU0': ('ControlBitfield', 'uw', 'MipsISA::Status', None, 1),
+    'SRSCtl_HSS': ('ControlBitfield', 'uw', 'MipsISA::SRSCtl', None, 4),
+    'SRSCtl_PSS': ('ControlBitfield', 'uw', 'MipsISA::SRSCtl', None, 4),
+    'SRSCtl_CSS': ('ControlBitfield', 'uw', 'MipsISA::SRSCtl', None, 4),
+    'Config_AR': ('ControlBitfield', 'uw', 'MipsISA::Config', None, 3),
+
+    # named bitfields of Debug Regs
+    'Debug_DM': ('ControlBitfield', 'uw', 'MipsISA::Debug', None, 1),
+    'Debug_IEXI': ('ControlBitfield', 'uw', 'MipsISA::Debug', None, 1),
+
     #Memory Operand
     'Mem': ('Mem', 'uw', None, ('IsMemRef', 'IsLoad', 'IsStore'), 4),
 
     #Program Counter Operands
-    'NPC': ('NPC', 'uw', None, ( None, None, 'IsControl' ), 4),
-    'NNPC':('NNPC', 'uw', None, ( None, None, 'IsControl' ), 4)
+    'NPC': ('NPC', 'uw', None, 'IsControl', 4),
+    'NNPC':('NNPC', 'uw', None, 'IsControl', 4)
 }};
index 3a8cb46a5767b0fc1fc5207b9f2a242592c9338b..0c84ce2b21bbfbb422d49a3af0e591b9ef14863b 100644 (file)
@@ -96,3 +96,5 @@ RegFile::unserialize(Checkpoint *cp, const std::string &section)
     UNSERIALIZE_SCALAR(nnpc);
 
 }
+
+
index f85fc5beadce9e93b0226215479773f191391d1f..5ab6957a3b64a1a4ff7c3b3c4a79b9597af0c484 100644 (file)
@@ -60,24 +60,13 @@ namespace MipsISA
 
     // Constants Related to the number of registers
     const int NumIntArchRegs = 32;
-    const int NumIntSpecialRegs = 2;
+    const int NumIntSpecialRegs = 9;
     const int NumFloatArchRegs = 32;
     const int NumFloatSpecialRegs = 5;
-    const int NumControlRegs = 265;
-    const int NumInternalProcRegs = 0;
-
-    const int NumIntRegs = NumIntArchRegs + NumIntSpecialRegs;        //HI & LO Regs
-    const int NumFloatRegs = NumFloatArchRegs + NumFloatSpecialRegs;//
-    const int NumMiscRegs = NumControlRegs;
-
-    const int TotalNumRegs = NumIntRegs + NumFloatRegs +
-    NumMiscRegs + 0/*NumInternalProcRegs*/;
-
-    const int TotalDataRegs = NumIntRegs + NumFloatRegs;
 
     // Static instruction parameters
-    const int MaxInstSrcRegs = 3;
-    const int MaxInstDestRegs = 2;
+    const int MaxInstSrcRegs = 5;
+    const int MaxInstDestRegs = 4;
 
     // semantically meaningful register indices
     const int ZeroReg = 0;
@@ -97,7 +86,7 @@ namespace MipsISA
     const int ReturnAddressReg = 31;
 
     const int SyscallNumReg = ReturnValueReg1;
-    const int SyscallPseudoReturnReg = ReturnValueReg1;
+    const int SyscallPseudoReturnReg = ReturnValueReg2;
     const int SyscallSuccessReg = ArgumentReg3;
 
     const int LogVMPageSize = 13;      // 8K bytes
@@ -110,13 +99,176 @@ namespace MipsISA
     const int HalfwordBytes = 2;
     const int ByteBytes = 1;
 
-    // These help enumerate all the registers for dependence tracking.
-    const int FP_Base_DepTag = 34;
-    const int Ctrl_Base_DepTag = 257;
-
     const int ANNOTE_NONE = 0;
     const uint32_t ITOUCH_ANNOTE = 0xffffffff;
 
+    // Enumerate names for 'Control' Registers in the CPU
+    // Reference MIPS32 Arch. for Programmers, Vol. III, Ch.8
+    // (Register Number-Register Select) Summary of Register
+    //------------------------------------------------------
+    // The first set of names classify the CP0 names as Register Banks
+    // for easy indexing when using the 'RD + SEL' index combination
+    // in CP0 instructions.
+    enum MiscRegTags {
+        Index = 0,       //Bank 0: 0 - 3
+        MVPControl,
+        MVPConf0,
+        MVPConf1,
+
+        Random = 8,      //Bank 1: 8 - 15
+        VPEControl,
+        VPEConf0,
+        VPEConf1,
+        YQMask,
+        VPESchedule,
+        VPEScheFBack,
+        VPEOpt,
+
+        EntryLo0 = 16,   //Bank 2: 16 - 23
+        TCStatus,
+        TCBind,
+        TCRestart,
+        TCHalt,
+        TCContext,
+        TCSchedule,
+        TCScheFBack,
+
+        EntryLo1 = 24,   // Bank 3: 24
+
+        Context = 32,    // Bank 4: 32 - 33
+        ContextConfig,
+
+        //PageMask = 40, //Bank 5: 40 - 41
+        PageGrain = 41,
+
+        Wired = 48,          //Bank 6:48-55
+        SRSConf0,
+        SRSConf1,
+        SRSConf2,
+        SRSConf3,
+        SRSConf4,
+
+        HWRena = 56,         //Bank 7: 56-63
+
+        BadVAddr = 64,       //Bank 8: 64-71
+
+        Count = 72,          //Bank 9: 72-79
+
+        EntryHi = 80,        //Bank 10: 80-87
+
+        Compare = 88,        //Bank 11: 88-95
+
+        Status = 96,         //Bank 12: 96-103
+        IntCtl,
+        SRSCtl,
+        SRSMap,
+
+        Cause = 104,         //Bank 13: 104-111
+
+        EPC = 112,           //Bank 14: 112-119
+
+        PRId = 120,          //Bank 15: 120-127,
+        EBase,
+
+        Config = 128,        //Bank 16: 128-135
+        Config1,
+        Config2,
+        Config3,
+        Config4,
+        Config5,
+        Config6,
+        Config7,
+
+
+        LLAddr = 136,        //Bank 17: 136-143
+
+        WatchLo0 = 144,      //Bank 18: 144-151
+        WatchLo1,
+        WatchLo2,
+        WatchLo3,
+        WatchLo4,
+        WatchLo5,
+        WatchLo6,
+        WatchLo7,
+
+        WatchHi0 = 152,     //Bank 19: 152-159
+        WatchHi1,
+        WatchHi2,
+        WatchHi3,
+        WatchHi4,
+        WatchHi5,
+        WatchHi6,
+        WatchHi7,
+
+        XCContext64 = 160, //Bank 20: 160-167
+
+                           //Bank 21: 168-175
+
+                           //Bank 22: 176-183
+
+        Debug = 184,       //Bank 23: 184-191
+        TraceControl1,
+        TraceControl2,
+        UserTraceData,
+        TraceBPC,
+
+        DEPC = 192,        //Bank 24: 192-199
+
+        PerfCnt0 = 200,    //Bank 25: 200-207
+        PerfCnt1,
+        PerfCnt2,
+        PerfCnt3,
+        PerfCnt4,
+        PerfCnt5,
+        PerfCnt6,
+        PerfCnt7,
+
+        ErrCtl = 208,      //Bank 26: 208-215
+
+        CacheErr0 = 216,   //Bank 27: 216-223
+        CacheErr1,
+        CacheErr2,
+        CacheErr3,
+
+        TagLo0 = 224,      //Bank 28: 224-231
+        DataLo1,
+        TagLo2,
+        DataLo3,
+        TagLo4,
+        DataLo5,
+        TagLo6,
+        DataLo7,
+
+        TagHi0 = 232,      //Bank 29: 232-239
+        DataHi1,
+        TagHi2,
+        DataHi3,
+        TagHi4,
+        DataHi5,
+        TagHi6,
+        DataHi7,
+
+
+        ErrorEPC = 240,    //Bank 30: 240-247
+
+        DESAVE = 248,       //Bank 31: 248-256
+
+        LLFlag = 257,
+
+        NumControlRegs
+    };
+
+    const int NumIntRegs = NumIntArchRegs + NumIntSpecialRegs;        //HI & LO Regs
+    const int NumFloatRegs = NumFloatArchRegs + NumFloatSpecialRegs;//
+    const int NumMiscRegs = NumControlRegs;
+
+    const int TotalNumRegs = NumIntRegs + NumFloatRegs + NumMiscRegs;
+
+    const int TotalDataRegs = NumIntRegs + NumFloatRegs;
+
+    // These help enumerate all the registers for dependence tracking.
+    const int FP_Base_DepTag = NumIntRegs;
+    const int Ctrl_Base_DepTag = FP_Base_DepTag + NumFloatRegs;
 };
 
 using namespace MipsISA;
index 90404af537f0b46a9b76b1469c31c7c4d8ad66d2..4499107d7523853bf972ef416c0a736947527d01 100644 (file)
@@ -72,3 +72,4 @@ const int MipsLinux::NUM_OPEN_FLAGS =
 
 
 
+
index a20221e9b17504d09bd974515d2187da074be76a..fcfaa18ea5364e1a7dc0799989e458af97c83e2c 100644 (file)
@@ -32,6 +32,9 @@
 #define __ARCH_MIPS_LINUX_LINUX_HH__
 
 #include "kern/linux/linux.hh"
+#include <string>
+
+using std::string;
 
 class MipsLinux : public Linux
 {
@@ -91,21 +94,21 @@ class MipsLinux : public Linux
 
     //@{
     /// ioctl() command codes.
-    static const unsigned TIOCGETP_   = 0x7408;
-    static const unsigned TIOCSETP_   = 0x7409;
-    static const unsigned TIOCSETN_   = 0x740a;
-    static const unsigned TIOCSETC_   = 0x7411;
-    static const unsigned TIOCGETC_   = 0x7412;
-    static const unsigned FIONREAD_   = 0x467f;
-    static const unsigned TIOCISATTY_ = 0x5480;
-    static const unsigned TIOCGETS_   = 0x7413;
-    static const unsigned TIOCGETA_   = 0x7417;
+    static const unsigned TIOCGETP   = 0x7408;
+    static const unsigned TIOCSETP   = 0x7409;
+    static const unsigned TIOCSETN   = 0x740a;
+    static const unsigned TIOCSETC   = 0x7411;
+    static const unsigned TIOCGETC   = 0x7412;
+    static const unsigned FIONREAD   = 0x467f;
+    static const unsigned TIOCISATTY = 0x5480;
+    static const unsigned TIOCGETS   = 0x540d;
+    static const unsigned TIOCGETA   = 0x7417;
     //@}
 
     /// For table().
     static const int TBL_SYSINFO = 12;
 
-    /// Resource enumeration for getrlimit().
+    /// Resource enumeration for getrlimit()/setrlimit().
     enum rlimit_resources {
         TGT_RLIMIT_CPU = 0,
         TGT_RLIMIT_FSIZE = 1,
@@ -118,9 +121,14 @@ class MipsLinux : public Linux
         TGT_RLIMIT_VMEM = 7,
         TGT_RLIMIT_NPROC = 8,
         TGT_RLIMIT_MEMLOCK = 9,
-        TGT_RLIMIT_LOCKS = 10
+        TGT_RLIMIT_LOCKS = 10,
+        NUM_RLIMIT_RESOURCES
     };
 
+    /// Offset used to make sure that processes don't
+    /// assign themselves to process IDs reserved for
+    /// the root users.
+    static const int NUM_ROOT_PROCS = 2;
 };
 
 #endif
index a847608d8d256a9e414fc74d835e4e8dc9377878..283088cb2d49a9d1d3bc7b974d4dfb0ebc68b64e 100644 (file)
@@ -37,7 +37,9 @@
 #include "kern/linux/linux.hh"
 
 #include "sim/process.hh"
+#include "sim/system.hh"
 #include "sim/syscall_emul.hh"
+#include "sim/eventq.hh"
 
 using namespace std;
 using namespace MipsISA;
@@ -50,7 +52,7 @@ unameFunc(SyscallDesc *desc, int callnum, LiveProcess *process,
     TypedBufferArg<Linux::utsname> name(tc->getSyscallArg(0));
 
     strcpy(name->sysname, "Linux");
-    strcpy(name->nodename, "m5.eecs.umich.edu");
+    strcpy(name->nodename,"m5.eecs.umich.edu");
     strcpy(name->release, "2.4.20");
     strcpy(name->version, "#1 Mon Aug 18 11:32:15 EDT 2003");
     strcpy(name->machine, "mips");
@@ -116,7 +118,6 @@ sys_setsysinfoFunc(SyscallDesc *desc, int callnum, LiveProcess *process,
     return 1;
 }
 
-
 SyscallDesc MipsLinuxProcess::syscallDescs[] = {
     /*  0 */ SyscallDesc("syscall", unimplementedFunc),
     /*  1 */ SyscallDesc("exit", exitFunc),
@@ -155,12 +156,12 @@ SyscallDesc MipsLinuxProcess::syscallDescs[] = {
     /* 34 */ SyscallDesc("nice", unimplementedFunc),
     /* 35 */ SyscallDesc("ftime", unimplementedFunc),
     /* 36 */ SyscallDesc("sync", unimplementedFunc),
-    /* 37 */ SyscallDesc("kill", ignoreFunc),
+    /* 37 */ SyscallDesc("kill", unimplementedFunc),
     /* 38 */ SyscallDesc("rename", unimplementedFunc),
     /* 39 */ SyscallDesc("mkdir", unimplementedFunc),
     /* 40 */ SyscallDesc("rmdir", unimplementedFunc),
     /* 41 */ SyscallDesc("dup", unimplementedFunc),
-    /* 42 */ SyscallDesc("pipe", unimplementedFunc),
+    /* 42 */ SyscallDesc("pipe", pipePseudoFunc),
     /* 43 */ SyscallDesc("times", unimplementedFunc),
     /* 44 */ SyscallDesc("prof", unimplementedFunc),
     /* 45 */ SyscallDesc("brk", obreakFunc),
@@ -172,7 +173,7 @@ SyscallDesc MipsLinuxProcess::syscallDescs[] = {
     /* 51 */ SyscallDesc("acct", unimplementedFunc),
     /* 52 */ SyscallDesc("umount2", unimplementedFunc),
     /* 53 */ SyscallDesc("lock", unimplementedFunc),
-    /* 54 */ SyscallDesc("ioctl", ioctlFunc<MipsLinux>),
+    /* 54 */ SyscallDesc("ioctl", unimplementedFunc/*ioctlFunc<MipsLinux>*/),
     /* 55 */ SyscallDesc("fcntl", fcntlFunc),
     /* 56 */ SyscallDesc("mpx", unimplementedFunc),
     /* 57 */ SyscallDesc("setpgid", unimplementedFunc),
@@ -193,9 +194,9 @@ SyscallDesc MipsLinuxProcess::syscallDescs[] = {
     /* 72 */ SyscallDesc("sigsuspend", unimplementedFunc),
     /* 73 */ SyscallDesc("sigpending", unimplementedFunc),
     /* 74 */ SyscallDesc("sethostname", ignoreFunc),
-    /* 75 */ SyscallDesc("setrlimit", unimplementedFunc),
-    /* 76 */ SyscallDesc("getrlimit", unimplementedFunc),
-    /* 77 */ SyscallDesc("getrusage", unimplementedFunc),
+    /* 75 */ SyscallDesc("setrlimit", unimplementedFunc/*setrlimitFunc<MipsLinux>*/),
+    /* 76 */ SyscallDesc("getrlimit", unimplementedFunc/*getrlimitFunc<MipsLinux>*/),
+    /* 77 */ SyscallDesc("getrusage", getrusageFunc<MipsLinux>),
     /* 78 */ SyscallDesc("gettimeofday", unimplementedFunc),
     /* 79 */ SyscallDesc("settimeofday", unimplementedFunc),
     /* 80 */ SyscallDesc("getgroups", unimplementedFunc),
@@ -212,8 +213,8 @@ SyscallDesc MipsLinuxProcess::syscallDescs[] = {
     /* 91 */ SyscallDesc("munmap",munmapFunc),
     /* 92 */ SyscallDesc("truncate", truncateFunc),
     /* 93 */ SyscallDesc("ftruncate", ftruncateFunc),
-    /* 94 */ SyscallDesc("fchmod", unimplementedFunc),
-    /* 95 */ SyscallDesc("fchown", unimplementedFunc),
+    /* 94 */ SyscallDesc("fchmod", fchmodFunc<MipsLinux>),
+    /* 95 */ SyscallDesc("fchown", fchownFunc),
     /* 96 */ SyscallDesc("getpriority", unimplementedFunc),
     /* 97 */ SyscallDesc("setpriority", unimplementedFunc),
     /* 98 */ SyscallDesc("profil", unimplementedFunc),
@@ -238,7 +239,7 @@ SyscallDesc MipsLinuxProcess::syscallDescs[] = {
     /* 117 */ SyscallDesc("ipc", unimplementedFunc),
     /* 118 */ SyscallDesc("fsync", unimplementedFunc),
     /* 119 */ SyscallDesc("sigreturn", unimplementedFunc),
-    /* 120 */ SyscallDesc("clone", unimplementedFunc),
+    /* 120 */ SyscallDesc("clone", unimplementedFunc/*cloneFunc<MipsLinux>*/),
     /* 121 */ SyscallDesc("setdomainname", unimplementedFunc),
     /* 122 */ SyscallDesc("uname", unameFunc),
     /* 123 */ SyscallDesc("modify_ldt", unimplementedFunc),
@@ -271,7 +272,7 @@ SyscallDesc MipsLinuxProcess::syscallDescs[] = {
     /* 150 */ SyscallDesc("unused#150", unimplementedFunc),
     /* 151 */ SyscallDesc("getsid", unimplementedFunc),
     /* 152 */ SyscallDesc("fdatasync", unimplementedFunc),
-    /* 153 */ SyscallDesc("sysctl", unimplementedFunc),
+    /* 153 */ SyscallDesc("sysctl", ignoreFunc),
     /* 154 */ SyscallDesc("mlock", unimplementedFunc),
     /* 155 */ SyscallDesc("munlock", unimplementedFunc),
     /* 156 */ SyscallDesc("mlockall", unimplementedFunc),
@@ -312,12 +313,12 @@ SyscallDesc MipsLinuxProcess::syscallDescs[] = {
     /* 191 */ SyscallDesc("getresgid", unimplementedFunc),
     /* 192 */ SyscallDesc("prctl", unimplementedFunc),
     /* 193 */ SyscallDesc("rt_sigreturn", unimplementedFunc),
-    /* 194 */ SyscallDesc("rt_sigaction", ignoreFunc),
-    /* 195 */ SyscallDesc("rt_sigprocmask", ignoreFunc),
+    /* 194 */ SyscallDesc("rt_sigaction", unimplementedFunc/*rt_sigactionFunc<MipsLinux>*/),
+    /* 195 */ SyscallDesc("rt_sigprocmask", unimplementedFunc/*rt_sigprocmaskFunc<MipsLinux>*/),
     /* 196 */ SyscallDesc("rt_sigpending", unimplementedFunc),
     /* 197 */ SyscallDesc("rt_sigtimedwait", unimplementedFunc),
     /* 198 */ SyscallDesc("rt_sigqueueinfo", ignoreFunc),
-    /* 199 */ SyscallDesc("rt_sigsuspend", unimplementedFunc),
+    /* 199 */ SyscallDesc("rt_sigsuspend", unimplementedFunc/*rt_sigsuspendFunc<MipsLinux>*/),
     /* 200 */ SyscallDesc("pread64", unimplementedFunc),
     /* 201 */ SyscallDesc("pwrite64", unimplementedFunc),
     /* 202 */ SyscallDesc("chown", unimplementedFunc),
@@ -400,9 +401,10 @@ SyscallDesc MipsLinuxProcess::syscallDescs[] = {
     /* 279 */ SyscallDesc("unknown #279", unimplementedFunc),
     /* 280 */ SyscallDesc("add_key", unimplementedFunc),
     /* 281 */ SyscallDesc("request_key", unimplementedFunc),
-    /* 282 */ SyscallDesc("keyctl", unimplementedFunc),
+    /* 282 */ SyscallDesc("keyctl", unimplementedFunc)
 };
 
+
 MipsLinuxProcess::MipsLinuxProcess(const std::string &name,
                                      ObjectFile *objFile,
                                      System *system,
@@ -421,7 +423,13 @@ MipsLinuxProcess::MipsLinuxProcess(const std::string &name,
     : MipsLiveProcess(name, objFile, system, stdin_fd, stdout_fd, stderr_fd,
                       argv, envp, cwd, _uid, _euid, _gid, _egid, _pid, _ppid),
      Num_Syscall_Descs(sizeof(syscallDescs) / sizeof(SyscallDesc))
-{ }
+{  }
+
+void
+MipsLinuxProcess::startup()
+{
+    MipsLiveProcess::argsInit(MachineBytes, VMPageSize);
+}
 
 SyscallDesc*
 MipsLinuxProcess::getDesc(int callnum)
@@ -434,3 +442,8 @@ MipsLinuxProcess::getDesc(int callnum)
 
     return &syscallDescs[m5_sys_idx];
 }
+
+
+
+
+
index 398e1cfc266aa55b243f4f980aa66b11a8e32492..d18c9618827de9605543168c07a5ac644745c3e2 100644 (file)
@@ -30,7 +30,8 @@
 #define __MIPS_LINUX_PROCESS_HH__
 
 #include "arch/mips/process.hh"
-
+#include "arch/mips/linux/linux.hh"
+#include "sim/eventq.hh"
 
 /// A process with emulated Mips/Linux syscalls.
 class MipsLinuxProcess : public MipsLiveProcess
@@ -48,16 +49,19 @@ class MipsLinuxProcess : public MipsLiveProcess
                       uint64_t _gid, uint64_t _egid,
                       uint64_t _pid, uint64_t _ppid);
 
+    void startup();
+
     virtual SyscallDesc* getDesc(int callnum);
 
     /// The target system's hostname.
     static const char *hostname;
 
-     /// Array of syscall descriptors, indexed by call number.
-    static SyscallDesc syscallDescs[];
+    /// ID of the thread group leader for the process
+    uint64_t __tgid;
 
+    /// Array of syscall descriptors, indexed by call number.
+    static SyscallDesc syscallDescs[];
     const int Num_Syscall_Descs;
 };
 
-
 #endif // __MIPS_LINUX_PROCESS_HH__
index 363cf1e90f086b26f0f9f2e6d3f95c04386a2079..9d7d02a03f5223d0d04b9fd53e22d5a912fabcd2 100644 (file)
@@ -37,6 +37,9 @@
  * ISA-specific helper functions for locked memory accesses.
  */
 
+#include "arch/isa_traits.hh"
+#include "base/misc.hh"
+#include "base/trace.hh"
 #include "mem/request.hh"
 
 
@@ -46,6 +49,11 @@ template <class XC>
 inline void
 handleLockedRead(XC *xc, Request *req)
 {
+    unsigned tid = req->getThreadNum();
+    xc->setMiscReg(LLAddr, req->getPaddr() & ~0xf, tid);
+    xc->setMiscReg(LLFlag, true, tid);
+    DPRINTF(LLSC, "[tid:%i]: Load-Link Flag Set & Load-Link Address set to %x.\n",
+            tid, req->getPaddr() & ~0xf);
 }
 
 
@@ -53,6 +61,52 @@ template <class XC>
 inline bool
 handleLockedWrite(XC *xc, Request *req)
 {
+    unsigned tid = req->getThreadNum();
+
+    if (req->isUncacheable()) {
+        // Funky Turbolaser mailbox access...don't update
+        // result register (see stq_c in decoder.isa)
+        req->setExtraData(2);
+    } else {
+        // standard store conditional
+        bool lock_flag = xc->readMiscReg(LLFlag, tid);
+        Addr lock_addr = xc->readMiscReg(LLAddr, tid);
+
+        if (!lock_flag || (req->getPaddr() & ~0xf) != lock_addr) {
+            // Lock flag not set or addr mismatch in CPU;
+            // don't even bother sending to memory system
+            req->setExtraData(0);
+            xc->setMiscReg(LLFlag, false, tid);
+
+            // the rest of this code is not architectural;
+            // it's just a debugging aid to help detect
+            // livelock by warning on long sequences of failed
+            // store conditionals
+            int stCondFailures = xc->readStCondFailures();
+            stCondFailures++;
+            xc->setStCondFailures(stCondFailures);
+            if (stCondFailures % 10 == 0) {
+                warn("%i: cpu %d: %d consecutive "
+                     "store conditional failures\n",
+                     curTick, xc->readCpuId(), stCondFailures);
+            }
+
+            if (stCondFailures == 5000) {
+                panic("Max (5000) Store Conditional Fails Reached. Check Code For Deadlock.\n");
+            }
+
+            if (!lock_flag){
+                DPRINTF(LLSC, "[tid:%i]: Lock Flag Set, Store Conditional Failed.\n",
+                        tid);
+            } else if ((req->getPaddr() & ~0xf) != lock_addr) {
+                DPRINTF(LLSC, "[tid:%i]: Load-Link Address Mismatch, Store Conditional Failed.\n",
+                        tid);
+            }
+            // store conditional failed already, so don't issue it to mem
+            return false;
+        }
+    }
+
     return true;
 }
 
diff --git a/src/arch/mips/mt.hh b/src/arch/mips/mt.hh
new file mode 100755 (executable)
index 0000000..6d78dd0
--- /dev/null
@@ -0,0 +1,302 @@
+/*
+ * Copyright (c) 2006 The Regents of The University of Michigan
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met: redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer;
+ * redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution;
+ * neither the name of the copyright holders nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * Authors: Korey Sewell
+ */
+
+#ifndef __ARCH_MIPS_MT_HH__
+#define __ARCH_MIPS_MT_HH__
+
+/**
+ * @file
+ *
+ * ISA-specific helper functions for multithreaded execution.
+ */
+
+#include "arch/isa_traits.hh"
+#include "arch/mips/faults.hh"
+#include "arch/mips/mt_constants.hh"
+#include "base/bitfield.hh"
+#include "base/trace.hh"
+#include "base/misc.hh"
+
+#include <iostream>
+using namespace std;
+
+namespace MipsISA
+{
+
+
+template <class TC>
+inline unsigned
+getVirtProcNum(TC *tc)
+{
+    MiscReg tcbind = tc->readMiscRegNoEffect(TCBind);
+    return bits(tcbind, TCB_CUR_VPE_HI, TCB_CUR_VPE_LO);
+}
+
+template <class TC>
+inline unsigned
+getTargetThread(TC *tc)
+{
+    MiscReg vpec_ctrl = tc->readMiscRegNoEffect(VPEControl);
+    return bits(vpec_ctrl, VPEC_TARG_TC_HI, VPEC_TARG_TC_LO);
+}
+
+template <class TC>
+inline void
+haltThread(TC *tc)
+{
+    if (tc->status() == TC::Active) {
+        tc->halt();
+
+        // Save last known PC in TCRestart
+        // @TODO: Needs to check if this is a branch and if so, take previous instruction
+        tc->setMiscReg(TCRestart, tc->readNextPC());
+
+        warn("%i: Halting thread %i in %s @ PC %x, setting restart PC to %x", curTick, tc->getThreadNum(), tc->getCpuPtr()->name(),
+             tc->readPC(), tc->readNextPC());
+    }
+}
+
+template <class TC>
+inline void
+restoreThread(TC *tc)
+{
+    if (tc->status() != TC::Active) {
+        // Restore PC from TCRestart
+        IntReg pc = tc->readMiscRegNoEffect(TCRestart);
+
+        // TODO: SET PC WITH AN EVENT INSTEAD OF INSTANTANEOUSLY
+        // tc->setPCEvent(pc, pc + 4, pc + 8);
+        tc->setPC(pc);
+        tc->setNextPC(pc + 4);
+        tc->setNextNPC(pc + 8);
+        tc->activate(0);
+
+        warn("%i: Restoring thread %i in %s @ PC %x", curTick, tc->getThreadNum(), tc->getCpuPtr()->name(),
+             tc->readPC());
+    }
+}
+
+template <class TC>
+void
+forkThread(TC *tc, Fault &fault, int Rd_bits, int Rs, int Rt)
+{
+    int num_threads = bits(tc->readMiscRegNoEffect(MVPConf0), MVPC0_PTC_HI, MVPC0_PTC_LO) + 1;
+
+    int success = 0;
+    for (int tid = 0; tid < num_threads && success == 0; tid++) {
+        unsigned tid_TCBind = tc->readRegOtherThread(MipsISA::TCBind + Ctrl_Base_DepTag,
+                                                     tid);
+        unsigned tc_bind = tc->readMiscRegNoEffect(MipsISA::TCBind);
+
+        if (bits(tid_TCBind, TCB_CUR_VPE_HI, TCB_CUR_VPE_LO) ==
+            bits(tc_bind, TCB_CUR_VPE_HI, TCB_CUR_VPE_LO)) {
+
+            unsigned tid_TCStatus = tc->readRegOtherThread(MipsISA::TCStatus + Ctrl_Base_DepTag,
+                                                           tid);
+
+            unsigned tid_TCHalt = tc->readRegOtherThread(MipsISA::TCHalt + Ctrl_Base_DepTag,
+                                                         tid);
+
+            if (bits(tid_TCStatus, TCS_DA) == 1 &&
+                bits(tid_TCHalt, TCH_H) == 0    &&
+                bits(tid_TCStatus, TCS_A) == 0  &&
+                success == 0) {
+
+                tc->setRegOtherThread(MipsISA::TCRestart + Ctrl_Base_DepTag, Rs, tid);
+
+                tc->setRegOtherThread(Rd_bits, Rt, tid);
+
+                unsigned status_ksu = bits(tc->readMiscReg(MipsISA::Status),
+                                           S_KSU_HI, S_KSU_LO);
+                unsigned tc_status_asid = bits(tc->readMiscReg(MipsISA::TCStatus),
+                                          TCS_ASID_HI, TCS_ASID_LO);
+
+                // Set Run-State to Running
+                replaceBits(tid_TCStatus, TCSTATUS_RNST_HI, TCSTATUS_RNST_LO, 0);
+
+                // Set Delay-Slot to 0
+                replaceBits(tid_TCStatus, TCSTATUS_TDS, 0);
+
+                // Set Dirty TC to 1
+                replaceBits(tid_TCStatus, TCSTATUS_DT, 1);
+
+                // Set Activated to 1
+                replaceBits(tid_TCStatus, TCSTATUS_A, 1);
+
+                // Set status to previous thread's status
+                replaceBits(tid_TCStatus, TCSTATUS_TKSU_HI, TCSTATUS_TKSU_LO, status_ksu);
+
+                // Set ASID to previous thread's state
+                replaceBits(tid_TCStatus, TCSTATUS_ASID_HI, TCSTATUS_ASID_LO, tc_status_asid);
+
+                // Write Status Register
+                tc->setRegOtherThread(MipsISA::TCStatus + Ctrl_Base_DepTag,
+                                      tid_TCStatus, tid);
+
+                // Mark As Successful Fork
+                success = 1;
+            }
+        } else {
+            std::cerr << "Bad VPEs" << endl;
+        }
+    }
+
+    if (success == 0) {
+        unsigned vpe_control = tc->readMiscRegNoEffect(MipsISA::VPEControl);
+        tc->setMiscReg(VPEControl, insertBits(vpe_control, VPEC_EXCPT_HI, VPEC_EXCPT_LO, 1));
+        fault = new ThreadFault();
+    }
+}
+
+
+template <class TC>
+int
+yieldThread(TC *tc, Fault &fault, int src_reg, uint32_t yield_mask)
+{
+    if (src_reg == 0) {
+        unsigned mvpconf0 = tc->readMiscRegNoEffect(MVPConf0);
+        int num_threads = bits(mvpconf0, MVPC0_PTC_HI, MVPC0_PTC_LO) + 1;
+
+        int ok = 0;
+
+        // Get Current VPE & TC numbers from calling thread
+        unsigned tcbind = tc->readMiscRegNoEffect(TCBind);
+        unsigned cur_vpe = bits(tcbind, TCB_CUR_VPE_HI, TCB_CUR_VPE_LO);
+        unsigned cur_tc = bits(tcbind, TCB_CUR_TC_HI, TCB_CUR_TC_LO);
+
+        for (int tid = 0; tid < num_threads; tid++) {
+            unsigned tid_TCStatus = tc->readRegOtherThread(MipsISA::TCStatus + Ctrl_Base_DepTag,
+                                                           tid);
+            unsigned tid_TCHalt = tc->readRegOtherThread(MipsISA::TCHalt + Ctrl_Base_DepTag,
+                                                         tid);
+            unsigned tid_TCBind = tc->readRegOtherThread(MipsISA::TCBind + Ctrl_Base_DepTag,
+                                                         tid);
+
+            unsigned tid_vpe = bits(tid_TCBind, TCB_CUR_VPE_HI, TCB_CUR_VPE_LO);
+            unsigned tid_tc = bits(tid_TCBind, TCB_CUR_TC_HI, TCB_CUR_TC_LO);
+            unsigned tid_tcstatus_da = bits(tid_TCStatus, TCS_DA);
+            unsigned tid_tcstatus_a = bits(tid_TCStatus, TCS_A);
+            unsigned tid_tchalt_h = bits(tid_TCHalt, TCH_H);
+
+            if (tid_vpe == cur_vpe &&
+                tid_tc == cur_tc &&
+                tid_tcstatus_da == 1 &&
+                tid_tchalt_h == 0    &&
+                tid_tcstatus_a == 1) {
+                ok = 1;
+            }
+        }
+
+        if (ok == 1) {
+            unsigned tcstatus = tc->readMiscRegNoEffect(TCStatus);
+            tc->setMiscReg(TCStatus, insertBits(tcstatus, TCS_A, TCS_A, 0));
+            warn("%i: Deactivating Hardware Thread Context #%i", curTick, tc->getThreadNum());
+        }
+    } else if (src_reg > 0) {
+        if (src_reg & !yield_mask != 0) {
+            unsigned vpe_control = tc->readMiscReg(VPEControl);
+            tc->setMiscReg(VPEControl, insertBits(vpe_control, VPEC_EXCPT_HI, VPEC_EXCPT_LO, 2));
+            fault = new ThreadFault();
+        } else {
+            //tc->setThreadRescheduleCondition(src_reg & yield_mask);
+        }
+    } else if (src_reg != -2) {
+        unsigned tcstatus = tc->readMiscRegNoEffect(TCStatus);
+        unsigned vpe_control = tc->readMiscRegNoEffect(VPEControl);
+        unsigned tcstatus_dt = bits(tcstatus, TCS_DT);
+        unsigned vpe_control_ysi = bits(vpe_control, VPEC_YSI);
+
+        if (vpe_control_ysi == 1 && tcstatus_dt == 1 ) {
+            tc->setMiscReg(VPEControl, insertBits(vpe_control, VPEC_EXCPT_HI, VPEC_EXCPT_LO, 4));
+            fault = new ThreadFault();
+        } else {
+            //tc->ScheduleOtherThreads();
+            //std::cerr << "T" << tc->getThreadNum() << "YIELD: Schedule Other Threads.\n" << std::endl;
+            //tc->suspend();
+            // Save last known PC in TCRestart
+            // @TODO: Needs to check if this is a branch and if so, take previous instruction
+            //tc->setMiscRegWithEffect(TCRestart, tc->readNextPC());
+        }
+    }
+
+    return src_reg & yield_mask;
+}
+
+
+// TC will usually be a object derived from ThreadContext
+// (src/cpu/thread_context.hh)
+template <class TC>
+inline void
+updateStatusView(TC *tc)
+{
+    // TCStatus' register view must be the same as
+    // Status register view for CU, MX, KSU bits
+    MiscReg tc_status = tc->readMiscRegNoEffect(TCStatus);
+    MiscReg status = tc->readMiscRegNoEffect(Status);
+
+    unsigned cu_bits = bits(tc_status, TCS_TCU_HI, TCS_TCU_LO);
+    replaceBits(status, S_CU_HI, S_CU_LO, cu_bits);
+
+    unsigned mx_bits = bits(tc_status, TCS_TMX);
+    replaceBits(status, S_MX, S_MX, mx_bits);
+
+    unsigned ksu_bits = bits(tc_status, TCS_TKSU_HI, TCS_TKSU_LO);
+    replaceBits(status, S_KSU_HI, S_KSU_LO, ksu_bits);
+
+    tc->setMiscRegNoEffect(Status, status);
+}
+
+// TC will usually be a object derived from ThreadContext
+// (src/cpu/thread_context.hh)
+template <class TC>
+inline void
+updateTCStatusView(TC *tc)
+{
+    // TCStatus' register view must be the same as
+    // Status register view for CU, MX, KSU bits
+    MiscReg tc_status = tc->readMiscRegNoEffect(TCStatus);
+    MiscReg status = tc->readMiscRegNoEffect(Status);
+
+    unsigned cu_bits = bits(status, S_CU_HI, S_CU_LO);
+    replaceBits(tc_status, TCS_TCU_HI, TCS_TCU_LO, cu_bits);
+
+    unsigned mx_bits = bits(status, S_MX, S_MX);
+    replaceBits(tc_status, TCS_TMX, mx_bits);
+
+    unsigned ksu_bits = bits(status, S_KSU_HI, S_KSU_LO);
+    replaceBits(tc_status, TCS_TKSU_HI, TCS_TKSU_LO, ksu_bits);
+
+    tc->setMiscRegNoEffect(TCStatus, tc_status);
+}
+
+} // namespace MipsISA
+
+
+#endif
diff --git a/src/arch/mips/mt_constants.hh b/src/arch/mips/mt_constants.hh
new file mode 100755 (executable)
index 0000000..0f69784
--- /dev/null
@@ -0,0 +1,122 @@
+/*
+ * Copyright (c) 2006 The Regents of The University of Michigan
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met: redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer;
+ * redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution;
+ * neither the name of the copyright holders nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * Authors: Korey Sewell
+ */
+
+#ifndef __ARCH_MIPS_MT_CONSTANTS_HH__
+#define __ARCH_MIPS_MT_CONSTANTS_HH__
+
+#include "arch/mips/types.hh"
+//#include "config/full_system.hh"
+
+namespace MipsISA
+{
+// MVPControl
+const unsigned MVPC_EVP = 0;
+const unsigned MVPC_CUR_VPE_HI = 3;
+const unsigned MVPC_CUR_VPE_LO = 0;
+
+// MVPConf0
+const unsigned MVPC0_TCA = 15;
+const unsigned MVPC0_PVPE_HI = 13;
+const unsigned MVPC0_PVPE_LO = 10;
+const unsigned MVPC0_PTC_HI = 7;
+const unsigned MVPC0_PTC_LO = 0;
+
+//VPEControl
+const unsigned VPEC_YSI = 21;
+const unsigned VPEC_EXCPT_HI = 18;
+const unsigned VPEC_EXCPT_LO = 16;
+const unsigned VPEC_TE = 15;
+const unsigned VPEC_TARG_TC_HI = 7;
+const unsigned VPEC_TARG_TC_LO = 0;
+
+//VPEConf0
+const unsigned VPEC0_MVP = 1;
+
+//TCBind
+const unsigned TCB_CUR_VPE_HI = 3;
+const unsigned TCB_CUR_VPE_LO = 0;
+const unsigned TCB_CUR_TC_HI = 28;
+const unsigned TCB_CUR_TC_LO = 21;
+
+
+//TCStatus
+const unsigned TCS_TCU_HI = 31;
+const unsigned TCS_TCU_LO = 28;
+const unsigned TCS_TMX = 27;
+const unsigned TCS_DT = 20;
+const unsigned TCS_DA = 15;
+const unsigned TCS_A = 13;
+const unsigned TCS_TKSU_HI = 12;
+const unsigned TCS_TKSU_LO = 11;
+const unsigned TCS_IXMT = 7;
+const unsigned TCS_ASID_HI = 7;
+const unsigned TCS_ASID_LO = 7;
+
+const unsigned TCSTATUS_TCU_HI = 31;
+const unsigned TCSTATUS_TCU_LO = 28;
+const unsigned TCSTATUS_TMX = 27;
+const unsigned TCSTATUS_RNST_HI = 24;
+const unsigned TCSTATUS_RNST_LO = 23;
+const unsigned TCSTATUS_TDS = 21;
+const unsigned TCSTATUS_DT = 20;
+const unsigned TCSTATUS_DA = 15;
+const unsigned TCSTATUS_A = 13;
+const unsigned TCSTATUS_TKSU_HI = 12;
+const unsigned TCSTATUS_TKSU_LO = 11;
+const unsigned TCSTATUS_IXMT = 7;
+const unsigned TCSTATUS_ASID_HI = 7;
+const unsigned TCSTATUS_ASID_LO = 7;
+
+//TCHalt
+const unsigned TCH_H = 0;
+
+//Status
+const unsigned S_CU_HI = 31;
+const unsigned S_CU_LO = 28;
+const unsigned S_MX = 24;
+const unsigned S_KSU_HI = 4;
+const unsigned S_KSU_LO = 3;
+
+// Config0
+const unsigned CFG_M = 31;
+
+// Config1
+const unsigned CFG1_M = 31;
+
+// Config2
+const unsigned CFG2_M = 31;
+
+// Config3
+const unsigned CFG3_M = 31;
+const unsigned CFG3_MT = 2;
+
+} // namespace MipsISA
+
+#endif
diff --git a/src/arch/mips/pra_constants.hh b/src/arch/mips/pra_constants.hh
new file mode 100755 (executable)
index 0000000..fb93e2d
--- /dev/null
@@ -0,0 +1,464 @@
+/*
+ * Copyright (c) 2006 The Regents of The University of Michigan
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met: redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer;
+ * redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution;
+ * neither the name of the copyright holders nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * Authors: Jaidev Patwardhan
+ */
+
+#ifndef __ARCH_MIPS_PRA_CONSTANTS_HH__
+#define __ARCH_MIPS_PRA_CONSTANTS_HH__
+
+#include "arch/mips/types.hh"
+//#include "config/full_system.hh"
+
+namespace MipsISA
+{
+  // See MIPS32(R) Architecture Reference Manual Volume - III
+  // This header file uses definitions from Revision 2.50
+
+  // Index Status Register - CP0 Reg 0, Sel 0
+
+  const unsigned Index_P_HI = 31;
+  const unsigned Index_P_LO = 31;
+  // Need to figure out how to put in the TLB specific bits here
+  // For now, we assume that the entire length is used by the index field
+  // In reality, Index_HI = N-1, where Ceiling(log2(TLB Entries))=N
+  const unsigned Index_HI = 30;
+  const unsigned Index_LO = 0;
+
+  // CP0 Reg 0, Sel 1-3 are MT registers, see mt_constants.hh
+
+  // Random Register - CP0 Reg 1, Sel 0
+  // This has a problem similar to the Index_HI fields. We'll keep both consistent at 30 for now
+  const unsigned Random_HI = 30;
+  const unsigned Random_LO = 0;
+
+  // EntryLo0 - CP0 Reg2, Sel 0  - Table 8-6, ARM Vol-3
+  const unsigned EntryLo0_Fill_HI = 31; // See Table 8-8, ARM Vol III
+  const unsigned EntryLo0_Fill_LO = 30;
+  const unsigned EntryLo0_PFN_HI  = 29; //PFN defines the Page Frame Number (see Table 8-7, ARM Vol III)
+  const unsigned EntryLo0_PFN_LO  =  6;
+  const unsigned EntryLo0_C_HI    =  5; // Coherency attribute of a Page (see Table 8-8, ARM Vol III)
+  const unsigned EntryLo0_C_LO    =  3;
+  const unsigned EntryLo0_D       =  2; // Dirty Bit, if D=1, page is writable. If D=0, a write causes a TLB Modified Exception
+  const unsigned EntryLo0_V       =  1; // Valid Bit
+  const unsigned EntryLo0_G       =  0; // Global Bit. From the ARM Vol-III, Table 8-5:
+                                        // On a TLB write, the logical AND of the G bits from EntryLo0 and EntryLo1
+                                        // becomes the G bit in the TLB entry. If the TLB entry G bit is 1, ASID comparisons are
+                                        // ignored during TLB matches. On a read from a TLB entry, the G bits of both Lo0 and Lo1
+                                        // reflect the state of the TLB G bit.
+
+  // EntryLo1 - CP0 Reg3, Sel 0
+  const unsigned EntryLo1_G       =  0;
+  const unsigned EntryLo1_V       =  1; // Valid Bit
+  const unsigned EntryLo1_D       =  2; // Dirty Bit, if D=1, page is writable. If D=0, a write causes a TLB Modified Exception
+  const unsigned EntryLo1_C_HI    =  5; // Coherency attribute of a Page (see Table 8-8, ARM Vol III)
+  const unsigned EntryLo1_C_LO    =  3;
+  const unsigned EntryLo1_PFN_HI  = 29; //PFN defines the Page Frame Number (see Table 8-7, ARM Vol III)
+  const unsigned EntryLo1_PFN_LO  =  6;
+  const unsigned EntryLo1_Fill_LO = 30;
+  const unsigned EntryLo1_Fill_HI = 31; // See Table 8-8, ARM Vol III
+
+
+  // Context Register - CP0 Reg 4, Sel 0
+  const unsigned Context_PTEBase_HI = 31; // Used by the OS to point into current PTE array
+  const unsigned Context_PTEBase_LO = 23;
+  const unsigned Context_BadVPN2_HI = 22; // This is written by hardware on a TLB exception. Contains bits 31-13 of the
+  const unsigned Context_BadVPN2_LO = 4;  // virtual address
+  // Bits 3-0 are zeros
+
+  // PageMask Register - CP0 Reg 5, Sel 0
+  // Bits 31-29 are 0
+  const unsigned PageMask_Mask_HI = 28; // (Table 8-10, ARM Vol-III) The Mask field is a bit mask in which a "1" indicates that
+  const unsigned PageMask_Mask_LO = 13; // the corresponding bit of the virtual address should not participate in the TLB match
+  const unsigned PageMask_MaskX_HI = 12; // See Table 8-10, ARM Vol-III
+  const unsigned PageMask_MaskX_LO = 11;
+  // Bits 10-0 are zero
+
+
+  // PageGrain Register - CP0 Reg 5, Sel 1
+  const unsigned PageGrain_ASE_UP_HI = 31; // ASE specific bits (SmartMIPS)
+  const unsigned PageGrain_ASE_UP_LO = 30; //
+  const unsigned PageGrain_ELPA = 29; // Used to enable support for large physical addresses in MIPS64 processors, unused in MIPS32
+  const unsigned PageGrain_ESP = 28; // Enables support for 1KB pages (1==enabled,0==disabled), See ARM Vol-III, Table 8-12
+  const unsigned PageGrain_ASE_DN_HI = 12;
+  const unsigned PageGrain_ASE_DN_LO = 8;
+  // Bits 27-13, 7-0 are zeros
+
+  // Wired Register - CPO Reg 6, Sel 0
+  // See note on Index register (CP0, Sel0) above
+  const unsigned Wired_HI = 30;
+  const unsigned Wired_LO = 0;
+
+
+  // HWREna Register - CP0 Reg 7, Sel 0
+  const unsigned HWREna_IMPL_HI = 31; // These bits enable access to implementation dependent hardware registers 31
+  const unsigned HWREna_IMPL_LO = 30; // and 30
+  const unsigned HWREna_Mask_HI = 3; // Each bit enables access to a particular hardware register. If bit 'n' is 1, HW Reg n is accessible
+  const unsigned HWREna_Mask_LO = 0; // See the RDHWR instruction for more details
+
+
+  // BadVAddr Register - CP0 Reg 8, Sel 0
+  const unsigned BadVAddr_HI = 31;
+  const unsigned BadVAddr_LO = 0;
+
+  // Count Register - CP0 Reg 9, Sel 0
+  const unsigned Count_HI = 31;
+  const unsigned Count_LO = 0;
+
+  // EntryHI Register - CP0 Reg 10, Sel 0
+  const unsigned Entry_HI_VPN2_HI = 31;  // This field is written by hardware on a TLB exception or on a TLB read
+  const unsigned Entry_HI_VPN2_LO = 13;  // and is written by software before a TLB write
+  const unsigned Entry_HI_VPN2X_HI = 12; // Extension to support 1KB pages
+  const unsigned Entry_HI_VPN2X_LO = 11;
+  const unsigned Entry_HI_ASID_HI = 7; // Address space identifier
+  const unsigned Entry_HI_ASID_LO = 0;
+
+  // Compare Register - CP0 Reg 11, Sel 0
+  const unsigned Compare_HI = 31; // Used in conjunction with Count
+  const unsigned Compare_LO = 0;
+
+  // Status Register - CP Reg 12, Sel 0
+  const unsigned Status_IE_HI = 0;
+  const unsigned Status_IE_LO = 0;
+
+  const unsigned Status_EXL_HI = 1;
+  const unsigned Status_EXL_LO = 1;
+  const unsigned Status_ERL_HI = 2;
+  const unsigned Status_ERL_LO = 2;
+  const unsigned Status_R0 = 3;
+  const unsigned Status_UM = 4;
+  const unsigned Status_KSU_HI = 4;  // R0 and UM are also aliased as KSU
+  const unsigned Status_KSU_LO = 3;
+  const unsigned Status_UX = 5;
+  const unsigned Status_SX = 6;
+  const unsigned Status_KX = 7;
+  const unsigned Status_IM0 = 8;
+  const unsigned Status_IM1 = 9;
+  const unsigned Status_IM2 = 10;
+  const unsigned Status_IM3 = 11;
+  const unsigned Status_IM4 = 12;
+  const unsigned Status_IM5 = 13;
+  const unsigned Status_IM6 = 14;
+  const unsigned Status_IM7 = 15;
+  const unsigned Status_IPL_HI = 15;  // IM7..IM2 are also aliased as IPL
+  const unsigned Status_IPL_LO = 10;
+  const unsigned Status_IMPL_HI = 17;
+  const unsigned Status_IMPL_LO = 16;
+  const unsigned Status_NMI = 19;
+  const unsigned Status_SR = 20;
+  const unsigned Status_TS = 21;
+  const unsigned Status_BEV = 22;
+  const unsigned Status_PX = 23;
+  const unsigned Status_MX = 24;
+  const unsigned Status_RE = 25;
+  const unsigned Status_FR = 26;
+  const unsigned Status_RP = 27;
+  const unsigned Status_CU3_HI = 31;
+  const unsigned Status_CU3_LO = 31;
+  const unsigned Status_CU2_HI = 30;
+  const unsigned Status_CU2_LO = 30;
+  const unsigned Status_CU1_HI = 29;
+  const unsigned Status_CU1_LO = 29;
+  const unsigned Status_CU0_HI = 28;
+  const unsigned Status_CU0_LO = 28;
+
+  // IntCtl Register - CP0 Reg 12, Sel 1
+  // Interrupt System status and control
+  const unsigned IntCtl_IPTI_HI = 31;
+  const unsigned IntCtl_IPTI_LO = 29;
+  const unsigned IntCtl_IPPCI_HI = 28;
+  const unsigned IntCtl_IPPCI_LO = 26;
+  const unsigned IntCtl_VS_HI = 9;
+  const unsigned IntCtl_VS_LO = 5;
+  // Bits 26-10, 4-0 are zeros
+
+  // SRSCtl Register - CP0 Reg 12, Sel 2
+  // Shadow Register Set Status and Control
+  const unsigned SRSCtl_HSS_HI=29; // Highest Shadow Set
+  const unsigned SRSCtl_HSS_LO=26;
+  const unsigned SRSCtl_EICSS_HI=21; //EIC interrupt mode shadow set
+  const unsigned SRSCtl_EICSS_LO=18;
+  const unsigned SRSCtl_ESS_HI=15; // Exception Shadow Set
+  const unsigned SRSCtl_ESS_LO=12;
+  const unsigned SRSCtl_PSS_HI=9; // Previous Shadow Set
+  const unsigned SRSCtl_PSS_LO=6;
+  const unsigned SRSCtl_CSS_HI=3; // Current Shadow Set
+  const unsigned SRSCtl_CSS_LO=0;
+
+  // SRSMap Register - CP0 Reg 12, Sel 3
+  // Shadow Set IPL mapping
+  const unsigned SRSMap_SSV7_HI = 31; // Shadow sets for particular vector numbers (7..0)
+  const unsigned SRSMap_SSV7_LO = 28;
+  const unsigned SRSMap_SSV6_HI = 27;
+  const unsigned SRSMap_SSV6_LO = 24;
+  const unsigned SRSMap_SSV5_HI = 23;
+  const unsigned SRSMap_SSV5_LO = 20;
+  const unsigned SRSMap_SSV4_HI = 19;
+  const unsigned SRSMap_SSV4_LO = 16;
+  const unsigned SRSMap_SSV3_HI = 15;
+  const unsigned SRSMap_SSV3_LO = 12;
+  const unsigned SRSMap_SSV2_HI = 11;
+  const unsigned SRSMap_SSV2_LO = 8;
+  const unsigned SRSMap_SSV1_HI = 7;
+  const unsigned SRSMap_SSV1_LO = 4;
+  const unsigned SRSMap_SSV0_HI = 3;
+  const unsigned SRSMap_SSV0_LO = 20;
+
+  // Cause Register - CP0 Reg 13, Sel 0
+  const unsigned Cause_BD = 31;
+  const unsigned Cause_TI = 30;
+  const unsigned Cause_CE_HI = 29;
+  const unsigned Cause_CE_LO = 28;
+  const unsigned Cause_DC = 27;
+  const unsigned Cause_PCI = 26;
+  const unsigned Cause_IV = 24;
+  const unsigned Cause_WP = 23;
+  const unsigned Cause_RIPL_HI = 15; // The individual bits of RIPL are also available as IP7..IP5
+  const unsigned Cause_RIPL_LO = 10;
+  const unsigned Cause_IP7 = 15;
+  const unsigned Cause_IP6 = 14;
+  const unsigned Cause_IP5 = 13;
+  const unsigned Cause_IP4 = 12;
+  const unsigned Cause_IP3 = 11;
+  const unsigned Cause_IP2 = 10;
+  const unsigned Cause_IP1 = 9;
+  const unsigned Cause_IP0 = 8;
+  const unsigned Cause_EXCCODE_HI = 6;
+  const unsigned Cause_EXCCODE_LO = 2;
+  // All intermediate undefined bits must be ZERO
+
+
+  // EPC Register - CP0 Reg 14, Sel 0
+  // Exception Program Counter
+  const unsigned EPC_HI = 31;
+  const unsigned EPC_LO = 0;
+
+  // PRId Register - CP0 Reg 15, Sel 0
+  // Processor Identification register
+  const unsigned PRIdCoOp_HI = 31;
+  const unsigned PRIdCoOp_LO = 24;
+  const unsigned PRIdCoID_HI = 23;
+  const unsigned PRIdCoID_LO = 16;
+  const unsigned PRIdProc_ID_HI = 15;
+  const unsigned PRIdProc_ID_LO = 8;
+  const unsigned PRIdRev_HI = 7;
+  const unsigned PRIdRev_LO = 0;
+
+
+  // EBase Register - CP0 Reg 15, Sel 1
+  // Exception Base Register
+  const unsigned EBase_MSB = 31; // MUST BE = 1
+  const unsigned EBase_EXCEPTION_Base_HI = 29;
+  const unsigned EBase_EXCEPTION_Base_LO = 12;
+  const unsigned EBase_CPUNum_HI = 9;
+  const unsigned EBase_CPUNum_LO = 0;
+  // Undefined bits must be zero
+
+  // Config Register - CP0 Reg 16, Sel 0
+  const unsigned Config_M = 31;
+  const unsigned Config_K23_HI = 30;
+  const unsigned Config_K23_LO = 28;
+  const unsigned Config_KU_HI = 27;
+  const unsigned Config_KU_LO = 25;
+  const unsigned Config_IMPL_HI = 24;
+  const unsigned Config_IMPL_LO = 16;
+  const unsigned Config_BE = 15;
+  const unsigned Config_AT_HI = 14;
+  const unsigned Config_AT_LO = 13;
+  const unsigned Config_AR_HI = 12;
+  const unsigned Config_AR_LO = 10;
+  const unsigned Config_MT_HI = 9;
+  const unsigned Config_MT_LO = 7;
+  const unsigned Config_VI = 3;
+  const unsigned Config_K0_HI = 2;
+  const unsigned Config_K0_LO = 0;
+
+  // Config1 Register - CP0 Reg 16, Sel 1
+  const unsigned Config1_M = 31;
+  const unsigned Config1_MMUSize_HI = 30;
+  const unsigned Config1_MMUSize_LO = 25;
+  const unsigned Config1_IS_HI = 24;
+  const unsigned Config1_IS_LO = 22;
+  const unsigned Config1_IL_HI = 21;
+  const unsigned Config1_IL_LO = 19;
+  const unsigned Config1_IA_HI = 18;
+  const unsigned Config1_IA_LO = 16;
+  const unsigned Config1_DS_HI = 15;
+  const unsigned Config1_DS_LO = 13;
+  const unsigned Config1_DL_HI = 12;
+  const unsigned Config1_DL_LO = 10;
+  const unsigned Config1_DA_HI = 9;
+  const unsigned Config1_DA_LO = 7;
+  const unsigned Config1_C2 = 6;
+  const unsigned Config1_MD = 5;
+  const unsigned Config1_PC = 4;
+  const unsigned Config1_WR = 3;
+  const unsigned Config1_CA = 2;
+  const unsigned Config1_EP = 1;
+  const unsigned Config1_FP = 0;
+
+
+  // Config2 Register - CP0 Reg 16, Sel 2
+  const unsigned Config2_M = 31;
+  const unsigned Config2_TU_HI = 30;
+  const unsigned Config2_TU_LO = 28;
+  const unsigned Config2_TS_HI = 27;
+  const unsigned Config2_TS_LO = 24;
+  const unsigned Config2_TL_HI = 23;
+  const unsigned Config2_TL_LO = 20;
+  const unsigned Config2_TA_HI = 19;
+  const unsigned Config2_TA_LO = 16;
+  const unsigned Config2_SU_HI = 15;
+  const unsigned Config2_SU_LO = 12;
+  const unsigned Config2_SS_HI = 11;
+  const unsigned Config2_SS_LO = 8;
+  const unsigned Config2_SL_HI = 7;
+  const unsigned Config2_SL_LO = 4;
+  const unsigned Config2_SA_HI = 3;
+  const unsigned Config2_SA_LO = 0;
+
+  // Config3 Register - CP0 Reg 16, Sel 3
+  const unsigned Config3_M = 31;
+  const unsigned Config3_DSPP = 10;
+  const unsigned Config3_LPA=7;
+  const unsigned Config3_VEIC=6;
+  const unsigned Config3_VINT=5;
+  const unsigned Config3_SP=4;
+  const unsigned Config3_MT=2;
+  const unsigned Config3_SM=1;
+  const unsigned Config3_TL=0;
+
+
+  // LLAddr Register - CP0 Reg 17, Sel 0
+  // Load Linked Address (Physical)
+  const unsigned LLAddr_PAddr_HI = 31;
+  const unsigned LLAddr_PAddr_LO = 0;
+
+
+
+  // WatchLo Register - CP0 Reg 18, Sel 0-n
+  // See WatchHi to determine how many pairs of these registers are available
+  const unsigned WatchLo_VAddr_HI = 31;
+  const unsigned WatchLo_VAddr_LO = 3;
+  const unsigned WatchLo_I = 2;
+  const unsigned WatchLo_R = 1;
+  const unsigned WatchLo_W = 0;
+
+
+  // WatchHi Register - CP0 Reg 19, Sel 0-n
+  const unsigned WatchHi_M = 31; // If M = 1, another pair of WatchHi/Lo registers exist
+  const unsigned WatchHi_G = 30;
+  const unsigned WatchHi_ASID_HI = 23;
+  const unsigned WatchHi_ASID_LO = 16;
+  const unsigned WatchHi_Mask_HI = 11;
+  const unsigned WatchHi_Mask_LO = 3;
+  const unsigned WatchHi_I = 2;
+  const unsigned WatchHi_R = 1;
+  const unsigned WatchHi_W = 0;
+
+  // Debug Register - CP0 Reg 23, Sel 0
+
+  // TraceControl Register - CP0 Reg 23, Sel 1
+  // TraceControl2 Register - CP0 Reg 23, Sel 2
+  // UserTraceData Register - CP0 Reg 23, Sel 3
+  // TraceBPC Register - CP0 Reg 23, Sel 4
+  // DEPC Register - CP0 Reg 24, Sel 0
+
+
+  // PerfCnt Register - CP0 Reg 25, Sel 0-n
+  // Each Perf. counter that exists is mapped onto even-odd select pairs of Reg 25
+  // Even values are control registers, odd values are the actual counter
+  // The format for the control reg is:
+  const unsigned PerfCntCtl_M = 31; // Is there another pair of perf counter registers?
+  const unsigned PerfCntCtl_W = 30;
+  const unsigned PerfCntCtl_Event_HI = 10;
+  const unsigned PerfCntCtl_Event_LO = 5;
+  const unsigned PerfCntCtl_IE = 4;
+  const unsigned PerfCntCtl_U = 3;
+  const unsigned PerfCntCtl_S = 2;
+  const unsigned PerfCntCtl_K = 1;
+  const unsigned PerfCntCtl_EXL = 0;
+
+  // The format for the counter is a 32-bit value (or 64-bit for MIPS64)
+  const unsigned PerfCnt_Count_HI = 31;
+  const unsigned PerfCnt_Count_LO = 0;
+
+  // ErrCtl Register - CP0 Reg 26, Sel 0
+  // This is implementation dependent, not defined by the ISA
+
+  // CacheErr Register - CP0 Reg 27, Sel 0
+  // NOTE: Page 65 of the ARM, Volume-III indicates that there are four sel. values (0-3)
+  // used by the CacheErr registers. However, on page 134, only one sel value is shown
+  const unsigned Cache_Err_ER = 31;
+  const unsigned Cache_Err_EC = 30;
+  const unsigned Cache_Err_ED = 29;
+  const unsigned Cache_Err_ET = 28;
+  const unsigned Cache_Err_ES = 27;
+  const unsigned Cache_Err_EE = 26;
+  const unsigned Cache_Err_EB = 25;
+  const unsigned Cache_Err_IMPL_HI = 24;
+  const unsigned Cache_Err_IMPL_LO = 22;
+  const unsigned Cache_Err_Index_HI = 21;
+  const unsigned Cache_Err_Index_LO = 0;
+
+  // TagLo Register - CP0 Reg 28 - Even Selects (0,2)
+  const unsigned TagLo_PTagLo_HI = 31;
+  const unsigned TagLo_PTagLo_LO = 8;
+  const unsigned TagLo_PState_HI = 7;
+  const unsigned TagLo_PState_LO = 6;
+  const unsigned TagLo_L = 5;
+  const unsigned TagLo_IMPL_HI = 4;
+  const unsigned TagLo_IMPL_LO = 3;
+  const unsigned TagLo_P = 0;
+  // undefined bits must be written 0
+
+
+  // DataLo Register - CP0 Reg 28 - Odd Selects (1,3)
+  const unsigned DataLo_HI = 31;
+  const unsigned DataLo_LO = 0;
+
+  // TagHi Register - CP0 Reg 29 - Even Selects (0,2)
+  // Not defined by the architecture
+
+  // DataHi Register - CP0 Reg 29 - Odd Selects (1,3)
+  const unsigned DataHi_HI = 31;
+  const unsigned DataHi_LO = 0;
+
+
+  // ErrorEPC - CP0 Reg 30, Sel 0
+  const unsigned ErrorPC_HI = 31;
+  const unsigned ErrorPC_LO = 0;
+
+  // DESAVE - CP0 Reg 31, Sel 0
+
+
+
+
+
+} // namespace MipsISA
+
+#endif
index af85e8ee9e7a92b24c081c87d1fc853b42e51cda..b6249f76dc5f7df4778d6c84fe990dbde34fed32 100644 (file)
@@ -48,12 +48,12 @@ class MipsLiveProcess : public LiveProcess
                 System *_system, int stdin_fd, int stdout_fd, int stderr_fd,
                 std::vector<std::string> &argv,
                 std::vector<std::string> &envp,
-                const std::string &cwd,
+                    const std::string &cwd,
                 uint64_t _uid, uint64_t _euid,
                 uint64_t _gid, uint64_t _egid,
                 uint64_t _pid, uint64_t _ppid);
 
-    void startup();
+    virtual void startup();
 
 };
 
index ce5f1fdde51bea675bb1c675df77667977fd8ace..21c16c23804e6cace6de85ceb61ac2c5791a00ea 100644 (file)
@@ -88,12 +88,9 @@ namespace MipsISA
 
       public:
 
-        void clear()
-        {
-            bzero(regs, sizeof(regs));
-        }
+        void clear() { bzero(&regs, sizeof(regs)); }
 
-        double readReg(int floatReg, int width)
+        double readReg(int floatReg, int width, unsigned tid = 0)
         {
             switch(width)
             {
@@ -115,7 +112,7 @@ namespace MipsISA
             }
         }
 
-        FloatRegBits readRegBits(int floatReg, int width)
+        FloatRegBits readRegBits(int floatReg, int width, unsigned tid = 0)
         {
             if (floatReg < NumFloatArchRegs - 1) {
                 switch(width)
@@ -137,8 +134,9 @@ namespace MipsISA
             }
         }
 
-        Fault setReg(int floatReg, const FloatRegVal &val, int width)
+        Fault setReg(int floatReg, const FloatRegVal &val, int width, unsigned tid = 0)
         {
+            using namespace std;
             switch(width)
             {
               case SingleWidth:
@@ -165,8 +163,9 @@ namespace MipsISA
             return NoFault;
         }
 
-        Fault setRegBits(int floatReg, const FloatRegBits &val, int width)
+        Fault setRegBits(int floatReg, const FloatRegBits &val, int width, unsigned tid = 0)
         {
+            using namespace std;
 
             switch(width)
             {
index a45a17a85cb16ba5439f7ee044d6cb774dcc93f8..2a034ad8d55e5a4d9b0009c85c13326841ec09c4 100644 (file)
@@ -47,8 +47,21 @@ namespace MipsISA
     }
 
     enum MiscIntRegNums {
-       HI = NumIntArchRegs,
-       LO
+       LO = NumIntArchRegs,
+       HI,
+       DSPACX0,
+       DSPLo1,
+       DSPHi1,
+       DSPACX1,
+       DSPLo2,
+       DSPHi2,
+       DSPACX2,
+       DSPLo3,
+       DSPHi3,
+       DSPACX3,
+       DSPControl,
+       DSPLo0 = LO,
+       DSPHi0 = HI
     };
 
     class IntRegFile
@@ -57,6 +70,8 @@ namespace MipsISA
         IntReg regs[NumIntRegs];
 
       public:
+        void clear() { bzero(&regs, sizeof(regs)); }
+
         IntReg readReg(int intReg)
         {
             return regs[intReg];
@@ -64,7 +79,10 @@ namespace MipsISA
 
         Fault setReg(int intReg, const IntReg &val)
         {
-            regs[intReg] = val;
+            if (intReg != ZeroReg) {
+                regs[intReg] = val;
+            }
+
             return NoFault;
         }
 
diff --git a/src/arch/mips/regfile/misc_regfile.cc b/src/arch/mips/regfile/misc_regfile.cc
new file mode 100755 (executable)
index 0000000..c97d93c
--- /dev/null
@@ -0,0 +1,377 @@
+/*
+ * Copyright (c) 2006 The Regents of The University of Michigan
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met: redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer;
+ * redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution;
+ * neither the name of the copyright holders nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * Authors: Korey Sewell
+ */
+
+#include "base/bitfield.hh"
+
+#include "arch/mips/regfile/misc_regfile.hh"
+#include "arch/mips/mt_constants.hh"
+#include "arch/mips/faults.hh"
+
+#include "cpu/thread_context.hh"
+#include "cpu/base.hh"
+#include "cpu/exetrace.hh"
+//#include "cpu/mixie/cpu.hh"
+
+using namespace std;
+
+std::string MiscRegFile::miscRegNames[NumMiscRegs] =
+{"Index", "MVPControl", "MVPConf0", "MVPConf1", "", "", "", "",
+ "Random", "VPEControl", "VPEConf0", "VPEConf1", "YQMask", "VPESchedule", "VPEScheFBack", "VPEOpt",
+ "EntryLo0", "TCStatus", "TCBind", "TCRestart", "TCHalt", "TCContext", "TCSchedule", "TCScheFBack",
+ "EntryLo1", "", "", "", "", "", "", "",
+ "Context", "ContextConfig", "", "", "", "", "", "",
+ "PageMask", "PageGrain", "", "", "", "", "", "",
+ "Wired", "SRSConf0", "SRCConf1", "SRSConf2", "SRSConf3", "SRSConf4", "", "",
+ "HWREna", "", "", "", "", "", "", "",
+ "BadVAddr", "", "", "", "", "", "", "",
+ "Count", "", "", "", "", "", "", "",
+ "EntryHi", "", "", "", "", "", "", "",
+ "Compare", "", "", "", "", "", "", "",
+ "Status", "IntCtl", "SRSCtl", "SRSMap", "", "", "", "",
+ "Cause", "", "", "", "", "", "", "",
+ "EPC", "", "", "", "", "", "", "",
+ "PRId", "EBase", "", "", "", "", "", "",
+ "Config", "Config1", "Config2", "Config3", "", "", "", "",
+ "LLAddr", "", "", "", "", "", "", "",
+ "WatchLo0", "WatchLo1", "WatchLo2", "WatchLo3", "WatchLo4", "WatchLo5", "WatchLo6", "WatchLo7",
+ "WatchHi0", "WatchHi1", "WatchHi2", "WatchHi3", "WatchHi4", "WatchHi5", "WatchHi6", "WatchHi7",
+ "XCContext64", "", "", "", "", "", "", "",
+ "", "", "", "", "", "", "", "",
+ "", "", "", "", "", "", "", "",
+ "Debug", "TraceControl1", "TraceControl2", "UserTraceData", "TraceBPC", "", "", "",
+ "DEPC", "", "", "", "", "", "", "",
+ "PerfCnt0", "PerfCnt1", "PerfCnt2", "PerfCnt3", "PerfCnt4", "PerfCnt5", "PerfCnt6", "PerfCnt7",
+ "ErrCtl", "", "", "", "", "", "", "",
+ "CacheErr0", "CacheErr1", "CacheErr2", "CacheErr3", "", "", "", "",
+ "TagLo0", "DataLo1", "TagLo2", "DataLo3", "TagLo4", "DataLo5", "TagLo6", "DataLo7",
+ "TagHi0", "DataHi1", "TagHi2", "DataHi3", "TagHi4", "DataHi5", "TagHi6", "DataHi7",
+ "ErrorEPC", "", "", "", "", "", "", "",
+ "DESAVE", "", "", "", "", "", "", "",
+ "LLFlag"
+};
+
+MiscRegFile::MiscRegFile()
+{
+    init();
+}
+
+MiscRegFile::MiscRegFile(BaseCPU *_cpu)
+{
+    cpu = _cpu;
+    init();
+}
+
+void
+MiscRegFile::init()
+{
+    miscRegFile.resize(NumMiscRegs);
+    bankType.resize(NumMiscRegs);
+
+    for (int i=0; i < NumMiscRegs; i++) {
+        miscRegFile[i].resize(1);
+        bankType[i] = perProcessor;
+    }
+
+    clear(0);
+}
+
+void
+MiscRegFile::clear(unsigned tid_or_vpn)
+{
+    for(int i = 0; i < NumMiscRegs; i++) {
+        miscRegFile[i][tid_or_vpn] = 0;
+    }
+}
+
+void
+MiscRegFile::expandForMultithreading(unsigned num_threads, unsigned num_vpes)
+{
+    // Initialize all Per-VPE regs
+    uint32_t per_vpe_regs[] = { VPEControl, VPEConf0, VPEConf1, YQMask,
+                                VPESchedule, VPEScheFBack, VPEOpt, SRSConf0,
+                                SRSConf1, SRSConf2, SRSConf3, SRSConf4,
+                                EBase
+                              };
+    uint32_t num_vpe_regs = sizeof(per_vpe_regs) / 4;
+    for (int i = 0; i < num_vpe_regs; i++) {
+        if (num_vpes > 1) {
+            miscRegFile[per_vpe_regs[i]].resize(num_vpes);
+        }
+        bankType[per_vpe_regs[i]] = perVirtProcessor;
+    }
+
+    // Initialize all Per-TC regs
+    uint32_t per_tc_regs[] = { Status, TCStatus, TCBind, TCRestart, TCHalt,
+                               TCContext, TCSchedule, TCScheFBack, Debug,
+                               LLAddr
+                             };
+    uint32_t num_tc_regs = sizeof(per_tc_regs) /  4;
+
+    for (int i = 0; i < num_tc_regs; i++) {
+        miscRegFile[per_tc_regs[i]].resize(num_threads);
+        bankType[per_tc_regs[i]] = perThreadContext;
+    }
+
+
+    if (num_vpes > 1) {
+        for (int i=1; i < num_vpes; i++) {
+            clear(i);
+        }
+    }
+
+}
+
+//@TODO: Use MIPS STYLE CONSTANTS (e.g. TCHALT_H instead of TCH_H)
+void
+MiscRegFile::reset(std::string core_name, unsigned num_threads,
+                   unsigned num_vpes)
+{
+    DPRINTF(MipsPRA, "Resetting CP0 State with %i TCs and %i VPEs\n",
+            num_threads, num_vpes);
+
+    // Do Default CP0 initialization HERE
+
+    // Do Initialization for MT cores here (eventually use
+    // core_name parameter to toggle this initialization)
+    // ===================================================
+    // Config
+    MiscReg cfg = readRegNoEffect(Config);
+    replaceBits(cfg, CFG_M, 1);
+    setRegNoEffect(Config, cfg);
+
+    // Config1
+    MiscReg cfg1 = readRegNoEffect(Config1);
+    replaceBits(cfg1, CFG1_M, 1);
+    setRegNoEffect(Config1, cfg1);
+
+    // Config2
+    MiscReg cfg2 = readRegNoEffect(Config2);
+    replaceBits(cfg2, CFG2_M, 1);
+    setRegNoEffect(Config2, cfg2);
+
+    // Config3
+    MiscReg cfg3 = readRegNoEffect(Config3);
+    replaceBits(cfg3, CFG3_MT, 1);
+    setRegNoEffect(Config3, cfg3);
+
+    // MVPConf0
+    MiscReg mvp_conf0 = readRegNoEffect(MVPConf0);
+    replaceBits(mvp_conf0, MVPC0_TCA, 1);
+    replaceBits(mvp_conf0, MVPC0_PVPE_HI, MVPC0_PVPE_LO, num_vpes - 1);
+    replaceBits(mvp_conf0, MVPC0_PTC_HI, MVPC0_PTC_LO, num_threads - 1);
+    setRegNoEffect(MVPConf0, mvp_conf0);
+
+    // VPEConf0
+    MiscReg vpe_conf0 = readRegNoEffect(VPEConf0);
+    replaceBits(vpe_conf0, VPEC0_MVP, 1);
+    setRegNoEffect(VPEConf0, vpe_conf0);
+
+    // TCBind
+    for (int tid = 0; tid < num_threads; tid++) {
+        MiscReg tc_bind = readRegNoEffect(TCBind, tid);
+        replaceBits(tc_bind, TCB_CUR_TC_HI, TCB_CUR_TC_LO, tid);
+        setRegNoEffect(TCBind, tc_bind, tid);
+    }
+
+    // TCHalt
+    MiscReg tc_halt = readRegNoEffect(TCHalt);
+    replaceBits(tc_halt, TCH_H, 0);
+    setRegNoEffect(TCHalt, tc_halt);
+    /*for (int tid = 1; tid < num_threads; tid++) {
+        // Set TCHalt Halt bit to 1 for all other threads
+        tc_halt = readRegNoEffect(TCHalt, tid);
+        replaceBits(tc_halt, TCH_H, 1);
+        setReg(TCHalt, tc_halt, tid);
+        }*/
+
+    // TCStatus
+    // Set TCStatus Activated to 1 for the initial thread that is running
+    MiscReg tc_status = readRegNoEffect(TCStatus);
+    replaceBits(tc_status, TCS_A, 1);
+    setRegNoEffect(TCStatus, tc_status);
+
+    // Set Dynamically Allocatable bit to 1 for all other threads
+    for (int tid = 0; tid < num_threads; tid++) {
+        tc_status = readRegNoEffect(TCStatus, tid);
+        replaceBits(tc_status, TCSTATUS_DA, 1);
+        setRegNoEffect(TCStatus, tc_status, tid);
+    }
+}
+
+inline std::string
+MipsISA::getMiscRegName(unsigned reg_idx)
+{
+    return MiscRegFile::miscRegNames[reg_idx];
+}
+
+inline unsigned
+MiscRegFile::getVPENum(unsigned tid)
+{
+    unsigned tc_bind = miscRegFile[TCBind][tid];
+    return bits(tc_bind, TCB_CUR_VPE_HI, TCB_CUR_VPE_LO);
+}
+
+MiscReg
+MiscRegFile::readRegNoEffect(int misc_reg, unsigned tid)
+{
+    unsigned reg_sel = (bankType[misc_reg] == perThreadContext)
+        ? tid : getVPENum(tid);
+
+    return miscRegFile[misc_reg][reg_sel];
+}
+
+//@TODO: MIPS MT's register view automatically connects
+//       Status to TCStatus depending on current thread
+MiscReg
+MiscRegFile::readReg(int misc_reg,
+                               ThreadContext *tc,  unsigned tid)
+{
+    DPRINTF(MipsPRA, "Reading CP0 Register:%u Select:%u (%s) with effect.\n",
+            misc_reg / 8, misc_reg % 8, getMiscRegName(misc_reg));
+
+    unsigned reg_sel = (bankType[misc_reg] == perThreadContext)
+        ? tid : getVPENum(tid);
+
+    switch (misc_reg)
+    {
+      default:
+        return miscRegFile[misc_reg][reg_sel];
+    }
+}
+
+void
+MiscRegFile::setRegNoEffect(int misc_reg, const MiscReg &val, unsigned tid)
+{
+    unsigned reg_sel = (bankType[misc_reg] == perThreadContext)
+        ? tid : getVPENum(tid);
+
+    miscRegFile[misc_reg][reg_sel] = val;
+}
+
+// PROGRAMMER'S NOTES:
+// (1) Some CP0 Registers have fields that cannot
+// be overwritten. Make sure to handle those particular registers
+// with care!
+void
+MiscRegFile::setReg(int misc_reg, const MiscReg &val,
+                              ThreadContext *tc, unsigned tid)
+{
+    unsigned reg_sel = (bankType[misc_reg] == perThreadContext)
+        ? tid : getVPENum(tid);
+
+    DPRINTF(MipsPRA, "[tid:%i]: Setting CP0 Register:%u Select:%u (%s) to %#x, with effect.\n",
+            tid, misc_reg / 8, misc_reg % 8, getMiscRegName(misc_reg), val);
+
+    MiscReg cp0_val = filterCP0Write(misc_reg, val);
+
+    miscRegFile[misc_reg][reg_sel] = cp0_val;
+
+    scheduleCP0Update();
+}
+
+void
+MiscRegFile::scheduleCP0Update(int delay)
+{
+    if (!cp0Updated) {
+        cp0Updated = true;
+
+        //schedule UPDATE
+        CP0Event *cp0_event = new CP0Event(this, cpu, UpdateCP0);
+        cp0_event->schedule(curTick + cpu->cycles(delay));
+    }
+}
+
+void
+MiscRegFile::updateCPU()
+{
+    ///////////////////////////////////////////////////////////////////
+    //
+    // EVALUATE CP0 STATE FOR MIPS MT
+    //
+    ///////////////////////////////////////////////////////////////////
+    unsigned mvp_conf0 = readRegNoEffect(MVPConf0);
+    unsigned num_threads = bits(mvp_conf0, MVPC0_PTC_HI, MVPC0_PTC_LO) + 1;
+
+    for (int tid = 0; tid < num_threads; tid++) {
+        MiscReg tc_status = readRegNoEffect(TCStatus, tid);
+        MiscReg tc_halt = readRegNoEffect(TCHalt, tid);
+
+        //@todo: add vpe/mt check here thru mvpcontrol & vpecontrol regs
+        if (bits(tc_halt, TCH_H) == 1 || bits(tc_status, TCS_A) == 0)  {
+            haltThread(cpu->getContext(tid));
+        } else if (bits(tc_halt, TCH_H) == 0 && bits(tc_status, TCS_A) == 1) {
+            restoreThread(cpu->getContext(tid));
+        }
+    }
+
+    num_threads = bits(mvp_conf0, MVPC0_PTC_HI, MVPC0_PTC_LO) + 1;
+
+    // Toggle update flag after we finished updating
+    cp0Updated = false;
+}
+
+MiscRegFile::CP0Event::CP0Event(CP0 *_cp0, BaseCPU *_cpu, CP0EventType e_type)
+    : Event(&mainEventQueue, CPU_Tick_Pri), cp0(_cp0), cpu(_cpu), cp0EventType(e_type)
+{  }
+
+void
+MiscRegFile::CP0Event::process()
+{
+    switch (cp0EventType)
+    {
+      case UpdateCP0:
+        cp0->updateCPU();
+        break;
+    }
+
+    //cp0EventRemoveList.push(this);
+}
+
+const char *
+MiscRegFile::CP0Event::description()
+{
+    return "Coprocessor-0 event";
+}
+
+void
+MiscRegFile::CP0Event::scheduleEvent(int delay)
+{
+    if (squashed())
+        reschedule(curTick + cpu->cycles(delay));
+    else if (!scheduled())
+        schedule(curTick + cpu->cycles(delay));
+}
+
+void
+MiscRegFile::CP0Event::unscheduleEvent()
+{
+    if (scheduled())
+        squash();
+}
index 53ee09512c5f1176cd14823cc03e898ea273a626..54b086a8b2d4123646127f6e39b690cf1fb976a6 100644 (file)
 #ifndef __ARCH_MIPS_REGFILE_MISC_REGFILE_HH__
 #define __ARCH_MIPS_REGFILE_MISC_REGFILE_HH__
 
+#include "arch/mips/isa_traits.hh"
 #include "arch/mips/types.hh"
+#include "arch/mips/mt.hh"
+#include "arch/mips/mt_constants.hh"
+#include "base/bitfield.hh"
+#include "cpu/base.hh"
 #include "sim/faults.hh"
+#include <queue>
 
 class ThreadContext;
 
 namespace MipsISA
 {
-    static inline std::string getMiscRegName(RegIndex)
-    {
-        return "";
-    }
-
-    //Coprocessor 0 Register Names
-    enum MiscRegTags {
-        //Reference MIPS32 Arch. for Programmers, Vol. III, Ch.8
-        //(Register Number-Register Select) Summary of Register
-        //------------------------------------------------------
-        Index = 0,       //Bank 0: 0 - 3
-        MVPControl,
-        MVPConf0,
-        MVPConf1,
-
-        Random = 8,      //Bank 1: 8 - 15
-        VPEControl,
-        VPEConf0,
-        VPEConf1,
-        YQMask,
-        VPESchedule,
-        VPEScheFBack,
-        VPEOpt,
-
-        EntryLo0 = 16,   //Bank 2: 16 - 23
-        TCStatus,
-        TCBind,
-        TCRestart,
-        TCHalt,
-        TCContext,
-        TCSchedule,
-        TCScheFBack,
-
-        EntryLo1 = 24,   // Bank 3: 24
-
-        Context = 32,    // Bank 4: 32 - 33
-        ContextConfig,
-
-        //PageMask = 40, //Bank 5: 40 - 41
-        PageGrain = 41,
-
-        Wired = 48,      //Bank 6: 48 - 55
-        SRSConf0,
-        SRSConf1,
-        SRSConf2,
-        SRSConf3,
-        SRSConf4,
-
-        HWRena = 56,     //Bank 7: 56
-
-        BadVAddr = 63,   //Bank 8: 63
-
-        Count = 64,      //Bank 9: 64
-
-        EntryHi = 72,   //Bank 10:72 - 79
-
-        Compare = 80,   //Bank 10:80 - 87
-
-        Status = 88,    //Bank 12:88 - 96
-        IntCtl = 89,
-        SRSCtl = 90,
-        SRSMap = 91,
-
-        Cause = 97,     //97-104
-
-        EPC = 105,      //105-112
-
-        PRId = 113,     //113-120,
-        EBase = 114,
-
-        Config = 121,   //Bank 16: 121-128
-        Config1 = 122,
-        Config2 = 123,
-        Config3 = 124,
-        Config6 = 127,
-        Config7 = 128,
-
-
-        LLAddr = 129,   //Bank 17: 129-136
-
-        WatchLo0 = 137, //Bank 18: 137-144
-        WatchLo1 = 138,
-        WatchLo2 = 139,
-        WatchLo3 = 140,
-        WatchLo4 = 141,
-        WatchLo5 = 142,
-        WatchLo6 = 143,
-        WatchLo7 = 144,
-
-        WatchHi0 = 145,//Bank 19: 145-152
-        WatchHi1 = 146,
-        WatchHi2 = 147,
-        WatchHi3 = 148,
-        WatchHi4 = 149,
-        WatchHi5 = 150,
-        WatchHi6 = 151,
-        WatchHi7 = 152,
-
-        XCContext64 = 153, //Bank 20: 153-160
-
-        //Bank 21: 161-168
-
-        //Bank 22: 169-176
-
-        Debug = 177, //Bank 23: 177-184
-        TraceControl1 = 178,
-        TraceControl2 = 179,
-        UserTraceData = 180,
-        TraceBPC = 181,
-
-        DEPC = 185,//Bank 24: 185-192
-
-        PerfCnt0 = 193,//Bank 25: 193 - 200
-        PerfCnt1 = 194,
-        PerfCnt2 = 195,
-        PerfCnt3 = 196,
-        PerfCnt4 = 197,
-        PerfCnt5 = 198,
-        PerfCnt6 = 199,
-        PerfCnt7 = 200,
+    class MiscRegFile {
+      public:
+        // Give RegFile object, private access
+        friend class RegFile;
 
-        ErrCtl = 201, //Bank 26: 201 - 208
+        // The MIPS name for this file is CP0 or Coprocessor 0
+        typedef MiscRegFile CP0;
 
-        CacheErr0 = 209, //Bank 27: 209 - 216
-        CacheErr1 = 210,
-        CacheErr2 = 211,
-        CacheErr3 = 212,
+      protected:
+        enum BankType {
+            perProcessor,
+            perThreadContext,
+            perVirtProcessor
+        };
 
-        TagLo0 = 217,//Bank 28: 217 - 224
-        DataLo1 = 218,
-        TagLo2 = 219,
-        DataLo3 = 220,
-        TagLo4 = 221,
-        DataLo5 = 222,
-        TagLo6 = 223,
-        DataLo7 = 234,
+        std::vector<std::vector<MiscReg> > miscRegFile;
+        std::vector<BankType> bankType;
 
-        TagHi0 = 233,//Bank 29: 233 - 240
-        DataHi1 = 234,
-        TagHi2 = 235,
-        DataHi3 = 236,
-        TagHi4 = 237,
-        DataHi5 = 238,
-        TagHi6 = 239,
-        DataHi7 = 240,
+        BaseCPU *cpu;
 
+      public:
+        MiscRegFile();
+        MiscRegFile(BaseCPU *cpu);
 
-        ErrorEPC = 249,//Bank 30: 241 - 248
+        void init();
 
-        DESAVE = 257//Bank 31: 249-256
-    };
+        void clear(unsigned tid_or_vpn = 0);
 
-    class MiscRegFile {
+        void reset(std::string core_name, unsigned num_threads, unsigned num_vpes);
 
-      protected:
-        uint64_t       fpcr;           // floating point condition codes
-                                        // FPCR is not used in MIPS. Condition
-                                        // codes are kept as part of the FloatRegFile
+        void expandForMultithreading(unsigned num_threads, unsigned num_vpes);
 
-        bool           lock_flag;      // lock flag for LL/SC
-                                        // use LL reg. in the future
+        void copyMiscRegs(ThreadContext *tc);
 
-        Addr           lock_addr;      // lock address for LL/SC
-                                        // use LLAddr reg. in the future
+        inline unsigned getVPENum(unsigned tid);
+
+        //////////////////////////////////////////////////////////
+        //
+        // READ/WRITE CP0 STATE
+        //
+        //
+        //////////////////////////////////////////////////////////
+        //@TODO: MIPS MT's register view automatically connects
+        //       Status to TCStatus depending on current thread
+        void updateCP0ReadView(int misc_reg, unsigned tid) { }
+        MiscReg readRegNoEffect(int misc_reg, unsigned tid = 0);
+        MiscReg readReg(int misc_reg,
+                        ThreadContext *tc,  unsigned tid = 0);
+
+        MiscReg filterCP0Write(int misc_reg, MiscReg val) { return val; }
+        void setRegNoEffect(int misc_reg, const MiscReg &val, unsigned tid = 0);
+        void setReg(int misc_reg, const MiscReg &val,
+                     ThreadContext *tc, unsigned tid = 0);
 
-        MiscReg miscRegFile[NumMiscRegs];
+        //////////////////////////////////////////////////////////
+        //
+        // DECLARE INTERFACE THAT WILL ALLOW A MiscRegFile (Cop0)
+        // TO SCHEDULE EVENTS
+        //
+        //////////////////////////////////////////////////////////
 
-      public:
-        void clear()
-        {
-            fpcr = 0;
-            lock_flag = 0;
-            lock_addr = 0;
-        }
+        // Flag that is set when CP0 state has been written to.
+        bool cp0Updated;
 
-        void copyMiscRegs(ThreadContext *tc);
+        // Enumerated List of CP0 Event Types
+        enum CP0EventType {
+            UpdateCP0
+        };
 
-        MiscReg readRegNoEffect(int misc_reg)
+        // Declare A CP0Event Class for scheduling
+        class CP0Event : public Event
         {
-            return miscRegFile[misc_reg];
-        }
+          protected:
+            MiscRegFile::CP0 *cp0;
+            BaseCPU *cpu;
+            CP0EventType cp0EventType;
+            Fault fault;
 
-        MiscReg readReg(int misc_reg, ThreadContext *tc)
-        {
-            return miscRegFile[misc_reg];
-        }
+          public:
+            /** Constructs a CP0 event. */
+            CP0Event(CP0 *_cp0, BaseCPU *_cpu, CP0EventType e_type);
 
-        void setRegNoEffect(int misc_reg, const MiscReg &val)
-        {
-            miscRegFile[misc_reg] = val;
-        }
+            /** Process this event. */
+            virtual void process();
 
-        void setReg(int misc_reg, const MiscReg &val,
-                               ThreadContext *tc)
-        {
-            miscRegFile[misc_reg] = val;
-        }
+            /** Returns the description of this event. */
+            const char *description();
 
-        friend class RegFile;
+            /** Schedule This Event */
+            void scheduleEvent(int delay);
+
+            /** Unschedule This Event */
+            void unscheduleEvent();
+        };
+
+        // Schedule a CP0 Update Event
+        void scheduleCP0Update(int delay = 0);
+
+        // If any changes have been made, then check the state for changes
+        // and if necessary alert the CPU
+        void updateCPU();
+
+        // Keep a List of CPU Events that need to be deallocated
+        std::queue<CP0Event*> cp0EventRemoveList;
+
+        static std::string miscRegNames[NumMiscRegs];
     };
+
+    inline std::string getMiscRegName(unsigned reg_idx);
 } // namespace MipsISA
 
 #endif
index 387fbd5c884223d19a7699dd7d81145c22d61c0a..f13653132ce52e0b2476242de16cc791d6a8a7f8 100644 (file)
@@ -32,6 +32,8 @@
 #define __ARCH_MIPS_REGFILE_REGFILE_HH__
 
 #include "arch/mips/types.hh"
+#include "arch/mips/isa_traits.hh"
+#include "arch/mips/mt.hh"
 #include "arch/mips/regfile/int_regfile.hh"
 #include "arch/mips/regfile/float_regfile.hh"
 #include "arch/mips/regfile/misc_regfile.hh"
@@ -49,33 +51,50 @@ namespace MipsISA
         MiscRegFile miscRegFile;       // control register file
 
       public:
-
         void clear()
+        {
+            intRegFile.clear();
+            floatRegFile.clear();
+            miscRegFile.clear();
+        }
+
+        void reset(std::string core_name, unsigned num_threads, unsigned num_vpes)
         {
             bzero(&intRegFile, sizeof(intRegFile));
             bzero(&floatRegFile, sizeof(floatRegFile));
-            bzero(&miscRegFile, sizeof(miscRegFile));
+            miscRegFile.reset(core_name, num_threads, num_vpes);
+        }
+
+        IntReg readIntReg(int intReg)
+        {
+            return intRegFile.readReg(intReg);
+        }
+
+        Fault setIntReg(int intReg, const IntReg &val)
+        {
+            return intRegFile.setReg(intReg, val);
         }
 
-        MiscReg readMiscRegNoEffect(int miscReg)
+        MiscReg readMiscRegNoEffect(int miscReg, unsigned tid = 0)
         {
-            return miscRegFile.readRegNoEffect(miscReg);
+            return miscRegFile.readRegNoEffect(miscReg, tid);
         }
 
-        MiscReg readMiscReg(int miscReg, ThreadContext *tc)
+        MiscReg readMiscReg(int miscReg, ThreadContext *tc,
+                                      unsigned tid = 0)
         {
-            return miscRegFile.readReg(miscReg, tc);
+            return miscRegFile.readReg(miscReg, tc, tid);
         }
 
-        void setMiscRegNoEffect(int miscReg, const MiscReg &val)
+        void setMiscRegNoEffect(int miscReg, const MiscReg &val, unsigned tid = 0)
         {
-            miscRegFile.setRegNoEffect(miscReg, val);
+            miscRegFile.setRegNoEffect(miscReg, val, tid);
         }
 
         void setMiscReg(int miscReg, const MiscReg &val,
-                ThreadContext * tc)
+                ThreadContext * tc, unsigned tid = 0)
         {
-            miscRegFile.setReg(miscReg, val, tc);
+            miscRegFile.setReg(miscReg, val, tc, tid);
         }
 
         FloatRegVal readFloatReg(int floatReg)
@@ -98,35 +117,26 @@ namespace MipsISA
             return floatRegFile.readRegBits(floatReg,width);
         }
 
-        void setFloatReg(int floatReg, const FloatRegVal &val)
-        {
-            floatRegFile.setReg(floatReg, val, SingleWidth);
-        }
-
-        void setFloatReg(int floatReg, const FloatRegVal &val, int width)
+        Fault setFloatReg(int floatReg, const FloatRegVal &val)
         {
-            floatRegFile.setReg(floatReg, val, width);
+            return floatRegFile.setReg(floatReg, val, SingleWidth);
         }
 
-        void setFloatRegBits(int floatReg, const FloatRegBits &val)
+        Fault setFloatReg(int floatReg, const FloatRegVal &val, int width)
         {
-            floatRegFile.setRegBits(floatReg, val, SingleWidth);
+            return floatRegFile.setReg(floatReg, val, width);
         }
 
-        void setFloatRegBits(int floatReg, const FloatRegBits &val, int width)
+        Fault setFloatRegBits(int floatReg, const FloatRegBits &val)
         {
-            floatRegFile.setRegBits(floatReg, val, width);
+            return floatRegFile.setRegBits(floatReg, val, SingleWidth);
         }
 
-        IntReg readIntReg(int intReg)
+        Fault setFloatRegBits(int floatReg, const FloatRegBits &val, int width)
         {
-            return intRegFile.readReg(intReg);
+            return floatRegFile.setRegBits(floatReg, val, width);
         }
 
-        void setIntReg(int intReg, const IntReg &val)
-        {
-            intRegFile.setReg(intReg, val);
-        }
       protected:
 
         Addr pc;                       // program counter
@@ -134,6 +144,7 @@ namespace MipsISA
         Addr nnpc;                     // next-next-cycle program counter
                                         // used to implement branch delay slot
                                         // not real register
+
       public:
         Addr readPC()
         {
index 9ac4bb6d8f226cd297369a912cb6c89b745865d7..8f113fb82227ccf44d9d37fc06f8aeecd6e47fdc 100644 (file)
  * Authors: Korey Sewell
  */
 
-#include "arch/mips/regfile.hh"
+#include "arch/mips/isa_traits.hh"
 #include "arch/mips/utility.hh"
-#include "base/misc.hh"
+#include "arch/mips/constants.hh"
+#include "config/full_system.hh"
+#include "cpu/thread_context.hh"
+#include "cpu/static_inst.hh"
+#include "sim/serialize.hh"
 #include "base/bitfield.hh"
+#include "base/misc.hh"
 
 using namespace MipsISA;
+using namespace std;
 
 uint64_t
 MipsISA::fpConvert(ConvertType cvt_type, double fp_val)
@@ -197,3 +203,9 @@ MipsISA::isSnan(void *val_ptr, int size)
         panic("Type unsupported. Size mismatch\n");
     }
 }
+
+void
+MipsISA::startupCPU(ThreadContext *tc, int cpuId)
+{
+        tc->activate(0);
+}
index 12db1de57ba38549ff3c1cb64c5026e1a9fd80ef..e3fd9daa84cfda49366d63f3292b4433621b0dea 100644 (file)
 #define __ARCH_MIPS_UTILITY_HH__
 
 #include "arch/mips/types.hh"
+#include "arch/mips/isa_traits.hh"
 #include "base/misc.hh"
 #include "config/full_system.hh"
-#include "cpu/thread_context.hh"
 //XXX This is needed for size_t. We should use something other than size_t
 //#include "kern/linux/linux.hh"
 #include "sim/host.hh"
 
+#include "cpu/thread_context.hh"
+
 class ThreadContext;
 
 namespace MipsISA {
@@ -66,6 +68,8 @@ namespace MipsISA {
     template <class TC>
     void zeroRegisters(TC *tc);
 
+    void startupCPU(ThreadContext *tc, int cpuId);
+
     void copyRegs(ThreadContext *src, ThreadContext *dest);
 
     // Instruction address compression hooks
@@ -88,9 +92,17 @@ namespace MipsISA {
         return 0;
     }
 
-    inline void startupCPU(ThreadContext *tc, int cpuId)
-    {
-        tc->activate(0);
+    static inline ExtMachInst
+    makeExtMI(MachInst inst, ThreadContext * xc) {
+#if FULL_SYSTEM
+        ExtMachInst ext_inst = inst;
+        if (xc->readPC() && 0x1)
+            return ext_inst|=(static_cast<ExtMachInst>(xc->readPC() & 0x1) << 32);
+        else
+            return ext_inst;
+#else
+        return ExtMachInst(inst);
+#endif
     }
 };
 
index 518bad6b87ad64fcbcad7203f8dc3364974ac01f..70a46386e4ad4901edf6368502ab298d02d07a3c 100644 (file)
@@ -58,6 +58,17 @@ bits(T val, int first, int last)
     return (val >> last) & mask(nbits);
 }
 
+/**
+ * Extract the bit from this position from 'val' and right justify it.
+ */
+template <class T>
+inline
+T
+bits(T val, int bit)
+{
+    return bits(val, bit, bit);
+}
+
 /**
  * Mask off the given bits in place like bits() but without shifting.
  * msb = 63, lsb = 0
@@ -101,6 +112,17 @@ insertBits(T val, int first, int last, B bit_val)
     return ((t_bit_val << last) & bmask) | (val & ~bmask);
 }
 
+/**
+ * Overloaded for access to only one bit in value
+ */
+template <class T, class B>
+inline
+T
+insertBits(T val, int bit, B bit_val)
+{
+    return insertBits(val, bit, bit, bit_val);
+}
+
 /**
  * A convenience function to replace bits first to last of val with bit_val
  * in place.
@@ -113,6 +135,14 @@ replaceBits(T& val, int first, int last, B bit_val)
     val = insertBits(val, first, last, bit_val);
 }
 
+/** Overloaded function to allow to access only 1 bit*/
+template <class T, class B>
+inline
+void
+replaceBits(T& val, int bit, B bit_val)
+{
+    val = insertBits(val, bit, bit, bit_val);
+}
 /**
  * Returns the bit position of the MSB that is set in the input
  */
index 6b241c410b8a1f0793c6bfeb531eb7c6fa776bdb..fddb86328078a2cb9ac673605e94108e5987927d 100644 (file)
@@ -128,6 +128,7 @@ baseFlags = [
     'Mbox',
     'MemDepUnit',
     'MemoryAccess',
+    'MipsPRA',
     'O3CPU',
     'OzoneCPU',
     'OzoneLSQ',
index d221baca85717ad606f57c777e79479279037867..243167db03e361eedf8e1c63a53fefdb61ac5e82 100644 (file)
@@ -215,6 +215,7 @@ class BaseSimpleCPU : public BaseCPU
         // need to do this...
     }
 
+
     Fault copySrcTranslate(Addr src);
 
     Fault copy(Addr dest);
@@ -353,6 +354,18 @@ class BaseSimpleCPU : public BaseCPU
         thread->setStCondFailures(sc_failures);
     }
 
+     MiscReg readRegOtherThread(int regIdx, int tid = -1)
+     {
+        panic("Simple CPU models do not support multithreaded "
+              "register access.\n");
+     }
+
+     void setRegOtherThread(int regIdx, const MiscReg &val, int tid = -1)
+     {
+        panic("Simple CPU models do not support multithreaded "
+              "register access.\n");
+     }
+
 #if FULL_SYSTEM
     Fault hwrei() { return thread->hwrei(); }
     void ev5_trap(Fault fault) { fault->invoke(tc); }
index 95848ee2ce2b129175148788199fc9387e7e0f3b..c20fe3d90653eab2f338e6e1f6b171a16bdfd649 100644 (file)
@@ -349,22 +349,22 @@ class SimpleThread : public ThreadState
         regs.setNextNPC(val);
     }
 
-    MiscReg readMiscRegNoEffect(int misc_reg)
+    MiscReg readMiscRegNoEffect(int misc_reg, unsigned tid = 0)
     {
         return regs.readMiscRegNoEffect(misc_reg);
     }
 
-    MiscReg readMiscReg(int misc_reg)
+    MiscReg readMiscReg(int misc_reg, unsigned tid = 0)
     {
         return regs.readMiscReg(misc_reg, tc);
     }
 
-    void setMiscRegNoEffect(int misc_reg, const MiscReg &val)
+    void setMiscRegNoEffect(int misc_reg, const MiscReg &val, unsigned tid = 0)
     {
         return regs.setMiscRegNoEffect(misc_reg, val);
     }
 
-    void setMiscReg(int misc_reg, const MiscReg &val)
+    void setMiscReg(int misc_reg, const MiscReg &val, unsigned tid = 0)
     {
         return regs.setMiscReg(misc_reg, val, tc);
     }
index 05c409c95ece1870ff759c4f2bb72bfe91f8bc0e..3706d8543ca426870ec2dda5ca8839570167a5d0 100644 (file)
@@ -234,6 +234,10 @@ class ThreadContext
 
     virtual void setMiscReg(int misc_reg, const MiscReg &val) = 0;
 
+    virtual uint64_t readRegOtherThread(int misc_reg, unsigned tid) { return 0; }
+
+    virtual void setRegOtherThread(int misc_reg, const MiscReg &val, unsigned tid) { };
+
     // Also not necessarily the best location for these two.  Hopefully will go
     // away once we decide upon where st cond failures goes.
     virtual unsigned readStCondFailures() = 0;