OSDN Git Service

2008-04-01 Rafael Espindola <espindola@google.com>
[pf3gnuchains/gcc-fork.git] / gcc / explow.c
index 361c717..612fb1b 100644 (file)
@@ -1,13 +1,13 @@
 /* Subroutines for manipulating rtx's in semantically interesting ways.
    Copyright (C) 1987, 1991, 1994, 1995, 1996, 1997, 1998,
 /* Subroutines for manipulating rtx's in semantically interesting ways.
    Copyright (C) 1987, 1991, 1994, 1995, 1996, 1997, 1998,
-   1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006
+   1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007
    Free Software Foundation, Inc.
 
 This file is part of GCC.
 
 GCC is free software; you can redistribute it and/or modify it under
 the terms of the GNU General Public License as published by the Free
    Free Software Foundation, Inc.
 
 This file is part of GCC.
 
 GCC is free software; you can redistribute it and/or modify it under
 the terms of the GNU General Public License as published by the Free
-Software Foundation; either version 2, or (at your option) any later
+Software Foundation; either version 3, or (at your option) any later
 version.
 
 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
 version.
 
 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
@@ -16,9 +16,8 @@ FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 for more details.
 
 You should have received a copy of the GNU General Public License
 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, 51 Franklin Street, Fifth Floor, Boston, MA
-02110-1301, USA.  */
+along with GCC; see the file COPYING3.  If not see
+<http://www.gnu.org/licenses/>.  */
 
 
 #include "config.h"
 
 
 #include "config.h"
@@ -245,9 +244,13 @@ expr_size (tree exp)
   if (TREE_CODE (exp) == WITH_SIZE_EXPR)
     size = TREE_OPERAND (exp, 1);
   else
   if (TREE_CODE (exp) == WITH_SIZE_EXPR)
     size = TREE_OPERAND (exp, 1);
   else
-    size = SUBSTITUTE_PLACEHOLDER_IN_EXPR (lang_hooks.expr_size (exp), exp);
+    {
+      size = lang_hooks.expr_size (exp);
+      gcc_assert (size);
+      size = SUBSTITUTE_PLACEHOLDER_IN_EXPR (size, exp);
+    }
 
 
-  return expand_expr (size, NULL_RTX, TYPE_MODE (sizetype), 0);
+  return expand_expr (size, NULL_RTX, TYPE_MODE (sizetype), EXPAND_NORMAL);
 }
 
 /* Return a wide integer for the size in bytes of the value of EXP, or -1
 }
 
 /* Return a wide integer for the size in bytes of the value of EXP, or -1
@@ -261,7 +264,10 @@ int_expr_size (tree exp)
   if (TREE_CODE (exp) == WITH_SIZE_EXPR)
     size = TREE_OPERAND (exp, 1);
   else
   if (TREE_CODE (exp) == WITH_SIZE_EXPR)
     size = TREE_OPERAND (exp, 1);
   else
-    size = lang_hooks.expr_size (exp);
+    {
+      size = lang_hooks.expr_size (exp);
+      gcc_assert (size);
+    }
 
   if (size == 0 || !host_integerp (size, 0))
     return -1;
 
   if (size == 0 || !host_integerp (size, 0))
     return -1;
@@ -375,12 +381,15 @@ convert_memory_address (enum machine_mode to_mode ATTRIBUTE_UNUSED,
     case MULT:
       /* For addition we can safely permute the conversion and addition
         operation if one operand is a constant and converting the constant
     case MULT:
       /* For addition we can safely permute the conversion and addition
         operation if one operand is a constant and converting the constant
-        does not change it.  We can always safely permute them if we are
-        making the address narrower.  */
+        does not change it or if one operand is a constant and we are
+        using a ptr_extend instruction  (POINTERS_EXTEND_UNSIGNED < 0).
+        We can always safely permute them if we are making the address
+        narrower.  */
       if (GET_MODE_SIZE (to_mode) < GET_MODE_SIZE (from_mode)
          || (GET_CODE (x) == PLUS
              && GET_CODE (XEXP (x, 1)) == CONST_INT
       if (GET_MODE_SIZE (to_mode) < GET_MODE_SIZE (from_mode)
          || (GET_CODE (x) == PLUS
              && GET_CODE (XEXP (x, 1)) == CONST_INT
-             && XEXP (x, 1) == convert_memory_address (to_mode, XEXP (x, 1))))
+             && (XEXP (x, 1) == convert_memory_address (to_mode, XEXP (x, 1))
+                 || POINTERS_EXTEND_UNSIGNED < 0)))
        return gen_rtx_fmt_ee (GET_CODE (x), to_mode,
                               convert_memory_address (to_mode, XEXP (x, 0)),
                               XEXP (x, 1));
        return gen_rtx_fmt_ee (GET_CODE (x), to_mode,
                               convert_memory_address (to_mode, XEXP (x, 0)),
                               XEXP (x, 1));
