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

📄 decoder.cc

📁 一个mips虚拟机非常好代码,使用C++来编写的,希望大家多学学,
💻 CC
📖 第 1 页 / 共 4 页
字号:
		    regname[rs(instr)],		    pc + 4 + (sign_extend<VA>(offset(instr), 16) << 2));	    Int64 x = gpr[rs(instr)];	    gpr[31] = sign_extend<UInt64>(pc + 8, 64);	    if (x >= 0) {		VA off = sign_extend<VA>(offset(instr), 16);		branch_target = pc + 4 + (off << 2);			if (pipeline == branch_delay) {		log("Illegal branch in branch delay slot at: %lx\n", pc);		assert(!"Can't handle branch in branch delay slot");	}		return branch_delay;	    }	    else {		// Nullify (skip) the next instruction.		pc += 4;		return nothing_special;	    }	}	default:	    // Reserved instruction.	    if (trace_level >= print_instructions)		log("[%lx]\t.long\t0x%08x", pc, instr);	    process_reserved_instruction();	    return nothing_special;	}    }    case J:    {	// Jump //////////////////////////////////////////////////////////////	if (trace_level >= print_instructions)	    log("[%lx]\tj\t0x%016lx", pc,		clear_bits(pc + 4, 27, 0) | (target(instr) << 2));	VA msb = clear_bits(pc + 4, 27, 0);	branch_target = msb | (target(instr) << 2);	if (pipeline == branch_delay) {		log("Illegal branch in branch delay slot at: %lx\n", pc);		assert(!"Can't handle branch in branch delay slot");	}	return branch_delay;    }    case JAL:    {	// Jump And Link /////////////////////////////////////////////////////	if (trace_level >= print_instructions)	    log("[%lx]\tjal\t0x%016lx", pc,		clear_bits(pc + 4, 27, 0) | (target(instr) << 2));	gpr[31] = sign_extend<UInt64>(pc + 8, 64);	VA msb = clear_bits(pc + 4, 27, 0);	branch_target = msb | (target(instr) << 2);	if (pipeline == branch_delay) {		log("Illegal branch in branch delay slot at: %lx\n", pc);		assert(!"Can't handle branch in branch delay slot");	}	return branch_delay;    }    case BEQ:    {	// Branch On Equal ///////////////////////////////////////////////////	if (trace_level >= print_instructions)	    log("[%lx]\tbeq\t%s, %s, 0x%016lx", pc,		regname[rs(instr)],		regname[rt(instr)],		pc + 4 + (sign_extend<Int64>(offset(instr), 16) << 2));	if (gpr[rs(instr)] == gpr[rt(instr)]) {	    VA off = sign_extend<VA>(offset(instr), 16);	    branch_target = pc + 4 + (off << 2);	}	else	    branch_target = pc + 8;		if (pipeline == branch_delay) {		log("Illegal branch in branch delay slot at: %lx\n", pc);		assert(!"Can't handle branch in branch delay slot");	}	return branch_delay;    }    case BNE:    {	// Branch On Not Equal ///////////////////////////////////////////////	if (trace_level >= print_instructions)	    log("[%lx]\tbne\t%s, %s, 0x%016lx", pc,		regname[rs(instr)],		regname[rt(instr)],		pc + 4 + (sign_extend<Int64>(offset(instr), 16) << 2));	if (gpr[rs(instr)] != gpr[rt(instr)]) {	    VA off = sign_extend<VA>(offset(instr), 16);	    branch_target = pc + 4 + (off << 2);	}	else	    branch_target = pc + 8;	if (pipeline == branch_delay) {		log("Illegal branch in branch delay slot at: %lx\n", pc);		assert(!"Can't handle branch in branch delay slot");	}	return branch_delay;    }    case BLEZ:    {	// Branch On Less Than Or Equal To Zero //////////////////////////////	if (trace_level >= print_instructions)	    log("[%lx]\tblez\t%s, 0x%016lx", pc,		regname[rs(instr)],		pc + 4 + (sign_extend<Int64>(offset(instr), 16) << 2));	Int64 x = gpr[rs(instr)];	if (x <= 0) {	    VA off = sign_extend<VA>(offset(instr), 16);	    branch_target = pc + 4 + (off << 2);	}	else	    branch_target = pc + 8;	if (pipeline == branch_delay) {		log("Illegal branch in branch delay slot at: %lx\n", pc);		assert(!"Can't handle branch in branch delay slot");	}	return branch_delay;    }    case BGTZ:    {	// Branch On Greater Than Zero ///////////////////////////////////////	if (trace_level >= print_instructions)	    log("[%lx]\tbgtz\t%s, 0x%016lx", pc,		regname[rs(instr)],		pc + 4 + (sign_extend<Int64>(offset(instr), 16) << 2));	Int64 x = gpr[rs(instr)];	if (x > 0) {	    VA off = sign_extend<VA>(offset(instr), 16);	    branch_target = pc + 4 + (off << 2);	}	else	    branch_target = pc + 8;		if (pipeline == branch_delay) {		log("Illegal branch in branch delay slot at: %lx\n", pc);		assert(!"Can't handle branch in branch delay slot");	}	return branch_delay;    }    case ADDI:    {	// Add Immediate /////////////////////////////////////////////////////	if (trace_level >= print_instructions)	    log("[%lx]\taddi\t%s, %s, 0x%04x", pc,		regname[rt(instr)],		regname[rs(instr)],		zero_extend<UInt32>(immediate(instr), 16));	UInt32 x = gpr[rs(instr)];	UInt32 y = sign_extend<UInt32>(immediate(instr), 16);	UInt32 z = x + y;	// Overflow occurs is sign(x) == sign(y) != sign(z).	if (bit(x ^ y, 31) == 0 && bit(x ^ z, 31) != 0)	    process_integer_overflow();	gpr[rt(instr)] = sign_extend<UInt64>(z, 32);	return nothing_special;    }    case ADDIU:    {	// Add Immediate Unsigned ////////////////////////////////////////////	if (trace_level >= print_instructions)	    log("[%lx]\taddiu\t%s, %s, 0x%04x", pc,		regname[rt(instr)],		regname[rs(instr)],		zero_extend<UInt32>(immediate(instr), 16));	UInt32 x = gpr[rs(instr)];	UInt32 y = sign_extend<UInt32>(immediate(instr), 16);	gpr[rt(instr)] = sign_extend<UInt64>(x + y, 32);	return nothing_special;    }    case SLTI:    {	// Set On Less Than Immediate ////////////////////////////////////////	if (trace_level >= print_instructions)	    log("[%lx]\tslti\t%s, %s, 0x%04x", pc,		regname[rt(instr)],		regname[rs(instr)],		zero_extend<UInt32>(immediate(instr), 16));	Int64 x = gpr[rs(instr)];	Int64 y = sign_extend<Int64>(immediate(instr), 16);	gpr[rt(instr)] = (x < y);	return nothing_special;    }    case SLTIU:    {	// Set On Less Than Immediate Unsigned ///////////////////////////////	if (trace_level >= print_instructions)	    log("[%lx]\tsltiu\t%s, %s, 0x%04x", pc,		regname[rt(instr)],		regname[rs(instr)],		zero_extend<UInt32>(immediate(instr), 16));	UInt64 x = gpr[rs(instr)];	UInt64 y = sign_extend<UInt64>(immediate(instr), 16);	gpr[rt(instr)] = (x < y);	return nothing_special;    }    case ANDI:    {	// And Immediate /////////////////////////////////////////////////////	if (trace_level >= print_instructions)	    log("[%lx]\tandi\t%s, %s, 0x%04x", pc,		regname[rt(instr)],		regname[rs(instr)],		zero_extend<UInt32>(immediate(instr), 16));	UInt16 x = gpr[rs(instr)];	UInt16 imm = zero_extend<UInt64>(immediate(instr), 16);	gpr[rt(instr)] = zero_extend<UInt64>(x & imm, 16);	return nothing_special;    }    case ORI:    {	// Or Immediate //////////////////////////////////////////////////////	if (trace_level >= print_instructions)	    log("[%lx]\tori\t%s, %s, 0x%04x", pc,		regname[rt(instr)],		regname[rs(instr)],		zero_extend<UInt32>(immediate(instr), 16));	UInt64 x = gpr[rs(instr)];	UInt64 imm = zero_extend<UInt64>(immediate(instr), 16);	gpr[rt(instr)] = x | imm;	return nothing_special;    }    case XORI:    {	// Exclusive Or Immediate ////////////////////////////////////////////	if (trace_level >= print_instructions)	    log("[%lx]\txori\t%s, %s, 0x%04x", pc,		regname[rt(instr)],		regname[rs(instr)],		zero_extend<UInt32>(immediate(instr), 16));	UInt64 x = gpr[rs(instr)];	UInt64 imm = zero_extend<UInt64>(immediate(instr), 16);	gpr[rt(instr)] = x ^ imm;	return nothing_special;    }    case LUI:    {	// Load Upper Immediate //////////////////////////////////////////////	if (trace_level >= print_instructions)	    log("[%lx]\tlui\t%s, 0x%04x", pc,		regname[rt(instr)],		zero_extend<UInt32>(immediate(instr), 32));	UInt32 imm = immediate(instr);	gpr[rt(instr)] = sign_extend<UInt64>(imm << 16, 32);	return nothing_special;    }    case COP0:    {	// Coprocessor 0 Operation ///////////////////////////////////////////	if (trace_level >= print_instructions) {	    if (bit(instr, 25)) {		switch (funct(instr)) {		case TLBR:		    log("[%lx]\ttlbr", pc);		    break;		case TLBWI:		    log("[%lx]\ttlbwi", pc);		    break;		case TLBWR:		    log("[%lx]\ttlbwr", pc);		    break;		case TLBP:		    log("[%lx]\ttlbp", pc);		    break;		case ERET:		    log("[%lx]\teret", pc);		    break;		case WAIT:		    log("[%lx]\twait", pc);		    break;		default:		    log("[%lx]\t.long\t0x%08x // cop0", pc, instr);		}	    }	    else {		switch (rs(instr)) {		case MFCz:		    log("[%lx]\tmfc0\t%s, %d", pc,			regname[rt(instr)],			rd(instr));		    break;		case DMFCz:		    log("[%lx]\tdmfc0\t%s, %d", pc,			regname[rt(instr)],			rd(instr));		    break;		case CFCz:		    log("[%lx]\t.long\t0x%08x // cfc0", pc, instr);		    break;		case MTCz:		    log("[%lx]\tmtc0\t%s, %d", pc,			regname[rt(instr)],			rd(instr));		    break;		case DMTCz:		    log("[%lx]\tdmtc0\t%s, %d", pc,			regname[rt(instr)],			rd(instr));		    break;		case CTCz:		    log("[%lx]\t.long\t0x%08x // ctc0", pc, instr);		    break;		case BCz:		    log("[%lx]\t.long\t0x%08x // bc0", pc, instr);		    break;		default:		    log("[%lx]\t.long\t0x%08x // cop0", pc, instr);		}	    }	}	return decode_cop0(instr);    }    case COP1:    {	// Coprocessor 1 Operation ///////////////////////////////////////////	if (trace_level >= print_instructions)	    log("[%lx]\t.long\t0x%08x // cop1", pc, instr);	return decode_cop1(instr);    }    case COP2:    {	// Coprocessor 2 Operation ///////////////////////////////////////////	if (trace_level >= print_instructions)	    log("[%lx]\t.long\t0x%08x // cop2", pc, instr);	process_reserved_instruction();	return nothing_special;    }    case BEQL:    {	// Branch On Equal Likely ////////////////////////////////////////////	if (trace_level >= print_instructions)	    log("[%lx]\tbeql\t%s, %s, 0x%016lx", pc,		regname[rs(instr)],		regname[rt(instr)],		pc + 4 + (sign_extend<VA>(offset(instr), 16) << 2));	if (gpr[rs(instr)] == gpr[rt(instr)]) {	    VA off = sign_extend<VA>(offset(instr), 16);	    branch_target = pc + 4 + (off << 2);	    	if (pipeline == branch_delay) {		log("Illegal branch in branch delay slot at: %lx\n", pc);		assert(!"Can't handle branch in branch delay slot");	}	    return branch_delay;	}	else {	    // Nullify (skip) the next instruction.	    pc += 4;	    return nothing_special;	}    }    case BNEL:    {	// Branch On Not Equal Likely ////////////////////////////////////////	if (trace_level >= print_instructions)	    log("[%lx]\tbnel\t%s, %s, 0x%016lx", pc,		regname[rs(instr)],		regname[rt(instr)],		pc + 4 + (sign_extend<VA>(offset(instr), 16) << 2));	if (gpr[rs(instr)] != gpr[rt(instr)]) {	    VA off = sign_extend<VA>(offset(instr), 16);	    branch_target = pc + 4 + (off << 2);	    	if (pipeline == branch_delay) {		log("Illegal branch in branch delay slot at: %lx\n", pc);		assert(!"Can't handle branch in branch delay slot");	}	    return branch_delay;	}	else {	    // Nullify (skip) the next instruction.	    pc += 4;	    return nothing_special;	}    }    case BLEZL:    {	// Branch On Less Than Or Equal To Zero Likely ///////////////////////	if (trace_level >= print_instructions)	    log("[%lx]\tblezl\t%s, 0x%016lx", pc,		regname[rs(instr)],		pc + 4 + (sign_extend<VA>(offset(instr), 16) << 2));	Int64 x = gpr[rs(instr)];	if (x <= 0) {	    VA off = sign_extend<VA>(offset(instr), 16);	    branch_target = pc + 4 + (off << 2);	    	if (pipeline == branch_delay) {		log("Illegal branch in branch delay slot at: %lx\n", pc);		assert(!"Can't handle branch in branch delay slot");	}	    return branch_delay;	}	else {	    // Nullify (skip) the next instruction.	    pc += 4;	    return nothing_special;	}    }    case BGTZL:    {	// Branch On Greater Than Zero Likely ////////////////////////////////	if (trace_level >= print_instructions)	    log("[%lx]\tbgtzl\t%s, 0x%016lx", pc,		regname[rs(instr)],		pc + 4 + (sign_extend<VA>(offset(instr), 16) << 2));	Int64 x = gpr[rs(instr)];	if (x > 0) {	    VA off = sign_extend<VA>(offset(instr), 16);	    branch_target = pc + 4 + (off << 2);	    	if (pipeline == branch_delay) {		log("Illegal branch in branch delay slot at: %lx\n", pc);		assert(!"Can't handle branch in branch delay slot");	}	    return branch_delay;	}	else {	    // Nullify (skip) the next instruction.	    pc += 4;	    return nothing_special;	}    }    case DADDI:    {	// Doubleword Add Immediate //////////////////////////////////////////	if (trace_level >= print_instructions)	    log("[%lx]\tdaddi\t%s, %s, 0x%04x", pc,		regname[rt(instr)],		regname[rs(instr)],		zero_extend<Int32>(immediate(instr), 16));	if (!allow_xinstr())	    process_reserved_instruction();	UInt64 x = gpr[rs(instr)];	UInt64 y = sign_extend<UInt64>(immediate(instr), 16);	UInt64 z = x + y;	// Overflow occurs is sign(x) == sign(y) != sign(z).	if (bit(x ^ y, 63) == 0 && bit(x ^ z, 63) != 0)	    process_integer_overflow();	gpr[rt(instr)] = sign_extend<UInt64>(z, 64);	return nothing_special;    }    case DADDIU:    {	// Doubleword Add Immediate Unsigned /////////////////////////////////	if (trace_level >= print_instructions)	    log("[%lx]\tdaddiu\t%s, %s, 0x%04x", pc,		regname[rt(instr)],		regname[rs(instr)],		sign_extend<Int32>(immediate(instr), 16));	if (!allow_xinstr())	    process_reserved_instruction();	UInt64 x = gpr[rs(instr)];	UInt64 y = sign_extend<UInt64>(immediate(instr), 16);	gpr[rt(instr)] = sign_extend<UInt64>(x + y, 64);	return nothing_special;    }    case LDL:    {	// Load Doubleword Left //////////////////////////////////////////////	if (trace_level >= print_instructions)	    log("[%lx]\tldl\t%s, %d(%s)", pc,		regname[rt(instr)],		sign_extend<Int32>(offset(instr), 16),		regname[base(instr)]);	if (!allow_xinstr())	    process_reserved_instruction();	if (sync_bit)	    sync();	VA va = sign_extend<VA>(offset(instr), 16) + gpr[base(instr)];	// WARNING: see the comment in unaligned.cc.	PA pa = translate_vaddr(va, data_load);	UInt64 mem = load<doubleword>(round_down(va, 8), round_down(pa, 8));	UInt64 reg = gpr[rt(instr)];	int syscmd = bits(va, 2, 0);	if (!big_endian_cpu())	    syscmd ^= bitmask(2, 0);	reg = set_bits(reg, mem, 63, syscmd * 8);	gpr[rt(instr)] = sign_extend<UInt64>(reg, 64);	return nothing_special;    }    case LDR:    {	// Load Doubleword Right /////////////////////////////////////////////	if (trace_level >= print_instructions)	    log("[%lx]\tldr\t%s, %d(%s)", pc,		regname[rt(instr)],		sign_extend<Int32>(offset(instr), 16),		regname[base(instr)]);	if (!allow_xinstr())	    process_reserved_instruction();	if (sync_bit)	    sync();	VA va = sign_extend<VA>(offset(instr), 16) + gpr[base(instr)];	// WARNING: see the comment in unaligned.cc.	PA pa = translate_vaddr(va, data_load);	UInt64 mem = load<doubleword>(round_down(va, 8), round_down(pa, 8));	UInt64 reg = gpr[rt(instr)];	int syscmd = bits(va, 2, 0);	if (big_endian_cpu())

⌨️ 快捷键说明

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