📄 stats.c
字号:
/* stats.c - statistical package routines *//* 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 <limits.h>#include <math.h>#include "host.h"#include "misc.h"#include "machine.h"#include "eval.h"#include "stats.h"/* evaluate a stat as an expression */struct eval_value_tstat_eval_ident(struct eval_state_t *es)/* an expression evaluator */{ struct stat_sdb_t *sdb = es->user_ptr; struct stat_stat_t *stat; static struct eval_value_t err_value = { et_int, { 0 } }; struct eval_value_t val; /* locate the stat variable */ for (stat = sdb->stats; stat != NULL; stat = stat->next) { if (!strcmp(stat->name, es->tok_buf)) { /* found it! */ break; } } if (!stat) { /* could not find stat variable */ eval_error = ERR_UNDEFVAR; return err_value; } /* else, return the value of stat */ /* convert the stat variable value to a typed expression value */ switch (stat->sc) { case sc_int: val.type = et_int; val.value.as_int = *stat->variant.for_int.var; break; case sc_uint: val.type = et_uint; val.value.as_uint = *stat->variant.for_uint.var; break;#ifdef HOST_HAS_QWORD case sc_qword: /* FIXME: cast to double, eval package doesn't support long long's */ val.type = et_double;#ifdef _MSC_VER /* FIXME: MSC does not implement qword_t to dbl conversion */ val.value.as_double = (double)(sqword_t)*stat->variant.for_qword.var;#else /* !_MSC_VER */ val.value.as_double = (double)*stat->variant.for_qword.var;#endif /* _MSC_VER */ break; case sc_sqword: /* FIXME: cast to double, eval package doesn't support long long's */ val.type = et_double; val.value.as_double = (double)*stat->variant.for_sqword.var; break;#endif /* HOST_HAS_QWORD */ case sc_float: val.type = et_float; val.value.as_float = *stat->variant.for_float.var; break; case sc_double: val.type = et_double; val.value.as_double = *stat->variant.for_double.var; break; case sc_dist: case sc_sdist: fatal("stat distributions not allowed in formula expressions"); break; case sc_formula: { /* instantiate a new evaluator to avoid recursion problems */ struct eval_state_t *es = eval_new(stat_eval_ident, sdb); char *endp; val = eval_expr(es, stat->variant.for_formula.formula, &endp); if (eval_error != ERR_NOERR || *endp != '\0') { /* pass through eval_error */ val = err_value; } /* else, use value returned */ eval_delete(es); } break; default: panic("bogus stat class"); } return val;}/* create a new stats database */struct stat_sdb_t *stat_new(void){ struct stat_sdb_t *sdb; sdb = (struct stat_sdb_t *)calloc(1, sizeof(struct stat_sdb_t)); if (!sdb) fatal("out of virtual memory"); sdb->stats = NULL; sdb->evaluator = eval_new(stat_eval_ident, sdb); return sdb;}/* delete a stats database */voidstat_delete(struct stat_sdb_t *sdb) /* stats database */{ int i; struct stat_stat_t *stat, *stat_next; struct bucket_t *bucket, *bucket_next; /* free all individual stat variables */ for (stat = sdb->stats; stat != NULL; stat = stat_next) { stat_next = stat->next; stat->next = NULL; /* free stat */ switch (stat->sc) { case sc_int: case sc_uint:#ifdef HOST_HAS_QWORD case sc_qword: case sc_sqword:#endif /* HOST_HAS_QWORD */ case sc_float: case sc_double: case sc_formula: /* no other storage to deallocate */ break; case sc_dist: /* free distribution array */ free(stat->variant.for_dist.arr); stat->variant.for_dist.arr = NULL; break; case sc_sdist: /* free all hash table buckets */ for (i=0; i<HTAB_SZ; i++) { for (bucket = stat->variant.for_sdist.sarr[i]; bucket != NULL; bucket = bucket_next) { bucket_next = bucket->next; bucket->next = NULL; free(bucket); } stat->variant.for_sdist.sarr[i] = NULL; } /* free hash table array */ free(stat->variant.for_sdist.sarr); stat->variant.for_sdist.sarr = NULL; break; default: panic("bogus stat class"); } /* free stat variable record */ free(stat); } sdb->stats = NULL; eval_delete(sdb->evaluator); sdb->evaluator = NULL; free(sdb);}/* add stat variable STAT to stat database SDB */static voidadd_stat(struct stat_sdb_t *sdb, /* stat database */ struct stat_stat_t *stat) /* stat variable */{ struct stat_stat_t *elt, *prev; /* append at end of stat database list */ for (prev=NULL, elt=sdb->stats; elt != NULL; prev=elt, elt=elt->next) /* nada */; /* append stat to stats chain */ if (prev != NULL) prev->next = stat; else /* prev == NULL */ sdb->stats = stat; stat->next = NULL;}/* register an integer statistical variable */struct stat_stat_t *stat_reg_int(struct stat_sdb_t *sdb, /* stat database */ char *name, /* stat variable name */ char *desc, /* stat variable description */ int *var, /* stat variable */ int init_val, /* stat variable initial value */ char *format) /* optional variable output format */{ struct stat_stat_t *stat; stat = (struct stat_stat_t *)calloc(1, sizeof(struct stat_stat_t)); if (!stat) fatal("out of virtual memory"); stat->name = mystrdup(name); stat->desc = mystrdup(desc); stat->format = format ? format : "%12d"; stat->sc = sc_int; stat->variant.for_int.var = var; stat->variant.for_int.init_val = init_val; /* link onto SDB chain */ add_stat(sdb, stat); /* initialize stat */ *var = init_val; return stat;}/* register an unsigned integer statistical variable */struct stat_stat_t *stat_reg_uint(struct stat_sdb_t *sdb, /* stat database */ char *name, /* stat variable name */ char *desc, /* stat variable description */ unsigned int *var, /* stat variable */ unsigned int init_val, /* stat variable initial value */ char *format) /* optional variable output format */{ struct stat_stat_t *stat; stat = (struct stat_stat_t *)calloc(1, sizeof(struct stat_stat_t)); if (!stat) fatal("out of virtual memory"); stat->name = mystrdup(name); stat->desc = mystrdup(desc); stat->format = format ? format : "%12u"; stat->sc = sc_uint; stat->variant.for_uint.var = var; stat->variant.for_uint.init_val = init_val; /* link onto SDB chain */ add_stat(sdb, stat); /* initialize stat */ *var = init_val; return stat;}#ifdef HOST_HAS_QWORD/* register a qword integer statistical variable */struct stat_stat_t *stat_reg_qword(struct stat_sdb_t *sdb, /* stat database */ char *name, /* stat variable name */ char *desc, /* stat variable description */ qword_t *var, /* stat variable */ qword_t init_val, /* stat variable initial value */ char *format) /* optional variable output format */{ struct stat_stat_t *stat; stat = (struct stat_stat_t *)calloc(1, sizeof(struct stat_stat_t)); if (!stat) fatal("out of virtual memory"); stat->name = mystrdup(name); stat->desc = mystrdup(desc); stat->format = format ? format : "%12lu"; stat->sc = sc_qword; stat->variant.for_qword.var = var; stat->variant.for_qword.init_val = init_val; /* link onto SDB chain */ add_stat(sdb, stat); /* initialize stat */ *var = init_val; return stat;}/* register a signed qword integer statistical variable */struct stat_stat_t *stat_reg_sqword(struct stat_sdb_t *sdb, /* stat database */ char *name, /* stat variable name */ char *desc, /* stat variable description */ sqword_t *var, /* stat variable */ sqword_t init_val, /* stat variable initial value */ char *format) /* optional variable output format */{ struct stat_stat_t *stat; stat = (struct stat_stat_t *)calloc(1, sizeof(struct stat_stat_t)); if (!stat) fatal("out of virtual memory"); stat->name = mystrdup(name); stat->desc = mystrdup(desc); stat->format = format ? format : "%12ld"; stat->sc = sc_sqword; stat->variant.for_sqword.var = var; stat->variant.for_sqword.init_val = init_val; /* link onto SDB chain */ add_stat(sdb, stat); /* initialize stat */ *var = init_val; return stat;}#endif /* HOST_HAS_QWORD *//* register a float statistical variable */struct stat_stat_t *stat_reg_float(struct stat_sdb_t *sdb, /* stat database */ char *name, /* stat variable name */ char *desc, /* stat variable description */ float *var, /* stat variable */ float init_val, /* stat variable initial value */ char *format) /* optional variable output format */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -