コード例 #1
0
ファイル: fixed-value.c プロジェクト: nevinhappy/gcc
void
fixed_to_decimal (char *str, const FIXED_VALUE_TYPE *f_orig,
		  size_t buf_size)
{
  REAL_VALUE_TYPE real_value, base_value, fixed_value;

  real_2expN (&base_value, GET_MODE_FBIT (f_orig->mode), f_orig->mode);
  real_from_integer (&real_value, VOIDmode, f_orig->data.low, f_orig->data.high,
		     UNSIGNED_FIXED_POINT_MODE_P (f_orig->mode));
  real_arithmetic (&fixed_value, RDIV_EXPR, &real_value, &base_value);
  real_to_decimal (str, &fixed_value, buf_size, 0, 1);
}
コード例 #2
0
ファイル: fixed-value.c プロジェクト: gmarkall/gcc
void
fixed_to_decimal (char *str, const FIXED_VALUE_TYPE *f_orig,
		  size_t buf_size)
{
  REAL_VALUE_TYPE real_value, base_value, fixed_value;

  signop sgn = UNSIGNED_FIXED_POINT_MODE_P (f_orig->mode) ? UNSIGNED : SIGNED;
  real_2expN (&base_value, GET_MODE_FBIT (f_orig->mode), VOIDmode);
  real_from_integer (&real_value, VOIDmode,
		     wide_int::from (f_orig->data,
				     GET_MODE_PRECISION (f_orig->mode), sgn),
		     sgn);
  real_arithmetic (&fixed_value, RDIV_EXPR, &real_value, &base_value);
  real_to_decimal (str, &fixed_value, buf_size, 0, 1);
}
コード例 #3
0
ファイル: fixed-value.c プロジェクト: gmarkall/gcc
void
fixed_from_string (FIXED_VALUE_TYPE *f, const char *str, machine_mode mode)
{
  REAL_VALUE_TYPE real_value, fixed_value, base_value;
  unsigned int fbit;
  enum fixed_value_range_code temp;
  bool fail;

  f->mode = mode;
  fbit = GET_MODE_FBIT (mode);

  real_from_string (&real_value, str);
  temp = check_real_for_fixed_mode (&real_value, f->mode);
  /* We don't want to warn the case when the _Fract value is 1.0.  */
  if (temp == FIXED_UNDERFLOW
      || temp == FIXED_GT_MAX_EPS
      || (temp == FIXED_MAX_EPS && ALL_ACCUM_MODE_P (f->mode)))
    warning (OPT_Woverflow,
	     "large fixed-point constant implicitly truncated to fixed-point type");
  real_2expN (&base_value, fbit, VOIDmode);
  real_arithmetic (&fixed_value, MULT_EXPR, &real_value, &base_value);
  wide_int w = real_to_integer (&fixed_value, &fail,
				GET_MODE_PRECISION (mode));
  f->data.low = w.ulow ();
  f->data.high = w.elt (1);

  if (temp == FIXED_MAX_EPS && ALL_FRACT_MODE_P (f->mode))
    {
      /* From the spec, we need to evaluate 1 to the maximal value.  */
      f->data.low = -1;
      f->data.high = -1;
      f->data = f->data.zext (GET_MODE_FBIT (f->mode)
				+ GET_MODE_IBIT (f->mode));
    }
  else
    f->data = f->data.ext (SIGNED_FIXED_POINT_MODE_P (f->mode)
			      + GET_MODE_FBIT (f->mode)
			      + GET_MODE_IBIT (f->mode),
			      UNSIGNED_FIXED_POINT_MODE_P (f->mode));
}
コード例 #4
0
ファイル: fixed-value.c プロジェクト: gmarkall/gcc
static enum fixed_value_range_code
check_real_for_fixed_mode (REAL_VALUE_TYPE *real_value, machine_mode mode)
{
  REAL_VALUE_TYPE max_value, min_value, epsilon_value;

  real_2expN (&max_value, GET_MODE_IBIT (mode), VOIDmode);
  real_2expN (&epsilon_value, -GET_MODE_FBIT (mode), VOIDmode);

  if (SIGNED_FIXED_POINT_MODE_P (mode))
    min_value = real_value_negate (&max_value);
  else
    real_from_string (&min_value, "0.0");

  if (real_compare (LT_EXPR, real_value, &min_value))
    return FIXED_UNDERFLOW;
  if (real_compare (EQ_EXPR, real_value, &max_value))
    return FIXED_MAX_EPS;
  real_arithmetic (&max_value, MINUS_EXPR, &max_value, &epsilon_value);
  if (real_compare (GT_EXPR, real_value, &max_value))
    return FIXED_GT_MAX_EPS;
  return FIXED_OK;
}
コード例 #5
0
ファイル: ubsan.c プロジェクト: acoxepochlabs/gcc
tree
ubsan_instrument_float_cast (location_t loc, tree type, tree expr)
{
  tree expr_type = TREE_TYPE (expr);
  tree t, tt, fn, min, max;
  enum machine_mode mode = TYPE_MODE (expr_type);
  int prec = TYPE_PRECISION (type);
  bool uns_p = TYPE_UNSIGNED (type);

  /* Float to integer conversion first truncates toward zero, so
     even signed char c = 127.875f; is not problematic.
     Therefore, we should complain only if EXPR is unordered or smaller
     or equal than TYPE_MIN_VALUE - 1.0 or greater or equal than
     TYPE_MAX_VALUE + 1.0.  */
  if (REAL_MODE_FORMAT (mode)->b == 2)
    {
      /* For maximum, TYPE_MAX_VALUE might not be representable
	 in EXPR_TYPE, e.g. if TYPE is 64-bit long long and
	 EXPR_TYPE is IEEE single float, but TYPE_MAX_VALUE + 1.0 is
	 either representable or infinity.  */
      REAL_VALUE_TYPE maxval = dconst1;
      SET_REAL_EXP (&maxval, REAL_EXP (&maxval) + prec - !uns_p);
      real_convert (&maxval, mode, &maxval);
      max = build_real (expr_type, maxval);

      /* For unsigned, assume -1.0 is always representable.  */
      if (uns_p)
	min = build_minus_one_cst (expr_type);
      else
	{
	  /* TYPE_MIN_VALUE is generally representable (or -inf),
	     but TYPE_MIN_VALUE - 1.0 might not be.  */
	  REAL_VALUE_TYPE minval = dconstm1, minval2;
	  SET_REAL_EXP (&minval, REAL_EXP (&minval) + prec - 1);
	  real_convert (&minval, mode, &minval);
	  real_arithmetic (&minval2, MINUS_EXPR, &minval, &dconst1);
	  real_convert (&minval2, mode, &minval2);
	  if (real_compare (EQ_EXPR, &minval, &minval2)
	      && !real_isinf (&minval))
	    {
	      /* If TYPE_MIN_VALUE - 1.0 is not representable and
		 rounds to TYPE_MIN_VALUE, we need to subtract
		 more.  As REAL_MODE_FORMAT (mode)->p is the number
		 of base digits, we want to subtract a number that
		 will be 1 << (REAL_MODE_FORMAT (mode)->p - 1)
		 times smaller than minval.  */
	      minval2 = dconst1;
	      gcc_assert (prec > REAL_MODE_FORMAT (mode)->p);
	      SET_REAL_EXP (&minval2,
			    REAL_EXP (&minval2) + prec - 1
			    - REAL_MODE_FORMAT (mode)->p + 1);
	      real_arithmetic (&minval2, MINUS_EXPR, &minval, &minval2);
	      real_convert (&minval2, mode, &minval2);
	    }
	  min = build_real (expr_type, minval2);
	}
    }
  else if (REAL_MODE_FORMAT (mode)->b == 10)
    {
      /* For _Decimal128 up to 34 decimal digits, - sign,
	 dot, e, exponent.  */
      char buf[64];
      mpfr_t m;
      int p = REAL_MODE_FORMAT (mode)->p;
      REAL_VALUE_TYPE maxval, minval;

      /* Use mpfr_snprintf rounding to compute the smallest
	 representable decimal number greater or equal than
	 1 << (prec - !uns_p).  */
      mpfr_init2 (m, prec + 2);
      mpfr_set_ui_2exp (m, 1, prec - !uns_p, GMP_RNDN);
      mpfr_snprintf (buf, sizeof buf, "%.*RUe", p - 1, m);
      decimal_real_from_string (&maxval, buf);
      max = build_real (expr_type, maxval);

      /* For unsigned, assume -1.0 is always representable.  */
      if (uns_p)
	min = build_minus_one_cst (expr_type);
      else
	{
	  /* Use mpfr_snprintf rounding to compute the largest
	     representable decimal number less or equal than
	     (-1 << (prec - 1)) - 1.  */
	  mpfr_set_si_2exp (m, -1, prec - 1, GMP_RNDN);
	  mpfr_sub_ui (m, m, 1, GMP_RNDN);
	  mpfr_snprintf (buf, sizeof buf, "%.*RDe", p - 1, m);
	  decimal_real_from_string (&minval, buf);
	  min = build_real (expr_type, minval);
	}
      mpfr_clear (m);
    }
  else
    return NULL_TREE;

  if (flag_sanitize_undefined_trap_on_error)
    fn = build_call_expr_loc (loc, builtin_decl_explicit (BUILT_IN_TRAP), 0);
  else
    {
      /* Create the __ubsan_handle_float_cast_overflow fn call.  */
      tree data = ubsan_create_data ("__ubsan_float_cast_overflow_data", NULL,
				     NULL, ubsan_type_descriptor (expr_type),
				     ubsan_type_descriptor (type), NULL_TREE);
      enum built_in_function bcode
	= flag_sanitize_recover
	  ? BUILT_IN_UBSAN_HANDLE_FLOAT_CAST_OVERFLOW
	  : BUILT_IN_UBSAN_HANDLE_FLOAT_CAST_OVERFLOW_ABORT;
      fn = builtin_decl_explicit (bcode);
      fn = build_call_expr_loc (loc, fn, 2,
				build_fold_addr_expr_loc (loc, data),
				ubsan_encode_value (expr, false));
    }

  t = fold_build2 (UNLE_EXPR, boolean_type_node, expr, min);
  tt = fold_build2 (UNGE_EXPR, boolean_type_node, expr, max);
  return fold_build3 (COND_EXPR, void_type_node,
		      fold_build2 (TRUTH_OR_EXPR, boolean_type_node, t, tt),
		      fn, integer_zero_node);
}