explow.c (convert_memory_address_addr_space): Rename to ...
authorAndrew Pinski <apinski@cavium.com>
Wed, 15 Oct 2014 00:39:16 +0000 (00:39 +0000)
committerAndrew Pinski <pinskia@gcc.gnu.org>
Wed, 15 Oct 2014 00:39:16 +0000 (17:39 -0700)
2014-10-14  Andrew Pinski  <apinski@cavium.com>

* explow.c (convert_memory_address_addr_space): Rename to ...
(convert_memory_address_addr_space_1): This.  Add in_const argument.
Inside a CONST RTL, permute the conversion and addition of constant
for zero and sign extended pointers.
(convert_memory_address_addr_space): New function.

From-SVN: r216230

gcc/ChangeLog
gcc/explow.c

index 34fbb3558187b7163f65c597c1774cb327b24c54..6edd51af2904c4d9cd2e20f64ebfa2517faf85a3 100644 (file)
@@ -1,3 +1,11 @@
+2014-10-14  Andrew Pinski  <apinski@cavium.com>
+
+       * explow.c (convert_memory_address_addr_space): Rename to ...
+       (convert_memory_address_addr_space_1): This.  Add in_const argument.
+       Inside a CONST RTL, permute the conversion and addition of constant
+       for zero and sign extended pointers.
+       (convert_memory_address_addr_space): New function.
+
 2014-10-14  Andrew Pinski  <apinski@cavium.com>
 
        Revert:
index 3ba766d2f1cd06fb80427877a716b8786e0490f4..4f6465bef7a6a0064189d1b283fbcde94f89fc98 100644 (file)
@@ -310,11 +310,13 @@ break_out_memory_refs (rtx x)
    an address in the address space's address mode, or vice versa (TO_MODE says
    which way).  We take advantage of the fact that pointers are not allowed to
    overflow by commuting arithmetic operations over conversions so that address
-   arithmetic insns can be used.  */
+   arithmetic insns can be used. IN_CONST is true if this conversion is inside
+   a CONST.  */
 
-rtx
-convert_memory_address_addr_space (enum machine_mode to_mode ATTRIBUTE_UNUSED,
-                                  rtx x, addr_space_t as ATTRIBUTE_UNUSED)
+static rtx
+convert_memory_address_addr_space_1 (enum machine_mode to_mode ATTRIBUTE_UNUSED,
+                                    rtx x, addr_space_t as ATTRIBUTE_UNUSED,
+                                    bool in_const)
 {
 #ifndef POINTERS_EXTEND_UNSIGNED
   gcc_assert (GET_MODE (x) == to_mode || GET_MODE (x) == VOIDmode);
@@ -370,8 +372,8 @@ convert_memory_address_addr_space (enum machine_mode to_mode ATTRIBUTE_UNUSED,
 
     case CONST:
       return gen_rtx_CONST (to_mode,
-                           convert_memory_address_addr_space
-                             (to_mode, XEXP (x, 0), as));
+                           convert_memory_address_addr_space_1
+                             (to_mode, XEXP (x, 0), as, true));
       break;
 
     case PLUS:
@@ -381,16 +383,18 @@ convert_memory_address_addr_space (enum machine_mode to_mode ATTRIBUTE_UNUSED,
         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.  */
+        narrower. Inside a CONST RTL, this is safe for both pointers
+        zero or sign extended as pointers cannot wrap. */
       if (GET_MODE_SIZE (to_mode) < GET_MODE_SIZE (from_mode)
          || (GET_CODE (x) == PLUS
              && CONST_INT_P (XEXP (x, 1))
-             && (XEXP (x, 1) == convert_memory_address_addr_space
-                                  (to_mode, XEXP (x, 1), as)
-                 || POINTERS_EXTEND_UNSIGNED < 0)))
+             && ((in_const && POINTERS_EXTEND_UNSIGNED != 0)
+                 || XEXP (x, 1) == convert_memory_address_addr_space_1
+                                    (to_mode, XEXP (x, 1), as, in_const)
+                  || POINTERS_EXTEND_UNSIGNED < 0)))
        return gen_rtx_fmt_ee (GET_CODE (x), to_mode,
-                              convert_memory_address_addr_space
-                                (to_mode, XEXP (x, 0), as),
+                              convert_memory_address_addr_space_1
+                                (to_mode, XEXP (x, 0), as, in_const),
                               XEXP (x, 1));
       break;
 
@@ -402,6 +406,18 @@ convert_memory_address_addr_space (enum machine_mode to_mode ATTRIBUTE_UNUSED,
                        x, POINTERS_EXTEND_UNSIGNED);
 #endif /* defined(POINTERS_EXTEND_UNSIGNED) */
 }
+
+/* Given X, a memory address in address space AS' pointer mode, convert it to
+   an address in the address space's address mode, or vice versa (TO_MODE says
+   which way).  We take advantage of the fact that pointers are not allowed to
+   overflow by commuting arithmetic operations over conversions so that address
+   arithmetic insns can be used.  */
+
+rtx
+convert_memory_address_addr_space (enum machine_mode to_mode, rtx x, addr_space_t as)
+{
+  return convert_memory_address_addr_space_1 (to_mode, x, as, false);
+}
 \f
 /* Return something equivalent to X but valid as a memory address for something
    of mode MODE in the named address space AS.  When X is not itself valid,