public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* Allow real_format to be passed to more real.h functions
@ 2015-10-29 16:01 Richard Sandiford
  2015-10-29 16:25 ` Richard Biener
  0 siblings, 1 reply; 2+ messages in thread
From: Richard Sandiford @ 2015-10-29 16:01 UTC (permalink / raw)
  To: gcc-patches

Most real.h routines used machine modes to specify the format of
an operation and converted that to a float_format * internally.
Some also had alternative versions that accepted a float_format *.

In an upcoming patch it seemed more convenient for the callers
I was adding to use float_format directly, since the callers need
to examine the format themselves for other reasons.  This patch
therefore replaces the machine_mode arguments with a new class that
allows both machine modes and float_format pointers to be used.

Tested on x86_64-linux-gnu, arm-linux-gnueabi and aarch64-linux-gnu.
OK to install?

Thanks,
Richard


gcc/
	* real.h (format_helper): New.
	(real_convert, exact_real_truncate, real_from_string3, real_to_target)
	(real_from_target, real_nan, real_2expN, real_value_truncate)
	(significand_size, real_from_string2, exact_real_inverse)
	(exact_real_inverse, real_powi, real_trunc, real_floor, real_ceil)
	(real_round, real_isinteger, real_from_integer): Replace
	machine_mode arguments with format_helper arguments.
	* real.c (exact_real_inverse, real_from_string2, real_from_string3)
	(real_from_integer, real_nan, real_2expN, real_convert)
	(real_value_truncate, exact_real_truncate, real_to_target)
	(real_from_target, significand_size, real_powi, real_trunc)
	(real_floor, real_ceil, real_round, real_isinteger): Replace
	machine_mode arguments with format_helper arguments.
	(real_to_target_fmt, real_from_target_fmt): Delete.
	* dfp.h (decimal_real_convert): Replace mode argument with real_format.
	* dfp.c (decimal_to_binary, decimal_real_convert): Replace mode
	argument with real_format.
	* builtins.c (do_real_to_int_conversion): Update type of fn argument.

gcc/java/
	* jcf-parse.c (get_constant): Use real_from_target rather than
	real_from_target_fmt.

diff --git a/gcc/builtins.c b/gcc/builtins.c
index 248c009..583a68e 100644
--- a/gcc/builtins.c
+++ b/gcc/builtins.c
@@ -7275,7 +7275,7 @@ fold_builtin_strlen (location_t loc, tree type, tree arg)
 
 static tree
 do_real_to_int_conversion (tree itype, tree arg,
-			   void (*fn) (REAL_VALUE_TYPE *, machine_mode,
+			   void (*fn) (REAL_VALUE_TYPE *, format_helper,
 				       const REAL_VALUE_TYPE *))
 {
   if (TREE_CODE (arg) != REAL_CST || TREE_OVERFLOW (arg))
diff --git a/gcc/dfp.c b/gcc/dfp.c
index ceb43d1..f3a3b6f 100644
--- a/gcc/dfp.c
+++ b/gcc/dfp.c
@@ -343,13 +343,13 @@ decode_decimal128 (const struct real_format *fmt ATTRIBUTE_UNUSED,
 
 static void
 decimal_to_binary (REAL_VALUE_TYPE *to, const REAL_VALUE_TYPE *from,
-		   machine_mode mode)
+		   const real_format *fmt)
 {
   char string[256];
   const decimal128 *const d128 = (const decimal128 *) from->sig;
 
   decimal128ToString (d128, string);
-  real_from_string3 (to, string, mode);
+  real_from_string3 (to, string, fmt);
 }
 
 
@@ -459,15 +459,13 @@ decimal_round_for_format (const struct real_format *fmt, REAL_VALUE_TYPE *r)
    binary and decimal types.  */
 
 void
-decimal_real_convert (REAL_VALUE_TYPE *r, machine_mode mode,
+decimal_real_convert (REAL_VALUE_TYPE *r, const real_format *fmt,
 		      const REAL_VALUE_TYPE *a)
 {
-  const struct real_format *fmt = REAL_MODE_FORMAT (mode);
-
   if (a->decimal && fmt->b == 10)
     return;
   if (a->decimal)
-      decimal_to_binary (r, a, mode);
+      decimal_to_binary (r, a, fmt);
   else
       decimal_from_binary (r, a);
 }
diff --git a/gcc/dfp.h b/gcc/dfp.h
index 013de8b..a3653c9 100644
--- a/gcc/dfp.h
+++ b/gcc/dfp.h
@@ -34,7 +34,8 @@ void encode_decimal128 (const struct real_format *fmt, long *, const REAL_VALUE_
 int  decimal_do_compare (const REAL_VALUE_TYPE *, const REAL_VALUE_TYPE *, int);
 void decimal_real_from_string (REAL_VALUE_TYPE *, const char *);
 void decimal_round_for_format (const struct real_format *, REAL_VALUE_TYPE *);
-void decimal_real_convert (REAL_VALUE_TYPE *, machine_mode, const REAL_VALUE_TYPE *);
+void decimal_real_convert (REAL_VALUE_TYPE *, const real_format *,
+			   const REAL_VALUE_TYPE *);
 void decimal_real_to_decimal (char *, const REAL_VALUE_TYPE *, size_t, size_t, int);
 void decimal_do_fix_trunc (REAL_VALUE_TYPE *, const REAL_VALUE_TYPE *);
 void decimal_real_maxval (REAL_VALUE_TYPE *, int, machine_mode);
diff --git a/gcc/java/jcf-parse.c b/gcc/java/jcf-parse.c
index bb6e743..88f1a06 100644
--- a/gcc/java/jcf-parse.c
+++ b/gcc/java/jcf-parse.c
@@ -1061,7 +1061,7 @@ get_constant (JCF *jcf, int index)
 	long buf = num;
 	REAL_VALUE_TYPE d;
 
-	real_from_target_fmt (&d, &buf, &ieee_single_format);
+	real_from_target (&d, &buf, &ieee_single_format);
 	value = build_real (float_type_node, d);
 	break;
       }
@@ -1079,7 +1079,7 @@ get_constant (JCF *jcf, int index)
 	else
 	  buf[0] = lo, buf[1] = hi;
 
-	real_from_target_fmt (&d, buf, &ieee_double_format);
+	real_from_target (&d, buf, &ieee_double_format);
 	value = build_real (double_type_node, d);
 	break;
       }
diff --git a/gcc/real.c b/gcc/real.c
index a292126..6d472be 100644
--- a/gcc/real.c
+++ b/gcc/real.c
@@ -1267,11 +1267,11 @@ real_identical (const REAL_VALUE_TYPE *a, const REAL_VALUE_TYPE *b)
   return true;
 }
 
-/* Try to change R into its exact multiplicative inverse in machine
-   mode MODE.  Return true if successful.  */
+/* Try to change R into its exact multiplicative inverse in format FMT.
+   Return true if successful.  */
 
 bool
-exact_real_inverse (machine_mode mode, REAL_VALUE_TYPE *r)
+exact_real_inverse (format_helper fmt, REAL_VALUE_TYPE *r)
 {
   const REAL_VALUE_TYPE *one = real_digit (1);
   REAL_VALUE_TYPE u;
@@ -1287,9 +1287,9 @@ exact_real_inverse (machine_mode mode, REAL_VALUE_TYPE *r)
   if (r->sig[SIGSZ-1] != SIG_MSB)
     return false;
 
-  /* Find the inverse and truncate to the required mode.  */
+  /* Find the inverse and truncate to the required format.  */
   do_divide (&u, one, r);
-  real_convert (&u, mode, &u);
+  real_convert (&u, fmt, &u);
 
   /* The rounding may have overflowed.  */
   if (u.cl != rvc_normal)
@@ -2105,35 +2105,36 @@ real_from_string (REAL_VALUE_TYPE *r, const char *str)
 /* Legacy.  Similar, but return the result directly.  */
 
 REAL_VALUE_TYPE
-real_from_string2 (const char *s, machine_mode mode)
+real_from_string2 (const char *s, format_helper fmt)
 {
   REAL_VALUE_TYPE r;
 
   real_from_string (&r, s);
-  if (mode != VOIDmode)
-    real_convert (&r, mode, &r);
+  if (fmt)
+    real_convert (&r, fmt, &r);
 
   return r;
 }
 
-/* Initialize R from string S and desired MODE. */
+/* Initialize R from string S and desired format FMT. */
 
 void
-real_from_string3 (REAL_VALUE_TYPE *r, const char *s, machine_mode mode)
+real_from_string3 (REAL_VALUE_TYPE *r, const char *s, format_helper fmt)
 {
-  if (DECIMAL_FLOAT_MODE_P (mode))
+  if (fmt.decimal_p ())
     decimal_real_from_string (r, s);
   else
     real_from_string (r, s);
 
-  if (mode != VOIDmode)
-    real_convert (r, mode, r);
+  if (fmt)
+    real_convert (r, fmt, r);
 }
 
-/* Initialize R from the wide_int VAL_IN.  The MODE is not VOIDmode,*/
+/* Initialize R from the wide_int VAL_IN.  Round it to format FMT if
+   FMT is nonnull.  */
 
 void
-real_from_integer (REAL_VALUE_TYPE *r, machine_mode mode,
+real_from_integer (REAL_VALUE_TYPE *r, format_helper fmt,
 		   const wide_int_ref &val_in, signop sgn)
 {
   if (val_in == 0)
@@ -2217,10 +2218,10 @@ real_from_integer (REAL_VALUE_TYPE *r, machine_mode mode,
       normalize (r);
     }
 
-  if (DECIMAL_FLOAT_MODE_P (mode))
+  if (fmt.decimal_p ())
     decimal_from_integer (r);
-  else if (mode != VOIDmode)
-    real_convert (r, mode, r);
+  else if (fmt)
+    real_convert (r, fmt, r);
 }
 
 /* Render R, an integral value, as a floating point constant with no
@@ -2449,13 +2450,8 @@ real_inf (REAL_VALUE_TYPE *r)
 
 bool
 real_nan (REAL_VALUE_TYPE *r, const char *str, int quiet,
-	  machine_mode mode)
+	  format_helper fmt)
 {
-  const struct real_format *fmt;
-
-  fmt = REAL_MODE_FORMAT (mode);
-  gcc_assert (fmt);
-
   if (*str == 0)
     {
       if (quiet)
@@ -2575,7 +2571,7 @@ real_maxval (REAL_VALUE_TYPE *r, int sign, machine_mode mode)
 /* Fills R with 2**N.  */
 
 void
-real_2expN (REAL_VALUE_TYPE *r, int n, machine_mode fmode)
+real_2expN (REAL_VALUE_TYPE *r, int n, format_helper fmt)
 {
   memset (r, 0, sizeof (*r));
 
@@ -2590,8 +2586,8 @@ real_2expN (REAL_VALUE_TYPE *r, int n, machine_mode fmode)
       SET_REAL_EXP (r, n);
       r->sig[SIGSZ-1] = SIG_MSB;
     }
-  if (DECIMAL_FLOAT_MODE_P (fmode))
-    decimal_real_convert (r, fmode, r);
+  if (fmt.decimal_p ())
+    decimal_real_convert (r, fmt, r);
 }
 
 \f
@@ -2613,7 +2609,7 @@ round_for_format (const struct real_format *fmt, REAL_VALUE_TYPE *r)
 	 (e.g. -O0 on '_Decimal32 x = 1.0 + 2.0dd'), but have not
 	 investigated whether this convert needs to be here, or
 	 something else is missing. */
-      decimal_real_convert (r, DFmode, r);
+      decimal_real_convert (r, REAL_MODE_FORMAT (DFmode), r);
     }
 
   p2 = fmt->p;
@@ -2719,21 +2715,16 @@ round_for_format (const struct real_format *fmt, REAL_VALUE_TYPE *r)
   clear_significand_below (r, np2);
 }
 
-/* Extend or truncate to a new mode.  */
+/* Extend or truncate to a new format.  */
 
 void
-real_convert (REAL_VALUE_TYPE *r, machine_mode mode,
+real_convert (REAL_VALUE_TYPE *r, format_helper fmt,
 	      const REAL_VALUE_TYPE *a)
 {
-  const struct real_format *fmt;
-
-  fmt = REAL_MODE_FORMAT (mode);
-  gcc_assert (fmt);
-
   *r = *a;
 
   if (a->decimal || fmt->b == 10)
-    decimal_real_convert (r, mode, a);
+    decimal_real_convert (r, fmt, a);
 
   round_for_format (fmt, r);
 
@@ -2745,32 +2736,28 @@ real_convert (REAL_VALUE_TYPE *r, machine_mode mode,
 /* Legacy.  Likewise, except return the struct directly.  */
 
 REAL_VALUE_TYPE
-real_value_truncate (machine_mode mode, REAL_VALUE_TYPE a)
+real_value_truncate (format_helper fmt, REAL_VALUE_TYPE a)
 {
   REAL_VALUE_TYPE r;
-  real_convert (&r, mode, &a);
+  real_convert (&r, fmt, &a);
   return r;
 }
 
-/* Return true if truncating to MODE is exact.  */
+/* Return true if truncating to FMT is exact.  */
 
 bool
-exact_real_truncate (machine_mode mode, const REAL_VALUE_TYPE *a)
+exact_real_truncate (format_helper fmt, const REAL_VALUE_TYPE *a)
 {
-  const struct real_format *fmt;
   REAL_VALUE_TYPE t;
   int emin2m1;
 
-  fmt = REAL_MODE_FORMAT (mode);
-  gcc_assert (fmt);
-
   /* Don't allow conversion to denormals.  */
   emin2m1 = fmt->emin - 1;
   if (REAL_EXP (a) <= emin2m1)
     return false;
 
-  /* After conversion to the new mode, the value must be identical.  */
-  real_convert (&t, mode, a);
+  /* After conversion to the new format, the value must be identical.  */
+  real_convert (&t, fmt, a);
   return real_identical (&t, a);
 }
 
@@ -2781,8 +2768,8 @@ exact_real_truncate (machine_mode mode, const REAL_VALUE_TYPE *a)
    Legacy: return word 0 for implementing REAL_VALUE_TO_TARGET_SINGLE.  */
 
 long
-real_to_target_fmt (long *buf, const REAL_VALUE_TYPE *r_orig,
-		    const struct real_format *fmt)
+real_to_target (long *buf, const REAL_VALUE_TYPE *r_orig,
+		format_helper fmt)
 {
   REAL_VALUE_TYPE r;
   long buf1;
@@ -2797,62 +2784,32 @@ real_to_target_fmt (long *buf, const REAL_VALUE_TYPE *r_orig,
   return *buf;
 }
 
-/* Similar, but look up the format from MODE.  */
-
-long
-real_to_target (long *buf, const REAL_VALUE_TYPE *r, machine_mode mode)
-{
-  const struct real_format *fmt;
-
-  fmt = REAL_MODE_FORMAT (mode);
-  gcc_assert (fmt);
-
-  return real_to_target_fmt (buf, r, fmt);
-}
-
 /* Read R from the given target format.  Read the words of the result
    in target word order in BUF.  There are always 32 bits in each
    long, no matter the size of the host long.  */
 
 void
-real_from_target_fmt (REAL_VALUE_TYPE *r, const long *buf,
-		      const struct real_format *fmt)
+real_from_target (REAL_VALUE_TYPE *r, const long *buf, format_helper fmt)
 {
   (*fmt->decode) (fmt, r, buf);
 }
 
-/* Similar, but look up the format from MODE.  */
-
-void
-real_from_target (REAL_VALUE_TYPE *r, const long *buf, machine_mode mode)
-{
-  const struct real_format *fmt;
-
-  fmt = REAL_MODE_FORMAT (mode);
-  gcc_assert (fmt);
-
-  (*fmt->decode) (fmt, r, buf);
-}
-
 /* Return the number of bits of the largest binary value that the
-   significand of MODE will hold.  */
+   significand of FMT will hold.  */
 /* ??? Legacy.  Should get access to real_format directly.  */
 
 int
-significand_size (machine_mode mode)
+significand_size (format_helper fmt)
 {
-  const struct real_format *fmt;
-
-  fmt = REAL_MODE_FORMAT (mode);
   if (fmt == NULL)
     return 0;
 
   if (fmt->b == 10)
     {
       /* Return the size in bits of the largest binary value that can be
-	 held by the decimal coefficient for this mode.  This is one more
+	 held by the decimal coefficient for this format.  This is one more
 	 than the number of bits required to hold the largest coefficient
-	 of this mode.  */
+	 of this format.  */
       double log2_10 = 3.3219281;
       return fmt->p * log2_10;
     }
@@ -4862,14 +4819,14 @@ const struct real_format real_internal_format =
     "real_internal"
   };
 \f
-/* Calculate X raised to the integer exponent N in mode MODE and store
+/* Calculate X raised to the integer exponent N in format FMT and store
    the result in R.  Return true if the result may be inexact due to
    loss of precision.  The algorithm is the classic "left-to-right binary
    method" described in section 4.6.3 of Donald Knuth's "Seminumerical
    Algorithms", "The Art of Computer Programming", Volume 2.  */
 
 bool
-real_powi (REAL_VALUE_TYPE *r, machine_mode mode,
+real_powi (REAL_VALUE_TYPE *r, format_helper fmt,
 	   const REAL_VALUE_TYPE *x, HOST_WIDE_INT n)
 {
   unsigned HOST_WIDE_INT bit;
@@ -4911,27 +4868,27 @@ real_powi (REAL_VALUE_TYPE *r, machine_mode mode,
   if (neg)
     inexact |= do_divide (&t, &dconst1, &t);
 
-  real_convert (r, mode, &t);
+  real_convert (r, fmt, &t);
   return inexact;
 }
 
 /* Round X to the nearest integer not larger in absolute value, i.e.
-   towards zero, placing the result in R in mode MODE.  */
+   towards zero, placing the result in R in format FMT.  */
 
 void
-real_trunc (REAL_VALUE_TYPE *r, machine_mode mode,
+real_trunc (REAL_VALUE_TYPE *r, format_helper fmt,
 	    const REAL_VALUE_TYPE *x)
 {
   do_fix_trunc (r, x);
-  if (mode != VOIDmode)
-    real_convert (r, mode, r);
+  if (fmt)
+    real_convert (r, fmt, r);
 }
 
 /* Round X to the largest integer not greater in value, i.e. round
-   down, placing the result in R in mode MODE.  */
+   down, placing the result in R in format FMT.  */
 
 void
-real_floor (REAL_VALUE_TYPE *r, machine_mode mode,
+real_floor (REAL_VALUE_TYPE *r, format_helper fmt,
 	    const REAL_VALUE_TYPE *x)
 {
   REAL_VALUE_TYPE t;
@@ -4939,17 +4896,17 @@ real_floor (REAL_VALUE_TYPE *r, machine_mode mode,
   do_fix_trunc (&t, x);
   if (! real_identical (&t, x) && x->sign)
     do_add (&t, &t, &dconstm1, 0);
-  if (mode != VOIDmode)
-    real_convert (r, mode, &t);
+  if (fmt)
+    real_convert (r, fmt, &t);
   else
     *r = t;
 }
 
 /* Round X to the smallest integer not less then argument, i.e. round
-   up, placing the result in R in mode MODE.  */
+   up, placing the result in R in format FMT.  */
 
 void
-real_ceil (REAL_VALUE_TYPE *r, machine_mode mode,
+real_ceil (REAL_VALUE_TYPE *r, format_helper fmt,
 	   const REAL_VALUE_TYPE *x)
 {
   REAL_VALUE_TYPE t;
@@ -4957,8 +4914,8 @@ real_ceil (REAL_VALUE_TYPE *r, machine_mode mode,
   do_fix_trunc (&t, x);
   if (! real_identical (&t, x) && ! x->sign)
     do_add (&t, &t, &dconst1, 0);
-  if (mode != VOIDmode)
-    real_convert (r, mode, &t);
+  if (fmt)
+    real_convert (r, fmt, &t);
   else
     *r = t;
 }
@@ -4967,13 +4924,13 @@ real_ceil (REAL_VALUE_TYPE *r, machine_mode mode,
    zero.  */
 
 void
-real_round (REAL_VALUE_TYPE *r, machine_mode mode,
+real_round (REAL_VALUE_TYPE *r, format_helper fmt,
 	    const REAL_VALUE_TYPE *x)
 {
   do_add (r, x, &dconsthalf, x->sign);
   do_fix_trunc (r, r);
-  if (mode != VOIDmode)
-    real_convert (r, mode, r);
+  if (fmt)
+    real_convert (r, fmt, r);
 }
 
 /* Set the sign of R to the sign of X.  */
@@ -4987,11 +4944,11 @@ real_copysign (REAL_VALUE_TYPE *r, const REAL_VALUE_TYPE *x)
 /* Check whether the real constant value given is an integer.  */
 
 bool
-real_isinteger (const REAL_VALUE_TYPE *c, machine_mode mode)
+real_isinteger (const REAL_VALUE_TYPE *c, format_helper fmt)
 {
   REAL_VALUE_TYPE cint;
 
-  real_trunc (&cint, mode, c);
+  real_trunc (&cint, fmt, c);
   return real_identical (c, &cint);
 }
 
diff --git a/gcc/real.h b/gcc/real.h
index d3b14e5..df5ccc9 100644
--- a/gcc/real.h
+++ b/gcc/real.h
@@ -193,6 +193,28 @@ extern const struct real_format *
   (FLOAT_MODE_P (MODE) \
    && FLOAT_MODE_FORMAT (MODE)->has_sign_dependent_rounding)
 
+/* This class allows functions in this file to accept a floating-point
+   format as either a mode or an explicit real_format pointer.  In the
+   former case the mode must be VOIDmode (which means "no particular
+   format") or must satisfy SCALAR_FLOAT_MODE_P.  */
+class format_helper
+{
+public:
+  format_helper (const real_format *format) : m_format (format) {}
+  format_helper (machine_mode m);
+  const real_format *operator-> () const { return m_format; }
+  operator const real_format *() const { return m_format; }
+
+  bool decimal_p () const { return m_format && m_format->b == 10; }
+
+private:
+  const real_format *m_format;
+};
+
+inline format_helper::format_helper (machine_mode m)
+  : m_format (m == VOIDmode ? 0 : REAL_MODE_FORMAT (m))
+{}
+
 /* Declare functions in real.c.  */
 
 /* True if the given mode has a NaN representation and the treatment of
@@ -254,12 +276,12 @@ extern bool real_identical (const REAL_VALUE_TYPE *, const REAL_VALUE_TYPE *);
 extern bool real_equal (const REAL_VALUE_TYPE *, const REAL_VALUE_TYPE *);
 extern bool real_less (const REAL_VALUE_TYPE *, const REAL_VALUE_TYPE *);
 
-/* Extend or truncate to a new mode.  */
-extern void real_convert (REAL_VALUE_TYPE *, machine_mode,
+/* Extend or truncate to a new format.  */
+extern void real_convert (REAL_VALUE_TYPE *, format_helper,
 			  const REAL_VALUE_TYPE *);
 
 /* Return true if truncating to NEW is exact.  */
-extern bool exact_real_truncate (machine_mode, const REAL_VALUE_TYPE *);
+extern bool exact_real_truncate (format_helper, const REAL_VALUE_TYPE *);
 
 /* Render R as a decimal floating point constant.  */
 extern void real_to_decimal (char *, const REAL_VALUE_TYPE *, size_t,
@@ -281,24 +303,20 @@ extern HOST_WIDE_INT real_to_integer (const REAL_VALUE_TYPE *);
    the value underflows, +1 if overflows, and 0 otherwise.  */
 extern int real_from_string (REAL_VALUE_TYPE *, const char *);
 /* Wrapper to allow different internal representation for decimal floats. */
-extern void real_from_string3 (REAL_VALUE_TYPE *, const char *, machine_mode);
+extern void real_from_string3 (REAL_VALUE_TYPE *, const char *, format_helper);
 
-extern long real_to_target_fmt (long *, const REAL_VALUE_TYPE *,
-				const struct real_format *);
-extern long real_to_target (long *, const REAL_VALUE_TYPE *, machine_mode);
+extern long real_to_target (long *, const REAL_VALUE_TYPE *, format_helper);
 
-extern void real_from_target_fmt (REAL_VALUE_TYPE *, const long *,
-				  const struct real_format *);
 extern void real_from_target (REAL_VALUE_TYPE *, const long *,
-			      machine_mode);
+			      format_helper);
 
 extern void real_inf (REAL_VALUE_TYPE *);
 
-extern bool real_nan (REAL_VALUE_TYPE *, const char *, int, machine_mode);
+extern bool real_nan (REAL_VALUE_TYPE *, const char *, int, format_helper);
 
 extern void real_maxval (REAL_VALUE_TYPE *, int, machine_mode);
 
-extern void real_2expN (REAL_VALUE_TYPE *, int, machine_mode);
+extern void real_2expN (REAL_VALUE_TYPE *, int, format_helper);
 
 extern unsigned int real_hash (const REAL_VALUE_TYPE *);
 
@@ -370,15 +388,14 @@ extern const struct real_format arm_half_format;
 #define REAL_VALUE_TO_TARGET_DECIMAL32(IN, OUT) \
   ((OUT) = real_to_target (NULL, &(IN), mode_for_size (32, MODE_DECIMAL_FLOAT, 0)))
 
-extern REAL_VALUE_TYPE real_value_truncate (machine_mode,
-					    REAL_VALUE_TYPE);
+extern REAL_VALUE_TYPE real_value_truncate (format_helper, REAL_VALUE_TYPE);
 
 extern REAL_VALUE_TYPE real_value_negate (const REAL_VALUE_TYPE *);
 extern REAL_VALUE_TYPE real_value_abs (const REAL_VALUE_TYPE *);
 
-extern int significand_size (machine_mode);
+extern int significand_size (format_helper);
 
-extern REAL_VALUE_TYPE real_from_string2 (const char *, machine_mode);
+extern REAL_VALUE_TYPE real_from_string2 (const char *, format_helper);
 
 #define REAL_VALUE_ATOF(s, m) \
   real_from_string2 (s, m)
@@ -437,8 +454,8 @@ REAL_VALUE_TYPE real_value_from_int_cst (const_tree, const_tree);
 /* Return a CONST_DOUBLE with value R and mode M.  */
 extern rtx const_double_from_real_value (REAL_VALUE_TYPE, machine_mode);
 
-/* Replace R by 1/R in the given machine mode, if the result is exact.  */
-extern bool exact_real_inverse (machine_mode, REAL_VALUE_TYPE *);
+/* Replace R by 1/R in the given format, if the result is exact.  */
+extern bool exact_real_inverse (format_helper, REAL_VALUE_TYPE *);
 
 /* Return true if arithmetic on values in IMODE that were promoted
    from values in TMODE is equivalent to direct arithmetic on values
@@ -451,25 +468,25 @@ extern tree build_real (tree, REAL_VALUE_TYPE);
 /* Likewise, but first truncate the value to the type.  */
 extern tree build_real_truncate (tree, REAL_VALUE_TYPE);
 
-/* Calculate R as X raised to the integer exponent N in mode MODE.  */
-extern bool real_powi (REAL_VALUE_TYPE *, machine_mode,
+/* Calculate R as X raised to the integer exponent N in format FMT.  */
+extern bool real_powi (REAL_VALUE_TYPE *, format_helper,
 		       const REAL_VALUE_TYPE *, HOST_WIDE_INT);
 
 /* Standard round to integer value functions.  */
-extern void real_trunc (REAL_VALUE_TYPE *, machine_mode,
+extern void real_trunc (REAL_VALUE_TYPE *, format_helper,
 			const REAL_VALUE_TYPE *);
-extern void real_floor (REAL_VALUE_TYPE *, machine_mode,
+extern void real_floor (REAL_VALUE_TYPE *, format_helper,
 			const REAL_VALUE_TYPE *);
-extern void real_ceil (REAL_VALUE_TYPE *, machine_mode,
+extern void real_ceil (REAL_VALUE_TYPE *, format_helper,
 		       const REAL_VALUE_TYPE *);
-extern void real_round (REAL_VALUE_TYPE *, machine_mode,
+extern void real_round (REAL_VALUE_TYPE *, format_helper,
 			const REAL_VALUE_TYPE *);
 
 /* Set the sign of R to the sign of X.  */
 extern void real_copysign (REAL_VALUE_TYPE *, const REAL_VALUE_TYPE *);
 
 /* Check whether the real constant value given is an integer.  */
-extern bool real_isinteger (const REAL_VALUE_TYPE *, machine_mode);
+extern bool real_isinteger (const REAL_VALUE_TYPE *, format_helper);
 extern bool real_isinteger (const REAL_VALUE_TYPE *, HOST_WIDE_INT *);
 
 /* Write into BUF the maximum representable finite floating-point
@@ -480,7 +497,7 @@ extern void get_max_float (const struct real_format *, char *, size_t);
 #ifndef GENERATOR_FILE
 /* real related routines.  */
 extern wide_int real_to_integer (const REAL_VALUE_TYPE *, bool *, int);
-extern void real_from_integer (REAL_VALUE_TYPE *, machine_mode,
+extern void real_from_integer (REAL_VALUE_TYPE *, format_helper,
 			       const wide_int_ref &, signop);
 #endif
 

^ permalink raw reply	[flat|nested] 2+ messages in thread

* Re: Allow real_format to be passed to more real.h functions
  2015-10-29 16:01 Allow real_format to be passed to more real.h functions Richard Sandiford
@ 2015-10-29 16:25 ` Richard Biener
  0 siblings, 0 replies; 2+ messages in thread