@@ -422,18 +431,21 @@ memory_address (enum machine_mode mode, rtx x)
 
       /* At this point, any valid address is accepted.  */
       if (memory_address_p (mode, x))
 
       /* At this point, any valid address is accepted.  */
       if (memory_address_p (mode, x))
-       goto win;
+       goto done;
 
       /* If it was valid before but breaking out memory refs invalidated it,
         use it the old way.  */
       if (memory_address_p (mode, oldx))
 
       /* If it was valid before but breaking out memory refs invalidated it,
         use it the old way.  */
       if (memory_address_p (mode, oldx))
-       goto win2;
+       {
+         x = oldx;
+         goto done;
+       }
 
       /* Perform machine-dependent transformations on X
         in certain cases.  This is not necessary since the code
         below can handle all possible cases, but machine-dependent
         transformations can make better code.  */
 
       /* Perform machine-dependent transformations on X
         in certain cases.  This is not necessary since the code
         below can handle all possible cases, but machine-dependent
         transformations can make better code.  */
-      LEGITIMIZE_ADDRESS (x, oldx, mode, win);
+      LEGITIMIZE_ADDRESS (x, oldx, mode, done);
 
       /* PLUS and MULT can appear in special ways
         as the result of attempts to make an address usable for indexing.
 
       /* PLUS and MULT can appear in special ways
         as the result of attempts to make an address usable for indexing.
@@ -473,21 +485,11 @@ memory_address (enum machine_mode mode, rtx x)
         the register is a valid address.  */
       else
        x = force_reg (Pmode, x);
         the register is a valid address.  */
       else
        x = force_reg (Pmode, x);
-
-      goto done;
-
-    win2:
-      x = oldx;
-    win:
-      if (flag_force_addr && ! cse_not_expected && !REG_P (x))
-       {
-         x = force_operand (x, NULL_RTX);
-         x = force_reg (Pmode, x);
-       }
     }
 
  done:
 
     }
 
  done:
 
+  gcc_assert (memory_address_p (mode, x));
   /* If we didn't change the address, we are done.  Otherwise, mark
      a reg as a pointer if we have REG or REG + CONST_INT.  */
   if (oldx == x)
   /* If we didn't change the address, we are done.  Otherwise, mark
      a reg as a pointer if we have REG or REG + CONST_INT.  */
   if (oldx == x)
@@ -506,20 +508,6 @@ memory_address (enum machine_mode mode, rtx x)
   return x;
 }
 
   return x;
 }
 
-/* Like `memory_address' but pretend `flag_force_addr' is 0.  */
-
-rtx
-memory_address_noforce (enum machine_mode mode, rtx x)
-{
-  int ambient_force_addr = flag_force_addr;
-  rtx val;
-
-  flag_force_addr = 0;
-  val = memory_address (mode, x);
-  flag_force_addr = ambient_force_addr;
-  return val;
-}
-
 /* Convert a mem ref into one with a valid memory address.
    Pass through anything else unchanged.  */
 
 /* Convert a mem ref into one with a valid memory address.
    Pass through anything else unchanged.  */
 
