ARM: Cleanup implementation of ITSTATE and put important code in PCState.
authorAli Saidi <Ali.Saidi@ARM.com>
Mon, 4 Apr 2011 16:42:28 +0000 (11:42 -0500)
committerAli Saidi <Ali.Saidi@ARM.com>
Mon, 4 Apr 2011 16:42:28 +0000 (11:42 -0500)
Consolidate all code to handle ITSTATE in the PCState object rather than
touching a variety of structures/objects.

21 files changed:
src/arch/alpha/predecoder.hh
src/arch/arm/faults.cc
src/arch/arm/isa.cc
src/arch/arm/isa/insts/data.isa
src/arch/arm/isa/insts/macromem.isa
src/arch/arm/isa/insts/misc.isa
src/arch/arm/isa/operands.isa
src/arch/arm/isa/templates/macromem.isa
src/arch/arm/isa/templates/mem.isa
src/arch/arm/isa/templates/misc.isa
src/arch/arm/isa/templates/neon.isa
src/arch/arm/isa/templates/pred.isa
src/arch/arm/miscregs.hh
src/arch/arm/predecoder.cc
src/arch/arm/predecoder.hh
src/arch/arm/types.hh
src/arch/mips/predecoder.hh
src/arch/power/predecoder.hh
src/arch/sparc/predecoder.hh
src/arch/x86/predecoder.hh
src/cpu/o3/fetch_impl.hh

index 2f8c4c2ef1dab8cfe945d9e14942890c102a6f1b..a8788051f3ec634bf7608f7b18cf037c54b7dc8a 100644 (file)
@@ -76,12 +76,6 @@ class Predecoder
         emiIsReady = false;
     }
 
-    void
-    reset(const ExtMachInst &old_emi)
-    {
-        reset();
-    }
-
     // Use this to give data to the predecoder. This should be used
     // when there is control flow.
     void
index 9fdd58da0e8eecbf5fb14e7f1e68f1546689dc16..01d43f3385842b2a49b7a770b70a0afd5422ead3 100644 (file)
@@ -108,7 +108,9 @@ ArmFault::invoke(ThreadContext *tc, StaticInstPtr inst)
     CPSR saved_cpsr = tc->readMiscReg(MISCREG_CPSR) | 
                       tc->readIntReg(INTREG_CONDCODES);
     Addr curPc M5_VAR_USED = tc->pcState().pc();
+    ITSTATE it = tc->pcState().itstate();
+    saved_cpsr.it2 = it.top6;
+    saved_cpsr.it1 = it.bottom2;
 
     cpsr.mode = nextMode();
     cpsr.it1 = cpsr.it2 = 0;
@@ -159,7 +161,7 @@ Reset::invoke(ThreadContext *tc, StaticInstPtr inst)
 {
     tc->getCpuPtr()->clearInterrupts();
     tc->clearArchRegs();
-    ArmFault::invoke(tc);
+    ArmFault::invoke(tc, inst);
 }
 
 #else