From: Richard Biener @ 2015-10-29 16:25 UTC (permalink / raw)
  To: Richard Sandiford, gcc-patches

On October 29, 2015 4:53:59 PM GMT+01:00, Richard Sandiford <richard.sandiford@arm.com> wrote:
>Most real.h routines used machine modes to specify the format of
>an operation and converted that to a float_format * internally.
>Some also had alternative versions that accepted a float_format *.
>
>In an upcoming patch it seemed more convenient for the callers
>I was adding to use float_format directly, since the callers need
>to examine the format themselves for other reasons.  This patch
>therefore replaces the machine_mode arguments with a new class that
>allows both machine modes and float_format pointers to be used.
>
>Tested on x86_64-linux-gnu, arm-linux-gnueabi and aarch64-linux-gnu.
>OK to install?

OK.

Richard.

>Thanks,
>Richard
>
>
>gcc/
>	* real.h (format_helper): New.
>	(real_convert, exact_real_truncate, real_from_string3, real_to_target)
>	(real_from_target, real_nan, real_2expN, real_value_truncate)
>	(significand_size, real_from_string2, exact_real_inverse)
>	(exact_real_inverse, real_powi, real_trunc, real_floor, real_ceil)
>	(real_round, real_isinteger, real_from_integer): Replace
>	machine_mode arguments with format_helper arguments.
>	* real.c (exact_real_inverse, real_from_string2, real_from_string3)
>	(real_from_integer, real_nan, real_2expN, real_convert)
>	(real_value_truncate, exact_real_truncate, real_to_target)
>	(real_from_target, significand_size, real_powi, real_trunc)
>	(real_floor, real_ceil, real_round, real_isinteger): Replace
>	machine_mode arguments with format_helper arguments.
>	(real_to_target_fmt, real_from_target_fmt): Delete.
>	* dfp.h (decimal_real_convert): Replace mode argument with
>real_format.
>	* dfp.c (decimal_to_binary, decimal_real_convert): Replace mode
>	argument with real_format.
>	* builtins.c (do_real_to_int_conversion): Update type of fn argument.
>
>gcc/java/
>	* jcf-parse.c (get_constant): Use real_from_target rather than
>	real_from_target_fmt.
>
>diff --git a/gcc/builtins.c b/gcc/builtins.c
>index 248c009..583a68e 100644
>--- a/gcc/builtins.c
>+++ b/gcc/builtins.c
>@@ -7275,7 +7275,7 @@ fold_builtin_strlen (location_t loc, tree type,
>tree arg)
> 
> static tree
> do_real_to_int_conversion (tree itype, tree arg,
>-			   void (*fn) (REAL_VALUE_TYPE *, machine_mode,
>+			   void (*fn) (REAL_VALUE_TYPE *, format_helper,
> 				       const REAL_VALUE_TYPE *))
> {
>   if (TREE_CODE (arg) != REAL_CST || TREE_OVERFLOW (arg))
>diff --git a/gcc/dfp.c b/gcc/dfp.c
>index ceb43d1..f3a3b6f 100644
>--- a/gcc/dfp.c
>+++ b/gcc/dfp.c
>@@ -343,13 +343,13 @@ decode_decimal128 (const struct real_format *fmt
>ATTRIBUTE_UNUSED,
> 
> static void
> decimal_to_binary (REAL_VALUE_TYPE *to, const REAL_VALUE_TYPE *from,
>-		   machine_mode mode)
>+		   const real_format *fmt)
> {
>   char string[256];
>   const decimal128 *const d128 = (const decimal128 *) from->sig;
> 
>   decimal128ToString (d128, string);
>-  real_from_string3 (to, string, mode);
>+  real_from_string3 (to, string, fmt);
> }
> 
> 
>@@ -459,15 +459,13 @@ decimal_round_for_format (const struct
>real_format *fmt, REAL_VALUE_TYPE *r)
>    binary and decimal types.  */
> 
> void
>-decimal_real_convert (REAL_VALUE_TYPE *r, machine_mode mode,
>+decimal_real_convert (REAL_VALUE_TYPE *r, const real_format *fmt,
> 		      const REAL_VALUE_TYPE *a)
> {
>-  const struct real_format *fmt = REAL_MODE_FORMAT (mode);
>-
>   if (a->decimal && fmt->b == 10)
>     return;
>   if (a->decimal)
>-      decimal_to_binary (r, a, mode);
>+      decimal_to_binary (r, a, fmt);
>   else
>       decimal_from_binary (r, a);
> }
>diff --git a/gcc/dfp.h b/gcc/dfp.h
>index 013de8b..a3653c9 100644
>--- a/gcc/dfp.h
>+++ b/gcc/dfp.h
>@@ -34,7 +34,8 @@ void encode_decimal128 (const struct real_format
>*fmt, long *, const REAL_VALUE_
>int  decimal_do_compare (const REAL_VALUE_TYPE *, const REAL_VALUE_TYPE
>*, int);
> void decimal_real_from_string (REAL_VALUE_TYPE *, const char *);
>void decimal_round_for_format (const struct real_format *,
>REAL_VALUE_TYPE *);
>-void decimal_real_convert (REAL_VALUE_TYPE *, machine_mode, const
>REAL_VALUE_TYPE *);
>+void decimal_real_convert (REAL_VALUE_TYPE *, const real_format *,
>+			   const REAL_VALUE_TYPE *);
>void decimal_real_to_decimal (char *, const REAL_VALUE_TYPE *, size_t,
>size_t, int);
>void decimal_do_fix_trunc (REAL_VALUE_TYPE *, const REAL_VALUE_TYPE *);
> void decimal_real_maxval (REAL_VALUE_TYPE *, int, machine_mode);
>diff --git a/gcc/java/jcf-parse.c b/gcc/java/jcf-parse.c
>index bb6e743..88f1a06 100644
>--- a/gcc/java/jcf-parse.c
>+++ b/gcc/java/jcf-parse.c
>@@ -1061,7 +1061,7 @@ get_constant (JCF *jcf, int index)
> 	long buf = num;
> 	REAL_VALUE_TYPE d;
> 
>-	real_from_target_fmt (&d, &buf, &ieee_single_format);
>+	real_from_target (&d, &buf, &ieee_single_format);
> 	value = build_real (float_type_node, d);
> 	break;
>       }
>@@ -1079,7 +1079,7 @@ get_constant (JCF *jcf, int index)
> 	else
> 	  buf[0] = lo, buf[1] = hi;
> 
>-	real_from_target_fmt (&d, buf, &ieee_double_format);
>+	real_from_target (&d, buf, &ieee_double_format);
> 	value = build_real (double_type_node, d);
> 	break;
>       }
>diff --git a/gcc/real.c b/gcc/real.c
>index a292126..6d472be 100644
>--- a/gcc/real.c
>+++ b/gcc/real.c
>@@ -1267,11 +1267,11 @@ real_identical (const REAL_VALUE_TYPE *a, const
>REAL_VALUE_TYPE *b)
>   return true;
> }
> 
>-/* Try to change R into its exact multiplicative inverse in machine
>-   mode MODE.  Return true if successful.  */
>+/* Try to change R into its exact multiplicative inverse in format
>FMT.
>+   Return true if successful.  */
> 
> bool
>-exact_real_inverse (machine_mode mode, REAL_VALUE_TYPE *r)
>+exact_real_inverse (format_helper fmt, REAL_VALUE_TYPE *r)
> {
>   const REAL_VALUE_TYPE *one = real_digit (1);
>   REAL_VALUE_TYPE u;
>@@ -1287,9 +1287,9 @@ exact_real_inverse (machine_mode mode,
>REAL_VALUE_TYPE *r)
>   if (r->sig[SIGSZ-1] != SIG_MSB)
>     return false;
> 
>-  /* Find the inverse and truncate to the required mode.  */
>+  /* Find the inverse and truncate to the required format.  */
>   do_divide (&u, one, r);
>-  real_convert (&u, mode, &u);
>+  real_convert (&u, fmt, &u);
> 
>   /* The rounding may have overflowed.  */
>   if (u.cl != rvc_normal)
>@@ -2105,35 +2105,36 @@ real_from_string (REAL_VALUE_TYPE *r, const
>char *str)
> /* Legacy.  Similar, but return the result directly.  */
> 
> REAL_VALUE_TYPE
>-real_from_string2 (const char *s, machine_mode mode)
>+real_from_string2 (const char *s, format_helper fmt)
> {
>   REAL_VALUE_TYPE r;
> 
>   real_from_string (&r, s);
>-  if (mode != VOIDmode)
>-    real_convert (&r, mode, &r);
>+  if (fmt)
>+    real_convert (&r, fmt, &r);
> 
>   return r;
> }
> 
>-/* Initialize R from string S and desired MODE. */
>+/* Initialize R from string S and desired format FMT. */
> 
> void
>-real_from_string3 (REAL_VALUE_TYPE *r, const char *s, machine_mode
>mode)
>+real_from_string3 (REAL_VALUE_TYPE *r, const char *s, format_helper
>fmt)
> {
>-  if (DECIMAL_FLOAT_MODE_P (mode))
>+  if (fmt.decimal_p ())
>     decimal_real_from_string (r, s);
>   else
>     real_from_string (r, s);
> 
>-  if (mode != VOIDmode)
>-    real_convert (r, mode, r);
>+  if (fmt)
>+    real_convert (r, fmt, r);
> }
> 
>-/* Initialize R from the wide_int VAL_IN.  The MODE is not VOIDmode,*/
>+/* Initialize R from the wide_int VAL_IN.  Round it to format FMT if
>+   FMT is nonnull.  */
> 
> void
>-real_from_integer (REAL_VALUE_TYPE *r, machine_mode mode,
>+real_from_integer (REAL_VALUE_TYPE *r, format_helper fmt,
> 		   const wide_int_ref &val_in, signop sgn)
> {
>   if (val_in == 0)
>@@ -2217,10 +2218,10 @@ real_from_integer (REAL_VALUE_TYPE *r,
>machine_mode mode,
>       normalize (r);
>     }
> 
>-  if (DECIMAL_FLOAT_MODE_P (mode))
>+  if (fmt.decimal_p ())
>     decimal_from_integer (r);
>-  else if (mode != VOIDmode)
>-    real_convert (r, mode, r);
>+  else if (fmt)
>+    real_convert (r, fmt, r);
> }
> 
> /* Render R, an integral value, as a floating point constant with no
>@@ -2449,13 +2450,8 @@ real_inf (REAL_VALUE_TYPE *r)
> 
> bool
> real_nan (REAL_VALUE_TYPE *r, const char *str, int quiet,
>-	  machine_mode mode)
>+	  format_helper fmt)
> {
>-  const struct real_format *fmt;
>-
>-  fmt = REAL_MODE_FORMAT (mode);
>-  gcc_assert (fmt);
>-
>   if (*str == 0)
>     {
>       if (quiet)
>@@ -2575,7 +2571,7 @@ real_maxval (REAL_VALUE_TYPE *r, int sign,
>machine_mode mode)
> /* Fills R with 2**N.  */
> 
> void
>-real_2expN (REAL_VALUE_TYPE *r, int n, machine_mode fmode)
>+real_2expN (REAL_VALUE_TYPE *r, int n, format_helper fmt)
> {
>   memset (r, 0, sizeof (*r));
> 
>@@ -2590,8 +2586,8 @@ real_2expN (REAL_VALUE_TYPE *r, int n,
>machine_mode fmode)
>       SET_REAL_EXP (r, n);
>       r->sig[SIGSZ-1] = SIG_MSB;
>     }
>-  if (DECIMAL_FLOAT_MODE_P (fmode))
>-    decimal_real_convert (r, fmode, r);
>+  if (fmt.decimal_p ())
>+    decimal_real_convert (r, fmt, r);
> }
> 
> \f>
>@@ -2613,7 +2609,7 @@ round_for_format (const struct real_format *fmt,
>REAL_VALUE_TYPE *r)
> 	 (e.g. -O0 on '_Decimal32 x = 1.0 + 2.0dd'), but have not
> 	 investigated whether this convert needs to be here, or
> 	 something else is missing. */
>-      decimal_real_convert (r, DFmode, r);
>+      decimal_real_convert (r, REAL_MODE_FORMAT (DFmode), r);
>     }
> 
>   p2 = fmt->p;
>@@ -2719,21 +2715,16 @@ round_for_format (const struct real_format
>*fmt, REAL_VALUE_TYPE *r)
>   clear_significand_below (r, np2);
> }
> 
>-/* Extend or truncate to a new mode.  */
>+/* Extend or truncate to a new format.  */
> 
> void
>-real_convert (REAL_VALUE_TYPE *r, machine_mode mode,
>+real_convert (REAL_VALUE_TYPE *r, format_helper fmt,
> 	      const REAL_VALUE_TYPE *a)
> {
>-  const struct real_format *fmt;
>-
>-  fmt = REAL_MODE_FORMAT (mode);
>-  gcc_assert (fmt);
>-
>   *r = *a;
> 
>   if (a->decimal || fmt->b == 10)
>-    decimal_real_convert (r, mode, a);
>+    decimal_real_convert (r, fmt, a);
> 
>   round_for_format (fmt, r);
> 
>@@ -2745,32 +2736,28 @@ real_convert (REAL_VALUE_TYPE *r, machine_mode
>mode,
> /* Legacy.  Likewise, except return the struct directly.  */
> 
> REAL_VALUE_TYPE
>-real_value_truncate (machine_mode mode, REAL_VALUE_TYPE a)
>+real_value_truncate (format_helper fmt, REAL_VALUE_TYPE a)
> {
>   REAL_VALUE_TYPE r;
>-  real_convert (&r, mode, &a);
>+  real_convert (&r, fmt, &a);
>   return r;
> }
> 
>-/* Return true if truncating to MODE is exact.  */
>+/* Return true if truncating to FMT is exact.  */
> 
> bool
>-exact_real_truncate (machine_mode mode, const REAL_VALUE_TYPE *a)
>+exact_real_truncate (format_helper fmt, const REAL_VALUE_TYPE *a)
> {
>-  const struct real_format *fmt;
>   REAL_VALUE_TYPE t;
>   int emin2m1;
> 
>-  fmt = REAL_MODE_FORMAT (mode);
>-  gcc_assert (fmt);
>-
>   /* Don't allow conversion to denormals.  */
>   emin2m1 = fmt->emin - 1;
>   if (REAL_EXP (a) <= emin2m1)
>     return false;
> 
>-  /* After conversion to the new mode, the value must be identical. 
>*/
>-  real_convert (&t, mode, a);
>+  /* After conversion to the new format, the value must be identical. 
>*/
>+  real_convert (&t, fmt, a);
>   return real_identical (&t, a);
> }
> 
>@@ -2781,8 +2768,8 @@ exact_real_truncate (machine_mode mode, const
>REAL_VALUE_TYPE *a)
>Legacy: return word 0 for implementing REAL_VALUE_TO_TARGET_SINGLE.  */
> 
> long
>-real_to_target_fmt (long *buf, const REAL_VALUE_TYPE *r_orig,
>-		    const struct real_format *fmt)
>+real_to_target (long *buf, const REAL_VALUE_TYPE *r_orig,
>+		format_helper fmt)
> {
>   REAL_VALUE_TYPE r;
>   long buf1;
>@@ -2797,62 +2784,32 @@ real_to_target_fmt (long *buf, const
>REAL_VALUE_TYPE *r_orig,
>   return *buf;
> }
> 
>-/* Similar, but look up the format from MODE.  */
>-
>-long
>-real_to_target (long *buf, const REAL_VALUE_TYPE *r, machine_mode
>mode)
>-{
>-  const struct real_format *fmt;
>-
>-  fmt = REAL_MODE_FORMAT (mode);
>-  gcc_assert (fmt);
>-
>-  return real_to_target_fmt (buf, r, fmt);
>-}
>-
> /* Read R from the given target format.  Read the words of the result
>    in target word order in BUF.  There are always 32 bits in each
>    long, no matter the size of the host long.  */
> 
> void
>-real_from_target_fmt (REAL_VALUE_TYPE *r, const long *buf,
>-		      const struct real_format *fmt)
>+real_from_target (REAL_VALUE_TYPE *r, const long *buf, format_helper
>fmt)
> {
>   (*fmt->decode) (fmt, r, buf);
> }
> 
>-/* Similar, but look up the format from MODE.  */
>-
>-void
>-real_from_target (REAL_VALUE_TYPE *r, const long *buf, machine_mode
>mode)
>-{
>-  const struct real_format *fmt;
>-
>-  fmt = REAL_MODE_FORMAT (mode);
>-  gcc_assert (fmt);
>-
>-  (*fmt->decode) (fmt, r, buf);
>-}
>-
> /* Return the number of bits of the largest binary value that the
>-   significand of MODE will hold.  */
>+   significand of FMT will hold.  */
> /* ??? Legacy.  Should get access to real_format directly.  */
> 
> int
>-significand_size (machine_mode mode)
>+significand_size (format_helper fmt)
> {
>-  const struct real_format *fmt;
>-
>-  fmt = REAL_MODE_FORMAT (mode);
>   if (fmt == NULL)
>     return 0;
> 
>   if (fmt->b == 10)
>     {
>     /* Return the size in bits of the largest binary value that can be
>-	 held by the decimal coefficient for this mode.  This is one more
>+	 held by the decimal coefficient for this format.  This is one more
> 	 than the number of bits required to hold the largest coefficient
>-	 of this mode.  */
>+	 of this format.  */
>       double log2_10 = 3.3219281;
>       return fmt->p * log2_10;
>     }
>@@ -4862,14 +4819,14 @@ const struct real_format real_internal_format =
>     "real_internal"
>   };
> \f>
>-/* Calculate X raised to the integer exponent N in mode MODE and store
>+/* Calculate X raised to the integer exponent N in format FMT and
>store
>    the result in R.  Return true if the result may be inexact due to
> loss of precision.  The algorithm is the classic "left-to-right binary
>    method" described in section 4.6.3 of Donald Knuth's "Seminumerical
>    Algorithms", "The Art of Computer Programming", Volume 2.  */
> 
> bool
>-real_powi (REAL_VALUE_TYPE *r, machine_mode mode,
>+real_powi (REAL_VALUE_TYPE *r, format_helper fmt,
> 	   const REAL_VALUE_TYPE *x, HOST_WIDE_INT n)
> {
>   unsigned HOST_WIDE_INT bit;
>@@ -4911,27 +4868,27 @@ real_powi (REAL_VALUE_TYPE *r, machine_mode
>mode,
>   if (neg)
>     inexact |= do_divide (&t, &dconst1, &t);
> 
>-  real_convert (r, mode, &t);
>+  real_convert (r, fmt, &t);
>   return inexact;
> }
> 
> /* Round X to the nearest integer not larger in absolute value, i.e.
>-   towards zero, placing the result in R in mode MODE.  */
>+   towards zero, placing the result in R in format FMT.  */
> 
> void
>-real_trunc (REAL_VALUE_TYPE *r, machine_mode mode,
>+real_trunc (REAL_VALUE_TYPE *r, format_helper fmt,
> 	    const REAL_VALUE_TYPE *x)
> {
>   do_fix_trunc (r, x);
>-  if (mode != VOIDmode)
>-    real_convert (r, mode, r);
>+  if (fmt)
>+    real_convert (r, fmt, r);
> }
> 
> /* Round X to the largest integer not greater in value, i.e. round
>-   down, placing the result in R in mode MODE.  */
>+   down, placing the result in R in format FMT.  */
> 
> void
>-real_floor (REAL_VALUE_TYPE *r, machine_mode mode,
>+real_floor (REAL_VALUE_TYPE *r, format_helper fmt,
> 	    const REAL_VALUE_TYPE *x)
> {
>   REAL_VALUE_TYPE t;
>@@ -4939,17 +4896,17 @@ real_floor (REAL_VALUE_TYPE *r, machine_mode
>mode,
>   do_fix_trunc (&t, x);
>   if (! real_identical (&t, x) && x->sign)
>     do_add (&t, &t, &dconstm1, 0);
>-  if (mode != VOIDmode)
>-    real_convert (r, mode, &t);
>+  if (fmt)
>+    real_convert (r, fmt, &t);
>   else
>     *r = t;
> }
> 
> /* Round X to the smallest integer not less then argument, i.e. round
>-   up, placing the result in R in mode MODE.  */
>+   up, placing the result in R in format FMT.  */
> 
> void
>-real_ceil (REAL_VALUE_TYPE *r, machine_mode mode,
>+real_ceil (REAL_VALUE_TYPE *r, format_helper fmt,
> 	   const REAL_VALUE_TYPE *x)
> {
>   REAL_VALUE_TYPE t;
>@@ -4957,8 +4914,8 @@ real_ceil (REAL_VALUE_TYPE *r, machine_mode mode,
>   do_fix_trunc (&t, x);
>   if (! real_identical (&t, x) && ! x->sign)
>     do_add (&t, &t, &dconst1, 0);
>-  if (mode != VOIDmode)
>-    real_convert (r, mode, &t);
>+  if (fmt)
>+    real_convert (r, fmt, &t);
>   else
>     *r = t;
> }
>@@ -4967,13 +4924,13 @@ real_ceil (REAL_VALUE_TYPE *r, machine_mode
>mode,
>    zero.  */
> 
> void
>-real_round (REAL_VALUE_TYPE *r, machine_mode mode,
>+real_round (REAL_VALUE_TYPE *r, format_helper fmt,
> 	    const REAL_VALUE_TYPE *x)
> {
>   do_add (r, x, &dconsthalf, x->sign);
>   do_fix_trunc (r, r);
>-  if (mode != VOIDmode)
>-    real_convert (r, mode, r);
>+  if (fmt)
>+    real_convert (r, fmt, r);
> }
> 
> /* Set the sign of R to the sign of X.  */
>@@ -4987,11 +4944,11 @@ real_copysign (REAL_VALUE_TYPE *r, const
>REAL_VALUE_TYPE *x)
> /* Check whether the real constant value given is an integer.  */
> 
> bool
>-real_isinteger (const REAL_VALUE_TYPE *c, machine_mode mode)
>+real_isinteger (const REAL_VALUE_TYPE *c, format_helper fmt)
> {
>   REAL_VALUE_TYPE cint;
> 
>-  real_trunc (&cint, mode, c);
>+  real_trunc (&cint, fmt, c);
>   return real_identical (c, &cint);
> }
> 
>diff --git a/gcc/real.h b/gcc/real.h
>index d3b14e5..df5ccc9 100644
>--- a/gcc/real.h
>+++ b/gcc/real.h
>@@ -193,6 +193,28 @@ extern const struct real_format *
>   (FLOAT_MODE_P (MODE) \
>    && FLOAT_MODE_FORMAT (MODE)->has_sign_dependent_rounding)
> 
>+/* This class allows functions in this file to accept a floating-point
>+   format as either a mode or an explicit real_format pointer.  In the
>+   former case the mode must be VOIDmode (which means "no particular
>+   format") or must satisfy SCALAR_FLOAT_MODE_P.  */
>+class format_helper
>+{
>+public:
>+  format_helper (const real_format *format) : m_format (format) {}
>+  format_helper (machine_mode m);
>+  const real_format *operator-> () const { return m_format; }
>+  operator const real_format *() const { return m_format; }
>+
>+  bool decimal_p () const { return m_format && m_format->b == 10; }
>+
>+private:
>+  const real_format *m_format;
>+};
>+
>+inline format_helper::format_helper (machine_mode m)
>+  : m_format (m == VOIDmode ? 0 : REAL_MODE_FORMAT (m))
>+{}
>+
> /* Declare functions in real.c.  */
> 
>/* True if the given mode has a NaN representation and the treatment of
>@@ -254,12 +276,12 @@ extern bool real_identical (const REAL_VALUE_TYPE
>*, const REAL_VALUE_TYPE *);
>extern bool real_equal (const REAL_VALUE_TYPE *, const REAL_VALUE_TYPE
>*);
>extern bool real_less (const REAL_VALUE_TYPE *, const REAL_VALUE_TYPE
>*);
> 
>-/* Extend or truncate to a new mode.  */
>-extern void real_convert (REAL_VALUE_TYPE *, machine_mode,
>+/* Extend or truncate to a new format.  */
>+extern void real_convert (REAL_VALUE_TYPE *, format_helper,
> 			  const REAL_VALUE_TYPE *);
> 
> /* Return true if truncating to NEW is exact.  */
>-extern bool exact_real_truncate (machine_mode, const REAL_VALUE_TYPE
>*);
>+extern bool exact_real_truncate (format_helper, const REAL_VALUE_TYPE
>*);
> 
> /* Render R as a decimal floating point constant.  */
> extern void real_to_decimal (char *, const REAL_VALUE_TYPE *, size_t,
>@@ -281,24 +303,20 @@ extern HOST_WIDE_INT real_to_integer (const
>REAL_VALUE_TYPE *);
>    the value underflows, +1 if overflows, and 0 otherwise.  */
> extern int real_from_string (REAL_VALUE_TYPE *, const char *);
>/* Wrapper to allow different internal representation for decimal
>floats. */
>-extern void real_from_string3 (REAL_VALUE_TYPE *, const char *,
>machine_mode);
>+extern void real_from_string3 (REAL_VALUE_TYPE *, const char *,
>format_helper);
> 
>-extern long real_to_target_fmt (long *, const REAL_VALUE_TYPE *,
>-				const struct real_format *);
>-extern long real_to_target (long *, const REAL_VALUE_TYPE *,
>machine_mode);
>+extern long real_to_target (long *, const REAL_VALUE_TYPE *,
>format_helper);
> 
>-extern void real_from_target_fmt (REAL_VALUE_TYPE *, const long *,
>-				  const struct real_format *);
> extern void real_from_target (REAL_VALUE_TYPE *, const long *,
>-			      machine_mode);
>+			      format_helper);
> 
> extern void real_inf (REAL_VALUE_TYPE *);
> 
>-extern bool real_nan (REAL_VALUE_TYPE *, const char *, int,
>machine_mode);
>+extern bool real_nan (REAL_VALUE_TYPE *, const char *, int,
>format_helper);
> 
> extern void real_maxval (REAL_VALUE_TYPE *, int, machine_mode);
> 
>-extern void real_2expN (REAL_VALUE_TYPE *, int, machine_mode);
>+extern void real_2expN (REAL_VALUE_TYPE *, int, format_helper);
> 
> extern unsigned int real_hash (const REAL_VALUE_TYPE *);
> 
>@@ -370,15 +388,14 @@ extern const struct real_format arm_half_format;
> #define REAL_VALUE_TO_TARGET_DECIMAL32(IN, OUT) \
>((OUT) = real_to_target (NULL, &(IN), mode_for_size (32,
>MODE_DECIMAL_FLOAT, 0)))
> 
>-extern REAL_VALUE_TYPE real_value_truncate (machine_mode,
>-					    REAL_VALUE_TYPE);
>+extern REAL_VALUE_TYPE real_value_truncate (format_helper,
>REAL_VALUE_TYPE);
> 
> extern REAL_VALUE_TYPE real_value_negate (const REAL_VALUE_TYPE *);
> extern REAL_VALUE_TYPE real_value_abs (const REAL_VALUE_TYPE *);
> 
>-extern int significand_size (machine_mode);
>+extern int significand_size (format_helper);
> 
>-extern REAL_VALUE_TYPE real_from_string2 (const char *, machine_mode);
>+extern REAL_VALUE_TYPE real_from_string2 (const char *,
>format_helper);
> 
> #define REAL_VALUE_ATOF(s, m) \
>   real_from_string2 (s, m)
>@@ -437,8 +454,8 @@ REAL_VALUE_TYPE real_value_from_int_cst
>(const_tree, const_tree);
> /* Return a CONST_DOUBLE with value R and mode M.  */
>extern rtx const_double_from_real_value (REAL_VALUE_TYPE,
>machine_mode);
> 
>-/* Replace R by 1/R in the given machine mode, if the result is exact.
> */
>-extern bool exact_real_inverse (machine_mode, REAL_VALUE_TYPE *);
>+/* Replace R by 1/R in the given format, if the result is exact.  */
>+extern bool exact_real_inverse (format_helper, REAL_VALUE_TYPE *);
> 
> /* Return true if arithmetic on values in IMODE that were promoted
>    from values in TMODE is equivalent to direct arithmetic on values
>@@ -451,25 +468,25 @@ extern tree build_real (tree, REAL_VALUE_TYPE);
> /* Likewise, but first truncate the value to the type.  */
> extern tree build_real_truncate (tree, REAL_VALUE_TYPE);
> 
>-/* Calculate R as X raised to the integer exponent N in mode MODE.  */
>-extern bool real_powi (REAL_VALUE_TYPE *, machine_mode,
>+/* Calculate R as X raised to the integer exponent N in format FMT. 
>*/
>+extern bool real_powi (REAL_VALUE_TYPE *, format_helper,
> 		       const REAL_VALUE_TYPE *, HOST_WIDE_INT);
> 
> /* Standard round to integer value functions.  */
>-extern void real_trunc (REAL_VALUE_TYPE *, machine_mode,
>+extern void real_trunc (REAL_VALUE_TYPE *, format_helper,
> 			const REAL_VALUE_TYPE *);
>-extern void real_floor (REAL_VALUE_TYPE *, machine_mode,
>+extern void real_floor (REAL_VALUE_TYPE *, format_helper,
> 			const REAL_VALUE_TYPE *);
>-extern void real_ceil (REAL_VALUE_TYPE *, machine_mode,
>+extern void real_ceil (REAL_VALUE_TYPE *, format_helper,
> 		       const REAL_VALUE_TYPE *);
>-extern void real_round (REAL_VALUE_TYPE *, machine_mode,
>+extern void real_round (REAL_VALUE_TYPE *, format_helper,
> 			const REAL_VALUE_TYPE *);
> 
> /* Set the sign of R to the sign of X.  */
>extern void real_copysign (REAL_VALUE_TYPE *, const REAL_VALUE_TYPE *);
> 
> /* Check whether the real constant value given is an integer.  */
>-extern bool real_isinteger (const REAL_VALUE_TYPE *, machine_mode);
>+extern bool real_isinteger (const REAL_VALUE_TYPE *, format_helper);
> extern bool real_isinteger (const REAL_VALUE_TYPE *, HOST_WIDE_INT *);
> 
> /* Write into BUF the maximum representable finite floating-point
>@@ -480,7 +497,7 @@ extern void get_max_float (const struct real_format
>*, char *, size_t);
> #ifndef GENERATOR_FILE
> /* real related routines.  */
>extern wide_int real_to_integer (const REAL_VALUE_TYPE *, bool *, int);
>-extern void real_from_integer (REAL_VALUE_TYPE *, machine_mode,
>+extern void real_from_integer (REAL_VALUE_TYPE *, format_helper,
> 			       const wide_int_ref &, signop);
> #endif
> 


^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2015-10-29 16:24 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-10-29 16:01 Allow real_format to be passed to more real.h functions Richard Sandiford
2015-10-29 16:25 ` Richard Biener

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).