ns32k-dis.c

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

C
896
字号
/* Print National Semiconductor 32000 instructions.   Copyright 1986, 1988, 1991, 1992, 1994, 1998   Free Software Foundation, Inc.This file is part of opcodes library.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 "bfd.h"#include "sysdep.h"#include "dis-asm.h"#if !defined(const) && !defined(__STDC__)#define const#endif#include "opcode/ns32k.h"#include "opintl.h"static disassemble_info *dis_info;/* * Hacks to get it to compile <= READ THESE AS FIXES NEEDED */#define INVALID_FLOAT(val, size) invalid_float((char *)val, size)static int print_insn_arg  PARAMS ((int, int, int *, char *, bfd_vma, char *, int));static int get_displacement PARAMS ((char *, int *));static int invalid_float PARAMS ((char *, int));static long read_memory_integer(addr, nr)     unsigned char *addr;     int nr;{  long val;  int i;  for (val = 0, i = nr - 1; i >= 0; i--) {    val =  (val << 8);    val |= (0xff & *(addr + i));  }  return val;}/* 32000 instructions are never longer than this.  */#define MAXLEN 62#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;}/* Number of elements in the opcode table.  */#define NOPCODES (sizeof ns32k_opcodes / sizeof ns32k_opcodes[0])#define NEXT_IS_ADDR	'|'struct ns32k_option {  char *pattern;		/* the option itself */  unsigned long value;		/* binary value of the option */  unsigned long match;		/* these bits must match */};static const struct ns32k_option opt_u[]= /* restore, exit */{  { "r0",	0x80,	0x80	},  { "r1",	0x40,	0x40	},  { "r2",	0x20,	0x20	},  { "r3",	0x10,	0x10	},  { "r4",	0x08,	0x08	},  { "r5",	0x04,	0x04	},  { "r6",	0x02,	0x02	},  { "r7",	0x01,	0x01	},  {  0 ,	0x00,	0x00	}};static const struct ns32k_option opt_U[]= /* save, enter */{  { "r0",	0x01,	0x01	},  { "r1",	0x02,	0x02	},  { "r2",	0x04,	0x04	},  { "r3",	0x08,	0x08	},  { "r4",	0x10,	0x10	},  { "r5",	0x20,	0x20	},  { "r6",	0x40,	0x40	},  { "r7",	0x80,	0x80	},  {  0 ,	0x00,	0x00	}};static const struct ns32k_option opt_O[]= /* setcfg */{  { "c",	0x8,	0x8	},  { "m",	0x4,	0x4	},  { "f",	0x2,	0x2	},  { "i",	0x1,	0x1	},  {  0 ,	0x0,	0x0	}};static const struct ns32k_option opt_C[]= /* cinv */{  { "a",	0x4,	0x4	},  { "i",	0x2,	0x2	},  { "d",	0x1,	0x1	},  {  0 ,	0x0,	0x0	}};static const struct ns32k_option opt_S[]= /* string inst */{  { "b",	0x1,	0x1	},  { "u",	0x6,	0x6	},  { "w",	0x2,	0x2	},  {  0 ,	0x0,	0x0	}};static const struct ns32k_option list_P532[]= /* lpr spr */{  { "us",	0x0,	0xf	},  { "dcr",	0x1,	0xf	},  { "bpc",	0x2,	0xf	},  { "dsr",	0x3,	0xf	},  { "car",	0x4,	0xf	},  { "fp",	0x8,	0xf	},  { "sp",	0x9,	0xf	},  { "sb",	0xa,	0xf	},  { "usp",	0xb,	0xf	},  { "cfg",	0xc,	0xf	},  { "psr",	0xd,	0xf	},  { "intbase",	0xe,	0xf	},  { "mod",	0xf,	0xf	},  {  0 ,	0x00,	0xf	}};static const struct ns32k_option list_M532[]= /* lmr smr */{  { "mcr",	0x9,	0xf	},  { "msr",	0xa,	0xf	},  { "tear",	0xb,	0xf	},  { "ptb0",	0xc,	0xf	},  { "ptb1",	0xd,	0xf	},  { "ivar0",	0xe,	0xf	},  { "ivar1",	0xf,	0xf	},  {  0 ,	0x0,	0xf	}};static const struct ns32k_option list_P032[]= /* lpr spr */{  { "upsr",	0x0,	0xf	},  { "fp",	0x8,	0xf	},  { "sp",	0x9,	0xf	},  { "sb",	0xa,	0xf	},  { "psr",	0xb,	0xf	},  { "intbase",	0xe,	0xf	},  { "mod",	0xf,	0xf	},  {  0 ,	0x0,	0xf	}};static const struct ns32k_option list_M032[]= /* lmr smr */{  { "bpr0",	0x0,	0xf	},  { "bpr1",	0x1,	0xf	},  { "pf0",	0x4,	0xf	},  { "pf1",	0x5,	0xf	},  { "sc",	0x8,	0xf	},  { "msr",	0xa,	0xf	},  { "bcnt",	0xb,	0xf	},  { "ptb0",	0xc,	0xf	},  { "ptb1",	0xd,	0xf	},  { "eia",	0xf,	0xf	},  {  0 ,	0x0,	0xf	}};/* * figure out which options are present */static voidoptlist(options, optionP, result)     int options;     const struct ns32k_option *optionP;     char *result;{    if (options == 0) {	sprintf(result, "[]");	return;    }    sprintf(result, "[");    for (; (options != 0) && optionP->pattern; optionP++) {	if ((options & optionP->match) == optionP->value) {	    /* we found a match, update result and options */	    strcat(result, optionP->pattern);	    options &= ~optionP->value;	    if (options != 0)	/* more options to come */		strcat(result, ",");	}    }    if (options != 0)	strcat(result, "undefined");    strcat(result, "]");}static voidlist_search (reg_value, optionP, result)     int reg_value;     const struct ns32k_option *optionP;     char *result;{    for (; optionP->pattern; optionP++) {	if ((reg_value & optionP->match) == optionP->value) {	    sprintf(result, "%s", optionP->pattern);	    return;	}    }    sprintf(result, "undefined");}/* * extract "count" bits starting "offset" bits * into buffer */static intbit_extract (buffer, offset, count)     bfd_byte *buffer;     int offset;     int count;{  int result;  int bit;  buffer += offset >> 3;  offset &= 7;  bit = 1;  result = 0;  while (count--)    {      FETCH_DATA(dis_info, buffer + 1);      if ((*buffer & (1 << offset)))	result |= bit;      if (++offset == 8)	{	  offset = 0;	  buffer++;	}      bit <<= 1;    }  return result;}/* Like bit extract but the buffer is valid and doen't need to be * fetched */static intbit_extract_simple (buffer, offset, count)     bfd_byte *buffer;     int offset;     int count;{  int result;  int mask;  int bit;  buffer += offset >> 3;  offset &= 7;  bit = 1;  result = 0;  while (count--)    {      if ((*buffer & (1 << offset)))	result |= bit;      if (++offset == 8)	{	  offset = 0;	  buffer++;	}      bit <<= 1;    }  return result;}static voidbit_copy (buffer, offset, count, to)     char *buffer;     int offset;     int count;     char *to;{  for(; count > 8; count -= 8, to++, offset += 8)    *to = bit_extract (buffer, offset, 8);  *to = bit_extract (buffer, offset, count);}static intsign_extend (value, bits)     int value, bits;{  value = value & ((1 << bits) - 1);  return (value & (1 << (bits-1))	  ? value | (~((1 << bits) - 1))	  : value);}static voidflip_bytes (ptr, count)     char *ptr;     int count;{  char tmp;  while (count > 0)    {      tmp = ptr[0];      ptr[0] = ptr[count-1];      ptr[count-1] = tmp;      ptr++;      count -= 2;    }}/* Given a character C, does it represent a general addressing mode?  */#define Is_gen(c) \  ((c) == 'F' || (c) == 'L' || (c) == 'B' \   || (c) == 'W' || (c) == 'D' || (c) == 'A' || (c) == 'I' || (c) == 'Z')/* Adressing modes.  */#define Adrmod_index_byte 0x1c#define Adrmod_index_word 0x1d#define Adrmod_index_doubleword 0x1e#define Adrmod_index_quadword 0x1f/* Is MODE an indexed addressing mode?  */#define Adrmod_is_index(mode) \  (mode == Adrmod_index_byte \   || mode == Adrmod_index_word \   || mode == Adrmod_index_doubleword \   || mode == Adrmod_index_quadword)/* Print the 32000 instruction at address MEMADDR in debugged memory,   on STREAM.  Returns length of the instruction, in bytes.  */intprint_insn_ns32k (memaddr, info)     bfd_vma memaddr;     disassemble_info *info;{  register unsigned int i;  register char *d;  unsigned short first_word;  int ioffset;		/* bits into instruction */  int aoffset;		/* bits into arguments */  char arg_bufs[MAX_ARGS+1][ARG_LEN];  int argnum;  int maxarg;  struct private priv;  bfd_byte *buffer = priv.the_buffer;  dis_info = info;  info->private_data = (PTR) &priv;  priv.max_fetched = priv.the_buffer;  priv.insn_start = memaddr;  if (setjmp (priv.bailout) != 0)    /* Error return.  */    return -1;  /* Look for 8bit opcodes first. Other wise, fetching two bytes could take   * us over the end of accessible data unnecessarilly   */  FETCH_DATA(info, buffer + 1);  for (i = 0; i < NOPCODES; i++)    if (ns32k_opcodes[i].opcode_id_size <= 8	&& ((buffer[0]	     & (((unsigned long) 1 << ns32k_opcodes[i].opcode_id_size) - 1))	    == ns32k_opcodes[i].opcode_seed))      break;  if (i == NOPCODES) {    /* Maybe it is 9 to 16 bits big */    FETCH_DATA(info, buffer + 2);    first_word = read_memory_integer(buffer, 2);    for (i = 0; i < NOPCODES; i++)      if ((first_word	   & (((unsigned long) 1 << ns32k_opcodes[i].opcode_id_size) - 1))	  == ns32k_opcodes[i].opcode_seed)	break;    /* Handle undefined instructions.  */    if (i == NOPCODES)      {	(*dis_info->fprintf_func)(dis_info->stream, "0%o", buffer[0]);	return 1;      }  }  (*dis_info->fprintf_func)(dis_info->stream, "%s", ns32k_opcodes[i].name);

⌨️ 快捷键说明

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