changeset b2c7e56572a4 in /z/repo/m5
details: http://repo.m5sim.org/m5?cmd=changeset;node=b2c7e56572a4
description:
        O3: Fix some variable length instruction issues with the O3 CPU and ARM 
ISA.

diffstat:

 src/arch/arm/predecoder.cc |  15 +++++++++++----
 src/arch/arm/predecoder.hh |  22 ++++++++++++++++++----
 src/cpu/o3/fetch_impl.hh   |  14 ++++++++++----
 3 files changed, 39 insertions(+), 12 deletions(-)

diffs (184 lines):

diff -r d25827665112 -r b2c7e56572a4 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
@@ -74,11 +74,15 @@
 void
 Predecoder::process()
 {
+    // emi is typically ready, with some caveats below...
+    emiReady = true;
+
     if (!emi.thumb) {
         emi.instBits = data;
         emi.sevenAndFour = bits(data, 7) && bits(data, 4);
         emi.isMisc = (bits(data, 24, 23) == 0x2 &&
                       bits(data, 20) == 0);
+        consumeBytes(4);
         DPRINTF(Predecoder, "Arm inst: %#x.\n", (uint64_t)emi);
     } else {
         uint16_t word = (data >> (offset * 8));
@@ -86,7 +90,7 @@
             // A 32 bit thumb inst is half collected.
             emi.instBits = emi.instBits | word;
             bigThumb = false;
-            offset += 2;
+            consumeBytes(2);
             DPRINTF(Predecoder, "Second half of 32 bit Thumb: %#x.\n",
                     emi.instBits);
             if (itstate.mask) {
@@ -105,7 +109,7 @@
                     emi.instBits = (data >> 16) | (data << 16);
                     DPRINTF(Predecoder, "All of 32 bit Thumb: %#x.\n",
                             emi.instBits);
-                    offset += 4;
+                    consumeBytes(4);
                     if (itstate.mask) {
                         emi.itstate = itstate;
                         advanceThumbCond();
@@ -117,11 +121,13 @@
                             "First half of 32 bit Thumb.\n");
                     emi.instBits = (uint32_t)word << 16;
                     bigThumb = true;
-                    offset += 2;
+                    consumeBytes(2);
+                    // emi not ready yet.
+                    emiReady = false;
                 }
             } else {
                 // A 16 bit thumb inst.
-                offset += 2;
+                consumeBytes(2);
                 emi.instBits = word;
                 // Set the condition code field artificially.
                 emi.condCode = COND_UC;
@@ -159,6 +165,7 @@
     CPSR cpsr = tc->readMiscReg(MISCREG_CPSR);
     itstate.top6 = cpsr.it2;
     itstate.bottom2 = cpsr.it1;
+    outOfBytes = false;
     process();
 }
 
diff -r d25827665112 -r b2c7e56572a4 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
@@ -45,6 +45,8 @@
 #ifndef __ARCH_ARM_PREDECODER_HH__
 #define __ARCH_ARM_PREDECODER_HH__
 
+#include <cassert>
+
 #include "arch/arm/types.hh"
 #include "arch/arm/miscregs.hh"
 #include "base/types.hh"
@@ -61,6 +63,8 @@
         ExtMachInst emi;
         MachInst data;
         bool bigThumb;
+        bool emiReady;
+        bool outOfBytes;
         int offset;
         ITSTATE itstate;
 
@@ -70,6 +74,8 @@
             bigThumb = false;
             offset = 0;
             emi = 0;
+            emiReady = false;
+            outOfBytes = true;
         }
 
         Predecoder(ThreadContext * _tc) :
@@ -103,16 +109,22 @@
             moreBytes(0, 0, machInst);
         }
 
+        inline void consumeBytes(int numBytes)
+        {
+            offset += numBytes;
+            assert(offset <= sizeof(MachInst));
+            if (offset == sizeof(MachInst))
+                outOfBytes = true;
+        }
+
         bool needMoreBytes()
         {
-            return sizeof(MachInst) > offset;
+            return outOfBytes;
         }
 
         bool extMachInstReady()
         {
-            // The only way an instruction wouldn't be ready is if this is a
-            // 32 bit ARM instruction that's not 32 bit aligned.
-            return !bigThumb;
+            return emiReady;
         }
 
         int getInstSize()
@@ -123,9 +135,11 @@
         //This returns a constant reference to the ExtMachInst to avoid a copy
         ExtMachInst getExtMachInst(PCState &pc)
         {
+            assert(emiReady);
             ExtMachInst thisEmi = emi;
             pc.npc(pc.pc() + getInstSize());
             emi = 0;
+            emiReady = false;
             return thisEmi;
         }
     };
diff -r d25827665112 -r b2c7e56572a4 src/cpu/o3/fetch_impl.hh
--- a/src/cpu/o3/fetch_impl.hh  Tue Jan 18 16:30:05 2011 -0600
+++ b/src/cpu/o3/fetch_impl.hh  Tue Jan 18 16:30:05 2011 -0600
@@ -384,7 +384,7 @@
 {
     ThreadID tid = pkt->req->threadId();
 
-    DPRINTF(Fetch, "[tid:%u] Waking up from cache miss.\n",tid);
+    DPRINTF(Fetch, "[tid:%u] Waking up from cache miss.\n", tid);
 
     assert(!pkt->wasNacked());
 
@@ -1011,7 +1011,7 @@
     instruction->setThreadState(cpu->thread[tid]);
 
     DPRINTF(Fetch, "[tid:%i]: Instruction PC %#x (%d) created "
-            "[sn:%lli]\n", tid, thisPC.instAddr(),
+            "[sn:%lli].\n", tid, thisPC.instAddr(),
             thisPC.microPC(), seq);
 
     DPRINTF(Fetch, "[tid:%i]: Instruction is: %s\n", tid,
@@ -1180,7 +1180,6 @@
                     ExtMachInst extMachInst;
 
                     extMachInst = predecoder.getExtMachInst(thisPC);
-                    pcOffset = 0;
                     staticInst = StaticInstPtr(extMachInst,
                                                thisPC.instAddr());
 
@@ -1188,7 +1187,12 @@
                     ++fetchedInsts;
 
                     if (staticInst->isMacroop())
+                    {
                         curMacroop = staticInst;
+                    }
+                    else {
+                        pcOffset = 0;
+                    }
                 } else {
                     // We need more bytes for this instruction.
                     break;
@@ -1196,8 +1200,10 @@
             }
             if (curMacroop) {
                 staticInst = curMacroop->fetchMicroop(thisPC.microPC());
-                if (staticInst->isLastMicroop())
+                if (staticInst->isLastMicroop()) {
                     curMacroop = NULL;
+                    pcOffset = 0;
+                }
             }
 
             DynInstPtr instruction =
_______________________________________________
m5-dev mailing list
m5-dev@m5sim.org
http://m5sim.org/mailman/listinfo/m5-dev

Reply via email to