h8500-dis.c

来自「基于4个mips核的noc设计」· C语言 代码 · 共 351 行

C
351
字号
/* Disassemble h8500 instructions.   Copyright 1993, 1998, 2000 Free Software Foundation, Inc.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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */#include <stdio.h>#define DISASSEMBLER_TABLE#define DEFINE_TABLE#include "sysdep.h"#include "h8500-opc.h"#include "dis-asm.h"#include "opintl.h"/* Maximum length of an instruction.  */#define MAXLEN 8#include <setjmp.h>struct private{  /* Points to first byte not fetched.  */  bfd_byte *max_fetched;  bfd_byte the_buffer[MAXLEN];  bfd_vma insn_start;  jmp_buf bailout;};/* Make sure that bytes from INFO->PRIVATE_DATA->BUFFER (inclusive)   to ADDR (exclusive) are valid.  Returns 1 for success, longjmps   on error.  */#define FETCH_DATA(info, addr) \  ((addr) <= ((struct private *)(info->private_data))->max_fetched \   ? 1 : fetch_data ((info), (addr)))static intfetch_data (info, addr)     struct disassemble_info *info;     bfd_byte *addr;{  int status;  struct private *priv = (struct private *) info->private_data;  bfd_vma start = priv->insn_start + (priv->max_fetched - priv->the_buffer);  status = (*info->read_memory_func) (start,				      priv->max_fetched,				      addr - priv->max_fetched,				      info);  if (status != 0)    {      (*info->memory_error_func) (status, start, info);      longjmp (priv->bailout, 1);    }  else    priv->max_fetched = addr;  return 1;}static char *crname[] = { "sr", "ccr", "*", "br", "ep", "dp", "*", "tp" };intprint_insn_h8500 (addr, info)     bfd_vma addr;     disassemble_info *info;{  h8500_opcode_info *opcode;  void *stream = info->stream;  fprintf_ftype func = info->fprintf_func;  struct private priv;  bfd_byte *buffer = priv.the_buffer;  info->private_data = (PTR) & priv;  priv.max_fetched = priv.the_buffer;  priv.insn_start = addr;  if (setjmp (priv.bailout) != 0)    /* Error return.  */    return -1;  if (0)    {      static int one;      if (!one)	{	  one = 1;	  for (opcode = h8500_table; opcode->name; opcode++)	    {	      if ((opcode->bytes[0].contents & 0x8) == 0)		printf ("%s\n", opcode->name);	    }	}    }  /* Run down the table to find the one which matches.  */  for (opcode = h8500_table; opcode->name; opcode++)    {      int byte;      int rn = 0;      int rd = 0;      int rs = 0;      int disp = 0;      int abs = 0;      int imm = 0;      int pcrel = 0;      int qim = 0;      int i;      int cr = 0;      for (byte = 0; byte < opcode->length; byte++)	{	  FETCH_DATA (info, buffer + byte + 1);	  if ((buffer[byte] & opcode->bytes[byte].mask)	      != (opcode->bytes[byte].contents))	    {	      goto next;	    }	  else	    {	      /* Extract any info parts.  */	      switch (opcode->bytes[byte].insert)		{		case 0:		case FP:		  break;		default:		  /* xgettext:c-format */		  func (stream, _("can't cope with insert %d\n"),			opcode->bytes[byte].insert);		  break;		case RN:		  rn = buffer[byte] & 0x7;		  break;		case RS:		  rs = buffer[byte] & 0x7;		  break;		case CRB:		  cr = buffer[byte] & 0x7;		  if (cr == 0)		    goto next;		  break;		case CRW:		  cr = buffer[byte] & 0x7;		  if (cr != 0)		    goto next;		  break;		case DISP16:		  FETCH_DATA (info, buffer + byte + 2);		  disp = (buffer[byte] << 8) | (buffer[byte + 1]);		  break;		case FPIND_D8:		case DISP8:		  disp = ((char) (buffer[byte]));		  break;		case RD:		case RDIND:		  rd = buffer[byte] & 0x7;		  break;		case ABS24:		  FETCH_DATA (info, buffer + byte + 3);		  abs =		    (buffer[byte] << 16)		    | (buffer[byte + 1] << 8)		    | (buffer[byte + 2]);		  break;		case ABS16:		  FETCH_DATA (info, buffer + byte + 2);		  abs = (buffer[byte] << 8) | (buffer[byte + 1]);		  break;		case ABS8:		  abs = (buffer[byte]);		  break;		case IMM16:		  FETCH_DATA (info, buffer + byte + 2);		  imm = (buffer[byte] << 8) | (buffer[byte + 1]);		  break;		case IMM4:		  imm = (buffer[byte]) & 0xf;		  break;		case IMM8:		case RLIST:		  imm = (buffer[byte]);		  break;		case PCREL16:		  FETCH_DATA (info, buffer + byte + 2);		  pcrel = (buffer[byte] << 8) | (buffer[byte + 1]);		  break;		case PCREL8:		  pcrel = (buffer[byte]);		  break;		case QIM:		  switch (buffer[byte] & 0x7)		    {		    case 0:		      qim = 1;		      break;		    case 1:		      qim = 2;		      break;		    case 4:		      qim = -1;		      break;		    case 5:		      qim = -2;		      break;		    }		  break;		}	    }	}      /* We get here when all the masks have passed so we can output	 the operands.  */      FETCH_DATA (info, buffer + opcode->length);      for (i = 0; i < opcode->length; i++)	{	  (func) (stream, "%02x ", buffer[i]);	}      for (; i < 6; i++)	{	  (func) (stream, "   ");	}      (func) (stream, "%s\t", opcode->name);      for (i = 0; i < opcode->nargs; i++)	{	  if (i)	    (func) (stream, ",");	  switch (opcode->arg_type[i])	    {	    case FP:	      func (stream, "fp");	      break;	    case RNIND_D16:	      func (stream, "@(0x%x:16,r%d)", disp, rn);	      break;	    case RNIND_D8:	      func (stream, "@(0x%x:8 (%d),r%d)", disp & 0xff, disp, rn);	      break;	    case RDIND_D16:	      func (stream, "@(0x%x:16,r%d)", disp, rd);	      break;	    case RDIND_D8:	      func (stream, "@(0x%x:8 (%d), r%d)", disp & 0xff, disp, rd);	      break;	    case FPIND_D8:	      func (stream, "@(0x%x:8 (%d), fp)", disp & 0xff, disp, rn);	      break;	    case CRB:	    case CRW:	      func (stream, "%s", crname[cr]);	      break;	    case RN:	      func (stream, "r%d", rn);	      break;	    case RD:	      func (stream, "r%d", rd);	      break;	    case RS:	      func (stream, "r%d", rs);	      break;	    case RNDEC:	      func (stream, "@-r%d", rn);	      break;	    case RNINC:	      func (stream, "@r%d+", rn);	      break;	    case RNIND:	      func (stream, "@r%d", rn);	      break;	    case RDIND:	      func (stream, "@r%d", rd);	      break;	    case SPINC:	      func (stream, "@sp+");	      break;	    case SPDEC:	      func (stream, "@-sp");	      break;	    case ABS24:	      func (stream, "@0x%0x:24", abs);	      break;	    case ABS16:	      func (stream, "@0x%0x:16", abs & 0xffff);	      break;	    case ABS8:	      func (stream, "@0x%0x:8", abs & 0xff);	      break;	    case IMM16:	      func (stream, "#0x%0x:16", imm & 0xffff);	      break;	    case RLIST:	      {		int i;		int nc = 0;		func (stream, "(");		for (i = 0; i < 8; i++)		  {		    if (imm & (1 << i))		      {			func (stream, "r%d", i);			if (nc)			  func (stream, ",");			nc = 1;		      }		  }		func (stream, ")");	      }	      break;	    case IMM8:	      func (stream, "#0x%0x:8", imm & 0xff);	      break;	    case PCREL16:	      func (stream, "0x%0x:16",		    (pcrel + addr + opcode->length) & 0xffff);	      break;	    case PCREL8:	      func (stream, "#0x%0x:8",		    ((char) pcrel + addr + opcode->length) & 0xffff);	      break;	    case QIM:	      func (stream, "#%d:q", qim);	      break;	    case IMM4:	      func (stream, "#%d:4", imm);	      break;	    }	}      return opcode->length;    next:      ;    }  /* Couldn't understand anything.  */  /* xgettext:c-format */  func (stream, _("%02x\t\t*unknown*"), buffer[0]);  return 1;}

⌨️ 快捷键说明

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