]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
Backport for mainline:
authorJohn David Anglin <dave.anglin@nrc-cnrc.gc.ca>
Thu, 6 Dec 2012 02:19:48 +0000 (02:19 +0000)
committerJohn David Anglin <danglin@gcc.gnu.org>
Thu, 6 Dec 2012 02:19:48 +0000 (02:19 +0000)
2011-11-30  John David Anglin  <dave.anglin@nrc-cnrc.gc.ca>

PR middle-end/50283
* config/pa/pa.md (in_branch_delay): Disallow frame related insns.
(in_nullified_branch_delay): Likewise.
(in_call_delay): Likewise.

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-12-05  John David Anglin  <dave.anglin@nrc-cnrc.gc.ca>

* config/pa/pa.md: Use "const_int 0" instead of match_test to simplify
opaque cond in all call insns.

From-SVN: r194238

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

index 600ebbcf4a8878856e6b3cc0a1af434124cdde5c..45e613e8ef851a276bf67234d386b19addd45447 100644 (file)
@@ -1,3 +1,36 @@
+2012-12-05  John David Anglin  <dave.anglin@nrc-cnrc.gc.ca>
+
+       Backport for mainline:
+       2011-11-30  John David Anglin  <dave.anglin@nrc-cnrc.gc.ca>
+
+       PR middle-end/50283
+       * config/pa/pa.md (in_branch_delay): Disallow frame related insns.
+       (in_nullified_branch_delay): Likewise.
+       (in_call_delay): Likewise.
+
+       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-12-05  John David Anglin  <dave.anglin@nrc-cnrc.gc.ca>
+
+       * config/pa/pa.md: Use "const_int 0" instead of match_test to simplify
+       opaque cond in all call insns.
+
 2012-12-03  Eric Botcazou  <ebotcazou@adacore.com>
 
        * config/ia64/ia64.c (ia64_compute_frame_size): Allocate the scratch
index 83e6e859e780599d3fe1ce5ee258d5daf780b643..8a4445fdcc14baa184e7aa1906db5ca4078ddbdc 100644 (file)
@@ -4955,12 +4955,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.  */
@@ -4969,19 +4966,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 = attr_length_millicode_call (insn);
+         break;
+       case TYPE_CALL:
+         length = attr_length_call (insn, 0);
+         break;
+       case TYPE_SIBCALL:
+         length = attr_length_call (insn, 1);
+         break;
+       case TYPE_DYNCALL:
+         length = attr_length_indirect_call (insn);
+         break;
+       case TYPE_SH_FUNC_ADRS:
+         length = 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
@@ -4990,7 +5008,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
@@ -4998,7 +5016,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))
     {
@@ -5007,11 +5025,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.  */
@@ -5021,11 +5039,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.  */
@@ -7573,15 +7589,13 @@ 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 e59cd5d45780286bd78707c266a2af1e36c2f00f..9c690b28bc03f9acd6f47cad088d78d5af276899 100644 (file)
@@ -1317,8 +1317,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 747613683b86ce79a39205c35e2a2f46b124cdee..7a032c8c07b9aed9e232b35c5fa2428f70633742 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.
 (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")
-                    (eq_attr "length" "4"))
+  (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")
+                    (eq (symbol_ref "RTX_FRAME_RELATED_P (insn)")
+                        (const_int 0)))
                (const_string "true")
                (const_string "false")))
 
 ;; 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")
-                    (eq_attr "length" "4"))
+  (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")
+                    (eq (symbol_ref "RTX_FRAME_RELATED_P (insn)")
+                        (const_int 0)))
                (const_string "true")
                (const_string "false")))
 
 ;; 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")
-             (eq_attr "length" "4"))
+  (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")
+             (eq (symbol_ref "RTX_FRAME_RELATED_P (insn)")
+                 (const_int 0)))
           (const_string "true")
         (eq_attr "type" "uncond_branch")
           (if_then_else (ne (symbol_ref "TARGET_JUMP_IN_DELAY")
 (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 output_mul_insn (0, insn);"
   [(set_attr "type" "milli")
-   (set (attr "length") (symbol_ref "attr_length_millicode_call (insn)"))])
+   (set (attr "length")
+       (cond [(and (const_int 0) (eq (const_int 0) (pc))) (const_int 8)]
+             (symbol_ref "attr_length_millicode_call (insn)")))])
 
 (define_insn ""
   [(set (reg:SI 29) (mult:SI (reg:SI 26) (reg:SI 25)))
   "TARGET_64BIT"
   "* return output_mul_insn (0, insn);"
   [(set_attr "type" "milli")
-   (set (attr "length") (symbol_ref "attr_length_millicode_call (insn)"))])
+   (set (attr "length")
+       (cond [(and (const_int 0) (eq (const_int 0) (pc))) (const_int 8)]
+             (symbol_ref "attr_length_millicode_call (insn)")))])
 
 (define_expand "muldi3"
   [(set (match_operand:DI 0 "register_operand" "")
   "*
    return output_div_insn (operands, 0, insn);"
   [(set_attr "type" "milli")
-   (set (attr "length") (symbol_ref "attr_length_millicode_call (insn)"))])
+   (set (attr "length")
+       (cond [(and (const_int 0) (eq (const_int 0) (pc))) (const_int 8)]
+             (symbol_ref "attr_length_millicode_call (insn)")))])
 
 (define_insn ""
   [(set (reg:SI 29)
   "*
    return output_div_insn (operands, 0, insn);"
   [(set_attr "type" "milli")
-   (set (attr "length") (symbol_ref "attr_length_millicode_call (insn)"))])
+   (set (attr "length")
+       (cond [(and (const_int 0) (eq (const_int 0) (pc))) (const_int 8)]
+             (symbol_ref "attr_length_millicode_call (insn)")))])
 
 (define_expand "udivsi3"
   [(set (reg:SI 26) (match_operand:SI 1 "move_src_operand" ""))
   "*
    return output_div_insn (operands, 1, insn);"
   [(set_attr "type" "milli")
-   (set (attr "length") (symbol_ref "attr_length_millicode_call (insn)"))])
+   (set (attr "length")
+       (cond [(and (const_int 0) (eq (const_int 0) (pc))) (const_int 8)]
+             (symbol_ref "attr_length_millicode_call (insn)")))])
 
 (define_insn ""
   [(set (reg:SI 29)
   "*
    return output_div_insn (operands, 1, insn);"
   [(set_attr "type" "milli")
-   (set (attr "length") (symbol_ref "attr_length_millicode_call (insn)"))])
+   (set (attr "length")
+       (cond [(and (const_int 0) (eq (const_int 0) (pc))) (const_int 8)]
+             (symbol_ref "attr_length_millicode_call (insn)")))])
 
 (define_expand "modsi3"
   [(set (reg:SI 26) (match_operand:SI 1 "move_src_operand" ""))
   "*
   return output_mod_insn (0, insn);"
   [(set_attr "type" "milli")
-   (set (attr "length") (symbol_ref "attr_length_millicode_call (insn)"))])
+   (set (attr "length")
+       (cond [(and (const_int 0) (eq (const_int 0) (pc))) (const_int 8)]
+             (symbol_ref "attr_length_millicode_call (insn)")))])
 
 (define_insn ""
   [(set (reg:SI 29) (mod:SI (reg:SI 26) (reg:SI 25)))
   "*
   return output_mod_insn (0, insn);"
   [(set_attr "type" "milli")
-   (set (attr "length") (symbol_ref "attr_length_millicode_call (insn)"))])
+   (set (attr "length")
+       (cond [(and (const_int 0) (eq (const_int 0) (pc))) (const_int 8)]
+             (symbol_ref "attr_length_millicode_call (insn)")))])
 
 (define_expand "umodsi3"
   [(set (reg:SI 26) (match_operand:SI 1 "move_src_operand" ""))
   "*
   return output_mod_insn (1, insn);"
   [(set_attr "type" "milli")
-   (set (attr "length") (symbol_ref "attr_length_millicode_call (insn)"))])
+   (set (attr "length")
+       (cond [(and (const_int 0) (eq (const_int 0) (pc))) (const_int 8)]
+             (symbol_ref "attr_length_millicode_call (insn)")))])
 
 (define_insn ""
   [(set (reg:SI 29) (umod:SI (reg:SI 26) (reg:SI 25)))
   "*
   return output_mod_insn (1, insn);"
   [(set_attr "type" "milli")
-   (set (attr "length") (symbol_ref "attr_length_millicode_call (insn)"))])
+   (set (attr "length")
+       (cond [(and (const_int 0) (eq (const_int 0) (pc))) (const_int 8)]
+             (symbol_ref "attr_length_millicode_call (insn)")))])
 
 ;;- and instructions
 ;; We define DImode `and` so with DImode `not` we can get
@@ -7188,7 +7218,9 @@ add,l %2,%3,%3\;bv,n %%r0(%3)"
   return output_call (insn, operands[0], 0);
 }"
   [(set_attr "type" "call")
-   (set (attr "length") (symbol_ref "attr_length_call (insn, 0)"))])
+   (set (attr "length")
+       (cond [(and (const_int 0) (eq (const_int 0) (pc))) (const_int 8)]
+             (symbol_ref "attr_length_call (insn, 0)")))])
 
 (define_insn "call_symref_pic"
   [(set (match_operand:SI 2 "register_operand" "=&r") (reg:SI 19))
@@ -7265,7 +7297,9 @@ add,l %2,%3,%3\;bv,n %%r0(%3)"
   return output_call (insn, operands[0], 0);
 }"
   [(set_attr "type" "call")
-   (set (attr "length") (symbol_ref "attr_length_call (insn, 0)"))])
+   (set (attr "length")
+       (cond [(and (const_int 0) (eq (const_int 0) (pc))) (const_int 8)]
+             (symbol_ref "attr_length_call (insn, 0)")))])
 
 ;; This pattern is split if it is necessary to save and restore the
 ;; PIC register.
@@ -7350,7 +7384,9 @@ add,l %2,%3,%3\;bv,n %%r0(%3)"
   return output_call (insn, operands[0], 0);
 }"
   [(set_attr "type" "call")
-   (set (attr "length") (symbol_ref "attr_length_call (insn, 0)"))])
+   (set (attr "length")
+       (cond [(and (const_int 0) (eq (const_int 0) (pc))) (const_int 8)]
+             (symbol_ref "attr_length_call (insn, 0)")))])
 
 (define_insn "call_reg"
   [(call (mem:SI (reg:SI 22))
@@ -7364,7 +7400,9 @@ add,l %2,%3,%3\;bv,n %%r0(%3)"
   return output_indirect_call (insn, gen_rtx_REG (word_mode, 22));
 }"
   [(set_attr "type" "dyncall")
-   (set (attr "length") (symbol_ref "attr_length_indirect_call (insn)"))])
+   (set (attr "length")
+       (cond [(and (const_int 0) (eq (const_int 0) (pc))) (const_int 8)]
+             (symbol_ref "attr_length_indirect_call (insn)")))])
 
 ;; This pattern is split if it is necessary to save and restore the
 ;; PIC register.
@@ -7442,7 +7480,9 @@ add,l %2,%3,%3\;bv,n %%r0(%3)"
   return output_indirect_call (insn, gen_rtx_REG (word_mode, 22));
 }"
   [(set_attr "type" "dyncall")
-   (set (attr "length") (symbol_ref "attr_length_indirect_call (insn)"))])
+   (set (attr "length")
+       (cond [(and (const_int 0) (eq (const_int 0) (pc))) (const_int 8)]
+             (symbol_ref "attr_length_indirect_call (insn)")))])
 
 ;; This pattern is split if it is necessary to save and restore the
 ;; PIC register.
@@ -7526,7 +7566,9 @@ add,l %2,%3,%3\;bv,n %%r0(%3)"
   return output_indirect_call (insn, operands[0]);
 }"
   [(set_attr "type" "dyncall")
-   (set (attr "length") (symbol_ref "attr_length_indirect_call (insn)"))])
+   (set (attr "length")
+       (cond [(and (const_int 0) (eq (const_int 0) (pc))) (const_int 12)]
+             (symbol_ref "attr_length_indirect_call (insn)")))])
 
 (define_expand "call_value"
   [(parallel [(set (match_operand 0 "" "")
@@ -7652,7 +7694,9 @@ add,l %2,%3,%3\;bv,n %%r0(%3)"
   return output_call (insn, operands[1], 0);
 }"
   [(set_attr "type" "call")
-   (set (attr "length") (symbol_ref "attr_length_call (insn, 0)"))])
+   (set (attr "length")
+       (cond [(and (const_int 0) (eq (const_int 0) (pc))) (const_int 8)]
+             (symbol_ref "attr_length_call (insn, 0)")))])
 
 (define_insn "call_val_symref_pic"
   [(set (match_operand:SI 3 "register_operand" "=&r") (reg:SI 19))
@@ -7735,7 +7779,9 @@ add,l %2,%3,%3\;bv,n %%r0(%3)"
   return output_call (insn, operands[1], 0);
 }"
   [(set_attr "type" "call")
-   (set (attr "length") (symbol_ref "attr_length_call (insn, 0)"))])
+   (set (attr "length")
+       (cond [(and (const_int 0) (eq (const_int 0) (pc))) (const_int 8)]
+             (symbol_ref "attr_length_call (insn, 0)")))])
 
 ;; This pattern is split if it is necessary to save and restore the
 ;; PIC register.
@@ -7826,7 +7872,9 @@ add,l %2,%3,%3\;bv,n %%r0(%3)"
   return output_call (insn, operands[1], 0);
 }"
   [(set_attr "type" "call")
-   (set (attr "length") (symbol_ref "attr_length_call (insn, 0)"))])
+   (set (attr "length")
+       (cond [(and (const_int 0) (eq (const_int 0) (pc))) (const_int 8)]
+             (symbol_ref "attr_length_call (insn, 0)")))])
 
 (define_insn "call_val_reg"
   [(set (match_operand 0 "" "")
@@ -7841,7 +7889,9 @@ add,l %2,%3,%3\;bv,n %%r0(%3)"
   return output_indirect_call (insn, gen_rtx_REG (word_mode, 22));
 }"
   [(set_attr "type" "dyncall")
-   (set (attr "length") (symbol_ref "attr_length_indirect_call (insn)"))])
+   (set (attr "length")
+       (cond [(and (const_int 0) (eq (const_int 0) (pc))) (const_int 8)]
+             (symbol_ref "attr_length_indirect_call (insn)")))])
 
 ;; This pattern is split if it is necessary to save and restore the
 ;; PIC register.
@@ -7925,7 +7975,9 @@ add,l %2,%3,%3\;bv,n %%r0(%3)"
   return output_indirect_call (insn, gen_rtx_REG (word_mode, 22));
 }"
   [(set_attr "type" "dyncall")
-   (set (attr "length") (symbol_ref "attr_length_indirect_call (insn)"))])
+   (set (attr "length")
+       (cond [(and (const_int 0) (eq (const_int 0) (pc))) (const_int 8)]
+             (symbol_ref "attr_length_indirect_call (insn)")))])
 
 ;; This pattern is split if it is necessary to save and restore the
 ;; PIC register.
@@ -8015,7 +8067,9 @@ add,l %2,%3,%3\;bv,n %%r0(%3)"
   return output_indirect_call (insn, operands[1]);
 }"
   [(set_attr "type" "dyncall")
-   (set (attr "length") (symbol_ref "attr_length_indirect_call (insn)"))])
+   (set (attr "length")
+       (cond [(and (const_int 0) (eq (const_int 0) (pc))) (const_int 12)]
+             (symbol_ref "attr_length_indirect_call (insn)")))])
 
 ;; Call subroutine returning any type.
 
@@ -8108,8 +8162,10 @@ add,l %2,%3,%3\;bv,n %%r0(%3)"
   output_arg_descriptor (insn);
   return output_call (insn, operands[0], 1);
 }"
-  [(set_attr "type" "call")
-   (set (attr "length") (symbol_ref "attr_length_call (insn, 1)"))])
+  [(set_attr "type" "sibcall")
+   (set (attr "length")
+       (cond [(and (const_int 0) (eq (const_int 0) (pc))) (const_int 8)]
+             (symbol_ref "attr_length_call (insn, 1)")))])
 
 (define_insn "sibcall_internal_symref_64bit"
   [(call (mem:SI (match_operand 0 "call_operand_address" ""))
@@ -8123,8 +8179,10 @@ add,l %2,%3,%3\;bv,n %%r0(%3)"
   output_arg_descriptor (insn);
   return output_call (insn, operands[0], 1);
 }"
-  [(set_attr "type" "call")
-   (set (attr "length") (symbol_ref "attr_length_call (insn, 1)"))])
+  [(set_attr "type" "sibcall")
+   (set (attr "length")
+       (cond [(and (const_int 0) (eq (const_int 0) (pc))) (const_int 8)]
+             (symbol_ref "attr_length_call (insn, 1)")))])
 
 (define_expand "sibcall_value"
   [(set (match_operand 0 "" "")
@@ -8192,8 +8250,10 @@ add,l %2,%3,%3\;bv,n %%r0(%3)"
   output_arg_descriptor (insn);
   return output_call (insn, operands[1], 1);
 }"
-  [(set_attr "type" "call")
-   (set (attr "length") (symbol_ref "attr_length_call (insn, 1)"))])
+  [(set_attr "type" "sibcall")
+   (set (attr "length")
+       (cond [(and (const_int 0) (eq (const_int 0) (pc))) (const_int 8)]
+             (symbol_ref "attr_length_call (insn, 1)")))])
 
 (define_insn "sibcall_value_internal_symref_64bit"
   [(set (match_operand 0 "" "")
@@ -8208,8 +8268,10 @@ add,l %2,%3,%3\;bv,n %%r0(%3)"
   output_arg_descriptor (insn);
   return output_call (insn, operands[1], 1);
 }"
-  [(set_attr "type" "call")
-   (set (attr "length") (symbol_ref "attr_length_call (insn, 1)"))])
+  [(set_attr "type" "sibcall")
+   (set (attr "length")
+       (cond [(and (const_int 0) (eq (const_int 0) (pc))) (const_int 8)]
+             (symbol_ref "attr_length_call (insn, 1)")))])
 
 (define_insn "nop"
   [(const_int 0)]
@@ -9245,10 +9307,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 "attr_length_millicode_call (insn)")
-             (const_int 20)))])
+       (cond [(and (const_int 0) (eq (const_int 0) (pc))) (const_int 28)]
+             (plus (symbol_ref "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