changeset ee6641d7c713 in /z/repo/m5
details: http://repo.m5sim.org/m5?cmd=changeset;node=ee6641d7c713
description:
        O3: Fix itstate prediction and recovery.

        Any change of control flow now resets the itstate to 0 mask and 0 
condition,
        except where the control flow alteration write into the cpsr register. 
These
        case, for example return from an iterrupt, require the predecoder to 
recover
        the itstate.

        As there is a window of opportunity between the return from an interrupt
        changing the control flow at the head of the pipe and the commit of the 
update
        to the CPSR, the predecoder needs to be able to grab the ITstate early. 
This
        is now handled by setting the forcedItState inside a PCstate for the 
control
        flow altering instruction.

        That instruction will have the correct mask/cond, but will not have a 
valid
        itstate until advancePC is called (note this happens to advance the 
execution).
        When the new PCstate is copy constructed it gets the itstate cond/mask, 
and
        upon advancing the PC the itstate becomes valid.

        Subsequent advancing invalidates the state and zeroes the cond/mask. 
This is
        handled in isolation for the ARM ISA and should have no impact on other 
ISAs.

        Refer arch/arm/types.hh and arch/arm/predecoder.cc for the details.

diffstat:

 src/arch/arm/isa/insts/data.isa     |   2 +
 src/arch/arm/isa/insts/ldr.isa      |   6 +++-
 src/arch/arm/isa/insts/macromem.isa |   2 +
 src/arch/arm/isa/insts/misc.isa     |   4 +++
 src/arch/arm/isa/operands.isa       |   1 +
 src/arch/arm/predecoder.cc          |  14 ++++++++++--
 src/arch/arm/predecoder.hh          |   7 ++++++
 src/arch/arm/types.hh               |  39 ++++++++++++++++++++++++++++++++++--
 8 files changed, 67 insertions(+), 8 deletions(-)

diffs (216 lines):

diff -r b2c7e56572a4 -r ee6641d7c713 src/arch/arm/isa/insts/data.isa
--- a/src/arch/arm/isa/insts/data.isa   Tue Jan 18 16:30:05 2011 -0600
+++ b/src/arch/arm/isa/insts/data.isa   Tue Jan 18 16:30:05 2011 -0600
@@ -241,6 +241,8 @@
             CondCodes = CondCodesMask & newCpsr;
             NextThumb = ((CPSR)newCpsr).t;
             NextJazelle = ((CPSR)newCpsr).j;
+            ForcedItState = ((((CPSR)newCpsr).it2 << 2) & 0xFC)
+                | (((CPSR)newCpsr).it1 & 0x3);
             '''
             buildImmDataInst(mnem + 's', code, flagType,
                              suffix = "ImmPclr", buildCc = False,
diff -r b2c7e56572a4 -r ee6641d7c713 src/arch/arm/isa/insts/ldr.isa
--- a/src/arch/arm/isa/insts/ldr.isa    Tue Jan 18 16:30:05 2011 -0600
+++ b/src/arch/arm/isa/insts/ldr.isa    Tue Jan 18 16:30:05 2011 -0600
@@ -107,13 +107,15 @@
             SCTLR sctlr = Sctlr;
             // Use the version of NPC that gets set before NextThumb
             pNPC = cSwap<uint32_t>(Mem.ud, cpsr.e);
+            uint32_t tempSpsr = cSwap<uint32_t>(Mem.ud >> 32, cpsr.e);
             uint32_t newCpsr =
-                cpsrWriteByInstr(cpsr | CondCodes,
-                                 cSwap<uint32_t>(Mem.ud >> 32, cpsr.e),
+                cpsrWriteByInstr(cpsr | CondCodes, tempSpsr,
                                  0xF, true, sctlr.nmfi);
             Cpsr = ~CondCodesMask & newCpsr;
             NextThumb = ((CPSR)newCpsr).t;
             NextJazelle = ((CPSR)newCpsr).j;
+            ForcedItState = ((((CPSR)tempSpsr).it2 << 2) & 0xFC)
+                | (((CPSR)tempSpsr).it1 & 0x3);
             CondCodes = CondCodesMask & newCpsr;
             '''
             self.codeBlobs["memacc_code"] = accCode
