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
