Index: gcc/config/rs6000/rs6000.md
===================================================================
--- gcc/config/rs6000/rs6000.md	(revision 178888)
+++ gcc/config/rs6000/rs6000.md	(working copy)
@@ -12165,43 +12165,67 @@ (define_insn "largetoc_low"
 (define_expand "call_indirect_aix32"
   [(set (match_dup 2)
 	(mem:SI (match_operand:SI 0 "gpc_reg_operand" "")))
-   (set (mem:SI (plus:SI (reg:SI 1) (const_int 20)))
+   (set (match_dup 3)
 	(reg:SI 2))
    (set (reg:SI 11)
 	(mem:SI (plus:SI (match_dup 0)
 			 (const_int 8))))
    (parallel [(call (mem:SI (match_dup 2))
 		    (match_operand 1 "" ""))
-	      (use (mem:SI (plus:SI (match_dup 0) (const_int 4))))
+	      (use (match_dup 4))
+	      (set (reg:SI 2) (match_dup 3))
 	      (use (reg:SI 11))
-	      (use (mem:SI (plus:SI (reg:SI 1) (const_int 20))))
 	      (clobber (reg:SI LR_REGNO))])]
   "TARGET_32BIT"
   "
-{ operands[2] = gen_reg_rtx (SImode); }")
+{
+  operands[2] = gen_reg_rtx (SImode);
+  operands[3] = gen_rtx_MEM (SImode,
+			     gen_rtx_PLUS (SImode, stack_pointer_rtx,
+					   GEN_INT (20)));
+
+  operands[4] = gen_rtx_MEM (SImode,
+			     gen_rtx_PLUS (SImode, operands[0],
+					   GEN_INT (4)));
+
+  /* Make sure the compiler does not optimize away the store of the TOC.  */
+  MEM_VOLATILE_P (operands[3]) = 1;
+}")
 
 (define_expand "call_indirect_aix64"
   [(set (match_dup 2)
 	(mem:DI (match_operand:DI 0 "gpc_reg_operand" "")))
-   (set (mem:DI (plus:DI (reg:DI 1) (const_int 40)))
+   (set (match_dup 3)
 	(reg:DI 2))
    (set (reg:DI 11)
 	(mem:DI (plus:DI (match_dup 0)
 			 (const_int 16))))
    (parallel [(call (mem:SI (match_dup 2))
 		    (match_operand 1 "" ""))
-	      (use (mem:DI (plus:DI (match_dup 0) (const_int 8))))
+	      (use (match_dup 4))
+	      (set (reg:DI 2) (match_dup 3))
 	      (use (reg:DI 11))
-	      (use (mem:DI (plus:DI (reg:DI 1) (const_int 40))))
-	      (clobber (reg:SI LR_REGNO))])]
+	      (clobber (reg:DI LR_REGNO))])]
   "TARGET_64BIT"
   "
-{ operands[2] = gen_reg_rtx (DImode); }")
+{
+  operands[2] = gen_reg_rtx (DImode);
+  operands[3] = gen_rtx_MEM (DImode,
+			     gen_rtx_PLUS (DImode, stack_pointer_rtx,
+					   GEN_INT (40)));
+
+  operands[4] = gen_rtx_MEM (DImode,
+			     gen_rtx_PLUS (DImode, operands[0],
+					   GEN_INT (8)));
+
+  /* Make sure the compiler does not optimize away the store of the TOC.  */
+  MEM_VOLATILE_P (operands[3]) = 1;
+}")
 
 (define_expand "call_value_indirect_aix32"
   [(set (match_dup 3)
 	(mem:SI (match_operand:SI 1 "gpc_reg_operand" "")))
-   (set (mem:SI (plus:SI (reg:SI 1) (const_int 20)))
+   (set (match_dup 4)
 	(reg:SI 2))
    (set (reg:SI 11)
 	(mem:SI (plus:SI (match_dup 1)
@@ -12209,18 +12233,30 @@ (define_expand "call_value_indirect_aix3
    (parallel [(set (match_operand 0 "" "")
 		   (call (mem:SI (match_dup 3))
 			 (match_operand 2 "" "")))
-	      (use (mem:SI (plus:SI (match_dup 1) (const_int 4))))
+	      (use (match_dup 5))
+	      (set (reg:SI 2) (match_dup 4))
 	      (use (reg:SI 11))
-	      (use (mem:SI (plus:SI (reg:SI 1) (const_int 20))))
 	      (clobber (reg:SI LR_REGNO))])]
   "TARGET_32BIT"
   "
-{ operands[3] = gen_reg_rtx (SImode); }")
+{
+  operands[3] = gen_reg_rtx (SImode);
+  operands[4] = gen_rtx_MEM (DImode,
+			     gen_rtx_PLUS (DImode, stack_pointer_rtx,
+					   GEN_INT (20)));
+
+  operands[5] = gen_rtx_MEM (SImode,
+			     gen_rtx_PLUS (SImode, operands[1],
+					   GEN_INT (4)));
+
+  /* Make sure the compiler does not optimize away the store of the TOC.  */
+  MEM_VOLATILE_P (operands[4]) = 1;
+}")
 
 (define_expand "call_value_indirect_aix64"
   [(set (match_dup 3)
 	(mem:DI (match_operand:DI 1 "gpc_reg_operand" "")))
-   (set (mem:DI (plus:DI (reg:DI 1) (const_int 40)))
+   (set (match_dup 4)
 	(reg:DI 2))
    (set (reg:DI 11)
 	(mem:DI (plus:DI (match_dup 1)
@@ -12228,13 +12264,25 @@ (define_expand "call_value_indirect_aix6
    (parallel [(set (match_operand 0 "" "")
 		   (call (mem:SI (match_dup 3))
 			 (match_operand 2 "" "")))
-	      (use (mem:DI (plus:DI (match_dup 1) (const_int 8))))
+	      (use (match_dup 5))
+	      (set (reg:DI 2) (match_dup 4))
 	      (use (reg:DI 11))
-	      (use (mem:DI (plus:DI (reg:DI 1) (const_int 40))))
-	      (clobber (reg:SI LR_REGNO))])]
+	      (clobber (reg:DI LR_REGNO))])]
   "TARGET_64BIT"
   "
-{ operands[3] = gen_reg_rtx (DImode); }")
+{
+  operands[3] = gen_reg_rtx (DImode);
+  operands[4] = gen_rtx_MEM (DImode,
+			     gen_rtx_PLUS (DImode, stack_pointer_rtx,
+					   GEN_INT (40)));
+
+  operands[5] = gen_rtx_MEM (DImode,
+			     gen_rtx_PLUS (DImode, operands[1],
+					   GEN_INT (8)));
+
+  /* Make sure the compiler does not optimize away the store of the TOC.  */
+  MEM_VOLATILE_P (operands[4]) = 1;
+}")
 
 ;; Now the definitions for the call and call_value insns
 (define_expand "call"
@@ -12427,47 +12475,27 @@ (define_insn "*call_value_local64"
 
 ;; Call to function which may be in another module.  Restore the TOC
 ;; pointer (r2) after the call unless this is System V.
-;; Operand2 is nonzero if we are using the V.4 calling sequence and
+;; Operand1 is nonzero if we are using the V.4 calling sequence and
 ;; either the function was not prototyped, or it was prototyped as a
 ;; variable argument function.  It is > 0 if FP registers were passed
 ;; and < 0 if they were not.
+;; Operand2 is the address of the 3 word function pointer that offset 4 points
+;; to the value to be loaded in the TOC register.  Do not split the load from
+;; the call, as it may move the load of the TOC before any addresses using
+;; the TOC.
 
-(define_insn_and_split "*call_indirect_nonlocal_aix32_internal"
+(define_insn "*call_indirect_nonlocal_aix32"
   [(call (mem:SI (match_operand:SI 0 "register_operand" "c,*l"))
 		 (match_operand 1 "" "g,g"))
-   (use (mem:SI (plus:SI (match_operand:SI 2 "register_operand" "b,b") (const_int 4))))
+   (use (match_operand:SI 2 "memory_operand" "m,m"))
+   (set (reg:SI 2) (match_operand:SI 3 "memory_operand" "m,m"))
    (use (reg:SI 11))
-   (use (mem:SI (plus:SI (reg:SI 1) (const_int 20))))
    (clobber (reg:SI LR_REGNO))]
   "TARGET_32BIT && DEFAULT_ABI == ABI_AIX"
-  "#"
-  "&& reload_completed"
-  [(set (reg:SI 2)
-	(mem:SI (plus:SI (match_dup 2) (const_int 4))))
-   (parallel [(call (mem:SI (match_dup 0))
-		    (match_dup 1))
-	      (use (reg:SI 2))
-	      (use (reg:SI 11))
-	      (set (reg:SI 2)
-		   (mem:SI (plus:SI (reg:SI 1) (const_int 20))))
-	      (clobber (reg:SI LR_REGNO))])]
-  ""
+  "{l|lwz} 2,%2\;b%T0l\;{l|lwz} 2,%3"
   [(set_attr "type" "jmpreg")
    (set_attr "length" "12")])
 
-(define_insn "*call_indirect_nonlocal_aix32"
-  [(call (mem:SI (match_operand:SI 0 "register_operand" "c,*l"))
-	 (match_operand 1 "" "g,g"))
-   (use (reg:SI 2))
-   (use (reg:SI 11))
-   (set (reg:SI 2)
-	(mem:SI (plus:SI (reg:SI 1) (const_int 20))))
-   (clobber (reg:SI LR_REGNO))]
-  "TARGET_32BIT && DEFAULT_ABI == ABI_AIX && reload_completed"
-  "b%T0l\;{l|lwz} 2,20(1)"
-  [(set_attr "type" "jmpreg")
-   (set_attr "length" "8")])
-
 (define_insn "*call_nonlocal_aix32"
   [(call (mem:SI (match_operand:SI 0 "symbol_ref_operand" "s"))
 	 (match_operand 1 "" "g"))
@@ -12480,43 +12508,18 @@ (define_insn "*call_nonlocal_aix32"
   [(set_attr "type" "branch")
    (set_attr "length" "8")])
    
-(define_insn_and_split "*call_indirect_nonlocal_aix64_internal"
+(define_insn "*call_indirect_nonlocal_aix64"
   [(call (mem:SI (match_operand:DI 0 "register_operand" "c,*l"))
 		 (match_operand 1 "" "g,g"))
-   (use (mem:DI (plus:DI (match_operand:DI 2 "register_operand" "b,b")
-			 (const_int 8))))
+   (use (match_operand:DI 2 "memory_operand" "m,m"))
+   (set (reg:DI 2) (match_operand:DI 3 "memory_operand" "m,m"))
    (use (reg:DI 11))
-   (use (mem:DI (plus:DI (reg:DI 1) (const_int 40))))
-   (clobber (reg:SI LR_REGNO))]
+   (clobber (reg:DI LR_REGNO))]
   "TARGET_64BIT && DEFAULT_ABI == ABI_AIX"
-  "#"
-  "&& reload_completed"
-  [(set (reg:DI 2)
-	(mem:DI (plus:DI (match_dup 2) (const_int 8))))
-   (parallel [(call (mem:SI (match_dup 0))
-		    (match_dup 1))
-	      (use (reg:DI 2))
-	      (use (reg:DI 11))
-	      (set (reg:DI 2)
-		   (mem:DI (plus:DI (reg:DI 1) (const_int 40))))
-	      (clobber (reg:SI LR_REGNO))])]
-  ""
+  "ld  2,%2\;b%T0l\;ld 2,%3"
   [(set_attr "type" "jmpreg")
    (set_attr "length" "12")])
 
-(define_insn "*call_indirect_nonlocal_aix64"
-  [(call (mem:SI (match_operand:DI 0 "register_operand" "c,*l"))
-	 (match_operand 1 "" "g,g"))
-   (use (reg:DI 2))
-   (use (reg:DI 11))
-   (set (reg:DI 2)
-	(mem:DI (plus:DI (reg:DI 1) (const_int 40))))
-   (clobber (reg:SI LR_REGNO))]
-  "TARGET_64BIT && DEFAULT_ABI == ABI_AIX && reload_completed"
-  "b%T0l\;ld 2,40(1)"
-  [(set_attr "type" "jmpreg")
-   (set_attr "length" "8")])
-
 (define_insn "*call_nonlocal_aix64"
   [(call (mem:SI (match_operand:DI 0 "symbol_ref_operand" "s"))
 	 (match_operand 1 "" "g"))
@@ -12529,44 +12532,18 @@ (define_insn "*call_nonlocal_aix64"
   [(set_attr "type" "branch")
    (set_attr "length" "8")])
 
-(define_insn_and_split "*call_value_indirect_nonlocal_aix32_internal"
-  [(set (match_operand 0 "" "")
-	(call (mem:SI (match_operand:SI 1 "register_operand" "c,*l"))
-		      (match_operand 2 "" "g,g")))
-	(use (mem:SI (plus:SI (match_operand:SI 3 "register_operand" "b,b")
-			      (const_int 4))))
-	(use (reg:SI 11))
-	(use (mem:SI (plus:SI (reg:SI 1) (const_int 20))))
-	(clobber (reg:SI LR_REGNO))]
-  "TARGET_32BIT && DEFAULT_ABI == ABI_AIX"
-  "#"
-  "&& reload_completed"
-  [(set (reg:SI 2)
-	(mem:SI (plus:SI (match_dup 3) (const_int 4))))
-   (parallel [(set (match_dup 0) (call (mem:SI (match_dup 1))
-				       (match_dup 2)))
-	      (use (reg:SI 2))
-	      (use (reg:SI 11))
-	      (set (reg:SI 2)
-		   (mem:SI (plus:SI (reg:SI 1) (const_int 20))))
-	      (clobber (reg:SI LR_REGNO))])]
-  ""
-  [(set_attr "type" "jmpreg")
-   (set_attr "length" "12")])
-
 (define_insn "*call_value_indirect_nonlocal_aix32"
   [(set (match_operand 0 "" "")
 	(call (mem:SI (match_operand:SI 1 "register_operand" "c,*l"))
-	      (match_operand 2 "" "g,g")))
-   (use (reg:SI 2))
+		      (match_operand 2 "" "g,g")))
+   (use (match_operand:SI 3 "memory_operand" "m,m"))
+   (set (reg:SI 2) (match_operand:SI 4 "memory_operand" "m,m"))
    (use (reg:SI 11))
-   (set (reg:SI 2)
-	(mem:SI (plus:SI (reg:SI 1) (const_int 20))))
    (clobber (reg:SI LR_REGNO))]
-  "TARGET_32BIT && DEFAULT_ABI == ABI_AIX && reload_completed"
-  "b%T1l\;{l|lwz} 2,20(1)"
+  "TARGET_32BIT && DEFAULT_ABI == ABI_AIX"
+  "{l|lwz} 2,%3\;b%T1l\;{l|lwz} 2,%4"
   [(set_attr "type" "jmpreg")
-   (set_attr "length" "8")])
+   (set_attr "length" "12")])
 
 (define_insn "*call_value_nonlocal_aix32"
   [(set (match_operand 0 "" "")
@@ -12581,45 +12558,19 @@ (define_insn "*call_value_nonlocal_aix32
   [(set_attr "type" "branch")
    (set_attr "length" "8")])
 
-(define_insn_and_split "*call_value_indirect_nonlocal_aix64_internal"
+(define_insn "*call_value_indirect_nonlocal_aix64"
   [(set (match_operand 0 "" "")
 	(call (mem:SI (match_operand:DI 1 "register_operand" "c,*l"))
 		      (match_operand 2 "" "g,g")))
-	(use (mem:DI (plus:DI (match_operand:DI 3 "register_operand" "b,b")
-			      (const_int 8))))
-	(use (reg:DI 11))
-	(use (mem:DI (plus:DI (reg:DI 1) (const_int 40))))
-	(clobber (reg:SI LR_REGNO))]
+   (use (match_operand:DI 3 "memory_operand" "m,m"))
+   (set (reg:DI 2) (match_operand:DI 4 "memory_operand" "m,m"))
+   (use (reg:DI 11))
+   (clobber (reg:DI LR_REGNO))]
   "TARGET_64BIT && DEFAULT_ABI == ABI_AIX"
-  "#"
-  "&& reload_completed"
-  [(set (reg:DI 2)
-	(mem:DI (plus:DI (match_dup 3) (const_int 8))))
-   (parallel [(set (match_dup 0) (call (mem:SI (match_dup 1))
-				       (match_dup 2)))
-	      (use (reg:DI 2))
-	      (use (reg:DI 11))
-	      (set (reg:DI 2)
-		   (mem:DI (plus:DI (reg:DI 1) (const_int 40))))
-	      (clobber (reg:SI LR_REGNO))])]
-  ""
+  "ld 2,%3\;b%T1l\;ld 2,%4"
   [(set_attr "type" "jmpreg")
    (set_attr "length" "12")])
 
-(define_insn "*call_value_indirect_nonlocal_aix64"
-  [(set (match_operand 0 "" "")
-	(call (mem:SI (match_operand:DI 1 "register_operand" "c,*l"))
-	      (match_operand 2 "" "g,g")))
-   (use (reg:DI 2))
-   (use (reg:DI 11))
-   (set (reg:DI 2)
-	(mem:DI (plus:DI (reg:DI 1) (const_int 40))))
-   (clobber (reg:SI LR_REGNO))]
-  "TARGET_64BIT && DEFAULT_ABI == ABI_AIX && reload_completed"
-  "b%T1l\;ld 2,40(1)"
-  [(set_attr "type" "jmpreg")
-   (set_attr "length" "8")])
-
 (define_insn "*call_value_nonlocal_aix64"
   [(set (match_operand 0 "" "")
 	(call (mem:SI (match_operand:DI 1 "symbol_ref_operand" "s"))
