OSDN Git Service

Daily bump.
[pf3gnuchains/gcc-fork.git] / gcc / dojump.c
index d4ce6cf..91bebee 100644 (file)
@@ -36,6 +36,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "ggc.h"
 #include "basic-block.h"
 #include "output.h"
+#include "tm_p.h"
 
 static bool prefer_and_bit_test (enum machine_mode, int);
 static void do_jump_by_parts_greater (tree, tree, int, rtx, rtx, int);
@@ -143,6 +144,8 @@ static GTY(()) rtx shift_test;
 static bool
 prefer_and_bit_test (enum machine_mode mode, int bitnum)
 {
+  bool speed_p;
+
   if (and_test == 0)
     {
       /* Set up rtxes for the two variations.  Use NULL as a placeholder
@@ -167,8 +170,9 @@ prefer_and_bit_test (enum machine_mode mode, int bitnum)
                                                 mode);
   XEXP (XEXP (shift_test, 0), 1) = GEN_INT (bitnum);
 
-  return (rtx_cost (and_test, IF_THEN_ELSE, optimize_insn_for_speed_p ())
-         <= rtx_cost (shift_test, IF_THEN_ELSE, optimize_insn_for_speed_p ()));
+  speed_p = optimize_insn_for_speed_p ();
+  return (rtx_cost (and_test, IF_THEN_ELSE, 0, speed_p)
+         <= rtx_cost (shift_test, IF_THEN_ELSE, 0, speed_p));
 }
 
 /* Subroutine of do_jump, dealing with exploded comparisons of the type
@@ -542,7 +546,7 @@ do_jump (tree exp, rtx if_false_label, rtx if_true_label, int prob)
                  unsigned HOST_WIDE_INT mask
                    = (unsigned HOST_WIDE_INT) 1 << TREE_INT_CST_LOW (shift);
                  do_jump (build2 (BIT_AND_EXPR, argtype, arg,
-                                  build_int_cst_wide_type (argtype, mask, 0)),
+                                  build_int_cstu (argtype, mask)),
                           clr_label, set_label, setclr_prob);
                  break;
                }
@@ -637,14 +641,33 @@ do_jump_by_parts_greater_rtx (enum machine_mode mode, int unsignedp, rtx op0,
 {
   int nwords = (GET_MODE_SIZE (mode) / UNITS_PER_WORD);
   rtx drop_through_label = 0;
+  bool drop_through_if_true = false, drop_through_if_false = false;
+  enum rtx_code code = GT;
   int i;
 
   if (! if_true_label || ! if_false_label)
     drop_through_label = gen_label_rtx ();
   if (! if_true_label)
-    if_true_label = drop_through_label;
+    {
+      if_true_label = drop_through_label;
+      drop_through_if_true = true;
+    }
   if (! if_false_label)
-    if_false_label = drop_through_label;
+    {
+      if_false_label = drop_through_label;
+      drop_through_if_false = true;
+    }
+
+  /* Deal with the special case 0 > x: only one comparison is necessary and
+     we reverse it to avoid jumping to the drop-through label.  */
+  if (op0 == const0_rtx && drop_through_if_true && !drop_through_if_false)
+    {
+      code = LE;
+      if_true_label = if_false_label;
+      if_false_label = drop_through_label;
+      drop_through_if_true = false;
+      drop_through_if_false = true;
+    }
 
   /* Compare a word at a time, high order first.  */
   for (i = 0; i < nwords; i++)
@@ -663,17 +686,20 @@ do_jump_by_parts_greater_rtx (enum machine_mode mode, int unsignedp, rtx op0,
         }
 
       /* All but high-order word must be compared as unsigned.  */
-      do_compare_rtx_and_jump (op0_word, op1_word, GT,
-                               (unsignedp || i > 0), word_mode, NULL_RTX,
-                              NULL_RTX, if_true_label, prob);
+      do_compare_rtx_and_jump (op0_word, op1_word, code, (unsignedp || i > 0),
+                              word_mode, NULL_RTX, NULL_RTX, if_true_label,
+                              prob);
+
+      /* Emit only one comparison for 0.  Do not emit the last cond jump.  */
+      if (op0 == const0_rtx || i == nwords - 1)
+       break;
 
       /* Consider lower words only if these are equal.  */
       do_compare_rtx_and_jump (op0_word, op1_word, NE, unsignedp, word_mode,
-                              NULL_RTX, NULL_RTX, if_false_label,
-                              inv (prob));
+                              NULL_RTX, NULL_RTX, if_false_label, inv (prob));
     }
 
-  if (if_false_label)
+  if (!drop_through_if_false)
     emit_jump (if_false_label);
   if (drop_through_label)
     emit_label (drop_through_label);
@@ -1023,7 +1049,7 @@ do_compare_rtx_and_jump (rtx op0, rtx op1, enum rtx_code code, int unsignedp,
     }
   else
     {
-      if (GET_MODE_CLASS (mode) == MODE_FLOAT
+      if (SCALAR_FLOAT_MODE_P (mode)
          && ! can_compare_p (code, mode, ccp_jump)
          && can_compare_p (swap_condition (code), mode, ccp_jump))
        {
@@ -1034,7 +1060,7 @@ do_compare_rtx_and_jump (rtx op0, rtx op1, enum rtx_code code, int unsignedp,
          op1 = tmp;
        }
 
-      else if (GET_MODE_CLASS (mode) == MODE_FLOAT
+      else if (SCALAR_FLOAT_MODE_P (mode)
               && ! can_compare_p (code, mode, ccp_jump)
 
               /* Never split ORDERED and UNORDERED.  These must be implemented.  */