diff --git a/gcc/ada/gcc-interface/trans.c b/gcc/ada/gcc-interface/trans.c
index f1e2dcb..f00dfee 100644
--- a/gcc/ada/gcc-interface/trans.c
+++ b/gcc/ada/gcc-interface/trans.c
@@ -9048,7 +9048,7 @@ convert_with_check (Entity_Id gnat_type, tree gnu_expr, bool overflowp,
       /* Compute the exact value calc_type'Pred (0.5) at compile time.  */
       fmt = REAL_MODE_FORMAT (TYPE_MODE (calc_type));
       real_2expN (&half_minus_pred_half, -(fmt->p) - 1, TYPE_MODE (calc_type));
-      real_arithmetic (&pred_half, MINUS_EXPR, &dconsthalf,
+      real_arithmetic (&pred_half, MINUS_EXPR, &dconst<1, 2> (),
 		       &half_minus_pred_half);
       gnu_pred_half = build_real (calc_type, pred_half);
 
diff --git a/gcc/builtins.c b/gcc/builtins.c
index 89bea60..85ba6dd 100644
--- a/gcc/builtins.c
+++ b/gcc/builtins.c
@@ -2659,7 +2659,7 @@ expand_builtin_cexpi (tree exp, rtx target)
 	}
 
       narg = fold_build2_loc (loc, COMPLEX_EXPR, ctype,
-			  build_real (type, dconst0), arg);
+			  build_real (type, dconst<0> ()), arg);
 
       /* Make sure not to fold the cexp call again.  */
       call = build1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (fn)), fn);
@@ -4983,7 +4983,7 @@ expand_builtin_signbit (tree exp, rtx target)
     gcc_assert (!fmt->has_signed_zero || !HONOR_SIGNED_ZEROS (fmode));
 
     arg = fold_build2_loc (loc, LT_EXPR, TREE_TYPE (exp), arg,
-		       build_real (TREE_TYPE (arg), dconst0));
+		       build_real (TREE_TYPE (arg), dconst<0> ()));
     return expand_expr (arg, target, VOIDmode, EXPAND_NORMAL);
   }
 
@@ -7642,7 +7642,7 @@ fold_builtin_cabs (location_t loc, tree arg, tree type, tree fndecl)
 static tree
 build_complex_cproj (tree type, bool neg)
 {
-  REAL_VALUE_TYPE rinf, rzero = dconst0;
+  REAL_VALUE_TYPE rinf, rzero = dconst<0> ();
   
   real_inf (&rinf);
   rzero.sign = neg;
@@ -7720,7 +7720,7 @@ fold_builtin_sqrt (location_t loc, tree arg, tree type)
     return NULL_TREE;
 
   /* Calculate the result when the argument is a constant.  */
-  if ((res = do_mpfr_arg1 (arg, type, mpfr_sqrt, &dconst0, NULL, true)))
+  if ((res = do_mpfr_arg1 (arg, type, mpfr_sqrt, &dconst<0> (), NULL, true)))
     return res;
 
   /* Optimize sqrt(expN(x)) = expN(x*0.5).  */
@@ -7730,7 +7730,7 @@ fold_builtin_sqrt (location_t loc, tree arg, tree type)
       tree expfn = TREE_OPERAND (CALL_EXPR_FN (arg), 0);
       arg = fold_build2_loc (loc, MULT_EXPR, type,
 			 CALL_EXPR_ARG (arg, 0),
-			 build_real (type, dconsthalf));
+			 build_real (type, dconst<1, 2> ()));
       return build_call_expr_loc (loc, expfn, 1, arg);
     }
 
@@ -7742,20 +7742,10 @@ fold_builtin_sqrt (location_t loc, tree arg, tree type)
       if (powfn)
 	{
 	  tree arg0 = CALL_EXPR_ARG (arg, 0);
-	  tree tree_root;
-	  /* The inner root was either sqrt or cbrt.  */
-	  /* This was a conditional expression but it triggered a bug
-	     in Sun C 5.5.  */
-	  REAL_VALUE_TYPE dconstroot;
-	  if (BUILTIN_SQRT_P (fcode))
-	    dconstroot = dconsthalf;
-	  else
-	    dconstroot = dconst_third ();
-
-	  /* Adjust for the outer root.  */
-	  SET_REAL_EXP (&dconstroot, REAL_EXP (&dconstroot) - 1);
-	  tree_root = build_real_truncate (type, dconstroot);
-	  return build_call_expr_loc (loc, powfn, 2, arg0, tree_root);
+	  tree arg1 = (BUILTIN_SQRT_P (fcode)
+		       ? build_real (type, dconst<1, 4> ())
+		       : build_real_truncate (type, dconst<1, 6> ()));
+	  return build_call_expr_loc (loc, powfn, 2, arg0, arg1);
 	}
     }
 
@@ -7772,7 +7762,7 @@ fold_builtin_sqrt (location_t loc, tree arg, tree type)
       if (!tree_expr_nonnegative_p (arg0))
 	arg0 = build1 (ABS_EXPR, type, arg0);
       narg1 = fold_build2_loc (loc, MULT_EXPR, type, arg1,
-			   build_real (type, dconsthalf));
+			   build_real (type, dconst<1, 2> ()));
       return build_call_expr_loc (loc, powfn, 2, arg0, narg1);
     }
 
@@ -7803,7 +7793,7 @@ fold_builtin_cbrt (location_t loc, tree arg, tree type)
 	  tree expfn = TREE_OPERAND (CALL_EXPR_FN (arg), 0);
 	  arg = fold_build2_loc (loc, MULT_EXPR, type,
 				 CALL_EXPR_ARG (arg, 0),
-				 build_real_truncate (type, dconst_third ()));
+				 build_real_truncate (type, dconst<1, 3> ()));
 	  return build_call_expr_loc (loc, expfn, 1, arg);
 	}
 
@@ -7815,11 +7805,7 @@ fold_builtin_cbrt (location_t loc, tree arg, tree type)
 	  if (powfn)
 	    {
 	      tree arg0 = CALL_EXPR_ARG (arg, 0);
-	      tree tree_root;
-	      REAL_VALUE_TYPE dconstroot = dconst_third ();
-
-	      SET_REAL_EXP (&dconstroot, REAL_EXP (&dconstroot) - 1);
-	      tree_root = build_real_truncate (type, dconstroot);
+	      tree tree_root = build_real_truncate (type, dconst<1, 6> ());
 	      return build_call_expr_loc (loc, powfn, 2, arg0, tree_root);
 	    }
 	}
@@ -7834,12 +7820,7 @@ fold_builtin_cbrt (location_t loc, tree arg, tree type)
 
 	      if (powfn)
 		{
-		  tree tree_root;
-		  REAL_VALUE_TYPE dconstroot;
-
-		  real_arithmetic (&dconstroot, MULT_EXPR,
-                                   dconst_third_ptr (), dconst_third_ptr ());
-		  tree_root = build_real_truncate (type, dconstroot);
+		  tree tree_root = build_real_truncate (type, dconst<1, 9> ());
 		  return build_call_expr_loc (loc, powfn, 2, arg0, tree_root);
 		}
 	    }
@@ -7855,7 +7836,7 @@ fold_builtin_cbrt (location_t loc, tree arg, tree type)
 	  if (tree_expr_nonnegative_p (arg00))
 	    {
 	      tree powfn = TREE_OPERAND (CALL_EXPR_FN (arg), 0);
-	      tree c = build_real_truncate (type, dconst_third ());
+	      tree c = build_real_truncate (type, dconst<1, 3> ());
 	      tree narg01 = fold_build2_loc (loc, MULT_EXPR, type, arg01, c);
 	      return build_call_expr_loc (loc, powfn, 2, arg00, narg01);
 	    }
@@ -8407,7 +8388,8 @@ fold_builtin_pow (location_t loc, tree fndecl, tree arg0, tree arg1, tree type)
 
   /* Optimize pow(1.0,y) = 1.0.  */
   if (real_onep (arg0))
-    return omit_one_operand_loc (loc, type, build_real (type, dconst1), arg1);
+    return omit_one_operand_loc (loc, type,
+				 build_real (type, dconst<1> ()), arg1);
 
   if (TREE_CODE (arg1) == REAL_CST
       && !TREE_OVERFLOW (arg1))
@@ -8419,22 +8401,22 @@ fold_builtin_pow (location_t loc, tree fndecl, tree arg0, tree arg1, tree type)
       c = TREE_REAL_CST (arg1);
 
       /* Optimize pow(x,0.0) = 1.0.  */
-      if (real_equal (&c, &dconst0))
-	return omit_one_operand_loc (loc, type, build_real (type, dconst1),
-				 arg0);
+      if (real_equal (&c, &dconst<0> ()))
+	return omit_one_operand_loc (loc, type,
+				     build_real (type, dconst<1> ()), arg0);
 
       /* Optimize pow(x,1.0) = x.  */
-      if (real_equal (&c, &dconst1))
+      if (real_equal (&c, &dconst<1> ()))
 	return arg0;
 
       /* Optimize pow(x,-1.0) = 1.0/x.  */
-      if (real_equal (&c, &dconstm1))
+      if (real_equal (&c, &dconst<-1> ()))
 	return fold_build2_loc (loc, RDIV_EXPR, type,
-			    build_real (type, dconst1), arg0);
+			    build_real (type, dconst<1> ()), arg0);
 
       /* Optimize pow(x,0.5) = sqrt(x).  */
       if (flag_unsafe_math_optimizations
-	  && real_equal (&c, &dconsthalf))
+	  && real_equal (&c, &dconst<1, 2> ()))
 	{
 	  tree sqrtfn = mathfn_built_in (type, BUILT_IN_SQRT);
 
@@ -8446,7 +8428,7 @@ fold_builtin_pow (location_t loc, tree fndecl, tree arg0, tree arg1, tree type)
       if (flag_unsafe_math_optimizations)
 	{
 	  const REAL_VALUE_TYPE dconstroot
-	    = real_value_truncate (TYPE_MODE (type), dconst_third ());
+	    = real_value_truncate (TYPE_MODE (type), dconst<1, 3> ());
 
 	  if (real_equal (&c, &dconstroot))
 	    {
@@ -8467,7 +8449,7 @@ fold_builtin_pow (location_t loc, tree fndecl, tree arg0, tree arg1, tree type)
 	      && !TREE_OVERFLOW (arg0)
 	      && (n > 0
 		  || (!flag_trapping_math && !flag_errno_math)
-		  || !real_equal (&TREE_REAL_CST (arg0), &dconst0)))
+		  || !real_equal (&TREE_REAL_CST (arg0), &dconst<0> ())))
 	    {
 	      REAL_VALUE_TYPE x;
 	      bool inexact;
@@ -8506,7 +8488,7 @@ fold_builtin_pow (location_t loc, tree fndecl, tree arg0, tree arg1, tree type)
 	{
 	  tree narg0 = CALL_EXPR_ARG (arg0, 0);
 	  tree narg1 = fold_build2_loc (loc, MULT_EXPR, type, arg1,
-				    build_real (type, dconsthalf));
+				    build_real (type, dconst<1, 2> ()));
 	  return build_call_expr_loc (loc, fndecl, 2, narg0, narg1);
 	}
 
@@ -8516,7 +8498,7 @@ fold_builtin_pow (location_t loc, tree fndecl, tree arg0, tree arg1, tree type)
 	  tree arg = CALL_EXPR_ARG (arg0, 0);
 	  if (tree_expr_nonnegative_p (arg))
 	    {
-	      tree c = build_real_truncate (type, dconst_third ());
+	      tree c = build_real_truncate (type, dconst<1, 3> ());
 	      tree narg1 = fold_build2_loc (loc, MULT_EXPR, type, arg1, c);
 	      return build_call_expr_loc (loc, fndecl, 2, arg, narg1);
 	    }
