示例#1
0
FIXED_VALUE_TYPE
fixed_from_double_int (double_int payload, machine_mode mode)
{
  FIXED_VALUE_TYPE value;

  gcc_assert (GET_MODE_BITSIZE (mode) <= HOST_BITS_PER_DOUBLE_INT);

  if (SIGNED_SCALAR_FIXED_POINT_MODE_P (mode))
    value.data = payload.sext (1 + GET_MODE_IBIT (mode) + GET_MODE_FBIT (mode));
  else if (UNSIGNED_SCALAR_FIXED_POINT_MODE_P (mode))
    value.data = payload.zext (GET_MODE_IBIT (mode) + GET_MODE_FBIT (mode));
  else
    gcc_unreachable ();

  value.mode = mode;

  return value;
}
示例#2
0
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);
}
示例#3
0
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
static bool
fixed_saturate1 (machine_mode mode, double_int a, double_int *f,
		 bool sat_p)
{
  bool overflow_p = false;
  bool unsigned_p = UNSIGNED_FIXED_POINT_MODE_P (mode);
  int i_f_bits = GET_MODE_IBIT (mode) + GET_MODE_FBIT (mode);

  if (unsigned_p) /* Unsigned type.  */
    {
      double_int max;
      max.low = -1;
      max.high = -1;
      max = max.zext (i_f_bits);
      if (a.ugt (max))
	{
	  if (sat_p)
	    *f = max;
	  else
	    overflow_p = true;
	}
    }
  else /* Signed type.  */
    {
      double_int max, min;
      max.high = -1;
      max.low = -1;
      max = max.zext (i_f_bits);
      min.high = 0;
      min.low = 1;
      min = min.alshift (i_f_bits, HOST_BITS_PER_DOUBLE_INT);
      min = min.sext (1 + i_f_bits);
      if (a.sgt (max))
	{
	  if (sat_p)
	    *f = max;
	  else
	    overflow_p = true;
	}
      else if (a.slt (min))
	{
	  if (sat_p)
	    *f = min;
	  else
	    overflow_p = true;
	}
    }
  return overflow_p;
}
示例#5
0
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);
}
示例#6
0
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;
}
示例#7
0
static bool
fixed_saturate2 (machine_mode mode, double_int a_high, double_int a_low,
		 double_int *f, bool sat_p)
{
  bool overflow_p = false;
  bool unsigned_p = UNSIGNED_FIXED_POINT_MODE_P (mode);
  int i_f_bits = GET_MODE_IBIT (mode) + GET_MODE_FBIT (mode);

  if (unsigned_p) /* Unsigned type.  */
    {
      double_int max_r, max_s;
      max_r.high = 0;
      max_r.low = 0;
      max_s.high = -1;
      max_s.low = -1;
      max_s = max_s.zext (i_f_bits);
      if (a_high.ugt (max_r)
	  || (a_high == max_r &&
	      a_low.ugt (max_s)))
	{
	  if (sat_p)
	    *f = max_s;
	  else
	    overflow_p = true;
	}
    }
  else /* Signed type.  */
    {
      double_int max_r, max_s, min_r, min_s;
      max_r.high = 0;
      max_r.low = 0;
      max_s.high = -1;
      max_s.low = -1;
      max_s = max_s.zext (i_f_bits);
      min_r.high = -1;
      min_r.low = -1;
      min_s.high = 0;
      min_s.low = 1;
      min_s = min_s.alshift (i_f_bits, HOST_BITS_PER_DOUBLE_INT);
      min_s = min_s.sext (1 + i_f_bits);
      if (a_high.sgt (max_r)
	  || (a_high == max_r &&
	      a_low.ugt (max_s)))
	{
	  if (sat_p)
	    *f = max_s;
	  else
	    overflow_p = true;
	}
      else if (a_high.slt (min_r)
	       || (a_high == min_r &&
		   a_low.ult (min_s)))
	{
	  if (sat_p)
	    *f = min_s;
	  else
	    overflow_p = true;
	}
    }
  return overflow_p;
}