OSDN Git Service

Merge from gcc-2.8
[pf3gnuchains/gcc-fork.git] / gcc / expr.c
index f07b3f6..a84beb5 100644 (file)
@@ -110,9 +110,13 @@ static rtx saveregs_value;
 /* Similarly for __builtin_apply_args.  */
 static rtx apply_args_value;
 
+/* Don't check memory usage, since code is being emitted to check a memory
+   usage.  Used when flag_check_memory_usage is true, to avoid infinite
+   recursion.  */
+static int in_check_memory_usage;
+
 /* This structure is used by move_by_pieces to describe the move to
    be performed.  */
-
 struct move_by_pieces
 {
   rtx to;
@@ -2551,10 +2555,11 @@ emit_push_insn (x, mode, type, size, align, partial, reg, extra,
          move_by_pieces (gen_rtx (MEM, BLKmode, gen_push_operand ()), xinner,
                          INTVAL (size) - used, align);
 
-         if (flag_check_memory_usage)
+         if (flag_check_memory_usage && ! in_check_memory_usage)
            {
              rtx temp;
              
+             in_check_memory_usage = 1;
              temp = get_push_address (INTVAL(size) - used);
              if (GET_CODE (x) == MEM && AGGREGATE_TYPE_P (type))
                emit_library_call (chkr_copy_bitmap_libfunc, 1, VOIDmode, 3,
@@ -2567,7 +2572,9 @@ emit_push_insn (x, mode, type, size, align, partial, reg, extra,
                                   temp, ptr_mode,
                                   GEN_INT (INTVAL(size) - used),
                                   TYPE_MODE (sizetype),
-                                  GEN_INT (MEMORY_USE_RW), QImode);
+                                  GEN_INT (MEMORY_USE_RW),
+                                  TYPE_MODE (integer_type_node));
+             in_check_memory_usage = 0;
            }
        }
       else
@@ -2604,10 +2611,11 @@ emit_push_insn (x, mode, type, size, align, partial, reg, extra,
                                   plus_constant (gen_rtx (PLUS, Pmode,
                                                           args_addr, args_so_far),
                                                  skip));
-         if (flag_check_memory_usage)
+         if (flag_check_memory_usage && ! in_check_memory_usage)
            {
              rtx target;
              
+             in_check_memory_usage = 1;
              target = copy_to_reg (temp);
              if (GET_CODE (x) == MEM && AGGREGATE_TYPE_P (type))
                emit_library_call (chkr_copy_bitmap_libfunc, 1, VOIDmode, 3,
@@ -2618,7 +2626,9 @@ emit_push_insn (x, mode, type, size, align, partial, reg, extra,
                emit_library_call (chkr_set_right_libfunc, 1, VOIDmode, 3,
                                   target, ptr_mode,
                                   size, TYPE_MODE (sizetype),
-                                  GEN_INT (MEMORY_USE_RW), QImode);
+                                  GEN_INT (MEMORY_USE_RW),
+                                  TYPE_MODE (integer_type_node));
+             in_check_memory_usage = 0;
            }
 
          /* TEMP is the address of the block.  Copy the data there.  */
@@ -2813,8 +2823,9 @@ emit_push_insn (x, mode, type, size, align, partial, reg, extra,
 
       emit_move_insn (gen_rtx (MEM, mode, addr), x);
 
-      if (flag_check_memory_usage)
+      if (flag_check_memory_usage && ! in_check_memory_usage)
        {
+         in_check_memory_usage = 1;
          if (target == 0)
            target = get_push_address (GET_MODE_SIZE (mode));
 
@@ -2829,7 +2840,9 @@ emit_push_insn (x, mode, type, size, align, partial, reg, extra,
                               target, ptr_mode,
                               GEN_INT (GET_MODE_SIZE (mode)),
                               TYPE_MODE (sizetype),
-                              GEN_INT (MEMORY_USE_RW), QImode);
+                              GEN_INT (MEMORY_USE_RW),
+                              TYPE_MODE (integer_type_node));
+         in_check_memory_usage = 0;
        }
     }
 
@@ -2954,6 +2967,15 @@ expand_assignment (to, from, want_value, suggest_reg)
 #endif
        }
 
