📄 sim.c
字号:
break; case OP_SLEU: 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_SLEUI: 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_SLL: opPtr = Isu_Issue(machPtr, wordPtr, INT, INT_OP, INT_OP, INT_OP); opPtr->result[0] = opPtr->source2[0] << (opPtr->source1[0] & 0x1f); break; case OP_SLLI: opPtr = Isu_Issue(machPtr, wordPtr, INT, IMM_OP, INT_OP, INT_OP); opPtr->result[0] = opPtr->source2[0] << wordPtr->extra; break; case OP_SLT: 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_SLTI: 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_SLTU: 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_SLTUI: 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_SNE: 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_SNEI: 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_SNEU: 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_SNEUI: 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_SRA: opPtr = Isu_Issue(machPtr, wordPtr, INT, INT_OP, INT_OP, INT_OP); opPtr->result[0] = opPtr->source2[0] >> (opPtr->source1[0] & 0x1f); break; case OP_SRAI: opPtr = Isu_Issue(machPtr, wordPtr, INT, IMM_OP, INT_OP, INT_OP); opPtr->result[0] = opPtr->source2[0] >> wordPtr->extra; break; case OP_SRL: opPtr = Isu_Issue(machPtr, wordPtr, INT, INT_OP, INT_OP, INT_OP); tmp = opPtr->source2[0]; tmp >>= (opPtr->source1[0] & 0x1f); opPtr->result[0] = tmp; break; case OP_SRLI: opPtr = Isu_Issue(machPtr, wordPtr, INT, IMM_OP, INT_OP, INT_OP); tmp = opPtr->source2[0]; tmp >>= wordPtr->extra; opPtr->result[0] = tmp; break; case OP_SUB: { int diff; opPtr = Isu_Issue(machPtr, wordPtr, INT, INT_OP, INT_OP, INT_OP); diff = opPtr->source1[0] - opPtr->source2[0]; if (((opPtr->source1[0] ^ opPtr->source2[0]) & SIGN_BIT) && ((opPtr->source1[0] ^ diff) & SIGN_BIT)) { result = Overflow(machPtr); if (result != TCL_OK) { goto stopSimulation; } else { goto endOfIns; } } opPtr->result[0] = diff; break; } case OP_SUBI: { int diff; opPtr = Isu_Issue(machPtr, wordPtr, INT, INT_OP, IMM_OP, INT_OP); diff = opPtr->source1[0] - wordPtr->extra; if (((opPtr->source1[0] ^ wordPtr->extra) & SIGN_BIT) && ((opPtr->source1[0] ^ diff) & SIGN_BIT)) { result = Overflow(machPtr); if (result != TCL_OK) { goto stopSimulation; } else { goto endOfIns; } } opPtr->result[0] = diff; break; } case OP_SUBU: opPtr = Isu_Issue(machPtr, wordPtr, INT, INT_OP, INT_OP, INT_OP); opPtr->result[0] = opPtr->source1[0] - opPtr->source2[0]; break; case OP_SUBUI: opPtr = Isu_Issue(machPtr, wordPtr, INT, INT_OP, IMM_OP, INT_OP); opPtr->result[0] = opPtr->source1[0] - (wordPtr->extra & 0xffff); break; case OP_SW: opPtr = Isu_Issue(machPtr, wordPtr, STORE_BUF, INT_OP, INT_OP, NON_OP); tmp = opPtr->address; if (WriteMem(machPtr, tmp, 4, opPtr->source2[0]) == 0) goto stopSimulation; break; case OP_TRAP: opPtr = Isu_Issue(machPtr, wordPtr, INT, NON_OP, NON_OP, NON_OP); switch (Trap_Handle(machPtr, (wordPtr->extra & 0x3ffffff))) { case 1 : printf("TRAP #%d failed\n", wordPtr->extra & 0x3ffffff); trapCaught = 1; break; case 2 : printf("TRAP #%d received\n", wordPtr->extra & 0x3ffffff); if (!wordPtr->extra) Tcl_VarEval(machPtr->interp, "Trap0", (char *)NULL); trapCaught = 1; break; } break; case OP_XOR: opPtr = Isu_Issue(machPtr, wordPtr, INT, INT_OP, INT_OP, INT_OP); opPtr->result[0] = opPtr->source1[0] ^ opPtr->source2[0]; break; case OP_XORI: opPtr = Isu_Issue(machPtr, wordPtr, INT, INT_OP, NON_OP, INT_OP); opPtr->result[0] = opPtr->source1[0] ^ (wordPtr->extra & 0xffff); break;/* floating point operations */ case OP_DIV: opPtr = Isu_Issue(machPtr, wordPtr, FP_DIV, INT_OP, INT_OP, INT_OP); if (opPtr->source2[0]) { opPtr->result[0] = opPtr->source1[0] / opPtr->source2[0]; } else { errMsg = "divide by zero"; goto error; } break; case OP_DIVU: opPtr = Isu_Issue(machPtr, wordPtr, FP_DIV, INT_OP, INT_OP, INT_OP); if (*((unsigned int *)&(opPtr->source2[0]))) { *((unsigned int *)&(opPtr->result[0])) = *((unsigned int *)&(opPtr->source1[0])) / *((unsigned int *)&(opPtr->source2[0])); } else { errMsg = "divide by zero"; goto error; } break; case OP_MULT: opPtr = Isu_Issue(machPtr, wordPtr, FP_MUL, INT_OP, INT_OP, INT_OP); if (Mult(opPtr->source1[0], opPtr->source2[0], 1, &opPtr->result[0])) { errMsg = "signed multiply overflow"; goto error; } break; case OP_MULTU: opPtr = Isu_Issue(machPtr, wordPtr, FP_MUL, INT_OP, INT_OP, INT_OP); if (Mult(opPtr->source1[0], opPtr->source2[0], 0, &opPtr->result[0])) { errMsg = "signed multiply overflow"; goto error; } break; case OP_ADDD: opPtr = Isu_Issue(machPtr, wordPtr, FP_ADD, DFP_OP, DFP_OP, DFP_OP); *((double *)&(opPtr->result[0])) = *((double *)&(opPtr->source1[0])) + *((double *)&(opPtr->source2[0])); break; case OP_ADDF: opPtr = Isu_Issue(machPtr, wordPtr, FP_ADD, SFP_OP, SFP_OP, SFP_OP); *((float *)&(opPtr->result[0])) = *((float *)&(opPtr->source1[0])) + *((float *)&(opPtr->source2[0])); break; case OP_CVTD2F: opPtr = Isu_Issue(machPtr, wordPtr, INT, DFP_OP, NON_OP, SFP_OP); *((float *)&(opPtr->result[0])) = *((double *)&(opPtr->source1[0])); break; case OP_CVTD2I: opPtr = Isu_Issue(machPtr, wordPtr, INT, DFP_OP, NON_OP, INT_OP); *((int *)&(opPtr->result[0])) = *((double *)&(opPtr->source1[0])); break; case OP_CVTF2D: opPtr = Isu_Issue(machPtr, wordPtr, INT, SFP_OP, NON_OP, DFP_OP); *((double *)&(opPtr->result[0])) = *((float *)&(opPtr->source1[0])); break; case OP_CVTF2I: opPtr = Isu_Issue(machPtr, wordPtr, INT, SFP_OP, NON_OP, INT_OP); *((int *)&(opPtr->result[0])) = *((float *)&(opPtr->source1[0])); break; case OP_CVTI2D: opPtr = Isu_Issue(machPtr, wordPtr, INT, INT_OP, NON_OP, DFP_OP); *((double *)&(opPtr->result[0])) = *((int *)&(opPtr->source1[0])); break; case OP_CVTI2F: opPtr = Isu_Issue(machPtr, wordPtr, INT, INT_OP, NON_OP, SFP_OP); *((float *)&(opPtr->result[0])) = *((int *)&(opPtr->source1[0])); break; case OP_DIVD: opPtr = Isu_Issue(machPtr, wordPtr, FP_DIV, DFP_OP, DFP_OP, DFP_OP); if (*((double *)&(opPtr->source2[0]))) { *((double *)&(opPtr->result[0])) = *((double *)&(opPtr->source1[0])) / *((double *)&(opPtr->source2[0])); } else { errMsg = "divide by zero"; goto error; } break; case OP_DIVF: opPtr = Isu_Issue(machPtr, wordPtr, FP_DIV, SFP_OP, SFP_OP, SFP_OP); if (*((float *)&(opPtr->source2[0]))) { *((float *)&(opPtr->result[0])) = *((float *)&(opPtr->source1[0])) / *((float *)&(opPtr->source2[0])); } else { errMsg = "divide by zero"; goto error; } break; case OP_EQD: opPtr = Isu_Issue(machPtr, wordPtr, INT, DFP_OP, DFP_OP, INT_OP); opPtr->result[0] = *((double *)&(opPtr->source1[0])) == *((double *)&(opPtr->source2[0])); break; case OP_EQF: opPtr = Isu_Issue(machPtr, wordPtr, INT, SFP_OP, SFP_OP, INT_OP); opPtr->result[0] = *((float *)&(opPtr->source1[0])) == *((float *)&(opPtr->source2[0])); break; case OP_GED: opPtr = Isu_Issue(machPtr, wordPtr, INT, DFP_OP, DFP_OP, INT_OP); opPtr->result[0] = *((double *)&(opPtr->source1[0])) >= *((double *)&(opPtr->source2[0])); break; case OP_GEF: opPtr = Isu_Issue(machPtr, wordPtr, INT, SFP_OP, SFP_OP, INT_OP); opPtr->result[0] = *((float *)&(opPtr->source1[0])) >= *((float *)&(opPtr->source2[0])); break; case OP_GTD: opPtr = Isu_Issue(machPtr, wordPtr, INT, DFP_OP, DFP_OP, INT_OP); opPtr->result[0] = *((double *)&(opPtr->source1[0])) > *((double *)&(opPtr->source2[0])); break; case OP_GTF: opPtr = Isu_Issue(machPtr, wordPtr, INT, SFP_OP, SFP_OP, INT_OP); opPtr->result[0] = *((float *)&(opPtr->source1[0])) > *((float *)&(opPtr->source2[0])); break; case OP_LED: opPtr = Isu_Issue(machPtr, wordPtr, INT, DFP_OP, DFP_OP, INT_OP); opPtr->result[0] = *((double *)&(opPtr->source1[0])) <= *((double *)&(opPtr->source2[0])); break; case OP_LEF: opPtr = Isu_Issue(machPtr, wordPtr, INT, SFP_OP, SFP_OP, INT_OP); opPtr->result[0] = *((float *)&(opPtr->source1[0])) <= *((float *)&(opPtr->source2[0])); break; case OP_LTD: opPtr = Isu_Issue(machPtr, wordPtr, INT, DFP_OP, DFP_OP, INT_OP); opPtr->result[0] = *((double *)&(opPtr->source1[0])) < *((double *)&(opPtr->source2[0])); break; case OP_LTF: opPtr = Isu_Issue(machPtr, wordPtr, INT, SFP_OP, SFP_OP, INT_OP); opPtr->result[0] = *((float *)&(opPtr->source1[0])) < *((float *)&(opPtr->source2[0])); break; case OP_MULTD: opPtr = Isu_Issue(machPtr, wordPtr, FP_MUL, DFP_OP, DFP_OP, DFP_OP); *((double *)&(opPtr->result[0])) = *((double *)&(opPtr->source1[0])) * *((double *)&(opPtr->source2[0])); break; case OP_MULTF: opPtr = Isu_Issue(machPtr, wordPtr, FP_MUL, SFP_OP, SFP_OP, SFP_OP); *((float *)&(opPtr->result[0])) = *((float *)&(opPtr->source1[0])) * *((float *)&(opPtr->source2[0])); break; case OP_NED: opPtr = Isu_Issue(machPtr, wordPtr, INT, DFP_OP, DFP_OP, INT_OP); opPtr->result[0] = *((double *)&(opPtr->source1[0])) != *((double *)&(opPtr->source2[0])); break; case OP_NEF: opPtr = Isu_Issue(machPtr, wordPtr, INT, SFP_OP, SFP_OP, INT_OP); opPtr->result[0] = *((float *)&(opPtr->source1[0])) != *((float *)&(opPtr->source2[0])); break; case OP_SUBD: opPtr = Isu_Issue(machPtr, wordPtr, FP_ADD, DFP_OP, DFP_OP, DFP_OP); *((double *)&(opPtr->result[0])) = *((double *)&(opPtr->source1[0])) - *((double *)&(opPtr->source2[0])); break; case OP_SUBF: opPtr = Isu_Issue(machPtr, wordPtr, FP_ADD, SFP_OP, SFP_OP, SFP_OP); *((float *)&(opPtr->result[0])) = *((float *)&(opPtr->source1[0])) - *((float *)&(opPtr->source2[0])); break; case OP_NOT_COMPILED: Compile(wordPtr); goto execute; break; case OP_RES: errMsg = "reserved operation"; goto error; case OP_UNIMP: errMsg = "instruction not implemented in simulator"; goto error; default: i = wordPtr->opCode; sprintf(interp->result, "internal error in Simulate(): bad opCode %d, pc = %.100s", i, Sym_GetString(machPtr, Sim_GetPC(machPtr))); result = TCL_ERROR; goto stopSimulation; } /* * Make sure R0 stays zero. */ machPtr->regs[0] = 0; switch (machPtr->config) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -