OSDN Git Service

Backport from mainline:
authordanglin <danglin@138bc75d-0d04-0410-961f-82ee72b054a4>
Sat, 1 Dec 2012 20:36:04 +0000 (20:36 +0000)
committerdanglin <danglin@138bc75d-0d04-0410-961f-82ee72b054a4>
Sat, 1 Dec 2012 20:36:04 +0000 (20:36 +0000)
2012-11-12  John David Anglin  <dave.anglin@nrc-cnrc.gc.ca>

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.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/branches/gcc-4_7-branch@194027 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/ChangeLog
gcc/config/pa/pa.c
gcc/config/pa/pa.h
gcc/config/pa/pa.md

index ce22b08..3c27095 100644 (file)
@@ -1,3 +1,24 @@
+2012-12-01  John David Anglin  <dave.anglin@nrc-cnrc.gc.ca>
+
+       Backport from mainline:
+       2012-11-12  John David Anglin  <dave.anglin@nrc-cnrc.gc.ca>
+
+       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.
+
 2012-11-29  Kai Tietz  <ktietz@redhat.com>
 
        PR target/55171
index 509e37f..1a87adc 100644 (file)
@@ -4851,12 +4851,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.  */
@@ -4865,19 +4862,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
@@ -4886,7 +4904,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
@@ -4894,7 +4912,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))
     {
@@ -4903,11 +4921,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.  */
@@ -4917,11 +4935,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.  */
@@ -7481,15 +7497,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);
     }
index d977c64..7a1a6fa 100644 (file)
@@ -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.
index 057eef0..570245b 100644 (file)
@@ -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"
 ;; 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")
 ;; 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")
 ;; 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")
 (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)])
 ;; 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")
 
 ;; 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")
 
   "!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)))
   "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" "")
   "*
    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)
   "*
    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" ""))
   "*
    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)
   "*
    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" ""))
   "*
   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)))
   "*
   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" ""))
   "*
   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)))
   "*
   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
@@ -7189,7 +7213,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"
   [(set (match_operand:SI 2 "register_operand" "=&r") (reg:SI 19))
@@ -7266,7 +7292,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.
@@ -7351,7 +7379,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))
@@ -7365,7 +7395,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.
@@ -7443,7 +7475,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.
@@ -7527,7 +7561,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 "" "")
@@ -7653,7 +7689,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:SI 3 "register_operand" "=&r") (reg:SI 19))
@@ -7736,7 +7774,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.
@@ -7827,7 +7867,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 "" "")
@@ -7842,7 +7884,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.
@@ -7926,7 +7970,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.
@@ -8016,7 +8062,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.
 
@@ -8109,8 +8157,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" ""))
@@ -8124,8 +8174,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 "" "")
@@ -8193,8 +8245,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 "" "")
@@ -8209,8 +8263,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)]
@@ -9246,10 +9302,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