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

📄 integerunit.cpp

📁 ppc750 system design simulator using system c
💻 CPP
📖 第 1 页 / 共 3 页
字号:
/***************************************************************************                          IntegerUnit.cpp  -  unite de calcul entier                             -------------------    begin                : Fri Apr 6 2001    copyright            : (C) 2001 Universite Paris Sud and CEA    author               : Gilles Mouchard    email                : gilles.mouchard@lri.fr, gilles.mouchard@.cea.fr ***************************************************************************/#include <IntegerUnit.h>inline int IntegerUnit::GetMulLatency(UInt32 op1, UInt32 op2){	op2 = (SInt32) op2 > 0 ? op2 : -op2;		if(op2 & 0xff000000) return 6;	if(op2 & 0x00ff0000) return 5;	if(op2 & 0x0000ff00) return 4;	if(op2 & 0x000000ff) return 3;	return 2;}inline UInt32 IntegerUnit::RotateLeft(UInt32 v, UInt8 n){	return (v << n) | ((v >> (32 - n)) & ((1 << n) - 1));}inline UInt32 IntegerUnit::Mask(UInt8 mb, UInt8 me){    return(((mb > me) ?            ~(((UInt32)-1 >> mb) ^ ((me >= 31) ? 0 : (UInt32) -1 >> (me + 1))):            (((UInt32)-1 >> mb) ^ ((me >= 31) ? 0 : (UInt32) -1 >> (me + 1)))));}bool IntegerUnit::Carry(UInt32 a, UInt32 b){	UInt32 c, x, y;	int i;	if((a == 0) || (b == 0)) return 0;	c = 0;	for(i = 0; i < 32; i++)	{	    x = (a >> i) & 0x1;		y = (b >> i) & 0x1;		c = x * y | x * c | y * c;	}	return c;}const SInt32 MaxInt = 0x7fffffff;bool IntegerUnit::Overflow(SInt32 a, SInt32 b){	return ((a > 0) && (b > 0) && (MaxInt - a < b)) || ((a < 0) && (b < 0) && (-MaxInt - a > b));}bool IntegerUnit::Underflow(SInt32 a, SInt32 b){	return ((a > 0) && (b < 0) && (MaxInt + b < a)) || ((a < 0) && (b > 0) && (-MaxInt + b > a));}void IntegerUnit::Execute(){	const IntegerOperation& operation = inOperation;	const IntegerOperands& operands = inOperands;	const IntegerTags& tags = inTags;#if defined(DEBUG) || defined(TRACE)	UInt32 dbgInstructionCounter = inInstructionCounter;	UInt32 dbgProgramCounter = inProgramCounter;	UInt32 dbgInstruction = inInstruction;#endif		if(inDispatched)	{		/* A new integer instruction has been started */		branchCounter = inBranchCounter;#ifdef DEBUG		if(Debug(DebugIntegerUnit))		{			cout << name() << ": dispatched (" << dbgInstructionCounter << ")  ";			ppc_disassemble_to_stream(dbgInstruction, dbgProgramCounter, stdout);			cout << endl;		}#endif#ifdef TRACE		if(Trace(TraceIntegerUnit))		{			trace_file->Begin("execute");			trace_file->Value("unit", "integer");			trace_file->Value("number", dbgInstructionCounter);			trace_file->Value("pc", dbgInstructionCounter);			trace_file->End("execute");		}#endif		dispatched = true;	}		if(dispatched)	{		/* An instruction is being executed */		if(latency == 0)		{			/* The instruction is beginning its execution */#ifdef DEBUG			if(Debug(DebugIntegerUnit))			{				cout << name() << ": Starting execution (" << dbgInstructionCounter << ")  ";				ppc_disassemble_to_stream(dbgInstruction, dbgProgramCounter, stdout);				cout << endl;				cout << name() << ": (RA/RS) = ";				WriteHex(cout, operands.data[0]);				cout << ", (RA/RB) = ";				WriteHex(cout, operands.data[1]);				cout << endl;			}#endif			/* RA : operands.data[0] */			/* RB, immed : operands.data[1] */			UInt64 result64;			ca = ov = false;						switch(operation.ident)			{						case ID_MULLI:					result32 = operands.data[0] * operands.data[1];					latency = GetMulLatency(operands.data[0], operands.data[1]);					break;								case ID_SUBFIC:					result32 = operands.data[1] - operands.data[0];					ca = operands.data[0] == 0 || Carry(-operands.data[0], operands.data[1]);					latency = 1;					break;								case ID_ADDIC:					result32 = operands.data[0] + operands.data[1];					ca = Carry(operands.data[0], operands.data[1]);					latency = 1;					break;									case ID_CMPLI:					lt = operands.data[0] < operands.data[1];					gt = operands.data[0] > operands.data[1];					eq = operands.data[0] == operands.data[1];					latency = 1;					break;								case ID_CMPI:					result32 = operands.data[0] - operands.data[1];					lt = ((SInt32) result32 < 0);					gt = ((SInt32) result32 > 0);					eq = ((UInt32) result32 == 0);					latency = 1;					break;								case ID_ADDICD:					result32 = operands.data[0] + operands.data[1];					ca = Carry(operands.data[0], operands.data[1]);					lt = ((SInt32) result32 < 0);					gt = ((SInt32) result32 > 0);					eq = ((UInt32) result32 == 0);					latency = 1;					break;								case ID_ADDI:					result32 = operation.nullRA ? operands.data[1] : operands.data[0] + operands.data[1];					latency = 1;					break;							case ID_ADDIS:					result32 = operation.nullRA ? (operands.data[1] << 16) : operands.data[0] + (operands.data[1] << 16);					latency = 1;					break;				case ID_ORI:					result32 = operands.data[0] | operands.data[1];					latency = 1;					break;							case ID_ORIS:					result32 = operands.data[0] | (operands.data[1] << 16);					latency = 1;					break;									case ID_XORI:					result32 = operands.data[0] ^ operands.data[1];					latency = 1;					break;								case ID_XORIS:					result32 = operands.data[0] ^ (operands.data[1] << 16);					latency = 1;					break;								case ID_ANDID:					result32 = operands.data[0] & operands.data[1];					lt = ((SInt32) result32 < 0);					gt = ((SInt32) result32 > 0);					eq = ((UInt32) result32 == 0);					latency = 1;					break;							case ID_ANDISD:					result32 = operands.data[0] & (operands.data[1] << 16);					lt = ((SInt32) result32 < 0);					gt = ((SInt32) result32 > 0);					eq = ((UInt32) result32 == 0);					latency = 1;					break;								case ID_RLWIMI:					{						UInt32 r = RotateLeft(operands.data[0], operation.extra.rotate.sh);						UInt32 m = Mask(operation.extra.rotate.mb, operation.extra.rotate.me);						result32 = (r & m) | (operands.data[1] & (~m));						latency = 1;					}					break;							case ID_RLWIMID:					{						UInt32 r = RotateLeft(operands.data[0], operation.extra.rotate.sh);						UInt32 m = Mask(operation.extra.rotate.mb, operation.extra.rotate.me);						result32 = (r & m) | (operands.data[1] & (~m));						lt = ((SInt32) result32 < 0);						gt = ((SInt32) result32 > 0);						eq = ((UInt32) result32 == 0);						latency = 1;					}					break;									case ID_RLWINM:					{						UInt32 r = RotateLeft(operands.data[0], operation.extra.rotate.sh);						UInt32 m = Mask(operation.extra.rotate.mb, operation.extra.rotate.me);						result32 = r & m;						latency = 1;					}					break;							case ID_RLWINMD:					{						UInt32 r = RotateLeft(operands.data[0], operation.extra.rotate.sh);						UInt32 m = Mask(operation.extra.rotate.mb, operation.extra.rotate.me);						result32 = r & m;						lt = ((SInt32) result32 < 0);						gt = ((SInt32) result32 > 0);						eq = ((UInt32) result32 == 0);						latency = 1;					}					break;							case ID_RLWNM:					{						UInt32 r = RotateLeft(operands.data[0], operands.data[1] & 31);						UInt32 m = Mask(operation.extra.rotate.mb, operation.extra.rotate.me);						result32 = r & m;						latency = 1;					}					break;							case ID_RLWNMD:					{						UInt32 r = RotateLeft(operands.data[0], operands.data[1] & 31);						UInt32 m = Mask(operation.extra.rotate.mb, operation.extra.rotate.me);						result32 = r & m;						lt = ((SInt32) result32 < 0);						gt = ((SInt32) result32 > 0);						eq = ((UInt32) result32 == 0);						latency = 1;					}					break;								case ID_CMP:					result32 = operands.data[0] - operands.data[1];					lt = ((SInt32) result32 < 0);					gt = ((SInt32) result32 > 0);					eq = ((UInt32) result32 == 0);					latency = 1;					break;							case ID_SUBFC:					result32 = operands.data[1] - operands.data[0];					ca = operands.data[0] == 0 || Carry(-operands.data[0], operands.data[1]);					latency = 1;					break;							case ID_SUBFCD:					result32 = operands.data[1] - operands.data[0];					ca = operands.data[0] == 0 || Carry(-operands.data[0], operands.data[1]);					lt = ((SInt32) result32 < 0);					gt = ((SInt32) result32 > 0);					eq = ((UInt32) result32 == 0);					latency = 1;					break;						case ID_SUBFCO:					result32 = operands.data[1] - operands.data[0];					ca = operands.data[0] == 0 || Carry(-operands.data[0], operands.data[1]);					ov = Underflow(operands.data[1], operands.data[0]);					latency = 1;					break;						case ID_SUBFCOD:					result32 = operands.data[1] - operands.data[0];					ca = operands.data[0] == 0 || Carry(-operands.data[0], operands.data[1]);					ov = Underflow(operands.data[1], operands.data[0]);					lt = ((SInt32) result32 < 0);					gt = ((SInt32) result32 > 0);					eq = ((UInt32) result32 == 0);					latency = 1;					break;								case ID_CMPL:					lt = operands.data[0] < operands.data[1];					gt = operands.data[0] > operands.data[1];					eq = operands.data[0] == operands.data[1];					latency = 1;					break;							case ID_ADDC:					result32 = operands.data[0] + operands.data[1];					ca = Carry(operands.data[0], operands.data[1]);					latency = 1;					break;						case ID_ADDCD:					result32 = operands.data[0] + operands.data[1];					ca = Carry(operands.data[0], operands.data[1]);					lt = ((SInt32) result32 < 0);					gt = ((SInt32) result32 > 0);					eq = ((UInt32) result32 == 0);					latency = 1;					break;								case ID_ADDCO:					result32 = operands.data[0] + operands.data[1];					ca = Carry(operands.data[0], operands.data[1]);					ov = Overflow(operands.data[0], operands.data[1]);					latency = 1;					break;							case ID_ADDCOD:					result32 = operands.data[0] + operands.data[1];					ca = Carry(operands.data[0], operands.data[1]);					ov = Overflow(operands.data[0], operands.data[1]);					lt = ((SInt32) result32 < 0);					gt = ((SInt32) result32 > 0);					eq = ((UInt32) result32 == 0);					latency = 1;					break;							case ID_MULHWU:					{						UInt64 res = (UInt64) operands.data[0] * (UInt64) operands.data[1];						res = (res >> 32);						result32 = (UInt32) res;						latency = GetMulLatency(operands.data[0], operands.data[1]);					}					break;									case ID_MULHWUD:					result32 = ((UInt64) operands.data[0] * (UInt64) operands.data[1]) >> 32;								lt = ((SInt32) result32 < 0);					gt = ((SInt32) result32 > 0);					eq = ((UInt32) result32 == 0);					latency = GetMulLatency(operands.data[0], operands.data[1]);					break;							case ID_SLW:					result32 = (operands.data[1] & 32) ? 0 : (operands.data[0] << (operands.data[1] & 31));					latency = 1;					break;								case ID_SLWD:					result32 = (operands.data[1] & 32) ? 0 : (operands.data[0] << (operands.data[1] & 31));					lt = ((SInt32) result32 < 0);					gt = ((SInt32) result32 > 0);					eq = ((UInt32) result32 == 0);					latency = 1;					break;				case ID_SRW:					result32 = (operands.data[1] & 32) ? 0 : (operands.data[0] >> (operands.data[1] & 31));					latency = 1;					break;														case ID_SRWD:  					result32 = (operands.data[1] & 32) ? 0 : (operands.data[0] >> (operands.data[1] & 31));					lt = ((SInt32) result32 < 0);					gt = ((SInt32) result32 > 0);					eq = ((UInt32) result32 == 0);					latency = 1;					break;							case ID_SRAW:					{						SInt32 src = operands.data[0];						UInt32 n = operands.data[1];												if(n == 0)						{							result32 = src;							ca = false;						}						else if(n & 0x20)						{							if(src < 0)							{								result32 = 0xffffffff;								if(src & 0x7fffffff) ca = true; else ca = false;							}							else							{								result32 = 0;								ca = false;							}						}						else						{							n = n & 0x1f;							result32 = (sword_t) src >> n;							if(src < 0 && (src << (32 - n)) != 0) ca = true; else ca = false;						}					}										latency = 1;					break;													case ID_SRAWD:					{						SInt32 src = operands.data[0];						UInt32 n = operands.data[1];												if(n == 0)						{							result32 = src;							ca = false;						}						else if(n & 0x20)						{							if(src < 0)							{								result32 = 0xffffffff;								if(src & 0x7fffffff) ca = true; else ca = false;							}							else							{								result32 = 0;								ca = false;							}						}						else						{							n = n & 0x1f;							result32 = (sword_t) src >> n;

⌨️ 快捷键说明

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