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

📄 mips-dis.c

📁 基于4个mips核的noc设计
💻 C
📖 第 1 页 / 共 2 页
字号:
}/* Disassemble mips16 instructions.  */static intprint_insn_mips16 (memaddr, info)     bfd_vma memaddr;     struct disassemble_info *info;{  int status;  bfd_byte buffer[2];  int length;  int insn;  boolean use_extend;  int extend = 0;  const struct mips_opcode *op, *opend;  info->bytes_per_chunk = 2;  info->display_endian = info->endian;  info->insn_info_valid = 1;  info->branch_delay_insns = 0;  info->data_size = 0;  info->insn_type = dis_nonbranch;  info->target = 0;  info->target2 = 0;  status = (*info->read_memory_func) (memaddr, buffer, 2, info);  if (status != 0)    {      (*info->memory_error_func) (status, memaddr, info);      return -1;    }  length = 2;  if (info->endian == BFD_ENDIAN_BIG)    insn = bfd_getb16 (buffer);  else    insn = bfd_getl16 (buffer);  /* Handle the extend opcode specially.  */  use_extend = false;  if ((insn & 0xf800) == 0xf000)    {      use_extend = true;      extend = insn & 0x7ff;      memaddr += 2;      status = (*info->read_memory_func) (memaddr, buffer, 2, info);      if (status != 0)	{	  (*info->fprintf_func) (info->stream, "extend 0x%x",				 (unsigned int) extend);	  (*info->memory_error_func) (status, memaddr, info);	  return -1;	}      if (info->endian == BFD_ENDIAN_BIG)	insn = bfd_getb16 (buffer);      else	insn = bfd_getl16 (buffer);      /* Check for an extend opcode followed by an extend opcode.  */      if ((insn & 0xf800) == 0xf000)	{	  (*info->fprintf_func) (info->stream, "extend 0x%x",				 (unsigned int) extend);	  info->insn_type = dis_noninsn;	  return length;	}      length += 2;    }  /* FIXME: Should probably use a hash table on the major opcode here.  */  opend = mips16_opcodes + bfd_mips16_num_opcodes;  for (op = mips16_opcodes; op < opend; op++)    {      if (op->pinfo != INSN_MACRO && (insn & op->mask) == op->match)	{	  const char *s;	  if (strchr (op->args, 'a') != NULL)	    {	      if (use_extend)		{		  (*info->fprintf_func) (info->stream, "extend 0x%x",					 (unsigned int) extend);		  info->insn_type = dis_noninsn;		  return length - 2;		}	      use_extend = false;	      memaddr += 2;	      status = (*info->read_memory_func) (memaddr, buffer, 2,						  info);	      if (status == 0)		{		  use_extend = true;		  if (info->endian == BFD_ENDIAN_BIG)		    extend = bfd_getb16 (buffer);		  else		    extend = bfd_getl16 (buffer);		  length += 2;		}	    }	  (*info->fprintf_func) (info->stream, "%s", op->name);	  if (op->args[0] != '\0')	    (*info->fprintf_func) (info->stream, "\t");	  for (s = op->args; *s != '\0'; s++)	    {	      if (*s == ','		  && s[1] == 'w'		  && (((insn >> MIPS16OP_SH_RX) & MIPS16OP_MASK_RX)		      == ((insn >> MIPS16OP_SH_RY) & MIPS16OP_MASK_RY)))		{		  /* Skip the register and the comma.  */		  ++s;		  continue;		}	      if (*s == ','		  && s[1] == 'v'		  && (((insn >> MIPS16OP_SH_RZ) & MIPS16OP_MASK_RZ)		      == ((insn >> MIPS16OP_SH_RX) & MIPS16OP_MASK_RX)))		{		  /* Skip the register and the comma.  */		  ++s;		  continue;		}	      print_mips16_insn_arg (*s, op, insn, use_extend, extend, memaddr,				     info);	    }	  if ((op->pinfo & INSN_UNCOND_BRANCH_DELAY) != 0)	    {	      info->branch_delay_insns = 1;	      if (info->insn_type != dis_jsr)		info->insn_type = dis_branch;	    }	  return length;	}    }  if (use_extend)    (*info->fprintf_func) (info->stream, "0x%x", extend | 0xf000);  (*info->fprintf_func) (info->stream, "0x%x", insn);  info->insn_type = dis_noninsn;  return length;}/* Disassemble an operand for a mips16 instruction.  */static voidprint_mips16_insn_arg (type, op, l, use_extend, extend, memaddr, info)     char type;     const struct mips_opcode *op;     int l;     boolean use_extend;     int extend;     bfd_vma memaddr;     struct disassemble_info *info;{  switch (type)    {    case ',':    case '(':    case ')':      (*info->fprintf_func) (info->stream, "%c", type);      break;    case 'y':    case 'w':      (*info->fprintf_func) (info->stream, "%s",			     mips16_reg_names[((l >> MIPS16OP_SH_RY)					       & MIPS16OP_MASK_RY)]);      break;    case 'x':    case 'v':      (*info->fprintf_func) (info->stream, "%s",			     mips16_reg_names[((l >> MIPS16OP_SH_RX)					       & MIPS16OP_MASK_RX)]);      break;    case 'z':      (*info->fprintf_func) (info->stream, "%s",			     mips16_reg_names[((l >> MIPS16OP_SH_RZ)					       & MIPS16OP_MASK_RZ)]);      break;    case 'Z':      (*info->fprintf_func) (info->stream, "%s",			     mips16_reg_names[((l >> MIPS16OP_SH_MOVE32Z)					       & MIPS16OP_MASK_MOVE32Z)]);      break;    case '0':      (*info->fprintf_func) (info->stream, "%s", mips32_reg_names[0]);      break;    case 'S':      (*info->fprintf_func) (info->stream, "%s", mips32_reg_names[29]);      break;    case 'P':      (*info->fprintf_func) (info->stream, "$pc");      break;    case 'R':      (*info->fprintf_func) (info->stream, "%s", mips32_reg_names[31]);      break;    case 'X':      (*info->fprintf_func) (info->stream, "%s",			     mips32_reg_names[((l >> MIPS16OP_SH_REGR32)					& MIPS16OP_MASK_REGR32)]);      break;    case 'Y':      (*info->fprintf_func) (info->stream, "%s",			     mips32_reg_names[MIPS16OP_EXTRACT_REG32R (l)]);      break;    case '<':    case '>':    case '[':    case ']':    case '4':    case '5':    case 'H':    case 'W':    case 'D':    case 'j':    case '6':    case '8':    case 'V':    case 'C':    case 'U':    case 'k':    case 'K':    case 'p':    case 'q':    case 'A':    case 'B':    case 'E':      {	int immed, nbits, shift, signedp, extbits, pcrel, extu, branch;	shift = 0;	signedp = 0;	extbits = 16;	pcrel = 0;	extu = 0;	branch = 0;	switch (type)	  {	  case '<':	    nbits = 3;	    immed = (l >> MIPS16OP_SH_RZ) & MIPS16OP_MASK_RZ;	    extbits = 5;	    extu = 1;	    break;	  case '>':	    nbits = 3;	    immed = (l >> MIPS16OP_SH_RX) & MIPS16OP_MASK_RX;	    extbits = 5;	    extu = 1;	    break;	  case '[':	    nbits = 3;	    immed = (l >> MIPS16OP_SH_RZ) & MIPS16OP_MASK_RZ;	    extbits = 6;	    extu = 1;	    break;	  case ']':	    nbits = 3;	    immed = (l >> MIPS16OP_SH_RX) & MIPS16OP_MASK_RX;	    extbits = 6;	    extu = 1;	    break;	  case '4':	    nbits = 4;	    immed = (l >> MIPS16OP_SH_IMM4) & MIPS16OP_MASK_IMM4;	    signedp = 1;	    extbits = 15;	    break;	  case '5':	    nbits = 5;	    immed = (l >> MIPS16OP_SH_IMM5) & MIPS16OP_MASK_IMM5;	    info->insn_type = dis_dref;	    info->data_size = 1;	    break;	  case 'H':	    nbits = 5;	    shift = 1;	    immed = (l >> MIPS16OP_SH_IMM5) & MIPS16OP_MASK_IMM5;	    info->insn_type = dis_dref;	    info->data_size = 2;	    break;	  case 'W':	    nbits = 5;	    shift = 2;	    immed = (l >> MIPS16OP_SH_IMM5) & MIPS16OP_MASK_IMM5;	    if ((op->pinfo & MIPS16_INSN_READ_PC) == 0		&& (op->pinfo & MIPS16_INSN_READ_SP) == 0)	      {		info->insn_type = dis_dref;		info->data_size = 4;	      }	    break;	  case 'D':	    nbits = 5;	    shift = 3;	    immed = (l >> MIPS16OP_SH_IMM5) & MIPS16OP_MASK_IMM5;	    info->insn_type = dis_dref;	    info->data_size = 8;	    break;	  case 'j':	    nbits = 5;	    immed = (l >> MIPS16OP_SH_IMM5) & MIPS16OP_MASK_IMM5;	    signedp = 1;	    break;	  case '6':	    nbits = 6;	    immed = (l >> MIPS16OP_SH_IMM6) & MIPS16OP_MASK_IMM6;	    break;	  case '8':	    nbits = 8;	    immed = (l >> MIPS16OP_SH_IMM8) & MIPS16OP_MASK_IMM8;	    break;	  case 'V':	    nbits = 8;	    shift = 2;	    immed = (l >> MIPS16OP_SH_IMM8) & MIPS16OP_MASK_IMM8;	    /* FIXME: This might be lw, or it might be addiu to $sp or               $pc.  We assume it's load.  */	    info->insn_type = dis_dref;	    info->data_size = 4;	    break;	  case 'C':	    nbits = 8;	    shift = 3;	    immed = (l >> MIPS16OP_SH_IMM8) & MIPS16OP_MASK_IMM8;	    info->insn_type = dis_dref;	    info->data_size = 8;	    break;	  case 'U':	    nbits = 8;	    immed = (l >> MIPS16OP_SH_IMM8) & MIPS16OP_MASK_IMM8;	    extu = 1;	    break;	  case 'k':	    nbits = 8;	    immed = (l >> MIPS16OP_SH_IMM8) & MIPS16OP_MASK_IMM8;	    signedp = 1;	    break;	  case 'K':	    nbits = 8;	    shift = 3;	    immed = (l >> MIPS16OP_SH_IMM8) & MIPS16OP_MASK_IMM8;	    signedp = 1;	    break;	  case 'p':	    nbits = 8;	    immed = (l >> MIPS16OP_SH_IMM8) & MIPS16OP_MASK_IMM8;	    signedp = 1;	    pcrel = 1;	    branch = 1;	    info->insn_type = dis_condbranch;	    break;	  case 'q':	    nbits = 11;	    immed = (l >> MIPS16OP_SH_IMM11) & MIPS16OP_MASK_IMM11;	    signedp = 1;	    pcrel = 1;	    branch = 1;	    info->insn_type = dis_branch;	    break;	  case 'A':	    nbits = 8;	    shift = 2;	    immed = (l >> MIPS16OP_SH_IMM8) & MIPS16OP_MASK_IMM8;	    pcrel = 1;	    /* FIXME: This can be lw or la.  We assume it is lw.  */	    info->insn_type = dis_dref;	    info->data_size = 4;	    break;	  case 'B':	    nbits = 5;	    shift = 3;	    immed = (l >> MIPS16OP_SH_IMM5) & MIPS16OP_MASK_IMM5;	    pcrel = 1;	    info->insn_type = dis_dref;	    info->data_size = 8;	    break;	  case 'E':	    nbits = 5;	    shift = 2;	    immed = (l >> MIPS16OP_SH_IMM5) & MIPS16OP_MASK_IMM5;	    pcrel = 1;	    break;	  default:	    abort ();	  }	if (! use_extend)	  {	    if (signedp && immed >= (1 << (nbits - 1)))	      immed -= 1 << nbits;	    immed <<= shift;	    if ((type == '<' || type == '>' || type == '[' || type == ']')		&& immed == 0)	      immed = 8;	  }	else	  {	    if (extbits == 16)	      immed |= ((extend & 0x1f) << 11) | (extend & 0x7e0);	    else if (extbits == 15)	      immed |= ((extend & 0xf) << 11) | (extend & 0x7f0);	    else	      immed = ((extend >> 6) & 0x1f) | (extend & 0x20);	    immed &= (1 << extbits) - 1;	    if (! extu && immed >= (1 << (extbits - 1)))	      immed -= 1 << extbits;	  }	if (! pcrel)	  (*info->fprintf_func) (info->stream, "%d", immed);	else	  {	    bfd_vma baseaddr;	    bfd_vma val;	    if (branch)	      {		immed *= 2;		baseaddr = memaddr + 2;	      }	    else if (use_extend)	      baseaddr = memaddr - 2;	    else	      {		int status;		bfd_byte buffer[2];		baseaddr = memaddr;		/* If this instruction is in the delay slot of a jr                   instruction, the base address is the address of the                   jr instruction.  If it is in the delay slot of jalr                   instruction, the base address is the address of the                   jalr instruction.  This test is unreliable: we have                   no way of knowing whether the previous word is                   instruction or data.  */		status = (*info->read_memory_func) (memaddr - 4, buffer, 2,						    info);		if (status == 0		    && (((info->endian == BFD_ENDIAN_BIG			  ? bfd_getb16 (buffer)			  : bfd_getl16 (buffer))			 & 0xf800) == 0x1800))		  baseaddr = memaddr - 4;		else		  {		    status = (*info->read_memory_func) (memaddr - 2, buffer,							2, info);		    if (status == 0			&& (((info->endian == BFD_ENDIAN_BIG			      ? bfd_getb16 (buffer)			      : bfd_getl16 (buffer))			     & 0xf81f) == 0xe800))		      baseaddr = memaddr - 2;		  }	      }	    val = (baseaddr & ~ ((1 << shift) - 1)) + immed;	    (*info->print_address_func) (val, info);	    info->target = val;	  }      }      break;    case 'a':      if (! use_extend)	extend = 0;      l = ((l & 0x1f) << 23) | ((l & 0x3e0) << 13) | (extend << 2);      (*info->print_address_func) (((memaddr + 4) & 0xf0000000) | l, info);      info->insn_type = dis_jsr;      info->target = ((memaddr + 4) & 0xf0000000) | l;      info->branch_delay_insns = 1;      break;    case 'l':    case 'L':      {	int need_comma, amask, smask;	need_comma = 0;	l = (l >> MIPS16OP_SH_IMM6) & MIPS16OP_MASK_IMM6;	amask = (l >> 3) & 7;	if (amask > 0 && amask < 5)	  {	    (*info->fprintf_func) (info->stream, "%s", mips32_reg_names[4]);	    if (amask > 1)	      (*info->fprintf_func) (info->stream, "-%s",				     mips32_reg_names[amask + 3]);	    need_comma = 1;	  }	smask = (l >> 1) & 3;	if (smask == 3)	  {	    (*info->fprintf_func) (info->stream, "%s??",				   need_comma ? "," : "");	    need_comma = 1;	  }	else if (smask > 0)	  {	    (*info->fprintf_func) (info->stream, "%s%s",				   need_comma ? "," : "",				   mips32_reg_names[16]);	    if (smask > 1)	      (*info->fprintf_func) (info->stream, "-%s",				     mips32_reg_names[smask + 15]);	    need_comma = 1;	  }	if (l & 1)	  {	    (*info->fprintf_func) (info->stream, "%s%s",				   need_comma ? "," : "",				   mips32_reg_names[31]);	    need_comma = 1;	  }	if (amask == 5 || amask == 6)	  {	    (*info->fprintf_func) (info->stream, "%s$f0",				   need_comma ? "," : "");	    if (amask == 6)	      (*info->fprintf_func) (info->stream, "-$f1");	  }      }      break;    default:      /* xgettext:c-format */      (*info->fprintf_func)	(info->stream,	 _("# internal disassembler error, unrecognised modifier (%c)"),	 type);      abort ();    }}

⌨️ 快捷键说明

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