From ab11fb42c35513a796626d9ddb70c8eaf4d4b037 Mon Sep 17 00:00:00 2001 From: John David Anglin Date: Tue, 13 Nov 2012 00:36:54 +0000 Subject: [PATCH] re PR target/55195 (shorten_branches generates incorrect forward branch distances) PR target/55195 * config/pa/pa.md (type): Add sibcall and sh_func_adrs insn types. (in_branch_delay): Don't allow sibcall or sh_func_adrs insns. (in_nullified_branch_delay): Likewise. (in_call_delay): Likewise. Define delay for sibcall insns. Adjust Z3 and Z4 insn reservations for new types. Add opaque cond to mark all calls, sibcalls, dyncalls and the $$sh_func_adrs call as variable. Update type of sibcalls and $$sh_func_adrs call. * config/pa/pa.c (pa_adjust_insn_length): Revise to return updated length instead of adjustment. Handle negative and undefined call adjustments for insn_default_length. Remove adjustment for millicode insn with unfilled delay slot. (pa_output_millicode_call): Update for revised millicode length. * config/pa/pa.h (ADJUST_INSN_LENGTH): Revise to set LENGTH. From-SVN: r193464 --- gcc/ChangeLog | 18 +++++++ gcc/config/pa/pa.c | 74 ++++++++++++++++------------ gcc/config/pa/pa.h | 4 +- gcc/config/pa/pa.md | 135 +++++++++++++++++++++++++++++++++++++--------------- 4 files changed, 160 insertions(+), 71 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 8f696b06caf..9cad8079d26 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,21 @@ +2012-11-12 John David Anglin + + PR target/55195 + * config/pa/pa.md (attr type): Add sibcall and sh_func_adrs insn types. + (in_branch_delay): Don't allow sibcall or sh_func_adrs insns. + (in_nullified_branch_delay): Likewise. + (in_call_delay): Likewise. + Define delay for sibcall insns. Adjust Z3 and Z4 insn reservations for + new types. Add opaque cond to mark all calls, sibcalls, dyncalls and + the $$sh_func_adrs call as variable. Update type of sibcalls and + $$sh_func_adrs call. + * config/pa/pa.c (pa_adjust_insn_length): Revise to return updated + length instead of adjustment. Handle negative and undefined call + adjustments for insn_default_length. Remove adjustment for millicode + insn with unfilled delay slot. + (pa_output_millicode_call): Update for revised millicode length. + * config/pa/pa.h (ADJUST_INSN_LENGTH): Revise to set LENGTH. + 2012-11-12 Eric Botcazou * tree-ssa-ccp.c (dump_lattice_value) : Fix duplication. diff --git a/gcc/config/pa/pa.c b/gcc/config/pa/pa.c index 6476daa0fc3..afcfd1a8d22 100644 --- a/gcc/config/pa/pa.c +++ b/gcc/config/pa/pa.c @@ -4880,12 +4880,9 @@ pa_issue_rate (void) -/* Return any length adjustment needed by INSN which already has its length - computed as LENGTH. Return zero if no adjustment is necessary. - - For the PA: function calls, millicode calls, and backwards short - conditional branches with unfilled delay slots need an adjustment by +1 - (to account for the NOP which will be inserted into the instruction stream). +/* Return any length plus adjustment needed by INSN which already has + its length computed as LENGTH. Return LENGTH if no adjustment is + necessary. Also compute the length of an inline block move here as it is too complicated to express as a length attribute in pa.md. */ @@ -4894,19 +4891,40 @@ pa_adjust_insn_length (rtx insn, int length) { rtx pat = PATTERN (insn); + /* If length is negative or undefined, provide initial length. */ + if ((unsigned int) length >= INT_MAX) + { + if (GET_CODE (pat) == SEQUENCE) + insn = XVECEXP (pat, 0, 0); + + switch (get_attr_type (insn)) + { + case TYPE_MILLI: + length = pa_attr_length_millicode_call (insn); + break; + case TYPE_CALL: + length = pa_attr_length_call (insn, 0); + break; + case TYPE_SIBCALL: + length = pa_attr_length_call (insn, 1); + break; + case TYPE_DYNCALL: + length = pa_attr_length_indirect_call (insn); + break; + case TYPE_SH_FUNC_ADRS: + length = pa_attr_length_millicode_call (insn) + 20; + break; + default: + gcc_unreachable (); + } + } + /* Jumps inside switch tables which have unfilled delay slots need adjustment. */ if (GET_CODE (insn) == JUMP_INSN && GET_CODE (pat) == PARALLEL && get_attr_type (insn) == TYPE_BTABLE_BRANCH) - return 4; - /* Millicode insn with an unfilled delay slot. */ - else if (GET_CODE (insn) == INSN - && GET_CODE (pat) != SEQUENCE - && GET_CODE (pat) != USE - && GET_CODE (pat) != CLOBBER - && get_attr_type (insn) == TYPE_MILLI) - return 4; + length += 4; /* Block move pattern. */ else if (GET_CODE (insn) == INSN && GET_CODE (pat) == PARALLEL @@ -4915,7 +4933,7 @@ pa_adjust_insn_length (rtx insn, int length) && GET_CODE (XEXP (XVECEXP (pat, 0, 0), 1)) == MEM && GET_MODE (XEXP (XVECEXP (pat, 0, 0), 0)) == BLKmode && GET_MODE (XEXP (XVECEXP (pat, 0, 0), 1)) == BLKmode) - return compute_movmem_length (insn) - 4; + length += compute_movmem_length (insn) - 4; /* Block clear pattern. */ else if (GET_CODE (insn) == INSN && GET_CODE (pat) == PARALLEL @@ -4923,7 +4941,7 @@ pa_adjust_insn_length (rtx insn, int length) && GET_CODE (XEXP (XVECEXP (pat, 0, 0), 0)) == MEM && XEXP (XVECEXP (pat, 0, 0), 1) == const0_rtx && GET_MODE (XEXP (XVECEXP (pat, 0, 0), 0)) == BLKmode) - return compute_clrmem_length (insn) - 4; + length += compute_clrmem_length (insn) - 4; /* Conditional branch with an unfilled delay slot. */ else if (GET_CODE (insn) == JUMP_INSN && ! simplejump_p (insn)) { @@ -4932,11 +4950,11 @@ pa_adjust_insn_length (rtx insn, int length) && length == 4 && JUMP_LABEL (insn) != NULL_RTX && ! forward_branch_p (insn)) - return 4; + length += 4; else if (GET_CODE (pat) == PARALLEL && get_attr_type (insn) == TYPE_PARALLEL_BRANCH && length == 4) - return 4; + length += 4; /* Adjust dbra insn with short backwards conditional branch with unfilled delay slot -- only for case where counter is in a general register register. */ @@ -4946,11 +4964,9 @@ pa_adjust_insn_length (rtx insn, int length) && ! FP_REG_P (XEXP (XVECEXP (pat, 0, 1), 0)) && length == 4 && ! forward_branch_p (insn)) - return 4; - else - return 0; + length += 4; } - return 0; + return length; } /* Implement the TARGET_PRINT_OPERAND_PUNCT_VALID_P hook. */ @@ -7511,15 +7527,13 @@ pa_output_millicode_call (rtx insn, rtx call_dest) /* Handle the common case where we are sure that the branch will reach the beginning of the $CODE$ subspace. The within reach - form of the $$sh_func_adrs call has a length of 28. Because - it has an attribute type of multi, it never has a nonzero - sequence length. The length of the $$sh_func_adrs is the same - as certain out of reach PIC calls to other routines. */ + form of the $$sh_func_adrs call has a length of 28. Because it + has an attribute type of sh_func_adrs, it never has a nonzero + sequence length (i.e., the delay slot is never filled). */ if (!TARGET_LONG_CALLS - && ((seq_length == 0 - && (attr_length == 12 - || (attr_length == 28 && get_attr_type (insn) == TYPE_MULTI))) - || (seq_length != 0 && attr_length == 8))) + && (attr_length == 8 + || (attr_length == 28 + && get_attr_type (insn) == TYPE_SH_FUNC_ADRS))) { output_asm_insn ("{bl|b,l} %0,%2", xoperands); } diff --git a/gcc/config/pa/pa.h b/gcc/config/pa/pa.h index 6bf126e8c12..89665c1cddc 100644 --- a/gcc/config/pa/pa.h +++ b/gcc/config/pa/pa.h @@ -1273,8 +1273,8 @@ do { \ /* Handling the special cases is going to get too complicated for a macro, just call `pa_adjust_insn_length' to do the real work. */ -#define ADJUST_INSN_LENGTH(INSN, LENGTH) \ - LENGTH += pa_adjust_insn_length (INSN, LENGTH); +#define ADJUST_INSN_LENGTH(INSN, LENGTH) \ + ((LENGTH) = pa_adjust_insn_length ((INSN), (LENGTH))) /* Millicode insns are actually function calls with some special constraints on arguments and register usage. diff --git a/gcc/config/pa/pa.md b/gcc/config/pa/pa.md index 80c40f5047a..705d336f3f0 100644 --- a/gcc/config/pa/pa.md +++ b/gcc/config/pa/pa.md @@ -81,7 +81,7 @@ ;; type "binary" insns have two input operands (1,2) and one output (0) (define_attr "type" - "move,unary,binary,shift,nullshift,compare,load,store,uncond_branch,btable_branch,branch,cbranch,fbranch,call,dyncall,fpload,fpstore,fpalu,fpcc,fpmulsgl,fpmuldbl,fpdivsgl,fpdivdbl,fpsqrtsgl,fpsqrtdbl,multi,milli,parallel_branch,fpstore_load,store_fpload" + "move,unary,binary,shift,nullshift,compare,load,store,uncond_branch,btable_branch,branch,cbranch,fbranch,call,sibcall,dyncall,fpload,fpstore,fpalu,fpcc,fpmulsgl,fpmuldbl,fpdivsgl,fpdivdbl,fpsqrtsgl,fpsqrtdbl,multi,milli,sh_func_adrs,parallel_branch,fpstore_load,store_fpload" (const_string "binary")) (define_attr "pa_combine_type" @@ -124,7 +124,7 @@ ;; For conditional branches. Frame related instructions are not allowed ;; because they confuse the unwind support. (define_attr "in_branch_delay" "false,true" - (if_then_else (and (eq_attr "type" "!uncond_branch,btable_branch,branch,cbranch,fbranch,call,dyncall,multi,milli,parallel_branch") + (if_then_else (and (eq_attr "type" "!uncond_branch,btable_branch,branch,cbranch,fbranch,call,sibcall,dyncall,multi,milli,sh_func_adrs,parallel_branch") (eq_attr "length" "4") (not (match_test "RTX_FRAME_RELATED_P (insn)"))) (const_string "true") @@ -133,7 +133,7 @@ ;; Disallow instructions which use the FPU since they will tie up the FPU ;; even if the instruction is nullified. (define_attr "in_nullified_branch_delay" "false,true" - (if_then_else (and (eq_attr "type" "!uncond_branch,btable_branch,branch,cbranch,fbranch,call,dyncall,multi,milli,fpcc,fpalu,fpmulsgl,fpmuldbl,fpdivsgl,fpdivdbl,fpsqrtsgl,fpsqrtdbl,parallel_branch") + (if_then_else (and (eq_attr "type" "!uncond_branch,btable_branch,branch,cbranch,fbranch,call,sibcall,dyncall,multi,milli,sh_func_adrs,fpcc,fpalu,fpmulsgl,fpmuldbl,fpdivsgl,fpdivdbl,fpsqrtsgl,fpsqrtdbl,parallel_branch") (eq_attr "length" "4") (not (match_test "RTX_FRAME_RELATED_P (insn)"))) (const_string "true") @@ -142,7 +142,7 @@ ;; For calls and millicode calls. Allow unconditional branches in the ;; delay slot. (define_attr "in_call_delay" "false,true" - (cond [(and (eq_attr "type" "!uncond_branch,btable_branch,branch,cbranch,fbranch,call,dyncall,multi,milli,parallel_branch") + (cond [(and (eq_attr "type" "!uncond_branch,btable_branch,branch,cbranch,fbranch,call,sibcall,dyncall,multi,milli,sh_func_adrs,parallel_branch") (eq_attr "length" "4") (not (match_test "RTX_FRAME_RELATED_P (insn)"))) (const_string "true") @@ -157,6 +157,10 @@ (define_delay (eq_attr "type" "call") [(eq_attr "in_call_delay" "true") (nil) (nil)]) +;; Sibcall delay slot description. +(define_delay (eq_attr "type" "sibcall") + [(eq_attr "in_call_delay" "true") (nil) (nil)]) + ;; Millicode call delay slot description. (define_delay (eq_attr "type" "milli") [(eq_attr "in_call_delay" "true") (nil) (nil)]) @@ -611,7 +615,7 @@ ;; to assume have zero latency. (define_insn_reservation "Z3" 0 (and - (eq_attr "type" "!load,fpload,store,fpstore,uncond_branch,btable_branch,branch,cbranch,fbranch,call,dyncall,multi,milli,parallel_branch,fpcc,fpalu,fpmulsgl,fpmuldbl,fpsqrtsgl,fpsqrtdbl,fpdivsgl,fpdivdbl,fpstore_load,store_fpload") + (eq_attr "type" "!load,fpload,store,fpstore,uncond_branch,btable_branch,branch,cbranch,fbranch,call,sibcall,dyncall,multi,milli,sh_func_adrs,parallel_branch,fpcc,fpalu,fpmulsgl,fpmuldbl,fpsqrtsgl,fpsqrtdbl,fpdivsgl,fpdivdbl,fpstore_load,store_fpload") (eq_attr "cpu" "8000")) "inm_8000,rnm_8000") @@ -619,7 +623,7 @@ ;; retirement unit. (define_insn_reservation "Z4" 0 (and - (eq_attr "type" "uncond_branch,btable_branch,branch,cbranch,fbranch,call,dyncall,multi,milli,parallel_branch") + (eq_attr "type" "uncond_branch,btable_branch,branch,cbranch,fbranch,call,sibcall,dyncall,multi,milli,sh_func_adrs,parallel_branch") (eq_attr "cpu" "8000")) "inm0_8000+inm1_8000,rnm0_8000+rnm1_8000") @@ -5336,7 +5340,9 @@ "!TARGET_64BIT" "* return pa_output_mul_insn (0, insn);" [(set_attr "type" "milli") - (set (attr "length") (symbol_ref "pa_attr_length_millicode_call (insn)"))]) + (set (attr "length") + (cond [(and (match_test "0") (eq (const_int 0) (pc))) (const_int 8)] + (symbol_ref "pa_attr_length_millicode_call (insn)")))]) (define_insn "" [(set (reg:SI 29) (mult:SI (reg:SI 26) (reg:SI 25))) @@ -5347,7 +5353,9 @@ "TARGET_64BIT" "* return pa_output_mul_insn (0, insn);" [(set_attr "type" "milli") - (set (attr "length") (symbol_ref "pa_attr_length_millicode_call (insn)"))]) + (set (attr "length") + (cond [(and (match_test "0") (eq (const_int 0) (pc))) (const_int 8)] + (symbol_ref "pa_attr_length_millicode_call (insn)")))]) (define_expand "muldi3" [(set (match_operand:DI 0 "register_operand" "") @@ -5438,7 +5446,9 @@ "* return pa_output_div_insn (operands, 0, insn);" [(set_attr "type" "milli") - (set (attr "length") (symbol_ref "pa_attr_length_millicode_call (insn)"))]) + (set (attr "length") + (cond [(and (match_test "0") (eq (const_int 0) (pc))) (const_int 8)] + (symbol_ref "pa_attr_length_millicode_call (insn)")))]) (define_insn "" [(set (reg:SI 29) @@ -5452,7 +5462,9 @@ "* return pa_output_div_insn (operands, 0, insn);" [(set_attr "type" "milli") - (set (attr "length") (symbol_ref "pa_attr_length_millicode_call (insn)"))]) + (set (attr "length") + (cond [(and (match_test "0") (eq (const_int 0) (pc))) (const_int 8)] + (symbol_ref "pa_attr_length_millicode_call (insn)")))]) (define_expand "udivsi3" [(set (reg:SI 26) (match_operand:SI 1 "move_src_operand" "")) @@ -5495,7 +5507,9 @@ "* return pa_output_div_insn (operands, 1, insn);" [(set_attr "type" "milli") - (set (attr "length") (symbol_ref "pa_attr_length_millicode_call (insn)"))]) + (set (attr "length") + (cond [(and (match_test "0") (eq (const_int 0) (pc))) (const_int 8)] + (symbol_ref "pa_attr_length_millicode_call (insn)")))]) (define_insn "" [(set (reg:SI 29) @@ -5509,7 +5523,9 @@ "* return pa_output_div_insn (operands, 1, insn);" [(set_attr "type" "milli") - (set (attr "length") (symbol_ref "pa_attr_length_millicode_call (insn)"))]) + (set (attr "length") + (cond [(and (match_test "0") (eq (const_int 0) (pc))) (const_int 8)] + (symbol_ref "pa_attr_length_millicode_call (insn)")))]) (define_expand "modsi3" [(set (reg:SI 26) (match_operand:SI 1 "move_src_operand" "")) @@ -5548,7 +5564,9 @@ "* return pa_output_mod_insn (0, insn);" [(set_attr "type" "milli") - (set (attr "length") (symbol_ref "pa_attr_length_millicode_call (insn)"))]) + (set (attr "length") + (cond [(and (match_test "0") (eq (const_int 0) (pc))) (const_int 8)] + (symbol_ref "pa_attr_length_millicode_call (insn)")))]) (define_insn "" [(set (reg:SI 29) (mod:SI (reg:SI 26) (reg:SI 25))) @@ -5561,7 +5579,9 @@ "* return pa_output_mod_insn (0, insn);" [(set_attr "type" "milli") - (set (attr "length") (symbol_ref "pa_attr_length_millicode_call (insn)"))]) + (set (attr "length") + (cond [(and (match_test "0") (eq (const_int 0) (pc))) (const_int 8)] + (symbol_ref "pa_attr_length_millicode_call (insn)")))]) (define_expand "umodsi3" [(set (reg:SI 26) (match_operand:SI 1 "move_src_operand" "")) @@ -5600,7 +5620,9 @@ "* return pa_output_mod_insn (1, insn);" [(set_attr "type" "milli") - (set (attr "length") (symbol_ref "pa_attr_length_millicode_call (insn)"))]) + (set (attr "length") + (cond [(and (match_test "0") (eq (const_int 0) (pc))) (const_int 8)] + (symbol_ref "pa_attr_length_millicode_call (insn)")))]) (define_insn "" [(set (reg:SI 29) (umod:SI (reg:SI 26) (reg:SI 25))) @@ -5613,7 +5635,9 @@ "* return pa_output_mod_insn (1, insn);" [(set_attr "type" "milli") - (set (attr "length") (symbol_ref "pa_attr_length_millicode_call (insn)"))]) + (set (attr "length") + (cond [(and (match_test "0") (eq (const_int 0) (pc))) (const_int 8)] + (symbol_ref "pa_attr_length_millicode_call (insn)")))]) ;;- and instructions ;; We define DImode `and` so with DImode `not` we can get @@ -7141,7 +7165,9 @@ add,l %2,%3,%3\;bv,n %%r0(%3)" return pa_output_call (insn, operands[0], 0); }" [(set_attr "type" "call") - (set (attr "length") (symbol_ref "pa_attr_length_call (insn, 0)"))]) + (set (attr "length") + (cond [(and (match_test "0") (eq (const_int 0) (pc))) (const_int 8)] + (symbol_ref "pa_attr_length_call (insn, 0)")))]) (define_insn "call_symref_pic" [(call (mem:SI (match_operand 0 "call_operand_address" "")) @@ -7215,7 +7241,9 @@ add,l %2,%3,%3\;bv,n %%r0(%3)" return pa_output_call (insn, operands[0], 0); }" [(set_attr "type" "call") - (set (attr "length") (symbol_ref "pa_attr_length_call (insn, 0)"))]) + (set (attr "length") + (cond [(and (match_test "0") (eq (const_int 0) (pc))) (const_int 8)] + (symbol_ref "pa_attr_length_call (insn, 0)")))]) ;; This pattern is split if it is necessary to save and restore the ;; PIC register. @@ -7297,7 +7325,9 @@ add,l %2,%3,%3\;bv,n %%r0(%3)" return pa_output_call (insn, operands[0], 0); }" [(set_attr "type" "call") - (set (attr "length") (symbol_ref "pa_attr_length_call (insn, 0)"))]) + (set (attr "length") + (cond [(and (match_test "0") (eq (const_int 0) (pc))) (const_int 8)] + (symbol_ref "pa_attr_length_call (insn, 0)")))]) (define_insn "call_reg" [(call (mem:SI (reg:SI 22)) @@ -7311,7 +7341,9 @@ add,l %2,%3,%3\;bv,n %%r0(%3)" return pa_output_indirect_call (insn, gen_rtx_REG (word_mode, 22)); }" [(set_attr "type" "dyncall") - (set (attr "length") (symbol_ref "pa_attr_length_indirect_call (insn)"))]) + (set (attr "length") + (cond [(and (match_test "0") (eq (const_int 0) (pc))) (const_int 8)] + (symbol_ref "pa_attr_length_indirect_call (insn)")))]) ;; This pattern is split if it is necessary to save and restore the ;; PIC register. @@ -7386,7 +7418,9 @@ add,l %2,%3,%3\;bv,n %%r0(%3)" return pa_output_indirect_call (insn, gen_rtx_REG (word_mode, 22)); }" [(set_attr "type" "dyncall") - (set (attr "length") (symbol_ref "pa_attr_length_indirect_call (insn)"))]) + (set (attr "length") + (cond [(and (match_test "0") (eq (const_int 0) (pc))) (const_int 8)] + (symbol_ref "pa_attr_length_indirect_call (insn)")))]) ;; This pattern is split if it is necessary to save and restore the ;; PIC register. @@ -7467,7 +7501,9 @@ add,l %2,%3,%3\;bv,n %%r0(%3)" return pa_output_indirect_call (insn, operands[0]); }" [(set_attr "type" "dyncall") - (set (attr "length") (symbol_ref "pa_attr_length_indirect_call (insn)"))]) + (set (attr "length") + (cond [(and (match_test "0") (eq (const_int 0) (pc))) (const_int 12)] + (symbol_ref "pa_attr_length_indirect_call (insn)")))]) (define_expand "call_value" [(parallel [(set (match_operand 0 "" "") @@ -7593,7 +7629,9 @@ add,l %2,%3,%3\;bv,n %%r0(%3)" return pa_output_call (insn, operands[1], 0); }" [(set_attr "type" "call") - (set (attr "length") (symbol_ref "pa_attr_length_call (insn, 0)"))]) + (set (attr "length") + (cond [(and (match_test "0") (eq (const_int 0) (pc))) (const_int 8)] + (symbol_ref "pa_attr_length_call (insn, 0)")))]) (define_insn "call_val_symref_pic" [(set (match_operand 0 "" "") @@ -7673,7 +7711,9 @@ add,l %2,%3,%3\;bv,n %%r0(%3)" return pa_output_call (insn, operands[1], 0); }" [(set_attr "type" "call") - (set (attr "length") (symbol_ref "pa_attr_length_call (insn, 0)"))]) + (set (attr "length") + (cond [(and (match_test "0") (eq (const_int 0) (pc))) (const_int 8)] + (symbol_ref "pa_attr_length_call (insn, 0)")))]) ;; This pattern is split if it is necessary to save and restore the ;; PIC register. @@ -7761,7 +7801,9 @@ add,l %2,%3,%3\;bv,n %%r0(%3)" return pa_output_call (insn, operands[1], 0); }" [(set_attr "type" "call") - (set (attr "length") (symbol_ref "pa_attr_length_call (insn, 0)"))]) + (set (attr "length") + (cond [(and (match_test "0") (eq (const_int 0) (pc))) (const_int 8)] + (symbol_ref "pa_attr_length_call (insn, 0)")))]) (define_insn "call_val_reg" [(set (match_operand 0 "" "") @@ -7776,7 +7818,9 @@ add,l %2,%3,%3\;bv,n %%r0(%3)" return pa_output_indirect_call (insn, gen_rtx_REG (word_mode, 22)); }" [(set_attr "type" "dyncall") - (set (attr "length") (symbol_ref "pa_attr_length_indirect_call (insn)"))]) + (set (attr "length") + (cond [(and (match_test "0") (eq (const_int 0) (pc))) (const_int 8)] + (symbol_ref "pa_attr_length_indirect_call (insn)")))]) ;; This pattern is split if it is necessary to save and restore the ;; PIC register. @@ -7857,7 +7901,9 @@ add,l %2,%3,%3\;bv,n %%r0(%3)" return pa_output_indirect_call (insn, gen_rtx_REG (word_mode, 22)); }" [(set_attr "type" "dyncall") - (set (attr "length") (symbol_ref "pa_attr_length_indirect_call (insn)"))]) + (set (attr "length") + (cond [(and (match_test "0") (eq (const_int 0) (pc))) (const_int 8)] + (symbol_ref "pa_attr_length_indirect_call (insn)")))]) ;; This pattern is split if it is necessary to save and restore the ;; PIC register. @@ -7944,7 +7990,9 @@ add,l %2,%3,%3\;bv,n %%r0(%3)" return pa_output_indirect_call (insn, operands[1]); }" [(set_attr "type" "dyncall") - (set (attr "length") (symbol_ref "pa_attr_length_indirect_call (insn)"))]) + (set (attr "length") + (cond [(and (match_test "0") (eq (const_int 0) (pc))) (const_int 12)] + (symbol_ref "pa_attr_length_indirect_call (insn)")))]) ;; Call subroutine returning any type. @@ -8037,8 +8085,10 @@ add,l %2,%3,%3\;bv,n %%r0(%3)" pa_output_arg_descriptor (insn); return pa_output_call (insn, operands[0], 1); }" - [(set_attr "type" "call") - (set (attr "length") (symbol_ref "pa_attr_length_call (insn, 1)"))]) + [(set_attr "type" "sibcall") + (set (attr "length") + (cond [(and (match_test "0") (eq (const_int 0) (pc))) (const_int 8)] + (symbol_ref "pa_attr_length_call (insn, 1)")))]) (define_insn "sibcall_internal_symref_64bit" [(call (mem:SI (match_operand 0 "call_operand_address" "")) @@ -8052,8 +8102,10 @@ add,l %2,%3,%3\;bv,n %%r0(%3)" pa_output_arg_descriptor (insn); return pa_output_call (insn, operands[0], 1); }" - [(set_attr "type" "call") - (set (attr "length") (symbol_ref "pa_attr_length_call (insn, 1)"))]) + [(set_attr "type" "sibcall") + (set (attr "length") + (cond [(and (match_test "0") (eq (const_int 0) (pc))) (const_int 8)] + (symbol_ref "pa_attr_length_call (insn, 1)")))]) (define_expand "sibcall_value" [(set (match_operand 0 "" "") @@ -8121,8 +8173,10 @@ add,l %2,%3,%3\;bv,n %%r0(%3)" pa_output_arg_descriptor (insn); return pa_output_call (insn, operands[1], 1); }" - [(set_attr "type" "call") - (set (attr "length") (symbol_ref "pa_attr_length_call (insn, 1)"))]) + [(set_attr "type" "sibcall") + (set (attr "length") + (cond [(and (match_test "0") (eq (const_int 0) (pc))) (const_int 8)] + (symbol_ref "pa_attr_length_call (insn, 1)")))]) (define_insn "sibcall_value_internal_symref_64bit" [(set (match_operand 0 "" "") @@ -8137,8 +8191,10 @@ add,l %2,%3,%3\;bv,n %%r0(%3)" pa_output_arg_descriptor (insn); return pa_output_call (insn, operands[1], 1); }" - [(set_attr "type" "call") - (set (attr "length") (symbol_ref "pa_attr_length_call (insn, 1)"))]) + [(set_attr "type" "sibcall") + (set (attr "length") + (cond [(and (match_test "0") (eq (const_int 0) (pc))) (const_int 8)] + (symbol_ref "pa_attr_length_call (insn, 1)")))]) (define_insn "nop" [(const_int 0)] @@ -9174,10 +9230,11 @@ add,l %2,%3,%3\;bv,n %%r0(%3)" gen_rtx_SYMBOL_REF (SImode, \"$$sh_func_adrs\")); }" - [(set_attr "type" "multi") + [(set_attr "type" "sh_func_adrs") (set (attr "length") - (plus (symbol_ref "pa_attr_length_millicode_call (insn)") - (const_int 20)))]) + (cond [(and (match_test "0") (eq (const_int 0) (pc))) (const_int 28)] + (plus (symbol_ref "pa_attr_length_millicode_call (insn)") + (const_int 20))))]) ;; On the PA, the PIC register is call clobbered, so it must ;; be saved & restored around calls by the caller. If the call -- 2.11.4.GIT