Enable register windows.
authorGabe Black <gblack@eecs.umich.edu>
Thu, 6 Apr 2006 18:47:03 +0000 (14:47 -0400)
committerGabe Black <gblack@eecs.umich.edu>
Thu, 6 Apr 2006 18:47:03 +0000 (14:47 -0400)
arch/alpha/isa_traits.hh:
arch/mips/isa_traits.cc:
    Turned the integer register file into a class instead of a typedef to an array.
arch/alpha/regfile.hh:
    Changed the integer register file into a class instead of a typedef to an array. Also put the parts of the register file, ie the int, float, and misc register files, pc, npc, and nnpc, behind accessor functions. Added a changeContext function, and ContextParam and ContextVal types, so that things like the register window can be changed through call backs.
arch/mips/isa_traits.hh:
    Turned the integer register file into a class instead of a typedef to an array. Also moved a "using namespace" into the namespace definition.
arch/sparc/isa_traits.hh:
    Turned the integer register file into a class instead of a typedef to an array. Also "fixed" the max number of src and dest regs. They may need to be even larger.
arch/sparc/regfile.hh:
    Changed the integer register file into a class instead of a typedef to an array. Also put the parts of the register file, ie the int, float, and misc register files, pc, npc, and nnpc, behind accessor functions. Added a changeContext function, and ContextParam and ContextVal types, so that things like the register window can be changed through call backs. Created setCWP and setAltGlobals functions for the IntRegFile.
cpu/cpu_exec_context.hh:
    Used the accessor functions for the register file, and added a changeRegFileContext function to call back into the RegFile. Used the RegFile clear function rather than memsetting it to 0.
cpu/exec_context.hh:
    Added the changeRegFileContext function.
cpu/exetrace.cc:
    Use the TheISA::NumIntRegs constant, and use readReg now that the integer register file is a class instead of an array.
cpu/exetrace.hh:
    Get the address of the regs object, now that it isn't an array.

--HG--
extra : convert_revision : ea2dd81be1c2e66b3c684af319eb58f8a77fd49c

arch/alpha/isa_traits.hh
arch/alpha/regfile.hh
arch/mips/isa_traits.cc
arch/mips/isa_traits.hh
arch/sparc/isa_traits.hh
arch/sparc/regfile.hh
cpu/cpu_exec_context.hh
cpu/exec_context.hh
cpu/exetrace.cc
cpu/exetrace.hh

index 842eea05a89a690315746df4766324f678e3705b..65c72115bd82f1ce2f5b4f4bec3722d4d1215c58 100644 (file)
@@ -98,12 +98,12 @@ extern const int reg_redir[NumIntRegs];
         // return value itself in the standard return value reg (v0).
         if (return_value.successful()) {
             // no error
-            regs->intRegFile[SyscallSuccessReg] = 0;
-            regs->intRegFile[ReturnValueReg] = return_value.value();
+            regs->setIntReg(SyscallSuccessReg, 0);
+            regs->setIntReg(ReturnValueReg, return_value.value());
         } else {
             // got an error, return details
-            regs->intRegFile[SyscallSuccessReg] = (IntReg) -1;
-            regs->intRegFile[ReturnValueReg] = -return_value.value();
+            regs->setIntReg(SyscallSuccessReg, (IntReg)-1);
+            regs->setIntReg(ReturnValueReg, -return_value.value());
         }
     }
 #endif