@@ -529,8 +517,7 @@ validize_mem (rtx ref)
   if (!MEM_P (ref))
     return ref;
   ref = use_anchored_address (ref);
   if (!MEM_P (ref))
     return ref;
   ref = use_anchored_address (ref);
-  if (! (flag_force_addr && CONSTANT_ADDRESS_P (XEXP (ref, 0)))
-      && memory_address_p (GET_MODE (ref), XEXP (ref, 0)))
+  if (memory_address_p (GET_MODE (ref), XEXP (ref, 0)))
     return ref;
 
   /* Don't alter REF itself, since that is probably a stack slot.  */
     return ref;
 
   /* Don't alter REF itself, since that is probably a stack slot.  */
@@ -566,7 +553,7 @@ use_anchored_address (rtx x)
 
   /* Check whether BASE is suitable for anchors.  */
   if (GET_CODE (base) != SYMBOL_REF
 
   /* Check whether BASE is suitable for anchors.  */
   if (GET_CODE (base) != SYMBOL_REF
-      || !SYMBOL_REF_IN_BLOCK_P (base)
+      || !SYMBOL_REF_HAS_BLOCK_INFO_P (base)
       || SYMBOL_REF_ANCHOR_P (base)
       || SYMBOL_REF_BLOCK (base) == NULL
       || !targetm.use_anchors_for_symbol_p (base))
       || SYMBOL_REF_ANCHOR_P (base)
       || SYMBOL_REF_BLOCK (base) == NULL
       || !targetm.use_anchors_for_symbol_p (base))
@@ -710,6 +697,8 @@ force_reg (enum machine_mode mode, rtx x)
 
        align = MIN (sa, ca);
       }
 
        align = MIN (sa, ca);
       }
+    else if (MEM_P (x) && MEM_POINTER (x))
+      align = MEM_ALIGN (x);
 
     if (align)
       mark_reg_pointer (temp, align);
 
     if (align)
       mark_reg_pointer (temp, align);
@@ -767,10 +756,10 @@ copy_to_suggested_reg (rtx x, rtx target, enum machine_mode mode)
 #endif
 
 enum machine_mode
 #endif
 
 enum machine_mode
-promote_mode (tree type, enum machine_mode mode, int *punsignedp,
+promote_mode (const_tree type, enum machine_mode mode, int *punsignedp,
              int for_call ATTRIBUTE_UNUSED)
 {
              int for_call ATTRIBUTE_UNUSED)
 {
-  enum tree_code code = TREE_CODE (type);
+  const enum tree_code code = TREE_CODE (type);
   int unsignedp = *punsignedp;
 
 #ifndef PROMOTE_MODE
   int unsignedp = *punsignedp;
 
 #ifndef PROMOTE_MODE
@@ -782,7 +771,7 @@ promote_mode (tree type, enum machine_mode mode, int *punsignedp,
     {
 #ifdef PROMOTE_FUNCTION_MODE
     case INTEGER_TYPE:   case ENUMERAL_TYPE:   case BOOLEAN_TYPE:
     {
 #ifdef PROMOTE_FUNCTION_MODE
     case INTEGER_TYPE:   case ENUMERAL_TYPE:   case BOOLEAN_TYPE:
-    case REAL_TYPE:      case OFFSET_TYPE:
+    case REAL_TYPE:      case OFFSET_TYPE:     case FIXED_POINT_TYPE:
 #ifdef PROMOTE_MODE
       if (for_call)
        {
 #ifdef PROMOTE_MODE
       if (for_call)
        {
@@ -1465,7 +1454,7 @@ probe_stack_range (HOST_WIDE_INT first, rtx size)
    and 0 otherwise.  */
 
 rtx
    and 0 otherwise.  */
 
 rtx
-hard_function_value (tree valtype, tree func, tree fntype,
+hard_function_value (const_tree valtype, const_tree func, const_tree fntype,
                     int outgoing ATTRIBUTE_UNUSED)
 {
   rtx val;
                     int outgoing ATTRIBUTE_UNUSED)
 {
   rtx val;