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

📄 cse.c

📁 这是完整的gcc源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
  const_arg2 = 0;  /* Try folding our operands.     Then see which ones have constant values known.  */  fmt = GET_RTX_FORMAT (code);  for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)    if (fmt[i] == 'e')      {	register rtx tem = fold_rtx (XEXP (x, i), copyflag);	/* If an operand has changed under folding, and we are not supposed to	   alter the original structure, copy X if we haven't yet done so.  */	if (! copied && tem != XEXP (x, i))	  {	    int j;	    rtx new = rtx_alloc (code);	    PUT_MODE (new, GET_MODE (x));	    for (j = 0; j < GET_RTX_LENGTH (code); j++)	      XINT (new, j) = XINT (x, j);	    x = new;	    copied = 1;	  }	/* Install the possibly altered folded operand.  */	XEXP (x, i) = tem;	/* For the first three operands, see if the operand	   is constant or equivalent to a constant.  */	if (i < 3)	  {	    rtx const_arg = equiv_constant (tem);	    switch (i)	      {	      case 0:		const_arg0 = const_arg;		break;	      case 1:		const_arg1 = const_arg;		break;	      case 2:		const_arg2 = const_arg;		break;	      }	  }      }    else if (fmt[i] == 'E')      /* Don't try to fold inside of a vector of expressions.	 Doing nothing is is harmless.  */      ;  /* If a commutative operation, place a constant integer as the second     operand unless the first operand is also a constant integer.  Otherwise,     place any constant second unless the first operand is also a constant.  */  switch (code)    {    case PLUS:    case MULT:    case UMULT:    case AND:    case IOR:    case XOR:    case NE:    case EQ:      if (const_arg0 && const_arg0 == XEXP (x, 0)	  && (! (const_arg1 && const_arg1 == XEXP (x, 1))	      || (GET_CODE (const_arg0) == CONST_INT		  && GET_CODE (const_arg1) != CONST_INT)))	{	  register rtx tem;	  if (! copied)	    copied = 1, x = copy_rtx (x);	  tem = XEXP (x, 0); XEXP (x, 0) = XEXP (x, 1); XEXP (x, 1) = tem;	  tem = const_arg0; const_arg0 = const_arg1; const_arg1 = tem;	}      break;    }  /* Now decode the kind of rtx X is     and then return X (if nothing can be done)     or return a folded rtx     or store a value in VAL and drop through     (to return a CONST_INT for the integer VAL).  */  if (GET_RTX_LENGTH (code) == 1)    {      if (const_arg0 == 0)	return x;      if (GET_CODE (const_arg0) == CONST_INT)	{	  register int arg0 = INTVAL (const_arg0);	  switch (GET_CODE (x))	    {	    case NOT:	      val = ~ arg0;	      break;	    case NEG:	      val = - arg0;	      break;	    case TRUNCATE:	      val = arg0;	      break;	    case ZERO_EXTEND:	      {		enum machine_mode mode = GET_MODE (XEXP (x, 0));		if (mode == VOIDmode)		  return x;		if (GET_MODE_BITSIZE (mode) < HOST_BITS_PER_INT)		  val = arg0 & ~((-1) << GET_MODE_BITSIZE (mode));		else		  return x;		break;	      }	    case SIGN_EXTEND:	      {		enum machine_mode mode = GET_MODE (XEXP (x, 0));		if (mode == VOIDmode)		  return x;		if (GET_MODE_BITSIZE (mode) < HOST_BITS_PER_INT)		  {		    val = arg0 & ~((-1) << GET_MODE_BITSIZE (mode));		    if (val & (1 << (GET_MODE_BITSIZE (mode) - 1)))		      val -= 1 << GET_MODE_BITSIZE (mode);		  }		else		  return x;		break;	      }	    default:	      return x;	    }	}#if ! defined (REAL_IS_NOT_DOUBLE) || defined (REAL_ARITHMETIC)      else if (GET_CODE (const_arg0) == CONST_DOUBLE	       && GET_CODE (x) == NEG	       && GET_MODE_CLASS (GET_MODE (x)) == MODE_FLOAT)	{	  union real_extract u;	  register REAL_VALUE_TYPE arg0;	  jmp_buf handler;	  if (setjmp (handler))	    {	      warning ("floating point trap in constant folding");	      return x;	    }	  set_float_handler (handler);	  bcopy (&CONST_DOUBLE_LOW (const_arg0), &u, sizeof u);	  arg0 = u.d;	  u.d = REAL_VALUE_NEGATE (arg0);	  x = immed_real_const_1 (u.d, GET_MODE (x));	  set_float_handler (0);	  return x;	}#endif      else	return x;    }  else if (GET_RTX_LENGTH (code) == 2)    {      register int arg0, arg1, arg0s, arg1s;      int arithwidth = width;      /* If 1st arg is the condition codes, 2nd must be zero	 and this must be a comparison.	 Decode the info on how the previous insn set the cc0	 and use that to deduce result of comparison.  */      if (XEXP (x, 0) == cc0_rtx	  || GET_CODE (XEXP (x, 0)) == COMPARE)	{	  if (XEXP (x, 0) == cc0_rtx)	    arg0 = prev_insn_cc0;	  else	    arg0 = fold_cc0 (VOIDmode, XEXP (x, 0));	  if (arg0 == 0	      || const_arg1 != const0_rtx	      /* 0200 bit in arg0 means only zeroness is known,		 and sign is not known.  */	      || ((arg0 & 0200) != 0 && code != EQ && code != NE))	    return x;	  /* Extract either the signed or the unsigned digit from ARG0.  */	  if (code == LEU || code == LTU || code == GEU || code == GTU)	    arg0 = arg0 & 7;	  else	    arg0 = (arg0 >> 3) & 7;	  if (arg0 == 7) arg0 = -1;	  switch (code)	    {	    case LE:	    case LEU:	      return (arg0 <= 0) ? const1_rtx : const0_rtx;	    case LT:	    case LTU:	      return (arg0 < 0) ? const1_rtx : const0_rtx;	    case GE:	    case GEU:	      return (arg0 >= 0) ? const1_rtx : const0_rtx;	    case GT:	    case GTU:	      return (arg0 > 0) ? const1_rtx : const0_rtx;	    case NE:	      return (arg0 != 0) ? const1_rtx : const0_rtx;	    case EQ:	      return (arg0 == 0) ? const1_rtx : const0_rtx;	    default:	      abort ();	    }	}      if (const_arg0 == 0 || const_arg1 == 0	  || GET_CODE (const_arg0) != CONST_INT	  || GET_CODE (const_arg1) != CONST_INT)	{	  /* Even if we can't compute a constant result,	     there are some cases worth simplifying.  */	  /* Note that we cannot rely on constant args to come last,	     even for commutative operators,	     because that happens only when the constant is explicit.  */	  switch (code)	    {	    case PLUS:	      if (const_arg0 == const0_rtx		  || const_arg0 == fconst0_rtx		  || const_arg0 == dconst0_rtx)		return XEXP (x, 1);	      if (const_arg1 == const0_rtx		  || const_arg1 == fconst0_rtx		  || const_arg1 == dconst0_rtx)		return XEXP (x, 0);	      /* Handle both-operands-constant cases.  */	      if (const_arg0 != 0 && const_arg1 != 0		  && GET_CODE (const_arg0) != CONST_DOUBLE		  && GET_CODE (const_arg1) != CONST_DOUBLE		  && GET_MODE_CLASS (GET_MODE (x)) == MODE_INT)	        {		  if (GET_CODE (const_arg1) == CONST_INT)		    new = plus_constant (const_arg0, INTVAL (const_arg1));#if 0 /* Don't combine two constants if neither is an explicit integer.	 Assemblers can't handle the sum of two symbols.  */		  else		    {		      new = gen_rtx (PLUS, GET_MODE (x), const0_rtx, const0_rtx);		      XEXP (new, 0) = const_arg0;		      if (GET_CODE (const_arg0) == CONST)			XEXP (new, 0) = XEXP (const_arg0, 0);		      XEXP (new, 1) = const_arg1;		      if (GET_CODE (const_arg1) == CONST)			XEXP (new, 1) = XEXP (const_arg1, 0);		      new = gen_rtx (CONST, GET_MODE (new), new);		    }#endif /* 0 */		}	      else if (const_arg1 != 0		       && GET_CODE (const_arg1) == CONST_INT		       && GET_CODE (XEXP (x, 0)) == PLUS		       && (CONSTANT_P (XEXP (XEXP (x, 0), 0))			   || CONSTANT_P (XEXP (XEXP (x, 0), 1))))		/* constant + (variable + constant)		   can result if an index register is made constant.		   We simplify this by adding the constants.		   If we did not, it would become an invalid address.  */		new = plus_constant (XEXP (x, 0),				     INTVAL (const_arg1));	      break;	    case COMPARE:	      if (const_arg1 == const0_rtx)		return XEXP (x, 0);	      if (XEXP (x, 0) == XEXP (x, 1)		  || (const_arg0 != 0 && const_arg0 == const_arg1))		{		  /* We can't assume x-x is 0 with IEEE floating point.  */		  if (GET_MODE_CLASS (GET_MODE (x)) == MODE_INT)		    return const0_rtx;		}	      break;	      	    case MINUS:	      if (const_arg1 == const0_rtx		  || const_arg1 == fconst0_rtx		  || const_arg1 == dconst0_rtx)		return XEXP (x, 0);	      if (XEXP (x, 0) == XEXP (x, 1)		  || (const_arg0 != 0 && const_arg0 == const_arg1))		{		  /* We can't assume x-x is 0 with IEEE floating point.  */		  if (GET_MODE_CLASS (GET_MODE (x)) == MODE_INT)		    return const0_rtx;		}	      /* Change subtraction from zero into negation.  */	      if (const_arg0 == const0_rtx)		return gen_rtx (NEG, GET_MODE (x), XEXP (x, 1));	      /* Don't let a relocatable value get a negative coeff.  */	      if (const_arg0 != 0 && const_arg1 != 0		  && GET_CODE (const_arg1) == CONST_INT)		new = plus_constant (const_arg0, - INTVAL (const_arg1));	      break;	    case MULT:	    case UMULT:	      if (const_arg1 && GET_CODE (const_arg1) == CONST_INT		  && INTVAL (const_arg1) == -1		  /* Don't do this in the case of widening multiplication.  */		  && GET_MODE (XEXP (x, 0)) == GET_MODE (x))		return gen_rtx (NEG, GET_MODE (x), XEXP (x, 0));	      if (const_arg0 && GET_CODE (const_arg0) == CONST_INT		  && INTVAL (const_arg0) == -1		  && GET_MODE (XEXP (x, 1)) == GET_MODE (x))		return gen_rtx (NEG, GET_MODE (x), XEXP (x, 1));	      if (const_arg1 == const0_rtx || const_arg0 == const0_rtx)		new = const0_rtx;	      if (const_arg1 == fconst0_rtx || const_arg0 == fconst0_rtx)		new = fconst0_rtx;	      if (const_arg1 == dconst0_rtx || const_arg0 == dconst0_rtx)		new = dconst0_rtx;	      if (const_arg1 == const1_rtx)		return XEXP (x, 0);	      if (const_arg0 == const1_rtx)		return XEXP (x, 1);	      break;	    case IOR:	      if (const_arg1 == const0_rtx)		return XEXP (x, 0);	      if (const_arg0 == const0_rtx)		return XEXP (x, 1);	      if (const_arg1 && GET_CODE (const_arg1) == CONST_INT		  && (INTVAL (const_arg1) & GET_MODE_MASK (GET_MODE (x)))		      == GET_MODE_MASK (GET_MODE (x)))		new = const_arg1;	      if (const_arg0 && GET_CODE (const_arg0) == CONST_INT		  && (INTVAL (const_arg0) & GET_MODE_MASK (GET_MODE (x)))		      == GET_MODE_MASK (GET_MODE (x)))		new = const_arg0;	      break;	    case XOR:	      if (const_arg1 == const0_rtx)		return XEXP (x, 0);	      if (const_arg0 == const0_rtx)		return XEXP (x, 1);	      if (const_arg1 && GET_CODE (const_arg1) == CONST_INT		  && (INTVAL (const_arg1) & GET_MODE_MASK (GET_MODE (x)))		      == GET_MODE_MASK (GET_MODE (x)))		return gen_rtx (NOT, GET_MODE (x), XEXP (x, 0));	      if (const_arg0 && GET_CODE (const_arg0) == CONST_INT		  && (INTVAL (const_arg0) & GET_MODE_MASK (GET_MODE (x)))		      == GET_MODE_MASK (GET_MODE (x)))		return gen_rtx (NOT, GET_MODE (x), XEXP (x, 1));	      break;	    case AND:	      if (const_arg1 == const0_rtx || const_arg0 == const0_rtx)		new = const0_rtx;	      if (const_arg1 && GET_CODE (const_arg1) == CONST_INT		  && (INTVAL (const_arg1) & GET_MODE_MASK (GET_MODE (x)))		      == GET_MODE_MASK (GET_MODE (x)))		return XEXP (x, 0);	      if (const_arg0 && GET_CODE (const_arg0) == CONST_INT		  && (INTVAL (const_arg0) & GET_MODE_MASK (GET_MODE (x)))		      == GET_MODE_MASK (GET_MODE (x)))		return XEXP (x, 1);	      break;	    case DIV:	    case UDIV:	      if (const_arg1 == const1_rtx)		return XEXP (x, 0);	      if (const_arg0 == const0_rtx)		new = const0_rtx;	      break;	    case UMOD:	    case MOD:	      if (const_arg0 == const0_rtx || const_arg1 == const1_rtx)		new = const0_rtx;	      break;	    case LSHIFT:	    case ASHIFT:	    case ROTATE:	    case ASHIFTRT:	    case LSHIFTRT:	    case ROTATERT:	      if (const_arg1 == const0_rtx)		return XEXP (x, 0);	      if (const_arg0 == const0_rtx)		new = const_arg0;	      break;	    }	  if (new != 0 && LEGITIMATE_CONSTANT_P (new))	    return new;	  return x;	}      if (arithwidth == 0)	{	  if (GET_MODE (XEXP (x, 0)) != VOIDmode)	    arithwidth = GET_MODE_BITSIZE (GET_MODE (XEXP (x, 0)));	  if (GET_MODE (XEXP (x, 1)) != VOIDmode)	    arithwidth = GET_MODE_BITSIZE (GET_MODE (XEXP (x, 1)));	}      /* Get the integer argument values in two forms:	 zero-extended in ARG0, ARG1 and sign-extended in ARG0S, ARG1S.  */      arg0 = INTVAL (const_arg0);      arg1 = INTVAL (const_arg1);      if (arithwidth < HOST_BITS_PER_INT && arithwidth > 0)	{	  arg0 &= (1 << arithwidth) - 1;	  arg1 &= (1 << arithwidth) - 1;	  arg0s = arg0;	  if (arg0s & (1 << (arithwidth - 1)))	    arg0s |= ((-1) << arithwidth);	  arg1s = arg1;	  if (arg1s & (1 << (arithwidth - 1)))	    arg1s |= ((-1) << arithwidth);	}      else	{	  arg0s = arg0;	  arg1s = arg1;	}      /* Compute the value of the arithmetic.  */      switch (code)	{	case PLUS:	  val = arg0 + arg1;	  break;	case MINUS:	  val = arg0 - arg1;	  break;

⌨️ 快捷键说明

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