re PR target/52698 (-maddress-mode=long doesn't work)
authorUros Bizjak <uros@gcc.gnu.org>
Tue, 27 Mar 2012 15:36:34 +0000 (17:36 +0200)
committerUros Bizjak <uros@gcc.gnu.org>
Tue, 27 Mar 2012 15:36:34 +0000 (17:36 +0200)
PR target/52698
* config/i386/i386-protos.h (ix86_legitimize_reload_address):
New prototype.
* config/i386/i386.h (LEGITIMIZE_RELOAD_ADDRESS): New define.
* config/i386/i386.c: Include reload.h.
(ix86_legitimize_reload_address): New function.

testsuite/ChangeLog:

PR target/52698
* gcc.target/i386/pr52698.c: New test.

From-SVN: r185883

gcc/ChangeLog
gcc/config/i386/i386-protos.h
gcc/config/i386/i386.c
gcc/config/i386/i386.h
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.target/i386/pr52698.c [new file with mode: 0644]

index b7736fb7983b2d65538de6d275c5617707cd9075..6cc16537d0bdb1908a1b0f5d38e457f150709fe2 100644 (file)
@@ -1,9 +1,17 @@
+2012-03-27  Uros Bizjak  <ubizjak@gmail.com>
+
+       PR target/52698
+       * config/i386/i386-protos.h (ix86_legitimize_reload_address):
+       New prototype.
+       * config/i386/i386.h (LEGITIMIZE_RELOAD_ADDRESS): New define.
+       * config/i386/i386.c: Include reload.h.
+       (ix86_legitimize_reload_address): New function.
+
 2012-03-27  H.J. Lu  <hongjiu.lu@intel.com>
 
        * opth-gen.awk: Allocated a bit for Mask and InverseMask if it
        hasn't been allocated.  Define a target macro for Mask and
-       InverseMask if it hasn't been defined.  Remove MaskExists
-       handling.
+       InverseMask if it hasn't been defined.  Remove MaskExists handling.
 
        * doc/options.texi: Remove MaskNeeded.
 
index 630112f625d96266a5a6179552d02a2ecd5948e9..f300a56834d853c33c91c0e3fea2419a8776ce72 100644 (file)
@@ -65,7 +65,8 @@ extern bool ix86_expand_strlen (rtx, rtx, rtx, rtx);
 extern bool constant_address_p (rtx);
 extern bool legitimate_pic_operand_p (rtx);
 extern bool legitimate_pic_address_disp_p (rtx);
-
+extern bool ix86_legitimize_reload_address (rtx, enum machine_mode,
+                                           int, int, int);
 extern void print_reg (rtx, int, FILE*);
 extern void ix86_print_operand (FILE *, rtx, int);
 
index a21f2da95b76cbd4496e99a5131b20e663760b8f..18172a10825f4d55869b649347e8f9bb6d9c0ecf 100644 (file)
@@ -47,6 +47,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "target-def.h"
 #include "common/common-target.h"
 #include "langhooks.h"
+#include "reload.h"
 #include "cgraph.h"
 #include "gimple.h"
 #include "dwarf2.h"
@@ -12010,6 +12011,64 @@ legitimate_pic_address_disp_p (rtx disp)
   return false;
 }
 
