src/Sim/Op/Op.cpp

説明を見る。
00001 // 
00002 // Copyright (c) 2005-2008 Kenichi Watanabe.
00003 // Copyright (c) 2005-2008 Yasuhiro Watari.
00004 // Copyright (c) 2005-2008 Hironori Ichibayashi.
00005 // Copyright (c) 2008-2009 Kazuo Horio.
00006 // Copyright (c) 2009-2013 Naruki Kurata.
00007 // Copyright (c) 2005-2013 Ryota Shioya.
00008 // Copyright (c) 2005-2013 Masahiro Goshima.
00009 // 
00010 // This software is provided 'as-is', without any express or implied
00011 // warranty. In no event will the authors be held liable for any damages
00012 // arising from the use of this software.
00013 // 
00014 // Permission is granted to anyone to use this software for any purpose,
00015 // including commercial applications, and to alter it and redistribute it
00016 // freely, subject to the following restrictions:
00017 // 
00018 // 1. The origin of this software must not be misrepresented; you must not
00019 // claim that you wrote the original software. If you use this software
00020 // in a product, an acknowledgment in the product documentation would be
00021 // appreciated but is not required.
00022 // 
00023 // 2. Altered source versions must be plainly marked as such, and must not be
00024 // misrepresented as being the original software.
00025 // 
00026 // 3. This notice may not be removed or altered from any source
00027 // distribution.
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     //m_id            = id;
00124     // m_event  retire/flush 
00125     // m_event.clear();
00126     // m_event.reserve(8);
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 //  m_dstPhyReg[index]->SetVal(value);
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     // Must set a correct TID because this method is called by
00215     // the emulator, which does not set a TID.
00216     access->address.tid = GetTID();
00217     m_thread->GetMemOrderManager()->Read( m_iterator, access );
00218 }
00219 
00220 void Op::Write( MemAccess* access )
00221 {
00222     // Must set a correct TID because this method is called by
00223     // the emulator, which does not set a TID.
00224     access->address.tid = GetTID();
00225     m_thread->GetMemOrderManager()->Write( m_iterator, access );
00226 }
00227 
00228 // Returned whether this op is ready to select in an 'index'-th scheduler.
00229 // 'newDeps' is a set of dependencies that will be satisfied.
00230 // You can test whether an op can be selected if 'newDeps' dependencies are 
00231 // satisfied. 'newDeps' argument can be NULL.
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 // dependency  reset 
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 // OpゥgXPW[
00301 void Op::RescheduleSelf( bool clearIssueState )
00302 {
00303     // XPW[XPW[
00304     if( !IsDispatched() ) {
00305         return;
00306     }
00307 
00308     // dependency Zbg
00309     ResetDependency();
00310     
00311     // event LZ
00312     CancelEvent();
00313 
00314     // Reset an issue state.
00315     if( clearIssueState ){
00316         m_issueState = IssueState();
00317     }
00318 }
00319 
00320 // タs
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 // Write execution results to physical registers.
00334 void Op::WriteExecutionResults()
00335 {
00336     // write back
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 // consumer tFb`
00365 // consumer 0
00366 OpIterator Op::GetFirstConsumer()
00367 {
00368     OpIterator result(0);
00369 
00370     // WX^tFb`consumerT
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         // vOEI[_l[sXg
00381         // XgtFb`
00382         OpIterator frontOp = consumers.front();
00383         if( result.IsNull() || result->GetSerialID() > frontOp->GetSerialID() ) {
00384             result = frontOp;
00385         }
00386     }
00387 
00388     // WX^tFb`consumerT
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         // vOEI[_l[sXg
00398         // XgtFb`
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 // \[XWX^ZbgAWX^consumer
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 // \[XZbgAconsumer
00429 void Op::SetSrcMem(int index, MemDependencyPtr memDep)
00430 {
00431     m_srcMem[index] = memDep;
00432     memDep->AddConsumer(m_iterator);
00433 }
00434 
00435 // index  destination WX^Zbg
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 // index  destination WX^
00449 int Op::GetDstReg(int index)
00450 {
00451     return m_dstReg[index];
00452 }
00453 
00454 // index  source WX^
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 // Returns a execution unit of this op.
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     // PC
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     // status 
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     // _WX^
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     // next pc 
00543     oss << "TPC: " << GetTakenPC().pid << "/"
00544         << hex << GetTakenPC().address << dec
00545         << ( GetTaken() ? "(t)" : "(n)" ) << delim;
00546 
00547     if(detail == 3) return oss.str();
00548     // WX^
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     // WX^l
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     // MemAccess g
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 }

Onikiri2に対してTue Jun 18 14:34:24 2013に生成されました。  doxygen 1.4.7