@@ -8552,7 +8534,8 @@ fold_builtin_powi (location_t loc, tree fndecl ATTRIBUTE_UNUSED,
 
   /* Optimize pow(1.0,y) = 1.0.  */
   if (real_onep (arg0))
-    return omit_one_operand_loc (loc, type, build_real (type, dconst1), arg1);
+    return omit_one_operand_loc (loc, type,
+				 build_real (type, dconst<1> ()), arg1);
 
   if (tree_fits_shwi_p (arg1))
     {
@@ -8570,8 +8553,8 @@ fold_builtin_powi (location_t loc, tree fndecl ATTRIBUTE_UNUSED,
 
       /* Optimize pow(x,0) = 1.0.  */
       if (c == 0)
-	return omit_one_operand_loc (loc, type, build_real (type, dconst1),
-				 arg0);
+	return omit_one_operand_loc (loc, type,
+				     build_real (type, dconst<1> ()), arg0);
 
       /* Optimize pow(x,1) = x.  */
       if (c == 1)
@@ -8580,7 +8563,7 @@ fold_builtin_powi (location_t loc, tree fndecl ATTRIBUTE_UNUSED,
       /* Optimize pow(x,-1) = 1.0/x.  */
       if (c == -1)
 	return fold_build2_loc (loc, RDIV_EXPR, type,
-			   build_real (type, dconst1), arg0);
+				build_real (type, dconst<1> ()), arg0);
     }
 
   return NULL_TREE;
@@ -8922,7 +8905,8 @@ fold_builtin_signbit (location_t loc, tree arg, tree type)
   if (!HONOR_SIGNED_ZEROS (arg))
     return fold_convert (type,
 			 fold_build2_loc (loc, LT_EXPR, boolean_type_node, arg,
-			build_real (TREE_TYPE (arg), dconst0)));
+					  build_real (TREE_TYPE (arg),
+						      dconst<0> ())));
 
   return NULL_TREE;
 }
@@ -9398,7 +9382,7 @@ fold_builtin_modf (location_t loc, tree arg0, tree arg1, tree rettype)
 	break;
       case rvc_inf:
 	/* For +-Inf, return (*arg1 = arg0, +-0).  */
-	frac = dconst0;
+	frac = dconst<0> ();
 	frac.sign = value->sign;
 	trunc = *value;
 	break;
@@ -9536,7 +9520,7 @@ fold_builtin_classify (location_t loc, tree fndecl, tree arg, int builtin_index)
 	{
 	  r = TREE_REAL_CST (arg);
 	  if (real_isinf (&r))
-	    return real_compare (GT_EXPR, &r, &dconst0)
+	    return real_compare (GT_EXPR, &r, &dconst<0> ())
 		   ? integer_one_node : integer_minus_one_node;
 	  else
 	    return integer_zero_node;
@@ -9651,7 +9635,7 @@ fold_builtin_fpclassify (location_t loc, tree *args, int nargs)
 	     (x == 0 ? FP_ZERO : FP_SUBNORMAL))).  */
 
   tmp = fold_build2_loc (loc, EQ_EXPR, integer_type_node, arg,
-		     build_real (type, dconst0));
+		     build_real (type, dconst<0> ()));
   res = fold_build3_loc (loc, COND_EXPR, integer_type_node,
 		     tmp, fp_zero, fp_subnormal);
 
@@ -9967,13 +9951,13 @@ fold_builtin_1 (location_t loc, tree fndecl, tree arg0)
     CASE_FLT_FN (BUILT_IN_ASIN):
       if (validate_arg (arg0, REAL_TYPE))
 	return do_mpfr_arg1 (arg0, type, mpfr_asin,
-			     &dconstm1, &dconst1, true);
+			     &dconst<-1> (), &dconst<1> (), true);
     break;
 
     CASE_FLT_FN (BUILT_IN_ACOS):
       if (validate_arg (arg0, REAL_TYPE))
 	return do_mpfr_arg1 (arg0, type, mpfr_acos,
-			     &dconstm1, &dconst1, true);
+			     &dconst<-1> (), &dconst<1> (), true);
     break;
 
     CASE_FLT_FN (BUILT_IN_ATAN):
@@ -9989,13 +9973,13 @@ fold_builtin_1 (location_t loc, tree fndecl, tree arg0)
     CASE_FLT_FN (BUILT_IN_ACOSH):
       if (validate_arg (arg0, REAL_TYPE))
 	return do_mpfr_arg1 (arg0, type, mpfr_acosh,
-			     &dconst1, NULL, true);
+			     &dconst<1> (), NULL, true);
     break;
 
     CASE_FLT_FN (BUILT_IN_ATANH):
       if (validate_arg (arg0, REAL_TYPE))
 	return do_mpfr_arg1 (arg0, type, mpfr_atanh,
-			     &dconstm1, &dconst1, false);
+			     &dconst<-1> (), &dconst<1> (), false);
     break;
 
     CASE_FLT_FN (BUILT_IN_SIN):
@@ -10062,23 +10046,25 @@ fold_builtin_1 (location_t loc, tree fndecl, tree arg0)
 
     CASE_FLT_FN (BUILT_IN_LOG):
       if (validate_arg (arg0, REAL_TYPE))
-        return do_mpfr_arg1 (arg0, type, mpfr_log, &dconst0, NULL, false);
+	return do_mpfr_arg1 (arg0, type, mpfr_log, &dconst<0> (), NULL, false);
       break;
 
     CASE_FLT_FN (BUILT_IN_LOG2):
       if (validate_arg (arg0, REAL_TYPE))
-        return do_mpfr_arg1 (arg0, type, mpfr_log2, &dconst0, NULL, false);
+	return do_mpfr_arg1 (arg0, type, mpfr_log2,
+			     &dconst<0> (), NULL, false);
       break;
 
     CASE_FLT_FN (BUILT_IN_LOG10):
       if (validate_arg (arg0, REAL_TYPE))
-        return do_mpfr_arg1 (arg0, type, mpfr_log10, &dconst0, NULL, false);
+	return do_mpfr_arg1 (arg0, type, mpfr_log10,
+			     &dconst<0> (), NULL, false);
       break;
 
     CASE_FLT_FN (BUILT_IN_LOG1P):
       if (validate_arg (arg0, REAL_TYPE))
 	return do_mpfr_arg1 (arg0, type, mpfr_log1p,
-			     &dconstm1, NULL, false);
+			     &dconst<-1> (), NULL, false);
     break;
 
     CASE_FLT_FN (BUILT_IN_J0):
@@ -10096,13 +10082,13 @@ fold_builtin_1 (location_t loc, tree fndecl, tree arg0)
     CASE_FLT_FN (BUILT_IN_Y0):
       if (validate_arg (arg0, REAL_TYPE))
 	return do_mpfr_arg1 (arg0, type, mpfr_y0,
-			     &dconst0, NULL, false);
+			     &dconst<0> (), NULL, false);
     break;
 
     CASE_FLT_FN (BUILT_IN_Y1):
       if (validate_arg (arg0, REAL_TYPE))
 	return do_mpfr_arg1 (arg0, type, mpfr_y1,
-			     &dconst0, NULL, false);
+			     &dconst<0> (), NULL, false);
     break;
 
     CASE_FLT_FN (BUILT_IN_NAN):
@@ -10247,7 +10233,7 @@ fold_builtin_2 (location_t loc, tree fndecl, tree arg0, tree arg1)
       if (validate_arg (arg0, INTEGER_TYPE)
 	  && validate_arg (arg1, REAL_TYPE))
 	return do_mpfr_bessel_n (arg0, arg1, type, mpfr_yn,
-				 &dconst0, false);
+				 &dconst<0> (), false);
     break;
 
     CASE_FLT_FN (BUILT_IN_DREM):
diff --git a/gcc/c-family/c-common.c b/gcc/c-family/c-common.c
index 4b64a44..9d1126b 100644
--- a/gcc/c-family/c-common.c
+++ b/gcc/c-family/c-common.c
@@ -4983,7 +4983,7 @@ c_common_truthvalue_conversion (location_t location, tree expr)
 				  : truthvalue_true_node;
 
     case REAL_CST:
-      return real_compare (NE_EXPR, &TREE_REAL_CST (expr), &dconst0)
+      return real_compare (NE_EXPR, &TREE_REAL_CST (expr), &dconst<0> ())
 	     ? truthvalue_true_node
 	     : truthvalue_false_node;
 
diff --git a/gcc/c-family/c-lex.c b/gcc/c-family/c-lex.c
index c69f4a6..30db6a9 100644
--- a/gcc/c-family/c-lex.c
+++ b/gcc/c-family/c-lex.c
@@ -914,9 +914,9 @@ interpret_float (const cpp_token *token, unsigned int flags,
 	}
     }
   /* We also give a warning if the value underflows.  */
-  else if (real_equal (&real, &dconst0)
+  else if (real_equal (&real, &dconst<0> ())
 	   || (const_type != type
-	       && real_equal (&real_trunc, &dconst0)))
+	       && real_equal (&real_trunc, &dconst<0> ())))
     {
       REAL_VALUE_TYPE realvoidmode;
       int oflow = real_from_string (&realvoidmode, copy);
@@ -924,7 +924,7 @@ interpret_float (const cpp_token *token, unsigned int flags,
 			      : (oflow < 0 ? OT_UNDERFLOW : OT_OVERFLOW));
       if (!(flags & CPP_N_USERDEF))
 	{
-	  if (oflow < 0 || !real_equal (&realvoidmode, &dconst0))
+	  if (oflow < 0 || !real_equal (&realvoidmode, &dconst<0> ()))
 	    warning (OPT_Woverflow, "floating constant truncated to zero");
 	}
     }
diff --git a/gcc/c-family/c-ubsan.c b/gcc/c-family/c-ubsan.c
index 672762c..68b76b8 100644
--- a/gcc/c-family/c-ubsan.c
+++ b/gcc/c-family/c-ubsan.c
@@ -65,7 +65,7 @@ ubsan_instrument_division (location_t loc, tree op0, tree op1)
   else if (TREE_CODE (type) == REAL_TYPE
 	   && (flag_sanitize & SANITIZE_FLOAT_DIVIDE))
     t = fold_build2 (EQ_EXPR, boolean_type_node,
-		     op1, build_real (type, dconst0));
+		     op1, build_real (type, dconst<0> ()));
   else
     return NULL_TREE;
 
diff --git a/gcc/config/aarch64/aarch64.c b/gcc/config/aarch64/aarch64.c
index c9fe368..7fe1831 100644
--- a/gcc/config/aarch64/aarch64.c
+++ b/gcc/config/aarch64/aarch64.c
@@ -3768,7 +3768,7 @@ aarch64_float_const_zero_rtx_p (rtx x)
 
   if (REAL_VALUE_MINUS_ZERO (*CONST_DOUBLE_REAL_VALUE (x)))
     return !HONOR_SIGNED_ZEROS (GET_MODE (x));
-  return real_equal (CONST_DOUBLE_REAL_VALUE (x), &dconst0);
+  return real_equal (CONST_DOUBLE_REAL_VALUE (x), &dconst<0> ());
 }
 
 /* Return the fixed registers used for condition codes.  */
diff --git a/gcc/config/c6x/c6x.md b/gcc/config/c6x/c6x.md
index fa89587..7824cd7 100644
--- a/gcc/config/c6x/c6x.md
+++ b/gcc/config/c6x/c6x.md
@@ -2809,7 +2809,8 @@
   "TARGET_FP && flag_reciprocal_math"
 {
   operands[3] = force_reg (SFmode,
-			   const_double_from_real_value (dconst2, SFmode));
+			   const_double_from_real_value (dconst<2> (),
+							 SFmode));
   operands[4] = gen_reg_rtx (SFmode);
   operands[5] = gen_reg_rtx (SFmode);
   operands[6] = gen_reg_rtx (SFmode);
