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

📄 genattrtab.c

📁 早期freebsd实现
💻 C
📖 第 1 页 / 共 5 页
字号:
/* Add an entry to the hash table for STRING with hash code HASHCODE.  */static voidattr_hash_add_string (hashcode, str)     int hashcode;     char *str;{  register struct attr_hash *h;  h = (struct attr_hash *) obstack_alloc (hash_obstack,					  sizeof (struct attr_hash));  h->hashcode = -hashcode;  h->u.str = str;  h->next = attr_hash_table[hashcode % RTL_HASH_SIZE];  attr_hash_table[hashcode % RTL_HASH_SIZE] = h;}/* Generate an RTL expression, but avoid duplicates.   Set the RTX_INTEGRATED_P flag for these permanent objects.   In some cases we cannot uniquify; then we return an ordinary   impermanent rtx with RTX_INTEGRATED_P clear.   Args are like gen_rtx, but without the mode:   rtx attr_rtx (code, [element1, ..., elementn])  *//*VARARGS1*/static rtxattr_rtx (va_alist)     va_dcl{  va_list p;  enum rtx_code code;  register int i;		/* Array indices...			*/  register char *fmt;		/* Current rtx's format...		*/  register rtx rt_val;		/* RTX to return to caller...		*/  int hashcode;  register struct attr_hash *h;  struct obstack *old_obstack = rtl_obstack;  va_start (p);  code = va_arg (p, enum rtx_code);  /* For each of several cases, search the hash table for an existing entry.     Use that entry if one is found; otherwise create a new RTL and add it     to the table.  */  if (GET_RTX_CLASS (code) == '1')    {      rtx arg0 = va_arg (p, rtx);      /* A permanent object cannot point to impermanent ones.  */      if (! RTX_INTEGRATED_P (arg0))	{	  rt_val = rtx_alloc (code);	  XEXP (rt_val, 0) = arg0;	  va_end (p);	  return rt_val;	}      hashcode = ((HOST_WIDE_INT) code + RTL_HASH (arg0));      for (h = attr_hash_table[hashcode % RTL_HASH_SIZE]; h; h = h->next)	if (h->hashcode == hashcode	    && GET_CODE (h->u.rtl) == code	    && XEXP (h->u.rtl, 0) == arg0)	  goto found;      if (h == 0)	{	  rtl_obstack = hash_obstack;	  rt_val = rtx_alloc (code);	  XEXP (rt_val, 0) = arg0;	}    }  else if (GET_RTX_CLASS (code) == 'c'	   || GET_RTX_CLASS (code) == '2'	   || GET_RTX_CLASS (code) == '<')    {      rtx arg0 = va_arg (p, rtx);      rtx arg1 = va_arg (p, rtx);      /* A permanent object cannot point to impermanent ones.  */      if (! RTX_INTEGRATED_P (arg0) || ! RTX_INTEGRATED_P (arg1))	{	  rt_val = rtx_alloc (code);	  XEXP (rt_val, 0) = arg0;	  XEXP (rt_val, 1) = arg1;	  va_end (p);	  return rt_val;	}      hashcode = ((HOST_WIDE_INT) code + RTL_HASH (arg0) + RTL_HASH (arg1));      for (h = attr_hash_table[hashcode % RTL_HASH_SIZE]; h; h = h->next)	if (h->hashcode == hashcode	    && GET_CODE (h->u.rtl) == code	    && XEXP (h->u.rtl, 0) == arg0	    && XEXP (h->u.rtl, 1) == arg1)	  goto found;      if (h == 0)	{	  rtl_obstack = hash_obstack;	  rt_val = rtx_alloc (code);	  XEXP (rt_val, 0) = arg0;	  XEXP (rt_val, 1) = arg1;	}    }  else if (GET_RTX_LENGTH (code) == 1	   && GET_RTX_FORMAT (code)[0] == 's')    {      char * arg0 = va_arg (p, char *);      if (code == SYMBOL_REF)	arg0 = attr_string (arg0, strlen (arg0));      hashcode = ((HOST_WIDE_INT) code + RTL_HASH (arg0));      for (h = attr_hash_table[hashcode % RTL_HASH_SIZE]; h; h = h->next)	if (h->hashcode == hashcode	    && GET_CODE (h->u.rtl) == code	    && XSTR (h->u.rtl, 0) == arg0)	  goto found;      if (h == 0)	{	  rtl_obstack = hash_obstack;	  rt_val = rtx_alloc (code);	  XSTR (rt_val, 0) = arg0;	}    }  else if (GET_RTX_LENGTH (code) == 2	   && GET_RTX_FORMAT (code)[0] == 's'	   && GET_RTX_FORMAT (code)[1] == 's')    {      char *arg0 = va_arg (p, char *);      char *arg1 = va_arg (p, char *);      hashcode = ((HOST_WIDE_INT) code + RTL_HASH (arg0) + RTL_HASH (arg1));      for (h = attr_hash_table[hashcode % RTL_HASH_SIZE]; h; h = h->next)	if (h->hashcode == hashcode	    && GET_CODE (h->u.rtl) == code	    && XSTR (h->u.rtl, 0) == arg0	    && XSTR (h->u.rtl, 1) == arg1)	  goto found;      if (h == 0)	{	  rtl_obstack = hash_obstack;	  rt_val = rtx_alloc (code);	  XSTR (rt_val, 0) = arg0;	  XSTR (rt_val, 1) = arg1;	}    }  else if (code == CONST_INT)    {      HOST_WIDE_INT arg0 = va_arg (p, HOST_WIDE_INT);      if (arg0 == 0)	return false_rtx;      if (arg0 == 1)	return true_rtx;      goto nohash;    }  else    {    nohash:      rt_val = rtx_alloc (code);	/* Allocate the storage space.  */            fmt = GET_RTX_FORMAT (code);	/* Find the right format...  */      for (i = 0; i < GET_RTX_LENGTH (code); i++)	{	  switch (*fmt++)	    {	    case '0':		/* Unused field.  */	      break;	    case 'i':		/* An integer?  */	      XINT (rt_val, i) = va_arg (p, int);	      break;	    case 'w':		/* A wide integer? */	      XWINT (rt_val, i) = va_arg (p, HOST_WIDE_INT);	      break;	    case 's':		/* A string?  */	      XSTR (rt_val, i) = va_arg (p, char *);	      break;	    case 'e':		/* An expression?  */	    case 'u':		/* An insn?  Same except when printing.  */	      XEXP (rt_val, i) = va_arg (p, rtx);	      break;	    case 'E':		/* An RTX vector?  */	      XVEC (rt_val, i) = va_arg (p, rtvec);	      break;	    default:	      abort();	    }	}      va_end (p);      return rt_val;    }  rtl_obstack = old_obstack;  va_end (p);  attr_hash_add_rtx (hashcode, rt_val);  RTX_INTEGRATED_P (rt_val) = 1;  return rt_val; found:  va_end (p);  return h->u.rtl;}/* Create a new string printed with the printf line arguments into a space   of at most LEN bytes:   rtx attr_printf (len, format, [arg1, ..., argn])  */#ifdef HAVE_VPRINTF/*VARARGS2*/static char *attr_printf (va_alist)     va_dcl{  va_list p;  register int len;  register char *fmt;  register char *str;  /* Print the string into a temporary location.  */  va_start (p);  len = va_arg (p, int);  str = (char *) alloca (len);  fmt = va_arg (p, char *);  vsprintf (str, fmt, p);  va_end (p);  return attr_string (str, strlen (str));}#else /* not HAVE_VPRINTF */static char *attr_printf (len, fmt, arg1, arg2, arg3)     int len;     char *fmt;     char *arg1, *arg2, *arg3; /* also int */{  register char *str;  /* Print the string into a temporary location.  */  str = (char *) alloca (len);  sprintf (str, fmt, arg1, arg2, arg3);  return attr_string (str, strlen (str));}#endif /* not HAVE_VPRINTF */rtxattr_eq (name, value)     char *name, *value;{  return attr_rtx (EQ_ATTR, attr_string (name, strlen (name)),		   attr_string (value, strlen (value)));}char *attr_numeral (n)     int n;{  return XSTR (make_numeric_value (n), 0);}/* Return a permanent (possibly shared) copy of a string STR (not assumed   to be null terminated) with LEN bytes.  */static char *attr_string (str, len)     char *str;     int len;{  register struct attr_hash *h;  int hashcode;  int i;  register char *new_str;  /* Compute the hash code.  */  hashcode = (len + 1) * 613 + (unsigned)str[0];  for (i = 1; i <= len; i += 2)    hashcode = ((hashcode * 613) + (unsigned)str[i]);  if (hashcode < 0)    hashcode = -hashcode;  /* Search the table for the string.  */  for (h = attr_hash_table[hashcode % RTL_HASH_SIZE]; h; h = h->next)    if (h->hashcode == -hashcode && h->u.str[0] == str[0]	&& !strncmp (h->u.str, str, len))      return h->u.str;			/* <-- return if found.  */  /* Not found; create a permanent copy and add it to the hash table.  */  new_str = (char *) obstack_alloc (hash_obstack, len + 1);  bcopy (str, new_str, len);  new_str[len] = '\0';  attr_hash_add_string (hashcode, new_str);  return new_str;			/* Return the new string.  */}/* Check two rtx's for equality of contents,   taking advantage of the fact that if both are hashed   then they can't be equal unless they are the same object.  */intattr_equal_p (x, y)     rtx x, y;{  return (x == y || (! (RTX_INTEGRATED_P (x) && RTX_INTEGRATED_P (y))		     && rtx_equal_p (x, y)));}/* Copy an attribute value expression,   descending to all depths, but not copying any   permanent hashed subexpressions.  */rtxattr_copy_rtx (orig)     register rtx orig;{  register rtx copy;  register int i, j;  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)

⌨️ 快捷键说明

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