//************************************************************************** bool iwindow_t::isInWindow( uint32 testNum ) { bool result; result = rangeOverlap( m_last_retired, m_last_decoded, testNum ); return ( result ); }
vector< vector<track_entry> > AnnotationDisplay::calculateTrackLayout(const vector<track_entry>& annotationFile) { max_width = 1; int line_start = ui->getStart(glWidget); int width = ui->getWidth(); int line_stop = line_start + width; int temp_display_size = current_display_size(); int nextInactiveAnnotation = 0; if(annotationFile.empty()) return vector< vector<track_entry> >(); /** activeEntries is the list annotations that are on the current display line this is a dynamically changing group with annotations coming in and out based on their start and stop positions.*/ vector<vector<track_entry> > layout; vector<track_entry> activeEntries = vector<track_entry>(); track_entry blank = track_entry(0,0, color(0,0,0)); activeEntries.push_back(blank); for(int row = 0; row < temp_display_size / width; row++)//for each line on the screen { //check to see if any of the tracks already in activeEntries stop on this line for(int k = 0; k < (int)activeEntries.size(); ++k) { if( !activeEntries[k].isBlank() ) { if( activeEntries[k].stop < line_start ) { if( activeEntries[k].col == color(200,200,200) ) activeEntries[k] = blank;//remove the entry else activeEntries[k].col = color(200,200,200); } } } //check to match start for a new track while(nextInactiveAnnotation < (int)annotationFile.size() && annotationFile[nextInactiveAnnotation].stop < line_start)//assumes tracks are in order nextInactiveAnnotation++; //keep adding annotations that start on this line while(nextInactiveAnnotation < (int)annotationFile.size() && rangeOverlap(annotationFile[nextInactiveAnnotation].start, annotationFile[nextInactiveAnnotation].stop, line_start, line_stop)) { stackEntry(activeEntries, annotationFile[nextInactiveAnnotation++]); //place new tracks in proper position } line_start += width; line_stop += width; if( (int)activeEntries.size()*2 > max_width) max_width = activeEntries.size()*2; layout.push_back(activeEntries); } return layout; }
//************************************************************************** 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 }