@@ -2834,7 +2835,8 @@
   "TARGET_FP && flag_reciprocal_math"
 {
   operands[3] = force_reg (DFmode,
-			   const_double_from_real_value (dconst2, DFmode));
+			   const_double_from_real_value (dconst<2> (),
+							 DFmode));
   operands[4] = gen_reg_rtx (DFmode);
   operands[5] = gen_reg_rtx (DFmode);
   operands[6] = gen_reg_rtx (DFmode);
diff --git a/gcc/config/fr30/fr30.c b/gcc/config/fr30/fr30.c
index 6afd5d4..20ab6e4 100644
--- a/gcc/config/fr30/fr30.c
+++ b/gcc/config/fr30/fr30.c
@@ -889,7 +889,7 @@ fr30_const_double_is_zero (rtx operand)
   if (operand == NULL || GET_CODE (operand) != CONST_DOUBLE)
     return 0;
 
-  return real_equal (CONST_DOUBLE_REAL_VALUE (operand), &dconst0);
+  return real_equal (CONST_DOUBLE_REAL_VALUE (operand), &dconst<0> ());
 }
 
 /*}}}*/
diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c
index d59b59b..5591f78 100644
--- a/gcc/config/i386/i386.c
+++ b/gcc/config/i386/i386.c
@@ -10511,7 +10511,7 @@ standard_80387_constant_p (rtx x)
      fldz;fchs or fld1;fchs sequence.  */
   if (real_isnegzero (r))
     return 8;
-  if (real_identical (r, &dconstm1))
+  if (real_identical (r, &dconst<-1> ()))
     return 9;
 
   return 0;
@@ -20296,8 +20296,8 @@ ix86_expand_convert_uns_didf_sse (rtx target, rtx input)
 
   /* Subtract off those 0x1.0p52 and 0x1.0p84 biases, to produce values
      in [0,2**32-1] and [0]+[2**32,2**64-1] respectively.  */
-  real_ldexp (&bias_lo_rvt, &dconst1, 52);
-  real_ldexp (&bias_hi_rvt, &dconst1, 84);
+  real_ldexp (&bias_lo_rvt, &dconst<1> (), 52);
+  real_ldexp (&bias_hi_rvt, &dconst<1> (), 84);
   biases = const_double_from_real_value (bias_lo_rvt, DFmode);
   x = const_double_from_real_value (bias_hi_rvt, DFmode);
   biases = gen_rtx_CONST_VECTOR (V2DFmode, gen_rtvec (2, biases, x));
@@ -20339,7 +20339,7 @@ ix86_expand_convert_uns_sidf_sse (rtx target, rtx input)
   fp = gen_reg_rtx (DFmode);
   emit_insn (gen_floatsidf2 (fp, x));
 
-  real_ldexp (&TWO31r, &dconst1, 31);
+  real_ldexp (&TWO31r, &dconst<1> (), 31);
   x = const_double_from_real_value (TWO31r, DFmode);
 
   x = expand_simple_binop (DFmode, PLUS, fp, x, target, 0, OPTAB_DIRECT);
@@ -20361,7 +20361,7 @@ ix86_expand_convert_sign_didf_sse (rtx target, rtx input)
 
   emit_insn (gen_floatsidf2 (fp_hi, gen_highpart (SImode, input)));
 
-  real_ldexp (&TWO32r, &dconst1, 32);
+  real_ldexp (&TWO32r, &dconst<1> (), 32);
   x = const_double_from_real_value (TWO32r, DFmode);
   fp_hi = expand_simple_binop (DFmode, MULT, fp_hi, x, fp_hi, 0, OPTAB_DIRECT);
 
@@ -20381,7 +20381,7 @@ ix86_expand_convert_uns_sisf_sse (rtx target, rtx input)
   REAL_VALUE_TYPE ONE16r;
   rtx fp_hi, fp_lo, int_hi, int_lo, x;
 
-  real_ldexp (&ONE16r, &dconst1, 16);
+  real_ldexp (&ONE16r, &dconst<1> (), 16);
   x = const_double_from_real_value (ONE16r, SFmode);
   int_lo = expand_simple_binop (SImode, AND, input, GEN_INT(0xffff),
 				      NULL, 0, OPTAB_DIRECT);
@@ -20425,7 +20425,7 @@ ix86_expand_vector_convert_uns_vsivsf (rtx target, rtx val)
   emit_insn (cvt (tmp[3], tmp[1]));
   tmp[4] = gen_reg_rtx (fltmode);
   emit_insn (cvt (tmp[4], tmp[2]));
-  real_ldexp (&TWO16r, &dconst1, 16);
+  real_ldexp (&TWO16r, &dconst<1> (), 16);
   tmp[5] = const_double_from_real_value (TWO16r, SFmode);
   tmp[5] = force_reg (fltmode, ix86_build_const_vector (fltmode, 1, tmp[5]));
   tmp[6] = expand_simple_binop (fltmode, MULT, tmp[4], tmp[5], NULL_RTX, 1,
@@ -20454,7 +20454,7 @@ ix86_expand_adjust_ufix_to_sfix_si (rtx val, rtx *xorp)
 
   for (i = 0; i < 3; i++)
     tmp[i] = gen_reg_rtx (mode);
-  real_ldexp (&TWO31r, &dconst1, 31);
+  real_ldexp (&TWO31r, &dconst<1> (), 31);
   two31r = const_double_from_real_value (TWO31r, scalarmode);
   two31r = ix86_build_const_vector (mode, 1, two31r);
   two31r = force_reg (mode, two31r);
@@ -47089,7 +47089,7 @@ void ix86_emit_i387_round (rtx op0, rtx op1)
   e2 = gen_reg_rtx (inmode);
   res = gen_reg_rtx (outmode);
 
-  half = const_double_from_real_value (dconsthalf, inmode);
+  half = const_double_from_real_value (dconst<1, 2> (), inmode);
 
   /* round(a) = sgn(a) * floor(fabs(a) + 0.5) */
 
@@ -47223,7 +47223,7 @@ void ix86_emit_swsqrtsf (rtx res, rtx a, machine_mode mode,
   real_from_integer (&r, VOIDmode, -3, SIGNED);
   mthree = const_double_from_real_value (r, SFmode);
 
-  real_arithmetic (&r, NEGATE_EXPR, &dconsthalf, NULL);
+  real_arithmetic (&r, NEGATE_EXPR, &dconst<1, 2> (), NULL);
   mhalf = const_double_from_real_value (r, SFmode);
   unspec = UNSPEC_RSQRT;
 
@@ -47508,7 +47508,7 @@ ix86_gen_TWO52 (machine_mode mode)
   REAL_VALUE_TYPE TWO52r;
   rtx TWO52;
 
-  real_ldexp (&TWO52r, &dconst1, mode == DFmode ? 52 : 23);
+  real_ldexp (&TWO52r, &dconst<1> (), mode == DFmode ? 52 : 23);
   TWO52 = const_double_from_real_value (TWO52r, mode);
   TWO52 = force_reg (mode, TWO52);
 
@@ -47532,7 +47532,8 @@ ix86_expand_lround (rtx op0, rtx op1)
   /* load nextafter (0.5, 0.0) */
   fmt = REAL_MODE_FORMAT (mode);
   real_2expN (&half_minus_pred_half, -(fmt->p) - 1, mode);
-  real_arithmetic (&pred_half, MINUS_EXPR, &dconsthalf, &half_minus_pred_half);
+  real_arithmetic (&pred_half, MINUS_EXPR, &dconst<1, 2> (),
+		   &half_minus_pred_half);
 
   /* adj = copysign (0.5, op1) */
   adj = force_reg (mode, const_double_from_real_value (pred_half, mode));
@@ -47664,7 +47665,8 @@ ix86_expand_floorceildf_32 (rtx operand0, rtx operand1, bool do_floor)
   /* generate 1.0 or -1.0 */
   one = force_reg (mode,
 	           const_double_from_real_value (do_floor
-						 ? dconst1 : dconstm1, mode));
+						 ? dconst<1> ()
+						 : dconst<-1> (), mode));
 
   /* Compensate: xa = xa - (xa > operand1 ? 1 : 0) */
   tmp = ix86_expand_sse_compare_mask (UNGT, xa, res, !do_floor);
@@ -47723,7 +47725,7 @@ ix86_expand_floorceil (rtx operand0, rtx operand1, bool do_floor)
   expand_float (xa, xi, 0);
 
   /* generate 1.0 */
-  one = force_reg (mode, const_double_from_real_value (dconst1, mode));
+  one = force_reg (mode, const_double_from_real_value (dconst<1> (), mode));
 
   /* Compensate: xa = xa - (xa > operand1 ? 1 : 0) */
   tmp = ix86_expand_sse_compare_mask (UNGT, xa, res, !do_floor);
@@ -47788,7 +47790,8 @@ ix86_expand_rounddf_32 (rtx operand0, rtx operand1)
   dxa = expand_simple_binop (mode, MINUS, xa2, xa, NULL_RTX, 0, OPTAB_DIRECT);
 
   /* generate 0.5, 1.0 and -0.5 */
-  half = force_reg (mode, const_double_from_real_value (dconsthalf, mode));
+  half = force_reg (mode, const_double_from_real_value (dconst<1, 2> (),
+							mode));
   one = expand_simple_binop (mode, PLUS, half, half, NULL_RTX, 0, OPTAB_DIRECT);
   mhalf = expand_simple_binop (mode, MINUS, half, one, NULL_RTX,
 			       0, OPTAB_DIRECT);
@@ -47898,7 +47901,7 @@ ix86_expand_truncdf_32 (rtx operand0, rtx operand1)
   emit_move_insn (res, tmp);
 
   /* generate 1.0 */
-  one = force_reg (mode, const_double_from_real_value (dconst1, mode));
+  one = force_reg (mode, const_double_from_real_value (dconst<1> (), mode));
 
   /* Compensate: res = xa2 - (res > xa ? 1 : 0)  */
   mask = ix86_expand_sse_compare_mask (UNGT, res, xa, false);
@@ -47946,7 +47949,8 @@ ix86_expand_round (rtx operand0, rtx operand1)
   /* load nextafter (0.5, 0.0) */
   fmt = REAL_MODE_FORMAT (mode);
   real_2expN (&half_minus_pred_half, -(fmt->p) - 1, mode);
-  real_arithmetic (&pred_half, MINUS_EXPR, &dconsthalf, &half_minus_pred_half);
+  real_arithmetic (&pred_half, MINUS_EXPR, &dconst<1, 2> (),
+		   &half_minus_pred_half);
 
   /* xa = xa + 0.5 */
   half = force_reg (mode, const_double_from_real_value (pred_half, mode));
@@ -47997,7 +48001,8 @@ ix86_expand_round_sse4 (rtx op0, rtx op1)
   /* load nextafter (0.5, 0.0) */
   fmt = REAL_MODE_FORMAT (mode);
   real_2expN (&half_minus_pred_half, -(fmt->p) - 1, mode);
-  real_arithmetic (&pred_half, MINUS_EXPR, &dconsthalf, &half_minus_pred_half);
+  real_arithmetic (&pred_half, MINUS_EXPR, &dconst<1, 2> (),
+		   &half_minus_pred_half);
   half = const_double_from_real_value (pred_half, mode);
 
   /* e1 = copysign (0.5, op1) */
diff --git a/gcc/config/i386/i386.md b/gcc/config/i386/i386.md
index 5fcebb5..140bc0f 100644
--- a/gcc/config/i386/i386.md
+++ b/gcc/config/i386/i386.md
@@ -4643,7 +4643,7 @@
   if (optimize_insn_for_size_p ())
     FAIL;
 
-  real_ldexp (&TWO31r, &dconst1, 31);
+  real_ldexp (&TWO31r, &dconst<1> (), 31);
   two31 = const_double_from_real_value (TWO31r, mode);
   two31 = ix86_build_const_vector (vecmode, true, two31);
   operands[2] = force_reg (vecmode, two31);
