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

📄 libexo.cc

📁 linux下基于c++的处理器仿真平台。具有处理器流水线
💻 CC
📖 第 1 页 / 共 2 页
字号:
/* * libexo.c - EXO library main line routines * * This file is a part of the SimpleScalar tool suite written by * Todd M. Austin as a part of the Multiscalar Research Project. * * The tool suite is currently maintained by Doug Burger and Todd M. Austin. * * Copyright (C) 1997 by Todd M. Austin * * This source file is distributed "as is" in the hope that it will be * useful.  The tool set comes with no warranty, and no author or * distributor accepts any responsibility for the consequences of its * use. * * Everyone is granted permission to copy, modify and redistribute * this tool set under the following conditions: * *    This source code is distributed for non-commercial use only. *    Please contact the maintainer for restrictions applying to *    commercial use. * *    Permission is granted to anyone to make or distribute copies *    of this source code, either as received or modified, in any *    medium, provided that all copyright notices, permission and *    nonwarranty notices are preserved, and that the distributor *    grants the recipient permission for further redistribution as *    permitted by this document. * *    Permission is granted to distribute this file in compiled *    or executable form under the same conditions that apply for *    source code, provided that either: * *    A. it is accompanied by the corresponding machine-readable *       source code, *    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 that they received concurrently. * * In other words, you are welcome to use, share and improve this * source file.  You are forbidden to forbid anyone else to use, share * and improve what you give them. * * INTERNET: dburger@cs.wisc.edu * US Mail:  1210 W. Dayton Street, Madison, WI 53706 * */#include <ctype.h>#include <limits.h>#include <errno.h>#include <assert.h>#include <stdarg.h>#include <iostream>#include <string>#include "base/cprintf.hh"#include "base/misc.hh"#include "encumbered/eio/libexo.h"#include "sim/host.hh"using namespace std;/* EXO term classes print strings */char *exo_class_str[ec_NUM] = {  "integer",  "address",  "float",  "char",  "string"  "list",  "array",  "token",  "blob"};#define ULL_MAX		(ULL(9223372036854775807) * ULL(2) + 1)/* convert a string to a unsigned result */uint64_tmyatoq(char *nptr, char **endp, int base){  char *s, *save;  int overflow;  uint64_t cutoff, cutlim, i;  unsigned char c;  if (!nptr || !*nptr)    panic("strtoll() passed a NULL string");  s = nptr;  /* skip white space */  while (isspace((int)(*s)))    ++s;  if (*s == '\0')    goto noconv;  if (base == 0)    {      if (s[0] == '0' && toupper((int)s[1]) == 'X')	base = 16;      else	base = 10;    }  if (base <= 1 || base > 36)    panic("bogus base: %d", base);  if (base == 16 && s[0] == '0' && toupper((int)s[1]) == 'X')    s += 2;  /* save the pointer so we can check later if anything happened */  save = s;  cutoff = ULL_MAX / (unsigned long int) base;  cutlim = ULL_MAX % (unsigned long int) base;  overflow = 0;  i = 0;  for (c = *s; c != '\0'; c = *++s)    {      if (isdigit (c))        c -= '0';      else if (isalpha (c))        c = toupper(c) - 'A' + 10;      else        break;      if (c >= base)        break;      /* check for overflow */      if (i > cutoff || (i == cutoff && c > cutlim))        overflow = 1;      else        {          i *= (unsigned long int) base;          i += c;        }    }  /* check if anything actually happened */  if (s == save)    goto noconv;  /* store in ENDP the address of one character past the last character     we converted */  if (endp != NULL)    *endp = (char *) s;  if (overflow)    {      errno = ERANGE;      return ULL_MAX;    }  else    {      errno = 0;      /* return the result of the appropriate sign */      return i;    }noconv:  /* there was no number to convert */  if (endp != NULL)    *endp = (char *) nptr;  return 0;}/* return the value of an escape sequence, ESCAPE is a pointer to the first   character following '\', sets NEXT to first character after escape *//* A2.5.2 */static intintern_escape(char *esc, char **next){  int c, value, empty, count;  switch (c = *esc++) {  case 'x':    /* \xhh hex value */    value = 0;    empty = true;    while (1)      {        c = *esc++;        if (!(c >= 'a' && c <= 'f')            && !(c >= 'A' && c <= 'F')            && !(c >= '0' && c <= '9'))          {            esc--;            break;          }        value *=16;        if (c >= 'a' && c <= 'f')          value += c - 'a' + 10;        if (c >= 'A' && c <= 'F')          value += c - 'A' + 10;        if (c >= '0' && c <= '9')          value += c - '0';        empty = false;      }    if (empty)      fatal("\\x used with no trailing hex digits");    break;  case '0': case '1': case '2': case '3':  case '4': case '5': case '6': case '7':    /* \ooo octal value */    value = 0;    count = 0;    while ((c <= '7') && (c >= '0') && (count++ < 3))      {        value = (value * 8) + (c - '0');        c = *esc++;      }    esc--;    break;  case '\\':  case '\'':  case '"':    value = c;    break;  case 'n':    value = '\n';    break;  case 't':    value = '\t';    break;  case 'r':    value = '\r';    break;  case 'f':    value = '\f';    break;  case 'b':    value = '\b';    break;  case 'a':    value = '\a';    break;  case 'v':    value = '\v';    break;  case '?':    value = c;    break;  case '(':  case '{':  case '[':  case '%':    value = c;    warn("non-ANSI escape sequence `\\%c'", c);    break;  default:    fatal("unknown escape, '\\' followed by char %x (`%c')", (int)c, c);  }  if (*next)    *next = esc;  return value;}/* return the value of an character literal sequence *//* A2.5.2 */static intintern_char(char *s, char **next){  unsigned char value;  if (s[0] != '\'' || s[strlen(s)-1] != '\'')    panic("mal-formed string constant");  if (s[1] != '\\')    {      value = (unsigned)s[1];      if (s[2] != '\'')	panic("mal-formed string constant");      if (next)	*next = s + 2;    }  else    {      /* escaped char constant */      value = intern_escape(s+2, next);    }  /* map to a signed char value */  value = (signed int)((unsigned char)((unsigned char)((unsigned int)value)));  return value;}static voidprint_char(unsigned char c, ostream &stream){  switch (c)    {    case '\n':      stream << "\\n";      break;    case '\\':      stream << "\\\\";      break;    case '\'':      stream << "\\'";      break;    case '\t':      stream << "\\t";      break;    case '\r':      stream << "\\r";      break;    case '\f':      stream << "\\f";      break;    case '\b':      stream << "\\b";      break;    case '\a':      stream << "\\a";      break;    case '\v':      stream << "\\v";      break;    default:      if (isprint(c))	  stream << c;      else	ccprintf(stream, "\\x%02x", c);    }}/* expand all escapes in string STR, return pointer to allocation w/ result */static char *intern_string(char *str){  char *s, *istr;  /* resulting string cannot be longer than STR */  s = istr = (char *)malloc(strlen(str)+1);  if (!str || !*str || *str != '\"') /* " */    panic("mal-formed string constant");  /* skip `"' */ /* " */  str++;  while (*str)    {      if (*str == '\\')        *s++ = intern_escape(str+1, &str);      else        {          /* A2.6 */          if (*str == '\n')            warn("ANSI C forbids newline in character constant");          /* A2.6 */          if (*str == '"' && str[1] != '\0')            panic("encountered `\"' embedded in string constant");          if (*str != '\"') /* " */            *s++ = *str;          str++;        }    }  *s = '\0';  return istr;}static voidprint_string(unsigned char *s, ostream &stream){    while (*s) {	print_char(*s, stream);	s++;    }}/* bogus token value */#define TOKEN_BOGON		0static int token_id = TOKEN_BOGON + 1;#define TOKEN_HASH_SIZE		1024struct exo_token_t *token_hash[TOKEN_HASH_SIZE];/* hash a string */static unsigned longhash_str(char *s){  unsigned h = 0;  while (*s)    h = (h << 1) + *s++;  return (h % TOKEN_HASH_SIZE);}/* intern token TOKEN_STR */struct exo_token_t *exo_intern(char *token_str)		/* string to intern */{  int index;  struct exo_token_t *ent;  index = hash_str(token_str);  for (ent=token_hash[index]; ent != NULL; ent=ent->next)    {      if (!strcmp(token_str, ent->str))	{	  /* got a match, return token entry */	  return ent;	}    }  /* not found, create a new entry */  ent = (struct exo_token_t *)calloc(1, sizeof(struct exo_token_t));  if (!ent)    fatal("out of virtual memory");  ent->str = strdup(token_str);  ent->token = token_id++;  ent->next = token_hash[index];  token_hash[index] = ent;  return ent;}/* intern token TOKEN_STR as value TOKEN */struct exo_token_t *exo_intern_as(char *token_str,		/* string to intern */	      int token)		/* internment value */{  struct exo_token_t *ent;#if 0  if (token_id > token)    fatal("token value is already in use");#endif  ent = exo_intern(token_str);  /* overide the default value */  ent->token = token;#if 0  if (ent->token != token)    fatal("symbol `%s' was previously interned", token_str);#endif  return ent;}/* allocate an EXO node, fill in its type */static struct exo_term_t *exo_alloc(enum exo_class_t ec){  struct exo_term_t *exo;  exo = (struct exo_term_t *)calloc(1, sizeof(struct exo_term_t));  if (!exo)    fatal("out of virtual memory");  exo->next = NULL;  exo->ec = ec;  return exo;}/* * create a new EXO term, usage: * *	exo_new(ec_integer, (exo_integer_t)<int>); *	exo_new(ec_address, (exo_integer_t)<int>); *	exo_new(ec_float, (exo_float_t)<float>); *	exo_new(ec_char, (int)<char>); *      exo_new(ec_string, "<string>"); *      exo_new(ec_list, <list_ent>..., NULL); *      exo_new(ec_array, <size>, <array_ent>..., NULL); *	exo_new(ec_token, "<token>");*/struct exo_term_t *exo_new(enum exo_class_t ec, ...){  struct exo_term_t *exo;  va_list v;  va_start(v, ec);  exo = exo_alloc(ec);  switch (ec)    {    case ec_integer:      exo->as_integer.val = va_arg(v, exo_integer_t);      break;    case ec_address:      exo->as_address.val = va_arg(v, exo_address_t);      break;    case ec_float:      exo->as_float.val = va_arg(v, exo_float_t);      break;    case ec_char:      exo->as_char.val = va_arg(v, int);      break;    case ec_string:      {	char *str;	str = va_arg(v, char *);	exo->as_string.str = (unsigned char *)strdup(str);      }      break;    case ec_list:      {	struct exo_term_t *ent;	exo->as_list.head = NULL;	do {	  ent = va_arg(v, struct exo_term_t *);	  exo->as_list.head = exo_chain(exo->as_list.head, ent);	} while (ent != NULL);      }      break;    case ec_array:      {	int i;	struct exo_term_t *ent;	exo->as_array.size = va_arg(v, int);	exo->as_array.array = (struct exo_term_t **)	  calloc(exo->as_array.size, sizeof(struct exo_term_t *));	if (!exo->as_array.array)	  fatal("out of virtual memory");	i = 0;	do {	  ent = va_arg(v, struct exo_term_t *);	  if (ent != NULL)	    {	      if (i == exo->as_array.size)		fatal("array constructor overflow");	      SET_EXO_ARR(exo, i, ent);	    }	  i++;	} while (ent != NULL);      }      break;    case ec_token:      {	char *str;	str = va_arg(v, char *);	exo->as_token.ent = exo_intern(str);      }      break;    case ec_blob:      {	unsigned size;	unsigned char *data;	size = va_arg(v, unsigned);	data = va_arg(v, unsigned char *);	exo->as_blob.size = size;	exo->as_blob.data = (unsigned char *)malloc(size);	if (data != NULL)	  memcpy(exo->as_blob.data, data, size);	else	  memset(exo->as_blob.data, 0, size);      }      break;    case ec_null:      break;    default:      panic("bogus EXO class");    }  va_end(v);  return exo;}/* release an EXO term */voidexo_delete(struct exo_term_t *exo){  exo->next = NULL;  switch (exo->ec)    {    case ec_integer:      /* no extra storage */      exo->as_integer.val = 0;      break;    case ec_address:      /* no extra storage */      exo->as_address.val = 0;      break;    case ec_float:      /* no extra storage */      exo->as_float.val = 0.0;      break;    case ec_char:      /* no extra storage */      exo->as_char.val = '\0';      break;    case ec_string:      free(exo->as_string.str);

⌨️ 快捷键说明

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