📄 sim.c
字号:
/* * 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 + -