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

📄 expr.c

📁 这是完整的gcc源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
  if (to_mode == SImode && from_mode == HImode)    {      if (unsignedp)	{#ifdef HAVE_zero_extendhisi2	  if (HAVE_zero_extendhisi2)	    emit_unop_insn (CODE_FOR_zero_extendhisi2, to, from, ZERO_EXTEND);	  else#endif	    abort ();	}      else	{#ifdef HAVE_extendhisi2	  if (HAVE_extendhisi2)	    emit_unop_insn (CODE_FOR_extendhisi2, to, from, SIGN_EXTEND);	  else#endif	    abort ();	}      return;    }  if (to_mode == SImode && from_mode == QImode)    {      if (unsignedp)	{#ifdef HAVE_zero_extendqisi2	  if (HAVE_zero_extendqisi2)	    {	      emit_unop_insn (CODE_FOR_zero_extendqisi2, to, from, ZERO_EXTEND);	      return;	    }#endif#if defined (HAVE_zero_extendqihi2) && defined (HAVE_extendhisi2)	  if (HAVE_zero_extendqihi2 && HAVE_extendhisi2)	    {	      register rtx temp = gen_reg_rtx (HImode);	      emit_unop_insn (CODE_FOR_zero_extendqihi2, temp, from, ZERO_EXTEND);	      emit_unop_insn (CODE_FOR_extendhisi2, to, temp, SIGN_EXTEND);	      return;	    }#endif	}      else	{#ifdef HAVE_extendqisi2	  if (HAVE_extendqisi2)	    {	      emit_unop_insn (CODE_FOR_extendqisi2, to, from, SIGN_EXTEND);	      return;	    }#endif#if defined (HAVE_extendqihi2) && defined (HAVE_extendhisi2)	  if (HAVE_extendqihi2 && HAVE_extendhisi2)	    {	      register rtx temp = gen_reg_rtx (HImode);	      emit_unop_insn (CODE_FOR_extendqihi2, temp, from, SIGN_EXTEND);	      emit_unop_insn (CODE_FOR_extendhisi2, to, temp, SIGN_EXTEND);	      return;	    }#endif	}      abort ();    }  if (to_mode == HImode && from_mode == QImode)    {      if (unsignedp)	{#ifdef HAVE_zero_extendqihi2	  if (HAVE_zero_extendqihi2)	    {	      emit_unop_insn (CODE_FOR_zero_extendqihi2, to, from, ZERO_EXTEND);	      return;	    }#endif	}      else	{#ifdef HAVE_extendqihi2	  if (HAVE_extendqihi2)	    {	      emit_unop_insn (CODE_FOR_extendqihi2, to, from, SIGN_EXTEND);	      return;	    }#endif	}      abort ();    }#if 0 /* This seems to be redundant with code 100 lines up.  */  /* Now we are truncating an integer to a smaller one.     If the result is a temporary, we might as well just copy it,     since only the low-order part of the result needs to be valid     and it is valid with no change.  */  if (GET_CODE (to) == REG)    {      if (GET_CODE (from) == REG)	{	  emit_move_insn (to, gen_lowpart (GET_MODE (to), from));	  return;	}      else if (GET_CODE (from) == SUBREG)	{	  from = copy_rtx (from);	  /* This is safe since FROM is not more than one word.  */	  PUT_MODE (from, GET_MODE (to));	  emit_move_insn (to, from);	  return;	}#ifndef BYTES_BIG_ENDIAN      else if (GET_CODE (from) == MEM)	{	  register rtx addr = XEXP (from, 0);	  if (memory_address_p (GET_MODE (to), addr))	    {	      emit_move_insn (to, gen_rtx (MEM, GET_MODE (to), addr));	      return;	    }	}#endif /* not BYTES_BIG_ENDIAN */    }#endif /* 0 */  if (from_mode == SImode && to_mode == HImode)    {#ifdef HAVE_truncsihi2      if (HAVE_truncsihi2)	{	  emit_unop_insn (CODE_FOR_truncsihi2, to, from, UNKNOWN);	  return;	}#endif      abort ();    }  if (from_mode == SImode && to_mode == QImode)    {#ifdef HAVE_truncsiqi2      if (HAVE_truncsiqi2)	{	  emit_unop_insn (CODE_FOR_truncsiqi2, to, from, UNKNOWN);	  return;	}#endif      abort ();    }  if (from_mode == HImode && to_mode == QImode)    {#ifdef HAVE_trunchiqi2      if (HAVE_trunchiqi2)	{	  emit_unop_insn (CODE_FOR_trunchiqi2, to, from, UNKNOWN);	  return;	}#endif      abort ();    }  /* 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.  */rtxconvert_to_mode (mode, x, unsignedp)     enum machine_mode mode;     rtx x;     int unsignedp;{  register rtx temp;  if (mode == GET_MODE (x))    return x;  if (integer_mode_p (mode)      && GET_MODE_SIZE (mode) <= GET_MODE_SIZE (GET_MODE (x))      && (GET_CODE (x) == REG || GET_CODE (x) == CONST_DOUBLE	  || (GET_CODE (x) == MEM && ! MEM_VOLATILE_P (x))))    return gen_lowpart (mode, x);  temp = gen_reg_rtx (mode);  convert_move (temp, x, unsignedp);  return temp;}intinteger_mode_p (mode)     enum machine_mode mode;{  return (int) mode > (int) VOIDmode && (int) mode <= (int) TImode;}/* 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.  */struct move_by_pieces{  rtx to;  rtx to_addr;  int autinc_to;  int explicit_inc_to;  rtx from;  rtx from_addr;  int autinc_from;  int explicit_inc_from;  int len;  int offset;  int reverse;};static void move_by_pieces_1 ();static int move_by_pieces_ninsns ();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);  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    = (GET_CODE (to_addr) == PRE_DEC || GET_CODE (to_addr) == POST_DEC);  if (data.reverse) data.offset = len;  data.len = len;  /* If copying requires more than two move insns,     copy addresses to registers (to make displacements shorter)     and use post-increment if available.  */  if (!(data.autinc_from && data.autinc_to)      && move_by_pieces_ninsns (len, align) > 2)    {#ifdef HAVE_PRE_DECREMENT      if (data.reverse && ! data.autinc_from)	{	  data.from_addr = copy_addr_to_reg (plus_constant (from_addr, len));	  data.autinc_from = 1;	  data.explicit_inc_from = -1;	}#endif#ifdef HAVE_POST_INCREMENT      if (! data.autinc_from)	{	  data.from_addr = copy_addr_to_reg (from_addr);	  data.autinc_from = 1;	  data.explicit_inc_from = 1;	}#endif      if (!data.autinc_from && CONSTANT_P (from_addr))	data.from_addr = copy_addr_to_reg (from_addr);#ifdef HAVE_PRE_DECREMENT      if (data.reverse && ! data.autinc_to)	{	  data.to_addr = copy_addr_to_reg (plus_constant (to_addr, len));	  data.autinc_to = 1;	  data.explicit_inc_to = -1;	}#endif#ifdef HAVE_POST_INCREMENT      if (! data.reverse && ! data.autinc_to)	{	  data.to_addr = copy_addr_to_reg (to_addr);	  data.autinc_to = 1;	  data.explicit_inc_to = 1;	}#endif      if (!data.autinc_to && CONSTANT_P (to_addr))	data.to_addr = copy_addr_to_reg (to_addr);    }#ifdef STRICT_ALIGNMENT  if (align > MOVE_MAX || align >= BIGGEST_ALIGNMENT / BITS_PER_UNIT)    align = MOVE_MAX;#else  align = MOVE_MAX;#endif#ifdef HAVE_movti  if (HAVE_movti && align >= GET_MODE_SIZE (TImode))    move_by_pieces_1 (gen_movti, TImode, &data);#endif#ifdef HAVE_movdi  if (HAVE_movdi && align >= GET_MODE_SIZE (DImode))    move_by_pieces_1 (gen_movdi, DImode, &data);#endif#ifdef HAVE_movsi  if (align >= GET_MODE_SIZE (SImode))    move_by_pieces_1 (gen_movsi, SImode, &data);#endif#ifdef HAVE_movhi  if (HAVE_movhi && align >= GET_MODE_SIZE (HImode))    move_by_pieces_1 (gen_movhi, HImode, &data);#endif#ifdef HAVE_movqi  move_by_pieces_1 (gen_movqi, QImode, &data);#else  movqi instruction required in machine description#endif}/* Return number of insns required to move L bytes by pieces.   ALIGN (in bytes) is maximum alignment we can assume.  */static intmove_by_pieces_ninsns (l, align)     unsigned int l;     int align;{  register int n_insns = 0;#ifdef STRICT_ALIGNMENT  if (align > MOVE_MAX || align >= BIGGEST_ALIGNMENT / BITS_PER_UNIT)    align = MOVE_MAX;#else  align = MOVE_MAX;#endif#ifdef HAVE_movti  if (HAVE_movti && align >= GET_MODE_SIZE (TImode))    n_insns += l / GET_MODE_SIZE (TImode), l %= GET_MODE_SIZE (TImode);#endif#ifdef HAVE_movdi  if (HAVE_movdi && align >= GET_MODE_SIZE (DImode))    n_insns += l / GET_MODE_SIZE (DImode), l %= GET_MODE_SIZE (DImode);#endif#ifdef HAVE_movsi  if (HAVE_movsi && align >= GET_MODE_SIZE (SImode))    n_insns += l / GET_MODE_SIZE (SImode), l %= GET_MODE_SIZE (SImode);#endif#ifdef HAVE_movhi  if (HAVE_movhi && align >= GET_MODE_SIZE (HImode))    n_insns += l / GET_MODE_SIZE (HImode), l %= GET_MODE_SIZE (HImode);#endif  n_insns += l;  return n_insns;}/* Subroutine of move_by_pieces.  Move as many bytes as appropriate   with move instructions for mode MODE.  GENFUN is the gen_... function   to make a move insn for that mode.  DATA has all the other info.  */static voidmove_by_pieces_1 (genfun, mode, data)     rtx (*genfun) ();     enum machine_mode mode;     struct move_by_pieces *data;{  register int size = GET_MODE_SIZE (mode);  register rtx to1, from1;  while (data->len >= size)    {      if (data->reverse) data->offset -= size;      to1 = (data->autinc_to	     ? gen_rtx (MEM, mode, data->to_addr)	     : change_address (data->to, mode,			       plus_constant (data->to_addr, data->offset)));      from1 =	(data->autinc_from	 ? gen_rtx (MEM, mode, data->from_addr)	 : change_address (data->from, mode,			   plus_constant (data->from_addr, data->offset)));#ifdef HAVE_PRE_DECREMENT      if (data->explicit_inc_to < 0)	emit_insn (gen_sub2_insn (data->to_addr,				  gen_rtx (CONST_INT, VOIDmode, size)));      if (data->explicit_inc_from < 0)	emit_insn (gen_sub2_insn (data->from_addr,				  gen_rtx (CONST_INT, VOIDmode, size)));#endif      emit_insn ((*genfun) (to1, from1));#ifdef HAVE_POST_INCREMENT      if (data->explicit_inc_to > 0)	emit_insn (gen_add2_insn (data->to_addr,				  gen_rtx (CONST_INT, VOIDmode, size)));      if (data->explicit_inc_from > 0)	emit_insn (gen_add2_insn (data->from_addr,				  gen_rtx (CONST_INT, VOIDmode, size)));#endif      if (! data->reverse) data->offset += size;      data->len -= size;    }}/* Emit code to move a block Y to a block X.   This may be done with string-move instructions,   with multiple scalar move instructions, or with a library call.   Both X and Y must be MEM rtx's (perhaps inside VOLATILE)   with mode BLKmode.   SIZE is an rtx that says how long they are.   ALIGN is the maximum alignment we can assume they have,   measured in bytes.  */static voidemit_block_move (x, y, size, align)     rtx x, y;     rtx size;     int align;{  if (GET_MODE (x) != BLKmode)    abort ();  if (GET_MODE (y) != BLKmode)    abort ();  x = protect_from_queue (x, 1);  y = protect_from_queue (y, 0);  if (GET_CODE (x) != MEM)    abort ();  if (GET_CODE (y) != MEM)    abort ();  if (size == 0)    abort ();  if (GET_CODE (size) == CONST_INT      && (move_by_pieces_ninsns ((unsigned) INTVAL (size), align)	  < MOVE_RATIO))    move_by_pieces (x, y, INTVAL (size), align);  else

⌨️ 快捷键说明

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