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

📄 cpu.cc

📁 一个mips虚拟机非常好代码,使用C++来编写的,希望大家多学学,
💻 CC
字号:
#include "assert.hh"#include "checkpoint.hh"#include "clock.hh"#include "cpu.hh"#include "module.hh"#include "sulima.hh"// Scheduler data.int CPU::cpu_count = 0;CPU *CPU::first_cpu = 0;CPU *CPU::last_cpu = 0;// Static constructor.CPU::CPU(const char *n, ClockValue f)    : Module(n), Clock(f){    ++cpu_count;    if (!last_cpu)	first_cpu = last_cpu = next_cpu = this;    else {	next_cpu = first_cpu;	last_cpu->next_cpu = this;	last_cpu = this;    }}// Dynamic constructor.CPU::CPU(const SimArgs &args)    : Module(args), Clock((long)args[2]){    ++cpu_count;    if (!last_cpu)	first_cpu = last_cpu = next_cpu = this;    else {	next_cpu = first_cpu;	last_cpu->next_cpu = this;	last_cpu = this;    }}// Serialized constructor.CPU::CPU(Checkpoint &cp)    : Serializable(cp), Module(cp), Clock(cp){    ++cpu_count;    if (!last_cpu)	first_cpu = last_cpu = next_cpu = this;    else {	next_cpu = first_cpu;	last_cpu->next_cpu = this;	last_cpu = this;    }}// Serialization support.voidCPU::checkpoint(Checkpoint &cp, bool parent) const{    assert(!parent);    Module::checkpoint(cp);    Clock::checkpoint(cp);}// GCD(x, y) using Euclid's algorithm.// Note that GCD(x, y, z) == GCD(GCD(x, y), z).static ClockValuegcd(ClockValue x, ClockValue y){    if (x < y) {	ClockValue t = x;	x = y;	y = t;    }    while (y) {	ClockValue t = x % y;	x = y;	y = t;    }    return x;}// Run the whole simulator.SimArgCPU::run_all(const SimArgs &args){    // Detect recursive invocations.    static bool running = false;    if (running)	throw Error("Recursive call to \"sim::run\".");    running = true;    // Detect bogus syntax.    if (args.length() > 2)	throw Error("Unexpected arguments to \"sim::run\".");    // Handle uniprocessor mode.    if (args.length() == 1 || cpu_count == 1) {	CPU *cpu;	if (!args.length())	    cpu = first_cpu;	else {	    const char *name = args[0];	    cpu = dynamic_cast<CPU *>(find_module(name));	    if (!cpu) {		throw Error("\"%#s\" is not a CPU module.", name);	    }	}	// Prepare the console for boot	sulima->enable_console(cpu);	// Run the module.	sulima->msg("Simulation started (1 CPU).");	cpu->run(Clock::infinity);	assert(UNREACHABLE);    }    // Otherwise, we're in a multiprocessor mode.    if (!cpu_count)	throw Error("No CPU modules have been installed.");    // Compute the timeslices.    // Find the GCD of all CPU clock frequencies    ClockValue freq = first_cpu->freq;    for (CPU *cpu = first_cpu->next_cpu;	 cpu->next_cpu != first_cpu; cpu = cpu->next_cpu)    {	freq = gcd(freq, cpu->freq);    }    // Compute the initial timeslices.    ClockValue min = infinity, max = 0;    for (CPU *cpu = first_cpu;	 cpu->next_cpu != first_cpu; cpu = cpu->next_cpu)    {	cpu->timeslice = cpu->freq / freq;	if (cpu->timeslice < min)	    min = cpu->timeslice;	if (cpu->timeslice > max)	    max = cpu->timeslice;    }    // Fix the timeslices so that each CPU gets at least 32 cycles,    // but not if that makes the longest cycle longer than 1024.    ClockValue repeat = (min + min_timeslice - 1) / min;    if (max * repeat > max_timeslice)	throw Error("The range of CPU frequencies is too large.");    // Fix the timeslices.    for (CPU *cpu = first_cpu;	 cpu->next_cpu != first_cpu; cpu = cpu->next_cpu)    {	cpu->timeslice *= repeat;    }    // Enjoy. Yeah right.    sulima->msg("Simulation started (%d CPUs).", cpu_count);    for (CPU *cpu = first_cpu;; cpu = cpu->next_cpu)	cpu->run(cpu->timeslice);}

⌨️ 快捷键说明

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