]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
optabs.c (init_floating_libfuncs): Handle decimal float modes.
authorJon Grimm <jgrimm2@us.ibm.com>
Sun, 18 Dec 2005 21:40:47 +0000 (21:40 +0000)
committerBen Elliston <bje@gcc.gnu.org>
Sun, 18 Dec 2005 21:40:47 +0000 (08:40 +1100)
* 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.

Co-Authored-By: Ben Elliston <bje@au.ibm.com>
Co-Authored-By: Janis Johnson <janis187@us.ibm.com>
From-SVN: r108762

gcc/ChangeLog
gcc/convert.c
gcc/dwarf2out.c
gcc/emit-rtl.c
gcc/expmed.c
gcc/expr.c
gcc/genopinit.c
gcc/optabs.c
gcc/simplify-rtx.c
gcc/stor-layout.c
gcc/varasm.c

index bf05ff9446159786cd65c2293e0483c03a1488e2..98468169d1cc4811973072823464ad3f5bc83472 100644 (file)
@@ -1,3 +1,28 @@
+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.
+       
 2005-12-18  Ulrich Weigand  <uweigand@de.ibm.com>
 
        PR rtl-optimization/21041
index 49d4a3ac5d6c2b7c79fd7ff436c7ce6929535485..e8030bf9f01e5fa135145ac81da111dcfbb80baa 100644 (file)
@@ -263,6 +263,28 @@ convert_to_real (tree type, tree expr)
                 && 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))
index f5860f213ecad59d9b8d1f5116b5790150ac3302..96c655637bd69123015ed454bb5ee6ad70d0e639 100644 (file)
@@ -8124,7 +8124,10 @@ base_type_die (tree type)
       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 d17258795fb4edbe5119094a61fdc2ce407b05a0..828651041a08d5cc8fb08704a5fefb5ab8051f7b 100644 (file)
@@ -5151,6 +5151,8 @@ gen_const_vector (enum machine_mode mode, int constant)
   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 @@ init_emit_once (int line_numbers)
   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 @@ init_emit_once (int line_numbers)
        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 @@ init_emit_once (int line_numbers)
       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 28f876ba22b4f672a0a71bc9111a63a77efb98d0..23909404005e21afd9758d11e872742a43acdf52 100644 (file)
@@ -3383,6 +3383,8 @@ extract_high_half (enum machine_mode mode, rtx op)
   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 @@ expand_mult_highpart_optab (enum machine_mode mode, rtx op0, rtx op1,
   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 @@ expand_mult_highpart (enum machine_mode mode, rtx op0, rtx op1,
   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 df86a57ee1813780c655a4115706d133e665423b..322db4ff27380ab39c0d14fb2961016769a019f9 100644 (file)
@@ -410,10 +410,15 @@ convert_move (rtx to, rtx from, int unsignedp)
       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 0c4a397667ecc67f0d9e36ee97cbf85c692e9b9f..ec8076b8206764d478c7f733539957d7033cf8f3 100644 (file)
@@ -304,7 +304,9 @@ gen_insn (rtx insn)
                             || mode_class[i] == MODE_INT
                             || mode_class[i] == MODE_PARTIAL_INT
                            || mode_class[i] == MODE_VECTOR_INT)
-                       && (! force_float || mode_class[i] == MODE_FLOAT 
+                       && (! force_float
+                           || mode_class[i] == MODE_FLOAT 
+                           || mode_class[i] == MODE_DECIMAL_FLOAT
                            || mode_class[i] == MODE_COMPLEX_FLOAT
                            || mode_class[i] == MODE_VECTOR_FLOAT))
                      break;
index 45bfbbde4822be67bede5dc28cd9624ab290a37f..d79cf668c60f10a64fc8fe1cb929cf575235fb67 100644 (file)
@@ -4375,9 +4375,10 @@ expand_float (rtx to, rtx from, int unsignedp)
          }
       }
 
