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

📄 expr.c

📁 GCC编译器源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
				size_int (GET_MODE_BITSIZE (lowpart_mode) - 1),				NULL_RTX, 0);	      fill_value = convert_to_mode (word_mode, fill_value, 1);	    }	}      /* Fill the remaining words.  */      for (i = GET_MODE_SIZE (lowpart_mode) / UNITS_PER_WORD; i < nwords; i++)	{	  int index = (WORDS_BIG_ENDIAN ? nwords - i - 1 : i);	  rtx subword = operand_subword (to, index, 1, to_mode);	  if (subword == 0)	    abort ();	  if (fill_value != subword)	    emit_move_insn (subword, fill_value);	}      insns = get_insns ();      end_sequence ();      emit_no_conflict_block (insns, to, from, NULL_RTX,			      gen_rtx (equiv_code, to_mode, copy_rtx (from)));      return;    }  /* Truncating multi-word to a word or less.  */  if (GET_MODE_BITSIZE (from_mode) > BITS_PER_WORD      && GET_MODE_BITSIZE (to_mode) <= BITS_PER_WORD)    {      if (!((GET_CODE (from) == MEM	     && ! MEM_VOLATILE_P (from)	     && direct_load[(int) to_mode]	     && ! mode_dependent_address_p (XEXP (from, 0)))	    || GET_CODE (from) == REG	    || GET_CODE (from) == SUBREG))	from = force_reg (from_mode, from);      convert_move (to, gen_lowpart (word_mode, from), 0);      return;    }  /* Handle pointer conversion */			/* SPEE 900220 */  if (to_mode == PSImode)    {      if (from_mode != SImode)	from = convert_to_mode (SImode, from, unsignedp);#ifdef HAVE_truncsipsi2      if (HAVE_truncsipsi2)	{	  emit_unop_insn (CODE_FOR_truncsipsi2, to, from, UNKNOWN);	  return;	}#endif /* HAVE_truncsipsi2 */      abort ();    }  if (from_mode == PSImode)    {      if (to_mode != SImode)	{	  from = convert_to_mode (SImode, from, unsignedp);	  from_mode = SImode;	}      else	{#ifdef HAVE_extendpsisi2	  if (HAVE_extendpsisi2)	    {	      emit_unop_insn (CODE_FOR_extendpsisi2, to, from, UNKNOWN);	      return;	    }#endif /* HAVE_extendpsisi2 */	  abort ();	}    }  if (to_mode == PDImode)    {      if (from_mode != DImode)	from = convert_to_mode (DImode, from, unsignedp);#ifdef HAVE_truncdipdi2      if (HAVE_truncdipdi2)	{	  emit_unop_insn (CODE_FOR_truncdipdi2, to, from, UNKNOWN);	  return;	}#endif /* HAVE_truncdipdi2 */      abort ();    }  if (from_mode == PDImode)    {      if (to_mode != DImode)	{	  from = convert_to_mode (DImode, from, unsignedp);	  from_mode = DImode;	}      else	{#ifdef HAVE_extendpdidi2	  if (HAVE_extendpdidi2)	    {	      emit_unop_insn (CODE_FOR_extendpdidi2, to, from, UNKNOWN);	      return;	    }#endif /* HAVE_extendpdidi2 */	  abort ();	}    }  /* Now follow all the conversions between integers     no more than a word long.  */  /* For truncation, usually we can just refer to FROM in a narrower mode.  */  if (GET_MODE_BITSIZE (to_mode) < GET_MODE_BITSIZE (from_mode)      && TRULY_NOOP_TRUNCATION (GET_MODE_BITSIZE (to_mode),				GET_MODE_BITSIZE (from_mode)))    {      if (!((GET_CODE (from) == MEM	     && ! MEM_VOLATILE_P (from)	     && direct_load[(int) to_mode]	     && ! mode_dependent_address_p (XEXP (from, 0)))	    || GET_CODE (from) == REG	    || GET_CODE (from) == SUBREG))	from = force_reg (from_mode, from);      if (GET_CODE (from) == REG && REGNO (from) < FIRST_PSEUDO_REGISTER	  && ! HARD_REGNO_MODE_OK (REGNO (from), to_mode))	from = copy_to_reg (from);      emit_move_insn (to, gen_lowpart (to_mode, from));      return;    }  /* Handle extension.  */  if (GET_MODE_BITSIZE (to_mode) > GET_MODE_BITSIZE (from_mode))    {      /* Convert directly if that works.  */      if ((code = can_extend_p (to_mode, from_mode, unsignedp))	  != CODE_FOR_nothing)	{	  emit_unop_insn (code, to, from, equiv_code);	  return;	}      else	{	  enum machine_mode intermediate;	  /* Search for a mode to convert via.  */	  for (intermediate = from_mode; intermediate != VOIDmode;	       intermediate = GET_MODE_WIDER_MODE (intermediate))	    if (((can_extend_p (to_mode, intermediate, unsignedp)		  != CODE_FOR_nothing)		 || (GET_MODE_SIZE (to_mode) < GET_MODE_SIZE (intermediate)		     && TRULY_NOOP_TRUNCATION (to_mode, intermediate)))		&& (can_extend_p (intermediate, from_mode, unsignedp)		    != CODE_FOR_nothing))	      {		convert_move (to, convert_to_mode (intermediate, from,						   unsignedp), unsignedp);		return;	      }	  /* No suitable intermediate mode.  */	  abort ();	}    }  /* Support special truncate insns for certain modes.  */   if (from_mode == DImode && to_mode == SImode)    {#ifdef HAVE_truncdisi2      if (HAVE_truncdisi2)	{	  emit_unop_insn (CODE_FOR_truncdisi2, to, from, UNKNOWN);	  return;	}#endif      convert_move (to, force_reg (from_mode, from), unsignedp);      return;    }  if (from_mode == DImode && to_mode == HImode)    {#ifdef HAVE_truncdihi2      if (HAVE_truncdihi2)	{	  emit_unop_insn (CODE_FOR_truncdihi2, to, from, UNKNOWN);	  return;	}#endif      convert_move (to, force_reg (from_mode, from), unsignedp);      return;    }  if (from_mode == DImode && to_mode == QImode)    {#ifdef HAVE_truncdiqi2      if (HAVE_truncdiqi2)	{	  emit_unop_insn (CODE_FOR_truncdiqi2, to, from, UNKNOWN);	  return;	}#endif      convert_move (to, force_reg (from_mode, from), unsignedp);      return;    }  if (from_mode == SImode && to_mode == HImode)    {#ifdef HAVE_truncsihi2      if (HAVE_truncsihi2)	{	  emit_unop_insn (CODE_FOR_truncsihi2, to, from, UNKNOWN);	  return;	}#endif      convert_move (to, force_reg (from_mode, from), unsignedp);      return;    }  if (from_mode == SImode && to_mode == QImode)    {#ifdef HAVE_truncsiqi2      if (HAVE_truncsiqi2)	{	  emit_unop_insn (CODE_FOR_truncsiqi2, to, from, UNKNOWN);	  return;	}#endif      convert_move (to, force_reg (from_mode, from), unsignedp);      return;    }  if (from_mode == HImode && to_mode == QImode)    {#ifdef HAVE_trunchiqi2      if (HAVE_trunchiqi2)	{	  emit_unop_insn (CODE_FOR_trunchiqi2, to, from, UNKNOWN);	  return;	}#endif      convert_move (to, force_reg (from_mode, from), unsignedp);      return;    }  if (from_mode == TImode && to_mode == DImode)    {#ifdef HAVE_trunctidi2      if (HAVE_trunctidi2)	{	  emit_unop_insn (CODE_FOR_trunctidi2, to, from, UNKNOWN);	  return;	}#endif      convert_move (to, force_reg (from_mode, from), unsignedp);      return;    }  if (from_mode == TImode && to_mode == SImode)    {#ifdef HAVE_trunctisi2      if (HAVE_trunctisi2)	{	  emit_unop_insn (CODE_FOR_trunctisi2, to, from, UNKNOWN);	  return;	}#endif      convert_move (to, force_reg (from_mode, from), unsignedp);      return;    }  if (from_mode == TImode && to_mode == HImode)    {#ifdef HAVE_trunctihi2      if (HAVE_trunctihi2)	{	  emit_unop_insn (CODE_FOR_trunctihi2, to, from, UNKNOWN);	  return;	}#endif      convert_move (to, force_reg (from_mode, from), unsignedp);      return;    }  if (from_mode == TImode && to_mode == QImode)    {#ifdef HAVE_trunctiqi2      if (HAVE_trunctiqi2)	{	  emit_unop_insn (CODE_FOR_trunctiqi2, to, from, UNKNOWN);	  return;	}#endif      convert_move (to, force_reg (from_mode, from), unsignedp);      return;    }  /* Handle truncation of volatile memrefs, and so on;     the things that couldn't be truncated directly,     and for which there was no special instruction.  */  if (GET_MODE_BITSIZE (to_mode) < GET_MODE_BITSIZE (from_mode))    {      rtx temp = force_reg (to_mode, gen_lowpart (to_mode, from));      emit_move_insn (to, temp);      return;    }  /* Mode combination is not recognized.  */  abort ();}/* Return an rtx for a value that would result   from converting X to mode MODE.   Both X and MODE may be floating, or both integer.   UNSIGNEDP is nonzero if X is an unsigned value.   This can be done by referring to a part of X in place   or by copying to a new temporary with conversion.   This function *must not* call protect_from_queue   except when putting X into an insn (in which case convert_move does it).  */rtxconvert_to_mode (mode, x, unsignedp)     enum machine_mode mode;     rtx x;     int unsignedp;{  return convert_modes (mode, VOIDmode, x, unsignedp);}/* Return an rtx for a value that would result   from converting X from mode OLDMODE to mode MODE.   Both modes may be floating, or both integer.   UNSIGNEDP is nonzero if X is an unsigned value.   This can be done by referring to a part of X in place   or by copying to a new temporary with conversion.   You can give VOIDmode for OLDMODE, if you are sure X has a nonvoid mode.   This function *must not* call protect_from_queue   except when putting X into an insn (in which case convert_move does it).  */rtxconvert_modes (mode, oldmode, x, unsignedp)     enum machine_mode mode, oldmode;     rtx x;     int unsignedp;{  register rtx temp;  /* If FROM is a SUBREG that indicates that we have already done at least     the required extension, strip it.  */  if (GET_CODE (x) == SUBREG && SUBREG_PROMOTED_VAR_P (x)      && GET_MODE_SIZE (GET_MODE (SUBREG_REG (x))) >= GET_MODE_SIZE (mode)      && SUBREG_PROMOTED_UNSIGNED_P (x) == unsignedp)    x = gen_lowpart (mode, x);  if (GET_MODE (x) != VOIDmode)    oldmode = GET_MODE (x);   if (mode == oldmode)    return x;  /* There is one case that we must handle specially: If we are converting     a CONST_INT into a mode whose size is twice HOST_BITS_PER_WIDE_INT and     we are to interpret the constant as unsigned, gen_lowpart will do     the wrong if the constant appears negative.  What we want to do is     make the high-order word of the constant zero, not all ones.  */  if (unsignedp && GET_MODE_CLASS (mode) == MODE_INT      && GET_MODE_BITSIZE (mode) == 2 * HOST_BITS_PER_WIDE_INT      && GET_CODE (x) == CONST_INT && INTVAL (x) < 0)    {      HOST_WIDE_INT val = INTVAL (x);      if (oldmode != VOIDmode	  && HOST_BITS_PER_WIDE_INT > GET_MODE_BITSIZE (oldmode))	{	  int width = GET_MODE_BITSIZE (oldmode);	  /* We need to zero extend VAL.  */	  val &= ((HOST_WIDE_INT) 1 << width) - 1;	}      return immed_double_const (val, (HOST_WIDE_INT) 0, mode);    }  /* We can do this with a gen_lowpart if both desired and current modes     are integer, and this is either a constant integer, a register, or a     non-volatile MEM.  Except for the constant case where MODE is no     wider than HOST_BITS_PER_WIDE_INT, we must be narrowing the operand.  */  if ((GET_CODE (x) == CONST_INT       && GET_MODE_BITSIZE (mode) <= HOST_BITS_PER_WIDE_INT)      || (GET_MODE_CLASS (mode) == MODE_INT	  && GET_MODE_CLASS (oldmode) == MODE_INT	  && (GET_CODE (x) == CONST_DOUBLE	      || (GET_MODE_SIZE (mode) <= GET_MODE_SIZE (oldmode)		  && ((GET_CODE (x) == MEM && ! MEM_VOLATILE_P (x)		       && direct_load[(int) mode])		      || (GET_CODE (x) == REG			  && TRULY_NOOP_TRUNCATION (GET_MODE_BITSIZE (mode),						    GET_MODE_BITSIZE (GET_MODE (x)))))))))    {      /* ?? If we don't know OLDMODE, we have to assume here that	 X does not need sign- or zero-extension.   This may not be	 the case, but it's the best we can do.  */      if (GET_CODE (x) == CONST_INT && oldmode != VOIDmode	  && GET_MODE_SIZE (mode) > GET_MODE_SIZE (oldmode))	{	  HOST_WIDE_INT val = INTVAL (x);	  int width = GET_MODE_BITSIZE (oldmode);	  /* We must sign or zero-extend in this case.  Start by	     zero-extending, then sign extend if we need to.  */	  val &= ((HOST_WIDE_INT) 1 << width) - 1;	  if (! unsignedp	      && (val & ((HOST_WIDE_INT) 1 << (width - 1))))	    val |= (HOST_WIDE_INT) (-1) << width;	  return GEN_INT (val);	}      return gen_lowpart (mode, x);    }  temp = gen_reg_rtx (mode);  convert_move (temp, x, unsignedp);  return temp;}/* Generate several move instructions to copy LEN bytes   from block FROM to block TO.  (These are MEM rtx's with BLKmode).   The caller must pass FROM and TO    through protect_from_queue before calling.   ALIGN (in bytes) is maximum alignment we can assume.  */static voidmove_by_pieces (to, from, len, align)     rtx to, from;     int len, align;{  struct move_by_pieces data;  rtx to_addr = XEXP (to, 0), from_addr = XEXP (from, 0);  int max_size = MOVE_MAX + 1;  data.offset = 0;  data.to_addr = to_addr;  data.from_addr = from_addr;  data.to = to;  data.from = from;  data.autinc_to    = (GET_CODE (to_addr) == PRE_INC || GET_CODE (to_addr) == PRE_DEC       || GET_CODE (to_addr) == POST_INC || GET_CODE (to_addr) == POST_DEC);  data.autinc_from    = (GET_CODE (from_addr) == PRE_INC || GET_CODE (from_addr) == PRE_DEC       || GET_CODE (from_addr) == POST_INC       || GET_CODE (from_addr) == POST_DEC);  data.explicit_inc_from = 0;  data.explicit_inc_to = 0;  data.reverse

⌨️ 快捷键说明

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