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

📄 out-pyr.c

📁 这是完整的gcc源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
    {      if (GET_MODE_SIZE (GET_MODE (SUBREG_REG (op1))) <= UNITS_PER_WORD)	return 0;      regno_off1 = SUBREG_WORD (op1);      op1 = SUBREG_REG (op1);      code1 = REG;    }  if (code0 != code1)    return 0;  switch (code0)    {    case CONST_INT:      /* Cannot permit any symbolic constants, even if the consecutive	 operand is 0, since a movl really performs sign extension.  */      if (code1 != CONST_INT)	return 0;      if ((INTVAL (op0) == 0 && INTVAL (op1) == 0)	  || (INTVAL (op0) == -1 && INTVAL (op1) == -1))	return 3;      if ((INTVAL (op0) == 0 && INTVAL (op1) > 0)	  || (INTVAL (op0) == -1 && INTVAL (op1) < 0))	return 2;      if ((INTVAL (op1) == 0 && INTVAL (op0) > 0)	  || (INTVAL (op1) == -1 && INTVAL (op0) < 0))	return 1;      break;    case REG:      regno_off0 = REGNO (op0) + regno_off0;      regno_off1 = REGNO (op1) + regno_off1;      cnst_diff = regno_off0 - regno_off1;      if (cnst_diff == 1)	{	  /* movl with the highest numbered parameter (local) register as	     source or destination, doesn't wrap to the lowest numbered local	     (temporary) register.  */	  if (regno_off0 % 16 != 0)	    return 1;	  else	    return 0;	}      else if (cnst_diff == -1)	{	  if (regno_off1 % 16 != 0)	    return 2;	  else	    return 0;	}      break;    case MEM:      op0 = XEXP (op0, 0);      op1 = XEXP (op1, 0);      if (GET_CODE (op0) == CONST)	op0 = XEXP (op0, 0);      if (GET_CODE (op1) == CONST)	op1 = XEXP (op1, 0);      cnst_diff = constant_diff (op0, op1);      if (cnst_diff)	{	  if (cnst_diff == 4)	    return 1;	  else if (cnst_diff == -4)	    return 2;	}      break;    }  return 0;}/* Return the constant difference of the rtx expressions OP0 and OP1,   or 0 if they don't have a constant difference.   This function is used to determine if addresses are consecutive,   and therefore possible to combine to fewer instructions.  */intconstant_diff (op0, op1)     rtx op0, op1;{  RTX_CODE code0, code1;  int cnst_diff;  code0 = GET_CODE (op0);  code1 = GET_CODE (op1);  if (code0 != code1)    {      if (code0 == PLUS)	{	  if (GET_CODE (XEXP (op0, 1)) == CONST_INT	      && rtx_equal_p (op1, XEXP (op0, 0)))	    return INTVAL (XEXP (op0, 1));	}      else if (code1 == PLUS)	{	  if (GET_CODE (XEXP (op1, 1)) == CONST_INT	      && rtx_equal_p (op0, XEXP (op1, 0)))	    return -INTVAL (XEXP (op1, 1));	}      return 0;    }  if (code0 == CONST_INT)    return INTVAL (op0) - INTVAL (op1);  if (code0 == PLUS)    {      cnst_diff = constant_diff (XEXP (op0, 0), XEXP (op1, 0));      if (cnst_diff)	return (rtx_equal_p (XEXP (op0, 1), XEXP (op1, 1)))	  ? cnst_diff : 0;      cnst_diff = constant_diff (XEXP (op0, 1), XEXP (op1, 1));      if (cnst_diff)	return (rtx_equal_p (XEXP (op0, 0), XEXP (op1, 0)))	  ? cnst_diff : 0;    }  return 0;}intalready_sign_extended (insn, from_mode, op)     rtx insn;     enum machine_mode from_mode;     rtx op;{  rtx xinsn, xdest, xsrc;  for (;;)    {      insn = PREV_INSN (insn);      if (insn == 0)	return 0;      if (GET_CODE (insn) == NOTE || GET_CODE (insn) == JUMP_INSN)	continue;      if (GET_CODE (insn) == CALL_INSN && ! call_used_regs[REGNO (op)])	continue;      if (GET_CODE (insn) != INSN)	return 0;      xinsn = PATTERN (insn);      if (GET_CODE (xinsn) != SET)	return 0;      xdest = SET_DEST (xinsn);      xsrc = SET_SRC (xinsn);      if (GET_CODE (xdest) == SUBREG)	abort ();      if ( ! REG_P (xdest))	continue;      if (REGNO (op) == REGNO (xdest)	  && ((GET_CODE (xsrc) == SIGN_EXTEND	   && GET_MODE (XEXP (xsrc, 0)) == from_mode)	  || (GET_CODE (xsrc) == MEM	      && GET_MODE (xsrc) == from_mode)))	return 1;      /* The register is modified by another operation.  */      if (reg_overlap_mentioned_p (xdest, op))	return 0;    }}char *output_move_double (operands)     rtx *operands;{  if (GET_CODE (operands[1]) == CONST_DOUBLE)    {      if (GET_MODE_CLASS (GET_MODE (operands[1])) == MODE_INT)	{	  /* In an integer, the low-order word is in CONST_DOUBLE_LOW.  */	  rtx const_op = operands[1];	  if ((CONST_DOUBLE_HIGH (const_op) == 0	       && CONST_DOUBLE_LOW (const_op) >= 0)	      || (CONST_DOUBLE_HIGH (const_op) == -1		  && CONST_DOUBLE_LOW (const_op) < 0))	    {	      operands[1] = gen_rtx (CONST_INT, VOIDmode,				     CONST_DOUBLE_LOW (const_op));	      return "movl %1,%0";	    }	  operands[1] = gen_rtx (CONST_INT, VOIDmode,				 CONST_DOUBLE_HIGH (const_op));	  output_asm_insn ("movw %1,%0", operands);	  operands[0] = gen_rtx (REG, SImode, REGNO (operands[0]) + 1);	  operands[1] = gen_rtx (CONST_INT, VOIDmode,				 CONST_DOUBLE_LOW (const_op));	  return "movw %1,%0";	}      else	{	  /* In a real, the low-address word is in CONST_DOUBLE_LOW.  */	  rtx const_op = operands[1];	  if ((CONST_DOUBLE_LOW (const_op) == 0	       && CONST_DOUBLE_HIGH (const_op) >= 0)	      || (CONST_DOUBLE_LOW (const_op) == -1		  && CONST_DOUBLE_HIGH (const_op) < 0))	    {	      operands[1] = gen_rtx (CONST_INT, VOIDmode,				     CONST_DOUBLE_HIGH (const_op));	      return "movl %1,%0";	    }	  operands[1] = gen_rtx (CONST_INT, VOIDmode,				 CONST_DOUBLE_LOW (const_op));	  output_asm_insn ("movw %1,%0", operands);	  operands[0] = gen_rtx (REG, SImode, REGNO (operands[0]) + 1);	  operands[1] = gen_rtx (CONST_INT, VOIDmode,				 CONST_DOUBLE_HIGH (const_op));	  return "movw %1,%0";	}    }  return "movl %1,%0";}/* Output a shift insns, after having reduced integer arguments to   avoid as warnings.  */char *output_shift (pattern, op2, mod)     char *pattern;     rtx op2;     int mod;{  if (GET_CODE (op2) == CONST_INT)    {      int cnt = INTVAL (op2) % mod;      if (cnt == 0)	{	  cc_status = cc_prev_status;	  return "";	}      op2 = gen_rtx (CONST_INT, VOIDmode, cnt);    }  return pattern;}/* Return non-zero if the code of this rtx pattern is a relop.  */intrelop (op, mode)     rtx op;     enum machine_mode mode;{  switch (GET_CODE (op))    {    case EQ:    case NE:    case LT:    case LE:    case GE:    case GT:    case LTU:    case LEU:    case GEU:    case GTU:      return 1;    }  return 0;}voidnotice_update_cc (EXP, INSN)     rtx EXP, INSN;{  switch (GET_CODE (EXP))    {    case SET:      switch (GET_CODE (SET_DEST (EXP)))	{	case CC0:	  cc_status.mdep = 0;	  cc_status.flags = 0;	  cc_status.value1 = 0;	  cc_status.value2 = SET_SRC (EXP);	  break;	case PC:	  break;	case REG:	  switch (GET_CODE (SET_SRC (EXP)))	    {	    case CALL:	      goto call;	    case MEM:	      if (GET_MODE (SET_SRC (EXP)) == QImode		  || GET_MODE (SET_SRC (EXP)) == HImode)		{		  cc_status.mdep = 0;		  cc_status.flags = CC_NO_OVERFLOW;		  cc_status.value1 = SET_DEST (EXP);		  cc_status.value2 = SET_SRC (EXP);		  break;		}	      /* else: Fall through.  */	    case CONST_INT:	    case SYMBOL_REF:	    case LABEL_REF:	    case CONST:	    case CONST_DOUBLE:	    case REG:	      if (cc_status.value1		  && reg_overlap_mentioned_p (SET_DEST (EXP),					      cc_status.value1))		cc_status.value1 = 0;	      if (cc_status.value2		  && reg_overlap_mentioned_p (SET_DEST (EXP),					      cc_status.value2))		cc_status.value2 = 0;	      break;	    case UDIV:	    case UMOD:	      cc_status.mdep = CC_VALID_FOR_UNSIGNED;	      cc_status.flags = CC_NO_OVERFLOW;	      cc_status.value1 = SET_DEST (EXP);	      cc_status.value2 = SET_SRC (EXP);	      break;	    default:	      cc_status.mdep = 0;	      cc_status.flags = CC_NO_OVERFLOW;	      cc_status.value1 = SET_DEST (EXP);	      cc_status.value2 = SET_SRC (EXP);	      break;	    }	  break;	case MEM:	  switch (GET_CODE (SET_SRC (EXP)))	    {	    case REG:	      if (GET_MODE (SET_SRC (EXP)) == QImode		  || GET_MODE (SET_SRC (EXP)) == HImode)		{		  cc_status.flags = CC_NO_OVERFLOW;		  cc_status.value1 = SET_DEST (EXP);		  cc_status.value2 = SET_SRC (EXP);		  cc_status.mdep = 0;		  break;		}	      /* else: Fall through.  */	    case CONST_INT:	    case SYMBOL_REF:	    case LABEL_REF:	    case CONST:	    case CONST_DOUBLE:	    case MEM:	      /* Need to forget cc_status about memory positions each		 time a memory store is made, even if the memory store		 insns in question doesn't modify the condition codes.  */	      if (cc_status.value1 &&		  GET_CODE (cc_status.value1) == MEM)		cc_status.value1 = 0;	      if (cc_status.value2 &&		  GET_CODE (cc_status.value2) == MEM)		cc_status.value2 = 0;	      break;	    case SIGN_EXTEND:	    case FLOAT_EXTEND:	    case FLOAT_TRUNCATE:	    case FLOAT:	    case FIX:	      cc_status.flags = CC_NO_OVERFLOW;	      cc_status.value1 = SET_DEST (EXP);	      cc_status.value2 = SET_SRC (EXP);	      cc_status.mdep = 0;	      break;	    default:	      abort ();	    }	  break;	default:	  abort ();	}      break;    case CALL:    call:      CC_STATUS_INIT;      break;      /* Do calls preserve the condition codes?  (At least forget	 cc_status expressions if they refer to registers	 not preserved across calls.  Also forget expressions	 about memory contents.)  */      if (cc_status.value1	  && (refers_to_regno_p (PYR_TREG (0), PYR_TREG (15),				 cc_status.value1, 0)	      || GET_CODE (cc_status.value1) == MEM))	cc_status.value1 = 0;      if (cc_status.value2	  && (refers_to_regno_p (PYR_TREG (0), PYR_TREG (15),				 cc_status.value2, 0)	      || GET_CODE (cc_status.value2) == MEM))	cc_status.value2 = 0;      break;    default:      CC_STATUS_INIT;    }}voidforget_cc_if_dependent (op)     rtx op;{  cc_status = cc_prev_status;  if (cc_status.value1 && reg_overlap_mentioned_p (op, cc_status.value1))    cc_status.value1 = 0;  if (cc_status.value2 && reg_overlap_mentioned_p (op, cc_status.value2))    cc_status.value2 = 0;}

⌨️ 快捷键说明

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