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

📄 eval.c

📁 一个很有名的硬件模拟器。可以模拟CPU
💻 C
📖 第 1 页 / 共 3 页
字号:
/* expr.c - expression evaluator 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 <ctype.h>#include <errno.h>#include "host.h"#include "misc.h"#include "eval.h"#if defined(sparc) && !defined(__svr4__)#define strtoul strtol#endif /* sparc *//* expression evaluation error, this must be a global */enum eval_err_t eval_error = ERR_NOERR;/* enum eval_err_t -> error description string map */char *eval_err_str[ERR_NUM] = {  /* ERR_NOERR */	"!! no error!!",  /* ERR_UPAREN */	"unmatched parenthesis",  /* ERR_NOTERM */	"expression term is missing",  /* ERR_DIV0 */	"divide by zero",  /* ERR_BADCONST */	"badly formed constant",  /* ERR_BADEXPR */	"badly formed expression",  /* ERR_UNDEFVAR */	"variable is undefined",  /* ERR_EXTRA */	"extra characters at end of expression"};/* *first* token character -> enum eval_token_t map */static enum eval_token_t tok_map[256];static int tok_map_initialized = FALSE;/* builds the first token map */static voidinit_tok_map(void){  int i;  for (i=0; i<256; i++)    tok_map[i] = tok_invalid;  /* identifier characters */  for (i='a'; i<='z'; i++)    tok_map[i] = tok_ident;  for (i='A'; i<='Z'; i++)    tok_map[i] = tok_ident;  tok_map[(int)'_'] = tok_ident;  tok_map[(int)'$'] = tok_ident;  /* numeric characters */  for (i='0'; i<='9'; i++)    tok_map[i] = tok_const;  tok_map[(int)'.'] = tok_const;  /* operator characters */  tok_map[(int)'+'] = tok_plus;  tok_map[(int)'-'] = tok_minus;  tok_map[(int)'*'] = tok_mult;  tok_map[(int)'/'] = tok_div;  tok_map[(int)'('] = tok_oparen;  tok_map[(int)')'] = tok_cparen;  /* whitespace characers */  tok_map[(int)' '] = tok_whitespace;  tok_map[(int)'\t'] = tok_whitespace;}/* get next token from the expression string */static enum eval_token_t		/* token parsed */get_next_token(struct eval_state_t *es)	/* expression evaluator */{  int allow_hex;  enum eval_token_t tok;  char *ptok_buf, last_char;  /* initialize the token map, if needed */  if (!tok_map_initialized)    {      init_tok_map();      tok_map_initialized = TRUE;    }  /* use the peek'ed token, if available, tok_buf should still be valid */  if (es->peek_tok != tok_invalid)    {      tok = es->peek_tok;      es->peek_tok = tok_invalid;      return tok;    }  /* set up the token string space */  ptok_buf = es->tok_buf;  *ptok_buf = '\0';  /* skip whitespace */  while (*es->p && tok_map[(int)*es->p] == tok_whitespace)    es->p++;  /* end of token stream? */  if (*es->p == '\0')    return tok_eof;  *ptok_buf++ = *es->p;  tok = tok_map[(int)*es->p++];  switch (tok)    {    case tok_ident:      /* parse off next identifier */      while (*es->p	     && (tok_map[(int)*es->p] == tok_ident		 || tok_map[(int)*es->p] == tok_const))	{	  *ptok_buf++ = *es->p++;	}      break;    case tok_const:      /* parse off next numeric literal */      last_char = '\0';      allow_hex = FALSE;      while (*es->p &&	     (tok_map[(int)*es->p] == tok_const	      || (*es->p == '-' && last_char == 'e')	      || (*es->p == '+' && last_char == 'e')	      || tolower(*es->p) == 'e'	      || tolower(*es->p) == 'x'	      || (tolower(*es->p) == 'a' && allow_hex)	      || (tolower(*es->p) == 'b' && allow_hex)	      || (tolower(*es->p) == 'c' && allow_hex)	      || (tolower(*es->p) == 'd' && allow_hex)	      || (tolower(*es->p) == 'e' && allow_hex)	      || (tolower(*es->p) == 'f' && allow_hex)))	{	  last_char = tolower(*es->p);	  if (*es->p == 'x' || *es->p == 'X')	    allow_hex = TRUE;	  *ptok_buf++ = *es->p++;	}      break;    case tok_plus:    case tok_minus:    case tok_mult:    case tok_div:    case tok_oparen:    case tok_cparen:      /* just pass on the token */      break;    default:      tok = tok_invalid;      break;    }  /* terminate the token string buffer */  *ptok_buf = '\0';  return tok;}/* peek ahead at the next token from the expression stream, currently   only the next token can be peek'ed at */static enum eval_token_t		 /* next token in expression */peek_next_token(struct eval_state_t *es) /* expression evalutor */{  /* if there is no peek ahead token, get one */  if (es->peek_tok == tok_invalid)    {      es->lastp = es->p;      es->peek_tok = get_next_token(es);    }  /* return peek ahead token */  return es->peek_tok;}/* forward declaration */static struct eval_value_t expr(struct eval_state_t *es);/* default expression error value, eval_err is also set */static struct eval_value_t err_value = { et_int, { 0 } };/* expression type strings */char *eval_type_str[et_NUM] = {  /* et_int */		"int",  /* et_uint */		"unsigned int",  /* et_addr */		"md_addr_t",#ifdef HOST_HAS_QWORD  /* et_qword */	"qword_t",  /* et_sqword */	"sqword_t",#endif /* HOST_HAS_QWORD */  /* et_float */	"float",  /* et_double */	"double",  /* et_symbol */	"symbol"};/* determine necessary arithmetic conversion on T1 <op> T2 */static enum eval_type_t			/* type of expression result */result_type(enum eval_type_t t1,	/* left operand type */	    enum eval_type_t t2)	/* right operand type */{  /* sanity check, symbols should not show up in arithmetic exprs */  if (t1 == et_symbol || t2 == et_symbol)    panic("symbol used in expression");  /* using C rules, i.e., A6.5 */  if (t1 == et_double || t2 == et_double)    return et_double;  else if (t1 == et_float || t2 == et_float)    return et_float;#ifdef HOST_HAS_QWORD  else if (t1 == et_qword || t2 == et_qword)    return et_qword;  else if (t1 == et_sqword || t2 == et_sqword)    return et_sqword;#endif /* HOST_HAS_QWORD */  else if (t1 == et_addr || t2 == et_addr)    return et_addr;  else if (t1 == et_uint || t2 == et_uint)    return et_uint;  else    return et_int;}/* * expression value arithmetic conversions *//* eval_value_t (any numeric type) -> double */doubleeval_as_double(struct eval_value_t val){  switch (val.type)    {    case et_double:      return val.value.as_double;    case et_float:      return (double)val.value.as_float;#ifdef HOST_HAS_QWORD    case et_qword:#ifdef _MSC_VER /* FIXME: MSC does not implement qword_t to dbl conversion */      return (double)(sqword_t)val.value.as_qword;#else /* !_MSC_VER */      return (double)val.value.as_qword;#endif /* _MSC_VER */    case et_sqword:      return (double)val.value.as_sqword;#endif /* HOST_HAS_QWORD */    case et_addr:#if defined(_MSC_VER) && defined(TARGET_ALPHA)      /* FIXME: MSC does not implement qword_t to double conversion */      return (double)(sqword_t)val.value.as_addr;#else      return (double)val.value.as_addr;#endif    case et_uint:      return (double)val.value.as_uint;    case et_int:      return (double)val.value.as_int;    case et_symbol:      panic("symbol used in expression");    default:      panic("illegal arithmetic expression conversion");    }}/* eval_value_t (any numeric type) -> float */floateval_as_float(struct eval_value_t val){  switch (val.type)    {    case et_double:      return (float)val.value.as_double;    case et_float:      return val.value.as_float;#ifdef HOST_HAS_QWORD    case et_qword:#ifdef _MSC_VER /* FIXME: MSC does not implement qword_t to dbl conversion */      return (float)(sqword_t)val.value.as_qword;#else /* !_MSC_VER */      return (float)val.value.as_qword;#endif /* _MSC_VER */    case et_sqword:      return (float)val.value.as_sqword;#endif /* HOST_HAS_QWORD */    case et_addr:#if defined(_MSC_VER) && defined(TARGET_ALPHA)      /* FIXME: MSC does not implement qword_t to double conversion */      return (float)(sqword_t)val.value.as_addr;#else      return (float)val.value.as_addr;#endif    case et_uint:      return (float)val.value.as_uint;    case et_int:      return (float)val.value.as_int;    case et_symbol:      panic("symbol used in expression");    default:      panic("illegal arithmetic expression conversion");    }}#ifdef HOST_HAS_QWORD/* eval_value_t (any numeric type) -> qword_t */qword_teval_as_qword(struct eval_value_t val){  switch (val.type)    {    case et_double:      return (qword_t)val.value.as_double;    case et_float:      return (qword_t)val.value.as_float;    case et_qword:      return val.value.as_qword;    case et_sqword:      return (qword_t)val.value.as_sqword;    case et_addr:      return (qword_t)val.value.as_addr;    case et_uint:      return (qword_t)val.value.as_uint;    case et_int:      return (qword_t)val.value.as_int;    case et_symbol:      panic("symbol used in expression");    default:      panic("illegal arithmetic expression conversion");    }}/* eval_value_t (any numeric type) -> sqword_t */sqword_teval_as_sqword(struct eval_value_t val){  switch (val.type)    {    case et_double:      return (sqword_t)val.value.as_double;    case et_float:      return (sqword_t)val.value.as_float;    case et_qword:      return (sqword_t)val.value.as_qword;    case et_sqword:      return val.value.as_sqword;    case et_addr:      return (sqword_t)val.value.as_addr;    case et_uint:      return (sqword_t)val.value.as_uint;    case et_int:      return (sqword_t)val.value.as_int;    case et_symbol:      panic("symbol used in expression");    default:      panic("illegal arithmetic expression conversion");    }}#endif /* HOST_HAS_QWORD *//* eval_value_t (any numeric type) -> unsigned int */md_addr_teval_as_addr(struct eval_value_t val){  switch (val.type)    {    case et_double:

⌨️ 快捷键说明

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