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.

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
 Support message passing with the Parallel Environment

Reply via email to