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

📄 cris-dis.c.svn-base

📁 我们自己开发的一个OSEK操作系统!不知道可不可以?
💻 SVN-BASE
📖 第 1 页 / 共 5 页
字号:
	strcpy (outbuffer, "pc");      break;    case 14:      strcpy (outbuffer, "sp");      break;    default:      sprintf (outbuffer, "r%d", regno);      break;    }  return outbuffer_start + strlen (outbuffer_start);}/* Format the name of a support register into outbuffer.  */static char *format_sup_reg (unsigned int regno,		char *outbuffer_start,		bfd_boolean with_reg_prefix){  char *outbuffer = outbuffer_start;  int i;  if (with_reg_prefix)    *outbuffer++ = REGISTER_PREFIX_CHAR;  for (i = 0; cris_support_regs[i].name != NULL; i++)    if (cris_support_regs[i].number == regno)      {	sprintf (outbuffer, "%s", cris_support_regs[i].name);	return outbuffer_start + strlen (outbuffer_start);      }  /* There's supposed to be register names covering all numbers, though     some may be generic names.  */  sprintf (outbuffer, "format_sup_reg-BUG");  return outbuffer_start + strlen (outbuffer_start);}/* Return the length of an instruction.  */static unsignedbytes_to_skip (unsigned int insn,	       const struct cris_opcode *matchedp,	       enum cris_disass_family distype,	       const struct cris_opcode *prefix_matchedp){  /* Each insn is a word plus "immediate" operands.  */  unsigned to_skip = 2;  const char *template = matchedp->args;  const char *s;  for (s = template; *s; s++)    if ((*s == 's' || *s == 'N' || *s == 'Y')	&& (insn & 0x400) && (insn & 15) == 15	&& prefix_matchedp == NULL)      {	/* Immediate via [pc+], so we have to check the size of the	   operand.  */	int mode_size = 1 << ((insn >> 4) & (*template == 'z' ? 1 : 3));	if (matchedp->imm_oprnd_size == SIZE_FIX_32)	  to_skip += 4;	else if (matchedp->imm_oprnd_size == SIZE_SPEC_REG)	  {	    const struct cris_spec_reg *sregp	      = spec_reg_info ((insn >> 12) & 15, distype);	    /* FIXME: Improve error handling; should have been caught	       earlier.  */	    if (sregp == NULL)	      return 2;	    /* PC is incremented by two, not one, for a byte.  Except on	       CRISv32, where constants are always DWORD-size for	       special registers.  */	    to_skip +=	      distype == cris_dis_v32 ? 4 : (sregp->reg_size + 1) & ~1;	  }	else	  to_skip += (mode_size + 1) & ~1;      }    else if (*s == 'n')      to_skip += 4;    else if (*s == 'b')      to_skip += 2;  return to_skip;}/* Print condition code flags.  */static char *print_flags (struct cris_disasm_data *disdata, unsigned int insn, char *cp){  /* Use the v8 (Etrax 100) flag definitions for disassembly.     The differences with v0 (Etrax 1..4) vs. Svinto are:      v0 'd' <=> v8 'm'      v0 'e' <=> v8 'b'.     FIXME: Emit v0..v3 flag names somehow.  */  static const char v8_fnames[] = "cvznxibm";  static const char v32_fnames[] = "cvznxiup";  const char *fnames    = disdata->distype == cris_dis_v32 ? v32_fnames : v8_fnames;  unsigned char flagbits = (((insn >> 8) & 0xf0) | (insn & 15));  int i;  for (i = 0; i < 8; i++)    if (flagbits & (1 << i))      *cp++ = fnames[i];  return cp;}/* Print out an insn with its operands, and update the info->insn_type   fields.  The prefix_opcodep and the rest hold a prefix insn that is   supposed to be output as an address mode.  */static voidprint_with_operands (const struct cris_opcode *opcodep,		     unsigned int insn,		     unsigned char *buffer,		     bfd_vma addr,		     disassemble_info *info,		     /* If a prefix insn was before this insn (and is supposed			to be output as an address), here is a description of			it.  */		     const struct cris_opcode *prefix_opcodep,		     unsigned int prefix_insn,		     unsigned char *prefix_buffer,		     bfd_boolean with_reg_prefix){  /* Get a buffer of somewhat reasonable size where we store     intermediate parts of the insn.  */  char temp[sizeof (".d [$r13=$r12-2147483648],$r10") * 2];  char *tp = temp;  static const char mode_char[] = "bwd?";  const char *s;  const char *cs;  struct cris_disasm_data *disdata    = (struct cris_disasm_data *) info->private_data;  /* Print out the name first thing we do.  */  (*info->fprintf_func) (info->stream, "%s", opcodep->name);  cs = opcodep->args;  s = cs;  /* Ignore any prefix indicator.  */  if (*s == 'p')    s++;  if (*s == 'm' || *s == 'M' || *s == 'z')    {      *tp++ = '.';      /* Get the size-letter.  */      *tp++ = *s == 'M'	? (insn & 0x8000 ? 'd'	   : insn & 0x4000 ? 'w' : 'b')	: mode_char[(insn >> 4) & (*s == 'z' ? 1 : 3)];      /* Ignore the size and the space character that follows.  */      s += 2;    }  /* Add a space if this isn't a long-branch, because for those will add     the condition part of the name later.  */  if (opcodep->match != (BRANCH_PC_LOW + BRANCH_INCR_HIGH * 256))    *tp++ = ' ';  /* Fill in the insn-type if deducible from the name (and there's no     better way).  */  if (opcodep->name[0] == 'j')    {      if (CONST_STRNEQ (opcodep->name, "jsr"))	/* It's "jsr" or "jsrc".  */	info->insn_type = dis_jsr;      else	/* Any other jump-type insn is considered a branch.  */	info->insn_type = dis_branch;    }  /* We might know some more fields right now.  */  info->branch_delay_insns = opcodep->delayed;  /* Handle operands.  */  for (; *s; s++)    {    switch (*s)      {      case 'T':	tp = format_sup_reg ((insn >> 12) & 15, tp, with_reg_prefix);	break;      case 'A':	if (with_reg_prefix)	  *tp++ = REGISTER_PREFIX_CHAR;	*tp++ = 'a';	*tp++ = 'c';	*tp++ = 'r';	break;      case '[':      case ']':      case ',':	*tp++ = *s;	break;      case '!':	/* Ignore at this point; used at earlier stages to avoid	   recognition if there's a prefix at something that in other	   ways looks like a "pop".  */	break;      case 'd':	/* Ignore.  This is an optional ".d " on the large one of	   relaxable insns.  */	break;      case 'B':	/* This was the prefix that made this a "push".  We've already	   handled it by recognizing it, so signal that the prefix is	   handled by setting it to NULL.  */	prefix_opcodep = NULL;	break;      case 'D':      case 'r':	tp = format_reg (disdata, insn & 15, tp, with_reg_prefix);	break;      case 'R':	tp = format_reg (disdata, (insn >> 12) & 15, tp, with_reg_prefix);	break;      case 'n':	{	  /* Like N but pc-relative to the start of the insn.  */	  unsigned long number	    = (buffer[2] + buffer[3] * 256 + buffer[4] * 65536	       + buffer[5] * 0x1000000 + addr);	  /* Finish off and output previous formatted bytes.  */	  *tp = 0;	  if (temp[0])	    (*info->fprintf_func) (info->stream, "%s", temp);	  tp = temp;	  (*info->print_address_func) ((bfd_vma) number, info);	}	break;      case 'u':	{	  /* Like n but the offset is bits <3:0> in the instruction.  */	  unsigned long number = (buffer[0] & 0xf) * 2 + addr;	  /* Finish off and output previous formatted bytes.  */	  *tp = 0;	  if (temp[0])	    (*info->fprintf_func) (info->stream, "%s", temp);	  tp = temp;	  (*info->print_address_func) ((bfd_vma) number, info);	}	break;      case 'N':      case 'y':      case 'Y':      case 'S':      case 's':	/* Any "normal" memory operand.  */	if ((insn & 0x400) && (insn & 15) == 15 && prefix_opcodep == NULL)	  {	    /* We're looking at [pc+], i.e. we need to output an immediate	       number, where the size can depend on different things.  */	    long number;	    int signedp	      = ((*cs == 'z' && (insn & 0x20))		 || opcodep->match == BDAP_QUICK_OPCODE);	    int nbytes;	    if (opcodep->imm_oprnd_size == SIZE_FIX_32)	      nbytes = 4;	    else if (opcodep->imm_oprnd_size == SIZE_SPEC_REG)	      {		const struct cris_spec_reg *sregp		  = spec_reg_info ((insn >> 12) & 15, disdata->distype);		/* A NULL return should have been as a non-match earlier,		   so catch it as an internal error in the error-case		   below.  */		if (sregp == NULL)		  /* Whatever non-valid size.  */		  nbytes = 42;		else		  /* PC is always incremented by a multiple of two.		     For CRISv32, immediates are always 4 bytes for		     special registers.  */		  nbytes = disdata->distype == cris_dis_v32		    ? 4 : (sregp->reg_size + 1) & ~1;	      }	    else	      {		int mode_size = 1 << ((insn >> 4) & (*cs == 'z' ? 1 : 3));		if (mode_size == 1)		  nbytes = 2;		else		  nbytes = mode_size;	      }	    switch (nbytes)	      {	      case 1:		number = buffer[2];		if (signedp && number > 127)		  number -= 256;		break;	      case 2:		number = buffer[2] + buffer[3] * 256;		if (signedp && number > 32767)		  number -= 65536;		break;	      case 4:		number		  = buffer[2] + buffer[3] * 256 + buffer[4] * 65536		  + buffer[5] * 0x1000000;		break;	      default:		strcpy (tp, "bug");		tp += 3;		number = 42;	      }	    if ((*cs == 'z' && (insn & 0x20))		|| (opcodep->match == BDAP_QUICK_OPCODE		    && (nbytes <= 2 || buffer[1 + nbytes] == 0)))	      tp = format_dec (number, tp, signedp);	    else	      {		unsigned int highbyte = (number >> 24) & 0xff;		/* Either output this as an address or as a number.  If it's		   a dword with the same high-byte as the address of the		   insn, assume it's an address, and also if it's a non-zero		   non-0xff high-byte.  If this is a jsr or a jump, then		   it's definitely an address.  */		if (nbytes == 4		    && (highbyte == ((addr >> 24) & 0xff)			|| (highbyte != 0 && highbyte != 0xff)			|| info->insn_type == dis_branch			|| info->insn_type == dis_jsr))		  {		    /* Finish off and output previous formatted bytes.  */		    *tp = 0;		    tp = temp;		    if (temp[0])		      (*info->fprintf_func) (info->stream, "%s", temp);		    (*info->print_address_func) ((bfd_vma) number, info);		    info->target = number;		  }		else		  tp = format_hex (number, tp, disdata);	      }	  }	else	  {	    /* Not an immediate number.  Then this is a (possibly	       prefixed) memory operand.  */	    if (info->insn_type != dis_nonbranch)	      {		int mode_size		  = 1 << ((insn >> 4)			  & (opcodep->args[0] == 'z' ? 1 : 3));		int size;		info->insn_type = dis_dref;		info->flags |= CRIS_DIS_FLAG_MEMREF;		if (opcodep->imm_oprnd_size == SIZE_FIX_32)		  size = 4;		else if (opcodep->imm_oprnd_size == SIZE_SPEC_REG)		  {		    const struct cris_spec_reg *sregp		      = spec_reg_info ((insn >> 12) & 15, disdata->distype);		    /* FIXME: Improve error handling; should have been caught		       earlier.  */		    if (sregp == NULL)		      size = 4;		    else		      size = sregp->reg_size;		  }		else		  size = mode_size;		info->data_size = size;	      }	    *tp++ = '[';	    if (prefix_opcodep		/* We don't match dip with a postincremented field		   as a side-effect address mode.  */		&& ((insn & 0x400) == 0		    || prefix_opcodep->match != DIP_OPCODE))	      {		if (insn & 0x400)		  {		    tp = format_reg (disdata, insn & 15, tp, with_reg_prefix);		    *tp++ = '=';		  }		/* We mainly ignore the prefix format string when the		   address-mode syntax is output.  */		switch (prefix_opcodep->match)		  {		  case DIP_OPCODE:		    /* It's [r], [r+] or [pc+].  */		    if ((prefix_insn & 0x400) && (prefix_insn & 15) == 15)		      {			/* It's [pc+].  This cannot possibly be anything			   but an address.  */			unsigned long number			  = prefix_buffer[2] + prefix_buffer[3] * 256			  + prefix_buffer[4] * 65536			  + prefix_buffer[5] * 0x1000000;			info->target = (bfd_vma) number;			/* Finish off and output previous formatted			   data.  */			*tp = 0;			tp = temp;			if (temp[0])			  (*info->fprintf_func) (info->stream, "%s", temp);			(*info->print_address_func) ((bfd_vma) number, info);		      }		    else		      {			/* For a memref in an address, we use target2.			   In this case, targ

⌨️ 快捷键说明

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