i860-dis.c

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

C
289
字号
/* Disassembler for the i860.   Copyright 2000 Free Software Foundation, Inc.   Contributed by Jason Eckhardt <jle@cygnus.com>.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 "dis-asm.h"#include "opcode/i860.h"/* Later we should probably choose the prefix based on which OS flavor.  */#define I860_REG_PREFIX "%"/* Integer register names (encoded as 0..31 in the instruction).  */static const char *const grnames[] =  {"r0",  "r1",  "sp",  "fp",  "r4",  "r5",  "r6",  "r7",  "r8",  "r9",  "r10", "r11", "r12", "r13", "r14", "r15",  "r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23",  "r24", "r25", "r26", "r27", "r28", "r29", "r30", "r31"};/* FP register names (encoded as 0..31 in the instruction).  */static const char *const frnames[] =  {"f0",  "f1",  "f2",  "f3",  "f4",  "f5",  "f6",  "f7",  "f8",  "f9",  "f10", "f11", "f12", "f13", "f14", "f15",  "f16", "f17", "f18", "f19", "f20", "f21", "f22", "f23",  "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31"};/* Control/status register names (encoded as 0..5 in the instruction).  */static const char *const crnames[] =  {"fir", "psr", "dirbase", "db", "fsr", "epsr", "", ""};/* Prototypes.  */static int sign_ext		PARAMS((unsigned int, int)); static void print_br_address	PARAMS((disassemble_info *, bfd_vma, long));/* True if opcode is xor, xorh, and, andh, or, orh, andnot, andnoth.  */#define BITWISE_OP(op)  ((op) == 0x30 || (op) == 0x31		\			 || (op) == 0x34 || (op) == 0x35	\			 || (op) == 0x38 || (op) == 0x39	\			 || (op) == 0x3c || (op) == 0x3d	\			 || (op) == 0x33 || (op) == 0x37	\			 || (op) == 0x3b || (op) == 0x3f)/* Sign extend N-bit number.  */static intsign_ext (x, n)     unsigned int x;     int n;{  int t;  t = x >> (n - 1);  t = ((-t) << n) | x;  return t;}/* Print a PC-relative branch offset.  VAL is the sign extended value   from the branch instruction.  */static voidprint_br_address (info, memaddr, val)     disassemble_info *info;     bfd_vma memaddr;     long val;{  long adj = (long)memaddr + 4 + (val << 2);  (*info->fprintf_func) (info->stream, "0x%08x", adj);	      /* Attempt to obtain a symbol for the target address.  */	  if (info->print_address_func && adj != 0)    {      (*info->fprintf_func) (info->stream, "\t// ");      (*info->print_address_func) (adj, info);    }}/* Print one instruction.  */intprint_insn_i860 (memaddr, info)     bfd_vma memaddr;     disassemble_info *info;{  bfd_byte buff[4];  unsigned int insn, i;  int status;  const struct i860_opcode *opcode = 0;  status = (*info->read_memory_func) (memaddr, buff, sizeof (buff), info);  if (status != 0)    {      (*info->memory_error_func) (status, memaddr, info);      return -1;    }  /* Note that i860 instructions are always accessed as little endian     data, regardless of the endian mode of the i860.  */  insn = bfd_getl32 (buff);  status = 0;  i = 0;  while (i860_opcodes[i].name != NULL)    {      opcode = &i860_opcodes[i];      if ((insn & opcode->match) == opcode->match	  && (insn & opcode->lose) == 0)	{	  status = 1;	  break;	}      ++i;    }  if (status == 0)    {      /* Instruction not in opcode table.  */      (*info->fprintf_func) (info->stream, ".long %#08x", insn);    }  else    {      const char *s;      int val;      /* If this a flop and its dual bit is set, prefix with 'd.'.  */ 	      if ((insn & 0xfc000000) == 0x48000000 && (insn & 0x200))	(*info->fprintf_func) (info->stream, "d.%s\t", opcode->name);      else	(*info->fprintf_func) (info->stream, "%s\t", opcode->name);      for (s = opcode->args; *s; s++)	{	  switch (*s)	    {	    /* Integer register (src1).  */	    case '1':	      (*info->fprintf_func) (info->stream, "%s%s", I860_REG_PREFIX,				     grnames[(insn >> 11) & 0x1f]);	      break;	    /* Integer register (src2).  */	    case '2':	      (*info->fprintf_func) (info->stream, "%s%s", I860_REG_PREFIX,				     grnames[(insn >> 21) & 0x1f]);	      break;	    /* Integer destination register.  */	    case 'd':	      (*info->fprintf_func) (info->stream, "%s%s", I860_REG_PREFIX,				     grnames[(insn >> 16) & 0x1f]);	      break;	    /* Floating-point register (src1).  */	    case 'e':	      (*info->fprintf_func) (info->stream, "%s%s", I860_REG_PREFIX,				     frnames[(insn >> 11) & 0x1f]);	      break;	    /* Floating-point register (src2).  */	    case 'f':	      (*info->fprintf_func) (info->stream, "%s%s", I860_REG_PREFIX,				     frnames[(insn >> 21) & 0x1f]);	      break;	    /* Floating-point destination register.  */	    case 'g':	      (*info->fprintf_func) (info->stream, "%s%s", I860_REG_PREFIX,				     frnames[(insn >> 16) & 0x1f]);	      break;	    /* Control register.  */	    case 'c':	      (*info->fprintf_func) (info->stream, "%s%s", I860_REG_PREFIX,				     crnames[(insn >> 21) & 0x7]);	      break;	    /* 16-bit immediate (sign extend, except for bitwise ops).  */	    case 'i':	      if (BITWISE_OP ((insn & 0xfc000000) >> 26))		(*info->fprintf_func) (info->stream, "0x%04x",				       (unsigned int) (insn & 0xffff));	      else		(*info->fprintf_func) (info->stream, "%d",				       sign_ext ((insn & 0xffff), 16));	      break;	    /* 16-bit immediate, aligned (2^0, ld.b).  */	    case 'I':	      (*info->fprintf_func) (info->stream, "%d",				     sign_ext ((insn & 0xffff), 16));	      break;	    /* 16-bit immediate, aligned (2^1, ld.s).  */	    case 'J':	      (*info->fprintf_func) (info->stream, "%d",				     sign_ext ((insn & 0xfffe), 16));	      break;	    /* 16-bit immediate, aligned (2^2, ld.l, {p}fld.l, fst.l).  */	    case 'K':	      (*info->fprintf_func) (info->stream, "%d",				     sign_ext ((insn & 0xfffc), 16));	      break;	    /* 16-bit immediate, aligned (2^3, {p}fld.d, fst.d).  */	    case 'L':	      (*info->fprintf_func) (info->stream, "%d",				     sign_ext ((insn & 0xfff8), 16));	      break;	    /* 16-bit immediate, aligned (2^4, {p}fld.q, fst.q).  */	    case 'M':	      (*info->fprintf_func) (info->stream, "%d",				     sign_ext ((insn & 0xfff0), 16));	      break;	    /* 5-bit immediate (zero extend).  */	    case '5':	      (*info->fprintf_func) (info->stream, "%d",				     ((insn >> 11) & 0x1f));	      break;	    /* Split 16 bit immediate (20..16:10..0).  */	    case 's':	      val = ((insn >> 5) & 0xf800) | (insn & 0x07ff);	      (*info->fprintf_func) (info->stream, "%d",				     sign_ext (val, 16));	      break;	    /* Split 16 bit immediate, aligned. (2^0, st.b).  */	    case 'S':	      val = ((insn >> 5) & 0xf800) | (insn & 0x07ff);	      (*info->fprintf_func) (info->stream, "%d",				     sign_ext (val, 16));	      break;	    /* Split 16 bit immediate, aligned. (2^1, st.s).  */	    case 'T':	      val = ((insn >> 5) & 0xf800) | (insn & 0x07fe);	      (*info->fprintf_func) (info->stream, "%d",				     sign_ext (val, 16));	      break;	    /* Split 16 bit immediate, aligned. (2^2, st.l).  */	    case 'U':	      val = ((insn >> 5) & 0xf800) | (insn & 0x07fc);	      (*info->fprintf_func) (info->stream, "%d",				     sign_ext (val, 16));	      break;	    /* 26-bit PC relative immediate (lbroff).  */	    case 'l':	      val = sign_ext ((insn & 0x03ffffff), 26);	      print_br_address (info, memaddr, val);	      break;	    /* 16-bit PC relative immediate (sbroff).  */	    case 'r':	      val = sign_ext ((((insn >> 5) & 0xf800) | (insn & 0x07ff)), 16);	      print_br_address (info, memaddr, val);	      break;	    default:	      (*info->fprintf_func) (info->stream, "%c", *s);	      break;	    }	}    }  return sizeof (insn);}

⌨️ 快捷键说明

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