Esempio n. 1
0
File: jbuf.c Progetto: soramimi/qSIP
/**
 * Flush all frames in the jitter buffer
 *
 * @param jb   Jitter buffer
 */
void jbuf_flush(struct jbuf *jb)
{
	struct le *le;

	if (!jb)
		return;

	if (jb->framel.head) {
		DEBUG_INFO("flush: %u frames\n", jb->n);
	}

	/* put all buffered frames back in free list */
	for (le = jb->framel.head; le; le = jb->framel.head) {
		DEBUG_INFO(" flush frame: seq=%u\n",
			   ((struct frame *)(le->data))->hdr.seq);

		frame_deref(jb, le->data);
	}

	jb->n       = 0;
	jb->running = false;

	STAT_INC(n_flush);
}
Esempio n. 2
0
//**************************************************************************
void iwindow_t::squash( pseq_t* the_pseq, int32 last_good, int32 &num_decoded)
{
  #ifdef DEBUG_IWIN
      DEBUG_OUT("iwindow_t:squash lastgood[%d] num_decoded[%d]\n",last_good,num_decoded);
  #endif
  // window index in the m_window
  uint32      windex;

  // check that last good is between the last_retired && the last_fetched
  if ( !rangeOverlap( m_last_retired, m_last_fetched, last_good ) ) {
    DEBUG_OUT( "squash: warning: last_good = %d. last_fetched = %d. last_retired = %d. [%0llx]\n",
               last_good, m_last_fetched, m_last_retired,
               the_pseq->getLocalCycle() );
  }

    #ifdef DEBUG_IWIN
      DEBUG_OUT("\tafter calling rangeOverlap\n",last_good,num_decoded);
  #endif
  if ( ( iwin_increment(last_good) == m_last_retired ) &&
       m_window[last_good] == NULL ) {   
    DEBUG_OUT( "squash: warning: last_good = %d. last_retired = %d. [%0llx]\n",
               last_good, m_last_retired, the_pseq->getLocalCycle() );
  }

  #ifdef DEBUG_IWIN
      DEBUG_OUT("\tbegin setting stage_squash \n",last_good,num_decoded);
  #endif
  uint32 stage_squash[dynamic_inst_t::MAX_INST_STAGE];
  for (uint32 i = 0; i < dynamic_inst_t::MAX_INST_STAGE; i++) {
    stage_squash[i] = 0;
  }
  windex = m_last_fetched;
  // squash all the fetched instructions (in reverse order)
  while (windex != m_last_decoded) {

    if (m_window[windex]) {
      // FetchSquash double checks this is OK to squash
      stage_squash[m_window[windex]->getStage()]++;
      #ifdef DEBUG_IWIN
          DEBUG_OUT("\tbefore calling FetchSquash\n",last_good,num_decoded);
       #endif
      m_window[windex]->FetchSquash();
        #ifdef DEBUG_IWIN
              DEBUG_OUT("\tafter calling FetchSquash\n",last_good,num_decoded);
       #endif
      delete m_window[windex];
        #ifdef DEBUG_IWIN
             DEBUG_OUT("\tsetting m_window[windex]=NULL\n",last_good,num_decoded);
        #endif
      m_window[windex] = NULL;
    } else {
      ERROR_OUT("error: iwindow: fetchsquash(): index %d is NULL\n", windex);
      SIM_HALT;
    }
    windex = iwin_decrement(windex);
  }

  // we squash instructions in the opposite order they were fetched,
  // the process of squashing restores the decode register map.
  windex = m_last_decoded;
  // squash all the decoded instructions (in reverse order)
  while (windex != (uint32) last_good) {
    
    // squash modifies the decode map to restore the original mapping
    if (m_window[windex]) {
      // if last_good is last_retired, windex may point to NULL entry
      stage_squash[m_window[windex]->getStage()]++;
        #ifdef DEBUG_IWIN
            DEBUG_OUT("\tbefore calling Squash\n",last_good,num_decoded);
        #endif
            assert(m_window[windex] != NULL);
          
      m_window[windex]->Squash();

        #ifdef DEBUG_IWIN
            DEBUG_OUT("\tafter calling Squash\n",last_good,num_decoded);
       #endif
      delete m_window[windex];
        #ifdef DEBUG_IWIN
           DEBUG_OUT("\tsetting m_window[windex]=NULL\n",last_good,num_decoded);
         #endif
      m_window[windex] = NULL;
    } else {
      ERROR_OUT("error: iwindow: squash(): index %d is NULL\n", windex);
      SIM_HALT;
    }
    windex = iwin_decrement(windex);
  }
  
  // assess stage-based statistics on what was squashed
  for (uint32 i = 0; i < dynamic_inst_t::MAX_INST_STAGE; i++) {
    if (stage_squash[i] >= (uint32) IWINDOW_ROB_SIZE) {
      ERROR_OUT("lots of instructions (%d) squashed from stage: %s\n",
                stage_squash[i],
                dynamic_inst_t::printStage( (dynamic_inst_t::stage_t) i ));
      stage_squash[i] = IWINDOW_ROB_SIZE - 1;
    }
    STAT_INC( the_pseq->m_hist_squash_stage[i][stage_squash[i]] );
  }
  
  // look back through the in-flight instructions,
  // restoring the most recent "good" branch predictors state
  windex = last_good;
  while (windex != m_last_retired) {
    if (m_window[windex] == NULL) {
      ERROR_OUT("error: iwindow: inflight: index %d is NULL\n", windex);
      SIM_HALT;
    } else {
      if (m_window[windex]->getStaticInst()->getType() == DYN_CONTROL) {
        predictor_state_t good_spec_state = (static_cast<control_inst_t*> (m_window[windex]))->getPredictorState();
         #ifdef DEBUG_IWIN
               DEBUG_OUT("\tbefore calling setSpecBPS\n",last_good,num_decoded);
         #endif
               the_pseq->setSpecBPS(good_spec_state);  
          #ifdef DEBUG_IWIN
               DEBUG_OUT("\tafter calling setSpecBPS\n",last_good,num_decoded);
           #endif
        break;
      }
    }
    windex = iwin_decrement(windex);
  }
  if (windex == m_last_retired) {
    /* no inflight branch, restore from retired "architectural" state */
    #ifdef DEBUG_IWIN
      DEBUG_OUT("\tbefore calling setSpecBPS (2)\n",last_good,num_decoded);
    #endif
    the_pseq->setSpecBPS(*(the_pseq->getArchBPS()) );
    #ifdef DEBUG_IWIN
      DEBUG_OUT("\tafter calling setSpecBPS (2)\n",last_good,num_decoded);
    #endif
  }

  m_last_fetched   = last_good;
  m_last_decoded   = last_good;

  // if we squash in execute, we can flush the decode pipeline, with no trouble
  // check if logically (m_last_scheduled > last_good)
 #ifdef DEBUG_IWIN
      DEBUG_OUT("\tbefore rangeOverlap\n",last_good,num_decoded);
  #endif
  if ( rangeOverlap( m_last_retired, m_last_scheduled, last_good ) ) {

    m_last_scheduled = last_good;
    num_decoded = 0;
    ASSERT( rangeSubtract( m_last_decoded, m_last_scheduled ) <= 0 );

  } else {

   #ifdef DEBUG_IWIN
      DEBUG_OUT("\tbefore calling rangeSubtract\n",last_good,num_decoded);
  #endif
    // else, last_good instruction is in decode ... so we need to pass
    // the number of currently decoded instructions back...
    num_decoded = (uint32) rangeSubtract( m_last_decoded, m_last_scheduled );
   #ifdef DEBUG_IWIN
      DEBUG_OUT("\tafter calling rangeSubtract\n",last_good,num_decoded);
  #endif
    
  }

  if (num_decoded > 8) {
    SIM_HALT;
  }
    #ifdef DEBUG_IWIN
      DEBUG_OUT("iwindow_t::squash END\n",last_good,num_decoded);
  #endif
}
Esempio n. 3
0
//**************************************************************************
void
control_inst_t::Retire( abstract_pc_t *a )
{
  #ifdef DEBUG_DYNAMIC_RET
  DEBUG_OUT("control_inst_t:Retire BEGIN, proc[%d]\n",m_proc);
  #endif

  #ifdef DEBUG_DYNAMIC
  char buf[128];
  s->printDisassemble(buf);
  DEBUG_OUT("\tcontrol_inst_t::Retire BEGIN %s seq_num[ %lld ] cycle[ %lld ] fetchPC[ 0x%llx ] fetchNPC[ 0x%llx ] PredictedPC[ 0x%llx ] PredictedNPC[ 0x%llx ]\n", buf, seq_num, m_pseq->getLocalCycle(), m_actual.pc, m_actual.npc, m_predicted.pc, m_predicted.npc);
     for(int i=0; i < SI_MAX_DEST; ++i){
       reg_id_t & dest = getDestReg(i);
       reg_id_t & tofree = getToFreeReg(i);
       if( !dest.isZero() ){
         DEBUG_OUT("\tDest[ %d ] Vanilla[ %d ] Physical[ %d ] Arf[ %s ] ToFree: Vanilla[ %d ] physical[ %d ] Arf[ %s ]\n", i, dest.getVanilla(), dest.getPhysical(), dest.rid_type_menomic( dest.getRtype() ), tofree.getVanilla(), tofree.getPhysical(), tofree.rid_type_menomic( tofree.getRtype() ) );
       }
     }
  #endif

  ASSERT( !getEvent( EVENT_FINALIZED ) );
  STAT_INC( m_pseq->m_stat_control_retired[m_proc] );
  
  // Need this bc we place fetch barrier on retry instead of stxa:
  if ( (s->getOpcode() == i_retry) || (s->getFlag( SI_FETCH_BARRIER)) ) {
    // if we have a branch misprediction, we already unstalled the fetch in partialSquash():
    if(getEvent(EVENT_BRANCH_MISPREDICT) == false){
      m_pseq->unstallFetch(m_proc);   
    }
  }

  STAT_INC( m_pseq->m_branch_seen_stat[s->getBranchType()][2] );
  STAT_INC( m_pseq->m_branch_seen_stat[s->getBranchType()][m_priv? 1:0] );

  // record when execution takes place
  m_event_times[EVENT_TIME_RETIRE] = m_pseq->getLocalCycle() - m_fetch_cycle;
  
  // update dynamic branch prediction (predicated) instruction statistics
  static_inst_t *s_instr = getStaticInst();
  if (s_instr->getType() == DYN_CONTROL) {
    uint32 inst;
    int    op2;
    int    pred;
    switch (s_instr->getBranchType()) {
    case BRANCH_COND:
      // conditional branch
      STAT_INC( m_pseq->m_nonpred_retire_count_stat[m_proc] );
      break;
      
    case BRANCH_PCOND:
      // predictated conditional
      inst = s_instr->getInst();
      op2  = maskBits32( inst, 22, 24 );
      pred = maskBits32( inst, 19, 19 );
      if ( op2 == 3 ) {
        // integer register w/ predication
        STAT_INC( m_pseq->m_pred_reg_retire_count_stat[m_proc] );
        if (pred) {
          STAT_INC( m_pseq->m_pred_reg_retire_taken_stat[m_proc] );
        } else {
          STAT_INC( m_pseq->m_pred_reg_retire_nottaken_stat[m_proc] );
        }
      } else {
        STAT_INC( m_pseq->m_pred_retire_count_stat[m_proc] );
        if (pred) {
          STAT_INC( m_pseq->m_pred_retire_count_taken_stat[m_proc] );
        } else {
          STAT_INC( m_pseq->m_pred_retire_count_nottaken_stat[m_proc] );
        }
      }
      if (pred == true && m_isTaken == false ||
          pred == false && m_isTaken == true) {
        STAT_INC( m_pseq->m_branch_wrong_static_stat );
      }
      break;
      
    default:
      ;      // ignore non-predictated branches
    }
  }

#ifdef DEBUG_RETIRE
  m_pseq->out_info("## Control Retire Stage\n");
  printDetail();
  m_pseq->printPC( &m_actual );
#endif


  bool mispredict = (m_events & EVENT_BRANCH_MISPREDICT);
  if (mispredict) {

    // incorrect branch prediction
    STAT_INC( m_pseq->m_branch_wrong_stat[s->getBranchType()][2] );
    STAT_INC( m_pseq->m_branch_wrong_stat[s->getBranchType()][m_priv? 1:0] );

    //train BRANCH_PRIV predictor
    if( (s->getBranchType() == BRANCH_PRIV) ){
      if (m_predicted.cwp != m_actual.cwp) {
        m_pseq->getRegstatePred()->update(getVPC(), CONTROL_CWP, m_actual.cwp, m_predicted.cwp);
      }
      if (m_predicted.tl != m_actual.tl) {
        m_pseq->getRegstatePred()->update(getVPC(), CONTROL_TL, m_actual.tl, m_predicted.tl);
      }
      if (m_predicted.pstate != m_actual.pstate) {
        m_pseq->getRegstatePred()->update(getVPC(), CONTROL_PSTATE, m_actual.pstate, m_predicted.pstate);
      }
    }

    //****************************** print out mispredicted inst *****************
    if(s->getBranchType() == BRANCH_PRIV){
      char buf[128];
      s->printDisassemble( buf );
      bool imm = s->getFlag(SI_ISIMMEDIATE); 
      #if 0
        if(m_predicted.pc != m_actual.pc){
          m_pseq->out_info("CONTROLOP: PC mispredict: predicted[ 0x%llx ] actual[ 0x%llx ] type=%s seqnum[ %lld ]  VPC[ 0x%llx ] PC[ 0x%llx ] fetched[ %lld ] executed[ %lld ] correctPC[ 0x%llx ] imm[ %d ] %s\n",
                           m_predicted.pc, m_actual.pc, pstate_t::branch_type_menomic[s->getBranchType()], seq_num, getVPC(), getPC(), m_fetch_cycle, m_event_times[EVENT_TIME_EXECUTE] + m_fetch_cycle, m_actual.pc, imm, buf);
        }
      #endif
      #if 0
        if(m_predicted.npc != m_actual.npc){
          m_pseq->out_info("CONTROLOP: NPC mispredict: predicted[ 0x%llx ] actual[ 0x%llx ] type=%s seqnum[ %lld ]  VPC[ 0x%llx ] PC[ 0x%llx ] fetched[ %lld ] executed[ %lld ] correctPC[ 0x%llx ] imm[ %d ] %s\n",
                           m_predicted.npc, m_actual.npc, pstate_t::branch_type_menomic[s->getBranchType()], seq_num, getVPC(), getPC(), m_fetch_cycle, m_event_times[EVENT_TIME_EXECUTE] + m_fetch_cycle, m_actual.pc, imm, buf);
        }
      #endif
      #if 0
        if (m_predicted.cwp != m_actual.cwp) {
          m_pseq->out_info("CONTROLOP: CWP mispredict: predicted[ %d ] actual[ %d ] type=%s seqnum[ %lld ]  VPC[ 0x%llx ] PC[ 0x%llx ] fetched[ %lld ] executed[ %lld ] correctPC[ 0x%llx ] imm[ %d ] %s\n",
                           m_predicted.cwp, m_actual.cwp, pstate_t::branch_type_menomic[s->getBranchType()], seq_num, getVPC(), getPC(), m_fetch_cycle, m_event_times[EVENT_TIME_EXECUTE] + m_fetch_cycle, m_actual.pc, imm, buf);
        }
      #endif
      #if 0
        if (m_predicted.tl != m_actual.tl) {
          m_pseq->out_info("CONTROLOP: TL mispredict: predicted[ %d ] actual[ %d ] type=%s seqnum[ %lld ] VPC[ 0x%llx ] PC[ 0x%llx ] fetched[ %lld ] executed[ %lld ] correctPC[ 0x%llx ] imm[ %d ] %s\n",
                           m_predicted.tl, m_actual.tl, pstate_t::branch_type_menomic[s->getBranchType()], seq_num, getVPC(), getPC(), m_fetch_cycle, m_event_times[EVENT_TIME_EXECUTE] + m_fetch_cycle, m_actual.pc, imm, buf);
        }
      #endif
      #if 0
        if (m_predicted.pstate != m_actual.pstate) {
          m_pseq->out_info("CONTROLOP: PSTATE mispredict: predicted[ 0x%0x ] actual[ 0x%0x ] type=%s seqnum[ %lld ] VPC[ 0x%llx ] PC[ 0x%llx ] fetched[ %lld ] executed[ %lld ] correctPC[ 0x%llx ] imm[ %d ] %s\n",
                           m_predicted.pstate, m_actual.pstate, pstate_t::branch_type_menomic[s->getBranchType()], seq_num, getVPC(), getPC(), m_fetch_cycle,  m_event_times[EVENT_TIME_EXECUTE] + m_fetch_cycle, m_actual.pc, imm, buf);
        }
      #endif
    }
    //**************************************************************************

    // train ras's exception table
    if (ras_t::EXCEPTION_TABLE && s->getBranchType() == BRANCH_RETURN) {
      my_addr_t tos;
      ras_t *ras = m_pseq->getRAS(m_proc);    
      ras->getTop(&(m_pred_state.ras_state), &tos);
      if(tos == m_actual.npc) {
        ras->markException(m_predicted.npc);
        // update RAS state
        ras->pop(&(m_pred_state.ras_state));
        m_pseq->setSpecBPS(m_pred_state);
        if (ras_t::DEBUG_RAS) m_pseq->out_info("*********** DEBUG_RAS ***********\n");
      } else {
        ras->unmarkException(m_actual.npc);
      }
    }

    // XU DEBUG
    if (0 && s->getBranchType() == BRANCH_RETURN) {
      m_pseq->out_info("**** %c:mispred 0x%llx, pred 0x%llx target 0x%llx, "
                       "next %d TOS %d\n", m_priv? 'K':'U', getVPC(),
                       m_predicted.npc, m_actual.npc,
                       m_pred_state.ras_state.next_free,
                       m_pred_state.ras_state.TOS);

      // print 5 instr after mis-pred
      generic_address_t addr = m_predicted.npc-8;
      for(uint32 i = 0; i < 5; i++, addr+=4) {
        //get the actual seq number for the pointer to m_state:
        int32 seq_num = m_pseq->getID() / CONFIG_LOGICAL_PER_PHY_PROC;
        assert(seq_num >= 0 && seq_num < system_t::inst->m_numSMTProcs);
             
        tuple_int_string_t *disassemble = SIM_disassemble((processor_t *) system_t::inst->m_state[seq_num]->getSimicsProcessor(m_proc), addr, /* logical */ 1);
        if (disassemble) m_pseq->out_info("     %s\n", disassemble->string);
      }
    }
  } else {
    // correct or no prediction
    STAT_INC( m_pseq->m_branch_right_stat[s->getBranchType()][2] );
    STAT_INC( m_pseq->m_branch_right_stat[s->getBranchType()][m_priv? 1:0] );
  }

  /* update branch predictor tables at retirement */
  if (s->getBranchType() == BRANCH_COND ||
      s->getBranchType() == BRANCH_PCOND) {
    m_pseq->getDirectBP()->Update(getVPC(),
                                  (m_pseq->getArchBPS()->cond_state),
                                  s->getFlag( SI_STATICPRED ),
                                  m_isTaken, m_proc);

  } else if (s->getBranchType() == BRANCH_INDIRECT ||
             (s->getBranchType() == BRANCH_CALL && s->getOpcode() != i_call) ) {
    // m_actual.npc is the indirect target
    m_pseq->getIndirectBP()->Update( getVPC(),
                                     &(m_pseq->getArchBPS()->indirect_state),
                                     m_actual.npc, m_proc );
  }

  m_pseq->setArchBPS(m_pred_state);
  
  // no need to update call&return, since we used checkpointed RAS
  // no update on traps right now
  SetStage(RETIRE_STAGE);

  /* retire any register overwritten by link register */
  retireRegisters(); 

  #if 0
  if(m_actual.pc == (my_addr_t) -1){
    char buf[128];
    s->printDisassemble(buf);
    ERROR_OUT("\tcontrol_inst_t::Retire %s seq_num[ %lld ] cycle[ %lld ] fetchPC[ 0x%llx ] fetchNPC[ 0x%llx ] fetched[ %lld ] executed[ %lld ]\n", buf, seq_num, m_pseq->getLocalCycle(), m_actual.pc, m_actual.npc, m_fetch_cycle, m_fetch_cycle+getEventTime(EVENT_TIME_EXECUTE_DONE));
    //print out writer cycle
    for(int i=0; i < SI_MAX_SOURCE; ++i){
      reg_id_t & source = getSourceReg(i);
      if(!source.isZero()){
        uint64 written_cycle = source.getARF()->getWrittenCycle( source, m_proc );
        uint64 writer_seqnum = source.getARF()->getWriterSeqnum( source, m_proc );
        ERROR_OUT("\tSource[ %d ] Vanilla[ %d ] Physical[ %d ] Arf[ %s ] written_cycle[ %lld ] writer_seqnum[ %lld ]\n", i, source.getVanilla(), source.getPhysical(), source.rid_type_menomic( source.getRtype() ), written_cycle, writer_seqnum);
      }
    }
  }
  #endif

  ASSERT( m_actual.pc != (my_addr_t) -1 );

  /* return pc, npc pair which are the results of execution */
  a->pc  = m_actual.pc;
  a->npc = m_actual.npc;
 
  markEvent( EVENT_FINALIZED );

  #ifdef DEBUG_DYNAMIC_RET
     DEBUG_OUT("control_inst_t:Retire END, proc[%d]\n",m_proc);
  #endif
}
Esempio n. 4
0
File: jbuf.c Progetto: soramimi/qSIP
/**
 * Put one frame into the jitter buffer
 *
 * @param jb   Jitter buffer
 * @param hdr  RTP Header
 * @param mem  Memory pointer - will be referenced
 *
 * @return 0 if success, otherwise errorcode
 */
