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

📄 cp0.cc

📁 一个mips虚拟机非常好代码,使用C++来编写的,希望大家多学学,
💻 CC
字号:
#include "instr.hh"#include "koala.hh"// Access to the System Coprocessor registers.UInt64Koala::read_cp0(int n) const{    switch (n) {    case Random:    {	return get_random();    }    case Count:    {	return cp0[Count] + ((now - count_seed) / 2);    }    case Cause:    {	return cp0[Cause] | (events & bitmask(Cause_IP_Last, Cause_IP_First));    }    default:	assert(n >= 0 && n <= 31);	return cp0[n];    }}voidKoala::write_cp0(int n, UInt64 x){    switch (n) {    case Index:    {	cp0[Index] = zero_extend<UInt64>(clear_bits(x, 30, 6), 32);	break;    }    case Random:    {	break;    }    case EntryLo0:    {	cp0[EntryLo0] = clear_bits(x, 63, 30);	break;    }    case EntryLo1:    {	cp0[EntryLo1] = clear_bits(x, 63, 30);	break;    }    case Context:    {	cp0[Context] = clear_bits(x, 3, 0);	break;    }    case PageMask:    {	cp0[PageMask] = x & bitmask(24, 13);	break;    }    case Wired:    {	random_seed = now;	cp0[Wired] = clear_bits(x, 63, 6) < tlb_size ?	    clear_bits(x, 63, 6) : tlb_size - 1;	break;    }    case BadVAddr:    {	break;    }    case Count:    {	count_seed = now;	cp0[Count] = zero_extend<UInt64>(x, 32);	set_timer();	break;    }    case EntryHi:    {	asid = bits(x, 7, 0);	cp0[EntryHi] = x & (bitmask(63, 62) |			    bitmask(vaddr_width - 1, 13) |			    bitmask(7, 0));	break;    }    case Compare:    {	cp0[Compare] = zero_extend<UInt64>(x, 32);	events = clear_bit(events, 7 + Cause_IP_First);	set_timer();	break;    }    case SR:    {	cp0[SR] =	    x & ~(bitmask(27) | bitmask(24, 23) | bitmask(21) |	bitmask(19));	leave_kernel_mode();	break;    }    case Cause:    {	events |= x & bitmask(Cause_IP1, Cause_IP0);	break;    }    case EPC:    {	cp0[EPC] = x;	break;    }    case PRId:    {	break;    }    case Config:    {	cp0[Config] = set_bits(cp0[Config], x, 2, 0);	break;    }    case LLAddr:    {	cp0[LLAddr] = zero_extend<UInt64>(x, 32);	break;    }    case WatchLo:    {	break;    }    case WatchHi:    {	break;    }    case XContext:    {	cp0[XContext] = clear_bits(x, 3, 0);	break;    }    case ECC:    {	cp0[ECC] = clear_bits(x, 63, 8);	break;    }    case CacheErr:    {	break;    }    case TagLo:    {	cp0[TagLo] = zero_extend<UInt64>(clear_bit(x, 1), 32);	break;    }    case TagHi:    {	break;    }    case ErrorEPC:    {	cp0[ErrorEPC] = x;	break;    }    default:	// bogus (ignored)	assert(n >= 0 && n <= 31);    }}intKoala::decode_cop0(Instr instr){    // CP0 is usable in kernel more or when the CU bit in SR is set.    if (!(mode & kmode) && !bit(cp0[SR], SR_CU0))	process_coprocessor_unusable(0);    // Only COP0, DMFC0, DMTC0, MFC0 and MTC0 make sense, although the R4K    // manuals say nothing about handling the others.    if (bit(instr, 25)) {	switch (funct(instr)) {	case TLBR:	{	    // Read Indexed TLB Entry ////////////////////////////////////////	    TLBEntry* e = &tlb[bits(cp0[Index], 5, 0)];	    cp0[PageMask] = clear_bits(~e->mask, 12, 0);	    cp0[EntryHi]  = clear_bits(e->hi | bits(e->asid, 7, 0), 61, 40);	    cp0[EntryLo1] = e->lo[1];	    cp0[EntryLo0] = e->lo[0];	    return nothing_special;	}	case TLBWI:	{	    // Write Indexed TLB Entry ///////////////////////////////////////	    set_tlb_entry(bits(cp0[Index], 5, 0));	    return nothing_special;	}	case TLBWR:	{	    // Write Random TLB Entry ////////////////////////////////////////	    set_tlb_entry(get_random());	    return nothing_special;	}	case TLBP:	{	    // Probe TLB For Matching Entry //////////////////////////////////	    VA va = cp0[EntryHi];	    //if (vaddr_region(va) == 3)	//	va = set_bits(va, 61, 40);	    TLBEntry* e = probe_tlb(va);	    cp0[Index] = (e) ? e->index : bitmask(31);	    return nothing_special;	}	case ERET:	{	    // Exception Return //////////////////////////////////////////////	    if (bit(cp0[SR], SR_ERL)) {		pc = cp0[ErrorEPC] - 4;		cp0[SR] = clear_bit(cp0[SR], SR_ERL);	    }	    else {		pc = cp0[EPC] - 4;		cp0[SR] = clear_bit(cp0[SR], SR_EXL);	    }	    leave_kernel_mode();	    ll_bit = false;	    return nothing_special;	}	case WAIT:	{	    // Wait //////////////////////////////////////////////////////////	    // This is implemented by busy-waiting for an interrupt.  It's of	    // course wrong in that the CP0 Random and CP0 Count are affected,	    // but, right now, I don't care.	    pc -= 4;	    return nothing_special;	}	default:	    // bogus: do nothing	    return nothing_special;	}    }    else {	switch (rs(instr)) {	case MFCz:	{	    // Move From System Control Coprocessor //////////////////////////	    gpr[rt(instr)] = sign_extend<UInt64>(read_cp0(rd(instr)), 32);	    return nothing_special;	}	case DMFCz:	{	    // Doubleword Move From System Control Coprocessor ///////////////	    gpr[rt(instr)] = sign_extend<UInt64>(read_cp0(rd(instr)), 64);	    return nothing_special;	}	case CFCz:	{	    // Move Control From Coprocessor /////////////////////////////////	    return nothing_special;	}	case MTCz:	{	    // Move To System Control Coprocessor ////////////////////////////	    write_cp0(rd(instr), sign_extend<UInt64>(gpr[rt(instr)], 32));	    return nothing_special;	}	case DMTCz:	{	    // Doubleword Move To System Control Coprocessor /////////////////	    write_cp0(rd(instr), gpr[rt(instr)]);	    return nothing_special;	}	case CTCz:	{	    // Move Control To Coprocessor ///////////////////////////////////	    return nothing_special;	}	case BCz:	{	    // Branch On Coprocessor Condition ///////////////////////////////	    switch (rt(instr)) {	    case BCzF:	    case BCzT:	    case BCzFL:	    case BCzTL:		return nothing_special;	    default:		process_reserved_instruction();	    }	}	default:	    process_reserved_instruction();	}    }    return nothing_special;}

⌨️ 快捷键说明

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