00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032 #include <pch.h>
00033
00034
00035 #include "Sim/Op/Op.h"
00036 #include "Sim/Dumper/Dumper.h"
00037
00038 #include "Sim/Foundation/SimPC.h"
00039 #include "Sim/Dependency/MemDependency/MemDependency.h"
00040 #include "Sim/Register/RegisterFile.h"
00041 #include "Sim/Foundation/TimeWheel/TimeWheelBase.h"
00042 #include "Sim/Pipeline/Scheduler/Scheduler.h"
00043 #include "Sim/Memory/MemOrderManager/MemOrderManager.h"
00044 #include "Sim/Foundation/Checkpoint/CheckpointMaster.h"
00045 #include "Sim/Foundation/Hook/HookUtil.h"
00046 #include "Sim/Op/OpInitArgs.h"
00047 #include "Sim/Thread/Thread.h"
00048 #include "Sim/Core/Core.h"
00049 #include "Sim/Foundation/SimPC.h"
00050 #include "Sim/Dependency/PhyReg/PhyReg.h"
00051 #include "Sim/ExecUnit/ExecUnitIF.h"
00052
00053 using namespace std;
00054 using namespace Onikiri;
00055
00056
00057 Op::Op(OpIterator iterator) :
00058 m_opInfo (0),
00059 m_opClass (0),
00060 m_no (0),
00061 m_localTID (TID_INVALID),
00062 m_serialID (0),
00063 m_globalSerialID (0),
00064 m_retireID (0),
00065 m_thread (0),
00066 m_core (0),
00067 m_inorderList(0),
00068 m_beforeCheckpoint (0),
00069 m_afterCheckpoint (0),
00070 m_taken (false),
00071 m_latPredResult(),
00072 m_issueState (),
00073 m_scheduler (0),
00074 m_regFile (0),
00075 m_srcNum (0),
00076 m_dstNum (0),
00077 m_iterator (iterator)
00078 {
00079 }
00080
00081 Op::~Op()
00082 {
00083 }
00084
00085 void Op::Initialize(const OpInitArgs& args)
00086 {
00087 m_pc = *args.pc;
00088 m_opInfo = args.opInfo;
00089 m_opClass = &m_opInfo->GetOpClass();
00090 m_no = args.no;
00091 m_localTID = args.thread->GetLocalThreadID();
00092 m_serialID = args.serialID;
00093 m_retireID = args.retireID;
00094 m_globalSerialID = args.globalSerialID;
00095 m_core = args.core;
00096 m_thread = args.thread;
00097 m_inorderList = args.thread->GetInorderList();
00098 m_status = OpStatus();
00099 m_beforeCheckpoint = 0;
00100 m_afterCheckpoint = 0;
00101 m_takenPC = PC(args.pc->pid, args.pc->tid, args.pc->address+4);
00102 m_taken = false;
00103 m_latPredResult = LatPredResult();
00104 m_issueState = IssueState();
00105 m_reserveExecUnit = false;
00106 m_scheduler = 0;
00107
00108 m_memAccess.address = Addr();
00109 m_memAccess.size = 0;
00110 m_memAccess.sign = false;
00111 m_memAccess.value = 0;
00112
00113 m_exception = Exception();
00114 m_cacheAccessResult = CacheAccessResult();
00115
00116 m_regFile = m_core->GetRegisterFile();
00117 m_srcNum = m_opInfo->GetSrcNum();
00118 m_dstNum = m_opInfo->GetDstNum();
00119
00120 SetPID( args.pc->pid );
00121 SetTID( args.pc->tid );
00122
00123
00124
00125
00126
00127
00128 for (int i = 0; i < SimISAInfo::MAX_DST_REG_COUNT; i++) {
00129 m_dstReg[i] = UNSET_REG;
00130 m_dstPhyReg[i] = 0;
00131 m_dstResultValue[i] = 0;
00132 }
00133
00134 for (int i = 0; i < SimISAInfo::MAX_SRC_REG_COUNT; i++) {
00135 m_srcReg[i] = UNSET_REG;
00136 m_srcPhyReg[i] = 0;
00137 }
00138
00139 for (int i = 0; i < MAX_SRC_MEM_NUM; i++) {
00140 m_srcMem[i].reset();
00141 }
00142
00143 for (int i = 0; i < MAX_DST_MEM_NUM; i++) {
00144 m_dstMem[i].reset();
00145 }
00146
00147 }
00148
00149
00150 PhyReg* Op::GetPhyReg(int phyRegNo)
00151 {
00152 return m_regFile->GetPhyReg(phyRegNo);
00153 }
00154
00155 const u64 Op::GetSrc(const int index) const
00156 {
00157 ASSERT(m_srcReg[index] != UNSET_REG,
00158 "physical register not set at index %d.", index);
00159
00160 return m_srcPhyReg[index]->GetVal();
00161 }
00162
00163 const u64 Op::GetDst(const int index) const
00164 {
00165 ASSERT(m_dstReg[index] != UNSET_REG,
00166 "physical register not set at index %d.", index);
00167
00168 return m_dstPhyReg[index]->GetVal();
00169 }
00170
00171 void Op::SetDst(const int index, const u64 value)
00172 {
00173 ASSERT(m_dstReg[index] != UNSET_REG,
00174 "physical register not set at index %d.", index);
00175
00176
00177 m_dstResultValue[index] = value;
00178 }
00179
00180 void Op::SetTaken(const bool taken)
00181 {
00182 m_taken = taken;
00183 }
00184
00185 bool Op::GetTaken() const
00186 {
00187 return m_taken;
00188 }
00189
00190 void Op::SetTakenPC(const PC takenPC)
00191 {
00192 m_takenPC = takenPC;
00193 }
00194
00195 PC Op::GetTakenPC() const
00196 {
00197 return m_takenPC;
00198 }
00199
00200 PC Op::GetNextPC()
00201 {
00202 if( m_taken ) {
00203 return m_takenPC;
00204 }else {
00205 SimPC nextPC(m_pc);
00206 nextPC++;
00207 return nextPC;
00208 }
00209 }
00210
00211
00212 void Op::Read( MemAccess* access )
00213 {
00214
00215
00216 access->address.tid = GetTID();
00217 m_thread->GetMemOrderManager()->Read( m_iterator, access );
00218 }
00219
00220 void Op::Write( MemAccess* access )
00221 {
00222
00223
00224 access->address.tid = GetTID();
00225 m_thread->GetMemOrderManager()->Write( m_iterator, access );
00226 }
00227
00228
00229
00230
00231
00232 bool Op::IsSrcReady( int index, const DependencySet* newDeps ) const
00233 {
00234 ASSERT( index == m_scheduler->GetIndex() );
00235
00236 for( int i = 0; i < m_srcNum; ++i ){
00237 Dependency* dep = m_srcPhyReg[i];
00238 if( dep->GetReadiness( index ) == false ){
00239 if( newDeps ){
00240 if( !newDeps->IsIncluded( dep ) ){
00241 return false;
00242 }
00243 }
00244 else{
00245 return false;
00246 }
00247 }
00248 }
00249
00250 for(int i = 0; i < MAX_SRC_MEM_NUM; ++i) {
00251 Dependency* dep = m_srcMem[i].get();
00252 if( dep && dep->GetReadiness(index) == false) {
00253 if( newDeps ){
00254 if( !newDeps->IsIncluded( dep ) ){
00255 return false;
00256 }
00257 }
00258 else{
00259 return false;
00260 }
00261 }
00262 }
00263
00264 return true;
00265 }
00266
00267 void Op::AddEvent(
00268 const EventPtr& evnt,
00269 TimeWheelBase* timeWheel,
00270 int time,
00271 EventMask mask
00272 )
00273 {
00274 timeWheel->AddEvent( evnt, time );
00275 if( !evnt->IsUpdated() ){
00276 m_event.AddEvent( evnt, mask );
00277 }
00278 }
00279
00280 void Op::CancelEvent( EventMask mask )
00281 {
00282 m_event.Cancel( mask );
00283 }
00284
00285 void Op::ClearEvent()
00286 {
00287 m_event.Clear();
00288 }
00289
00290
00291
00292 void Op::ResetDependency()
00293 {
00294 int dstDepNum = GetDstDepNum();
00295 for( int i = 0; i < dstDepNum; ++i ){
00296 GetDstDep(i)->Reset();
00297 }
00298 }
00299
00300
00301 void Op::RescheduleSelf( bool clearIssueState )
00302 {
00303
00304 if( !IsDispatched() ) {
00305 return;
00306 }
00307
00308
00309 ResetDependency();
00310
00311
00312 CancelEvent();
00313
00314
00315 if( clearIssueState ){
00316 m_issueState = IssueState();
00317 }
00318 }
00319
00320
00321 void Op::ExecutionBegin()
00322 {
00323 m_core->GetEmulator()->Execute(this, m_opInfo);
00324 }
00325
00326 void Op::ExecutionEnd()
00327 {
00328 ASSERT( GetStatus() == OpStatus::OS_EXECUTING );
00329 WriteExecutionResults();
00330 SetStatus( OpStatus::OS_FINISHED );
00331 }
00332
00333
00334 void Op::WriteExecutionResults()
00335 {
00336
00337 for( int i = 0; i < m_dstNum; ++i ){
00338 m_dstPhyReg[i]->SetVal( m_dstResultValue[i] );
00339 }
00340 }
00341
00342 void Op::DissolveSrcReg()
00343 {
00344 if( GetStatus() == OpStatus::OS_FETCH ){
00345 return;
00346 }
00347 for( int i = 0; i < m_srcNum; ++i ) {
00348 m_srcPhyReg[i]->RemoveConsumer( m_iterator );
00349 }
00350 }
00351
00352 void Op::DissolveSrcMem()
00353 {
00354 if( GetStatus() == OpStatus::OS_FETCH ){
00355 return;
00356 }
00357 for( int i = 0; i < MAX_SRC_MEM_NUM; ++i ) {
00358 if( m_srcMem[i] != NULL ) {
00359 m_srcMem[i]->RemoveConsumer( m_iterator );
00360 }
00361 }
00362 }
00363
00364
00365
00366 OpIterator Op::GetFirstConsumer()
00367 {
00368 OpIterator result(0);
00369
00370
00371 int dstRegNum = m_dstNum;
00372 for( int i = 0; i < dstRegNum; ++i ) {
00373 if(m_dstReg[i] == UNSET_REG) continue;
00374
00375 PhyReg* phyReg = m_dstPhyReg[i];
00376 const Dependency::ConsumerListType& consumers = phyReg->GetConsumers();
00377
00378 if( consumers.empty() ) continue;
00379
00380
00381
00382 OpIterator frontOp = consumers.front();
00383 if( result.IsNull() || result->GetSerialID() > frontOp->GetSerialID() ) {
00384 result = frontOp;
00385 }
00386 }
00387
00388
00389 int dstMemNum = MAX_DST_MEM_NUM;
00390 for( int i = 0; i < dstMemNum; ++i ) {
00391 MemDependencyPtr memDependency = m_dstMem[i];
00392 if( memDependency == 0 ) continue;
00393
00394 const Dependency::ConsumerListType& consumers = memDependency->GetConsumers();
00395 if( consumers.empty() ) continue;
00396
00397
00398
00399 OpIterator frontOp = consumers.front();
00400 if( result.IsNull() || result->GetSerialID() > frontOp->GetSerialID() ) {
00401 result = frontOp;
00402 }
00403 }
00404
00405 if( m_opClass->IsStore() ){
00406 MemOrderManager* memOrder = m_thread->GetMemOrderManager();
00407 OpIterator consumer = memOrder->GetConsumerLoad( m_iterator, m_memAccess, 0 );
00408 if( !consumer.IsNull() &&
00409 ( result.IsNull() ||
00410 result->GetSerialID() > consumer->GetSerialID()
00411 )
00412 ){
00413 result = consumer;
00414 }
00415 }
00416 return result;
00417
00418 }
00419
00420
00421 void Op::SetSrcReg(int index, int phyRegNo)
00422 {
00423 m_srcReg[index] = phyRegNo;
00424 m_srcPhyReg[index] = GetPhyReg(phyRegNo);
00425 GetPhyReg(phyRegNo)->AddConsumer(m_iterator);
00426 }
00427
00428
00429 void Op::SetSrcMem(int index, MemDependencyPtr memDep)
00430 {
00431 m_srcMem[index] = memDep;
00432 memDep->AddConsumer(m_iterator);
00433 }
00434
00435
00436 void Op::SetDstReg(int index, int phyRegNo)
00437 {
00438 m_dstReg[index] = phyRegNo;
00439 PhyReg* phyReg = GetPhyReg(phyRegNo);
00440 m_dstPhyReg[index] = phyReg;
00441 }
00442
00443 void Op::SetDstMem(int index, MemDependencyPtr dstMem)
00444 {
00445 m_dstMem[index] = dstMem;
00446 }
00447
00448
00449 int Op::GetDstReg(int index)
00450 {
00451 return m_dstReg[index];
00452 }
00453
00454
00455 int Op::GetSrcReg(int index)
00456 {
00457 return m_srcReg[index];
00458 }
00459
00460 int Op::GetDstDepNum() const
00461 {
00462 int memDepNum = 0;
00463 for( int i = 0; i < MAX_DST_MEM_NUM; i++ ){
00464 if( m_dstMem[i] ){
00465 memDepNum++;
00466 }
00467 else{
00468 break;
00469 }
00470 }
00471 return m_dstNum + memDepNum;
00472 }
00473
00474 Dependency* Op::GetDstDep( int index ) const
00475 {
00476 if( index < m_dstNum ){
00477 return GetDstPhyReg( index );
00478 }
00479 else{
00480 return m_dstMem[ index - m_dstNum ].get();
00481 }
00482 }
00483
00484
00485 ExecUnitIF* Op::GetExecUnit() const
00486 {
00487 ASSERT( m_scheduler != NULL );
00488 return m_scheduler->GetExecUnit( GetOpClass().GetCode() );
00489 }
00490
00491
00492 std::string Op::ToString(int detail, bool valDetail, const char* delim)
00493 {
00494 ostringstream oss;
00495
00496
00497 oss
00498 << "GID: " << GetGlobalSerialID() << delim
00499 << "TID: " << GetTID() << delim
00500 << "SID: " << GetSerialID() << delim
00501 << "RID: " << GetRetireID() << delim
00502 << "PID: " << GetPID() << delim
00503 << "PC: " << GetPC().pid << "/"
00504 << hex << GetPC().address << dec
00505 << "[" << GetNo() <<"]" << delim;
00506
00507 if(detail == 0) return oss.str();
00508
00509
00510 oss << GetStatus().ToString() << delim;
00511
00512 if(detail == 1) return oss.str();
00513
00514 oss << GetOpInfo()->GetMnemonic() << delim;
00515 oss << GetOpClass().ToString() << delim;
00516
00517
00518 int dstNum = GetOpInfo()->GetDstNum();
00519 for(int i = 0; i < dstNum; ++i) {
00520 oss << "d" << i << ": " ;
00521 oss << GetOpInfo()->GetDstOperand(i) << delim;
00522 }
00523 for(int i = dstNum;
00524 i < SimISAInfo::MAX_DST_REG_COUNT; ++i)
00525 {
00526 oss << "d" << i << ": -1"<< delim;
00527 }
00528
00529 int srcNum = GetOpInfo()->GetSrcNum();
00530 for(int i = 0; i < srcNum; ++i) {
00531 oss << "s" << i << ": "
00532 << GetOpInfo()->GetSrcOperand(i) <<delim;
00533 }
00534 for(int i = GetOpInfo()->GetSrcNum();
00535 i < SimISAInfo::MAX_SRC_REG_COUNT; ++i)
00536 {
00537 oss << "s" << i << ": -1"<< delim;
00538 }
00539
00540 if(detail == 2) return oss.str();
00541
00542
00543 oss << "TPC: " << GetTakenPC().pid << "/"
00544 << hex << GetTakenPC().address << dec
00545 << ( GetTaken() ? "(t)" : "(n)" ) << delim;
00546
00547 if(detail == 3) return oss.str();
00548
00549 for(int i = 0; i < SimISAInfo::MAX_DST_REG_COUNT; ++i) {
00550 if( m_dstReg[i] != UNSET_REG) {
00551 oss << "r" << GetOpInfo()->GetDstOperand(i)
00552 << "= p" << GetDstReg(i);
00553 }else {
00554 oss << "r_ = p_";
00555 }
00556 oss << delim;
00557 }
00558
00559 for(int i = 0; i < SimISAInfo::MAX_SRC_REG_COUNT; ++i) {
00560 if( m_srcReg[i] != UNSET_REG ) {
00561 oss << "r" << GetOpInfo()->GetSrcOperand(i)
00562 << "= p" << GetSrcReg(i);
00563 }else {
00564 oss << "r_ = p_";
00565 }
00566 oss << delim;
00567 }
00568
00569 if(detail == 4) return oss.str();
00570
00571
00572 for(int i = 0; i < SimISAInfo::MAX_DST_REG_COUNT; ++i) {
00573 if( m_dstReg[i] != UNSET_REG) {
00574 oss << "r" << GetOpInfo()->GetDstOperand(i)
00575 << "= " << GetDst(i);
00576 if( valDetail ) {
00577 oss << "/" << (double)GetDst(i)
00578 << "/" << hex << GetDst(i) << dec;
00579 }
00580 }else {
00581 oss << "r_ = 0";
00582 }
00583 oss << delim;
00584 }
00585
00586 for(int i = 0; i < SimISAInfo::MAX_SRC_REG_COUNT; ++i) {
00587 if( m_srcReg[i] != UNSET_REG ) {
00588 oss << "r" << GetOpInfo()->GetSrcOperand(i)
00589 << "= " << GetSrc(i);
00590 if( valDetail ) {
00591 oss << "/" << (double)GetSrc(i)
00592 << "/" << hex << GetSrc(i) << dec;
00593 }
00594 }else {
00595 oss << "r_ = 0";
00596 }
00597 oss << delim;
00598 }
00599
00600 if(detail == 5) return oss.str();
00601
00602
00603 oss << "Mem: " << hex << GetMemAccess().address.address << dec << "/"
00604 << GetMemAccess().size << "/"
00605 << (GetMemAccess().sign ? "s" : "u") << "/"
00606 << GetMemAccess().value;
00607
00608 if( valDetail ) {
00609 oss << "/" << (double)GetMemAccess().value
00610 << "/" << hex << GetMemAccess().value << dec;
00611 }
00612 oss << delim;
00613 return oss.str();
00614 }