+/* Our implementation of LEGITIMIZE_RELOAD_ADDRESS.  Returns a value to
+   replace the input X, or the original X if no replacement is called for.
+   The output parameter *WIN is 1 if the calling macro should goto WIN,
+   0 if it should not.  */
+
+bool
+ix86_legitimize_reload_address (rtx x,
+                               enum machine_mode mode ATTRIBUTE_UNUSED,
+                               int opnum, int type,
+                               int ind_levels ATTRIBUTE_UNUSED)
+{
+  /* Reload can generate:
+
+     (plus:DI (plus:DI (unspec:DI [(const_int 0 [0])] UNSPEC_TP)
+                      (reg:DI 97))
+             (reg:DI 2 cx))
+
+     This RTX is rejected from ix86_legitimate_address_p due to
+     non-strictness of base register 97.  Following this rejection, 
+     reload pushes all three components into separate registers,
+     creating invalid memory address RTX.
+
+     Following code reloads only the invalid part of the
+     memory address RTX.  */
+
+  if (GET_CODE (x) == PLUS
+      && REG_P (XEXP (x, 1))
+      && GET_CODE (XEXP (x, 0)) == PLUS
+      && REG_P (XEXP (XEXP (x, 0), 1)))
+    {
+      rtx base, index;
+      bool something_reloaded = false;
+
+      base = XEXP (XEXP (x, 0), 1);      
+      if (!REG_OK_FOR_BASE_STRICT_P (base))
+       {
+         push_reload (base, NULL_RTX, &XEXP (XEXP (x, 0), 1), NULL,
+                      BASE_REG_CLASS, GET_MODE (x), VOIDmode, 0, 0,
+                      opnum, (enum reload_type) type);
+         something_reloaded = true;
+       }
+
+      index = XEXP (x, 1);
+      if (!REG_OK_FOR_INDEX_STRICT_P (index))
+       {
+         push_reload (index, NULL_RTX, &XEXP (x, 1), NULL,
+                      INDEX_REG_CLASS, GET_MODE (x), VOIDmode, 0, 0,
+                      opnum, (enum reload_type) type);
+         something_reloaded = true;
+       }
+
+      gcc_assert (something_reloaded);
+      return true;
+    }
+
+  return false;
+}
+
 /* Recognizes RTL expressions that are valid memory addresses for an
    instruction.  The MODE argument is the machine mode for the MEM
    expression that wants to use this address.
index 3fcd2093e362d23b89eef30108d3a3a3cc0d9b7c..a53c70a31dc2dff3ac9dff5a722b3faf914abec9 100644 (file)
@@ -1630,6 +1630,17 @@ typedef struct ix86_args {
 
 #define CONSTANT_ADDRESS_P(X)  constant_address_p (X)
 
+/* Try a machine-dependent way of reloading an illegitimate address
+   operand.  If we find one, push the reload and jump to WIN.  This
+   macro is used in only one place: `find_reloads_address' in reload.c.  */
+
+#define LEGITIMIZE_RELOAD_ADDRESS(X, MODE, OPNUM, TYPE, INDL, WIN)     \
+do {                                                                   \
+  if (ix86_legitimize_reload_address ((X), (MODE), (OPNUM),            \
+                                     (int)(TYPE), (INDL)))             \
+    goto WIN;                                                          \
+} while (0)
+
 /* If defined, a C expression to determine the base term of address X.
    This macro is used in only one place: `find_base_term' in alias.c.
 
index 408184a26b875ac6308b984cfd2fa65d77c6f8fa..a9f0bc8c0695139fc40133ce8ac08d7ce152c4f3 100644 (file)
@@ -1,3 +1,9 @@
+2012-03-27  Uros Bizjak  <ubizjak@gmail.com>
+           H.J. Lu  <hongjiu.lu@intel.com>
+
+       PR target/52698
+       * gcc.target/i386/pr52698.c: New test.
+
 2012-03-27  Richard Guenther  <rguenther@suse.de>
 
        PR middle-end/52720
diff --git a/gcc/testsuite/gcc.target/i386/pr52698.c b/gcc/testsuite/gcc.target/i386/pr52698.c
new file mode 100644 (file)
index 0000000..d84685c
--- /dev/null
@@ -0,0 +1,18 @@
+/* { dg-do compile { target { ! { ia32 } } } } */
+/* { dg-options "-O2 -mx32 -maddress-mode=long" } */
+
+extern void abort (void);
+static __thread unsigned char foo [32]
+__attribute__ ((tls_model ("initial-exec"), aligned (sizeof (void *))));
+
+void
+test2 (void)
+{
+  unsigned int s;
+  for (s = 0; s < sizeof (foo); ++s)
+    {
+      if (foo [s] != s)
+       abort ();
+      foo [s] = sizeof (foo) - s;
+    }
+}