OSDN Git Service

* genemit.c (gen_insn): Call gen_exp with a non-null used
[pf3gnuchains/gcc-fork.git] / gcc / stmt.c
index 3bb4f42..d5a181b 100644 (file)
@@ -1,6 +1,6 @@
 /* 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, 2005
+   1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006
    Free Software Foundation, Inc.
 
 This file is part of GCC.
@@ -112,7 +112,6 @@ 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 void expand_value_return (rtx);
-static void do_jump_if_equal (rtx, rtx, rtx, int);
 static int estimate_case_costs (case_node_ptr);
 static bool lshift_cheap_p (void);
 static int case_bit_test_cmp (const void *, const void *);
@@ -568,9 +567,9 @@ decl_overlaps_hard_reg_set_p (tree *declp, int *walk_subtrees ATTRIBUTE_UNUSED,
   tree decl = *declp;
   const HARD_REG_SET *regs = data;
 
-  if (TREE_CODE (decl) == VAR_DECL || TREE_CODE (decl) == PARM_DECL)
+  if (TREE_CODE (decl) == VAR_DECL)
     {
-      if (DECL_REGISTER (decl)
+      if (DECL_HARD_REGISTER (decl)
          && REG_P (DECL_RTL (decl))
          && REGNO (DECL_RTL (decl)) < FIRST_PSEUDO_REGISTER)
        {
@@ -586,7 +585,7 @@ decl_overlaps_hard_reg_set_p (tree *declp, int *walk_subtrees ATTRIBUTE_UNUSED,
        }
       walk_subtrees = 0;
     }
-  else if (TYPE_P (decl))
+  else if (TYPE_P (decl) || TREE_CODE (decl) == PARM_DECL)
     walk_subtrees = 0;
   return NULL_TREE;
 }
@@ -694,7 +693,11 @@ expand_asm_operands (tree string, tree outputs, tree inputs,
   CLEAR_HARD_REG_SET (clobbered_regs);
   for (tail = clobbers; tail; tail = TREE_CHAIN (tail))
     {
-      const char *regname = TREE_STRING_POINTER (TREE_VALUE (tail));
+      const char *regname;
+
+      if (TREE_VALUE (tail) == error_mark_node)
+       return;
+      regname = TREE_STRING_POINTER (TREE_VALUE (tail));
 
       i = decode_reg_name (regname);
       if (i >= 0 || i == -4)
@@ -882,9 +885,13 @@ expand_asm_operands (tree string, tree outputs, tree inputs,
 
       val = TREE_VALUE (tail);
       type = TREE_TYPE (val);
+      /* EXPAND_INITIALIZER will not generate code for valid initializer
+        constants, but will still generate code for other types of operand.
+        This is the behavior we want for constant constraints.  */
       op = expand_expr (val, NULL_RTX, VOIDmode,
-                       (allows_mem && !allows_reg
-                        ? EXPAND_MEMORY : EXPAND_NORMAL));
+                       allows_reg ? EXPAND_NORMAL
+                       : allows_mem ? EXPAND_MEMORY
+                       : EXPAND_INITIALIZER);
 
       /* Never pass a CONCAT to an ASM.  */
       if (GET_CODE (op) == CONCAT)
@@ -2287,7 +2294,7 @@ emit_case_bit_tests (tree index_type, tree index_expr, tree minval,
 #define HAVE_tablejump 0
 #endif
 
-/* Terminate a case (Pascal) or switch (C) statement
+/* Terminate a case (Pascal/Ada) or switch (C) statement
    in which ORIG_INDEX is the expression to be tested.
    If ORIG_TYPE is not NULL, it is the original ORIG_INDEX
    type as given in the source before any compiler conversions.
@@ -2349,26 +2356,24 @@ expand_case (tree exp)
 
       for (i = TREE_VEC_LENGTH (vec) - 1; --i >= 0; )
        {
+         tree low, high;
          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));
-       }
 
+         low = CASE_LOW (elt);
+         gcc_assert (low);
+         high = CASE_HIGH (elt);
 
-      /* Make sure start points to something that won't need any
-        transformation before the end of this function.  */
-      start = get_last_insn ();
-      if (! NOTE_P (start))
-       {
-         emit_note (NOTE_INSN_DELETED);
-         start = get_last_insn ();
+         /* Discard empty ranges.  */
+         if (high && INT_CST_LT (high, low))
+           continue;
+
+         case_list = add_case_node (case_list, index_type, low, high,
+                                    CASE_LABEL (elt));
        }
 
-      default_label = label_rtx (default_label_decl);
 
-      before_case = get_last_insn ();
+      before_case = start = get_last_insn ();
+      default_label = label_rtx (default_label_decl);
 
       /* Get upper and lower bounds of case values.  */
 
@@ -2588,21 +2593,14 @@ expand_case (tree exp)
   free_temp_slots ();
 }
 