-  /* Unsigned integer, and no way to convert directly.
-     Convert as signed, then conditionally adjust the result.  */
-  if (unsignedp && can_do_signed)
+  /* Unsigned integer, and no way to convert directly.  For binary
+     floating point modes, convert as signed, then conditionally adjust
+     the result.  */
+  if (unsignedp && can_do_signed && !DECIMAL_FLOAT_MODE_P (GET_MODE (to)))
     {
       rtx label = gen_label_rtx ();
       rtx temp;
@@ -4837,6 +4838,8 @@ static void
 init_floating_libfuncs (optab optable, const char *opname, int suffix)
 {
   init_libfuncs (optable, MIN_MODE_FLOAT, MAX_MODE_FLOAT, opname, suffix);
+  init_libfuncs (optable, MIN_MODE_DECIMAL_FLOAT, MAX_MODE_DECIMAL_FLOAT,
+                opname, suffix);
 }
 
 /* Initialize the libfunc fields of an entire group of entries of an
@@ -5254,16 +5257,32 @@ init_optabs (void)
   /* Conversions.  */
   init_interclass_conv_libfuncs (sfloat_optab, "float",
                                 MODE_INT, MODE_FLOAT);
+  init_interclass_conv_libfuncs (sfloat_optab, "float",
+                                MODE_INT, MODE_DECIMAL_FLOAT);
   init_interclass_conv_libfuncs (ufloat_optab, "floatun",
                                 MODE_INT, MODE_FLOAT);
+  init_interclass_conv_libfuncs (ufloat_optab, "floatun",
+                                MODE_INT, MODE_DECIMAL_FLOAT);
   init_interclass_conv_libfuncs (sfix_optab, "fix",
                                 MODE_FLOAT, MODE_INT);
+  init_interclass_conv_libfuncs (sfix_optab, "fix",
+                                MODE_DECIMAL_FLOAT, MODE_INT);
   init_interclass_conv_libfuncs (ufix_optab, "fixuns",
                                 MODE_FLOAT, MODE_INT);
+  init_interclass_conv_libfuncs (ufix_optab, "fixuns",
+                                MODE_DECIMAL_FLOAT, MODE_INT);
+  init_interclass_conv_libfuncs (ufloat_optab, "floatuns",
+                                MODE_INT, MODE_DECIMAL_FLOAT);
 
   /* sext_optab is also used for FLOAT_EXTEND.  */
   init_intraclass_conv_libfuncs (sext_optab, "extend", MODE_FLOAT, true);
+  init_intraclass_conv_libfuncs (sext_optab, "extend", MODE_DECIMAL_FLOAT, true);
+  init_interclass_conv_libfuncs (sext_optab, "extend", MODE_FLOAT, MODE_DECIMAL_FLOAT);
+  init_interclass_conv_libfuncs (sext_optab, "extend", MODE_DECIMAL_FLOAT, MODE_FLOAT);
   init_intraclass_conv_libfuncs (trunc_optab, "trunc", MODE_FLOAT, false);
+  init_intraclass_conv_libfuncs (trunc_optab, "trunc", MODE_DECIMAL_FLOAT, false);
+  init_interclass_conv_libfuncs (trunc_optab, "trunc", MODE_FLOAT, MODE_DECIMAL_FLOAT);
+  init_interclass_conv_libfuncs (trunc_optab, "trunc", MODE_DECIMAL_FLOAT, MODE_FLOAT);
 
   /* Use cabs for double complex abs, since systems generally have cabs.
      Don't define any libcall for float complex, so that cabs will be used.  */
index 3c5da5e9aebf164119a9d5099556ca9f08eeda22..c773900c4054140f75c94e826a93a6757a1f82f1 100644 (file)
@@ -640,6 +640,9 @@ simplify_unary_operation_1 (enum rtx_code code, enum machine_mode mode, rtx op)
       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 @@ simplify_unary_operation_1 (enum rtx_code code, enum machine_mode mode, rtx op)
       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 @@ simplify_immed_subreg (enum machine_mode outermode, rtx op,
          break;
       
        case MODE_FLOAT:
+       case MODE_DECIMAL_FLOAT:
          {
            REAL_VALUE_TYPE r;
            long tmp[max_bitsize / 32];
index b4e9ad1072f1f7b9d6b74a83220977f55e248e9f..7db35673d57546a3a4d2b004f52cbe21afc72031 100644 (file)
@@ -232,6 +232,7 @@ int_mode_for_mode (enum machine_mode mode)
     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 82c2df32c14f7743cbfff82a93d996aa7e3502d5..3a2fe22b116f491e024056944af14c1fe3a0749c 100644 (file)
@@ -3077,6 +3077,7 @@ output_constant_pool_2 (enum machine_mode mode, rtx x, unsigned int align)
   switch (GET_MODE_CLASS (mode))
     {
     case MODE_FLOAT:
+    case MODE_DECIMAL_FLOAT:
       {
        REAL_VALUE_TYPE r;