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

📄 armemul.cpp

📁 RISC processor ARM-7 emulator
💻 CPP
字号:
/*************************************************************************
    Copyright (C) 2002,2003,2004,2005 Wei Qin
    See file COPYING for more information.

    This program is free software; you can redistribute it and/or modify    
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; either version 2 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.
*************************************************************************/

#include <csignal>
#include <cstdio>
#include "armemul.h"
#include "decode.h"

#include "auto_impl.h"
#include "arm_dec.h"

#define DEF_CLASS(a,b) b,
const char *mnemonic_table[] = {
#include "inst_class.h"
};

static const UInt16 cond_table[] =
{0xf0f0, 0x0f0f, 0xcccc, 0x3333,
 0xff00, 0x00ff, 0xaaaa, 0x5555,
 0x0c0c, 0xf3f3, 0xaa55, 0x55aa,
 0x0a05, 0xf5fa, 0xffff, 0x0000};

#include "external_dev.h"

using namespace emulator;

static inline UInt32 eval_cond(arm_emulator *emu, arm_inst_t inst)
{
	UInt32 val;
	val = (cond_table[COND] >> CC)&1;
#if 0
	switch (COND) {
		case 0: val = Z_FLAG; break;
		case 1: val = !Z_FLAG; break;
		case 2: val = C_FLAG; break;
		case 3: val = !C_FLAG; break;
		case 4: val = N_FLAG; break;
		case 5: val = !N_FLAG; break;
		case 6: val = V_FLAG; break;
		case 7: val = !V_FLAG; break;
		case 8: val = C_FLAG & ~Z_FLAG; break;
		case 9: val = !(C_FLAG & ~Z_FLAG); break;
		case 10: val = N_FLAG == V_FLAG; break;
		case 11: val = N_FLAG ^ V_FLAG; break;
		case 12: val = !(Z_FLAG | (N_FLAG ^ V_FLAG)); break;
		case 13: val = Z_FLAG | (N_FLAG ^ V_FLAG); break;
		case 14: val = 1; break;
		default: val = 0; break;
	}
#endif
	return val;
}

arm_emulator::arm_emulator(bool verbose, bool emulate_syscall) :
	verbose(verbose), emulate_syscall(emulate_syscall), in_fpe(false)
{
	init_registers();
	reset_instruction_counters();
	brk_point = 0;
	mmap_brk_point = MMAP_BASE;

	running = false;
	debuging = false;

	mem = new memory();
	dev_master = new device_master();
	init_devices(dev_master);
}

arm_emulator::~arm_emulator()
{
	delete mem;
	close_devices(dev_master);
	delete dev_master;
}

void arm_emulator::execute(arm_inst_t inst, word_t addr)
{

#if 0
	{
		int x=0,i;
		for (i=0;i<15;i++) x=x+my_regs.gpr[i];
			fprintf(stderr, "0x%x 0x%x\n", PC,x);
	}
	arm_disassemble_to_stream(inst, get_pc(), stderr);
	fprintf(stderr, "0x%08x : 0x%08x\n", addr, inst);
#endif
	/* set default next PC; operation can override */
	write_gpr2(PC_REAL_IND, addr+4);
	if (COND == 0xe || eval_cond(this, inst)) {

		/*operation sees PC+8*/
		write_gpr2(PC_AHEAD_IND, addr+8);

		decode_main(this, inst);
	}
	else
		ncount++;

	icount++;
}

UInt64 arm_emulator::run_count(UInt64 count)
{
	arm_inst_t inst;

	icount = 0;
	running = true;
	while(running && icount<count)
	{
		inst = fetch_inst(get_pc());
		execute(inst, get_pc());
	}

	return icount;
}

void arm_emulator::init_registers()
{
	for (int i=0; i<NUM_GPR; i++)
		my_regs.gpr[i] = 0;

	my_regs.cpsr = 0;
	my_regs.spsr = 0;
	my_regs.cc = 0;
}

void arm_emulator::reset_instruction_counters()
{
	int i;
	icount = 0;
	ncount = 0;
	for(i = 0; i < INST_TOTAL; i++)
		counters[i] = 0;
}

void arm_emulator::reset()
{
	init_registers();
	mem->reset();
	reset_instruction_counters();
	brk_point = 0;
	mmap_brk_point = MMAP_BASE;

	in_fpe = false;
	running = false;
	debuging = false;
}

void arm_emulator::dump_instruction_counters(FILE *fp)
{
	int i;
	
	fprintf(fp, "\n");
	for(i = 0; i < INST_TOTAL; i++) {
		if(counters[i] > 0) {
			fprintf(fp, "%s : ", mnemonic_table[i]);
			dump_int64(counters[i], fp);
			if(counters[i] > 1000000) {
				fputs(" (", fp);
				dump_int64_smart(counters[i], fp);
				fputs(")", fp);
			}
			fputs("\n", fp);
		}
	}
	fputs("Total instructions : ", fp);
	dump_int64(icount, fp);
	if (icount > 1000000) {
		fputs(" (", fp);
		dump_int64_smart(icount, fp);
		fputs(")", fp);
	}

	fputs(" including ", fp);
	dump_int64(ncount, fp);
	if (ncount > 1000000) {
		fputs(" (", fp);
		dump_int64_smart(ncount, fp);
		fputs(")", fp);
	}
	fputs(" nullified\n", fp);
}

⌨️ 快捷键说明

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