summaryrefslogtreecommitdiff
path: root/src/arch/mips
diff options
context:
space:
mode:
Diffstat (limited to 'src/arch/mips')
-rw-r--r--src/arch/mips/SConscript83
-rw-r--r--src/arch/mips/faults.cc136
-rw-r--r--src/arch/mips/faults.hh296
-rw-r--r--src/arch/mips/isa/base.isa111
-rw-r--r--src/arch/mips/isa/bitfields.isa102
-rw-r--r--src/arch/mips/isa/decoder.isa1102
-rw-r--r--src/arch/mips/isa/formats/basic.isa96
-rw-r--r--src/arch/mips/isa/formats/branch.isa278
-rw-r--r--src/arch/mips/isa/formats/control.isa156
-rw-r--r--src/arch/mips/isa/formats/formats.isa66
-rw-r--r--src/arch/mips/isa/formats/fp.isa373
-rw-r--r--src/arch/mips/isa/formats/int.isa269
-rw-r--r--src/arch/mips/isa/formats/mem.isa604
-rw-r--r--src/arch/mips/isa/formats/mt.isa82
-rw-r--r--src/arch/mips/isa/formats/noop.isa139
-rw-r--r--src/arch/mips/isa/formats/tlbop.isa80
-rw-r--r--src/arch/mips/isa/formats/trap.isa81
-rw-r--r--src/arch/mips/isa/formats/unimp.isa145
-rw-r--r--src/arch/mips/isa/formats/unknown.isa84
-rw-r--r--src/arch/mips/isa/formats/util.isa189
-rw-r--r--src/arch/mips/isa/includes.isa82
-rw-r--r--src/arch/mips/isa/main.isa61
-rw-r--r--src/arch/mips/isa/operands.isa91
-rw-r--r--src/arch/mips/isa_traits.cc98
-rw-r--r--src/arch/mips/isa_traits.hh124
-rw-r--r--src/arch/mips/linux/linux.cc74
-rw-r--r--src/arch/mips/linux/linux.hh126
-rw-r--r--src/arch/mips/linux/process.cc435
-rw-r--r--src/arch/mips/linux/process.hh62
-rw-r--r--src/arch/mips/process.cc71
-rw-r--r--src/arch/mips/process.hh60
-rw-r--r--src/arch/mips/regfile.hh36
-rw-r--r--src/arch/mips/regfile/float_regfile.hh195
-rw-r--r--src/arch/mips/regfile/int_regfile.hh79
-rw-r--r--src/arch/mips/regfile/misc_regfile.hh243
-rw-r--r--src/arch/mips/regfile/regfile.hh184
-rw-r--r--src/arch/mips/stacktrace.hh121
-rw-r--r--src/arch/mips/syscallreturn.hh84
-rw-r--r--src/arch/mips/types.hh98
-rw-r--r--src/arch/mips/utility.cc199
-rw-r--r--src/arch/mips/utility.hh103
41 files changed, 7098 insertions, 0 deletions
diff --git a/src/arch/mips/SConscript b/src/arch/mips/SConscript
new file mode 100644
index 000000000..8353bcde7
--- /dev/null
+++ b/src/arch/mips/SConscript
@@ -0,0 +1,83 @@
+# -*- mode:python -*-
+
+# Copyright (c) 2004-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: Gabe Black
+# Steve Reinhardt
+# Korey Sewell
+
+import os
+import sys
+from os.path import isdir
+
+# Import build environment variable from SConstruct.
+Import('env')
+
+###################################################
+#
+# Define needed sources.
+#
+###################################################
+
+# Base sources used by all configurations.
+base_sources = Split('''
+ faults.cc
+ isa_traits.cc
+ utility.cc
+ ''')
+
+# Full-system sources
+full_system_sources = Split('''
+ #Insert Full-System Files Here
+ ''')
+
+# Syscall emulation (non-full-system) sources
+syscall_emulation_sources = Split('''
+ linux/linux.cc
+ linux/process.cc
+ process.cc
+ ''')
+
+# Set up complete list of sources based on configuration.
+sources = base_sources
+
+if env['FULL_SYSTEM']:
+ sources += full_system_sources
+else:
+ sources += syscall_emulation_sources
+
+# Convert file names to SCons File objects. This takes care of the
+# path relative to the top of the directory tree.
+sources = [File(s) for s in sources]
+
+# Add in files generated by the ISA description.
+isa_desc_files = env.ISADesc('isa/main.isa')
+# Only non-header files need to be compiled.
+isa_desc_sources = [f for f in isa_desc_files if not f.path.endswith('.hh')]
+sources += isa_desc_sources
+
+Return('sources')
diff --git a/src/arch/mips/faults.cc b/src/arch/mips/faults.cc
new file mode 100644
index 000000000..2a8ab1df5
--- /dev/null
+++ b/src/arch/mips/faults.cc
@@ -0,0 +1,136 @@
+/*
+ * 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: Gabe Black
+ * Korey Sewell
+ */
+
+#include "arch/mips/faults.hh"
+#include "cpu/thread_context.hh"
+#include "cpu/base.hh"
+#include "base/trace.hh"
+
+#if !FULL_SYSTEM
+#include "sim/process.hh"
+#include "mem/page_table.hh"
+#endif
+
+namespace MipsISA
+{
+
+FaultName MachineCheckFault::_name = "Machine Check";
+FaultVect MachineCheckFault::_vect = 0x0401;
+FaultStat MachineCheckFault::_count;
+
+FaultName AlignmentFault::_name = "Alignment";
+FaultVect AlignmentFault::_vect = 0x0301;
+FaultStat AlignmentFault::_count;
+
+FaultName ResetFault::_name = "reset";
+FaultVect ResetFault::_vect = 0x0001;
+FaultStat ResetFault::_count;
+
+FaultName ArithmeticFault::_name = "arith";
+FaultVect ArithmeticFault::_vect = 0x0501;
+FaultStat ArithmeticFault::_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;
+
+FaultName NDtbMissFault::_name = "dtb_miss_single";
+FaultVect NDtbMissFault::_vect = 0x0201;
+FaultStat NDtbMissFault::_count;
+
+FaultName PDtbMissFault::_name = "dtb_miss_double";
+FaultVect PDtbMissFault::_vect = 0x0281;
+FaultStat PDtbMissFault::_count;
+
+FaultName DtbPageFault::_name = "dfault";
+FaultVect DtbPageFault::_vect = 0x0381;
+FaultStat DtbPageFault::_count;
+
+FaultName DtbAcvFault::_name = "dfault";
+FaultVect DtbAcvFault::_vect = 0x0381;
+FaultStat DtbAcvFault::_count;
+
+FaultName ItbMissFault::_name = "itbmiss";
+FaultVect ItbMissFault::_vect = 0x0181;
+FaultStat ItbMissFault::_count;
+
+FaultName ItbPageFault::_name = "itbmiss";
+FaultVect ItbPageFault::_vect = 0x0181;
+FaultStat ItbPageFault::_count;
+
+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;
+
+void PageTableFault::invoke(ThreadContext *tc)
+{
+ Process *p = tc->getProcessPtr();
+
+ // 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)
+ fatal("Over max stack size for one thread\n");
+ p->pTable->allocate(p->stack_min, PageBytes);
+ warn("Increasing stack size by one page.");
+ } else {
+ FaultBase::invoke(tc);
+ }
+}
+
+} // namespace MipsISA
+
diff --git a/src/arch/mips/faults.hh b/src/arch/mips/faults.hh
new file mode 100644
index 000000000..9d2c5df32
--- /dev/null
+++ b/src/arch/mips/faults.hh
@@ -0,0 +1,296 @@
+/*
+ * 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: Gabe Black
+ * Korey Sewell
+ */
+
+#ifndef __MIPS_FAULTS_HH__
+#define __MIPS_FAULTS_HH__
+
+#include "sim/faults.hh"
+
+// The design of the "name" and "vect" functions is in sim/faults.hh
+
+namespace MipsISA
+{
+
+typedef const Addr FaultVect;
+
+class MipsFault : public FaultBase
+{
+ protected:
+ virtual bool skipFaultingInstruction() {return false;}
+ virtual bool setRestartAddress() {return true;}
+ public:
+#if FULL_SYSTEM
+ void invoke(ThreadContext * tc);
+#endif
+ virtual FaultVect vect() = 0;
+ virtual FaultStat & countStat() = 0;
+};
+
+class MachineCheckFault : 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;}
+ bool isMachineCheckFault() {return true;}
+};
+
+class AlignmentFault : 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;}
+ bool isAlignmentFault() {return true;}
+};
+
+#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;
+}
+
+static inline Fault genAlignmentFault()
+{
+ return new AlignmentFault;
+}
+
+class ResetFault : 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 ArithmeticFault : public MipsFault
+{
+ protected:
+ bool skipFaultingInstruction() {return true;}
+ 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
+ void invoke(ThreadContext * tc);
+#endif
+};
+
+class InterruptFault : public MipsFault
+{
+ protected:
+ bool setRestartAddress() {return false;}
+ private:
+ static FaultName _name;
+ static FaultVect _vect;
+ static FaultStat _count;
+ public:
+ FaultName name() {return _name;}
+ FaultVect vect() {return _vect;}
+ FaultStat & countStat() {return _count;}
+};
+
+class NDtbMissFault : 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 PDtbMissFault : 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 DtbPageFault : 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 DtbAcvFault : 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 ItbMissFault : 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 ItbPageFault : 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 ItbAcvFault : 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 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:
+ static FaultName _name;
+ static FaultVect _vect;
+ static FaultStat _count;
+ public:
+ FaultName name() {return _name;}
+ FaultVect vect() {return _vect;}
+ FaultStat & countStat() {return _count;}
+};
+
+class PalFault : public MipsFault
+{
+ protected:
+ bool skipFaultingInstruction() {return true;}
+ private:
+ static FaultName _name;
+ static FaultVect _vect;
+ static FaultStat _count;
+ public:
+ FaultName name() {return _name;}
+ FaultVect vect() {return _vect;}
+ FaultStat & countStat() {return _count;}
+};
+
+class IntegerOverflowFault : 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;}
+};
+
+} // MipsISA namespace
+
+#endif // __FAULTS_HH__
diff --git a/src/arch/mips/isa/base.isa b/src/arch/mips/isa/base.isa
new file mode 100644
index 000000000..7c042f16f
--- /dev/null
+++ b/src/arch/mips/isa/base.isa
@@ -0,0 +1,111 @@
+// -*- 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
+
+////////////////////////////////////////////////////////////////////
+//
+// Base class for MIPS instructions, and some support functions
+//
+
+//Outputs to decoder.hh
+output header {{
+
+ using namespace MipsISA;
+
+ /**
+ * Base class for all MIPS static instructions.
+ */
+ class MipsStaticInst : public StaticInst
+ {
+ protected:
+
+ // Constructor
+ MipsStaticInst(const char *mnem, MachInst _machInst, OpClass __opClass)
+ : StaticInst(mnem, _machInst, __opClass)
+ {
+ }
+
+ /// Print a register name for disassembly given the unique
+ /// dependence tag number (FP or int).
+ void printReg(std::ostream &os, int reg) const;
+
+ std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const;
+ };
+
+}};
+
+//Ouputs to decoder.cc
+output decoder {{
+
+ void MipsStaticInst::printReg(std::ostream &os, int reg) const
+ {
+ if (reg < FP_Base_DepTag) {
+ ccprintf(os, "r%d", reg);
+ }
+ else {
+ ccprintf(os, "f%d", reg - FP_Base_DepTag);
+ }
+ }
+
+ std::string MipsStaticInst::generateDisassembly(Addr pc, const SymbolTable *symtab) const
+ {
+ std::stringstream ss;
+
+ ccprintf(ss, "%-10s ", mnemonic);
+
+ // Need to find standard way to not print
+ // this info. Maybe add bool variable to
+ // class?
+ if (mnemonic != "syscall") {
+ if(_numDestRegs > 0){
+ printReg(ss, _destRegIdx[0]);
+ }
+
+ if(_numSrcRegs > 0) {
+ ss << ", ";
+ printReg(ss, _srcRegIdx[0]);
+ }
+
+ if(_numSrcRegs > 1) {
+ ss << ", ";
+ printReg(ss, _srcRegIdx[1]);
+ }
+ }
+
+ // Should we define a separate inst. class
+ // just for two insts?
+ if(mnemonic == "sll" || mnemonic == "sra"){
+ ccprintf(ss,", %d",SA);
+ }
+
+ return ss.str();
+ }
+
+}};
+
diff --git a/src/arch/mips/isa/bitfields.isa b/src/arch/mips/isa/bitfields.isa
new file mode 100644
index 000000000..35815bf1f
--- /dev/null
+++ b/src/arch/mips/isa/bitfields.isa
@@ -0,0 +1,102 @@
+// -*- 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
+
+////////////////////////////////////////////////////////////////////
+//
+// Bitfield definitions.
+//
+
+def bitfield OPCODE <31:26>;
+def bitfield OPCODE_HI <31:29>;
+def bitfield OPCODE_LO <28:26>;
+
+def bitfield REGIMM <20:16>;
+def bitfield REGIMM_HI <20:19>;
+def bitfield REGIMM_LO <18:16>;
+
+def bitfield FUNCTION < 5: 0>;
+def bitfield FUNCTION_HI < 5: 3>;
+def bitfield FUNCTION_LO < 2: 0>;
+
+def bitfield RS <25:21>;
+def bitfield RS_MSB <25:25>;
+def bitfield RS_HI <25:24>;
+def bitfield RS_LO <23:21>;
+def bitfield RS_SRL <25:22>;
+def bitfield RS_RT <25:16>;
+def bitfield RT <20:16>;
+def bitfield RT_HI <20:19>;
+def bitfield RT_LO <18:16>;
+def bitfield RT_RD <20:11>;
+def bitfield RD <15:11>;
+
+def bitfield INTIMM <15: 0>;
+
+// Floating-point operate format
+def bitfield FMT <25:21>;
+def bitfield FR <25:21>;
+def bitfield FT <20:16>;
+def bitfield FS <15:11>;
+def bitfield FD <10:6>;
+
+def bitfield ND <17:17>;
+def bitfield TF <16:16>;
+def bitfield MOVCI <16:16>;
+def bitfield MOVCF <16:16>;
+def bitfield SRL <21:21>;
+def bitfield SRLV < 6: 6>;
+def bitfield SA <10: 6>;
+
+// Floating Point Condition Codes
+def bitfield CC <10:8>;
+def bitfield BRANCH_CC <20:18>;
+
+// CP0 Register Select
+def bitfield SEL < 2: 0>;
+
+// Interrupts
+def bitfield SC < 5: 5>;
+
+// Branch format
+def bitfield OFFSET <15: 0>; // displacement
+
+// Jmp format
+def bitfield JMPTARG <25: 0>;
+def bitfield HINT <10: 6>;
+
+def bitfield SYSCALLCODE <25: 6>;
+def bitfield TRAPCODE <15:13>;
+
+// EXT/INS instructions
+def bitfield MSB <15:11>;
+def bitfield LSB <10: 6>;
+
+// M5 instructions
+def bitfield M5FUNC <7:0>;
diff --git a/src/arch/mips/isa/decoder.isa b/src/arch/mips/isa/decoder.isa
new file mode 100644
index 000000000..d65e3eb94
--- /dev/null
+++ b/src/arch/mips/isa/decoder.isa
@@ -0,0 +1,1102 @@
+// -*- 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
+
+////////////////////////////////////////////////////////////////////
+//
+// The actual MIPS32 ISA decoder
+// -----------------------------
+// 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)
+//
+decode OPCODE_HI default Unknown::unknown() {
+ //Table A-2
+ 0x0: decode OPCODE_LO {
+ 0x0: decode FUNCTION_HI {
+ 0x0: decode FUNCTION_LO {
+ 0x1: decode MOVCI {
+ format BasicOp {
+ 0: movf({{ Rd = (getCondCode(FCSR, CC) == 0) ? Rd : Rs; }});
+ 1: movt({{ Rd = (getCondCode(FCSR, CC) == 1) ? Rd : Rs; }});
+ }
+ }
+
+ format BasicOp {
+ //Table A-3 Note: "Specific encodings of the rd, rs, and
+ //rt fields are used to distinguish SLL, SSNOP, and EHB
+ //functions
+ 0x0: decode RS {
+ 0x0: decode RT_RD {
+ 0x0: decode SA default Nop::nop(){
+ 0x1: WarnUnimpl::ssnop();
+ 0x3: WarnUnimpl::ehb();
+ }
+ default: sll({{ Rd = Rt.uw << SA; }});
+ }
+ }
+
+ 0x2: decode RS_SRL {
+ 0x0:decode SRL {
+ 0: srl({{ Rd = Rt.uw >> SA; }});
+
+ //Hardcoded assuming 32-bit ISA, probably need parameter here
+ 1: rotr({{ Rd = (Rt.uw << (32 - SA)) | (Rt.uw >> SA);}});
+ }
+ }
+
+ 0x3: decode RS {
+ 0x0: sra({{
+ uint32_t temp = Rt >> SA;
+ if ( (Rt & 0x80000000) > 0 ) {
+ uint32_t mask = 0x80000000;
+ for(int i=0; i < SA; i++) {
+ temp |= mask;
+ mask = mask >> 1;
+ }
+ }
+ Rd = temp;
+ }});
+ }
+
+ 0x4: sllv({{ Rd = Rt.uw << Rs<4:0>; }});
+
+ 0x6: decode SRLV {
+ 0: srlv({{ Rd = Rt.uw >> Rs<4:0>; }});
+
+ //Hardcoded assuming 32-bit ISA, probably need parameter here
+ 1: rotrv({{ Rd = (Rt.uw << (32 - Rs<4:0>)) | (Rt.uw >> Rs<4:0>);}});
+ }
+
+ 0x7: srav({{
+ int shift_amt = Rs<4:0>;
+
+ uint32_t temp = Rt >> shift_amt;
+
+ if ( (Rt & 0x80000000) > 0 ) {
+ uint32_t mask = 0x80000000;
+ for(int i=0; i < shift_amt; i++) {
+ temp |= mask;
+ mask = mask >> 1;
+ }
+ }
+
+ Rd = temp;
+ }});
+ }
+ }
+
+ 0x1: decode FUNCTION_LO {
+ //Table A-3 Note: "Specific encodings of the hint field are
+ //used to distinguish JR from JR.HB and JALR from JALR.HB"
+ format Jump {
+ 0x0: decode HINT {
+ 0x1: jr_hb({{ NNPC = Rs & ~1; }}, IsReturn, ClearHazards);
+ default: jr({{ NNPC = Rs & ~1; }}, IsReturn);
+ }
+
+ 0x1: decode HINT {
+ 0x1: jalr_hb({{ Rd = NNPC; NNPC = Rs; }}, IsCall, Link
+ , ClearHazards);
+ default: jalr({{ Rd = NNPC; NNPC = Rs; }}, IsCall,
+ Link);
+ }
+ }
+
+ format BasicOp {
+ 0x2: movz({{ Rd = (Rt == 0) ? Rs : Rd; }});
+ 0x3: movn({{ Rd = (Rt != 0) ? Rs : Rd; }});
+ 0x4: syscall({{ xc->syscall(R2); }},
+ IsSerializeAfter, IsNonSpeculative);
+ 0x7: sync({{ ; }}, IsMemBarrier);
+ }
+
+ format FailUnimpl {
+ 0x5: break();
+ }
+ }
+
+ 0x2: decode FUNCTION_LO {
+ format HiLoMiscOp {
+ 0x0: mfhi({{ Rd = HI; }});
+ 0x1: mthi({{ HI = Rs; }});
+ 0x2: mflo({{ Rd = LO; }});
+ 0x3: mtlo({{ LO = Rs; }});
+ }
+ }
+
+ 0x3: decode FUNCTION_LO {
+ format HiLoOp {
+ 0x0: mult({{ val = Rs.sd * Rt.sd; }});
+ 0x1: multu({{ val = Rs.ud * Rt.ud; }});
+ }
+
+ format HiLoMiscOp {
+ 0x2: div({{ if (Rt.sd != 0) {
+ HI = Rs.sd % Rt.sd;
+ LO = Rs.sd / Rt.sd;
+ }
+ }});
+ 0x3: divu({{ if (Rt.ud != 0) {
+ HI = Rs.ud % Rt.ud;
+ LO = Rs.ud / Rt.ud;
+ }
+ }});
+ }
+ }
+
+ 0x4: decode HINT {
+ 0x0: decode FUNCTION_LO {
+ format IntOp {
+ 0x0: add({{ Rd.sw = Rs.sw + Rt.sw; /*Trap on Overflow*/}});
+ 0x1: addu({{ Rd.sw = Rs.sw + Rt.sw;}});
+ 0x2: sub({{ Rd.sw = Rs.sw - Rt.sw; /*Trap on Overflow*/}});
+ 0x3: subu({{ Rd.sw = Rs.sw - Rt.sw;}});
+ 0x4: and({{ Rd = Rs & Rt;}});
+ 0x5: or({{ Rd = Rs | Rt;}});
+ 0x6: xor({{ Rd = Rs ^ Rt;}});
+ 0x7: nor({{ Rd = ~(Rs | Rt);}});
+ }
+ }
+ }
+
+ 0x5: decode HINT {
+ 0x0: decode FUNCTION_LO {
+ format IntOp{
+ 0x2: slt({{ Rd.sw = ( Rs.sw < Rt.sw ) ? 1 : 0}});
+ 0x3: sltu({{ Rd.uw = ( Rs.uw < Rt.uw ) ? 1 : 0}});
+ }
+ }
+ }
+
+ 0x6: decode FUNCTION_LO {
+ format Trap {
+ 0x0: tge({{ cond = (Rs.sw >= Rt.sw); }});
+ 0x1: tgeu({{ cond = (Rs.uw >= Rt.uw); }});
+ 0x2: tlt({{ cond = (Rs.sw < Rt.sw); }});
+ 0x3: tltu({{ cond = (Rs.uw >= Rt.uw); }});
+ 0x4: teq({{ cond = (Rs.sw == Rt.sw); }});
+ 0x6: tne({{ cond = (Rs.sw != Rt.sw); }});
+ }
+ }
+ }
+
+ 0x1: decode REGIMM_HI {
+ 0x0: decode REGIMM_LO {
+ format Branch {
+ 0x0: bltz({{ cond = (Rs.sw < 0); }});
+ 0x1: bgez({{ cond = (Rs.sw >= 0); }});
+ 0x2: bltzl({{ cond = (Rs.sw < 0); }}, Likely);
+ 0x3: bgezl({{ cond = (Rs.sw >= 0); }}, Likely);
+ }
+ }
+
+ 0x1: decode REGIMM_LO {
+ format Trap {
+ 0x0: tgei( {{ cond = (Rs.sw >= INTIMM); }});
+ 0x1: tgeiu({{ cond = (Rs.uw >= INTIMM); }});
+ 0x2: tlti( {{ cond = (Rs.sw < INTIMM); }});
+ 0x3: tltiu({{ cond = (Rs.uw < INTIMM); }});
+ 0x4: teqi( {{ cond = (Rs.sw == INTIMM);}});
+ 0x6: tnei( {{ cond = (Rs.sw != INTIMM);}});
+ }
+ }
+
+ 0x2: decode REGIMM_LO {
+ format Branch {
+ 0x0: bltzal({{ cond = (Rs.sw < 0); }}, Link);
+ 0x1: decode RS {
+ 0x0: bal ({{ cond = 1; }}, IsCall, Link);
+ default: bgezal({{ cond = (Rs.sw >= 0); }}, Link);
+ }
+ 0x2: bltzall({{ cond = (Rs.sw < 0); }}, Link, Likely);
+ 0x3: bgezall({{ cond = (Rs.sw >= 0); }}, Link, Likely);
+ }
+ }
+
+ 0x3: decode REGIMM_LO {
+ format WarnUnimpl {
+ 0x7: synci();
+ }
+ }
+ }
+
+ format Jump {
+ 0x2: j({{ NNPC = (NPC & 0xF0000000) | (JMPTARG << 2);}});
+ 0x3: jal({{ NNPC = (NPC & 0xF0000000) | (JMPTARG << 2); }}, IsCall,
+ Link);
+ }
+
+ format Branch {
+ 0x4: decode RS_RT {
+ 0x0: b({{ cond = 1; }});
+ default: beq({{ cond = (Rs.sw == Rt.sw); }});
+ }
+ 0x5: bne({{ cond = (Rs.sw != Rt.sw); }});
+ 0x6: blez({{ cond = (Rs.sw <= 0); }});
+ 0x7: bgtz({{ cond = (Rs.sw > 0); }});
+ }
+ }
+
+ 0x1: decode OPCODE_LO {
+ format IntImmOp {
+ 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 }});
+ 0x4: andi({{ Rt.sw = Rs.sw & zextImm;}});
+ 0x5: ori({{ Rt.sw = Rs.sw | zextImm;}});
+ 0x6: xori({{ Rt.sw = Rs.sw ^ zextImm;}});
+
+ 0x7: decode RS {
+ 0x0: lui({{ Rt = imm << 16}});
+ }
+ }
+ }
+
+ 0x2: decode OPCODE_LO {
+ //Table A-11 MIPS32 COP0 Encoding of rs Field
+ 0x0: decode RS_MSB {
+ 0x0: decode RS {
+ format CP0Control {
+ 0x0: mfc0({{ Rt = xc->readMiscReg(RD << 5 | SEL); }});
+ 0x4: mtc0({{ xc->setMiscReg(RD << 5 | 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 FailUnimpl {
+ 0xA: rdpgpr();
+ 0xE: wrpgpr();
+ }
+ }
+
+ //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();
+
+ 0x18: eret();
+ 0x1F: deret();
+ 0x20: wait();
+ }
+ }
+ }
+
+ //Table A-13 MIPS32 COP1 Encoding of rs Field
+ 0x1: decode RS_MSB {
+
+ 0x0: decode RS_HI {
+ 0x0: decode RS_LO {
+ format CP1Control {
+ 0x0: mfc1 ({{ Rt.uw = Fs.uw; }});
+
+ 0x2: cfc1({{
+ switch (FS)
+ {
+ case 0:
+ Rt = FIR;
+ break;
+ case 25:
+ Rt = 0 | (FCSR & 0xFE000000) >> 24 | (FCSR & 0x00800000) >> 23;
+ break;
+ case 26:
+ Rt = 0 | (FCSR & 0x0003F07C);
+ break;
+ case 28:
+ Rt = 0 | (FCSR & 0x00000F80) | (FCSR & 0x01000000) >> 21 | (FCSR & 0x00000003);
+ break;
+ case 31:
+ Rt = FCSR;
+ break;
+ default:
+ panic("FP Control Value (%d) Not Valid");
+ }
+ }});
+
+ 0x3: mfhc1({{ Rt.uw = Fs.ud<63:32>;}});
+
+ 0x4: mtc1 ({{ Fs.uw = Rt.uw; }});
+
+ 0x6: ctc1({{
+ switch (FS)
+ {
+ case 25:
+ FCSR = 0 | (Rt.uw<7:1> << 25) // move 31...25
+ | (FCSR & 0x01000000) // bit 24
+ | (FCSR & 0x004FFFFF);// bit 22...0
+ break;
+
+ case 26:
+ FCSR = 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:
+ FCSR = 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:
+ FCSR = Rt.uw;
+ break;
+
+ default:
+ panic("FP Control Value (%d) Not Available. Ignoring Access to"
+ "Floating Control Status Register", FS);
+ }
+ }});
+
+ 0x7: mthc1({{
+ uint64_t fs_hi = Rt.uw;
+ uint64_t fs_lo = Fs.ud & 0x0FFFFFFFF;
+ Fs.ud = (fs_hi << 32) | fs_lo;
+ }});
+
+ }
+ }
+
+ 0x1: decode ND {
+ format Branch {
+ 0x0: decode TF {
+ 0x0: bc1f({{ cond = getCondCode(FCSR, BRANCH_CC) == 0;
+ }});
+ 0x1: bc1t({{ cond = getCondCode(FCSR, BRANCH_CC) == 1;
+ }});
+ }
+ 0x1: decode TF {
+ 0x0: bc1fl({{ cond = getCondCode(FCSR, BRANCH_CC) == 0;
+ }}, Likely);
+ 0x1: bc1tl({{ cond = getCondCode(FCSR, BRANCH_CC) == 1;
+ }}, Likely);
+ }
+ }
+ }
+ }
+
+ 0x1: decode RS_HI {
+ 0x2: decode RS_LO {
+ //Table A-14 MIPS32 COP1 Encoding of Function Field When rs=S
+ //(( single-precision floating point))
+ 0x0: decode FUNCTION_HI {
+ 0x0: decode FUNCTION_LO {
+ format FloatOp {
+ 0x0: add_s({{ Fd.sf = Fs.sf + Ft.sf;}});
+ 0x1: sub_s({{ Fd.sf = Fs.sf - Ft.sf;}});
+ 0x2: mul_s({{ Fd.sf = Fs.sf * Ft.sf;}});
+ 0x3: div_s({{ Fd.sf = Fs.sf / Ft.sf;}});
+ 0x4: sqrt_s({{ Fd.sf = sqrt(Fs.sf);}});
+ 0x5: abs_s({{ Fd.sf = fabs(Fs.sf);}});
+ 0x7: neg_s({{ Fd.sf = -Fs.sf;}});
+ }
+
+ 0x6: BasicOp::mov_s({{ Fd.sf = Fs.sf;}});
+ }
+
+ 0x1: decode FUNCTION_LO {
+ format FloatConvertOp {
+ 0x0: round_l_s({{ val = Fs.sf; }}, ToLong,
+ Round);
+ 0x1: trunc_l_s({{ val = Fs.sf; }}, ToLong,
+ Trunc);
+ 0x2: ceil_l_s({{ val = Fs.sf; }}, ToLong,
+ Ceil);
+ 0x3: floor_l_s({{ val = Fs.sf; }}, ToLong,
+ Floor);
+ 0x4: round_w_s({{ val = Fs.sf; }}, ToWord,
+ Round);
+ 0x5: trunc_w_s({{ val = Fs.sf; }}, ToWord,
+ Trunc);
+ 0x6: ceil_w_s({{ val = Fs.sf; }}, ToWord,
+ Ceil);
+ 0x7: floor_w_s({{ val = Fs.sf; }}, ToWord,
+ Floor);
+ }
+ }
+
+ 0x2: decode FUNCTION_LO {
+ 0x1: decode MOVCF {
+ format BasicOp {
+ 0x0: movf_s({{ Fd = (getCondCode(FCSR,CC) == 0) ? Fs : Fd; }});
+ 0x1: movt_s({{ Fd = (getCondCode(FCSR,CC) == 1) ? Fs : Fd; }});
+ }
+ }
+
+ format BasicOp {
+ 0x2: movz_s({{ Fd = (Rt == 0) ? Fs : Fd; }});
+ 0x3: movn_s({{ Fd = (Rt != 0) ? Fs : Fd; }});
+ }
+
+ format FloatOp {
+ 0x5: recip_s({{ Fd = 1 / Fs; }});
+ 0x6: rsqrt_s({{ Fd = 1 / sqrt(Fs);}});
+ }
+ }
+
+ 0x4: decode FUNCTION_LO {
+ format FloatConvertOp {
+ 0x1: cvt_d_s({{ val = Fs.sf; }}, ToDouble);
+ 0x4: cvt_w_s({{ val = Fs.sf; }}, ToWord);
+ 0x5: cvt_l_s({{ val = Fs.sf; }}, ToLong);
+ }
+
+ 0x6: FloatOp::cvt_ps_s({{
+ Fd.ud = (uint64_t) Fs.uw << 32 |
+ (uint64_t) Ft.uw;
+ }});
+ }
+
+ 0x6: decode FUNCTION_LO {
+ format FloatCompareOp {
+ 0x0: c_f_s({{ cond = 0; }}, SinglePrecision,
+ UnorderedFalse);
+ 0x1: c_un_s({{ cond = 0; }}, SinglePrecision,
+ UnorderedTrue);
+ 0x2: c_eq_s({{ cond = (Fs.sf == Ft.sf); }},
+ UnorderedFalse);
+ 0x3: c_ueq_s({{ cond = (Fs.sf == Ft.sf); }},
+ UnorderedTrue);
+ 0x4: c_olt_s({{ cond = (Fs.sf < Ft.sf); }},
+ UnorderedFalse);
+ 0x5: c_ult_s({{ cond = (Fs.sf < Ft.sf); }},
+ UnorderedTrue);
+ 0x6: c_ole_s({{ cond = (Fs.sf <= Ft.sf); }},
+ UnorderedFalse);
+ 0x7: c_ule_s({{ cond = (Fs.sf <= Ft.sf); }},
+ UnorderedTrue);
+ }
+ }
+
+ 0x7: decode FUNCTION_LO {
+ format FloatCompareOp {
+ 0x0: c_sf_s({{ cond = 0; }}, SinglePrecision,
+ UnorderedFalse, QnanException);
+ 0x1: c_ngle_s({{ cond = 0; }}, SinglePrecision,
+ UnorderedTrue, QnanException);
+ 0x2: c_seq_s({{ cond = (Fs.sf == Ft.sf);}},
+ UnorderedFalse, QnanException);
+ 0x3: c_ngl_s({{ cond = (Fs.sf == Ft.sf); }},
+ UnorderedTrue, QnanException);
+ 0x4: c_lt_s({{ cond = (Fs.sf < Ft.sf); }},
+ UnorderedFalse, QnanException);
+ 0x5: c_nge_s({{ cond = (Fs.sf < Ft.sf); }},
+ UnorderedTrue, QnanException);
+ 0x6: c_le_s({{ cond = (Fs.sf <= Ft.sf); }},
+ UnorderedFalse, QnanException);
+ 0x7: c_ngt_s({{ cond = (Fs.sf <= Ft.sf); }},
+ UnorderedTrue, QnanException);
+ }
+ }
+ }
+
+ //Table A-15 MIPS32 COP1 Encoding of Function Field When rs=D
+ 0x1: decode FUNCTION_HI {
+ 0x0: decode FUNCTION_LO {
+ format FloatOp {
+ 0x0: add_d({{ Fd.df = Fs.df + Ft.df; }});
+ 0x1: sub_d({{ Fd.df = Fs.df - Ft.df; }});
+ 0x2: mul_d({{ Fd.df = Fs.df * Ft.df; }});
+ 0x3: div_d({{ Fd.df = Fs.df / Ft.df; }});
+ 0x4: sqrt_d({{ Fd.df = sqrt(Fs.df); }});
+ 0x5: abs_d({{ Fd.df = fabs(Fs.df); }});
+ 0x7: neg_d({{ Fd.df = -1 * Fs.df; }});
+ }
+
+ 0x6: BasicOp::mov_d({{ Fd.df = Fs.df; }});
+ }
+
+ 0x1: decode FUNCTION_LO {
+ format FloatConvertOp {
+ 0x0: round_l_d({{ val = Fs.df; }}, ToLong,
+ Round);
+ 0x1: trunc_l_d({{ val = Fs.df; }}, ToLong,
+ Trunc);
+ 0x2: ceil_l_d({{ val = Fs.df; }}, ToLong,
+ Ceil);
+ 0x3: floor_l_d({{ val = Fs.df; }}, ToLong,
+ Floor);
+ 0x4: round_w_d({{ val = Fs.df; }}, ToWord,
+ Round);
+ 0x5: trunc_w_d({{ val = Fs.df; }}, ToWord,
+ Trunc);
+ 0x6: ceil_w_d({{ val = Fs.df; }}, ToWord,
+ Ceil);
+ 0x7: floor_w_d({{ val = Fs.df; }}, ToWord,
+ Floor);
+ }
+ }
+
+ 0x2: decode FUNCTION_LO {
+ 0x1: decode MOVCF {
+ format BasicOp {
+ 0x0: movf_d({{ Fd.df = (getCondCode(FCSR,CC) == 0) ?
+ Fs.df : Fd.df;
+ }});
+ 0x1: movt_d({{ Fd.df = (getCondCode(FCSR,CC) == 1) ?
+ Fs.df : Fd.df;
+ }});
+ }
+ }
+
+ format BasicOp {
+ 0x2: movz_d({{ Fd.df = (Rt == 0) ? Fs.df : Fd.df; }});
+ 0x3: movn_d({{ Fd.df = (Rt != 0) ? Fs.df : Fd.df; }});
+ }
+
+ format FloatOp {
+ 0x5: recip_d({{ Fd.df = 1 / Fs.df }});
+ 0x6: rsqrt_d({{ Fd.df = 1 / sqrt(Fs.df) }});
+ }
+ }
+
+ 0x4: decode FUNCTION_LO {
+ format FloatConvertOp {
+ 0x0: cvt_s_d({{ val = Fs.df; }}, ToSingle);
+ 0x4: cvt_w_d({{ val = Fs.df; }}, ToWord);
+ 0x5: cvt_l_d({{ val = Fs.df; }}, ToLong);
+ }
+ }
+
+ 0x6: decode FUNCTION_LO {
+ format FloatCompareOp {
+ 0x0: c_f_d({{ cond = 0; }}, DoublePrecision,
+ UnorderedFalse);
+ 0x1: c_un_d({{ cond = 0; }}, DoublePrecision,
+ UnorderedTrue);
+ 0x2: c_eq_d({{ cond = (Fs.df == Ft.df); }},
+ UnorderedFalse);
+ 0x3: c_ueq_d({{ cond = (Fs.df == Ft.df); }},
+ UnorderedTrue);
+ 0x4: c_olt_d({{ cond = (Fs.df < Ft.df); }},
+ UnorderedFalse);
+ 0x5: c_ult_d({{ cond = (Fs.df < Ft.df); }},
+ UnorderedTrue);
+ 0x6: c_ole_d({{ cond = (Fs.df <= Ft.df); }},
+ UnorderedFalse);
+ 0x7: c_ule_d({{ cond = (Fs.df <= Ft.df); }},
+ UnorderedTrue);
+ }
+ }
+
+ 0x7: decode FUNCTION_LO {
+ format FloatCompareOp {
+ 0x0: c_sf_d({{ cond = 0; }}, DoublePrecision,
+ UnorderedFalse, QnanException);
+ 0x1: c_ngle_d({{ cond = 0; }}, DoublePrecision,
+ UnorderedTrue, QnanException);
+ 0x2: c_seq_d({{ cond = (Fs.df == Ft.df); }},
+ UnorderedFalse, QnanException);
+ 0x3: c_ngl_d({{ cond = (Fs.df == Ft.df); }},
+ UnorderedTrue, QnanException);
+ 0x4: c_lt_d({{ cond = (Fs.df < Ft.df); }},
+ UnorderedFalse, QnanException);
+ 0x5: c_nge_d({{ cond = (Fs.df < Ft.df); }},
+ UnorderedTrue, QnanException);
+ 0x6: c_le_d({{ cond = (Fs.df <= Ft.df); }},
+ UnorderedFalse, QnanException);
+ 0x7: c_ngt_d({{ cond = (Fs.df <= Ft.df); }},
+ UnorderedTrue, QnanException);
+ }
+ }
+ }
+
+ //Table A-16 MIPS32 COP1 Encoding of Function Field When rs=W
+ 0x4: decode FUNCTION {
+ format FloatConvertOp {
+ 0x20: cvt_s_w({{ val = Fs.uw; }}, ToSingle);
+ 0x21: cvt_d_w({{ val = Fs.uw; }}, ToDouble);
+ 0x26: FailUnimpl::cvt_ps_w();
+ }
+ }
+
+ //Table A-16 MIPS32 COP1 Encoding of Function Field When rs=L1
+ //Note: "1. Format type L is legal only if 64-bit floating point operations
+ //are enabled."
+ 0x5: decode FUNCTION_HI {
+ format FloatConvertOp {
+ 0x20: cvt_s_l({{ val = Fs.ud; }}, ToSingle);
+ 0x21: cvt_d_l({{ val = Fs.ud; }}, ToDouble);
+ 0x26: FailUnimpl::cvt_ps_l();
+ }
+ }
+
+ //Table A-17 MIPS64 COP1 Encoding of Function Field When rs=PS1
+ //Note: "1. Format type PS is legal only if 64-bit floating point operations
+ //are enabled. "
+ 0x6: decode FUNCTION_HI {
+ 0x0: decode FUNCTION_LO {
+ format Float64Op {
+ 0x0: add_ps({{
+ Fd1.sf = Fs1.sf + Ft2.sf;
+ Fd2.sf = Fs2.sf + Ft2.sf;
+ }});
+ 0x1: sub_ps({{
+ Fd1.sf = Fs1.sf - Ft2.sf;
+ Fd2.sf = Fs2.sf - Ft2.sf;
+ }});
+ 0x2: mul_ps({{
+ Fd1.sf = Fs1.sf * Ft2.sf;
+ Fd2.sf = Fs2.sf * Ft2.sf;
+ }});
+ 0x5: abs_ps({{
+ Fd1.sf = fabs(Fs1.sf);
+ Fd2.sf = fabs(Fs2.sf);
+ }});
+ 0x6: mov_ps({{
+ Fd1.sf = Fs1.sf;
+ Fd2.sf = Fs2.sf;
+ }});
+ 0x7: neg_ps({{
+ Fd1.sf = -(Fs1.sf);
+ Fd2.sf = -(Fs2.sf);
+ }});
+ }
+ }
+
+ 0x2: decode FUNCTION_LO {
+ 0x1: decode MOVCF {
+ format Float64Op {
+ 0x0: movf_ps({{
+ Fd1 = (getCondCode(FCSR, CC) == 0) ?
+ Fs1 : Fd1;
+ Fd2 = (getCondCode(FCSR, CC+1) == 0) ?
+ Fs2 : Fd2;
+ }});
+ 0x1: movt_ps({{
+ Fd2 = (getCondCode(FCSR, CC) == 1) ?
+ Fs1 : Fd1;
+ Fd2 = (getCondCode(FCSR, CC+1) == 1) ?
+ Fs2 : Fd2;
+ }});
+ }
+ }
+
+ format Float64Op {
+ 0x2: movz_ps({{
+ Fd1 = (getCondCode(FCSR, CC) == 0) ?
+ Fs1 : Fd1;
+ Fd2 = (getCondCode(FCSR, CC) == 0) ?
+ Fs2 : Fd2;
+ }});
+ 0x3: movn_ps({{
+ Fd1 = (getCondCode(FCSR, CC) == 1) ?
+ Fs1 : Fd1;
+ Fd2 = (getCondCode(FCSR, CC) == 1) ?
+ Fs2 : Fd2;
+ }});
+ }
+
+ }
+
+ 0x4: decode FUNCTION_LO {
+ 0x0: FloatOp::cvt_s_pu({{ Fd.sf = Fs2.sf; }});
+ }
+
+ 0x5: decode FUNCTION_LO {
+ 0x0: FloatOp::cvt_s_pl({{ Fd.sf = Fs1.sf; }});
+
+ format Float64Op {
+ 0x4: pll({{ Fd.ud = (uint64_t) Fs1.uw << 32 |
+ Ft1.uw;
+ }});
+ 0x5: plu({{ Fd.ud = (uint64_t) Fs1.uw << 32 |
+ Ft2.uw;
+ }});
+ 0x6: pul({{ Fd.ud = (uint64_t) Fs2.uw << 32 |
+ Ft1.uw;
+ }});
+ 0x7: puu({{ Fd.ud = (uint64_t) Fs2.uw << 32 |
+ Ft2.uw;
+ }});
+ }
+ }
+
+ 0x6: decode FUNCTION_LO {
+ format FloatPSCompareOp {
+ 0x0: c_f_ps({{ cond1 = 0; }}, {{ cond2 = 0; }},
+ UnorderedFalse);
+ 0x1: c_un_ps({{ cond1 = 0; }}, {{ cond2 = 0; }},
+ UnorderedTrue);
+ 0x2: c_eq_ps({{ cond1 = (Fs1.sf == Ft1.sf); }},
+ {{ cond2 = (Fs2.sf == Ft2.sf); }},
+ UnorderedFalse);
+ 0x3: c_ueq_ps({{ cond1 = (Fs1.sf == Ft1.sf); }},
+ {{ cond2 = (Fs2.sf == Ft2.sf); }},
+ UnorderedTrue);
+ 0x4: c_olt_ps({{ cond1 = (Fs1.sf < Ft1.sf); }},
+ {{ cond2 = (Fs2.sf < Ft2.sf); }},
+ UnorderedFalse);
+ 0x5: c_ult_ps({{ cond1 = (Fs.sf < Ft.sf); }},
+ {{ cond2 = (Fs2.sf < Ft2.sf); }},
+ UnorderedTrue);
+ 0x6: c_ole_ps({{ cond1 = (Fs.sf <= Ft.sf); }},
+ {{ cond2 = (Fs2.sf <= Ft2.sf); }},
+ UnorderedFalse);
+ 0x7: c_ule_ps({{ cond1 = (Fs1.sf <= Ft1.sf); }},
+ {{ cond2 = (Fs2.sf <= Ft2.sf); }},
+ UnorderedTrue);
+ }
+ }
+
+ 0x7: decode FUNCTION_LO {
+ format FloatPSCompareOp {
+ 0x0: c_sf_ps({{ cond1 = 0; }}, {{ cond2 = 0; }},
+ UnorderedFalse, QnanException);
+ 0x1: c_ngle_ps({{ cond1 = 0; }},
+ {{ cond2 = 0; }},
+ UnorderedTrue, QnanException);
+ 0x2: c_seq_ps({{ cond1 = (Fs1.sf == Ft1.sf); }},
+ {{ cond2 = (Fs2.sf == Ft2.sf); }},
+ UnorderedFalse, QnanException);
+ 0x3: c_ngl_ps({{ cond1 = (Fs1.sf == Ft1.sf); }},
+ {{ cond2 = (Fs2.sf == Ft2.sf); }},
+ UnorderedTrue, QnanException);
+ 0x4: c_lt_ps({{ cond1 = (Fs1.sf < Ft1.sf); }},
+ {{ cond2 = (Fs2.sf < Ft2.sf); }},
+ UnorderedFalse, QnanException);
+ 0x5: c_nge_ps({{ cond1 = (Fs1.sf < Ft1.sf); }},
+ {{ cond2 = (Fs2.sf < Ft2.sf); }},
+ UnorderedTrue, QnanException);
+ 0x6: c_le_ps({{ cond1 = (Fs1.sf <= Ft1.sf); }},
+ {{ cond2 = (Fs2.sf <= Ft2.sf); }},
+ UnorderedFalse, QnanException);
+ 0x7: c_ngt_ps({{ cond1 = (Fs1.sf <= Ft1.sf); }},
+ {{ cond2 = (Fs2.sf <= Ft2.sf); }},
+ UnorderedTrue, QnanException);
+ }
+ }
+ }
+ }
+ }
+ }
+
+ //Table A-19 MIPS32 COP2 Encoding of rs Field
+ 0x2: decode RS_MSB {
+ format FailUnimpl {
+ 0x0: decode RS_HI {
+ 0x0: decode RS_LO {
+ 0x0: mfc2();
+ 0x2: cfc2();
+ 0x3: mfhc2();
+ 0x4: mtc2();
+ 0x6: ctc2();
+ 0x7: mftc2();
+ }
+
+ 0x1: decode ND {
+ 0x0: decode TF {
+ 0x0: bc2f();
+ 0x1: bc2t();
+ }
+
+ 0x1: decode TF {
+ 0x0: bc2fl();
+ 0x1: bc2tl();
+ }
+ }
+ }
+ }
+ }
+
+ //Table A-20 MIPS64 COP1X Encoding of Function Field 1
+ //Note: "COP1X instructions are legal only if 64-bit floating point
+ //operations are enabled."
+ 0x3: decode FUNCTION_HI {
+ 0x0: decode FUNCTION_LO {
+ format LoadIndexedMemory {
+ 0x0: lwxc1({{ Fd.uw = Mem.uw;}});
+ 0x1: ldxc1({{ Fd.ud = Mem.ud;}});
+ 0x5: luxc1({{ Fd.ud = Mem.ud;}},
+ {{ EA = (Rs + Rt) & ~7; }});
+ }
+ }
+
+ 0x1: decode FUNCTION_LO {
+ format StoreIndexedMemory {
+ 0x0: swxc1({{ Mem.uw = Fs.uw;}});
+ 0x1: sdxc1({{ Mem.ud = Fs.ud;}});
+ 0x5: suxc1({{ Mem.ud = Fs.ud;}},
+ {{ EA = (Rs + Rt) & ~7; }});
+ }
+
+ 0x7: Prefetch::prefx({{ EA = Rs + Rt; }});
+ }
+
+ 0x3: decode FUNCTION_LO {
+ 0x6: Float64Op::alnv_ps({{ if (Rs<2:0> == 0) {
+ Fd.ud = Fs.ud;
+ } else if (Rs<2:0> == 4) {
+ #if BYTE_ORDER == BIG_ENDIAN
+ Fd.ud = Fs.ud<31:0> << 32 |
+ Ft.ud<63:32>;
+ #elif BYTE_ORDER == LITTLE_ENDIAN
+ Fd.ud = Ft.ud<31:0> << 32 |
+ Fs.ud<63:32>;
+ #endif
+ } else {
+ Fd.ud = Fd.ud;
+ }
+ }});
+ }
+
+ format FloatAccOp {
+ 0x4: decode FUNCTION_LO {
+ 0x0: madd_s({{ Fd.sf = (Fs.sf * Ft.sf) + Fr.sf; }});
+ 0x1: madd_d({{ Fd.df = (Fs.df * Ft.df) + Fr.df; }});
+ 0x6: madd_ps({{
+ Fd1.sf = (Fs1.df * Ft1.df) + Fr1.df;
+ Fd2.sf = (Fs2.df * Ft2.df) + Fr2.df;
+ }});
+ }
+
+ 0x5: decode FUNCTION_LO {
+ 0x0: msub_s({{ Fd.sf = (Fs.sf * Ft.sf) - Fr.sf; }});
+ 0x1: msub_d({{ Fd.df = (Fs.df * Ft.df) - Fr.df; }});
+ 0x6: msub_ps({{
+ Fd1.sf = (Fs1.df * Ft1.df) - Fr1.df;
+ Fd2.sf = (Fs2.df * Ft2.df) - Fr2.df;
+ }});
+ }
+
+ 0x6: decode FUNCTION_LO {
+ 0x0: nmadd_s({{ Fd.sf = (-1 * Fs.sf * Ft.sf) - Fr.sf; }});
+ 0x1: nmadd_d({{ Fd.df = (-1 * Fs.df * Ft.df) + Fr.df; }});
+ 0x6: nmadd_ps({{
+ Fd1.sf = -((Fs1.df * Ft1.df) + Fr1.df);
+ Fd2.sf = -((Fs2.df * Ft2.df) + Fr2.df);
+ }});
+ }
+
+ 0x7: decode FUNCTION_LO {
+ 0x0: nmsub_s({{ Fd.sf = (-1 * Fs.sf * Ft.sf) - Fr.sf; }});
+ 0x1: nmsub_d({{ Fd.df = (-1 * Fs.df * Ft.df) - Fr.df; }});
+ 0x6: nmsub_ps({{
+ Fd1.sf = -((Fs1.df * Ft1.df) - Fr1.df);
+ Fd2.sf = -((Fs2.df * Ft2.df) - Fr2.df);
+ }});
+ }
+
+ }
+ }
+
+ format Branch {
+ 0x4: beql({{ cond = (Rs.sw == Rt.sw); }}, Likely);
+ 0x5: bnel({{ cond = (Rs.sw != Rt.sw); }}, Likely);
+ 0x6: blezl({{ cond = (Rs.sw <= 0); }}, Likely);
+ 0x7: bgtzl({{ cond = (Rs.sw > 0); }}, Likely);
+ }
+ }
+
+ 0x3: decode OPCODE_LO {
+ //Table A-5 MIPS32 SPECIAL2 Encoding of Function Field
+ 0x4: decode FUNCTION_HI {
+ 0x0: decode FUNCTION_LO {
+ 0x2: IntOp::mul({{ int64_t temp1 = Rs.sd * Rt.sd;
+ Rd.sw = temp1<31:0>
+ }});
+
+ format HiLoOp {
+ 0x0: madd({{ val = ((int64_t) HI << 32 | LO) +
+ (Rs.sd * Rt.sd);
+ }});
+ 0x1: maddu({{ val = ((uint64_t) HI << 32 | LO) +
+ (Rs.ud * Rt.ud);
+ }});
+ 0x4: msub({{ val = ((int64_t) HI << 32 | LO) -
+ (Rs.sd * Rt.sd);
+ }});
+ 0x5: msubu({{ val = ((uint64_t) HI << 32 | LO) -
+ (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;
+ }});
+ 0x1: clo({{ int cnt = 32;
+ for (int idx = 31; idx >= 0; idx--) {
+ if( Rs<idx:idx> == 0) {
+ cnt = 31 - idx;
+ break;
+ }
+ }
+ Rd.uw = cnt;
+ }});
+ }
+ }
+
+ 0x7: decode FUNCTION_LO {
+ 0x7: FailUnimpl::sdbbp();
+ }
+ }
+
+ //Table A-6 MIPS32 SPECIAL3 Encoding of Function Field for Release 2
+ //of the Architecture
+ 0x7: decode FUNCTION_HI {
+ 0x0: decode FUNCTION_LO {
+ format BasicOp {
+ 0x0: ext({{ Rt.uw = bits(Rs.uw, MSB+LSB, LSB); }});
+ 0x4: ins({{ Rt.uw = bits(Rt.uw, 31, MSB+1) << (MSB+1) |
+ bits(Rs.uw, MSB-LSB, 0) << LSB |
+ bits(Rt.uw, LSB-1, 0);
+ }});
+ }
+ }
+
+ 0x1: decode FUNCTION_LO {
+ format MipsMT {
+ 0x0: fork();
+ 0x1: yield();
+ }
+ }
+
+ //Table A-10 MIPS32 BSHFL Encoding of sa Field
+ 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>;
+ }});
+ 0x10: seb({{ Rd.sw = Rt.sb; }});
+ 0x18: seh({{ Rd.sw = Rt.sh; }});
+ }
+ }
+
+ 0x6: decode FUNCTION_LO {
+ 0x7: FailUnimpl::rdhwr();
+ }
+ }
+ }
+
+ 0x4: decode OPCODE_LO {
+ format LoadMemory {
+ 0x0: lb({{ Rt.sw = Mem.sb; }});
+ 0x1: lh({{ Rt.sw = Mem.sh; }});
+ 0x3: lw({{ Rt.sw = Mem.sw; }});
+ 0x4: lbu({{ Rt.uw = Mem.ub; }});
+ 0x5: lhu({{ Rt.uw = Mem.uh; }});
+ }
+
+ format LoadUnalignedMemory {
+ 0x2: lwl({{ uint32_t mem_shift = 24 - (8 * byte_offset);
+ Rt.uw = mem_word << 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;
+ }});
+ }
+ }
+
+ 0x5: decode OPCODE_LO {
+ format StoreMemory {
+ 0x0: sb({{ Mem.ub = Rt<7:0>; }});
+ 0x1: sh({{ Mem.uh = Rt<15:0>; }});
+ 0x3: sw({{ Mem.uw = Rt<31:0>; }});
+ }
+
+ format StoreUnalignedMemory {
+ 0x2: swl({{ uint32_t reg_shift = 24 - (8 * byte_offset);
+ uint32_t mem_shift = 32 - reg_shift;
+ mem_word = mem_word & (mask(reg_shift) << mem_shift) |
+ Rt.uw >> reg_shift;
+ }});
+ 0x6: swr({{ uint32_t reg_shift = 8 * byte_offset;
+ mem_word = Rt.uw << reg_shift |
+ mem_word & (mask(reg_shift));
+ }});
+ }
+
+ 0x7: FailUnimpl::cache();
+ }
+
+ 0x6: decode OPCODE_LO {
+ format LoadMemory {
+ 0x0: ll({{ Rt.uw = Mem.uw; }}, mem_flags=LOCKED);
+ 0x1: lwc1({{ Ft.uw = Mem.uw; }});
+ 0x5: ldc1({{ Ft.ud = Mem.ud; }});
+ }
+
+ 0x3: Prefetch::pref();
+ }
+
+
+ 0x7: decode OPCODE_LO {
+ 0x0: StoreCond::sc({{ Mem.uw = Rt.uw;}},
+ {{ uint64_t tmp = write_result;
+ Rt.uw = (tmp == 0 || tmp == 1) ? tmp : Rt.uw;
+ }}, mem_flags=LOCKED, inst_flags = IsStoreConditional);
+
+ format StoreMemory {
+ 0x1: swc1({{ Mem.uw = Ft.uw; }});
+ 0x5: sdc1({{ Mem.ud = Ft.ud; }});
+ }
+ }
+}
+
+
diff --git a/src/arch/mips/isa/formats/basic.isa b/src/arch/mips/isa/formats/basic.isa
new file mode 100644
index 000000000..29a445b2c
--- /dev/null
+++ b/src/arch/mips/isa/formats/basic.isa
@@ -0,0 +1,96 @@
+// -*- 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: Steve Reinhardt
+// Korey Sewell
+
+// Declarations for execute() methods.
+def template BasicExecDeclare {{
+ Fault execute(%(CPU_exec_context)s *, Trace::InstRecord *) const;
+}};
+
+// Basic instruction class declaration template.
+def template BasicDeclare {{
+ /**
+ * Static instruction class for "%(mnemonic)s".
+ */
+ class %(class_name)s : public %(base_class)s
+ {
+ public:
+ /// Constructor.
+ %(class_name)s(MachInst machInst);
+ %(BasicExecDeclare)s
+ };
+}};
+
+// Basic instruction class constructor template.
+def template BasicConstructor {{
+ inline %(class_name)s::%(class_name)s(MachInst machInst) : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s)
+ {
+ %(constructor)s;
+ }
+}};
+
+
+// Basic instruction class execute method template.
+def template BasicExecute {{
+ Fault %(class_name)s::execute(%(CPU_exec_context)s *xc, Trace::InstRecord *traceData) const
+ {
+ Fault fault = NoFault;
+
+ %(fp_enable_check)s;
+ %(op_decl)s;
+ %(op_rd)s;
+ %(code)s;
+
+ if(fault == NoFault)
+ {
+ %(op_wb)s;
+ }
+ return fault;
+ }
+}};
+
+// Basic decode template.
+def template BasicDecode {{
+ return new %(class_name)s(machInst);
+}};
+
+// Basic decode template, passing mnemonic in as string arg to constructor.
+def template BasicDecodeWithMnemonic {{
+ return new %(class_name)s("%(mnemonic)s", machInst);
+}};
+
+// The most basic instruction format...
+def format BasicOp(code, *flags) {{
+ iop = InstObjParams(name, Name, 'MipsStaticInst', CodeBlock(code), flags)
+ header_output = BasicDeclare.subst(iop)
+ decoder_output = BasicConstructor.subst(iop)
+ decode_block = BasicDecode.subst(iop)
+ exec_output = BasicExecute.subst(iop)
+}};
diff --git a/src/arch/mips/isa/formats/branch.isa b/src/arch/mips/isa/formats/branch.isa
new file mode 100644
index 000000000..8c89fbfa2
--- /dev/null
+++ b/src/arch/mips/isa/formats/branch.isa
@@ -0,0 +1,278 @@
+// -*- 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
+
+////////////////////////////////////////////////////////////////////
+//
+// Control transfer instructions
+//
+
+output header {{
+
+#include <iostream>
+
+ /**
+ * Base class for instructions whose disassembly is not purely a
+ * function of the machine instruction (i.e., it depends on the
+ * PC). This class overrides the disassemble() method to check
+ * the PC and symbol table values before re-using a cached
+ * disassembly string. This is necessary for branches and jumps,
+ * where the disassembly string includes the target address (which
+ * may depend on the PC and/or symbol table).
+ */
+ class PCDependentDisassembly : public MipsStaticInst
+ {
+ protected:
+ /// Cached program counter from last disassembly
+ mutable Addr cachedPC;
+
+ /// Cached symbol table pointer from last disassembly
+ mutable const SymbolTable *cachedSymtab;
+
+ /// Constructor
+ PCDependentDisassembly(const char *mnem, MachInst _machInst,
+ OpClass __opClass)
+ : MipsStaticInst(mnem, _machInst, __opClass),
+ cachedPC(0), cachedSymtab(0)
+ {
+ }
+
+ const std::string &
+ disassemble(Addr pc, const SymbolTable *symtab) const;
+ };
+
+ /**
+ * Base class for branches (PC-relative control transfers),
+ * conditional or unconditional.
+ */
+ class Branch : public PCDependentDisassembly
+ {
+ protected:
+ /// target address (signed) Displacement .
+ int32_t disp;
+
+ /// Constructor.
+ Branch(const char *mnem, MachInst _machInst, OpClass __opClass)
+ : PCDependentDisassembly(mnem, _machInst, __opClass),
+ disp(OFFSET << 2)
+ {
+ //If Bit 17 is 1 then Sign Extend
+ if ( (disp & 0x00020000) > 0 ) {
+ disp |= 0xFFFE0000;
+ }
+ }
+
+ Addr branchTarget(Addr branchPC) const;
+
+ std::string
+ generateDisassembly(Addr pc, const SymbolTable *symtab) const;
+ };
+
+ /**
+ * Base class for jumps (register-indirect control transfers). In
+ * the Mips ISA, these are always unconditional.
+ */
+ class Jump : public PCDependentDisassembly
+ {
+ protected:
+
+ /// Displacement to target address (signed).
+ int32_t disp;
+
+ uint32_t target;
+
+ public:
+ /// Constructor
+ Jump(const char *mnem, MachInst _machInst, OpClass __opClass)
+ : PCDependentDisassembly(mnem, _machInst, __opClass),
+ disp(JMPTARG << 2)
+ {
+ }
+
+ Addr branchTarget(ThreadContext *tc) const;
+
+ std::string
+ generateDisassembly(Addr pc, const SymbolTable *symtab) const;
+ };
+}};
+
+output decoder {{
+ Addr
+ Branch::branchTarget(Addr branchPC) const
+ {
+ return branchPC + 4 + disp;
+ }
+
+ Addr
+ Jump::branchTarget(ThreadContext *tc) const
+ {
+ Addr NPC = tc->readPC() + 4;
+ uint64_t Rb = tc->readIntReg(_srcRegIdx[0]);
+ return (Rb & ~3) | (NPC & 1);
+ }
+
+ const std::string &
+ PCDependentDisassembly::disassemble(Addr pc,
+ const SymbolTable *symtab) const
+ {
+ if (!cachedDisassembly ||
+ pc != cachedPC || symtab != cachedSymtab)
+ {
+ if (cachedDisassembly)
+ delete cachedDisassembly;
+
+ cachedDisassembly =
+ new std::string(generateDisassembly(pc, symtab));
+ cachedPC = pc;
+ cachedSymtab = symtab;
+ }
+
+ return *cachedDisassembly;
+ }
+
+ std::string
+ Branch::generateDisassembly(Addr pc, const SymbolTable *symtab) const
+ {
+ std::stringstream ss;
+
+ ccprintf(ss, "%-10s ", mnemonic);
+
+ // There's only one register arg (RA), but it could be
+ // either a source (the condition for conditional
+ // branches) or a destination (the link reg for
+ // unconditional branches)
+ if (_numSrcRegs == 1) {
+ printReg(ss, _srcRegIdx[0]);
+ ss << ", ";
+ } else if(_numSrcRegs == 2) {
+ printReg(ss, _srcRegIdx[0]);
+ ss << ", ";
+ printReg(ss, _srcRegIdx[1]);
+ ss << ", ";
+ }
+
+ Addr target = pc + 4 + disp;
+
+ std::string str;
+ if (symtab && symtab->findSymbol(target, str))
+ ss << str;
+ else
+ ccprintf(ss, "0x%x", target);
+
+ return ss.str();
+ }
+
+ std::string
+ Jump::generateDisassembly(Addr pc, const SymbolTable *symtab) const
+ {
+ std::stringstream ss;
+
+ ccprintf(ss, "%-10s ", mnemonic);
+
+ if ( mnemonic == "jal" ) {
+ Addr npc = pc + 4;
+ ccprintf(ss,"0x%x",(npc & 0xF0000000) | disp);
+ } else if (_numSrcRegs == 0) {
+ std::string str;
+ if (symtab && symtab->findSymbol(disp, str))
+ ss << str;
+ else
+ ccprintf(ss, "0x%x", disp);
+ } else if (_numSrcRegs == 1) {
+ printReg(ss, _srcRegIdx[0]);
+ } else if(_numSrcRegs == 2) {
+ printReg(ss, _srcRegIdx[0]);
+ ss << ", ";
+ printReg(ss, _srcRegIdx[1]);
+ }
+
+ return ss.str();
+ }
+}};
+
+def format Branch(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', )
+
+ #Condition code
+ code = 'bool cond;\n' + code
+ code += 'if (cond) {\n'
+ code += ' NNPC = NPC + disp;\n'
+ code += '} else {\n'
+ code += not_taken_code
+
+ iop = InstObjParams(name, Name, 'Branch', CodeBlock(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
+ inst_flags = ('IsIndirectControl', 'IsUncondControl')
+ for x in opt_flags:
+ if x == 'Link':
+ code = 'R31 = NNPC;\n' + code
+ elif x == 'ClearHazards':
+ code += '/* Code Needed to Clear Execute & Inst Hazards */\n'
+ else:
+ inst_flags += (x, )
+
+ iop = InstObjParams(name, Name, 'Jump', CodeBlock(code), inst_flags)
+ header_output = BasicDeclare.subst(iop)
+ decoder_output = BasicConstructor.subst(iop)
+ decode_block = BasicDecode.subst(iop)
+ exec_output = BasicExecute.subst(iop)
+}};
+
+
+
+
diff --git a/src/arch/mips/isa/formats/control.isa b/src/arch/mips/isa/formats/control.isa
new file mode 100644
index 000000000..6c7d396f3
--- /dev/null
+++ b/src/arch/mips/isa/formats/control.isa
@@ -0,0 +1,156 @@
+// -*- 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
+
+////////////////////////////////////////////////////////////////////
+//
+// Integer operate 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
+ {
+ protected:
+
+ /// Constructor
+ CP0Control(const char *mnem, MachInst _machInst, OpClass __opClass) :
+ Control(mnem, _machInst, __opClass)
+ {
+ }
+
+ std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const;
+ };
+
+ class CP1Control : public Control
+ {
+ protected:
+
+ /// Constructor
+ CP1Control(const char *mnem, MachInst _machInst, OpClass __opClass) :
+ Control(mnem, _machInst, __opClass)
+ {
+ }
+
+ std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const;
+ };
+
+}};
+
+//Outputs to decoder.cc
+output decoder {{
+ std::string Control::generateDisassembly(Addr pc, const SymbolTable *symtab) 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]);
+ }
+
+ if (_numSrcRegs > 1) {
+ ss << ", ";
+ printReg(ss, _srcRegIdx[1]);
+ }
+ }
+
+ return ss.str();
+ }
+
+ 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);
+ return ss.str();
+ }
+
+ std::string CP1Control::generateDisassembly(Addr pc, const SymbolTable *symtab) const
+ {
+ std::stringstream ss;
+ ccprintf(ss, "%-10s r%d, f%d", mnemonic, RT, FS);
+ return ss.str();
+ }
+
+}};
+
+def format System(code, *flags) {{
+ iop = InstObjParams(name, Name, 'Control', CodeBlock(code), flags)
+ header_output = BasicDeclare.subst(iop)
+ decoder_output = BasicConstructor.subst(iop)
+ decode_block = BasicDecode.subst(iop)
+ exec_output = BasicExecute.subst(iop)
+}};
+
+def format CP0Control(code, *flags) {{
+ iop = InstObjParams(name, Name, 'CP0Control', CodeBlock(code), flags)
+ header_output = BasicDeclare.subst(iop)
+ decoder_output = BasicConstructor.subst(iop)
+ decode_block = BasicDecode.subst(iop)
+ exec_output = BasicExecute.subst(iop)
+}};
+
+def format CP1Control(code, *flags) {{
+ iop = InstObjParams(name, Name, 'CP1Control', CodeBlock(code), flags)
+ header_output = BasicDeclare.subst(iop)
+ decoder_output = BasicConstructor.subst(iop)
+ decode_block = BasicDecode.subst(iop)
+ exec_output = BasicExecute.subst(iop)
+}};
+
+
diff --git a/src/arch/mips/isa/formats/formats.isa b/src/arch/mips/isa/formats/formats.isa
new file mode 100644
index 000000000..4c3eec132
--- /dev/null
+++ b/src/arch/mips/isa/formats/formats.isa
@@ -0,0 +1,66 @@
+// -*- mode:c++ -*-
+
+// 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: Korey Sewell
+
+//Templates from this format are used later
+//Include the basic format
+##include "basic.isa"
+
+//Include the basic format
+##include "noop.isa"
+
+//Include utility functions
+##include "util.isa"
+
+//Include the control/cp0/cp1 formats
+##include "control.isa"
+
+//Include the integer formats
+##include "int.isa"
+
+//Include the floatOp format
+##include "fp.isa"
+
+//Include the mem format
+##include "mem.isa"
+
+//Include the mem format
+##include "mt.isa"
+
+//Include the trap format
+##include "trap.isa"
+
+//Include the branch format
+##include "branch.isa"
+
+//Include the noop format
+##include "unimp.isa"
+
+//Include the noop format
+##include "unknown.isa"
diff --git a/src/arch/mips/isa/formats/fp.isa b/src/arch/mips/isa/formats/fp.isa
new file mode 100644
index 000000000..cdb892b3f
--- /dev/null
+++ b/src/arch/mips/isa/formats/fp.isa
@@ -0,0 +1,373 @@
+// -*- 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
+
+////////////////////////////////////////////////////////////////////
+//
+// Floating Point operate instructions
+//
+
+output header {{
+ /**
+ * Base class for FP operations.
+ */
+ class FPOp : public MipsStaticInst
+ {
+ protected:
+
+ /// Constructor
+ FPOp(const char *mnem, MachInst _machInst, OpClass __opClass) : MipsStaticInst(mnem, _machInst, __opClass)
+ {
+ }
+
+ //std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const;
+
+ //needs function to check for fpEnable or not
+ };
+
+ class FPCompareOp : public FPOp
+ {
+ protected:
+ FPCompareOp(const char *mnem, MachInst _machInst, OpClass __opClass) : FPOp(mnem, _machInst, __opClass)
+ {
+ }
+
+ std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const;
+
+ };
+}};
+
+output decoder {{
+ std::string FPCompareOp::generateDisassembly(Addr pc, const SymbolTable *symtab) const
+ {
+ std::stringstream ss;
+
+ ccprintf(ss, "%-10s ", mnemonic);
+
+ ccprintf(ss,"%d",CC);
+
+ if(_numSrcRegs > 0) {
+ ss << ", ";
+ printReg(ss, _srcRegIdx[0]);
+ }
+
+ if(_numSrcRegs > 1) {
+ ss << ", ";
+ printReg(ss, _srcRegIdx[1]);
+ }
+
+ return ss.str();
+ }
+}};
+
+output exec {{
+
+ //If any operand is Nan return the appropriate QNaN
+ template <class T>
+ bool
+ fpNanOperands(FPOp *inst, %(CPU_exec_context)s *xc, const T &src_type,
+ Trace::InstRecord *traceData)
+ {
+ uint64_t mips_nan = 0;
+ T src_op = 0;
+ int size = sizeof(src_op) * 8;
+
+ for (int i = 0; i < inst->numSrcRegs(); i++) {
+ uint64_t src_bits = xc->readFloatRegBits(inst, 0, size);
+
+ if (isNan(&src_bits, size) ) {
+ if (isSnan(&src_bits, size)) {
+ switch (size)
+ {
+ case 32: mips_nan = MIPS32_QNAN; break;
+ case 64: mips_nan = MIPS64_QNAN; break;
+ default: panic("Unsupported Floating Point Size (%d)", size);
+ }
+ } else {
+ mips_nan = src_bits;
+ }
+
+ xc->setFloatRegBits(inst, 0, mips_nan, size);
+ if (traceData) { traceData->setData(mips_nan); }
+ return true;
+ }
+ }
+ return false;
+ }
+
+ template <class T>
+ bool
+ fpInvalidOp(FPOp *inst, %(CPU_exec_context)s *cpu, const T dest_val,
+ Trace::InstRecord *traceData)
+ {
+ uint64_t mips_nan = 0;
+ T src_op = dest_val;
+ int size = sizeof(src_op) * 8;
+
+ if (isNan(&src_op, size)) {
+ switch (size)
+ {
+ case 32: mips_nan = MIPS32_QNAN; break;
+ case 64: mips_nan = MIPS64_QNAN; break;
+ default: panic("Unsupported Floating Point Size (%d)", size);
+ }
+
+ //Set value to QNAN
+ cpu->setFloatRegBits(inst, 0, mips_nan, size);
+
+ //Read FCSR from FloatRegFile
+ uint32_t fcsr_bits = cpu->tcBase()->readFloatRegBits(FCSR);
+
+ //Write FCSR from FloatRegFile
+ cpu->tcBase()->setFloatRegBits(FCSR, genInvalidVector(fcsr_bits));
+
+ if (traceData) { traceData->setData(mips_nan); }
+ return true;
+ }
+
+ return false;
+ }
+
+ void
+ fpResetCauseBits(%(CPU_exec_context)s *cpu)
+ {
+ //Read FCSR from FloatRegFile
+ uint32_t fcsr = cpu->tcBase()->readFloatRegBits(FCSR);
+
+ fcsr = bits(fcsr, 31, 18) << 18 | bits(fcsr, 11, 0);
+
+ //Write FCSR from FloatRegFile
+ cpu->tcBase()->setFloatRegBits(FCSR, fcsr);
+ }
+}};
+
+def template FloatingPointExecute {{
+ Fault %(class_name)s::execute(%(CPU_exec_context)s *xc, Trace::InstRecord *traceData) const
+ {
+ Fault fault = NoFault;
+
+ %(fp_enable_check)s;
+
+ //When is the right time to reset cause bits?
+ //start of every instruction or every cycle?
+#if FULL_SYSTEM
+ fpResetCauseBits(xc);
+#endif
+ %(op_decl)s;
+ %(op_rd)s;
+
+ //Check if any FP operand is a NaN value
+ if (!fpNanOperands((FPOp*)this, xc, Fd, traceData)) {
+ %(code)s;
+
+ //Change this code for Full-System/Sycall Emulation
+ //separation
+ //----
+ //Should Full System-Mode throw a fault here?
+ //----
+ //Check for IEEE 754 FP Exceptions
+ //fault = fpNanOperands((FPOp*)this, xc, Fd, traceData);
+ if (
+#if FULL_SYSTEM
+ !fpInvalidOp((FPOp*)this, xc, Fd, traceData) &&
+#endif
+ fault == NoFault)
+ {
+ %(op_wb)s;
+ }
+ }
+
+ return fault;
+ }
+}};
+
+// Primary format for float point operate instructions:
+def format FloatOp(code, *flags) {{
+ iop = InstObjParams(name, Name, 'FPOp', CodeBlock(code), flags)
+ header_output = BasicDeclare.subst(iop)
+ decoder_output = BasicConstructor.subst(iop)
+ decode_block = BasicDecode.subst(iop)
+ exec_output = FloatingPointExecute.subst(iop)
+}};
+
+def format FloatCompareOp(cond_code, *flags) {{
+ import sys
+
+ code = 'bool cond;\n'
+ if '.sf' in cond_code or 'SinglePrecision' in flags:
+ if 'QnanException' in flags:
+ code += 'if (isQnan(&Fs.sf, 32) || isQnan(&Ft.sf, 32)) {\n'
+ code += '\tFCSR = genInvalidVector(FCSR);\n'
+ code += '\treturn NoFault;'
+ code += '}\n else '
+ code += 'if (isNan(&Fs.sf, 32) || isNan(&Ft.sf, 32)) {\n'
+ elif '.df' in cond_code or 'DoublePrecision' in flags:
+ if 'QnanException' in flags:
+ code += 'if (isQnan(&Fs.df, 64) || isQnan(&Ft.df, 64)) {\n'
+ code += '\tFCSR = genInvalidVector(FCSR);\n'
+ code += '\treturn NoFault;'
+ code += '}\n else '
+ code += 'if (isNan(&Fs.df, 64) || isNan(&Ft.df, 64)) {\n'
+ else:
+ sys.exit('Decoder Failed: Can\'t Determine Operand Type\n')
+
+ if 'UnorderedTrue' in flags:
+ code += 'cond = 1;\n'
+ elif 'UnorderedFalse' in flags:
+ code += 'cond = 0;\n'
+ else:
+ sys.exit('Decoder Failed: Float Compare Instruction Needs A Unordered Flag\n')
+
+ code += '} else {\n'
+ code += cond_code + '}'
+ code += 'FCSR = genCCVector(FCSR, CC, cond);\n'
+
+ iop = InstObjParams(name, Name, 'FPCompareOp', CodeBlock(code))
+ header_output = BasicDeclare.subst(iop)
+ decoder_output = BasicConstructor.subst(iop)
+ decode_block = BasicDecode.subst(iop)
+ exec_output = BasicExecute.subst(iop)
+}};
+
+def format FloatConvertOp(code, *flags) {{
+ import sys
+
+ #Determine Source Type
+ convert = 'fpConvert('
+ if '.sf' in code:
+ code = 'float ' + code + '\n'
+ convert += 'SINGLE_TO_'
+ elif '.df' in code:
+ code = 'double ' + code + '\n'
+ convert += 'DOUBLE_TO_'
+ elif '.uw' in code:
+ code = 'uint32_t ' + code + '\n'
+ convert += 'WORD_TO_'
+ elif '.ud' in code:
+ code = 'uint64_t ' + code + '\n'
+ convert += 'LONG_TO_'
+ else:
+ sys.exit("Error Determining Source Type for Conversion")
+
+ #Determine Destination Type
+ if 'ToSingle' in flags:
+ code += 'Fd.uw = ' + convert + 'SINGLE, '
+ elif 'ToDouble' in flags:
+ code += 'Fd.ud = ' + convert + 'DOUBLE, '
+ elif 'ToWord' in flags:
+ code += 'Fd.uw = ' + convert + 'WORD, '
+ elif 'ToLong' in flags:
+ code += 'Fd.ud = ' + convert + 'LONG, '
+ else:
+ sys.exit("Error Determining Destination Type for Conversion")
+
+ #Figure out how to round value
+ if 'Ceil' in flags:
+ code += 'ceil(val)); '
+ elif 'Floor' in flags:
+ code += 'floor(val)); '
+ elif 'Round' in flags:
+ code += 'roundFP(val, 0)); '
+ elif 'Trunc' in flags:
+ code += 'truncFP(val));'
+ else:
+ code += 'val); '
+
+ iop = InstObjParams(name, Name, 'FPOp', CodeBlock(code))
+ header_output = BasicDeclare.subst(iop)
+ decoder_output = BasicConstructor.subst(iop)
+ decode_block = BasicDecode.subst(iop)
+ exec_output = BasicExecute.subst(iop)
+}};
+
+def format FloatAccOp(code, *flags) {{
+ iop = InstObjParams(name, Name, 'FPOp', CodeBlock(code), flags)
+ header_output = BasicDeclare.subst(iop)
+ decoder_output = BasicConstructor.subst(iop)
+ decode_block = BasicDecode.subst(iop)
+ exec_output = BasicExecute.subst(iop)
+}};
+
+// Primary format for float64 operate instructions:
+def format Float64Op(code, *flags) {{
+ iop = InstObjParams(name, Name, 'MipsStaticInst', CodeBlock(code), flags)
+ header_output = BasicDeclare.subst(iop)
+ decoder_output = BasicConstructor.subst(iop)
+ decode_block = BasicDecode.subst(iop)
+ exec_output = BasicExecute.subst(iop)
+}};
+
+def format FloatPSCompareOp(cond_code1, cond_code2, *flags) {{
+ import sys
+
+ code = 'bool cond1, cond2;\n'
+ code += 'bool code_block1, code_block2;\n'
+ code += 'code_block1 = code_block2 = true;\n'
+
+ if 'QnanException' in flags:
+ code += 'if (isQnan(&Fs1.sf, 32) || isQnan(&Ft1.sf, 32)) {\n'
+ code += '\tFCSR = genInvalidVector(FCSR);\n'
+ code += 'code_block1 = false;'
+ code += '}\n'
+ code += 'if (isQnan(&Fs2.sf, 32) || isQnan(&Ft2.sf, 32)) {\n'
+ code += '\tFCSR = genInvalidVector(FCSR);\n'
+ code += 'code_block2 = false;'
+ code += '}\n'
+
+ code += 'if (code_block1) {'
+ code += '\tif (isNan(&Fs1.sf, 32) || isNan(&Ft1.sf, 32)) {\n'
+ if 'UnorderedTrue' in flags:
+ code += 'cond1 = 1;\n'
+ elif 'UnorderedFalse' in flags:
+ code += 'cond1 = 0;\n'
+ else:
+ sys.exit('Decoder Failed: Float Compare Instruction Needs A Unordered Flag\n')
+ code += '} else {\n'
+ code += cond_code1
+ code += 'FCSR = genCCVector(FCSR, CC, cond1);}\n}\n'
+
+ code += 'if (code_block2) {'
+ code += '\tif (isNan(&Fs2.sf, 32) || isNan(&Ft2.sf, 32)) {\n'
+ if 'UnorderedTrue' in flags:
+ code += 'cond2 = 1;\n'
+ elif 'UnorderedFalse' in flags:
+ code += 'cond2 = 0;\n'
+ else:
+ sys.exit('Decoder Failed: Float Compare Instruction Needs A Unordered Flag\n')
+ code += '} else {\n'
+ code += cond_code2
+ code += 'FCSR = genCCVector(FCSR, CC, cond2);}\n}'
+
+ iop = InstObjParams(name, Name, 'FPCompareOp', CodeBlock(code))
+ header_output = BasicDeclare.subst(iop)
+ decoder_output = BasicConstructor.subst(iop)
+ decode_block = BasicDecode.subst(iop)
+ exec_output = BasicExecute.subst(iop)
+}};
+
diff --git a/src/arch/mips/isa/formats/int.isa b/src/arch/mips/isa/formats/int.isa
new file mode 100644
index 000000000..654dd8921
--- /dev/null
+++ b/src/arch/mips/isa/formats/int.isa
@@ -0,0 +1,269 @@
+// -*- 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
+
+////////////////////////////////////////////////////////////////////
+//
+// Integer operate instructions
+//
+output header {{
+#include <iostream>
+ /**
+ * Base class for integer operations.
+ */
+ class IntOp : public MipsStaticInst
+ {
+ protected:
+
+ /// Constructor
+ IntOp(const char *mnem, MachInst _machInst, OpClass __opClass) :
+ MipsStaticInst(mnem, _machInst, __opClass)
+ {
+ }
+
+ std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const;
+ };
+
+
+ class HiLoOp: public IntOp
+ {
+ protected:
+
+ /// Constructor
+ HiLoOp(const char *mnem, MachInst _machInst, OpClass __opClass) :
+ IntOp(mnem, _machInst, __opClass)
+ {
+ }
+
+ std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const;
+ };
+
+ class HiLoMiscOp: public HiLoOp
+ {
+ protected:
+
+ /// Constructor
+ HiLoMiscOp(const char *mnem, MachInst _machInst, OpClass __opClass) :
+ HiLoOp(mnem, _machInst, __opClass)
+ {
+ }
+
+ std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const;
+ };
+
+
+ class IntImmOp : public MipsStaticInst
+ {
+ protected:
+
+ int16_t imm;
+ int32_t sextImm;
+ uint32_t zextImm;
+
+ /// Constructor
+ IntImmOp(const char *mnem, MachInst _machInst, OpClass __opClass) :
+ MipsStaticInst(mnem, _machInst, __opClass),imm(INTIMM),
+ sextImm(INTIMM),zextImm(0x0000FFFF & INTIMM)
+ {
+ //If Bit 15 is 1 then Sign Extend
+ int32_t temp = sextImm & 0x00008000;
+ if (temp > 0 && mnemonic != "lui") {
+ sextImm |= 0xFFFF0000;
+ }
+ }
+
+ std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const;
+
+
+ };
+
+}};
+
+// HiLo<Misc> instruction class execute method template.
+// Mainly to get instruction trace data to print out
+// correctly
+def template HiLoExecute {{
+ Fault %(class_name)s::execute(%(CPU_exec_context)s *xc, Trace::InstRecord *traceData) const
+ {
+ Fault fault = NoFault;
+
+ %(fp_enable_check)s;
+ %(op_decl)s;
+ %(op_rd)s;
+ %(code)s;
+
+ 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;
+ }
+}};
+
+//Outputs to decoder.cc
+output decoder {{
+ std::string IntOp::generateDisassembly(Addr pc, const SymbolTable *symtab) const
+ {
+ std::stringstream ss;
+
+ ccprintf(ss, "%-10s ", mnemonic);
+
+ // 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]);
+ }
+
+ if (_numSrcRegs > 1) {
+ ss << ", ";
+ printReg(ss, _srcRegIdx[1]);
+ }
+
+ return ss.str();
+ }
+
+ std::string HiLoOp::generateDisassembly(Addr pc, const SymbolTable *symtab) const
+ {
+ std::stringstream ss;
+
+ ccprintf(ss, "%-10s ", mnemonic);
+
+ //Destination Registers are implicit for HI/LO ops
+ if (_numSrcRegs > 0) {
+ printReg(ss, _srcRegIdx[0]);
+ }
+
+ if (_numSrcRegs > 1) {
+ ss << ", ";
+ printReg(ss, _srcRegIdx[1]);
+ }
+
+ return ss.str();
+ }
+
+ std::string HiLoMiscOp::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 IntImmOp::generateDisassembly(Addr pc, const SymbolTable *symtab) const
+ {
+ std::stringstream ss;
+
+ ccprintf(ss, "%-10s ", mnemonic);
+
+ if (_numDestRegs > 0) {
+ printReg(ss, _destRegIdx[0]);
+ }
+
+ ss << ", ";
+
+ if (_numSrcRegs > 0) {
+ printReg(ss, _srcRegIdx[0]);
+ ss << ", ";
+ }
+
+ if( mnemonic == "lui")
+ ccprintf(ss, "0x%x ", sextImm);
+ else
+ ss << (int) sextImm;
+
+ return ss.str();
+ }
+
+}};
+
+def format IntOp(code, *opt_flags) {{
+ iop = InstObjParams(name, Name, 'IntOp', CodeBlock(code), opt_flags)
+ header_output = BasicDeclare.subst(iop)
+ decoder_output = BasicConstructor.subst(iop)
+ decode_block = RegNopCheckDecode.subst(iop)
+ exec_output = BasicExecute.subst(iop)
+}};
+
+def format IntImmOp(code, *opt_flags) {{
+ iop = InstObjParams(name, Name, 'IntImmOp', CodeBlock(code), opt_flags)
+ header_output = BasicDeclare.subst(iop)
+ decoder_output = BasicConstructor.subst(iop)
+ decode_block = ImmNopCheckDecode.subst(iop)
+ exec_output = BasicExecute.subst(iop)
+}};
+
+def format HiLoOp(code, *opt_flags) {{
+ if '.sd' in code:
+ code = 'int64_t ' + code
+ elif '.ud' in code:
+ code = 'uint64_t ' + code
+
+ code += 'HI = val<63:32>;\n'
+ code += 'LO = val<31:0>;\n'
+
+ iop = InstObjParams(name, Name, 'HiLoOp', CodeBlock(code), opt_flags)
+ header_output = BasicDeclare.subst(iop)
+ decoder_output = BasicConstructor.subst(iop)
+ decode_block = BasicDecode.subst(iop)
+ exec_output = HiLoExecute.subst(iop)
+}};
+
+def format HiLoMiscOp(code, *opt_flags) {{
+ iop = InstObjParams(name, Name, 'HiLoMiscOp', CodeBlock(code), opt_flags)
+ header_output = BasicDeclare.subst(iop)
+ decoder_output = BasicConstructor.subst(iop)
+ decode_block = BasicDecode.subst(iop)
+ exec_output = HiLoExecute.subst(iop)
+}};
+
+
+
+
+
diff --git a/src/arch/mips/isa/formats/mem.isa b/src/arch/mips/isa/formats/mem.isa
new file mode 100644
index 000000000..d6b0c2938
--- /dev/null
+++ b/src/arch/mips/isa/formats/mem.isa
@@ -0,0 +1,604 @@
+// -*- 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: Steve Reinhardt
+// Korey Sewell
+
+////////////////////////////////////////////////////////////////////
+//
+// Memory-format instructions
+//
+
+output header {{
+ /**
+ * Base class for general Mips memory-format instructions.
+ */
+ class Memory : public MipsStaticInst
+ {
+ protected:
+
+ /// Memory request flags. See mem_req_base.hh.
+ unsigned memAccessFlags;
+ /// Pointer to EAComp object.
+ const StaticInstPtr eaCompPtr;
+ /// Pointer to MemAcc object.
+ const StaticInstPtr memAccPtr;
+
+ /// Displacement for EA calculation (signed).
+ int32_t disp;
+
+ /// Constructor
+ Memory(const char *mnem, MachInst _machInst, OpClass __opClass,
+ StaticInstPtr _eaCompPtr = nullStaticInstPtr,
+ StaticInstPtr _memAccPtr = nullStaticInstPtr)
+ : MipsStaticInst(mnem, _machInst, __opClass),
+ memAccessFlags(0), eaCompPtr(_eaCompPtr), memAccPtr(_memAccPtr),
+ disp(sext<16>(OFFSET))
+ {
+ }
+
+ std::string
+ generateDisassembly(Addr pc, const SymbolTable *symtab) const;
+
+ public:
+
+ const StaticInstPtr &eaCompInst() const { return eaCompPtr; }
+ const StaticInstPtr &memAccInst() const { return memAccPtr; }
+ };
+
+ /**
+ * Base class for a few miscellaneous memory-format insts
+ * that don't interpret the disp field
+ */
+ class MemoryNoDisp : public Memory
+ {
+ protected:
+ /// Constructor
+ MemoryNoDisp(const char *mnem, ExtMachInst _machInst, OpClass __opClass,
+ StaticInstPtr _eaCompPtr = nullStaticInstPtr,
+ StaticInstPtr _memAccPtr = nullStaticInstPtr)
+ : Memory(mnem, _machInst, __opClass, _eaCompPtr, _memAccPtr)
+ {
+ }
+
+ std::string
+ generateDisassembly(Addr pc, const SymbolTable *symtab) const;
+ };
+}};
+
+
+output decoder {{
+ std::string
+ Memory::generateDisassembly(Addr pc, const SymbolTable *symtab) const
+ {
+ return csprintf("%-10s %c%d, %d(r%d)", mnemonic,
+ flags[IsFloating] ? 'f' : 'r', RT, disp, RS);
+ }
+
+ std::string
+ MemoryNoDisp::generateDisassembly(Addr pc, const SymbolTable *symtab) const
+ {
+ return csprintf("%-10s %c%d, r%d(r%d)", mnemonic,
+ flags[IsFloating] ? 'f' : 'r',
+ flags[IsFloating] ? FD : RD,
+ RS, RT);
+ }
+}};
+
+def template LoadStoreDeclare {{
+ /**
+ * Static instruction class for "%(mnemonic)s".
+ */
+ class %(class_name)s : public %(base_class)s
+ {
+ protected:
+
+ /**
+ * "Fake" effective address computation class for "%(mnemonic)s".
+ */
+ class EAComp : public %(base_class)s
+ {
+ public:
+ /// Constructor
+ EAComp(MachInst machInst);
+
+ %(BasicExecDeclare)s
+ };
+
+ /**
+ * "Fake" memory access instruction class for "%(mnemonic)s".
+ */
+ class MemAcc : public %(base_class)s
+ {
+ public:
+ /// Constructor
+ MemAcc(MachInst machInst);
+
+ %(BasicExecDeclare)s
+ };
+
+ public:
+
+ /// Constructor.
+ %(class_name)s(MachInst machInst);
+
+ %(BasicExecDeclare)s
+
+ %(InitiateAccDeclare)s
+
+ %(CompleteAccDeclare)s
+ };
+}};
+
+
+def template InitiateAccDeclare {{
+ Fault initiateAcc(%(CPU_exec_context)s *, Trace::InstRecord *) const;
+}};
+
+
+def template CompleteAccDeclare {{
+ Fault completeAcc(Packet *, %(CPU_exec_context)s *, Trace::InstRecord *) const;
+}};
+
+
+def template LoadStoreConstructor {{
+ /** 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)
+ : %(base_class)s("%(mnemonic)s (EAComp)", machInst, IntAluOp)
+ {
+ %(ea_constructor)s;
+ }
+
+ inline %(class_name)s::MemAcc::MemAcc(MachInst machInst)
+ : %(base_class)s("%(mnemonic)s (MemAcc)", machInst, %(op_class)s)
+ {
+ %(memacc_constructor)s;
+ }
+
+ inline %(class_name)s::%(class_name)s(MachInst machInst)
+ : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s,
+ new EAComp(machInst), new MemAcc(machInst))
+ {
+ %(constructor)s;
+ }
+}};
+
+
+def template EACompExecute {{
+ Fault
+ %(class_name)s::EAComp::execute(%(CPU_exec_context)s *xc,
+ Trace::InstRecord *traceData) const
+ {
+ Addr EA;
+ Fault fault = NoFault;
+
+ %(fp_enable_check)s;
+ %(op_decl)s;
+ %(op_rd)s;
+ %(code)s;
+
+ if (fault == NoFault) {
+ %(op_wb)s;
+ xc->setEA(EA);
+ }
+
+ return fault;
+ }
+}};
+
+def template LoadMemAccExecute {{
+ Fault
+ %(class_name)s::MemAcc::execute(%(CPU_exec_context)s *xc,
+ Trace::InstRecord *traceData) const
+ {
+ 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);
+ %(code)s;
+ }
+
+ if (fault == NoFault) {
+ %(op_wb)s;
+ }
+
+ return fault;
+ }
+}};
+
+
+def template LoadExecute {{
+ Fault %(class_name)s::execute(%(CPU_exec_context)s *xc,
+ Trace::InstRecord *traceData) const
+ {
+ Addr EA;
+ Fault fault = NoFault;
+
+ %(fp_enable_check)s;
+ %(op_decl)s;
+ %(op_rd)s;
+ %(ea_code)s;
+
+ if (fault == NoFault) {
+ fault = xc->read(EA, (uint%(mem_acc_size)d_t&)Mem, memAccessFlags);
+ %(memacc_code)s;
+ }
+
+ if (fault == NoFault) {
+ %(op_wb)s;
+ }
+
+ return fault;
+ }
+}};
+
+
+def template LoadInitiateAcc {{
+ Fault %(class_name)s::initiateAcc(%(CPU_exec_context)s *xc,
+ Trace::InstRecord *traceData) const
+ {
+ Addr EA;
+ Fault fault = NoFault;
+
+ %(fp_enable_check)s;
+ %(op_src_decl)s;
+ %(op_rd)s;
+ %(ea_code)s;
+
+ if (fault == NoFault) {
+ fault = xc->read(EA, (uint%(mem_acc_size)d_t &)Mem, memAccessFlags);
+ }
+
+ return fault;
+ }
+}};
+
+
+def template LoadCompleteAcc {{
+ Fault %(class_name)s::completeAcc(Packet *pkt,
+ %(CPU_exec_context)s *xc,
+ Trace::InstRecord *traceData) const
+ {
+ Fault fault = NoFault;
+
+ %(fp_enable_check)s;
+ %(op_decl)s;
+
+ Mem = pkt->get<typeof(Mem)>();
+
+ if (fault == NoFault) {
+ %(memacc_code)s;
+ }
+
+ if (fault == NoFault) {
+ %(op_wb)s;
+ }
+
+ return fault;
+ }
+}};
+
+
+def template StoreMemAccExecute {{
+ Fault
+ %(class_name)s::MemAcc::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;
+ %(op_rd)s;
+ EA = xc->getEA();
+
+ if (fault == NoFault) {
+ %(code)s;
+ }
+
+ if (fault == NoFault) {
+ fault = xc->write((uint%(mem_acc_size)d_t&)Mem, EA,
+ memAccessFlags, &write_result);
+ if (traceData) { traceData->setData(Mem); }
+ }
+
+ if (fault == NoFault) {
+ %(postacc_code)s;
+ }
+
+ if (fault == NoFault) {
+ %(op_wb)s;
+ }
+
+ return fault;
+ }
+}};
+
+
+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;
+ %(op_rd)s;
+ %(ea_code)s;
+
+ if (fault == NoFault) {
+ %(memacc_code)s;
+ }
+
+ if (fault == NoFault) {
+ fault = xc->write((uint%(mem_acc_size)d_t&)Mem, EA,
+ memAccessFlags, &write_result);
+ if (traceData) { traceData->setData(Mem); }
+ }
+
+ if (fault == NoFault) {
+ %(postacc_code)s;
+ }
+
+ if (fault == NoFault) {
+ %(op_wb)s;
+ }
+
+ return fault;
+ }
+}};
+
+def template StoreInitiateAcc {{
+ Fault %(class_name)s::initiateAcc(%(CPU_exec_context)s *xc,
+ Trace::InstRecord *traceData) const
+ {
+ Addr EA;
+ Fault fault = NoFault;
+
+ %(fp_enable_check)s;
+ %(op_decl)s;
+ %(op_rd)s;
+ %(ea_code)s;
+
+ if (fault == NoFault) {
+ %(memacc_code)s;
+ }
+
+ if (fault == NoFault) {
+ fault = xc->write((uint%(mem_acc_size)d_t&)Mem, EA,
+ memAccessFlags, NULL);
+ if (traceData) { traceData->setData(Mem); }
+ }
+
+ return fault;
+ }
+}};
+
+
+def template StoreCompleteAcc {{
+ Fault %(class_name)s::completeAcc(Packet *pkt,
+ %(CPU_exec_context)s *xc,
+ Trace::InstRecord *traceData) const
+ {
+ Fault fault = NoFault;
+
+ %(fp_enable_check)s;
+ %(op_dest_decl)s;
+
+ if (fault == NoFault) {
+ %(postacc_code)s;
+ }
+
+ if (fault == NoFault) {
+ %(op_wb)s;
+ }
+
+ return fault;
+ }
+}};
+
+def template StoreCondCompleteAcc {{
+ Fault %(class_name)s::completeAcc(Packet *pkt,
+ %(CPU_exec_context)s *xc,
+ Trace::InstRecord *traceData) const
+ {
+ Fault fault = NoFault;
+
+ %(fp_enable_check)s;
+ %(op_dest_decl)s;
+
+ uint64_t write_result = pkt->req->getScResult();
+
+ if (fault == NoFault) {
+ %(postacc_code)s;
+ }
+
+ if (fault == NoFault) {
+ %(op_wb)s;
+ }
+
+ return fault;
+ }
+}};
+
+
+def template MiscMemAccExecute {{
+ Fault %(class_name)s::MemAcc::execute(%(CPU_exec_context)s *xc,
+ Trace::InstRecord *traceData) const
+ {
+ Addr EA;
+ Fault fault = NoFault;
+
+ %(fp_enable_check)s;
+ %(op_decl)s;
+ %(op_rd)s;
+ EA = xc->getEA();
+
+ if (fault == NoFault) {
+ %(code)s;
+ }
+
+ return NoFault;
+ }
+}};
+
+def template MiscExecute {{
+ Fault %(class_name)s::execute(%(CPU_exec_context)s *xc,
+ Trace::InstRecord *traceData) const
+ {
+ Addr EA;
+ Fault fault = NoFault;
+
+ %(fp_enable_check)s;
+ %(op_decl)s;
+ %(op_rd)s;
+ %(ea_code)s;
+
+ if (fault == NoFault) {
+ %(memacc_code)s;
+ }
+
+ return NoFault;
+ }
+}};
+
+def template MiscInitiateAcc {{
+ Fault %(class_name)s::initiateAcc(%(CPU_exec_context)s *xc,
+ Trace::InstRecord *traceData) const
+ {
+ panic("Misc instruction does not support split access method!");
+ return NoFault;
+ }
+}};
+
+
+def template MiscCompleteAcc {{
+ Fault %(class_name)s::completeAcc(Packet *pkt,
+ %(CPU_exec_context)s *xc,
+ Trace::InstRecord *traceData) const
+ {
+ panic("Misc instruction does not support split access method!");
+
+ return NoFault;
+ }
+}};
+
+def format LoadMemory(memacc_code, ea_code = {{ EA = Rs + disp; }},
+ mem_flags = [], inst_flags = []) {{
+ (header_output, decoder_output, decode_block, exec_output) = \
+ LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags,
+ decode_template = ImmNopCheckDecode,
+ exec_template_base = 'Load')
+}};
+
+def format StoreMemory(memacc_code, ea_code = {{ EA = Rs + disp; }},
+ mem_flags = [], inst_flags = []) {{
+ (header_output, decoder_output, decode_block, exec_output) = \
+ LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags,
+ exec_template_base = 'Store')
+}};
+
+def format LoadIndexedMemory(memacc_code, ea_code = {{ EA = Rs + Rt; }},
+ mem_flags = [], inst_flags = []) {{
+ (header_output, decoder_output, decode_block, exec_output) = \
+ LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags,
+ decode_template = ImmNopCheckDecode,
+ exec_template_base = 'Load')
+}};
+
+def format StoreIndexedMemory(memacc_code, ea_code = {{ EA = Rs + Rt; }},
+ mem_flags = [], inst_flags = []) {{
+ (header_output, decoder_output, decode_block, exec_output) = \
+ LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags,
+ exec_template_base = 'Store')
+}};
+
+def format LoadUnalignedMemory(memacc_code, ea_code = {{ EA = (Rs + disp) & ~3; }},
+ mem_flags = [], inst_flags = []) {{
+ decl_code = 'uint32_t mem_word = Mem.uw;\n'
+ decl_code += 'uint32_t unalign_addr = Rs + disp;\n'
+ decl_code += 'uint32_t byte_offset = unalign_addr & 3;\n'
+ decl_code += '#if BYTE_ORDER == BIG_ENDIAN\n'
+ decl_code += '\tbyte_offset ^= 3;\n'
+ decl_code += '#endif\n'
+
+ memacc_code = decl_code + memacc_code
+
+ (header_output, decoder_output, decode_block, exec_output) = \
+ LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags,
+ decode_template = ImmNopCheckDecode,
+ exec_template_base = 'Load')
+}};
+
+def format StoreUnalignedMemory(memacc_code, ea_code = {{ EA = (Rs + disp) & ~3; }},
+ mem_flags = [], inst_flags = []) {{
+ decl_code = 'uint32_t mem_word = 0;\n'
+ decl_code += 'uint32_t unaligned_addr = Rs + disp;\n'
+ decl_code += 'uint32_t byte_offset = unaligned_addr & 3;\n'
+ decl_code += '#if BYTE_ORDER == BIG_ENDIAN\n'
+ decl_code += '\tbyte_offset ^= 3;\n'
+ decl_code += '#endif\n'
+ decl_code += 'fault = xc->read(EA, (uint32_t&)mem_word, memAccessFlags);\n'
+ memacc_code = decl_code + memacc_code + '\nMem = mem_word;\n'
+
+ (header_output, decoder_output, decode_block, exec_output) = \
+ LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags,
+ exec_template_base = 'Store')
+}};
+
+def format Prefetch(ea_code = {{ EA = Rs + disp; }},
+ mem_flags = [], pf_flags = [], inst_flags = []) {{
+ pf_mem_flags = mem_flags + pf_flags + ['NO_FAULT']
+ pf_inst_flags = inst_flags + ['IsMemRef', 'IsLoad',
+ 'IsDataPrefetch', 'MemReadOp']
+
+ (header_output, decoder_output, decode_block, exec_output) = \
+ LoadStoreBase(name, Name, ea_code,
+ 'xc->prefetch(EA, memAccessFlags);',
+ pf_mem_flags, pf_inst_flags, exec_template_base = 'Misc')
+
+}};
+
+def format StoreCond(memacc_code, postacc_code,
+ ea_code = {{ EA = Rs + disp; }},
+ mem_flags = [], inst_flags = []) {{
+ (header_output, decoder_output, decode_block, exec_output) = \
+ LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags,
+ postacc_code, exec_template_base = 'StoreCond')
+}};
diff --git a/src/arch/mips/isa/formats/mt.isa b/src/arch/mips/isa/formats/mt.isa
new file mode 100644
index 000000000..96435f8c9
--- /dev/null
+++ b/src/arch/mips/isa/formats/mt.isa
@@ -0,0 +1,82 @@
+// -*- 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
+
+////////////////////////////////////////////////////////////////////
+//
+// MT instructions
+//
+
+output header {{
+ /**
+ * Base class for MIPS MT ASE operations.
+ */
+ class MT : public MipsStaticInst
+ {
+ protected:
+
+ /// Constructor
+ MT(const char *mnem, MachInst _machInst, OpClass __opClass) :
+ MipsStaticInst(mnem, _machInst, __opClass)
+ {
+ }
+
+ 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";
+ }
+}};
+
+def template MTExecute {{
+ //Edit This Template When MT is Implemented
+ Fault %(class_name)s::execute(%(CPU_exec_context)s *xc, Trace::InstRecord *traceData) const
+ {
+ //Write the resulting state to the execution context
+ %(op_wb)s;
+
+ //Call into the trap handler with the appropriate fault
+ return No_Fault;
+ }
+}};
+
+// Primary format for integer operate instructions:
+def format MipsMT() {{
+ code = 'panic(\"Mips MT Is Currently Unimplemented.\");\n'
+ iop = InstObjParams(name, Name, 'MT', CodeBlock(code))
+ header_output = BasicDeclare.subst(iop)
+ decoder_output = BasicConstructor.subst(iop)
+ decode_block = BasicDecode.subst(iop)
+ exec_output = BasicExecute.subst(iop)
+}};
diff --git a/src/arch/mips/isa/formats/noop.isa b/src/arch/mips/isa/formats/noop.isa
new file mode 100644
index 000000000..7f3d313ad
--- /dev/null
+++ b/src/arch/mips/isa/formats/noop.isa
@@ -0,0 +1,139 @@
+// -*- 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
+
+////////////////////////////////////////////////////////////////////
+//
+// Nop
+//
+
+output header {{
+ /**
+ * Static instruction class for no-ops. This is a leaf class.
+ */
+ class Nop : public MipsStaticInst
+ {
+ /// Disassembly of original instruction.
+ const std::string originalDisassembly;
+
+ public:
+ /// Constructor
+ Nop(const std::string _originalDisassembly, MachInst _machInst)
+ : MipsStaticInst("nop", _machInst, No_OpClass),
+ originalDisassembly(_originalDisassembly)
+ {
+ flags[IsNop] = true;
+ }
+
+ ~Nop() { }
+
+ std::string
+ generateDisassembly(Addr pc, const SymbolTable *symtab) const;
+
+ %(BasicExecDeclare)s
+ };
+}};
+
+output decoder {{
+ std::string Nop::generateDisassembly(Addr pc,
+ const SymbolTable *symtab) const
+ {
+ return csprintf("%-10s %s", "nop", originalDisassembly);
+ }
+
+ /// Helper function for decoding nops. Substitute Nop object
+ /// for original inst passed in as arg (and delete latter).
+ inline
+ MipsStaticInst *
+ makeNop(MipsStaticInst *inst)
+ {
+ std::string nop_str = "(" + inst->disassemble(0) + ")";
+ MipsStaticInst *nop = new Nop(nop_str, inst->machInst);
+ delete inst;
+ return nop;
+ }
+}};
+
+output exec {{
+ Fault
+ Nop::execute(%(CPU_exec_context)s *, Trace::InstRecord *) const
+ {
+ return NoFault;
+ }
+}};
+
+// Int & FP operate instructions use RD as dest, so check for
+// RD == 0 to detect nops
+def template RegNopCheckDecode {{
+ {
+ MipsStaticInst *i = new %(class_name)s(machInst);
+ //if (RD == 0) {
+ //i = makeNop(i);
+ //}
+ return i;
+ }
+}};
+
+def template OperateNopCheckDecode {{
+ {
+ MipsStaticInst *i = new %(class_name)s(machInst);
+ //if (RD == 0) {
+ // i = makeNop(i);
+ //}
+ return i;
+ }
+}};
+
+// IntImm & Memory instructions use Rt as dest, so check for
+// Rt == 0 to detect nops
+def template ImmNopCheckDecode {{
+ {
+ MipsStaticInst *i = new %(class_name)s(machInst);
+ //if (RT == 0) {
+ // i = makeNop(i);
+ // }
+ return i;
+ }
+}};
+
+
+// Like BasicOperate format, but generates NOP if RC/FC == 31
+def format BasicOperateWithNopCheck(code, *opt_args) {{
+ iop = InstObjParams(name, Name, 'MipsStaticInst', CodeBlock(code),
+ opt_args)
+ header_output = BasicDeclare.subst(iop)
+ decoder_output = BasicConstructor.subst(iop)
+ decode_block = OperateNopCheckDecode.subst(iop)
+ exec_output = BasicExecute.subst(iop)
+}};
+
+def format Nop() {{
+ decode_block = 'return new Nop(\"\",machInst);\n'
+}};
+
diff --git a/src/arch/mips/isa/formats/tlbop.isa b/src/arch/mips/isa/formats/tlbop.isa
new file mode 100644
index 000000000..b974ccbed
--- /dev/null
+++ b/src/arch/mips/isa/formats/tlbop.isa
@@ -0,0 +1,80 @@
+// -*- 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
+
+////////////////////////////////////////////////////////////////////
+//
+// TlbOp instructions
+//
+
+output header {{
+ /**
+ * Base class for integer operations.
+ */
+ class TlbOp : public MipsStaticInst
+ {
+ protected:
+
+ /// Constructor
+ TlbOp(const char *mnem, MachInst _machInst, OpClass __opClass) : MipsStaticInst(mnem, _machInst, __opClass)
+ {
+ }
+
+ std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const;
+ };
+}};
+
+output decoder {{
+ std::string TlbOp::generateDisassembly(Addr pc, const SymbolTable *symtab) const
+ {
+ return "Disassembly of integer instruction\n";
+ }
+}};
+
+def template TlbOpExecute {{
+ Fault %(class_name)s::execute(%(CPU_exec_context)s *xc, Trace::InstRecord *traceData) const
+ {
+ //Write the resulting state to the execution context
+ %(op_wb)s;
+
+ //Call into the trap handler with the appropriate fault
+ return No_Fault;
+ }
+}};
+
+// Primary format for integer operate instructions:
+def format TlbOp(code, *opt_flags) {{
+ orig_code = code
+ cblk = CodeBlock(code)
+ iop = InstObjParams(name, Name, 'MipsStaticInst', cblk, opt_flags)
+ header_output = BasicDeclare.subst(iop)
+ decoder_output = BasicConstructor.subst(iop)
+ decode_block = BasicDecodeWithMnemonic.subst(iop)
+ exec_output = TlbOpExecute.subst(iop)
+}};
diff --git a/src/arch/mips/isa/formats/trap.isa b/src/arch/mips/isa/formats/trap.isa
new file mode 100644
index 000000000..b9066f374
--- /dev/null
+++ b/src/arch/mips/isa/formats/trap.isa
@@ -0,0 +1,81 @@
+// -*- 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
+
+////////////////////////////////////////////////////////////////////
+//
+// Trap instructions
+//
+
+output header {{
+ /**
+ * Base class for integer operations.
+ */
+ class Trap : public MipsStaticInst
+ {
+ protected:
+
+ /// Constructor
+ Trap(const char *mnem, MachInst _machInst, OpClass __opClass) : MipsStaticInst(mnem, _machInst, __opClass)
+ {
+ }
+
+ std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const;
+ };
+}};
+
+output decoder {{
+ std::string Trap::generateDisassembly(Addr pc, const SymbolTable *symtab) const
+ {
+ return "Disassembly of trap instruction\n";
+ }
+}};
+
+def template TrapExecute {{
+ //Edit This Template When Traps Are Implemented
+ Fault %(class_name)s::execute(%(CPU_exec_context)s *xc, Trace::InstRecord *traceData) const
+ {
+ //Write the resulting state to the execution context
+ %(op_wb)s;
+
+ //Call into the trap handler with the appropriate fault
+ return No_Fault;
+ }
+}};
+
+def format Trap(code, *flags) {{
+ code = 'warn(\"'
+ code += 'Trap Exception Handler Is Currently Not Implemented.'
+ code += '\");'
+ iop = InstObjParams(name, Name, 'MipsStaticInst', CodeBlock(code), flags)
+ header_output = BasicDeclare.subst(iop)
+ decoder_output = BasicConstructor.subst(iop)
+ decode_block = BasicDecode.subst(iop)
+ exec_output = BasicExecute.subst(iop)
+}};
diff --git a/src/arch/mips/isa/formats/unimp.isa b/src/arch/mips/isa/formats/unimp.isa
new file mode 100644
index 000000000..03068fa74
--- /dev/null
+++ b/src/arch/mips/isa/formats/unimp.isa
@@ -0,0 +1,145 @@
+// -*- 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
+
+////////////////////////////////////////////////////////////////////
+//
+// Unimplemented instructions
+//
+
+output header {{
+ /**
+ * Static instruction class for unimplemented instructions that
+ * cause simulator termination. Note that these are recognized
+ * (legal) instructions that the simulator does not support; the
+ * 'Unknown' class is used for unrecognized/illegal instructions.
+ * This is a leaf class.
+ */
+ class FailUnimplemented : public MipsStaticInst
+ {
+ public:
+ /// Constructor
+ FailUnimplemented(const char *_mnemonic, MachInst _machInst)
+ : MipsStaticInst(_mnemonic, _machInst, No_OpClass)
+ {
+ // don't call execute() (which panics) if we're on a
+ // speculative path
+ flags[IsNonSpeculative] = true;
+ }
+
+ %(BasicExecDeclare)s
+
+ std::string
+ generateDisassembly(Addr pc, const SymbolTable *symtab) const;
+ };
+
+ /**
+ * Base class for unimplemented instructions that cause a warning
+ * to be printed (but do not terminate simulation). This
+ * implementation is a little screwy in that it will print a
+ * warning for each instance of a particular unimplemented machine
+ * instruction, not just for each unimplemented opcode. Should
+ * probably make the 'warned' flag a static member of the derived
+ * class.
+ */
+ class WarnUnimplemented : public MipsStaticInst
+ {
+ private:
+ /// Have we warned on this instruction yet?
+ mutable bool warned;
+
+ public:
+ /// Constructor
+ WarnUnimplemented(const char *_mnemonic, MachInst _machInst)
+ : MipsStaticInst(_mnemonic, _machInst, No_OpClass), warned(false)
+ {
+ // don't call execute() (which panics) if we're on a
+ // speculative path
+ flags[IsNonSpeculative] = true;
+ }
+
+ %(BasicExecDeclare)s
+
+ std::string
+ generateDisassembly(Addr pc, const SymbolTable *symtab) const;
+ };
+}};
+
+output decoder {{
+ std::string
+ FailUnimplemented::generateDisassembly(Addr pc,
+ const SymbolTable *symtab) const
+ {
+ return csprintf("%-10s (unimplemented)", mnemonic);
+ }
+
+ std::string
+ WarnUnimplemented::generateDisassembly(Addr pc,
+ const SymbolTable *symtab) const
+ {
+ return csprintf("%-10s (unimplemented)", mnemonic);
+ }
+}};
+
+output exec {{
+ Fault
+ FailUnimplemented::execute(%(CPU_exec_context)s *xc,
+ Trace::InstRecord *traceData) const
+ {
+ panic("attempt to execute unimplemented instruction '%s' "
+ "(inst 0x%08x, opcode 0x%x, binary:%s)", mnemonic, machInst, OPCODE,
+ inst2string(machInst));
+ return new UnimplementedOpcodeFault;
+ }
+
+ Fault
+ WarnUnimplemented::execute(%(CPU_exec_context)s *xc,
+ Trace::InstRecord *traceData) const
+ {
+ if (!warned) {
+ warn("\tinstruction '%s' unimplemented\n", mnemonic);
+ warned = true;
+ }
+
+ return NoFault;
+ }
+}};
+
+
+def format FailUnimpl() {{
+ iop = InstObjParams(name, 'FailUnimplemented')
+ decode_block = BasicDecodeWithMnemonic.subst(iop)
+}};
+
+def format WarnUnimpl() {{
+ iop = InstObjParams(name, 'WarnUnimplemented')
+ decode_block = BasicDecodeWithMnemonic.subst(iop)
+}};
+
diff --git a/src/arch/mips/isa/formats/unknown.isa b/src/arch/mips/isa/formats/unknown.isa
new file mode 100644
index 000000000..70b3901e9
--- /dev/null
+++ b/src/arch/mips/isa/formats/unknown.isa
@@ -0,0 +1,84 @@
+// -*- 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
+
+////////////////////////////////////////////////////////////////////
+//
+// Unknown instructions
+//
+
+output header {{
+ /**
+ * Static instruction class for unknown (illegal) instructions.
+ * These cause simulator termination if they are executed in a
+ * non-speculative mode. This is a leaf class.
+ */
+ class Unknown : public MipsStaticInst
+ {
+ public:
+ /// Constructor
+ Unknown(MachInst _machInst)
+ : MipsStaticInst("unknown", _machInst, No_OpClass)
+ {
+ // don't call execute() (which panics) if we're on a
+ // speculative path
+ flags[IsNonSpeculative] = true;
+ }
+
+ %(BasicExecDeclare)s
+
+ std::string
+ generateDisassembly(Addr pc, const SymbolTable *symtab) const;
+ };
+}};
+
+output decoder {{
+ std::string
+ Unknown::generateDisassembly(Addr pc, const SymbolTable *symtab) const
+ {
+ return csprintf("%-10s (inst 0x%x, opcode 0x%x, binary:%s)",
+ "unknown", machInst, OPCODE, inst2string(machInst));
+ }
+}};
+
+output exec {{
+ Fault
+ Unknown::execute(%(CPU_exec_context)s *xc,
+ Trace::InstRecord *traceData) const
+ {
+ panic("attempt to execute unknown instruction "
+ "(inst 0x%08x, opcode 0x%x, binary: %s)", machInst, OPCODE, inst2string(machInst));
+ return new UnimplementedOpcodeFault;
+ }
+}};
+
+def format Unknown() {{
+ decode_block = 'return new Unknown(machInst);\n'
+}};
+
diff --git a/src/arch/mips/isa/formats/util.isa b/src/arch/mips/isa/formats/util.isa
new file mode 100644
index 000000000..73164bc0d
--- /dev/null
+++ b/src/arch/mips/isa/formats/util.isa
@@ -0,0 +1,189 @@
+// -*- 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: Steve Reinhardt
+// Korey Sewell
+
+let {{
+def LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags,
+ postacc_code = '', base_class = 'Memory',
+ decode_template = BasicDecode, exec_template_base = ''):
+ # Make sure flags are in lists (convert to lists if not).
+ mem_flags = makeList(mem_flags)
+ inst_flags = makeList(inst_flags)
+
+ # add hook to get effective addresses into execution trace output.
+ ea_code += '\nif (traceData) { traceData->setAddr(EA); }\n'
+
+ # generate code block objects
+ ea_cblk = CodeBlock(ea_code)
+ memacc_cblk = CodeBlock(memacc_code)
+ postacc_cblk = CodeBlock(postacc_code)
+
+ # Some CPU models execute the memory operation as an atomic unit,
+ # while others want to separate them into an effective address
+ # computation and a memory access operation. As a result, we need
+ # to generate three StaticInst objects. Note that the latter two
+ # are nested inside the larger "atomic" one.
+
+ # generate InstObjParams for EAComp object
+ ea_iop = InstObjParams(name, Name, base_class, ea_cblk, inst_flags)
+
+ # generate InstObjParams for MemAcc object
+ memacc_iop = InstObjParams(name, Name, base_class, memacc_cblk, inst_flags)
+ # in the split execution model, the MemAcc portion is responsible
+ # for the post-access code.
+ memacc_iop.postacc_code = postacc_cblk.code
+
+ # generate InstObjParams for InitiateAcc, CompleteAcc object
+ # The code used depends on the template being used
+ if (exec_template_base == 'Load'):
+ initiateacc_cblk = CodeBlock(ea_code + memacc_code)
+ completeacc_cblk = CodeBlock(memacc_code + postacc_code)
+ elif (exec_template_base.startswith('Store')):
+ initiateacc_cblk = CodeBlock(ea_code + memacc_code)
+ completeacc_cblk = CodeBlock(postacc_code)
+ else:
+ initiateacc_cblk = ''
+ completeacc_cblk = ''
+
+ initiateacc_iop = InstObjParams(name, Name, base_class, initiateacc_cblk,
+ inst_flags)
+
+ completeacc_iop = InstObjParams(name, Name, base_class, completeacc_cblk,
+ inst_flags)
+
+ if (exec_template_base == 'Load'):
+ initiateacc_iop.ea_code = ea_cblk.code
+ initiateacc_iop.memacc_code = memacc_cblk.code
+ completeacc_iop.memacc_code = memacc_cblk.code
+ completeacc_iop.postacc_code = postacc_cblk.code
+ elif (exec_template_base.startswith('Store')):
+ initiateacc_iop.ea_code = ea_cblk.code
+ initiateacc_iop.memacc_code = memacc_cblk.code
+ completeacc_iop.postacc_code = postacc_cblk.code
+
+ # generate InstObjParams for unified execution
+ cblk = CodeBlock(ea_code + memacc_code + postacc_code)
+ iop = InstObjParams(name, Name, base_class, cblk, inst_flags)
+
+ iop.ea_constructor = ea_cblk.constructor
+ iop.ea_code = ea_cblk.code
+ iop.memacc_constructor = memacc_cblk.constructor
+ iop.memacc_code = memacc_cblk.code
+ iop.postacc_code = postacc_cblk.code
+
+ if mem_flags:
+ s = '\n\tmemAccessFlags = ' + string.join(mem_flags, '|') + ';'
+ iop.constructor += s
+ memacc_iop.constructor += s
+
+ # select templates
+
+ # define aliases... most StoreCond templates are the same as the
+ # corresponding Store templates (only CompleteAcc is different).
+ StoreCondMemAccExecute = StoreMemAccExecute
+ StoreCondExecute = StoreExecute
+ StoreCondInitiateAcc = StoreInitiateAcc
+
+ memAccExecTemplate = eval(exec_template_base + 'MemAccExecute')
+ fullExecTemplate = eval(exec_template_base + 'Execute')
+ initiateAccTemplate = eval(exec_template_base + 'InitiateAcc')
+ completeAccTemplate = eval(exec_template_base + 'CompleteAcc')
+
+ # (header_output, decoder_output, decode_block, exec_output)
+ return (LoadStoreDeclare.subst(iop), LoadStoreConstructor.subst(iop),
+ decode_template.subst(iop),
+ EACompExecute.subst(ea_iop)
+ + memAccExecTemplate.subst(memacc_iop)
+ + fullExecTemplate.subst(iop)
+ + initiateAccTemplate.subst(initiateacc_iop)
+ + completeAccTemplate.subst(completeacc_iop))
+}};
+output header {{
+ std::string inst2string(MachInst machInst);
+}};
+
+output decoder {{
+
+std::string inst2string(MachInst machInst)
+{
+ std::string str = "";
+ uint32_t mask = 0x80000000;
+
+ for(int i=0; i < 32; i++) {
+ if ((machInst & mask) == 0) {
+ str += "0";
+ } else {
+ str += "1";
+ }
+
+ mask = mask >> 1;
+ }
+
+ return str;
+}
+
+}};
+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
+
+
+
+}};
+
+
diff --git a/src/arch/mips/isa/includes.isa b/src/arch/mips/isa/includes.isa
new file mode 100644
index 000000000..f58c8adaa
--- /dev/null
+++ b/src/arch/mips/isa/includes.isa
@@ -0,0 +1,82 @@
+// -*- 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
+
+////////////////////////////////////////////////////////////////////
+//
+// Output include file directives.
+//
+
+output header {{
+#include <sstream>
+#include <iostream>
+#include <iomanip>
+
+#include "cpu/static_inst.hh"
+#include "arch/mips/isa_traits.hh"
+}};
+
+output decoder {{
+#include "arch/mips/isa_traits.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/utility.hh"
+
+#include <math.h>
+#if defined(linux)
+#include <fenv.h>
+#endif
+
+using namespace MipsISA;
+}};
+
+output exec {{
+#include "arch/mips/faults.hh"
+#include "arch/mips/isa_traits.hh"
+#include "arch/mips/utility.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 "sim/sim_exit.hh"
+#include "mem/packet_impl.hh"
+
+using namespace MipsISA;
+}};
+
diff --git a/src/arch/mips/isa/main.isa b/src/arch/mips/isa/main.isa
new file mode 100644
index 000000000..2d7c63cd5
--- /dev/null
+++ b/src/arch/mips/isa/main.isa
@@ -0,0 +1,61 @@
+// -*- 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
+
+////////////////////////////////////////////////////////////////////
+//
+// MIPS ISA description file.
+//
+////////////////////////////////////////////////////////////////////
+
+//Include the C++ include directives
+##include "includes.isa"
+
+////////////////////////////////////////////////////////////////////
+//
+// Namespace statement. Everything below this line will be in the
+// MipsISAInst namespace.
+//
+
+namespace MipsISA;
+
+//Include the bitfield definitions
+##include "bitfields.isa"
+
+//Include the operand_types and operand definitions
+##include "operands.isa"
+
+//Include the base class for mips instructions, and some support code
+##include "base.isa"
+
+//Include the definitions for the instruction formats
+##include "formats/formats.isa"
+
+//Include the decoder definition
+##include "decoder.isa"
diff --git a/src/arch/mips/isa/operands.isa b/src/arch/mips/isa/operands.isa
new file mode 100644
index 000000000..3843dc053
--- /dev/null
+++ b/src/arch/mips/isa/operands.isa
@@ -0,0 +1,91 @@
+// -*- 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
+
+def operand_types {{
+ 'sb' : ('signed int', 8),
+ 'ub' : ('unsigned int', 8),
+ 'sh' : ('signed int', 16),
+ 'uh' : ('unsigned int', 16),
+ 'sw' : ('signed int', 32),
+ 'uw' : ('unsigned int', 32),
+ 'sd' : ('signed int', 64),
+ 'ud' : ('unsigned int', 64),
+ 'sf' : ('float', 32),
+ 'df' : ('float', 64),
+ 'qf' : ('float', 128)
+}};
+
+def operands {{
+ #General Purpose Integer Reg Operands
+ 'Rd': ('IntReg', 'uw', 'RD', 'IsInteger', 1),
+ 'Rs': ('IntReg', 'uw', 'RS', 'IsInteger', 2),
+ 'Rt': ('IntReg', 'uw', 'RT', '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),
+
+ #Immediate Value operand
+ 'IntImm': ('IntReg', 'uw', 'INTIMM', 'IsInteger', 3),
+
+ #Floating Point Reg Operands
+ 'Fd': ('FloatReg', 'sf', 'FD', 'IsFloating', 1),
+ 'Fs': ('FloatReg', 'sf', 'FS', 'IsFloating', 2),
+ 'Ft': ('FloatReg', 'sf', 'FT', 'IsFloating', 3),
+ 'Fr': ('FloatReg', 'sf', 'FR', 'IsFloating', 3),
+
+ #Special 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
+ 'Fd1': ('FloatReg', 'sf', 'FD', 'IsFloating', 4),
+ 'Fd2': ('FloatReg', 'sf', 'FD+1', 'IsFloating', 4),
+ 'Fs1': ('FloatReg', 'sf', 'FS', 'IsFloating', 5),
+ 'Fs2': ('FloatReg', 'sf', 'FS+1', 'IsFloating', 5),
+ 'Ft1': ('FloatReg', 'sf', 'FT', 'IsFloating', 6),
+ 'Ft2': ('FloatReg', 'sf', 'FT+1', 'IsFloating', 6),
+ 'Fr1': ('FloatReg', 'sf', 'FR', 'IsFloating', 7),
+ 'Fr2': ('FloatReg', 'sf', 'FR+1', 'IsFloating', 7),
+
+ #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)
+}};
diff --git a/src/arch/mips/isa_traits.cc b/src/arch/mips/isa_traits.cc
new file mode 100644
index 000000000..3a8cb46a5
--- /dev/null
+++ b/src/arch/mips/isa_traits.cc
@@ -0,0 +1,98 @@
+/*
+ * 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: Gabe Black
+ * Korey Sewell
+ */
+
+#include "arch/mips/isa_traits.hh"
+#include "arch/mips/regfile/regfile.hh"
+#include "sim/serialize.hh"
+#include "base/bitfield.hh"
+
+using namespace MipsISA;
+using namespace std;
+
+void
+MipsISA::copyRegs(ThreadContext *src, ThreadContext *dest)
+{
+ panic("Copy Regs Not Implemented Yet\n");
+}
+
+void
+MipsISA::copyMiscRegs(ThreadContext *src, ThreadContext *dest)
+{
+ panic("Copy Misc. Regs Not Implemented Yet\n");
+}
+
+void
+MipsISA::MiscRegFile::copyMiscRegs(ThreadContext *tc)
+{
+ panic("Copy Misc. Regs Not Implemented Yet\n");
+}
+
+void
+IntRegFile::serialize(std::ostream &os)
+{
+ SERIALIZE_ARRAY(regs, NumIntRegs);
+}
+
+void
+IntRegFile::unserialize(Checkpoint *cp, const std::string &section)
+{
+ UNSERIALIZE_ARRAY(regs, NumIntRegs);
+}
+
+void
+RegFile::serialize(std::ostream &os)
+{
+ intRegFile.serialize(os);
+ //SERIALIZE_ARRAY(floatRegFile, NumFloatRegs);
+ //SERIALZE_ARRAY(miscRegFile);
+ //SERIALIZE_SCALAR(miscRegs.fpcr);
+ //SERIALIZE_SCALAR(miscRegs.lock_flag);
+ //SERIALIZE_SCALAR(miscRegs.lock_addr);
+ SERIALIZE_SCALAR(pc);
+ SERIALIZE_SCALAR(npc);
+ SERIALIZE_SCALAR(nnpc);
+}
+
+
+void
+RegFile::unserialize(Checkpoint *cp, const std::string &section)
+{
+ intRegFile.unserialize(cp, section);
+ //UNSERIALIZE_ARRAY(floatRegFile);
+ //UNSERIALZE_ARRAY(miscRegFile);
+ //UNSERIALIZE_SCALAR(miscRegs.fpcr);
+ //UNSERIALIZE_SCALAR(miscRegs.lock_flag);
+ //UNSERIALIZE_SCALAR(miscRegs.lock_addr);
+ UNSERIALIZE_SCALAR(pc);
+ UNSERIALIZE_SCALAR(npc);
+ UNSERIALIZE_SCALAR(nnpc);
+
+}
diff --git a/src/arch/mips/isa_traits.hh b/src/arch/mips/isa_traits.hh
new file mode 100644
index 000000000..f85fc5bea
--- /dev/null
+++ b/src/arch/mips/isa_traits.hh
@@ -0,0 +1,124 @@
+/*
+ * 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: Gabe Black
+ * Korey Sewell
+ */
+
+#ifndef __ARCH_MIPS_ISA_TRAITS_HH__
+#define __ARCH_MIPS_ISA_TRAITS_HH__
+
+#include "arch/mips/types.hh"
+#include "sim/host.hh"
+
+namespace LittleEndianGuest {};
+
+#define TARGET_MIPS
+
+class StaticInstPtr;
+
+namespace MipsISA
+{
+ using namespace LittleEndianGuest;
+
+ StaticInstPtr decodeInst(ExtMachInst);
+
+ // MIPS DOES a delay slot
+ #define ISA_HAS_DELAY_SLOT 1
+
+ const Addr PageShift = 13;
+ const Addr PageBytes = ULL(1) << PageShift;
+ const Addr PageMask = ~(PageBytes - 1);
+ const Addr PageOffset = PageBytes - 1;
+
+ // return a no-op instruction... used for instruction fetch faults
+ const ExtMachInst NoopMachInst = 0x00000000;
+
+ // Constants Related to the number of registers
+ const int NumIntArchRegs = 32;
+ const int NumIntSpecialRegs = 2;
+ 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;
+
+ // semantically meaningful register indices
+ const int ZeroReg = 0;
+ const int AssemblerReg = 1;
+ const int ReturnValueReg = 2;
+ const int ReturnValueReg1 = 2;
+ const int ReturnValueReg2 = 3;
+ const int ArgumentReg0 = 4;
+ const int ArgumentReg1 = 5;
+ const int ArgumentReg2 = 6;
+ const int ArgumentReg3 = 7;
+ const int KernelReg0 = 26;
+ const int KernelReg1 = 27;
+ const int GlobalPointerReg = 28;
+ const int StackPointerReg = 29;
+ const int FramePointerReg = 30;
+ const int ReturnAddressReg = 31;
+
+ const int SyscallNumReg = ReturnValueReg1;
+ const int SyscallPseudoReturnReg = ReturnValueReg1;
+ const int SyscallSuccessReg = ArgumentReg3;
+
+ const int LogVMPageSize = 13; // 8K bytes
+ const int VMPageSize = (1 << LogVMPageSize);
+
+ const int BranchPredAddrShiftAmt = 2; // instructions are 4-byte aligned
+
+ const int MachineBytes = 4;
+ const int WordBytes = 4;
+ 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;
+
+};
+
+using namespace MipsISA;
+
+#endif // __ARCH_MIPS_ISA_TRAITS_HH__
diff --git a/src/arch/mips/linux/linux.cc b/src/arch/mips/linux/linux.cc
new file mode 100644
index 000000000..90404af53
--- /dev/null
+++ b/src/arch/mips/linux/linux.cc
@@ -0,0 +1,74 @@
+/*
+ * 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 "arch/mips/linux/linux.hh"
+
+#include <fcntl.h>
+
+// open(2) flags translation table
+OpenFlagTransTable MipsLinux::openFlagTable[] = {
+#ifdef _MSC_VER
+ { MipsLinux::TGT_O_RDONLY, _O_RDONLY },
+ { MipsLinux::TGT_O_WRONLY, _O_WRONLY },
+ { MipsLinux::TGT_O_RDWR, _O_RDWR },
+ { MipsLinux::TGT_O_APPEND, _O_APPEND },
+ { MipsLinux::TGT_O_CREAT, _O_CREAT },
+ { MipsLinux::TGT_O_TRUNC, _O_TRUNC },
+ { MipsLinux::TGT_O_EXCL, _O_EXCL },
+#ifdef _O_NONBLOCK
+ { MipsLinux::TGT_O_NONBLOCK, _O_NONBLOCK },
+#endif
+#ifdef _O_NOCTTY
+ { MipsLinux::TGT_O_NOCTTY, _O_NOCTTY },
+#endif
+#ifdef _O_SYNC
+ { MipsLinux::TGT_O_SYNC, _O_SYNC },
+#endif
+#else /* !_MSC_VER */
+ { MipsLinux::TGT_O_RDONLY, O_RDONLY },
+ { MipsLinux::TGT_O_WRONLY, O_WRONLY },
+ { MipsLinux::TGT_O_RDWR, O_RDWR },
+ { MipsLinux::TGT_O_APPEND, O_APPEND },
+ { MipsLinux::TGT_O_CREAT, O_CREAT },
+ { MipsLinux::TGT_O_TRUNC, O_TRUNC },
+ { MipsLinux::TGT_O_EXCL, O_EXCL },
+ { MipsLinux::TGT_O_NONBLOCK, O_NONBLOCK },
+ { MipsLinux::TGT_O_NOCTTY, O_NOCTTY },
+#ifdef O_SYNC
+ { MipsLinux::TGT_O_SYNC, O_SYNC },
+#endif
+#endif /* _MSC_VER */
+};
+
+const int MipsLinux::NUM_OPEN_FLAGS =
+ (sizeof(MipsLinux::openFlagTable)/sizeof(MipsLinux::openFlagTable[0]));
+
+
+
diff --git a/src/arch/mips/linux/linux.hh b/src/arch/mips/linux/linux.hh
new file mode 100644
index 000000000..f85935bb9
--- /dev/null
+++ b/src/arch/mips/linux/linux.hh
@@ -0,0 +1,126 @@
+/*
+ * 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_LINUX_LINUX_HH__
+#define __ARCH_MIPS_LINUX_LINUX_HH__
+
+#include "kern/linux/linux.hh"
+
+class MipsLinux : public Linux
+{
+ public:
+
+ /// This table maps the target open() flags to the corresponding
+ /// host open() flags.
+ static OpenFlagTransTable openFlagTable[];
+
+ /// Number of entries in openFlagTable[].
+ static const int NUM_OPEN_FLAGS;
+
+ //@{
+ /// open(2) flag values.
+ static const int TGT_O_RDONLY = 0x00000000; //!< O_RDONLY
+ static const int TGT_O_WRONLY = 0x00000001; //!< O_WRONLY
+ static const int TGT_O_RDWR = 0x00000002; //!< O_RDWR
+ static const int TGT_O_NONBLOCK = 0x00000080; //!< O_NONBLOCK
+ static const int TGT_O_APPEND = 0x00000008; //!< O_APPEND
+ static const int TGT_O_CREAT = 0x00000100; //!< O_CREAT
+ static const int TGT_O_TRUNC = 0x00000200; //!< O_TRUNC
+ static const int TGT_O_EXCL = 0x00000400; //!< O_EXCL
+ static const int TGT_O_NOCTTY = 0x00000800; //!< O_NOCTTY
+ static const int TGT_O_SYNC = 0x00000010; //!< O_SYNC
+ static const int TGT_O_DRD = 0x00010000; //!< O_DRD
+ static const int TGT_O_DIRECTIO = 0x00020000; //!< O_DIRECTIO
+ static const int TGT_O_CACHE = 0x00002000; //!< O_CACHE
+ static const int TGT_O_DSYNC = 0x00008000; //!< O_DSYNC
+ static const int TGT_O_RSYNC = 0x00040000; //!< O_RSYNC
+ //@}
+
+ /// For mmap().
+ static const unsigned TGT_MAP_ANONYMOUS = 0x800;
+
+ //@{
+ /// For getsysinfo().
+ static const unsigned GSI_PLATFORM_NAME = 103; //!< platform name as string
+ static const unsigned GSI_CPU_INFO = 59; //!< CPU information
+ static const unsigned GSI_PROC_TYPE = 60; //!< get proc_type
+ static const unsigned GSI_MAX_CPU = 30; //!< max # cpu's on this machine
+ static const unsigned GSI_CPUS_IN_BOX = 55; //!< number of CPUs in system
+ static const unsigned GSI_PHYSMEM = 19; //!< Physical memory in KB
+ static const unsigned GSI_CLK_TCK = 42; //!< clock freq in Hz
+ //@}
+
+ //@{
+ /// For getrusage().
+ static const int TGT_RUSAGE_SELF = 0;
+ static const int TGT_RUSAGE_CHILDREN = -1;
+ static const int TGT_RUSAGE_BOTH = -2;
+ //@}
+
+ //@{
+ /// For setsysinfo().
+ static const unsigned SSI_IEEE_FP_CONTROL = 14; //!< ieee_set_fp_control()
+ //@}
+
+ //@{
+ /// 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;
+ //@}
+
+ /// For table().
+ static const int TBL_SYSINFO = 12;
+
+ /// Resource enumeration for getrlimit().
+ enum rlimit_resources {
+ TGT_RLIMIT_CPU = 0,
+ TGT_RLIMIT_FSIZE = 1,
+ TGT_RLIMIT_DATA = 2,
+ TGT_RLIMIT_STACK = 3,
+ TGT_RLIMIT_CORE = 4,
+ TGT_RLIMIT_NOFILE = 5,
+ TGT_RLIMIT_AS = 6,
+ TGT_RLIMIT_RSS = 7,
+ TGT_RLIMIT_VMEM = 7,
+ TGT_RLIMIT_NPROC = 8,
+ TGT_RLIMIT_MEMLOCK = 9,
+ TGT_RLIMIT_LOCKS = 10
+ };
+
+};
+
+#endif
diff --git a/src/arch/mips/linux/process.cc b/src/arch/mips/linux/process.cc
new file mode 100644
index 000000000..d182cfa30
--- /dev/null
+++ b/src/arch/mips/linux/process.cc
@@ -0,0 +1,435 @@
+/*
+ * 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: Korey Sewell
+ */
+
+#include "arch/mips/linux/linux.hh"
+#include "arch/mips/linux/process.hh"
+#include "arch/mips/isa_traits.hh"
+
+#include "base/trace.hh"
+#include "cpu/thread_context.hh"
+#include "kern/linux/linux.hh"
+
+#include "sim/process.hh"
+#include "sim/syscall_emul.hh"
+
+using namespace std;
+using namespace MipsISA;
+
+/// Target uname() handler.
+static SyscallReturn
+unameFunc(SyscallDesc *desc, int callnum, LiveProcess *process,
+ ThreadContext *tc)
+{
+ TypedBufferArg<Linux::utsname> name(tc->getSyscallArg(0));
+
+ strcpy(name->sysname, "Linux");
+ 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");
+
+ name.copyOut(tc->getMemPort());
+ return 0;
+}
+
+/// Target sys_getsysyinfo() handler. Even though this call is
+/// borrowed from Tru64, the subcases that get used appear to be
+/// different in practice from those used by Tru64 processes.
+static SyscallReturn
+sys_getsysinfoFunc(SyscallDesc *desc, int callnum, LiveProcess *process,
+ ThreadContext *tc)
+{
+ unsigned op = tc->getSyscallArg(0);
+ // unsigned nbytes = tc->getSyscallArg(2);
+
+ switch (op) {
+
+ case 45: { // GSI_IEEE_FP_CONTROL
+ TypedBufferArg<uint64_t> fpcr(tc->getSyscallArg(1));
+ // I don't think this exactly matches the HW FPCR
+ *fpcr = 0;
+ fpcr.copyOut(tc->getMemPort());
+ return 0;
+ }
+
+ default:
+ cerr << "sys_getsysinfo: unknown op " << op << endl;
+ abort();
+ break;
+ }
+
+ return 1;
+}
+
+/// Target sys_setsysinfo() handler.
+static SyscallReturn
+sys_setsysinfoFunc(SyscallDesc *desc, int callnum, LiveProcess *process,
+ ThreadContext *tc)
+{
+ unsigned op = tc->getSyscallArg(0);
+ // unsigned nbytes = tc->getSyscallArg(2);
+
+ switch (op) {
+
+ case 14: { // SSI_IEEE_FP_CONTROL
+ TypedBufferArg<uint64_t> fpcr(tc->getSyscallArg(1));
+ // I don't think this exactly matches the HW FPCR
+ fpcr.copyIn(tc->getMemPort());
+ DPRINTFR(SyscallVerbose, "sys_setsysinfo(SSI_IEEE_FP_CONTROL): "
+ " setting FPCR to 0x%x\n", gtoh(*(uint64_t*)fpcr));
+ return 0;
+ }
+
+ default:
+ cerr << "sys_setsysinfo: unknown op " << op << endl;
+ abort();
+ break;
+ }
+
+ return 1;
+}
+
+
+SyscallDesc MipsLinuxProcess::syscallDescs[] = {
+ /* 0 */ SyscallDesc("syscall", unimplementedFunc),
+ /* 1 */ SyscallDesc("exit", exitFunc),
+ /* 2 */ SyscallDesc("fork", unimplementedFunc),
+ /* 3 */ SyscallDesc("read", readFunc),
+ /* 4 */ SyscallDesc("write", writeFunc),
+ /* 5 */ SyscallDesc("open", openFunc<MipsLinux>),
+ /* 6 */ SyscallDesc("close", closeFunc),
+ /* 7 */ SyscallDesc("waitpid", unimplementedFunc),
+ /* 8 */ SyscallDesc("creat", unimplementedFunc),
+ /* 9 */ SyscallDesc("link", unimplementedFunc),
+ /* 10 */ SyscallDesc("unlink", unlinkFunc),
+ /* 11 */ SyscallDesc("execve", unimplementedFunc),
+ /* 12 */ SyscallDesc("chdir", unimplementedFunc),
+ /* 13 */ SyscallDesc("time", unimplementedFunc),
+ /* 14 */ SyscallDesc("mknod", unimplementedFunc),
+ /* 15 */ SyscallDesc("chmod", chmodFunc<MipsLinux>),
+ /* 16 */ SyscallDesc("lchown", chownFunc),
+ /* 17 */ SyscallDesc("break", obreakFunc),
+ /* 18 */ SyscallDesc("unused#18", unimplementedFunc),
+ /* 19 */ SyscallDesc("lseek", lseekFunc),
+ /* 20 */ SyscallDesc("getpid", getpidFunc),
+ /* 21 */ SyscallDesc("mount", unimplementedFunc),
+ /* 22 */ SyscallDesc("umount", unimplementedFunc),
+ /* 23 */ SyscallDesc("setuid", setuidFunc),
+ /* 24 */ SyscallDesc("getuid", getuidFunc),
+ /* 25 */ SyscallDesc("stime", unimplementedFunc),
+ /* 26 */ SyscallDesc("ptrace", unimplementedFunc),
+ /* 27 */ SyscallDesc("alarm", unimplementedFunc),
+ /* 28 */ SyscallDesc("unused#28", unimplementedFunc),
+ /* 29 */ SyscallDesc("pause", unimplementedFunc),
+ /* 30 */ SyscallDesc("utime", unimplementedFunc),
+ /* 31 */ SyscallDesc("stty", unimplementedFunc),
+ /* 32 */ SyscallDesc("gtty", unimplementedFunc),
+ /* 33 */ SyscallDesc("access", unimplementedFunc),
+ /* 34 */ SyscallDesc("nice", unimplementedFunc),
+ /* 35 */ SyscallDesc("ftime", unimplementedFunc),
+ /* 36 */ SyscallDesc("sync", unimplementedFunc),
+ /* 37 */ SyscallDesc("kill", ignoreFunc),
+ /* 38 */ SyscallDesc("rename", unimplementedFunc),
+ /* 39 */ SyscallDesc("mkdir", unimplementedFunc),
+ /* 40 */ SyscallDesc("rmdir", unimplementedFunc),
+ /* 41 */ SyscallDesc("dup", unimplementedFunc),
+ /* 42 */ SyscallDesc("pipe", unimplementedFunc),
+ /* 43 */ SyscallDesc("times", unimplementedFunc),
+ /* 44 */ SyscallDesc("prof", unimplementedFunc),
+ /* 45 */ SyscallDesc("brk", obreakFunc),
+ /* 46 */ SyscallDesc("setgid", unimplementedFunc),
+ /* 47 */ SyscallDesc("getgid", getgidFunc),
+ /* 48 */ SyscallDesc("signal", ignoreFunc),
+ /* 49 */ SyscallDesc("geteuid", geteuidFunc),
+ /* 50 */ SyscallDesc("getegid", getegidFunc),
+ /* 51 */ SyscallDesc("acct", unimplementedFunc),
+ /* 52 */ SyscallDesc("umount2", unimplementedFunc),
+ /* 53 */ SyscallDesc("lock", unimplementedFunc),
+ /* 54 */ SyscallDesc("ioctl", ioctlFunc<MipsLinux>),
+ /* 55 */ SyscallDesc("fcntl", fcntlFunc),
+ /* 56 */ SyscallDesc("mpx", unimplementedFunc),
+ /* 57 */ SyscallDesc("setpgid", unimplementedFunc),
+ /* 58 */ SyscallDesc("ulimit", unimplementedFunc),
+ /* 59 */ SyscallDesc("unused#59", unimplementedFunc),
+ /* 60 */ SyscallDesc("umask", unimplementedFunc),
+ /* 61 */ SyscallDesc("chroot", unimplementedFunc),
+ /* 62 */ SyscallDesc("ustat", unimplementedFunc),
+ /* 63 */ SyscallDesc("dup2", unimplementedFunc),
+ /* 64 */ SyscallDesc("getppid", getpagesizeFunc),
+ /* 65 */ SyscallDesc("getpgrp", unimplementedFunc),
+ /* 66 */ SyscallDesc("setsid", unimplementedFunc),
+ /* 67 */ SyscallDesc("sigaction",unimplementedFunc),
+ /* 68 */ SyscallDesc("sgetmask", unimplementedFunc),
+ /* 69 */ SyscallDesc("ssetmask", unimplementedFunc),
+ /* 70 */ SyscallDesc("setreuid", unimplementedFunc),
+ /* 71 */ SyscallDesc("setregid", unimplementedFunc),
+ /* 72 */ SyscallDesc("sigsuspend", unimplementedFunc),
+ /* 73 */ SyscallDesc("sigpending", unimplementedFunc),
+ /* 74 */ SyscallDesc("sethostname", ignoreFunc),
+ /* 75 */ SyscallDesc("setrlimit", unimplementedFunc),
+ /* 76 */ SyscallDesc("getrlimit", unimplementedFunc),
+ /* 77 */ SyscallDesc("getrusage", unimplementedFunc),
+ /* 78 */ SyscallDesc("gettimeofday", unimplementedFunc),
+ /* 79 */ SyscallDesc("settimeofday", unimplementedFunc),
+ /* 80 */ SyscallDesc("getgroups", unimplementedFunc),
+ /* 81 */ SyscallDesc("setgroups", unimplementedFunc),
+ /* 82 */ SyscallDesc("reserved#82", unimplementedFunc),
+ /* 83 */ SyscallDesc("symlink", unimplementedFunc),
+ /* 84 */ SyscallDesc("unused#84", unimplementedFunc),
+ /* 85 */ SyscallDesc("readlink", unimplementedFunc),
+ /* 86 */ SyscallDesc("uselib", unimplementedFunc),
+ /* 87 */ SyscallDesc("swapon", gethostnameFunc),
+ /* 88 */ SyscallDesc("reboot", unimplementedFunc),
+ /* 89 */ SyscallDesc("readdir", unimplementedFunc),
+ /* 90 */ SyscallDesc("mmap", mmapFunc<MipsLinux>),
+ /* 91 */ SyscallDesc("munmap",munmapFunc),
+ /* 92 */ SyscallDesc("truncate", truncateFunc),
+ /* 93 */ SyscallDesc("ftruncate", ftruncateFunc),
+ /* 94 */ SyscallDesc("fchmod", unimplementedFunc),
+ /* 95 */ SyscallDesc("fchown", unimplementedFunc),
+ /* 96 */ SyscallDesc("getpriority", unimplementedFunc),
+ /* 97 */ SyscallDesc("setpriority", unimplementedFunc),
+ /* 98 */ SyscallDesc("profil", unimplementedFunc),
+ /* 99 */ SyscallDesc("statfs", unimplementedFunc),
+ /* 100 */ SyscallDesc("fstatfs", unimplementedFunc),
+ /* 101 */ SyscallDesc("ioperm", unimplementedFunc),
+ /* 102 */ SyscallDesc("socketcall", unimplementedFunc),
+ /* 103 */ SyscallDesc("syslog", unimplementedFunc),
+ /* 104 */ SyscallDesc("setitimer", unimplementedFunc),
+ /* 105 */ SyscallDesc("getitimer", unimplementedFunc),
+ /* 106 */ SyscallDesc("stat", statFunc<MipsLinux>),
+ /* 107 */ SyscallDesc("lstat", unimplementedFunc),
+ /* 108 */ SyscallDesc("fstat", fstatFunc<MipsLinux>),
+ /* 109 */ SyscallDesc("unused#109", unimplementedFunc),
+ /* 110 */ SyscallDesc("iopl", unimplementedFunc),
+ /* 111 */ SyscallDesc("vhangup", unimplementedFunc),
+ /* 112 */ SyscallDesc("idle", ignoreFunc),
+ /* 113 */ SyscallDesc("vm86", unimplementedFunc),
+ /* 114 */ SyscallDesc("wait4", unimplementedFunc),
+ /* 115 */ SyscallDesc("swapoff", unimplementedFunc),
+ /* 116 */ SyscallDesc("sysinfo", unimplementedFunc),
+ /* 117 */ SyscallDesc("ipc", unimplementedFunc),
+ /* 118 */ SyscallDesc("fsync", unimplementedFunc),
+ /* 119 */ SyscallDesc("sigreturn", unimplementedFunc),
+ /* 120 */ SyscallDesc("clone", unimplementedFunc),
+ /* 121 */ SyscallDesc("setdomainname", unimplementedFunc),
+ /* 122 */ SyscallDesc("uname", unameFunc),
+ /* 123 */ SyscallDesc("modify_ldt", unimplementedFunc),
+ /* 124 */ SyscallDesc("adjtimex", unimplementedFunc),
+ /* 125 */ SyscallDesc("mprotect", ignoreFunc),
+ /* 126 */ SyscallDesc("sigprocmask", unimplementedFunc),
+ /* 127 */ SyscallDesc("create_module", unimplementedFunc),
+ /* 128 */ SyscallDesc("init_module", unimplementedFunc),
+ /* 129 */ SyscallDesc("delete_module", unimplementedFunc),
+ /* 130 */ SyscallDesc("get_kernel_syms", unimplementedFunc),
+ /* 131 */ SyscallDesc("quotactl", unimplementedFunc),
+ /* 132 */ SyscallDesc("getpgid", unimplementedFunc),
+ /* 133 */ SyscallDesc("fchdir", unimplementedFunc),
+ /* 134 */ SyscallDesc("bdflush", unimplementedFunc),
+ /* 135 */ SyscallDesc("sysfs", unimplementedFunc),
+ /* 136 */ SyscallDesc("personality", unimplementedFunc),
+ /* 137 */ SyscallDesc("afs_syscall", unimplementedFunc),
+ /* 138 */ SyscallDesc("setfsuid", unimplementedFunc),
+ /* 139 */ SyscallDesc("setfsgid", unimplementedFunc),
+ /* 140 */ SyscallDesc("llseek", unimplementedFunc),
+ /* 141 */ SyscallDesc("getdents", unimplementedFunc),
+ /* 142 */ SyscallDesc("newselect", unimplementedFunc),
+ /* 143 */ SyscallDesc("flock", unimplementedFunc),
+ /* 144 */ SyscallDesc("msync", unimplementedFunc),
+ /* 145 */ SyscallDesc("readv", unimplementedFunc),
+ /* 146 */ SyscallDesc("writev", writevFunc<MipsLinux>),
+ /* 147 */ SyscallDesc("cacheflush", unimplementedFunc),
+ /* 148 */ SyscallDesc("cachectl", unimplementedFunc),
+ /* 149 */ SyscallDesc("sysmips", unimplementedFunc),
+ /* 150 */ SyscallDesc("unused#150", unimplementedFunc),
+ /* 151 */ SyscallDesc("getsid", unimplementedFunc),
+ /* 152 */ SyscallDesc("fdatasync", unimplementedFunc),
+ /* 153 */ SyscallDesc("sysctl", unimplementedFunc),
+ /* 154 */ SyscallDesc("mlock", unimplementedFunc),
+ /* 155 */ SyscallDesc("munlock", unimplementedFunc),
+ /* 156 */ SyscallDesc("mlockall", unimplementedFunc),
+ /* 157 */ SyscallDesc("munlockall", unimplementedFunc),
+ /* 158 */ SyscallDesc("sched_setparam", unimplementedFunc),
+ /* 159 */ SyscallDesc("sched_getparam", unimplementedFunc),
+ /* 160 */ SyscallDesc("sched_setscheduler", unimplementedFunc),
+ /* 161 */ SyscallDesc("sched_getscheduler", unimplementedFunc),
+ /* 162 */ SyscallDesc("sched_yield", unimplementedFunc),
+ /* 163 */ SyscallDesc("sched_get_prioritymax", unimplementedFunc),
+ /* 164 */ SyscallDesc("sched_get_priority_min", unimplementedFunc),
+ /* 165 */ SyscallDesc("sched_rr_get_interval", unimplementedFunc),
+ /* 166 */ SyscallDesc("nanosleep", unimplementedFunc),
+ /* 167 */ SyscallDesc("mremap", unimplementedFunc),
+ /* 168 */ SyscallDesc("accept", unimplementedFunc),
+ /* 169 */ SyscallDesc("bind", unimplementedFunc),
+ /* 170 */ SyscallDesc("connect", unimplementedFunc),
+ /* 171 */ SyscallDesc("getpeername", unimplementedFunc),
+ /* 172 */ SyscallDesc("getsockname", unimplementedFunc),
+ /* 173 */ SyscallDesc("getsockopt", unimplementedFunc),
+ /* 174 */ SyscallDesc("listen", unimplementedFunc),
+ /* 175 */ SyscallDesc("recv", unimplementedFunc),
+ /* 176 */ SyscallDesc("recvmsg", unimplementedFunc),
+ /* 177 */ SyscallDesc("send", unimplementedFunc),
+ /* 178 */ SyscallDesc("sendmsg", ignoreFunc),
+ /* 179 */ SyscallDesc("sendto", unimplementedFunc),
+ /* 180 */ SyscallDesc("setsockopt", unimplementedFunc),
+ /* 181 */ SyscallDesc("shutdown", unimplementedFunc),
+ /* 182 */ SyscallDesc("unknown #182", unimplementedFunc),
+ /* 183 */ SyscallDesc("socket", ignoreFunc),
+ /* 184 */ SyscallDesc("socketpair", unimplementedFunc),
+ /* 185 */ SyscallDesc("setresuid", unimplementedFunc),
+ /* 186 */ SyscallDesc("getresuid", unimplementedFunc),
+ /* 187 */ SyscallDesc("query_module", unimplementedFunc),
+ /* 188 */ SyscallDesc("poll", unimplementedFunc),
+ /* 189 */ SyscallDesc("nfsservctl", unimplementedFunc),
+ /* 190 */ SyscallDesc("setresgid", unimplementedFunc),
+ /* 191 */ SyscallDesc("getresgid", unimplementedFunc),
+ /* 192 */ SyscallDesc("prctl", unimplementedFunc),
+ /* 193 */ SyscallDesc("rt_sigreturn", unimplementedFunc),
+ /* 194 */ SyscallDesc("rt_sigaction", ignoreFunc),
+ /* 195 */ SyscallDesc("rt_sigprocmask", ignoreFunc),
+ /* 196 */ SyscallDesc("rt_sigpending", unimplementedFunc),
+ /* 197 */ SyscallDesc("rt_sigtimedwait", unimplementedFunc),
+ /* 198 */ SyscallDesc("rt_sigqueueinfo", ignoreFunc),
+ /* 199 */ SyscallDesc("rt_sigsuspend", unimplementedFunc),
+ /* 200 */ SyscallDesc("pread64", unimplementedFunc),
+ /* 201 */ SyscallDesc("pwrite64", unimplementedFunc),
+ /* 202 */ SyscallDesc("chown", unimplementedFunc),
+ /* 203 */ SyscallDesc("getcwd", unimplementedFunc),
+ /* 204 */ SyscallDesc("capget", unimplementedFunc),
+ /* 205 */ SyscallDesc("capset", unimplementedFunc),
+ /* 206 */ SyscallDesc("sigalstack", unimplementedFunc),
+ /* 207 */ SyscallDesc("sendfile", unimplementedFunc),
+ /* 208 */ SyscallDesc("getpmsg", unimplementedFunc),
+ /* 209 */ SyscallDesc("putpmsg", unimplementedFunc),
+ /* 210 */ SyscallDesc("mmap2", unimplementedFunc),
+ /* 211 */ SyscallDesc("truncate64", unimplementedFunc),
+ /* 212 */ SyscallDesc("ftruncate64", unimplementedFunc),
+ /* 213 */ SyscallDesc("stat64", unimplementedFunc),
+ /* 214 */ SyscallDesc("lstat64", lstat64Func<MipsLinux>),
+ /* 215 */ SyscallDesc("fstat64", fstat64Func<MipsLinux>),
+ /* 216 */ SyscallDesc("pivot_root", unimplementedFunc),
+ /* 217 */ SyscallDesc("mincore", unimplementedFunc),
+ /* 218 */ SyscallDesc("madvise", unimplementedFunc),
+ /* 219 */ SyscallDesc("getdents64", unimplementedFunc),
+ /* 220 */ SyscallDesc("fcntl64", fcntl64Func),
+ /* 221 */ SyscallDesc("reserved#221", unimplementedFunc),
+ /* 222 */ SyscallDesc("gettid", unimplementedFunc),
+ /* 223 */ SyscallDesc("readahead", unimplementedFunc),
+ /* 224 */ SyscallDesc("setxattr", unimplementedFunc),
+ /* 225 */ SyscallDesc("lsetxattr", unimplementedFunc),
+ /* 226 */ SyscallDesc("fsetxattr", unimplementedFunc),
+ /* 227 */ SyscallDesc("getxattr", unimplementedFunc),
+ /* 228 */ SyscallDesc("lgetxattr", unimplementedFunc),
+ /* 229 */ SyscallDesc("fgetxattr", unimplementedFunc),
+ /* 230 */ SyscallDesc("listxattr", unimplementedFunc),
+ /* 231 */ SyscallDesc("llistxattr", unimplementedFunc),
+ /* 232 */ SyscallDesc("flistxattr", unimplementedFunc),
+ /* 233 */ SyscallDesc("removexattr", unimplementedFunc),
+ /* 234 */ SyscallDesc("lremovexattr", unimplementedFunc),
+ /* 235 */ SyscallDesc("fremovexattr", ignoreFunc),
+ /* 236 */ SyscallDesc("tkill", unimplementedFunc),
+ /* 237 */ SyscallDesc("sendfile64", unimplementedFunc),
+ /* 238 */ SyscallDesc("futex", unimplementedFunc),
+ /* 239 */ SyscallDesc("sched_setaffinity", unimplementedFunc),
+ /* 240 */ SyscallDesc("sched_getaffinity", unimplementedFunc),
+ /* 241 */ SyscallDesc("io_setup", unimplementedFunc),
+ /* 242 */ SyscallDesc("io_destroy", unimplementedFunc),
+ /* 243 */ SyscallDesc("io_getevents", unimplementedFunc),
+ /* 244 */ SyscallDesc("io_submit", unimplementedFunc),
+ /* 245 */ SyscallDesc("io_cancel", unimplementedFunc),
+ /* 246 */ SyscallDesc("exit_group", exitFunc),
+ /* 247 */ SyscallDesc("lookup_dcookie", unimplementedFunc),
+ /* 248 */ SyscallDesc("epoll_create", unimplementedFunc),
+ /* 249 */ SyscallDesc("epoll_ctl", unimplementedFunc),
+ /* 250 */ SyscallDesc("epoll_wait", unimplementedFunc),
+ /* 251 */ SyscallDesc("remap_file_pages", unimplementedFunc),
+ /* 252 */ SyscallDesc("set_tid_address", unimplementedFunc),
+ /* 253 */ SyscallDesc("restart_syscall", unimplementedFunc),
+ /* 254 */ SyscallDesc("fadvise64", unimplementedFunc),
+ /* 255 */ SyscallDesc("statfs64", unimplementedFunc),
+ /* 256 */ SyscallDesc("fstafs64", unimplementedFunc),
+ /* 257 */ SyscallDesc("timer_create", sys_getsysinfoFunc),
+ /* 258 */ SyscallDesc("timer_settime", sys_setsysinfoFunc),
+ /* 259 */ SyscallDesc("timer_gettime", unimplementedFunc),
+ /* 260 */ SyscallDesc("timer_getoverrun", unimplementedFunc),
+ /* 261 */ SyscallDesc("timer_delete", unimplementedFunc),
+ /* 262 */ SyscallDesc("clock_settime", unimplementedFunc),
+ /* 263 */ SyscallDesc("clock_gettime", unimplementedFunc),
+ /* 264 */ SyscallDesc("clock_getres", unimplementedFunc),
+ /* 265 */ SyscallDesc("clock_nanosleep", unimplementedFunc),
+ /* 266 */ SyscallDesc("tgkill", unimplementedFunc),
+ /* 267 */ SyscallDesc("utimes", unimplementedFunc),
+ /* 268 */ SyscallDesc("mbind", unimplementedFunc),
+ /* 269 */ SyscallDesc("get_mempolicy", unimplementedFunc),
+ /* 270 */ SyscallDesc("set_mempolicy", unimplementedFunc),
+ /* 271 */ SyscallDesc("mq_open", unimplementedFunc),
+ /* 272 */ SyscallDesc("mq_unlink", unimplementedFunc),
+ /* 273 */ SyscallDesc("mq_timedsend", unimplementedFunc),
+ /* 274 */ SyscallDesc("mq_timedreceive", unimplementedFunc),
+ /* 275 */ SyscallDesc("mq_notify", unimplementedFunc),
+ /* 276 */ SyscallDesc("mq_getsetattr", unimplementedFunc),
+ /* 277 */ SyscallDesc("vserver", unimplementedFunc),
+ /* 278 */ SyscallDesc("waitid", unimplementedFunc),
+ /* 279 */ SyscallDesc("unknown #279", unimplementedFunc),
+ /* 280 */ SyscallDesc("add_key", unimplementedFunc),
+ /* 281 */ SyscallDesc("request_key", unimplementedFunc),
+ /* 282 */ SyscallDesc("keyctl", unimplementedFunc),
+};
+
+MipsLinuxProcess::MipsLinuxProcess(const std::string &name,
+ ObjectFile *objFile,
+ System *system,
+ int stdin_fd,
+ int stdout_fd,
+ int stderr_fd,
+ std::vector<std::string> &argv,
+ std::vector<std::string> &envp,
+ uint64_t _uid,
+ uint64_t _euid,
+ uint64_t _gid,
+ uint64_t _egid,
+ uint64_t _pid,
+ uint64_t _ppid)
+ : MipsLiveProcess(name, objFile, system, stdin_fd, stdout_fd, stderr_fd,
+ argv, envp, _uid, _euid, _gid, _egid, _pid, _ppid),
+ Num_Syscall_Descs(sizeof(syscallDescs) / sizeof(SyscallDesc))
+{ }
+
+SyscallDesc*
+MipsLinuxProcess::getDesc(int callnum)
+{
+ //MIPS32 syscalls are in the range of 4000 - 4999
+ int m5_sys_idx = callnum - 4000;
+
+ if (m5_sys_idx < 0 || m5_sys_idx > Num_Syscall_Descs)
+ return NULL;
+
+ return &syscallDescs[m5_sys_idx];
+}
diff --git a/src/arch/mips/linux/process.hh b/src/arch/mips/linux/process.hh
new file mode 100644
index 000000000..06f86379c
--- /dev/null
+++ b/src/arch/mips/linux/process.hh
@@ -0,0 +1,62 @@
+/*
+ * Copyright (c) 2003-2004 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.
+ */
+
+#ifndef __MIPS_LINUX_PROCESS_HH__
+#define __MIPS_LINUX_PROCESS_HH__
+
+#include "arch/mips/process.hh"
+
+
+/// A process with emulated Mips/Linux syscalls.
+class MipsLinuxProcess : public MipsLiveProcess
+{
+ public:
+ /// Constructor.
+ MipsLinuxProcess(const std::string &name,
+ ObjectFile *objFile,
+ System *system,
+ int stdin_fd, int stdout_fd, int stderr_fd,
+ std::vector<std::string> &argv,
+ std::vector<std::string> &envp,
+ uint64_t _uid, uint64_t _euid,
+ uint64_t _gid, uint64_t _egid,
+ uint64_t _pid, uint64_t _ppid);
+
+ 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[];
+
+ const int Num_Syscall_Descs;
+};
+
+
+#endif // __MIPS_LINUX_PROCESS_HH__
diff --git a/src/arch/mips/process.cc b/src/arch/mips/process.cc
new file mode 100644
index 000000000..4bc91ca24
--- /dev/null
+++ b/src/arch/mips/process.cc
@@ -0,0 +1,71 @@
+
+/*
+ * Copyright (c) 2003-2004 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: Gabe Black
+ * Ali Saidi
+ * Korey Sewell
+ */
+
+#include "arch/mips/isa_traits.hh"
+#include "arch/mips/process.hh"
+#include "base/loader/object_file.hh"
+#include "base/misc.hh"
+#include "cpu/thread_context.hh"
+#include "sim/system.hh"
+
+using namespace std;
+using namespace MipsISA;
+
+MipsLiveProcess::MipsLiveProcess(const std::string &nm, ObjectFile *objFile,
+ System *_system, int stdin_fd, int stdout_fd, int stderr_fd,
+ std::vector<std::string> &argv, std::vector<std::string> &envp,
+ uint64_t _uid, uint64_t _euid, uint64_t _gid, uint64_t _egid,
+ uint64_t _pid, uint64_t _ppid)
+ : LiveProcess(nm, objFile, _system, stdin_fd, stdout_fd, stderr_fd,
+ argv, envp, _uid, _euid, _gid, _egid, _pid, _ppid)
+{
+ // Set up stack. On MIPS, stack starts at the top of kuseg
+ // user address space. MIPS stack grows down from here
+ stack_base = 0x7FFFFFFF;
+
+ // Set pointer for next thread stack. Reserve 8M for main stack.
+ next_thread_stack_base = stack_base - (8 * 1024 * 1024);
+
+ // Set up break point (Top of Heap)
+ brk_point = objFile->dataBase() + objFile->dataSize() + objFile->bssSize();
+ brk_point = roundUp(brk_point, VMPageSize);
+
+ // Set up region for mmaps. For now, start at bottom of kuseg space.
+ mmap_start = mmap_end = 0x10000;
+}
+
+void
+MipsLiveProcess::startup()
+{
+ argsInit(MachineBytes, VMPageSize);
+}
diff --git a/src/arch/mips/process.hh b/src/arch/mips/process.hh
new file mode 100644
index 000000000..fb004375d
--- /dev/null
+++ b/src/arch/mips/process.hh
@@ -0,0 +1,60 @@
+/*
+ * Copyright (c) 2003-2004 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: Gabe Black
+ * Ali Saidi
+ * Korey Sewell
+ */
+
+#ifndef __MIPS_PROCESS_HH__
+#define __MIPS_PROCESS_HH__
+
+#include <string>
+#include <vector>
+#include "sim/process.hh"
+
+class LiveProcess;
+class ObjectFile;
+class System;
+
+class MipsLiveProcess : public LiveProcess
+{
+ protected:
+ MipsLiveProcess(const std::string &nm, ObjectFile *objFile,
+ System *_system, int stdin_fd, int stdout_fd, int stderr_fd,
+ std::vector<std::string> &argv,
+ std::vector<std::string> &envp,
+ uint64_t _uid, uint64_t _euid,
+ uint64_t _gid, uint64_t _egid,
+ uint64_t _pid, uint64_t _ppid);
+
+ void startup();
+
+};
+
+
+#endif // __MIPS_PROCESS_HH__
diff --git a/src/arch/mips/regfile.hh b/src/arch/mips/regfile.hh
new file mode 100644
index 000000000..4b2f1ac35
--- /dev/null
+++ b/src/arch/mips/regfile.hh
@@ -0,0 +1,36 @@
+/*
+ * 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_REGFILE_HH__
+#define __ARCH_MIPS_REGFILE_HH__
+
+#include "arch/mips/regfile/regfile.hh"
+
+#endif
diff --git a/src/arch/mips/regfile/float_regfile.hh b/src/arch/mips/regfile/float_regfile.hh
new file mode 100644
index 000000000..ce5f1fdde
--- /dev/null
+++ b/src/arch/mips/regfile/float_regfile.hh
@@ -0,0 +1,195 @@
+/*
+ * 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.
+ */
+
+#ifndef __ARCH_MIPS_REGFILE_FLOAT_REGFILE_HH__
+#define __ARCH_MIPS_REGFILE_FLOAT_REGFILE_HH__
+
+#include "arch/mips/types.hh"
+#include "arch/mips/isa_traits.hh"
+#include "base/misc.hh"
+#include "base/bitfield.hh"
+#include "sim/faults.hh"
+
+#include <string>
+
+class Checkpoint;
+
+namespace MipsISA
+{
+ static inline std::string getFloatRegName(RegIndex)
+ {
+ return "";
+ }
+
+ const uint32_t MIPS32_QNAN = 0x7fbfffff;
+ const uint64_t MIPS64_QNAN = ULL(0x7fbfffffffffffff);
+
+ enum FPControlRegNums {
+ FIR = NumFloatArchRegs,
+ FCCR,
+ FEXR,
+ FENR,
+ FCSR
+ };
+
+ enum FCSRBits {
+ Inexact = 1,
+ Underflow,
+ Overflow,
+ DivideByZero,
+ Invalid,
+ Unimplemented
+ };
+
+ enum FCSRFields {
+ Flag_Field = 1,
+ Enable_Field = 6,
+ Cause_Field = 11
+ };
+
+ const int SingleWidth = 32;
+ const int SingleBytes = SingleWidth / 4;
+
+ const int DoubleWidth = 64;
+ const int DoubleBytes = DoubleWidth / 4;
+
+ const int QuadWidth = 128;
+ const int QuadBytes = QuadWidth / 4;
+
+ class FloatRegFile
+ {
+ protected:
+ FloatReg32 regs[NumFloatRegs];
+
+ public:
+
+ void clear()
+ {
+ bzero(regs, sizeof(regs));
+ }
+
+ double readReg(int floatReg, int width)
+ {
+ switch(width)
+ {
+ case SingleWidth:
+ {
+ void *float_ptr = &regs[floatReg];
+ return *(float *) float_ptr;
+ }
+
+ case DoubleWidth:
+ {
+ uint64_t double_val = (FloatReg64)regs[floatReg + 1] << 32 | regs[floatReg];
+ void *double_ptr = &double_val;
+ return *(double *) double_ptr;
+ }
+
+ default:
+ panic("Attempted to read a %d bit floating point register!", width);
+ }
+ }
+
+ FloatRegBits readRegBits(int floatReg, int width)
+ {
+ if (floatReg < NumFloatArchRegs - 1) {
+ switch(width)
+ {
+ case SingleWidth:
+ return regs[floatReg];
+
+ case DoubleWidth:
+ return (FloatReg64)regs[floatReg + 1] << 32 | regs[floatReg];
+
+ default:
+ panic("Attempted to read a %d bit floating point register!", width);
+ }
+ } else {
+ if (width > SingleWidth)
+ assert("Control Regs are only 32 bits wide");
+
+ return regs[floatReg];
+ }
+ }
+
+ Fault setReg(int floatReg, const FloatRegVal &val, int width)
+ {
+ switch(width)
+ {
+ case SingleWidth:
+ {
+ float temp = val;
+ void *float_ptr = &temp;
+ regs[floatReg] = *(FloatReg32 *) float_ptr;
+ break;
+ }
+
+ case DoubleWidth:
+ {
+ const void *double_ptr = &val;
+ FloatReg64 temp_double = *(FloatReg64 *) double_ptr;
+ regs[floatReg + 1] = bits(temp_double, 63, 32);
+ regs[floatReg] = bits(temp_double, 31, 0);
+ break;
+ }
+
+ default:
+ panic("Attempted to read a %d bit floating point register!", width);
+ }
+
+ return NoFault;
+ }
+
+ Fault setRegBits(int floatReg, const FloatRegBits &val, int width)
+ {
+
+ switch(width)
+ {
+ case SingleWidth:
+ regs[floatReg] = val;
+ break;
+
+ case DoubleWidth:
+ regs[floatReg + 1] = bits(val, 63, 32);
+ regs[floatReg] = bits(val, 31, 0);
+ break;
+
+ default:
+ panic("Attempted to read a %d bit floating point register!", width);
+ }
+ return NoFault;
+ }
+
+ void serialize(std::ostream &os);
+
+ void unserialize(Checkpoint *cp, const std::string &section);
+ };
+
+} // namespace MipsISA
+
+#endif
diff --git a/src/arch/mips/regfile/int_regfile.hh b/src/arch/mips/regfile/int_regfile.hh
new file mode 100644
index 000000000..a45a17a85
--- /dev/null
+++ b/src/arch/mips/regfile/int_regfile.hh
@@ -0,0 +1,79 @@
+/*
+ * 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_REGFILE_INT_REGFILE_HH__
+#define __ARCH_MIPS_REGFILE_INT_REGFILE_HH__
+
+#include "arch/mips/types.hh"
+#include "arch/mips/isa_traits.hh"
+#include "base/misc.hh"
+#include "sim/faults.hh"
+
+class Checkpoint;
+class ThreadContext;
+
+namespace MipsISA
+{
+ static inline std::string getIntRegName(RegIndex)
+ {
+ return "";
+ }
+
+ enum MiscIntRegNums {
+ HI = NumIntArchRegs,
+ LO
+ };
+
+ class IntRegFile
+ {
+ protected:
+ IntReg regs[NumIntRegs];
+
+ public:
+ IntReg readReg(int intReg)
+ {
+ return regs[intReg];
+ }
+
+ Fault setReg(int intReg, const IntReg &val)
+ {
+ regs[intReg] = val;
+ return NoFault;
+ }
+
+ void serialize(std::ostream &os);
+
+ void unserialize(Checkpoint *cp, const std::string &section);
+
+ };
+
+} // namespace MipsISA
+
+#endif
diff --git a/src/arch/mips/regfile/misc_regfile.hh b/src/arch/mips/regfile/misc_regfile.hh
new file mode 100644
index 000000000..a4527a203
--- /dev/null
+++ b/src/arch/mips/regfile/misc_regfile.hh
@@ -0,0 +1,243 @@
+/*
+ * 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_REGFILE_MISC_REGFILE_HH__
+#define __ARCH_MIPS_REGFILE_MISC_REGFILE_HH__
+
+#include "arch/mips/types.hh"
+#include "sim/faults.hh"
+
+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,
+
+ ErrCtl = 201, //Bank 26: 201 - 208
+
+ CacheErr0 = 209, //Bank 27: 209 - 216
+ CacheErr1 = 210,
+ CacheErr2 = 211,
+ CacheErr3 = 212,
+
+ TagLo0 = 217,//Bank 28: 217 - 224
+ DataLo1 = 218,
+ TagLo2 = 219,
+ DataLo3 = 220,
+ TagLo4 = 221,
+ DataLo5 = 222,
+ TagLo6 = 223,
+ DataLo7 = 234,
+
+ TagHi0 = 233,//Bank 29: 233 - 240
+ DataHi1 = 234,
+ TagHi2 = 235,
+ DataHi3 = 236,
+ TagHi4 = 237,
+ DataHi5 = 238,
+ TagHi6 = 239,
+ DataHi7 = 240,
+
+
+ ErrorEPC = 249,//Bank 30: 241 - 248
+
+ DESAVE = 257//Bank 31: 249-256
+ };
+
+ class MiscRegFile {
+
+ protected:
+ uint64_t fpcr; // floating point condition codes
+ // FPCR is not used in MIPS. Condition
+ // codes are kept as part of the FloatRegFile
+
+ bool lock_flag; // lock flag for LL/SC
+ // use LL reg. in the future
+
+ Addr lock_addr; // lock address for LL/SC
+ // use LLAddr reg. in the future
+
+ MiscReg miscRegFile[NumMiscRegs];
+
+ public:
+ void clear()
+ {
+ fpcr = 0;
+ lock_flag = 0;
+ lock_addr = 0;
+ }
+
+ void copyMiscRegs(ThreadContext *tc);
+
+ MiscReg readReg(int misc_reg)
+ {
+ return miscRegFile[misc_reg];
+ }
+
+ MiscReg readRegWithEffect(int misc_reg, Fault &fault, ThreadContext *tc)
+ {
+ return miscRegFile[misc_reg];
+ }
+
+ Fault setReg(int misc_reg, const MiscReg &val)
+ {
+ miscRegFile[misc_reg] = val; return NoFault;
+ }
+
+ Fault setRegWithEffect(int misc_reg, const MiscReg &val,
+ ThreadContext *tc)
+ {
+ miscRegFile[misc_reg] = val; return NoFault;
+ }
+
+ friend class RegFile;
+ };
+} // namespace MipsISA
+
+#endif
diff --git a/src/arch/mips/regfile/regfile.hh b/src/arch/mips/regfile/regfile.hh
new file mode 100644
index 000000000..3a18c681b
--- /dev/null
+++ b/src/arch/mips/regfile/regfile.hh
@@ -0,0 +1,184 @@
+/*
+ * 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_REGFILE_REGFILE_HH__
+#define __ARCH_MIPS_REGFILE_REGFILE_HH__
+
+#include "arch/mips/types.hh"
+#include "arch/mips/regfile/int_regfile.hh"
+#include "arch/mips/regfile/float_regfile.hh"
+#include "arch/mips/regfile/misc_regfile.hh"
+#include "sim/faults.hh"
+
+class Checkpoint;
+class ThreadContext;
+
+namespace MipsISA
+{
+ class RegFile {
+ protected:
+ IntRegFile intRegFile; // (signed) integer register file
+ FloatRegFile floatRegFile; // floating point register file
+ MiscRegFile miscRegFile; // control register file
+
+ public:
+
+ void clear()
+ {
+ bzero(&intRegFile, sizeof(intRegFile));
+ bzero(&floatRegFile, sizeof(floatRegFile));
+ bzero(&miscRegFile, sizeof(miscRegFile));
+ }
+
+ MiscReg readMiscReg(int miscReg)
+ {
+ return miscRegFile.readReg(miscReg);
+ }
+
+ MiscReg readMiscRegWithEffect(int miscReg,
+ Fault &fault, ThreadContext *tc)
+ {
+ fault = NoFault;
+ return miscRegFile.readRegWithEffect(miscReg, fault, tc);
+ }
+
+ Fault setMiscReg(int miscReg, const MiscReg &val)
+ {
+ return miscRegFile.setReg(miscReg, val);
+ }
+
+ Fault setMiscRegWithEffect(int miscReg, const MiscReg &val,
+ ThreadContext * tc)
+ {
+ return miscRegFile.setRegWithEffect(miscReg, val, tc);
+ }
+
+ FloatRegVal readFloatReg(int floatReg)
+ {
+ return floatRegFile.readReg(floatReg,SingleWidth);
+ }
+
+ FloatRegVal readFloatReg(int floatReg, int width)
+ {
+ return floatRegFile.readReg(floatReg,width);
+ }
+
+ FloatRegBits readFloatRegBits(int floatReg)
+ {
+ return floatRegFile.readRegBits(floatReg,SingleWidth);
+ }
+
+ FloatRegBits readFloatRegBits(int floatReg, int width)
+ {
+ return floatRegFile.readRegBits(floatReg,width);
+ }
+
+ Fault setFloatReg(int floatReg, const FloatRegVal &val)
+ {
+ return floatRegFile.setReg(floatReg, val, SingleWidth);
+ }
+
+ Fault setFloatReg(int floatReg, const FloatRegVal &val, int width)
+ {
+ return floatRegFile.setReg(floatReg, val, width);
+ }
+
+ Fault setFloatRegBits(int floatReg, const FloatRegBits &val)
+ {
+ return floatRegFile.setRegBits(floatReg, val, SingleWidth);
+ }
+
+ Fault setFloatRegBits(int floatReg, const FloatRegBits &val, int width)
+ {
+ return floatRegFile.setRegBits(floatReg, val, width);
+ }
+
+ IntReg readIntReg(int intReg)
+ {
+ return intRegFile.readReg(intReg);
+ }
+
+ Fault setIntReg(int intReg, const IntReg &val)
+ {
+ return intRegFile.setReg(intReg, val);
+ }
+ protected:
+
+ Addr pc; // program counter
+ Addr npc; // next-cycle program counter
+ Addr nnpc; // next-next-cycle program counter
+ // used to implement branch delay slot
+ // not real register
+ public:
+ Addr readPC()
+ {
+ return pc;
+ }
+
+ void setPC(Addr val)
+ {
+ pc = val;
+ }
+
+ Addr readNextPC()
+ {
+ return npc;
+ }
+
+ void setNextPC(Addr val)
+ {
+ npc = val;
+ }
+
+ Addr readNextNPC()
+ {
+ return nnpc;
+ }
+
+ void setNextNPC(Addr val)
+ {
+ nnpc = val;
+ }
+
+ void serialize(std::ostream &os);
+ void unserialize(Checkpoint *cp, const std::string &section);
+
+ void changeContext(RegContextParam param, RegContextVal val)
+ {
+ }
+ };
+
+ void copyRegs(ThreadContext *src, ThreadContext *dest);
+
+ void copyMiscRegs(ThreadContext *src, ThreadContext *dest);
+
+} // namespace MipsISA
+
+#endif
diff --git a/src/arch/mips/stacktrace.hh b/src/arch/mips/stacktrace.hh
new file mode 100644
index 000000000..f9e092dbd
--- /dev/null
+++ b/src/arch/mips/stacktrace.hh
@@ -0,0 +1,121 @@
+/*
+ * Copyright (c) 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: Ali Saidi
+ */
+
+#ifndef __ARCH_MIPS_STACKTRACE_HH__
+#define __ARCH_MIPS_STACKTRACE_HH__
+
+#include "base/trace.hh"
+#include "cpu/static_inst.hh"
+
+class ThreadContext;
+class StackTrace;
+
+class ProcessInfo
+{
+ private:
+ ThreadContext *tc;
+
+ int thread_info_size;
+ int task_struct_size;
+ int task_off;
+ int pid_off;
+ int name_off;
+
+ public:
+ ProcessInfo(ThreadContext *_tc);
+
+ Addr task(Addr ksp) const;
+ int pid(Addr ksp) const;
+ std::string name(Addr ksp) const;
+};
+
+class StackTrace
+{
+ protected:
+ typedef TheISA::MachInst MachInst;
+ private:
+ ThreadContext *tc;
+ std::vector<Addr> stack;
+
+ private:
+ bool isEntry(Addr addr);
+ bool decodePrologue(Addr sp, Addr callpc, Addr func, int &size, Addr &ra);
+ bool decodeSave(MachInst inst, int &reg, int &disp);
+ bool decodeStack(MachInst inst, int &disp);
+
+ void trace(ThreadContext *tc, bool is_call);
+
+ public:
+ StackTrace();
+ StackTrace(ThreadContext *tc, StaticInstPtr inst);
+ ~StackTrace();
+
+ void clear()
+ {
+ tc = 0;
+ stack.clear();
+ }
+
+ bool valid() const { return tc != NULL; }
+ bool trace(ThreadContext *tc, StaticInstPtr inst);
+
+ public:
+ const std::vector<Addr> &getstack() const { return stack; }
+
+ static const int user = 1;
+ static const int console = 2;
+ static const int unknown = 3;
+
+#if TRACING_ON
+ private:
+ void dump();
+
+ public:
+ void dprintf() { if (DTRACE(Stack)) dump(); }
+#else
+ public:
+ void dprintf() {}
+#endif
+};
+
+inline bool
+StackTrace::trace(ThreadContext *tc, StaticInstPtr inst)
+{
+ if (!inst->isCall() && !inst->isReturn())
+ return false;
+
+ if (valid())
+ clear();
+
+ trace(tc, !inst->isReturn());
+ return true;
+}
+
+#endif // __ARCH_MIPS_STACKTRACE_HH__
diff --git a/src/arch/mips/syscallreturn.hh b/src/arch/mips/syscallreturn.hh
new file mode 100644
index 000000000..ef1093caf
--- /dev/null
+++ b/src/arch/mips/syscallreturn.hh
@@ -0,0 +1,84 @@
+/*
+ * 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: Gabe Black
+ * Korey Sewell
+ */
+
+#ifndef __ARCH_MIPS_SYSCALLRETURN_HH__
+#define __ARCH_MIPS_SYSCALLRETURN_HH__
+
+class SyscallReturn {
+ public:
+ template <class T>
+ SyscallReturn(T v, bool s)
+ {
+ retval = (uint32_t)v;
+ success = s;
+ }
+
+ template <class T>
+ SyscallReturn(T v)
+ {
+ success = (v >= 0);
+ retval = (uint32_t)v;
+ }
+
+ ~SyscallReturn() {}
+
+ SyscallReturn& operator=(const SyscallReturn& s) {
+ retval = s.retval;
+ success = s.success;
+ return *this;
+ }
+
+ bool successful() { return success; }
+ uint64_t value() { return retval; }
+
+
+ private:
+ uint64_t retval;
+ bool success;
+};
+
+namespace MipsISA
+{
+ static inline void setSyscallReturn(SyscallReturn return_value, RegFile *regs)
+ {
+ if (return_value.successful()) {
+ // no error
+ regs->setIntReg(SyscallSuccessReg, 0);
+ regs->setIntReg(ReturnValueReg1, return_value.value());
+ } else {
+ // got an error, return details
+ regs->setIntReg(SyscallSuccessReg, (IntReg) -1);
+ regs->setIntReg(ReturnValueReg1, -return_value.value());
+ }
+ }
+}
+
+#endif
diff --git a/src/arch/mips/types.hh b/src/arch/mips/types.hh
new file mode 100644
index 000000000..d4fa296fd
--- /dev/null
+++ b/src/arch/mips/types.hh
@@ -0,0 +1,98 @@
+/*
+ * 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_TYPES_HH__
+#define __ARCH_MIPS_TYPES_HH__
+
+#include "sim/host.hh"
+
+namespace MipsISA
+{
+ typedef uint32_t MachInst;
+ typedef uint64_t ExtMachInst;
+ typedef uint8_t RegIndex;
+
+ typedef uint32_t IntReg;
+
+ // floating point register file entry type
+ typedef uint32_t FloatReg32;
+ typedef uint64_t FloatReg64;
+ typedef uint64_t FloatRegBits;
+
+ typedef double FloatRegVal;
+ typedef double FloatReg;
+
+ // cop-0/cop-1 system control register
+ typedef uint64_t MiscReg;
+
+ typedef union {
+ IntReg intreg;
+ FloatReg fpreg;
+ MiscReg ctrlreg;
+ } AnyReg;
+
+ typedef int RegContextParam;
+ typedef int RegContextVal;
+
+ //used in FP convert & round function
+ enum ConvertType{
+ SINGLE_TO_DOUBLE,
+ SINGLE_TO_WORD,
+ SINGLE_TO_LONG,
+
+ DOUBLE_TO_SINGLE,
+ DOUBLE_TO_WORD,
+ DOUBLE_TO_LONG,
+
+ LONG_TO_SINGLE,
+ LONG_TO_DOUBLE,
+ LONG_TO_WORD,
+ LONG_TO_PS,
+
+ WORD_TO_SINGLE,
+ WORD_TO_DOUBLE,
+ WORD_TO_LONG,
+ WORD_TO_PS,
+
+ PL_TO_SINGLE,
+ PU_TO_SINGLE
+ };
+
+ //used in FP convert & round function
+ enum RoundMode{
+ RND_ZERO,
+ RND_DOWN,
+ RND_UP,
+ RND_NEAREST
+ };
+
+} // namespace MipsISA
+
+#endif
diff --git a/src/arch/mips/utility.cc b/src/arch/mips/utility.cc
new file mode 100644
index 000000000..9ac4bb6d8
--- /dev/null
+++ b/src/arch/mips/utility.cc
@@ -0,0 +1,199 @@
+/*
+ * 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: Korey Sewell
+ */
+
+#include "arch/mips/regfile.hh"
+#include "arch/mips/utility.hh"
+#include "base/misc.hh"
+#include "base/bitfield.hh"
+
+using namespace MipsISA;
+
+uint64_t
+MipsISA::fpConvert(ConvertType cvt_type, double fp_val)
+{
+
+ switch (cvt_type)
+ {
+ case SINGLE_TO_DOUBLE:
+ {
+ double sdouble_val = fp_val;
+ void *sdouble_ptr = &sdouble_val;
+ uint64_t sdp_bits = *(uint64_t *) sdouble_ptr;
+ return sdp_bits;
+ }
+
+ case SINGLE_TO_WORD:
+ {
+ int32_t sword_val = (int32_t) fp_val;
+ void *sword_ptr = &sword_val;
+ uint64_t sword_bits= *(uint32_t *) sword_ptr;
+ return sword_bits;
+ }
+
+ case WORD_TO_SINGLE:
+ {
+ float wfloat_val = fp_val;
+ void *wfloat_ptr = &wfloat_val;
+ uint64_t wfloat_bits = *(uint32_t *) wfloat_ptr;
+ return wfloat_bits;
+ }
+
+ case WORD_TO_DOUBLE:
+ {
+ double wdouble_val = fp_val;
+ void *wdouble_ptr = &wdouble_val;
+ uint64_t wdp_bits = *(uint64_t *) wdouble_ptr;
+ return wdp_bits;
+ }
+
+ default:
+ panic("Invalid Floating Point Conversion Type (%d). See \"types.hh\" for List of Conversions\n",cvt_type);
+ return 0;
+ }
+}
+
+double
+MipsISA::roundFP(double val, int digits)
+{
+ double digit_offset = pow(10.0,digits);
+ val = val * digit_offset;
+ val = val + 0.5;
+ val = floor(val);
+ val = val / digit_offset;
+ return val;
+}
+
+double
+MipsISA::truncFP(double val)
+{
+ int trunc_val = (int) val;
+ return (double) trunc_val;
+}
+
+bool
+MipsISA::getCondCode(uint32_t fcsr, int cc_idx)
+{
+ int shift = (cc_idx == 0) ? 23 : cc_idx + 24;
+ bool cc_val = (fcsr >> shift) & 0x00000001;
+ return cc_val;
+}
+
+uint32_t
+MipsISA::genCCVector(uint32_t fcsr, int cc_num, uint32_t cc_val)
+{
+ int cc_idx = (cc_num == 0) ? 23 : cc_num + 24;
+
+ fcsr = bits(fcsr, 31, cc_idx + 1) << cc_idx + 1 |
+ cc_val << cc_idx |
+ bits(fcsr, cc_idx - 1, 0);
+
+ return fcsr;
+}
+
+uint32_t
+MipsISA::genInvalidVector(uint32_t fcsr_bits)
+{
+ //Set FCSR invalid in "flag" field
+ int invalid_offset = Invalid + Flag_Field;
+ fcsr_bits = fcsr_bits | (1 << invalid_offset);
+
+ //Set FCSR invalid in "cause" flag
+ int cause_offset = Invalid + Cause_Field;
+ fcsr_bits = fcsr_bits | (1 << cause_offset);
+
+ return fcsr_bits;
+}
+
+bool
+MipsISA::isNan(void *val_ptr, int size)
+{
+ switch (size)
+ {
+ case 32:
+ {
+ uint32_t val_bits = *(uint32_t *) val_ptr;
+ return (bits(val_bits, 30, 23) == 0xFF);
+ }
+
+ case 64:
+ {
+ uint64_t val_bits = *(uint64_t *) val_ptr;
+ return (bits(val_bits, 62, 52) == 0x7FF);
+ }
+
+ default:
+ panic("Type unsupported. Size mismatch\n");
+ }
+}
+
+
+bool
+MipsISA::isQnan(void *val_ptr, int size)
+{
+ switch (size)
+ {
+ case 32:
+ {
+ uint32_t val_bits = *(uint32_t *) val_ptr;
+ return (bits(val_bits, 30, 22) == 0x1FE);
+ }
+
+ case 64:
+ {
+ uint64_t val_bits = *(uint64_t *) val_ptr;
+ return (bits(val_bits, 62, 51) == 0xFFE);
+ }
+
+ default:
+ panic("Type unsupported. Size mismatch\n");
+ }
+}
+
+bool
+MipsISA::isSnan(void *val_ptr, int size)
+{
+ switch (size)
+ {
+ case 32:
+ {
+ uint32_t val_bits = *(uint32_t *) val_ptr;
+ return (bits(val_bits, 30, 22) == 0x1FF);
+ }
+
+ case 64:
+ {
+ uint64_t val_bits = *(uint64_t *) val_ptr;
+ return (bits(val_bits, 62, 51) == 0xFFF);
+ }
+
+ default:
+ panic("Type unsupported. Size mismatch\n");
+ }
+}
diff --git a/src/arch/mips/utility.hh b/src/arch/mips/utility.hh
new file mode 100644
index 000000000..ae2fe1aea
--- /dev/null
+++ b/src/arch/mips/utility.hh
@@ -0,0 +1,103 @@
+/*
+ * 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: Nathan Binkert
+ * Steve Reinhardt
+ */
+
+#ifndef __ARCH_MIPS_UTILITY_HH__
+#define __ARCH_MIPS_UTILITY_HH__
+
+#include "arch/mips/types.hh"
+#include "base/misc.hh"
+#include "config/full_system.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"
+
+class ThreadContext;
+
+namespace MipsISA {
+
+ //Floating Point Utility Functions
+ uint64_t fpConvert(ConvertType cvt_type, double fp_val);
+ double roundFP(double val, int digits);
+ double truncFP(double val);
+
+ bool getCondCode(uint32_t fcsr, int cc);
+ uint32_t genCCVector(uint32_t fcsr, int num, uint32_t cc_val);
+ uint32_t genInvalidVector(uint32_t fcsr);
+
+ bool isNan(void *val_ptr, int size);
+ bool isQnan(void *val_ptr, int size);
+ bool isSnan(void *val_ptr, int size);
+
+ /**
+ * Function to insure ISA semantics about 0 registers.
+ * @param tc The thread context.
+ */
+ template <class TC>
+ void zeroRegisters(TC *tc);
+
+ void copyRegs(ThreadContext *src, ThreadContext *dest);
+
+ // Instruction address compression hooks
+ static inline Addr realPCToFetchPC(const Addr &addr) {
+ return addr;
+ }
+
+ static inline Addr fetchPCToRealPC(const Addr &addr) {
+ return addr;
+ }
+
+ // the size of "fetched" instructions (not necessarily the size
+ // of real instructions for PISA)
+ static inline size_t fetchInstSize() {
+ return sizeof(MachInst);
+ }
+
+ static inline MachInst makeRegisterCopy(int dest, int src) {
+ panic("makeRegisterCopy not implemented");
+ return 0;
+ }
+
+ static inline ExtMachInst
+ makeExtMI(MachInst inst, const uint64_t &pc) {
+#if FULL_SYSTEM
+ ExtMachInst ext_inst = inst;
+ if (pc && 0x1)
+ return ext_inst|=(static_cast<ExtMachInst>(pc & 0x1) << 32);
+ else
+ return ext_inst;
+#else
+ return ExtMachInst(inst);
+#endif
+ }
+};
+
+
+#endif