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
This commit is contained in:
John David Anglin 2008-10-11 15:54:27 +00:00 committed by John David Anglin
parent e47911ce21
commit e40375e0e2
3 changed files with 365 additions and 354 deletions

View File

@ -1,3 +1,16 @@
2008-10-11 John David Anglin <dave.anglin@nrc-cnrc.gc.ca>
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.
2008-10-11 David Edelsohn <edelsohn@gnu.org>
* config/rs6000/rs6000.md (aux_truncdfsf2): Remove TARGET_SINGLE_FLOAT.

View File

@ -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);

View File

@ -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))])]
"")
(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))
(use (match_dup 2))
(use (reg:SI 19))
(use (const_int 0))])]
"!TARGET_PORTABLE_RUNTIME && !TARGET_64BIT && reload_completed"
[(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))]
"")
;; 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" ""))
(match_operand 1 "" ""))
(clobber (reg:SI 1))
(clobber (reg:SI 2))
(clobber (reg:SI 4))
(use (reg:SI 19))
(use (const_int 0))])]
"!TARGET_PORTABLE_RUNTIME && !TARGET_64BIT && reload_completed"
[(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) (match_dup 2))]
"")
(define_insn "*call_symref_pic_post_reload"
@ -7838,44 +7839,61 @@ 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))])]
"")
(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))
(use (match_dup 2))
(use (reg:DI 27))
(use (reg:DI 29))
(use (const_int 0))])]
"TARGET_64BIT && reload_completed"
[(set (match_dup 2) (reg:DI 27))
(parallel [(call (mem:SI (match_dup 0))
(match_dup 1))
(clobber (reg:DI 1))
@ -7883,29 +7901,7 @@ add,l %2,%3,%3\;bv,n %%r0(%3)"
(use (reg:DI 27))
(use (reg:DI 29))
(use (const_int 0))])
(set (reg:DI 27) (reg:DI 4))]
"")
;; 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" ""))
(match_operand 1 "" ""))
(clobber (reg:DI 1))
(clobber (reg:DI 2))
(clobber (reg:DI 4))
(use (reg:DI 27))
(use (reg:DI 29))
(use (const_int 0))])]
"TARGET_64BIT && reload_completed"
[(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) (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))])]
"")
(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))
(use (match_dup 1))
(use (reg:SI 19))
(use (const_int 1))])]
"!TARGET_64BIT && reload_completed"
[(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))]
"")
;; 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))
(match_operand 0 "" ""))
(clobber (reg:SI 1))
(clobber (reg:SI 2))
(clobber (reg:SI 4))
(use (reg:SI 19))
(use (const_int 1))])]
"!TARGET_64BIT && reload_completed"
[(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) (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,44 +8227,61 @@ 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))])]
"")
(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))
(use (match_dup 3))
(use (reg:SI 19))
(use (const_int 0))])]
"!TARGET_PORTABLE_RUNTIME && !TARGET_64BIT && reload_completed"
[(set (match_dup 3) (reg:SI 19))
(parallel [(set (match_dup 0)
(call (mem:SI (match_dup 1))
(match_dup 2)))
@ -8269,29 +8289,7 @@ add,l %2,%3,%3\;bv,n %%r0(%3)"
(clobber (reg:SI 2))
(use (reg:SI 19))
(use (const_int 0))])
(set (reg:SI 19) (reg:SI 4))]
"")
;; 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 "" "")
(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 (reg:SI 19))
(use (const_int 0))])]
"!TARGET_PORTABLE_RUNTIME && !TARGET_64BIT && reload_completed"
[(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) (match_dup 3))]
"")
(define_insn "*call_val_symref_pic_post_reload"
@ -8314,46 +8312,65 @@ 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)))
(clobber (reg:DI 1))
(clobber (reg:DI 2))
(use (reg:DI 27))
(use (reg:DI 29))
(use (const_int 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))
(use (match_dup 3))
(use (reg:DI 27))
(use (reg:DI 29))
(use (const_int 0))])]
"TARGET_64BIT && reload_completed"
[(set (match_dup 3) (reg:DI 27))
(parallel [(set (match_dup 0)
(call (mem:SI (match_dup 1))
(match_dup 2)))
@ -8362,31 +8379,7 @@ add,l %2,%3,%3\;bv,n %%r0(%3)"
(use (reg:DI 27))
(use (reg:DI 29))
(use (const_int 0))])
(set (reg:DI 27) (reg:DI 4))]
"")
;; 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 "" "")
(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 (reg:DI 27))
(use (reg:DI 29))
(use (const_int 0))])]
"TARGET_64BIT && reload_completed"
[(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))])]
(set (reg:DI 27) (match_dup 3))]
"")
(define_insn "*call_val_symref_64bit_post_reload"
@ -8425,43 +8418,61 @@ 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))])]
"")
(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))
(use (match_dup 2))
(use (reg:SI 19))
(use (const_int 1))])]
"!TARGET_64BIT && reload_completed"
[(set (match_dup 2) (reg:SI 19))
(parallel [(set (match_dup 0)
(call (mem:SI (reg:SI 22))
(match_dup 1)))
@ -8469,29 +8480,7 @@ add,l %2,%3,%3\;bv,n %%r0(%3)"
(clobber (reg:SI 2))
(use (reg:SI 19))
(use (const_int 1))])
(set (reg:SI 19) (reg:SI 4))]
"")
;; 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 "" "")
(call (mem:SI (reg:SI 22))
(match_operand 1 "" "")))
(clobber (reg:SI 1))
(clobber (reg:SI 2))
(clobber (reg:SI 4))
(use (reg:SI 19))
(use (const_int 1))])]
"!TARGET_64BIT && reload_completed"
[(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) (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))