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

📄 arm-dis.c

📁 基于4个mips核的noc设计
💻 C
📖 第 1 页 / 共 2 页
字号:
				{				  long reg;				  				  reg = given >> bitstart;				  reg &= (2 << (bitend - bitstart)) - 1;				  				  func (stream, "%s", arm_regnames[reg]);				}				break;			      case 'd':				{				  long reg;				  				  reg = given >> bitstart;				  reg &= (2 << (bitend - bitstart)) - 1;				  				  func (stream, "%d", reg);				}				break;			      case 'x':				{				  long reg;				  				  reg = given >> bitstart;				  reg &= (2 << (bitend - bitstart)) - 1;				  				  func (stream, "0x%08x", reg);				  				  /* Some SWI instructions have special				     meanings.  */				  if ((given & 0x0fffffff) == 0x0FF00000)				    func (stream, "\t; IMB");				  else if ((given & 0x0fffffff) == 0x0FF00001)				    func (stream, "\t; IMBRange");				}				break;			      case 'X':				{				  long reg;				  				  reg = given >> bitstart;				  reg &= (2 << (bitend - bitstart)) - 1;				  				  func (stream, "%01x", reg & 0xf);				}				break;			      case 'f':				{				  long reg;				  				  reg = given >> bitstart;				  reg &= (2 << (bitend - bitstart)) - 1;				  				  if (reg > 7)				    func (stream, "#%s",					  arm_fp_const[reg & 7]);				  else				    func (stream, "f%d", reg);				}				break;			      default:				abort ();			      }			    break;			    			  case '`':			    c++;			    if ((given & (1 << bitstart)) == 0)			      func (stream, "%c", *c);			    break;			  case '\'':			    c++;			    if ((given & (1 << bitstart)) != 0)			      func (stream, "%c", *c);			    break;			  case '?':			    ++c;			    if ((given & (1 << bitstart)) != 0)			      func (stream, "%c", *c++);			    else			      func (stream, "%c", *++c);			    break;			  default:			    abort ();			  }			break;		      default:			abort ();		      }		    }		}	      else		func (stream, "%c", *c);	    }	  return 4;	}    }  abort ();}/* Print one instruction from PC on INFO->STREAM.   Return the size of the instruction. */static intprint_insn_thumb (pc, info, given)     bfd_vma                   pc;     struct disassemble_info * info;     long                      given;{  struct thumb_opcode * insn;  void *                stream = info->stream;  fprintf_ftype         func = info->fprintf_func;  for (insn = thumb_opcodes; insn->assembler; insn++)    {      if ((given & insn->mask) == insn->value)        {          char * c = insn->assembler;          /* Special processing for Thumb 2 instruction BL sequence:  */          if (!*c) /* Check for empty (not NULL) assembler string.  */            {	      info->bytes_per_chunk = 4;	      info->bytes_per_line  = 4;	      	      if ((given & 0x10000000) == 0)                 func (stream, "blx\t");	      else                func (stream, "bl\t");		              info->print_address_func (BDISP23 (given) * 2 + pc + 4, info);              return 4;            }          else            {	      info->bytes_per_chunk = 2;	      info->bytes_per_line  = 4;	  	                    given &= 0xffff;	                    for (; *c; c++)                {                  if (*c == '%')                    {                      int domaskpc = 0;                      int domasklr = 0;		                            switch (*++c)                        {                        case '%':                          func (stream, "%%");                          break;                        case 'S':                          {                            long reg;			                                reg = (given >> 3) & 0x7;                            if (given & (1 << 6))                              reg += 8;			                                func (stream, "%s", arm_regnames[reg]);                          }                          break;                        case 'D':                          {                            long reg;			                                reg = given & 0x7;                            if (given & (1 << 7))                             reg += 8;			                                func (stream, "%s", arm_regnames[reg]);                          }                          break;                        case 'T':                          func (stream, "%s",                                arm_conditional [(given >> 8) & 0xf]);                          break;                        case 'N':                          if (given & (1 << 8))                            domasklr = 1;                          /* Fall through.  */                        case 'O':                          if (*c == 'O' && (given & (1 << 8)))                            domaskpc = 1;                          /* Fall through.  */                        case 'M':                          {                            int started = 0;                            int reg;			                                func (stream, "{");			                                /* It would be nice if we could spot                               ranges, and generate the rS-rE format: */                            for (reg = 0; (reg < 8); reg++)                              if ((given & (1 << reg)) != 0)                                {                                  if (started)                                    func (stream, ", ");                                  started = 1;                                  func (stream, "%s", arm_regnames[reg]);                                }                            if (domasklr)                              {                                if (started)                                  func (stream, ", ");                                started = 1;                                func (stream, arm_regnames[14] /* "lr" */);                              }                            if (domaskpc)                              {                                if (started)                                  func (stream, ", ");                                func (stream, arm_regnames[15] /* "pc" */);                              }                            func (stream, "}");                          }                          break;                        case '0': case '1': case '2': case '3': case '4':                         case '5': case '6': case '7': case '8': case '9':                          {                            int bitstart = *c++ - '0';                            int bitend = 0;			                                while (*c >= '0' && *c <= '9')                              bitstart = (bitstart * 10) + *c++ - '0';                            switch (*c)                              {                              case '-':                                {                                  long reg;				                                    c++;                                  while (*c >= '0' && *c <= '9')                                    bitend = (bitend * 10) + *c++ - '0';                                  if (!bitend)                                    abort ();                                  reg = given >> bitstart;                                  reg &= (2 << (bitend - bitstart)) - 1;                                  switch (*c)                                    {                                    case 'r':                                      func (stream, "%s", arm_regnames[reg]);                                      break;                                    case 'd':                                      func (stream, "%d", reg);                                      break;                                    case 'H':                                      func (stream, "%d", reg << 1);                                      break;                                    case 'W':                                      func (stream, "%d", reg << 2);                                      break;                                    case 'a':				      /* PC-relative address -- the bottom two					 bits of the address are dropped					 before the calculation.  */                                      info->print_address_func					(((pc + 4) & ~3) + (reg << 2), info);                                      break;                                    case 'x':                                      func (stream, "0x%04x", reg);                                      break;                                    case 'I':                                      reg = ((reg ^ (1 << bitend)) - (1 << bitend));                                      func (stream, "%d", reg);                                      break;                                    case 'B':                                      reg = ((reg ^ (1 << bitend)) - (1 << bitend));                                      (*info->print_address_func)                                        (reg * 2 + pc + 4, info);                                      break;                                    default:                                      abort ();                                    }                                }                                break;                              case '\'':                                c++;                                if ((given & (1 << bitstart)) != 0)                                  func (stream, "%c", *c);                                break;                              case '?':                                ++c;                                if ((given & (1 << bitstart)) != 0)                                  func (stream, "%c", *c++);                                else                                  func (stream, "%c", *++c);                                break;                              default:                                 abort ();                              }                          }                          break;                        default:                          abort ();                        }                    }                  else                    func (stream, "%c", *c);                }             }          return 2;       }    }  /* No match.  */  abort ();}/* Parse an individual disassembler option.  */voidparse_arm_disassembler_option (option)     char * option;{  if (option == NULL)    return;        if (strneq (option, "reg-names-", 10))    {      int i;	      option += 10;      for (i = NUM_ARM_REGNAMES; i--;)	if (streq (option, regnames[i].name))	  {	    regname_selected = i;	    break;	  }            if (i < 0)	fprintf (stderr, _("Unrecognised register name set: %s\n"), option);    }  else if (streq (option, "force-thumb"))    force_thumb = 1;  else if (streq (option, "no-force-thumb"))    force_thumb = 0;  else    fprintf (stderr, _("Unrecognised disassembler option: %s\n"), option);    return;}/* Parse the string of disassembler options, spliting it at whitespaces.  */static voidparse_disassembler_options (options)     char * options;{  char * space;    if (options == NULL)    return;  do    {      space = strchr (options, ' ');      if (space)	{	  * space = '\0';	  parse_arm_disassembler_option (options);	  * space = ' ';	  options = space + 1;	}      else	parse_arm_disassembler_option (options);    }  while (space);}/* NOTE: There are no checks in these routines that   the relevant number of data bytes exist.  */static intprint_insn (pc, info, little)     bfd_vma pc;     struct disassemble_info * info;     boolean little;{  unsigned char      b[4];  long               given;  int                status;  int                is_thumb;  if (info->disassembler_options)    {      parse_disassembler_options (info->disassembler_options);            /* To avoid repeated parsing of these options, we remove them here.  */      info->disassembler_options = NULL;    }    is_thumb = force_thumb;    if (!is_thumb && info->symbols != NULL)    {      if (bfd_asymbol_flavour (*info->symbols) == bfd_target_coff_flavour)	{	  coff_symbol_type * cs;	  	  cs = coffsymbol (*info->symbols);	  is_thumb = (   cs->native->u.syment.n_sclass == C_THUMBEXT		      || cs->native->u.syment.n_sclass == C_THUMBSTAT		      || cs->native->u.syment.n_sclass == C_THUMBLABEL		      || cs->native->u.syment.n_sclass == C_THUMBEXTFUNC		      || cs->native->u.syment.n_sclass == C_THUMBSTATFUNC);	}      else if (bfd_asymbol_flavour (*info->symbols) == bfd_target_elf_flavour)	{	  elf_symbol_type *  es;	  unsigned int       type;	  	  es = *(elf_symbol_type **)(info->symbols);	  type = ELF_ST_TYPE (es->internal_elf_sym.st_info);	  	  is_thumb = (type == STT_ARM_TFUNC) || (type == STT_ARM_16BIT);	}    }    info->bytes_per_chunk = 4;  info->display_endian  = little ? BFD_ENDIAN_LITTLE : BFD_ENDIAN_BIG;  if (little)    {      status = info->read_memory_func (pc, (bfd_byte *) &b[0], 4, info);      if (status != 0 && is_thumb)	{	  info->bytes_per_chunk = 2;	  	  status = info->read_memory_func (pc, (bfd_byte *) b, 2, info);	  b[3] = b[2] = 0;	}            if (status != 0)	{	  info->memory_error_func (status, pc, info);	  return -1;	}            given = (b[0]) | (b[1] << 8) | (b[2] << 16) | (b[3] << 24);    }  else    {      status = info->read_memory_func	(pc & ~ 0x3, (bfd_byte *) &b[0], 4, info);      if (status != 0)	{	  info->memory_error_func (status, pc, info);	  return -1;	}            if (is_thumb)	{	  if (pc & 0x2)	    {	      given = (b[2] << 8) | b[3];	      	      status = info->read_memory_func		((pc + 4) & ~ 0x3, (bfd_byte *) b, 4, info);	      if (status != 0)		{		  info->memory_error_func (status, pc + 4, info);		  return -1;		}	      	      given |= (b[0] << 24) | (b[1] << 16);	    }	  else	    given = (b[0] << 8) | b[1] | (b[2] << 24) | (b[3] << 16);	}      else	given = (b[0] << 24) | (b[1] << 16) | (b[2] << 8) | (b[3]);    }    if (info->flags & INSN_HAS_RELOC)    /* If the instruction has a reloc associated with it, then       the offset field in the instruction will actually be the       addend for the reloc.  (We are using REL type relocs).       In such cases, we can ignore the pc when computing       addresses, since the addend is not currently pc-relative.  */    pc = 0;    if (is_thumb)    status = print_insn_thumb (pc, info, given);  else    status = print_insn_arm (pc, info, given);  return status;}intprint_insn_big_arm (pc, info)     bfd_vma pc;     struct disassemble_info * info;{  return print_insn (pc, info, false);}intprint_insn_little_arm (pc, info)     bfd_vma pc;     struct disassemble_info * info;{  return print_insn (pc, info, true);}voidprint_arm_disassembler_options (FILE * stream){  int i;  fprintf (stream, _("\n\The following ARM specific disassembler options are supported for use with\n\the -M switch:\n"));    for (i = NUM_ARM_REGNAMES; i--;)    fprintf (stream, "  reg-names-%s %*c%s\n",	     regnames[i].name,	     14 - strlen (regnames[i].name), ' ',	     regnames[i].description);  fprintf (stream, "  force-thumb              Assume all insns are Thumb insns\n");  fprintf (stream, "  no-force-thumb           Examine preceeding label to determine an insn's type\n\n");}

⌨️ 快捷键说明

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