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

📄 decoder.cc

📁 一个mips虚拟机非常好代码,使用C++来编写的,希望大家多学学,
💻 CC
📖 第 1 页 / 共 4 页
字号:
	    // Set On Less Than //////////////////////////////////////////////	    if (trace_level >= print_instructions)		log("[%lx]\tslt\t%s, %s, %s", pc,		    regname[rd(instr)],		    regname[rs(instr)],		    regname[rt(instr)]);	    Int64 x = gpr[rs(instr)];	    Int64 y = gpr[rt(instr)];	    gpr[rd(instr)] = (x < y);	    return nothing_special;	}	case SLTU:	{	    // Set On Less Than Unsigned /////////////////////////////////////	    if (trace_level >= print_instructions)		log("[%lx]\tsltu\t%s, %s, %s", pc,		    regname[rd(instr)],		    regname[rs(instr)],		    regname[rt(instr)]);	    gpr[rd(instr)] = (gpr[rs(instr)] < gpr[rt(instr)]);	    return nothing_special;	}	case DADD:	{	    // Doubleword Add ////////////////////////////////////////////////	    if (trace_level >= print_instructions)		log("[%lx]\tdadd\t%s, %s, %s", pc, regname[rd(instr)],		    regname[rs(instr)], regname[rt(instr)]);	    if (!allow_xinstr())		process_reserved_instruction();	    UInt64 x = gpr[rs(instr)];	    UInt64 y = gpr[rt(instr)];	    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[rd(instr)] = sign_extend<UInt64>(z, 64);	    return nothing_special;	}	case DADDU:	{	    // Doubleword Add Unsigned ///////////////////////////////////////	    if (trace_level >= print_instructions)		log("[%lx]\tdaddu\t%s, %s, %s", pc,		    regname[rd(instr)],		    regname[rs(instr)],		    regname[rt(instr)]);	    if (!allow_xinstr())		process_reserved_instruction();	    UInt64 x = gpr[rs(instr)];	    UInt64 y = gpr[rt(instr)];	    gpr[rd(instr)] = sign_extend<UInt64>(x + y, 64);	    return nothing_special;	}	case DSUB:	{	    // Doubleword Subtract ///////////////////////////////////////////	    if (trace_level >= print_instructions)		log("[%lx]\tdsub\t%s, %s, %s", pc,		    regname[rd(instr)],		    regname[rs(instr)],		    regname[rt(instr)]);	    if (!allow_xinstr())		process_reserved_instruction();	    Int64 x = zero_extend<UInt64>(gpr[rs(instr)], 64);	    Int64 y = zero_extend<UInt64>(gpr[rt(instr)], 64);	    Int64 z = UInt64(x) - UInt64(y);	    if ((y < 0 && z < x) || (y > 0 && z > x))		process_integer_overflow();	    gpr[rd(instr)] = sign_extend<UInt64>(z, 64);	    return nothing_special;	}	case DSUBU:	{	    // Doubleword Subtract Unsigned //////////////////////////////////	    if (trace_level >= print_instructions)		log("[%lx]\tdsubu\t%s, %s, %s", pc,		    regname[rd(instr)],		    regname[rs(instr)],		    regname[rt(instr)]);	    if (!allow_xinstr())		process_reserved_instruction();	    UInt64 x = zero_extend<UInt64>(gpr[rs(instr)], 64);	    UInt64 y = zero_extend<UInt64>(gpr[rt(instr)], 64);	    gpr[rd(instr)] = sign_extend<UInt64>(x - y, 64);	    return nothing_special;	}	case TGE:	{	    // Trap If Greater Than Or Equal /////////////////////////////////	    if (trace_level >= print_instructions)		log("[%lx]\ttge\t%s, %s", pc,		    regname[rs(instr)],		    regname[rt(instr)]);	    Int64 x = gpr[rs(instr)];	    Int64 y = gpr[rt(instr)];	    if (x >= y)		process_trap();	    return nothing_special;	}	case TGEU:	{	    // Trap If Greater Than Or Equal Unsigned ////////////////////////	    if (trace_level >= print_instructions)		log("[%lx]\ttgeu\t%s, %s", pc,		    regname[rs(instr)],		    regname[rt(instr)]);	    if (gpr[rs(instr)] >= gpr[rt(instr)])		process_trap();	    return nothing_special;	}	case TLT:	{	    // Trap If Less Than /////////////////////////////////////////////	    if (trace_level >= print_instructions)		log("[%lx]\ttlt\t%s, %s", pc,		    regname[rs(instr)],		    regname[rt(instr)]);	    Int64 x = gpr[rs(instr)];	    Int64 y = gpr[rt(instr)];	    if (x < y)		process_trap();	    return nothing_special;	}	case TLTU:	{	    // Trap If Less Than Unsigned ////////////////////////////////////	    if (trace_level >= print_instructions)		log("[%lx]\ttltu\t%s, %s", pc,		    regname[rs(instr)],		    regname[rt(instr)]);	    if (gpr[rs(instr)] < gpr[rt(instr)])		process_trap();	    return nothing_special;	}	case TEQ:	{	    // Trap If Equal /////////////////////////////////////////////////	    if (trace_level >= print_instructions)		log("[%lx]\tteq\t%s, %s", pc,		    regname[rs(instr)],		    regname[rt(instr)]);	    if (gpr[rs(instr)] == gpr[rt(instr)])		process_trap();	    return nothing_special;	}	case TNE:	{	    // Trap If Not Equal /////////////////////////////////////////////	    if (trace_level >= print_instructions)		log("[%lx]\ttne\t%s, %s", pc,		    regname[rs(instr)],		    regname[rt(instr)]);	    if (gpr[rs(instr)] != gpr[rt(instr)])		process_trap();	    return nothing_special;	}	case DSLL:	{	    // Doubleword Shift Left Logical /////////////////////////////////	    if (trace_level >= print_instructions)		log("[%lx]\tdsll\t%s, %s, %d", pc,		    regname[rd(instr)],		    regname[rt(instr)],		    shamt(instr));	    if (!allow_xinstr())		process_reserved_instruction();	    UInt64 x = gpr[rt(instr)];	    int s = shamt(instr);	    gpr[rd(instr)] = sign_extend<UInt64>(x << s, 64);	    return nothing_special;	}	case DSRL:	{	    // Doubleword Shift Right Logical ////////////////////////////////	    if (trace_level >= print_instructions)		log("[%lx]\tdsrl\t%s, %s, %d", pc,		    regname[rd(instr)],		    regname[rt(instr)],		    shamt(instr));	    if (!allow_xinstr())		process_reserved_instruction();	    UInt64 x = zero_extend<UInt64>(gpr[rt(instr)], 64);	    int s = shamt(instr);	    gpr[rd(instr)] = sign_extend<UInt64>(x >> s, 64);	    return nothing_special;	}	case DSRA:	{	    // Doubleword Shift Right Arithmetic /////////////////////////////	    if (trace_level >= print_instructions)		log("[%lx]\tdsra\t%s, %s, %d", pc,		    regname[rd(instr)],		    regname[rt(instr)],		    shamt(instr));	    if (!allow_xinstr())		process_reserved_instruction();	    UInt64 x = gpr[rt(instr)];	    int s = shamt(instr);	    gpr[rd(instr)] = sign_extend<UInt64>(x >> s, 64 - s);	    return nothing_special;	}	case DSLL32:	{	    // Doubleword Shift Left Logical + 32 ////////////////////////////	    if (trace_level >= print_instructions)		log("[%lx]\tdsll\t%s, %s, %d", pc,		    regname[rd(instr)],		    regname[rt(instr)],		    shamt(instr) + 32);	    if (!allow_xinstr())		process_reserved_instruction();	    UInt64 x = gpr[rt(instr)];	    int s = shamt(instr) + 32;	    gpr[rd(instr)] = sign_extend<UInt64>(x << s, 64);	    return nothing_special;	}	case DSRL32:	{	    // Doubleword Shift Right Logical + 32 ///////////////////////////	    if (trace_level >= print_instructions)		log("[%lx]\tdsrl\t%s, %s, %d", pc,		    regname[rd(instr)],		    regname[rt(instr)],		    shamt(instr) + 32);	    if (!allow_xinstr())		process_reserved_instruction();	    UInt64 x = zero_extend<UInt64>(gpr[rt(instr)], 64);	    int s = shamt(instr) + 32;	    gpr[rd(instr)] = sign_extend<UInt64>(x >> s, 64);	    return nothing_special;	}	case DSRA32:	{	    // Doubleword Shift Right Arithmetic + 32 ////////////////////////	    if (trace_level >= print_instructions)		log("[%lx]\tdsra\t%s, %s, %d", pc,		    regname[rd(instr)],		    regname[rt(instr)],		    shamt(instr) + 32);	    if (!allow_xinstr())		process_reserved_instruction();	    UInt64 x = gpr[rt(instr)];	    int s = shamt(instr) + 32;	    gpr[rd(instr)] = sign_extend<UInt64>(x >> s, 64 - s);	    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 REGIMM:    {	// Conditional branches, decoded using the (rt) field.	switch (rt(instr)) {	case BLTZ:	{	    // Branch On Less Than Zero //////////////////////////////////////	    if (trace_level >= print_instructions)		log("[%lx]\tbltz\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);	    }	    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 BGEZ:	{	    // Branch On Greater Than Or Equal To Zero ///////////////////////	    if (trace_level >= print_instructions)		log("[%lx]\tbgez\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);	    }	    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 BLTZL:	{	    // Branch On Less Than Zero Likely ///////////////////////////////	    if (trace_level >= print_instructions)		log("[%lx]\tbltzl\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 BGEZL:	{	    // Branch On Greater Than Or Equal To Zero Likely ////////////////	    if (trace_level >= print_instructions)		log("[%lx]\tbgezl\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 TGEI:	{	    // Trap If Greater Than Or Equal Immediate ///////////////////////	    if (trace_level >= print_instructions)		log("[%lx]\ttgei\t%s, 0x%04x", pc,		    regname[rs(instr)],		    zero_extend<UInt32>(immediate(instr), 16));	    Int64 x = gpr[rs(instr)];	    Int64 y = sign_extend<Int64>(immediate(instr), 16);	    if (x >= y)		process_trap();	    return nothing_special;	}	case TGEIU:	{	    // Trap If Greater Than Or Equal Immediate Unsigned //////////////	    if (trace_level >= print_instructions)		log("[%lx]\ttgeiu\t%s, 0x%04x", pc,		    regname[rs(instr)],		    zero_extend<UInt32>(immediate(instr), 16));	    UInt64 x = gpr[rs(instr)];	    UInt64 y = sign_extend<UInt64>(immediate(instr), 16);	    if (x >= y)		process_trap();	    return nothing_special;	}	case TLTI:	{	    // Trap If Less Than Immediate ///////////////////////////////////	    if (trace_level >= print_instructions)		log("[%lx]\ttlti\t%s, 0x%04x", pc,		    regname[rs(instr)],		    zero_extend<UInt32>(immediate(instr), 16));	    Int64 x = gpr[rs(instr)];	    Int64 y = sign_extend<Int64>(immediate(instr), 16);	    if (x < y)		process_trap();	    return nothing_special;	}	case TLTIU:	{	    // Trap If Less Than Immediate Unsigned //////////////////////////	    if (trace_level >= print_instructions)		log("[%lx]\ttltiu\t%s, 0x%04x", pc,		    regname[rs(instr)],		    zero_extend<UInt32>(immediate(instr), 16));	    UInt64 x = gpr[rs(instr)];	    UInt64 y = sign_extend<UInt64>(immediate(instr), 16);	    if (x < y)		process_trap();	    return nothing_special;	}	case TEQI:	{	    // Trap If Equal Immediate ///////////////////////////////////////	    if (trace_level >= print_instructions)		log("[%lx]\tteqi\t%s, 0x%04x", pc,		    regname[rs(instr)],		    zero_extend<UInt32>(immediate(instr), 16));	    UInt64 x = gpr[rs(instr)];	    UInt64 y = sign_extend<UInt64>(immediate(instr), 16);	    if (x == y)		process_trap();	    return nothing_special;	}	case TNEI:	{	    // Trap If Not Equal Immediate ///////////////////////////////////	    if (trace_level >= print_instructions)		log("[%lx]\ttnei\t%s, 0x%04x", pc,		    regname[rs(instr)],		    zero_extend<UInt32>(immediate(instr), 16));	    UInt64 x = gpr[rs(instr)];	    UInt64 y = sign_extend<UInt64>(immediate(instr), 16);	    if (x != y)		process_trap();	    return nothing_special;	}	case BLTZAL:	{	    // Branch On Less Than Zero And Link /////////////////////////////	    if (trace_level >= print_instructions)		log("[%lx]\tbltzal\t%s, 0x%016lx", pc,		    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);	    }	    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 BGEZAL:	{	    // Branch On Greater Than Or Equal To Zero And Link //////////////	    if (trace_level >= print_instructions)		log("[%lx]\tbltzal\t%s, 0x%016lx", pc,		    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);	    }	    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 BLTZALL:	{	    // Branch On Less Than Zero And Link Likely //////////////////////	    if (trace_level >= print_instructions)		log("[%lx]\tbltzall\t%s, 0x%016lx", pc,		    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;	    }	}	case BGEZALL:	{	    // Branch On Greater Than Or Equal To Zero And Link Likely ///////	    if (trace_level >= print_instructions)		log("[%lx]\tbgezall\t%s, 0x%016lx", pc,

⌨️ 快捷键说明

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