[PATCH], PR 50341, Fix TOC load scheduling for powerpc on GCC 4.6 and 4.7 (patches included)

Michael Meissner meissner@linux.vnet.ibm.com
Thu Sep 15 18:35:00 GMT 2011


It would help if I included the patches:

[gcc-4.6]
2011-09-15  Alan Modra  <amodra@gmail.com>
	    Michael Meissner  <meissner@linux.vnet.ibm.com>

	PR target/50341
	* config/rs6000/rs6000.md (call_indirect_aix32): Do not split the
	load of the indirect function's TOC from the call to prevent the
	compiler from moving the load of the new TOC above code that
	references the current function's TOC.
	(call_indirect_aix64): Ditto.
	(call_value_indirect_aix32): Ditto.
	(call_value_indirect_aix64): Ditto.
	(call_indirect_nonlocal_aix32_internal): Ditto.
	(call_indirect_nonlocal_aix32): Ditto.
	(call_indirect_nonlocal_aix64_internal): Ditto.
	(call_indirect_nonlocal_aix64): Ditto.
	(call_value_indirect_nonlocal_aix32_internal): Ditto.
	(call_value_indirect_nonlocal_aix32): Ditto.
	(call_value_indirect_nonlocal_aix64_internal): Ditto.
	(call_value_indirect_nonlocal_aix64): Ditto.

[gcc-4.7]
2011-09-15  Alan Modra  <amodra@gmail.com>
	    Michael Meissner  <meissner@linux.vnet.ibm.com>

	PR target/50341
	* config/rs6000/rs6000.md (call_indirect_aix<ptrsize>): Do not
	split the load of the indirect function's TOC from the call to
	prevent the compiler from moving the load of the new TOC above
	code that references the current function's TOC.
	(call_indirect_aix<ptrsize>_internal): Ditto.
	(call_indirect_aix<ptrsize>_nor11): Ditto.
	(call_indirect_aix<ptrsize>_internal2): Ditto.
	(call_value_indirect_aix<ptrsize>): Ditto.
	(call_value_indirect_aix<ptrsize>_internal): Ditto.
	(call_value_indirect_aix<ptrsize>_nor11): Ditto.
	(call_value_indirect_aix<ptrsize>_internal2): Ditto.


