PATCH: middle-end changes for decimal float support

Ben Elliston bje@au1.ibm.com
Fri Dec 16 12:39:00 GMT 2005


Ian Taylor has already taken a preliminary look at these patches, but
I am posting them here again for public approval.  Due to Paolo
Bonzini's overhaul of simplify-rtx.c, I have had to refresh this patch
and re-test it (bootstrap and regression tested on powerpc-linux).

Okay for the trunk?

2005-12-17  Jon Grimm  <jgrimm2@us.ibm.com>
	    Janis Johnson  <janis187@us.ibm.com>
	    Ben Elliston  <bje@au.ibm.com>

	* optabs.c (init_floating_libfuncs): Handle decimal float modes.
	(init_optabs): Handle libfuncs for decimal float.
	* genopinit.c (gen_insn): Handle MODE_DECIMAL_FLOAT.
	* stor-layout.c (int_mode_for_mode): Likewise.
	* simplify-rtx.c (simplify_immed_subreg): Likewise.
	(simplify_unary_operation_1): Skip optimisations for decimal float
	modes.
	* varasm.c (output_constant_pool_2): Handle MODE_DECIMAL_FLOAT.
	* emit-rtl.c (gen_const_vector): Add assertion check.
	(init_emit_once): Populate const_tiny_rtx with constants in each
	decimal float mode.
	* expmed.c (extract_high_half, expand_mult_highpart_optab,
	expand_mult_highpart): Assert that mode is not a scalar float
	mode.
	* expr.c (convert_move): Handle conversion between decimal and
	binary floats of the same size.
	* convert.c (convert_to_real): Consider decimal float types when
	folding.
	* dwarf2out.c (base_type_die): Use DW_ATE_decimal_float to
	describe decimal floating point types.
	
Index: dwarf2out.c
===================================================================
--- dwarf2out.c	(revision 108635)
+++ dwarf2out.c	(working copy)
@@ -8124,7 +8124,10 @@
       break;
 
     case REAL_TYPE:
-      encoding = DW_ATE_float;
+      if (DECIMAL_FLOAT_MODE_P (TYPE_MODE (type)))
+	encoding = DW_ATE_decimal_float;
+      else
+	encoding = DW_ATE_float;
       break;
 
       /* Dwarf2 doesn't know anything about complex ints, so use
Index: expr.c
===================================================================
--- expr.c	(revision 108635)
+++ expr.c	(working copy)
@@ -410,10 +410,15 @@
       rtx value, insns;
       convert_optab tab;
 
-      gcc_assert (GET_MODE_PRECISION (from_mode)
-		  != GET_MODE_PRECISION (to_mode));
+      gcc_assert ((GET_MODE_PRECISION (from_mode)
+		   != GET_MODE_PRECISION (to_mode))
+		  || (DECIMAL_FLOAT_MODE_P (from_mode)
+		      != DECIMAL_FLOAT_MODE_P (to_mode)));
       
-      if (GET_MODE_PRECISION (from_mode) < GET_MODE_PRECISION (to_mode))
+      if (GET_MODE_PRECISION (from_mode) == GET_MODE_PRECISION (to_mode))
+	/* Conversion between decimal float and binary float, same size.  */
+	tab = DECIMAL_FLOAT_MODE_P (from_mode) ? trunc_optab : sext_optab;
+      else if (GET_MODE_PRECISION (from_mode) < GET_MODE_PRECISION (to_mode))
 	tab = sext_optab;
       else
 	tab = trunc_optab;
Index: stor-layout.c
===================================================================
--- stor-layout.c	(revision 108635)
+++ stor-layout.c	(working copy)
@@ -232,6 +232,7 @@
     case MODE_COMPLEX_INT:
     case MODE_COMPLEX_FLOAT:
     case MODE_FLOAT:
+    case MODE_DECIMAL_FLOAT:
     case MODE_VECTOR_INT:
     case MODE_VECTOR_FLOAT:
       mode = mode_for_size (GET_MODE_BITSIZE (mode), MODE_INT, 0);
Index: expmed.c
===================================================================
--- expmed.c	(revision 108635)
+++ expmed.c	(working copy)
@@ -3383,6 +3383,8 @@
   if (mode == word_mode)
     return gen_highpart (mode, op);
 
+  gcc_assert (!SCALAR_FLOAT_MODE_P (mode));
+
   wider_mode = GET_MODE_WIDER_MODE (mode);
   op = expand_shift (RSHIFT_EXPR, wider_mode, op,
 		     build_int_cst (NULL_TREE, GET_MODE_BITSIZE (mode)), 0, 1);
@@ -3402,6 +3404,8 @@
   rtx tem;
   int size;
 
+  gcc_assert (!SCALAR_FLOAT_MODE_P (mode));
+
   wider_mode = GET_MODE_WIDER_MODE (mode);
   size = GET_MODE_BITSIZE (mode);
 
@@ -3512,6 +3516,7 @@
   struct algorithm alg;
   rtx tem;
 
+  gcc_assert (!SCALAR_FLOAT_MODE_P (mode));
   /* We can't support modes wider than HOST_BITS_PER_INT.  */
   gcc_assert (GET_MODE_BITSIZE (mode) <= HOST_BITS_PER_WIDE_INT);
 
Index: emit-rtl.c
===================================================================
--- emit-rtl.c	(revision 108635)
+++ emit-rtl.c	(working copy)
@@ -5151,6 +5151,8 @@
   units = GET_MODE_NUNITS (mode);
   inner = GET_MODE_INNER (mode);
 
