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); }
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; }
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); }
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)); }
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; }