predicates.md (add_cint_operand): New.
authorAlan Modra <amodra@gmail.com>
Mon, 9 Sep 2013 23:40:34 +0000 (09:10 +0930)
committerAlan Modra <amodra@gcc.gnu.org>
Mon, 9 Sep 2013 23:40:34 +0000 (09:10 +0930)
gcc/
* config/rs6000/predicates.md (add_cint_operand): New.
(reg_or_add_cint_operand, small_toc_ref): Use add_cint_operand.
* config/rs6000/rs6000.md (largetoc_high_plus): Restrict offset
using add_cint_operand.
(largetoc_high_plus_aix): Likewise.
gcc/testsuite/
* gcc.target/powerpc/medium_offset.c: New.

From-SVN: r202417

gcc/ChangeLog
gcc/config/rs6000/predicates.md
gcc/config/rs6000/rs6000.md
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.target/powerpc/medium_offset.c [new file with mode: 0644]

index dd9a3e0cbc1b21ee161804182ad3bb8b99303326..42d1dc7249cb6f7a38ce1b2c9150eb6d8523c4a5 100644 (file)
@@ -1,3 +1,11 @@
+2013-09-10  Alan Modra  <amodra@gmail.com>
+
+       * config/rs6000/predicates.md (add_cint_operand): New.
+       (reg_or_add_cint_operand, small_toc_ref): Use add_cint_operand.
+       * config/rs6000/rs6000.md (largetoc_high_plus): Restrict offset
+       using add_cint_operand.
+       (largetoc_high_plus_aix): Likewise.
+
 2013-09-09  Jakub Jelinek  <jakub@redhat.com>
 
        PR tree-optimization/58364
index 7338e764c5cffe8db589516069f83c49d6570bc9..b5bff04477911819aadfed8431ec113c30cf081b 100644 (file)
   (ior (match_code "const_int")
        (match_operand 0 "gpc_reg_operand")))
 
+;; Return 1 if op is a constant integer valid for addition with addis, addi.
+(define_predicate "add_cint_operand"
+  (and (match_code "const_int")
+       (match_test "(unsigned HOST_WIDE_INT)
+                     (INTVAL (op) + (mode == SImode ? 0x80000000 : 0x80008000))
+                   < (unsigned HOST_WIDE_INT) 0x100000000ll")))
+
 ;; Return 1 if op is a constant integer valid for addition
 ;; or non-special register.
 (define_predicate "reg_or_add_cint_operand"
   (if_then_else (match_code "const_int")
-    (match_test "(unsigned HOST_WIDE_INT) (INTVAL (op) + 0x80008000)
-                < (unsigned HOST_WIDE_INT) 0x100000000ll")
+    (match_operand 0 "add_cint_operand")
     (match_operand 0 "gpc_reg_operand")))
 
 ;; Return 1 if op is a constant integer valid for subtraction
 (define_predicate "small_toc_ref"
   (match_code "unspec,plus")
 {
-  if (GET_CODE (op) == PLUS && CONST_INT_P (XEXP (op, 1)))
+  if (GET_CODE (op) == PLUS && add_cint_operand (XEXP (op, 1), mode))
     op = XEXP (op, 0);
 
   return GET_CODE (op) == UNSPEC && XINT (op, 1) == UNSPEC_TOCREL;
index 3880f9175a221cfebb66c27f3f7d95bf85455392..0757d4de5ad564f490056c11932dd637284b49dc 100644 (file)
            (unspec [(match_operand:DI 1 "" "")
                     (match_operand:DI 2 "gpc_reg_operand" "b")]
                    UNSPEC_TOCREL)
-           (match_operand 3 "const_int_operand" "n"))))]
+           (match_operand:DI 3 "add_cint_operand" "n"))))]
    "TARGET_ELF && TARGET_CMODEL != CMODEL_SMALL"
    "addis %0,%2,%1+%3@toc@ha")
 
            (unspec [(match_operand:P 1 "" "")
                     (match_operand:P 2 "gpc_reg_operand" "b")]
                    UNSPEC_TOCREL)
-           (match_operand 3 "const_int_operand" "n"))))]
+           (match_operand:P 3 "add_cint_operand" "n"))))]
    "TARGET_XCOFF && TARGET_CMODEL != CMODEL_SMALL"
    "addis %0,%1+%3@u(%2)")
 
index 7da14443bb5b5c4eb97379faf5aac59a3c17f9bf..61d1469f1a8e970a2b5b823dbd5514d41b189b42 100644 (file)
@@ -1,3 +1,7 @@
+2013-09-10  Alan Modra  <amodra@gmail.com>
+
+       * gcc.target/powerpc/medium_offset.c: New.
+
 2013-09-09  Jakub Jelinek  <jakub@redhat.com>
 
        PR c++/58325
diff --git a/gcc/testsuite/gcc.target/powerpc/medium_offset.c b/gcc/testsuite/gcc.target/powerpc/medium_offset.c
new file mode 100644 (file)
index 0000000..f29eba0
--- /dev/null
@@ -0,0 +1,12 @@
+/* { dg-do compile { target { powerpc*-*-* } } } */
+/* { dg-require-effective-target lp64 } */
+/* { dg-options "-O" } */
+/* { dg-final { scan-assembler-not "\\+4611686018427387904" } } */
+
+static int x;
+
+unsigned long
+foo (void)
+{
+  return ((unsigned long) &x) - 0xc000000000000000;
+}