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

📄 mipssim.cc

📁 nachos系统作业 实现线程系统 实现一个电梯模拟 附实验报告
💻 CC
📖 第 1 页 / 共 2 页
字号:
	      case OP_MFLO:	registers[instr->rd] = registers[LoReg];	break;	      case OP_MTHI:	registers[HiReg] = registers[instr->rs];	break;	      case OP_MTLO:	registers[LoReg] = registers[instr->rs];	break;	      case OP_MULT:	Mult(registers[instr->rs], registers[instr->rt], TRUE,	     &registers[HiReg], &registers[LoReg]);	break;	      case OP_MULTU:	Mult(registers[instr->rs], registers[instr->rt], FALSE,	     &registers[HiReg], &registers[LoReg]);	break;	      case OP_NOR:	registers[instr->rd] = ~(registers[instr->rs] | registers[instr->rt]);	break;	      case OP_OR:	registers[instr->rd] = registers[instr->rs] | registers[instr->rs];	break;	      case OP_ORI:	registers[instr->rt] = registers[instr->rs] | (instr->extra & 0xffff);	break;	      case OP_SB:	if (!machine->WriteMem((unsigned) 		(registers[instr->rs] + instr->extra), 1, registers[instr->rt]))	    return;	break;	      case OP_SH:	if (!machine->WriteMem((unsigned) 		(registers[instr->rs] + instr->extra), 2, registers[instr->rt]))	    return;	break;	      case OP_SLL:	registers[instr->rd] = registers[instr->rt] << instr->extra;	break;	      case OP_SLLV:	registers[instr->rd] = registers[instr->rt] <<	    (registers[instr->rs] & 0x1f);	break;	      case OP_SLT:	if (registers[instr->rs] < registers[instr->rt])	    registers[instr->rd] = 1;	else	    registers[instr->rd] = 0;	break;	      case OP_SLTI:	if (registers[instr->rs] < instr->extra)	    registers[instr->rt] = 1;	else	    registers[instr->rt] = 0;	break;	      case OP_SLTIU:	  	rs = registers[instr->rs];	imm = instr->extra;	if (rs < imm)	    registers[instr->rt] = 1;	else	    registers[instr->rt] = 0;	break;      	      case OP_SLTU:	  	rs = registers[instr->rs];	rt = registers[instr->rt];	if (rs < rt)	    registers[instr->rd] = 1;	else	    registers[instr->rd] = 0;	break;      	      case OP_SRA:	registers[instr->rd] = registers[instr->rt] >> instr->extra;	break;	      case OP_SRAV:	registers[instr->rd] = registers[instr->rt] >>	    (registers[instr->rs] & 0x1f);	break;	      case OP_SRL:	tmp = registers[instr->rt];	tmp >>= instr->extra;	registers[instr->rd] = tmp;	break;	      case OP_SRLV:	tmp = registers[instr->rt];	tmp >>= (registers[instr->rs] & 0x1f);	registers[instr->rd] = tmp;	break;	      case OP_SUB:	  	diff = registers[instr->rs] - registers[instr->rt];	if (((registers[instr->rs] ^ registers[instr->rt]) & SIGN_BIT) &&	    ((registers[instr->rs] ^ diff) & SIGN_BIT)) {	    RaiseException(OverflowException, 0);	    return;	}	registers[instr->rd] = diff;	break;      	      case OP_SUBU:	registers[instr->rd] = registers[instr->rs] - registers[instr->rt];	break;	      case OP_SW:	if (!machine->WriteMem((unsigned) 		(registers[instr->rs] + instr->extra), 4, registers[instr->rt]))	    return;	break;	      case OP_SWL:	  	tmp = registers[instr->rs] + instr->extra;	// The little endian/big endian swap code would        // fail (I think) if the other cases are ever exercised.	ASSERT((tmp & 0x3) == 0);  	if (!machine->ReadMem((tmp & ~0x3), 4, &value))	    return;	switch (tmp & 0x3) {	  case 0:	    value = registers[instr->rt];	    break;	  case 1:	    value = (value & 0xff000000) | ((registers[instr->rt] >> 8) &					    0xffffff);	    break;	  case 2:	    value = (value & 0xffff0000) | ((registers[instr->rt] >> 16) &					    0xffff);	    break;	  case 3:	    value = (value & 0xffffff00) | ((registers[instr->rt] >> 24) &					    0xff);	    break;	}	if (!machine->WriteMem((tmp & ~0x3), 4, value))	    return;	break;    	      case OP_SWR:	  	tmp = registers[instr->rs] + instr->extra;	// The little endian/big endian swap code would        // fail (I think) if the other cases are ever exercised.	ASSERT((tmp & 0x3) == 0);  	if (!machine->ReadMem((tmp & ~0x3), 4, &value))	    return;	switch (tmp & 0x3) {	  case 0:	    value = (value & 0xffffff) | (registers[instr->rt] << 24);	    break;	  case 1:	    value = (value & 0xffff) | (registers[instr->rt] << 16);	    break;	  case 2:	    value = (value & 0xff) | (registers[instr->rt] << 8);	    break;	  case 3:	    value = registers[instr->rt];	    break;	}	if (!machine->WriteMem((tmp & ~0x3), 4, value))	    return;	break;    	      case OP_SYSCALL:	RaiseException(SyscallException, 0);	return; 	      case OP_XOR:	registers[instr->rd] = registers[instr->rs] ^ registers[instr->rt];	break;	      case OP_XORI:	registers[instr->rt] = registers[instr->rs] ^ (instr->extra & 0xffff);	break;	      case OP_RES:      case OP_UNIMP:	RaiseException(IllegalInstrException, 0);	return;	      default:	ASSERT(FALSE);    }        // Now we have successfully executed the instruction.        // Do any delayed load operation    DelayedLoad(nextLoadReg, nextLoadValue);        // Advance program counters.    registers[PrevPCReg] = registers[PCReg];	// for debugging, in case we						// are jumping into lala-land    registers[PCReg] = registers[NextPCReg];    registers[NextPCReg] = pcAfter;}//----------------------------------------------------------------------// Machine::DelayedLoad// 	Simulate effects of a delayed load.//// 	NOTE -- RaiseException/CheckInterrupts must also call DelayedLoad,//	since any delayed load must get applied before we trap to the kernel.//----------------------------------------------------------------------voidMachine::DelayedLoad(int nextReg, int nextValue){    registers[registers[LoadReg]] = registers[LoadValueReg];    registers[LoadReg] = nextReg;    registers[LoadValueReg] = nextValue;    registers[0] = 0; 	// and always make sure R0 stays zero.}//----------------------------------------------------------------------// Instruction::Decode// 	Decode a MIPS instruction //----------------------------------------------------------------------voidInstruction::Decode(){    OpInfo *opPtr;        rs = (value >> 21) & 0x1f;    rt = (value >> 16) & 0x1f;    rd = (value >> 11) & 0x1f;    opPtr = &opTable[(value >> 26) & 0x3f];    opCode = opPtr->opCode;    if (opPtr->format == IFMT) {	extra = value & 0xffff;	if (extra & 0x8000) {    	   extra |= 0xffff0000;	}    } else if (opPtr->format == RFMT) {	extra = (value >> 6) & 0x1f;    } else {	extra = value & 0x3ffffff;    }    if (opCode == SPECIAL) {	opCode = specialTable[value & 0x3f];    } else if (opCode == BCOND) {	int i = value & 0x1f0000;	if (i == 0) {    	    opCode = OP_BLTZ;	} else if (i == 0x10000) {    	    opCode = OP_BGEZ;	} else if (i == 0x100000) {    	    opCode = OP_BLTZAL;	} else if (i == 0x110000) {    	    opCode = OP_BGEZAL;	} else {    	    opCode = OP_UNIMP;	}    }}//----------------------------------------------------------------------// Mult// 	Simulate R2000 multiplication.// 	The words at *hiPtr and *loPtr are overwritten with the// 	double-length result of the multiplication.//----------------------------------------------------------------------static voidMult(int a, int b, bool signedArith, int* hiPtr, int* loPtr){    if ((a == 0) || (b == 0)) {	*hiPtr = *loPtr = 0;	return;    }    // Compute the sign of the result, then make everything positive    // so unsigned computation can be done in the main loop.    bool negative = FALSE;    if (signedArith) {	if (a < 0) {	    negative = !negative;	    a = -a;	}	if (b < 0) {	    negative = !negative;	    b = -b;	}    }    // Compute the result in unsigned arithmetic (check a's bits one at    // a time, and add in a shifted value of b).    unsigned int bLo = b;    unsigned int bHi = 0;    unsigned int lo = 0;    unsigned int hi = 0;    for (int i = 0; i < 32; i++) {	if (a & 1) {	    lo += bLo;	    if (lo < bLo)  // Carry out of the low bits?		hi += 1;	    hi += bHi;	    if ((a & 0xfffffffe) == 0)		break;	}	bHi <<= 1;	if (bLo & 0x80000000)	    bHi |= 1;		bLo <<= 1;	a >>= 1;    }    // If the result is supposed to be negative, compute the two's    // complement of the double-word result.    if (negative) {	hi = ~hi;	lo = ~lo;	lo++;	if (lo == 0)	    hi++;    }        *hiPtr = (int) hi;    *loPtr = (int) lo;}

⌨️ 快捷键说明

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