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

📄 cp1.cc

📁 一个mips虚拟机非常好代码,使用C++来编写的,希望大家多学学,
💻 CC
字号:
#include <assert.hh>#include "instr.hh"#include "koala.hh"const char* Koala::condname[16] = {    "f", "un", "eq", "ueq", "olt", "ult", "ole", "ule",    "sf", "ngle", "seq", "ngl", "lt", "nge", "le", "ngt"};intKoala::decode_cop1_s(Instr instr){    switch (function(instr))    {    case FADD:	{	    log("[%lx]\tadd.s\tf%d, f%d, f%d", pc,		fd(instr), fs(instr), ft(instr));	    float x = convert_from_s(fpr[fs(instr)]);	    float y = convert_from_s(fpr[ft(instr)]);	    float z = x + y;	    fpr[fd(instr)] = convert_to_s(z);	    return nothing_special;	}    case TRUNC_W:	{	    log("[%lx]\ttrunc.w.s\tf%d, f%d", pc,		fd(instr), fs(instr));	    UInt32 x = (UInt32)convert_from_s(fpr[fs(instr)]);	    fpr[fd(instr)] = x;	    return nothing_special;	}    case CVT_W:	{	    log("[%lx]\tcvt.w.s\tf%d, f%d", pc,		fd(instr), fs(instr));	    UInt32 x = (UInt32)convert_from_s(fpr[fs(instr)]);	    fpr[fd(instr)] = x;	    return nothing_special;	}    default:	log("[%lx]\t.long\t0x%08x", pc, instr);	assert(TODO);	return nothing_special;    }}intKoala::decode_cop1_d(Instr instr){    switch (function(instr))    {    case FADD:	{	    log("[%lx]\tadd.d\tf%d, f%d, f%d", pc,		fd(instr), fs(instr), ft(instr));	    double x = convert_from_d(fpr[fs(instr)]);	    double y = convert_from_d(fpr[ft(instr)]);	    double z = x + y;	    fpr[fd(instr)] = convert_to_d(z);	    return nothing_special;	}    case FDIV:	{	    log("[%lx]\tdiv.d\tf%d, f%d, f%d", pc,		fd(instr), fs(instr), ft(instr));	    double x = convert_from_d(fpr[fs(instr)]);	    double y = convert_from_d(fpr[ft(instr)]);	    double z = x / y;	    fpr[fd(instr)] = convert_to_d(z);	    return nothing_special;	}    case FMUL:	{	    log("[%lx]\tmul.d\tf%d, f%d, f%d", pc,		fd(instr), fs(instr), ft(instr));	    double x = convert_from_d(fpr[fs(instr)]);	    double y = convert_from_d(fpr[ft(instr)]);	    double z = x * y;	    fpr[fd(instr)] = convert_to_d(z);	    return nothing_special;	}    case C_F:    case C_UN:    case C_EQ:    case C_UEQ:    case C_OLT:    case C_ULT:    case C_OLE:    case C_ULE:    case C_SF:    case C_NGLE:    case C_SEQ:    case C_NGL:    case C_LT:    case C_NGE:    case C_LE:    case C_NGT:	{	    UInt8 cond = bits(instr, 3, 0);	    log("[%lx]\tc.%s.d\tf%d, f%d", pc, condname[cond],		fs(instr), ft(instr));	    double x = convert_from_d(fpr[fs(instr)]);	    double y = convert_from_d(fpr[ft(instr)]);	    UInt64 result = (bit(cond, 2) && (x < y)) || (bit(cond, 1) && (x == y));	    cp1[FCR31] = set_bit(cp1[FCR31], result, FP_C);	    return nothing_special;	}    case TRUNC_W:	{	    log("[%lx]\ttrunc.w.d\tf%d, f%d", pc,		fd(instr), fs(instr));	    UInt32 x = (UInt32)convert_from_d(fpr[fs(instr)]);	    fpr[fd(instr)] = x;	    return nothing_special;	}    case TRUNC_L:	{	    log("[%lx]\ttrunc.l.d\tf%d, f%d", pc,		fd(instr), fs(instr));	    UInt64 x = (UInt64)convert_from_d(fpr[fs(instr)]);	    fpr[fd(instr)] = x;	    return nothing_special;	}    case CVT_W:	{	    log("[%lx]\tcvt.w.d\tf%d, f%d", pc,		fd(instr), fs(instr));	    UInt32 x = (UInt32)convert_from_d(fpr[fs(instr)]);	    fpr[fd(instr)] = x;	    return nothing_special;	}    default:	log("[%lx]\t.long\t0x%08x", pc, instr);	assert(TODO);	return nothing_special;    }}intKoala::decode_cop1_w(Instr instr){    switch (function(instr))    {    case CVT_S:	{	    log("[%lx]\tcvt.s.w\tf%d, f%d", pc,		fd(instr), fs(instr));	    float x = (float)fpr[fs(instr)];	    fpr[fd(instr)] = convert_to_s(x);	    return nothing_special;	}    case CVT_D:	{	    log("[%lx]\tcvt.d.w\tf%d, f%d", pc,		fd(instr), fs(instr));	    double x = (double)fpr[fs(instr)];	    fpr[fd(instr)] = convert_to_d(x);	    return nothing_special;	}    default:	log("[%lx]\t.long\t0x%08x", pc, instr);	assert(TODO);	return nothing_special;    }}intKoala::decode_cop1_l(Instr instr){    log("[%lx]\t.long\t0x%08x", pc, instr);    assert(TODO);    return nothing_special;}intKoala::decode_cop1(Instr instr){    // CP1 is unusable when the CU bit in SR is clear.    if (!bit(cp0[SR], SR_CU1))	process_coprocessor_unusable(1);    switch (fmt(instr))    {    case S:	{	    decode_cop1_s(instr);	    break;	}    case D:	{	    decode_cop1_d(instr);	    break;	}    case W:	{	    decode_cop1_w(instr);	    break;	}    case L:	{	    decode_cop1_l(instr);	    break;	}    case CTCz:	{	    log("[%lx]\tctc1\t%s, f%d", pc,		regname[rt(instr)],		rd(instr));	    if (rd(instr) == 31)		cp1[FCR31] = gpr[rt(instr)];	    break;	}    case CFCz:	{	    log("[%lx]\tcfc1\t%s, f%d", pc,		regname[rt(instr)],		rd(instr));	    gpr[rt(instr)] = cp1[rd(instr)];	    break;	}    case MFCz: // FIXME    case DMFCz:	{	    log("[%lx]\tmfc1\t%s, f%d", pc,		regname[rt(instr)],		rd(instr));	    gpr[rt(instr)] = fpr[rd(instr)];	    break;	}    case MTCz: // FIXME    case DMTCz:	{	    log("[%lx]\tmtc1\t%s, f%d", pc,		regname[rt(instr)],		rd(instr));	    fpr[rd(instr)] = gpr[rt(instr)];	    break;	}    case BCz:	{	    bool cond = bit(rt(instr), 0);	    bool likely = bit(rt(instr), 1);	    UInt64 target = pc + 4 + (sign_extend<VA>(offset(instr), 16) << 2);	    log("[%lx]\tbc1%c%s\t%s, 0x%016lx", pc, cond ? 't' : 'f',		likely ? "l" : "", regname[rs(instr)], target);	    if (bit(cp1[FCR31], FP_C) == cond) {		branch_target = target;		return branch_delay;	    } else if (likely) {		// Nullify (skip) the next instruction.		pc += 4;		return nothing_special;	    } else {		branch_target = pc + 8;		return branch_delay;	    }	    break;	}    default:	{	    log("[%lx]\t.long\t0x%08x", pc, instr);	    assert(TODO);	}    }    dump_fpr_registers();    return nothing_special;}intKoala::decode_ldc1(Instr instr){    // Load Doubleword To Coprocessor 1 //////////////////////////////////#if 0    if (trace_level >= print_instructions)#endif	log("[%lx]\tldc1\tf%d, %d(%s)", pc,		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)];    if (bits(va, 2, 0))	process_address_error(data_load, va);    PA pa = translate_vaddr(va, data_load);    UInt64 x = load<doubleword>(va, pa);    fpr[rt(instr)] = sign_extend<UInt64>(x, 64);    dump_fpr_registers();    return nothing_special;}intKoala::decode_lwc1(Instr instr){	// Load Word to Coprocessor 1 ////////////////////////////////////////#if 0	if (trace_level >= print_instructions)#endif	    log("[%lx]\tlwc1\tf%d, %d(%s)", pc,		rt(instr),		sign_extend<Int32>(offset(instr), 16),		regname[base(instr)]);	if (sync_bit)	    sync();	VA va = sign_extend<VA>(offset(instr), 16) + gpr[base(instr)];	if (bits(va, 1, 0))	    process_address_error(data_load, va);	PA pa = translate_vaddr(va, data_load);	UInt32 x = load<word>(va, pa);	fpr[rt(instr)] = sign_extend<UInt64>(x, 32);    dump_fpr_registers();	return nothing_special;}intKoala::decode_sdc1(Instr instr){	// Store Doubleword From Coprocessor 1 ///////////////////////////////#if 0	if (trace_level >= print_instructions)#endif	    log("[%lx]\tsdc1\tf%d, %d(%s)", pc,		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)];	if (bits(va, 2, 0))	    process_address_error(data_store, va);	PA pa = translate_vaddr(va, data_store);	store<doubleword>(fpr[rt(instr)], va, pa);    dump_fpr_registers();	return nothing_special;}intKoala::decode_swc1(Instr instr){	// Store Word From Coprocessor 1 /////////////////////////////////////#if 0	if (trace_level >= print_instructions)#endif	    log("[%lx]\tswc1\tf%d, %d(%s)", pc,		rt(instr),		sign_extend<Int32>(offset(instr), 16),		regname[base(instr)]);	if (sync_bit)	    sync();	VA va = sign_extend<VA>(offset(instr), 16) + gpr[base(instr)];	if (bits(va, 1, 0))	    process_address_error(data_store, va);	PA pa = translate_vaddr(va, data_store);	store<word>(fpr[rt(instr)], va, pa);    dump_fpr_registers();	return nothing_special;}voidKoala::dump_fpr_registers() const{    for (int i = 0; i < 32; i += 2) {        log("\tf%-2d = %016lx  %-2d = %016lx",            i, fpr[i], i+1, fpr[i+1]);    }}

⌨️ 快捷键说明

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