⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 branchunit.cpp

📁 ppc750 system design simulator using system c
💻 CPP
字号:
/***************************************************************************                          BranchUnit.cpp  -  description                             -------------------    begin                : Mon May 21 2001    copyright            : (C) 2001 Universite Paris Sud and CEA    author               : Gilles Mouchard    email                : gilles.mouchard@lri.fr, gilles.mouchard@.cea.fr ***************************************************************************/#include <BranchUnit.h>void BranchUnit::Execute(){	if(inDispatched)	{		const BranchOperation& operation = inOperation;		const BranchOperands& operands = inOperands;		const BranchTags& tags = inTags;#if defined(DEBUG) || defined(TRACE)		UInt32 dbgInstructionCounter = inInstructionCounter;		UInt32 dbgInstruction = inInstruction;#endif			#ifdef DEBUG		if(Debug(DebugBranchUnit))		{			cout << name() << ": dispatched (" << dbgInstructionCounter << ")  ";			ppc_disassemble_to_stream(dbgInstruction, operands.pc, stdout);			cout << endl;		}#endif#ifdef TRACE		if(Trace(TraceBranchUnit))		{			trace_file->Begin("execute");			trace_file->Value("unit", "branch");			trace_file->Value("number", dbgInstructionCounter);			trace_file->Value("pc", dbgInstructionCounter);			trace_file->End("execute");		}#endif		UInt32 cia = operands.pc;		UInt32 nia = cia + 4;		UInt32 lr;		UInt32 ctr;		bool takenBranch;		bool updateBHT;		bool misprediction = false;				switch(operation.ident)		{			case ID_B:#ifdef DEBUG				if(Debug(DebugBranchUnit))				{					cout << name() << ": immed = ";					WriteHex(cout, operands.immed);					if(operation.extra.b.aa)						cout << "(absolute)";					else						cout << "(relative)";					cout << endl;				}#endif				takenBranch = true;				if(operation.extra.b.aa)					nia = operands.immed;				else					nia = cia + operands.immed;							if(operation.extra.b.lk)					lr = cia + 4; //lr = (cia + 4) >> 2;								updateBHT = false;#ifdef DEBUG				if(Debug(DebugBranchUnit))				{					cout << name() << ": Unconditional branch (cia = ";					WriteHex(cout, cia);					cout << ", nia = ";					WriteHex(cout, nia);					cout << ", in lr = ";					WriteHex(cout, operands.lr);					cout << ", out lr = ";					WriteHex(cout, lr);					cout << ")" << endl;				}#endif				break;						case ID_BC:				{					bool ctr_ok;					bool cond_ok;										if((operation.extra.bc.bo & 16) == 0)					{#ifdef DEBUG						if(Debug(DebugBranchUnit))							cout << name() << ": conditional branch" << endl;#endif						/* Conditional branch */						if(operation.extra.bc.bo & 8)						{#ifdef DEBUG							if(Debug(DebugBranchUnit))								cout << name() << ": branch if condition is true" << endl;#endif							/* Branch if condition is true */							cond_ok = ((operands.crfield << (operation.extra.bc.bi %4)) & 8) != 0;						}						else						{#ifdef DEBUG							if(Debug(DebugBranchUnit))								cout << name() << ": branch if condition is false" << endl;#endif							/* Branch if condition is false */							cond_ok = ((operands.crfield << (operation.extra.bc.bi %4)) & 8) == 0;						}					}					else					{						cond_ok = true;					}										if((operation.extra.bc.bo & 4) == 0)					{#ifdef DEBUG						if(Debug(DebugBranchUnit))							cout << name() << ": branch decrement CTR" << endl;#endif						/* Decrement CTR */						ctr = operands.ctr - 1;						/* Test whether to branch if CTR is zero or not */						if(operation.extra.bc.bo & 2)						{#ifdef DEBUG							if(Debug(DebugBranchUnit))								cout << name() << ": branch if ctr == 0" << endl;#endif							ctr_ok = ctr == 0;						}						else						{#ifdef DEBUG							if(Debug(DebugBranchUnit))								cout << name() << ": branch if ctr != 0" << endl;#endif							ctr_ok = ctr != 0;						}					}					else					{						ctr_ok = true;					}										takenBranch = ctr_ok && cond_ok;					#ifdef DEBUG					if(Debug(DebugBranchUnit))					{						cout << name() << ": immed = ";						WriteHex(cout, operands.immed);						if(operation.extra.bc.aa)							cout << "(absolute)";						else							cout << "(relative)";						cout << endl;					}#endif					if(takenBranch)					{#ifdef DEBUG						if(Debug(DebugBranchUnit))							cout << name() << ": Taken branch" << endl;#endif						if(operation.extra.bc.aa)							nia = operands.immed;						else							nia = cia + operands.immed;									}										if(operation.extra.bc.lk)						lr = cia + 4; //lr = (cia + 4) >> 2;#ifdef DEBUG					if(Debug(DebugBranchUnit))					{						cout << name() << ": Conditional branch (cr = ";						WriteHex(cout, operands.crfield);						cout << ", cia = ";						WriteHex(cout, cia);						cout << ", nia = ";						WriteHex(cout, nia);						cout << ", in lr = ";						WriteHex(cout, operands.lr);						cout << ", out lr = ";						WriteHex(cout, lr);						cout << ", in ctr = ";						WriteHex(cout, operands.ctr);						cout << ", out ctr = ";						WriteHex(cout, ctr);						cout << ")" << endl;					}#endif				}				updateBHT = true;				misprediction = operands.branchPredictedTaken != takenBranch;				nBC++;				if(misprediction) nMispredictedBC++;				break;						case ID_BCLR:				{					bool ctr_ok;					bool cond_ok;										if((operation.extra.bclr.bo & 16) == 0)					{						/* Conditional branch */						if(operation.extra.bclr.bo & 8)						{							/* Branch if condition is true */							cond_ok = ((operands.crfield << (operation.extra.bclr.bi %4)) & 8) != 0;						}						else						{							/* Branch if condition is false */							cond_ok = ((operands.crfield << (operation.extra.bclr.bi %4)) & 8) == 0;						}					}					else					{						cond_ok = true;					}										if((operation.extra.bclr.bo & 4) == 0)					{						/* Decrement CTR */						ctr = operands.ctr - 1;						/* Test whether to branch if CTR is zero or not */						ctr_ok = (operation.extra.bclr.bo & 2) ? ctr == 0 : ctr != 0;					}					else					{						ctr_ok = true;					}									takenBranch = ctr_ok && cond_ok;										if(takenBranch)					{#ifdef DEBUG						if(Debug(DebugBranchUnit))							cout << "Taken branch" << endl;#endif						nia = operands.lr & 0xfffffffc; //nia = operands.lr << 2;										}										if(operation.extra.bclr.lk)						lr = cia + 4; //lr = (cia + 4) >> 2;									updateBHT = false;					misprediction = operands.branchPredictedTaken != takenBranch;					#ifdef DEBUG					if(Debug(DebugBranchUnit))					{						cout << name() << ": Branch To Link Register (cia = ";						WriteHex(cout, cia);						cout << ", nia = ";						WriteHex(cout, nia);						cout << ", CR =";						WriteHex(cout, operands.crfield);						cout << ", in lr = ";						WriteHex(cout, operands.lr);						cout << ", out lr = ";						WriteHex(cout, lr);						cout << ")" << endl;					}#endif				}				nBCLR++;				break;						case ID_BCCTR:				{					bool cond_ok;										if((operation.extra.bcctr.bo & 16) == 0)					{						/* Conditional branch */						if(operation.extra.bcctr.bo & 8)						{							/* Branch if condition is true */							cond_ok = (operands.crfield << (operation.extra.bcctr.bi %4) & 8) != 0;						}						else						{							/* Branch if condition is false */							cond_ok = (operands.crfield << (operation.extra.bcctr.bi %4) & 8) == 0;						}					}					else					{						cond_ok = true;					}									takenBranch = cond_ok;										if(takenBranch)					{#ifdef DEBUG						if(Debug(DebugBranchUnit))							cout << "Taken branch" << endl;#endif						nia = operands.ctr & 0xfffffffc; //nia = operands.ctr << 2;									}										if(operation.extra.bcctr.lk)						lr = cia + 4; //lr = (cia + 4) >> 2;									updateBHT = false;					misprediction = operands.branchPredictedTaken != takenBranch;#ifdef DEBUG					if(Debug(DebugBranchUnit))					{						cout << name() << ": Branch To Count Register (cia = ";						WriteHex(cout, cia);						cout << ", nia = ";						WriteHex(cout, nia);						cout << ", in lr = ";						WriteHex(cout, operands.lr);						cout << ", out lr = ";						WriteHex(cout, lr);						cout << ")" << endl;					}#endif				}				nBCCTR++;				break;		}				outMispredictedBranch = misprediction;		if(misprediction)			mispredictedBranches++;		else			wellPredictedBranches++;/*		if(misprediction)		{			cerr << "Branch at "; WriteHex(cerr, operands.pc); cerr << " is mispredicted (" << (operands.branchPredictedTaken ? "taken" : "not taken") << " instead of " << (takenBranch ? "taken" : "not taken") <<")" << endl;		}*/		#ifdef DEBUG		if(Debug(DebugBranchUnit))			if(misprediction)				cout << name() << ": Mispredicted branch" << endl;#endif				outUpdateBHT = updateBHT;		if(updateBHT)		{#ifdef DEBUG			if(Debug(DebugBranchUnit))				cout << name() << ": Updating BHT" << endl;#endif			outBHTPC = operands.pc;			outTakenBranch = takenBranch;		}				if(tags.LRTag >= 0)		{#ifdef DEBUG			if(Debug(DebugBranchUnit))				cout << name() << ": result LR = " << lr << endl;#endif			outResultLRValid = true;			outResultLRTag = tags.LRTag;			outResultLRData = lr;		}		else		{			outResultLRValid = false;		}			if(tags.CTRTag >= 0)		{#ifdef DEBUG			if(Debug(DebugBranchUnit))				cout << name() << ": result CTR = " << ctr << endl;#endif			outResultCTRValid = true;			outResultCTRTag = tags.CTRTag;			outResultCTRData = ctr;		}		else		{			outResultCTRValid = false;		}#ifdef DEBUG		if(Debug(DebugBranchUnit))		{			cout << name() << ": Branch finished (tag =" << (int) tags.tag << ")  (" << dbgInstructionCounter << ")  ";			ppc_disassemble_to_stream(dbgInstruction, operands.pc, stdout);			cout << endl;		}#endif			outFinished = true;		outTag = tags.tag;		outPC = nia;	}	else	{		outUpdateBHT = false;		outFinished = false;		outResultLRValid = false;		outResultCTRValid = false;	}	outBusy = false;}void BranchUnit::Reset(){	mispredictedBranches = 0;	wellPredictedBranches = 0;	nBC = 0;	nMispredictedBC = 0;	nBCLR = 0;	nBCCTR = 0;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -