From e40375e0e23145c3140d375d3cf8f164800983ee Mon Sep 17 00:00:00 2001 From: John David Anglin Date: Sat, 11 Oct 2008 15:54:27 +0000 Subject: 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 --- gcc/config/pa/pa.c | 19 +- gcc/config/pa/pa.md | 551 ++++++++++++++++++++++++++-------------------------- 2 files changed, 284 insertions(+), 286 deletions(-) (limited to 'gcc/config/pa') 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)) -- cgit v1.1