===================================================================
@@ -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"))