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
DInst *LSQFull::executing(DInst *dinst)
  /* dinst got executed (out-of-order) {{{1 */
{
  I(dinst->getAddr());

  AddrType tag = calcWord(dinst);

  const Instruction *inst = dinst->getInst();
  DInst *faulty = 0;

#if 0
  AddrDInstQMap::const_iterator instIt = instMap.begin();
  I(instIt != instMap.end());

  I(!dinst->isExecuted());

  while(instIt != instMap.end()) {
    if (instIt->first != tag){
      instIt++;
      continue; 
    }
#endif
  std::pair<AddrDInstQMap::iterator, AddrDInstQMap::iterator> ret;
  ret = instMap.equal_range(tag);
  for (AddrDInstQMap::iterator instIt=ret.first; instIt!=ret.second; ++instIt) {
    I(instIt->first == tag);

    //inst->dump("Executed");
    DInst *qdinst = instIt->second;
    if(qdinst == dinst) {
      continue;
    }

    const Instruction *qinst  = qdinst->getInst();

    //bool beforeInst = qdinst->getID() < dinst->getID();
    bool oooExecuted = qdinst->getID() > dinst->getID();
    if(oooExecuted){

      if(qdinst->isExecuted() && qdinst->getPC() != dinst->getPC()) { 

        if(inst->isStore() && qinst->isLoad()) { 
          if (faulty == 0)
            faulty = qdinst; 
          else if (faulty->getID() < qdinst->getID())
            faulty = qdinst;
        }
      }
    }else{
      if (!dinst->isLoadForwarded() && inst->isLoad() && qinst->isStore() && qdinst->isExecuted()) {
        dinst->setLoadForwarded();
        stldForwarding.inc(dinst->getStatsFlag());
      }
    }
  }

  I(!dinst->isExecuted()); // first clear, then mark executed
  return faulty;
}
/* }}} */

void LSQFull::remove(DInst *dinst)
  /* Remove from the LSQ {{{1 (in-order) */
{
  I(dinst->getAddr());

 //const Instruction *inst = dinst->getInst();

  std::pair<AddrDInstQMap::iterator,AddrDInstQMap::iterator> rangeIt;
  //rangeIt = instMap.equal_range(calcWord(dinst));  
  AddrDInstQMap::iterator instIt = instMap.begin();

  //for(AddrDInstQMap::iterator it = rangeIt.first; it != rangeIt.second ; it++) {
  while(instIt != instMap.end()){
    if(instIt->second == dinst) {
      instMap.erase(instIt);
      return;
    }
    instIt++;
  }
}