From patchwork Mon Nov 12 18:17:11 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: AIX large toc support Date: Mon, 12 Nov 2012 08:17:11 -0000 From: David Edelsohn X-Patchwork-Id: 198437 Message-Id: To: GCC Patches , Alan Modra 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): New. (largetoc_high_plus_aix): New. (largetoc_low): 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 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 < /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" + [(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" + [(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" + [(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