OSDN Git Service

Move constructor/destructor handling into target hooks.
[pf3gnuchains/gcc-fork.git] / gcc / explow.c
index b1c2a89..9f2357a 100644 (file)
@@ -1,6 +1,6 @@
 /* Subroutines for manipulating rtx's in semantically interesting ways.
    Copyright (C) 1987, 1991, 1994, 1995, 1996, 1997, 1998,
-   1999, 2000 Free Software Foundation, Inc.
+   1999, 2000, 2001 Free Software Foundation, Inc.
 
 This file is part of GNU CC.
 
@@ -78,6 +78,7 @@ plus_constant_wide (x, c)
      register HOST_WIDE_INT c;
 {
   register RTX_CODE code;
+  rtx y;
   register enum machine_mode mode;
   register rtx tem;
   int all_constant = 0;
@@ -89,6 +90,8 @@ plus_constant_wide (x, c)
 
   code = GET_CODE (x);
   mode = GET_MODE (x);
+  y = x;
+
   switch (code)
     {
     case CONST_INT:
@@ -159,22 +162,24 @@ plus_constant_wide (x, c)
          x = XEXP (x, 0);
          goto restart;
        }
-      else if (CONSTANT_P (XEXP (x, 0)))
+      else if (CONSTANT_P (XEXP (x, 1)))
        {
-         x = gen_rtx_PLUS (mode,
-                           plus_constant (XEXP (x, 0), c),
-                           XEXP (x, 1));
+         x = gen_rtx_PLUS (mode, XEXP (x, 0), plus_constant (XEXP (x, 1), c));
          c = 0;
        }
-      else if (CONSTANT_P (XEXP (x, 1)))
+      else if (find_constant_term_loc (&y))
        {
-         x = gen_rtx_PLUS (mode,
-                           XEXP (x, 0),
-                           plus_constant (XEXP (x, 1), c));
+         /* We need to be careful since X may be shared and we can't
+            modify it in place.  */
+         rtx copy = copy_rtx (x);
+         rtx *const_loc = find_constant_term_loc (&copy);
+
+         *const_loc = plus_constant (*const_loc, c);
+         x = copy;
          c = 0;
        }
       break;
-      
+
     default:
       break;
     }
@@ -189,25 +194,6 @@ plus_constant_wide (x, c)
   else
     return x;
 }