-- 
Michael Meissner, IBM
5 Technology Place Drive, M/S 2757, Westford, MA 01886-3141, USA
meissner@linux.vnet.ibm.com	fax +1 (978) 399-6899
-------------- next part --------------
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"))
-------------- next part --------------
Index: gcc/config/rs6000/rs6000.md
===================================================================
--- gcc/config/rs6000/rs6000.md	(revision 178858)
+++ gcc/config/rs6000/rs6000.md	(working copy)
@@ -12379,169 +12379,73 @@ (define_insn "*call_value_local64"
 ;; Operand2 is the location in the function descriptor to load r2 from
 ;; Operand3 is the stack location to hold the current TOC pointer
 
-(define_insn_and_split "call_indirect_aix<ptrsize>"
+(define_insn "call_indirect_aix<ptrsize>"
   [(call (mem:SI (match_operand:P 0 "register_operand" "c,*l"))
 	 (match_operand 1 "" "g,g"))
    (use (match_operand:P 2 "memory_operand" "m,m"))
-   (use (match_operand:P 3 "memory_operand" "m,m"))
+   (set (reg:P TOC_REGNUM) (match_operand:P 3 "memory_operand" "m,m"))
    (use (reg:P STATIC_CHAIN_REGNUM))
    (clobber (reg:P LR_REGNO))]
   "DEFAULT_ABI == ABI_AIX && TARGET_POINTERS_TO_NESTED_FUNCTIONS"
-  "#"
-  "&& reload_completed"
-  [(set (reg:P TOC_REGNUM) (match_dup 2))
-   (parallel [(call (mem:SI (match_dup 0))
-		    (match_dup 1))
-	      (use (reg:P TOC_REGNUM))
-	      (use (reg:P STATIC_CHAIN_REGNUM))
-	      (use (match_dup 3))
-	      (set (reg:P TOC_REGNUM) (match_dup 3))
-	      (clobber (reg:P LR_REGNO))])]
-  ""
+  "<ptrload> 2,%2\;b%T0l\;<ptrload> 2,%3"
   [(set_attr "type" "jmpreg")
    (set_attr "length" "12")])
 
-(define_insn "*call_indirect_aix<ptrsize>_internal"
-  [(call (mem:SI (match_operand:P 0 "register_operand" "c,*l"))
-	 (match_operand 1 "" "g,g"))
-   (use (reg:P TOC_REGNUM))
-   (use (reg:P STATIC_CHAIN_REGNUM))
-   (use (match_operand:P 2 "memory_operand" "m,m"))
-   (set (reg:P TOC_REGNUM) (match_dup 2))
-   (clobber (reg:P LR_REGNO))]
-  "DEFAULT_ABI == ABI_AIX && reload_completed
-   && TARGET_POINTERS_TO_NESTED_FUNCTIONS"
-  "b%T0l\;<ptrload> 2,%2"
-  [(set_attr "type" "jmpreg")
-   (set_attr "length" "8")])
-
-;; Like call_indirect_aix<ptrsize>, except don't load the static chain
+;; Like call_indirect_aix<ptrsize>, but no use of the static chain
 ;; Operand0 is the addresss of the function to call
 ;; Operand1 is the flag for System V.4 for unprototyped or FP registers
 ;; Operand2 is the location in the function descriptor to load r2 from
 ;; Operand3 is the stack location to hold the current TOC pointer
 
-(define_insn_and_split "call_indirect_aix<ptrsize>_nor11"
+(define_insn "call_indirect_aix<ptrsize>_nor11"
   [(call (mem:SI (match_operand:P 0 "register_operand" "c,*l"))
 	 (match_operand 1 "" "g,g"))
    (use (match_operand:P 2 "memory_operand" "m,m"))
-   (use (match_operand:P 3 "memory_operand" "m,m"))
+   (set (reg:P TOC_REGNUM) (match_operand:P 3 "memory_operand" "m,m"))
    (clobber (reg:P LR_REGNO))]
   "DEFAULT_ABI == ABI_AIX && !TARGET_POINTERS_TO_NESTED_FUNCTIONS"
-  "#"
-  "&& reload_completed"
-  [(set (reg:P TOC_REGNUM) (match_dup 2))
-   (parallel [(call (mem:SI (match_dup 0))
-		    (match_dup 1))
-	      (use (reg:P TOC_REGNUM))
-	      (use (match_dup 3))
-	      (set (reg:P TOC_REGNUM) (match_dup 3))
-	      (clobber (reg:P LR_REGNO))])]
-  ""
+  "<ptrload> 2,%2\;b%T0l\;<ptrload> 2,%3"
   [(set_attr "type" "jmpreg")
    (set_attr "length" "12")])
 
-(define_insn "*call_indirect_aix<ptrsize>_internal2"
-  [(call (mem:SI (match_operand:P 0 "register_operand" "c,*l"))
-	 (match_operand 1 "" "g,g"))
-   (use (reg:P TOC_REGNUM))
-   (use (match_operand:P 2 "memory_operand" "m,m"))
-   (set (reg:P TOC_REGNUM) (match_dup 2))
-   (clobber (reg:P LR_REGNO))]
-  "DEFAULT_ABI == ABI_AIX && reload_completed
-   && !TARGET_POINTERS_TO_NESTED_FUNCTIONS"
-  "b%T0l\;<ptrload> 2,%2"
-  [(set_attr "type" "jmpreg")
-   (set_attr "length" "8")])
-
 ;; Operand0 is the return result of the function
 ;; Operand1 is the addresss of the function to call
 ;; Operand2 is the flag for System V.4 for unprototyped or FP registers
 ;; Operand3 is the location in the function descriptor to load r2 from
 ;; Operand4 is the stack location to hold the current TOC pointer
 
-(define_insn_and_split "call_value_indirect_aix<ptrsize>"
+(define_insn "call_value_indirect_aix<ptrsize>"
   [(set (match_operand 0 "" "")
 	(call (mem:SI (match_operand:P 1 "register_operand" "c,*l"))
 	      (match_operand 2 "" "g,g")))
    (use (match_operand:P 3 "memory_operand" "m,m"))
-   (use (match_operand:P 4 "memory_operand" "m,m"))
+   (set (reg:P TOC_REGNUM) (match_operand:P 4 "memory_operand" "m,m"))
    (use (reg:P STATIC_CHAIN_REGNUM))
    (clobber (reg:P LR_REGNO))]
   "DEFAULT_ABI == ABI_AIX && TARGET_POINTERS_TO_NESTED_FUNCTIONS"
-  "#"
-  "&& reload_completed"
-  [(set (reg:P TOC_REGNUM) (match_dup 3))
-   (parallel [(set (match_dup 0)
-		   (call (mem:SI (match_dup 1))
-			 (match_dup 2)))
-	      (use (reg:P TOC_REGNUM))
-	      (use (reg:P STATIC_CHAIN_REGNUM))
-	      (use (match_dup 4))
-	      (set (reg:P TOC_REGNUM) (match_dup 4))
-	      (clobber (reg:P LR_REGNO))])]
-  ""
+  "<ptrload> 2,%3\;b%T1l\;<ptrload> 2,%4"
   [(set_attr "type" "jmpreg")
    (set_attr "length" "12")])
 
-(define_insn "*call_value_indirect_aix<ptrsize>_internal"
-  [(set (match_operand 0 "" "")
-	(call (mem:SI (match_operand:P 1 "register_operand" "c,*l"))
-	      (match_operand 2 "" "g,g")))
-   (use (reg:P TOC_REGNUM))
-   (use (reg:P STATIC_CHAIN_REGNUM))
-   (use (match_operand:P 3 "memory_operand" "m,m"))
-   (set (reg:P TOC_REGNUM) (match_dup 3))
-   (clobber (reg:P LR_REGNO))]
-  "DEFAULT_ABI == ABI_AIX && reload_completed
-   && TARGET_POINTERS_TO_NESTED_FUNCTIONS"
-  "b%T1l\;<ptrload> 2,%3"
-  [(set_attr "type" "jmpreg")
-   (set_attr "length" "8")])
-
-;; Like call_value_indirect_aix<ptrsize>, but don't load the static chain
+;; Like call_value_indirect_aix<ptrsize>, but no use of the static chain
 ;; Operand0 is the return result of the function
 ;; Operand1 is the addresss of the function to call
 ;; Operand2 is the flag for System V.4 for unprototyped or FP registers
 ;; Operand3 is the location in the function descriptor to load r2 from
 ;; Operand4 is the stack location to hold the current TOC pointer
 
-(define_insn_and_split "call_value_indirect_aix<ptrsize>_nor11"
+(define_insn "call_value_indirect_aix<ptrsize>_nor11"
   [(set (match_operand 0 "" "")
 	(call (mem:SI (match_operand:P 1 "register_operand" "c,*l"))
 	      (match_operand 2 "" "g,g")))
    (use (match_operand:P 3 "memory_operand" "m,m"))
-   (use (match_operand:P 4 "memory_operand" "m,m"))
+   (set (reg:P TOC_REGNUM) (match_operand:P 4 "memory_operand" "m,m"))
    (clobber (reg:P LR_REGNO))]
   "DEFAULT_ABI == ABI_AIX && !TARGET_POINTERS_TO_NESTED_FUNCTIONS"
-  "#"
-  "&& reload_completed"
-  [(set (reg:P TOC_REGNUM) (match_dup 3))
-   (parallel [(set (match_dup 0)
-		   (call (mem:SI (match_dup 1))
-			 (match_dup 2)))
-	      (use (reg:P TOC_REGNUM))
-	      (use (match_dup 4))
-	      (set (reg:P TOC_REGNUM) (match_dup 4))
-	      (clobber (reg:P LR_REGNO))])]
-  ""
+  "<ptrload> 2,%3\;b%T1l\;<ptrload> 2,%4"
   [(set_attr "type" "jmpreg")
    (set_attr "length" "12")])
 
-(define_insn "*call_value_indirect_aix<ptrsize>_internal2"
-  [(set (match_operand 0 "" "")
-	(call (mem:SI (match_operand:P 1 "register_operand" "c,*l"))
-	      (match_operand 2 "" "g,g")))
-   (use (reg:P TOC_REGNUM))
-   (use (match_operand:P 3 "memory_operand" "m,m"))
-   (set (reg:P TOC_REGNUM) (match_dup 3))
-   (clobber (reg:P LR_REGNO))]
-  "DEFAULT_ABI == ABI_AIX && reload_completed
-   && !TARGET_POINTERS_TO_NESTED_FUNCTIONS"
-  "b%T1l\;<ptrload> 2,%3"
-  [(set_attr "type" "jmpreg")
-   (set_attr "length" "8")])
-
 ;; 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


More information about the Gcc-patches mailing list