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

📄 m68k-dis.c

📁 qemu虚拟机代码
💻 C
📖 第 1 页 / 共 5 页
字号:
      if (place == 'b')	disp = NEXTBYTE (p);      else if (place == 'B')	disp = COERCE_SIGNED_CHAR (buffer[1]);      else if (place == 'w' || place == 'W')	disp = NEXTWORD (p);      else if (place == 'l' || place == 'L' || place == 'C')	disp = NEXTLONG (p);      else if (place == 'g')	{	  disp = NEXTBYTE (buffer);	  if (disp == 0)	    disp = NEXTWORD (p);	  else if (disp == -1)	    disp = NEXTLONG (p);	}      else if (place == 'c')	{	  if (buffer[1] & 0x40)		/* If bit six is one, long offset.  */	    disp = NEXTLONG (p);	  else	    disp = NEXTWORD (p);	}      else	return -2;      (*info->print_address_func) (addr + disp, info);      break;    case 'd':      val = NEXTWORD (p);      (*info->fprintf_func)	(info->stream, "%s@(%d)",	 reg_names[fetch_arg (buffer, place, 3, info) + 8], val);      break;    case 's':      (*info->fprintf_func) (info->stream, "%s",			     fpcr_names[fetch_arg (buffer, place, 3, info)]);      break;    case 'e':      val = fetch_arg(buffer, place, 2, info);      (*info->fprintf_func) (info->stream, "%%acc%d", val);      break;    case 'g':      val = fetch_arg(buffer, place, 1, info);      (*info->fprintf_func) (info->stream, "%%accext%s", val==0 ? "01" : "23");      break;    case 'i':      val = fetch_arg(buffer, place, 2, info);      if (val == 1)	(*info->fprintf_func) (info->stream, "<<");      else if (val == 3)	(*info->fprintf_func) (info->stream, ">>");      else	return -1;      break;    case 'I':      /* Get coprocessor ID... */      val = fetch_arg (buffer, 'd', 3, info);      if (val != 1)				/* Unusual coprocessor ID?  */	(*info->fprintf_func) (info->stream, "(cpid=%d) ", val);      break;    case '4':    case '*':    case '~':    case '%':    case ';':    case '@':    case '!':    case '$':    case '?':    case '/':    case '&':    case '|':    case '<':    case '>':    case 'm':    case 'n':    case 'o':    case 'p':    case 'q':    case 'v':    case 'b':    case 'w':    case 'y':    case 'z':      if (place == 'd')	{	  val = fetch_arg (buffer, 'x', 6, info);	  val = ((val & 7) << 3) + ((val >> 3) & 7);	}      else	val = fetch_arg (buffer, 's', 6, info);      /* If the <ea> is invalid for *d, then reject this match.  */      if (!m68k_valid_ea (*d, val))	return -1;      /* Get register number assuming address register.  */      regno = (val & 7) + 8;      regname = reg_names[regno];      switch (val >> 3)	{	case 0:	  (*info->fprintf_func) (info->stream, "%s", reg_names[val]);	  break;	case 1:	  (*info->fprintf_func) (info->stream, "%s", regname);	  break;	case 2:	  (*info->fprintf_func) (info->stream, "%s@", regname);	  break;	case 3:	  (*info->fprintf_func) (info->stream, "%s@+", regname);	  break;	case 4:	  (*info->fprintf_func) (info->stream, "%s@-", regname);	  break;	case 5:	  val = NEXTWORD (p);	  (*info->fprintf_func) (info->stream, "%s@(%d)", regname, val);	  break;	case 6:	  p = print_indexed (regno, p, addr, info);	  break;	case 7:	  switch (val & 7)	    {	    case 0:	      val = NEXTWORD (p);	      (*info->print_address_func) (val, info);	      break;	    case 1:	      uval = NEXTULONG (p);	      (*info->print_address_func) (uval, info);	      break;	    case 2:	      val = NEXTWORD (p);	      (*info->fprintf_func) (info->stream, "%%pc@(");	      (*info->print_address_func) (addr + val, info);	      (*info->fprintf_func) (info->stream, ")");	      break;	    case 3:	      p = print_indexed (-1, p, addr, info);	      break;	    case 4:	      flt_p = 1;	/* Assume it's a float... */	      switch (place)	      {		case 'b':		  val = NEXTBYTE (p);		  flt_p = 0;		  break;		case 'w':		  val = NEXTWORD (p);		  flt_p = 0;		  break;		case 'l':		  val = NEXTLONG (p);		  flt_p = 0;		  break;		case 'f':		  NEXTSINGLE (flval, p);		  break;		case 'F':		  NEXTDOUBLE (flval, p);		  break;		case 'x':		  NEXTEXTEND (flval, p);		  break;		case 'p':		  flval = NEXTPACKED (p);		  break;		default:		  return -1;	      }	      if (flt_p)	/* Print a float? */		(*info->fprintf_func) (info->stream, "#%g", flval);	      else		(*info->fprintf_func) (info->stream, "#%d", val);	      break;	    default:	      return -1;	    }	}      /* If place is '/', then this is the case of the mask bit for	 mac/emac loads. Now that the arg has been printed, grab the	 mask bit and if set, add a '&' to the arg.  */      if (place == '/')	{	  val = fetch_arg (buffer, place, 1, info);	  if (val)	    info->fprintf_func (info->stream, "&");	}      break;    case 'L':    case 'l':	if (place == 'w')	  {	    char doneany;	    p1 = buffer + 2;	    val = NEXTWORD (p1);	    /* Move the pointer ahead if this point is farther ahead	       than the last.  */	    p = p1 > p ? p1 : p;	    if (val == 0)	      {		(*info->fprintf_func) (info->stream, "#0");		break;	      }	    if (*d == 'l')	      {		int newval = 0;		for (regno = 0; regno < 16; ++regno)		  if (val & (0x8000 >> regno))		    newval |= 1 << regno;		val = newval;	      }	    val &= 0xffff;	    doneany = 0;	    for (regno = 0; regno < 16; ++regno)	      if (val & (1 << regno))		{		  int first_regno;		  if (doneany)		    (*info->fprintf_func) (info->stream, "/");		  doneany = 1;		  (*info->fprintf_func) (info->stream, "%s", reg_names[regno]);		  first_regno = regno;		  while (val & (1 << (regno + 1)))		    ++regno;		  if (regno > first_regno)		    (*info->fprintf_func) (info->stream, "-%s",					   reg_names[regno]);		}	  }	else if (place == '3')	  {	    /* `fmovem' insn.  */	    char doneany;	    val = fetch_arg (buffer, place, 8, info);	    if (val == 0)	      {		(*info->fprintf_func) (info->stream, "#0");		break;	      }	    if (*d == 'l')	      {		int newval = 0;		for (regno = 0; regno < 8; ++regno)		  if (val & (0x80 >> regno))		    newval |= 1 << regno;		val = newval;	      }	    val &= 0xff;	    doneany = 0;	    for (regno = 0; regno < 8; ++regno)	      if (val & (1 << regno))		{		  int first_regno;		  if (doneany)		    (*info->fprintf_func) (info->stream, "/");		  doneany = 1;		  (*info->fprintf_func) (info->stream, "%%fp%d", regno);		  first_regno = regno;		  while (val & (1 << (regno + 1)))		    ++regno;		  if (regno > first_regno)		    (*info->fprintf_func) (info->stream, "-%%fp%d", regno);		}	  }	else if (place == '8')	  {	    /* fmoveml for FP status registers.  */	    (*info->fprintf_func) (info->stream, "%s",				   fpcr_names[fetch_arg (buffer, place, 3,							 info)]);	  }	else	  return -2;      break;    case 'X':      place = '8';    case 'Y':    case 'Z':    case 'W':    case '0':    case '1':    case '2':    case '3':      {	int val = fetch_arg (buffer, place, 5, info);	char *name = 0;	switch (val)	  {	  case 2: name = "%tt0"; break;	  case 3: name = "%tt1"; break;	  case 0x10: name = "%tc"; break;	  case 0x11: name = "%drp"; break;	  case 0x12: name = "%srp"; break;	  case 0x13: name = "%crp"; break;	  case 0x14: name = "%cal"; break;	  case 0x15: name = "%val"; break;	  case 0x16: name = "%scc"; break;	  case 0x17: name = "%ac"; break; 	  case 0x18: name = "%psr"; break;	  case 0x19: name = "%pcsr"; break;	  case 0x1c:	  case 0x1d:	    {	      int break_reg = ((buffer[3] >> 2) & 7);	      (*info->fprintf_func)		(info->stream, val == 0x1c ? "%%bad%d" : "%%bac%d",		 break_reg);	    }	    break;	  default:	    (*info->fprintf_func) (info->stream, "<mmu register %d>", val);	  }	if (name)	  (*info->fprintf_func) (info->stream, "%s", name);      }      break;    case 'f':      {	int fc = fetch_arg (buffer, place, 5, info);	if (fc == 1)	  (*info->fprintf_func) (info->stream, "%%dfc");	else if (fc == 0)	  (*info->fprintf_func) (info->stream, "%%sfc");	else	  /* xgettext:c-format */	  (*info->fprintf_func) (info->stream, _("<function code %d>"), fc);      }      break;    case 'V':      (*info->fprintf_func) (info->stream, "%%val");      break;    case 't':      {	int level = fetch_arg (buffer, place, 3, info);	(*info->fprintf_func) (info->stream, "%d", level);      }      break;    case 'u':      {	short is_upper = 0;	int reg = fetch_arg (buffer, place, 5, info);	if (reg & 0x10)	  {	    is_upper = 1;	    reg &= 0xf;	  }	(*info->fprintf_func) (info->stream, "%s%s",			       reg_half_names[reg],			       is_upper ? "u" : "l");      }      break;    default:      return -2;    }  return p - p0;}/* Try to match the current instruction to best and if so, return the   number of bytes consumed from the instruction stream, else zero.  */static intmatch_insn_m68k (bfd_vma memaddr,		 disassemble_info * info,		 const struct m68k_opcode * best,		 struct private * priv){  unsigned char *save_p;  unsigned char *p;  const char *d;  bfd_byte *buffer = priv->the_buffer;  fprintf_ftype save_printer = info->fprintf_func;  void (* save_print_address) (bfd_vma, struct disassemble_info *)    = info->print_address_func;  /* Point at first word of argument data,     and at descriptor for first argument.  */  p = buffer + 2;  /* Figure out how long the fixed-size portion of the instruction is.     The only place this is stored in the opcode table is     in the arguments--look for arguments which specify fields in the 2nd     or 3rd words of the instruction.  */  for (d = best->args; *d; d += 2)    {      /* I don't think it is necessary to be checking d[0] here;	 I suspect all this could be moved to the case statement below.  */

⌨️ 快捷键说明

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