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

📄 expr.c

📁 早期freebsd实现
💻 C
📖 第 1 页 / 共 5 页
字号:
    abort ();  if (to_mode == from_mode      || (from_mode == VOIDmode && CONSTANT_P (from)))    {      emit_move_insn (to, from);      return;    }  if (to_real)    {#ifdef HAVE_extendsfdf2      if (HAVE_extendsfdf2 && from_mode == SFmode && to_mode == DFmode)	{	  emit_unop_insn (CODE_FOR_extendsfdf2, to, from, UNKNOWN);	  return;	}#endif#ifdef HAVE_extendsfxf2      if (HAVE_extendsfxf2 && from_mode == SFmode && to_mode == XFmode)	{	  emit_unop_insn (CODE_FOR_extendsfxf2, to, from, UNKNOWN);	  return;	}#endif#ifdef HAVE_extendsftf2      if (HAVE_extendsftf2 && from_mode == SFmode && to_mode == TFmode)	{	  emit_unop_insn (CODE_FOR_extendsftf2, to, from, UNKNOWN);	  return;	}#endif#ifdef HAVE_extenddfxf2      if (HAVE_extenddfxf2 && from_mode == DFmode && to_mode == XFmode)	{	  emit_unop_insn (CODE_FOR_extenddfxf2, to, from, UNKNOWN);	  return;	}#endif#ifdef HAVE_extenddftf2      if (HAVE_extenddftf2 && from_mode == DFmode && to_mode == TFmode)	{	  emit_unop_insn (CODE_FOR_extenddftf2, 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;	    }	  break;	case DFmode:	  switch (to_mode)	    {	    case SFmode:	      libcall = truncdfsf2_libfunc;	      break;	    case XFmode:	      libcall = extenddfxf2_libfunc;	      break;	    case TFmode:	      libcall = extenddftf2_libfunc;	      break;	    }	  break;	case XFmode:	  switch (to_mode)	    {	    case SFmode:	      libcall = truncxfsf2_libfunc;	      break;	    case DFmode:	      libcall = truncxfdf2_libfunc;	      break;	    }	  break;	case TFmode:	  switch (to_mode)	    {	    case SFmode:	      libcall = trunctfsf2_libfunc;	      break;	    case DFmode:	      libcall = trunctfdf2_libfunc;	      break;	    }	  break;	}      if (libcall == (rtx) 0)	/* This conversion is not implemented yet.  */	abort ();      emit_library_call (libcall, 1, to_mode, 1, from, from_mode);      emit_move_insn (to, hard_libcall_value (to_mode));      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))	{	  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 ();      /* 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,				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, from));      return;    }  if (GET_MODE_BITSIZE (from_mode) > BITS_PER_WORD)    {      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_truncsipsi      if (HAVE_truncsipsi)	{	  emit_unop_insn (CODE_FOR_truncsipsi, to, from, UNKNOWN);	  return;	}#endif /* HAVE_truncsipsi */      abort ();    }  if (from_mode == PSImode)    {      if (to_mode != SImode)	{	  from = convert_to_mode (SImode, from, unsignedp);	  from_mode = SImode;	}      else	{#ifdef HAVE_extendpsisi	  if (HAVE_extendpsisi)	    {	      emit_unop_insn (CODE_FOR_extendpsisi, to, from, UNKNOWN);	      return;	    }#endif /* HAVE_extendpsisi */	  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))      && ((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))    {      emit_move_insn (to, gen_lowpart (to_mode, from));      return;    }  /* For truncation, usually we can just refer to FROM in a narrower mode.  */  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)	{	  /* 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;	}      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)		&& (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;    }  /* 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.

⌨️ 快捷键说明

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