diff --git a/gcc/config/i386/sse.md b/gcc/config/i386/sse.md
index 9b7a338..a016b26 100644
--- a/gcc/config/i386/sse.md
+++ b/gcc/config/i386/sse.md
@@ -5432,7 +5432,7 @@
   rtx x;
   int i;
 
-  real_ldexp (&TWO32r, &dconst1, 32);
+  real_ldexp (&TWO32r, &dconst<1> (), 32);
   x = const_double_from_real_value (TWO32r, DFmode);
 
   operands[3] = force_reg (V2DFmode, CONST0_RTX (V2DFmode));
@@ -5463,7 +5463,7 @@
   rtx x;
   int i;
 
-  real_ldexp (&TWO32r, &dconst1, 32);
+  real_ldexp (&TWO32r, &dconst<1> (), 32);
   x = const_double_from_real_value (TWO32r, DFmode);
 
   operands[3] = force_reg (V2DFmode, CONST0_RTX (V2DFmode));
@@ -5483,7 +5483,7 @@
   rtx x, tmp[6];
   int i;
 
-  real_ldexp (&TWO32r, &dconst1, 32);
+  real_ldexp (&TWO32r, &dconst<1> (), 32);
   x = const_double_from_real_value (TWO32r, DFmode);
 
   tmp[0] = force_reg (V4DFmode, CONST0_RTX (V4DFmode));
@@ -5508,7 +5508,7 @@
   REAL_VALUE_TYPE TWO32r;
   rtx k, x, tmp[4];
 
-  real_ldexp (&TWO32r, &dconst1, 32);
+  real_ldexp (&TWO32r, &dconst<1> (), 32);
   x = const_double_from_real_value (TWO32r, DFmode);
 
   tmp[0] = force_reg (V8DFmode, CONST0_RTX (V8DFmode));
@@ -5534,7 +5534,7 @@
   rtx x, tmp[5];
   int i;
 
-  real_ldexp (&TWO32r, &dconst1, 32);
+  real_ldexp (&TWO32r, &dconst<1> (), 32);
   x = const_double_from_real_value (TWO32r, DFmode);
 
   tmp[0] = force_reg (V4DFmode, CONST0_RTX (V4DFmode));
@@ -5557,7 +5557,7 @@
   REAL_VALUE_TYPE TWO32r;
   rtx k, x, tmp[3];
 
-  real_ldexp (&TWO32r, &dconst1, 32);
+  real_ldexp (&TWO32r, &dconst<1> (), 32);
   x = const_double_from_real_value (TWO32r, DFmode);
 
   tmp[0] = force_reg (V8DFmode, CONST0_RTX (V8DFmode));
@@ -14881,7 +14881,8 @@
   /* load nextafter (0.5, 0.0) */
   fmt = REAL_MODE_FORMAT (scalar_mode);
   real_2expN (&half_minus_pred_half, -(fmt->p) - 1, scalar_mode);
-  real_arithmetic (&pred_half, MINUS_EXPR, &dconsthalf, &half_minus_pred_half);
+  real_arithmetic (&pred_half, MINUS_EXPR, &dconst<1, 2> (),
+		   &half_minus_pred_half);
   half = const_double_from_real_value (pred_half, scalar_mode);
 
   vec_half = ix86_build_const_vector (<MODE>mode, true, half);
diff --git a/gcc/config/m68k/m68k.c b/gcc/config/m68k/m68k.c
index bfc19f3..e7226ac 100644
--- a/gcc/config/m68k/m68k.c
+++ b/gcc/config/m68k/m68k.c
@@ -4365,7 +4365,7 @@ floating_exact_log2 (rtx x)
 
   r = CONST_DOUBLE_REAL_VALUE (x);
 
-  if (real_less (r, &dconst1))
+  if (real_less (r, &dconst<1> ()))
     return 0;
 
   exp = real_exponent (r);
diff --git a/gcc/config/rs6000/rs6000.c b/gcc/config/rs6000/rs6000.c
index c00d730..39a9a75 100644
--- a/gcc/config/rs6000/rs6000.c
+++ b/gcc/config/rs6000/rs6000.c
@@ -31944,7 +31944,7 @@ rs6000_emit_swdiv (rtx dst, rtx n, rtx d, bool note_p)
 
   gcc_assert (code != CODE_FOR_nothing);
 
-  one = rs6000_load_constant_and_splat (mode, dconst1);
+  one = rs6000_load_constant_and_splat (mode, dconst<1> ());
 
   /* x0 = 1./d estimate */
   x0 = gen_reg_rtx (mode);
@@ -32684,7 +32684,7 @@ rs6000_scale_v2df (rtx tgt, rtx src, int scale)
   rtvec v = rtvec_alloc (2);
   rtx elt;
   rtx scale_vec = gen_reg_rtx (V2DFmode);
-  (void)real_powi (&r_pow, DFmode, &dconst2, hwi_scale);
+  (void)real_powi (&r_pow, DFmode, &dconst<2> (), hwi_scale);
   elt = const_double_from_real_value (r_pow, DFmode);
   RTVEC_ELT (v, 0) = elt;
   RTVEC_ELT (v, 1) = elt;
diff --git a/gcc/config/rs6000/rs6000.md b/gcc/config/rs6000/rs6000.md
index cf40f10..ae4f492 100644
--- a/gcc/config/rs6000/rs6000.md
+++ b/gcc/config/rs6000/rs6000.md
@@ -10578,7 +10578,7 @@
   operands[14] = force_const_mem (DFmode,
 				  const_double_from_real_value (rv, DFmode));
   operands[15] = force_const_mem (DFmode,
-				  const_double_from_real_value (dconst0,
+				  const_double_from_real_value (dconst<0> (),
 								DFmode));
   if (TARGET_TOC)
     {
diff --git a/gcc/config/sh/sh.c b/gcc/config/sh/sh.c
index 92e9f9f..f7543d1 100644
--- a/gcc/config/sh/sh.c
+++ b/gcc/config/sh/sh.c
@@ -10005,8 +10005,7 @@ fp_zero_operand (rtx op)
   if (GET_MODE (op) != SFmode)
     return false;
 
-  r = CONST_DOUBLE_REAL_VALUE (op);
-  return real_equal (r, &dconst0) && ! REAL_VALUE_MINUS_ZERO (*r);
+  return real_equal (r, &dconst<0> ()) && ! REAL_VALUE_MINUS_ZERO (*r);
 }
 
 /* Returns true if OP is a floating point value with value 1.0.  */
@@ -10016,7 +10015,7 @@ fp_one_operand (rtx op)
   if (GET_MODE (op) != SFmode)
     return false;
 
-  return real_equal (CONST_DOUBLE_REAL_VALUE (op), &dconst1);
+  return real_equal (CONST_DOUBLE_REAL_VALUE (op), &dconst<1> ());
 }
 
 /* Return the TLS type for TLS symbols.  */
diff --git a/gcc/config/xtensa/predicates.md b/gcc/config/xtensa/predicates.md
index 00f2370..81e5ebe 100644
--- a/gcc/config/xtensa/predicates.md
+++ b/gcc/config/xtensa/predicates.md
@@ -150,7 +150,7 @@
 (define_predicate "const_float_1_operand"
   (match_code "const_double")
 {
-  return real_equal (CONST_DOUBLE_REAL_VALUE (op), &dconst1);
+  return real_equal (CONST_DOUBLE_REAL_VALUE (op), &dconst<1> ());
 })
 
 (define_predicate "fpmem_offset_operand"
diff --git a/gcc/cprop.c b/gcc/cprop.c
index 4cb8586..f983350 100644
--- a/gcc/cprop.c
+++ b/gcc/cprop.c
@@ -1352,7 +1352,7 @@ implicit_set_cond_p (const_rtx cond)
       /* ??? The complex and vector checks are not implemented yet.  We just
 	 always return zero for them.  */
       if (CONST_DOUBLE_AS_FLOAT_P (cst)
-	  && real_equal (CONST_DOUBLE_REAL_VALUE (cst), &dconst0))
+	  && real_equal (CONST_DOUBLE_REAL_VALUE (cst), &dconst<0> ()))
 	return 0;
       else
 	return 0;
diff --git a/gcc/dfp.c b/gcc/dfp.c
index ceb43d1..6dbdcad 100644
--- a/gcc/dfp.c
+++ b/gcc/dfp.c
@@ -115,22 +115,22 @@ decimal_to_decnumber (const REAL_VALUE_TYPE *r, decNumber *dn)
 	  /* dconst{1,2,m1,half} are used in various places in
 	     the middle-end and optimizers, allow them here
 	     as an exception by converting them to decimal.  */
-	  if (memcmp (r, &dconst1, sizeof (*r)) == 0)
+	  if (memcmp (r, &dconst<1> (), sizeof (*r)) == 0)
 	    {
 	      decNumberFromString (dn, "1", &set);
 	      break;
 	    }
-	  if (memcmp (r, &dconst2, sizeof (*r)) == 0)
+	  if (memcmp (r, &dconst<2> (), sizeof (*r)) == 0)
 	    {
 	      decNumberFromString (dn, "2", &set);
 	      break;
 	    }
-	  if (memcmp (r, &dconstm1, sizeof (*r)) == 0)
+	  if (memcmp (r, &dconst<-1> (), sizeof (*r)) == 0)
 	    {
 	      decNumberFromString (dn, "-1", &set);
 	      break;
 	    }
