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

📄 cris-dis.c.svn-base

📁 我们自己开发的一个OSEK操作系统!不知道可不可以?
💻 SVN-BASE
📖 第 1 页 / 共 5 页
字号:
/* Return the number of bits in the argument.  */static intnumber_of_bits (unsigned int val){  int bits;  for (bits = 0; val != 0; val &= val - 1)    bits++;  return bits;}/* Get an entry in the opcode-table.  */static const struct cris_opcode *get_opcode_entry (unsigned int insn,		  unsigned int prefix_insn,		  struct cris_disasm_data *disdata){  /* For non-prefixed insns, we keep a table of pointers, indexed by the     insn code.  Each entry is initialized when found to be NULL.  */  static const struct cris_opcode **opc_table = NULL;  const struct cris_opcode *max_matchedp = NULL;  const struct cris_opcode **prefix_opc_table = NULL;  /* We hold a table for each prefix that need to be handled differently.  */  static const struct cris_opcode **dip_prefixes = NULL;  static const struct cris_opcode **bdapq_m1_prefixes = NULL;  static const struct cris_opcode **bdapq_m2_prefixes = NULL;  static const struct cris_opcode **bdapq_m4_prefixes = NULL;  static const struct cris_opcode **rest_prefixes = NULL;  /* Allocate and clear the opcode-table.  */  if (opc_table == NULL)    {      opc_table = malloc (65536 * sizeof (opc_table[0]));      if (opc_table == NULL)	return NULL;      memset (opc_table, 0, 65536 * sizeof (const struct cris_opcode *));      dip_prefixes	= malloc (65536 * sizeof (const struct cris_opcode **));      if (dip_prefixes == NULL)	return NULL;      memset (dip_prefixes, 0, 65536 * sizeof (dip_prefixes[0]));      bdapq_m1_prefixes	= malloc (65536 * sizeof (const struct cris_opcode **));      if (bdapq_m1_prefixes == NULL)	return NULL;      memset (bdapq_m1_prefixes, 0, 65536 * sizeof (bdapq_m1_prefixes[0]));      bdapq_m2_prefixes	= malloc (65536 * sizeof (const struct cris_opcode **));      if (bdapq_m2_prefixes == NULL)	return NULL;      memset (bdapq_m2_prefixes, 0, 65536 * sizeof (bdapq_m2_prefixes[0]));      bdapq_m4_prefixes	= malloc (65536 * sizeof (const struct cris_opcode **));      if (bdapq_m4_prefixes == NULL)	return NULL;      memset (bdapq_m4_prefixes, 0, 65536 * sizeof (bdapq_m4_prefixes[0]));      rest_prefixes	= malloc (65536 * sizeof (const struct cris_opcode **));      if (rest_prefixes == NULL)	return NULL;      memset (rest_prefixes, 0, 65536 * sizeof (rest_prefixes[0]));    }  /* Get the right table if this is a prefix.     This code is connected to cris_constraints in that it knows what     prefixes play a role in recognition of patterns; the necessary     state is reflected by which table is used.  If constraints     involving match or non-match of prefix insns are changed, then this     probably needs changing too.  */  if (prefix_insn != NO_CRIS_PREFIX)    {      const struct cris_opcode *popcodep	= (opc_table[prefix_insn] != NULL	   ? opc_table[prefix_insn]	   : get_opcode_entry (prefix_insn, NO_CRIS_PREFIX, disdata));      if (popcodep == NULL)	return NULL;      if (popcodep->match == BDAP_QUICK_OPCODE)	{	  /* Since some offsets are recognized with "push" macros, we	     have to have different tables for them.  */	  int offset = (prefix_insn & 255);	  if (offset > 127)	    offset -= 256;	  switch (offset)	    {	    case -4:	      prefix_opc_table = bdapq_m4_prefixes;	      break;	    case -2:	      prefix_opc_table = bdapq_m2_prefixes;	      break;	    case -1:	      prefix_opc_table = bdapq_m1_prefixes;	      break;	    default:	      prefix_opc_table = rest_prefixes;	      break;	    }	}      else if (popcodep->match == DIP_OPCODE)	/* We don't allow postincrement when the prefix is DIP, so use a	   different table for DIP.  */	prefix_opc_table = dip_prefixes;      else	prefix_opc_table = rest_prefixes;    }  if (prefix_insn != NO_CRIS_PREFIX      && prefix_opc_table[insn] != NULL)    max_matchedp = prefix_opc_table[insn];  else if (prefix_insn == NO_CRIS_PREFIX && opc_table[insn] != NULL)    max_matchedp = opc_table[insn];  else    {      const struct cris_opcode *opcodep;      int max_level_of_match = -1;      for (opcodep = cris_opcodes;	   opcodep->name != NULL;	   opcodep++)	{	  int level_of_match;	  if (disdata->distype == cris_dis_v32)	    {	      switch (opcodep->applicable_version)		{		case cris_ver_version_all:		  break;		case cris_ver_v0_3:		case cris_ver_v0_10:		case cris_ver_v3_10:		case cris_ver_sim_v0_10:		case cris_ver_v8_10:		case cris_ver_v10:		case cris_ver_warning:		  continue;		case cris_ver_v3p:		case cris_ver_v8p:		case cris_ver_v10p:		case cris_ver_v32p:		  break;		case cris_ver_v8:		  abort ();		default:		  abort ();		}	    }	  else	    {	      switch (opcodep->applicable_version)		{		case cris_ver_version_all:		case cris_ver_v0_3:		case cris_ver_v3p:		case cris_ver_v0_10:		case cris_ver_v8p:		case cris_ver_v8_10:		case cris_ver_v10:		case cris_ver_sim_v0_10:		case cris_ver_v10p:		case cris_ver_warning:		  break;		case cris_ver_v32p:		  continue;		case cris_ver_v8:		  abort ();		default:		  abort ();		}	    }	  /* We give a double lead for bits matching the template in	     cris_opcodes.  Not even, because then "move p8,r10" would	     be given 2 bits lead over "clear.d r10".  When there's a	     tie, the first entry in the table wins.  This is	     deliberate, to avoid a more complicated recognition	     formula.  */	  if ((opcodep->match & insn) == opcodep->match	      && (opcodep->lose & insn) == 0	      && ((level_of_match		   = cris_constraint (opcodep->args,				      insn,				      prefix_insn,				      disdata))		  >= 0)	      && ((level_of_match		   += 2 * number_of_bits (opcodep->match					  | opcodep->lose))			  > max_level_of_match))		    {		      max_matchedp = opcodep;		      max_level_of_match = level_of_match;		      /* If there was a full match, never mind looking			 further.  */		      if (level_of_match >= 2 * 16)			break;		    }		}      /* Fill in the new entry.	 If there are changes to the opcode-table involving prefixes, and	 disassembly then does not work correctly, try removing the	 else-clause below that fills in the prefix-table.  If that	 helps, you need to change the prefix_opc_table setting above, or	 something related.  */      if (prefix_insn == NO_CRIS_PREFIX)	opc_table[insn] = max_matchedp;      else	prefix_opc_table[insn] = max_matchedp;    }  return max_matchedp;}/* Return -1 if the constraints of a bitwise-matched instruction say   that there is no match.  Otherwise return a nonnegative number   indicating the confidence in the match (higher is better).  */static intcris_constraint (const char *cs,		 unsigned int insn,		 unsigned int prefix_insn,		 struct cris_disasm_data *disdata){  int retval = 0;  int tmp;  int prefix_ok = 0;  const char *s;  for (s = cs; *s; s++)    switch (*s)      {      case '!':	/* Do not recognize "pop" if there's a prefix and then only for           v0..v10.  */	if (prefix_insn != NO_CRIS_PREFIX	    || disdata->distype != cris_dis_v0_v10)	  return -1;	break;      case 'U':	/* Not recognized at disassembly.  */	return -1;      case 'M':	/* Size modifier for "clear", i.e. special register 0, 4 or 8.	   Check that it is one of them.  Only special register 12 could	   be mismatched, but checking for matches is more logical than	   checking for mismatches when there are only a few cases.  */	tmp = ((insn >> 12) & 0xf);	if (tmp != 0 && tmp != 4 && tmp != 8)	  return -1;	break;      case 'm':	if ((insn & 0x30) == 0x30)	  return -1;	break;      case 'S':	/* A prefix operand without side-effect.  */	if (prefix_insn != NO_CRIS_PREFIX && (insn & 0x400) == 0)	  {	    prefix_ok = 1;	    break;	  }	else	  return -1;      case 's':      case 'y':      case 'Y':	/* If this is a prefixed insn with postincrement (side-effect),	   the prefix must not be DIP.  */	if (prefix_insn != NO_CRIS_PREFIX)	  {	    if (insn & 0x400)	      {		const struct cris_opcode *prefix_opcodep		  = get_opcode_entry (prefix_insn, NO_CRIS_PREFIX, disdata);		if (prefix_opcodep->match == DIP_OPCODE)		  return -1;	      }	    prefix_ok = 1;	  }	break;      case 'B':	/* If we don't fall through, then the prefix is ok.  */	prefix_ok = 1;	/* A "push" prefix.  Check for valid "push" size.	   In case of special register, it may be != 4.  */	if (prefix_insn != NO_CRIS_PREFIX)	  {	    /* Match the prefix insn to BDAPQ.  */	    const struct cris_opcode *prefix_opcodep	      = get_opcode_entry (prefix_insn, NO_CRIS_PREFIX, disdata);	    if (prefix_opcodep->match == BDAP_QUICK_OPCODE)	      {		int pushsize = (prefix_insn & 255);		if (pushsize > 127)		  pushsize -= 256;		if (s[1] == 'P')		  {		    unsigned int spec_reg = (insn >> 12) & 15;		    const struct cris_spec_reg *sregp		      = spec_reg_info (spec_reg, disdata->distype);		    /* For a special-register, the "prefix size" must		       match the size of the register.  */		    if (sregp && sregp->reg_size == (unsigned int) -pushsize)		      break;		  }		else if (s[1] == 'R')		  {		    if ((insn & 0x30) == 0x20 && pushsize == -4)		      break;		  }		/* FIXME:  Should abort here; next constraint letter		   *must* be 'P' or 'R'.  */	      }	  }	return -1;      case 'D':	retval = (((insn >> 12) & 15) == (insn & 15));	if (!retval)	  return -1;	else	  retval += 4;	break;      case 'P':	{	  const struct cris_spec_reg *sregp	    = spec_reg_info ((insn >> 12) & 15, disdata->distype);	  /* Since we match four bits, we will give a value of 4-1 = 3	     in a match.  If there is a corresponding exact match of a	     special register in another pattern, it will get a value of	     4, which will be higher.  This should be correct in that an	     exact pattern would match better than a general pattern.	     Note that there is a reason for not returning zero; the	     pattern for "clear" is partly  matched in the bit-pattern	     (the two lower bits must be zero), while the bit-pattern	     for a move from a special register is matched in the	     register constraint.  */	  if (sregp != NULL)	    {	      retval += 3;	      break;	    }	  else	    return -1;	}      }  if (prefix_insn != NO_CRIS_PREFIX && ! prefix_ok)    return -1;  return retval;}/* Format number as hex with a leading "0x" into outbuffer.  */static char *format_hex (unsigned long number,	    char *outbuffer,	    struct cris_disasm_data *disdata){  /* Truncate negative numbers on >32-bit hosts.  */  number &= 0xffffffff;  sprintf (outbuffer, "0x%lx", number);  /* Save this value for the "case" support.  */  if (TRACE_CASE)    last_immediate = number;  return outbuffer + strlen (outbuffer);}/* Format number as decimal into outbuffer.  Parameter signedp says   whether the number should be formatted as signed (!= 0) or   unsigned (== 0).  */static char *format_dec (long number, char *outbuffer, int signedp){  last_immediate = number;  sprintf (outbuffer, signedp ? "%ld" : "%lu", number);  return outbuffer + strlen (outbuffer);}/* Format the name of the general register regno into outbuffer.  */static char *format_reg (struct cris_disasm_data *disdata,	    int regno,	    char *outbuffer_start,	    bfd_boolean with_reg_prefix){  char *outbuffer = outbuffer_start;  if (with_reg_prefix)    *outbuffer++ = REGISTER_PREFIX_CHAR;  switch (regno)    {    case 15:      /* For v32, there is no context in which we output PC.  */      if (disdata->distype == cris_dis_v32)	strcpy (outbuffer, "acr");      else

⌨️ 快捷键说明

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