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

📄 tc-cris.c

📁 基于4个mips核的noc设计
💻 C
📖 第 1 页 / 共 5 页
字号:
	  *size_bitsp = 0;	  break;	case 'W':	case 'w':	  *size_bitsp = 1;	  break;	case 'D':	case 'd':	  *size_bitsp = 2;	  break;	default:	  return 0;	}      /* Consume the size letter.  */      (*cPP)++;      return 1;    }}/* Get a B or W size modifier from the string pointed out by *cPP,   which must point to a '.' in front of the modifier.	On successful   return, *cPP is advanced to the character following the size   modifier, and is undefined otherwise.   cPP		Pointer to pointer to string starting		with the size modifier.   size_bitsp	Pointer to variable to contain the size bits on		successful return.   Return 1 iff a correct size modifier is found, else 0.  */static intget_bw_size_modifier (cPP, size_bitsp)     char **cPP;     int *size_bitsp;{  if (**cPP != '.')    return 0;  else    {      /* Consume the '.'.  */      (*cPP)++;      switch (**cPP)	{	case 'B':	case 'b':	  *size_bitsp = 0;	  break;	case 'W':	case 'w':	  *size_bitsp = 1;	  break;	default:	  return 0;	}      /* Consume the size letter.  */      (*cPP)++;      return 1;    }}/* Get a general register from the string pointed out by *cPP.  The   variable *cPP is advanced to the character following the general   register name on a successful return, and has its initial position   otherwise.   cPP	    Pointer to pointer to string, beginning with a general	    register name.   regnop   Pointer to int containing the register number.   Return 1 iff a correct general register designator is found,	    else 0.  */static intget_gen_reg (cPP, regnop)     char **cPP;     int *regnop;{  char *oldp;  oldp = *cPP;  /* Handle a sometimes-mandatory dollar sign as register prefix.  */  if (**cPP == REGISTER_PREFIX_CHAR)    (*cPP)++;  else if (demand_register_prefix)    return 0;  switch (**cPP)    {    case 'P':    case 'p':      /* "P" as in "PC"?  Consume the "P".  */      (*cPP)++;      if ((**cPP == 'C' || **cPP == 'c')	  && ! isalnum ((*cPP)[1]))	{	  /* It's "PC": consume the "c" and we're done.  */	  (*cPP)++;	  *regnop = REG_PC;	  return 1;	}      break;    case 'R':    case 'r':      /* Hopefully r[0-9] or r1[0-5].  Consume 'R' or 'r'.  */      (*cPP)++;      if (isdigit (**cPP))	{	  /* It's r[0-9].  Consume and check the next digit.  */	  *regnop = **cPP - '0';	  (*cPP)++;	  if (! isalnum (**cPP))	    {	      /* No more digits, we're done.  */	      return 1;	    }	  else	    {	      /* One more digit.  Consume and add.  */	      *regnop = *regnop * 10 + (**cPP - '0');	      /* We need to check for a valid register number; Rn,		 0 <= n <= MAX_REG.  */	      if (*regnop <= MAX_REG)		{		  /* Consume second digit.  */		  (*cPP)++;		  return 1;		}	    }	}      break;    case 'S':    case 's':      /* "S" as in "SP"?  Consume the "S".  */      (*cPP)++;      if (**cPP == 'P' || **cPP == 'p')	{	  /* It's "SP": consume the "p" and we're done.  */	  (*cPP)++;	  *regnop = REG_SP;	  return 1;	}      break;    default:      /* Just here to silence compilation warnings.  */      ;    }  /* We get here if we fail.  Restore the pointer.  */  *cPP = oldp;  return 0;}/* Get a special register from the string pointed out by *cPP. The   variable *cPP is advanced to the character following the special   register name if one is found, and retains its original position   otherwise.   cPP	    Pointer to pointer to string starting with a special register	    name.   sregpp   Pointer to Pointer to struct spec_reg, where a pointer to the	    register description will be stored.   Return 1 iff a correct special register name is found.  */static intget_spec_reg (cPP, sregpp)     char **cPP;     const struct cris_spec_reg **sregpp;{  char *s1;  const char *s2;  char *name_begin = *cPP;  const struct cris_spec_reg *sregp;  /* Handle a sometimes-mandatory dollar sign as register prefix.  */  if (*name_begin == REGISTER_PREFIX_CHAR)    name_begin++;  else if (demand_register_prefix)    return 0;  /* Loop over all special registers.  */  for (sregp = cris_spec_regs; sregp->name != NULL; sregp++)    {      /* Start over from beginning of the supposed name.  */      s1 = name_begin;      s2 = sregp->name;      while (*s2 != '\0'	     && (isupper (*s1) ? tolower (*s1) == *s2 : *s1 == *s2))	{	  s1++;	  s2++;	}      /* For a match, we must have consumed the name in the table, and we	 must be outside what could be part of a name.	Assume here that a	 test for alphanumerics is sufficient for a name test.  */      if (*s2 == 0 && ! isalnum (*s1))	{	  /* We have a match.  Update the pointer and be done.  */	  *cPP = s1;	  *sregpp = sregp;	  return 1;	}    }  /* If we got here, we did not find any name.  */  return 0;}/* Get an unprefixed or side-effect-prefix operand from the string pointed   out by *cPP.  The pointer *cPP is advanced to the character following   the indirect operand if we have success, else it contains an undefined   value.   cPP		 Pointer to pointer to string beginning with the first		 character of the supposed operand.   prefixp	 Pointer to structure containing an optional instruction		 prefix.   is_autoincp	 Pointer to int indicating the indirect or autoincrement		 bits.   src_regnop	 Pointer to int containing the source register number in		 the instruction.   imm_foundp	 Pointer to an int indicating if an immediate expression		 is found.   imm_exprP	 Pointer to a structure containing an immediate		 expression, if success and if *imm_foundp is nonzero.   Return 1 iff a correct indirect operand is found.  */static intget_autoinc_prefix_or_indir_op (cPP, prefixp, is_autoincp, src_regnop,				imm_foundp, imm_exprP)     char **cPP;     struct cris_prefix *prefixp;     int *is_autoincp;     int *src_regnop;     int *imm_foundp;     expressionS *imm_exprP;{  /* Assume there was no immediate mode expression.  */  *imm_foundp = 0;  if (**cPP == '[')    {      /* So this operand is one of:	 Indirect: [rN]	 Autoincrement: [rN+]	 Indexed with assign: [rN=rM+rO.S]	 Offset with assign: [rN=rM+I], [rN=rM+[rO].s], [rN=rM+[rO+].s]	 Either way, consume the '['.  */      (*cPP)++;      /* Get the rN register.  */      if (! get_gen_reg (cPP, src_regnop))	/* If there was no register, then this cannot match.  */	return 0;      else	{	  /* We got the register, now check the next character.  */	  switch (**cPP)	    {	    case ']':	      /* Indirect mode.  We're done here.  */	      prefixp->kind = PREFIX_NONE;	      *is_autoincp = 0;	      break;	    case '+':	      /* This must be an auto-increment mode, if there's a		 match.  */	      prefixp->kind = PREFIX_NONE;	      *is_autoincp = 1;	      /* We consume this character and break out to check the		 closing ']'.  */	      (*cPP)++;	      break;	    case '=':	      /* This must be indexed with assign, or offset with assign		 to match.  */	      (*cPP)++;	      /* Either way, the next thing must be a register.  */	      if (! get_gen_reg (cPP, &prefixp->base_reg_number))		/* No register, no match.  */		return 0;	      else		{		  /* We've consumed "[rN=rM", so we must be looking at		     "+rO.s]" or "+I]", or "-I]", or "+[rO].s]" or		     "+[rO+].s]".  */		  if (**cPP == '+')		    {		      int index_reg_number;		      (*cPP)++;		      if (**cPP == '[')			{			  int size_bits;			  /* This must be [rx=ry+[rz].s] or			     [rx=ry+[rz+].s] or no match.  We must be			     looking at rz after consuming the '['.  */			  (*cPP)++;			  if (!get_gen_reg (cPP, &index_reg_number))			    return 0;			  prefixp->kind = PREFIX_BDAP;			  prefixp->opcode			    = (BDAP_INDIR_OPCODE			       + (prefixp->base_reg_number << 12)			       + index_reg_number);			  if (**cPP == '+')			    {			      /* We've seen "[rx=ry+[rz+" here, so now we				 know that there must be "].s]" left to				 check.  */			      (*cPP)++;			      prefixp->opcode |= AUTOINCR_BIT << 8;			    }			  /* If it wasn't autoincrement, we don't need to			     add anything.  */			  /* Check the next-to-last ']'.  */			  if (**cPP != ']')			    return 0;			  (*cPP)++;			  /* Check the ".s" modifier.  */			  if (! get_bwd_size_modifier (cPP, &size_bits))			    return 0;			  prefixp->opcode |= size_bits << 4;			  /* Now we got [rx=ry+[rz+].s or [rx=ry+[rz].s.			     We break out to check the final ']'.  */			  break;			}		      /* It wasn't an indirection.  Check if it's a			 register.  */		      else if (get_gen_reg (cPP, &index_reg_number))			{			  int size_bits;			  /* Indexed with assign mode: "[rN+rM.S]".  */			  prefixp->kind = PREFIX_BIAP;			  prefixp->opcode			    = (BIAP_OPCODE + (index_reg_number << 12)			       + prefixp->base_reg_number /* << 0 */);			  if (! get_bwd_size_modifier (cPP, &size_bits))			    /* Size missing, this isn't a match.  */			    return 0;			  else			    {			      /* Size found, break out to check the				 final ']'.  */			      prefixp->opcode |= size_bits << 4;			      break;			    }			}		      /* Not a register.  Then this must be "[rN+I]".  */		      else if (cris_get_expression (cPP, &prefixp->expr))			{			  /* We've got offset with assign mode.  Fill			     in the blanks and break out to match the			     final ']'.  */			  prefixp->kind = PREFIX_BDAP_IMM;			  break;			}		      else			/* Neither register nor expression found, so			   this can't be a match.  */			return 0;		    }		  /* Not "[rN+" but perhaps "[rN-"?  */		  else if (**cPP == '-')		    {		      /* We must have an offset with assign mode.  */		      if (! cris_get_expression (cPP, &prefixp->expr))			/* No expression, no match.  */			return 0;		      else			{			  /* We've got offset with assign mode.  Fill			     in the blanks and break out to match the			     final ']'.  */			  prefixp->kind = PREFIX_BDAP_IMM;			  break;			}		    }		  else		    /* Neither '+' nor '-' after "[rN=rM".  Lose.  */		    return 0;		}	    default:	      /* Neither ']' nor '+' nor '=' after "[rN".  Lose.  */	      return 0;	    }	}      /* When we get here, we have a match and will just check the closing	 ']'.  We can still fail though.  */      if (**cPP != ']')	return 0;      else	{	  /* Don't forget to consume the final ']'.	     Then return in glory.  */	  (*cPP)++;	  return 1;	}    }  /* No indirection.  Perhaps a constant?  */  else if (cris_get_expression (cPP, imm_exprP))    {      /* Expression found, this is immediate mode.  */      prefixp->kind = PREFIX_NONE;      *is_autoincp = 1;      *src_regnop = REG_PC;      *imm_foundp = 1;      return 1;    }  /* No luck today.  */  return 0;}/* This function gets an indirect operand in a three-address operand   combination from the string pointed out by *cPP.  The pointer *cPP is   advanced to the character following the indirect operand on success, or   has an unspecified value on failure.   cPP	     Pointer to pointer to string begining	     with the operand   prefixp   Pointer to structure containing an	     instruction prefix   Returns 1 iff a correct indirect operand is found.  */static intget_3op_or_dip_prefix_op (cPP, prefixp)     char **cPP;     struct cris_prefix *prefixp;{  int reg_number;  if (**cPP != '[')

⌨️ 快捷键说明

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