-	  if (memcmp (r, &dconsthalf, sizeof (*r)) == 0)
+	  if (memcmp (r, &dconst<1, 2> (), sizeof (*r)) == 0)
 	    {
 	      decNumberFromString (dn, "0.5", &set);
 	      break;
diff --git a/gcc/doc/match-and-simplify.texi b/gcc/doc/match-and-simplify.texi
index c5c2b7e..cc1f573 100644
--- a/gcc/doc/match-and-simplify.texi
+++ b/gcc/doc/match-and-simplify.texi
@@ -165,7 +165,7 @@ chain conditions avoiding nesting @code{if}s too much:
  (switch
   /* a CMP (-0) -> a CMP 0  */
   (if (REAL_VALUE_MINUS_ZERO (TREE_REAL_CST (@@1)))
-   (cmp @@0 @{ build_real (TREE_TYPE (@@1), dconst0); @}))
+   (cmp @@0 @{ build_real (TREE_TYPE (@@1), dconst<0> ()); @}))
   /* x != NaN is always true, other ops are always false.  */
   (if (REAL_VALUE_ISNAN (TREE_REAL_CST (@@1))
        && ! HONOR_SNANS (@@1))
@@ -180,7 +180,7 @@ Is equal to
  (switch
   /* a CMP (-0) -> a CMP 0  */
   (if (REAL_VALUE_MINUS_ZERO (TREE_REAL_CST (@@1)))
-   (cmp @@0 @{ build_real (TREE_TYPE (@@1), dconst0); @})
+   (cmp @@0 @{ build_real (TREE_TYPE (@@1), dconst<0> ()); @})
    /* x != NaN is always true, other ops are always false.  */
    (if (REAL_VALUE_ISNAN (TREE_REAL_CST (@@1))
         && ! HONOR_SNANS (@@1))
@@ -310,7 +310,8 @@ be added to a new @code{for}.  For example
 (define_operator_list POW BUILT_IN_POWF BUILT_IN_POW BUILT_IN_POWL)
 (simplify
  (SQRT (POW @@0 @@1))
- (POW (abs @@0) (mult @@1 @{ built_real (TREE_TYPE (@@1), dconsthalf); @})))
+ (POW (abs @@0) (mult @@1 @{ build_real (TREE_TYPE (@@1),
+                                      dconst<1, 2> ()); @})))
 @end smallexample
 
 is the same as
@@ -320,7 +321,8 @@ is the same as
      POW (BUILT_IN_POWF BUILT_IN_POW BUILT_IN_POWL)
  (simplify
   (SQRT (POW @@0 @@1))
-  (POW (abs @@0) (mult @@1 @{ built_real (TREE_TYPE (@@1), dconsthalf); @}))))
+  (POW (abs @@0) (mult @@1 @{ build_real (TREE_TYPE (@@1),
+                                       dconst<1, 2> ()); @}))))
 @end smallexample
 
 Another building block are @code{with} expressions in the
diff --git a/gcc/emit-rtl.c b/gcc/emit-rtl.c
index c418c24..7d1dc5e 100644
--- a/gcc/emit-rtl.c
+++ b/gcc/emit-rtl.c
@@ -104,12 +104,6 @@ rtx const_tiny_rtx[4][(int) MAX_MACHINE_MODE];
 
 rtx const_true_rtx;
 
-REAL_VALUE_TYPE dconst0;
-REAL_VALUE_TYPE dconst1;
-REAL_VALUE_TYPE dconst2;
-REAL_VALUE_TYPE dconstm1;
-REAL_VALUE_TYPE dconsthalf;
-
 /* Record fixed-point constant 0 and 1.  */
 FIXED_VALUE_TYPE fconst0[MAX_FCONST0];
 FIXED_VALUE_TYPE fconst1[MAX_FCONST1];
@@ -5878,7 +5872,6 @@ init_emit_once (void)
 {
   int i;
   machine_mode mode;
-  machine_mode double_mode;
 
   /* Initialize the CONST_INT, CONST_WIDE_INT, CONST_DOUBLE,
      CONST_FIXED, and memory attribute hash tables.  */
@@ -5917,20 +5910,10 @@ init_emit_once (void)
 
   double_mode = mode_for_size (DOUBLE_TYPE_SIZE, MODE_FLOAT, 0);
 
-  real_from_integer (&dconst0, double_mode, 0, SIGNED);
-  real_from_integer (&dconst1, double_mode, 1, SIGNED);
-  real_from_integer (&dconst2, double_mode, 2, SIGNED);
-
-  dconstm1 = dconst1;
-  dconstm1.sign = 1;
-
-  dconsthalf = dconst1;
-  SET_REAL_EXP (&dconsthalf, REAL_EXP (&dconsthalf) - 1);
-
   for (i = 0; i < 3; i++)
     {
       const REAL_VALUE_TYPE *const r =
-	(i == 0 ? &dconst0 : i == 1 ? &dconst1 : &dconst2);
+	(i == 0 ? &dconst<0> () : i == 1 ? &dconst<1> () : &dconst<2> ());
 
       for (mode = GET_CLASS_NARROWEST_MODE (MODE_FLOAT);
 	   mode != VOIDmode;
diff --git a/gcc/expmed.c b/gcc/expmed.c
index 93cf508..6327993 100644
--- a/gcc/expmed.c
+++ b/gcc/expmed.c
@@ -3235,7 +3235,7 @@ expand_mult (machine_mode mode, rtx op0, rtx op1, rtx target,
 
   /* Expand x*2.0 as x+x.  */
   if (CONST_DOUBLE_AS_FLOAT_P (scalar_op1)
-      && real_equal (CONST_DOUBLE_REAL_VALUE (scalar_op1), &dconst2))
+      && real_equal (CONST_DOUBLE_REAL_VALUE (scalar_op1), &dconst<2> ()))
     {
       op0 = force_reg (GET_MODE (op0), op0);
       return expand_binop (mode, add_optab, op0, op0,
diff --git a/gcc/fold-const.c b/gcc/fold-const.c
index 2851a29..60149c8 100644
--- a/gcc/fold-const.c
+++ b/gcc/fold-const.c
@@ -1176,7 +1176,7 @@ const_binop (enum tree_code code, tree arg1, tree arg2)
       /* Don't perform operation if it would raise a division
 	 by zero exception.  */
       if (code == RDIV_EXPR
-	  && real_equal (&d2, &dconst0)
+	  && real_equal (&d2, &dconst<0> ())
 	  && (flag_trapping_math || ! MODE_HAS_INFINITIES (mode)))
 	return NULL_TREE;
 
@@ -3600,9 +3600,9 @@ distribute_real_division (location_t loc, enum tree_code code, tree type,
       r0 = TREE_REAL_CST (TREE_OPERAND (arg0, 1));
       r1 = TREE_REAL_CST (TREE_OPERAND (arg1, 1));
       if (!mul0)
-	real_arithmetic (&r0, RDIV_EXPR, &dconst1, &r0);
+	real_arithmetic (&r0, RDIV_EXPR, &dconst<1> (), &r0);
       if (!mul1)
-        real_arithmetic (&r1, RDIV_EXPR, &dconst1, &r1);
+	real_arithmetic (&r1, RDIV_EXPR, &dconst<1> (), &r1);
       real_arithmetic (&r0, code, &r0, &r1);
       return fold_build2_loc (loc, MULT_EXPR, type,
 			  TREE_OPERAND (arg0, 0),
@@ -9914,7 +9914,7 @@ fold_binary_loc (location_t loc,
 
 		  if (powfn)
 		    {
-		      tree arg = build_real (type, dconst2);
+		      tree arg = build_real (type, dconst<2> ());
 		      return build_call_expr_loc (loc, powfn, 2, arg0, arg);
 		    }
 		}
diff --git a/gcc/java/decl.c b/gcc/java/decl.c
index c035fe0..6bb3aa1 100644
--- a/gcc/java/decl.c
+++ b/gcc/java/decl.c
@@ -669,8 +669,8 @@ java_init_decl_processing (void)
                         double_type_node));
   layout_type (double_type_node);
 
-  float_zero_node = build_real (float_type_node, dconst0);
-  double_zero_node = build_real (double_type_node, dconst0);
+  float_zero_node = build_real (float_type_node, dconst<0> ());
+  double_zero_node = build_real (double_type_node, dconst<0> ());
 
   /* These are the vtables for arrays of primitives.  */
   boolean_array_vtable = create_primitive_vtable ("boolean");
diff --git a/gcc/match.pd b/gcc/match.pd
index 9962b0a..8e2069b 100644
--- a/gcc/match.pd
+++ b/gcc/match.pd
@@ -1298,7 +1298,7 @@ along with GCC; see the file COPYING3.  If not see
 (simplify
  (plus @0 @0)
  (if (SCALAR_FLOAT_TYPE_P (type))
-  (mult @0 { build_real (type, dconst2); })))
+  (mult @0 { build_real (type, dconst<2> ()); })))
 
 (simplify
  (minus integer_zerop @1)
@@ -1598,7 +1598,7 @@ along with GCC; see the file COPYING3.  If not see
   (switch
    /* a CMP (-0) -> a CMP 0  */
    (if (REAL_VALUE_MINUS_ZERO (TREE_REAL_CST (@1)))
-    (cmp @0 { build_real (TREE_TYPE (@1), dconst0); }))
+    (cmp @0 { build_real (TREE_TYPE (@1), dconst<0> ()); }))
    /* x != NaN is always true, other ops are always false.  */
    (if (REAL_VALUE_ISNAN (TREE_REAL_CST (@1))
 	&& ! HONOR_SNANS (@1))
@@ -1694,7 +1694,7 @@ along with GCC; see the file COPYING3.  If not see
        (if (cmp == NE_EXPR || !HONOR_NANS (@0))
 	{ constant_boolean_node (true, type); })
        /* sqrt(x) > y is the same as x >= 0, if y is negative.  */
-       (ge @0 { build_real (TREE_TYPE (@0), dconst0); })))
+       (ge @0 { build_real (TREE_TYPE (@0), dconst<0> ()); })))
      (if (cmp == GT_EXPR || cmp == GE_EXPR)
       (with
        {
@@ -1731,11 +1731,11 @@ along with GCC; see the file COPYING3.  If not see
 	 /* sqrt(x) < y is x >= 0 when y is very large and we
 	    don't care about Infinities.  */
 	 (if (! HONOR_INFINITIES (@0))
-	  (ge @0 { build_real (TREE_TYPE (@0), dconst0); }))
+	  (ge @0 { build_real (TREE_TYPE (@0), dconst<0> ()); }))
 	 /* sqrt(x) < y is x >= 0 && x != +Inf, when y is large.  */
 	 (if (GENERIC)
 	  (truth_andif
-	   (ge @0 { build_real (TREE_TYPE (@0), dconst0); })
+	   (ge @0 { build_real (TREE_TYPE (@0), dconst<0> ()); })
 	   (ne @0 { build_real (TREE_TYPE (@0), c2); }))))
 	/* sqrt(x) < c is the same as x < c*c, if we ignore NaNs.  */
 	(if (! HONOR_NANS (@0))
@@ -1743,7 +1743,7 @@ along with GCC; see the file COPYING3.  If not see
 	 /* sqrt(x) < c is the same as x >= 0 && x < c*c.  */
 	 (if (GENERIC)
 	  (truth_andif
-	   (ge @0 { build_real (TREE_TYPE (@0), dconst0); })
+	   (ge @0 { build_real (TREE_TYPE (@0), dconst<0> ()); })
 	   (cmp @0 { build_real (TREE_TYPE (@0), c2); }))))))))))))
 
 /* Unordered tests if either argument is a NaN.  */
@@ -2193,7 +2193,7 @@ along with GCC; see the file COPYING3.  If not see
          break;
        CASE_FLT_FN (BUILT_IN_EXP2):
          /* Prepare to do logN(exp2(exponent) -> exponent*logN(2).  */
-         x = build_real (type, dconst2);
+         x = build_real (type, dconst<2> ());
          break;
        CASE_FLT_FN (BUILT_IN_EXP10):
        CASE_FLT_FN (BUILT_IN_POW10):