+      if (TREE_CODE (to) == COMPONENT_REF
+         && TREE_READONLY (TREE_OPERAND (to, 1)))
+       {
+         if (offset = 0)
+           to_rtx = copy_rtx (to_rtx);
+
+         RTX_UNCHANGING_P (to_rtx) = 1;
+       }
+
       /* Check the access.  */
       if (flag_check_memory_usage && GET_CODE (to_rtx) == MEM)
        {
@@ -2978,7 +3000,8 @@ expand_assignment (to, from, want_value, suggest_reg)
            emit_library_call (chkr_check_addr_libfunc, 1, VOIDmode, 3,
                               to_addr, ptr_mode,
                               GEN_INT (size), TYPE_MODE (sizetype),
-                              GEN_INT (MEMORY_USE_WO), QImode);
+                              GEN_INT (MEMORY_USE_WO),
+                              TYPE_MODE (integer_type_node));
        }
 
       result = store_field (to_rtx, bitsize, bitpos, mode1, from,
@@ -3169,16 +3192,16 @@ store_expr (exp, target, want_value)
       do_pending_stack_adjust ();
       NO_DEFER_POP;
       jumpifnot (TREE_OPERAND (exp, 0), lab1);
-      start_cleanup_deferal ();
+      start_cleanup_deferral ();
       store_expr (TREE_OPERAND (exp, 1), target, 0);
-      end_cleanup_deferal ();
+      end_cleanup_deferral ();
       emit_queue ();
       emit_jump_insn (gen_jump (lab2));
       emit_barrier ();
       emit_label (lab1);
-      start_cleanup_deferal ();
+      start_cleanup_deferral ();
       store_expr (TREE_OPERAND (exp, 2), target, 0);
-      end_cleanup_deferal ();
+      end_cleanup_deferral ();
       emit_queue ();
       emit_label (lab2);
       OK_DEFER_POP;
@@ -3309,7 +3332,8 @@ store_expr (exp, target, want_value)
         emit_library_call (chkr_check_addr_libfunc, 1, VOIDmode, 3,
                           XEXP (target, 0), ptr_mode, 
                           expr_size (exp), TYPE_MODE (sizetype),
-                          GEN_INT (MEMORY_USE_WO), QImode);
+                          GEN_INT (MEMORY_USE_WO), 
+                          TYPE_MODE (integer_type_node));
     }
 
   /* If value was not generated in the target, store it there.
@@ -3400,7 +3424,8 @@ store_expr (exp, target, want_value)
                    emit_library_call (chkr_check_addr_libfunc, 1, VOIDmode, 3,
                                       addr, ptr_mode,
                                       size, TYPE_MODE (sizetype),
-                                      GEN_INT (MEMORY_USE_WO), QImode);
+                                      GEN_INT (MEMORY_USE_WO), 
+                                      TYPE_MODE (integer_type_node));
 #ifdef TARGET_MEM_FUNCTIONS
                  emit_library_call (memset_libfunc, 0, VOIDmode, 3,
                                     addr, ptr_mode,
@@ -3675,7 +3700,7 @@ store_constructor (exp, target, cleared)
 
              if (contains_placeholder_p (offset))
                offset = build (WITH_RECORD_EXPR, sizetype,
-                               offset, exp);
+                               offset, make_tree (TREE_TYPE (exp), target));
 
              offset = size_binop (FLOOR_DIV_EXPR, offset,
                                   size_int (BITS_PER_UNIT));
@@ -4403,9 +4428,14 @@ get_inner_reference (exp, pbitsize, pbitpos, poffset, pmode,
              && TREE_INT_CST_HIGH (index) == 0)
            *pbitpos += TREE_INT_CST_LOW (index);
          else
-           offset = size_binop (PLUS_EXPR, offset,
-                                size_binop (FLOOR_DIV_EXPR, index,
-                                            size_int (BITS_PER_UNIT)));
+           {
+             offset = size_binop (PLUS_EXPR, offset,
+                                  size_binop (FLOOR_DIV_EXPR, index,
+                                              size_int (BITS_PER_UNIT)));
+
+             if (contains_placeholder_p (offset))
+               offset = build (WITH_RECORD_EXPR, sizetype, offset, exp);
+           }
        }
       else if (TREE_CODE (exp) != NON_LVALUE_EXPR
               && ! ((TREE_CODE (exp) == NOP_EXPR
@@ -5016,7 +5046,8 @@ expand_expr (exp, target, tmode, modifier)
                               XEXP (DECL_RTL (exp), 0), ptr_mode,
                               GEN_INT (int_size_in_bytes (type)),
                               TYPE_MODE (sizetype),
-                              GEN_INT (memory_usage), QImode);
+                              GEN_INT (memory_usage),
+                              TYPE_MODE (integer_type_node));
        }
 
       /* ... fall through ...  */
