dlite.c

来自「一个很有名的硬件模拟器。可以模拟CPU」· C语言 代码 · 共 2,262 行 · 第 1/4 页

C
2,262 行
字号
  dlite_step_into = FALSE;  /* no error */  return NULL;}#endif/* print the value of <expr> using format <modifiers> */static char *				      	/* err str, NULL for no err */dlite_print(int nargs, union arg_val_t args[],	/* command arguments */	    struct regs_t *regs,		/* registers to access */	    struct mem_t *mem)			/* memory to access */{  int modifiers = 0;  char *err_str;  struct eval_value_t val;  if (nargs != 1 && nargs != 2)    return "wrong number of arguments";  if (nargs == 2)    {      /* arguments include modifiers and expression value */      modifiers = args[0].as_modifier;      val = args[1].as_value;    }  else    {      /* arguments include only expression value */      val = args[0].as_value;    }  /* print expression value */  err_str = print_val(modifiers, val);  if (err_str)    return err_str;  fprintf(stdout, "\n");  /* no error */  return NULL;}/* print the value of all command line options */static char *					/* err str, NULL for no err */dlite_options(int nargs, union arg_val_t args[],/* command arguments */	      struct regs_t *regs,		/* registers to access */	      struct mem_t *mem)		/* memory to access */{  if (nargs != 0)    return "wrong number of arguments";  /* print all options */  opt_print_options(sim_odb, stdout, /* terse */TRUE, /* !notes */FALSE);  /* no error */  return NULL;}/* print the value of all (or single) command line options */static char *					/* err str, NULL for no err */dlite_option(int nargs, union arg_val_t args[],	/* command arguments */	     struct regs_t *regs,		/* registers to access */	     struct mem_t *mem)			/* memory to access */{  struct opt_opt_t *opt;  if (nargs != 1)    return "wrong number of arguments";  /* print a single option, specified by argument */  opt = opt_find_option(sim_odb, args[0].as_str);  if (!opt)    return "option is not defined";  /* else, print this option's value */  fprintf(stdout, "%-16s  ", opt->name);  opt_print_option(opt, stdout);  if (opt->desc)    fprintf(stdout, " # %s", opt->desc);  fprintf(stdout, "\n");  /* no error */  return NULL;}/* print the value of all statistical variables */static char *					/* err str, NULL for no err */dlite_stats(int nargs, union arg_val_t args[],	/* command arguments */	    struct regs_t *regs,		/* registers to access */	    struct mem_t *mem)			/* memory to access */{  if (nargs != 0)    return "wrong number of arguments";  /* print all options */  stat_print_stats(sim_sdb, stdout);  sim_aux_stats(stdout);  /* no error */  return NULL;}/* print the value of a statistical variable */static char *					/* err str, NULL for no err */dlite_stat(int nargs, union arg_val_t args[],	/* command arguments */	   struct regs_t *regs,			/* registers to access */	   struct mem_t *mem)			/* memory to access */{  struct stat_stat_t *stat;  if (nargs != 1)    return "wrong number of arguments";  /* print a single option, specified by argument */  stat = stat_find_stat(sim_sdb, args[0].as_str);  if (!stat)    return "statistical variable is not defined";  /* else, print this option's value */  stat_print_stat(sim_sdb, stat, stdout);  /* no error */  return NULL;}/* print the type of expression <expr> */static char *					/* err str, NULL for no err */dlite_whatis(int nargs, union arg_val_t args[],	/* command arguments */	     struct regs_t *regs,		/* registers to access */	     struct mem_t *mem)			/* memory to access */{  if (nargs != 1)    return "wrong number of arguments";  fprintf(stdout, "type == `%s'\n", eval_type_str[args[0].as_value.type]);  /* no error */  return NULL;}/* print integer register contents */static char *					/* err str, NULL for no err */dlite_iregs(int nargs, union arg_val_t args[],	/* command arguments */	    struct regs_t *regs,		/* registers to access */	    struct mem_t *mem)			/* memory to access */{  char *err_str;  if (nargs != 0)    return "too many arguments";  /* print integer registers */  myfprintf(stdout, "PC: 0x%08p   NPC: 0x%08p\n",	    regs->regs_PC, regs->regs_NPC);  if ((err_str = dlite_cregs(nargs, args, regs, mem)) != NULL)    return err_str;  md_print_iregs(regs->regs_R, stdout);  /* no error */  return NULL;}/* print floating point register contents */static char *					/* err str, NULL for no err */dlite_fpregs(int nargs, union arg_val_t args[],	/* command arguments */	     struct regs_t *regs,		/* registers to access */	     struct mem_t *mem)			/* memory to access */{  /* print floating point registers */  md_print_fpregs(regs->regs_F, stdout);  /* no error */  return NULL;}/* print floating point register contents */static char *					/* err str, NULL for no err */dlite_cregs(int nargs, union arg_val_t args[],	/* command arguments */	    struct regs_t *regs,		/* registers to access */	    struct mem_t *mem)			/* memory to access */{  /* print floating point registers */  md_print_cregs(regs->regs_C, stdout);  /* no error */  return NULL;}/* print all register contents */static char *					/* err str, NULL for no err */dlite_regs(int nargs, union arg_val_t args[],	/* command arguments */	   struct regs_t *regs,			/* registers to access */	   struct mem_t *mem)			/* memory to access */{  char *err_str;  myfprintf(stdout, "PC: 0x%08p   NPC: 0x%08p\n",	    regs->regs_PC, regs->regs_NPC);  if ((err_str = dlite_cregs(nargs, args, regs, mem)) != NULL)    return err_str;  md_print_iregs(regs->regs_R, stdout);  dlite_pause();  if ((err_str = dlite_fpregs(nargs, args, regs, mem)) != NULL)    return err_str;  /* no error */  return NULL;}/* print machine specific state (simulator dependent) */static char *					/* err str, NULL for no err */dlite_mstate(int nargs, union arg_val_t args[],	/* command arguments */	     struct regs_t *regs,		/* registers to access */	     struct mem_t *mem)			/* memory to access */{  char *errstr;  if (nargs != 0 && nargs != 1)    return "too many arguments";  if (f_dlite_mstate_obj)    {      if (nargs == 0)	{	  errstr = f_dlite_mstate_obj(stdout, NULL, regs, mem);	  if (errstr)	    return errstr;	}      else	{	  errstr = f_dlite_mstate_obj(stdout, args[0].as_str, regs, mem);	  if (errstr)	    return errstr;	}    }  /* no error */  return NULL;}/* display the value at memory location <addr> using format <modifiers> */static char *					/* err str, NULL for no err */dlite_display(int nargs, union arg_val_t args[],/* command arguments */	      struct regs_t *regs,		/* registers to access */	      struct mem_t *mem)		/* memory to access */{  int modifiers, size;  md_addr_t addr;  unsigned char buf[512];  struct eval_value_t val;  char *errstr;  if (nargs != 1 && nargs != 2)    return "wrong number of arguments";  if (nargs == 1)    {      /* no modifiers */      modifiers = 0;      /* check address */      if (!EVAL_INTEGRAL(args[0].as_value.type))	return "address argument must be an integral type";      /* reset address */      addr = eval_as_addr(args[0].as_value);    }  else if (nargs == 2)    {      modifiers = args[0].as_modifier;      /* check address */      if (!EVAL_INTEGRAL(args[1].as_value.type))	return "address argument must be an integral type";      /* reset address */      addr = eval_as_addr(args[1].as_value);    }  /* determine operand size */  if (modifiers & (MOD_BYTE|MOD_CHAR))    size = 1;  else if (modifiers & MOD_HALF)    size = 2;  else if (modifiers & (MOD_QWORD|MOD_DOUBLE))    size = 8;  else /* no modifiers, or MOD_WORD|MOD_FLOAT */    size = 4;  /* read memory */  errstr = f_dlite_mem_obj(mem, /* !is_write */FALSE, addr, (char *)buf, size);  if (errstr)    return errstr;  /* marshall a value */  if (modifiers & (MOD_BYTE|MOD_CHAR))    {      /* size == 1 */      val.type = et_int;      val.value.as_int = (int)*(unsigned char *)buf;    }  else if (modifiers & MOD_HALF)    {      /* size == 2 */      val.type = et_int;      val.value.as_int = (int)*(unsigned short *)buf;    }  else if (modifiers & (MOD_QWORD|MOD_DOUBLE))    {      /* size == 8 */      val.type = et_double;      val.value.as_double = *(double *)buf;    }  else /* no modifiers, or MOD_WORD|MOD_FLOAT */    {      /* size == 4 */      val.type = et_uint;      val.value.as_uint = *(unsigned int *)buf;    }  /* print the value */  errstr = print_val(modifiers, val);  if (errstr)    return errstr;  fprintf(stdout, "\n");  /* no error */  return NULL;}/* `dump' command print format */#define BYTES_PER_LINE			16 /* must be a power of two */#define LINES_PER_SCREEN		4/* dump the contents of memory to screen */static char *					/* err str, NULL for no err */dlite_dump(int nargs, union arg_val_t args[],	/* command arguments */	   struct regs_t *regs,			/* registers to access */	   struct mem_t *mem)			/* memory to access */{  int i, j;  int count = LINES_PER_SCREEN * BYTES_PER_LINE, i_count, fmt_count, fmt_lines;  md_addr_t fmt_addr, i_addr;  static md_addr_t addr = 0;  unsigned char byte;  char buf[512];  char *errstr;  if (nargs < 0 || nargs > 2)    return "too many arguments";  if (nargs == 1)    {      /* check address */      if (!EVAL_INTEGRAL(args[0].as_value.type))	return "address argument must be an integral type";      /* reset PC */      addr = eval_as_addr(args[0].as_value);    }  else if (nargs == 2)    {      /* check address */      if (!EVAL_INTEGRAL(args[0].as_value.type))	return "address argument must be an integral type";      /* reset addr */      addr = eval_as_addr(args[0].as_value);      /* check count */      if (!EVAL_INTEGRAL(args[1].as_value.type))	return "count argument must be an integral type";      if (eval_as_uint(args[1].as_value) > 1024)	return "bad count argument";      /* reset count */      count = eval_as_uint(args[1].as_value);    }  /* else, nargs == 0, use addr, count */  /* normalize start address and count */  fmt_addr = addr & ~(BYTES_PER_LINE - 1);  fmt_count = (count + (BYTES_PER_LINE - 1)) & ~(BYTES_PER_LINE - 1);  fmt_lines = fmt_count / BYTES_PER_LINE;  if (fmt_lines < 1)    panic("no output lines");  /* print dump */  if (fmt_lines == 1)    {      /* unformatted dump */      i_addr = fmt_addr;      myfprintf(stdout, "0x%08p: ", i_addr);      for (i=0; i < count; i++)	{	  errstr =	    f_dlite_mem_obj(mem, /* !is_write */FALSE,			    i_addr, (char *)&byte, 1);	  if (errstr)	    return errstr;	  fprintf(stdout, "%02x ", byte);	  if (isprint(byte))	    buf[i] = byte;	  else	    buf[i] = '.';	  i_addr++;	  addr++;	}      buf[i] = '\0';      /* character view */      fprintf(stdout, "[%s]\n", buf);    }  else /* lines > 1 */    {      i_count = 0;      i_addr = fmt_addr;      for (i=0; i < fmt_lines; i++)	{	  myfprintf(stdout, "0x%08p: ", i_addr);	  /* byte view */	  for (j=0; j < BYTES_PER_LINE; j++)	    {	      if (i_addr >= addr && i_count <= count)		{		  errstr =		    f_dlite_mem_obj(mem, /* !is_write */FALSE,				    i_addr, (char *)&byte, 1);		  if (errstr)		    return errstr;		  fprintf(stdout, "%02x ", byte);		  if (isprint(byte))		    buf[j] = byte;		  else		    buf[j] = '.';		  i_count++;		  addr++;		}	      else		{		  fprintf(stdout, "   ");		  buf[j] = ' ';		}	      i_addr++;	    }	  buf[j] = '\0';	  /* character view */	  fprintf(stdout, "[%s]\n", buf);	}    }  /* no error */  return NULL;}/* disassembler print format */#define INSTS_PER_SCREEN		16/* disassemble instructions at specified address */static char *					/* err str, NULL for no err */dlite_dis(int nargs, union arg_val_t args[],	/* command arguments */	  struct regs_t *regs,			/* registers to access */	  struct mem_t *mem)			/* memory to access */{  int i;  int count = INSTS_PER_SCREEN;  static md_addr_t addr = 0;  md_inst_t inst;  char *errstr;  if (nargs < 0 || nargs > 2)    return "too many arguments";  if (nargs == 1)    {      /* check address */      if (!EVAL_INTEGRAL(args[0].as_value.type))	return "address argument must be an integral type";      /* reset PC */      addr = eval_as_addr(args[0].as_value);    }  else if (nargs == 2)    {      /* check address */      if (!EVAL_INTEGRAL(args[0].as_value.type))	return "address argument must be an integral type";      /* reset addr */      addr = eval_as_addr(args[0].as_value);      /* check count */      if (!EVAL_INTEGRAL(args[0].as_value.type))	return "count argument must be an integral type";      /* reset count */      count = eval_as_uint(args[1].as_value);      if (count < 0 || count > 1024)	return "bad count argument";    }  /* else, nargs == 0, use addr, count */  if ((addr % sizeof(md_inst_t)) != 0)    return "instruction addresses are a multiple of eight";  /* disassemble COUNT insts at ADDR */  for (i=0; i<count; i++)    {      /* read and disassemble instruction */      myfprintf(stdout, "    0x%08p:   ", addr);      errstr =	f_dlite_mem_obj(mem, /* !is_write */FALSE,			addr, (char *)&inst, sizeof(inst));      inst = MD_SWAPI(inst);      if (errstr)	return errstr;      md_print_insn(inst, addr, stdout);      fprintf(stdout, "\n");      /* go to next instruction */      addr += sizeof(md_inst_t);    }  /* no error */  return NULL;}/* break instance descriptor, one allocated for each breakpoint set */struct dlite_break_t {  struct dlite_break_t *next;	/* next active breakpoint */  int id;			/* break id */  int class;			/* break class */  struct range_range_t range;	/* break range */};/* all active break points, in a list */static struct dlite_break_t *dlite_bps = NULL;/* unique id of next breakpoint */static int break_id = 1;/* return breakpoint class as a string */static char *					/* breakpoint class string */bp_class_str(int class)				/* breakpoint class mask */{  if (class == (ACCESS_READ|ACCESS_WRITE|ACCESS_EXEC))    return "read|write|exec";  else if (class == (ACCESS_READ|ACCESS_WRITE))    return "read|write";  else if (class == (ACCESS_WRITE|ACCESS_EXEC))    return "write|exec";  else if (class == (ACCESS_READ|ACCESS_EXEC))    return "read|exec";  else if (class == ACCESS_READ)    return "read";  else if (class == ACCESS_WRITE)    return "write";  else if (class == ACCESS_EXEC)    return "exec";  else    panic("bogus access class");

⌨️ 快捷键说明

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