int jbuf_put(struct jbuf *jb, const struct rtp_header *hdr, void *mem)
{
	struct frame *f;
	struct le *le, *tail;
	uint16_t seq;
	int err = 0;

	if (!jb || !hdr)
		return EINVAL;

	seq = hdr->seq;

	STAT_INC(n_put);

	if (jb->running) {

		/* Packet arrived too late to be put into buffer */
		if (seq_less((seq + jb->n), jb->seq_put)) {
			STAT_INC(n_late);
			DEBUG_INFO("packet too late: seq=%u (seq_put=%u)\n",
				   seq, jb->seq_put);
			return ETIMEDOUT;
		}
	}

	frame_alloc(jb, &f);

	tail = jb->framel.tail;

	/* If buffer is empty -> append to tail
	   Frame is later than tail -> append to tail
	*/
	if (!tail || seq_less(((struct frame *)tail->data)->hdr.seq, seq)) {
		list_append(&jb->framel, &f->le, f);
		goto out;
	}

	/* Out-of-sequence, find right position */
	for (le = tail; le; le = le->prev) {
		const uint16_t seq_le = ((struct frame *)le->data)->hdr.seq;

		if (seq_less(seq_le, seq)) { /* most likely */
			DEBUG_INFO("put: out-of-sequence"
				   " - inserting after seq=%u (seq=%u)\n",
				   seq_le, seq);
			list_insert_after(&jb->framel, le, &f->le, f);
			break;
		}
		else if (seq == seq_le) { /* less likely */
			/* Detect duplicates */
			DEBUG_INFO("duplicate: seq=%u\n", seq);
			STAT_INC(n_dups);
			list_insert_after(&jb->framel, le, &f->le, f);
			frame_deref(jb, f);
			return EALREADY;
		}

		/* sequence number less than current seq, continue */
	}

	/* no earlier timestamps found, put in head */
	if (!le) {
		DEBUG_INFO("put: out-of-sequence"
			   " - put in head (seq=%u)\n", seq);
		list_prepend(&jb->framel, &f->le, f);
	}

	STAT_INC(n_oos);

 out:
	/* Update last timestamp */
	jb->running = true;
	jb->seq_put = seq;

	/* Success */
	f->hdr = *hdr;
	f->mem = mem_ref(mem);

	return err;
}
Esempio n. 5
0
//**************************************************************************
void 
control_inst_t::Execute()
{
  STAT_INC( m_pseq->m_stat_control_exec[m_proc] );
  m_event_times[EVENT_TIME_EXECUTE_DONE] = m_pseq->getLocalCycle() - m_fetch_cycle;

  // call the appropriate function
  static_inst_t *si = getStaticInst();

  char buf[128];
  s->printDisassemble(buf);

  if (true) {

     #ifdef DEBUG_DYNAMIC
        char buf[128];
        s->printDisassemble(buf);
        DEBUG_OUT("[ %d ] control_inst_t: EXECUTE %s NAV[ %d ] seqnum[ %lld ] fetched[ %lld ] cycle[ %lld ]", m_pseq->getID(), buf, getInstrNAV(), seq_num, m_fetch_cycle, m_pseq->getLocalCycle());
        //print source and dest regs
        DEBUG_OUT(" SOURCES: ");
        for(int i=0; i < SI_MAX_SOURCE; ++i){
          reg_id_t & source = getSourceReg(i);
          if(!source.isZero()){
            DEBUG_OUT("( [%d] V: %d P: %d Arf: %s WriterSN: %lld WrittenCycle: %lld State: 0x%x)", i,source.getVanilla(), source.getPhysical(), source.rid_type_menomic( source.getRtype() ), source.getARF()->getWriterSeqnum( source, m_proc ), source.getARF()->getWrittenCycle( source, m_proc ), source.getVanillaState() );
          }
        }
        DEBUG_OUT(" DESTS: ");
        for(int i=0; i < SI_MAX_DEST; ++i){
          reg_id_t & dest = getDestReg(i);
          if(!dest.isZero()){
            DEBUG_OUT("( [%d] V: %d P: %d Arf: %s )", i,dest.getVanilla(), dest.getPhysical(), dest.rid_type_menomic( dest.getRtype() ));
          }
        }
        DEBUG_OUT("\n");
     #endif

    // execute the instruction using the jump table
    pmf_dynamicExecute pmf = m_jump_table[si->getOpcode()];
    (this->*pmf)();

     // Due to functional bugs sometimes m_actual.pc will be -1
     //ASSERT( m_actual.pc != (my_addr_t) -1 );

  } else {
    // NOT executed!
    dp_control_t dp_value;
    dp_value.m_at      = &m_actual;
    dp_value.m_taken   = false;
    dp_value.m_annul   = si->getAnnul();
    dp_value.m_offset  = si->getOffset();

    // do the operation
    exec_fn_execute( (i_opcode) si->getOpcode(), (dp_int_t *) &dp_value );
    
    // write result back to this dynamic instruction
    m_isTaken = dp_value.m_taken;
  }

  SetStage(COMPLETE_STAGE);

  #ifdef DEBUG_DYNAMIC
     char buf[128];
     s->printDisassemble(buf);
     DEBUG_OUT("control_inst_t: AFTER Execute %s NAV[ %d ] seqnum[ %lld ] fetched[ %lld ] cycle[ %lld ] PredPC[ 0x%llx ] ActualPC[ 0x%llx ] PredNPC[ 0x%llx ] ActualNPC[ 0x%llx ] PredCWP[ 0x%x ] ActualCWP[ 0x%x ] PredTL[ 0x%x ] ActualTL[ 0x%x ] PredPstate[ 0x%x ] ActualPstate[ 0x%x ]\n", buf, getInstrNAV(), seq_num, m_fetch_cycle, m_pseq->getLocalCycle(), m_predicted.pc, m_actual.pc, m_predicted.npc, m_actual.npc, m_predicted.cwp, m_actual.cwp, m_predicted.tl, m_actual.tl, m_predicted.pstate, m_actual.pstate);
  #endif

      
  // All control op should be checked, all of them can mis-predict
  // if the predicted PC, nPC pairs don't match with actual, cause exeception
  if ( (m_predicted.pc     != m_actual.pc ||
        m_predicted.npc    != m_actual.npc ||
        m_predicted.cwp    != m_actual.cwp ||
        m_predicted.tl     != m_actual.tl ||
        m_predicted.pstate != m_actual.pstate) ) {
    /* There was a branch mis-prediction --
     *    patch up branch predictor state */

     #ifdef DEBUG_DYNAMIC
         char buf[128];
         s->printDisassemble(buf);
         DEBUG_OUT("[ %d ] control_inst_t: MISPREDICT %s NAV[ %d ] seqnum[ %lld ] fetched[ %lld ] cycle[ %lld ] PredPC[ 0x%llx ] ActualPC[ 0x%llx ] PredNPC[ 0x%llx ] ActualNPC[ 0x%llx ] PredCWP[ 0x%x ] ActualCWP[ 0x%x ] PredTL[ 0x%x ] ActualTL[ 0x%x ] PredPstate[ 0x%x ] ActualPstate[ 0x%x ]\n", m_pseq->getID(), buf, getInstrNAV(), seq_num, m_fetch_cycle, m_pseq->getLocalCycle(), m_predicted.pc, m_actual.pc, m_predicted.npc, m_actual.npc, m_predicted.cwp, m_actual.cwp, m_predicted.tl, m_actual.tl, m_predicted.pstate, m_actual.pstate);
     #endif

    // This preformatted debugging information is left for your convenience
    // NOT very useful here, bc this might indicate a misprediction AFTER another misprediction
    // print this out inside Retire()!
    /*
    char buf[128];
    s->printDisassemble( buf );
      if (m_predicted.cwp != m_actual.cwp) {
      m_pseq->out_info("CONTROLOP: CWP mispredict: predicted[ %d ] actual[ %d ] type=%s seqnum[ %lld ]  VPC[ 0x%llx ] PC[ 0x%llx ] fetched[ %lld ] executed[ %lld ] correctPC[ 0x%llx ] %s\n",
      m_predicted.cwp, m_actual.cwp, pstate_t::branch_type_menomic[s->getBranchType()], seq_num, getVPC(), getPC(), m_fetch_cycle, m_event_times[EVENT_TIME_EXECUTE] + m_fetch_cycle, m_actual.pc, buf);
      }
      if (m_predicted.tl != m_actual.tl) {
      m_pseq->out_info("CONTROLOP: TL mispredict: predicted[ %d ] actual[ %d ] type=%s seqnum[ %lld ] VPC[ 0x%llx ] PC[ 0x%llx ] fetched[ %lld ] executed[ %lld ] correctPC[ 0x%llx ] %s\n",
      m_predicted.tl, m_actual.tl, pstate_t::branch_type_menomic[s->getBranchType()], seq_num, getVPC(), getPC(), m_fetch_cycle, m_event_times[EVENT_TIME_EXECUTE] + m_fetch_cycle, m_actual.pc, buf);
      }
      if (m_predicted.pstate != m_actual.pstate) {
      m_pseq->out_info("CONTROLOP: PSTATE mispredict: predicted[ 0x%0x ] actual[ 0x%0x ] type=%s seqnum[ %lld ] VPC[ 0x%llx ] PC[ 0x%llx ] fetched[ %lld ] executed[ %lld ] correctPC[ 0x%llx ] %s\n",
      m_predicted.pstate, m_actual.pstate, pstate_t::branch_type_menomic[s->getBranchType()], seq_num, getVPC(), getPC(), m_fetch_cycle,  m_event_times[EVENT_TIME_EXECUTE] + m_fetch_cycle, m_actual.pc, buf);
      }
    
    */

    markEvent(EVENT_BRANCH_MISPREDICT);
    if (s->getBranchType()      == BRANCH_COND ||
        s->getBranchType()      == BRANCH_PCOND ) {
      // flip the last bit of the history to correct the misprediction
      m_pred_state.cond_state = m_pred_state.cond_state ^ 1;
        
    } else if (s->getBranchType() == BRANCH_INDIRECT ||
               (s->getBranchType() == BRANCH_CALL && s->getOpcode() != i_call) ) {
      /*
        m_pseq->out_info(" INDIRECT:  predicted 0x%0llx, 0x%0llx\n",
        m_predicted.pc, m_predicted.npc);
        m_pseq->out_info(" INDIRECT:  actual    0x%0llx, 0x%0llx\n",
        m_actual.pc, m_actual.npc);
      */
      m_pseq->getIndirectBP()->FixupState(&(m_pred_state.indirect_state), 
                                          getVPC());
    }
    // no predictor fixup on PRIV, TRAP or TRAP_RETURN right now
    
    // TASK: should update the BTB here
    
    // TASK: determine the fetch location (and state)
    
    m_actual.gset = pstate_t::getGlobalSet( m_actual.pstate );
    
    /* cause a branch misprediction exception */
    m_pseq->raiseException(EXCEPT_MISPREDICT, getWindowIndex(),
                           (enum i_opcode) s->getOpcode(),
                           &m_actual, 0, BRANCHPRED_MISPRED_PENALTY, m_proc );
  }
}