@@ -2221,11 +2221,11 @@ along with GCC; see the file COPYING3.  If not see
        {
        CASE_FLT_FN (BUILT_IN_SQRT):
 	 /* Prepare to do logN(sqrt(x) -> 0.5*logN(x).  */
-	 x = build_real (type, dconsthalf);
+	 x = build_real (type, dconst<1, 2> ());
          break;
        CASE_FLT_FN (BUILT_IN_CBRT):
 	 /* Prepare to do logN(cbrt(x) -> (1/3)*logN(x).  */
-         x = build_real_truncate (type, dconst_third ());
+	 x = build_real_truncate (type, dconst<1, 3> ());
          break;
        default:
 	 gcc_unreachable ();
diff --git a/gcc/real.c b/gcc/real.c
index 49d6739..fb77502 100644
--- a/gcc/real.c
+++ b/gcc/real.c
@@ -111,7 +111,6 @@ static void decimal_integer_string (char *, const REAL_VALUE_TYPE *,
 
 static const REAL_VALUE_TYPE * ten_to_ptwo (int);
 static const REAL_VALUE_TYPE * ten_to_mptwo (int);
-static const REAL_VALUE_TYPE * real_digit (int);
 static void times_pten (REAL_VALUE_TYPE *, int);
 
 static void round_for_format (const struct real_format *, REAL_VALUE_TYPE *);
@@ -1273,7 +1272,7 @@ real_identical (const REAL_VALUE_TYPE *a, const REAL_VALUE_TYPE *b)
 bool
 exact_real_inverse (machine_mode mode, REAL_VALUE_TYPE *r)
 {
-  const REAL_VALUE_TYPE *one = real_digit (1);
+  const REAL_VALUE_TYPE *one = &dconst<1> ();
   REAL_VALUE_TYPE u;
   int i;
 
@@ -1579,7 +1578,7 @@ real_to_decimal_for_mode (char *str, const REAL_VALUE_TYPE *r_orig,
   if (digits > max_digits)
     digits = max_digits;
 
-  one = real_digit (1);
+  one = &dconst<1> ();
   ten = ten_to_ptwo (0);
 
   sign = r.sign;
@@ -2225,6 +2224,22 @@ real_from_integer (REAL_VALUE_TYPE *r, machine_mode mode,
     real_convert (r, mode, r);
 }
 
+/* Set VALUE to A/B, in maximum precision.  */
+
+void
+real_from_fraction (REAL_VALUE_TYPE *value, int a, int b)
+{
+  if (b == 1)
+    real_from_integer (value, VOIDmode, a, SIGNED);
+  else
+    {
+      REAL_VALUE_TYPE areal, breal;
+      real_from_integer (&areal, VOIDmode, a, SIGNED);
+      real_from_integer (&breal, VOIDmode, b, SIGNED);
+      real_arithmetic (value, RDIV_EXPR, &areal, &breal);
+    }
+}
+
 /* Render R, an integral value, as a floating point constant with no
    specified exponent.  */
 
@@ -2252,7 +2267,7 @@ decimal_integer_string (char *str, const REAL_VALUE_TYPE *r_orig,
   digits = dec_exp + 1;
   gcc_assert ((digits + 2) < (int)buf_size);
 
-  pten = *real_digit (1);
+  pten = dconst<1> ();
   times_pten (&pten, dec_exp);
 
   p = str;
@@ -2326,27 +2341,11 @@ ten_to_mptwo (int n)
   gcc_assert (n < EXP_BITS);
 
   if (tens[n].cl == rvc_zero)
-    do_divide (&tens[n], real_digit (1), ten_to_ptwo (n));
+    do_divide (&tens[n], &dconst<1> (), ten_to_ptwo (n));
 
   return &tens[n];
 }
 
-/* Returns N.  */
-
-static const REAL_VALUE_TYPE *
-real_digit (int n)
-{
-  static REAL_VALUE_TYPE num[10];
-
-  gcc_assert (n >= 0);
-  gcc_assert (n <= 9);
-
-  if (n > 0 && num[n].cl == rvc_zero)
-    real_from_integer (&num[n], VOIDmode, n, UNSIGNED);
-
-  return &num[n];
-}
-
 /* Multiply R by 10**EXP.  */
 
 static void
@@ -2359,7 +2358,7 @@ times_pten (REAL_VALUE_TYPE *r, int exp)
   if (negative)
     {
       exp = -exp;
-      pten = *real_digit (1);
+      pten = dconst<1> ();
       rr = &pten;
     }
   else
@@ -2395,22 +2394,6 @@ dconst_e_ptr (void)
   return &value;
 }
 
-/* Returns the special REAL_VALUE_TYPE corresponding to 1/3.  */
-
-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.cl == rvc_zero)
-    {
-      real_arithmetic (&value, RDIV_EXPR, &dconst1, real_digit (3));
-    }
-  return &value;
-}
-
 /* Returns the special REAL_VALUE_TYPE corresponding to sqrt(2).  */
 
 const REAL_VALUE_TYPE *
@@ -4878,7 +4861,7 @@ real_powi (REAL_VALUE_TYPE *r, machine_mode mode,
 
   if (n == 0)
     {
-      *r = dconst1;
+      *r = dconst<1> ();
       return false;
     }
   else if (n < 0)
@@ -4906,7 +4889,7 @@ real_powi (REAL_VALUE_TYPE *r, machine_mode mode,
     }
 
   if (neg)
-    inexact |= do_divide (&t, &dconst1, &t);
+    inexact |= do_divide (&t, &dconst<1> (), &t);
 
   real_convert (r, mode, &t);
   return inexact;
@@ -4935,7 +4918,7 @@ 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);
+    do_add (&t, &t, &dconst<-1> (), 0);
   if (mode != VOIDmode)
     real_convert (r, mode, &t);
   else
@@ -4953,7 +4936,7 @@ 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);
+    do_add (&t, &t, &dconst<1> (), 0);
   if (mode != VOIDmode)
     real_convert (r, mode, &t);
   else
@@ -4967,7 +4950,7 @@ void
 real_round (REAL_VALUE_TYPE *r, machine_mode mode,
 	    const REAL_VALUE_TYPE *x)
 {
-  do_add (r, x, &dconsthalf, x->sign);
+  do_add (r, x, &dconst<1, 2> (), x->sign);
   do_fix_trunc (r, r);
   if (mode != VOIDmode)
     real_convert (r, mode, r);
diff --git a/gcc/real.h b/gcc/real.h
index 1497279..72e1a04 100644
--- a/gcc/real.h
+++ b/gcc/real.h
@@ -403,22 +403,12 @@ extern void real_ldexp (REAL_VALUE_TYPE *, const REAL_VALUE_TYPE *, int);
 
 /* Constant real values 0, 1, 2, -1 and 0.5.  */
 
-extern REAL_VALUE_TYPE dconst0;
-extern REAL_VALUE_TYPE dconst1;
-extern REAL_VALUE_TYPE dconst2;
-extern REAL_VALUE_TYPE dconstm1;
-extern REAL_VALUE_TYPE dconsthalf;
-
-#define dconst_e()  (*dconst_e_ptr ())
-#define dconst_third()  (*dconst_third_ptr ())
-#define dconst_sqrt2()  (*dconst_sqrt2_ptr ())
+#define dconst_e() (*dconst_e_ptr ())
+#define dconst_sqrt2() (*dconst_sqrt2_ptr ())
 
 /* Function to return the real value special constant 'e'.  */
 extern const REAL_VALUE_TYPE * dconst_e_ptr (void);
 
-/* Returns the special REAL_VALUE_TYPE corresponding to 1/3.  */
-extern const REAL_VALUE_TYPE * dconst_third_ptr (void);
-
 /* Returns the special REAL_VALUE_TYPE corresponding to sqrt(2).  */
 extern const REAL_VALUE_TYPE * dconst_sqrt2_ptr (void);
 
@@ -473,6 +463,26 @@ extern void get_max_float (const struct real_format *, char *, size_t);
 extern wide_int real_to_integer (const REAL_VALUE_TYPE *, bool *, int);
 extern void real_from_integer (REAL_VALUE_TYPE *, machine_mode,
 			       const wide_int_ref &, signop);
+extern void real_from_fraction (REAL_VALUE_TYPE *, int, int);
+
+/* Return a constant A/B, in maximum precision.  */
+template<int a, int b>
+inline const REAL_VALUE_TYPE &
+dconst (void)
+{
+  static REAL_VALUE_TYPE value;
+  if (value.cl == rvc_zero)
+    real_from_fraction (&value, a, b);
+  return value;
+}
+
+/* Return a real for integer constant A.  */
+template<int a>
+inline const REAL_VALUE_TYPE &
+dconst (void)
+{
+  return dconst<a, 1> ();
+}
 #endif
 
 #endif /* ! GCC_REAL_H */
diff --git a/gcc/simplify-rtx.c b/gcc/simplify-rtx.c
index 1f91afc..2e0afdd 100644
--- a/gcc/simplify-rtx.c
+++ b/gcc/simplify-rtx.c
@@ -2464,11 +2464,11 @@ simplify_binary_operation_1 (enum rtx_code code, machine_mode mode,
 	{
 	  const REAL_VALUE_TYPE *d1 = CONST_DOUBLE_REAL_VALUE (trueop1);
 
-	  if (real_equal (d1, &dconst2))
+	  if (real_equal (d1, &dconst<2> ()))
 	    return simplify_gen_binary (PLUS, mode, op0, copy_rtx (op0));
 
 	  if (!HONOR_SNANS (mode)
-	      && real_equal (d1, &dconstm1))
+	      && real_equal (d1, &dconst<-1> ()))
 	    return simplify_gen_unary (NEG, mode, op0, mode);
 	}
 
@@ -3093,17 +3093,17 @@ simplify_binary_operation_1 (enum rtx_code code, machine_mode mode,
 	      const REAL_VALUE_TYPE *d1 = CONST_DOUBLE_REAL_VALUE (trueop1);
 
 	      /* x/-1.0 is -x.  */
-	      if (real_equal (d1, &dconstm1)
+	      if (real_equal (d1, &dconst<-1> ())
 		  && !HONOR_SNANS (mode))
 		return simplify_gen_unary (NEG, mode, op0, mode);
 
 	      /* Change FP division by a constant into multiplication.
 		 Only do this with -freciprocal-math.  */
 	      if (flag_reciprocal_math
-		  && !real_equal (d1, &dconst0))
+		  && !real_equal (d1, &dconst<0> ()))
 		{
 		  REAL_VALUE_TYPE d;
-		  real_arithmetic (&d, RDIV_EXPR, &dconst1, d1);
+		  real_arithmetic (&d, RDIV_EXPR, &dconst<1> (), d1);
 		  tem = const_double_from_real_value (d, mode);
 		  return simplify_gen_binary (MULT, mode, op0, tem);
 		}
@@ -3862,7 +3862,7 @@ simplify_const_binary_operation (enum rtx_code code, machine_mode mode,
 	    return 0;
 
 	  if (code == DIV
-	      && real_equal (&f1, &dconst0)
+	      && real_equal (&f1, &dconst<0> ())
 	      && (flag_trapping_math || ! MODE_HAS_INFINITIES (mode)))
 	    return 0;
 
@@ -3895,9 +3895,9 @@ simplify_const_binary_operation (enum rtx_code code, machine_mode mode,
 
 	  if (code == MULT && MODE_HAS_INFINITIES (mode) && HONOR_NANS (mode)
 	      && flag_trapping_math
-	      && ((REAL_VALUE_ISINF (f0) && real_equal (&f1, &dconst0))
+	      && ((REAL_VALUE_ISINF (f0) && real_equal (&f1, &dconst<0> ()))
 		  || (REAL_VALUE_ISINF (f1)
-		      && real_equal (&f0, &dconst0))))
+		      && real_equal (&f0, &dconst<0> ()))))
 	    /* Inf * 0 = NaN plus exception.  */
 	    return 0;
 
diff --git a/gcc/tree-call-cdce.c b/gcc/tree-call-cdce.c
index 112a325..640e7e5 100644
--- a/gcc/tree-call-cdce.c
+++ b/gcc/tree-call-cdce.c
@@ -199,9 +199,9 @@ check_pow (gcall *pow_call)
       /* Only handle a fixed range of constant.  */
       REAL_VALUE_TYPE mv;
       REAL_VALUE_TYPE bcv = TREE_REAL_CST (base);
-      if (real_equal (&bcv, &dconst1))
+      if (real_equal (&bcv, &dconst<1> ()))
         return false;
-      if (real_less (&bcv, &dconst1))
+      if (real_less (&bcv, &dconst<1> ()))
         return false;
       real_from_integer (&mv, TYPE_MODE (TREE_TYPE (base)), 256, UNSIGNED);
       if (real_less (&mv, &bcv))
@@ -420,8 +420,8 @@ gen_conditions_for_pow_cst_base (tree base, tree expn,
      sure it is consistent with check_pow.  */
   REAL_VALUE_TYPE mv;
   REAL_VALUE_TYPE bcv = TREE_REAL_CST (base);
-  gcc_assert (!real_equal (&bcv, &dconst1)
-              && !real_less (&bcv, &dconst1));
+  gcc_assert (!real_equal (&bcv, &dconst<1> ())
+	      && !real_less (&bcv, &dconst<1> ()));
   real_from_integer (&mv, TYPE_MODE (TREE_TYPE (base)), 256, UNSIGNED);
   gcc_assert (!real_less (&mv, &bcv));
 
diff --git a/gcc/tree-chrec.c b/gcc/tree-chrec.c
index 649c9fe..4a67eb5 100644
--- a/gcc/tree-chrec.c
+++ b/gcc/tree-chrec.c
@@ -132,7 +132,7 @@ chrec_fold_plus_poly_poly (enum tree_code code,
 	   chrec_fold_minus (type, poly0, CHREC_LEFT (poly1)),
 	   chrec_fold_multiply (type, CHREC_RIGHT (poly1),
 				SCALAR_FLOAT_TYPE_P (type)
-				? build_real (type, dconstm1)
+				? build_real (type, dconst<-1> ())
 				: build_int_cst_type (type, -1)));
     }
 
@@ -233,7 +233,7 @@ chrec_fold_multiply_poly_poly (tree type,
   t1 = chrec_fold_plus (type, t1, t2);
   /* "2*b*d".  */
   t2 = chrec_fold_multiply (type, SCALAR_FLOAT_TYPE_P (type)
-			    ? build_real (type, dconst2)
+			    ? build_real (type, dconst<2> ())
 			    : build_int_cst (type, 2), t2);
 
   var = CHREC_VARIABLE (poly0);
@@ -326,7 +326,7 @@ chrec_fold_plus_1 (enum tree_code code, tree type,
 	       chrec_fold_minus (type, op0, CHREC_LEFT (op1)),
 	       chrec_fold_multiply (type, CHREC_RIGHT (op1),
 				    SCALAR_FLOAT_TYPE_P (type)
-				    ? build_real (type, dconstm1)
+				    ? build_real (type, dconst<-1> ())
 				    : build_int_cst_type (type, -1)));
 
 	CASE_CONVERT:
diff --git a/gcc/tree-complex.c b/gcc/tree-complex.c
index 93c0a54..2dce4dc 100644
--- a/gcc/tree-complex.c
+++ b/gcc/tree-complex.c
@@ -118,7 +118,7 @@ some_nonzerop (tree t)
      cannot be treated the same as operations with a real or imaginary
      operand if we care about the signs of zeros in the result.  */
   if (TREE_CODE (t) == REAL_CST && !flag_signed_zeros)
-    zerop = real_identical (&TREE_REAL_CST (t), &dconst0);
+    zerop = real_identical (&TREE_REAL_CST (t), &dconst<0> ());
   else if (TREE_CODE (t) == FIXED_CST)
     zerop = fixed_zerop (t);
   else if (TREE_CODE (t) == INTEGER_CST)
@@ -495,7 +495,7 @@ get_component_ssa_name (tree ssa_name, bool imag_p)
     {
       tree inner_type = TREE_TYPE (TREE_TYPE (ssa_name));
       if (SCALAR_FLOAT_TYPE_P (inner_type))
-	return build_real (inner_type, dconst0);
+	return build_real (inner_type, dconst<0> ());
       else
 	return build_int_cst (inner_type, 0);
     }
@@ -1021,7 +1021,7 @@ expand_complex_multiplication (gimple_stmt_iterator *gsi, tree inner_type,
     case PAIR (ONLY_IMAG, ONLY_REAL):
       rr = ar;
       if (TREE_CODE (ai) == REAL_CST
-	  && real_identical (&TREE_REAL_CST (ai), &dconst1))
+	  && real_identical (&TREE_REAL_CST (ai), &dconst<1> ()))
 	ri = br;
       else
 	ri = gimplify_build2 (gsi, MULT_EXPR, inner_type, ai, br);
diff --git a/gcc/tree-inline.c b/gcc/tree-inline.c
index 9b525f3..0758895 100644
--- a/gcc/tree-inline.c
+++ b/gcc/tree-inline.c
@@ -4094,7 +4094,7 @@ estimate_num_insns (gimple *stmt, eni_weights *weights)
 		      if (TREE_CODE (gimple_call_arg (stmt, 1)) == REAL_CST
 			  && (real_equal
 			      (&TREE_REAL_CST (gimple_call_arg (stmt, 1)),
-			       &dconst2)))
+			       &dconst<2> ())))
 			return estimate_operator_cost
 			    (MULT_EXPR, weights, gimple_call_arg (stmt, 0),
 			     gimple_call_arg (stmt, 0));
