コード例 #1
0
ファイル: fold-const-call.c プロジェクト: shabesoglu/gcc
static bool
fold_const_builtin_load_exponent (real_value *result, const real_value *arg0,
				  const wide_int_ref &arg1,
				  const real_format *format)
{
  /* Bound the maximum adjustment to twice the range of the
     mode's valid exponents.  Use abs to ensure the range is
     positive as a sanity check.  */
  int max_exp_adj = 2 * labs (format->emax - format->emin);

  /* The requested adjustment must be inside this range.  This
     is a preliminary cap to avoid things like overflow, we
     may still fail to compute the result for other reasons.  */
  if (wi::les_p (arg1, -max_exp_adj) || wi::ges_p (arg1, max_exp_adj))
    return false;

  REAL_VALUE_TYPE initial_result;
  real_ldexp (&initial_result, arg0, arg1.to_shwi ());

  /* Ensure we didn't overflow.  */
  if (real_isinf (&initial_result))
    return false;

  /* Only proceed if the target mode can hold the
     resulting value.  */
  *result = real_value_truncate (format, initial_result);
  return real_equal (&initial_result, result);
}
コード例 #2
0
ファイル: fold-const-call.c プロジェクト: gmarkall/gcc
static bool
fold_const_call_sss (real_value *result, combined_fn fn,
		     const real_value *arg0, const wide_int_ref &arg1,
		     const real_format *format)
{
  switch (fn)
    {
    CASE_CFN_LDEXP:
      return fold_const_builtin_load_exponent (result, arg0, arg1, format);

    CASE_CFN_SCALBN:
    CASE_CFN_SCALBLN:
      return (format->b == 2
	      && fold_const_builtin_load_exponent (result, arg0, arg1,
						   format));

    CASE_CFN_POWI:
      /* Avoid the folding if flag_signaling_nans is on and
         operand is a signaling NaN.  */
      if (!flag_unsafe_math_optimizations
	  && flag_signaling_nans
	  && REAL_VALUE_ISSIGNALING_NAN (*arg0))
        return false;

      real_powi (result, format, arg0, arg1.to_shwi ());
      return true;

    default:
      return false;
    }
}
コード例 #3
0
ファイル: fold-const-call.c プロジェクト: shabesoglu/gcc
static bool
do_mpfr_arg2 (real_value *result,
	      int (*func) (mpfr_ptr, long, mpfr_srcptr, mp_rnd_t),
	      const wide_int_ref &arg0, const real_value *arg1,
	      const real_format *format)
{
  if (format->b != 2 || !real_isfinite (arg1))
    return false;

  int prec = format->p;
  mp_rnd_t rnd = format->round_towards_zero ? GMP_RNDZ : GMP_RNDN;
  mpfr_t m;

  mpfr_init2 (m, prec);
  mpfr_from_real (m, arg1, GMP_RNDN);
  mpfr_clear_flags ();
  bool inexact = func (m, arg0.to_shwi (), m, rnd);
  bool ok = do_mpfr_ckconv (result, m, inexact, format);
  mpfr_clear (m);

  return ok;
}
コード例 #4
0
ファイル: fold-const-call.c プロジェクト: shabesoglu/gcc
static bool
fold_const_call_sss (real_value *result, built_in_function fn,
		     const real_value *arg0, const wide_int_ref &arg1,
		     const real_format *format)
{
  switch (fn)
    {
    CASE_FLT_FN (BUILT_IN_LDEXP):
      return fold_const_builtin_load_exponent (result, arg0, arg1, format);

    CASE_FLT_FN (BUILT_IN_SCALBN):
    CASE_FLT_FN (BUILT_IN_SCALBLN):
      return (format->b == 2
	      && fold_const_builtin_load_exponent (result, arg0, arg1,
						   format));

    CASE_FLT_FN (BUILT_IN_POWI):
      real_powi (result, format, arg0, arg1.to_shwi ());
      return true;

    default:
      return false;
    }
}