IA MCU psABI support: changes to libraries
[gcc.git] / gcc / real.c
index cebbe8d7a7ec99de7f99dad0ac16e11b1ee90e85..2d34b6202790f170c1f3a746b92e61b5117d3caf 100644 (file)
@@ -1,5 +1,5 @@
 /* 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,
@@ -2064,9 +2066,10 @@ real_from_string (REAL_VALUE_TYPE *r, const char *str)
             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);
        }
     }
 
@@ -3019,7 +3022,8 @@ const struct real_format ieee_single_format =
     true,
     true,
     true,
-    false
+    false,
+    "ieee_single"
   };
 
 const struct real_format mips_single_format =
@@ -3040,7 +3044,8 @@ const struct real_format mips_single_format =
     true,
     true,
     false,
-    true
+    true,
+    "mips_single"
   };
 
 const struct real_format motorola_single_format =
@@ -3061,7 +3066,8 @@ 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
@@ -3093,7 +3099,8 @@ const struct real_format spu_single_format =
     true,
     true,
     false,
-    false
+    false,
+    "spu_single"
   };
 \f
 /* IEEE double-precision format.  */
@@ -3302,7 +3309,8 @@ const struct real_format ieee_double_format =
     true,
     true,
     true,
-    false
+    false,
+    "ieee_double"
   };
 
 const struct real_format mips_double_format =
@@ -3323,7 +3331,8 @@ const struct real_format mips_double_format =
     true,
     true,
     false,
-    true
+    true,
+    "mips_double"
   };
 
 const struct real_format motorola_double_format =
@@ -3344,7 +3353,8 @@ 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
@@ -3688,7 +3698,8 @@ const struct real_format ieee_extended_motorola_format =
     true,
     true,
     true,
-    true
+    true,
+    "ieee_extended_motorola"
   };
 
 const struct real_format ieee_extended_intel_96_format =
@@ -3709,7 +3720,8 @@ 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 =
@@ -3730,7 +3742,8 @@ 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
@@ -3753,7 +3766,8 @@ const struct real_format ieee_extended_intel_96_round_53_format =
     true,
     true,
     true,
-    false
+    false,
+    "ieee_extended_intel_96_round_53"
   };
 \f
 /* IBM 128-bit extended precision format: a pair of IEEE double precision
@@ -3841,7 +3855,8 @@ const struct real_format ibm_extended_format =
     true,
     true,
     true,
-    false
+    false,
+    "ibm_extended"
   };
 
 const struct real_format mips_extended_format =
@@ -3862,7 +3877,8 @@ const struct real_format mips_extended_format =
     true,
     true,
     false,
-    true
+    true,
+    "mips_extended"
   };
 
 \f
@@ -4125,7 +4141,8 @@ const struct real_format ieee_quad_format =
     true,
     true,
     true,
-    false
+    false,
+    "ieee_quad"
   };
 
 const struct real_format mips_quad_format =
@@ -4146,7 +4163,8 @@ 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
@@ -4446,7 +4464,8 @@ const struct real_format vax_f_format =
     false,
     false,
     false,
-    false
+    false,
+    "vax_f"
   };
 
 const struct real_format vax_d_format =
@@ -4467,7 +4486,8 @@ const struct real_format vax_d_format =
     false,
     false,
     false,
-    false
+    false,
+    "vax_d"
   };
 
 const struct real_format vax_g_format =
@@ -4488,7 +4508,8 @@ 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.  */
@@ -4564,7 +4585,8 @@ const struct real_format decimal_single_format =
     true,
     true,
     true,
-    false
+    false,
+    "decimal_single"
   };
 
 /* Double precision decimal floating point (IEEE 754). */
@@ -4586,7 +4608,8 @@ const struct real_format decimal_double_format =
     true,
     true,
     true,
-    false
+    false,
+    "decimal_double"
   };
 
 /* Quad precision decimal floating point (IEEE 754). */
@@ -4608,7 +4631,8 @@ const struct real_format decimal_quad_format =
     true,
     true,
     true,
-    false
+    false,
+    "decimal_quad"
   };
 \f
 /* Encode half-precision floats.  This routine is used both for the IEEE
@@ -4745,7 +4769,8 @@ const struct real_format ieee_half_format =
     true,
     true,
     true,
-    false
+    false,
+    "ieee_half"
   };
 
 /* ARM's alternative half-precision format, similar to IEEE but with
@@ -4769,7 +4794,8 @@ const struct real_format arm_half_format =
     true,
     true,
     false,
-    false
+    false,
+    "arm_half"
   };
 \f
 /* A synthetic "format" for internal arithmetic.  It's the size of the
@@ -4814,7 +4840,8 @@ const struct real_format real_internal_format =
     false,
     true,
     true,
-    false
+    false,
+    "real_internal"
   };
 \f
 /* Calculate X raised to the integer exponent N in mode MODE and store
@@ -4981,3 +5008,107 @@ get_max_float (const struct real_format *fmt, char *buf, size_t len)
 
   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));
+}