📄 sim.c
字号:
Sim_DumpStats(clientData, interp, argc, argv) ClientData clientData; Tcl_Interp *interp; /* Current interpreter. */ int argc; /* Number of arguments. */ char **argv; /* Argument strings. */{ return TCL_OK;}/* *---------------------------------------------------------------------- * * Sim_GoCmd -- * * This procedure is invoked to process the "go" Tcl command. * See the user documentation for details on what it does. * * Results: * A standard Tcl result. * * Side effects: * See the user documentation. * *---------------------------------------------------------------------- */intSim_GoCmd(clientData, interp, argc, argv) ClientData clientData; Tcl_Interp *interp; /* Current interpreter. */ int argc; /* Number of arguments. */ char **argv; /* Argument strings. */{ DLX *machPtr = (DLX *) clientData; int effectiveCycleCount; if (argc > 2) { sprintf(interp->result, "too many args: should be \"%.50s\" [address]", argv[0]); return TCL_ERROR; } if (argc == 2) { char *end; int newPc; if (Sym_EvalExpr(machPtr, (char *) NULL, argv[1], 0, &newPc, &end) != TCL_OK) { return TCL_ERROR; } if ((*end != 0) || (newPc & 0x3)) { sprintf(interp->result, "\"%.50s\" isn't a valid starting address", argv[1]); return TCL_ERROR; } machPtr->regs[PC_REG] = ADDR_TO_INDEX(newPc); machPtr->regs[NEXT_PC_REG] = machPtr->regs[PC_REG] + 1; machPtr->flags = 0; machPtr->badPC = 0; } Tcl_VarEval(machPtr->interp, "ChangeCycleTitle 0; set fastmode 1", (char *)NULL); if (machPtr->config == BASICPIPE) { effectiveCycleCount = machPtr->nextIF; } else { effectiveCycleCount = machPtr->cycleCount; } if (machPtr->cycleDisplayMode && machPtr->cycleDisplayCount < effectiveCycleCount) { while (machPtr->cycleDisplayCount < effectiveCycleCount) { NextCycle (machPtr, interp); } } machPtr->cycleDisplayMode = 0; return Simulate(machPtr, interp, 0);}/* *---------------------------------------------------------------------- * * Sim_StepCmd -- * * This procedure is invoked to process the "step" Tcl command. * See the user documentation for details on what it does. * * Results: * A standard Tcl result. * * Side effects: * See the user documentation. * *---------------------------------------------------------------------- */intSim_StepCmd(clientData, interp, argc, argv) ClientData clientData; Tcl_Interp *interp; /* Current interpreter. */ int argc; /* Number of arguments. */ char **argv; /* Argument strings. */{ DLX *machPtr = (DLX *) clientData; int effectiveCycleCount; if (argc > 2) { sprintf(interp->result, "too many args: should be \"%.50s\" [address]", argv[0]); return TCL_ERROR; } if (argc == 2) { char *end; int newPc; if (Sym_EvalExpr(machPtr, (char *) NULL, argv[1], 0, &newPc, &end) != TCL_OK) { return TCL_ERROR; } if ((*end != 0) || (newPc & 0x3)) { sprintf(interp->result, "\"%.50s\" isn't a valid address", argv[1]); return TCL_ERROR; } machPtr->regs[PC_REG] = ADDR_TO_INDEX(newPc); machPtr->regs[NEXT_PC_REG] = machPtr->regs[PC_REG] + 1; machPtr->flags = 0; machPtr->badPC = 0; } Tcl_VarEval(machPtr->interp, "ChangeCycleTitle 0; set fastmode 0", (char *)NULL); if (machPtr->config == BASICPIPE) { effectiveCycleCount = machPtr->nextIF + 1; } else { effectiveCycleCount = machPtr->cycleCount; } if (machPtr->cycleDisplayMode && machPtr->cycleDisplayCount < effectiveCycleCount) { while (machPtr->cycleDisplayCount < effectiveCycleCount) { NextCycle (machPtr, interp); } machPtr->cycleDisplayMode = 0; return TCL_OK; } else { machPtr->cycleDisplayMode = 0; return Simulate(machPtr, interp, 1); }}/* *---------------------------------------------------------------------- * * Sim_CycleCmd -- * * This procedure is invoked to process the "cycle" Tcl command. * See the user documentation for details on what it does. * * Results: * A standard Tcl result. * * Side effects: * See the user documentation. * *---------------------------------------------------------------------- */intSim_CycleCmd(clientData, interp, argc, argv) ClientData clientData; Tcl_Interp *interp; /* Current interpreter. */ int argc; /* Number of arguments. */ char **argv; /* Argument strings. */{ DLX *machPtr = (DLX *) clientData; if (argc > 2) { sprintf(interp->result, "too many args: should be \"%.50s\" [address]", argv[0]); return TCL_ERROR; } if (argc == 2) { char *end; int newPc; if (Sym_EvalExpr(machPtr, (char *) NULL, argv[1], 0, &newPc, &end) != TCL_OK) { return TCL_ERROR; } if ((*end != 0) || (newPc & 0x3)) { sprintf(interp->result, "\"%.50s\" isn't a valid starting address", argv[1]); return TCL_ERROR; } machPtr->regs[PC_REG] = ADDR_TO_INDEX(newPc); machPtr->regs[NEXT_PC_REG] = machPtr->regs[PC_REG] + 1; machPtr->flags = 0; machPtr->badPC = 0; } if (!machPtr->cycleDisplayMode) { if (machPtr->config == BASICPIPE) machPtr->cycleDisplayCount = machPtr->lastIF + 1; else machPtr->cycleDisplayCount = machPtr->cycleCount; machPtr->cycleDisplayMode = 1; } Tcl_VarEval(machPtr->interp, "ChangeCycleTitle 1; set fastmode 0", (char *)NULL); return NextCycle(machPtr, interp);}/* *---------------------------------------------------------------------- * * Sim_CallBack -- * * Arrange for a particular procedure to be invoked after a given * number of instructions have been simulated. * * Results: * None. * * Side effects: * After numIns instructions have been executed, proc will be * invoked in the following way: * * void * proc(clientData, machPtr) * ClientData clientData; * DLX *machPtr; * { * } * * The clientData and machPtr arguments will be the same as those * passed to this procedure. *---------------------------------------------------------------------- */voidSim_CallBack(machPtr, numIns, proc, clientData) DLX *machPtr; /* Machine of interest. */ int numIns; /* Call proc after this many instructions * have been executed in machPtr. */ void (*proc)(); /* Procedure to call. */ ClientData clientData; /* Arbitrary one-word value to pass to proc. */{ register CallBack *cbPtr; cbPtr = (CallBack *) calloc(1, sizeof(CallBack)); cbPtr->serialNum = machPtr->insCount + numIns; cbPtr->proc = proc; cbPtr->clientData = clientData; if ((machPtr->callBackList == NULL) || (cbPtr->serialNum < machPtr->callBackList->serialNum)) { cbPtr->nextPtr = machPtr->callBackList; machPtr->callBackList = cbPtr; } else { register CallBack *cbPtr2; for (cbPtr2 = machPtr->callBackList; cbPtr2->nextPtr != NULL; cbPtr2 = cbPtr2->nextPtr) { if (cbPtr->serialNum < cbPtr2->nextPtr->serialNum) { break; } } cbPtr->nextPtr = cbPtr2->nextPtr; cbPtr2->nextPtr = cbPtr; } if (cbPtr->serialNum < checkNum) { checkNum = cbPtr->serialNum; }}/* *---------------------------------------------------------------------- * * Sim_Stop -- * * Arrange for the execution of the machine to stop after the * current instruction. * * Results: * None. * * Side effects: * The machine will stop executing (if it was executing in the * first place). * *---------------------------------------------------------------------- */voidSim_Stop(machPtr) DLX *machPtr; /* Machine to stop. */{ machPtr->flags |= STOP_REQUESTED; checkNum = machPtr->insCount + 1;}/* *---------------------------------------------------------------------- * * Sim_GetPC -- * * This procedure computes the current program counter for * machPtr. * * Results: * The return value is the current program counter for the * machine. This is a bit tricky to compute because the PC * is stored as an index, and there may have been an unaligned * value put in the PC. * * Side effects: * None. * *---------------------------------------------------------------------- */unsigned intSim_GetPC(machPtr) register DLX *machPtr; /* Machine whose PC is wanted. */{ if ((machPtr->badPC != 0) && (machPtr->insCount >= machPtr->addrErrNum)) { return machPtr->badPC; } return INDEX_TO_ADDR(machPtr->regs[PC_REG]);}intSim_EquationCmd(clientData, interp, argc, argv) ClientData clientData; Tcl_Interp *interp; /* Current interpreter. */ int argc; /* Number of arguments. */ char **argv; /* Argument strings. */{ DLX *machPtr = (DLX *) clientData; int unit; int cycle; Op *opPtr1, *opPtr2; Tcl_DString list; char part[20]; if (argc != 4) { interp->result = "wrong # args"; return TCL_ERROR; } unit = atoi(argv[1]); cycle = atoi(argv[2]); Tcl_DStringInit(&list); if (!(strcmp(argv[3], "issue"))) { for (opPtr1 = machPtr->opsList; opPtr1 != NULL; opPtr1 = opPtr1->nextPtr) { if (opPtr1->unit == unit) { if (opPtr1->rs1 != -1 && opPtr1->rs1 < 64) { if (opPtr1->rs1 < 32) sprintf(part, "R%d", opPtr1->rs1); else sprintf(part, "F%d", opPtr1->rs1 - 32); Tcl_DStringAppendElement(&list, part); if (opPtr1->rs1Ready) Tcl_DStringAppendElement(&list, "1"); else Tcl_DStringAppendElement(&list, "0"); } else { Tcl_DStringAppendElement(&list, ""); Tcl_DStringAppendElement(&list, "0"); } if (opPtr1->rs2 != -1 && opPtr1->rs2 < 64) { if (opPtr1->rs2 < 32) sprintf(part, "R%d", opPtr1->rs2); else sprintf(part, "F%d", opPtr1->rs2 - 32); Tcl_DStringAppendElement(&list, part); if (opPtr1->rs2Ready) Tcl_DStringAppendElement(&list, "1"); else Tcl_DStringAppendElement(&list, "0"); } else { Tcl_DStringAppendElement(&list, ""); Tcl_DStringAppendElement(&list, "0"); } if (opPtr1->resultType != NON_OP && opPtr1->rd < 64) { if (opPtr1->rd < 32) sprintf(part, "R%d", opPtr1->rd); else sprintf(part, "F%d", opPtr1->rd - 32); Tcl_DStringAppendElement(&list, part); } else { Tcl_DStringAppendElement(&list, ""); } Tcl_DStringResult(interp, &list); break; } } } else if (!(strcmp(argv[3], "write"))) { for (opPtr1 = machPtr->finishList; opPtr1 != NULL; opPtr1 = opPtr1->nextPtr) { if (opPtr1->resultType != NON_OP && opPtr1->unit == unit && opPtr1->rdReady == cycle) { if (machPtr->waiting_regs[opPtr1->rd] == 0) { if (opPtr1->rd < 32) sprintf(part, "R%d", opPtr1->rd); else sprintf(part, "F%d", opPtr1->rd - 32); Tcl_DStringAppendElement(&list, part); } else { Tcl_DStringAppendElement(&list, ""); } for (opPtr2 = machPtr->opsList; opPtr2 != NULL; opPtr2 = opPtr2->nextPtr) { if (opPtr2->rs1 == opPtr1->rd && opPtr2->rs1Ready > cycle) { if (machPtr->config == TOMASULO && opPtr2->rs1Ready != cycle + 1) continue; Tcl_DStringAppendElement(&list, "1"); sprintf(part, "%s", Units[opPtr2->unit]); Tcl_DStringAppendElement(&list, part); } } for (opPtr2 = machPtr->opsList; opPtr2 != NULL; opPtr2 = opPtr2->nextPtr) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -