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

📄 sim-profile.c

📁 一个很有名的硬件模拟器。可以模拟CPU
💻 C
📖 第 1 页 / 共 2 页
字号:
/* sim-profile.c - sample functional simulator implementation w/ profiling *//* SimpleScalar(TM) Tool Suite * Copyright (C) 1994-2003 by Todd M. Austin, Ph.D. and SimpleScalar, LLC. * All Rights Reserved.  *  * THIS IS A LEGAL DOCUMENT, BY USING SIMPLESCALAR, * YOU ARE AGREEING TO THESE TERMS AND CONDITIONS. *  * No portion of this work may be used by any commercial entity, or for any * commercial purpose, without the prior, written permission of SimpleScalar, * LLC (info@simplescalar.com). Nonprofit and noncommercial use is permitted * as described below. *  * 1. SimpleScalar is provided AS IS, with no warranty of any kind, express * or implied. The user of the program accepts full responsibility for the * application of the program and the use of any results. *  * 2. Nonprofit and noncommercial use is encouraged. SimpleScalar may be * downloaded, compiled, executed, copied, and modified solely for nonprofit, * educational, noncommercial research, and noncommercial scholarship * purposes provided that this notice in its entirety accompanies all copies. * Copies of the modified software can be delivered to persons who use it * solely for nonprofit, educational, noncommercial research, and * noncommercial scholarship purposes provided that this notice in its * entirety accompanies all copies. *  * 3. ALL COMMERCIAL USE, AND ALL USE BY FOR PROFIT ENTITIES, IS EXPRESSLY * PROHIBITED WITHOUT A LICENSE FROM SIMPLESCALAR, LLC (info@simplescalar.com). *  * 4. No nonprofit user may place any restrictions on the use of this software, * including as modified by the user, by any other authorized user. *  * 5. Noncommercial and nonprofit users may distribute copies of SimpleScalar * in compiled or executable form as set forth in Section 2, provided that * either: (A) it is accompanied by the corresponding machine-readable source * code, or (B) it is accompanied by a written offer, with no time limit, to * give anyone a machine-readable copy of the corresponding source code in * return for reimbursement of the cost of distribution. This written offer * must permit verbatim duplication by anyone, or (C) it is distributed by * someone who received only the executable form, and is accompanied by a * copy of the written offer of source code. *  * 6. SimpleScalar was developed by Todd M. Austin, Ph.D. The tool suite is * currently maintained by SimpleScalar LLC (info@simplescalar.com). US Mail: * 2395 Timbercrest Court, Ann Arbor, MI 48105. *  * Copyright (C) 1994-2003 by Todd M. Austin, Ph.D. and SimpleScalar, LLC. */#include <stdio.h>#include <stdlib.h>#include <math.h>#include "host.h"#include "misc.h"#include "machine.h"#include "regs.h"#include "memory.h"#include "loader.h"#include "syscall.h"#include "dlite.h"#include "symbol.h"#include "options.h"#include "stats.h"#include "sim.h"/* * This file implements a functional simulator with profiling support.  Run * with the `-h' flag to see profiling options available. *//* simulated registers */static struct regs_t regs;/* simulated memory */static struct mem_t *mem = NULL;/* track number of refs */static counter_t sim_num_refs = 0;/* maximum number of inst's to execute */static unsigned int max_insts;/* profiling options */static int prof_all /* = FALSE */;static int prof_ic /* = FALSE */;static int prof_inst /* = FALSE */;static int prof_bc /* = FALSE */;static int prof_am /* = FALSE */;static int prof_seg /* = FALSE */;static int prof_tsyms /* = FALSE */;static int prof_dsyms /* = FALSE */;static int load_locals /* = FALSE */;static int prof_taddr /* = FALSE */;/* text-based stat profiles */#define MAX_PCSTAT_VARS 8static int pcstat_nelt = 0;static char *pcstat_vars[MAX_PCSTAT_VARS];/* register simulator-specific options */voidsim_reg_options(struct opt_odb_t *odb){  opt_reg_header(odb, "sim-profile: This simulator implements a functional simulator with\n""profiling support.  Run with the `-h' flag to see profiling options\n""available.\n"		 );  /* instruction limit */  opt_reg_uint(odb, "-max:inst", "maximum number of inst's to execute",	       &max_insts, /* default */0,	       /* print */TRUE, /* format */NULL);  opt_reg_flag(odb, "-all", "enable all profile options",	       &prof_all, /* default */FALSE, /* print */TRUE, NULL);  opt_reg_flag(odb, "-iclass", "enable instruction class profiling",	       &prof_ic, /* default */FALSE, /* print */TRUE, NULL);  opt_reg_flag(odb, "-iprof", "enable instruction profiling",	       &prof_inst, /* default */FALSE, /* print */TRUE, NULL);  opt_reg_flag(odb, "-brprof", "enable branch instruction profiling",	       &prof_bc, /* default */FALSE, /* print */TRUE, NULL);  opt_reg_flag(odb, "-amprof", "enable address mode profiling",	       &prof_am, /* default */FALSE, /* print */TRUE, NULL);  opt_reg_flag(odb, "-segprof", "enable load/store address segment profiling",	       &prof_seg, /* default */FALSE, /* print */TRUE, NULL);  opt_reg_flag(odb, "-tsymprof", "enable text symbol profiling",	       &prof_tsyms, /* default */FALSE, /* print */TRUE, NULL);  opt_reg_flag(odb, "-taddrprof", "enable text address profiling",	       &prof_taddr, /* default */FALSE, /* print */TRUE, NULL);  opt_reg_flag(odb, "-dsymprof", "enable data symbol profiling",	       &prof_dsyms, /* default */FALSE, /* print */TRUE, NULL);  opt_reg_flag(odb, "-internal",	       "include compiler-internal symbols during symbol profiling",	       &load_locals, /* default */FALSE, /* print */TRUE, NULL);  opt_reg_string_list(odb, "-pcstat",		      "profile stat(s) against text addr's (mult uses ok)",		      pcstat_vars, MAX_PCSTAT_VARS, &pcstat_nelt, NULL,		      /* !print */FALSE, /* format */NULL, /* accrue */TRUE);}/* check simulator-specific option values */voidsim_check_options(struct opt_odb_t *odb, int argc, char **argv){  if (prof_all)    {      /* enable all options */      prof_ic = TRUE;      prof_inst = TRUE;      prof_bc = TRUE;      prof_am = TRUE;      prof_seg = TRUE;      prof_tsyms = TRUE;      prof_dsyms = TRUE;      prof_taddr = TRUE;    }}/* instruction classes */enum inst_class_t {  ic_load,		/* load inst */  ic_store,		/* store inst */  ic_uncond,		/* uncond branch */  ic_cond,		/* cond branch */  ic_icomp,		/* all other integer computation */  ic_fcomp,		/* all floating point computation */  ic_trap,		/* system call */  ic_NUM};/* instruction class strings */static char *inst_class_str[ic_NUM] = {  "load",		/* load inst */  "store",		/* store inst */  "uncond branch",	/* uncond branch */  "cond branch",	/* cond branch */  "int computation",	/* all other integer computation */  "fp computation",	/* all floating point computation */  "trap"		/* system call */};/* instruction class profile */static struct stat_stat_t *ic_prof = NULL;/* instruction description strings */static char *inst_str[OP_MAX];/* instruction profile */static struct stat_stat_t *inst_prof = NULL;/* branch class profile */enum branch_class_t {  bc_uncond_dir,	/* direct unconditional branch */  bc_cond_dir,		/* direct conditional branch */  bc_call_dir,		/* direct functional call */  bc_uncond_indir,	/* indirect unconditional branch */  bc_cond_indir,	/* indirect conditional branch */  bc_call_indir,	/* indirect function call */  bc_NUM};/* branch class description strings */static char *branch_class_str[bc_NUM] = {  "uncond direct",	/* direct unconditional branch */  "cond direct",	/* direct conditional branch */  "call direct",	/* direct functional call */  "uncond indirect",	/* indirect unconditional branch */  "cond indirect",	/* indirect conditional branch */  "call indirect"	/* indirect function call */};/* branch profile */static struct stat_stat_t *bc_prof = NULL;/* addressing mode profile */static struct stat_stat_t *am_prof = NULL;/* address segments */enum addr_seg_t {  seg_data,		/* data segment */  seg_heap,		/* heap segment */  seg_stack,		/* stack segment */  seg_text,		/* text segment */  seg_NUM};/* address segment strings */static char *addr_seg_str[seg_NUM] = {  "data segment",	/* data segment */  "heap segment",	/* heap segment */  "stack segment",	/* stack segment */  "text segment",	/* text segment */};/* address segment profile */static struct stat_stat_t *seg_prof = NULL;/* bind ADDR to the segment it references */static enum addr_seg_t			/* segment referenced by ADDR */bind_to_seg(md_addr_t addr)		/* address to bind to a segment */{  if (ld_data_base <= addr && addr < (ld_data_base + ld_data_size))    return seg_data;  else if ((ld_data_base + ld_data_size) <= addr && addr < ld_brk_point)    return seg_heap;  /* FIXME: ouch! */  else if ((ld_stack_base - (16*1024*1024)) <= addr && addr < ld_stack_base)    return seg_stack;  else if (ld_text_base <= addr && addr < (ld_text_base + ld_text_size))    return seg_text;  else    panic("cannot bind address to segment");}/* text symbol profile */static struct stat_stat_t *tsym_prof = NULL;static char **tsym_names = NULL;/* data symbol profile */static struct stat_stat_t *dsym_prof = NULL;static char **dsym_names = NULL;/* text address profile */static struct stat_stat_t *taddr_prof = NULL;/* text-based stat profiles */static struct stat_stat_t *pcstat_stats[MAX_PCSTAT_VARS];static counter_t pcstat_lastvals[MAX_PCSTAT_VARS];static struct stat_stat_t *pcstat_sdists[MAX_PCSTAT_VARS];/* wedge all stat values into a counter_t */#define STATVAL(STAT)							\  ((STAT)->sc == sc_int							\   ? (counter_t)*((STAT)->variant.for_int.var)				\   : ((STAT)->sc == sc_uint						\      ? (counter_t)*((STAT)->variant.for_uint.var)			\      : ((STAT)->sc == sc_counter					\	 ? *((STAT)->variant.for_counter.var)				\	 : (panic("bad stat class"), 0))))/* register simulator-specific statistics */voidsim_reg_stats(struct stat_sdb_t *sdb){  int i;  stat_reg_counter(sdb, "sim_num_insn",		   "total number of instructions executed",		   &sim_num_insn, sim_num_insn, NULL);  stat_reg_counter(sdb, "sim_num_refs",		   "total number of loads and stores executed",		   &sim_num_refs, 0, NULL);  stat_reg_int(sdb, "sim_elapsed_time",	       "total simulation time in seconds",	       &sim_elapsed_time, 0, NULL);  stat_reg_formula(sdb, "sim_inst_rate",		   "simulation speed (in insts/sec)",		   "sim_num_insn / sim_elapsed_time", NULL);  if (prof_ic)    {      /* instruction class profile */      ic_prof = stat_reg_dist(sdb, "sim_inst_class_prof",			      "instruction class profile",			      /* initial value */0,			      /* array size */ic_NUM,			      /* bucket size */1,			      /* print format */(PF_COUNT|PF_PDF),			      /* format */NULL,			      /* index map */inst_class_str,			      /* print fn */NULL);    }  if (prof_inst)    {      int i;      char buf[512];      /* conjure up appropriate instruction description strings */      for (i=0; i < /* skip NA */OP_MAX-1; i++)	{	  sprintf(buf, "%-8s %-6s", md_op2name[i+1], md_op2format[i+1]);	  inst_str[i] = mystrdup(buf);	}            /* instruction profile */      inst_prof = stat_reg_dist(sdb, "sim_inst_prof",				"instruction profile",				/* initial value */0,				/* array size */ /* skip NA */OP_MAX-1,				/* bucket size */1,				/* print format */(PF_COUNT|PF_PDF),				/* format */NULL,				/* index map */inst_str,				/* print fn */NULL);    }  if (prof_bc)    {      /* instruction branch profile */      bc_prof = stat_reg_dist(sdb, "sim_branch_prof",			      "branch instruction profile",			      /* initial value */0,			      /* array size */bc_NUM,			      /* bucket size */1,			      /* print format */(PF_COUNT|PF_PDF),			      /* format */NULL,			      /* index map */branch_class_str,			      /* print fn */NULL);    }  if (prof_am)    {      /* instruction branch profile */      am_prof = stat_reg_dist(sdb, "sim_addr_mode_prof",			      "addressing mode profile",			      /* initial value */0,			      /* array size */md_amode_NUM,			      /* bucket size */1,			      /* print format */(PF_COUNT|PF_PDF),			      /* format */NULL,			      /* index map */md_amode_str,			      /* print fn */NULL);    }  if (prof_seg)    {      /* instruction branch profile */      seg_prof = stat_reg_dist(sdb, "sim_addr_seg_prof",			       "load/store address segment profile",			       /* initial value */0,			       /* array size */seg_NUM,			       /* bucket size */1,			       /* print format */(PF_COUNT|PF_PDF),			       /* format */NULL,			       /* index map */addr_seg_str,			       /* print fn */NULL);    }  if (prof_tsyms && sym_ntextsyms != 0)    {      int i;      /* load program symbols */      sym_loadsyms(ld_prog_fname, load_locals);      /* conjure up appropriate instruction description strings */      tsym_names = (char **)calloc(sym_ntextsyms, sizeof(char *));      for (i=0; i < sym_ntextsyms; i++)	tsym_names[i] = sym_textsyms[i]->name;            /* text symbol profile */      tsym_prof = stat_reg_dist(sdb, "sim_text_sym_prof",				"text symbol profile",				/* initial value */0,				/* array size */sym_ntextsyms,				/* bucket size */1,				/* print format */(PF_COUNT|PF_PDF),				/* format */NULL,				/* index map */tsym_names,				/* print fn */NULL);    }  if (prof_dsyms && sym_ndatasyms != 0)    {      int i;      /* load program symbols */      sym_loadsyms(ld_prog_fname, load_locals);      /* conjure up appropriate instruction description strings */      dsym_names = (char **)calloc(sym_ndatasyms, sizeof(char *));      for (i=0; i < sym_ndatasyms; i++)	dsym_names[i] = sym_datasyms[i]->name;            /* data symbol profile */      dsym_prof = stat_reg_dist(sdb, "sim_data_sym_prof",				"data symbol profile",				/* initial value */0,				/* array size */sym_ndatasyms,				/* bucket size */1,				/* print format */(PF_COUNT|PF_PDF),				/* format */NULL,				/* index map */dsym_names,				/* print fn */NULL);    }

⌨️ 快捷键说明

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