I went back and checked this out, and this was actually fine. I would
have still liked to have determined that before it went in, but the
problem I had with it was misguided. Good work ARM folks, and sorry for
the hassle.

Gabe

On 01/18/11 15:08, Gabe Black wrote:
> I'm pretty sure I mentioned twice that this is likely not the right way
> to do this. The ARM predecoder should consume the bytes it has, not
> ensure through special behavior in fetch that what it needs will always
> be there. I haven't tried it yet, but I remember having concerns that
> this would break x86 as well. On top of that, there are style problems.
>
> Gabe
>
> Matt Horsnell wrote:
>> 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
>>   
> _______________________________________________
> m5-dev mailing list
> m5-dev@m5sim.org
> http://m5sim.org/mailman/listinfo/m5-dev

_______________________________________________
m5-dev mailing list
m5-dev@m5sim.org
http://m5sim.org/mailman/listinfo/m5-dev

Reply via email to