index 8a11a8eb6e74c3536090e5cb0d068dfb7c7092fb..2a331258487ccb9b88dc1edacd354c5bde29aa1e 100644 (file)
@@ -38,61 +38,38 @@ class ExecContext;
 
 namespace AlphaISA
 {
-
-    typedef IntReg IntRegFile[NumIntRegs];
-
-    class FloatRegFile
+    class IntRegFile
     {
       protected:
-
-        union {
-            uint64_t q[NumFloatRegs];  // integer qword view
-            double d[NumFloatRegs];    // double-precision floating point view
-        };
+        IntReg regs[NumIntRegs];
 
       public:
 
-        FloatReg readReg(int floatReg)
+        IntReg readReg(int intReg)
         {
-            return d[floatReg];
+            return regs[intReg];
         }
 
-        FloatReg readReg(int floatReg, int width)
+        Fault setReg(int intReg, const IntReg &val)
         {
-            return readReg(floatReg);
-        }
-
-        FloatRegBits readRegBits(int floatReg)
-        {
-            return q[floatReg];
+            regs[intReg] = val;
+            return NoFault;
         }
 
-        FloatRegBits readRegBits(int floatReg, int width)
-        {
-            return readRegBits(floatReg);
-        }
+        void serialize(std::ostream &os);
 
-        Fault setReg(int floatReg, const FloatReg &val)
-        {
-            d[floatReg] = val;
-            return NoFault;
-        }
+        void unserialize(Checkpoint *cp, const std::string &section);
 
-        Fault setReg(int floatReg, const FloatReg &val, int width)
-        {
-            return setReg(floatReg, val);
-        }
+    };
 
-        Fault setRegBits(int floatReg, const FloatRegBits &val)
-        {
-            q[floatReg] = val;
-            return NoFault;
-        }
+    class FloatRegFile
+    {
+      public:
 
-        Fault setRegBits(int floatReg, const FloatRegBits &val, int width)
-        {
-            return setRegBits(floatReg, val);
-        }
+        union {
+            uint64_t q[NumFloatRegs];  // integer qword view
+            double d[NumFloatRegs];    // double-precision floating point view
+        };
 
         void serialize(std::ostream &os);
 
@@ -110,17 +87,18 @@ namespace AlphaISA
       public:
         MiscReg readReg(int misc_reg);
 
+        MiscReg readRegWithEffect(int misc_reg, Fault &fault,
+                ExecContext *xc);
+
         //These functions should be removed once the simplescalar cpu model
         //has been replaced.
         int getInstAsid();
         int getDataAsid();
 
-        MiscReg readRegWithEffect(int misc_reg, Fault &fault, ExecContext *xc);
-
         Fault setReg(int misc_reg, const MiscReg &val);
 
         Fault setRegWithEffect(int misc_reg, const MiscReg &val,
-                               ExecContext *xc);
+                ExecContext *xc);
 
 #if FULL_SYSTEM
       protected:
@@ -136,14 +114,51 @@ namespace AlphaISA
         friend class RegFile;
     };
 
-    struct RegFile {
-        IntRegFile intRegFile;         // (signed) integer register file
-        FloatRegFile floatRegFile;     // floating point register file
-        MiscRegFile miscRegs;          // control register file
+    class RegFile {
+
+      protected:
         Addr pc;                       // program counter
         Addr npc;                      // next-cycle 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;         // (signed) integer register file
+        FloatRegFile floatRegFile;     // floating point register file
+        MiscRegFile miscRegFile;       // control register file
+
+      public:
+
 #if FULL_SYSTEM
         int intrflag;                  // interrupt flag
         inline int instAsid()
@@ -152,8 +167,103 @@ namespace AlphaISA
         { return miscRegs.getDataAsid(); }
 #endif // FULL_SYSTEM
 
+        void clear()
+        {
+            bzero(&intRegFile, sizeof(intRegFile));
+            bzero(&floatRegFile, sizeof(floatRegFile));
+            bzero(&miscRegFile, sizeof(miscRegFile));
+        }
+
+        MiscReg readMiscReg(int miscReg)
+        {
+            return miscRegFile.readReg(miscReg);
+        }
+
+        MiscReg readMiscRegWithEffect(int miscReg,
+                Fault &fault, ExecContext *xc)
+        {
+            fault = NoFault;
+            return miscRegFile.readRegWithEffect(miscReg, fault, xc);
+        }
+
+        Fault setMiscReg(int miscReg, const MiscReg &val)
+        {
+            return miscRegFile.setReg(miscReg, val);
+        }
+
+        Fault setMiscRegWithEffect(int miscReg, const MiscReg &val,
+                ExecContext * xc)
+        {
+            return miscRegFile.setRegWithEffect(miscReg, val, xc);
+        }
+
+        FloatReg readFloatReg(int floatReg)
+        {
+            return floatRegFile.d[floatReg];
+        }
+
+        FloatReg readFloatReg(int floatReg, int width)
+        {
+            return readFloatReg(floatReg);
+        }
+
+        FloatRegBits readFloatRegBits(int floatReg)
+        {
+            return floatRegFile.q[floatReg];
+        }
+
+        FloatRegBits readFloatRegBits(int floatReg, int width)
+        {
+            return readFloatRegBits(floatReg);
+        }
+
+        Fault setFloatReg(int floatReg, const FloatReg &val)
+        {
+            floatRegFile.d[floatReg] = val;
+            return NoFault;
+        }
+
+        Fault setFloatReg(int floatReg, const FloatReg &val, int width)
+        {
+            return setFloatReg(floatReg, val);
+        }
+
+        Fault setFloatRegBits(int floatReg, const FloatRegBits &val)
+        {
+            floatRegFile.q[floatReg] = val;
+            return NoFault;
+        }
+
+        Fault setFloatRegBits(int floatReg, const FloatRegBits &val, int width)
+        {
+            return setFloatRegBits(floatReg, val);
+        }
+
+        IntReg readIntReg(int intReg)
+        {
+            return intRegFile.readReg(intReg);
+        }
+
+        Fault setIntReg(int intReg, const IntReg &val)
+        {
+            return intRegFile.setReg(intReg, val);
+        }
+
         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)
+        {
+            //This would be an alternative place to call/implement
+            //the swapPALShadow function
+        }
     };
 
     void copyRegs(ExecContext *src, ExecContext *dest);
