#include <ForwardEmulator.h>
Onikiri::ForwardEmulatorに対する継承グラフ
ForwardEmulator.h の 51 行で定義されています。
ForwardEmulator.h の 142 行で定義されています。
ForwardEmulator::ForwardEmulator | ( | ) |
ForwardEmulator.cpp の 42 行で定義されています。
00042 : 00043 m_emulator( NULL ), 00044 m_enable( false ) 00045 { 00046 }
ForwardEmulator::~ForwardEmulator | ( | ) | [virtual] |
Onikiri::ForwardEmulator::BEGIN_PARAM_PATH | ( | GetParamPath() | ) |
void ForwardEmulator::Finalize | ( | ) | [virtual] |
Onikiri::PhysicalResourceNodeを再定義しています。
ForwardEmulator.cpp の 62 行で定義されています。
参照先 Onikiri::PhysicalResourceNode::ReleaseParam().
00063 { 00064 ReleaseParam(); 00065 }
関数の呼び出しグラフ:
EmulatorIF* Onikiri::ForwardEmulator::GetEmulator | ( | ) | const [inline] |
ForwardEmulator.h の 81 行で定義されています。
参照先 m_emulator.
参照元 Onikiri::PerfectMemDepPred::Initialize().
00081 { return m_emulator; };
Here is the caller graph for this function:
ForwardEmulator.cpp の 385 行で定義されています。
参照先 Onikiri::Addr::address・Onikiri::OpStateIF::GetTaken()・Onikiri::OpStateIF::GetTakenPC()・Onikiri::SimISAInfoDef::SimISAInfo_IW32_RW64_AS64::INSTRUCTION_WORD_BYTE_SIZE.
参照元 UpdateArchContext()・UpdateFixedPath().
00386 { 00387 if( state->GetTaken() ){ 00388 return state->GetTakenPC(); 00389 } 00390 else{ 00391 current.address += SimISAInfo::INSTRUCTION_WORD_BYTE_SIZE; 00392 return current; 00393 } 00394 }
関数の呼び出しグラフ:
Here is the caller graph for this function:
const OpStateIF * ForwardEmulator::GetExecutionResult | ( | OpIterator | op | ) |
ForwardEmulator.cpp の 260 行で定義されています。
参照先 Onikiri::ForwardEmulator::InflightOp::emuOp・GetInflightOp().
参照元 Onikiri::BPred::Predict().
00261 { 00262 InflightOp* ifOp = GetInflightOp( op ); 00263 return (ifOp != NULL ) ? &ifOp->emuOp : NULL; 00264 }
関数の呼び出しグラフ:
Here is the caller graph for this function:
ForwardEmulator::InflightOp * ForwardEmulator::GetInflightOp | ( | OpIterator | op, | |
bool | reverse = true | |||
) |
ForwardEmulator.cpp の 337 行で定義されています。
参照先 m_inflightOps.
参照元 GetExecutionResult()・GetMemoryAccessResult()・UpdateFixedPath().
00338 { 00339 int tid = op->GetTID(); 00340 InflightOpList* inflightOps = &m_inflightOps[ tid ]; 00341 00342 u64 retireID = op->GetRetireID(); 00343 00344 if( reverse ){ 00345 for( InflightOpList::reverse_iterator i = inflightOps->rbegin(); i != inflightOps->rend(); ++i ){ 00346 if( i->retireId == retireID ){ 00347 return &(*i); 00348 } 00349 } 00350 } 00351 else{ 00352 for( InflightOpList::iterator i = inflightOps->begin(); i != inflightOps->end(); ++i ){ 00353 if( i->retireId == retireID ){ 00354 return &(*i); 00355 } 00356 } 00357 } 00358 return NULL; 00359 }
Here is the caller graph for this function:
const MemAccess * ForwardEmulator::GetMemoryAccessResult | ( | OpIterator | op | ) |
ForwardEmulator.cpp の 266 行で定義されています。
参照先 GetInflightOp()・Onikiri::ForwardEmulator::InflightOp::memAccess.
参照元 Onikiri::PerfectMemDepPred::Resolve().
00267 { 00268 InflightOp* ifOp = GetInflightOp( op ); 00269 return (ifOp != NULL ) ? &ifOp->memAccess : NULL; 00270 }
関数の呼び出しグラフ:
Here is the caller graph for this function:
ForwardEmulator::InflightOp * ForwardEmulator::GetProducerStore | ( | const InflightOp & | consumerLoad | ) |
ForwardEmulator.cpp の 362 行で定義されています。
参照先 Onikiri::MemAccess::address・Onikiri::MemOrderOperations::IsOverlapped()・m_inflightOps・m_memOperations・Onikiri::ForwardEmulator::InflightOp::memAccess・Onikiri::ForwardEmulator::InflightOp::retireId・Onikiri::LogicalData::tid.
参照元 Read().
00363 { 00364 const MemAccess& access = consumerLoad.memAccess; 00365 int tid = access.address.tid; 00366 InflightOpList* inflightOps = &m_inflightOps[ tid ]; 00367 00368 InflightOpList::reverse_iterator end = inflightOps->rend(); 00369 for( InflightOpList::reverse_iterator i = inflightOps->rbegin(); i != end; ++i ){ 00370 if( !i->isStore ){ 00371 continue; 00372 } 00373 if( consumerLoad.retireId < i->retireId ){ 00374 continue; 00375 } 00376 00377 if( m_memOperations.IsOverlapped( access, i->memAccess ) ){ 00378 return &(*i); 00379 } 00380 } 00381 return NULL; 00382 }
関数の呼び出しグラフ:
Here is the caller graph for this function:
void ForwardEmulator::Initialize | ( | InitPhase | phase | ) |
ForwardEmulator.cpp の 52 行で定義されています。
参照先 Onikiri::EmulatorIF::GetISAInfo()・Onikiri::PhysicalResourceNode::INIT_POST_CONNECTION・Onikiri::PhysicalResourceNode::INIT_PRE_CONNECTION・Onikiri::ISAInfoIF::IsLittleEndian()・Onikiri::ParamExchange::LoadParam()・m_emulator・m_memOperations・Onikiri::MemOrderOperations::SetTargetEndian().
00053 { 00054 if( phase == INIT_PRE_CONNECTION ){ 00055 LoadParam(); 00056 } 00057 else if( phase == INIT_POST_CONNECTION ){ 00058 m_memOperations.SetTargetEndian( m_emulator->GetISAInfo()->IsLittleEndian() ); 00059 } 00060 }
関数の呼び出しグラフ:
bool Onikiri::ForwardEmulator::IsEnabled | ( | ) | const [inline] |
ForwardEmulator.h の 82 行で定義されています。
参照先 m_enable.
参照元 Onikiri::PerfectMemDepPred::Initialize()・Onikiri::BPred::Initialize().
00082 { return m_enable; }
Here is the caller graph for this function:
bool ForwardEmulator::IsInMissPredictedPath | ( | OpIterator | op | ) |
ForwardEmulator.cpp の 273 行で定義されています。
参照先 m_threadContext・Onikiri::ForwardEmulator::ThreadContext::nextFixedRetireID.
参照元 Onikiri::PerfectMemDepPred::Resolve().
00274 { 00275 int tid = op->GetTID(); 00276 ThreadContext* threadContext = &m_threadContext[ tid ]; 00277 return ( op->GetRetireID() >= threadContext->nextFixedRetireID ) ? true : false; 00278 }
Here is the caller graph for this function:
void Onikiri::ForwardEmulator::OnBranchPrediction | ( | PC * | predPC | ) |
void ForwardEmulator::OnCommit | ( | OpIterator | op | ) |
ForwardEmulator.cpp の 183 行で定義されています。
参照先 ASSERT・Onikiri::OpInfo::GetDstNum()・Onikiri::OpIterator::GetOp()・Onikiri::OpInfo::GetOpClass()・Onikiri::OpClass::IsMem()・Onikiri::OpClass::IsSyscall()・m_context・m_enable・m_inflightOps・THROW_RUNTIME_ERROR・UpdateArchContext()・UpdateFixedPath().
参照元 Onikiri::Retirer::Commit().
00184 { 00185 if( !m_enable ) 00186 return; 00187 00188 int tid = simOp->GetTID(); 00189 InflightOpList* inflightOps = &m_inflightOps[ tid ]; 00190 InflightOpList::iterator front = inflightOps->begin(); 00191 00192 ASSERT( 00193 front != inflightOps->end(), 00194 "A list of in-flight ops is empty." 00195 ); 00196 ASSERT( 00197 front->retireId == simOp->GetRetireID(), 00198 "A retire-id of a forwardly emulated op (%lld) and that of a simulated op (%lld) are inconsistent.", 00199 front->retireId, 00200 simOp->GetRetireID() 00201 ); 00202 00203 EmulationOp* emuOp = &( front->emuOp ); 00204 00205 const OpInfo* emuOpInfo = emuOp->GetOpInfo(); 00206 const OpClass& emuOpClass = emuOpInfo->GetOpClass(); 00207 00208 if( emuOpClass.IsSyscall() ){ 00209 // System calls are treated specially. 00210 // The execution of system calls is delayed to OnCommit, because 00211 // executing system calls immediately affect architecture state such as memory image. 00212 ArchitectureState* context = &m_context[ tid ]; 00213 UpdateArchContext( 00214 context, 00215 simOp.GetOp(), 00216 simOp->GetOpInfo(), 00217 front->updatePC, 00218 front->updateMicroOpIndex 00219 ); 00220 UpdateFixedPath( simOp ); 00221 //ASSERT( inflightOps->size() == 1, "System call must be serialized." ); 00222 } 00223 else{ 00224 u64 simDst = simOp->GetDstRegNum() > 0 ? simOp->GetDst(0) : 0; 00225 u64 emuDst = emuOpInfo->GetDstNum() > 0 ? emuOp->GetDst(0) : 0; 00226 u64 simPC = simOp->GetPC().address; 00227 u64 emuPC = emuOp->GetPC().address; 00228 u64 simAddr = emuOpClass.IsMem() ? simOp->GetMemAccess().address.address : 0; 00229 u64 emuAddr = emuOpClass.IsMem() ? front->memAccess.address.address : 0; 00230 00231 if( simDst != emuDst || simPC != emuPC || simAddr != emuAddr ){ 00232 THROW_RUNTIME_ERROR( 00233 "Simulation result is incorrect.\n" 00234 "Forward emulation result: '%08x%08x'\n" 00235 "Simulation result: '%08x%08x'\n" 00236 "Forward emulation pc: '%08x%08x'\n" 00237 "Simulation pc: '%08x%08x'\n" 00238 "Forward emulation address: '%08x%08x'\n" 00239 "Simulation address: '%08x%08x'\n" 00240 "%s\n%s", 00241 (u32)(emuDst >> 32), (u32)(emuDst & 0xffffffff), 00242 (u32)(simDst >> 32), (u32)(simDst & 0xffffffff), 00243 (u32)(emuPC >> 32), (u32)(emuPC & 0xffffffff), 00244 (u32)(simPC >> 32), (u32)(simPC & 0xffffffff), 00245 (u32)(emuAddr >> 32), (u32)(emuAddr & 0xffffffff), 00246 (u32)(simAddr >> 32), (u32)(simAddr & 0xffffffff), 00247 simOp->ToString().c_str(), 00248 simOp->GetOpInfo()->GetMnemonic() 00249 ); 00250 } 00251 } 00252 00253 00254 00255 inflightOps->pop_front(); 00256 }
関数の呼び出しグラフ:
Here is the caller graph for this function:
void ForwardEmulator::OnFetch | ( | OpIterator | op | ) |
ForwardEmulator.cpp の 79 行で定義されています。
参照先 Onikiri::Addr::address・ASSERT・Onikiri::ForwardEmulator::InflightOp::emuOp・Onikiri::EmulatorIF::Execute()・Onikiri::EmulatorIF::GetOp()・Onikiri::OpInfo::GetOpClass()・Onikiri::OpInfo::GetSrcNum()・Onikiri::OpInfo::GetSrcOperand()・Onikiri::SimISAInfoDef::SimISAInfo_IW32_RW64_AS64::INSTRUCTION_WORD_BYTE_SIZE・Onikiri::OpClass::IsStore()・Onikiri::ForwardEmulator::InflightOp::isStore・Onikiri::OpClass::IsSyscall()・m_context・m_emulator・m_enable・m_inflightOps・Onikiri::ArchitectureState::microOpIndex・Onikiri::ArchitectureState::pc・Onikiri::ArchitectureState::registerValue・Onikiri::ForwardEmulator::InflightOp::retireId・Onikiri::EmulationOp::SetMem()・Onikiri::EmulationOp::SetOpInfo()・Onikiri::EmulationOp::SetPC()・Onikiri::EmulationOp::SetSrc()・Onikiri::EmulationOp::SetTaken()・Onikiri::EmulationOp::SetTakenPC()・Onikiri::ForwardEmulator::InflightOp::simOp・UpdateArchContext()・UpdateFixedPath()・Onikiri::ForwardEmulator::InflightOp::updateMicroOpIndex・Onikiri::ForwardEmulator::InflightOp::updatePC.
参照元 Onikiri::Fetcher::Fetch().
00080 { 00081 if( !m_enable ) 00082 return; 00083 00084 int tid = simOp->GetTID(); 00085 ArchitectureState* context = &m_context[ tid ]; 00086 InflightOpList* inflightOps = &m_inflightOps[ tid ]; 00087 00088 // Return when emulation is already done on recovery 00089 // from branch miss prediction. 00090 if( inflightOps->size() > 0 ){ 00091 InflightOp* entry = &inflightOps->back(); 00092 if( entry->retireId >= simOp->GetRetireID() ){ 00093 // Already executed in ForwardEmulator. 00094 UpdateFixedPath( simOp ); 00095 return; 00096 } 00097 00098 // System calls are treated specially. 00099 // The execution of system calls is delayed to OnCommit, because 00100 // executing system calls immediately affect architecture state such as memory image. 00101 // A system call may be divided to multiple micro ops and second or later divided ops 00102 // are not pushed to 'm_inflightOps', so PCs do not match. 00103 if( entry->emuOp.GetOpInfo()->GetOpClass().IsSyscall() && 00104 entry->emuOp.GetPC() != simOp->GetPC() 00105 ){ 00106 return; 00107 } 00108 } 00109 00110 00111 // 00112 // Execution 00113 // 00114 00115 inflightOps->push_back( InflightOp() ); 00116 InflightOp* entry = &inflightOps->back(); 00117 entry->simOp = simOp; 00118 entry->retireId = simOp->GetRetireID(); 00119 00120 // Get OpInfo 00121 std::pair<OpInfo**, int> ops = 00122 m_emulator->GetOp( context->pc ); 00123 OpInfo** opInfoArray = ops.first; 00124 int opCount = ops.second; 00125 ASSERT( context->microOpIndex < opCount ); 00126 OpInfo* opInfo = opInfoArray[ context->microOpIndex ]; 00127 entry->updatePC = context->microOpIndex >= opCount - 1; 00128 entry->isStore = opInfo->GetOpClass().IsStore(); 00129 00130 // Initialize an emu op. 00131 EmulationOp* emuOp = &entry->emuOp; 00132 emuOp->SetMem( this ); 00133 emuOp->SetPC( context->pc ); 00134 emuOp->SetTakenPC( Addr( tid, simOp->GetTID(), context->pc.address + SimISAInfo::INSTRUCTION_WORD_BYTE_SIZE ) ); 00135 emuOp->SetOpInfo( opInfo ); 00136 emuOp->SetTaken( false ); 00137 // Set source operands. 00138 int srcCount = opInfo->GetSrcNum(); 00139 for( int i = 0; i < srcCount; i++ ) { 00140 emuOp->SetSrc(i, context->registerValue[ opInfo->GetSrcOperand( i ) ] ); 00141 } 00142 00143 // Execution 00144 if( opInfo->GetOpClass().IsSyscall() ){ 00145 // System calls are treated specially. 00146 // The execution of system calls is delayed to OnCommit, because 00147 // executing system calls immediately affect architecture state such as memory image. 00148 entry->updateMicroOpIndex = false; 00149 context->microOpIndex++; 00150 return; 00151 } 00152 else{ 00153 m_emulator->Execute( emuOp, opInfo ); 00154 UpdateArchContext( context, emuOp, opInfo, entry->updatePC, true ); 00155 UpdateFixedPath( simOp ); 00156 } 00157 }
関数の呼び出しグラフ:
Here is the caller graph for this function:
void ForwardEmulator::Read | ( | MemAccess * | access | ) | [virtual] |
Onikiri::MemIFを実装しています。
ForwardEmulator.cpp の 280 行で定義されています。
参照先 Onikiri::MemAccess::address・Onikiri::EmulatorIF::GetMemImage()・GetProducerStore()・Onikiri::MemOrderOperations::IsInnerAccess()・Onikiri::MemOrderOperations::IsOverlapped()・m_emulator・m_inflightOps・m_memOperations・Onikiri::ForwardEmulator::InflightOp::memAccess・Onikiri::MemOrderOperations::MergePartialAccess()・Onikiri::MemIF::Read()・Onikiri::MemOrderOperations::ReadPreviousAccess()・Onikiri::LogicalData::tid・Onikiri::MemAccess::value.
00281 { 00282 int tid = access->address.tid; 00283 InflightOpList* inflightOps = &m_inflightOps[ tid ]; 00284 InflightOp* entry = &inflightOps->back(); 00285 00286 entry->memAccess = *access; 00287 InflightOp* producer = GetProducerStore( *entry ); 00288 00289 bool partial = false; 00290 if( producer != NULL ){ 00291 if( m_memOperations.IsInnerAccess( *access, producer->memAccess ) ){ 00292 access->value = m_memOperations.ReadPreviousAccess( *access, producer->memAccess ); 00293 entry->memAccess = *access; 00294 return; 00295 } 00296 else{ 00297 partial = true; 00298 //THROW_RUNTIME_ERROR( "A partial read access in ForwardEmulator is not supported yet." ); 00299 } 00300 } 00301 00302 if( partial ){ 00303 00304 // Merge multiple stores to one load. 00305 MemAccess base = *access; 00306 m_emulator->GetMemImage()->Read( &base ); 00307 00308 for( InflightOpList::iterator i = inflightOps->begin(); i != inflightOps->end(); ++i ){ 00309 if( !i->isStore ){ 00310 continue; 00311 } 00312 00313 if( m_memOperations.IsOverlapped( base, i->memAccess ) ){ 00314 base.value = 00315 m_memOperations.MergePartialAccess( base, i->memAccess ); 00316 } 00317 } 00318 00319 *access = base; 00320 entry->memAccess = base; 00321 return; 00322 } 00323 00324 m_emulator->GetMemImage()->Read( access ); 00325 entry->memAccess = *access; 00326 }
関数の呼び出しグラフ:
void ForwardEmulator::SetContext | ( | const ArchitectureStateList & | context | ) |
ForwardEmulator.cpp の 67 行で定義されています。
参照先 m_context・m_inflightOps・m_threadContext.
00068 { 00069 m_context = context; 00070 m_inflightOps.clear(); 00071 m_inflightOps.resize( m_context.size() ); 00072 00073 m_threadContext.resize( m_context.size() ); 00074 for( size_t i = 0; i < m_context.size(); ++i ){ 00075 m_threadContext[i].nextFixedPC = context[i].pc; 00076 } 00077 }
void ForwardEmulator::UpdateArchContext | ( | ArchitectureState * | context, | |
OpStateIF * | state, | |||
OpInfo * | info, | |||
bool | updatePC, | |||
bool | updateMicroOpIndex | |||
) |
ForwardEmulator.cpp の 159 行で定義されています。
参照先 Onikiri::OpStateIF::GetDst()・Onikiri::OpInfo::GetDstNum()・Onikiri::OpInfo::GetDstOperand()・GetExecutedNextPC()・Onikiri::ArchitectureState::microOpIndex・Onikiri::ArchitectureState::pc・Onikiri::ArchitectureState::registerValue.
参照元 OnCommit()・OnFetch().
00165 { 00166 // Get results. 00167 int dstCount = info->GetDstNum(); 00168 for (int i = 0; i < dstCount; i ++) { 00169 context->registerValue[ info->GetDstOperand(i) ] = state->GetDst(i); 00170 } 00171 00172 // Update PCs 00173 if( updateMicroOpIndex ) 00174 context->microOpIndex++; 00175 00176 if( updatePC ){ 00177 context->microOpIndex = 0; 00178 context->pc = GetExecutedNextPC( context->pc, state ); 00179 } 00180 }
関数の呼び出しグラフ:
Here is the caller graph for this function:
void ForwardEmulator::UpdateFixedPath | ( | OpIterator | simOp | ) |
ForwardEmulator.cpp の 397 行で定義されています。
参照先 ASSERT・Onikiri::ForwardEmulator::InflightOp::emuOp・GetExecutedNextPC()・GetInflightOp()・Onikiri::EmulationOp::GetPC()・m_threadContext・MAX_RID_DIFFERENCE・Onikiri::ForwardEmulator::ThreadContext::nextFixedPC・Onikiri::ForwardEmulator::ThreadContext::nextFixedRetireID・Onikiri::ForwardEmulator::InflightOp::updatePC.
参照元 OnCommit()・OnFetch().
00398 { 00399 int tid = simOp->GetTID(); 00400 ThreadContext* thread = &m_threadContext[ tid ]; 00401 u64 rid = simOp->GetRetireID(); 00402 00403 if( ( thread->nextFixedRetireID == rid && thread->nextFixedPC == simOp->GetPC() ) || 00404 thread->nextFixedRetireID > rid 00405 ){ 00406 // When re-fetch recovery occurs (nextFixedRetireID > rid ), 00407 // nextFixedRetireID and nextFixedPC must be set to a recovered ones. 00408 00409 // 'reverse' is set to false, because it may be found near the head of 'inflightOps'. 00410 InflightOp* inflightOp = GetInflightOp( simOp ); 00411 ASSERT( inflightOp != NULL ); 00412 00413 if( inflightOp->updatePC ){ 00414 thread->nextFixedPC = 00415 GetExecutedNextPC( inflightOp->emuOp.GetPC(), &inflightOp->emuOp ); 00416 } 00417 else 00418 { 00419 // You must overwrite nextFixedPC because 00420 // it might hold illegal PC as a result of recovery. 00421 thread->nextFixedPC = inflightOp->emuOp.GetPC(); 00422 } 00423 thread->nextFixedRetireID = rid + 1; 00424 } 00425 00426 ASSERT( 00427 ((s64)rid - (s64)thread->nextFixedRetireID) < MAX_RID_DIFFERENCE, 00428 "The difference between a current retirement id and a next fixed retirement id is too large." 00429 ); 00430 00431 }
関数の呼び出しグラフ:
Here is the caller graph for this function:
void ForwardEmulator::Write | ( | MemAccess * | access | ) | [virtual] |
Onikiri::MemIFを実装しています。
ForwardEmulator.cpp の 328 行で定義されています。
参照先 Onikiri::MemAccess::address・m_inflightOps・Onikiri::ForwardEmulator::InflightOp::memAccess・Onikiri::LogicalData::tid.
00329 { 00330 int tid = access->address.tid; 00331 InflightOpList* inflightOps = &m_inflightOps[ tid ]; 00332 InflightOp* op = &inflightOps->back(); 00333 op->memAccess = *access; 00334 }
BEGIN_PARAM_PATH ( GetResultPath() ) protected EmulatorIF* Onikiri::ForwardEmulator::m_emulator |
ForwardEmulator.h の 146 行で定義されています。
std::vector< InflightOpList > Onikiri::ForwardEmulator::m_inflightOps |
ForwardEmulator.h の 143 行で定義されています。
参照元 GetInflightOp()・GetProducerStore()・OnCommit()・OnFetch()・Read()・SetContext()・Write().
std::vector< ThreadContext > Onikiri::ForwardEmulator::m_threadContext |
const s64 Onikiri::ForwardEmulator::MAX_RID_DIFFERENCE = 1024 [static] |