@@ -5483,7 +5514,8 @@ expand_expr (exp, target, tmode, modifier)
                                 op0, ptr_mode,
                                 GEN_INT (int_size_in_bytes (type)),
                                 TYPE_MODE (sizetype),
-                                GEN_INT (memory_usage), QImode);
+                                GEN_INT (memory_usage),
+                                TYPE_MODE (integer_type_node));
          }
 
        temp = gen_rtx (MEM, mode, op0);
@@ -5737,7 +5769,8 @@ expand_expr (exp, target, tmode, modifier)
                                     to, ptr_mode,
                                     GEN_INT (size / BITS_PER_UNIT),
                                     TYPE_MODE (sizetype),
-                                    GEN_INT (memory_usage), QImode);
+                                    GEN_INT (memory_usage), 
+                                    TYPE_MODE (integer_type_node));
              }
          }
 
@@ -6859,7 +6892,7 @@ expand_expr (exp, target, tmode, modifier)
            else
              jumpifnot (TREE_OPERAND (exp, 0), op0);
 
-           start_cleanup_deferal ();
+           start_cleanup_deferral ();
            if (binary_op && temp == 0)
              /* Just touch the other operand.  */
              expand_expr (TREE_OPERAND (binary_op, 1),
@@ -6893,7 +6926,7 @@ expand_expr (exp, target, tmode, modifier)
            store_expr (TREE_OPERAND (exp, 1), temp, 0);
            jumpif (TREE_OPERAND (exp, 0), op0);
 
-           start_cleanup_deferal ();
+           start_cleanup_deferral ();
            store_expr (TREE_OPERAND (exp, 2), temp, 0);
            op1 = op0;
          }
@@ -6911,7 +6944,7 @@ expand_expr (exp, target, tmode, modifier)
            store_expr (TREE_OPERAND (exp, 2), temp, 0);
            jumpifnot (TREE_OPERAND (exp, 0), op0);
 
-           start_cleanup_deferal ();
+           start_cleanup_deferral ();
            store_expr (TREE_OPERAND (exp, 1), temp, 0);
            op1 = op0;
          }
@@ -6920,18 +6953,18 @@ expand_expr (exp, target, tmode, modifier)
            op1 = gen_label_rtx ();
            jumpifnot (TREE_OPERAND (exp, 0), op0);
 
-           start_cleanup_deferal ();
+           start_cleanup_deferral ();
            if (temp != 0)
              store_expr (TREE_OPERAND (exp, 1), temp, 0);
            else
              expand_expr (TREE_OPERAND (exp, 1),
                           ignore ? const0_rtx : NULL_RTX, VOIDmode, 0);
-           end_cleanup_deferal ();
+           end_cleanup_deferral ();
            emit_queue ();
            emit_jump_insn (gen_jump (op1));
            emit_barrier ();
            emit_label (op0);
-           start_cleanup_deferal ();
+           start_cleanup_deferral ();
            if (temp != 0)
              store_expr (TREE_OPERAND (exp, 2), temp, 0);
            else
@@ -6939,7 +6972,7 @@ expand_expr (exp, target, tmode, modifier)
                           ignore ? const0_rtx : NULL_RTX, VOIDmode, 0);
          }
 
-       end_cleanup_deferal ();
+       end_cleanup_deferral ();
 
        emit_queue ();
        emit_label (op1);
@@ -8855,7 +8888,8 @@ expand_builtin (exp, target, subtarget, mode, ignore)
          if (flag_check_memory_usage)
            emit_library_call (chkr_check_str_libfunc, 1, VOIDmode, 2,
                               src_rtx, ptr_mode,
-                              GEN_INT (MEMORY_USE_RO), QImode);
+                              GEN_INT (MEMORY_USE_RO),
+                              TYPE_MODE (integer_type_node));
 
          char_rtx = const0_rtx;
          char_mode = insn_operand_mode[(int)icode][2];