index 849d3311da5c5578eddee7d29670168670c98406..c6cfb2a0fd1c5009f7fc85d69ca013414c665475 100644 (file)
@@ -274,10 +274,22 @@ static inline Addr
 RoundPage(Addr addr)
 { return (addr + MipsISA::PageBytes - 1) & ~(MipsISA::PageBytes - 1); }
 
+void
+IntRegFile::serialize(std::ostream &os)
+{
+    SERIALIZE_ARRAY(regs, NumIntRegs);
+}
+
+void
+IntRegFile::unserialize(Checkpoint *cp, const std::string &section)
+{
+    UNSERIALIZE_ARRAY(regs, NumIntRegs);
+}
+
 void
 RegFile::serialize(std::ostream &os)
 {
-    SERIALIZE_ARRAY(intRegFile, NumIntRegs);
+    intRegFile.serialize(os);
     //SERIALIZE_ARRAY(floatRegFile.q, NumFloatRegs);
     //SERIALIZE_SCALAR(miscRegs.fpcr);
     //SERIALIZE_SCALAR(miscRegs.uniq);
@@ -298,7 +310,7 @@ RegFile::serialize(std::ostream &os)
 void
 RegFile::unserialize(Checkpoint *cp, const std::string &section)
 {
-    UNSERIALIZE_ARRAY(intRegFile, NumIntRegs);
+    intRegFile.unserialize(cp, section);
     //UNSERIALIZE_ARRAY(floatRegFile.q, NumFloatRegs);
     //UNSERIALIZE_SCALAR(miscRegs.fpcr);
     //UNSERIALIZE_SCALAR(miscRegs.uniq);
index 486a5d13032ebb3bcdc7b6e1d6a610c67ec250ad..35c207828d3df16911dc9ab52779e049eddf2b86 100644 (file)
@@ -43,7 +43,6 @@ class Checkpoint;
 class ExecContext;
 
 namespace LittleEndianGuest {};
-using namespace LittleEndianGuest;
 
 #define TARGET_MIPS
 
@@ -92,6 +91,8 @@ class SyscallReturn {
 
 namespace MipsISA
 {
+    using namespace LittleEndianGuest;
+
     typedef uint32_t MachInst;
     typedef uint32_t MachInst;
     typedef uint64_t ExtMachInst;
@@ -163,7 +164,29 @@ namespace MipsISA
     };
 
     typedef uint64_t IntReg;
-    typedef IntReg IntRegFile[NumIntRegs];
+
+    class IntRegFile
+    {
+      protected:
+        IntReg regs[NumIntRegs];
+
+      public:
+        IntReg readReg(int intReg)
+        {
+            return regs[intReg];
+        }
+
+        Fault setReg(int intReg, const IntReg &val)
+        {
+            regs[intReg] = val;
+            return NoFault;
+        }
+
+        void serialize(std::ostream &os);
+
+        void unserialize(Checkpoint *cp, const std::string &section);
+
+    };
 
 /* floating point register file entry type
     typedef union {
@@ -483,17 +506,130 @@ extern const Addr PageOffset;
         MiscReg ctrlreg;
     } AnyReg;
 
-    struct RegFile {
+    class RegFile {
+      protected:
         IntRegFile intRegFile;         // (signed) integer register file
         FloatRegFile floatRegFile;     // floating point register file
-        MiscRegFile miscRegs;          // control register file
+        MiscRegFile miscRegFile;       // control register file
+
+      public:
+
+        void clear()
+        {
+            bzero(&intRegFile, sizeof(intRegFile));
+            bzero(&floatRegFile, sizeof(floatRegFile));
+            bzero(&miscRegFile, sizeof(miscRegFile));
+        }
+
+        MiscReg readMiscReg(int miscReg)
+        {
+            return miscRegFile.readReg(miscReg);
+        }
+
+        MiscReg readMiscRegWithEffect(int miscReg,
+                Fault &fault, ExecContext *xc)
+        {
+            fault = NoFault;
+            return miscRegFile.readRegWithEffect(miscReg, fault, xc);
+        }
+
+        Fault setMiscReg(int miscReg, const MiscReg &val)
+        {
+            return miscRegFile.setReg(miscReg, val);
+        }
+
+        Fault setMiscRegWithEffect(int miscReg, const MiscReg &val,
+                ExecContext * xc)
+        {
+            return miscRegFile.setRegWithEffect(miscReg, val, xc);
+        }
+
+        FloatReg readFloatReg(int floatReg)
+        {
+            return floatRegFile.readReg(floatReg);
+        }
+
+        FloatReg readFloatReg(int floatReg, int width)
+        {
+            return readFloatReg(floatReg);
+        }
+
+        FloatRegBits readFloatRegBits(int floatReg)
+        {
+            return floatRegFile.readRegBits(floatReg);
+        }
+
+        FloatRegBits readFloatRegBits(int floatReg, int width)
+        {
+            return readFloatRegBits(floatReg);
+        }
+
+        Fault setFloatReg(int floatReg, const FloatReg &val)
+        {
+            return floatRegFile.setReg(floatReg, val);
+        }
+
+        Fault setFloatReg(int floatReg, const FloatReg &val, int width)
+        {
+            return setFloatReg(floatReg, val);
+        }
+
+        Fault setFloatRegBits(int floatReg, const FloatRegBits &val)
+        {
+            return floatRegFile.setRegBits(floatReg, val);
+        }
+
+        Fault setFloatRegBits(int floatReg, const FloatRegBits &val, int width)
+        {
+            return setFloatRegBits(floatReg, val);
+        }
 
+        IntReg readIntReg(int intReg)
+        {
+            return intRegFile.readReg(intReg);
+        }
+
+        Fault setIntReg(int intReg, const IntReg &val)
+        {
+            return intRegFile.setReg(intReg, val);
+        }
+      protected:
 
         Addr pc;                       // program counter
         Addr npc;                      // next-cycle program counter
         Addr nnpc;                     // next-next-cycle program counter
                                         // used to implement branch delay slot
                                         // not real register
+      public:
+        Addr readPC()
+        {
+            return pc;
+        }
+
+        void setPC(Addr val)
+        {
+            pc = val;
+        }
+
+        Addr readNextPC()
+        {
+            return npc;
+        }
+
+        void setNextPC(Addr val)
+        {
+            npc = val;
+        }
+
+        Addr readNextNPC()
+        {
+            return nnpc;
+        }
+
+        void setNextNPC(Addr val)
+        {
+            nnpc = val;
+        }
 
         MiscReg hi;                     // MIPS HI Register
         MiscReg lo;                     // MIPS LO Register
@@ -514,6 +650,13 @@ extern const Addr PageOffset;
 
         void createCP0Regs();
         void coldReset();
+
+        typedef int ContextParam;
+        typedef int ContextVal;
+
+        void changeContext(ContextParam param, ContextVal val)
+        {
+        }
     };
 
     StaticInstPtr decodeInst(ExtMachInst);
@@ -594,12 +737,12 @@ extern const Addr PageOffset;
         // return value itself in the standard return value reg (v0).
         if (return_value.successful()) {
             // no error
-            regs->intRegFile[ReturnValueReg1] = 0;
-            regs->intRegFile[ReturnValueReg2] = return_value.value();
+            regs->setIntReg(ReturnValueReg1, 0);
+            regs->setIntReg(ReturnValueReg2, return_value.value());
         } else {
             // got an error, return details
-            regs->intRegFile[ReturnValueReg1] = (IntReg) -1;
-            regs->intRegFile[ReturnValueReg2] = -return_value.value();
+            regs->setIntReg(ReturnValueReg1, (IntReg) -1);
+            regs->setIntReg(ReturnValueReg2, -return_value.value());
         }
 
         //regs->intRegFile[ReturnValueReg1] = (IntReg)return_value;
index bbc66202c23d817ea6daa5c600e67cbe6f258e5d..57206c5e598a69cddb749d2ead3920559076889a 100644 (file)
@@ -123,8 +123,8 @@ namespace SparcISA
     const int SyscallPseudoReturnReg = ArgumentReg1;
 
     //XXX These numbers are bogus
-    const int MaxInstSrcRegs = 3;
-    const int MaxInstDestRegs = 2;
+    const int MaxInstSrcRegs = 8;
+    const int MaxInstDestRegs = 3;
 
     typedef uint64_t IntReg;
 
@@ -174,12 +174,12 @@ namespace SparcISA
         // and put the return value itself in the standard return value reg ().
         if (return_value.successful()) {
             // no error
-            regs->miscRegs.setReg(MISCREG_CCR_ICC_C, 0);
-            regs->intRegFile[ReturnValueReg] = return_value.value();
+            regs->setMiscReg(MISCREG_CCR_ICC_C, 0);
+            regs->setIntReg(ReturnValueReg, return_value.value());
         } else {
             // got an error, return details
-            regs->miscRegs.setReg(MISCREG_CCR_ICC_C, 1);
-            regs->intRegFile[ReturnValueReg] = -return_value.value();
+            regs->setMiscReg(MISCREG_CCR_ICC_C, 1);
+            regs->setIntReg(ReturnValueReg, return_value.value());
         }
     }
 #endif
index 09b8e49d7a380295243a6971d10412918b7606b0..6186e3e453de3560e6fe1ae0cb14a6c5b86d58d5 100644 (file)
@@ -30,6 +30,7 @@
 #define __ARCH_SPARC_REGFILE_HH__
 
 #include "arch/sparc/faults.hh"
+#include "base/trace.hh"
 #include "sim/byteswap.hh"
 #include "sim/host.hh"
 
@@ -40,11 +41,110 @@ namespace SparcISA
 
     typedef uint8_t  RegIndex;
 
-    // Maximum trap level
+    // MAXTL - maximum trap level
     const int MaxTL = 4;
 
-    //For right now, let's pretend the register file is flat
-    typedef IntReg IntRegFile[NumIntRegs];
+    // NWINDOWS - number of register windows, can be 3 to 32
+    const int NWindows = 6;
+
+    class IntRegFile
+    {
+      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[RegsPerFrame];
+        IntReg altGlobals[RegsPerFrame];
+        IntReg regSegments[2 * NWindows][RegsPerFrame];
+
+        enum regFrame {Globals, Outputs, Locals, Inputs, NumFrames};
+
+        IntReg * regView[NumFrames];
+
+        static const int RegGlobalOffset = 0;
+        static const int AltGlobalOffset = 8;
+        static const int FrameOffset = 16;
+        int offset[NumFrames];
+
+      public:
+
+        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()
+        {
+            bzero(regGlobals, sizeof(regGlobals));
+            bzero(altGlobals, sizeof(altGlobals));
+            for(int x = 0; x < 2 * NWindows; x++)
+                bzero(regSegments[x], sizeof(regSegments[x]));
+        }
+
+        IntRegFile()
+        {
+            offset[Globals] = 0;
+            regView[Globals] = regGlobals;
+            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 setAltGlobals(bool useAlt)
+        {
+            regView[Globals] = useAlt ? altGlobals : regGlobals;
+            offset[Globals] = useAlt ? AltGlobalOffset : RegGlobalOffset;
+        }
+
+        void serialize(std::ostream &os);
+
+        void unserialize(Checkpoint *cp, const std::string &section);
+    };
 
     typedef float float32_t;
     typedef double float64_t;
@@ -54,11 +154,13 @@ namespace SparcISA
 
     class FloatRegFile
     {
-      protected:
+      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.
@@ -66,6 +168,11 @@ namespace SparcISA
 
       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
@@ -90,12 +197,6 @@ namespace SparcISA
             }
         }
 
-        FloatReg readReg(int floatReg)
-        {
-            //Use the "natural" width of a single float
-            return readReg(floatReg, SingleWidth);
-        }
-
         FloatRegBits readRegBits(int floatReg, int width)
         {
             //In each of these cases, we have to copy the value into a temporary
@@ -120,12 +221,6 @@ namespace SparcISA
             }
         }
 
-        FloatRegBits readRegBits(int floatReg)
-        {
-            //Use the "natural" width of a single float
-            return readRegBits(floatReg, SingleWidth);
-        }
-
         Fault setReg(int floatReg, const FloatReg &val, int width)
         {
             //In each of these cases, we have to copy the value into a temporary
@@ -148,12 +243,6 @@ namespace SparcISA
             return NoFault;
         }
 
-        Fault setReg(int floatReg, const FloatReg &val)
-        {
-            //Use the "natural" width of a single float
-            return setReg(floatReg, val, SingleWidth);
-        }
-
         Fault setRegBits(int floatReg, const FloatRegBits &val, int width)
         {
             //In each of these cases, we have to copy the value into a temporary
@@ -176,12 +265,6 @@ namespace SparcISA
             return NoFault;
         }
 
-        Fault setRegBits(int floatReg, const FloatRegBits &val)
-        {
-            //Use the "natural" width of a single float
-            return setReg(floatReg, val, SingleWidth);
-        }
-
         void serialize(std::ostream &os);
 
         void unserialize(Checkpoint *cp, const std::string &section);
@@ -474,14 +557,59 @@ namespace SparcISA
         };
 
       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;
+            tt[tl] = PowerOnReset.trapType();
+            pstateFields.mm = 0; //Total Store Order
+            pstateFields.red = 1; //Enter RED_State
+            pstateFields.am = 0; //Address Masking is turned off
+            pstateFields.priv = 1; //Processor enters privileged mode
+            pstateFields.ie = 0; //Interrupts are disabled
+            pstateFields.ag = 1; //Globals are replaced with alternate globals
+            pstateFields.tle = 0; //Big Endian mode for traps
+            pstateFields.cle = 0; //Big Endian mode for non-traps
+            tickFields.npt = 1; //The TICK register is unreadable by
+                                //non-priveleged software
+#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();
+        }
+
         MiscReg readReg(int miscReg);
 
         MiscReg readRegWithEffect(int miscReg, Fault &fault, ExecContext *xc);
 
         Fault setReg(int miscReg, const MiscReg &val);
 
-        Fault setRegWithEffect(int miscReg, const MiscReg &val,
-                               ExecContext *xc);
+        Fault setRegWithEffect(int miscReg,
+                const MiscReg &val, ExecContext * xc);
 
         void serialize(std::ostream & os);
 
@@ -497,18 +625,169 @@ namespace SparcISA
         MiscReg ctrlreg;
     } AnyReg;
 
-    struct RegFile
+    class RegFile
     {
-        IntRegFile intRegFile;         // (signed) integer register file
-        FloatRegFile floatRegFile;     // floating point register file
-        MiscRegFile miscRegs;  // control register file
-
+      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
+
+      public:
+
+        void clear()
+        {
+            intRegFile.clear();
+            floatRegFile.clear();
+        }
+
+        int flattenIntIndex(int reg)
+        {
+            return intRegFile.flattenIndex(reg);
+        }
+
+        MiscReg readMiscReg(int miscReg)
+        {
+            return miscRegFile.readReg(miscReg);
+        }
+
+        MiscReg readMiscRegWithEffect(int miscReg,
+                Fault &fault, ExecContext *xc)
+        {
+            return miscRegFile.readRegWithEffect(miscReg, fault, xc);
+        }
+
+        Fault setMiscReg(int miscReg, const MiscReg &val)
+        {
+            return miscRegFile.setReg(miscReg, val);
+        }
+
+        Fault setMiscRegWithEffect(int miscReg, const MiscReg &val,
+                ExecContext * xc)
+        {
+            return miscRegFile.setRegWithEffect(miscReg, val, xc);
+        }
+
+        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);
+        }
+
         void serialize(std::ostream &os);
         void unserialize(Checkpoint *cp, const std::string &section);
+
+      public:
+
+        enum ContextParam
+        {
+            CONTEXT_CWP,
+            CONTEXT_GLOBALS
+        };
+
+        union ContextVal
+        {
+            MiscReg reg;
+            bool altGlobals;
+        };
+
+        void changeContext(ContextParam param, ContextVal val)
+        {
+            switch(param)
+            {
+              case CONTEXT_CWP:
+                intRegFile.setCWP(val.reg);
+              case CONTEXT_GLOBALS:
+                intRegFile.setAltGlobals(val.altGlobals);
+              default:
+                panic("Tried to set illegal context parameter in the SPARC regfile.\n");
+            }
+        }
     };
 
     void copyRegs(ExecContext *src, ExecContext *dest);
index 7ceb7f2d89e57b9ec7f78f9f56f0a2fa24d4a088..b023fdcf82c5910bef0f65f47279549de2854241 100644 (file)
@@ -373,103 +373,103 @@ class CPUExecContext
     //
     uint64_t readIntReg(int reg_idx)
     {
-        return regs.intRegFile[reg_idx];
+        return regs.readIntReg(reg_idx);
     }
 
     FloatReg readFloatReg(int reg_idx, int width)
     {
-        return regs.floatRegFile.readReg(reg_idx, width);
+        return regs.readFloatReg(reg_idx, width);
     }
 
     FloatReg readFloatReg(int reg_idx)
     {
-        return regs.floatRegFile.readReg(reg_idx);
+        return regs.readFloatReg(reg_idx);
     }
 
     FloatRegBits readFloatRegBits(int reg_idx, int width)
     {
-        return regs.floatRegFile.readRegBits(reg_idx, width);
+        return regs.readFloatRegBits(reg_idx, width);
     }
 
     FloatRegBits readFloatRegBits(int reg_idx)
     {
-        return regs.floatRegFile.readRegBits(reg_idx);
+        return regs.readFloatRegBits(reg_idx);
     }
 
     void setIntReg(int reg_idx, uint64_t val)
     {
-        regs.intRegFile[reg_idx] = val;
+        regs.setIntReg(reg_idx, val);
     }
 
     void setFloatReg(int reg_idx, FloatReg val, int width)
     {
-        regs.floatRegFile.setReg(reg_idx, val, width);
+        regs.setFloatReg(reg_idx, val, width);
     }
 
     void setFloatReg(int reg_idx, FloatReg val)
     {
-        regs.floatRegFile.setReg(reg_idx, val);
+        regs.setFloatReg(reg_idx, val);
     }
 
     void setFloatRegBits(int reg_idx, FloatRegBits val, int width)
     {
-        regs.floatRegFile.setRegBits(reg_idx, val, width);
+        regs.setFloatRegBits(reg_idx, val, width);
     }
 
     void setFloatRegBits(int reg_idx, FloatRegBits val)
     {
-        regs.floatRegFile.setRegBits(reg_idx, val);
+        regs.setFloatRegBits(reg_idx, val);
     }
 
     uint64_t readPC()
     {
-        return regs.pc;
+        return regs.readPC();
     }
 
     void setPC(uint64_t val)
     {
-        regs.pc = val;
+        regs.setPC(val);
     }
 
     uint64_t readNextPC()
     {
-        return regs.npc;
+        return regs.readNextPC();
     }
 
     void setNextPC(uint64_t val)
     {
-        regs.npc = val;
+        regs.setNextPC(val);
     }
 
     uint64_t readNextNPC()
     {
-        return regs.nnpc;
+        return regs.readNextNPC();
     }
 
     void setNextNPC(uint64_t val)
     {
-        regs.nnpc = val;
+        regs.setNextNPC(val);
     }
 
 
     MiscReg readMiscReg(int misc_reg)
     {
-        return regs.miscRegs.readReg(misc_reg);
+        return regs.readMiscReg(misc_reg);
     }
 
     MiscReg readMiscRegWithEffect(int misc_reg, Fault &fault)
     {
-        return regs.miscRegs.readRegWithEffect(misc_reg, fault, proxy);
+        return regs.readMiscRegWithEffect(misc_reg, fault, proxy);
     }
 
     Fault setMiscReg(int misc_reg, const MiscReg &val)
     {
-        return regs.miscRegs.setReg(misc_reg, val);
+        return regs.setMiscReg(misc_reg, val);
     }
 
     Fault setMiscRegWithEffect(int misc_reg, const MiscReg &val)
     {
-        return regs.miscRegs.setRegWithEffect(misc_reg, val, proxy);
+        return regs.setMiscRegWithEffect(misc_reg, val, proxy);
     }
 
     unsigned readStCondFailures() { return storeCondFailures; }
@@ -477,7 +477,7 @@ class CPUExecContext
     void setStCondFailures(unsigned sc_failures)
     { storeCondFailures = sc_failures; }
 
-    void clearArchRegs() { memset(&regs, 0, sizeof(regs)); }
+    void clearArchRegs() { regs.clear(); }
 
 #if FULL_SYSTEM
     int readIntrFlag() { return regs.intrflag; }
@@ -490,13 +490,13 @@ class CPUExecContext
 #if !FULL_SYSTEM
     TheISA::IntReg getSyscallArg(int i)
     {
-        return regs.intRegFile[TheISA::ArgumentReg0 + i];
+        return regs.readIntReg(TheISA::ArgumentReg0 + i);
     }
 
     // used to shift args for indirect syscall
     void setSyscallArg(int i, TheISA::IntReg val)
     {
-        regs.intRegFile[TheISA::ArgumentReg0 + i] = val;
+        regs.setIntReg(TheISA::ArgumentReg0 + i, val);
     }
 
     void setSyscallReturn(SyscallReturn return_value)
@@ -513,6 +513,12 @@ class CPUExecContext
 
     void setFuncExeInst(Counter new_val) { func_exe_inst = new_val; }
 #endif
+
+    void changeRegFileContext(RegFile::ContextParam param,
+            RegFile::ContextVal val)
+    {
+        regs.changeContext(param, val);
+    }
 };
 
 
index 8f93875a1e04061b814261a005c5dcb4e0b9c7aa..2fd49b16665f0cbecfab3629192051e4037b39e7 100644 (file)
@@ -233,6 +233,9 @@ class ExecContext
 
     virtual void setFuncExeInst(Counter new_val) = 0;
 #endif
+
+    virtual void changeRegFileContext(RegFile::ContextParam param,
+            RegFile::ContextVal val) = 0;
 };
 
 template <class XC>
@@ -422,6 +425,12 @@ class ProxyExecContext : public ExecContext
     void setFuncExeInst(Counter new_val)
     { return actualXC->setFuncExeInst(new_val); }
 #endif
+
+    void changeRegFileContext(RegFile::ContextParam param,
+            RegFile::ContextVal val)
+    {
+        actualXC->changeRegFileContext(param, val);
+    }
 };
 
 #endif
index 4db72320c7a351800f4ae590d670dac3e3d92bd7..0ed3b43c430ae39bebd93ffe2e0aa88806bb48cb 100644 (file)
@@ -128,10 +128,11 @@ Trace::InstRecord::dump(ostream &outs)
             outs << " A=0x" << hex << addr;
 
         if (flags[PRINT_INT_REGS] && regs_valid) {
-            for (int i = 0; i < 32;)
+            for (int i = 0; i < TheISA::NumIntRegs;)
                 for (int j = i + 1; i <= j; i++)
-                    ccprintf(outs, "r%02d = %#018x%s", i, iregs->regs[i],
-                             ((i == j) ? "\n" : "    "));
+                    ccprintf(outs, "r%02d = %#018x%s", i,
+                            iregs->regs.readReg(i),
+                            ((i == j) ? "\n" : "    "));
             outs << "\n";
         }
 
index 67d042ec8c2ce03a7b4805aa150b1e04d08b53eb..a26cdc517bd3d9a3b81abc2900f2e7c12e055d53 100644 (file)
@@ -163,7 +163,7 @@ InstRecord::setRegs(const IntRegFile &regs)
     if (!iregs)
       iregs = new iRegFile;
 
-    memcpy(&iregs->regs, regs, sizeof(IntRegFile));
+    memcpy(&iregs->regs, &regs, sizeof(IntRegFile));
     regs_valid = true;
 }