Ejemplo n.º 1
0
void FetchEngine::realfetch(IBucket *bucket, EmulInterface *eint, FlowID fid, int32_t n2Fetch, uint16_t maxbb) {

  uint16_t tempmaxbb = maxbb; // FIXME: delete me

  AddrType lastpc = 0;
  bool     lastdiff = false;

#ifdef USE_FUSE
  RegType  last_dest = LREG_R0;
  RegType  last_src1 = LREG_R0;
  RegType  last_src2 = LREG_R0;
#endif

  do {
    DInst *dinst = 0;
    dinst = eint->executeHead(fid);
    if (dinst == 0) {
      //if (fid)
      //I(0);
      break;
    }

#ifdef USE_FUSE
    if (/*!dinst->getStatsFlag() && */dinst->getPC() == 0) {
      if (dinst->getInst()->isLoad()) {
        MemRequest::sendReqReadWarmup(gms->getDL1(), dinst->getAddr());
        dinst->scrap(eint);
        dinst = 0;
      } else if (dinst->getInst()->isStore()) {
        MemRequest::sendReqWriteWarmup(gms->getDL1(), dinst->getAddr());
        dinst->scrap(eint);
        dinst = 0;
      }
    }
    if (dinst == 0) { // Drain cache (mostly) during warmup. FIXME: add a drain cache method?
      EventScheduler::advanceClock();
      EventScheduler::advanceClock();
      EventScheduler::advanceClock();
      EventScheduler::advanceClock();
      EventScheduler::advanceClock();
      EventScheduler::advanceClock();
      continue;
    }
#endif
    if (lastpc == 0) {
      if (AlignedFetch) {
        n2Fetch -= ((dinst->getPC())>>FetchWidthBits) & (FetchWidth-1);
      }
      n2Fetch--;
      lastdiff = false;
    }else{
      if ((lastpc+4) != dinst->getPC()) {
        //        n2Fetch -= (dinst->getPC()-lastpc)>>2;
        n2Fetch--;
        if (lastdiff) {
          n2Fetch--; // Missed NOP
        }
        lastdiff = true;
      }else{
        n2Fetch--;
        lastdiff = false;
      }
    }
    lastpc  = dinst->getPC();




    I(!missInst);

    dinst->setFetchTime();
#ifdef USE_FUSE
    if(dinst->getInst()->isControl()) {
      RegType src1 = dinst->getInst()->getSrc1();
      if (dinst->getInst()->doesJump2Label() && dinst->getInst()->getSrc2() == LREG_R0 
          && (src1 == last_dest || src1 == last_src1 || src1 == last_src2 || src1 == LREG_R0) ) {
        //MSG("pc %x fusion with previous", dinst->getPC());
        dinst->scrap(eint);
        continue;
      }
    }
#endif
    bucket->push(dinst);
        
    if(dinst->getInst()->isControl()) {
      bool stall_fetch = processBranch(dinst, n2Fetch,&tempmaxbb);
      if (stall_fetch) {
        //bucket->push(dinst);
        break;
      }
      I(!missInst);
    }else{
      //bucket->push(dinst);
    }
#ifdef USE_FUSE
    last_dest = dinst->getInst()->getDst1();
    last_src1 = dinst->getInst()->getSrc1();
    last_src2 = dinst->getInst()->getSrc2();
#endif

    // Fetch uses getHead, ROB retires getTail
  } while(n2Fetch>0);
Ejemplo n.º 2
0
void DInst::killSilently()
{
  I(getPendEvent()==0);
  I(getResource()==0);

#ifdef SESC_BAAD
  if (fetch2Time == 0) {
    fetch1QSize--;
  }else if (renameTime == 0) {
    fetch2QSize--;
  }else if (issueTime == 0) {
    issueQSize--;
  }else if (schedTime == 0) {
    schedQSize--;
  }else if (exeTime == 0) {
    exeQSize--;
  }else{
    retireQSize--;
  }
#endif

  markIssued();
  markExecuted();
  if( getFetch() ) {
    getFetch()->unBlockFetch();
    IS(setFetch(0));
  }

  if (getInst()->isStore())
    LDSTBuffer::storeLocallyPerformed(this);
 
  while (hasPending()) {
    DInst *dstReady = getNextPending();

    if (!dstReady->isIssued()) {
      // Accross processor dependence
      if (dstReady->hasDepsAtRetire())
        dstReady->clearDepsAtRetire();
      
      I(!dstReady->hasDeps());
      continue;
    }
    if (dstReady->isExecuted()) {
      // The instruction got executed even though it has dependences. This is
      // because the instruction got silently killed (killSilently)
      if (!dstReady->hasDeps())
        dstReady->scrap();
      continue;
    }

    if (!dstReady->hasDeps()) {
      I(dstReady->isIssued());
      I(!dstReady->isExecuted());
      Resource *dstRes = dstReady->getResource();
      I(dstRes);
      dstRes->simTime(dstReady);
    }
  }

#ifdef TASKSCALAR
  notifyDataDepViolation(DataDepViolationAtRetire);

  if (lvid) { // maybe got killSilently
    lvid = 0;
    lvidVersion->decOutsReqs();
    lvidVersion->garbageCollect();
    IS(lvidVersion=0);
  }
  
  I(lvidVersion==0);
#endif

  I(!getFetch());

  if (hasDeps())
    return;
  
  I(nDeps == 0);   // No deps src

#if (defined TLS)
  I(!myEpoch);
#endif

  I(!getFetch());
#if (defined MIPS_EMUL)
  context->delDInst();
  context=0;
#endif
  dInstPool.in(this); 
}