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

📄 sim.c

📁 计算机系统结构的讲义,浓缩了一本一千多页的书.真的是好东西.
💻 C
📖 第 1 页 / 共 5 页
字号:
	/*	 * Execute the instruction.	 */	execute:	machPtr->operationCount[wordPtr->opCode]++;	switch (wordPtr->opCode) {	    case OP_NOP:                 Isu_Issue(machPtr, wordPtr, INT, NON_OP, NON_OP, NON_OP);                break;	    case OP_ADD: {	        int sum;		opPtr = Isu_Issue(machPtr, wordPtr, INT, INT_OP, INT_OP, INT_OP);		sum = opPtr->source1[0] + opPtr->source2[0];		if (!((opPtr->source1[0] ^ opPtr->source2[0])			& SIGN_BIT) && ((opPtr->source1[0]			^ sum) & SIGN_BIT)) {		    result = Overflow(machPtr);		    if (result != TCL_OK) {			goto stopSimulation;		    } else {			goto endOfIns;		    }		}		opPtr->result[0] = sum;		break;            }	    case OP_ADDI: {	        int sum;		opPtr = Isu_Issue(machPtr, wordPtr, INT, INT_OP, IMM_OP, INT_OP);		sum = opPtr->source1[0] + wordPtr->extra;		if (!((opPtr->source1[0] ^ wordPtr->extra)			& SIGN_BIT) && ((opPtr->source1[0]			^ sum) & SIGN_BIT)) {		    result = Overflow(machPtr);		    if (result != TCL_OK) {			goto stopSimulation;		    } else {			goto endOfIns;		    }		}		opPtr->result[0] = sum;		break;            }	    case OP_ADDU:		opPtr = Isu_Issue(machPtr, wordPtr, INT, INT_OP, INT_OP, INT_OP);		opPtr->result[0] = opPtr->source1[0] + opPtr->source2[0];		break;	    case OP_ADDUI:		opPtr = Isu_Issue(machPtr, wordPtr, INT, INT_OP, IMM_OP, INT_OP);		opPtr->result[0] = opPtr->source1[0] + (wordPtr->extra & 0xffff);		break;	    case OP_AND:		opPtr = Isu_Issue(machPtr, wordPtr, INT, INT_OP, INT_OP, INT_OP);		opPtr->result[0] = opPtr->source1[0] & opPtr->source2[0];		break;	    case OP_ANDI:		opPtr = Isu_Issue(machPtr, wordPtr, INT, INT_OP, IMM_OP, INT_OP);		opPtr->result[0] = opPtr->source1[0] & (wordPtr->extra & 0xffff);		break;	    case OP_BEQZ:	    case OP_BFPF:	        opPtr = Isu_Issue(machPtr, wordPtr, BRANCH, INT_OP, NON_OP, NON_OP);	        if (opPtr->source1[0] == 0) {	    	  pc = machPtr->regs[NEXT_PC_REG] + ADDR_TO_INDEX(wordPtr->extra);		  machPtr->branchYes++;	        }	        else                   machPtr->branchNo++;	        machPtr->branchSerial = machPtr->insCount;	        machPtr->branchPC = INDEX_TO_ADDR(machPtr->regs[PC_REG]);	        break;	    	    case OP_BNEZ:            case OP_BFPT:                opPtr = Isu_Issue(machPtr, wordPtr, BRANCH, INT_OP, NON_OP, NON_OP);      	        if (opPtr->source1[0] != 0) {	  	  pc = machPtr->regs[NEXT_PC_REG] + ADDR_TO_INDEX(wordPtr->extra);		  machPtr->branchYes++;	        }	        else                   machPtr->branchNo++;	        machPtr->branchSerial = machPtr->insCount;	        machPtr->branchPC = INDEX_TO_ADDR(machPtr->regs[PC_REG]);	        break;	    case OP_JAL:                opPtr = Isu_Issue(machPtr, wordPtr, BRANCH, NON_OP, NON_OP, INT_OP);		opPtr->result[0] = INDEX_TO_ADDR(machPtr->regs[NEXT_PC_REG] + 1);		pc = machPtr->regs[NEXT_PC_REG] + ADDR_TO_INDEX(wordPtr->extra);		machPtr->branchSerial = machPtr->insCount;		machPtr->branchPC = INDEX_TO_ADDR(machPtr->regs[PC_REG]);		break;	    case OP_J:                Isu_Issue(machPtr, wordPtr, BRANCH, NON_OP, NON_OP, NON_OP);		pc = machPtr->regs[NEXT_PC_REG] + ADDR_TO_INDEX(wordPtr->extra);		machPtr->branchSerial = machPtr->insCount;		machPtr->branchPC = INDEX_TO_ADDR(machPtr->regs[PC_REG]);		break;	    case OP_JALR:                opPtr = Isu_Issue(machPtr, wordPtr, BRANCH, INT_OP, NON_OP, INT_OP);		opPtr->result[0] = INDEX_TO_ADDR(machPtr->regs[NEXT_PC_REG] + 1);		tmp = opPtr->source1[0];		pc = ADDR_TO_INDEX(tmp);		if ((tmp & 0x3) && (machPtr->badPC == 0)) {		    machPtr->badPC = tmp;		    machPtr->addrErrNum = machPtr->insCount + 2;		    if (checkNum > machPtr->addrErrNum) {			checkNum = machPtr->addrErrNum;		    }		}		machPtr->branchSerial = machPtr->insCount;		machPtr->branchPC = INDEX_TO_ADDR(machPtr->regs[PC_REG]);		break;	    case OP_JR:		opPtr = Isu_Issue(machPtr, wordPtr, BRANCH, INT_OP, NON_OP, NON_OP);		tmp = opPtr->source1[0];		pc = ADDR_TO_INDEX(tmp);		if ((tmp & 0x3) && (machPtr->badPC == 0)) {		    machPtr->badPC = tmp;		    machPtr->addrErrNum = machPtr->insCount + 2;		    if (checkNum > machPtr->addrErrNum) {			checkNum = machPtr->addrErrNum;		    }		}		machPtr->branchSerial = machPtr->insCount;		machPtr->branchPC = INDEX_TO_ADDR(machPtr->regs[PC_REG]);		break;	    case OP_LB:	    case OP_LBU: {		int value;		opPtr = Isu_Issue(machPtr, wordPtr, LOAD_BUF, INT_OP, NON_OP, INT_OP);		tmp = opPtr->address;		if (ReadMem(machPtr, tmp, &value) == 0) {		    goto stopSimulation;		}		switch (tmp & 0x3) {		    case 0:			value >>= 24;			break;		    case 1:			value >>= 16;			break;		    case 2:			value >>= 8;		}		if ((value & 0x80) && (wordPtr->opCode == OP_LB)) {		    value |= 0xffffff00;		} else {		    value &= 0xff;		}                opPtr->result[0] = value;		break;	    }	    case OP_LD:                 opPtr = Isu_Issue(machPtr, wordPtr, LOAD_BUF, INT_OP, NON_OP, DFP_OP);		tmp = opPtr->address;		if (tmp & 0x3) {		    result = AddressError(machPtr, tmp, 1);		    if (result != TCL_OK) {			goto stopSimulation;		    } else {			goto endOfIns;		    }		}		if (ReadMem(machPtr, tmp, &(opPtr->result[0])) == 0) {		  goto stopSimulation;		}		if (ReadMem(machPtr, tmp+4, &(opPtr->result[1])) == 0) {		  goto stopSimulation;		}		break;	    case OP_LF:		opPtr = Isu_Issue(machPtr, wordPtr, LOAD_BUF, INT_OP, NON_OP, SFP_OP);		tmp = opPtr->address;		if (tmp & 0x3) {		    result = AddressError(machPtr, tmp, 1);		    if (result != TCL_OK) {			goto stopSimulation;		    } else {			goto endOfIns;		    }		}		if (ReadMem(machPtr, tmp, &(opPtr->result[0])) == 0) {		    goto stopSimulation;		}	        break;	    	    case OP_LH:	    case OP_LHU: {		int value;		opPtr = Isu_Issue(machPtr, wordPtr, LOAD_BUF, INT_OP, NON_OP, INT_OP);		tmp = opPtr->source1[0] + wordPtr->extra;		if (tmp & 0x1) {		    result = AddressError(machPtr, tmp, 1);		    if (result != TCL_OK) {			goto stopSimulation;		    } else {			goto endOfIns;		    }		}		if (ReadMem(machPtr, tmp, &value) == 0) {		    goto stopSimulation;		}		if (!(tmp & 0x2)) {		    value >>= 16;		}		if ((value & 0x8000) && (wordPtr->opCode == OP_LH)) {		    value |= 0xffff0000;		} else {		    value &= 0xffff;		}                opPtr->result[0] = value;		break;	    }	    case OP_LHI:		opPtr = Isu_Issue(machPtr, wordPtr, INT, IMM_OP, NON_OP, INT_OP);		opPtr->result[0] = wordPtr->extra << 16;		break;	    case OP_LW: 		opPtr = Isu_Issue(machPtr, wordPtr, LOAD_BUF, INT_OP, NON_OP, INT_OP);		tmp = opPtr->source1[0] + wordPtr->extra;		if (tmp & 0x3) {		    result = AddressError(machPtr, tmp, 1);		    if (result != TCL_OK) {			goto stopSimulation;		    } else {			goto endOfIns;		    }		}		if (ReadMem(machPtr, tmp, &(opPtr->result[0])) == 0) {		    goto stopSimulation;		}		break;	  	    case OP_MOVD: 		opPtr = Isu_Issue(machPtr, wordPtr, INT, DFP_OP, NON_OP, DFP_OP);                *((double *)&(opPtr->result[0])) = *((double *)&(opPtr->source1[0]));	        break;	    case OP_MOVF: 		opPtr = Isu_Issue(machPtr, wordPtr, INT, SFP_OP, NON_OP, SFP_OP);                *((float *)&(opPtr->result[0])) = *((float *)&(opPtr->source1[0]));	        break;	    case OP_MOVFP2I: 	    case OP_MOVI2FP:		opPtr = Isu_Issue(machPtr, wordPtr, INT, INT_OP, NON_OP, INT_OP);                opPtr->result[0] = opPtr->source1[0];	        break;	    case OP_MOVI2S:	        errMsg = "MOVI2S instruction is unimplemented";	        goto error;	    case OP_MOVS2I:	        errMsg = "MOVS2I instruction is unimplemented";	        goto error;	    case OP_OR:	        opPtr = Isu_Issue(machPtr, wordPtr, INT, INT_OP, INT_OP, INT_OP);		opPtr->result[0] = opPtr->source1[0] | opPtr->source2[0];		break;	    case OP_ORI:	        opPtr = Isu_Issue(machPtr, wordPtr, INT, INT_OP, IMM_OP, INT_OP);		opPtr->result[0] = opPtr->source1[0] | (wordPtr->extra & 0xffff);		break;	    case OP_RFE:	        errMsg = "RFE instruction is unimplemented";	        goto error;	    case OP_SB:		opPtr = Isu_Issue(machPtr, wordPtr, STORE_BUF, INT_OP, INT_OP, NON_OP);		tmp = opPtr->address;		if (WriteMem(machPtr, tmp, 1, opPtr->source2[0]) == 0) 		    goto stopSimulation;				break;	    case OP_SD:                 opPtr = Isu_Issue(machPtr, wordPtr, STORE_BUF, INT_OP, DFP_OP, NON_OP);		tmp = opPtr->address;	        if (WriteMem(machPtr, tmp, 4, opPtr->source2[0]) == 0)		    goto stopSimulation;	        if (WriteMem(machPtr, tmp + 4, 4, opPtr->source2[1]) == 0)		    goto stopSimulation;		        break;	    case OP_SEQ:		opPtr = Isu_Issue(machPtr, wordPtr, INT, INT_OP, INT_OP, INT_OP);		if (opPtr->source1[0] == opPtr->source2[0]) 		  opPtr->result[0] = 1;		else		  opPtr->result[0] = 0;		break;	    case OP_SEQI:		opPtr = Isu_Issue(machPtr, wordPtr, INT, INT_OP, IMM_OP, INT_OP);		if (opPtr->source1[0] == wordPtr->extra) 		  opPtr->result[0] = 1;		else		  opPtr->result[0] = 0;		break;	    case OP_SEQU:		opPtr = Isu_Issue(machPtr, wordPtr, INT, INT_OP, INT_OP, INT_OP);		if (((unsigned int) opPtr->source1[0]) ==                    ((unsigned int) opPtr->source2[0])) 		  opPtr->result[0] = 1;		else		  opPtr->result[0] = 0;		break;	    case OP_SEQUI:		opPtr = Isu_Issue(machPtr, wordPtr, INT, INT_OP, IMM_OP, INT_OP);		if (((unsigned int) opPtr->source1[0]) ==                    ((unsigned int) wordPtr->extra)) 		  opPtr->result[0] = 1;		else		  opPtr->result[0] = 0;		break;	    case OP_SF:	        opPtr = Isu_Issue(machPtr, wordPtr, STORE_BUF, INT_OP, SFP_OP, NON_OP);		tmp = opPtr->address;	        if (WriteMem(machPtr, tmp, 4, opPtr->source2[0]) == 0)		    goto stopSimulation;	        break;	      	    case OP_SGE:		opPtr = Isu_Issue(machPtr, wordPtr, INT, INT_OP, INT_OP, INT_OP);		if (opPtr->source1[0] >= opPtr->source2[0]) 		  opPtr->result[0] = 1;		else		  opPtr->result[0] = 0;		break;	    case OP_SGEI:		opPtr = Isu_Issue(machPtr, wordPtr, INT, INT_OP, IMM_OP, INT_OP);		if (opPtr->source1[0] >= wordPtr->extra) 		  opPtr->result[0] = 1;		else		  opPtr->result[0] = 0;		break;	    case OP_SGEU:		opPtr = Isu_Issue(machPtr, wordPtr, INT, INT_OP, INT_OP, INT_OP);		if (((unsigned int) opPtr->source1[0]) >=                    ((unsigned int) opPtr->source2[0])) 		  opPtr->result[0] = 1;		else		  opPtr->result[0] = 0;		break;	    case OP_SGEUI:		opPtr = Isu_Issue(machPtr, wordPtr, INT, INT_OP, IMM_OP, INT_OP);		if (((unsigned int) opPtr->source1[0]) >=                    ((unsigned int) wordPtr->extra)) 		  opPtr->result[0] = 1;		else		  opPtr->result[0] = 0;		break;       	    case OP_SGT:		opPtr = Isu_Issue(machPtr, wordPtr, INT, INT_OP, INT_OP, INT_OP);		if (opPtr->source1[0] > opPtr->source2[0]) 		  opPtr->result[0] = 1;		else		  opPtr->result[0] = 0;		break;	    case OP_SGTI:		opPtr = Isu_Issue(machPtr, wordPtr, INT, INT_OP, IMM_OP, INT_OP);		if (opPtr->source1[0] > wordPtr->extra) 		  opPtr->result[0] = 1;		else		  opPtr->result[0] = 0;		break;	    case OP_SGTU:		opPtr = Isu_Issue(machPtr, wordPtr, INT, INT_OP, INT_OP, INT_OP);		if (((unsigned int) opPtr->source1[0]) >                    ((unsigned int) opPtr->source2[0])) 		  opPtr->result[0] = 1;		else		  opPtr->result[0] = 0;		break;	    case OP_SGTUI:		opPtr = Isu_Issue(machPtr, wordPtr, INT, INT_OP, IMM_OP, INT_OP);		if (((unsigned int) opPtr->source1[0]) >                    ((unsigned int) wordPtr->extra)) 		  opPtr->result[0] = 1;		else		  opPtr->result[0] = 0;		break;	    case OP_SH:		opPtr = Isu_Issue(machPtr, wordPtr, STORE_BUF, INT_OP, INT_OP, NON_OP);		tmp = opPtr->address;	        if (WriteMem(machPtr, tmp, 2, opPtr->source2[0]) == 0)		    goto stopSimulation;	        break;		    case OP_SLE:		opPtr = Isu_Issue(machPtr, wordPtr, INT, INT_OP, INT_OP, INT_OP);		if (opPtr->source1[0] <= opPtr->source2[0]) 		  opPtr->result[0] = 1;		else		  opPtr->result[0] = 0;		break;	    case OP_SLEI:		opPtr = Isu_Issue(machPtr, wordPtr, INT, INT_OP, IMM_OP, INT_OP);		if (opPtr->source1[0] <= wordPtr->extra) 		    opPtr->result[0] = 1;		else 		    opPtr->result[0] = 0;

⌨️ 快捷键说明

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