diff -r b2c7e56572a4 -r ee6641d7c713 src/arch/arm/isa/insts/macromem.isa
--- a/src/arch/arm/isa/insts/macromem.isa       Tue Jan 18 16:30:05 2011 -0600
+++ b/src/arch/arm/isa/insts/macromem.isa       Tue Jan 18 16:30:05 2011 -0600
@@ -94,6 +94,8 @@
         Cpsr = ~CondCodesMask & newCpsr;
         CondCodes = CondCodesMask & newCpsr;
         IWNPC = cSwap(Mem.uw, cpsr.e) | ((Spsr & 0x20) ? 1 : 0);
+        ForcedItState = ((((CPSR)Spsr).it2 << 2) & 0xFC)
+                | (((CPSR)Spsr).it1 & 0x3);
     '''
     microLdrRetUopIop = InstObjParams('ldr_ret_uop', 'MicroLdrRetUop',
                                       'MicroMemOp',
diff -r b2c7e56572a4 -r ee6641d7c713 src/arch/arm/isa/insts/misc.isa
--- a/src/arch/arm/isa/insts/misc.isa   Tue Jan 18 16:30:05 2011 -0600
+++ b/src/arch/arm/isa/insts/misc.isa   Tue Jan 18 16:30:05 2011 -0600
@@ -85,6 +85,8 @@
         Cpsr = ~CondCodesMask & newCpsr;
         NextThumb = ((CPSR)newCpsr).t;
         NextJazelle = ((CPSR)newCpsr).j;
+        ForcedItState = ((((CPSR)Op1).it2 << 2) & 0xFC)
+                | (((CPSR)Op1).it1 & 0x3);
         CondCodes = CondCodesMask & newCpsr;
     '''
     msrCpsrRegIop = InstObjParams("msr", "MsrCpsrReg", "MsrRegOp",
@@ -111,6 +113,8 @@
         Cpsr = ~CondCodesMask & newCpsr;
         NextThumb = ((CPSR)newCpsr).t;
         NextJazelle = ((CPSR)newCpsr).j;
+        ForcedItState = ((((CPSR)imm).it2 << 2) & 0xFC)
+            | (((CPSR)imm).it1 & 0x3);
         CondCodes = CondCodesMask & newCpsr;
     '''
     msrCpsrImmIop = InstObjParams("msr", "MsrCpsrImm", "MsrImmOp",
diff -r b2c7e56572a4 -r ee6641d7c713 src/arch/arm/isa/operands.isa
--- a/src/arch/arm/isa/operands.isa     Tue Jan 18 16:30:05 2011 -0600
+++ b/src/arch/arm/isa/operands.isa     Tue Jan 18 16:30:05 2011 -0600
@@ -245,6 +245,7 @@
     'Thumb': pcStateReg('thumb', srtPC),
     'NextThumb': pcStateReg('nextThumb', srtMode),
     'NextJazelle': pcStateReg('nextJazelle', srtMode),
+    'ForcedItState': pcStateReg('forcedItState', srtMode),
 
     #Register operands depending on a field in the instruction encoding. These
     #should be avoided since they may not be portable across different
diff -r b2c7e56572a4 -r ee6641d7c713 src/arch/arm/predecoder.cc
--- a/src/arch/arm/predecoder.cc        Tue Jan 18 16:30:05 2011 -0600
+++ b/src/arch/arm/predecoder.cc        Tue Jan 18 16:30:05 2011 -0600
@@ -162,9 +162,17 @@
     FPSCR fpscr = tc->readMiscReg(MISCREG_FPSCR);
     emi.fpscrLen = fpscr.len;
     emi.fpscrStride = fpscr.stride;
-    CPSR cpsr = tc->readMiscReg(MISCREG_CPSR);
-    itstate.top6 = cpsr.it2;
-    itstate.bottom2 = cpsr.it1;
+
+    if (pc.forcedItStateIsValid()) {
+        // returns from exceptions/interrupts force the it state.
+        itstate = pc.forcedItState();
+        DPRINTF(Predecoder, "Predecoder, itstate forced = %08x.\n", 
pc.forcedItState());
+    } else if (predAddrValid && (pc.instAddr() != predAddr)) {
+        // Control flow changes necessitate a 0 itstate.
+        itstate.top6 = 0;
+        itstate.bottom2 = 0;
+    }
+
     outOfBytes = false;
     process();
 }
diff -r b2c7e56572a4 -r ee6641d7c713 src/arch/arm/predecoder.hh
--- a/src/arch/arm/predecoder.hh        Tue Jan 18 16:30:05 2011 -0600
+++ b/src/arch/arm/predecoder.hh        Tue Jan 18 16:30:05 2011 -0600
@@ -67,6 +67,8 @@
         bool outOfBytes;
         int offset;
         ITSTATE itstate;
+        Addr predAddr;
+        bool predAddrValid;
 
       public:
         void reset()
@@ -76,6 +78,9 @@
             emi = 0;
             emiReady = false;
             outOfBytes = true;
+            itstate = 0;
+            predAddr = 0;
+            predAddrValid = false;
         }
 
         Predecoder(ThreadContext * _tc) :
@@ -138,6 +143,8 @@
             assert(emiReady);
             ExtMachInst thisEmi = emi;
             pc.npc(pc.pc() + getInstSize());
+            predAddrValid = true;
+            predAddr = pc.pc() + getInstSize();
             emi = 0;
             emiReady = false;
             return thisEmi;
diff -r b2c7e56572a4 -r ee6641d7c713 src/arch/arm/types.hh
--- a/src/arch/arm/types.hh     Tue Jan 18 16:30:05 2011 -0600
+++ b/src/arch/arm/types.hh     Tue Jan 18 16:30:05 2011 -0600
@@ -202,9 +202,10 @@
         };
         uint8_t flags;
         uint8_t nextFlags;
-
+        uint8_t forcedItStateValue;
+        bool forcedItStateValid;
       public:
-        PCState() : flags(0), nextFlags(0)
+        PCState() : flags(0), nextFlags(0), forcedItStateValue(0), 
forcedItStateValid(false)
         {}
 
         void
@@ -214,7 +215,7 @@
             npc(val + (thumb() ? 2 : 4));
         }
 
-        PCState(Addr val) : flags(0), nextFlags(0)
+        PCState(Addr val) : flags(0), nextFlags(0), forcedItStateValue(0), 
forcedItStateValid(false)
         { set(val); }
 
         bool
@@ -277,12 +278,40 @@
                 nextFlags &= ~JazelleBit;
         }
 
+        uint8_t
+        forcedItState() const
+        {
+            return forcedItStateValue;
+        }
+
+        void
+        forcedItState(uint8_t value)
+        {
+            forcedItStateValue = value;
+            // Not valid unless the advance is called.
+            forcedItStateValid = false;
+        }
+
+        bool
+        forcedItStateIsValid() const
+        {
+            return forcedItStateValid;
+        }
+
         void
         advance()
         {
             Base::advance();
             npc(pc() + (thumb() ? 2 : 4));
             flags = nextFlags;
+
+            // Validate the itState
+            if (forcedItStateValue != 0 && !forcedItStateValid) {
+                forcedItStateValid = true;
+            } else {
+                forcedItStateValid = false;
+                forcedItStateValue = 0;
+            }
         }
 
         void
@@ -366,6 +395,8 @@
             Base::serialize(os);
             SERIALIZE_SCALAR(flags);
             SERIALIZE_SCALAR(nextFlags);
+            SERIALIZE_SCALAR(forcedItStateValue);
+            SERIALIZE_SCALAR(forcedItStateValid);
         }
 
         void
@@ -374,6 +405,8 @@
             Base::unserialize(cp, section);
             UNSERIALIZE_SCALAR(flags);
             UNSERIALIZE_SCALAR(nextFlags);
+            UNSERIALIZE_SCALAR(forcedItStateValue);
+            UNSERIALIZE_SCALAR(forcedItStateValid);
         }
     };
 
_______________________________________________
m5-dev mailing list
m5-dev@m5sim.org
http://m5sim.org/mailman/listinfo/m5-dev

Reply via email to