SPARC: Get rid of the copy/pasted StackTrace stolen from Alpha.
[gem5.git] / src / arch / arm / isa.hh
index cb207bf13852508f4035ce031bc0226c344e88ff..8318417f59c3ea59add17099036f29ff41a0b4cf 100644 (file)
@@ -1,4 +1,16 @@
 /*
+ * Copyright (c) 2010 ARM Limited
+ * All rights reserved
+ *
+ * The license below extends only to copyright in the software and shall
+ * not be construed as granting a license to any other intellectual
+ * property including but not limited to intellectual property relating
+ * to a hardware implementation of the functionality of the software
+ * licensed hereunder.  You may use the software subject to the license
+ * terms below provided that you ensure that this notice is replicated
+ * unmodified and in its entirety in all distributions of the software,
+ * modified or unmodified, in source code or in binary form.
+ *
  * Copyright (c) 2009 The Regents of The University of Michigan
  * All rights reserved.
  *
  */
 
 #ifndef __ARCH_ARM_ISA_HH__
-#define __ARCH_MRM_ISA_HH__
+#define __ARCH_ARM_ISA_HH__
 
-#include "arch/arm/regfile/misc_regfile.hh"
+#include "arch/arm/registers.hh"
+#include "arch/arm/tlb.hh"
 #include "arch/arm/types.hh"
 
+class ThreadContext;
 class Checkpoint;
 class EventManager;
 
@@ -42,22 +56,79 @@ namespace ArmISA
     class ISA
     {
       protected:
-        MiscRegFile miscRegFile;
+        MiscReg miscRegs[NumMiscRegs];
+        const IntRegIndex *intRegMap;
+
+        void
+        updateRegMap(CPSR cpsr)
+        {
+            switch (cpsr.mode) {
+              case MODE_USER:
+              case MODE_SYSTEM:
+                intRegMap = IntRegUsrMap;
+                break;
+              case MODE_FIQ:
+                intRegMap = IntRegFiqMap;
+                break;
+              case MODE_IRQ:
+                intRegMap = IntRegIrqMap;
+                break;
+              case MODE_SVC:
+                intRegMap = IntRegSvcMap;
+                break;
+              case MODE_MON:
+                intRegMap = IntRegMonMap;
+                break;
+              case MODE_ABORT:
+                intRegMap = IntRegAbtMap;
+                break;
+              case MODE_UNDEFINED:
+                intRegMap = IntRegUndMap;
+                break;
+              default:
+                panic("Unrecognized mode setting in CPSR.\n");
+            }
+        }
 
       public:
         void clear();
 
-        MiscReg readMiscRegNoEffect(int miscReg);
-        MiscReg readMiscReg(int miscReg, ThreadContext *tc);
-
-        void setMiscRegNoEffect(int miscReg, const MiscReg val);
-        void setMiscReg(int miscReg, const MiscReg val,
-                ThreadContext *tc);
+        MiscReg readMiscRegNoEffect(int misc_reg);
+        MiscReg readMiscReg(int misc_reg, ThreadContext *tc);
+        void setMiscRegNoEffect(int misc_reg, const MiscReg &val);
+        void setMiscReg(int misc_reg, const MiscReg &val, ThreadContext *tc);
 
         int
         flattenIntIndex(int reg)
         {
-            return reg;
+            assert(reg >= 0);
+            if (reg < NUM_ARCH_INTREGS) {
+                return intRegMap[reg];
+            } else if (reg < NUM_INTREGS) {
+                return reg;
+            } else {
+                int mode = reg / intRegsPerMode;
+                reg = reg % intRegsPerMode;
+                switch (mode) {
+                  case MODE_USER:
+                  case MODE_SYSTEM:
+                    return INTREG_USR(reg);
+                  case MODE_FIQ:
+                    return INTREG_FIQ(reg);
+                  case MODE_IRQ:
+                    return INTREG_IRQ(reg);
+                  case MODE_SVC:
+                    return INTREG_SVC(reg);
+                  case MODE_MON:
+                    return INTREG_MON(reg);
+                  case MODE_ABORT:
+                    return INTREG_ABT(reg);
+                  case MODE_UNDEFINED:
+                    return INTREG_UND(reg);
+                  default:
+                    panic("Flattening into an unknown mode.\n");
+                }
+            }
         }
 
         int
@@ -66,11 +137,58 @@ namespace ArmISA
             return reg;
         }
 
-        void serialize(std::ostream &os);
-        void unserialize(Checkpoint *cp, const std::string &section);
+        int
+        flattenMiscIndex(int reg)
+        {
+            if (reg == MISCREG_SPSR) {
+                int spsr_idx = NUM_MISCREGS;
+                CPSR cpsr = miscRegs[MISCREG_CPSR];
+                switch (cpsr.mode) {
+                  case MODE_USER:
+                    warn("User mode does not have SPSR\n");
+                    spsr_idx = MISCREG_SPSR;
+                    break;
+                  case MODE_FIQ:
+                    spsr_idx = MISCREG_SPSR_FIQ;
+                    break;
+                  case MODE_IRQ:
+                    spsr_idx = MISCREG_SPSR_IRQ;
+                    break;
+                  case MODE_SVC:
+                    spsr_idx = MISCREG_SPSR_SVC;
+                    break;
+                  case MODE_MON:
+                    spsr_idx = MISCREG_SPSR_MON;
+                    break;
+                  case MODE_ABORT:
+                    spsr_idx = MISCREG_SPSR_ABT;
+                    break;
+                  case MODE_UNDEFINED:
+                    spsr_idx = MISCREG_SPSR_UND;
+                    break;
+                  default:
+                    warn("Trying to access SPSR in an invalid mode: %d\n",
+                         cpsr.mode);
+                    spsr_idx = MISCREG_SPSR;
+                    break;
+                }
+                return spsr_idx;
+            }
+            return reg;
+        }
+
+        void serialize(EventManager *em, std::ostream &os)
+        {}
+        void unserialize(EventManager *em, Checkpoint *cp,
+                const std::string &section)
+        {}
 
         ISA()
         {
+            SCTLR sctlr;
+            sctlr = 0;
+            miscRegs[MISCREG_SCTLR_RST] = sctlr;
+
             clear();
         }
     };