diff mbox

AIX large toc support

Message ID CAGWvnykfYNqXkwGV2jy+oDpjZwXJ50Pf3=EH0EEagk7+pgSjhw@mail.gmail.com
State New
Headers show

Commit Message

David Edelsohn Nov. 12, 2012, 6:17 p.m. UTC
AIX has added its equivalent to PPC64 Linux Large TOC support.  The
appended patch implements GCC support and enables it if the AIX system
tools support the new relocs.  This is not the default for XLC and
will not be the default for GCC.

GCC testsuite produces same results if run with -mcmodel=large.

Bootstrapped on powerpc-ibm-aix7.1.0.0.

I wanted to allow a chance for additional eyes before I commit it.

Thanks, David

	* configure.ac (HAVE_LD_LARGE_TOC): Add AIX ld test.
	* configure: Regenerated.
	* config/rs6000/aix61.h (SUBTARGET_OVERRIDE_OPTIONS): Disable
	TARGET_NO_FP_IN_TOC and TARGET_NO_SUM_IN_TOC if not CMODEL_SMALL.
	CMODEL_MEDIUM means CMODEL_LARGE on AIX.
	(ASM_SPEC): -mvsx implies -mpwr6. Add -many.
	(ASM_DEFAULT_SPEC): Use -mpwr4.
	* config/rs6000/rs6000.md (largetoc_high_aix<mode>): New.
	(largetoc_high_plus_aix<mode>): New.
	(largetoc_low<mode>): Change to mode iterator. Test TARGET_TOC
	instead of TARGET_ELF.
	(tocref): Remove TARGET_ELF test.
	* config/rs6000/aix64.opt (mcmodel): New.

 Support message passing with the Parallel Environment
diff mbox

Patch

Index: configure.ac
===================================================================
--- configure.ac	(revision 193425)
+++ configure.ac	(working copy)
@@ -4496,6 +4496,35 @@ 
     ;;
 esac