-/* Generate code to jump to LABEL if OP1 and OP2 are equal.  */
+/* Generate code to jump to LABEL if OP0 and OP1 are equal in mode MODE.  */
 
 static void
-do_jump_if_equal (rtx op1, rtx op2, rtx label, int unsignedp)
+do_jump_if_equal (enum machine_mode mode, rtx op0, rtx op1, rtx label,
+                 int unsignedp)
 {
-  if (GET_CODE (op1) == CONST_INT && GET_CODE (op2) == CONST_INT)
-    {
-      if (op1 == op2)
-       emit_jump (label);
-    }
-  else
-    emit_cmp_and_jump_insns (op1, op2, EQ, NULL_RTX,
-                            (GET_MODE (op1) == VOIDmode
-                            ? GET_MODE (op2) : GET_MODE (op1)),
-                            unsignedp, label);
+  do_compare_rtx_and_jump (op0, op1, EQ, unsignedp, mode,
+                          NULL_RTX, NULL_RTX, label);
 }
 \f
 /* Not all case values are encountered equally.  This function
@@ -2944,6 +2942,10 @@ emit_case_nodes (rtx index, case_node_ptr node, rtx default_label,
   enum machine_mode mode = GET_MODE (index);
   enum machine_mode imode = TYPE_MODE (index_type);
 
+  /* Handle indices detected as constant during RTL expansion.  */
+  if (mode == VOIDmode)
+    mode = imode;
+
   /* See if our parents have already tested everything for us.
      If they have, emit an unconditional jump for this node.  */
   if (node_is_bounded (node, index_type))
@@ -2954,7 +2956,7 @@ emit_case_nodes (rtx index, case_node_ptr node, rtx default_label,
       /* Node is single valued.  First see if the index expression matches
         this node and then check our children, if any.  */
 
-      do_jump_if_equal (index,
+      do_jump_if_equal (mode, index,
                        convert_modes (mode, imode,
                                       expand_normal (node->low),
                                       unsignedp),
@@ -3007,7 +3009,7 @@ emit_case_nodes (rtx index, case_node_ptr node, rtx default_label,
 
              /* See if the value matches what the right hand side
                 wants.  */
-             do_jump_if_equal (index,
+             do_jump_if_equal (mode, index,
                                convert_modes (mode, imode,
                                               expand_normal (node->right->low),
                                               unsignedp),
@@ -3016,7 +3018,7 @@ emit_case_nodes (rtx index, case_node_ptr node, rtx default_label,
 
              /* See if the value matches what the left hand side
                 wants.  */
-             do_jump_if_equal (index,
+             do_jump_if_equal (mode, index,
                                convert_modes (mode, imode,
                                               expand_normal (node->left->low),
                                               unsignedp),
@@ -3082,7 +3084,7 @@ emit_case_nodes (rtx index, case_node_ptr node, rtx default_label,
            /* We cannot process node->right normally
               since we haven't ruled out the numbers less than
               this node's value.  So handle node->right explicitly.  */
-           do_jump_if_equal (index,
+           do_jump_if_equal (mode, index,
                              convert_modes
                              (mode, imode,
                               expand_normal (node->right->low),
@@ -3113,7 +3115,7 @@ emit_case_nodes (rtx index, case_node_ptr node, rtx default_label,
            /* We cannot process node->left normally
               since we haven't ruled out the numbers less than
               this node's value.  So handle node->left explicitly.  */
-           do_jump_if_equal (index,
+           do_jump_if_equal (mode, index,
                              convert_modes
                              (mode, imode,
                               expand_normal (node->left->low),