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

📄 genattrtab.c

📁 gcc库的原代码,对编程有很大帮助.
💻 C
📖 第 1 页 / 共 5 页
字号:
  register RTX_CODE code;  register char *format_ptr;  /* No need to copy a permanent object.  */  if (RTX_INTEGRATED_P (orig))    return orig;  code = GET_CODE (orig);  switch (code)    {    case REG:    case QUEUED:    case CONST_INT:    case CONST_DOUBLE:    case SYMBOL_REF:    case CODE_LABEL:    case PC:    case CC0:      return orig;    }  copy = rtx_alloc (code);  PUT_MODE (copy, GET_MODE (orig));  copy->in_struct = orig->in_struct;  copy->volatil = orig->volatil;  copy->unchanging = orig->unchanging;  copy->integrated = orig->integrated;    format_ptr = GET_RTX_FORMAT (GET_CODE (copy));  for (i = 0; i < GET_RTX_LENGTH (GET_CODE (copy)); i++)    {      switch (*format_ptr++)	{	case 'e':	  XEXP (copy, i) = XEXP (orig, i);	  if (XEXP (orig, i) != NULL)	    XEXP (copy, i) = attr_copy_rtx (XEXP (orig, i));	  break;	case 'E':	case 'V':	  XVEC (copy, i) = XVEC (orig, i);	  if (XVEC (orig, i) != NULL)	    {	      XVEC (copy, i) = rtvec_alloc (XVECLEN (orig, i));	      for (j = 0; j < XVECLEN (copy, i); j++)		XVECEXP (copy, i, j) = attr_copy_rtx (XVECEXP (orig, i, j));	    }	  break;	case 'n':	case 'i':	  XINT (copy, i) = XINT (orig, i);	  break;	case 'w':	  XWINT (copy, i) = XWINT (orig, i);	  break;	case 's':	case 'S':	  XSTR (copy, i) = XSTR (orig, i);	  break;	default:	  abort ();	}    }  return copy;}/* Given a test expression for an attribute, ensure it is validly formed.   IS_CONST indicates whether the expression is constant for each compiler   run (a constant expression may not test any particular insn).   Convert (eq_attr "att" "a1,a2") to (ior (eq_attr ... ) (eq_attrq ..))   and (eq_attr "att" "!a1") to (not (eq_attr "att" "a1")).  Do the latter   test first so that (eq_attr "att" "!a1,a2,a3") works as expected.   Update the string address in EQ_ATTR expression to be the same used   in the attribute (or `alternative_name') to speed up subsequent   `find_attr' calls and eliminate most `strcmp' calls.   Return the new expression, if any.   */static rtxcheck_attr_test (exp, is_const)     rtx exp;     int is_const;{  struct attr_desc *attr;  struct attr_value *av;  char *name_ptr, *p;  rtx orexp, newexp;  switch (GET_CODE (exp))    {    case EQ_ATTR:      /* Handle negation test.  */      if (XSTR (exp, 1)[0] == '!')	return check_attr_test (attr_rtx (NOT,					  attr_eq (XSTR (exp, 0),						   &XSTR (exp, 1)[1])),				is_const);      else if (n_comma_elts (XSTR (exp, 1)) == 1)	{	  attr = find_attr (XSTR (exp, 0), 0);	  if (attr == NULL)	    {	      if (! strcmp (XSTR (exp, 0), "alternative"))		{		  XSTR (exp, 0) = alternative_name;		  /* This can't be simplified any further.  */		  RTX_UNCHANGING_P (exp) = 1;		  return exp;		}	      else		fatal ("Unknown attribute `%s' in EQ_ATTR", XEXP (exp, 0));	    }	  if (is_const && ! attr->is_const)	    fatal ("Constant expression uses insn attribute `%s' in EQ_ATTR",		   XEXP (exp, 0));	  /* Copy this just to make it permanent,	     so expressions using it can be permanent too.  */	  exp = attr_eq (XSTR (exp, 0), XSTR (exp, 1));	  /* It shouldn't be possible to simplify the value given to a	     constant attribute, so don't expand this until it's time to	     write the test expression.  */	       	  if (attr->is_const)	    RTX_UNCHANGING_P (exp) = 1;	  if (attr->is_numeric)	    {	      for (p = XSTR (exp, 1); *p; p++)		if (*p < '0' || *p > '9')		   fatal ("Attribute `%s' takes only numeric values", 			  XEXP (exp, 0));	    }	  else	    {	      for (av = attr->first_value; av; av = av->next)		if (GET_CODE (av->value) == CONST_STRING		    && ! strcmp (XSTR (exp, 1), XSTR (av->value, 0)))		  break;	      if (av == NULL)		fatal ("Unknown value `%s' for `%s' attribute",		       XEXP (exp, 1), XEXP (exp, 0));	    }	}      else	{	  /* Make an IOR tree of the possible values.  */	  orexp = false_rtx;	  name_ptr = XSTR (exp, 1);	  while ((p = next_comma_elt (&name_ptr)) != NULL)	    {	      newexp = attr_eq (XSTR (exp, 0), p);	      orexp = insert_right_side (IOR, orexp, newexp, -2, -2);	    }	  return check_attr_test (orexp, is_const);	}      break;    case ATTR_FLAG:      break;    case CONST_INT:      /* Either TRUE or FALSE.  */      if (XWINT (exp, 0))	return true_rtx;      else	return false_rtx;    case IOR:    case AND:      XEXP (exp, 0) = check_attr_test (XEXP (exp, 0), is_const);      XEXP (exp, 1) = check_attr_test (XEXP (exp, 1), is_const);      break;    case NOT:      XEXP (exp, 0) = check_attr_test (XEXP (exp, 0), is_const);      break;    case MATCH_OPERAND:      if (is_const)	fatal ("RTL operator \"%s\" not valid in constant attribute test",	       GET_RTX_NAME (MATCH_OPERAND));      /* These cases can't be simplified.  */      RTX_UNCHANGING_P (exp) = 1;      break;    case LE:  case LT:  case GT:  case GE:    case LEU: case LTU: case GTU: case GEU:    case NE:  case EQ:      if (GET_CODE (XEXP (exp, 0)) == SYMBOL_REF	  && GET_CODE (XEXP (exp, 1)) == SYMBOL_REF)	exp = attr_rtx (GET_CODE (exp),			attr_rtx (SYMBOL_REF, XSTR (XEXP (exp, 0), 0)),			attr_rtx (SYMBOL_REF, XSTR (XEXP (exp, 1), 0)));      /* These cases can't be simplified.  */      RTX_UNCHANGING_P (exp) = 1;      break;    case SYMBOL_REF:      if (is_const)	{	  /* These cases are valid for constant attributes, but can't be	     simplified.  */	  exp = attr_rtx (SYMBOL_REF, XSTR (exp, 0));	  RTX_UNCHANGING_P (exp) = 1;	  break;	}    default:      fatal ("RTL operator \"%s\" not valid in attribute test",	     GET_RTX_NAME (GET_CODE (exp)));    }  return exp;}/* Given an expression, ensure that it is validly formed and that all named   attribute values are valid for the given attribute.  Issue a fatal error   if not.  If no attribute is specified, assume a numeric attribute.   Return a perhaps modified replacement expression for the value.  */static rtxcheck_attr_value (exp, attr)     rtx exp;     struct attr_desc *attr;{  struct attr_value *av;  char *p;  int i;  switch (GET_CODE (exp))    {    case CONST_INT:      if (attr && ! attr->is_numeric)	fatal ("CONST_INT not valid for non-numeric `%s' attribute",	       attr->name);      if (INTVAL (exp) < 0)	fatal ("Negative numeric value specified for `%s' attribute",	       attr->name);      break;    case CONST_STRING:      if (! strcmp (XSTR (exp, 0), "*"))	break;      if (attr == 0 || attr->is_numeric)	{	  p = XSTR (exp, 0);	  if (attr && attr->negative_ok && *p == '-')	    p++;	  for (; *p; p++)	    if (*p > '9' || *p < '0')	      fatal ("Non-numeric value for numeric `%s' attribute",		     attr ? attr->name : "internal");	  break;	}      for (av = attr->first_value; av; av = av->next)	if (GET_CODE (av->value) == CONST_STRING	    && ! strcmp (XSTR (av->value, 0), XSTR (exp, 0)))	  break;      if (av == NULL)	fatal ("Unknown value `%s' for `%s' attribute",	       XSTR (exp, 0), attr ? attr->name : "internal");      break;    case IF_THEN_ELSE:      XEXP (exp, 0) = check_attr_test (XEXP (exp, 0),				       attr ? attr->is_const : 0);      XEXP (exp, 1) = check_attr_value (XEXP (exp, 1), attr);      XEXP (exp, 2) = check_attr_value (XEXP (exp, 2), attr);      break;    case COND:      if (XVECLEN (exp, 0) % 2 != 0)	fatal ("First operand of COND must have even length");      for (i = 0; i < XVECLEN (exp, 0); i += 2)	{	  XVECEXP (exp, 0, i) = check_attr_test (XVECEXP (exp, 0, i),						 attr ? attr->is_const : 0);	  XVECEXP (exp, 0, i + 1)	    = check_attr_value (XVECEXP (exp, 0, i + 1), attr);	}      XEXP (exp, 1) = check_attr_value (XEXP (exp, 1), attr);      break;    case SYMBOL_REF:      if (attr && attr->is_const)	/* A constant SYMBOL_REF is valid as a constant attribute test and	   is expanded later by make_canonical into a COND.  */	return attr_rtx (SYMBOL_REF, XSTR (exp, 0));      /* Otherwise, fall through... */    default:      fatal ("Invalid operation `%s' for attribute value",	     GET_RTX_NAME (GET_CODE (exp)));    }  return exp;}/* Given an SET_ATTR_ALTERNATIVE expression, convert to the canonical SET.   It becomes a COND with each test being (eq_attr "alternative "n") */static rtxconvert_set_attr_alternative (exp, num_alt, insn_code, insn_index)     rtx exp;     int num_alt;     int insn_code, insn_index;{  rtx condexp;  int i;  if (XVECLEN (exp, 1) != num_alt)    fatal ("Bad number of entries in SET_ATTR_ALTERNATIVE for insn %d",	   insn_index);  /* Make a COND with all tests but the last.  Select the last value via the     default.  */  condexp = rtx_alloc (COND);  XVEC (condexp, 0) = rtvec_alloc ((num_alt - 1) * 2);  for (i = 0; i < num_alt - 1; i++)    {      char *p;      p = attr_numeral (i);      XVECEXP (condexp, 0, 2 * i) = attr_eq (alternative_name, p);#if 0      /* Sharing this EQ_ATTR rtl causes trouble.  */         XVECEXP (condexp, 0, 2 * i) = rtx_alloc (EQ_ATTR);      XSTR (XVECEXP (condexp, 0, 2 * i), 0) = alternative_name;      XSTR (XVECEXP (condexp, 0, 2 * i), 1) = p;#endif      XVECEXP (condexp, 0, 2 * i + 1) = XVECEXP (exp, 1, i);    }  XEXP (condexp, 1) = XVECEXP (exp, 1, i);  return attr_rtx (SET, attr_rtx (ATTR, XSTR (exp, 0)), condexp);}/* Given a SET_ATTR, convert to the appropriate SET.  If a comma-separated   list of values is given, convert to SET_ATTR_ALTERNATIVE first.  */static rtxconvert_set_attr (exp, num_alt, insn_code, insn_index)     rtx exp;     int num_alt;     int insn_code, insn_index;{  rtx newexp;  char *name_ptr;  char *p;  int n;  /* See how many alternative specified.  */  n = n_comma_elts (XSTR (exp, 1));  if (n == 1)    return attr_rtx (SET,		     attr_rtx (ATTR, XSTR (exp, 0)),		     attr_rtx (CONST_STRING, XSTR (exp, 1)));  newexp = rtx_alloc (SET_ATTR_ALTERNATIVE);  XSTR (newexp, 0) = XSTR (exp, 0);  XVEC (newexp, 1) = rtvec_alloc (n);  /* Process each comma-separated name.  */  name_ptr = XSTR (exp, 1);  n = 0;  while ((p = next_comma_elt (&name_ptr)) != NULL)    XVECEXP (newexp, 1, n++) = attr_rtx (CONST_STRING, p);  return convert_set_attr_alternative (newexp, num_alt, insn_code, insn_index);}/* Scan all definitions, checking for validity.  Also, convert any SET_ATTR   and SET_ATTR_ALTERNATIVE expressions to the corresponding SET   expressions. */static voidcheck_defs (){  struct insn_def *id;  struct attr_desc *attr;  int i;  rtx value;  for (id = defs; id; id = id->next)    {      if (XVEC (id->def, id->vec_idx) == NULL)	continue;      for (i = 0; i < XVECLEN (id->def, id->vec_idx); i++)	{	  value = XVECEXP (id->def, id->vec_idx, i);	  switch (GET_CODE (value))	    {	    case SET:	      if (GET_CODE (XEXP (value, 0)) != ATTR)		fatal ("Bad attribute set in pattern %d", id->insn_index);	      break;

⌨️ 快捷键说明

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