OSDN Git Service

PR middle-end/20219
[pf3gnuchains/gcc-fork.git] / gcc / stmt.c
index 5560dbc..ad75392 100644 (file)
@@ -1,6 +1,7 @@
 /* Expands front end tree to back end RTL for GCC
    Copyright (C) 1987, 1988, 1989, 1992, 1993, 1994, 1995, 1996, 1997,
-   1998, 1999, 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
+   1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005
+   Free Software Foundation, Inc.
 
 This file is part of GCC.
 
@@ -16,8 +17,8 @@ for more details.
 
 You should have received a copy of the GNU General Public License
 along with GCC; see the file COPYING.  If not, write to the Free
-Software Foundation, 59 Temple Place - Suite 330, Boston, MA
-02111-1307, USA.  */
+Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301, USA.  */
 
 /* This file handles the generation of rtl code from tree structure
    above the level of expressions, using subroutines in exp*.c and emit-rtl.c.
@@ -30,6 +31,7 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
 #include "tm.h"
 
 #include "rtl.h"
+#include "hard-reg-set.h"
 #include "tree.h"
 #include "tm_p.h"
 #include "flags.h"
@@ -38,7 +40,6 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
 #include "insn-config.h"
 #include "expr.h"
 #include "libfuncs.h"
-#include "hard-reg-set.h"
 #include "recog.h"
 #include "machmode.h"
 #include "toplev.h"
@@ -110,7 +111,6 @@ static bool check_operand_nalternatives (tree, tree);
 static bool check_unique_operand_names (tree, tree);
 static char *resolve_operand_name_1 (char *, tree, tree);
 static void expand_null_return_1 (void);
-static rtx shift_return_value (rtx);
 static void expand_value_return (rtx);
 static void do_jump_if_equal (rtx, rtx, rtx, int);
 static int estimate_case_costs (case_node_ptr);
@@ -260,7 +260,7 @@ n_occurrences (int c, const char *s)
    or an ADDR_EXPR containing a STRING_CST.  VOL nonzero means the
    insn is volatile; don't optimize it.  */
 
