Patchwork [RS6000] powerpc64 -mcmodel=medium large symbol offsets

login
register
mail settings
Submitter Alan Modra
Date Sept. 9, 2013, 9:07 a.m.
Message ID <20130909090703.GC2643@bubble.grove.modra.org>
Download mbox | patch
Permalink /patch/273530/
State New
Headers show

Comments

Alan Modra - Sept. 9, 2013, 9:07 a.m.
Revised patch with testcase.  This one also fixes a small problem with
reg_or_add_cint_operand in that any 32-bit value is valid for SImode.
Compare with reg_or_sub_cint_operand.

Bootstrapped and regression tested powerpc64-linux.  OK to apply?

gcc/
	* config/rs6000/predicates.md (add_cint_operand): New.
	(reg_or_add_cint_operand): Use add_cint_operand.
	* config/rs6000/rs6000.md (largetoc_high_plus): Restrict offset
	using add_cint_operand.
	(largetoc_high_plus_aix, small_toc_ref): Likewise.
gcc/testsuite/
	* gcc.target/powerpc/medium_offset.c: New.
David Edelsohn - Sept. 9, 2013, 3:20 p.m.
On Mon, Sep 9, 2013 at 5:07 AM, Alan Modra <amodra@gmail.com> wrote:
> Revised patch with testcase.  This one also fixes a small problem with
> reg_or_add_cint_operand in that any 32-bit value is valid for SImode.
> Compare with reg_or_sub_cint_operand.
>
> Bootstrapped and regression tested powerpc64-linux.  OK to apply?
>
> gcc/
>         * config/rs6000/predicates.md (add_cint_operand): New.
>         (reg_or_add_cint_operand): Use add_cint_operand.
>         * config/rs6000/rs6000.md (largetoc_high_plus): Restrict offset
>         using add_cint_operand.
>         (largetoc_high_plus_aix, small_toc_ref): Likewise.
> gcc/testsuite/
>         * gcc.target/powerpc/medium_offset.c: New.

Okay. This seems much better.

Thanks, David

Patch

Index: gcc/config/rs6000/predicates.md
===================================================================
--- gcc/config/rs6000/predicates.md	(revision 202351)
+++ gcc/config/rs6000/predicates.md	(working copy)
@@ -376,12 +376,18 @@ 
   (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
@@ -1697,7 +1703,7 @@ 
 (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: gcc/config/rs6000/rs6000.md
===================================================================
--- gcc/config/rs6000/rs6000.md	(revision 202351)
+++ gcc/config/rs6000/rs6000.md	(working copy)
@@ -12207,7 +12209,7 @@ 
 	    (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")
 
@@ -12218,7 +12220,7 @@ 
 	    (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: gcc/testsuite/gcc.target/powerpc/medium_offset.c
===================================================================
--- gcc/testsuite/gcc.target/powerpc/medium_offset.c	(revision 0)
+++ gcc/testsuite/gcc.target/powerpc/medium_offset.c	(revision 0)
@@ -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;
+}