diff --git a/gcc/tree-scalar-evolution.c b/gcc/tree-scalar-evolution.c
index 0753bf3..e3f94fa 100644
--- a/gcc/tree-scalar-evolution.c
+++ b/gcc/tree-scalar-evolution.c
@@ -638,7 +638,7 @@ add_to_evolution_1 (unsigned loop_nb, tree chrec_before, tree to_add,
 	      var = loop_nb;
 	      left = chrec_before;
 	      right = SCALAR_FLOAT_TYPE_P (type)
-		? build_real (type, dconst0)
+		? build_real (type, dconst<0> ())
 		: build_int_cst (type, 0);
 	    }
 	  else
@@ -840,7 +840,7 @@ add_to_evolution (unsigned loop_nb, tree chrec_before, enum tree_code code,
 
   if (code == MINUS_EXPR)
     to_add = chrec_fold_multiply (type, to_add, SCALAR_FLOAT_TYPE_P (type)
-				  ? build_real (type, dconstm1)
+				  ? build_real (type, dconst<-1> ())
 				  : build_int_cst_type (type, -1));
 
   res = add_to_evolution_1 (loop_nb, chrec_before, to_add, at_stmt);
diff --git a/gcc/tree-ssa-dom.c b/gcc/tree-ssa-dom.c
index c226da5..5919c84 100644
--- a/gcc/tree-ssa-dom.c
+++ b/gcc/tree-ssa-dom.c
@@ -1158,7 +1158,7 @@ record_equality (tree x, tree y, class const_and_copies *const_and_copies)
      nonzero.  */
   if (HONOR_SIGNED_ZEROS (x)
       && (TREE_CODE (y) != REAL_CST
-	  || real_equal (&dconst0, &TREE_REAL_CST (y))))
+	  || real_equal (&dconst<0> (), &TREE_REAL_CST (y))))
     return;
 
   const_and_copies->record_const_or_copy (x, y, prev_x);
