*r = u;
return true;
}
+
+/* Return true if arithmetic on values in IMODE that were promoted
+ from values in TMODE is equivalent to direct arithmetic on values
+ in TMODE. */
+
+bool
+real_can_shorten_arithmetic (enum machine_mode imode, enum machine_mode tmode)
+{
+ const struct real_format *tfmt, *ifmt;
+ tfmt = REAL_MODE_FORMAT (tmode);
+ ifmt = REAL_MODE_FORMAT (imode);
+ /* These conditions are conservative rather than trying to catch the
+ exact boundary conditions; the main case to allow is IEEE float
+ and double. */
+ return (ifmt->b == tfmt->b
+ && ifmt->p > 2 * tfmt->p
+ && ifmt->emin < 2 * tfmt->emin - tfmt->p - 2
+ && ifmt->emin < tfmt->emin - tfmt->emax - tfmt->p - 2
+ && ifmt->emax > 2 * tfmt->emax + 2
+ && ifmt->emax > tfmt->emax - tfmt->emin + tfmt->p + 2
+ && ifmt->round_towards_zero == tfmt->round_towards_zero
+ && (ifmt->has_sign_dependent_rounding
+ == tfmt->has_sign_dependent_rounding)
+ && ifmt->has_nans >= tfmt->has_nans
+ && ifmt->has_inf >= tfmt->has_inf
+ && ifmt->has_signed_zero >= tfmt->has_signed_zero
+ && !MODE_COMPOSITE_P (tmode)
+ && !MODE_COMPOSITE_P (imode));
+}
\f
/* Render R as an integer. */
do_divide (r, r, &pten);
}
-/* Returns the special REAL_VALUE_TYPE enumerated by E. */
+/* Returns the special REAL_VALUE_TYPE corresponding to 'e'. */
const REAL_VALUE_TYPE *
-get_real_const (enum real_value_const e)
+dconst_e_ptr (void)
{
- static REAL_VALUE_TYPE value[rv_max];
+ static REAL_VALUE_TYPE value;
+
+ /* Initialize mathematical constants for constant folding builtins.
+ These constants need to be given to at least 160 bits precision. */
+ if (value.cl == rvc_zero)
+ {
+ mpfr_t m;
+ mpfr_init2 (m, SIGNIFICAND_BITS);
+ mpfr_set_ui (m, 1, GMP_RNDN);
+ mpfr_exp (m, m, GMP_RNDN);
+ real_from_mpfr (&value, m, NULL_TREE, GMP_RNDN);
+ mpfr_clear (m);
+
+ }
+ return &value;
+}
+
+/* Returns the special REAL_VALUE_TYPE corresponding to 1/3. */
- gcc_assert (e < rv_max);
+const REAL_VALUE_TYPE *
+dconst_third_ptr (void)
+{
+ static REAL_VALUE_TYPE value;
/* Initialize mathematical constants for constant folding builtins.
These constants need to be given to at least 160 bits precision. */
- if (value[e].cl == rvc_zero)
- switch (e)
+ if (value.cl == rvc_zero)
{
- case rv_e:
- {
- mpfr_t m;
- mpfr_init2 (m, SIGNIFICAND_BITS);
- mpfr_set_ui (m, 1, GMP_RNDN);
- mpfr_exp (m, m, GMP_RNDN);
- real_from_mpfr (&value[e], m, NULL_TREE, GMP_RNDN);
- mpfr_clear (m);
- }
- break;
- case rv_third:
- real_arithmetic (&value[e], RDIV_EXPR, &dconst1, real_digit (3));
- break;
- case rv_sqrt2:
- {
- mpfr_t m;
- mpfr_init2 (m, SIGNIFICAND_BITS);
- mpfr_sqrt_ui (m, 2, GMP_RNDN);
- real_from_mpfr (&value[e], m, NULL_TREE, GMP_RNDN);
- mpfr_clear (m);
- }
- break;
- default:
- gcc_unreachable();
+ real_arithmetic (&value, RDIV_EXPR, &dconst1, real_digit (3));
}
+ return &value;
+}
+
+/* Returns the special REAL_VALUE_TYPE corresponding to sqrt(2). */
- return &value[e];
+const REAL_VALUE_TYPE *
+dconst_sqrt2_ptr (void)
+{
+ static REAL_VALUE_TYPE value;
+
+ /* Initialize mathematical constants for constant folding builtins.
+ These constants need to be given to at least 160 bits precision. */
+ if (value.cl == rvc_zero)
+ {
+ mpfr_t m;
+ mpfr_init2 (m, SIGNIFICAND_BITS);
+ mpfr_sqrt_ui (m, 2, GMP_RNDN);
+ real_from_mpfr (&value, m, NULL_TREE, GMP_RNDN);
+ mpfr_clear (m);
+ }
+ return &value;
}
/* Fills R with +Inf. */
required to be the value of the long double rounded to the
nearest double. Rounding means we need a slightly smaller
value for LDBL_MAX. */
- clear_significand_bit (r, SIGNIFICAND_BITS - fmt->pnan);
+ clear_significand_bit (r, SIGNIFICAND_BITS - fmt->pnan - 1);
}
}