OSDN Git Service

Fix ChangeLog entry.
[pf3gnuchains/gcc-fork.git] / gcc / expmed.c
index 2390940..a4396c2 100644 (file)
@@ -1,7 +1,8 @@
 /* Medium-level subroutines: convert bit-field store and extract
    and shifts, multiplies and divides to rtl instructions.
    Copyright (C) 1987, 1988, 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
-   1999, 2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
+   1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006
+   Free Software Foundation, Inc.
 
 This file is part of GCC.
 
@@ -614,7 +615,6 @@ store_bit_field (rtx str_rtx, unsigned HOST_WIDE_INT bitsize,
 
   if (HAVE_insv
       && GET_MODE (value) != BLKmode
-      && !(bitsize == 1 && GET_CODE (value) == CONST_INT)
       && bitsize > 0
       && GET_MODE_BITSIZE (op_mode) >= bitsize
       && ! ((REG_P (op0) || GET_CODE (op0) == SUBREG)
@@ -2170,7 +2170,7 @@ expand_shift (enum tree_code code, enum machine_mode mode, rtx shifted,
      and shifted in the other direction; but that does not work
      on all machines.  */
 
-  op1 = expand_expr (amount, NULL_RTX, VOIDmode, 0);
+  op1 = expand_normal (amount);
 
   if (SHIFT_COUNT_TRUNCATED)
     {
@@ -5025,69 +5025,6 @@ make_tree (tree type, rtx x)
       return t;
     }
 }
-
-/* Check whether the multiplication X * MULT + ADD overflows.
-   X, MULT and ADD must be CONST_*.
-   MODE is the machine mode for the computation.
-   X and MULT must have mode MODE.  ADD may have a different mode.
-   So can X (defaults to same as MODE).
-   UNSIGNEDP is nonzero to do unsigned multiplication.  */
-
-bool
-const_mult_add_overflow_p (rtx x, rtx mult, rtx add,
-                          enum machine_mode mode, int unsignedp)
-{
-  tree type, mult_type, add_type, result;
-
-  type = lang_hooks.types.type_for_mode (mode, unsignedp);
-
-  /* In order to get a proper overflow indication from an unsigned
-     type, we have to pretend that it's a sizetype.  */
-  mult_type = type;
-  if (unsignedp)
-    {
-      /* FIXME:It would be nice if we could step directly from this
-        type to its sizetype equivalent.  */
-      mult_type = build_distinct_type_copy (type);
-      TYPE_IS_SIZETYPE (mult_type) = 1;
-    }
-
-  add_type = (GET_MODE (add) == VOIDmode ? mult_type
-             : lang_hooks.types.type_for_mode (GET_MODE (add), unsignedp));
-
-  result = fold_build2 (PLUS_EXPR, mult_type,
-                       fold_build2 (MULT_EXPR, mult_type,
-                                    make_tree (mult_type, x),
-                                    make_tree (mult_type, mult)),
-                       make_tree (add_type, add));
-
-  return TREE_CONSTANT_OVERFLOW (result);
-}
-
-/* Return an rtx representing the value of X * MULT + ADD.
-   TARGET is a suggestion for where to store the result (an rtx).
-   MODE is the machine mode for the computation.
-   X and MULT must have mode MODE.  ADD may have a different mode.
-   So can X (defaults to same as MODE).
-   UNSIGNEDP is nonzero to do unsigned multiplication.
-   This may emit insns.  */
-
-rtx
-expand_mult_add (rtx x, rtx target, rtx mult, rtx add, enum machine_mode mode,
-                int unsignedp)
-{
-  tree type = lang_hooks.types.type_for_mode (mode, unsignedp);
-  tree add_type = (GET_MODE (add) == VOIDmode
-                  ? type: lang_hooks.types.type_for_mode (GET_MODE (add),
-                                                          unsignedp));
-  tree result = fold_build2 (PLUS_EXPR, type,
-                            fold_build2 (MULT_EXPR, type,
-                                         make_tree (type, x),
-                                         make_tree (type, mult)),
-                            make_tree (add_type, add));
-
-  return expand_expr (result, target, VOIDmode, 0);
-}
 \f
 /* Compute the logical-and of OP0 and OP1, storing it in TARGET
    and returning TARGET.
@@ -5603,66 +5540,14 @@ emit_store_flag_force (rtx target, enum rtx_code code, rtx op0, rtx op1,
 }
 \f
 /* Perform possibly multi-word comparison and conditional jump to LABEL
-   if ARG1 OP ARG2 true where ARG1 and ARG2 are of mode MODE
-
-   The algorithm is based on the code in expr.c:do_jump.
-
-   Note that this does not perform a general comparison.  Only
-   variants generated within expmed.c are correctly handled, others
-   could be handled if needed.  */
+   if ARG1 OP ARG2 true where ARG1 and ARG2 are of mode MODE.  This is
+   now a thin wrapper around do_compare_rtx_and_jump.  */
 
 static void
 do_cmp_and_jump (rtx arg1, rtx arg2, enum rtx_code op, enum machine_mode mode,
                 rtx label)
 {
-  /* If this mode is an integer too wide to compare properly,
-     compare word by word.  Rely on cse to optimize constant cases.  */
-
-  if (GET_MODE_CLASS (mode) == MODE_INT
-      && ! can_compare_p (op, mode, ccp_jump))
-    {
-      rtx label2 = gen_label_rtx ();
-
-      switch (op)
-       {
-       case LTU:
-         do_jump_by_parts_greater_rtx (mode, 1, arg2, arg1, label2, label);
-         break;
-
-       case LEU:
-         do_jump_by_parts_greater_rtx (mode, 1, arg1, arg2, label, label2);
-         break;
-
-       case LT:
-         do_jump_by_parts_greater_rtx (mode, 0, arg2, arg1, label2, label);
-         break;
-
-       case GT:
-         do_jump_by_parts_greater_rtx (mode, 0, arg1, arg2, label2, label);
-         break;
-
-       case GE:
-         do_jump_by_parts_greater_rtx (mode, 0, arg2, arg1, label, label2);
-         break;
-
-         /* do_jump_by_parts_equality_rtx compares with zero.  Luckily
-            that's the only equality operations we do */
-       case EQ:
-         gcc_assert (arg2 == const0_rtx && mode == GET_MODE(arg1));
-         do_jump_by_parts_equality_rtx (arg1, label2, label);
-         break;
-
-       case NE:
-         gcc_assert (arg2 == const0_rtx && mode == GET_MODE(arg1));
-         do_jump_by_parts_equality_rtx (arg1, label, label2);
-         break;
-
-       default:
-         gcc_unreachable ();
-       }
-
-      emit_label (label2);
-    }
-  else
-    emit_cmp_and_jump_insns (arg1, arg2, op, NULL_RTX, mode, 0, label);
+  int unsignedp = (op == LTU || op == LEU || op == GTU || op == GEU);
+  do_compare_rtx_and_jump (arg1, arg2, op, unsignedp, mode,
+                          NULL_RTX, NULL_RTX, label);
 }