summaryrefslogtreecommitdiff
path: root/src/arch
diff options
context:
space:
mode:
authorGabe Black <gblack@eecs.umich.edu>2006-08-11 19:43:10 -0400
committerGabe Black <gblack@eecs.umich.edu>2006-08-11 19:43:10 -0400
commit800e6ecc07d01c49808cc4f9597d94cc8cfd9fae (patch)
treebdc05bad76c4a757533cccb5002dadc15eca0456 /src/arch
parentf612f09669310359d6a194645b00e32a3921283b (diff)
downloadgem5-800e6ecc07d01c49808cc4f9597d94cc8cfd9fae.tar.xz
Pushed most of constants.hh back into isa_traits.hh and regfile.hh and created a seperate file for the syscallreturn class.
--HG-- extra : convert_revision : 9507ea1c09fda959f00aec9ec8ffb887ec8dd0f9
Diffstat (limited to 'src/arch')
-rw-r--r--src/arch/SConscript3
-rw-r--r--src/arch/alpha/isa_traits.hh289
-rw-r--r--src/arch/alpha/process.cc2
-rw-r--r--src/arch/alpha/regfile.hh16
-rw-r--r--src/arch/alpha/syscallreturn.hh87
-rw-r--r--src/arch/alpha/types.hh9
-rw-r--r--src/arch/alpha/utility.hh2
-rw-r--r--src/arch/mips/isa_traits.cc4
-rw-r--r--src/arch/mips/isa_traits.hh194
-rw-r--r--src/arch/mips/regfile.hh36
-rw-r--r--src/arch/mips/regfile/float_regfile.hh48
-rw-r--r--src/arch/mips/regfile/int_regfile.hh12
-rw-r--r--src/arch/mips/regfile/misc_regfile.hh155
-rw-r--r--src/arch/mips/regfile/regfile.hh11
-rw-r--r--src/arch/mips/syscallreturn.hh84
-rw-r--r--src/arch/mips/types.hh3
-rw-r--r--src/arch/mips/utility.hh46
-rw-r--r--src/arch/sparc/SConscript11
-rw-r--r--src/arch/sparc/floatregfile.cc174
-rw-r--r--src/arch/sparc/floatregfile.hh83
-rw-r--r--src/arch/sparc/intregfile.cc133
-rw-r--r--src/arch/sparc/intregfile.hh103
-rw-r--r--src/arch/sparc/isa_traits.hh106
-rw-r--r--src/arch/sparc/miscregfile.cc540
-rw-r--r--src/arch/sparc/miscregfile.hh410
-rw-r--r--src/arch/sparc/regfile.cc279
-rw-r--r--src/arch/sparc/regfile.hh824
-rw-r--r--src/arch/sparc/syscallreturn.hh90
-rw-r--r--src/arch/sparc/types.hh63
29 files changed, 2719 insertions, 1098 deletions
diff --git a/src/arch/SConscript b/src/arch/SConscript
index 0a5962889..d77060d62 100644
--- a/src/arch/SConscript
+++ b/src/arch/SConscript
@@ -47,13 +47,12 @@ sources = []
# List of headers to generate
isa_switch_hdrs = Split('''
- arguments.hh
- constants.hh
faults.hh
isa_traits.hh
process.hh
regfile.hh
stacktrace.hh
+ syscallreturn.hh
tlb.hh
types.hh
utility.hh
diff --git a/src/arch/alpha/isa_traits.hh b/src/arch/alpha/isa_traits.hh
index 663b144ab..ae4397c4c 100644
--- a/src/arch/alpha/isa_traits.hh
+++ b/src/arch/alpha/isa_traits.hh
@@ -35,49 +35,12 @@
namespace LittleEndianGuest {}
#include "arch/alpha/types.hh"
-#include "arch/alpha/constants.hh"
-#include "arch/alpha/regfile.hh"
+#include "arch/alpha/isa_traits.hh"
#include "config/full_system.hh"
#include "sim/host.hh"
class StaticInstPtr;
-#if !FULL_SYSTEM
-class SyscallReturn {
- public:
- template <class T>
- SyscallReturn(T v, bool s)
- {
- retval = (uint64_t)v;
- success = s;
- }
-
- template <class T>
- SyscallReturn(T v)
- {
- success = (v >= 0);
- retval = (uint64_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;
-};
-
-#endif
-
#if FULL_SYSTEM
#include "arch/alpha/isa_fullsys_traits.hh"
#endif
@@ -86,30 +49,244 @@ class SyscallReturn {
namespace AlphaISA
{
-using namespace LittleEndianGuest;
+ using namespace LittleEndianGuest;
-// redirected register map, really only used for the full system case.
-extern const int reg_redir[NumIntRegs];
+ // These enumerate all the registers for dependence tracking.
+ enum DependenceTags {
+ // 0..31 are the integer regs 0..31
+ // 32..63 are the FP regs 0..31, i.e. use (reg + FP_Base_DepTag)
+ FP_Base_DepTag = 40,
+ Ctrl_Base_DepTag = 72,
+ Fpcr_DepTag = 72, // floating point control register
+ Uniq_DepTag = 73,
+ Lock_Flag_DepTag = 74,
+ Lock_Addr_DepTag = 75,
+ IPR_Base_DepTag = 76
+ };
StaticInstPtr decodeInst(ExtMachInst);
-#if !FULL_SYSTEM
- static inline void setSyscallReturn(SyscallReturn return_value, RegFile *regs)
+ const Addr PageShift = 13;
+ const Addr PageBytes = ULL(1) << PageShift;
+ const Addr PageMask = ~(PageBytes - 1);
+ const Addr PageOffset = PageBytes - 1;
+
+
+#if FULL_SYSTEM
+
+ ////////////////////////////////////////////////////////////////////////
+ //
+ // Translation stuff
+ //
+
+ const Addr PteShift = 3;
+ const Addr NPtePageShift = PageShift - PteShift;
+ const Addr NPtePage = ULL(1) << NPtePageShift;
+ const Addr PteMask = NPtePage - 1;
+
+ // User Virtual
+ const Addr USegBase = ULL(0x0);
+ const Addr USegEnd = ULL(0x000003ffffffffff);
+
+ // Kernel Direct Mapped
+ const Addr K0SegBase = ULL(0xfffffc0000000000);
+ const Addr K0SegEnd = ULL(0xfffffdffffffffff);
+
+ // Kernel Virtual
+ const Addr K1SegBase = ULL(0xfffffe0000000000);
+ const Addr K1SegEnd = ULL(0xffffffffffffffff);
+
+ // For loading... XXX This maybe could be USegEnd?? --ali
+ const Addr LoadAddrMask = ULL(0xffffffffff);
+
+ ////////////////////////////////////////////////////////////////////////
+ //
+ // Interrupt levels
+ //
+ enum InterruptLevels
+ {
+ INTLEVEL_SOFTWARE_MIN = 4,
+ INTLEVEL_SOFTWARE_MAX = 19,
+
+ INTLEVEL_EXTERNAL_MIN = 20,
+ INTLEVEL_EXTERNAL_MAX = 34,
+
+ INTLEVEL_IRQ0 = 20,
+ INTLEVEL_IRQ1 = 21,
+ INTINDEX_ETHERNET = 0,
+ INTINDEX_SCSI = 1,
+ INTLEVEL_IRQ2 = 22,
+ INTLEVEL_IRQ3 = 23,
+
+ INTLEVEL_SERIAL = 33,
+
+ NumInterruptLevels = INTLEVEL_EXTERNAL_MAX
+ };
+
+
+ // EV5 modes
+ enum mode_type
+ {
+ mode_kernel = 0, // kernel
+ mode_executive = 1, // executive (unused by unix)
+ mode_supervisor = 2, // supervisor (unused by unix)
+ mode_user = 3, // user mode
+ mode_number // number of modes
+ };
+
+#endif
+
+#if FULL_SYSTEM
+ ////////////////////////////////////////////////////////////////////////
+ //
+ // Internal Processor Reigsters
+ //
+ enum md_ipr_names
{
- // check for error condition. Alpha syscall convention is to
- // indicate success/failure in reg a3 (r19) and put the
- // return value itself in the standard return value reg (v0).
- if (return_value.successful()) {
- // no error
- regs->setIntReg(SyscallSuccessReg, 0);
- regs->setIntReg(ReturnValueReg, return_value.value());
- } else {
- // got an error, return details
- regs->setIntReg(SyscallSuccessReg, (IntReg)-1);
- regs->setIntReg(ReturnValueReg, -return_value.value());
- }
- }
+ IPR_ISR = 0x100, // interrupt summary register
+ IPR_ITB_TAG = 0x101, // ITLB tag register
+ IPR_ITB_PTE = 0x102, // ITLB page table entry register
+ IPR_ITB_ASN = 0x103, // ITLB address space register
+ IPR_ITB_PTE_TEMP = 0x104, // ITLB page table entry temp register
+ IPR_ITB_IA = 0x105, // ITLB invalidate all register
+ IPR_ITB_IAP = 0x106, // ITLB invalidate all process register
+ IPR_ITB_IS = 0x107, // ITLB invalidate select register
+ IPR_SIRR = 0x108, // software interrupt request register
+ IPR_ASTRR = 0x109, // asynchronous system trap request register
+ IPR_ASTER = 0x10a, // asynchronous system trap enable register
+ IPR_EXC_ADDR = 0x10b, // exception address register
+ IPR_EXC_SUM = 0x10c, // exception summary register
+ IPR_EXC_MASK = 0x10d, // exception mask register
+ IPR_PAL_BASE = 0x10e, // PAL base address register
+ IPR_ICM = 0x10f, // instruction current mode
+ IPR_IPLR = 0x110, // interrupt priority level register
+ IPR_INTID = 0x111, // interrupt ID register
+ IPR_IFAULT_VA_FORM = 0x112, // formatted faulting virtual addr register
+ IPR_IVPTBR = 0x113, // virtual page table base register
+ IPR_HWINT_CLR = 0x115, // H/W interrupt clear register
+ IPR_SL_XMIT = 0x116, // serial line transmit register
+ IPR_SL_RCV = 0x117, // serial line receive register
+ IPR_ICSR = 0x118, // instruction control and status register
+ IPR_IC_FLUSH = 0x119, // instruction cache flush control
+ IPR_IC_PERR_STAT = 0x11a, // inst cache parity error status register
+ IPR_PMCTR = 0x11c, // performance counter register
+
+ // PAL temporary registers...
+ // register meanings gleaned from osfpal.s source code
+ IPR_PALtemp0 = 0x140, // local scratch
+ IPR_PALtemp1 = 0x141, // local scratch
+ IPR_PALtemp2 = 0x142, // entUna
+ IPR_PALtemp3 = 0x143, // CPU specific impure area pointer
+ IPR_PALtemp4 = 0x144, // memory management temp
+ IPR_PALtemp5 = 0x145, // memory management temp
+ IPR_PALtemp6 = 0x146, // memory management temp
+ IPR_PALtemp7 = 0x147, // entIF
+ IPR_PALtemp8 = 0x148, // intmask
+ IPR_PALtemp9 = 0x149, // entSys
+ IPR_PALtemp10 = 0x14a, // ??
+ IPR_PALtemp11 = 0x14b, // entInt
+ IPR_PALtemp12 = 0x14c, // entArith
+ IPR_PALtemp13 = 0x14d, // reserved for platform specific PAL
+ IPR_PALtemp14 = 0x14e, // reserved for platform specific PAL
+ IPR_PALtemp15 = 0x14f, // reserved for platform specific PAL
+ IPR_PALtemp16 = 0x150, // scratch / whami<7:0> / mces<4:0>
+ IPR_PALtemp17 = 0x151, // sysval
+ IPR_PALtemp18 = 0x152, // usp
+ IPR_PALtemp19 = 0x153, // ksp
+ IPR_PALtemp20 = 0x154, // PTBR
+ IPR_PALtemp21 = 0x155, // entMM
+ IPR_PALtemp22 = 0x156, // kgp
+ IPR_PALtemp23 = 0x157, // PCBB
+
+ IPR_DTB_ASN = 0x200, // DTLB address space number register
+ IPR_DTB_CM = 0x201, // DTLB current mode register
+ IPR_DTB_TAG = 0x202, // DTLB tag register
+ IPR_DTB_PTE = 0x203, // DTLB page table entry register
+ IPR_DTB_PTE_TEMP = 0x204, // DTLB page table entry temporary register
+
+ IPR_MM_STAT = 0x205, // data MMU fault status register
+ IPR_VA = 0x206, // fault virtual address register
+ IPR_VA_FORM = 0x207, // formatted virtual address register
+ IPR_MVPTBR = 0x208, // MTU virtual page table base register
+ IPR_DTB_IAP = 0x209, // DTLB invalidate all process register
+ IPR_DTB_IA = 0x20a, // DTLB invalidate all register
+ IPR_DTB_IS = 0x20b, // DTLB invalidate single register
+ IPR_ALT_MODE = 0x20c, // alternate mode register
+ IPR_CC = 0x20d, // cycle counter register
+ IPR_CC_CTL = 0x20e, // cycle counter control register
+ IPR_MCSR = 0x20f, // MTU control register
+
+ IPR_DC_FLUSH = 0x210,
+ IPR_DC_PERR_STAT = 0x212, // Dcache parity error status register
+ IPR_DC_TEST_CTL = 0x213, // Dcache test tag control register
+ IPR_DC_TEST_TAG = 0x214, // Dcache test tag register
+ IPR_DC_TEST_TAG_TEMP = 0x215, // Dcache test tag temporary register
+ IPR_DC_MODE = 0x216, // Dcache mode register
+ IPR_MAF_MODE = 0x217, // miss address file mode register
+
+ NumInternalProcRegs // number of IPR registers
+ };
+#else
+ const int NumInternalProcRegs = 0;
#endif
+
+ // Constants Related to the number of registers
+
+ const int NumIntArchRegs = 32;
+ const int NumPALShadowRegs = 8;
+ const int NumFloatArchRegs = 32;
+ // @todo: Figure out what this number really should be.
+ const int NumMiscArchRegs = 32;
+
+ const int NumIntRegs = NumIntArchRegs + NumPALShadowRegs;
+ const int NumFloatRegs = NumFloatArchRegs;
+ const int NumMiscRegs = NumMiscArchRegs;
+
+ const int TotalNumRegs = NumIntRegs + NumFloatRegs +
+ NumMiscRegs + NumInternalProcRegs;
+
+ const int TotalDataRegs = NumIntRegs + NumFloatRegs;
+
+ // Static instruction parameters
+ const int MaxInstSrcRegs = 3;
+ const int MaxInstDestRegs = 2;
+
+ // semantically meaningful register indices
+ const int ZeroReg = 31; // architecturally meaningful
+ // the rest of these depend on the ABI
+ const int StackPointerReg = 30;
+ const int GlobalPointerReg = 29;
+ const int ProcedureValueReg = 27;
+ const int ReturnAddressReg = 26;
+ const int ReturnValueReg = 0;
+ const int FramePointerReg = 15;
+ const int ArgumentReg0 = 16;
+ const int ArgumentReg1 = 17;
+ const int ArgumentReg2 = 18;
+ const int ArgumentReg3 = 19;
+ const int ArgumentReg4 = 20;
+ const int ArgumentReg5 = 21;
+ const int SyscallNumReg = ReturnValueReg;
+ const int SyscallPseudoReturnReg = ArgumentReg4;
+ const int SyscallSuccessReg = 19;
+
+ const int LogVMPageSize = 13; // 8K bytes
+ const int VMPageSize = (1 << LogVMPageSize);
+
+ const int BranchPredAddrShiftAmt = 2; // instructions are 4-byte aligned
+
+ const int MachineBytes = 8;
+ const int WordBytes = 4;
+ const int HalfwordBytes = 2;
+ const int ByteBytes = 1;
+
+ // return a no-op instruction... used for instruction fetch faults
+ // Alpha UNOP (ldq_u r31,0(r0))
+ const ExtMachInst NoopMachInst = 0x2ffe0000;
+
+ // redirected register map, really only used for the full system case.
+ extern const int reg_redir[NumIntRegs];
+
};
#endif // __ARCH_ALPHA_ISA_TRAITS_HH__
diff --git a/src/arch/alpha/process.cc b/src/arch/alpha/process.cc
index 970292cd8..32fb97229 100644
--- a/src/arch/alpha/process.cc
+++ b/src/arch/alpha/process.cc
@@ -29,7 +29,7 @@
* Ali Saidi
*/
-#include "arch/alpha/constants.hh"
+#include "arch/alpha/isa_traits.hh"
#include "arch/alpha/process.hh"
#include "base/loader/object_file.hh"
#include "base/misc.hh"
diff --git a/src/arch/alpha/regfile.hh b/src/arch/alpha/regfile.hh
index 9ecad6f42..c31619408 100644
--- a/src/arch/alpha/regfile.hh
+++ b/src/arch/alpha/regfile.hh
@@ -32,14 +32,19 @@
#define __ARCH_ALPHA_REGFILE_HH__
#include "arch/alpha/types.hh"
-#include "arch/alpha/constants.hh"
+#include "arch/alpha/isa_traits.hh"
#include "sim/faults.hh"
+#include <string>
+
+//XXX These should be implemented by someone who knows the alpha stuff better
+
class Checkpoint;
class ThreadContext;
namespace AlphaISA
{
+
class IntRegFile
{
protected:
@@ -268,14 +273,7 @@ namespace AlphaISA
void serialize(std::ostream &os);
void unserialize(Checkpoint *cp, const std::string &section);
- enum ContextParam
- {
- CONTEXT_PALMODE
- };
-
- typedef bool ContextVal;
-
- void changeContext(ContextParam param, ContextVal val)
+ void changeContext(RegContextParam param, RegContextVal val)
{
//This would be an alternative place to call/implement
//the swapPALShadow function
diff --git a/src/arch/alpha/syscallreturn.hh b/src/arch/alpha/syscallreturn.hh
new file mode 100644
index 000000000..803c3b7da
--- /dev/null
+++ b/src/arch/alpha/syscallreturn.hh
@@ -0,0 +1,87 @@
+/*
+ * 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: Steve Reinhardt
+ * Gabe Black
+ */
+
+#ifndef __ARCH_ALPHA_SYSCALLRETURN_HH__
+#define __ARCH_ALPHA_SYSCALLRETURN_HH__
+
+class SyscallReturn {
+ public:
+ template <class T>
+ SyscallReturn(T v, bool s)
+ {
+ retval = (uint64_t)v;
+ success = s;
+ }
+
+ template <class T>
+ SyscallReturn(T v)
+ {
+ success = (v >= 0);
+ retval = (uint64_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 AlphaISA
+{
+ static inline void setSyscallReturn(SyscallReturn return_value, RegFile *regs)
+ {
+ // check for error condition. Alpha syscall convention is to
+ // indicate success/failure in reg a3 (r19) and put the
+ // return value itself in the standard return value reg (v0).
+ if (return_value.successful()) {
+ // no error
+ regs->setIntReg(SyscallSuccessReg, 0);
+ regs->setIntReg(ReturnValueReg, return_value.value());
+ } else {
+ // got an error, return details
+ regs->setIntReg(SyscallSuccessReg, (IntReg)-1);
+ regs->setIntReg(ReturnValueReg, -return_value.value());
+ }
+ }
+}
+
+#endif
diff --git a/src/arch/alpha/types.hh b/src/arch/alpha/types.hh
index 5859052e9..ae42552d8 100644
--- a/src/arch/alpha/types.hh
+++ b/src/arch/alpha/types.hh
@@ -32,7 +32,7 @@
#ifndef __ARCH_ALPHA_TYPES_HH__
#define __ARCH_ALPHA_TYPES_HH__
-#include "sim/host.hh"
+#include <inttypes.h>
namespace AlphaISA
{
@@ -56,6 +56,13 @@ namespace AlphaISA
MiscReg ctrlreg;
} AnyReg;
+ enum RegContextParam
+ {
+ CONTEXT_PALMODE
+ };
+
+ typedef bool RegContextVal;
+
enum annotes {
ANNOTE_NONE = 0,
// An impossible number for instruction annotations
diff --git a/src/arch/alpha/utility.hh b/src/arch/alpha/utility.hh
index ec136091c..d3ccc0444 100644
--- a/src/arch/alpha/utility.hh
+++ b/src/arch/alpha/utility.hh
@@ -34,7 +34,7 @@
#include "config/full_system.hh"
#include "arch/alpha/types.hh"
-#include "arch/alpha/constants.hh"
+#include "arch/alpha/isa_traits.hh"
#include "arch/alpha/regfile.hh"
#include "base/misc.hh"
diff --git a/src/arch/mips/isa_traits.cc b/src/arch/mips/isa_traits.cc
index 1ec4bde3e..3a8cb46a5 100644
--- a/src/arch/mips/isa_traits.cc
+++ b/src/arch/mips/isa_traits.cc
@@ -30,15 +30,13 @@
*/
#include "arch/mips/isa_traits.hh"
-//#include "config/full_system.hh"
-#include "cpu/static_inst.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)
{
diff --git a/src/arch/mips/isa_traits.hh b/src/arch/mips/isa_traits.hh
index 2f485c7fd..fd484e315 100644
--- a/src/arch/mips/isa_traits.hh
+++ b/src/arch/mips/isa_traits.hh
@@ -32,149 +32,87 @@
#ifndef __ARCH_MIPS_ISA_TRAITS_HH__
#define __ARCH_MIPS_ISA_TRAITS_HH__
-#include "arch/mips/constants.hh"
#include "arch/mips/types.hh"
-#include "arch/mips/regfile/regfile.hh"
-#include "arch/mips/faults.hh"
-#include "arch/mips/utility.hh"
-#include "base/misc.hh"
-#include "config/full_system.hh"
-#include "sim/byteswap.hh"
#include "sim/host.hh"
-#include "sim/faults.hh"
-
-#include <vector>
-
-class FastCPU;
-class FullCPU;
-class Checkpoint;
-class ThreadContext;
namespace LittleEndianGuest {};
#define TARGET_MIPS
-class StaticInst;
class StaticInstPtr;
-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
{
using namespace LittleEndianGuest;
- 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());
- }
- }
-
StaticInstPtr decodeInst(ExtMachInst);
- 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
- }
-
- /**
- * Function to insure ISA semantics about 0 registers.
- * @param tc The thread context.
- */
- template <class TC>
- void zeroRegisters(TC *tc);
-
-// const Addr MaxAddr = (Addr)-1;
-
- void copyRegs(ThreadContext *src, ThreadContext *dest);
-
- // Machine operations
-
- void saveMachineReg(AnyReg &savereg, const RegFile &reg_file,
- int regnum);
-
- void restoreMachineReg(RegFile &regs, const AnyReg &reg,
- int regnum);
-
-#if 0
- static void serializeSpecialRegs(const Serializable::Proxy &proxy,
- const RegFile &regs);
-
- static void unserializeSpecialRegs(const IniFile *db,
- const std::string &category,
- ConfigNode *node,
- RegFile &regs);
-#endif
-
- static inline Addr alignAddress(const Addr &addr,
- unsigned int nbytes) {
- return (addr & ~(nbytes - 1));
- }
-
- // 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;
- }
+ 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;
};
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
index 61efbb416..f057461ae 100644
--- a/src/arch/mips/regfile/float_regfile.hh
+++ b/src/arch/mips/regfile/float_regfile.hh
@@ -26,24 +26,56 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#ifndef __ARCH_MIPS_FLOAT_REGFILE_HH__
-#define __ARCH_MIPS_FLOAT_REGFILE_HH__
+#ifndef __ARCH_MIPS_REGFILE_FLOAT_REGFILE_HH__
+#define __ARCH_MIPS_REGFILE_FLOAT_REGFILE_HH__
#include "arch/mips/types.hh"
-#include "arch/mips/constants.hh"
+#include "arch/mips/isa_traits.hh"
#include "base/misc.hh"
#include "base/bitfield.hh"
-#include "config/full_system.hh"
-#include "sim/byteswap.hh"
#include "sim/faults.hh"
-#include "sim/host.hh"
+
+#include <string>
class Checkpoint;
-class ExecContext;
-class Regfile;
namespace MipsISA
{
+ 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:
diff --git a/src/arch/mips/regfile/int_regfile.hh b/src/arch/mips/regfile/int_regfile.hh
index 5add1b7be..5496fc1f5 100644
--- a/src/arch/mips/regfile/int_regfile.hh
+++ b/src/arch/mips/regfile/int_regfile.hh
@@ -28,20 +28,24 @@
* Authors: Korey Sewell
*/
-#ifndef __ARCH_MIPS_INT_REGFILE_HH__
-#define __ARCH_MIPS_INT_REGFILE_HH__
+#ifndef __ARCH_MIPS_REGFILE_INT_REGFILE_HH__
+#define __ARCH_MIPS_REGFILE_INT_REGFILE_HH__
#include "arch/mips/types.hh"
-#include "arch/mips/constants.hh"
+#include "arch/mips/isa_traits.hh"
#include "base/misc.hh"
#include "sim/faults.hh"
class Checkpoint;
class ThreadContext;
-class Regfile;
namespace MipsISA
{
+ enum MiscIntRegNums {
+ HI = NumIntArchRegs,
+ LO
+ };
+
class IntRegFile
{
protected:
diff --git a/src/arch/mips/regfile/misc_regfile.hh b/src/arch/mips/regfile/misc_regfile.hh
index 67aef9c63..66d3218d4 100644
--- a/src/arch/mips/regfile/misc_regfile.hh
+++ b/src/arch/mips/regfile/misc_regfile.hh
@@ -28,19 +28,164 @@
* Authors: Korey Sewell
*/
-#ifndef __ARCH_MIPS_MISC_REGFILE_HH__
-#define __ARCH_MIPS_MISC_REGFILE_HH__
+#ifndef __ARCH_MIPS_REGFILE_MISC_REGFILE_HH__
+#define __ARCH_MIPS_REGFILE_MISC_REGFILE_HH__
+#include "arch/mips/isa_traits.hh"
#include "arch/mips/types.hh"
-#include "arch/mips/constants.hh"
#include "sim/faults.hh"
-class Checkpoint;
class ThreadContext;
-class Regfile;
namespace MipsISA
{
+ //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:
diff --git a/src/arch/mips/regfile/regfile.hh b/src/arch/mips/regfile/regfile.hh
index a68120299..dce015a36 100644
--- a/src/arch/mips/regfile/regfile.hh
+++ b/src/arch/mips/regfile/regfile.hh
@@ -28,11 +28,11 @@
* Authors: Korey Sewell
*/
-#ifndef __ARCH_MIPS_REGFILE_HH__
-#define __ARCH_MIPS_REGFILE_HH__
+#ifndef __ARCH_MIPS_REGFILE_REGFILE_HH__
+#define __ARCH_MIPS_REGFILE_REGFILE_HH__
#include "arch/mips/types.hh"
-#include "arch/mips/constants.hh"
+#include "arch/mips/isa_traits.hh"
#include "arch/mips/regfile/int_regfile.hh"
#include "arch/mips/regfile/float_regfile.hh"
#include "arch/mips/regfile/misc_regfile.hh"
@@ -171,10 +171,7 @@ namespace MipsISA
void serialize(std::ostream &os);
void unserialize(Checkpoint *cp, const std::string &section);
- typedef int ContextParam;
- typedef int ContextVal;
-
- void changeContext(ContextParam param, ContextVal val)
+ void changeContext(RegContextParam param, RegContextVal val)
{
}
};
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
index 6330044d9..d4fa296fd 100644
--- a/src/arch/mips/types.hh
+++ b/src/arch/mips/types.hh
@@ -58,6 +58,9 @@ namespace MipsISA
MiscReg ctrlreg;
} AnyReg;
+ typedef int RegContextParam;
+ typedef int RegContextVal;
+
//used in FP convert & round function
enum ConvertType{
SINGLE_TO_DOUBLE,
diff --git a/src/arch/mips/utility.hh b/src/arch/mips/utility.hh
index c5c69ddcd..9558aa235 100644
--- a/src/arch/mips/utility.hh
+++ b/src/arch/mips/utility.hh
@@ -33,8 +33,10 @@
#define __ARCH_MIPS_UTILITY_HH__
#include "arch/mips/types.hh"
-#include "arch/mips/constants.hh"
+#include "arch/mips/isa_traits.hh"
#include "base/misc.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"
namespace MipsISA {
@@ -51,6 +53,48 @@ namespace MipsISA {
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
+ }
};
diff --git a/src/arch/sparc/SConscript b/src/arch/sparc/SConscript
index e7a8278db..66f2b57e0 100644
--- a/src/arch/sparc/SConscript
+++ b/src/arch/sparc/SConscript
@@ -45,22 +45,25 @@ Import('env')
# Base sources used by all configurations.
base_sources = Split('''
faults.cc
- isa_traits.cc
+ floatregfile.cc
+ intregfile.cc
+ miscregfile.cc
+ regfile.cc
''')
# Full-system sources
full_system_sources = Split('''
- vtophys.cc
ua2005.cc
+ vtophys.cc
''')
# Syscall emulation (non-full-system) sources
syscall_emulation_sources = Split('''
linux/linux.cc
linux/process.cc
- solaris/solaris.cc
- solaris/process.cc
process.cc
+ solaris/process.cc
+ solaris/solaris.cc
''')
sources = base_sources
diff --git a/src/arch/sparc/floatregfile.cc b/src/arch/sparc/floatregfile.cc
new file mode 100644
index 000000000..3cacbb278
--- /dev/null
+++ b/src/arch/sparc/floatregfile.cc
@@ -0,0 +1,174 @@
+/*
+ * 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
+ * Ali Saidi
+ */
+
+#include "arch/sparc/floatregfile.hh"
+#include "base/trace.hh"
+#include "sim/byteswap.hh"
+#include "sim/serialize.hh"
+
+using namespace SparcISA;
+using namespace std;
+
+class Checkpoint;
+
+string SparcISA::getFloatRegName(RegIndex index)
+{
+ static std::string floatRegName[NumFloatRegs] =
+ {"f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7",
+ "f8", "f9", "f10", "f11", "f12", "f13", "f14", "f15",
+ "f16", "f17", "f18", "f19", "f20", "f21", "f22", "f23",
+ "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31",
+ "f32", "f33", "f34", "f35", "f36", "f37", "f38", "f39",
+ "f40", "f41", "f42", "f43", "f44", "f45", "f46", "f47",
+ "f48", "f49", "f50", "f51", "f52", "f53", "f54", "f55",
+ "f56", "f57", "f58", "f59", "f60", "f61", "f62", "f63"};
+ return floatRegName[index];
+}
+
+void FloatRegFile::clear()
+{
+ bzero(regSpace, sizeof(regSpace));
+}
+
+FloatReg FloatRegFile::readReg(int floatReg, int width)
+{
+ //In each of these cases, we have to copy the value into a temporary
+ //variable. This is because we may otherwise try to access an
+ //unaligned portion of memory.
+ switch(width)
+ {
+ case SingleWidth:
+ float32_t result32;
+ memcpy(&result32, regSpace + 4 * floatReg, sizeof(result32));
+ return htog(result32);
+ case DoubleWidth:
+ float64_t result64;
+ memcpy(&result64, regSpace + 4 * floatReg, sizeof(result64));
+ return htog(result64);
+ case QuadWidth:
+ float128_t result128;
+ memcpy(&result128, regSpace + 4 * floatReg, sizeof(result128));
+ return htog(result128);
+ default:
+ panic("Attempted to read a %d bit floating point register!", width);
+ }
+}
+
+FloatRegBits FloatRegFile::readRegBits(int floatReg, int width)
+{
+ //In each of these cases, we have to copy the value into a temporary
+ //variable. This is because we may otherwise try to access an
+ //unaligned portion of memory.
+ switch(width)
+ {
+ case SingleWidth:
+ uint32_t result32;
+ memcpy(&result32, regSpace + 4 * floatReg, sizeof(result32));
+ return htog(result32);
+ case DoubleWidth:
+ uint64_t result64;
+ memcpy(&result64, regSpace + 4 * floatReg, sizeof(result64));
+ return htog(result64);
+ case QuadWidth:
+ uint64_t result128;
+ memcpy(&result128, regSpace + 4 * floatReg, sizeof(result128));
+ return htog(result128);
+ default:
+ panic("Attempted to read a %d bit floating point register!", width);
+ }
+}
+
+Fault FloatRegFile::setReg(int floatReg, const FloatReg &val, int width)
+{
+ //In each of these cases, we have to copy the value into a temporary
+ //variable. This is because we may otherwise try to access an
+ //unaligned portion of memory.
+
+ uint32_t result32;
+ uint64_t result64;
+ DPRINTF(Sparc, "Setting floating point register %d\n", floatReg);
+ switch(width)
+ {
+ case SingleWidth:
+ result32 = gtoh((uint32_t)val);
+ memcpy(regSpace + 4 * floatReg, &result32, sizeof(result32));
+ break;
+ case DoubleWidth:
+ result64 = gtoh((uint64_t)val);
+ memcpy(regSpace + 4 * floatReg, &result64, sizeof(result64));
+ break;
+ case QuadWidth:
+ panic("Quad width FP not implemented.");
+ break;
+ default:
+ panic("Attempted to read a %d bit floating point register!", width);
+ }
+ return NoFault;
+}
+
+Fault FloatRegFile::setRegBits(int floatReg, const FloatRegBits &val, int width)
+{
+ //In each of these cases, we have to copy the value into a temporary
+ //variable. This is because we may otherwise try to access an
+ //unaligned portion of memory.
+ uint32_t result32;
+ uint64_t result64;
+ switch(width)
+ {
+ case SingleWidth:
+ result32 = gtoh((uint32_t)val);
+ memcpy(regSpace + 4 * floatReg, &result32, sizeof(result32));
+ break;
+ case DoubleWidth:
+ result64 = gtoh((uint64_t)val);
+ memcpy(regSpace + 4 * floatReg, &result64, sizeof(result64));
+ break;
+ case QuadWidth:
+ panic("Quad width FP not implemented.");
+ break;
+ default:
+ panic("Attempted to read a %d bit floating point register!", width);
+ }
+ return NoFault;
+}
+
+void FloatRegFile::serialize(std::ostream &os)
+{
+ SERIALIZE_ARRAY((unsigned char *)regSpace,
+ SingleWidth / 8 * NumFloatRegs);
+}
+
+void FloatRegFile::unserialize(Checkpoint *cp, const std::string &section)
+{
+ UNSERIALIZE_ARRAY((unsigned char *)regSpace,
+ SingleWidth / 8 * NumFloatRegs);
+}
+
diff --git a/src/arch/sparc/floatregfile.hh b/src/arch/sparc/floatregfile.hh
new file mode 100644
index 000000000..9d760c9ff
--- /dev/null
+++ b/src/arch/sparc/floatregfile.hh
@@ -0,0 +1,83 @@
+/*
+ * 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
+ * Ali Saidi
+ */
+
+#ifndef __ARCH_SPARC_FLOATREGFILE_HH__
+#define __ARCH_SPARC_FLOATREGFILE_HH__
+
+#include "arch/sparc/faults.hh"
+#include "arch/sparc/isa_traits.hh"
+#include "arch/sparc/types.hh"
+
+#include <string>
+
+namespace SparcISA
+{
+ std::string getFloatRegName(RegIndex);
+
+ typedef float float32_t;
+ typedef double float64_t;
+ //FIXME long double refers to a 10 byte float, rather than a
+ //16 byte float as required. This data type may have to be emulated.
+ typedef double float128_t;
+
+ class FloatRegFile
+ {
+ public:
+ static const int SingleWidth = 32;
+ static const int DoubleWidth = 64;
+ static const int QuadWidth = 128;
+
+ protected:
+
+ //Since the floating point registers overlap each other,
+ //A generic storage space is used. The float to be returned is
+ //pulled from the appropriate section of this region.
+ char regSpace[(SingleWidth / 8) * NumFloatRegs];
+
+ public:
+
+ void clear();
+
+ FloatReg readReg(int floatReg, int width);
+
+ FloatRegBits readRegBits(int floatReg, int width);
+
+ Fault setReg(int floatReg, const FloatReg &val, int width);
+
+ Fault setRegBits(int floatReg, const FloatRegBits &val, int width);
+
+ void serialize(std::ostream &os);
+
+ void unserialize(Checkpoint *cp, const std::string &section);
+ };
+}
+
+#endif
diff --git a/src/arch/sparc/intregfile.cc b/src/arch/sparc/intregfile.cc
new file mode 100644
index 000000000..0cc0a886a
--- /dev/null
+++ b/src/arch/sparc/intregfile.cc
@@ -0,0 +1,133 @@
+/*
+ * 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
+ * Ali Saidi
+ */
+
+#include "arch/sparc/intregfile.hh"
+#include "base/trace.hh"
+#include "sim/serialize.hh"
+
+using namespace SparcISA;
+using namespace std;
+
+class Checkpoint;
+
+string SparcISA::getIntRegName(RegIndex index)
+{
+ static std::string intRegName[NumIntRegs] =
+ {"g0", "g1", "g2", "g3", "g4", "g5", "g6", "g7",
+ "o0", "o1", "o2", "o3", "o4", "o5", "o6", "o7",
+ "l0", "l1", "l2", "l3", "l4", "l5", "l6", "l7",
+ "i0", "i1", "i2", "i3", "i4", "i5", "i6", "i7"};
+ return intRegName[index];
+}
+
+int IntRegFile::flattenIndex(int reg)
+{
+ int flatIndex = offset[reg >> FrameOffsetBits]
+ | (reg & FrameOffsetMask);
+ DPRINTF(Sparc, "Flattened index %d into %d.\n", reg, flatIndex);
+ return flatIndex;
+}
+
+void IntRegFile::clear()
+{
+ int x;
+ for (x = 0; x < MaxGL; x++)
+ memset(regGlobals[x], 0, sizeof(regGlobals[x]));
+ for(int x = 0; x < 2 * NWindows; x++)
+ bzero(regSegments[x], sizeof(regSegments[x]));
+}
+
+IntRegFile::IntRegFile()
+{
+ offset[Globals] = 0;
+ regView[Globals] = regGlobals[0];
+ setCWP(0);
+ clear();
+}
+
+IntReg IntRegFile::readReg(int intReg)
+{
+ IntReg val =
+ regView[intReg >> FrameOffsetBits][intReg & FrameOffsetMask];
+ DPRINTF(Sparc, "Read register %d = 0x%x\n", intReg, val);
+ return val;
+}
+
+Fault IntRegFile::setReg(int intReg, const IntReg &val)
+{
+ if(intReg)
+ DPRINTF(Sparc, "Wrote register %d = 0x%x\n", intReg, val);
+ regView[intReg >> FrameOffsetBits][intReg & FrameOffsetMask] = val;
+ return NoFault;
+}
+
+//This doesn't effect the actual CWP register.
+//It's purpose is to adjust the view of the register file
+//to what it would be if CWP = cwp.
+void IntRegFile::setCWP(int cwp)
+{
+ int index = ((NWindows - cwp) % NWindows) * 2;
+ offset[Outputs] = FrameOffset + (index * RegsPerFrame);
+ offset[Locals] = FrameOffset + ((index+1) * RegsPerFrame);
+ offset[Inputs] = FrameOffset +
+ (((index+2) % (NWindows * 2)) * RegsPerFrame);
+ regView[Outputs] = regSegments[index];
+ regView[Locals] = regSegments[index+1];
+ regView[Inputs] = regSegments[(index+2) % (NWindows * 2)];
+
+ DPRINTF(Sparc, "Changed the CWP value to %d\n", cwp);
+}
+
+void IntRegFile::setGlobals(int gl)
+{
+ DPRINTF(Sparc, "Now using %d globals", gl);
+
+ regView[Globals] = regGlobals[gl];
+ offset[Globals] = RegGlobalOffset + gl * RegsPerFrame;
+}
+
+void IntRegFile::serialize(std::ostream &os)
+{
+ unsigned int x;
+ for(x = 0; x < MaxGL; x++)
+ SERIALIZE_ARRAY(regGlobals[x], RegsPerFrame);
+ for(x = 0; x < 2 * NWindows; x++)
+ SERIALIZE_ARRAY(regSegments[x], RegsPerFrame);
+}
+
+void IntRegFile::unserialize(Checkpoint *cp, const std::string &section)
+{
+ unsigned int x;
+ for(x = 0; x < MaxGL; x++)
+ UNSERIALIZE_ARRAY(regGlobals[x], RegsPerFrame);
+ for(unsigned int x = 0; x < 2 * NWindows; x++)
+ UNSERIALIZE_ARRAY(regSegments[x], RegsPerFrame);
+}
diff --git a/src/arch/sparc/intregfile.hh b/src/arch/sparc/intregfile.hh
new file mode 100644
index 000000000..d305c753b
--- /dev/null
+++ b/src/arch/sparc/intregfile.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: Gabe Black
+ * Ali Saidi
+ */
+
+#ifndef __ARCH_SPARC_INTREGFILE_HH__
+#define __ARCH_SPARC_INTREGFILE_HH__
+
+#include "arch/sparc/faults.hh"
+#include "arch/sparc/isa_traits.hh"
+#include "arch/sparc/types.hh"
+
+#include <string>
+
+namespace SparcISA
+{
+ class RegFile;
+
+ //This function translates integer register file indices into names
+ std::string getIntRegName(RegIndex);
+
+ class IntRegFile
+ {
+ private:
+ friend class RegFile;
+ protected:
+ static const int FrameOffsetBits = 3;
+ static const int FrameNumBits = 2;
+
+ static const int RegsPerFrame = 1 << FrameOffsetBits;
+ static const int FrameNumMask =
+ (FrameNumBits == sizeof(int)) ?
+ (unsigned int)(-1) :
+ (1 << FrameNumBits) - 1;
+ static const int FrameOffsetMask =
+ (FrameOffsetBits == sizeof(int)) ?
+ (unsigned int)(-1) :
+ (1 << FrameOffsetBits) - 1;
+
+ IntReg regGlobals[MaxGL][RegsPerFrame];
+ IntReg regSegments[2 * NWindows][RegsPerFrame];
+
+ enum regFrame {Globals, Outputs, Locals, Inputs, NumFrames};
+
+ IntReg * regView[NumFrames];
+
+ static const int RegGlobalOffset = 0;
+ static const int FrameOffset = MaxGL * RegsPerFrame;
+ int offset[NumFrames];
+
+ public:
+
+ int flattenIndex(int reg);
+
+ void clear();
+
+ IntRegFile();
+
+ IntReg readReg(int intReg);
+
+ Fault setReg(int intReg, const IntReg &val);
+
+ void serialize(std::ostream &os);
+
+ void unserialize(Checkpoint *cp, const std::string &section);
+
+ protected:
+ //This doesn't effect the actual CWP register.
+ //It's purpose is to adjust the view of the register file
+ //to what it would be if CWP = cwp.
+ void setCWP(int cwp);
+
+ void setGlobals(int gl);
+ };
+}
+
+#endif
diff --git a/src/arch/sparc/isa_traits.hh b/src/arch/sparc/isa_traits.hh
index 346f7b730..7f830eb28 100644
--- a/src/arch/sparc/isa_traits.hh
+++ b/src/arch/sparc/isa_traits.hh
@@ -25,13 +25,13 @@
* (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
- * Gabe Black
+ * Authors: Gabe Black
*/
#ifndef __ARCH_SPARC_ISA_TRAITS_HH__
#define __ARCH_SPARC_ISA_TRAITS_HH__
+#include "arch/sparc/types.hh"
#include "base/misc.hh"
#include "config/full_system.hh"
#include "sim/host.hh"
@@ -46,70 +46,45 @@ class StaticInstPtr;
namespace BigEndianGuest {}
-#if !FULL_SYSTEM
-class SyscallReturn
-{
- public:
- template <class T>
- SyscallReturn(T v, bool s)
- {
- retval = (uint64_t)v;
- success = s;
- }
-
- template <class T>
- SyscallReturn(T v)
- {
- success = (v >= 0);
- retval = (uint64_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;
-};
-
-#endif
-
#if FULL_SYSTEM
#include "arch/sparc/isa_fullsys_traits.hh"
#endif
namespace SparcISA
{
+ class RegFile;
+
+ //This makes sure the big endian versions of certain functions are used.
+ using namespace BigEndianGuest;
+
+ //TODO this needs to be a SPARC Noop
+ // Alpha UNOP (ldq_u r31,0(r0))
+ const MachInst NoopMachInst = 0x2ffe0000;
+
+ const int NumIntRegs = 32;
+ const int NumFloatRegs = 64;
+ const int NumMiscRegs = 40;
// These enumerate all the registers for dependence tracking.
enum DependenceTags {
// 0..31 are the integer regs 0..31
- // 32..63 are the FP regs 0..31, i.e. use (reg + FP_Base_DepTag)
- FP_Base_DepTag = 32,
- Ctrl_Base_DepTag = 96,
+ // 32..95 are the FP regs 0..31, i.e. use (reg + FP_Base_DepTag)
+ FP_Base_DepTag = NumIntRegs,
+ Ctrl_Base_DepTag = NumIntRegs + NumFloatRegs,
//XXX These are here solely to get compilation and won't work
Fpcr_DepTag = 0,
Uniq_DepTag = 0
};
- //This makes sure the big endian versions of certain functions are used.
- using namespace BigEndianGuest;
- typedef uint32_t MachInst;
- typedef uint64_t ExtMachInst;
+ // MAXTL - maximum trap level
+ const int MaxPTL = 2;
+ const int MaxTL = 6;
+ const int MaxGL = 3;
+ const int MaxPGL = 2;
- const int NumIntRegs = 32;
- const int NumFloatRegs = 64;
- const int NumMiscRegs = 32;
+ // NWINDOWS - number of register windows, can be 3 to 32
+ const int NWindows = 32;
// semantically meaningful register indices
const int ZeroReg = 0; // architecturally meaningful
@@ -131,14 +106,6 @@ namespace SparcISA
const int MaxInstSrcRegs = 8;
const int MaxInstDestRegs = 9;
- typedef uint64_t IntReg;
-
- // control register file contents
- typedef uint64_t MiscReg;
-
- typedef double FloatReg;
- typedef uint64_t FloatRegBits;
-
//8K. This value is implmentation specific; and should probably
//be somewhere else.
const int LogVMPageSize = 13;
@@ -165,29 +132,4 @@ namespace SparcISA
extern const MachInst NoopMachInst;
}
-#include "arch/sparc/regfile.hh"
-
-namespace SparcISA
-{
-
-#if !FULL_SYSTEM
- static inline void setSyscallReturn(SyscallReturn return_value,
- RegFile *regs)
- {
- // check for error condition. SPARC syscall convention is to
- // indicate success/failure in reg the carry bit of the ccr
- // and put the return value itself in the standard return value reg ().
- if (return_value.successful()) {
- // no error, clear XCC.C
- regs->setMiscReg(MISCREG_CCR, regs->readMiscReg(MISCREG_CCR) & 0xEF);
- regs->setIntReg(ReturnValueReg, return_value.value());
- } else {
- // got an error, set XCC.C
- regs->setMiscReg(MISCREG_CCR, regs->readMiscReg(MISCREG_CCR) | 0x10);
- regs->setIntReg(ReturnValueReg, return_value.value());
- }
- }
-#endif
-};
-
#endif // __ARCH_SPARC_ISA_TRAITS_HH__
diff --git a/src/arch/sparc/miscregfile.cc b/src/arch/sparc/miscregfile.cc
new file mode 100644
index 000000000..8041e45c0
--- /dev/null
+++ b/src/arch/sparc/miscregfile.cc
@@ -0,0 +1,540 @@
+/*
+ * 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
+ * Ali Saidi
+ */
+
+#include "arch/sparc/miscregfile.hh"
+#include "base/trace.hh"
+#include "cpu/base.hh"
+#include "cpu/thread_context.hh"
+
+using namespace SparcISA;
+using namespace std;
+
+class Checkpoint;
+
+//These functions map register indices to names
+string SparcISA::getMiscRegName(RegIndex index)
+{
+ static::string miscRegName[NumMiscRegs] =
+ {"y", "ccr", "asi", "tick", "pc", "fprs", "pcr", "pic",
+ "gsr", "softint_set", "softint_clr", "softint", "tick_cmpr",
+ "stick", "stick_cmpr",
+ "tpc", "tnpc", "tstate", "tt", "privtick", "tba", "pstate", "tl",
+ "pil", "cwp", "cansave", "canrestore", "cleanwin", "otherwin",
+ "wstate", "gl",
+ "hpstate", "htstate", "hintp", "htba", "hver", "strand_sts_reg",
+ "hstick_cmpr",
+ "fsr"};
+ return miscRegName[index];
+}
+
+#if FULL_SYSTEM
+
+//XXX These need an implementation someplace
+/** Fullsystem only register version of ReadRegWithEffect() */
+MiscReg MiscRegFile::readFSRegWithEffect(int miscReg, Fault &fault, ThreadContext *tc);
+/** Fullsystem only register version of SetRegWithEffect() */
+Fault MiscRegFile::setFSRegWithEffect(int miscReg, const MiscReg &val,
+ ThreadContext * tc);
+#endif
+
+void MiscRegFile::reset()
+{
+ pstateFields.pef = 0; //No FPU
+ //pstateFields.pef = 1; //FPU
+#if FULL_SYSTEM
+ //For SPARC, when a system is first started, there is a power
+ //on reset Trap which sets the processor into the following state.
+ //Bits that aren't set aren't defined on startup.
+ tl = MaxTL;
+ gl = MaxGL;
+
+ tickFields.counter = 0; //The TICK register is unreadable bya
+ tickFields.npt = 1; //The TICK register is unreadable by by !priv
+
+ softint = 0; // Clear all the soft interrupt bits
+ tick_cmprFields.int_dis = 1; // disable timer compare interrupts
+ tick_cmprFields.tick_cmpr = 0; // Reset to 0 for pretty printing
+ stickFields.npt = 1; //The TICK register is unreadable by by !priv
+ stick_cmprFields.int_dis = 1; // disable timer compare interrupts
+ stick_cmprFields.tick_cmpr = 0; // Reset to 0 for pretty printing
+
+
+ tt[tl] = power_on_reset;
+ pstate = 0; // fields 0 but pef
+ pstateFields.pef = 1;
+
+ hpstate = 0;
+ hpstateFields.red = 1;
+ hpstateFields.hpriv = 1;
+ hpstateFields.tlz = 0; // this is a guess
+ hintp = 0; // no interrupts pending
+ hstick_cmprFields.int_dis = 1; // disable timer compare interrupts
+ hstick_cmprFields.tick_cmpr = 0; // Reset to 0 for pretty printing
+#else
+/* //This sets up the initial state of the processor for usermode processes
+ pstateFields.priv = 0; //Process runs in user mode
+ pstateFields.ie = 1; //Interrupts are enabled
+ fsrFields.rd = 0; //Round to nearest
+ fsrFields.tem = 0; //Floating point traps not enabled
+ fsrFields.ns = 0; //Non standard mode off
+ fsrFields.qne = 0; //Floating point queue is empty
+ fsrFields.aexc = 0; //No accrued exceptions
+ fsrFields.cexc = 0; //No current exceptions
+
+ //Register window management registers
+ otherwin = 0; //No windows contain info from other programs
+ canrestore = 0; //There are no windows to pop
+ cansave = MaxTL - 2; //All windows are available to save into
+ cleanwin = MaxTL;*/
+#endif
+}
+
+MiscReg MiscRegFile::readReg(int miscReg)
+{
+ switch (miscReg) {
+ case MISCREG_Y:
+ return y;
+ case MISCREG_CCR:
+ return ccr;
+ case MISCREG_ASI:
+ return asi;
+ case MISCREG_FPRS:
+ return fprs;
+ case MISCREG_TICK:
+ return tick;
+ case MISCREG_PCR:
+ case MISCREG_PIC:
+ panic("ASR number %d not implemented\n", miscReg - AsrStart);
+ case MISCREG_GSR:
+ return gsr;
+ case MISCREG_SOFTINT:
+ return softint;
+ case MISCREG_TICK_CMPR:
+ return tick_cmpr;
+ case MISCREG_STICK:
+ return stick;
+ case MISCREG_STICK_CMPR:
+ return stick_cmpr;
+
+ /** Privilged Registers */
+ case MISCREG_TPC:
+ return tpc[tl-1];
+ case MISCREG_TNPC:
+ return tnpc[tl-1];
+ case MISCREG_TSTATE:
+ return tstate[tl-1];
+ case MISCREG_TT:
+ return tt[tl-1];
+ case MISCREG_PRIVTICK:
+ panic("Priviliged access to tick registers not implemented\n");
+ case MISCREG_TBA:
+ return tba;
+ case MISCREG_PSTATE:
+ return pstate;
+ case MISCREG_TL:
+ return tl;
+ case MISCREG_PIL:
+ return pil;
+ case MISCREG_CWP:
+ return cwp;
+ case MISCREG_CANSAVE:
+ return cansave;
+ case MISCREG_CANRESTORE:
+ return canrestore;
+ case MISCREG_CLEANWIN:
+ return cleanwin;
+ case MISCREG_OTHERWIN:
+ return otherwin;
+ case MISCREG_WSTATE:
+ return wstate;
+ case MISCREG_GL:
+ return gl;
+
+ /** Hyper privileged registers */
+ case MISCREG_HPSTATE:
+ return hpstate;
+ case MISCREG_HTSTATE:
+ return htstate[tl-1];
+ case MISCREG_HINTP:
+ panic("HINTP not implemented\n");
+ case MISCREG_HTBA:
+ return htba;
+ case MISCREG_HVER:
+ return NWindows | MaxTL << 8 | MaxGL << 16;
+ case MISCREG_STRAND_STS_REG:
+ return strandStatusReg;
+ case MISCREG_HSTICK_CMPR:
+ return hstick_cmpr;
+
+ /** Floating Point Status Register */
+ case MISCREG_FSR:
+ return fsr;
+ default:
+ panic("Miscellaneous register %d not implemented\n", miscReg);
+ }
+}
+
+MiscReg MiscRegFile::readRegWithEffect(int miscReg,
+ Fault &fault, ThreadContext * tc)
+{
+ fault = NoFault;
+ switch (miscReg) {
+ case MISCREG_Y:
+ case MISCREG_CCR:
+ case MISCREG_ASI:
+ return readReg(miscReg);
+
+ case MISCREG_TICK:
+ case MISCREG_PRIVTICK:
+ // Check for reading privilege
+ if (tickFields.npt && !isNonPriv()) {
+ fault = new PrivilegedAction;
+ return 0;
+ }
+ return tc->getCpuPtr()->curCycle() - tickFields.counter |
+ tickFields.npt << 63;
+ case MISCREG_PC:
+ return tc->readPC();
+ case MISCREG_FPRS:
+ fault = new UnimpFault("FPU not implemented\n");
+ return 0;
+ case MISCREG_PCR:
+ fault = new UnimpFault("Performance Instrumentation not impl\n");
+ return 0;
+ case MISCREG_PIC:
+ fault = new UnimpFault("Performance Instrumentation not impl\n");
+ return 0;
+ case MISCREG_GSR:
+ return readReg(miscReg);
+
+ /** Privilged Registers */
+ case MISCREG_TPC:
+ case MISCREG_TNPC:
+ case MISCREG_TSTATE:
+ case MISCREG_TT:
+ if (tl == 0) {
+ fault = new IllegalInstruction;
+ return 0;
+ } // NOTE THE FALL THROUGH!
+ case MISCREG_PSTATE:
+ case MISCREG_TL:
+ return readReg(miscReg);
+
+ case MISCREG_TBA:
+ return readReg(miscReg) & ULL(~0x7FFF);
+
+ case MISCREG_PIL:
+
+ case MISCREG_CWP:
+ case MISCREG_CANSAVE:
+ case MISCREG_CANRESTORE:
+ case MISCREG_CLEANWIN:
+ case MISCREG_OTHERWIN:
+ case MISCREG_WSTATE:
+ case MISCREG_GL:
+ return readReg(miscReg);
+
+ /** Floating Point Status Register */
+ case MISCREG_FSR:
+ panic("Floating Point not implemented\n");
+ default:
+#if FULL_SYSTEM
+ return readFSRegWithEffect(miscReg, fault, tc);
+#else
+ fault = new IllegalInstruction;
+ return 0;
+#endif
+ }
+}
+
+Fault MiscRegFile::setReg(int miscReg, const MiscReg &val)
+{
+ switch (miscReg) {
+ case MISCREG_Y:
+ y = val;
+ return NoFault;
+ case MISCREG_CCR:
+ ccr = val;
+ return NoFault;
+ case MISCREG_ASI:
+ asi = val;
+ return NoFault;
+ case MISCREG_FPRS:
+ fprs = val;
+ return NoFault;
+ case MISCREG_TICK:
+ tick = val;
+ return NoFault;
+ case MISCREG_PCR:
+ case MISCREG_PIC:
+ panic("ASR number %d not implemented\n", miscReg - AsrStart);
+ case MISCREG_GSR:
+ gsr = val;
+ case MISCREG_SOFTINT:
+ softint = val;
+ return NoFault;
+ case MISCREG_TICK_CMPR:
+ tick_cmpr = val;
+ return NoFault;
+ case MISCREG_STICK:
+ stick = val;
+ return NoFault;
+ case MISCREG_STICK_CMPR:
+ stick_cmpr = val;
+ return NoFault;
+
+ /** Privilged Registers */
+ case MISCREG_TPC:
+ tpc[tl-1] = val;
+ return NoFault;
+ case MISCREG_TNPC:
+ tnpc[tl-1] = val;
+ return NoFault;
+ case MISCREG_TSTATE:
+ tstate[tl-1] = val;
+ return NoFault;
+ case MISCREG_TT:
+ tt[tl-1] = val;
+ return NoFault;
+ case MISCREG_PRIVTICK:
+ panic("Priviliged access to tick regesiters not implemented\n");
+ case MISCREG_TBA:
+ tba = val;
+ return NoFault;
+ case MISCREG_PSTATE:
+ pstate = val;
+ return NoFault;
+ case MISCREG_TL:
+ tl = val;
+ return NoFault;
+ case MISCREG_PIL:
+ pil = val;
+ return NoFault;
+ case MISCREG_CWP:
+ cwp = val;
+ return NoFault;
+ case MISCREG_CANSAVE:
+ cansave = val;
+ return NoFault;
+ case MISCREG_CANRESTORE:
+ canrestore = val;
+ return NoFault;
+ case MISCREG_CLEANWIN:
+ cleanwin = val;
+ return NoFault;
+ case MISCREG_OTHERWIN:
+ otherwin = val;
+ return NoFault;
+ case MISCREG_WSTATE:
+ wstate = val;
+ return NoFault;
+ case MISCREG_GL:
+ gl = val;
+ return NoFault;
+
+ /** Hyper privileged registers */
+ case MISCREG_HPSTATE:
+ hpstate = val;
+ return NoFault;
+ case MISCREG_HTSTATE:
+ htstate[tl-1] = val;
+ return NoFault;
+ case MISCREG_HINTP:
+ panic("HINTP not implemented\n");
+ case MISCREG_HTBA:
+ htba = val;
+ return NoFault;
+ case MISCREG_STRAND_STS_REG:
+ strandStatusReg = val;
+ return NoFault;
+ case MISCREG_HSTICK_CMPR:
+ hstick_cmpr = val;
+ return NoFault;
+
+ /** Floating Point Status Register */
+ case MISCREG_FSR:
+ fsr = val;
+ return NoFault;
+ default:
+ panic("Miscellaneous register %d not implemented\n", miscReg);
+ }
+}
+
+Fault MiscRegFile::setRegWithEffect(int miscReg,
+ const MiscReg &val, ThreadContext * tc)
+{
+ const uint64_t Bit64 = (1ULL << 63);
+ switch (miscReg) {
+ case MISCREG_Y:
+ case MISCREG_CCR:
+ case MISCREG_ASI:
+ setReg(miscReg, val);
+ return NoFault;
+ case MISCREG_PRIVTICK:
+ case MISCREG_TICK:
+ if (isNonPriv())
+ return new PrivilegedOpcode;
+ if (isPriv())
+ return new PrivilegedAction;
+ tickFields.counter = tc->getCpuPtr()->curCycle() - val & ~Bit64;
+ tickFields.npt = val & Bit64 ? 1 : 0;
+ return NoFault;
+ case MISCREG_PC:
+ return new IllegalInstruction;
+ case MISCREG_FPRS:
+ return new UnimpFault("FPU not implemented\n");
+ case MISCREG_PCR:
+ return new UnimpFault("Performance Instrumentation not impl\n");
+ case MISCREG_PIC:
+ return new UnimpFault("Performance Instrumentation not impl\n");
+ case MISCREG_GSR:
+ return setReg(miscReg, val);
+
+ /** Privilged Registers */
+ case MISCREG_TPC:
+ case MISCREG_TNPC:
+ case MISCREG_TSTATE:
+ case MISCREG_TT:
+ if (tl == 0)
+ return new IllegalInstruction;
+ setReg(miscReg, val);
+ return NoFault;
+
+ case MISCREG_TBA:
+ // clear lower 7 bits on writes.
+ setReg(miscReg, val & ULL(~0x7FFF));
+ return NoFault;
+
+ case MISCREG_PSTATE:
+ setReg(miscReg, val);
+ return NoFault;
+
+ case MISCREG_TL:
+ if (isHyperPriv() && val > MaxTL)
+ setReg(miscReg, MaxTL);
+ else if (isPriv() && !isHyperPriv() && val > MaxPTL)
+ setReg(miscReg, MaxPTL);
+ else
+ setReg(miscReg, val);
+ return NoFault;
+
+ case MISCREG_CWP:
+ tc->changeRegFileContext(CONTEXT_CWP, val);
+ case MISCREG_CANSAVE:
+ case MISCREG_CANRESTORE:
+ case MISCREG_CLEANWIN:
+ case MISCREG_OTHERWIN:
+ case MISCREG_WSTATE:
+ setReg(miscReg, val);
+ return NoFault;
+
+ case MISCREG_GL:
+ int newval;
+ if (isHyperPriv() && val > MaxGL)
+ newval = MaxGL;
+ else if (isPriv() && !isHyperPriv() && val > MaxPGL)
+ newval = MaxPGL;
+ else
+ newval = val;
+ tc->changeRegFileContext(CONTEXT_GLOBALS, newval);
+ setReg(miscReg, newval);
+ return NoFault;
+
+ /** Floating Point Status Register */
+ case MISCREG_FSR:
+ panic("Floating Point not implemented\n");
+ default:
+#if FULL_SYSTEM
+ setFSRegWithEffect(miscReg, val, tc);
+#else
+ return new IllegalInstruction;
+#endif
+ }
+}
+
+void MiscRegFile::serialize(std::ostream & os)
+{
+ SERIALIZE_SCALAR(pstate);
+ SERIALIZE_SCALAR(tba);
+ SERIALIZE_SCALAR(y);
+ SERIALIZE_SCALAR(pil);
+ SERIALIZE_SCALAR(gl);
+ SERIALIZE_SCALAR(cwp);
+ SERIALIZE_ARRAY(tt, MaxTL);
+ SERIALIZE_SCALAR(ccr);
+ SERIALIZE_SCALAR(asi);
+ SERIALIZE_SCALAR(tl);
+ SERIALIZE_ARRAY(tpc, MaxTL);
+ SERIALIZE_ARRAY(tnpc, MaxTL);
+ SERIALIZE_ARRAY(tstate, MaxTL);
+ SERIALIZE_SCALAR(tick);
+ SERIALIZE_SCALAR(cansave);
+ SERIALIZE_SCALAR(canrestore);
+ SERIALIZE_SCALAR(otherwin);
+ SERIALIZE_SCALAR(cleanwin);
+ SERIALIZE_SCALAR(wstate);
+ SERIALIZE_SCALAR(fsr);
+ SERIALIZE_SCALAR(fprs);
+ SERIALIZE_SCALAR(hpstate);
+ SERIALIZE_ARRAY(htstate, MaxTL);
+ SERIALIZE_SCALAR(htba);
+ SERIALIZE_SCALAR(hstick_cmpr);
+}
+
+void MiscRegFile::unserialize(Checkpoint * cp, const std::string & section)
+{
+ UNSERIALIZE_SCALAR(pstate);
+ UNSERIALIZE_SCALAR(tba);
+ UNSERIALIZE_SCALAR(y);
+ UNSERIALIZE_SCALAR(pil);
+ UNSERIALIZE_SCALAR(gl);
+ UNSERIALIZE_SCALAR(cwp);
+ UNSERIALIZE_ARRAY(tt, MaxTL);
+ UNSERIALIZE_SCALAR(ccr);
+ UNSERIALIZE_SCALAR(asi);
+ UNSERIALIZE_SCALAR(tl);
+ UNSERIALIZE_ARRAY(tpc, MaxTL);
+ UNSERIALIZE_ARRAY(tnpc, MaxTL);
+ UNSERIALIZE_ARRAY(tstate, MaxTL);
+ UNSERIALIZE_SCALAR(tick);
+ UNSERIALIZE_SCALAR(cansave);
+ UNSERIALIZE_SCALAR(canrestore);
+ UNSERIALIZE_SCALAR(otherwin);
+ UNSERIALIZE_SCALAR(cleanwin);
+ UNSERIALIZE_SCALAR(wstate);
+ UNSERIALIZE_SCALAR(fsr);
+ UNSERIALIZE_SCALAR(fprs);
+ UNSERIALIZE_SCALAR(hpstate);
+ UNSERIALIZE_ARRAY(htstate, MaxTL);
+ UNSERIALIZE_SCALAR(htba);
+ UNSERIALIZE_SCALAR(hstick_cmpr);
+}
+
diff --git a/src/arch/sparc/miscregfile.hh b/src/arch/sparc/miscregfile.hh
new file mode 100644
index 000000000..be143311f
--- /dev/null
+++ b/src/arch/sparc/miscregfile.hh
@@ -0,0 +1,410 @@
+/*
+ * 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
+ * Ali Saidi
+ */
+
+#ifndef __ARCH_SPARC_MISCREGFILE_HH__
+#define __ARCH_SPARC_MISCREGFILE_HH__
+
+#include "arch/sparc/faults.hh"
+#include "arch/sparc/isa_traits.hh"
+#include "arch/sparc/types.hh"
+
+#include <string>
+
+namespace SparcISA
+{
+
+ //These functions map register indices to names
+ std::string getMiscRegName(RegIndex);
+
+ const int AsrStart = 0;
+ const int PrStart = 32;
+ const int HprStart = 64;
+ const int MiscStart = 96;
+
+ enum MiscRegIndex
+ {
+ /** Ancillary State Registers */
+ MISCREG_Y = AsrStart + 0,
+ MISCREG_CCR = AsrStart + 2,
+ MISCREG_ASI = AsrStart + 3,
+ MISCREG_TICK = AsrStart + 4,
+ MISCREG_PC = AsrStart + 5,
+ MISCREG_FPRS = AsrStart + 6,
+ MISCREG_PCR = AsrStart + 16,
+ MISCREG_PIC = AsrStart + 17,
+ MISCREG_GSR = AsrStart + 19,
+ MISCREG_SOFTINT_SET = AsrStart + 20,
+ MISCREG_SOFTINT_CLR = AsrStart + 21,
+ MISCREG_SOFTINT = AsrStart + 22,
+ MISCREG_TICK_CMPR = AsrStart + 23,
+ MISCREG_STICK = AsrStart + 24,
+ MISCREG_STICK_CMPR = AsrStart + 25,
+
+ /** Privilged Registers */
+ MISCREG_TPC = PrStart + 0,
+ MISCREG_TNPC = PrStart + 1,
+ MISCREG_TSTATE = PrStart + 2,
+ MISCREG_TT = PrStart + 3,
+ MISCREG_PRIVTICK = PrStart + 4,
+ MISCREG_TBA = PrStart + 5,
+ MISCREG_PSTATE = PrStart + 6,
+ MISCREG_TL = PrStart + 7,
+ MISCREG_PIL = PrStart + 8,
+ MISCREG_CWP = PrStart + 9,
+ MISCREG_CANSAVE = PrStart + 10,
+ MISCREG_CANRESTORE = PrStart + 11,
+ MISCREG_CLEANWIN = PrStart + 12,
+ MISCREG_OTHERWIN = PrStart + 13,
+ MISCREG_WSTATE = PrStart + 14,
+ MISCREG_GL = PrStart + 16,
+
+ /** Hyper privileged registers */
+ MISCREG_HPSTATE = HprStart + 0,
+ MISCREG_HTSTATE = HprStart + 1,
+ MISCREG_HINTP = HprStart + 3,
+ MISCREG_HTBA = HprStart + 5,
+ MISCREG_HVER = HprStart + 6,
+ MISCREG_STRAND_STS_REG = HprStart + 16,
+ MISCREG_HSTICK_CMPR = HprStart + 31,
+
+ /** Floating Point Status Register */
+ MISCREG_FSR = MiscStart + 0
+
+ };
+
+ // The control registers, broken out into fields
+ class MiscRegFile
+ {
+ private:
+
+ /* ASR Registers */
+ union {
+ uint64_t y; // Y (used in obsolete multiplication)
+ struct {
+ uint64_t value:32; // The actual value stored in y
+ uint64_t :32; // reserved bits
+ } yFields;
+ };
+ union {
+ uint8_t ccr; // Condition Code Register
+ struct {
+ union {
+ uint8_t icc:4; // 32-bit condition codes
+ struct {
+ uint8_t c:1; // Carry
+ uint8_t v:1; // Overflow
+ uint8_t z:1; // Zero
+ uint8_t n:1; // Negative
+ } iccFields;
+ };
+ union {
+ uint8_t xcc:4; // 64-bit condition codes
+ struct {
+ uint8_t c:1; // Carry
+ uint8_t v:1; // Overflow
+ uint8_t z:1; // Zero
+ uint8_t n:1; // Negative
+ } xccFields;
+ };
+ } ccrFields;
+ };
+ uint8_t asi; // Address Space Identifier
+ union {
+ uint64_t tick; // Hardware clock-tick counter
+ struct {
+ int64_t counter:63; // Clock-tick count
+ uint64_t npt:1; // Non-priveleged trap
+ } tickFields;
+ };
+ union {
+ uint8_t fprs; // Floating-Point Register State
+ struct {
+ uint8_t dl:1; // Dirty lower
+ uint8_t du:1; // Dirty upper
+ uint8_t fef:1; // FPRS enable floating-Point
+ } fprsFields;
+ };
+ union {
+ uint64_t gsr; //General Status Register
+ struct {
+ uint64_t mask:32;
+ uint64_t :4;
+ uint64_t im:1;
+ uint64_t irnd:2;
+ uint64_t :17;
+ uint64_t scale:5;
+ uint64_t align:3;
+ } gsrFields;
+ };
+ union {
+ uint64_t softint;
+ struct {
+ uint64_t tm:1;
+ uint64_t int_level:14;
+ uint64_t sm:1;
+ } softintFields;
+ };
+ union {
+ uint64_t tick_cmpr; // Hardware tick compare registers
+ struct {
+ uint64_t tick_cmpr:63; // Clock-tick count
+ uint64_t int_dis:1; // Non-priveleged trap
+ } tick_cmprFields;
+ };
+ union {
+ uint64_t stick; // Hardware clock-tick counter
+ struct {
+ int64_t :63; // Not used, storage in SparcSystem
+ uint64_t npt:1; // Non-priveleged trap
+ } stickFields;
+ };
+ union {
+ uint64_t stick_cmpr; // Hardware tick compare registers
+ struct {
+ uint64_t tick_cmpr:63; // Clock-tick count
+ uint64_t int_dis:1; // Non-priveleged trap
+ } stick_cmprFields;
+ };
+
+
+ /* Privileged Registers */
+ uint64_t tpc[MaxTL]; // Trap Program Counter (value from
+ // previous trap level)
+ uint64_t tnpc[MaxTL]; // Trap Next Program Counter (value from
+ // previous trap level)
+ union {
+ uint64_t tstate[MaxTL]; // Trap State
+ struct {
+ //Values are from previous trap level
+ uint64_t cwp:5; // Current Window Pointer
+ uint64_t :3; // Reserved bits
+ uint64_t pstate:13; // Process State
+ uint64_t :3; // Reserved bits
+ uint64_t asi:8; // Address Space Identifier
+ uint64_t ccr:8; // Condition Code Register
+ uint64_t gl:8; // Global level
+ } tstateFields[MaxTL];
+ };
+ uint16_t tt[MaxTL]; // Trap Type (Type of trap which occured
+ // on the previous level)
+ uint64_t tba; // Trap Base Address
+
+ union {
+ uint16_t pstate; // Process State Register
+ struct {
+ uint16_t :1; // reserved
+ uint16_t ie:1; // Interrupt enable
+ uint16_t priv:1; // Privelege mode
+ uint16_t am:1; // Address mask
+ uint16_t pef:1; // PSTATE enable floating-point
+ uint16_t :1; // reserved2
+ uint16_t mm:2; // Memory Model
+ uint16_t tle:1; // Trap little-endian
+ uint16_t cle:1; // Current little-endian
+ } pstateFields;
+ };
+ uint8_t tl; // Trap Level
+ uint8_t pil; // Process Interrupt Register
+ uint8_t cwp; // Current Window Pointer
+ uint8_t cansave; // Savable windows
+ uint8_t canrestore; // Restorable windows
+ uint8_t cleanwin; // Clean windows
+ uint8_t otherwin; // Other windows
+ union {
+ uint8_t wstate; // Window State
+ struct {
+ uint8_t normal:3; // Bits TT<4:2> are set to on a normal
+ // register window trap
+ uint8_t other:3; // Bits TT<4:2> are set to on an "otherwin"
+ // register window trap
+ } wstateFields;
+ };
+ uint8_t gl; // Global level register
+
+
+ /** Hyperprivileged Registers */
+ union {
+ uint64_t hpstate; // Hyperprivileged State Register
+ struct {
+ uint8_t tlz: 1;
+ uint8_t :1;
+ uint8_t hpriv:1;
+ uint8_t :2;
+ uint8_t red:1;
+ uint8_t :4;
+ uint8_t ibe:1;
+ uint8_t id:1;
+ } hpstateFields;
+ };
+
+ uint64_t htstate[MaxTL]; // Hyperprivileged Trap State Register
+ uint64_t hintp;
+ uint64_t htba; // Hyperprivileged Trap Base Address register
+ union {
+ uint64_t hstick_cmpr; // Hardware tick compare registers
+ struct {
+ uint64_t tick_cmpr:63; // Clock-tick count
+ uint64_t int_dis:1; // Non-priveleged trap
+ } hstick_cmprFields;
+ };
+
+ uint64_t strandStatusReg; // Per strand status register
+
+
+ /** Floating point misc registers. */
+ union {
+ uint64_t fsr; // Floating-Point State Register
+ struct {
+ union {
+ uint64_t cexc:5; // Current excpetion
+ struct {
+ uint64_t nxc:1; // Inexact
+ uint64_t dzc:1; // Divide by zero
+ uint64_t ufc:1; // Underflow
+ uint64_t ofc:1; // Overflow
+ uint64_t nvc:1; // Invalid operand
+ } cexcFields;
+ };
+ union {
+ uint64_t aexc:5; // Accrued exception
+ struct {
+ uint64_t nxc:1; // Inexact
+ uint64_t dzc:1; // Divide by zero
+ uint64_t ufc:1; // Underflow
+ uint64_t ofc:1; // Overflow
+ uint64_t nvc:1; // Invalid operand
+ } aexcFields;
+ };
+ uint64_t fcc0:2; // Floating-Point condtion codes
+ uint64_t :1; // Reserved bits
+ uint64_t qne:1; // Deferred trap queue not empty
+ // with no queue, it should read 0
+ uint64_t ftt:3; // Floating-Point trap type
+ uint64_t ver:3; // Version (of the FPU)
+ uint64_t :2; // Reserved bits
+ uint64_t ns:1; // Nonstandard floating point
+ union {
+ uint64_t tem:5; // Trap Enable Mask
+ struct {
+ uint64_t nxm:1; // Inexact
+ uint64_t dzm:1; // Divide by zero
+ uint64_t ufm:1; // Underflow
+ uint64_t ofm:1; // Overflow
+ uint64_t nvm:1; // Invalid operand
+ } temFields;
+ };
+ uint64_t :2; // Reserved bits
+ uint64_t rd:2; // Rounding direction
+ uint64_t fcc1:2; // Floating-Point condition codes
+ uint64_t fcc2:2; // Floating-Point condition codes
+ uint64_t fcc3:2; // Floating-Point condition codes
+ uint64_t :26; // Reserved bits
+ } fsrFields;
+ };
+
+ // These need to check the int_dis field and if 0 then
+ // set appropriate bit in softint and checkinterrutps on the cpu
+#if FULL_SYSTEM
+ /** Process a tick compare event and generate an interrupt on the cpu if
+ * appropriate. */
+ void processTickCompare(ThreadContext *tc);
+ void processSTickCompare(ThreadContext *tc);
+ void processHSTickCompare(ThreadContext *tc);
+
+ typedef CpuEventWrapper<MiscRegFile,
+ &MiscRegFile::processTickCompare> TickCompareEvent;
+ TickCompareEvent *tickCompare;
+
+ typedef CpuEventWrapper<MiscRegFile,
+ &MiscRegFile::processSTickCompare> STickCompareEvent;
+ STickCompareEvent *sTickCompare;
+
+ typedef CpuEventWrapper<MiscRegFile,
+ &MiscRegFile::processHSTickCompare> HSTickCompareEvent;
+ HSTickCompareEvent *hSTickCompare;
+
+ /** Fullsystem only register version of ReadRegWithEffect() */
+ MiscReg readFSRegWithEffect(int miscReg, Fault &fault, ThreadContext *tc);
+ /** Fullsystem only register version of SetRegWithEffect() */
+ Fault setFSRegWithEffect(int miscReg, const MiscReg &val,
+ ThreadContext * tc);
+#endif
+ public:
+
+ void reset();
+
+ MiscRegFile()
+ {
+ reset();
+ }
+
+ /** read a value out of an either an SE or FS IPR. No checking is done
+ * about SE vs. FS as this is mostly used to copy the regfile. Thus more
+ * register are copied that are necessary for FS. However this prevents
+ * a bunch of ifdefs and is rarely called so is not performance
+ * criticial. */
+ MiscReg readReg(int miscReg);
+
+ /** Read a value from an IPR. Only the SE iprs are here and the rest
+ * are are readFSRegWithEffect (which is called by readRegWithEffect()).
+ * Checking is done for permission based on state bits in the miscreg
+ * file. */
+ MiscReg readRegWithEffect(int miscReg, Fault &fault, ThreadContext *tc);
+
+ /** write a value into an either an SE or FS IPR. No checking is done
+ * about SE vs. FS as this is mostly used to copy the regfile. Thus more
+ * register are copied that are necessary for FS. However this prevents
+ * a bunch of ifdefs and is rarely called so is not performance
+ * criticial.*/
+ Fault setReg(int miscReg, const MiscReg &val);
+
+ /** Write a value into an IPR. Only the SE iprs are here and the rest
+ * are are setFSRegWithEffect (which is called by setRegWithEffect()).
+ * Checking is done for permission based on state bits in the miscreg
+ * file. */
+ Fault setRegWithEffect(int miscReg,
+ const MiscReg &val, ThreadContext * tc);
+
+ void serialize(std::ostream & os);
+
+ void unserialize(Checkpoint * cp, const std::string & section);
+
+ void copyMiscRegs(ThreadContext * tc);
+
+ protected:
+
+ bool isHyperPriv() { return hpstateFields.hpriv; }
+ bool isPriv() { return hpstateFields.hpriv || pstateFields.priv; }
+ bool isNonPriv() { return !isPriv(); }
+ };
+}
+
+#endif
diff --git a/src/arch/sparc/regfile.cc b/src/arch/sparc/regfile.cc
new file mode 100644
index 000000000..747426781
--- /dev/null
+++ b/src/arch/sparc/regfile.cc
@@ -0,0 +1,279 @@
+/*
+ * 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
+ * Ali Saidi
+ */
+
+#include "arch/sparc/regfile.hh"
+#include "cpu/thread_context.hh"
+
+class Checkpoint;
+
+using namespace SparcISA;
+using namespace std;
+
+//RegFile class methods
+Addr RegFile::readPC()
+{
+ return pc;
+}
+
+void RegFile::setPC(Addr val)
+{
+ pc = val;
+}
+
+Addr RegFile::readNextPC()
+{
+ return npc;
+}
+
+void RegFile::setNextPC(Addr val)
+{
+ npc = val;
+}
+
+Addr RegFile::readNextNPC()
+{
+ return nnpc;
+}
+
+void RegFile::setNextNPC(Addr val)
+{
+ nnpc = val;
+}
+
+void RegFile::clear()
+{
+ intRegFile.clear();
+ floatRegFile.clear();
+}
+
+MiscReg RegFile::readMiscReg(int miscReg)
+{
+ return miscRegFile.readReg(miscReg);
+}
+
+MiscReg RegFile::readMiscRegWithEffect(int miscReg,
+ Fault &fault, ThreadContext *tc)
+{
+ return miscRegFile.readRegWithEffect(miscReg, fault, tc);
+}
+
+Fault RegFile::setMiscReg(int miscReg, const MiscReg &val)
+{
+ return miscRegFile.setReg(miscReg, val);
+}
+
+Fault RegFile::setMiscRegWithEffect(int miscReg, const MiscReg &val,
+ ThreadContext * tc)
+{
+ return miscRegFile.setRegWithEffect(miscReg, val, tc);
+}
+
+FloatReg RegFile::readFloatReg(int floatReg, int width)
+{
+ return floatRegFile.readReg(floatReg, width);
+}
+
+FloatReg RegFile::readFloatReg(int floatReg)
+{
+ //Use the "natural" width of a single float
+ return floatRegFile.readReg(floatReg, FloatRegFile::SingleWidth);
+}
+
+FloatRegBits RegFile::readFloatRegBits(int floatReg, int width)
+{
+ return floatRegFile.readRegBits(floatReg, width);
+}
+
+FloatRegBits RegFile::readFloatRegBits(int floatReg)
+{
+ //Use the "natural" width of a single float
+ return floatRegFile.readRegBits(floatReg,
+ FloatRegFile::SingleWidth);
+}
+
+Fault RegFile::setFloatReg(int floatReg, const FloatReg &val, int width)
+{
+ return floatRegFile.setReg(floatReg, val, width);
+}
+
+Fault RegFile::setFloatReg(int floatReg, const FloatReg &val)
+{
+ //Use the "natural" width of a single float
+ return setFloatReg(floatReg, val, FloatRegFile::SingleWidth);
+}
+
+Fault RegFile::setFloatRegBits(int floatReg, const FloatRegBits &val, int width)
+{
+ return floatRegFile.setRegBits(floatReg, val, width);
+}
+
+Fault RegFile::setFloatRegBits(int floatReg, const FloatRegBits &val)
+{
+ //Use the "natural" width of a single float
+ return floatRegFile.setRegBits(floatReg, val,
+ FloatRegFile::SingleWidth);
+}
+
+IntReg RegFile::readIntReg(int intReg)
+{
+ return intRegFile.readReg(intReg);
+}
+
+Fault RegFile::setIntReg(int intReg, const IntReg &val)
+{
+ return intRegFile.setReg(intReg, val);
+}
+
+void RegFile::serialize(std::ostream &os)
+{
+ intRegFile.serialize(os);
+ floatRegFile.serialize(os);
+ miscRegFile.serialize(os);
+ SERIALIZE_SCALAR(pc);
+ SERIALIZE_SCALAR(npc);
+}
+
+void RegFile::unserialize(Checkpoint *cp, const std::string &section)
+{
+ intRegFile.unserialize(cp, section);
+ floatRegFile.unserialize(cp, section);
+ miscRegFile.unserialize(cp, section);
+ UNSERIALIZE_SCALAR(pc);
+ UNSERIALIZE_SCALAR(npc);
+}
+
+void RegFile::changeContext(RegContextParam param, RegContextVal val)
+{
+ switch(param)
+ {
+ case CONTEXT_CWP:
+ intRegFile.setCWP(val);
+ break;
+ case CONTEXT_GLOBALS:
+ intRegFile.setGlobals(val);
+ break;
+ default:
+ panic("Tried to set illegal context parameter in the SPARC regfile.\n");
+ }
+}
+
+int SparcISA::InterruptLevel(uint64_t softint)
+{
+ if (softint & 0x10000 || softint & 0x1)
+ return 14;
+
+ int level = 14;
+ while (level >= 0 && !(1 << (level + 1) & softint))
+ level--;
+ if (1 << (level + 1) & softint)
+ return level;
+ return 0;
+}
+
+void SparcISA::copyMiscRegs(ThreadContext *src, ThreadContext *dest)
+{
+
+ uint8_t tl = src->readMiscReg(MISCREG_TL);
+
+ // Read all the trap level dependent registers and save them off
+ for(int i = 1; i <= MaxTL; i++)
+ {
+ src->setMiscReg(MISCREG_TL, i);
+ dest->setMiscReg(MISCREG_TL, i);
+
+ dest->setMiscReg(MISCREG_TT, src->readMiscReg(MISCREG_TT));
+ dest->setMiscReg(MISCREG_TPC, src->readMiscReg(MISCREG_TPC));
+ dest->setMiscReg(MISCREG_TNPC, src->readMiscReg(MISCREG_TNPC));
+ dest->setMiscReg(MISCREG_TSTATE, src->readMiscReg(MISCREG_TSTATE));
+ }
+
+ // Save off the traplevel
+ dest->setMiscReg(MISCREG_TL, tl);
+ src->setMiscReg(MISCREG_TL, tl);
+
+
+ // ASRs
+ dest->setMiscReg(MISCREG_Y, src->readMiscReg(MISCREG_Y));
+ dest->setMiscReg(MISCREG_CCR, src->readMiscReg(MISCREG_CCR));
+ dest->setMiscReg(MISCREG_ASI, src->readMiscReg(MISCREG_ASI));
+ dest->setMiscReg(MISCREG_TICK, src->readMiscReg(MISCREG_TICK));
+ dest->setMiscReg(MISCREG_FPRS, src->readMiscReg(MISCREG_FPRS));
+ dest->setMiscReg(MISCREG_SOFTINT, src->readMiscReg(MISCREG_SOFTINT));
+ dest->setMiscReg(MISCREG_TICK_CMPR, src->readMiscReg(MISCREG_TICK_CMPR));
+ dest->setMiscReg(MISCREG_STICK, src->readMiscReg(MISCREG_STICK));
+ dest->setMiscReg(MISCREG_STICK_CMPR, src->readMiscReg(MISCREG_STICK_CMPR));
+
+ // Priv Registers
+ dest->setMiscReg(MISCREG_TICK, src->readMiscReg(MISCREG_TICK));
+ dest->setMiscReg(MISCREG_TBA, src->readMiscReg(MISCREG_TBA));
+ dest->setMiscReg(MISCREG_PSTATE, src->readMiscReg(MISCREG_PSTATE));
+ dest->setMiscReg(MISCREG_PIL, src->readMiscReg(MISCREG_PIL));
+ dest->setMiscReg(MISCREG_CWP, src->readMiscReg(MISCREG_CWP));
+ dest->setMiscReg(MISCREG_CANSAVE, src->readMiscReg(MISCREG_CANSAVE));
+ dest->setMiscReg(MISCREG_CANRESTORE, src->readMiscReg(MISCREG_CANRESTORE));
+ dest->setMiscReg(MISCREG_OTHERWIN, src->readMiscReg(MISCREG_OTHERWIN));
+ dest->setMiscReg(MISCREG_CLEANWIN, src->readMiscReg(MISCREG_CLEANWIN));
+ dest->setMiscReg(MISCREG_WSTATE, src->readMiscReg(MISCREG_WSTATE));
+ dest->setMiscReg(MISCREG_GL, src->readMiscReg(MISCREG_GL));
+
+ // Hyperprivilged registers
+ dest->setMiscReg(MISCREG_HPSTATE, src->readMiscReg(MISCREG_HPSTATE));
+ dest->setMiscReg(MISCREG_HINTP, src->readMiscReg(MISCREG_HINTP));
+ dest->setMiscReg(MISCREG_HTBA, src->readMiscReg(MISCREG_HTBA));
+ dest->setMiscReg(MISCREG_STRAND_STS_REG,
+ src->readMiscReg(MISCREG_STRAND_STS_REG));
+ dest->setMiscReg(MISCREG_HSTICK_CMPR,
+ src->readMiscReg(MISCREG_HSTICK_CMPR));
+
+ // FSR
+ dest->setMiscReg(MISCREG_FSR, src->readMiscReg(MISCREG_FSR));
+}
+
+void SparcISA::copyRegs(ThreadContext *src, ThreadContext *dest)
+{
+ // First loop through the integer registers.
+ for (int i = 0; i < TheISA::NumIntRegs; ++i) {
+ dest->setIntReg(i, src->readIntReg(i));
+ }
+
+ // Then loop through the floating point registers.
+ for (int i = 0; i < TheISA::NumFloatRegs; ++i) {
+ dest->setFloatRegBits(i, src->readFloatRegBits(i));
+ }
+
+ // Copy misc. registers
+ copyMiscRegs(src, dest);
+
+ // Lastly copy PC/NPC
+ dest->setPC(src->readPC());
+ dest->setNextPC(src->readNextPC());
+ dest->setNextNPC(src->readNextNPC());
+}
diff --git a/src/arch/sparc/regfile.hh b/src/arch/sparc/regfile.hh
index db48b2d78..500fbbba4 100644
--- a/src/arch/sparc/regfile.hh
+++ b/src/arch/sparc/regfile.hh
@@ -32,832 +32,84 @@
#ifndef __ARCH_SPARC_REGFILE_HH__
#define __ARCH_SPARC_REGFILE_HH__
-#include "arch/sparc/exceptions.hh"
#include "arch/sparc/faults.hh"
-#include "base/trace.hh"
-#include "sim/byteswap.hh"
-#include "cpu/cpuevent.hh"
+#include "arch/sparc/floatregfile.hh"
+#include "arch/sparc/intregfile.hh"
+#include "arch/sparc/isa_traits.hh"
+#include "arch/sparc/miscregfile.hh"
+#include "arch/sparc/types.hh"
#include "sim/host.hh"
+#include <string>
+
class Checkpoint;
namespace SparcISA
{
-
- typedef uint8_t RegIndex;
-
- // MAXTL - maximum trap level
- const int MaxPTL = 2;
- const int MaxTL = 6;
- const int MaxGL = 3;
- const int MaxPGL = 2;
-
- // NWINDOWS - number of register windows, can be 3 to 32
- const int NWindows = 32;
-
- const int AsrStart = 0;
- const int PrStart = 32;
- const int HprStart = 64;
- const int MiscStart = 96;
-
- const uint64_t Bit64 = (1ULL << 63);
- class IntRegFile
+ class RegFile
{
protected:
- static const int FrameOffsetBits = 3;
- static const int FrameNumBits = 2;
-
- static const int RegsPerFrame = 1 << FrameOffsetBits;
- static const int FrameNumMask =
- (FrameNumBits == sizeof(int)) ?
- (unsigned int)(-1) :
- (1 << FrameNumBits) - 1;
- static const int FrameOffsetMask =
- (FrameOffsetBits == sizeof(int)) ?
- (unsigned int)(-1) :
- (1 << FrameOffsetBits) - 1;
-
- IntReg regGlobals[MaxGL][RegsPerFrame];
- IntReg regSegments[2 * NWindows][RegsPerFrame];
-
- enum regFrame {Globals, Outputs, Locals, Inputs, NumFrames};
-
- IntReg * regView[NumFrames];
-
- static const int RegGlobalOffset = 0;
- static const int FrameOffset = MaxGL * RegsPerFrame;
- int offset[NumFrames];
+ Addr pc; // Program Counter
+ Addr npc; // Next Program Counter
+ Addr nnpc;
public:
+ Addr readPC();
+ void setPC(Addr val);
- int flattenIndex(int reg)
- {
- int flatIndex = offset[reg >> FrameOffsetBits]
- | (reg & FrameOffsetMask);
- DPRINTF(Sparc, "Flattened index %d into %d.\n", reg, flatIndex);
- return flatIndex;
- }
-
- void clear()
- {
- int x;
- for (x = 0; x < MaxGL; x++)
- memset(regGlobals[x], 0, sizeof(regGlobals[x]));
- for(int x = 0; x < 2 * NWindows; x++)
- bzero(regSegments[x], sizeof(regSegments[x]));
- }
-
- IntRegFile()
- {
- offset[Globals] = 0;
- regView[Globals] = regGlobals[0];
- setCWP(0);
- clear();
- }
-
- IntReg readReg(int intReg)
- {
- IntReg val =
- regView[intReg >> FrameOffsetBits][intReg & FrameOffsetMask];
- DPRINTF(Sparc, "Read register %d = 0x%x\n", intReg, val);
- return val;
- }
-
- Fault setReg(int intReg, const IntReg &val)
- {
- if(intReg)
- DPRINTF(Sparc, "Wrote register %d = 0x%x\n", intReg, val);
- regView[intReg >> FrameOffsetBits][intReg & FrameOffsetMask] = val;
- return NoFault;
- }
-
- //This doesn't effect the actual CWP register.
- //It's purpose is to adjust the view of the register file
- //to what it would be if CWP = cwp.
- void setCWP(int cwp)
- {
- int index = ((NWindows - cwp) % NWindows) * 2;
- offset[Outputs] = FrameOffset + (index * RegsPerFrame);
- offset[Locals] = FrameOffset + ((index+1) * RegsPerFrame);
- offset[Inputs] = FrameOffset +
- (((index+2) % (NWindows * 2)) * RegsPerFrame);
- regView[Outputs] = regSegments[index];
- regView[Locals] = regSegments[index+1];
- regView[Inputs] = regSegments[(index+2) % (NWindows * 2)];
-
- DPRINTF(Sparc, "Changed the CWP value to %d\n", cwp);
- }
-
- void setGlobals(int gl)
- {
-
- DPRINTF(Sparc, "Now using %d globals", gl);
-
- regView[Globals] = regGlobals[gl];
- offset[Globals] = RegGlobalOffset + gl * RegsPerFrame;
- }
+ Addr readNextPC();
+ void setNextPC(Addr val);
- void serialize(std::ostream &os);
-
- void unserialize(Checkpoint *cp, const std::string &section);
- };
-
- typedef float float32_t;
- typedef double float64_t;
- //FIXME long double refers to a 10 byte float, rather than a
- //16 byte float as required. This data type may have to be emulated.
- typedef double float128_t;
-
- class FloatRegFile
- {
- public:
- static const int SingleWidth = 32;
- static const int DoubleWidth = 64;
- static const int QuadWidth = 128;
+ Addr readNextNPC();
+ void setNextNPC(Addr val);
protected:
-
- //Since the floating point registers overlap each other,
- //A generic storage space is used. The float to be returned is
- //pulled from the appropriate section of this region.
- char regSpace[(SingleWidth / 8) * NumFloatRegs];
+ IntRegFile intRegFile; // integer register file
+ FloatRegFile floatRegFile; // floating point register file
+ MiscRegFile miscRegFile; // control register file
public:
- void clear()
- {
- bzero(regSpace, sizeof(regSpace));
- }
-
- FloatReg readReg(int floatReg, int width)
- {
- //In each of these cases, we have to copy the value into a temporary
- //variable. This is because we may otherwise try to access an
- //unaligned portion of memory.
- switch(width)
- {
- case SingleWidth:
- float32_t result32;
- memcpy(&result32, regSpace + 4 * floatReg, sizeof(result32));
- return htog(result32);
- case DoubleWidth:
- float64_t result64;
- memcpy(&result64, regSpace + 4 * floatReg, sizeof(result64));
- return htog(result64);
- case QuadWidth:
- float128_t result128;
- memcpy(&result128, regSpace + 4 * floatReg, sizeof(result128));
- return htog(result128);
- default:
- panic("Attempted to read a %d bit floating point register!", width);
- }
- }
-
- FloatRegBits readRegBits(int floatReg, int width)
- {
- //In each of these cases, we have to copy the value into a temporary
- //variable. This is because we may otherwise try to access an
- //unaligned portion of memory.
- switch(width)
- {
- case SingleWidth:
- uint32_t result32;
- memcpy(&result32, regSpace + 4 * floatReg, sizeof(result32));
- return htog(result32);
- case DoubleWidth:
- uint64_t result64;
- memcpy(&result64, regSpace + 4 * floatReg, sizeof(result64));
- return htog(result64);
- case QuadWidth:
- uint64_t result128;
- memcpy(&result128, regSpace + 4 * floatReg, sizeof(result128));
- return htog(result128);
- default:
- panic("Attempted to read a %d bit floating point register!", width);
- }
- }
-
- Fault setReg(int floatReg, const FloatReg &val, int width)
- {
- //In each of these cases, we have to copy the value into a temporary
- //variable. This is because we may otherwise try to access an
- //unaligned portion of memory.
-
- uint32_t result32;
- uint64_t result64;
- DPRINTF(Sparc, "Setting floating point register %d\n", floatReg);
- switch(width)
- {
- case SingleWidth:
- result32 = gtoh((uint32_t)val);
- memcpy(regSpace + 4 * floatReg, &result32, sizeof(result32));
- break;
- case DoubleWidth:
- result64 = gtoh((uint64_t)val);
- memcpy(regSpace + 4 * floatReg, &result64, sizeof(result64));
- break;
- case QuadWidth:
- panic("Quad width FP not implemented.");
- break;
- default:
- panic("Attempted to read a %d bit floating point register!", width);
- }
- return NoFault;
- }
-
- Fault setRegBits(int floatReg, const FloatRegBits &val, int width)
- {
- //In each of these cases, we have to copy the value into a temporary
- //variable. This is because we may otherwise try to access an
- //unaligned portion of memory.
- uint32_t result32;
- uint64_t result64;
- switch(width)
- {
- case SingleWidth:
- result32 = gtoh((uint32_t)val);
- memcpy(regSpace + 4 * floatReg, &result32, sizeof(result32));
- break;
- case DoubleWidth:
- result64 = gtoh((uint64_t)val);
- memcpy(regSpace + 4 * floatReg, &result64, sizeof(result64));
- break;
- case QuadWidth:
- panic("Quad width FP not implemented.");
- break;
- default:
- panic("Attempted to read a %d bit floating point register!", width);
- }
- return NoFault;
- }
+ void clear();
- void serialize(std::ostream &os);
+ int FlattenIntIndex(int reg);
- void unserialize(Checkpoint *cp, const std::string &section);
- };
+ MiscReg readMiscReg(int miscReg);
- enum MiscRegIndex
- {
- /** Ancillary State Registers */
- MISCREG_Y = AsrStart + 0,
- MISCREG_CCR = AsrStart + 2,
- MISCREG_ASI = AsrStart + 3,
- MISCREG_TICK = AsrStart + 4,
- MISCREG_PC = AsrStart + 5,
- MISCREG_FPRS = AsrStart + 6,
- MISCREG_PCR = AsrStart + 16,
- MISCREG_PIC = AsrStart + 17,
- MISCREG_GSR = AsrStart + 19,
- MISCREG_SOFTINT_SET = AsrStart + 20,
- MISCREG_SOFTINT_CLR = AsrStart + 21,
- MISCREG_SOFTINT = AsrStart + 22,
- MISCREG_TICK_CMPR = AsrStart + 23,
- MISCREG_STICK = AsrStart + 24,
- MISCREG_STICK_CMPR = AsrStart + 25,
-
- /** Privilged Registers */
- MISCREG_TPC = PrStart + 0,
- MISCREG_TNPC = PrStart + 1,
- MISCREG_TSTATE = PrStart + 2,
- MISCREG_TT = PrStart + 3,
- MISCREG_PRIVTICK = PrStart + 4,
- MISCREG_TBA = PrStart + 5,
- MISCREG_PSTATE = PrStart + 6,
- MISCREG_TL = PrStart + 7,
- MISCREG_PIL = PrStart + 8,
- MISCREG_CWP = PrStart + 9,
- MISCREG_CANSAVE = PrStart + 10,
- MISCREG_CANRESTORE = PrStart + 11,
- MISCREG_CLEANWIN = PrStart + 12,
- MISCREG_OTHERWIN = PrStart + 13,
- MISCREG_WSTATE = PrStart + 14,
- MISCREG_GL = PrStart + 16,
-
- /** Hyper privileged registers */
- MISCREG_HPSTATE = HprStart + 0,
- MISCREG_HTSTATE = HprStart + 1,
- MISCREG_HINTP = HprStart + 3,
- MISCREG_HTBA = HprStart + 5,
- MISCREG_HVER = HprStart + 6,
- MISCREG_STRAND_STS_REG = HprStart + 16,
- MISCREG_HSTICK_CMPR = HprStart + 31,
-
- /** Floating Point Status Register */
- MISCREG_FSR = MiscStart + 0
+ MiscReg readMiscRegWithEffect(int miscReg,
+ Fault &fault, ThreadContext *tc);
- };
+ Fault setMiscReg(int miscReg, const MiscReg &val);
- // The control registers, broken out into fields
- class MiscRegFile
- {
- private:
-
- /* ASR Registers */
- union {
- uint64_t y; // Y (used in obsolete multiplication)
- struct {
- uint64_t value:32; // The actual value stored in y
- uint64_t :32; // reserved bits
- } yFields;
- };
- union {
- uint8_t ccr; // Condition Code Register
- struct {
- union {
- uint8_t icc:4; // 32-bit condition codes
- struct {
- uint8_t c:1; // Carry
- uint8_t v:1; // Overflow
- uint8_t z:1; // Zero
- uint8_t n:1; // Negative
- } iccFields;
- };
- union {
- uint8_t xcc:4; // 64-bit condition codes
- struct {
- uint8_t c:1; // Carry
- uint8_t v:1; // Overflow
- uint8_t z:1; // Zero
- uint8_t n:1; // Negative
- } xccFields;
- };
- } ccrFields;
- };
- uint8_t asi; // Address Space Identifier
- union {
- uint64_t tick; // Hardware clock-tick counter
- struct {
- int64_t counter:63; // Clock-tick count
- uint64_t npt:1; // Non-priveleged trap
- } tickFields;
- };
- union {
- uint8_t fprs; // Floating-Point Register State
- struct {
- uint8_t dl:1; // Dirty lower
- uint8_t du:1; // Dirty upper
- uint8_t fef:1; // FPRS enable floating-Point
- } fprsFields;
- };
- union {
- uint64_t softint;
- struct {
- uint64_t tm:1;
- uint64_t int_level:14;
- uint64_t sm:1;
- } softintFields;
- };
- union {
- uint64_t tick_cmpr; // Hardware tick compare registers
- struct {
- uint64_t tick_cmpr:63; // Clock-tick count
- uint64_t int_dis:1; // Non-priveleged trap
- } tick_cmprFields;
- };
- union {
- uint64_t stick; // Hardware clock-tick counter
- struct {
- int64_t :63; // Not used, storage in SparcSystem
- uint64_t npt:1; // Non-priveleged trap
- } stickFields;
- };
- union {
- uint64_t stick_cmpr; // Hardware tick compare registers
- struct {
- uint64_t tick_cmpr:63; // Clock-tick count
- uint64_t int_dis:1; // Non-priveleged trap
- } stick_cmprFields;
- };
-
-
- /* Privileged Registers */
- uint64_t tpc[MaxTL]; // Trap Program Counter (value from
- // previous trap level)
- uint64_t tnpc[MaxTL]; // Trap Next Program Counter (value from
- // previous trap level)
- union {
- uint64_t tstate[MaxTL]; // Trap State
- struct {
- //Values are from previous trap level
- uint64_t cwp:5; // Current Window Pointer
- uint64_t :3; // Reserved bits
- uint64_t pstate:13; // Process State
- uint64_t :3; // Reserved bits
- uint64_t asi:8; // Address Space Identifier
- uint64_t ccr:8; // Condition Code Register
- uint64_t gl:8; // Global level
- } tstateFields[MaxTL];
- };
- uint16_t tt[MaxTL]; // Trap Type (Type of trap which occured
- // on the previous level)
- uint64_t tba; // Trap Base Address
-
- union {
- uint16_t pstate; // Process State Register
- struct {
- uint16_t :1; // reserved
- uint16_t ie:1; // Interrupt enable
- uint16_t priv:1; // Privelege mode
- uint16_t am:1; // Address mask
- uint16_t pef:1; // PSTATE enable floating-point
- uint16_t :1; // reserved2
- uint16_t mm:2; // Memory Model
- uint16_t tle:1; // Trap little-endian
- uint16_t cle:1; // Current little-endian
- } pstateFields;
- };
- uint8_t tl; // Trap Level
- uint8_t pil; // Process Interrupt Register
- uint8_t cwp; // Current Window Pointer
- uint8_t cansave; // Savable windows
- uint8_t canrestore; // Restorable windows
- uint8_t cleanwin; // Clean windows
- uint8_t otherwin; // Other windows
- union {
- uint8_t wstate; // Window State
- struct {
- uint8_t normal:3; // Bits TT<4:2> are set to on a normal
- // register window trap
- uint8_t other:3; // Bits TT<4:2> are set to on an "otherwin"
- // register window trap
- } wstateFields;
- };
- uint8_t gl; // Global level register
-
-
- /** Hyperprivileged Registers */
- union {
- uint64_t hpstate; // Hyperprivileged State Register
- struct {
- uint8_t tlz: 1;
- uint8_t :1;
- uint8_t hpriv:1;
- uint8_t :2;
- uint8_t red:1;
- uint8_t :4;
- uint8_t ibe:1;
- uint8_t id:1;
- } hpstateFields;
- };
-
- uint64_t htstate[MaxTL]; // Hyperprivileged Trap State Register
- uint64_t hintp;
- uint64_t htba; // Hyperprivileged Trap Base Address register
- union {
- uint64_t hstick_cmpr; // Hardware tick compare registers
- struct {
- uint64_t tick_cmpr:63; // Clock-tick count
- uint64_t int_dis:1; // Non-priveleged trap
- } hstick_cmprFields;
- };
-
- uint64_t strandStatusReg; // Per strand status register
-
-
- /** Floating point misc registers. */
- union {
- uint64_t fsr; // Floating-Point State Register
- struct {
- union {
- uint64_t cexc:5; // Current excpetion
- struct {
- uint64_t nxc:1; // Inexact
- uint64_t dzc:1; // Divide by zero
- uint64_t ufc:1; // Underflow
- uint64_t ofc:1; // Overflow
- uint64_t nvc:1; // Invalid operand
- } cexcFields;
- };
- union {
- uint64_t aexc:5; // Accrued exception
- struct {
- uint64_t nxc:1; // Inexact
- uint64_t dzc:1; // Divide by zero
- uint64_t ufc:1; // Underflow
- uint64_t ofc:1; // Overflow
- uint64_t nvc:1; // Invalid operand
- } aexcFields;
- };
- uint64_t fcc0:2; // Floating-Point condtion codes
- uint64_t :1; // Reserved bits
- uint64_t qne:1; // Deferred trap queue not empty
- // with no queue, it should read 0
- uint64_t ftt:3; // Floating-Point trap type
- uint64_t ver:3; // Version (of the FPU)
- uint64_t :2; // Reserved bits
- uint64_t ns:1; // Nonstandard floating point
- union {
- uint64_t tem:5; // Trap Enable Mask
- struct {
- uint64_t nxm:1; // Inexact
- uint64_t dzm:1; // Divide by zero
- uint64_t ufm:1; // Underflow
- uint64_t ofm:1; // Overflow
- uint64_t nvm:1; // Invalid operand
- } temFields;
- };
- uint64_t :2; // Reserved bits
- uint64_t rd:2; // Rounding direction
- uint64_t fcc1:2; // Floating-Point condition codes
- uint64_t fcc2:2; // Floating-Point condition codes
- uint64_t fcc3:2; // Floating-Point condition codes
- uint64_t :26; // Reserved bits
- } fsrFields;
- };
-
- // These need to check the int_dis field and if 0 then
- // set appropriate bit in softint and checkinterrutps on the cpu
-#if FULL_SYSTEM
- /** Process a tick compare event and generate an interrupt on the cpu if
- * appropriate. */
- void processTickCompare(ThreadContext *tc);
- void processSTickCompare(ThreadContext *tc);
- void processHSTickCompare(ThreadContext *tc);
-
- typedef CpuEventWrapper<MiscRegFile,
- &MiscRegFile::processTickCompare> TickCompareEvent;
- TickCompareEvent *tickCompare;
-
- typedef CpuEventWrapper<MiscRegFile,
- &MiscRegFile::processSTickCompare> STickCompareEvent;
- STickCompareEvent *sTickCompare;
-
- typedef CpuEventWrapper<MiscRegFile,
- &MiscRegFile::processHSTickCompare> HSTickCompareEvent;
- HSTickCompareEvent *hSTickCompare;
-
- /** Fullsystem only register version of ReadRegWithEffect() */
- MiscReg readFSRegWithEffect(int miscReg, Fault &fault, ThreadContext *tc);
- /** Fullsystem only register version of SetRegWithEffect() */
- Fault setFSRegWithEffect(int miscReg, const MiscReg &val,
+ Fault setMiscRegWithEffect(int miscReg, const MiscReg &val,
ThreadContext * tc);
-#endif
- public:
- void reset()
- {
- pstateFields.pef = 0; //No FPU
- //pstateFields.pef = 1; //FPU
-#if FULL_SYSTEM
- //For SPARC, when a system is first started, there is a power
- //on reset Trap which sets the processor into the following state.
- //Bits that aren't set aren't defined on startup.
- tl = MaxTL;
- gl = MaxGL;
-
- tickFields.counter = 0; //The TICK register is unreadable bya
- tickFields.npt = 1; //The TICK register is unreadable by by !priv
-
- softint = 0; // Clear all the soft interrupt bits
- tick_cmprFields.int_dis = 1; // disable timer compare interrupts
- tick_cmprFields.tick_cmpr = 0; // Reset to 0 for pretty printing
- stickFields.npt = 1; //The TICK register is unreadable by by !priv
- stick_cmprFields.int_dis = 1; // disable timer compare interrupts
- stick_cmprFields.tick_cmpr = 0; // Reset to 0 for pretty printing
-
-
- tt[tl] = power_on_reset;
- pstate = 0; // fields 0 but pef
- pstateFields.pef = 1;
-
- hpstate = 0;
- hpstateFields.red = 1;
- hpstateFields.hpriv = 1;
- hpstateFields.tlz = 0; // this is a guess
- hintp = 0; // no interrupts pending
- hstick_cmprFields.int_dis = 1; // disable timer compare interrupts
- hstick_cmprFields.tick_cmpr = 0; // Reset to 0 for pretty printing
-#else
-/* //This sets up the initial state of the processor for usermode processes
- pstateFields.priv = 0; //Process runs in user mode
- pstateFields.ie = 1; //Interrupts are enabled
- fsrFields.rd = 0; //Round to nearest
- fsrFields.tem = 0; //Floating point traps not enabled
- fsrFields.ns = 0; //Non standard mode off
- fsrFields.qne = 0; //Floating point queue is empty
- fsrFields.aexc = 0; //No accrued exceptions
- fsrFields.cexc = 0; //No current exceptions
-
- //Register window management registers
- otherwin = 0; //No windows contain info from other programs
- canrestore = 0; //There are no windows to pop
- cansave = MaxTL - 2; //All windows are available to save into
- cleanwin = MaxTL;*/
-#endif
- }
-
- MiscRegFile()
- {
- reset();
- }
-
- /** read a value out of an either an SE or FS IPR. No checking is done
- * about SE vs. FS as this is mostly used to copy the regfile. Thus more
- * register are copied that are necessary for FS. However this prevents
- * a bunch of ifdefs and is rarely called so is not performance
- * criticial. */
- MiscReg readReg(int miscReg);
-
- /** Read a value from an IPR. Only the SE iprs are here and the rest
- * are are readFSRegWithEffect (which is called by readRegWithEffect()).
- * Checking is done for permission based on state bits in the miscreg
- * file. */
- MiscReg readRegWithEffect(int miscReg, Fault &fault, ThreadContext *tc);
-
- /** write a value into an either an SE or FS IPR. No checking is done
- * about SE vs. FS as this is mostly used to copy the regfile. Thus more
- * register are copied that are necessary for FS. However this prevents
- * a bunch of ifdefs and is rarely called so is not performance
- * criticial.*/
- Fault setReg(int miscReg, const MiscReg &val);
-
- /** Write a value into an IPR. Only the SE iprs are here and the rest
- * are are setFSRegWithEffect (which is called by setRegWithEffect()).
- * Checking is done for permission based on state bits in the miscreg
- * file. */
- Fault setRegWithEffect(int miscReg,
- const MiscReg &val, ThreadContext * tc);
-
- void serialize(std::ostream & os);
-
- void unserialize(Checkpoint * cp, const std::string & section);
-
- void copyMiscRegs(ThreadContext * tc);
+ FloatReg readFloatReg(int floatReg, int width);
- protected:
+ FloatReg readFloatReg(int floatReg);
- bool isHyperPriv() { return hpstateFields.hpriv; }
- bool isPriv() { return hpstateFields.hpriv || pstateFields.priv; }
- bool isNonPriv() { return !isPriv(); }
- };
+ FloatRegBits readFloatRegBits(int floatReg, int width);
- typedef union
- {
- IntReg intreg;
- FloatReg fpreg;
- MiscReg ctrlreg;
- } AnyReg;
+ FloatRegBits readFloatRegBits(int floatReg);
- class RegFile
- {
- protected:
- Addr pc; // Program Counter
- Addr npc; // Next Program Counter
- Addr nnpc;
-
- 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;
- }
-
- protected:
- IntRegFile intRegFile; // integer register file
- FloatRegFile floatRegFile; // floating point register file
- MiscRegFile miscRegFile; // control register file
+ Fault setFloatReg(int floatReg, const FloatReg &val, int width);
- public:
+ Fault setFloatReg(int floatReg, const FloatReg &val);
- void clear()
- {
- intRegFile.clear();
- floatRegFile.clear();
- }
+ Fault setFloatRegBits(int floatReg, const FloatRegBits &val, int width);
- int FlattenIntIndex(int reg)
- {
- return intRegFile.flattenIndex(reg);
- }
+ Fault setFloatRegBits(int floatReg, const FloatRegBits &val);
- MiscReg readMiscReg(int miscReg)
- {
- return miscRegFile.readReg(miscReg);
- }
+ IntReg readIntReg(int intReg);
- MiscReg readMiscRegWithEffect(int miscReg,
- Fault &fault, ThreadContext *tc)
- {
- 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);
- }
-
- FloatReg readFloatReg(int floatReg, int width)
- {
- return floatRegFile.readReg(floatReg, width);
- }
-
- FloatReg readFloatReg(int floatReg)
- {
- //Use the "natural" width of a single float
- return floatRegFile.readReg(floatReg, FloatRegFile::SingleWidth);
- }
-
- FloatRegBits readFloatRegBits(int floatReg, int width)
- {
- return floatRegFile.readRegBits(floatReg, width);
- }
-
- FloatRegBits readFloatRegBits(int floatReg)
- {
- //Use the "natural" width of a single float
- return floatRegFile.readRegBits(floatReg,
- FloatRegFile::SingleWidth);
- }
-
- Fault setFloatReg(int floatReg, const FloatReg &val, int width)
- {
- return floatRegFile.setReg(floatReg, val, width);
- }
-
- Fault setFloatReg(int floatReg, const FloatReg &val)
- {
- //Use the "natural" width of a single float
- return setFloatReg(floatReg, val, FloatRegFile::SingleWidth);
- }
-
- Fault setFloatRegBits(int floatReg, const FloatRegBits &val, int width)
- {
- return floatRegFile.setRegBits(floatReg, val, width);
- }
-
- Fault setFloatRegBits(int floatReg, const FloatRegBits &val)
- {
- //Use the "natural" width of a single float
- return floatRegFile.setRegBits(floatReg, val,
- FloatRegFile::SingleWidth);
- }
-
- IntReg readIntReg(int intReg)
- {
- return intRegFile.readReg(intReg);
- }
-
- Fault setIntReg(int intReg, const IntReg &val)
- {
- return intRegFile.setReg(intReg, val);
- }
+ Fault setIntReg(int intReg, const IntReg &val);
void serialize(std::ostream &os);
void unserialize(Checkpoint *cp, const std::string &section);
public:
- enum ContextParam
- {
- CONTEXT_CWP,
- CONTEXT_GLOBALS
- };
- typedef int ContextVal;
-
- void changeContext(ContextParam param, ContextVal val)
- {
- switch(param)
- {
- case CONTEXT_CWP:
- intRegFile.setCWP(val);
- break;
- case CONTEXT_GLOBALS:
- intRegFile.setGlobals(val);
- break;
- default:
- panic("Tried to set illegal context parameter in the SPARC regfile.\n");
- }
- }
+ void changeContext(RegContextParam param, RegContextVal val);
};
void copyRegs(ThreadContext *src, ThreadContext *dest);
diff --git a/src/arch/sparc/syscallreturn.hh b/src/arch/sparc/syscallreturn.hh
new file mode 100644
index 000000000..fd63a8868
--- /dev/null
+++ b/src/arch/sparc/syscallreturn.hh
@@ -0,0 +1,90 @@
+/*
+ * 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
+ */
+
+#ifndef __ARCH_SPARC_SYSCALLRETURN_HH__
+#define __ARCH_SPARC_SYSCALLRETURN_HH__
+
+#include <inttypes.h>
+
+class SyscallReturn
+{
+ public:
+ template <class T>
+ SyscallReturn(T v, bool s)
+ {
+ retval = (uint64_t)v;
+ success = s;
+ }
+
+ template <class T>
+ SyscallReturn(T v)
+ {
+ success = (v >= 0);
+ retval = (uint64_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 SparcISA
+{
+ static inline void setSyscallReturn(SyscallReturn return_value,
+ RegFile *regs)
+ {
+ // check for error condition. SPARC syscall convention is to
+ // indicate success/failure in reg the carry bit of the ccr
+ // and put the return value itself in the standard return value reg ().
+ if (return_value.successful()) {
+ // no error, clear XCC.C
+ regs->setMiscReg(MISCREG_CCR, regs->readMiscReg(MISCREG_CCR) & 0xEF);
+ regs->setIntReg(ReturnValueReg, return_value.value());
+ } else {
+ // got an error, set XCC.C
+ regs->setMiscReg(MISCREG_CCR, regs->readMiscReg(MISCREG_CCR) | 0x10);
+ regs->setIntReg(ReturnValueReg, return_value.value());
+ }
+ }
+};
+
+#endif
diff --git a/src/arch/sparc/types.hh b/src/arch/sparc/types.hh
new file mode 100644
index 000000000..88fb24153
--- /dev/null
+++ b/src/arch/sparc/types.hh
@@ -0,0 +1,63 @@
+/*
+ * 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
+ */
+
+#ifndef __ARCH_SPARC_TYPES_HH__
+#define __ARCH_SPARC_TYPES_HH__
+
+#include <inttypes.h>
+
+namespace SparcISA
+{
+ typedef uint32_t MachInst;
+ typedef uint64_t ExtMachInst;
+
+ typedef uint64_t IntReg;
+ typedef uint64_t MiscReg;
+ typedef double FloatReg;
+ typedef uint64_t FloatRegBits;
+ typedef union
+ {
+ IntReg intReg;
+ FloatReg fpreg;
+ MiscReg ctrlreg;
+ } AnyReg;
+
+ enum RegContextParam
+ {
+ CONTEXT_CWP,
+ CONTEXT_GLOBALS
+ };
+
+ typedef int RegContextVal;
+
+ typedef uint8_t RegIndex;
+}
+
+#endif