+  gcc_assert (!DECIMAL_FLOAT_MODE_P (inner));
+
   v = rtvec_alloc (units);
 
   /* We need to call this function after we set the scalar const_tiny_rtx
@@ -5227,7 +5229,8 @@
   word_mode = VOIDmode;
   double_mode = VOIDmode;
 
-  for (mode = GET_CLASS_NARROWEST_MODE (MODE_INT); mode != VOIDmode;
+  for (mode = GET_CLASS_NARROWEST_MODE (MODE_INT);
+       mode != VOIDmode;
        mode = GET_MODE_WIDER_MODE (mode))
     {
       if (GET_MODE_BITSIZE (mode) == BITS_PER_UNIT
@@ -5239,7 +5242,8 @@
 	word_mode = mode;
     }
 
-  for (mode = GET_CLASS_NARROWEST_MODE (MODE_FLOAT); mode != VOIDmode;
+  for (mode = GET_CLASS_NARROWEST_MODE (MODE_FLOAT);
+       mode != VOIDmode;
        mode = GET_MODE_WIDER_MODE (mode))
     {
       if (GET_MODE_BITSIZE (mode) == DOUBLE_TYPE_SIZE
@@ -5324,14 +5328,22 @@
       REAL_VALUE_TYPE *r =
 	(i == 0 ? &dconst0 : i == 1 ? &dconst1 : &dconst2);
 
-      for (mode = GET_CLASS_NARROWEST_MODE (MODE_FLOAT); mode != VOIDmode;
+      for (mode = GET_CLASS_NARROWEST_MODE (MODE_FLOAT);
+	   mode != VOIDmode;
 	   mode = GET_MODE_WIDER_MODE (mode))
 	const_tiny_rtx[i][(int) mode] =
 	  CONST_DOUBLE_FROM_REAL_VALUE (*r, mode);
 
+      for (mode = GET_CLASS_NARROWEST_MODE (MODE_DECIMAL_FLOAT);
+	   mode != VOIDmode;
+	   mode = GET_MODE_WIDER_MODE (mode))
+	const_tiny_rtx[i][(int) mode] =
+	  CONST_DOUBLE_FROM_REAL_VALUE (*r, mode);
+
       const_tiny_rtx[i][(int) VOIDmode] = GEN_INT (i);
 
-      for (mode = GET_CLASS_NARROWEST_MODE (MODE_INT); mode != VOIDmode;
+      for (mode = GET_CLASS_NARROWEST_MODE (MODE_INT);
+	   mode != VOIDmode;
 	   mode = GET_MODE_WIDER_MODE (mode))
 	const_tiny_rtx[i][(int) mode] = GEN_INT (i);
 
Index: simplify-rtx.c
===================================================================
--- simplify-rtx.c	(revision 108635)
+++ simplify-rtx.c	(working copy)
@@ -640,6 +640,9 @@
       break;
 
     case FLOAT_TRUNCATE:
+      if (DECIMAL_FLOAT_MODE_P (mode))
+	break;
+
       /* (float_truncate:SF (float_extend:DF foo:SF)) = foo:SF.  */
       if (GET_CODE (op) == FLOAT_EXTEND
 	  && GET_MODE (XEXP (op, 0)) == mode)
@@ -693,6 +696,9 @@
       break;
 
     case FLOAT_EXTEND:
+      if (DECIMAL_FLOAT_MODE_P (mode))
+	break;
+
       /*  (float_extend (float_extend x)) is (float_extend x)
 
 	  (float_extend (float x)) is (float x) assuming that double
@@ -4284,6 +4290,7 @@
 	  break;
       
 	case MODE_FLOAT:
+	case MODE_DECIMAL_FLOAT:
 	  {
 	    REAL_VALUE_TYPE r;
 	    long tmp[max_bitsize / 32];
Index: varasm.c
===================================================================
--- varasm.c	(revision 108635)
+++ varasm.c	(working copy)
@@ -3077,6 +3077,7 @@
   switch (GET_MODE_CLASS (mode))
     {
     case MODE_FLOAT:
+    case MODE_DECIMAL_FLOAT:
       {
 	REAL_VALUE_TYPE r;
 	
Index: convert.c
===================================================================
--- convert.c	(revision 108635)
+++ convert.c	(working copy)
@@ -263,6 +263,28 @@
 		 && FLOAT_TYPE_P (TREE_TYPE (arg1)))
 	       {
 		  tree newtype = type;
+
+		  if (TYPE_MODE (TREE_TYPE (arg0)) == SDmode
+		      || TYPE_MODE (TREE_TYPE (arg1)) == SDmode)
+		    newtype = dfloat32_type_node;
+		  if (TYPE_MODE (TREE_TYPE (arg0)) == DDmode
+		      || TYPE_MODE (TREE_TYPE (arg1)) == DDmode)
+		    newtype = dfloat64_type_node;
+		  if (TYPE_MODE (TREE_TYPE (arg0)) == TDmode
+		      || TYPE_MODE (TREE_TYPE (arg1)) == TDmode)
+                    newtype = dfloat128_type_node;
+		  if (newtype == dfloat32_type_node
+		      || newtype == dfloat64_type_node
+		      || newtype == dfloat128_type_node)
+		    {
+		      expr = build2 (TREE_CODE (expr), newtype,
+				     fold (convert_to_real (newtype, arg0)),
+				     fold (convert_to_real (newtype, arg1)));
+		      if (newtype == type)
+			return expr;
+		      break;
+		    }
+
 		  if (TYPE_PRECISION (TREE_TYPE (arg0)) > TYPE_PRECISION (newtype))
 		    newtype = TREE_TYPE (arg0);
 		  if (TYPE_PRECISION (TREE_TYPE (arg1)) > TYPE_PRECISION (newtype))



More information about the Gcc-patches mailing list