@@ -203,7 +205,7 @@ template<class T>
 void
 AbortFault<T>::invoke(ThreadContext *tc, StaticInstPtr inst)
 {
-    ArmFaultVals<T>::invoke(tc);
+    ArmFaultVals<T>::invoke(tc, inst);
     FSR fsr = 0;
     fsr.fsLow = bits(status, 3, 0);
     fsr.fsHigh = bits(status, 4);
@@ -223,7 +225,6 @@ FlushPipe::invoke(ThreadContext *tc, StaticInstPtr inst) {
     // start refetching from the next instruction.
     PCState pc = tc->pcState();
     assert(inst);
-    pc.forcedItState(inst->machInst.newItstate);
     inst->advancePC(pc);
     tc->pcState(pc);
 }
index d720becba4299fdda80419231398c54498e01a9f..f3f73089634dee80978b746ba44989b49e282b40 100644 (file)
@@ -266,18 +266,6 @@ ISA::setMiscReg(int misc_reg, const MiscReg &val, ThreadContext *tc)
               miscRegName[misc_reg], val);
     } else {
         switch (misc_reg) {
-          case MISCREG_ITSTATE:
-            {
-                ITSTATE itstate = newVal;
-                CPSR cpsr = miscRegs[MISCREG_CPSR];
-                cpsr.it1 = itstate.bottom2;
-                cpsr.it2 = itstate.top6;
-                miscRegs[MISCREG_CPSR] = cpsr;
-                DPRINTF(MiscRegs,
-                        "Updating ITSTATE -> %#x in CPSR -> %#x.\n",
-                        (uint8_t)itstate, (uint32_t)cpsr);
-            }
-            break;
           case MISCREG_CPACR:
             {
                 CPACR newCpacr = 0;
index 9af81b465e81a31c94a895715b78acd03a1f5326..e8012ff894a65cf10d0e0cce5b72751cd4ce920d 100644 (file)
@@ -245,7 +245,7 @@ let {{
             CondCodes = CondCodesMask & newCpsr;
             NextThumb = ((CPSR)newCpsr).t;
             NextJazelle = ((CPSR)newCpsr).j;
-            ForcedItState = ((((CPSR)newCpsr).it2 << 2) & 0xFC)
+            NextItState = ((((CPSR)newCpsr).it2 << 2) & 0xFC)
                 | (((CPSR)newCpsr).it1 & 0x3);
             '''
             buildImmDataInst(mnem + 's', code, flagType,
index 15879e0e30cbbc40a07e10b842c5f92032971d80..28b140b93b0eeceb06068d667c320070fede009c 100644 (file)
@@ -94,7 +94,7 @@ let {{
         Cpsr = ~CondCodesMask & newCpsr;
         CondCodes = CondCodesMask & newCpsr;
         IWNPC = cSwap(%s, cpsr.e) | ((Spsr & 0x20) ? 1 : 0);
-        ForcedItState = ((((CPSR)Spsr).it2 << 2) & 0xFC)
+        NextItState = ((((CPSR)Spsr).it2 << 2) & 0xFC)
                 | (((CPSR)Spsr).it1 & 0x3);
     '''
 
@@ -628,7 +628,7 @@ let {{
                     Cpsr = ~CondCodesMask & newCpsr;
                     NextThumb = ((CPSR)newCpsr).t;
                     NextJazelle = ((CPSR)newCpsr).j;
-                    ForcedItState = ((((CPSR)URb).it2 << 2) & 0xFC)
+                    NextItState = ((((CPSR)URb).it2 << 2) & 0xFC)
                                     | (((CPSR)URb).it1 & 0x3);
                     CondCodes = CondCodesMask & newCpsr;
                     '''
index cf5c7b47ab5f84b8dca08eda59b8a8b0ed164f67..35df88c813fb7a1909892638a2427c265ca2ede0 100644 (file)
@@ -83,10 +83,6 @@ let {{
         uint32_t newCpsr =
             cpsrWriteByInstr(Cpsr | CondCodes, Op1, byteMask, false, sctlr.nmfi);
         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,10 +107,6 @@ let {{
         uint32_t newCpsr =
             cpsrWriteByInstr(Cpsr | CondCodes, imm, byteMask, false, sctlr.nmfi);
         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",
@@ -538,7 +530,7 @@ let {{
     exec_output += PredOpExecute.subst(sevIop)
 
     itIop = InstObjParams("it", "ItInst", "PredOp", \
-            { "code" : "Itstate = machInst.newItstate;",
+            { "code" : ";",
               "predicate_test" : predicateTest },
             ["IsNonSpeculative", "IsSerializeAfter"])
     header_output += BasicDeclare.subst(itIop)
index 20ce6df52122a1255f36d1c45b1fe6ff0edf33bb..49a86021338aeaad5ca9dbbf1dd0b36c4cfc2b63 100644 (file)
@@ -217,7 +217,6 @@ def operands {{
 
     #Fixed index control regs
     'Cpsr': cntrlReg('MISCREG_CPSR', srtCpsr),
-    'Itstate': cntrlRegNC('MISCREG_ITSTATE', type = 'ub'),
     'Spsr': cntrlRegNC('MISCREG_SPSR'),
     'Fpsr': cntrlRegNC('MISCREG_FPSR'),
     'Fpsid': cntrlRegNC('MISCREG_FPSID'),
@@ -247,7 +246,8 @@ def operands {{
     'Thumb': pcStateReg('thumb', srtPC),
     'NextThumb': pcStateReg('nextThumb', srtMode),
     'NextJazelle': pcStateReg('nextJazelle', srtMode),
-    'ForcedItState': pcStateReg('forcedItState', srtMode),
+    'NextItState': pcStateReg('nextItstate', srtMode),
+    'Itstate': pcStateReg('itstate', srtMode),
 
     #Register operands depending on a field in the instruction encoding. These
     #should be avoided since they may not be portable across different
index a7f7f0da8aeacdfe37d8fcc32c474e6ce816ca6f..a62dec5cf24ca94197731ab334d5f76415d8bd8a 100644 (file)
@@ -241,10 +241,6 @@ def template MicroNeonMixExecute {{
             xc->setPredicate(false);
         }
 
-        if (fault == NoFault && machInst.itstateMask != 0) {
-            xc->setMiscReg(MISCREG_ITSTATE, machInst.newItstate);
-        }
-
         return fault;
     }
 }};
index f26ee55e83e4d68930100a11263b80214cb7c74b..43a7422427338c6921b76c5bdacf83d1f8360863 100644 (file)
@@ -102,11 +102,6 @@ def template SwapExecute {{
             xc->setPredicate(false);
         }
 
-        if (fault == NoFault && machInst.itstateMask != 0 &&
-                (!isMicroop() || isLastMicroop())) {
-            xc->setMiscReg(MISCREG_ITSTATE, machInst.newItstate);
-        }
-
         return fault;
     }
 }};
@@ -135,11 +130,6 @@ def template SwapInitiateAcc {{
             xc->setPredicate(false);
         }
 
-        if (fault == NoFault && machInst.itstateMask != 0 &&
-                (!isMicroop() || isLastMicroop())) {
-            xc->setMiscReg(MISCREG_ITSTATE, machInst.newItstate);
-        }
-
         return fault;
     }
 }};
@@ -166,10 +156,6 @@ def template SwapCompleteAcc {{
             }
         }
 
-        if (fault == NoFault && machInst.itstateMask != 0) {
-            xc->setMiscReg(MISCREG_ITSTATE, machInst.newItstate);
-        }
-
         return fault;
     }
 }};
@@ -199,11 +185,6 @@ def template LoadExecute {{
             xc->setPredicate(false);
         }
 
-        if (fault == NoFault && machInst.itstateMask != 0 &&
-                (!isMicroop() || isLastMicroop())) {
-            xc->setMiscReg(MISCREG_ITSTATE, machInst.newItstate);
-        }
-
         return fault;
     }
 }};
@@ -238,11 +219,6 @@ def template NeonLoadExecute {{
             xc->setPredicate(false);
         }
 
-        if (fault == NoFault && machInst.itstateMask != 0 &&
-                (!isMicroop() || isLastMicroop())) {
-            xc->setMiscReg(MISCREG_ITSTATE, machInst.newItstate);
-        }
-
         return fault;
     }
 }};
@@ -276,11 +252,6 @@ def template StoreExecute {{
             xc->setPredicate(false);
         }
 
-        if (fault == NoFault && machInst.itstateMask != 0 &&
-                (!isMicroop() || isLastMicroop())) {
-            xc->setMiscReg(MISCREG_ITSTATE, machInst.newItstate);
-        }
-
         return fault;
     }
 }};
@@ -319,11 +290,6 @@ def template NeonStoreExecute {{
             xc->setPredicate(false);
         }
 
-        if (fault == NoFault && machInst.itstateMask != 0 &&
-                (!isMicroop() || isLastMicroop())) {
-            xc->setMiscReg(MISCREG_ITSTATE, machInst.newItstate);
-        }
-
         return fault;
     }
 }};
@@ -363,11 +329,6 @@ def template StoreExExecute {{
             xc->setPredicate(false);
         }
 
-        if (fault == NoFault && machInst.itstateMask != 0 &&
-                (!isMicroop() || isLastMicroop())) {
-            xc->setMiscReg(MISCREG_ITSTATE, machInst.newItstate);
-        }
-
         return fault;
     }
 }};
@@ -396,10 +357,6 @@ def template StoreExInitiateAcc {{
         } else {
             xc->setPredicate(false);
         }
-        if (fault == NoFault && machInst.itstateMask != 0 &&
-                (!isMicroop() || isLastMicroop())) {
-            xc->setMiscReg(MISCREG_ITSTATE, machInst.newItstate);
-        }
 
         return fault;
     }
@@ -430,11 +387,6 @@ def template StoreInitiateAcc {{
             xc->setPredicate(false);
         }
 
-        if (fault == NoFault && machInst.itstateMask != 0 &&
-                (!isMicroop() || isLastMicroop())) {
-            xc->setMiscReg(MISCREG_ITSTATE, machInst.newItstate);
-        }
-
         return fault;
     }
 }};
@@ -467,11 +419,6 @@ def template NeonStoreInitiateAcc {{
             xc->setPredicate(false);
         }
 
-        if (fault == NoFault && machInst.itstateMask != 0 &&
-                (!isMicroop() || isLastMicroop())) {
-            xc->setMiscReg(MISCREG_ITSTATE, machInst.newItstate);
-        }
-
         return fault;
     }
 }};
@@ -494,10 +441,6 @@ def template LoadInitiateAcc {{
             }
         } else {
             xc->setPredicate(false);
-            if (fault == NoFault && machInst.itstateMask != 0 &&
-                    (!isMicroop() || isLastMicroop())) {
-                xc->setMiscReg(MISCREG_ITSTATE, machInst.newItstate);
-            }
         }
 
         return fault;
@@ -523,10 +466,6 @@ def template NeonLoadInitiateAcc {{
             }
         } else {
             xc->setPredicate(false);
-            if (fault == NoFault && machInst.itstateMask != 0 &&
-                   (!isMicroop() || isLastMicroop())) {
-                xc->setMiscReg(MISCREG_ITSTATE, machInst.newItstate);
-            }
         }
 
         return fault;
@@ -557,10 +496,6 @@ def template LoadCompleteAcc {{
             }
         }
 
-        if (fault == NoFault && machInst.itstateMask != 0) {
-            xc->setMiscReg(MISCREG_ITSTATE, machInst.newItstate);
-        }
-
         return fault;
     }
 }};
@@ -591,10 +526,6 @@ def template NeonLoadCompleteAcc {{
             }
         }
 
-        if (fault == NoFault && machInst.itstateMask != 0) {
-            xc->setMiscReg(MISCREG_ITSTATE, machInst.newItstate);
-        }
-
         return fault;
     }
 }};
@@ -604,10 +535,6 @@ def template StoreCompleteAcc {{
                                       %(CPU_exec_context)s *xc,
                                       Trace::InstRecord *traceData) const
     {
-        if (machInst.itstateMask != 0) {
-            warn_once("Complete acc isn't called on normal stores in O3.");
-            xc->setMiscReg(MISCREG_ITSTATE, machInst.newItstate);
-        }
         return NoFault;
     }
 }};
@@ -618,10 +545,6 @@ def template NeonStoreCompleteAcc {{
             PacketPtr pkt, %(CPU_exec_context)s *xc,
             Trace::InstRecord *traceData) const
     {
-        if (machInst.itstateMask != 0) {
-            warn_once("Complete acc isn't called on normal stores in O3.");
-            xc->setMiscReg(MISCREG_ITSTATE, machInst.newItstate);
-        }
         return NoFault;
     }
 }};
@@ -646,10 +569,6 @@ def template StoreExCompleteAcc {{
             }
         }
 
-        if (fault == NoFault && machInst.itstateMask != 0) {
-            xc->setMiscReg(MISCREG_ITSTATE, machInst.newItstate);
-        }
-
         return fault;
     }
 }};
index 0347869f8bcc1696126267877329e7b9a63a8206..694dc46da738067a81f635de0ff7f99bd2ac4e2d 100644 (file)
@@ -438,9 +438,6 @@ def template ClrexInitiateAcc {{
             }
         } else {
             xc->setPredicate(false);
-            if (fault == NoFault && machInst.itstateMask != 0) {
-                xc->setMiscReg(MISCREG_ITSTATE, machInst.newItstate);
-            }
         }
 
         return fault;
@@ -452,10 +449,6 @@ def template ClrexCompleteAcc {{
                                       %(CPU_exec_context)s *xc,
                                       Trace::InstRecord *traceData) const
     {
-        if (machInst.itstateMask != 0) {
-            xc->setMiscReg(MISCREG_ITSTATE, machInst.newItstate);
-        }
-
         return NoFault;
     }
 }};
index 2e88c9333e09e3b380d2944c0113bd87769f71a4..fe3a026b8a6af301fe0d0653004569e126ff6faa 100644 (file)
@@ -229,10 +229,6 @@ def template NeonEqualRegExecute {{
             xc->setPredicate(false);
         }
 
-        if (fault == NoFault && machInst.itstateMask != 0) {
-            xc->setMiscReg(MISCREG_ITSTATE, machInst.newItstate);
-        }
-
         return fault;
     }
 }};
@@ -281,10 +277,6 @@ def template NeonUnequalRegExecute {{
             xc->setPredicate(false);
         }
 
-        if (fault == NoFault && machInst.itstateMask != 0) {
-            xc->setMiscReg(MISCREG_ITSTATE, machInst.newItstate);
-        }
-
         return fault;
     }
 }};
index 95c7c8e1b77768b09e9be73f7da92b48ebc9be70..4ab1335e0f7c774f4b05b28e5be36ee1e082f6ed 100644 (file)
@@ -174,11 +174,6 @@ def template PredOpExecute {{
             xc->setPredicate(false);
         }
 
-        if (fault == NoFault && machInst.itstateMask != 0&&
-                (!isMicroop() || isLastMicroop())) {
-            xc->setMiscReg(MISCREG_ITSTATE, machInst.newItstate);
-        }
-
         return fault;
     }
 }};
@@ -206,11 +201,6 @@ def template QuiescePredOpExecute {{
 #endif
         }
 
-        if (fault == NoFault && machInst.itstateMask != 0&&
-                (!isMicroop() || isLastMicroop())) {
-            xc->setMiscReg(MISCREG_ITSTATE, machInst.newItstate);
-        }
-
         return fault;
     }
 }};
index f56f68c0a0f15767a5624b48ad2b3edf1f681ce9..1e105799fbe6cd34d2c747654c010731717e513b 100644 (file)
@@ -67,7 +67,6 @@ namespace ArmISA
 
     enum MiscRegIndex {
         MISCREG_CPSR = 0,
-        MISCREG_ITSTATE,
         MISCREG_SPSR,
         MISCREG_SPSR_FIQ,
         MISCREG_SPSR_IRQ,
@@ -207,7 +206,7 @@ namespace ArmISA
                                unsigned crm, unsigned opc2);
 
     const char * const miscRegName[NUM_MISCREGS] = {
-        "cpsr", "itstate", "spsr", "spsr_fiq", "spsr_irq", "spsr_svc",
+        "cpsr", "spsr", "spsr_fiq", "spsr_irq", "spsr_svc",
         "spsr_mon", "spsr_und", "spsr_abt",
         "fpsr", "fpsid", "fpscr", "fpscr_qc", "fpscr_exc", "fpexc",
         "mvfr0", "mvfr1",
@@ -264,20 +263,6 @@ namespace ArmISA
         Bitfield<4, 0> mode;
     EndBitUnion(CPSR)
 
-    BitUnion8(ITSTATE)
-        /* Note that the split (cond, mask) below is not as in ARM ARM.
-         * But it is more convenient for simulation. The condition
-         * is always the concatenation of the top 3 bits and the next bit,
-         * which applies when one of the bottom 4 bits is set.
-         * Refer to predecoder.cc for the use case.
-         */
-        Bitfield<7, 4> cond;
-        Bitfield<3, 0> mask;
-        // Bitfields for moving to/from CPSR
-        Bitfield<7, 2> top6;
-        Bitfield<1, 0> bottom2;
-    EndBitUnion(ITSTATE)
-
     // This mask selects bits of the CPSR that actually go in the CondCodes
     // integer register to allow renaming.
     static const uint32_t CondCodesMask = 0xF80F0000;
index e532359b5cff3e57a418425ddb13659a2017490f..b87ca622e4b364b2249d385f88efb43c4c49bf67 100644 (file)
 namespace ArmISA
 {
 
-void
-Predecoder::advanceThumbCond()
-{
-    uint8_t condMask = itstate.mask;
-    uint8_t thumbCond = itstate.cond;
-    DPRINTF(Predecoder, "Advancing ITSTATE from %#x, %#x.\n",
-            thumbCond, condMask);
-    condMask = condMask << 1;
-    uint8_t newBit = bits(condMask, 4);
-    condMask &= mask(4);
-    if (condMask == 0) {
-        thumbCond = 0;
-    } else {
-        replaceBits(thumbCond, 0, newBit);
-    }
-    DPRINTF(Predecoder, "Advancing ITSTATE to %#x, %#x.\n",
-            thumbCond, condMask);
-    itstate.mask = condMask;
-    itstate.cond = thumbCond;
-}
-
 void
 Predecoder::process()
 {
@@ -93,11 +72,6 @@ Predecoder::process()
             consumeBytes(2);
             DPRINTF(Predecoder, "Second half of 32 bit Thumb: %#x.\n",
                     emi.instBits);
-            if (itstate.mask) {
-                emi.itstate = itstate;
-                advanceThumbCond();
-                emi.newItstate = itstate;
-            }
         } else {
             uint16_t highBits = word & 0xF800;
             if (highBits == 0xE800 || highBits == 0xF000 ||
@@ -110,11 +84,6 @@ Predecoder::process()
                     DPRINTF(Predecoder, "All of 32 bit Thumb: %#x.\n",
                             emi.instBits);
                     consumeBytes(4);
-                    if (itstate.mask) {
-                        emi.itstate = itstate;
-                        advanceThumbCond();
-                        emi.newItstate = itstate;
-                    }
                 } else {
                     // We only have the first half word.
                     DPRINTF(Predecoder,
@@ -135,16 +104,11 @@ Predecoder::process()
                         emi.instBits);
                 if (bits(word, 15, 8) == 0xbf &&
                         bits(word, 3, 0) != 0x0) {
-                    emi.itstate = itstate;
-                    itstate = bits(word, 7, 0);
-                    emi.newItstate = itstate;
+                    foundIt = true;
+                    itBits = bits(word, 7, 0);
                     DPRINTF(Predecoder,
                             "IT detected, cond = %#x, mask = %#x\n",
-                            itstate.cond, itstate.mask);
-                } else if (itstate.mask) {
-                    emi.itstate = itstate;
-                    advanceThumbCond();
-                    emi.newItstate = itstate;
+                            itBits.cond, itBits.mask);
                 }
             }
         }
@@ -163,16 +127,6 @@ Predecoder::moreBytes(const PCState &pc, Addr fetchPC, MachInst inst)
     emi.fpscrLen = fpscr.len;
     emi.fpscrStride = fpscr.stride;
 
-    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();
 }
index 08e1676c0df77d4a78e3a33da24cc781ea8ade19..e650d52d60184542a7ab768ec22cb7a9d310aa76 100644 (file)
@@ -66,9 +66,8 @@ namespace ArmISA
         bool emiReady;
         bool outOfBytes;
         int offset;
-        ITSTATE itstate;
-        Addr predAddr;
-        bool predAddrValid;
+        bool foundIt;
+        ITSTATE itBits;
 
       public:
         void reset()
@@ -78,15 +77,7 @@ namespace ArmISA
             emi = 0;
             emiReady = false;
             outOfBytes = true;
-            itstate = 0;
-            predAddr = 0;
-            predAddrValid = false;
-        }
-
-        void reset(const ExtMachInst &old_emi)
-        {
-            reset();
-            itstate = old_emi.newItstate;
+            foundIt = false;
         }
 
         Predecoder(ThreadContext * _tc) :
@@ -106,7 +97,6 @@ namespace ArmISA
             tc = _tc;
         }
 
-        void advanceThumbCond();
         void process();
 
         //Use this to give data to the predecoder. This should be used
@@ -149,11 +139,13 @@ namespace ArmISA
             assert(emiReady);
             ExtMachInst thisEmi = emi;
             pc.npc(pc.pc() + getInstSize());
-            predAddrValid = true;
-            predAddr = pc.pc() + getInstSize();
+            if (foundIt)
+                pc.nextItstate(itBits);
+            thisEmi.itstate = pc.itstate();
             pc.size(getInstSize());
             emi = 0;
             emiReady = false;
+            foundIt = false;
             return thisEmi;
         }
     };
index 7f4f125be3d6d1740e9613def81e496d9c6e16b7..6bd449e3d5e878da7d73d5b5a1e2dd03f4101fd4 100644 (file)
@@ -53,8 +53,22 @@ namespace ArmISA
 {
     typedef uint32_t MachInst;
 
+    BitUnion8(ITSTATE)
+        /* Note that the split (cond, mask) below is not as in ARM ARM.
+         * But it is more convenient for simulation. The condition
+         * is always the concatenation of the top 3 bits and the next bit,
+         * which applies when one of the bottom 4 bits is set.
+         * Refer to predecoder.cc for the use case.
+         */
+        Bitfield<7, 4> cond;
+        Bitfield<3, 0> mask;
+        // Bitfields for moving to/from CPSR
+        Bitfield<7, 2> top6;
+        Bitfield<1, 0> bottom2;
+    EndBitUnion(ITSTATE)
+
+
     BitUnion64(ExtMachInst)
-        Bitfield<63, 56> newItstate;
         // ITSTATE bits
         Bitfield<55, 48> itstate;
         Bitfield<55, 52> itstateCond;
@@ -202,11 +216,11 @@ namespace ArmISA
         };
         uint8_t flags;
         uint8_t nextFlags;
-        uint8_t forcedItStateValue;
+        uint8_t _itstate;
+        uint8_t _nextItstate;
         uint8_t _size;
-        bool forcedItStateValid;
       public:
-        PCState() : flags(0), nextFlags(0), forcedItStateValue(0), forcedItStateValid(false)
+        PCState() : flags(0), nextFlags(0), _itstate(0), _nextItstate(0)
         {}
 
         void
@@ -216,7 +230,7 @@ namespace ArmISA
             npc(val + (thumb() ? 2 : 4));
         }
 
-        PCState(Addr val) : flags(0), nextFlags(0), forcedItStateValue(0), forcedItStateValid(false)
+        PCState(Addr val) : flags(0), nextFlags(0), _itstate(0), _nextItstate(0)
         { set(val); }
 
         bool
@@ -290,23 +304,27 @@ namespace ArmISA
         }
 
         uint8_t
-        forcedItState() const
+        itstate() const
         {
-            return forcedItStateValue;
+            return _itstate;
         }
 
         void
-        forcedItState(uint8_t value)
+        itstate(uint8_t value)
         {
-            forcedItStateValue = value;
-            // Not valid unless the advance is called.
-            forcedItStateValid = false;
+            _itstate = value;
         }
 
-        bool
-        forcedItStateIsValid() const
+        uint8_t
+        nextItstate() const
         {
-            return forcedItStateValid;
+            return _nextItstate;
+        }
+
+        void
+        nextItstate(uint8_t value)
+        {
+            _nextItstate = value;
         }
 
         void
@@ -316,12 +334,27 @@ namespace ArmISA
             npc(pc() + (thumb() ? 2 : 4));
             flags = nextFlags;
 
-            // Validate the itState
-            if (forcedItStateValue != 0 && !forcedItStateValid) {
-                forcedItStateValid = true;
-            } else {
-                forcedItStateValid = false;
-                forcedItStateValue = 0;
+            if (_nextItstate) {
+                _itstate = _nextItstate;
+                _nextItstate = 0;
+            } else if (_itstate) {
+                ITSTATE it = _itstate;
+                uint8_t cond_mask = it.mask;
+                uint8_t thumb_cond = it.cond;
+                DPRINTF(Predecoder, "Advancing ITSTATE from %#x,%#x.\n",
+                        thumb_cond, cond_mask);
+                cond_mask <<= 1;
+                uint8_t new_bit = bits(cond_mask, 4);
+                cond_mask &= mask(4);
+                if (cond_mask == 0)
+                    thumb_cond = 0;
+                else
+                    replaceBits(thumb_cond, 0, new_bit);
+                DPRINTF(Predecoder, "Advancing ITSTATE to %#x,%#x.\n",
+                        thumb_cond, cond_mask);
+                it.mask = cond_mask;
+                it.cond = thumb_cond;
+                _itstate = it;
             }
         }
 
@@ -395,7 +428,8 @@ namespace ArmISA
         operator == (const PCState &opc) const
         {
             return Base::operator == (opc) &&
-                flags == opc.flags && nextFlags == opc.nextFlags;
+                flags == opc.flags && nextFlags == opc.nextFlags &&
+                _itstate == opc._itstate && _nextItstate == opc._nextItstate;
         }
 
         void
@@ -405,8 +439,8 @@ namespace ArmISA
             SERIALIZE_SCALAR(flags);
             SERIALIZE_SCALAR(_size);
             SERIALIZE_SCALAR(nextFlags);
-            SERIALIZE_SCALAR(forcedItStateValue);
-            SERIALIZE_SCALAR(forcedItStateValid);
+            SERIALIZE_SCALAR(_itstate);
+            SERIALIZE_SCALAR(_nextItstate);
         }
 
         void
@@ -416,8 +450,8 @@ namespace ArmISA
             UNSERIALIZE_SCALAR(flags);
             UNSERIALIZE_SCALAR(_size);
             UNSERIALIZE_SCALAR(nextFlags);
-            UNSERIALIZE_SCALAR(forcedItStateValue);
-            UNSERIALIZE_SCALAR(forcedItStateValid);
+            UNSERIALIZE_SCALAR(_itstate);
+            UNSERIALIZE_SCALAR(_nextItstate);
         }
     };
 
index 110493cc54ea2ba258823a0e3d8ae99ed291f781..4220b768c6fd0ebefce55531492b334d8caaf147 100644 (file)
@@ -75,12 +75,6 @@ class Predecoder
         emiIsReady = false;
     }
 
-    void
-    reset(const ExtMachInst &old_emi)
-    {
-        reset();
-    }
-
     //Use this to give data to the predecoder. This should be used
     //when there is control flow.
     void
index c10bc51bf7a61032305ee0850639559ed4fd8351..8b10890957a04a1ce5008ab922acd9c02ccb4909 100644 (file)
@@ -82,12 +82,6 @@ class Predecoder
         emiIsReady = false;
     }
 
-    void
-    reset(const ExtMachInst &old_emi)
-    {
-        reset();
-    }
-
     // Use this to give data to the predecoder. This should be used
     // when there is control flow.
     void
index 082adeb7296d643c75b47d9978ec3724bf90c072..a7a543621f2bad7e8fb0d6ae32bbc94ee2eba226 100644 (file)
@@ -75,12 +75,6 @@ class Predecoder
         emiIsReady = false;
     }
 
-    void
-    reset(const ExtMachInst &old_emi)
-    {
-        reset();
-    }
-
     // Use this to give data to the predecoder. This should be used
     // when there is control flow.
     void
index 790453b98ef1279c0c17acc4aabe5da75bb96023..5c67e28e19acf28498f88635649abfbf8052c011 100644 (file)
@@ -174,12 +174,6 @@ namespace X86ISA
             state = ResetState;
         }
 
-        void
-        reset(const ExtMachInst &old_emi)
-        {
-            reset();
-        }
-
         ThreadContext * getTC()
         {
             return tc;
index 6c1ac456d0ab85c57048b1569134e221f621809a..c611f0e493f60e95b49fea2763f5a57253b5f429 100644 (file)
@@ -821,8 +821,6 @@ DefaultFetch<Impl>::squash(const TheISA::PCState &newPC,
     DPRINTF(Fetch, "[tid:%u]: Squash from commit.\n", tid);
 
     doSquash(newPC, tid);
-    if (squashInst)
-        predecoder.reset(squashInst->staticInst->machInst);
 
     // Tell the CPU to remove any instructions that are not in the ROB.
     cpu->removeInstsNotInROB(tid);