Ejemplo n.º 1
0
/**
 * Runs the instruction at the program counters position in memory.
 */
void vm_exec()
{
	cycles++;
	Instruction* op = mem_load_instr(pcounter);
	print_instr(op);

	switch(op->op)
	{
		case OP_NAP: break;

		case OP_ADD: 	op_add(op); 	break;
		case OP_SUB: 	op_sub(op); 	break;

		case OP_EXP:	op_exp(op);		break;
		case OP_SIN:	op_sin(op);		break;
		case OP_COS:	op_cos(op);		break;
		case OP_TAN:	op_tan(op);		break;

		case OP_LW: 	op_lw(op);		break;

		case OP_SW:		op_sw(op);		break;
		case OP_SB:		op_sb(op);		break;

		case OP_J:		op_j(op); 		return; // Jump
		case OP_JR:		op_jr(op);		return;
		case OP_JAL:	op_jal(op);		return;
		case OP_JZ:		op_jz(op);		return;
		case OP_JNZ:	op_jnz(op);		return;
		case OP_JEQ:	op_jeq(op);		return;
		case OP_JNQ:	op_jnq(op);		return;

		case OP_PUSH:	op_push(op);	break;
		case OP_POP:	op_pop(op);		break;

		case OP_PRTI:	op_prti(op);	break;

		case OP_EXIT: 	
			vm_exit(op->k); 
			return;

		/* Unsupported operation */
		default:
			printf("Error: Invalid operation at %d\n", pcounter);
			print_instr(op);
			vm_exit(-1);
			return;
	}

	pcounter = pcounter + 8;
}
Ejemplo n.º 2
0
void process_instruction(){

	//1. Fetch instruction
	instruction instr = INST_INFO[(CURRENT_STATE.PC - MEM_TEXT_START)/4];
	//printf("opcode: %x\n",instr.opcode);
	//2. PC update
	CURRENT_STATE.PC += 4;
	//3. Perform operation
	//3-1. R-type running
	if(instr.opcode == 0x0)
	{
		unsigned char rd, rs, rt, shamt;
		shamt = instr.r_t.r_i.r_i.r.shamt;
		rd = instr.r_t.r_i.r_i.r.rd;
		rs = instr.r_t.r_i.rs;
		rt = instr.r_t.r_i.rt;
		void (*operation)(unsigned char, unsigned char, unsigned char);
		if(instr.r_t.r_i.r_i.r.shamt == 0)
		{
			switch(instr.func_code)
			{
				case 0x21:
					operation = op_addu;
					break;
				case 0x24:
					operation = op_and;
					break;
				case 0x8:
					operation = op_jr;
					break;
				case 0x27:
					operation = op_nor;
					break;
				case 0x25:
					operation = op_or;
					break;
				case 0x23:
					operation = op_subu;
					break;
				case 0x2B:
					operation = op_sltu;
					break;
			};
			operation(rd, rs, rt);
		}
		else
		{
			if(instr.func_code == 0) operation = op_sll;
			else op_srl;
			operation(rd, rt, shamt);
		}
	}
	//3-2. J-type running
	else if(instr.opcode == 0x2 || instr.opcode == 0x3)
	{
		void (*operation)(uint32_t);
		uint32_t target = instr.r_t.target;
		if(instr.opcode == 0x2)
		{
			op_j(target);
		}
		else
		{
			op_jal(target);
		}
	}
	//3-3. I-type running
	else
	{
		void (*operation)(unsigned char, unsigned char, short);
		unsigned char rt, rs;
		short imm;
		rt = instr.r_t.r_i.rt;
		rs = instr.r_t.r_i.rs;
		imm = instr.r_t.r_i.r_i.imm;
		switch(instr.opcode)
		{
			case 0x9:
				operation = op_addiu;
				break;
			case 0x4:
				operation = op_beq;
				break;
			case 0x5:
				operation = op_bne;
				break;
			case 0x23:
				operation = op_lw;
				break;
			case 0xB:
				operation = op_sltiu;
				break;
			case 0x2B:
				operation = op_sw;
				break;
			case 0xF:
				operation = op_lui;
				break;
			case 0xD:
				operation = op_ori;
				break;
			case 0xC:
				operation = op_andi;
				break;
		};
		operation(rt, rs, imm);
	}
	if(CURRENT_STATE.PC - MEM_TEXT_START == NUM_INST * 4) {
		RUN_BIT = false;
		return;
	}
}
Ejemplo n.º 3
0
void doop(Mips * emu, uint32_t op) {
    switch(op & 0xfc000000) {
        case 0x8000000:
            op_j(emu,op);
            return;
        case 0xc000000:
            op_jal(emu,op);
            return;
        case 0x10000000:
            op_beq(emu,op);
            return;
        case 0x14000000:
            op_bne(emu,op);
            return;
        case 0x18000000:
            op_blez(emu,op);
            return;
        case 0x1c000000:
            op_bgtz(emu,op);
            return;
        case 0x20000000:
            op_addi(emu,op);
            return;
        case 0x24000000:
            op_addiu(emu,op);
            return;
        case 0x28000000:
            op_slti(emu,op);
            return;
        case 0x2c000000:
            op_sltiu(emu,op);
            return;
        case 0x30000000:
            op_andi(emu,op);
            return;
        case 0x34000000:
            op_ori(emu,op);
            return;
        case 0x38000000:
            op_xori(emu,op);
            return;
        case 0x3c000000:
            op_lui(emu,op);
            return;
        case 0x50000000:
            op_beql(emu,op);
            return;
        case 0x54000000:
            op_bnel(emu,op);
            return;
        case 0x58000000:
            op_blezl(emu,op);
            return;
        case 0x80000000:
            op_lb(emu,op);
            return;
        case 0x84000000:
            op_lh(emu,op);
            return;
        case 0x88000000:
            op_lwl(emu,op);
            return;
        case 0x8c000000:
            op_lw(emu,op);
            return;
        case 0x90000000:
            op_lbu(emu,op);
            return;
        case 0x94000000:
            op_lhu(emu,op);
            return;
        case 0x98000000:
            op_lwr(emu,op);
            return;
        case 0xa0000000:
            op_sb(emu,op);
            return;
        case 0xa4000000:
            op_sh(emu,op);
            return;
        case 0xa8000000:
            op_swl(emu,op);
            return;
        case 0xac000000:
            op_sw(emu,op);
            return;
        case 0xb8000000:
            op_swr(emu,op);
            return;
        case 0xbc000000:
            op_cache(emu,op);
            return;
        case 0xc0000000:
            op_ll(emu,op);
            return;
        case 0xcc000000:
            op_pref(emu,op);
            return;
        case 0xe0000000:
            op_sc(emu,op);
            return;
    }
    switch(op & 0xfc00003f) {
        case 0x0:
            op_sll(emu,op);
            return;
        case 0x2:
            op_srl(emu,op);
            return;
        case 0x3:
            op_sra(emu,op);
            return;
        case 0x4:
            op_sllv(emu,op);
            return;
        case 0x6:
            op_srlv(emu,op);
            return;
        case 0x7:
            op_srav(emu,op);
            return;
        case 0x8:
            op_jr(emu,op);
            return;
        case 0x9:
            op_jalr(emu,op);
            return;
        case 0xc:
            op_syscall(emu,op);
            return;
        case 0xf:
            op_sync(emu,op);
            return;
        case 0x10:
            op_mfhi(emu,op);
            return;
        case 0x11:
            op_mthi(emu,op);
            return;
        case 0x12:
            op_mflo(emu,op);
            return;
        case 0x13:
            op_mtlo(emu,op);
            return;
        case 0x18:
            op_mult(emu,op);
            return;
        case 0x19:
            op_multu(emu,op);
            return;
        case 0x1a:
            op_div(emu,op);
            return;
        case 0x1b:
            op_divu(emu,op);
            return;
        case 0x20:
            op_add(emu,op);
            return;
        case 0x21:
            op_addu(emu,op);
            return;
        case 0x22:
            op_sub(emu,op);
            return;
        case 0x23:
            op_subu(emu,op);
            return;
        case 0x24:
            op_and(emu,op);
            return;
        case 0x25:
            op_or(emu,op);
            return;
        case 0x26:
            op_xor(emu,op);
            return;
        case 0x27:
            op_nor(emu,op);
            return;
        case 0x2a:
            op_slt(emu,op);
            return;
        case 0x2b:
            op_sltu(emu,op);
            return;
	case 0x2d:
	    op_addu(emu,op); //daddu
	    return;
        case 0x36:
            op_tne(emu,op);
            return;
    }
    switch(op & 0xfc1f0000) {
        case 0x4000000:
            op_bltz(emu,op);
            return;
        case 0x4010000:
            op_bgez(emu,op);
            return;
        case 0x4020000:
            op_bltzl(emu,op);
            return;
        case 0x4030000:
            op_bgezl(emu,op);
            return;
        case 0x4100000:
            op_bltzal(emu,op);
            return;
        case 0x4110000:
            op_bgezal(emu,op);
            return;
        case 0x5c000000:
            op_bgtzl(emu,op);
            return;
    }
    switch(op & 0xffffffff) {
        case 0x42000002:
            op_tlbwi(emu,op);
            return;
        case 0x42000006:
            op_tlbwr(emu,op);
            return;
        case 0x42000008:
            op_tlbp(emu,op);
            return;
        case 0x42000018:
            op_eret(emu,op);
            return;
    }
    switch(op & 0xfc0007ff) {
        case 0xa:
            op_movz(emu,op);
            return;
        case 0xb:
            op_movn(emu,op);
            return;
        case 0x70000002:
            op_mul(emu,op);
            return;
    }
    switch(op & 0xffe00000) {
        case 0x40000000:
            op_mfc0(emu,op);
            return;
        case 0x40800000:
            op_mtc0(emu,op);
            return;
    }
    switch(op & 0xfe00003f) {
        case 0x42000020:
            op_wait(emu,op);
            return;
    }
    // printf("unhandled opcode at %x -> %x\n",emu->pc,op);
    setExceptionCode(emu,EXC_RI);
    emu->exceptionOccured = 1;
    return;
}