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

📄 expr.c

📁 GCC编译器源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
	  if (QUEUED_INSN (y))	    {	      register rtx temp = gen_reg_rtx (GET_MODE (new));	      emit_insn_before (gen_move_insn (temp, new),				QUEUED_INSN (y));	      return temp;	    }	  return new;	}      /* Otherwise, recursively protect the subexpressions of all	 the kinds of rtx's that can contain a QUEUED.  */      if (code == MEM)	{	  rtx tem = protect_from_queue (XEXP (x, 0), 0);	  if (tem != XEXP (x, 0))	    {	      x = copy_rtx (x);	      XEXP (x, 0) = tem;	    }	}      else if (code == PLUS || code == MULT)	{	  rtx new0 = protect_from_queue (XEXP (x, 0), 0);	  rtx new1 = protect_from_queue (XEXP (x, 1), 0);	  if (new0 != XEXP (x, 0) || new1 != XEXP (x, 1))	    {	      x = copy_rtx (x);	      XEXP (x, 0) = new0;	      XEXP (x, 1) = new1;	    }	}      return x;    }  /* If the increment has not happened, use the variable itself.  */  if (QUEUED_INSN (x) == 0)    return QUEUED_VAR (x);  /* If the increment has happened and a pre-increment copy exists,     use that copy.  */  if (QUEUED_COPY (x) != 0)    return QUEUED_COPY (x);  /* The increment has happened but we haven't set up a pre-increment copy.     Set one up now, and use it.  */  QUEUED_COPY (x) = gen_reg_rtx (GET_MODE (QUEUED_VAR (x)));  emit_insn_before (gen_move_insn (QUEUED_COPY (x), QUEUED_VAR (x)),		    QUEUED_INSN (x));  return QUEUED_COPY (x);}/* Return nonzero if X contains a QUEUED expression:   if it contains anything that will be altered by a queued increment.   We handle only combinations of MEM, PLUS, MINUS and MULT operators   since memory addresses generally contain only those.  */static intqueued_subexp_p (x)     rtx x;{  register enum rtx_code code = GET_CODE (x);  switch (code)    {    case QUEUED:      return 1;    case MEM:      return queued_subexp_p (XEXP (x, 0));    case MULT:    case PLUS:    case MINUS:      return (queued_subexp_p (XEXP (x, 0))	      || queued_subexp_p (XEXP (x, 1)));    default:      return 0;    }}/* Perform all the pending incrementations.  */voidemit_queue (){  register rtx p;  while (p = pending_chain)    {      QUEUED_INSN (p) = emit_insn (QUEUED_BODY (p));      pending_chain = QUEUED_NEXT (p);    }}static voidinit_queue (){  if (pending_chain)    abort ();}/* Copy data from FROM to TO, where the machine modes are not the same.   Both modes may be integer, or both may be floating.   UNSIGNEDP should be nonzero if FROM is an unsigned type.   This causes zero-extension instead of sign-extension.  */voidconvert_move (to, from, unsignedp)     register rtx to, from;     int unsignedp;{  enum machine_mode to_mode = GET_MODE (to);  enum machine_mode from_mode = GET_MODE (from);  int to_real = GET_MODE_CLASS (to_mode) == MODE_FLOAT;  int from_real = GET_MODE_CLASS (from_mode) == MODE_FLOAT;  enum insn_code code;  rtx libcall;  /* rtx code for making an equivalent value.  */  enum rtx_code equiv_code = (unsignedp ? ZERO_EXTEND : SIGN_EXTEND);  to = protect_from_queue (to, 1);  from = protect_from_queue (from, 0);  if (to_real != from_real)    abort ();  /* If FROM is a SUBREG that indicates that we have already done at least     the required extension, strip it.  We don't handle such SUBREGs as     TO here.  */  if (GET_CODE (from) == SUBREG && SUBREG_PROMOTED_VAR_P (from)      && (GET_MODE_SIZE (GET_MODE (SUBREG_REG (from)))	  >= GET_MODE_SIZE (to_mode))      && SUBREG_PROMOTED_UNSIGNED_P (from) == unsignedp)    from = gen_lowpart (to_mode, from), from_mode = to_mode;  if (GET_CODE (to) == SUBREG && SUBREG_PROMOTED_VAR_P (to))    abort ();  if (to_mode == from_mode      || (from_mode == VOIDmode && CONSTANT_P (from)))    {      emit_move_insn (to, from);      return;    }  if (to_real)    {      rtx value;      if (GET_MODE_BITSIZE (from_mode) < GET_MODE_BITSIZE (to_mode))	{	  /* Try converting directly if the insn is supported.  */	  if ((code = can_extend_p (to_mode, from_mode, 0))	      != CODE_FOR_nothing)	    {	      emit_unop_insn (code, to, from, UNKNOWN);	      return;	    }	} #ifdef HAVE_trunchfqf2      if (HAVE_trunchfqf2 && from_mode == HFmode && to_mode == QFmode)	{	  emit_unop_insn (CODE_FOR_trunchfqf2, to, from, UNKNOWN);	  return;	}#endif#ifdef HAVE_trunctqfqf2      if (HAVE_trunctqfqf2 && from_mode == TQFmode && to_mode == QFmode)	{	  emit_unop_insn (CODE_FOR_trunctqfqf2, to, from, UNKNOWN);	  return;	}#endif#ifdef HAVE_truncsfqf2      if (HAVE_truncsfqf2 && from_mode == SFmode && to_mode == QFmode)	{	  emit_unop_insn (CODE_FOR_truncsfqf2, to, from, UNKNOWN);	  return;	}#endif#ifdef HAVE_truncdfqf2      if (HAVE_truncdfqf2 && from_mode == DFmode && to_mode == QFmode)	{	  emit_unop_insn (CODE_FOR_truncdfqf2, to, from, UNKNOWN);	  return;	}#endif#ifdef HAVE_truncxfqf2      if (HAVE_truncxfqf2 && from_mode == XFmode && to_mode == QFmode)	{	  emit_unop_insn (CODE_FOR_truncxfqf2, to, from, UNKNOWN);	  return;	}#endif#ifdef HAVE_trunctfqf2      if (HAVE_trunctfqf2 && from_mode == TFmode && to_mode == QFmode)	{	  emit_unop_insn (CODE_FOR_trunctfqf2, to, from, UNKNOWN);	  return;	}#endif#ifdef HAVE_trunctqfhf2      if (HAVE_trunctqfhf2 && from_mode == TQFmode && to_mode == HFmode)	{	  emit_unop_insn (CODE_FOR_trunctqfhf2, to, from, UNKNOWN);	  return;	}#endif#ifdef HAVE_truncsfhf2      if (HAVE_truncsfhf2 && from_mode == SFmode && to_mode == HFmode)	{	  emit_unop_insn (CODE_FOR_truncsfhf2, to, from, UNKNOWN);	  return;	}#endif#ifdef HAVE_truncdfhf2      if (HAVE_truncdfhf2 && from_mode == DFmode && to_mode == HFmode)	{	  emit_unop_insn (CODE_FOR_truncdfhf2, to, from, UNKNOWN);	  return;	}#endif#ifdef HAVE_truncxfhf2      if (HAVE_truncxfhf2 && from_mode == XFmode && to_mode == HFmode)	{	  emit_unop_insn (CODE_FOR_truncxfhf2, to, from, UNKNOWN);	  return;	}#endif#ifdef HAVE_trunctfhf2      if (HAVE_trunctfhf2 && from_mode == TFmode && to_mode == HFmode)	{	  emit_unop_insn (CODE_FOR_trunctfhf2, to, from, UNKNOWN);	  return;	}#endif#ifdef HAVE_truncsftqf2      if (HAVE_truncsftqf2 && from_mode == SFmode && to_mode == TQFmode)	{	  emit_unop_insn (CODE_FOR_truncsftqf2, to, from, UNKNOWN);	  return;	}#endif#ifdef HAVE_truncdftqf2      if (HAVE_truncdftqf2 && from_mode == DFmode && to_mode == TQFmode)	{	  emit_unop_insn (CODE_FOR_truncdftqf2, to, from, UNKNOWN);	  return;	}#endif#ifdef HAVE_truncxftqf2      if (HAVE_truncxftqf2 && from_mode == XFmode && to_mode == TQFmode)	{	  emit_unop_insn (CODE_FOR_truncxftqf2, to, from, UNKNOWN);	  return;	}#endif#ifdef HAVE_trunctftqf2      if (HAVE_trunctftqf2 && from_mode == TFmode && to_mode == TQFmode)	{	  emit_unop_insn (CODE_FOR_trunctftqf2, to, from, UNKNOWN);	  return;	}#endif#ifdef HAVE_truncdfsf2      if (HAVE_truncdfsf2 && from_mode == DFmode && to_mode == SFmode)	{	  emit_unop_insn (CODE_FOR_truncdfsf2, to, from, UNKNOWN);	  return;	}#endif#ifdef HAVE_truncxfsf2      if (HAVE_truncxfsf2 && from_mode == XFmode && to_mode == SFmode)	{	  emit_unop_insn (CODE_FOR_truncxfsf2, to, from, UNKNOWN);	  return;	}#endif#ifdef HAVE_trunctfsf2      if (HAVE_trunctfsf2 && from_mode == TFmode && to_mode == SFmode)	{	  emit_unop_insn (CODE_FOR_trunctfsf2, to, from, UNKNOWN);	  return;	}#endif#ifdef HAVE_truncxfdf2      if (HAVE_truncxfdf2 && from_mode == XFmode && to_mode == DFmode)	{	  emit_unop_insn (CODE_FOR_truncxfdf2, to, from, UNKNOWN);	  return;	}#endif#ifdef HAVE_trunctfdf2      if (HAVE_trunctfdf2 && from_mode == TFmode && to_mode == DFmode)	{	  emit_unop_insn (CODE_FOR_trunctfdf2, to, from, UNKNOWN);	  return;	}#endif      libcall = (rtx) 0;      switch (from_mode)	{	case SFmode:	  switch (to_mode)	    {	    case DFmode:	      libcall = extendsfdf2_libfunc;	      break;	    case XFmode:	      libcall = extendsfxf2_libfunc;	      break;	    case TFmode:	      libcall = extendsftf2_libfunc;	      break;	      	    default:	      break;	    }	  break;	case DFmode:	  switch (to_mode)	    {	    case SFmode:	      libcall = truncdfsf2_libfunc;	      break;	    case XFmode:	      libcall = extenddfxf2_libfunc;	      break;	    case TFmode:	      libcall = extenddftf2_libfunc;	      break;	      	    default:	      break;	    }	  break;	case XFmode:	  switch (to_mode)	    {	    case SFmode:	      libcall = truncxfsf2_libfunc;	      break;	    case DFmode:	      libcall = truncxfdf2_libfunc;	      break;	      	    default:	      break;	    }	  break;	case TFmode:	  switch (to_mode)	    {	    case SFmode:	      libcall = trunctfsf2_libfunc;	      break;	    case DFmode:	      libcall = trunctfdf2_libfunc;	      break;	      	    default:	      break;	    }	  break;	  	default:	  break;	}      if (libcall == (rtx) 0)	/* This conversion is not implemented yet.  */	abort ();      value = emit_library_call_value (libcall, NULL_RTX, 1, to_mode,				       1, from, from_mode);      emit_move_insn (to, value);      return;    }  /* Now both modes are integers.  */  /* Handle expanding beyond a word.  */  if (GET_MODE_BITSIZE (from_mode) < GET_MODE_BITSIZE (to_mode)      && GET_MODE_BITSIZE (to_mode) > BITS_PER_WORD)    {      rtx insns;      rtx lowpart;      rtx fill_value;      rtx lowfrom;      int i;      enum machine_mode lowpart_mode;      int nwords = CEIL (GET_MODE_SIZE (to_mode), UNITS_PER_WORD);      /* Try converting directly if the insn is supported.  */      if ((code = can_extend_p (to_mode, from_mode, unsignedp))	  != CODE_FOR_nothing)	{	  /* If FROM is a SUBREG, put it into a register.  Do this	     so that we always generate the same set of insns for	     better cse'ing; if an intermediate assignment occurred,	     we won't be doing the operation directly on the SUBREG.  */	  if (optimize > 0 && GET_CODE (from) == SUBREG)	    from = force_reg (from_mode, from);	  emit_unop_insn (code, to, from, equiv_code);	  return;	}      /* Next, try converting via full word.  */      else if (GET_MODE_BITSIZE (from_mode) < BITS_PER_WORD	       && ((code = can_extend_p (to_mode, word_mode, unsignedp))		   != CODE_FOR_nothing))	{	  if (GET_CODE (to) == REG)	    emit_insn (gen_rtx (CLOBBER, VOIDmode, to));	  convert_move (gen_lowpart (word_mode, to), from, unsignedp);	  emit_unop_insn (code, to,			  gen_lowpart (word_mode, to), equiv_code);	  return;	}      /* No special multiword conversion insn; do it by hand.  */      start_sequence ();      /* Since we will turn this into a no conflict block, we must ensure	 that the source does not overlap the target.  */      if (reg_overlap_mentioned_p (to, from))	from = force_reg (from_mode, from);      /* Get a copy of FROM widened to a word, if necessary.  */      if (GET_MODE_BITSIZE (from_mode) < BITS_PER_WORD)	lowpart_mode = word_mode;      else	lowpart_mode = from_mode;      lowfrom = convert_to_mode (lowpart_mode, from, unsignedp);      lowpart = gen_lowpart (lowpart_mode, to);      emit_move_insn (lowpart, lowfrom);      /* Compute the value to put in each remaining word.  */      if (unsignedp)	fill_value = const0_rtx;      else	{#ifdef HAVE_slt	  if (HAVE_slt	      && insn_operand_mode[(int) CODE_FOR_slt][0] == word_mode	      && STORE_FLAG_VALUE == -1)	    {	      emit_cmp_insn (lowfrom, const0_rtx, NE, NULL_RTX,			     lowpart_mode, 0, 0);	      fill_value = gen_reg_rtx (word_mode);	      emit_insn (gen_slt (fill_value));	    }	  else#endif	    {	      fill_value		= expand_shift (RSHIFT_EXPR, lowpart_mode, lowfrom,

⌨️ 快捷键说明

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