/* real.c - software floating point emulation.
- Copyright (C) 1993-2014 Free Software Foundation, Inc.
+ Copyright (C) 1993-2015 Free Software Foundation, Inc.
Contributed by Stephen L. Moshier (moshier@world.std.com).
Re-written by Richard Henderson <rth@redhat.com>
#include "system.h"
#include "coretypes.h"
#include "tm.h"
+#include "alias.h"
+#include "symtab.h"
#include "tree.h"
#include "diagnostic-core.h"
-#include "real.h"
#include "realmpfr.h"
#include "tm_p.h"
#include "dfp.h"
-#include "wide-int.h"
+#include "rtl.h"
+#include "options.h"
/* The floating point model used internally is not exactly IEEE 754
compliant, and close to the description in the ISO C99 standard,
because the hex digits used in real_from_mpfr did not
start with a digit 8 to f, but the exponent bounds above
should have avoided underflow or overflow. */
- gcc_assert (r->cl = rvc_normal);
+ gcc_assert (r->cl == rvc_normal);
/* Set a sticky bit if mpfr_strtofr was inexact. */
r->sig[0] |= inexact;
+ mpfr_clear (m);
}
}
true,
true,
true,
- false
+ false,
+ "ieee_single"
};
const struct real_format mips_single_format =
true,
true,
false,
- true
+ true,
+ "mips_single"
};
const struct real_format motorola_single_format =
true,
true,
true,
- true
+ true,
+ "motorola_single"
};
/* SPU Single Precision (Extended-Range Mode) format is the same as IEEE
true,
true,
false,
- false
+ false,
+ "spu_single"
};
\f
/* IEEE double-precision format. */
true,
true,
true,
- false
+ false,
+ "ieee_double"
};
const struct real_format mips_double_format =
true,
true,
false,
- true
+ true,
+ "mips_double"
};
const struct real_format motorola_double_format =
true,
true,
true,
- true
+ true,
+ "motorola_double"
};
\f
/* IEEE extended real format. This comes in three flavors: Intel's as
true,
true,
true,
- true
+ true,
+ "ieee_extended_motorola"
};
const struct real_format ieee_extended_intel_96_format =
true,
true,
true,
- false
+ false,
+ "ieee_extended_intel_96"
};
const struct real_format ieee_extended_intel_128_format =
true,
true,
true,
- false
+ false,
+ "ieee_extended_intel_128"
};
/* The following caters to i386 systems that set the rounding precision
true,
true,
true,
- false
+ false,
+ "ieee_extended_intel_96_round_53"
};
\f
/* IBM 128-bit extended precision format: a pair of IEEE double precision
true,
true,
true,
- false
+ false,
+ "ibm_extended"
};
const struct real_format mips_extended_format =
true,
true,
false,
- true
+ true,
+ "mips_extended"
};
\f
true,
true,
true,
- false
+ false,
+ "ieee_quad"
};
const struct real_format mips_quad_format =
true,
true,
false,
- true
+ true,
+ "mips_quad"
};
\f
/* Descriptions of VAX floating point formats can be found beginning at
false,
false,
false,
- false
+ false,
+ "vax_f"
};
const struct real_format vax_d_format =
false,
false,
false,
- false
+ false,
+ "vax_d"
};
const struct real_format vax_g_format =
false,
false,
false,
- false
+ false,
+ "vax_g"
};
\f
/* Encode real R into a single precision DFP value in BUF. */
true,
true,
true,
- false
+ false,
+ "decimal_single"
};
/* Double precision decimal floating point (IEEE 754). */
true,
true,
true,
- false
+ false,
+ "decimal_double"
};
/* Quad precision decimal floating point (IEEE 754). */
true,
true,
true,
- false
+ false,
+ "decimal_quad"
};
\f
/* Encode half-precision floats. This routine is used both for the IEEE
true,
true,
true,
- false
+ false,
+ "ieee_half"
};
/* ARM's alternative half-precision format, similar to IEEE but with
true,
true,
false,
- false
+ false,
+ "arm_half"
};
\f
/* A synthetic "format" for internal arithmetic. It's the size of the
false,
true,
true,
- false
+ false,
+ "real_internal"
};
\f
/* Calculate X raised to the integer exponent N in mode MODE and store
gcc_assert (strlen (buf) < len);
}
+
+/* True if mode M has a NaN representation and
+ the treatment of NaN operands is important. */
+
+bool
+HONOR_NANS (machine_mode m)
+{
+ return MODE_HAS_NANS (m) && !flag_finite_math_only;
+}
+
+bool
+HONOR_NANS (const_tree t)
+{
+ return HONOR_NANS (element_mode (t));
+}
+
+bool
+HONOR_NANS (const_rtx x)
+{
+ return HONOR_NANS (GET_MODE (x));
+}
+
+/* Like HONOR_NANs, but true if we honor signaling NaNs (or sNaNs). */
+
+bool
+HONOR_SNANS (machine_mode m)
+{
+ return flag_signaling_nans && HONOR_NANS (m);
+}
+
+bool
+HONOR_SNANS (const_tree t)
+{
+ return HONOR_SNANS (element_mode (t));
+}
+
+bool
+HONOR_SNANS (const_rtx x)
+{
+ return HONOR_SNANS (GET_MODE (x));
+}
+
+/* As for HONOR_NANS, but true if the mode can represent infinity and
+ the treatment of infinite values is important. */
+
+bool
+HONOR_INFINITIES (machine_mode m)
+{
+ return MODE_HAS_INFINITIES (m) && !flag_finite_math_only;
+}
+
+bool
+HONOR_INFINITIES (const_tree t)
+{
+ return HONOR_INFINITIES (element_mode (t));
+}
+
+bool
+HONOR_INFINITIES (const_rtx x)
+{
+ return HONOR_INFINITIES (GET_MODE (x));
+}
+
+/* Like HONOR_NANS, but true if the given mode distinguishes between
+ positive and negative zero, and the sign of zero is important. */
+
+bool
+HONOR_SIGNED_ZEROS (machine_mode m)
+{
+ return MODE_HAS_SIGNED_ZEROS (m) && flag_signed_zeros;
+}
+
+bool
+HONOR_SIGNED_ZEROS (const_tree t)
+{
+ return HONOR_SIGNED_ZEROS (element_mode (t));
+}
+
+bool
+HONOR_SIGNED_ZEROS (const_rtx x)
+{
+ return HONOR_SIGNED_ZEROS (GET_MODE (x));
+}
+
+/* Like HONOR_NANS, but true if given mode supports sign-dependent rounding,
+ and the rounding mode is important. */
+
+bool
+HONOR_SIGN_DEPENDENT_ROUNDING (machine_mode m)
+{
+ return MODE_HAS_SIGN_DEPENDENT_ROUNDING (m) && flag_rounding_math;
+}
+
+bool
+HONOR_SIGN_DEPENDENT_ROUNDING (const_tree t)
+{
+ return HONOR_SIGN_DEPENDENT_ROUNDING (element_mode (t));
+}
+
+bool
+HONOR_SIGN_DEPENDENT_ROUNDING (const_rtx x)
+{
+ return HONOR_SIGN_DEPENDENT_ROUNDING (GET_MODE (x));
+}