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

📄 vax.c

📁 GUN开源阻止下的编译器GCC
💻 C
📖 第 1 页 / 共 2 页
字号:
	  break;	case DImode:	  c = 16;		/* 6 on VAX 9000, 28 on VAX 2 */	  break;	case SImode:	case HImode:	case QImode:	  c = 10;		/* 3-4 on VAX 9000, 20-28 on VAX 2 */	  break;	}      break;    case UDIV:      c = 17;      break;    case DIV:      if (mode == DImode)	c = 30;	/* highly variable */      else if (mode == DFmode)	/* divide takes 28 cycles if the result is not zero, 13 otherwise */	c = 24;      else	c = 11;			/* 25 on VAX 2 */      break;    case MOD:      c = 23;      break;    case UMOD:      c = 29;      break;    case FLOAT:      c = 6 + (mode == DFmode) + (GET_MODE (XEXP (x, 0)) != SImode);      /* 4 on VAX 9000 */      break;    case FIX:      c = 7;			/* 17 on VAX 2 */      break;    case ASHIFT:    case LSHIFTRT:    case ASHIFTRT:      if (mode == DImode)	c = 12;      else	c = 10;			/* 6 on VAX 9000 */      break;    case ROTATE:    case ROTATERT:      c = 6;			/* 5 on VAX 2, 4 on VAX 9000 */      if (GET_CODE (XEXP (x, 1)) == CONST_INT)	fmt = "e";	/* all constant rotate counts are short */      break;    case PLUS:      /* Check for small negative integer operand: subl2 can be used with	 a short positive constant instead.  */      if (GET_CODE (XEXP (x, 1)) == CONST_INT)	if ((unsigned)(INTVAL (XEXP (x, 1)) + 63) < 127)	  fmt = "e";    case MINUS:      c = (mode == DFmode) ? 13 : 8;	/* 6/8 on VAX 9000, 16/15 on VAX 2 */    case IOR:    case XOR:      c = 3;      break;    case AND:      /* AND is special because the first operand is complemented. */      c = 3;      if (GET_CODE (XEXP (x, 0)) == CONST_INT)	{	  if ((unsigned)~INTVAL (XEXP (x, 0)) > 63)	    c = 4;	  fmt = "e";	  i = 1;	}      break;    case NEG:      if (mode == DFmode)	return 9;      else if (mode == SFmode)	return 6;      else if (mode == DImode)	return 4;    case NOT:      return 2;    case ZERO_EXTRACT:    case SIGN_EXTRACT:      c = 15;      break;    case MEM:      if (mode == DImode || mode == DFmode)	c = 5;				/* 7 on VAX 2 */      else	c = 3;				/* 4 on VAX 2 */      x = XEXP (x, 0);      if (GET_CODE (x) == REG || GET_CODE (x) == POST_INC)	return c;      return c + vax_address_cost (x);    default:      c = 3;      break;    }  /* Now look inside the expression.  Operands which are not registers or     short constants add to the cost.     FMT and I may have been adjusted in the switch above for instructions     which require special handling */  while (*fmt++ == 'e')    {      register rtx op = XEXP (x, i++);      code = GET_CODE (op);      /* A NOT is likely to be found as the first operand of an AND	 (in which case the relevant cost is of the operand inside	 the not) and not likely to be found anywhere else.  */      if (code == NOT)	op = XEXP (op, 0), code = GET_CODE (op);      switch (code)	{	case CONST_INT:	  if ((unsigned)INTVAL (op) > 63 && GET_MODE (x) != QImode)	    c += 1;		/* 2 on VAX 2 */	  break;	case CONST:	case LABEL_REF:	case SYMBOL_REF:	  c += 1;		/* 2 on VAX 2 */	  break;	case CONST_DOUBLE:	  if (GET_MODE_CLASS (GET_MODE (op)) == MODE_FLOAT)	    {	      /* Registers are faster than floating point constants -- even		 those constants which can be encoded in a single byte.  */	      if (vax_float_literal (op))		c++;	      else		c += (GET_MODE (x) == DFmode) ? 3 : 2;	    }	  else	    {	      if (CONST_DOUBLE_HIGH (op) != 0		  || (unsigned)CONST_DOUBLE_LOW (op) > 63)		c += 2;	    }	  break;	case MEM:	  c += 1;		/* 2 on VAX 2 */	  if (GET_CODE (XEXP (op, 0)) != REG)	    c += vax_address_cost (XEXP (op, 0));	  break;	case REG:	case SUBREG:	  break;	default:	  c += 1;	  break;	}    }  return c;}/* Check a `double' value for validity for a particular machine mode.  */static char *float_strings[] ={   "1.70141173319264430e+38", /* 2^127 (2^24 - 1) / 2^24 */  "-1.70141173319264430e+38",   "2.93873587705571877e-39", /* 2^-128 */  "-2.93873587705571877e-39"};static REAL_VALUE_TYPE float_values[4];static int inited_float_values = 0;intcheck_float_value (mode, d, overflow)     enum machine_mode mode;     REAL_VALUE_TYPE *d;     int overflow;{  if (inited_float_values == 0)    {      int i;      for (i = 0; i < 4; i++)	{	  float_values[i] = REAL_VALUE_ATOF (float_strings[i], DFmode);	}      inited_float_values = 1;    }  if (overflow)    {      bcopy (&float_values[0], d, sizeof (REAL_VALUE_TYPE));      return 1;    }  if ((mode) == SFmode)    {      REAL_VALUE_TYPE r;      bcopy (d, &r, sizeof (REAL_VALUE_TYPE));      if (REAL_VALUES_LESS (float_values[0], r))	{	  bcopy (&float_values[0], d, sizeof (REAL_VALUE_TYPE));	  return 1;	}      else if (REAL_VALUES_LESS (r, float_values[1]))	{	  bcopy (&float_values[1], d, sizeof (REAL_VALUE_TYPE));	  return 1;	}      else if (REAL_VALUES_LESS (dconst0, r)		&& REAL_VALUES_LESS (r, float_values[2]))	{	  bcopy (&dconst0, d, sizeof (REAL_VALUE_TYPE));	  return 1;	}      else if (REAL_VALUES_LESS (r, dconst0)		&& REAL_VALUES_LESS (float_values[3], r))	{	  bcopy (&dconst0, d, sizeof (REAL_VALUE_TYPE));	  return 1;	}    }  return 0;}#ifdef VMS_TARGET/* Additional support code for VMS target. *//* Linked list of all externals that are to be emitted when optimizing   for the global pointer if they haven't been declared by the end of   the program with an appropriate .comm or initialization.  */staticstruct extern_list {  struct extern_list *next;	/* next external */  char *name;			/* name of the external */  int size;			/* external's actual size */  int in_const;			/* section type flag */} *extern_head = 0, *pending_head = 0;/* Check whether NAME is already on the external definition list.  If not,   add it to either that list or the pending definition list.  */voidvms_check_external (decl, name, pending)     tree decl;     char *name;     int pending;{  register struct extern_list *p, *p0;  for (p = extern_head; p; p = p->next)    if (!strcmp (p->name, name))      return;  for (p = pending_head, p0 = 0; p; p0 = p, p = p->next)    if (!strcmp (p->name, name))      {	if (pending)	  return;	/* Was pending, but has now been defined; move it to other list.  */	if (p == pending_head)	  pending_head = p->next;	else	  p0->next = p->next;	p->next = extern_head;	extern_head = p;	return;      }  /* Not previously seen; create a new list entry.  */  p = (struct extern_list *)permalloc ((long) sizeof (struct extern_list));  p->name = name;  if (pending)    {      /* Save the size and section type and link to `pending' list.  */      p->size = (DECL_SIZE (decl) == 0) ? 0 :	TREE_INT_CST_LOW (size_binop (CEIL_DIV_EXPR, DECL_SIZE (decl),				      size_int (BITS_PER_UNIT)));      p->in_const = (TREE_READONLY (decl) && ! TREE_THIS_VOLATILE (decl));      p->next = pending_head;      pending_head = p;    }  else    {      /* Size and section type don't matter; link to `declared' list.  */      p->size = p->in_const = 0;        /* arbitrary init */      p->next = extern_head;      extern_head = p;    }  return;}voidvms_flush_pending_externals (file)     FILE *file;{  register struct extern_list *p;  while (pending_head)    {      /* Move next pending declaration to the "done" list.  */      p = pending_head;      pending_head = p->next;      p->next = extern_head;      extern_head = p;      /* Now output the actual declaration.  */      if (p->in_const)	const_section ();      else	data_section ();      fputs (".comm ", file);      assemble_name (file, p->name);      fprintf (file, ",%d\n", p->size);    }}#endif /* VMS_TARGET */#ifdef VMS/* Additional support code for VMS host. */#ifdef QSORT_WORKAROUND  /*	Do not use VAXCRTL's qsort() due to a severe bug:  once you've	sorted something which has a size that's an exact multiple of 4	and is longword aligned, you cannot safely sort anything which	is either not a multiple of 4 in size or not longword aligned.	A static "move-by-longword" optimization flag inside qsort() is	never reset.  This is known of affect VMS V4.6 through VMS V5.5-1,	and was finally fixed in VMS V5.5-2.	In this work-around an insertion sort is used for simplicity.	The qsort code from glibc should probably be used instead.   */voidnot_qsort (array, count, size, compare)     void *array;     unsigned count, size;     int (*compare)();{  if (size == sizeof (short))    {      register int i;      register short *next, *prev;      short tmp, *base = array;      for (next = base, i = count - 1; i > 0; i--)	{	  prev = next++;	  if ((*compare)(next, prev) < 0)	    {	      tmp = *next;	      do  *(prev + 1) = *prev;		while (--prev >= base ? (*compare)(&tmp, prev) < 0 : 0);	      *(prev + 1) = tmp;	    }	}    }  else if (size == sizeof (long))    {      register int i;      register long *next, *prev;      long tmp, *base = array;      for (next = base, i = count - 1; i > 0; i--)	{	  prev = next++;	  if ((*compare)(next, prev) < 0)	    {	      tmp = *next;	      do  *(prev + 1) = *prev;		while (--prev >= base ? (*compare)(&tmp, prev) < 0 : 0);	      *(prev + 1) = tmp;	    }	}    }  else  /* arbitrary size */    {#ifdef USE_C_ALLOCA      extern void *alloca ();#endif      register int i;      register char *next, *prev, *tmp = alloca (size), *base = array;      for (next = base, i = count - 1; i > 0; i--)	{   /* count-1 forward iterations */	  prev = next,  next += size;		/* increment front pointer */	  if ((*compare)(next, prev) < 0)	    {	/* found element out of order; move others up then re-insert */	      memcpy (tmp, next, size);		/* save smaller element */	      do { memcpy (prev + size, prev, size); /* move larger elem. up */		   prev -= size;		/* decrement back pointer */		 } while (prev >= base ? (*compare)(tmp, prev) < 0 : 0);	      memcpy (prev + size, tmp, size);	/* restore small element */	    }	}#ifdef USE_C_ALLOCA      alloca (0);#endif    }  return;}#endif /* QSORT_WORKAROUND */#endif /* VMS */

⌨️ 快捷键说明

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