diff --git a/gcc/tree-ssa-math-opts.c b/gcc/tree-ssa-math-opts.c
index 39c027c..288daef 100644
--- a/gcc/tree-ssa-math-opts.c
+++ b/gcc/tree-ssa-math-opts.c
@@ -1003,7 +1003,7 @@ powi_as_mults (gimple_stmt_iterator *gsi, location_t loc,
   tree target;
 
   if (n == 0)
-    return build_real (type, dconst1);
+    return build_real (type, dconst<1> ());
 
   memset (cache, 0,  sizeof (cache));
   cache[1] = arg0;
@@ -1015,7 +1015,7 @@ powi_as_mults (gimple_stmt_iterator *gsi, location_t loc,
   /* If the original exponent was negative, reciprocate the result.  */
   target = make_temp_ssa_name (type, NULL, "powmult");
   div_stmt = gimple_build_assign (target, RDIV_EXPR,
-				  build_real (type, dconst1), result);
+				  build_real (type, dconst<1> ()), result);
   gimple_set_location (div_stmt, loc);
   gsi_insert_before (gsi, div_stmt, GSI_SAME_STMT);
 
@@ -1128,7 +1128,7 @@ bool
 representable_as_half_series_p (REAL_VALUE_TYPE c, unsigned n,
 				 struct pow_synth_sqrt_info *info)
 {
-  REAL_VALUE_TYPE factor = dconsthalf;
+  REAL_VALUE_TYPE factor = dconst<1, 2> ();
   REAL_VALUE_TYPE remainder = c;
 
   info->deepest = 0;
@@ -1145,7 +1145,7 @@ representable_as_half_series_p (REAL_VALUE_TYPE c, unsigned n,
 
       /* We have hit zero.  The number is representable as a sum
          of powers of 0.5.  */
-      if (real_equal (&res, &dconst0))
+      if (real_equal (&res, &dconst<0> ()))
 	{
 	  info->factors[i] = true;
 	  info->deepest = i + 1;
@@ -1160,7 +1160,7 @@ representable_as_half_series_p (REAL_VALUE_TYPE c, unsigned n,
       else
 	info->factors[i] = false;
 
-      real_arithmetic (&factor, MULT_EXPR, &factor, &dconsthalf);
+      real_arithmetic (&factor, MULT_EXPR, &factor, &dconst<1, 2> ());
     }
   return false;
 }
@@ -1320,8 +1320,8 @@ expand_pow_as_sqrts (gimple_stmt_iterator *gsi, location_t loc,
   real_arithmetic (&frac_part, MINUS_EXPR, &exp, &whole_part);
 
 
-  REAL_VALUE_TYPE ceil_whole = dconst0;
-  REAL_VALUE_TYPE ceil_fract = dconst0;
+  REAL_VALUE_TYPE ceil_whole = dconst<0> ();
+  REAL_VALUE_TYPE ceil_fract = dconst<0> ();
 
   if (neg_exp)
     {
@@ -1367,7 +1367,7 @@ expand_pow_as_sqrts (gimple_stmt_iterator *gsi, location_t loc,
 
   memset (cache, 0, (max_depth + 1) * sizeof (tree));
 
-  tree integer_res = n == 0 ? build_real (type, dconst1) : arg0;
+  tree integer_res = n == 0 ? build_real (type, dconst<1> ()) : arg0;
 
   /* Calculate the integer part of the exponent.  */
   if (n > 1)
@@ -1447,7 +1447,7 @@ expand_pow_as_sqrts (gimple_stmt_iterator *gsi, location_t loc,
 	    res = fract_res;
 
 	  res = build_and_insert_binop (gsi, loc, "powrootrecip", RDIV_EXPR,
-					  build_real (type, dconst1), res);
+					build_real (type, dconst<1> ()), res);
 	}
       else
 	{
@@ -1470,17 +1470,13 @@ static tree
 gimple_expand_builtin_pow (gimple_stmt_iterator *gsi, location_t loc, 
 			   tree arg0, tree arg1)
 {
-  REAL_VALUE_TYPE c, cint, dconst1_3, dconst1_4, dconst1_6;
-  REAL_VALUE_TYPE c2, dconst3;
+  REAL_VALUE_TYPE c, c2, cint, dconst1_3, dconst1_6;
   HOST_WIDE_INT n;
   tree type, sqrtfn, cbrtfn, sqrt_arg0, result, cbrt_x, powi_cbrt_x;
   machine_mode mode;
   bool speed_p = optimize_bb_for_speed_p (gsi_bb (*gsi));
   bool hw_sqrt_exists, c_is_int, c2_is_int;
 
-  dconst1_4 = dconst1;
-  SET_REAL_EXP (&dconst1_4, REAL_EXP (&dconst1_4) - 2);
-
   /* If the exponent isn't a constant, there's nothing of interest
      to be done.  */
   if (TREE_CODE (arg1) != REAL_CST)
@@ -1509,7 +1505,7 @@ gimple_expand_builtin_pow (gimple_stmt_iterator *gsi, location_t loc,
      unless signed zeros must be maintained.  pow(-0,0.5) = +0, while
      sqrt(-0) = -0.  */
   if (sqrtfn
-      && real_equal (&c, &dconsthalf)
+      && real_equal (&c, &dconst<1, 2> ())
       && !HONOR_SIGNED_ZEROS (mode))
     return build_and_insert_call (gsi, loc, sqrtfn, arg0);
 
@@ -1522,7 +1518,7 @@ gimple_expand_builtin_pow (gimple_stmt_iterator *gsi, location_t loc,
      of 1./3. actually has an even denominator.  The correct value
      of cbrt(x) is a negative real value.  */
   cbrtfn = mathfn_built_in (type, BUILT_IN_CBRT);
-  dconst1_3 = real_value_truncate (mode, dconst_third ());
+  dconst1_3 = real_value_truncate (mode, dconst<1, 3> ());
 
   if (flag_unsafe_math_optimizations
       && cbrtfn
@@ -1556,7 +1552,7 @@ gimple_expand_builtin_pow (gimple_stmt_iterator *gsi, location_t loc,
   if (flag_unsafe_math_optimizations
       && sqrtfn
       && hw_sqrt_exists
-      && (speed_p || real_equal (&c, &dconst1_4))
+      && (speed_p || real_equal (&c, &dconst<1, 4> ()))
       && !HONOR_SIGNED_ZEROS (mode))
     {
       unsigned int max_depth = speed_p
@@ -1570,7 +1566,7 @@ gimple_expand_builtin_pow (gimple_stmt_iterator *gsi, location_t loc,
 	return expand_with_sqrts;
     }
 
-  real_arithmetic (&c2, MULT_EXPR, &c, &dconst2);
+  real_arithmetic (&c2, MULT_EXPR, &c, &dconst<2> ());
   n = real_to_integer (&c2);
   real_from_integer (&cint, VOIDmode, n, SIGNED);
   c2_is_int = real_identical (&c2, &cint);
@@ -1584,12 +1580,11 @@ gimple_expand_builtin_pow (gimple_stmt_iterator *gsi, location_t loc,
      different from pow(x, 1./3.) due to rounding and behavior with
      negative x, we need to constrain this transformation to unsafe
      math and positive x or finite math.  */
-  real_from_integer (&dconst3, VOIDmode, 3, SIGNED);
-  real_arithmetic (&c2, MULT_EXPR, &c, &dconst3);
+  real_arithmetic (&c2, MULT_EXPR, &c, &dconst<3> ());
   real_round (&c2, mode, &c2);
   n = real_to_integer (&c2);
   real_from_integer (&cint, VOIDmode, n, SIGNED);
-  real_arithmetic (&c2, RDIV_EXPR, &cint, &dconst3);
+  real_arithmetic (&c2, RDIV_EXPR, &cint, &dconst<3> ());
   real_convert (&c2, mode, &c2);
 
   if (flag_unsafe_math_optimizations
@@ -1634,7 +1629,8 @@ gimple_expand_builtin_pow (gimple_stmt_iterator *gsi, location_t loc,
       /* If n is negative, reciprocate the result.  */
       if (n < 0)
 	result = build_and_insert_binop (gsi, loc, "powroot", RDIV_EXPR,
-					 build_real (type, dconst1), result);
+					 build_real (type, dconst<1> ()),
+					 result);
 
       return result;
     }
@@ -1793,8 +1789,8 @@ pass_cse_sincos::execute (function *fun)
 
 		      t0 = TREE_TYPE (arg0);
 		      t1 = TREE_TYPE (arg1);
-		      one = build_real (t0, dconst1);
-		      minus_one = build_real (t0, dconstm1);
+		      one = build_real (t0, dconst<1> ());
+		      minus_one = build_real (t0, dconst<-1> ());
 
 		      cond = make_temp_ssa_name (t1, NULL, "powi_cond");
 		      stmt = gimple_build_assign (cond, BIT_AND_EXPR,
@@ -3591,7 +3587,7 @@ pass_optimize_widening_mul::execute (function *fun)
 			if (TREE_CODE (gimple_call_arg (stmt, 1)) == REAL_CST
 			    && real_equal
 			         (&TREE_REAL_CST (gimple_call_arg (stmt, 1)),
-				  &dconst2)
+				  &dconst<2> ())
 			    && convert_mult_to_fma (stmt,
 						    gimple_call_arg (stmt, 0),
 						    gimple_call_arg (stmt, 0)))
diff --git a/gcc/tree-ssa-uncprop.c b/gcc/tree-ssa-uncprop.c
index 0f16c50..c247db7 100644
--- a/gcc/tree-ssa-uncprop.c
+++ b/gcc/tree-ssa-uncprop.c
@@ -153,7 +153,7 @@ associate_equivalences_with_edges (void)
 		     this value unless we know that the value is nonzero.  */
 		  if (HONOR_SIGNED_ZEROS (op0)
 		      && (TREE_CODE (op1) != REAL_CST
-			  || real_equal (&dconst0, &TREE_REAL_CST (op1))))
+			  || real_equal (&dconst<0> (), &TREE_REAL_CST (op1))))
 		    continue;
 
 		  equivalency = XNEW (struct edge_equivalency);
diff --git a/gcc/tree-vect-loop.c b/gcc/tree-vect-loop.c
index 63e29aa..7d23428 100644
--- a/gcc/tree-vect-loop.c
+++ b/gcc/tree-vect-loop.c
@@ -3821,7 +3821,7 @@ get_initial_def_for_reduction (gimple *stmt, tree init_val,
   int i;
   bool nested_in_vect_loop = false;
   tree init_value;
-  REAL_VALUE_TYPE real_init_val = dconst0;
+  REAL_VALUE_TYPE real_init_val = dconst<0> ();
   int int_init_val = 0;
   gimple *def_stmt = NULL;
 
@@ -3886,7 +3886,7 @@ get_initial_def_for_reduction (gimple *stmt, tree init_val,
 
         if (code == MULT_EXPR)
           {
-            real_init_val = dconst1;
+            real_init_val = dconst<1> ();
             int_init_val = 1;
           }
 
diff --git a/gcc/tree-vect-patterns.c b/gcc/tree-vect-patterns.c
index 48b5298..e78de75 100644
--- a/gcc/tree-vect-patterns.c
+++ b/gcc/tree-vect-patterns.c
@@ -1084,7 +1084,7 @@ vect_recog_pow_pattern (vec<gimple *> *stmts, tree *type_in,
   if ((tree_fits_shwi_p (exp)
        && tree_to_shwi (exp) == 2)
       || (TREE_CODE (exp) == REAL_CST
-          && real_equal (&TREE_REAL_CST (exp), &dconst2)))
+	  && real_equal (&TREE_REAL_CST (exp), &dconst<2> ())))
     {
       *type_in = TREE_TYPE (base);
 
@@ -1095,7 +1095,7 @@ vect_recog_pow_pattern (vec<gimple *> *stmts, tree *type_in,
 
   /* Catch square root.  */
   if (TREE_CODE (exp) == REAL_CST
-      && real_equal (&TREE_REAL_CST (exp), &dconsthalf))
+      && real_equal (&TREE_REAL_CST (exp), &dconst<1, 2> ()))
     {
       tree newfn = mathfn_built_in (TREE_TYPE (base), BUILT_IN_SQRT);
       *type_in = get_vectype_for_scalar_type (TREE_TYPE (base));
diff --git a/gcc/tree-vect-slp.c b/gcc/tree-vect-slp.c
index 7a2d623..3b8e26b 100644
--- a/gcc/tree-vect-slp.c
+++ b/gcc/tree-vect-slp.c
@@ -2617,7 +2617,7 @@ vect_get_constant_vectors (tree op, slp_tree slp_node,
           case BIT_IOR_EXPR:
           case BIT_XOR_EXPR:
              if (SCALAR_FLOAT_TYPE_P (TREE_TYPE (op)))
-               neutral_op = build_real (TREE_TYPE (op), dconst0);
+               neutral_op = build_real (TREE_TYPE (op), dconst<0> ());
              else
                neutral_op = build_int_cst (TREE_TYPE (op), 0);
 
@@ -2625,7 +2625,7 @@ vect_get_constant_vectors (tree op, slp_tree slp_node,
 
           case MULT_EXPR:
              if (SCALAR_FLOAT_TYPE_P (TREE_TYPE (op)))
-               neutral_op = build_real (TREE_TYPE (op), dconst1);
+               neutral_op = build_real (TREE_TYPE (op), dconst<1> ());
              else
                neutral_op = build_int_cst (TREE_TYPE (op), 1);
 
diff --git a/gcc/tree.c b/gcc/tree.c
index f78a2c2..ef70b03 100644
--- a/gcc/tree.c
+++ b/gcc/tree.c
@@ -1991,7 +1991,7 @@ build_one_cst (tree type)
       return build_int_cst (type, 1);
 
     case REAL_TYPE:
-      return build_real (type, dconst1);
+      return build_real (type, dconst<1> ());
 
     case FIXED_POINT_TYPE:
       /* We can only generate 1 for accum types.  */
@@ -2044,7 +2044,7 @@ build_minus_one_cst (tree type)
       return build_int_cst (type, -1);
 
     case REAL_TYPE:
-      return build_real (type, dconstm1);
+      return build_real (type, dconst<-1> ());
 
     case FIXED_POINT_TYPE:
       /* We can only generate 1 for accum types.  */
@@ -2084,7 +2084,7 @@ build_zero_cst (tree type)
       return build_int_cst (type, 0);
 
     case REAL_TYPE:
-      return build_real (type, dconst0);
+      return build_real (type, dconst<0> ());
 
     case FIXED_POINT_TYPE:
       return build_fixed (type, FCONST0 (TYPE_MODE (type)));
@@ -2554,7 +2554,7 @@ real_zerop (const_tree expr)
   switch (TREE_CODE (expr))
     {
     case REAL_CST:
-      return real_equal (&TREE_REAL_CST (expr), &dconst0)
+      return real_equal (&TREE_REAL_CST (expr), &dconst<0> ())
 	     && !(DECIMAL_FLOAT_MODE_P (TYPE_MODE (TREE_TYPE (expr))));
     case COMPLEX_CST:
       return real_zerop (TREE_REALPART (expr))
@@ -2584,7 +2584,7 @@ real_onep (const_tree expr)
   switch (TREE_CODE (expr))
     {
     case REAL_CST:
-      return real_equal (&TREE_REAL_CST (expr), &dconst1)
+      return real_equal (&TREE_REAL_CST (expr), &dconst<1> ())
 	     && !(DECIMAL_FLOAT_MODE_P (TYPE_MODE (TREE_TYPE (expr))));
     case COMPLEX_CST:
       return real_onep (TREE_REALPART (expr))
@@ -2613,7 +2613,7 @@ real_minus_onep (const_tree expr)
   switch (TREE_CODE (expr))
     {
     case REAL_CST:
-      return real_equal (&TREE_REAL_CST (expr), &dconstm1)
+      return real_equal (&TREE_REAL_CST (expr), &dconst<-1> ())
 	     && !(DECIMAL_FLOAT_MODE_P (TYPE_MODE (TREE_TYPE (expr))));
     case COMPLEX_CST:
       return real_minus_onep (TREE_REALPART (expr))
diff --git a/gcc/ubsan.c b/gcc/ubsan.c
index af586e3..fe2491c 100644
--- a/gcc/ubsan.c
+++ b/gcc/ubsan.c
@@ -1496,7 +1496,7 @@ ubsan_instrument_float_cast (location_t loc, tree type, tree expr, tree arg)
 	 in EXPR_TYPE, e.g. if TYPE is 64-bit long long and
 	 EXPR_TYPE is IEEE single float, but TYPE_MAX_VALUE + 1.0 is
 	 either representable or infinity.  */
-      REAL_VALUE_TYPE maxval = dconst1;
+      REAL_VALUE_TYPE maxval = dconst<1> ();
       SET_REAL_EXP (&maxval, REAL_EXP (&maxval) + prec - !uns_p);
       real_convert (&maxval, mode, &maxval);
       max = build_real (expr_type, maxval);
@@ -1508,10 +1508,10 @@ ubsan_instrument_float_cast (location_t loc, tree type, tree expr, tree arg)
 	{
 	  /* TYPE_MIN_VALUE is generally representable (or -inf),
 	     but TYPE_MIN_VALUE - 1.0 might not be.  */
-	  REAL_VALUE_TYPE minval = dconstm1, minval2;
+	  REAL_VALUE_TYPE minval = dconst<-1> (), minval2;
 	  SET_REAL_EXP (&minval, REAL_EXP (&minval) + prec - 1);
 	  real_convert (&minval, mode, &minval);
-	  real_arithmetic (&minval2, MINUS_EXPR, &minval, &dconst1);
+	  real_arithmetic (&minval2, MINUS_EXPR, &minval, &dconst<1> ());
 	  real_convert (&minval2, mode, &minval2);
 	  if (real_compare (EQ_EXPR, &minval, &minval2)
 	      && !real_isinf (&minval))
@@ -1522,7 +1522,7 @@ ubsan_instrument_float_cast (location_t loc, tree type, tree expr, tree arg)
 		 of base digits, we want to subtract a number that
 		 will be 1 << (REAL_MODE_FORMAT (mode)->p - 1)
 		 times smaller than minval.  */
-	      minval2 = dconst1;
+	      minval2 = dconst<1> ();
 	      gcc_assert (prec > REAL_MODE_FORMAT (mode)->p);
 	      SET_REAL_EXP (&minval2,
 			    REAL_EXP (&minval2) + prec - 1
