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

📄 genattrtab.c

📁 早期freebsd实现
💻 C
📖 第 1 页 / 共 5 页
字号:
	{	  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);	    }	  return check_attr_test (orexp, is_const);	}      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 ("Illegal 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;	    case SET_ATTR_ALTERNATIVE:	      value = convert_set_attr_alternative (value,						    id->num_alternatives,						    id->insn_code,						    id->insn_index);	      break;	    case SET_ATTR:	      value = convert_set_attr (value, id->num_alternatives,					id->insn_code, id->insn_index);	      break;	    default:	      fatal ("Invalid attribute code `%s' for pattern %d",		     GET_RTX_NAME (GET_CODE (value)), id->insn_index);	    }	  if ((attr = find_attr (XSTR (XEXP (value, 0), 0), 0)) == NULL)	    fatal ("Unknown attribute `%s' for pattern number %d",		   XSTR (XEXP (value, 0), 0), id->insn_index);	  XVECEXP (id->def, id->vec_idx, i) = value;	  XEXP (value, 1) = check_attr_value (XEXP (value, 1), attr);	}    }}/* Given a constant SYMBOL_REF expression, convert to a COND that   explicitly tests each enumerated value.  */static rtxconvert_const_symbol_ref (exp, attr)     rtx exp;     struct attr_desc *attr;{  rtx condexp;  struct attr_value *av;  int i;  int num_alt = 0;  for (av = attr->first_value; av; av = av->next)    num_alt++;  /* Make a COND with all tests but the last, and in the original order.     Select the last value via the default.  Note that the attr values     are constructed in reverse order.  */  condexp = rtx_alloc (COND);  XVEC (condexp, 0) = rtvec_alloc ((num_alt - 1) * 2);  av = attr->first_value;  XEXP (condexp, 1) = av->value;  for (i = num_alt - 2; av = av->next, i >= 0; i--)    {      char *p, *string;      rtx value;      string = p = (char *) oballoc (2				     + strlen (attr->name)				     + strlen (XSTR (av->value, 0)));      strcpy (p, attr->name);      strcat (p, "_");      strcat (p, XSTR (av->value, 0));      for (; *p != '\0'; p++)	if (*p >= 'a' && *p <= 'z')	  *p -= 'a' - 'A';      value = attr_rtx (SYMBOL_REF, string);      RTX_UNCHANGING_P (value) = 1;            XVECEXP (condexp, 0, 2 * i) = attr_rtx (EQ, exp, value);      XVECEXP (condexp, 0, 2 * i + 1) = av->value;    }  return condexp;}/* Given a valid expression for an attribute value, remove any IF_THEN_ELSE   expressions by converting them into a COND.  This removes cases from this   program.  Also, replace an attribute value of "*" with the default attribute   value.  */static rtxmake_canonical (attr, exp)     struct attr_desc *attr;     rtx exp;{  int i;  rtx newexp;  switch (GET_CODE (exp))    {    case CONST_INT:      exp = make_numeric_value (INTVAL (exp));      break;    case CONST_STRING:      if (! strcmp (XSTR (exp, 0), "*"))	{	  if (attr == 0 || attr->default_val == 0)	    fatal ("(attr_value \"*\") used in invalid context.");	  exp = attr->default_val->value;	}      break;    case SYMBOL_REF:      if (!attr->is_const || RTX_UNCHANGING_P (exp))	break;      /* The SYMBOL_REF is constant for a given run, so mark it as unchanging.	 This makes the COND something that won't be considered an arbitrary	 expression by walk_attr_value.  */      RTX_UNCHANGING_P (exp) = 1;      exp = convert_const_symbol_ref (exp, attr);      RTX_UNCHANGING_P (exp) = 1;      exp = check_attr_value (exp, attr);      /* Goto COND case since this is now a COND.  Note that while the         new expression is rescanned, all symbol_ref notes are mared as	 unchanging.  */      goto cond;    case IF_THEN_ELSE:      newexp = rtx_alloc (COND);      XVEC (newexp, 0) = rtvec_alloc (2);      XVECEXP (newexp, 0, 0) = XEXP (exp, 0);      XVECEXP (newexp, 0, 1) = XEXP (exp, 1);      XEXP (newexp, 1) = XEXP (exp, 2);

⌨️ 快捷键说明

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