-
-/* This is the same as `plus_constant', except that it handles LO_SUM.
-
-   This function should be used via the `plus_constant_for_output' macro.  */
-
-rtx
-plus_constant_for_output_wide (x, c)
-     register rtx x;
-     register HOST_WIDE_INT c;
-{
-  register enum machine_mode mode = GET_MODE (x);
-
-  if (GET_CODE (x) == LO_SUM)
-    return gen_rtx_LO_SUM (mode, XEXP (x, 0),
-                          plus_constant_for_output (XEXP (x, 1), c));
-
-  else
-    return plus_constant (x, c);
-}
 \f
 /* If X is a sum, return a new sum like X but lacking any constant terms.
    Add all the removed constant terms into *CONSTPTR.
@@ -301,7 +287,13 @@ rtx
 expr_size (exp)
      tree exp;
 {
-  tree size = size_in_bytes (TREE_TYPE (exp));
+  tree size;
+
+  if (TREE_CODE_CLASS (TREE_CODE (exp)) == 'd'
+      && DECL_SIZE_UNIT (exp) != 0)
+    size = DECL_SIZE_UNIT (exp);
+  else
+    size = size_in_bytes (TREE_TYPE (exp));
 
   if (TREE_CODE (size) != INTEGER_CST
       && contains_placeholder_p (size))
@@ -373,25 +365,36 @@ convert_memory_address (to_mode, x)
       return x;
 
     case SUBREG:
-      if (GET_MODE (SUBREG_REG (x)) == to_mode)
+      if (POINTERS_EXTEND_UNSIGNED >= 0
+         && GET_MODE (SUBREG_REG (x)) == to_mode)
        return SUBREG_REG (x);
       break;
 
     case LABEL_REF:
-      temp = gen_rtx_LABEL_REF (to_mode, XEXP (x, 0));
-      LABEL_REF_NONLOCAL_P (temp) = LABEL_REF_NONLOCAL_P (x);
-      return temp;
+      if (POINTERS_EXTEND_UNSIGNED >= 0)
+       {
+         temp = gen_rtx_LABEL_REF (to_mode, XEXP (x, 0));
+         LABEL_REF_NONLOCAL_P (temp) = LABEL_REF_NONLOCAL_P (x);
+         return temp;
+       }
+      break;
 
     case SYMBOL_REF:
-      temp = gen_rtx_SYMBOL_REF (to_mode, XSTR (x, 0));
-      SYMBOL_REF_FLAG (temp) = SYMBOL_REF_FLAG (x);
-      CONSTANT_POOL_ADDRESS_P (temp) = CONSTANT_POOL_ADDRESS_P (x);
-      STRING_POOL_ADDRESS_P (temp) = STRING_POOL_ADDRESS_P (x);
-      return temp;
+      if (POINTERS_EXTEND_UNSIGNED >= 0)
+       {
+         temp = gen_rtx_SYMBOL_REF (to_mode, XSTR (x, 0));
+         SYMBOL_REF_FLAG (temp) = SYMBOL_REF_FLAG (x);
+         CONSTANT_POOL_ADDRESS_P (temp) = CONSTANT_POOL_ADDRESS_P (x);
+         STRING_POOL_ADDRESS_P (temp) = STRING_POOL_ADDRESS_P (x);
+         return temp;
+       }
+      break;
 
     case CONST:
-      return gen_rtx_CONST (to_mode, 
-                           convert_memory_address (to_mode, XEXP (x, 0)));
+      if (POINTERS_EXTEND_UNSIGNED >= 0)
+        return gen_rtx_CONST (to_mode, 
+                             convert_memory_address (to_mode, XEXP (x, 0)));
+      break;
 
     case PLUS:
     case MULT:
@@ -399,10 +402,11 @@ convert_memory_address (to_mode, x)
         permute the conversion and addition operation.  We can always safely
         permute them if we are making the address narrower.  In addition,
         always permute the operations if this is a constant.  */
-      if (GET_MODE_SIZE (to_mode) < GET_MODE_SIZE (from_mode)
-         || (GET_CODE (x) == PLUS && GET_CODE (XEXP (x, 1)) == CONST_INT
-             && (INTVAL (XEXP (x, 1)) + 20000 < 40000
-                 || CONSTANT_P (XEXP (x, 0)))))
+      if (POINTERS_EXTEND_UNSIGNED >= 0
+         && (GET_MODE_SIZE (to_mode) < GET_MODE_SIZE (from_mode)
+             || (GET_CODE (x) == PLUS && GET_CODE (XEXP (x, 1)) == CONST_INT
+                 && (INTVAL (XEXP (x, 1)) + 20000 < 40000
+                     || CONSTANT_P (XEXP (x, 0))))))
        return gen_rtx_fmt_ee (GET_CODE (x), to_mode, 
                               convert_memory_address (to_mode, XEXP (x, 0)),
                               convert_memory_address (to_mode, XEXP (x, 1)));
@@ -613,10 +617,12 @@ validize_mem (ref)
 {
   if (GET_CODE (ref) != MEM)
     return ref;
-  if (memory_address_p (GET_MODE (ref), XEXP (ref, 0)))
+  if (! (flag_force_addr && CONSTANT_ADDRESS_P (XEXP (ref, 0)))
+      && memory_address_p (GET_MODE (ref), XEXP (ref, 0)))
     return ref;
+
   /* Don't alter REF itself, since that is probably a stack slot.  */
-  return change_address (ref, GET_MODE (ref), XEXP (ref, 0));
+  return replace_equiv_address (ref, XEXP (ref, 0));
 }
 \f
 /* Given REF, either a MEM or a REG, and T, either the type of X or
@@ -667,12 +673,12 @@ set_mem_attributes (ref, t, objectp)
      here, because, in C and C++, the fact that a location is accessed
      through a const expression does not mean that the value there can
      never change.  */