@@ -9024,7 +9058,8 @@ expand_builtin (exp, target, subtarget, mode, ignore)
            emit_library_call (chkr_check_addr_libfunc, 1, VOIDmode, 3,
                               dest_rtx, ptr_mode,
                               len_rtx, TYPE_MODE (sizetype),
-                              GEN_INT (MEMORY_USE_WO), QImode);
+                              GEN_INT (MEMORY_USE_WO),
+                              TYPE_MODE (integer_type_node));
 
 
          /* There could be a void* cast on top of the object.  */
@@ -9598,7 +9633,14 @@ expand_builtin_apply (function, arguments, argsize)
 
   /* Push a new argument block and copy the arguments.  */
   do_pending_stack_adjust ();
-  emit_stack_save (SAVE_BLOCK, &old_stack_level, NULL_RTX);
+
+  /* Save the stack with nonlocal if available */
+#ifdef HAVE_save_stack_nonlocal
+  if (HAVE_save_stack_nonlocal)
+    emit_stack_save (SAVE_NONLOCAL, &old_stack_level, NULL_RTX);
+  else
+#endif
+    emit_stack_save (SAVE_BLOCK, &old_stack_level, NULL_RTX);
 
   /* Push a block of memory onto the stack to store the memory arguments.
      Save the address in a register, and copy the memory arguments.  ??? I
@@ -9724,7 +9766,12 @@ expand_builtin_apply (function, arguments, argsize)
     CALL_INSN_FUNCTION_USAGE (call_insn) = call_fusage;
 
   /* Restore the stack.  */
-  emit_stack_restore (SAVE_BLOCK, old_stack_level, NULL_RTX);
+#ifdef HAVE_save_stack_nonlocal
+  if (HAVE_save_stack_nonlocal)
+    emit_stack_restore (SAVE_NONLOCAL, old_stack_level, NULL_RTX);
+  else
+#endif
+    emit_stack_restore (SAVE_BLOCK, old_stack_level, NULL_RTX);
 
   /* Return the address of the result block.  */
   return copy_addr_to_reg (XEXP (result, 0));
@@ -10249,18 +10296,18 @@ do_jump (exp, if_false_label, if_true_label)
       if (if_false_label == 0)
        if_false_label = drop_through_label = gen_label_rtx ();
       do_jump (TREE_OPERAND (exp, 0), if_false_label, NULL_RTX);
-      start_cleanup_deferal ();
+      start_cleanup_deferral ();
       do_jump (TREE_OPERAND (exp, 1), if_false_label, if_true_label);
-      end_cleanup_deferal ();
+      end_cleanup_deferral ();
       break;
 
     case TRUTH_ORIF_EXPR:
       if (if_true_label == 0)
        if_true_label = drop_through_label = gen_label_rtx ();
       do_jump (TREE_OPERAND (exp, 0), NULL_RTX, if_true_label);
-      start_cleanup_deferal ();
+      start_cleanup_deferral ();
       do_jump (TREE_OPERAND (exp, 1), if_false_label, if_true_label);
-      end_cleanup_deferal ();
+      end_cleanup_deferral ();
       break;
 
     case COMPOUND_EXPR:
@@ -10321,7 +10368,7 @@ do_jump (exp, if_false_label, if_true_label)
 
          do_jump (TREE_OPERAND (exp, 0), label1, NULL_RTX);
 
-         start_cleanup_deferal ();
+         start_cleanup_deferral ();
          /* Now the THEN-expression.  */
          do_jump (TREE_OPERAND (exp, 1),
                   if_false_label ? if_false_label : drop_through_label,
@@ -10334,7 +10381,7 @@ do_jump (exp, if_false_label, if_true_label)
          do_jump (TREE_OPERAND (exp, 2),
                   if_false_label ? if_false_label : drop_through_label,
                   if_true_label ? if_true_label : drop_through_label);
-         end_cleanup_deferal ();
+         end_cleanup_deferral ();
        }
       break;