sh-dis.c

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

C
739
字号
      print_insn_ddt ((nibs[1] << 8) | (nibs[2] << 4) | nibs[3], info);      return 2;    }  for (op = sh_table; op->name; op++)    {      int n;      int imm = 0;      int rn = 0;      int rm = 0;      int rb = 0;      int disp_pc;      bfd_vma disp_pc_addr = 0;      if ((op->arch & target_arch) == 0)	goto fail;      for (n = 0; n < 4; n++)	{	  int i = op->nibbles[n];	  if (i < 16)	    {	      if (nibs[n] == i)		continue;	      goto fail;	    }	  switch (i)	    {	    case BRANCH_8:	      imm = (nibs[2] << 4) | (nibs[3]);	      if (imm & 0x80)		imm |= ~0xff;	      imm = ((char) imm) * 2 + 4;	      goto ok;	    case BRANCH_12:	      imm = ((nibs[1]) << 8) | (nibs[2] << 4) | (nibs[3]);	      if (imm & 0x800)		imm |= ~0xfff;	      imm = imm * 2 + 4;	      goto ok;	    case IMM0_4:	    case IMM1_4:	      imm = nibs[3];	      goto ok;	    case IMM0_4BY2:	    case IMM1_4BY2:	      imm = nibs[3] << 1;	      goto ok;	    case IMM0_4BY4:	    case IMM1_4BY4:	      imm = nibs[3] << 2;	      goto ok;	    case IMM0_8:	    case IMM1_8:	      imm = (nibs[2] << 4) | nibs[3];	      goto ok;	    case PCRELIMM_8BY2:	      imm = ((nibs[2] << 4) | nibs[3]) << 1;	      relmask = ~(bfd_vma) 1;	      goto ok;	    case PCRELIMM_8BY4:	      imm = ((nibs[2] << 4) | nibs[3]) << 2;	      relmask = ~(bfd_vma) 3;	      goto ok;	    case IMM0_8BY2:	    case IMM1_8BY2:	      imm = ((nibs[2] << 4) | nibs[3]) << 1;	      goto ok;	    case IMM0_8BY4:	    case IMM1_8BY4:	      imm = ((nibs[2] << 4) | nibs[3]) << 2;	      goto ok;	    case REG_N:	      rn = nibs[n];	      break;	    case REG_M:	      rm = nibs[n];	      break;	    case REG_NM:	      rn = (nibs[n] & 0xc) >> 2;	      rm = (nibs[n] & 0x3);	      break;	    case REG_B:	      rb = nibs[n] & 0x07;	      break;	    case SDT_REG_N:	      /* sh-dsp: single data transfer.  */	      rn = nibs[n];	      if ((rn & 0xc) != 4)		goto fail;	      rn = rn & 0x3;	      rn |= (rn & 2) << 1;	      break;	    case PPI:	    case REPEAT:	      goto fail;	    default:	      abort ();	    }	}    ok:      fprintf_fn (stream, "%s\t", op->name);      disp_pc = 0;      for (n = 0; n < 3 && op->arg[n] != A_END; n++)	{	  if (n && op->arg[1] != A_END)	    fprintf_fn (stream, ",");	  switch (op->arg[n])	    {	    case A_IMM:	      fprintf_fn (stream, "#%d", (char) (imm));	      break;	    case A_R0:	      fprintf_fn (stream, "r0");	      break;	    case A_REG_N:	      fprintf_fn (stream, "r%d", rn);	      break;	    case A_INC_N:	      fprintf_fn (stream, "@r%d+", rn);	      break;	    case A_DEC_N:	      fprintf_fn (stream, "@-r%d", rn);	      break;	    case A_IND_N:	      fprintf_fn (stream, "@r%d", rn);	      break;	    case A_DISP_REG_N:	      fprintf_fn (stream, "@(%d,r%d)", imm, rn);	      break;	    case A_PMOD_N:	      fprintf_fn (stream, "@r%d+r8", rn);	      break;	    case A_REG_M:	      fprintf_fn (stream, "r%d", rm);	      break;	    case A_INC_M:	      fprintf_fn (stream, "@r%d+", rm);	      break;	    case A_DEC_M:	      fprintf_fn (stream, "@-r%d", rm);	      break;	    case A_IND_M:	      fprintf_fn (stream, "@r%d", rm);	      break;	    case A_DISP_REG_M:	      fprintf_fn (stream, "@(%d,r%d)", imm, rm);	      break;	    case A_REG_B:	      fprintf_fn (stream, "r%d_bank", rb);	      break;	    case A_DISP_PC:	      disp_pc = 1;	      disp_pc_addr = imm + 4 + (memaddr & relmask);	      (*info->print_address_func) (disp_pc_addr, info);	      break;	    case A_IND_R0_REG_N:	      fprintf_fn (stream, "@(r0,r%d)", rn);	      break;	    case A_IND_R0_REG_M:	      fprintf_fn (stream, "@(r0,r%d)", rm);	      break;	    case A_DISP_GBR:	      fprintf_fn (stream, "@(%d,gbr)", imm);	      break;	    case A_R0_GBR:	      fprintf_fn (stream, "@(r0,gbr)");	      break;	    case A_BDISP12:	    case A_BDISP8:	      (*info->print_address_func) (imm + memaddr, info);	      break;	    case A_SR:	      fprintf_fn (stream, "sr");	      break;	    case A_GBR:	      fprintf_fn (stream, "gbr");	      break;	    case A_VBR:	      fprintf_fn (stream, "vbr");	      break;	    case A_DSR:	      fprintf_fn (stream, "dsr");	      break;	    case A_MOD:	      fprintf_fn (stream, "mod");	      break;	    case A_RE:	      fprintf_fn (stream, "re");	      break;	    case A_RS:	      fprintf_fn (stream, "rs");	      break;	    case A_A0:	      fprintf_fn (stream, "a0");	      break;	    case A_X0:	      fprintf_fn (stream, "x0");	      break;	    case A_X1:	      fprintf_fn (stream, "x1");	      break;	    case A_Y0:	      fprintf_fn (stream, "y0");	      break;	    case A_Y1:	      fprintf_fn (stream, "y1");	      break;	    case DSP_REG_M:	      print_dsp_reg (rm, fprintf_fn, stream);	      break;	    case A_SSR:	      fprintf_fn (stream, "ssr");	      break;	    case A_SPC:	      fprintf_fn (stream, "spc");	      break;	    case A_MACH:	      fprintf_fn (stream, "mach");	      break;	    case A_MACL:	      fprintf_fn (stream, "macl");	      break;	    case A_PR:	      fprintf_fn (stream, "pr");	      break;	    case A_SGR:	      fprintf_fn (stream, "sgr");	      break;	    case A_DBR:	      fprintf_fn (stream, "dbr");	      break;	    case F_REG_N:	      fprintf_fn (stream, "fr%d", rn);	      break;	    case F_REG_M:	      fprintf_fn (stream, "fr%d", rm);	      break;	    case DX_REG_N:	      if (rn & 1)		{		  fprintf_fn (stream, "xd%d", rn & ~1);		  break;		}	    case D_REG_N:	      fprintf_fn (stream, "dr%d", rn);	      break;	    case DX_REG_M:	      if (rm & 1)		{		  fprintf_fn (stream, "xd%d", rm & ~1);		  break;		}	    case D_REG_M:	      fprintf_fn (stream, "dr%d", rm);	      break;	    case FPSCR_M:	    case FPSCR_N:	      fprintf_fn (stream, "fpscr");	      break;	    case FPUL_M:	    case FPUL_N:	      fprintf_fn (stream, "fpul");	      break;	    case F_FR0:	      fprintf_fn (stream, "fr0");	      break;	    case V_REG_N:	      fprintf_fn (stream, "fv%d", rn * 4);	      break;	    case V_REG_M:	      fprintf_fn (stream, "fv%d", rm * 4);	      break;	    case XMTRX_M4:	      fprintf_fn (stream, "xmtrx");	      break;	    default:	      abort ();	    }	}#if 0      /* This code prints instructions in delay slots on the same line         as the instruction which needs the delay slots.  This can be         confusing, since other disassembler don't work this way, and         it means that the instructions are not all in a line.  So I         disabled it.  Ian.  */      if (!(info->flags & 1)	  && (op->name[0] == 'j'	      || (op->name[0] == 'b'		  && (op->name[1] == 'r'		      || op->name[1] == 's'))	      || (op->name[0] == 'r' && op->name[1] == 't')	      || (op->name[0] == 'b' && op->name[2] == '.')))	{	  info->flags |= 1;	  fprintf_fn (stream, "\t(slot ");	  print_insn_shx (memaddr + 2, info);	  info->flags &= ~1;	  fprintf_fn (stream, ")");	  return 4;	}#endif      if (disp_pc && strcmp (op->name, "mova") != 0)	{	  int size;	  bfd_byte bytes[4];	  if (relmask == ~(bfd_vma) 1)	    size = 2;	  else	    size = 4;	  status = info->read_memory_func (disp_pc_addr, bytes, size, info);	  if (status == 0)	    {	      unsigned int val;	      if (size == 2)		{		  if ((info->flags & LITTLE_BIT) != 0)		    val = bfd_getl16 (bytes);		  else		    val = bfd_getb16 (bytes);		}	      else		{		  if ((info->flags & LITTLE_BIT) != 0)		    val = bfd_getl32 (bytes);		  else		    val = bfd_getb32 (bytes);		}	      fprintf_fn (stream, "\t! 0x%x", val);	    }	}      return 2;    fail:      ;    }  fprintf_fn (stream, ".word 0x%x%x%x%x", nibs[0], nibs[1], nibs[2], nibs[3]);  return 2;}intprint_insn_shl (memaddr, info)     bfd_vma memaddr;     struct disassemble_info *info;{  int r;  info->flags = LITTLE_BIT;  r = print_insn_shx (memaddr, info);  return r;}intprint_insn_sh (memaddr, info)     bfd_vma memaddr;     struct disassemble_info *info;{  int r;  info->flags = 0;  r = print_insn_shx (memaddr, info);  return r;}

⌨️ 快捷键说明

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