📄 sim-profile.c
字号:
/* 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 + -