aboutsummaryrefslogtreecommitdiff
path: root/gcc/config/pa
diff options
context:
space:
mode:
authorJohn David Anglin <dave.anglin@nrc-cnrc.gc.ca>2008-10-11 15:54:27 +0000
committerJohn David Anglin <danglin@gcc.gnu.org>2008-10-11 15:54:27 +0000
commite40375e0e23145c3140d375d3cf8f164800983ee (patch)
treea4e93d66ea422b21cd664acd15b8fd5b210ef62e /gcc/config/pa
parente47911ce2145c3efd181bffc191cf38c7271177c (diff)
downloadgcc-e40375e0e23145c3140d375d3cf8f164800983ee.zip
gcc-e40375e0e23145c3140d375d3cf8f164800983ee.tar.gz
gcc-e40375e0e23145c3140d375d3cf8f164800983ee.tar.bz2
re PR middle-end/37608 (libgcc2.c:1981: ICE: vector VEC(m em_ref_p,base) index domain error, in create_vop_ref_mapping_loop at tree-ssa-lo op-im.c:1519)
PR middle-end/37608 * pa.md (call, call_value): Generate an rtx for register r4 and pass it to PIC call patterns. (call_symref_pic): Revise pattern to expose PIC register save. Remove code generation and attributes from pattern. Change peephole2 to split for noreturn case. Revise split pattern for non noreturn case. (call_symref_64bit, call_reg_pic, call_reg_64bit, call_val_symref_pic, call_val_symref_64bit, call_val_reg_pic, call_val_reg_64bit): Likewise. * pa.c (attr_length_call): Simplify extraction of call rtx. Add some asserts. From-SVN: r141063
Diffstat (limited to 'gcc/config/pa')
-rw-r--r--gcc/config/pa/pa.c19
-rw-r--r--gcc/config/pa/pa.md551
2 files changed, 284 insertions, 286 deletions
diff --git a/gcc/config/pa/pa.c b/gcc/config/pa/pa.c
index 652eba5..3d3c96d 100644
--- a/gcc/config/pa/pa.c
+++ b/gcc/config/pa/pa.c
@@ -7377,12 +7377,14 @@ int
attr_length_call (rtx insn, int sibcall)
{
int local_call;
- rtx call_dest;
+ rtx call, call_dest;
tree call_decl;
int length = 0;
rtx pat = PATTERN (insn);
unsigned long distance = -1;
+ gcc_assert (GET_CODE (insn) == CALL_INSN);
+
if (INSN_ADDRESSES_SET_P ())
{
unsigned long total;
@@ -7393,12 +7395,17 @@ attr_length_call (rtx insn, int sibcall)
distance = -1;
}
- /* Determine if this is a local call. */
- if (GET_CODE (XVECEXP (pat, 0, 0)) == CALL)
- call_dest = XEXP (XEXP (XVECEXP (pat, 0, 0), 0), 0);
- else
- call_dest = XEXP (XEXP (XEXP (XVECEXP (pat, 0, 0), 1), 0), 0);
+ gcc_assert (GET_CODE (pat) == PARALLEL);
+ /* Get the call rtx. */
+ call = XVECEXP (pat, 0, 0);
+ if (GET_CODE (call) == SET)
+ call = SET_SRC (call);
+
+ gcc_assert (GET_CODE (call) == CALL);
+
+ /* Determine if this is a local call. */
+ call_dest = XEXP (XEXP (call, 0), 0);
call_decl = SYMBOL_REF_DECL (call_dest);
local_call = call_decl && targetm.binds_local_p (call_decl);
diff --git a/gcc/config/pa/pa.md b/gcc/config/pa/pa.md
index b50ab4c..b845182 100644
--- a/gcc/config/pa/pa.md
+++ b/gcc/config/pa/pa.md
@@ -7669,19 +7669,20 @@ add,l %2,%3,%3\;bv,n %%r0(%3)"
need to have a use of the PIC register in the return pattern and
the final save/restore operation is not needed.
- I elected to just clobber %r4 in the PIC patterns and use it instead
+ I elected to just use register %r4 in the PIC patterns instead
of trying to force hppa_pic_save_rtx () to a callee saved register.
This might have required a new register class and constraint. It
was also simpler to just handle the restore from a register than a
generic pseudo. */
if (TARGET_64BIT)
{
+ rtx r4 = gen_rtx_REG (word_mode, 4);
if (GET_CODE (op) == SYMBOL_REF)
- call_insn = emit_call_insn (gen_call_symref_64bit (op, nb));
+ call_insn = emit_call_insn (gen_call_symref_64bit (op, nb, r4));
else
{
op = force_reg (word_mode, op);
- call_insn = emit_call_insn (gen_call_reg_64bit (op, nb));
+ call_insn = emit_call_insn (gen_call_reg_64bit (op, nb, r4));
}
}
else
@@ -7689,17 +7690,22 @@ add,l %2,%3,%3\;bv,n %%r0(%3)"
if (GET_CODE (op) == SYMBOL_REF)
{
if (flag_pic)
- call_insn = emit_call_insn (gen_call_symref_pic (op, nb));
+ {
+ rtx r4 = gen_rtx_REG (word_mode, 4);
+ call_insn = emit_call_insn (gen_call_symref_pic (op, nb, r4));
+ }
else
call_insn = emit_call_insn (gen_call_symref (op, nb));
}
else
{
rtx tmpreg = gen_rtx_REG (word_mode, 22);
-
emit_move_insn (tmpreg, force_reg (word_mode, op));
if (flag_pic)
- call_insn = emit_call_insn (gen_call_reg_pic (nb));
+ {
+ rtx r4 = gen_rtx_REG (word_mode, 4);
+ call_insn = emit_call_insn (gen_call_reg_pic (nb, r4));
+ }
else
call_insn = emit_call_insn (gen_call_reg (nb));
}
@@ -7754,69 +7760,64 @@ add,l %2,%3,%3\;bv,n %%r0(%3)"
(set (attr "length") (symbol_ref "attr_length_call (insn, 0)"))])
(define_insn "call_symref_pic"
- [(call (mem:SI (match_operand 0 "call_operand_address" ""))
+ [(set (match_operand:SI 2 "register_operand" "=&r") (reg:SI 19))
+ (call (mem:SI (match_operand 0 "call_operand_address" ""))
(match_operand 1 "" "i"))
(clobber (reg:SI 1))
(clobber (reg:SI 2))
- (clobber (reg:SI 4))
+ (use (match_dup 2))
(use (reg:SI 19))
(use (const_int 0))]
"!TARGET_PORTABLE_RUNTIME && !TARGET_64BIT"
- "*
-{
- output_arg_descriptor (insn);
- return output_call (insn, operands[0], 0);
-}"
- [(set_attr "type" "call")
- (set (attr "length")
- (plus (symbol_ref "attr_length_call (insn, 0)")
- (symbol_ref "attr_length_save_restore_dltp (insn)")))])
-
-;; Split out the PIC register save and restore after reload. This is
-;; done only if the function returns. As the split is done after reload,
-;; there are some situations in which we unnecessarily save and restore
-;; %r4. This happens when there is a single call and the PIC register
-;; is "dead" after the call. This isn't easy to fix as the usage of
-;; the PIC register isn't completely determined until the reload pass.
+ "#")
+
+;; Split out the PIC register save and restore after reload. As the
+;; split is done after reload, there are some situations in which we
+;; unnecessarily save and restore %r4. This happens when there is a
+;; single call and the PIC register is not used after the call.
+;;
+;; The split has to be done since call_from_call_insn () can't handle
+;; the pattern as is. Noreturn calls are special because they have to
+;; terminate the basic block. The split has to contain more than one
+;; insn.
(define_split
- [(parallel [(call (mem:SI (match_operand 0 "call_operand_address" ""))
+ [(parallel [(set (match_operand:SI 2 "register_operand" "") (reg:SI 19))
+ (call (mem:SI (match_operand 0 "call_operand_address" ""))
(match_operand 1 "" ""))
(clobber (reg:SI 1))
(clobber (reg:SI 2))
- (clobber (reg:SI 4))
+ (use (match_dup 2))
(use (reg:SI 19))
(use (const_int 0))])]
- "!TARGET_PORTABLE_RUNTIME && !TARGET_64BIT
- && reload_completed
- && !find_reg_note (insn, REG_NORETURN, NULL_RTX)"
- [(set (reg:SI 4) (reg:SI 19))
+ "!TARGET_PORTABLE_RUNTIME && !TARGET_64BIT && reload_completed
+ && find_reg_note (insn, REG_NORETURN, NULL_RTX)"
+ [(set (match_dup 2) (reg:SI 19))
(parallel [(call (mem:SI (match_dup 0))
(match_dup 1))
(clobber (reg:SI 1))
(clobber (reg:SI 2))
(use (reg:SI 19))
- (use (const_int 0))])
- (set (reg:SI 19) (reg:SI 4))]
+ (use (const_int 0))])]
"")
-;; Remove the clobber of register 4 when optimizing. This has to be
-;; done with a peephole optimization rather than a split because the
-;; split sequence for a call must be longer than one instruction.
-(define_peephole2
- [(parallel [(call (mem:SI (match_operand 0 "call_operand_address" ""))
+(define_split
+ [(parallel [(set (match_operand:SI 2 "register_operand" "") (reg:SI 19))
+ (call (mem:SI (match_operand 0 "call_operand_address" ""))
(match_operand 1 "" ""))
(clobber (reg:SI 1))
(clobber (reg:SI 2))
- (clobber (reg:SI 4))
+ (use (match_dup 2))
(use (reg:SI 19))
(use (const_int 0))])]
"!TARGET_PORTABLE_RUNTIME && !TARGET_64BIT && reload_completed"
- [(parallel [(call (mem:SI (match_dup 0))
+ [(set (match_dup 2) (reg:SI 19))
+ (parallel [(call (mem:SI (match_dup 0))
(match_dup 1))
(clobber (reg:SI 1))
(clobber (reg:SI 2))
(use (reg:SI 19))
- (use (const_int 0))])]
+ (use (const_int 0))])
+ (set (reg:SI 19) (match_dup 2))]
"")
(define_insn "*call_symref_pic_post_reload"
@@ -7838,74 +7839,69 @@ add,l %2,%3,%3\;bv,n %%r0(%3)"
;; This pattern is split if it is necessary to save and restore the
;; PIC register.
(define_insn "call_symref_64bit"
- [(call (mem:SI (match_operand 0 "call_operand_address" ""))
+ [(set (match_operand:DI 2 "register_operand" "=&r") (reg:DI 27))
+ (call (mem:SI (match_operand 0 "call_operand_address" ""))
(match_operand 1 "" "i"))
(clobber (reg:DI 1))
(clobber (reg:DI 2))
- (clobber (reg:DI 4))
+ (use (match_dup 2))
(use (reg:DI 27))
(use (reg:DI 29))
(use (const_int 0))]
"TARGET_64BIT"
- "*
-{
- output_arg_descriptor (insn);
- return output_call (insn, operands[0], 0);
-}"
- [(set_attr "type" "call")
- (set (attr "length")
- (plus (symbol_ref "attr_length_call (insn, 0)")
- (symbol_ref "attr_length_save_restore_dltp (insn)")))])
-
-;; Split out the PIC register save and restore after reload. This is
-;; done only if the function returns. As the split is done after reload,
-;; there are some situations in which we unnecessarily save and restore
-;; %r4. This happens when there is a single call and the PIC register
-;; is "dead" after the call. This isn't easy to fix as the usage of
-;; the PIC register isn't completely determined until the reload pass.
+ "#")
+
+;; Split out the PIC register save and restore after reload. As the
+;; split is done after reload, there are some situations in which we
+;; unnecessarily save and restore %r4. This happens when there is a
+;; single call and the PIC register is not used after the call.
+;;
+;; The split has to be done since call_from_call_insn () can't handle
+;; the pattern as is. Noreturn calls are special because they have to
+;; terminate the basic block. The split has to contain more than one
+;; insn.
(define_split
- [(parallel [(call (mem:SI (match_operand 0 "call_operand_address" ""))
+ [(parallel [(set (match_operand:DI 2 "register_operand" "") (reg:DI 27))
+ (call (mem:SI (match_operand 0 "call_operand_address" ""))
(match_operand 1 "" ""))
(clobber (reg:DI 1))
(clobber (reg:DI 2))
- (clobber (reg:DI 4))
+ (use (match_dup 2))
(use (reg:DI 27))
(use (reg:DI 29))
(use (const_int 0))])]
- "TARGET_64BIT
- && reload_completed
- && !find_reg_note (insn, REG_NORETURN, NULL_RTX)"
- [(set (reg:DI 4) (reg:DI 27))
+ "TARGET_64BIT && reload_completed
+ && find_reg_note (insn, REG_NORETURN, NULL_RTX)"
+ [(set (match_dup 2) (reg:DI 27))
(parallel [(call (mem:SI (match_dup 0))
(match_dup 1))
(clobber (reg:DI 1))
(clobber (reg:DI 2))
(use (reg:DI 27))
(use (reg:DI 29))
- (use (const_int 0))])
- (set (reg:DI 27) (reg:DI 4))]
+ (use (const_int 0))])]
"")
-;; Remove the clobber of register 4 when optimizing. This has to be
-;; done with a peephole optimization rather than a split because the
-;; split sequence for a call must be longer than one instruction.
-(define_peephole2
- [(parallel [(call (mem:SI (match_operand 0 "call_operand_address" ""))
+(define_split
+ [(parallel [(set (match_operand:DI 2 "register_operand" "") (reg:DI 27))
+ (call (mem:SI (match_operand 0 "call_operand_address" ""))
(match_operand 1 "" ""))
(clobber (reg:DI 1))
(clobber (reg:DI 2))
- (clobber (reg:DI 4))
+ (use (match_dup 2))
(use (reg:DI 27))
(use (reg:DI 29))
(use (const_int 0))])]
"TARGET_64BIT && reload_completed"
- [(parallel [(call (mem:SI (match_dup 0))
+ [(set (match_dup 2) (reg:DI 27))
+ (parallel [(call (mem:SI (match_dup 0))
(match_dup 1))
(clobber (reg:DI 1))
(clobber (reg:DI 2))
(use (reg:DI 27))
(use (reg:DI 29))
- (use (const_int 0))])]
+ (use (const_int 0))])
+ (set (reg:DI 27) (match_dup 2))]
"")
(define_insn "*call_symref_64bit_post_reload"
@@ -7942,68 +7938,64 @@ add,l %2,%3,%3\;bv,n %%r0(%3)"
;; This pattern is split if it is necessary to save and restore the
;; PIC register.
(define_insn "call_reg_pic"
- [(call (mem:SI (reg:SI 22))
+ [(set (match_operand:SI 1 "register_operand" "=&r") (reg:SI 19))
+ (call (mem:SI (reg:SI 22))
(match_operand 0 "" "i"))
(clobber (reg:SI 1))
(clobber (reg:SI 2))
- (clobber (reg:SI 4))
+ (use (match_dup 1))
(use (reg:SI 19))
(use (const_int 1))]
"!TARGET_64BIT"
- "*
-{
- return output_indirect_call (insn, gen_rtx_REG (word_mode, 22));
-}"
- [(set_attr "type" "dyncall")
- (set (attr "length")
- (plus (symbol_ref "attr_length_indirect_call (insn)")
- (symbol_ref "attr_length_save_restore_dltp (insn)")))])
-
-;; Split out the PIC register save and restore after reload. This is
-;; done only if the function returns. As the split is done after reload,
-;; there are some situations in which we unnecessarily save and restore
-;; %r4. This happens when there is a single call and the PIC register
-;; is "dead" after the call. This isn't easy to fix as the usage of
-;; the PIC register isn't completely determined until the reload pass.
+ "#")
+
+;; Split out the PIC register save and restore after reload. As the
+;; split is done after reload, there are some situations in which we
+;; unnecessarily save and restore %r4. This happens when there is a
+;; single call and the PIC register is not used after the call.
+;;
+;; The split has to be done since call_from_call_insn () can't handle
+;; the pattern as is. Noreturn calls are special because they have to
+;; terminate the basic block. The split has to contain more than one
+;; insn.
(define_split
- [(parallel [(call (mem:SI (reg:SI 22))
+ [(parallel [(set (match_operand:SI 1 "register_operand" "") (reg:SI 19))
+ (call (mem:SI (reg:SI 22))
(match_operand 0 "" ""))
(clobber (reg:SI 1))
(clobber (reg:SI 2))
- (clobber (reg:SI 4))
+ (use (match_dup 1))
(use (reg:SI 19))
(use (const_int 1))])]
- "!TARGET_64BIT
- && reload_completed
- && !find_reg_note (insn, REG_NORETURN, NULL_RTX)"
- [(set (reg:SI 4) (reg:SI 19))
+ "!TARGET_64BIT && reload_completed
+ && find_reg_note (insn, REG_NORETURN, NULL_RTX)"
+ [(set (match_dup 1) (reg:SI 19))
(parallel [(call (mem:SI (reg:SI 22))
(match_dup 0))
(clobber (reg:SI 1))
(clobber (reg:SI 2))
(use (reg:SI 19))
- (use (const_int 1))])
- (set (reg:SI 19) (reg:SI 4))]
+ (use (const_int 1))])]
"")
-;; Remove the clobber of register 4 when optimizing. This has to be
-;; done with a peephole optimization rather than a split because the
-;; split sequence for a call must be longer than one instruction.
-(define_peephole2
- [(parallel [(call (mem:SI (reg:SI 22))
+(define_split
+ [(parallel [(set (match_operand:SI 1 "register_operand" "") (reg:SI 19))
+ (call (mem:SI (reg:SI 22))
(match_operand 0 "" ""))
(clobber (reg:SI 1))
(clobber (reg:SI 2))
- (clobber (reg:SI 4))
+ (use (match_dup 1))
(use (reg:SI 19))
(use (const_int 1))])]
"!TARGET_64BIT && reload_completed"
- [(parallel [(call (mem:SI (reg:SI 22))
+ [(set (match_dup 1) (reg:SI 19))
+ (parallel [(call (mem:SI (reg:SI 22))
(match_dup 0))
(clobber (reg:SI 1))
(clobber (reg:SI 2))
(use (reg:SI 19))
- (use (const_int 1))])]
+ (use (const_int 1))])
+ (set (reg:SI 19) (match_dup 1))]
"")
(define_insn "*call_reg_pic_post_reload"
@@ -8024,73 +8016,75 @@ add,l %2,%3,%3\;bv,n %%r0(%3)"
;; This pattern is split if it is necessary to save and restore the
;; PIC register.
(define_insn "call_reg_64bit"
- [(call (mem:SI (match_operand:DI 0 "register_operand" "r"))
+ [(set (match_operand:DI 2 "register_operand" "=&r") (reg:DI 27))
+ (call (mem:SI (match_operand:DI 0 "register_operand" "r"))
(match_operand 1 "" "i"))
+ (clobber (reg:DI 1))
(clobber (reg:DI 2))
- (clobber (reg:DI 4))
+ (use (match_dup 2))
(use (reg:DI 27))
(use (reg:DI 29))
(use (const_int 1))]
"TARGET_64BIT"
- "*
-{
- return output_indirect_call (insn, operands[0]);
-}"
- [(set_attr "type" "dyncall")
- (set (attr "length")
- (plus (symbol_ref "attr_length_indirect_call (insn)")
- (symbol_ref "attr_length_save_restore_dltp (insn)")))])
-
-;; Split out the PIC register save and restore after reload. This is
-;; done only if the function returns. As the split is done after reload,
-;; there are some situations in which we unnecessarily save and restore
-;; %r4. This happens when there is a single call and the PIC register
-;; is "dead" after the call. This isn't easy to fix as the usage of
-;; the PIC register isn't completely determined until the reload pass.
+ "#")
+
+;; Split out the PIC register save and restore after reload. As the
+;; split is done after reload, there are some situations in which we
+;; unnecessarily save and restore %r4. This happens when there is a
+;; single call and the PIC register is not used after the call.
+;;
+;; The split has to be done since call_from_call_insn () can't handle
+;; the pattern as is. Noreturn calls are special because they have to
+;; terminate the basic block. The split has to contain more than one
+;; insn.
(define_split
- [(parallel [(call (mem:SI (match_operand 0 "register_operand" ""))
+ [(parallel [(set (match_operand:DI 2 "register_operand" "") (reg:DI 27))
+ (call (mem:SI (match_operand 0 "register_operand" ""))
(match_operand 1 "" ""))
+ (clobber (reg:DI 1))
(clobber (reg:DI 2))
- (clobber (reg:DI 4))
+ (use (match_dup 2))
(use (reg:DI 27))
(use (reg:DI 29))
(use (const_int 1))])]
- "TARGET_64BIT
- && reload_completed
- && !find_reg_note (insn, REG_NORETURN, NULL_RTX)"
- [(set (reg:DI 4) (reg:DI 27))
+ "TARGET_64BIT && reload_completed
+ && find_reg_note (insn, REG_NORETURN, NULL_RTX)"
+ [(set (match_dup 2) (reg:DI 27))
(parallel [(call (mem:SI (match_dup 0))
(match_dup 1))
+ (clobber (reg:DI 1))
(clobber (reg:DI 2))
(use (reg:DI 27))
(use (reg:DI 29))
- (use (const_int 1))])
- (set (reg:DI 27) (reg:DI 4))]
+ (use (const_int 1))])]
"")
-;; Remove the clobber of register 4 when optimizing. This has to be
-;; done with a peephole optimization rather than a split because the
-;; split sequence for a call must be longer than one instruction.
-(define_peephole2
- [(parallel [(call (mem:SI (match_operand 0 "register_operand" ""))
+(define_split
+ [(parallel [(set (match_operand:DI 2 "register_operand" "") (reg:DI 27))
+ (call (mem:SI (match_operand 0 "register_operand" ""))
(match_operand 1 "" ""))
+ (clobber (reg:DI 1))
(clobber (reg:DI 2))
- (clobber (reg:DI 4))
+ (use (match_dup 2))
(use (reg:DI 27))
(use (reg:DI 29))
(use (const_int 1))])]
"TARGET_64BIT && reload_completed"
- [(parallel [(call (mem:SI (match_dup 0))
+ [(set (match_dup 2) (reg:DI 27))
+ (parallel [(call (mem:SI (match_dup 0))
(match_dup 1))
+ (clobber (reg:DI 1))
(clobber (reg:DI 2))
(use (reg:DI 27))
(use (reg:DI 29))
- (use (const_int 1))])]
+ (use (const_int 1))])
+ (set (reg:DI 27) (match_dup 2))]
"")
(define_insn "*call_reg_64bit_post_reload"
[(call (mem:SI (match_operand:DI 0 "register_operand" "r"))
(match_operand 1 "" "i"))
+ (clobber (reg:DI 1))
(clobber (reg:DI 2))
(use (reg:DI 27))
(use (reg:DI 29))
@@ -8168,19 +8162,22 @@ add,l %2,%3,%3\;bv,n %%r0(%3)"
need to have a use of the PIC register in the return pattern and
the final save/restore operation is not needed.
- I elected to just clobber %r4 in the PIC patterns and use it instead
+ I elected to just use register %r4 in the PIC patterns instead
of trying to force hppa_pic_save_rtx () to a callee saved register.
This might have required a new register class and constraint. It
was also simpler to just handle the restore from a register than a
generic pseudo. */
if (TARGET_64BIT)
{
+ rtx r4 = gen_rtx_REG (word_mode, 4);
if (GET_CODE (op) == SYMBOL_REF)
- call_insn = emit_call_insn (gen_call_val_symref_64bit (dst, op, nb));
+ call_insn
+ = emit_call_insn (gen_call_val_symref_64bit (dst, op, nb, r4));
else
{
op = force_reg (word_mode, op);
- call_insn = emit_call_insn (gen_call_val_reg_64bit (dst, op, nb));
+ call_insn
+ = emit_call_insn (gen_call_val_reg_64bit (dst, op, nb, r4));
}
}
else
@@ -8188,17 +8185,23 @@ add,l %2,%3,%3\;bv,n %%r0(%3)"
if (GET_CODE (op) == SYMBOL_REF)
{
if (flag_pic)
- call_insn = emit_call_insn (gen_call_val_symref_pic (dst, op, nb));
+ {
+ rtx r4 = gen_rtx_REG (word_mode, 4);
+ call_insn
+ = emit_call_insn (gen_call_val_symref_pic (dst, op, nb, r4));
+ }
else
call_insn = emit_call_insn (gen_call_val_symref (dst, op, nb));
}
else
{
rtx tmpreg = gen_rtx_REG (word_mode, 22);
-
emit_move_insn (tmpreg, force_reg (word_mode, op));
if (flag_pic)
- call_insn = emit_call_insn (gen_call_val_reg_pic (dst, nb));
+ {
+ rtx r4 = gen_rtx_REG (word_mode, 4);
+ call_insn = emit_call_insn (gen_call_val_reg_pic (dst, nb, r4));
+ }
else
call_insn = emit_call_insn (gen_call_val_reg (dst, nb));
}
@@ -8224,74 +8227,69 @@ add,l %2,%3,%3\;bv,n %%r0(%3)"
(set (attr "length") (symbol_ref "attr_length_call (insn, 0)"))])
(define_insn "call_val_symref_pic"
- [(set (match_operand 0 "" "")
+ [(set (match_operand:SI 3 "register_operand" "=&r") (reg:SI 19))
+ (set (match_operand 0 "" "")
(call (mem:SI (match_operand 1 "call_operand_address" ""))
(match_operand 2 "" "i")))
(clobber (reg:SI 1))
(clobber (reg:SI 2))
- (clobber (reg:SI 4))
+ (use (match_dup 3))
(use (reg:SI 19))
(use (const_int 0))]
"!TARGET_PORTABLE_RUNTIME && !TARGET_64BIT"
- "*
-{
- output_arg_descriptor (insn);
- return output_call (insn, operands[1], 0);
-}"
- [(set_attr "type" "call")
- (set (attr "length")
- (plus (symbol_ref "attr_length_call (insn, 0)")
- (symbol_ref "attr_length_save_restore_dltp (insn)")))])
-
-;; Split out the PIC register save and restore after reload. This is
-;; done only if the function returns. As the split is done after reload,
-;; there are some situations in which we unnecessarily save and restore
-;; %r4. This happens when there is a single call and the PIC register
-;; is "dead" after the call. This isn't easy to fix as the usage of
-;; the PIC register isn't completely determined until the reload pass.
+ "#")
+
+;; Split out the PIC register save and restore after reload. As the
+;; split is done after reload, there are some situations in which we
+;; unnecessarily save and restore %r4. This happens when there is a
+;; single call and the PIC register is not used after the call.
+;;
+;; The split has to be done since call_from_call_insn () can't handle
+;; the pattern as is. Noreturn calls are special because they have to
+;; terminate the basic block. The split has to contain more than one
+;; insn.
(define_split
- [(parallel [(set (match_operand 0 "" "")
+ [(parallel [(set (match_operand:SI 3 "register_operand" "") (reg:SI 19))
+ (set (match_operand 0 "" "")
(call (mem:SI (match_operand 1 "call_operand_address" ""))
(match_operand 2 "" "")))
(clobber (reg:SI 1))
(clobber (reg:SI 2))
- (clobber (reg:SI 4))
+ (use (match_dup 3))
(use (reg:SI 19))
(use (const_int 0))])]
- "!TARGET_PORTABLE_RUNTIME && !TARGET_64BIT
- && reload_completed
- && !find_reg_note (insn, REG_NORETURN, NULL_RTX)"
- [(set (reg:SI 4) (reg:SI 19))
+ "!TARGET_PORTABLE_RUNTIME && !TARGET_64BIT && reload_completed
+ && find_reg_note (insn, REG_NORETURN, NULL_RTX)"
+ [(set (match_dup 3) (reg:SI 19))
(parallel [(set (match_dup 0)
(call (mem:SI (match_dup 1))
(match_dup 2)))
(clobber (reg:SI 1))
(clobber (reg:SI 2))
(use (reg:SI 19))
- (use (const_int 0))])
- (set (reg:SI 19) (reg:SI 4))]
+ (use (const_int 0))])]
"")
-;; Remove the clobber of register 4 when optimizing. This has to be
-;; done with a peephole optimization rather than a split because the
-;; split sequence for a call must be longer than one instruction.
-(define_peephole2
- [(parallel [(set (match_operand 0 "" "")
+(define_split
+ [(parallel [(set (match_operand:SI 3 "register_operand" "") (reg:SI 19))
+ (set (match_operand 0 "" "")
(call (mem:SI (match_operand 1 "call_operand_address" ""))
(match_operand 2 "" "")))
(clobber (reg:SI 1))
(clobber (reg:SI 2))
- (clobber (reg:SI 4))
+ (use (match_dup 3))
(use (reg:SI 19))
(use (const_int 0))])]
"!TARGET_PORTABLE_RUNTIME && !TARGET_64BIT && reload_completed"
- [(parallel [(set (match_dup 0)
+ [(set (match_dup 3) (reg:SI 19))
+ (parallel [(set (match_dup 0)
(call (mem:SI (match_dup 1))
(match_dup 2)))
(clobber (reg:SI 1))
(clobber (reg:SI 2))
(use (reg:SI 19))
- (use (const_int 0))])]
+ (use (const_int 0))])
+ (set (reg:SI 19) (match_dup 3))]
"")
(define_insn "*call_val_symref_pic_post_reload"
@@ -8314,46 +8312,42 @@ add,l %2,%3,%3\;bv,n %%r0(%3)"
;; This pattern is split if it is necessary to save and restore the
;; PIC register.
(define_insn "call_val_symref_64bit"
- [(set (match_operand 0 "" "")
+ [(set (match_operand:DI 3 "register_operand" "=&r") (reg:DI 27))
+ (set (match_operand 0 "" "")
(call (mem:SI (match_operand 1 "call_operand_address" ""))
(match_operand 2 "" "i")))
(clobber (reg:DI 1))
(clobber (reg:DI 2))
- (clobber (reg:DI 4))
+ (use (match_dup 3))
(use (reg:DI 27))
(use (reg:DI 29))
(use (const_int 0))]
"TARGET_64BIT"
- "*
-{
- output_arg_descriptor (insn);
- return output_call (insn, operands[1], 0);
-}"
- [(set_attr "type" "call")
- (set (attr "length")
- (plus (symbol_ref "attr_length_call (insn, 0)")
- (symbol_ref "attr_length_save_restore_dltp (insn)")))])
-
-;; Split out the PIC register save and restore after reload. This is
-;; done only if the function returns. As the split is done after reload,
-;; there are some situations in which we unnecessarily save and restore
-;; %r4. This happens when there is a single call and the PIC register
-;; is "dead" after the call. This isn't easy to fix as the usage of
-;; the PIC register isn't completely determined until the reload pass.
+ "#")
+
+;; Split out the PIC register save and restore after reload. As the
+;; split is done after reload, there are some situations in which we
+;; unnecessarily save and restore %r4. This happens when there is a
+;; single call and the PIC register is not used after the call.
+;;
+;; The split has to be done since call_from_call_insn () can't handle
+;; the pattern as is. Noreturn calls are special because they have to
+;; terminate the basic block. The split has to contain more than one
+;; insn.
(define_split
- [(parallel [(set (match_operand 0 "" "")
+ [(parallel [(set (match_operand:DI 3 "register_operand" "") (reg:DI 27))
+ (set (match_operand 0 "" "")
(call (mem:SI (match_operand 1 "call_operand_address" ""))
(match_operand 2 "" "")))
(clobber (reg:DI 1))
(clobber (reg:DI 2))
- (clobber (reg:DI 4))
+ (use (match_dup 3))
(use (reg:DI 27))
(use (reg:DI 29))
(use (const_int 0))])]
- "TARGET_64BIT
- && reload_completed
- && !find_reg_note (insn, REG_NORETURN, NULL_RTX)"
- [(set (reg:DI 4) (reg:DI 27))
+ "TARGET_64BIT && reload_completed
+ && find_reg_note (insn, REG_NORETURN, NULL_RTX)"
+ [(set (match_dup 3) (reg:DI 27))
(parallel [(set (match_dup 0)
(call (mem:SI (match_dup 1))
(match_dup 2)))
@@ -8361,32 +8355,31 @@ add,l %2,%3,%3\;bv,n %%r0(%3)"
(clobber (reg:DI 2))
(use (reg:DI 27))
(use (reg:DI 29))
- (use (const_int 0))])
- (set (reg:DI 27) (reg:DI 4))]
+ (use (const_int 0))])]
"")
-;; Remove the clobber of register 4 when optimizing. This has to be
-;; done with a peephole optimization rather than a split because the
-;; split sequence for a call must be longer than one instruction.
-(define_peephole2
- [(parallel [(set (match_operand 0 "" "")
+(define_split
+ [(parallel [(set (match_operand:DI 3 "register_operand" "") (reg:DI 27))
+ (set (match_operand 0 "" "")
(call (mem:SI (match_operand 1 "call_operand_address" ""))
(match_operand 2 "" "")))
(clobber (reg:DI 1))
(clobber (reg:DI 2))
- (clobber (reg:DI 4))
+ (use (match_dup 3))
(use (reg:DI 27))
(use (reg:DI 29))
(use (const_int 0))])]
"TARGET_64BIT && reload_completed"
- [(parallel [(set (match_dup 0)
+ [(set (match_dup 3) (reg:DI 27))
+ (parallel [(set (match_dup 0)
(call (mem:SI (match_dup 1))
(match_dup 2)))
(clobber (reg:DI 1))
(clobber (reg:DI 2))
(use (reg:DI 27))
(use (reg:DI 29))
- (use (const_int 0))])]
+ (use (const_int 0))])
+ (set (reg:DI 27) (match_dup 3))]
"")
(define_insn "*call_val_symref_64bit_post_reload"
@@ -8425,73 +8418,69 @@ add,l %2,%3,%3\;bv,n %%r0(%3)"
;; This pattern is split if it is necessary to save and restore the
;; PIC register.
(define_insn "call_val_reg_pic"
- [(set (match_operand 0 "" "")
+ [(set (match_operand:SI 2 "register_operand" "=&r") (reg:SI 19))
+ (set (match_operand 0 "" "")
(call (mem:SI (reg:SI 22))
(match_operand 1 "" "i")))
(clobber (reg:SI 1))
(clobber (reg:SI 2))
- (clobber (reg:SI 4))
+ (use (match_dup 2))
(use (reg:SI 19))
(use (const_int 1))]
"!TARGET_64BIT"
- "*
-{
- return output_indirect_call (insn, gen_rtx_REG (word_mode, 22));
-}"
- [(set_attr "type" "dyncall")
- (set (attr "length")
- (plus (symbol_ref "attr_length_indirect_call (insn)")
- (symbol_ref "attr_length_save_restore_dltp (insn)")))])
-
-;; Split out the PIC register save and restore after reload. This is
-;; done only if the function returns. As the split is done after reload,
-;; there are some situations in which we unnecessarily save and restore
-;; %r4. This happens when there is a single call and the PIC register
-;; is "dead" after the call. This isn't easy to fix as the usage of
-;; the PIC register isn't completely determined until the reload pass.
+ "#")
+
+;; Split out the PIC register save and restore after reload. As the
+;; split is done after reload, there are some situations in which we
+;; unnecessarily save and restore %r4. This happens when there is a
+;; single call and the PIC register is not used after the call.
+;;
+;; The split has to be done since call_from_call_insn () can't handle
+;; the pattern as is. Noreturn calls are special because they have to
+;; terminate the basic block. The split has to contain more than one
+;; insn.
(define_split
- [(parallel [(set (match_operand 0 "" "")
+ [(parallel [(set (match_operand:SI 2 "register_operand" "") (reg:SI 19))
+ (set (match_operand 0 "" "")
(call (mem:SI (reg:SI 22))
(match_operand 1 "" "")))
(clobber (reg:SI 1))
(clobber (reg:SI 2))
- (clobber (reg:SI 4))
+ (use (match_dup 2))
(use (reg:SI 19))
(use (const_int 1))])]
- "!TARGET_64BIT
- && reload_completed
- && !find_reg_note (insn, REG_NORETURN, NULL_RTX)"
- [(set (reg:SI 4) (reg:SI 19))
+ "!TARGET_64BIT && reload_completed
+ && find_reg_note (insn, REG_NORETURN, NULL_RTX)"
+ [(set (match_dup 2) (reg:SI 19))
(parallel [(set (match_dup 0)
(call (mem:SI (reg:SI 22))
(match_dup 1)))
(clobber (reg:SI 1))
(clobber (reg:SI 2))
(use (reg:SI 19))
- (use (const_int 1))])
- (set (reg:SI 19) (reg:SI 4))]
+ (use (const_int 1))])]
"")
-;; Remove the clobber of register 4 when optimizing. This has to be
-;; done with a peephole optimization rather than a split because the
-;; split sequence for a call must be longer than one instruction.
-(define_peephole2
- [(parallel [(set (match_operand 0 "" "")
+(define_split
+ [(parallel [(set (match_operand:SI 2 "register_operand" "") (reg:SI 19))
+ (set (match_operand 0 "" "")
(call (mem:SI (reg:SI 22))
(match_operand 1 "" "")))
(clobber (reg:SI 1))
(clobber (reg:SI 2))
- (clobber (reg:SI 4))
+ (use (match_dup 2))
(use (reg:SI 19))
(use (const_int 1))])]
"!TARGET_64BIT && reload_completed"
- [(parallel [(set (match_dup 0)
+ [(set (match_dup 2) (reg:SI 19))
+ (parallel [(set (match_dup 0)
(call (mem:SI (reg:SI 22))
(match_dup 1)))
(clobber (reg:SI 1))
(clobber (reg:SI 2))
(use (reg:SI 19))
- (use (const_int 1))])]
+ (use (const_int 1))])
+ (set (reg:SI 19) (match_dup 2))]
"")
(define_insn "*call_val_reg_pic_post_reload"
@@ -8513,79 +8502,81 @@ add,l %2,%3,%3\;bv,n %%r0(%3)"
;; This pattern is split if it is necessary to save and restore the
;; PIC register.
(define_insn "call_val_reg_64bit"
- [(set (match_operand 0 "" "")
+ [(set (match_operand:DI 3 "register_operand" "=&r") (reg:DI 27))
+ (set (match_operand 0 "" "")
(call (mem:SI (match_operand:DI 1 "register_operand" "r"))
(match_operand 2 "" "i")))
+ (clobber (reg:DI 1))
(clobber (reg:DI 2))
- (clobber (reg:DI 4))
+ (use (match_dup 3))
(use (reg:DI 27))
(use (reg:DI 29))
(use (const_int 1))]
"TARGET_64BIT"
- "*
-{
- return output_indirect_call (insn, operands[1]);
-}"
- [(set_attr "type" "dyncall")
- (set (attr "length")
- (plus (symbol_ref "attr_length_indirect_call (insn)")
- (symbol_ref "attr_length_save_restore_dltp (insn)")))])
-
-;; Split out the PIC register save and restore after reload. This is
-;; done only if the function returns. As the split is done after reload,
-;; there are some situations in which we unnecessarily save and restore
-;; %r4. This happens when there is a single call and the PIC register
-;; is "dead" after the call. This isn't easy to fix as the usage of
-;; the PIC register isn't completely determined until the reload pass.
+ "#")
+
+;; Split out the PIC register save and restore after reload. As the
+;; split is done after reload, there are some situations in which we
+;; unnecessarily save and restore %r4. This happens when there is a
+;; single call and the PIC register is not used after the call.
+;;
+;; The split has to be done since call_from_call_insn () can't handle
+;; the pattern as is. Noreturn calls are special because they have to
+;; terminate the basic block. The split has to contain more than one
+;; insn.
(define_split
- [(parallel [(set (match_operand 0 "" "")
+ [(parallel [(set (match_operand:DI 3 "register_operand" "") (reg:DI 27))
+ (set (match_operand 0 "" "")
(call (mem:SI (match_operand:DI 1 "register_operand" ""))
(match_operand 2 "" "")))
+ (clobber (reg:DI 1))
(clobber (reg:DI 2))
- (clobber (reg:DI 4))
+ (use (match_dup 3))
(use (reg:DI 27))
(use (reg:DI 29))
(use (const_int 1))])]
- "TARGET_64BIT
- && reload_completed
- && !find_reg_note (insn, REG_NORETURN, NULL_RTX)"
- [(set (reg:DI 4) (reg:DI 27))
+ "TARGET_64BIT && reload_completed
+ && find_reg_note (insn, REG_NORETURN, NULL_RTX)"
+ [(set (match_dup 3) (reg:DI 27))
(parallel [(set (match_dup 0)
(call (mem:SI (match_dup 1))
(match_dup 2)))
+ (clobber (reg:DI 1))
(clobber (reg:DI 2))
(use (reg:DI 27))
(use (reg:DI 29))
- (use (const_int 1))])
- (set (reg:DI 27) (reg:DI 4))]
+ (use (const_int 1))])]
"")
-;; Remove the clobber of register 4 when optimizing. This has to be
-;; done with a peephole optimization rather than a split because the
-;; split sequence for a call must be longer than one instruction.
-(define_peephole2
- [(parallel [(set (match_operand 0 "" "")
+(define_split
+ [(parallel [(set (match_operand:DI 3 "register_operand" "") (reg:DI 27))
+ (set (match_operand 0 "" "")
(call (mem:SI (match_operand:DI 1 "register_operand" ""))
(match_operand 2 "" "")))
+ (clobber (reg:DI 1))
(clobber (reg:DI 2))
- (clobber (reg:DI 4))
+ (use (match_dup 3))
(use (reg:DI 27))
(use (reg:DI 29))
(use (const_int 1))])]
"TARGET_64BIT && reload_completed"
- [(parallel [(set (match_dup 0)
+ [(set (match_dup 3) (reg:DI 27))
+ (parallel [(set (match_dup 0)
(call (mem:SI (match_dup 1))
(match_dup 2)))
+ (clobber (reg:DI 1))
(clobber (reg:DI 2))
(use (reg:DI 27))
(use (reg:DI 29))
- (use (const_int 1))])]
+ (use (const_int 1))])
+ (set (reg:DI 27) (match_dup 3))]
"")
(define_insn "*call_val_reg_64bit_post_reload"
[(set (match_operand 0 "" "")
(call (mem:SI (match_operand:DI 1 "register_operand" "r"))
(match_operand 2 "" "i")))
+ (clobber (reg:DI 1))
(clobber (reg:DI 2))
(use (reg:DI 27))
(use (reg:DI 29))