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 #include "Sim/Predictor/DepPred/RegDepPred/RMT.h"
00035 #include "Sim/Foundation/Checkpoint/CheckpointMaster.h"
00036 #include "Interface/ISAInfo.h"
00037 #include "Sim/Op/Op.h"
00038 #include "Sim/Foundation/Hook/HookUtil.h"
00039
00040
00041
00042 using namespace Onikiri;
00043 using namespace std;
00044 using namespace boost;
00045
00046 namespace Onikiri
00047 {
00048 HookPoint<RMT,RMT::HookParam> RMT::s_allocateRegHook;
00049 HookPoint<RMT,RMT::HookParam> RMT::s_releaseRegHook;
00050 HookPoint<RMT,RMT::HookParam> RMT::s_deallocateRegHook;
00051 };
00052
00053
00054
00055 RMT::RMT() :
00056 m_numLogicalReg(0),
00057 m_numRegSegment(0),
00058 m_core(0),
00059 m_checkpointMaster(0),
00060 m_emulator(0),
00061 m_registerFile(0),
00062 m_regFreeList(0),
00063 m_allocationTable()
00064 {
00065 }
00066
00067 RMT::~RMT()
00068 {
00069 ReleaseParam();
00070 }
00071
00072 void RMT::Initialize(InitPhase phase)
00073 {
00074 if(phase == INIT_POST_CONNECTION){
00075
00076 CheckNodeInitialized( "registerFile", m_registerFile );
00077 CheckNodeInitialized( "regFreeList", m_regFreeList );
00078 CheckNodeInitialized( "emulator", m_emulator );
00079 CheckNodeInitialized( "checkpointMaster", m_checkpointMaster );
00080
00081 ISAInfoIF* isaInfo = m_emulator->GetISAInfo();
00082
00083 m_numLogicalReg = isaInfo->GetRegisterCount();
00084 m_numRegSegment = isaInfo->GetRegisterSegmentCount();
00085
00086
00087 CheckpointMaster* checkpointMaster = m_checkpointMaster;
00088 m_allocationTable.Initialize(
00089 checkpointMaster,
00090 CheckpointMaster::SLOT_RENAME
00091 );
00092
00093
00094 m_segmentTable.assign(-1);
00095 for (int i = 0; i < m_numLogicalReg; ++i) {
00096 int segment = isaInfo->GetRegisterSegmentID(i);
00097 m_segmentTable[i] = segment;
00098 }
00099 vector<int> logicalRegNum( m_numRegSegment , 0 );
00100
00101
00102 for (int i = 0; i < m_numLogicalReg; i++) {
00103
00104 int segment = GetRegisterSegmentID(i);
00105 int phyRegNo = m_regFreeList->Allocate(segment);
00106 logicalRegNum[segment]++;
00107
00108
00109 (*m_allocationTable)[i] = phyRegNo;
00110
00111
00112
00113 PhyReg* phyReg = (*m_registerFile)[phyRegNo];
00114 phyReg->Clear();
00115
00116
00117 phyReg->Set();
00118
00119 phyReg->SetVal(m_emulator->GetInitialRegValue(0, i));
00120 }
00121
00122
00123
00124
00125 m_releaseTable.resize(m_registerFile->GetTotalCapacity(), -1);
00126 }
00127 }
00128
00129
00130 int RMT::ResolveReg(int lno)
00131 {
00132
00133
00134 return PeekReg(lno);
00135 }
00136
00137
00138
00139 int RMT::PeekReg(int lno) const
00140 {
00141 ASSERT(
00142 lno >= 0 && lno < m_numLogicalReg,
00143 "illegal register No.: %d\n", lno
00144 );
00145
00146 return ( m_allocationTable.GetCurrent() )[lno];
00147 }
00148
00149
00150
00151 int RMT::AllocateReg( OpIterator op, int lno )
00152 {
00153 HookParam hookParam = {op, lno, 0};
00154 HookEntry(
00155 this,
00156 &RMT::AllocateRegBody,
00157 &s_allocateRegHook,
00158 &hookParam
00159 );
00160 return hookParam.physicalRegNum;
00161 }
00162
00163
00164 void RMT::ReleaseReg( OpIterator op, const int lno, int phyRegNo )
00165 {
00166 HookParam hookParam = { op, lno, phyRegNo };
00167 HookEntry(
00168 this,
00169 &RMT::ReleaseRegBody,
00170 &s_releaseRegHook,
00171 &hookParam
00172 );
00173 }
00174
00175
00176 void RMT::DeallocateReg( OpIterator op, const int lno, int phyRegNo )
00177 {
00178 HookParam hookParam = { op, lno, phyRegNo };
00179 HookEntry(
00180 this,
00181 &RMT::DeallocateRegBody,
00182 &s_deallocateRegHook,
00183 &hookParam
00184 );
00185 }
00186
00187
00188
00189 void RMT::AllocateRegBody( HookParam* param )
00190 {
00191 int lno = param->logicalRegNum;
00192 int segment = GetRegisterSegmentID( lno );
00193
00194 ASSERT(
00195 lno >= 0 && lno < m_numLogicalReg,
00196 "illegal register No.: %d\n", lno
00197 );
00198
00199
00200 int phyRegNo = m_regFreeList->Allocate( segment );
00201
00202
00203 PhyReg* phyReg = (*m_registerFile)[ phyRegNo ];
00204 phyReg->Clear();
00205
00206
00207
00208 m_releaseTable[ phyRegNo ] = ( m_allocationTable.GetCurrent() )[ lno ];
00209
00210
00211 ( m_allocationTable.GetCurrent() )[ lno ] = phyRegNo;
00212
00213 param->physicalRegNum = phyRegNo;
00214 }
00215
00216
00217 void RMT::ReleaseRegBody( HookParam* param )
00218 {
00219 int lno = param->logicalRegNum;
00220 ASSERT(
00221 lno >= 0 && lno < m_numLogicalReg,
00222 "illegal register No.: %d\n", lno
00223 );
00224
00225 int segment = GetRegisterSegmentID( lno );
00226
00227
00228 int releasedPhyReg = m_releaseTable[ param->physicalRegNum ];
00229 m_regFreeList->Release( segment, releasedPhyReg );
00230 param->physicalRegNum = releasedPhyReg;
00231 }
00232
00233
00234 void RMT::DeallocateRegBody( HookParam* param )
00235 {
00236 int lno = param->logicalRegNum;
00237 ASSERT(
00238 lno >= 0 && lno < m_numLogicalReg,
00239 "illegal register No.: %d\n", lno
00240 );
00241
00242 int segment = GetRegisterSegmentID( lno );
00243
00244 m_regFreeList->Release( segment, param->physicalRegNum );
00245 }
00246
00247
00248 bool RMT::CanAllocate(OpIterator* infoArray, int numOp)
00249 {
00250
00251 boost::array<size_t, SimISAInfo::MAX_REG_SEGMENT_COUNT> requiredRegCount;
00252 requiredRegCount.assign(0);
00253
00254 for(int i = 0; i < numOp; ++i) {
00255 OpInfo* opInfo = infoArray[i]->GetOpInfo();
00256
00257 int dstNum = opInfo->GetDstNum();
00258 for( int k = 0; k < dstNum; ++k ){
00259 int dstOperand = opInfo->GetDstOperand( k );
00260 int segment = GetRegisterSegmentID( dstOperand );
00261 ++requiredRegCount[segment];
00262 }
00263 }
00264
00265
00266 for(int m = 0; m < m_numRegSegment; ++m){
00267 size_t freeRegCount = (size_t)m_regFreeList->GetFreeEntryCount(m);
00268 if( freeRegCount < requiredRegCount[m] ) {
00269 return false;
00270 }
00271 }
00272 return true;
00273 }
00274
00275
00276 int RMT::GetRegSegmentCount()
00277 {
00278 return m_numRegSegment;
00279 }
00280
00281 int RMT::GetLogicalRegCount(int segment)
00282 {
00283 if( segment >= m_numRegSegment )
00284 return 0;
00285
00286 return m_segmentTable[segment];
00287 }
00288
00289 int RMT::GetTotalLogicalRegCount()
00290 {
00291 return m_numLogicalReg;
00292 }