-  MEM_ALIAS_SET (ref) = get_alias_set (t);
+  set_mem_alias_set (ref, get_alias_set (t));
   MEM_VOLATILE_P (ref) = TYPE_VOLATILE (type);
   MEM_IN_STRUCT_P (ref) = AGGREGATE_TYPE_P (type);
 
   /* If we are making an object of this type, we know that it is a scalar if
-     the type is not an aggregate. */
+     the type is not an aggregate.  */
   if (objectp && ! AGGREGATE_TYPE_P (type))
     MEM_SCALAR_P (ref) = 1;
 
@@ -702,6 +708,7 @@ set_mem_attributes (ref, t, objectp)
   if (DECL_P (t))
     MEM_SCALAR_P (ref) = 1;
   else if (TREE_CODE (t) == COMPONENT_REF || TREE_CODE (t) == ARRAY_REF
+          || TREE_CODE (t) == ARRAY_RANGE_REF
           || TREE_CODE (t) == BIT_FIELD_REF)
     MEM_IN_STRUCT_P (ref) = 1;
 }
@@ -715,21 +722,13 @@ rtx
 stabilize (x)
      rtx x;
 {
-  register rtx addr;
 
-  if (GET_CODE (x) != MEM)
+  if (GET_CODE (x) != MEM
+      || ! rtx_unstable_p (XEXP (x, 0)))
     return x;
 
-  addr = XEXP (x, 0);
-  if (rtx_unstable_p (addr))
-    {
-      rtx temp = force_reg (Pmode, copy_all_regs (addr));
-      rtx mem = gen_rtx_MEM (GET_MODE (x), temp);
-
-      MEM_COPY_ATTRIBUTES (mem, x);
-      return mem;
-    }
-  return x;
+  return
+    replace_equiv_address (x, force_reg (Pmode, copy_all_regs (XEXP (x, 0))));
 }
 \f
 /* Copy the value or contents of X to a new temp reg and return that reg.  */
@@ -1625,13 +1624,13 @@ probe_stack_range (first, size)
          || REGNO (test_addr) < FIRST_PSEUDO_REGISTER)
        test_addr = force_reg (Pmode, test_addr);
 
-      emit_note (NULL_PTR, NOTE_INSN_LOOP_BEG);
+      emit_note (NULL, NOTE_INSN_LOOP_BEG);
       emit_jump (test_lab);
 
       emit_label (loop_lab);
       emit_stack_probe (test_addr);
 
-      emit_note (NULL_PTR, NOTE_INSN_LOOP_CONT);
+      emit_note (NULL, NOTE_INSN_LOOP_CONT);
 
 #ifdef STACK_GROWS_DOWNWARD
 #define CMP_OPCODE GTU
@@ -1650,7 +1649,7 @@ probe_stack_range (first, size)
       emit_cmp_and_jump_insns (test_addr, last_addr, CMP_OPCODE,
                               NULL_RTX, Pmode, 1, 0, loop_lab);
       emit_jump (end_lab);
-      emit_note (NULL_PTR, NOTE_INSN_LOOP_END);
+      emit_note (NULL, NOTE_INSN_LOOP_END);
       emit_label (end_lab);
 
       emit_stack_probe (last_addr);
@@ -1664,7 +1663,7 @@ probe_stack_range (first, size)
    otherwise 0.
    OUTGOING is 1 if on a machine with register windows this function
    should return the register in which the function will put its result
-   and 0 otherwise. */
+   and 0 otherwise.  */
 
 rtx
 hard_function_value (valtype, func, outgoing)