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

📄 m68k-dis.c

📁 qemu虚拟机代码
💻 C
📖 第 1 页 / 共 5 页
字号:
      break;    case '~':      mask = M (0,0,1,1,1,1,1,1,1,0,0,0);      break;    case '%':      mask = M (1,1,1,1,1,1,1,1,1,0,0,0);      break;    case ';':      mask = M (1,0,1,1,1,1,1,1,1,1,1,1);      break;    case '@':      mask = M (1,0,1,1,1,1,1,1,1,1,1,0);      break;    case '!':      mask = M (0,0,1,0,0,1,1,1,1,1,1,0);      break;    case '&':      mask = M (0,0,1,0,0,1,1,1,1,0,0,0);      break;    case '$':      mask = M (1,0,1,1,1,1,1,1,1,0,0,0);      break;    case '?':      mask = M (1,0,1,0,0,1,1,1,1,0,0,0);      break;    case '/':      mask = M (1,0,1,0,0,1,1,1,1,1,1,0);      break;    case '|':      mask = M (0,0,1,0,0,1,1,1,1,1,1,0);      break;    case '>':      mask = M (0,0,1,0,1,1,1,1,1,0,0,0);      break;    case '<':      mask = M (0,0,1,1,0,1,1,1,1,1,1,0);      break;    case 'm':      mask = M (1,1,1,1,1,0,0,0,0,0,0,0);      break;    case 'n':      mask = M (0,0,0,0,0,1,0,0,0,1,0,0);      break;    case 'o':      mask = M (0,0,0,0,0,0,1,1,1,0,1,1);      break;    case 'p':      mask = M (1,1,1,1,1,1,0,0,0,0,0,0);      break;    case 'q':      mask = M (1,0,1,1,1,1,0,0,0,0,0,0);      break;    case 'v':      mask = M (1,0,1,1,1,1,0,1,1,0,0,0);      break;    case 'b':      mask = M (1,0,1,1,1,1,0,0,0,1,0,0);      break;    case 'w':      mask = M (0,0,1,1,1,1,0,0,0,1,0,0);      break;    case 'y':      mask = M (0,0,1,0,0,1,0,0,0,0,0,0);      break;    case 'z':      mask = M (0,0,1,0,0,1,0,0,0,1,0,0);      break;    case '4':      mask = M (0,0,1,1,1,1,0,0,0,0,0,0);      break;    default:      abort ();    }#undef M  mode = (val >> 3) & 7;  if (mode == 7)    mode += val & 7;  return (mask & (1 << mode)) != 0;}/* Print a base register REGNO and displacement DISP, on INFO->STREAM.   REGNO = -1 for pc, -2 for none (suppressed).  */static voidprint_base (int regno, bfd_vma disp, disassemble_info *info){  if (regno == -1)    {      (*info->fprintf_func) (info->stream, "%%pc@(");      (*info->print_address_func) (disp, info);    }  else    {      char buf[50];      if (regno == -2)	(*info->fprintf_func) (info->stream, "@(");      else if (regno == -3)	(*info->fprintf_func) (info->stream, "%%zpc@(");      else	(*info->fprintf_func) (info->stream, "%s@(", reg_names[regno]);      sprintf_vma (buf, disp);      (*info->fprintf_func) (info->stream, "%s", buf);    }}/* Print an indexed argument.  The base register is BASEREG (-1 for pc).   P points to extension word, in buffer.   ADDR is the nominal core address of that extension word.  */static unsigned char *print_indexed (int basereg,	       unsigned char *p,	       bfd_vma addr,	       disassemble_info *info){  int word;  static char *const scales[] = { "", ":2", ":4", ":8" };  bfd_vma base_disp;  bfd_vma outer_disp;  char buf[40];  char vmabuf[50];  word = NEXTWORD (p);  /* Generate the text for the index register.     Where this will be output is not yet determined.  */  sprintf (buf, "%s:%c%s",	   reg_names[(word >> 12) & 0xf],	   (word & 0x800) ? 'l' : 'w',	   scales[(word >> 9) & 3]);  /* Handle the 68000 style of indexing.  */  if ((word & 0x100) == 0)    {      base_disp = word & 0xff;      if ((base_disp & 0x80) != 0)	base_disp -= 0x100;      if (basereg == -1)	base_disp += addr;      print_base (basereg, base_disp, info);      (*info->fprintf_func) (info->stream, ",%s)", buf);      return p;    }  /* Handle the generalized kind.  */  /* First, compute the displacement to add to the base register.  */  if (word & 0200)    {      if (basereg == -1)	basereg = -3;      else	basereg = -2;    }  if (word & 0100)    buf[0] = '\0';  base_disp = 0;  switch ((word >> 4) & 3)    {    case 2:      base_disp = NEXTWORD (p);      break;    case 3:      base_disp = NEXTLONG (p);    }  if (basereg == -1)    base_disp += addr;  /* Handle single-level case (not indirect).  */  if ((word & 7) == 0)    {      print_base (basereg, base_disp, info);      if (buf[0] != '\0')	(*info->fprintf_func) (info->stream, ",%s", buf);      (*info->fprintf_func) (info->stream, ")");      return p;    }  /* Two level.  Compute displacement to add after indirection.  */  outer_disp = 0;  switch (word & 3)    {    case 2:      outer_disp = NEXTWORD (p);      break;    case 3:      outer_disp = NEXTLONG (p);    }  print_base (basereg, base_disp, info);  if ((word & 4) == 0 && buf[0] != '\0')    {      (*info->fprintf_func) (info->stream, ",%s", buf);      buf[0] = '\0';    }  sprintf_vma (vmabuf, outer_disp);  (*info->fprintf_func) (info->stream, ")@(%s", vmabuf);  if (buf[0] != '\0')    (*info->fprintf_func) (info->stream, ",%s", buf);  (*info->fprintf_func) (info->stream, ")");  return p;}/* Returns number of bytes "eaten" by the operand, or   return -1 if an invalid operand was found, or -2 if   an opcode tabe error was found.   ADDR is the pc for this arg to be relative to.  */static intprint_insn_arg (const char *d,		unsigned char *buffer,		unsigned char *p0,		bfd_vma addr,		disassemble_info *info){  int val = 0;  int place = d[1];  unsigned char *p = p0;  int regno;  const char *regname;  unsigned char *p1;  double flval;  int flt_p;  bfd_signed_vma disp;  unsigned int uval;  switch (*d)    {    case 'c':		/* Cache identifier.  */      {        static char *const cacheFieldName[] = { "nc", "dc", "ic", "bc" };        val = fetch_arg (buffer, place, 2, info);        (*info->fprintf_func) (info->stream, cacheFieldName[val]);        break;      }    case 'a':		/* Address register indirect only. Cf. case '+'.  */      {        (*info->fprintf_func)	  (info->stream,	   "%s@",	   reg_names[fetch_arg (buffer, place, 3, info) + 8]);        break;      }    case '_':		/* 32-bit absolute address for move16.  */      {        uval = NEXTULONG (p);	(*info->print_address_func) (uval, info);        break;      }    case 'C':      (*info->fprintf_func) (info->stream, "%%ccr");      break;    case 'S':      (*info->fprintf_func) (info->stream, "%%sr");      break;    case 'U':      (*info->fprintf_func) (info->stream, "%%usp");      break;    case 'E':      (*info->fprintf_func) (info->stream, "%%acc");      break;    case 'G':      (*info->fprintf_func) (info->stream, "%%macsr");      break;    case 'H':      (*info->fprintf_func) (info->stream, "%%mask");      break;    case 'J':      {	/* FIXME: There's a problem here, different m68k processors call the	   same address different names. This table can't get it right	   because it doesn't know which processor it's disassembling for.  */	static const struct { char *name; int value; } names[]	  = {{"%sfc", 0x000}, {"%dfc", 0x001}, {"%cacr", 0x002},	     {"%tc",  0x003}, {"%itt0",0x004}, {"%itt1", 0x005},             {"%dtt0",0x006}, {"%dtt1",0x007}, {"%buscr",0x008},	     {"%usp", 0x800}, {"%vbr", 0x801}, {"%caar", 0x802},	     {"%msp", 0x803}, {"%isp", 0x804},	     {"%flashbar", 0xc04}, {"%rambar", 0xc05}, /* mcf528x added these.  */	     /* Should we be calling this psr like we do in case 'Y'?  */	     {"%mmusr",0x805},             {"%urp", 0x806}, {"%srp", 0x807}, {"%pcr", 0x808}};	val = fetch_arg (buffer, place, 12, info);	for (regno = sizeof names / sizeof names[0] - 1; regno >= 0; regno--)	  if (names[regno].value == val)	    {	      (*info->fprintf_func) (info->stream, "%s", names[regno].name);	      break;	    }	if (regno < 0)	  (*info->fprintf_func) (info->stream, "%d", val);      }      break;    case 'Q':      val = fetch_arg (buffer, place, 3, info);      /* 0 means 8, except for the bkpt instruction... */      if (val == 0 && d[1] != 's')	val = 8;      (*info->fprintf_func) (info->stream, "#%d", val);      break;    case 'x':      val = fetch_arg (buffer, place, 3, info);      /* 0 means -1.  */      if (val == 0)	val = -1;      (*info->fprintf_func) (info->stream, "#%d", val);      break;    case 'M':      if (place == 'h')	{	  static char *const scalefactor_name[] = { "<<", ">>" };	  val = fetch_arg (buffer, place, 1, info);	  (*info->fprintf_func) (info->stream, scalefactor_name[val]);	}      else	{	  val = fetch_arg (buffer, place, 8, info);	  if (val & 0x80)	    val = val - 0x100;	  (*info->fprintf_func) (info->stream, "#%d", val);	}      break;    case 'T':      val = fetch_arg (buffer, place, 4, info);      (*info->fprintf_func) (info->stream, "#%d", val);      break;    case 'D':      (*info->fprintf_func) (info->stream, "%s",			     reg_names[fetch_arg (buffer, place, 3, info)]);      break;    case 'A':      (*info->fprintf_func)	(info->stream, "%s",	 reg_names[fetch_arg (buffer, place, 3, info) + 010]);      break;    case 'R':      (*info->fprintf_func)	(info->stream, "%s",	 reg_names[fetch_arg (buffer, place, 4, info)]);      break;    case 'r':      regno = fetch_arg (buffer, place, 4, info);      if (regno > 7)	(*info->fprintf_func) (info->stream, "%s@", reg_names[regno]);      else	(*info->fprintf_func) (info->stream, "@(%s)", reg_names[regno]);      break;    case 'F':      (*info->fprintf_func)	(info->stream, "%%fp%d",	 fetch_arg (buffer, place, 3, info));      break;    case 'O':      val = fetch_arg (buffer, place, 6, info);      if (val & 0x20)	(*info->fprintf_func) (info->stream, "%s", reg_names[val & 7]);      else	(*info->fprintf_func) (info->stream, "%d", val);      break;    case '+':      (*info->fprintf_func)	(info->stream, "%s@+",	 reg_names[fetch_arg (buffer, place, 3, info) + 8]);      break;    case '-':      (*info->fprintf_func)	(info->stream, "%s@-",	 reg_names[fetch_arg (buffer, place, 3, info) + 8]);      break;    case 'k':      if (place == 'k')	(*info->fprintf_func)	  (info->stream, "{%s}",	   reg_names[fetch_arg (buffer, place, 3, info)]);      else if (place == 'C')	{	  val = fetch_arg (buffer, place, 7, info);	  if (val > 63)		/* This is a signed constant.  */	    val -= 128;	  (*info->fprintf_func) (info->stream, "{#%d}", val);	}      else	return -2;      break;    case '#':    case '^':      p1 = buffer + (*d == '#' ? 2 : 4);      if (place == 's')	val = fetch_arg (buffer, place, 4, info);      else if (place == 'C')	val = fetch_arg (buffer, place, 7, info);      else if (place == '8')	val = fetch_arg (buffer, place, 3, info);      else if (place == '3')	val = fetch_arg (buffer, place, 8, info);      else if (place == 'b')	val = NEXTBYTE (p1);      else if (place == 'w' || place == 'W')	val = NEXTWORD (p1);      else if (place == 'l')	val = NEXTLONG (p1);      else	return -2;      (*info->fprintf_func) (info->stream, "#%d", val);      break;    case 'B':

⌨️ 快捷键说明

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