m68k-dis.c

来自「基于4个mips核的noc设计」· C语言 代码 · 共 1,329 行 · 第 1/3 页

C
1,329
字号
  if (*d)    (*info->fprintf_func) (info->stream, " ");  while (*d)    {      p += print_insn_arg (d, buffer, p, memaddr + (p - buffer), info);      d += 2;      if (*d && *(d - 2) != 'I' && *d != 'k')	(*info->fprintf_func) (info->stream, ",");    }  return p - buffer; invalid:  /* Handle undefined instructions.  */  info->fprintf_func = save_printer;  info->print_address_func = save_print_address;  (*info->fprintf_func) (info->stream, "0%o",			 (buffer[0] << 8) + buffer[1]);  return 2;}/* 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. */static intprint_insn_arg (d, buffer, p0, addr, info)     const char *d;     unsigned char *buffer;     unsigned char *p0;     bfd_vma addr;		/* PC for this arg to be relative to */     disassemble_info *info;{  register int val = 0;  register int place = d[1];  register unsigned char *p = p0;  int regno;  register CONST char *regname;  register 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':      {	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},	     /* 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 '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':      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 '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 '*':    case '~':    case '%':    case ';':    case '@':    case '!':    case '$':    case '?':    case '/':    case '&':    case '|':    case '<':    case '>':    case 'm':    case 'n':    case 'o':    case 'p':    case 'q':    case 'v':      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);      /* 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;	    }	}      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')	      {		register int newval = 0;

⌨️ 快捷键说明

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