+case "$target" in
+  *-*-aix*)
+    AC_CACHE_CHECK(linker large toc support,
+    gcc_cv_ld_large_toc,
+    [gcc_cv_ld_large_toc=no
+    if test x$gcc_cv_as != x -a x$gcc_cv_ld != x ; then
+      cat > conftest.s <<EOF
+        .toc
+        .tc a[TC],a[RW]
+        .extern a[RW]
+        .csect .text[PR]
+.largetoctest:
+        addis 9,a@u(2)
+        ld 3,a@l(9)
+EOF
+      if $gcc_cv_as -a64 -o conftest.o conftest.s > /dev/null 2>&1; then
+        gcc_cv_ld_large_toc=yes
+      fi
+      rm -f conftest conftest.o conftest.s
+    fi
+    ])
+    if test x"$gcc_cv_ld_large_toc" = xyes; then
+      AC_DEFINE(HAVE_LD_LARGE_TOC, 1,
+    [Define if your AIX linker supports a large TOC.])
+    fi
+    ;;
+esac
+
 AC_CACHE_CHECK(linker --build-id support,
   gcc_cv_ld_buildid,
   [gcc_cv_ld_buildid=no
Index: config/rs6000/aix61.h
===================================================================
--- config/rs6000/aix61.h	(revision 193425)
+++ config/rs6000/aix61.h	(working copy)
@@ -39,6 +39,15 @@ 
     {									\
       error ("-maix64 required: 64-bit computation with 32-bit
addressing not yet supported"); \
     }									\
+  if (rs6000_current_cmodel != CMODEL_SMALL)				\
+    {									\
+      TARGET_NO_FP_IN_TOC = 0;						\
+      TARGET_NO_SUM_IN_TOC = 0;						\
+    }									\
+  if (rs6000_current_cmodel == CMODEL_MEDIUM)				\
+    {									\
+      rs6000_current_cmodel = CMODEL_LARGE;				\
+    }									\
 } while (0);

 #undef ASM_SPEC
@@ -72,10 +81,12 @@ 
 %{mcpu=620: -m620} \
 %{mcpu=630: -m620} \
 %{mcpu=970: -m970} \
-%{mcpu=G5: -m970}"
+%{mcpu=G5: -m970} \
+%{mvsx: %{!mcpu*: -mpwr6}} \
+-many"

 #undef	ASM_DEFAULT_SPEC
-#define ASM_DEFAULT_SPEC "-mppc"
+#define ASM_DEFAULT_SPEC "-mpwr4"

 #undef TARGET_OS_CPP_BUILTINS
 #define TARGET_OS_CPP_BUILTINS()     \
Index: config/rs6000/rs6000.md
===================================================================
--- config/rs6000/rs6000.md	(revision 193425)
+++ config/rs6000/rs6000.md	(working copy)
@@ -10339,6 +10339,15 @@ 
    "TARGET_ELF && TARGET_CMODEL != CMODEL_SMALL"
    "addis %0,%2,%1@toc@ha")

+(define_insn "*largetoc_high_aix<mode>"
+  [(set (match_operand:P 0 "gpc_reg_operand" "=b*r")
+        (high:P
+	  (unspec [(match_operand:P 1 "" "")
+		   (match_operand:P 2 "gpc_reg_operand" "b")]
+		  UNSPEC_TOCREL)))]
+   "TARGET_XCOFF && TARGET_CMODEL != CMODEL_SMALL"
+   "addis %0,%1@u(%2)")
+
 (define_insn "*largetoc_high_plus"
   [(set (match_operand:DI 0 "gpc_reg_operand" "=b*r")
         (high:DI
@@ -10350,11 +10359,22 @@ 
    "TARGET_ELF && TARGET_CMODEL != CMODEL_SMALL"
    "addis %0,%2,%1+%3@toc@ha")

-(define_insn "*largetoc_low"
-  [(set (match_operand:DI 0 "gpc_reg_operand" "=r,r")
-        (lo_sum:DI (match_operand:DI 1 "gpc_reg_operand" "b,!*r")
-	           (match_operand:DI 2 "" "")))]
-   "TARGET_ELF && TARGET_CMODEL != CMODEL_SMALL"
+(define_insn "*largetoc_high_plus_aix<mode>"
+  [(set (match_operand:P 0 "gpc_reg_operand" "=b*r")
+        (high:P
+	  (plus:P
+	    (unspec [(match_operand:P 1 "" "")
+		     (match_operand:P 2 "gpc_reg_operand" "b")]
+		    UNSPEC_TOCREL)
+	    (match_operand 3 "const_int_operand" "n"))))]
+   "TARGET_XCOFF && TARGET_CMODEL != CMODEL_SMALL"
+   "addis %0,%2,%1+%3@u")
+
+(define_insn "*largetoc_low<mode>"
+  [(set (match_operand:P 0 "gpc_reg_operand" "=r,r")
+        (lo_sum:P (match_operand:P 1 "gpc_reg_operand" "b,!*r")
+	           (match_operand:P 2 "" "")))]
+   "TARGET_TOC && TARGET_CMODEL != CMODEL_SMALL"
    "@
     addi %0,%1,%2@l
     addic %0,%1,%2@l")
@@ -10364,7 +10384,7 @@ 
 	(match_operand:P 1 "small_toc_ref" "R"))]
    "TARGET_TOC"
    "la %0,%a1"
-   "&& TARGET_ELF && TARGET_CMODEL != CMODEL_SMALL && reload_completed"
+   "&& TARGET_CMODEL != CMODEL_SMALL && reload_completed"
   [(set (match_dup 0) (high:P (match_dup 1)))
    (set (match_dup 0) (lo_sum:P (match_dup 0) (match_dup 1)))])

Index: config/rs6000/aix64.opt
===================================================================
--- config/rs6000/aix64.opt	(revision 193425)
+++ config/rs6000/aix64.opt	(working copy)
@@ -27,6 +27,23 @@ 
 Target Report RejectNegative Negative(maix64) InverseMask(64BIT)
Var(rs6000_isa_flags)
 Compile for 32-bit pointers

+mcmodel=
+Target RejectNegative Joined Enum(rs6000_cmodel) Var(rs6000_current_cmodel)
+Select code model
+
+Enum
+Name(rs6000_cmodel) Type(enum rs6000_cmodel)
+Known code models (for use with the -mcmodel= option):
+
+EnumValue
+Enum(rs6000_cmodel) String(small) Value(CMODEL_SMALL)
+
+EnumValue
+Enum(rs6000_cmodel) String(medium) Value(CMODEL_MEDIUM)
+
+EnumValue
+Enum(rs6000_cmodel) String(large) Value(CMODEL_LARGE)
+
 mpe
 Target Report RejectNegative Var(internal_nothing_1) Save