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

📄 run.cc

📁 一个mips虚拟机非常好代码,使用C++来编写的,希望大家多学学,
💻 CC
字号:
#include "koala.hh"// Koala correctly simulates the intricate details of the R4600/R4700 five// stage pipeline. Each iteration of the loop completely executes the// instruction from the W pipeline stage in that Pclock cycle. This highly// simplifies accurate simulation of the pipeline.//// - Exceptions (which abort all following instructions and slip) can be// processed as slips, as we haven't attempted to process the aborted// instructions yet.//// - Pipeline slips (including exceptions) are handled simply by incrementing// the clock by the number of slip cycles.//// - Stalls are more complicated, in that the already-processed instruction// are delayed. This is normally not a problem, as these instructions are// still guranteed to complete, unless the instructions access external timing// data such as Random or an interrupt source. WARNING: currently, I ignore// this subtle difference and treat all stalls as slips.//// Originally, I was using C++ exceptions to simulate MIPS interrupts and// exceptions. However, this is somewhat messy and inefficient (although in// theory it shouldn't be), so I've switched to longjmp() instead. Also, in// order to accurately simulate interrupt priorities, asynchronous events// (interrupts, NMI, soft reset and cold reset) are signalled directly by// setting the corresponding bit of (events). As ironic as handling// synchronous exceptions asynchronously and asynchronous interrupts// synchronously sounds, it works well.#include <stdio.h>voidKoala::run(ClockValue timeslice){    setjmp(env);    for (;;) {	// Reset gpr[0].	gpr[0] = 0;	// First of all, increment the PClock counter. After this, all we need	// to handle is any slips and stalls.	++now;	poll();	// Check for interrupts. In read hardware, these have a priority lower	// than all exceptions, but simulating this effect is too hard to be	// worth the effort (interrupts and resets are not meant to be	// delivered accurately anyway.)	if (events) {	    if (bits(events, 7, 0))		process_reset();	    else if (bit(cp0[SR], SR_IE) && !bit(cp0[SR], SR_EXL) && !bit(cp0[SR], SR_ERL) && (events & cp0[SR]))		process_interrupt();	}	// Look up the ITLB. It's not clear from the manuals whether the ITLB	// stores the ASIDs or not. I assume it does. ITLB has the same size	// as in the real hardware, mapping two 4KB pages.  Because decoding a	// MIPS64 virtual address is far from trivial, ITLB and DTLB actually	// improve the simulator's performance: something I cannot say about	// caches and JTLB.	PA pa;	VA vpn = pc / 4096;	if (vpn == itlb[0].vpn && asid_match(asid, itlb[0].asid)) {	    pa = itlb[0].pa + (pc % 4096);	    lru_itlb = 1;	}	else if (vpn == itlb[1].vpn && asid_match(asid, itlb[1].asid)) {	    pa = itlb[1].pa + (pc % 4096);	    lru_itlb = 0;	}	else {	    // Do a full address translation. This introduces a slip in the I	    // pipeline stage. The slip costs 1 cycle for branch, jump and	    // ERET instructions, and 2 cycles otherwise.	    ++now;	    pa = translate_vaddr(pc, instr_fetch);	    itlb[lru_itlb].vpn = vpn;	    itlb[lru_itlb].asid = asid;	    itlb[lru_itlb].pa = round_down(pa, 4096);	    lru_itlb = !lru_itlb;	}	// Access the instruction cache. Because the simulated caches are	// slow, we maintain a two-entry buffer to cut down full fetches by	// the factor of (up to) sixteen.	Instr instr;	if (ibuf_match(pc, ibuf[0].tag)) {	    instr = swizzle<word>(ibuf[0][pc], pc);	    lru_ibuf = 1;	}	else if (ibuf_match(pc, ibuf[1].tag)) {	    instr = swizzle<word>(ibuf[1][pc], pc);	    lru_ibuf = 0;	}	else {	    // No such luck: fetch the data from the cache.	    instr = fetch(pc, pa);	}	// Now, we can decode and execute the instruction.	int next_state = decode(instr);	// Dump the registers if required.	if (trace_level >= dump_gprs)	    dump_gpr_registers();	// Advance the PC.	switch (pipeline) {	case nothing_special:	    pc += 4;	    break;	case branch_delay:	    pc = branch_target;	    break;	case instr_addr_error:	    process_address_error(instr_fetch, branch_target);	}	pipeline = next_state;    }}voidKoala::dump_gpr_registers() const{    log("\tpc = %016lx  sr = %016lx", pc, cp0[SR]);    for (int i = 0; i < 32; i += 2) {	log("\t%s = %016lx  %s = %016lx",	    regname[i], gpr[i], regname[i + 1], gpr[i + 1]);    }}voidKoala::dump_state(){    size_t i;    msg("Registers:");    msg("\tpc = %016lx  sr = %016lx", pc, cp0[SR]);    for (int i = 0; i < 32; i += 2) {	msg("\t%s = %016lx  %s = %016lx",	    regname[i], gpr[i], regname[i + 1], gpr[i + 1]);    }    msg("TLB:");    for (i = 0; i < tlb_size; i++)	msg("\thi = %016lx  lo0 = %08x  lo1 = %08x", tlb[i].hi, tlb[i].lo[0], tlb[i].lo[1]);}

⌨️ 快捷键说明

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