示例#1
0
void execute_one_inst(processor_t* p, int prompt, int print_regs)
{
  inst_t inst;

  /* fetch an instruction */
  inst.bits = load_mem(p->pc, SIZE_WORD);

  /* interactive-mode prompt */
  if(prompt)
  {
    if (prompt == 1) {
      printf("simulator paused, enter to continue...");
      while(getchar() != '\n')
        ;
    }
    printf("%08x: ",p->pc);
    disassemble(inst);
  }
	uint32_t temp;
  switch (inst.rtype.opcode) /* could also use e.g. inst.itype.opcode */
  {
  case 0x0: // opcode == 0x0 (SPECIAL)
  
    switch (inst.rtype.funct) {
    	case 0x0: // funct == 0x0 (sll)
    		p->R[inst.rtype.rd] = p->R[inst.rtype.rt] << inst.rtype.shamt;
     	 	p->pc += 4;
      	break;    		
    
    	case 0x2: // funct == 0x0 (srl)
    		p->R[inst.rtype.rd] = p->R[inst.rtype.rt] >> inst.rtype.shamt;
     	 	p->pc += 4;
      	break;   
      
      case 0x3: // funct == 0x0 (sra)
      	p->R[inst.rtype.rd] = (signed)p->R[inst.rtype.rt] >> inst.rtype.shamt;
    		p->pc += 4;
      	break;
      
      case 0x8: // funct == 0x8 (jr)
      	p->pc = p->R[inst.rtype.rs];
    		break;
    	
    	case 0x9: // funct == 0x9 (jalr)
    		temp = p->pc + 4;
    		p->pc = p->R[inst.rtype.rs];
    		p->R[inst.rtype.rd] = temp;
    		break;
				
    	case 0x10: // funct == 0x10 (mfhi)
    		p->R[inst.rtype.rd] = p->RHI;
    		p->pc += 4;
    		break;
    
    	case 0x12: // funct == 0x12 (mflo)
    		p->R[inst.rtype.rd] = p->RLO;
    		p->pc += 4;
    		break;
    	
    	case 0x18: // funct == 0x18 (mult)
    		perform_mult(p->R[inst.rtype.rs], p->R[inst.rtype.rt], &(p->RHI), &(p->RLO));
    		p->pc += 4;
    		break;
    	
    	case 0x21: // funct == 0x21 (addu)
    		p->R[inst.rtype.rd] = p->R[inst.rtype.rs] + p->R[inst.rtype.rt];
    		p->pc += 4;
    		break;
    	
    	case 0x23: // funct == 0x23 (subu)
    		p->R[inst.rtype.rd] = p->R[inst.rtype.rs] - p->R[inst.rtype.rd];
    		p->pc += 4;
    		break;
    	
    	case 0x24: // funct == 0x24 (and)
    		p->R[inst.rtype.rd] = p->R[inst.rtype.rs] & p->R[inst.rtype.rt];
    		p->pc += 4;
    		break;
    	
    	case 0x26: // funct == 0x26 (xor)
    		p->R[inst.rtype.rd] = p->R[inst.rtype.rs] ^ p->R[inst.rtype.rt];
    		p->pc += 4;
    		break;
    	
    	case 0x27: // funct == 0x27 (nor)
    		p->R[inst.rtype.rd] = ~(p->R[inst.rtype.rs] | p->R[inst.rtype.rt]);
    		p->pc += 4;
    		break;
    	
    	case 0x2a: // funct == 0x2a (slt)
    		p->R[inst.rtype.rd] = (signed)p->R[inst.rtype.rs] < (signed)p->R[inst.rtype.rt];
    		p->pc += 4;
    		break;
    	
    	case 0x2b: // funct == 0x2a (sltu)
    		p->R[inst.rtype.rd] = p->R[inst.rtype.rs] < p->R[inst.rtype.rt];
    		p->pc += 4;
    		break;
    		
    	case 0xc: // funct == 0xc (SYSCALL)
      	handle_syscall(p);
     	 	p->pc += 4;
      	break;

    	case 0x25: // funct == 0x25 (OR)
      	p->R[inst.rtype.rd] = p->R[inst.rtype.rs] | p->R[inst.rtype.rt];
      	p->pc += 4;
      	break;

    	default: // undefined funct
      	fprintf(stderr, "%s: pc=%08x, illegal instruction=%08x\n", __FUNCTION__, p->pc, inst.bits);
      	exit(-1);
      	break;
    	}
    break;
	
	case 0x3: // opcode == 0x3 (jal)
		p->R[31] = p->pc += 4;
		p->pc = ((p->pc+4) & 0xf0000000) | (inst.jtype.addr << 2);
		break;
	
	case 0x4: // opcode == 0x4 (beq)
		if (p->R[inst.itype.rs] == p->R[inst.itype.rt]) {
			p->pc += 4 + signext(inst.itype.imm)*4;
		}
		else {
			p->pc += 4;
		}
		break;
	
	case 0x5: // opcode == 0x4 (bne)
		if (p->R[inst.itype.rs] != p->R[inst.itype.rt]) {
			p->pc += 4 + signext(inst.itype.imm)*4;
		}
		else {
			p->pc += 4;
		}
		break;
	
	case 0x9: // opcode == 0x9 (addiu)
		p->R[inst.rtype.rt] = p->R[inst.itype.rs] + signext(inst.itype.imm);
    p->pc += 4;
    break;
  
  case 0xa: // opcode == 0xa (slti)
  	p->R[inst.itype.rt] = (signed)p->R[inst.itype.rs] < signext(inst.itype.imm);
    p->pc += 4;
    break;
		
	case 0xb: // opcode == 0xb (sltiu)
		p->R[inst.rtype.rt] = (signed)p->R[inst.itype.rs] < signext(inst.itype.imm);
    p->pc += 4;
    break;
  
  case 0xc: // opcode == 0xc (andi)
  	p->R[inst.rtype.rt] = p->R[inst.itype.rs] & zeroext(inst.itype.imm);
  	p->pc += 4;
  	break;
  
  case 0xe: // opcode == 0xe (xori)
  	p->R[inst.rtype.rt] = p->R[inst.itype.rs] ^ zeroext(inst.itype.imm);
  	p->pc += 4;
  	break;
  
  case 0xf: // opcode == 0xf (lui)
  	p->R[inst.rtype.rt] = inst.itype.imm << 16;
  	p->pc += 4;
  	break;
  
  case 0x20: // opcode == 0x20 (lb)
  	p->R[inst.rtype.rt] = signext(load_mem(p->R[inst.itype.rs] + signext(inst.itype.imm), SIZE_BYTE));
  	p->pc += 4;
  	break;
  
  case 0x23: // opcode == 0x23 (lw)
  	p->R[inst.rtype.rt] = load_mem(p->R[inst.itype.rs] + signext(inst.itype.imm), SIZE_WORD);
  	p->pc += 4;
  	break;
  
  case 0x24: // opcode == 0x24 (lbu)
  	p->R[inst.itype.rt] = zeroext(load_mem(p->R[inst.itype.rs] + signext(inst.itype.imm), SIZE_WORD));
  	p->pc += 4;
  	break;
  
  case 0x28: // opcode == 0x28 (sb)
  	store_mem(p->R[inst.itype.rs] + signext(inst.itype.imm), SIZE_BYTE, p->R[inst.itype.rt]);
  	p->pc += 4;
  	break;
  
  case 0x2b: // opcode == 0x20 (sw)
  	store_mem(p->R[inst.itype.rs] + signext(inst.itype.imm), SIZE_WORD, p->R[inst.itype.rt]);
  	p->pc += 4;
  	break;
	
  case 0xd: // opcode == 0xd (ORI)
    p->R[inst.itype.rt] = (p->R[inst.itype.rs] | inst.itype.imm);
    p->pc += 4;
    break;

  case 0x2: // opcode == 0x2 (J)
    p->pc = ((p->pc+4) & 0xf0000000) | (inst.jtype.addr << 2);
    break;

  default: // undefined opcode
    fprintf(stderr, "%s: pc=%08x, illegal instruction: %08x\n", __FUNCTION__, p->pc, inst.bits);
    exit(-1);
    break;
  }

  // enforce $0 being hard-wired to 0
  p->R[0] = 0;

  if(print_regs) {
    print_registers(p);
	}
}
示例#2
0
void execute_one_inst(processor_t* p, int prompt, int print_regs)
{
	inst_t inst;
	
	/* fetch an instruction */
	inst.bits = load_mem(p->pc, SIZE_WORD);
	
	/* interactive-mode prompt */
	if(prompt)
	{
		if (prompt == 1) {
			printf("simulator paused, enter to continue...");
			while(getchar() != '\n')
				;
		}
		printf("%08x: ",p->pc);
		disassemble(inst);
	}
	
	switch (inst.rtype.opcode) /* could also use e.g. inst.itype.opcode */
	{
		case 0x0: // opcode == 0x0 (SPECIAL)
			
			switch (inst.rtype.funct)
		{
			case 0x0: //opcode = 0x0 (SLL)
				p->R[inst.rtype.rd] = p->R[inst.rtype.rt] << inst.rtype.shamt;
				p->pc += 4;
				break;
				
			case 0x2: //opcode = 0x2 (SRL)
				p->R[inst.rtype.rd] = p->R[inst.rtype.rt] >> inst.rtype.shamt;
				p->pc += 4;
				break;
				
			case 0x3: //opcode = 0x3 (SRA)
				p->R[inst.rtype.rd] = (signed int)(p->R[inst.rtype.rt]) >> inst.rtype.shamt;
				p->pc += 4;
				break;
				
			case 0x8: //opcode = 0x8 (JR)
				p->pc = p->R[inst.rtype.rs];
				break;
				
			case 0x9: //opcode = 0x9 (JALR)
			{
				int tmp = p->pc + 4;
				p->pc = p->R[inst.rtype.rs];
				p->R[inst.rtype.rd] = tmp;
			}
				break;
				
			case 0xc: // funct == 0xc (SYSCALL)
				handle_syscall(p);
				p->pc += 4;
				break;
				
			case 0x21: //opcode = 0x21 (ADDU)
				p->R[inst.rtype.rd] = p->R[inst.rtype.rs] + p->R[inst.rtype.rt];
				p->pc += 4;
				break;
				
			case 0x23: //opcode = 0x23 (SUBU)
				p->R[inst.rtype.rd] = p->R[inst.rtype.rs] - p->R[inst.rtype.rt]; 
				p->pc += 4;
				break;
				
			case 0x24: //opcode = 0x24 (AND)
				p->R[inst.rtype.rd] = p->R[inst.rtype.rs] & p->R[inst.rtype.rt];
				p->pc += 4;
				break;
				
			case 0x25: // funct == 0x25 (OR)
				p->R[inst.rtype.rd] = p->R[inst.rtype.rs] | p->R[inst.rtype.rt];
				p->pc += 4;
				break;
				
			case 0x26: // funct == 0x26 (XOR)
				p->R[inst.rtype.rd] = p->R[inst.rtype.rs] ^ p->R[inst.rtype.rt];
				p->pc += 4;
				break;
				
			case 0x27: // funct == 0x27 (NOR)
				p->R[inst.rtype.rd] = ~(p->R[inst.rtype.rs] ^ p->R[inst.rtype.rt]);
				p->pc += 4;
				break;
				
			case 0x2a: // funct == 0x2a (SLT)
				p->R[inst.rtype.rd] = (signed int)(p->R[inst.rtype.rs]) < (signed int)(p->R[inst.rtype.rt]);
				p->pc += 4;
				break;
				
			case 0x2b: // funct == 0x2b (SLTU)
				p->R[inst.rtype.rd] = p->R[inst.rtype.rs] < p->R[inst.rtype.rt];
				p->pc += 4;
				break;
				
			default: // undefined funct
				fprintf(stderr, "%s: pc=%08x, illegal instruction=%08x\n", __FUNCTION__, p->pc, inst.bits);
				exit(-1);
				break;
		}
			break;
			
		case 0x2: // opcode == 0x2 (J)
			p->pc = ((p->pc+4) & 0xf0000000) | (inst.jtype.addr << 2);
			break;
			
		case 0x3: // opcode == 0x3 (JAL)
			p->R[31] = p->pc + 4;
			p->pc = ((p->pc+4) & 0xf0000000) | (inst.jtype.addr << 2);
			break;
			
		case 0x4: // opcode == 0x4 (BEQ)
			if (p->R[inst.itype.rs] == p->R[inst.itype.rt]) {
				p->pc += (4 + (((int16_t)inst.itype.imm) << 2));
			}
			else {
				p->pc += 4;
			}
			break;
			
		case 0x5: // opcode == 0x5 (BNE)
			if (p->R[inst.itype.rs] != p->R[inst.itype.rt]) {
				p->pc += (4 + (((int16_t)inst.itype.imm) << 2));
			}
			else {
				p->pc += 4;
			}
			break;
			
		case 0x9: // opcode == 0x9 (ADDIU)
			p->R[inst.itype.rt] = p->R[inst.itype.rs] + (int16_t)(inst.itype.imm);
			p->pc += 4;
			break;
			
		case 0xa: // opcode == 0xa (SLTI)
			p->R[inst.itype.rt] = (signed int)p->R[inst.itype.rs] < (int16_t)(inst.itype.imm);
			p->pc += 4;
			break;
			
		case 0xb: // opcode == 0xb (SLTIU)
			p->R[inst.itype.rt] = p->R[inst.itype.rs] < (int16_t)(inst.itype.imm);
			p->pc += 4;
			break;
			
		case 0xc: // opcode == 0xc (ANDI)
			p->R[inst.itype.rt] = p->R[inst.itype.rs] & inst.itype.imm;
			p->pc += 4;
			break;
			
		case 0xd: // opcode == 0xd (ORI)
			p->R[inst.itype.rt] = p->R[inst.itype.rs] | inst.itype.imm;
			p->pc += 4;
			break;
			
		case 0xe: // opcode == 0xe (XORI)
			p->R[inst.itype.rt] = p->R[inst.itype.rs] ^ inst.itype.imm;
			p->pc += 4;
			break;
			
		case 0xf: // opcode == 0xf (LUI)
			p->R[inst.itype.rt] = inst.itype.imm << 16;
			p->pc += 4;
			break;
			
		case 0x20: // opcode == 0x20 (LB)
			p->R[inst.itype.rt] = (int8_t)(load_mem(p->R[inst.itype.rs] + (int16_t)(inst.itype.imm), SIZE_BYTE));  
			p->pc += 4;
			break;
			
		case 0x21: // opcode == 0x21 (LH)
			p->R[inst.itype.rt] = (int16_t)(load_mem(p->R[inst.itype.rs] + (int16_t)(inst.itype.imm), SIZE_HALF_WORD));  
			p->pc += 4;
			break;
			
		case 0x23: // opcode == 0x23 (LW)
			p->R[inst.itype.rt] = (int32_t)load_mem(p->R[inst.itype.rs] + (int16_t)(inst.itype.imm), SIZE_WORD);  
			p->pc += 4;
			break;
			
		case 0x24: // opcode == 0x24 (LBU)
			p->R[inst.itype.rt] = load_mem(p->R[inst.itype.rs] + (int16_t)(inst.itype.imm), SIZE_BYTE);  
			p->pc += 4;
			break;
			
		case 0x25: // opcode == 0x25 (LHU)
			p->R[inst.itype.rt] = load_mem(p->R[inst.itype.rs] + (int16_t)(inst.itype.imm), SIZE_HALF_WORD);  
			p->pc += 4;
			break;
			
		case 0x28: // opcode == 0x28 (SB)
			store_mem(p->R[inst.itype.rs] + (int16_t)(inst.itype.imm), SIZE_BYTE, p->R[inst.itype.rt]);
			p->pc += 4;
			break;
			
		case 0x29: // opcode == 0x29 (SH)
			store_mem(p->R[inst.itype.rs] + (int16_t)(inst.itype.imm), SIZE_HALF_WORD, p->R[inst.itype.rt]);
			p->pc += 4;
			break;
			
		case 0x2b: // opcode == 0x2b (SW)
			store_mem(p->R[inst.itype.rs] + (int16_t)(inst.itype.imm), SIZE_WORD, p->R[inst.itype.rt]);
			p->pc += 4;
			break;
			
		default: // undefined opcode
			fprintf(stderr, "%s: pc=%08x, illegal instruction: %08x\n", __FUNCTION__, p->pc, inst.bits);
			exit(-1);
			break;
	}
	
	// enforce $0 being hard-wired to 0
	p->R[0] = 0;
	
	if(print_regs)
		print_registers(p);
}