m68k-dis.c

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

C
1,329
字号
		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')	      {		register 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_names[reg],			       is_upper ? "u" : "l");      }      break;	    default:      return -2;    }  return p - p0;}/* Fetch BITS bits from a position in the instruction specified by CODE.   CODE is a "place to put an argument", or 'x' for a destination   that is a general address (mode and register).   BUFFER contains the instruction.  */static intfetch_arg (buffer, code, bits, info)     unsigned char *buffer;     int code;     int bits;     disassemble_info *info;{  register int val = 0;  switch (code)    {    case 's':      val = buffer[1];      break;    case 'd':			/* Destination, for register or quick.  */      val = (buffer[0] << 8) + buffer[1];      val >>= 9;      break;    case 'x':			/* Destination, for general arg */      val = (buffer[0] << 8) + buffer[1];      val >>= 6;      break;    case 'k':      FETCH_DATA (info, buffer + 3);      val = (buffer[3] >> 4);      break;    case 'C':      FETCH_DATA (info, buffer + 3);      val = buffer[3];      break;    case '1':      FETCH_DATA (info, buffer + 3);      val = (buffer[2] << 8) + buffer[3];      val >>= 12;      break;    case '2':      FETCH_DATA (info, buffer + 3);      val = (buffer[2] << 8) + buffer[3];      val >>= 6;      break;    case '3':    case 'j':      FETCH_DATA (info, buffer + 3);      val = (buffer[2] << 8) + buffer[3];      break;    case '4':      FETCH_DATA (info, buffer + 5);      val = (buffer[4] << 8) + buffer[5];      val >>= 12;      break;    case '5':      FETCH_DATA (info, buffer + 5);      val = (buffer[4] << 8) + buffer[5];      val >>= 6;      break;    case '6':      FETCH_DATA (info, buffer + 5);      val = (buffer[4] << 8) + buffer[5];      break;    case '7':      FETCH_DATA (info, buffer + 3);      val = (buffer[2] << 8) + buffer[3];      val >>= 7;      break;          case '8':      FETCH_DATA (info, buffer + 3);      val = (buffer[2] << 8) + buffer[3];      val >>= 10;      break;    case '9':      FETCH_DATA (info, buffer + 3);      val = (buffer[2] << 8) + buffer[3];      val >>= 5;      break;    case 'e':      val = (buffer[1] >> 6);      break;    case 'm':       val = (buffer[1] & 0x40 ? 0x8 : 0)	| ((buffer[0] >> 1) & 0x7)	| (buffer[3] & 0x80 ? 0x10 : 0);      break;    case 'n':       val = (buffer[1] & 0x40 ? 0x8 : 0) | ((buffer[0] >> 1) & 0x7);      break;    case 'o':      val = (buffer[2] >> 4) | (buffer[3] & 0x80 ? 0x10 : 0);      break;    case 'M':      val = buffer[1] | (buffer[3] & 0x40 ? 0x10 : 0);      break;    case 'N':      val = buffer[3] | (buffer[3] & 0x40 ? 0x10 : 0);      break;    case 'h':      val = buffer[2] >> 2;      break;    default:      abort ();    }  switch (bits)    {    case 1:      return val & 1;    case 2:      return val & 3;    case 3:      return val & 7;    case 4:      return val & 017;    case 5:      return val & 037;    case 6:      return val & 077;    case 7:      return val & 0177;    case 8:      return val & 0377;    case 12:      return val & 07777;    default:      abort ();    }}/* 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 (basereg, p, addr, info)     int basereg;     unsigned char *p;     bfd_vma addr;     disassemble_info *info;{  register 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;}/* Print a base register REGNO and displacement DISP, on INFO->STREAM.   REGNO = -1 for pc, -2 for none (suppressed).  */static voidprint_base (regno, disp, info)     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);    }}

⌨️ 快捷键说明

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