-void
+static void
 expand_asm (tree string, int vol)
 {
   rtx body;
@@ -323,13 +323,13 @@ parse_output_constraint (const char **constraint_p, int operand_num,
   *is_inout = (*p == '+');
 
   /* Canonicalize the output constraint so that it begins with `='.  */
-  if (p != constraint || is_inout)
+  if (p != constraint || *is_inout)
     {
       char *buf;
       size_t c_len = strlen (constraint);
 
       if (p != constraint)
-       warning ("output constraint %qc for operand %d "
+       warning (0, "output constraint %qc for operand %d "
                 "is not at the beginning",
                 *p, operand_num);
 
@@ -553,38 +553,37 @@ parse_input_constraint (const char **constraint_p, int input_num,
       }
 
   if (saw_match && !*allows_reg)
-    warning ("matching constraint does not allow a register");
+    warning (0, "matching constraint does not allow a register");
 
   return true;
 }
 
-/* INPUT is one of the input operands from EXPR, an ASM_EXPR.  Returns true
-   if it is an operand which must be passed in memory (i.e. an "m"
-   constraint), false otherwise.  */
+/* Return true iff there's an overlap between REGS and DECL, where DECL
+   can be an asm-declared register.  */
 
 bool
-asm_op_is_mem_input (tree input, tree expr)
+decl_overlaps_hard_reg_set_p (tree decl, const HARD_REG_SET regs)
 {
-  const char *constraint = TREE_STRING_POINTER (TREE_VALUE (TREE_PURPOSE (input)));
-  tree outputs = ASM_OUTPUTS (expr);
-  int noutputs = list_length (outputs);
-  const char **constraints
-    = (const char **) alloca ((noutputs) * sizeof (const char *));
-  int i = 0;
-  bool allows_mem, allows_reg;
-  tree t;
+  if ((TREE_CODE (decl) == VAR_DECL || TREE_CODE (decl) == PARM_DECL)
+      && DECL_REGISTER (decl)
+      && REG_P (DECL_RTL (decl))
+      && REGNO (DECL_RTL (decl)) < FIRST_PSEUDO_REGISTER)
+    {
+      rtx reg = DECL_RTL (decl);
+      unsigned int regno;
 
-  /* Collect output constraints.  */
-  for (t = outputs; t ; t = TREE_CHAIN (t), i++)
-    constraints[i] = TREE_STRING_POINTER (TREE_VALUE (TREE_PURPOSE (t)));
+      for (regno = REGNO (reg);
+          regno < (REGNO (reg)
+                   + hard_regno_nregs[REGNO (reg)][GET_MODE (reg)]);
+          regno++)
+       if (TEST_HARD_REG_BIT (regs, regno))
+         return true;
+    }
 
-  /* We pass 0 for input_num, ninputs and ninout; they are only used for
-     error checking which will be done at expand time.  */
-  parse_input_constraint (&constraint, 0, 0, noutputs, 0, constraints,
-                         &allows_mem, &allows_reg);
-  return (!allows_reg && allows_mem);
+  return false;
 }
 
+
 /* Check for overlap between registers marked in CLOBBERED_REGS and
    anything inappropriate in DECL.  Emit error and return TRUE for error,
    FALSE for ok.  */
@@ -594,30 +593,17 @@ decl_conflicts_with_clobbers_p (tree decl, const HARD_REG_SET clobbered_regs)
 {
   /* Conflicts between asm-declared register variables and the clobber
      list are not allowed.  */
-  if ((TREE_CODE (decl) == VAR_DECL || TREE_CODE (decl) == PARM_DECL)
-      && DECL_REGISTER (decl)
-      && REG_P (DECL_RTL (decl))
-      && REGNO (DECL_RTL (decl)) < FIRST_PSEUDO_REGISTER)
+  if (decl_overlaps_hard_reg_set_p (decl, clobbered_regs))
     {
-      rtx reg = DECL_RTL (decl);
-      unsigned int regno;
+      error ("asm-specifier for variable %qs conflicts with asm clobber list",
+            IDENTIFIER_POINTER (DECL_NAME (decl)));
 
-      for (regno = REGNO (reg);
-          regno < (REGNO (reg)
-                   + hard_regno_nregs[REGNO (reg)][GET_MODE (reg)]);
-          regno++)
-       if (TEST_HARD_REG_BIT (clobbered_regs, regno))
-         {
-           error ("asm-specifier for variable %qs conflicts with "
-                  "asm clobber list",
-                  IDENTIFIER_POINTER (DECL_NAME (decl)));
-
-           /* Reset registerness to stop multiple errors emitted for a
-              single variable.  */
-           DECL_REGISTER (decl) = 0;
-           return true;
-         }
+      /* Reset registerness to stop multiple errors emitted for a single
+        variable.  */
+      DECL_REGISTER (decl) = 0;
+      return true;
     }
+
   return false;
 }
 
@@ -638,7 +624,7 @@ decl_conflicts_with_clobbers_p (tree decl, const HARD_REG_SET clobbered_regs)
 
    VOL nonzero means the insn is volatile; don't optimize it.  */
 
-void
+static void
 expand_asm_operands (tree string, tree outputs, tree inputs,
                     tree clobbers, int vol, location_t locus)
 {
@@ -683,7 +669,7 @@ expand_asm_operands (tree string, tree outputs, tree inputs,
      Case in point is when the i386 backend moved from cc0 to a hard reg --
      maintaining source-level compatibility means automatically clobbering
      the flags register.  */
-  clobbers = targetm.md_asm_clobbers (clobbers);
+  clobbers = targetm.md_asm_clobbers (outputs, inputs, clobbers);
 
   /* Count the number of meaningful clobbered registers, ignoring what
      we would ignore later.  */
@@ -891,10 +877,10 @@ expand_asm_operands (tree string, tree outputs, tree inputs,
 
       if (asm_operand_ok (op, constraint) <= 0)
        {
-         if (allows_reg)
+         if (allows_reg && TYPE_MODE (type) != BLKmode)
            op = force_reg (TYPE_MODE (type), op);
          else if (!allows_mem)
-           warning ("asm operand %d probably doesn%'t match constraints",
+           warning (0, "asm operand %d probably doesn%'t match constraints",
                     i + noutputs);
          else if (MEM_P (op))
            {
@@ -904,7 +890,7 @@ expand_asm_operands (tree string, tree outputs, tree inputs,
            }
          else
            {
-             warning ("use of memory input without lvalue in "
+             warning (0, "use of memory input without lvalue in "
                       "asm operand %d is deprecated", i + noutputs);
 
              if (CONSTANT_P (op))
@@ -1108,7 +1094,7 @@ expand_asm_expr (tree exp)
     {
       if (o[i] != TREE_VALUE (tail))
        {
-         expand_assignment (o[i], TREE_VALUE (tail), 0);
+         expand_assignment (o[i], TREE_VALUE (tail));
          free_temp_slots ();
 
          /* Restore the original value so that it's correct the next
@@ -1387,7 +1373,7 @@ int
 warn_if_unused_value (tree exp, location_t locus)
 {
  restart:
-  if (TREE_USED (exp))
+  if (TREE_USED (exp) || TREE_NO_WARNING (exp))
     return 0;
 
   /* Don't warn about void constructs.  This includes casting to void,
@@ -1430,8 +1416,6 @@ warn_if_unused_value (tree exp, location_t locus)
       goto restart;
 
     case COMPOUND_EXPR:
-      if (TREE_NO_WARNING (exp))
-       return 0;
       if (warn_if_unused_value (TREE_OPERAND (exp, 0), locus))
        return 1;
       /* Let people do `(foo (), 0)' without a warning.  */
@@ -1440,27 +1424,12 @@ warn_if_unused_value (tree exp, location_t locus)
       exp = TREE_OPERAND (exp, 1);
       goto restart;
 
-    case NOP_EXPR:
-    case CONVERT_EXPR:
-    case NON_LVALUE_EXPR:
-      /* Don't warn about conversions not explicit in the user's program.  */
-      if (TREE_NO_WARNING (exp))
+    case COND_EXPR:
+      /* If this is an expression with side effects, don't warn; this
+        case commonly appears in macro expansions.  */
+      if (TREE_SIDE_EFFECTS (exp))
        return 0;
-      /* Assignment to a cast usually results in a cast of a modify.
-        Don't complain about that.  There can be an arbitrary number of
-        casts before the modify, so we must loop until we find the first
-        non-cast expression and then test to see if that is a modify.  */
-      {
-       tree tem = TREE_OPERAND (exp, 0);
-
-       while (TREE_CODE (tem) == CONVERT_EXPR || TREE_CODE (tem) == NOP_EXPR)
-         tem = TREE_OPERAND (tem, 0);
-
-       if (TREE_CODE (tem) == MODIFY_EXPR || TREE_CODE (tem) == INIT_EXPR
-           || TREE_CODE (tem) == CALL_EXPR)
-         return 0;
-      }
-      goto maybe_warn;
+      goto warn;
 
     case INDIRECT_REF:
       /* Don't warn about automatic dereferencing of references, since
@@ -1484,12 +1453,8 @@ warn_if_unused_value (tree exp, location_t locus)
       if (EXPRESSION_CLASS_P (exp) && TREE_CODE_LENGTH (TREE_CODE (exp)) == 0)
        return 0;
 
-    maybe_warn:
-      /* If this is an expression with side effects, don't warn.  */
-      if (TREE_SIDE_EFFECTS (exp))
-       return 0;
-
-      warning ("%Hvalue computed is not used", &locus);
+    warn:
+      warning (0, "%Hvalue computed is not used", &locus);
       return 1;
     }
 }
@@ -1527,33 +1492,6 @@ expand_naked_return (void)
   emit_jump (end_label);
 }
 
-/* If the current function returns values in the most significant part
-   of a register, shift return value VAL appropriately.  The mode of
-   the function's return type is known not to be BLKmode.  */
-
-static rtx
-shift_return_value (rtx val)
-{
-  tree type;
-
-  type = TREE_TYPE (DECL_RESULT (current_function_decl));
-  if (targetm.calls.return_in_msb (type))
-    {
-      rtx target;
-      HOST_WIDE_INT shift;
-
-      target = DECL_RTL (DECL_RESULT (current_function_decl));
-      shift = (GET_MODE_BITSIZE (GET_MODE (target))
-              - BITS_PER_UNIT * int_size_in_bytes (type));
-      if (shift > 0)
-       val = expand_shift (LSHIFT_EXPR, GET_MODE (target),
-                           gen_lowpart (GET_MODE (target), val),
-                           build_int_cst (NULL_TREE, shift), target, 1);
-    }
-  return val;
-}
-
-
 /* Generate RTL to return from the current function, with value VAL.  */
 
 static void
@@ -1591,15 +1529,9 @@ expand_value_return (rtx val)
 static void
 expand_null_return_1 (void)
 {
-  rtx end_label;
-
   clear_pending_stack_adjust ();
   do_pending_stack_adjust ();
-
-  end_label = return_label;
-  if (end_label == 0)
-     end_label = return_label = gen_label_rtx ();
-  emit_jump (end_label);
+  emit_jump (return_label);
 }
 \f
 /* Generate RTL to evaluate the expression RETVAL and return it
@@ -1770,7 +1702,7 @@ expand_return (tree retval)
       val = expand_expr (retval_rhs, val, GET_MODE (val), 0);
       val = force_not_mem (val);
       /* Return the calculated value.  */
-      expand_value_return (shift_return_value (val));
+      expand_value_return (val);
     }
   else
     {
@@ -2139,8 +2071,10 @@ add_case_node (struct case_node *head, tree type, tree low, tree high,
   if (!high || tree_int_cst_equal (low, high))
     {
       /* If the simple case value is unreachable, ignore it.  */
-      if (tree_int_cst_compare (low, min_value) < 0
-         || tree_int_cst_compare (low, max_value) > 0)
+      if ((TREE_CODE (min_value) == INTEGER_CST
+            && tree_int_cst_compare (low, min_value) < 0)
+         || (TREE_CODE (max_value) == INTEGER_CST
+             && tree_int_cst_compare (low, max_value) > 0))
        return head;
       low = fold_convert (type, low);
       high = low;
@@ -2148,19 +2082,23 @@ add_case_node (struct case_node *head, tree type, tree low, tree high,
   else
     {
       /* If the entire case range is unreachable, ignore it.  */
-      if (tree_int_cst_compare (high, min_value) < 0
-         || tree_int_cst_compare (low, max_value) > 0)
+      if ((TREE_CODE (min_value) == INTEGER_CST
+            && tree_int_cst_compare (high, min_value) < 0)
+         || (TREE_CODE (max_value) == INTEGER_CST
+             && tree_int_cst_compare (low, max_value) > 0))
        return head;
 
       /* If the lower bound is less than the index type's minimum
         value, truncate the range bounds.  */
-      if (tree_int_cst_compare (low, min_value) < 0)
+      if (TREE_CODE (min_value) == INTEGER_CST
+            && tree_int_cst_compare (low, min_value) < 0)
        low = min_value;
       low = fold_convert (type, low);
 
       /* If the upper bound is greater than the index type's maximum
         value, truncate the range bounds.  */
-      if (tree_int_cst_compare (high, max_value) > 0)
+      if (TREE_CODE (max_value) == INTEGER_CST
+         && tree_int_cst_compare (high, max_value) > 0)
        high = max_value;
       high = fold_convert (type, high);
     }
@@ -2279,10 +2217,10 @@ emit_case_bit_tests (tree index_type, tree index_expr, tree minval,
       else
         test[i].bits++;
 
-      lo = tree_low_cst (fold (build2 (MINUS_EXPR, index_type,
-                                      n->low, minval)), 1);
-      hi = tree_low_cst (fold (build2 (MINUS_EXPR, index_type,
-                                      n->high, minval)), 1);
+      lo = tree_low_cst (fold_build2 (MINUS_EXPR, index_type,
+                                     n->low, minval), 1);
+      hi = tree_low_cst (fold_build2 (MINUS_EXPR, index_type,
+                                     n->high, minval), 1);
       for (j = lo; j <= hi; j++)
         if (j >= HOST_BITS_PER_WIDE_INT)
          test[i].hi |= (HOST_WIDE_INT) 1 << (j - HOST_BITS_PER_INT);
@@ -2292,9 +2230,9 @@ emit_case_bit_tests (tree index_type, tree index_expr, tree minval,
 
   qsort (test, count, sizeof(*test), case_bit_test_cmp);
 
-  index_expr = fold (build2 (MINUS_EXPR, index_type,
-                            convert (index_type, index_expr),
-                            convert (index_type, minval)));
+  index_expr = fold_build2 (MINUS_EXPR, index_type,
+                           fold_convert (index_type, index_expr),
+                           fold_convert (index_type, minval));
   index = expand_expr (index_expr, NULL_RTX, VOIDmode, 0);
   do_pending_stack_adjust ();
 
@@ -2338,7 +2276,7 @@ expand_case (tree exp)
 {
   tree minval = NULL_TREE, maxval = NULL_TREE, range = NULL_TREE;
   rtx default_label = 0;
-  struct case_node *n, *m;
+  struct case_node *n;
   unsigned int count, uniq;
   rtx index;
   rtx table_label;
@@ -2362,7 +2300,7 @@ expand_case (tree exp)
   struct case_node *case_list = 0;
 
   /* Label to jump to if no case matches.  */
-  tree default_label_decl = 0;
+  tree default_label_decl;
 
   /* The switch body is lowered in gimplify.c, we should never have
      switches with a non-NULL SWITCH_BODY here.  */
@@ -2374,20 +2312,26 @@ expand_case (tree exp)
   /* An ERROR_MARK occurs for various reasons including invalid data type.  */
   if (index_type != error_mark_node)
     {
-      for (i = TREE_VEC_LENGTH (vec); --i >= 0; )
-       {
-         tree elt = TREE_VEC_ELT (vec, i);
+      tree elt;
+      bitmap label_bitmap;
 
-         /* Handle default labels specially.  */
-         if (!CASE_HIGH (elt) && !CASE_LOW (elt))
-           {
-             gcc_assert (!default_label_decl);
-             default_label_decl = CASE_LABEL (elt);
-           }
-         else
-           case_list = add_case_node (case_list, index_type,
-                                      CASE_LOW (elt), CASE_HIGH (elt),
-                                      CASE_LABEL (elt));
+      /* cleanup_tree_cfg removes all SWITCH_EXPR with their index
+        expressions being INTEGER_CST.  */
+      gcc_assert (TREE_CODE (index_expr) != INTEGER_CST);
+
+      /* The default case is at the end of TREE_VEC.  */
+      elt = TREE_VEC_ELT (vec, TREE_VEC_LENGTH (vec) - 1);
+      gcc_assert (!CASE_HIGH (elt));
+      gcc_assert (!CASE_LOW (elt));
+      default_label_decl = CASE_LABEL (elt);
+
+      for (i = TREE_VEC_LENGTH (vec) - 1; --i >= 0; )
+       {
+         elt = TREE_VEC_ELT (vec, i);
+         gcc_assert (CASE_LOW (elt));
+         case_list = add_case_node (case_list, index_type,
+                                    CASE_LOW (elt), CASE_HIGH (elt),
+                                    CASE_LABEL (elt));
        }
 
 
@@ -2400,23 +2344,15 @@ expand_case (tree exp)
          start = get_last_insn ();
        }
 
-      /* If we don't have a default-label, create one here,
-        after the body of the switch.  */
-      if (default_label_decl == 0)
-       {
-         default_label_decl
-           = build_decl (LABEL_DECL, NULL_TREE, NULL_TREE);
-         expand_label (default_label_decl);
-       }
       default_label = label_rtx (default_label_decl);
 
       before_case = get_last_insn ();
 
-      /* Get upper and lower bounds of case values.
-        Also convert all the case values to the index expr's data type.  */
+      /* Get upper and lower bounds of case values.  */
 
       uniq = 0;
       count = 0;
+      label_bitmap = BITMAP_ALLOC (NULL);
       for (n = case_list; n; n = n->right)
        {
          /* Count the elements and track the largest and smallest
@@ -2437,38 +2373,42 @@ expand_case (tree exp)
          if (! tree_int_cst_equal (n->low, n->high))
            count++;
 
-         /* Count the number of unique case node targets.  */
-          uniq++;
+         /* If we have not seen this label yet, then increase the
+            number of unique case node targets seen.  */
          lab = label_rtx (n->code_label);
-          for (m = case_list; m != n; m = m->right)
-            if (label_rtx (m->code_label) == lab)
-              {
-                uniq--;
-                break;
-              }
+         if (!bitmap_bit_p (label_bitmap, CODE_LABEL_NUMBER (lab)))
+           {
+             bitmap_set_bit (label_bitmap, CODE_LABEL_NUMBER (lab));
+             uniq++;
+           }
        }
 
-      /* Compute span of values.  */
-      if (count != 0)
-       range = fold (build2 (MINUS_EXPR, index_type, maxval, minval));
+      BITMAP_FREE (label_bitmap);
 
+      /* cleanup_tree_cfg removes all SWITCH_EXPR with a single
+        destination, such as one with a default case only.  However,
+        it doesn't remove cases that are out of range for the switch
+        type, so we may still get a zero here.  */
       if (count == 0)
        {
-         expand_expr (index_expr, const0_rtx, VOIDmode, 0);
          emit_jump (default_label);
+         return;
        }
 
+      /* Compute span of values.  */
+      range = fold_build2 (MINUS_EXPR, index_type, maxval, minval);
+
       /* Try implementing this switch statement by a short sequence of
         bit-wise comparisons.  However, we let the binary-tree case
         below handle constant index expressions.  */
-      else if (CASE_USE_BIT_TESTS
-              && ! TREE_CONSTANT (index_expr)
-              && compare_tree_int (range, GET_MODE_BITSIZE (word_mode)) < 0
-              && compare_tree_int (range, 0) > 0
-              && lshift_cheap_p ()
-              && ((uniq == 1 && count >= 3)
-                  || (uniq == 2 && count >= 5)
-                  || (uniq == 3 && count >= 6)))
+      if (CASE_USE_BIT_TESTS
+         && ! TREE_CONSTANT (index_expr)
+         && compare_tree_int (range, GET_MODE_BITSIZE (word_mode)) < 0
+         && compare_tree_int (range, 0) > 0
+         && lshift_cheap_p ()
+         && ((uniq == 1 && count >= 3)
+             || (uniq == 2 && count >= 5)
+             || (uniq == 3 && count >= 6)))
        {
          /* Optimize the case where all the case values fit in a
             word without having to subtract MINVAL.  In this case,
@@ -2476,7 +2416,7 @@ expand_case (tree exp)
          if (compare_tree_int (minval, 0) > 0
              && compare_tree_int (maxval, GET_MODE_BITSIZE (word_mode)) < 0)
            {
-             minval = integer_zero_node;
+             minval = build_int_cst (index_type, 0);
              range = maxval;
            }
          emit_case_bit_tests (index_type, index_expr, minval, range,
@@ -2497,6 +2437,7 @@ expand_case (tree exp)
 #ifndef ASM_OUTPUT_ADDR_DIFF_ELT
               || flag_pic
 #endif
+              || !flag_jump_tables
               || TREE_CONSTANT (index_expr)
               /* If neither casesi or tablejump is available, we can
                  only go this way.  */
@@ -2526,58 +2467,26 @@ expand_case (tree exp)
 
          if (MEM_P (index))
            index = copy_to_reg (index);
-         if (GET_CODE (index) == CONST_INT
-             || TREE_CODE (index_expr) == INTEGER_CST)
-           {
-             /* Make a tree node with the proper constant value
-                if we don't already have one.  */
-             if (TREE_CODE (index_expr) != INTEGER_CST)
-               {
-                 index_expr
-                   = build_int_cst_wide (NULL_TREE, INTVAL (index),
-                                         unsignedp || INTVAL (index) >= 0
-                                         ? 0 : -1);
-                 index_expr = convert (index_type, index_expr);
-               }
 
-             /* For constant index expressions we need only
-                issue an unconditional branch to the appropriate
-                target code.  The job of removing any unreachable
-                code is left to the optimization phase if the
-                "-O" option is specified.  */
-             for (n = case_list; n; n = n->right)
-               if (! tree_int_cst_lt (index_expr, n->low)
-                   && ! tree_int_cst_lt (n->high, index_expr))
-                 break;
-
-             if (n)
-               emit_jump (label_rtx (n->code_label));
-             else
-               emit_jump (default_label);
-           }
-         else
-           {
-             /* If the index expression is not constant we generate
-                a binary decision tree to select the appropriate
-                target code.  This is done as follows:
+         /* We generate a binary decision tree to select the
+            appropriate target code.  This is done as follows:
 
-                The list of cases is rearranged into a binary tree,
-                nearly optimal assuming equal probability for each case.
+            The list of cases is rearranged into a binary tree,
+            nearly optimal assuming equal probability for each case.
 
-                The tree is transformed into RTL, eliminating
-                redundant test conditions at the same time.
+            The tree is transformed into RTL, eliminating
+            redundant test conditions at the same time.
 
-                If program flow could reach the end of the
-                decision tree an unconditional jump to the
-                default code is emitted.  */
+            If program flow could reach the end of the
+            decision tree an unconditional jump to the
+            default code is emitted.  */
 
-             use_cost_table
-               = (TREE_CODE (orig_type) != ENUMERAL_TYPE
-                  && estimate_case_costs (case_list));
-             balance_case_nodes (&case_list, NULL);
-             emit_case_nodes (index, case_list, default_label, index_type);
-             emit_jump (default_label);
-           }
+         use_cost_table
+           = (TREE_CODE (orig_type) != ENUMERAL_TYPE
+              && estimate_case_costs (case_list));
+         balance_case_nodes (&case_list, NULL);
+         emit_case_nodes (index, case_list, default_label, index_type);
+         emit_jump (default_label);
        }
       else
        {
@@ -2586,7 +2495,6 @@ expand_case (tree exp)
                            table_label, default_label))
            {
              bool ok;
-             index_type = integer_type_node;
 
              /* Index jumptables from zero for suitable values of
                  minval to avoid a subtraction.  */
@@ -2594,7 +2502,7 @@ expand_case (tree exp)
                  && compare_tree_int (minval, 0) > 0
                  && compare_tree_int (minval, 3) < 0)
                {
-                 minval = integer_zero_node;
+                 minval = build_int_cst (index_type, 0);
                  range = maxval;
                }
 
@@ -2615,11 +2523,11 @@ expand_case (tree exp)
                 value since that should fit in a HOST_WIDE_INT while the
                 actual values may not.  */
              HOST_WIDE_INT i_low
-               = tree_low_cst (fold (build2 (MINUS_EXPR, index_type,
-                                             n->low, minval)), 1);
+               = tree_low_cst (fold_build2 (MINUS_EXPR, index_type,
+                                            n->low, minval), 1);
              HOST_WIDE_INT i_high
-               = tree_low_cst (fold (build2 (MINUS_EXPR, index_type,
-                                             n->high, minval)), 1);
+               = tree_low_cst (fold_build2 (MINUS_EXPR, index_type,
+                                            n->high, minval), 1);
              HOST_WIDE_INT i;
 
              for (i = i_low; i <= i_high; i ++)
@@ -2644,14 +2552,8 @@ expand_case (tree exp)
            emit_jump_insn (gen_rtx_ADDR_VEC (CASE_VECTOR_MODE,
                                              gen_rtvec_v (ncases, labelvec)));
 
-         /* If the case insn drops through the table,
-            after the table we must jump to the default-label.
-            Otherwise record no drop-through after the table.  */
-#ifdef CASE_DROPS_THROUGH
-         emit_jump (default_label);
-#else
+         /* Record no drop-through after the table.  */
          emit_barrier ();
-#endif
        }
 
       before_case = NEXT_INSN (before_case);
@@ -2708,8 +2610,7 @@ static int
 estimate_case_costs (case_node_ptr node)
 {
   tree min_ascii = integer_minus_one_node;
-  tree max_ascii = convert (TREE_TYPE (node->high),
-                           build_int_cst (NULL_TREE, 127));
+  tree max_ascii = build_int_cst (TREE_TYPE (node->high), 127);
   case_node_ptr n;
   int i;
 
@@ -2907,8 +2808,9 @@ node_has_low_bound (case_node_ptr node, tree index_type)
   if (node->left)
     return 0;
 
-  low_minus_one = fold (build2 (MINUS_EXPR, TREE_TYPE (node->low),
-                               node->low, integer_one_node));
+  low_minus_one = fold_build2 (MINUS_EXPR, TREE_TYPE (node->low),
+                              node->low,
+                              build_int_cst (TREE_TYPE (node->low), 1));
 
   /* If the subtraction above overflowed, we can't verify anything.
      Otherwise, look for a parent that tests our value - 1.  */
@@ -2957,8 +2859,9 @@ node_has_high_bound (case_node_ptr node, tree index_type)
   if (node->right)
     return 0;
 
-  high_plus_one = fold (build2 (PLUS_EXPR, TREE_TYPE (node->high),
-                               node->high, integer_one_node));
+  high_plus_one = fold_build2 (PLUS_EXPR, TREE_TYPE (node->high),
+                              node->high,
+                              build_int_cst (TREE_TYPE (node->high), 1));
 
   /* If the addition above overflowed, we can't verify anything.
      Otherwise, look for a parent that tests our value + 1.  */
@@ -3138,11 +3041,12 @@ emit_case_nodes (rtx index, case_node_ptr node, rtx default_label,
 
       else if (node->right != 0 && node->left == 0)
        {
-         /* Here we have a right child but no left so we issue conditional
+         /* Here we have a right child but no left so we issue conditional
             branch to default and process the right child.
 
-            Omit the conditional branch to default if we it avoid only one
-            right child; it costs too much space to save so little time.  */
+            Omit the conditional branch to default if the right child
+            does not have any children and is single valued; it would
+            cost too much space to save so little time.  */
 
          if (node->right->right || node->right->left
              || !tree_int_cst_equal (node->right->low, node->right->high))
@@ -3381,8 +3285,8 @@ emit_case_nodes (rtx index, case_node_ptr node, rtx default_label,
              new_index = expand_simple_binop (mode, MINUS, index, low_rtx,
                                               NULL_RTX, unsignedp,
                                               OPTAB_WIDEN);
-             new_bound = expand_expr (fold (build2 (MINUS_EXPR, type,
-                                                    high, low)),
+             new_bound = expand_expr (fold_build2 (MINUS_EXPR, type,
+                                                   high, low),
                                       NULL_RTX, mode, 0);
 
              emit_cmp_and_jump_insns (new_index, new_bound, GT, NULL_RTX,