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

📄 m68k-pinsn.c

📁 早期freebsd实现
💻 C
📖 第 1 页 / 共 2 页
字号:
/* Print Motorola 68k instructions for GDB, the GNU debugger.   Copyright 1986, 1987, 1989, 1991, 1992 Free Software Foundation, Inc.This file is part of GDB.This program is free software; you can redistribute it and/or modifyit under the terms of the GNU General Public License as published bythe Free Software Foundation; either version 2 of the License, or(at your option) any later version.This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; without even the implied warranty ofMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See theGNU General Public License for more details.You should have received a copy of the GNU General Public Licensealong with this program; if not, write to the Free SoftwareFoundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */#include "defs.h"#include "symtab.h"#include "opcode/m68k.h"#include "gdbcore.h"#include "ieee-float.h"/* Local function prototypes */static intfetch_arg PARAMS ((unsigned char *, int, int));static voidprint_base PARAMS ((int, int, FILE *));static unsigned char *print_indexed PARAMS ((int, unsigned char *, CORE_ADDR, FILE *));static unsigned char *print_insn_arg PARAMS ((char *, unsigned char *, unsigned char *, CORE_ADDR,			FILE *));/* 68k instructions are never longer than this many bytes.  */#define MAXLEN 22/* Number of elements in the opcode table.  */#define NOPCODES (sizeof m68k_opcodes / sizeof m68k_opcodes[0])const char * const fpcr_names[] = {  "", "fpiar", "fpsr", "fpiar/fpsr", "fpcr",  "fpiar/fpcr", "fpsr/fpcr", "fpiar/fpsr/fpcr"};/* Define accessors for 68K's 1, 2, and 4-byte signed quantities.   The _SHIFT values move the quantity to the high order end of an   `int' value, so it will sign-extend.  Probably a few more casts   are needed to make it compile without warnings on finicky systems.  */#define	BITS_PER_BYTE	8#define	BYTE_SHIFT (BITS_PER_BYTE * ((sizeof (int)) - 1))#define	WORD_SHIFT (BITS_PER_BYTE * ((sizeof (int)) - 2))#define	LONG_SHIFT (BITS_PER_BYTE * ((sizeof (int)) - 4))#define NEXTBYTE(p)  (p += 2, ((int)(p[-1]) << BYTE_SHIFT) >> BYTE_SHIFT)#define NEXTWORD(p)  \  (p += 2, (((int)((p[-2] << 8) + p[-1])) << WORD_SHIFT) >> WORD_SHIFT)#define NEXTLONG(p)  \  (p += 4, (((int)((((((p[-4] << 8) + p[-3]) << 8) + p[-2]) << 8) + p[-1])) \				   << LONG_SHIFT) >> LONG_SHIFT)/* Ecch -- assumes host == target float formats.  FIXME.  */#define NEXTSINGLE(p) \  (p += 4, *((float *)(p - 4)))#define NEXTDOUBLE(p) \  (p += 8, *((double *)(p - 8)))/* Print the m68k instruction at address MEMADDR in debugged memory,   on STREAM.  Returns length of the instruction, in bytes.  */intprint_insn (memaddr, stream)     CORE_ADDR memaddr;     FILE *stream;{  unsigned char buffer[MAXLEN];  register int i;  register unsigned char *p;  register char *d;  register int bestmask;  int best;  read_memory (memaddr, (char *) buffer, MAXLEN);  bestmask = 0;  best = -1;  for (i = 0; i < NOPCODES; i++)    {      register unsigned int opcode = m68k_opcodes[i].opcode;      register unsigned int match = m68k_opcodes[i].match;      if (((0xff & buffer[0] & (match >> 24)) == (0xff & (opcode >> 24)))	  && ((0xff & buffer[1] & (match >> 16)) == (0xff & (opcode >> 16)))	  && ((0xff & buffer[2] & (match >> 8)) == (0xff & (opcode >> 8)))	  && ((0xff & buffer[3] & match) == (0xff & opcode)))	{	  /* Don't use for printout the variants of divul and divsl	     that have the same register number in two places.	     The more general variants will match instead.  */	  for (d = m68k_opcodes[i].args; *d; d += 2)	    if (d[1] == 'D')	      break;	  /* Don't use for printout the variants of most floating	     point coprocessor instructions which use the same	     register number in two places, as above. */	  if (*d == 0)	    for (d = m68k_opcodes[i].args; *d; d += 2)	      if (d[1] == 't')		break;	  if (*d == 0 && match > bestmask)	    {	      best = i;	      bestmask = match;	    }	}    }  /* Handle undefined instructions.  */  if (best < 0)    {      fprintf_filtered (stream, "0%o", (buffer[0] << 8) + buffer[1]);      return 2;    }  fprintf_filtered (stream, "%s", m68k_opcodes[best].name);  /* Point at first word of argument data,     and at descriptor for first argument.  */  p = buffer + 2;    /* Why do this this way? -MelloN */  for (d = m68k_opcodes[best].args; *d; d += 2)    {      if (d[0] == '#')	{	  if (d[1] == 'l' && p - buffer < 6)	    p = buffer + 6;	  else if (p - buffer < 4 && d[1] != 'C' && d[1] != '8' )	    p = buffer + 4;	}      if (d[1] >= '1' && d[1] <= '3' && p - buffer < 4)	p = buffer + 4;      if (d[1] >= '4' && d[1] <= '6' && p - buffer < 6)	p = buffer + 6;      if ((d[0] == 'L' || d[0] == 'l') && d[1] == 'w' && p - buffer < 4)	p = buffer + 4;    }  d = m68k_opcodes[best].args;  if (*d)    fputs_filtered (" ", stream);  while (*d)    {      p = print_insn_arg (d, buffer, p, memaddr + p - buffer, stream);      d += 2;      if (*d && *(d - 2) != 'I' && *d != 'k')	fputs_filtered (",", stream);    }  return p - buffer;}static unsigned char *print_insn_arg (d, buffer, p, addr, stream)     char *d;     unsigned char *buffer;     register unsigned char *p;     CORE_ADDR addr;		/* PC for this arg to be relative to */     FILE *stream;{  register int val;  register int place = d[1];  int regno;  register const char *regname;  register unsigned char *p1;  double flval;  int flt_p;  switch (*d)    {    case 'c':		/* cache identifier */      {        static char *cacheFieldName[] = { "NOP", "dc", "ic", "bc" };        val = fetch_arg (buffer, place, 2);        fprintf_filtered (stream, cacheFieldName[val]);        break;      }    case 'a':		/* address register indirect only. Cf. case '+'. */      {        fprintf_filtered (stream,			  "%s@",			  reg_names [fetch_arg (buffer, place, 3) + 8]);        break;      }    case '_':		/* 32-bit absolute address for move16. */      {        val = NEXTLONG (p);        fprintf_filtered (stream, "@#");	print_address (val, stream);        break;      }    case 'C':      fprintf_filtered (stream, "ccr");      break;    case 'S':      fprintf_filtered (stream, "sr");      break;    case 'U':      fprintf_filtered (stream, "usp");      break;    case 'J':      {	static struct { char *name; int value; } names[]	  = {{"sfc", 0x000}, {"dfc", 0x001}, {"cacr", 0x002},	     {"tc",  0x003}, {"itt0",0x004}, {"itt1", 0x005},             {"dtt0",0x006}, {"dtt1",0x007},	     {"usp", 0x800}, {"vbr", 0x801}, {"caar", 0x802},	     {"msp", 0x803}, {"isp", 0x804}, {"mmusr",0x805},             {"urp", 0x806}, {"srp", 0x807}};	val = fetch_arg (buffer, place, 12);	for (regno = sizeof names / sizeof names[0] - 1; regno >= 0; regno--)	  if (names[regno].value == val)	    {	      fprintf_filtered (stream, names[regno].name);	      break;	    }	if (regno < 0)	  fprintf_filtered (stream, "%d", val);      }      break;    case 'Q':      val = fetch_arg (buffer, place, 3);      /* 0 means 8, except for the bkpt instruction... */      if (val == 0 && d[1] != 's')	val = 8;      fprintf_filtered (stream, "#%d", val);      break;    case 'M':      val = fetch_arg (buffer, place, 8);      if (val & 0x80)	val = val - 0x100;      fprintf_filtered (stream, "#%d", val);      break;    case 'T':      val = fetch_arg (buffer, place, 4);      fprintf_filtered (stream, "#%d", val);      break;    case 'D':      fprintf_filtered (stream, "%s", reg_names[fetch_arg (buffer, place, 3)]);      break;    case 'A':      fprintf_filtered (stream, "%s",			reg_names[fetch_arg (buffer, place, 3) + 010]);      break;    case 'R':      fprintf_filtered (stream, "%s", reg_names[fetch_arg (buffer, place, 4)]);      break;    case 'r':      fprintf_filtered (stream, "%s@", reg_names[fetch_arg (buffer, place, 4)]);      break;    case 'F':      fprintf_filtered (stream, "fp%d", fetch_arg (buffer, place, 3));      break;    case 'O':      val = fetch_arg (buffer, place, 6);      if (val & 0x20)	fprintf_filtered (stream, "%s", reg_names [val & 7]);      else	fprintf_filtered (stream, "%d", val);      break;    case '+':      fprintf_filtered (stream, "%s@+",			reg_names[fetch_arg (buffer, place, 3) + 8]);      break;    case '-':      fprintf_filtered (stream, "%s@-",	       reg_names[fetch_arg (buffer, place, 3) + 8]);      break;    case 'k':      if (place == 'k')	fprintf_filtered (stream, "{%s}", reg_names[fetch_arg (buffer, place, 3)]);      else if (place == 'C')	{	  val = fetch_arg (buffer, place, 7);	  if ( val > 63 )		/* This is a signed constant. */	    val -= 128;	  fprintf_filtered (stream, "{#%d}", val);	}      else	error ("Invalid arg format in opcode table: \"%c%c\".",	       *d, place);      break;    case '#':    case '^':      p1 = buffer + (*d == '#' ? 2 : 4);      if (place == 's')	val = fetch_arg (buffer, place, 4);      else if (place == 'C')	val = fetch_arg (buffer, place, 7);      else if (place == '8')	val = fetch_arg (buffer, place, 3);      else if (place == '3')	val = fetch_arg (buffer, place, 8);      else if (place == 'b')	val = NEXTBYTE (p1);      else if (place == 'w')	val = NEXTWORD (p1);      else if (place == 'l')	val = NEXTLONG (p1);      else	error ("Invalid arg format in opcode table: \"%c%c\".",	       *d, place);      fprintf_filtered (stream, "#%d", val);      break;    case 'B':      if (place == 'b')	val = NEXTBYTE (p);      else if (place == 'B')	val = NEXTBYTE (buffer);	/* from the opcode word */      else if (place == 'w' || place == 'W')	val = NEXTWORD (p);      else if (place == 'l' || place == 'L')	val = NEXTLONG (p);      else if (place == 'g')	{	  val = NEXTBYTE (buffer);	  if (val == 0)	    val = NEXTWORD (p);	  else if (val == -1)	    val = NEXTLONG (p);	}      else if (place == 'c')	{	  if (buffer[1] & 0x40)		/* If bit six is one, long offset */	    val = NEXTLONG (p);	  else	    val = NEXTWORD (p);	}      else	error ("Invalid arg format in opcode table: \"%c%c\".",	       *d, place);      print_address (addr + val, stream);      break;    case 'd':      val = NEXTWORD (p);      fprintf_filtered (stream, "%s@(%d)",			reg_names[fetch_arg (buffer, place, 3)], val);      break;    case 's':      fprintf_filtered (stream, "%s",			fpcr_names[fetch_arg (buffer, place, 3)]);      break;    case 'I':      val = fetch_arg (buffer, 'd', 3);		  /* Get coprocessor ID... */      if (val != 1)				/* Unusual coprocessor ID? */	fprintf_filtered (stream, "(cpid=%d) ", val);      if (place == 'i')	p += 2;			     /* Skip coprocessor extended operands */      break;    case '*':    case '~':    case '%':    case ';':    case '@':    case '!':    case '$':    case '?':    case '/':    case '&':    case '`':      if (place == 'd')	{	  val = fetch_arg (buffer, 'x', 6);	  val = ((val & 7) << 3) + ((val >> 3) & 7);	}      else	val = fetch_arg (buffer, 's', 6);

⌨️ 快捷键说明

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