pa.h (enum processor_type): New enumeration describing the processor to schedule...
authorJeff Law <law@gcc.gnu.org>
Sat, 7 Jan 1995 07:59:42 +0000 (00:59 -0700)
committerJeff Law <law@gcc.gnu.org>
Sat, 7 Jan 1995 07:59:42 +0000 (00:59 -0700)
* pa.h (enum processor_type): New enumeration describing the
processor to schedule for (700, 7100, 7100LC).
(pa_cpu_attr, TARGET_OPTIONS, OVERRIDE_OPTIONS): Define.
(pa_cpu_string, pa_cpu): Provide extern decls.
* pa.c (pa_cpu, pa_cpu_string): Provide definitions.
(override_options): New function.
(pa_adjust_cost): Handle PROCESSOR_7100 and PROCESSOR_7100LC
scheduling.  Handle anti-dependendy cases involving fp division
and sqrt.  Handle output dependencies correctly.  Break TYPE_FPMUL
into TYPE_FPMULSGL and TYPE_FPMULDBL.
* pa.md (cpu attribute): New attribute.
Clean up comments for PROCESSOR_700 scheduling info.  Slightly
simplify.  Make conditional on PROCESSOR_700.
Add comments and scheduling information for PROCESSOR_7100 and
PROCESSOR_7100LC.  Set types for instructions which use the shifter
to "shift".  Explicitly set lengths and types for all instructions.
Break type "fpmul" into "fmulsgl" and "fpmuldbl".

From-SVN: r8723

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

index 50e1a3e..2d2eb12 100644 (file)
@@ -41,6 +41,12 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
 rtx hppa_compare_op0, hppa_compare_op1;
 enum cmp_type hppa_branch_type;
 
+/* Which cpu we are scheduling for.  */
+enum processor_type pa_cpu;
+
+/* String to hold which cpu we are scheduling for.  */
+char *pa_cpu_string;
+
 rtx hppa_save_pic_table_rtx;
 
 /* Set by the FUNCTION_PROFILER macro. */
@@ -57,6 +63,34 @@ static rtx find_addr_reg ();
 
 unsigned int total_code_bytes;
 
+void
+override_options ()
+{
+  /* Default to 700 scheduling which is reasonable for older 800 processors
+     correct for the 700s, and not too bad for the 7100s and 7100LCs.  */
+  if (pa_cpu_string == NULL
+      || ! strcmp (pa_cpu_string, "700"))
+    {
+      pa_cpu_string = "700";
+      pa_cpu = PROCESSOR_700;
+    }
+  else if (! strcmp (pa_cpu_string, "7100"))
+    {
+      pa_cpu_string = "7100";
+      pa_cpu = PROCESSOR_7100;
+    }
+  else if (! strncmp (pa_cpu_string, "7100LC"))
+    {
+      pa_cpu_string = "7100LC";
+      pa_cpu = PROCESSOR_7100LC;
+    }
+  else
+    {
+      warning ("Unknown -mschedule= option (%s).\nValid options are 700, 7100 and 7100LC\n", pa_cpu_string);
+    }
+}
+
+
 /* Return non-zero only if OP is a register of mode MODE,
    or CONST0_RTX.  */
 int
@@ -2498,18 +2532,20 @@ pa_adjust_cost (insn, link, dep_insn, cost)
              switch (get_attr_type (dep_insn))
                {
                case TYPE_FPLOAD:
-                 /* This cost 3 cycles, not 2 as the md says.  */
-                 return cost + 1;
+                 /* This cost 3 cycles, not 2 as the md says for the
+                    700 and 7100.  Note scaling of cost for 7100.  */
+                 return cost + (pa_cpu_attr == PROCESSOR_700) ? 1 : 2;
 
                case TYPE_FPALU:
-               case TYPE_FPMUL:
+               case TYPE_FPMULSGL:
+               case TYPE_FPMULDBL:
                case TYPE_FPDIVSGL:
                case TYPE_FPDIVDBL:
                case TYPE_FPSQRTSGL:
                case TYPE_FPSQRTDBL:
                  /* In these important cases, we save one cycle compared to
                     when flop instruction feed each other.  */
-                 return cost - 1;
+                 return cost - (pa_cpu_attr == PROCESSOR_700) ? 1 : 2;
 
                default:
                  return cost;
@@ -2547,16 +2583,52 @@ pa_adjust_cost (insn, link, dep_insn, cost)
              switch (get_attr_type (dep_insn))
                {
                case TYPE_FPALU:
-               case TYPE_FPMUL:
+               case TYPE_FPMULSGL:
+               case TYPE_FPMULDBL:
                case TYPE_FPDIVSGL:
                case TYPE_FPDIVDBL:
                case TYPE_FPSQRTSGL:
                case TYPE_FPSQRTDBL:
                  /* A fpload can't be issued until one cycle before a
-                    preceeding arithmetic operation has finished, if
+                    preceeding arithmetic operation has finished if
                     the target of the fpload is any of the sources
                     (or destination) of the arithmetic operation.  */
-                 return cost - 1;
+                 return cost - (pa_cpu_attr == PROCESSOR_700) ? 1 : 2;
+
+               default:
+                 return 0;
+               }
+           }
+       }
+      else if (get_attr_type (insn) == TYPE_FPALU)
+       {
+         rtx pat = PATTERN (insn);
+         rtx dep_pat = PATTERN (dep_insn);
+         if (GET_CODE (pat) == PARALLEL)
+           {
+             /* This happens for the fldXs,mb patterns.  */
+             pat = XVECEXP (pat, 0, 0);
+           }
+         if (GET_CODE (pat) != SET || GET_CODE (dep_pat) != SET)
+           /* If this happens, we have to extend this to schedule
+              optimally.  Return 0 for now.  */
+         return 0;
+
+         if (reg_mentioned_p (SET_DEST (pat), SET_SRC (dep_pat)))
+           {
+             if (! recog_memoized (dep_insn))
+               return 0;
+             switch (get_attr_type (dep_insn))
+               {
+               case TYPE_FPDIVSGL:
+               case TYPE_FPDIVDBL:
+               case TYPE_FPSQRTSGL:
+               case TYPE_FPSQRTDBL:
+                 /* An ALU flop can't be issued until two cycles before a
+                    preceeding divide or sqrt operation has finished if
+                    the target of the ALU flop is any of the sources
+                    (or destination) of the divide or sqrt operation.  */
+                 return cost - (pa_cpu_attr == PROCESSOR_700) ? 2 : 4;
 
                default:
                  return 0;
@@ -2567,9 +2639,89 @@ pa_adjust_cost (insn, link, dep_insn, cost)
       /* For other anti dependencies, the cost is 0.  */
       return 0;
     }
+  else if (REG_NOTE_KIND (link) == REG_DEP_OUTPUT)
+    {
+      /* Output dependency; DEP_INSN writes a register that INSN writes some
+        cycles later.  */
+      if (get_attr_type (insn) == TYPE_FPLOAD)
+       {
+         rtx pat = PATTERN (insn);
+         rtx dep_pat = PATTERN (dep_insn);
+         if (GET_CODE (pat) == PARALLEL)
+           {
+             /* This happens for the fldXs,mb patterns.  */
+             pat = XVECEXP (pat, 0, 0);
+           }
+         if (GET_CODE (pat) != SET || GET_CODE (dep_pat) != SET)
+           /* If this happens, we have to extend this to schedule
+              optimally.  Return 0 for now.  */
+         return 0;
+
+         if (reg_mentioned_p (SET_DEST (pat), SET_DEST (dep_pat)))
+           {
+             if (! recog_memoized (dep_insn))
+               return 0;
+             switch (get_attr_type (dep_insn))
+               {
+               case TYPE_FPALU:
+               case TYPE_FPMULSGL:
+               case TYPE_FPMULDBL:
+               case TYPE_FPDIVSGL:
+               case TYPE_FPDIVDBL:
+               case TYPE_FPSQRTSGL:
+               case TYPE_FPSQRTDBL:
+                 /* A fpload can't be issued until one cycle before a
+                    preceeding arithmetic operation has finished if
+                    the target of the fpload is the destination of the
+                    arithmetic operation.  */
+                 return cost - (pa_cpu_attr == PROCESSOR_700) ? 1 : 2;
 
-  /* For output dependencies, the cost is often one too high.  */
-  return cost - 1;
+               default:
+                 return 0;
+               }
+           }
+       }
+      else if (get_attr_type (insn) == TYPE_FPALU)
+       {
+         rtx pat = PATTERN (insn);
+         rtx dep_pat = PATTERN (dep_insn);
+         if (GET_CODE (pat) == PARALLEL)
+           {
+             /* This happens for the fldXs,mb patterns.  */
+             pat = XVECEXP (pat, 0, 0);
+           }
+         if (GET_CODE (pat) != SET || GET_CODE (dep_pat) != SET)
+           /* If this happens, we have to extend this to schedule
+              optimally.  Return 0 for now.  */
+         return 0;
+
+         if (reg_mentioned_p (SET_DEST (pat), SET_DEST (dep_pat)))
+           {
+             if (! recog_memoized (dep_insn))
+               return 0;
+             switch (get_attr_type (dep_insn))
+               {
+               case TYPE_FPDIVSGL:
+               case TYPE_FPDIVDBL:
+               case TYPE_FPSQRTSGL:
+               case TYPE_FPSQRTDBL:
+                 /* An ALU flop can't be issued until two cycles before a
+                    preceeding divide or sqrt operation has finished if
+                    the target of the ALU flop is also the target of
+                    of the divide or sqrt operation.  */
+                 return cost - (pa_cpu_attr == PROCESSOR_700) ? 2 : 4;
+
+               default:
+                 return 0;
+               }
+           }
+       }
+
+      /* For other output dependencies, the cost is 0.  */
+      return 0;
+    }
+  else
+    abort ();
 }
 
 /* Return any length adjustment needed by INSN which already has its length
index 197c79b..9b414c2 100644 (file)
@@ -31,6 +31,21 @@ enum cmp_type                                /* comparison type */
 /* For long call handling.  */
 extern unsigned int total_code_bytes;
 
+/* Which processor to schedule for.  */
+
+enum processor_type
+{
+  PROCESSOR_700,
+  PROCESSOR_7100,
+  PROCESSOR_7100LC,
+};
+
+#define pa_cpu_attr ((enum attr_cpu)pa_cpu)
+
+/* For -mschedule= option.  */
+extern char *pa_cpu_string;
+extern enum processor_type pa_cpu;
+
 /* Print subsidiary information on the compiler version in use.  */
 
 #define TARGET_VERSION fprintf (stderr, " (hppa)");
@@ -123,6 +138,13 @@ extern int target_flags;
 #define TARGET_DEFAULT 0x88            /* TARGET_GAS + TARGET_JUMP_IN_DELAY */
 #endif
 
+#define TARGET_OPTIONS                 \
+{                                      \
+  { "schedule=",       &pa_cpu_string }\
+}
+
+#define OVERRIDE_OPTIONS override_options ()
+
 #define DBX_DEBUGGING_INFO
 #define DEFAULT_GDB_EXTENSIONS 1
 
index b7c187c..1af7597 100644 (file)
 ;; type "binary" insns have two input operands (1,2) and one output (0)
 
 (define_attr "type"
-  "move,unary,binary,compare,load,store,uncond_branch,branch,cbranch,fbranch,call,dyncall,fpload,fpstore,fpalu,fpcc,fpmul,fpdivsgl,fpdivdbl,fpsqrtsgl,fpsqrtdbl,multi,misc,milli"
+  "move,unary,binary,shift,nullshift,compare,load,store,uncond_branch,branch,cbranch,fbranch,call,dyncall,fpload,fpstore,fpalu,fpcc,fpmulsgl,fpmuldbl,fpdivsgl,fpdivdbl,fpsqrtsgl,fpsqrtdbl,multi,milli"
   (const_string "binary"))
 
+;; Processor type (for scheduling, not code generation) -- this attribute
+;; must exactly match the processor_type enumeration in pa.h.
+;;
+;; FIXME: Add 800 scheduling for completeness?
+
+(define_attr "cpu" "700,7100,7100LC" (const (symbol_ref "pa_cpu_attr")))
+
 ;; Length (in # of insns).
 (define_attr "length" ""
   (cond [(eq_attr "type" "load,fpload")
         (if_then_else (match_operand 0 "symbolic_memory_operand" "")
                       (const_int 8) (const_int 4))
 
-        (eq_attr "type" "binary")
+        (eq_attr "type" "binary,shift,nullshift")
         (if_then_else (match_operand 2 "arith_operand" "")
                       (const_int 4) (const_int 12))
 
-        (eq_attr "type" "move,unary")
+        (eq_attr "type" "move,unary,shift,nullshift")
         (if_then_else (match_operand 1 "arith_operand" "")
                       (const_int 4) (const_int 8))]
 
@@ -69,7 +76,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,branch,cbranch,fbranch,call,dyncall,multi,milli,fpcc,fpalu,fpmul,fpdivsgl,fpdivdbl,fpsqrtsgl,fpsqrtdbl")
+  (if_then_else (and (eq_attr "type" "!uncond_branch,branch,cbranch,fbranch,call,dyncall,multi,milli,fpcc,fpalu,fpmulsgl,fpmuldbl,fpdivsgl,fpdivdbl,fpsqrtsgl,fpsqrtdbl")
                     (eq_attr "length" "4"))
                (const_string "true")
                (const_string "false")))
    (and (eq_attr "in_nullified_branch_delay" "true")
        (attr_flag "backward"))])
 
-;; Function units of the HPPA. The following data is for the "Snake"
-;; (Mustang CPU + Timex FPU) because that's what I have the docs for.
+;; Function units of the HPPA. The following data is for the 700 CPUs
+;; (Mustang CPU + Timex FPU aka PA-89) because that's what I have the docs for.
 ;; Scheduling instructions for PA-83 machines according to the Snake
 ;; constraints shouldn't hurt.
 
 ;; be specified.)
 
 ;; (define_function_unit "alu" 1 0
-;;  (eq_attr "type" "unary,binary,move,address") 1 0)
+;;  (and (eq_attr "type" "unary,shift,nullshift,binary,move,address")
+;;      (eq_attr "cpu" "700"))
+;;  1 0)
 
 
 ;; Memory. Disregarding Cache misses, the Mustang memory times are:
-;; load: 2
+;; load: 2, fpload: 3
 ;; store, fpstore: 3, no D-cache operations should be scheduled.
-;; fpload: 3 (really 2 for flops, but I don't think we can specify that).
 
-(define_function_unit "memory" 1 0 (eq_attr "type" "load") 2 0)
-(define_function_unit "memory" 1 0 (eq_attr "type" "store,fpstore") 3 3)
-(define_function_unit "memory" 1 0 (eq_attr "type" "fpload") 2 0)
+(define_function_unit "pa700memory" 1 0
+  (and (eq_attr "type" "load,fpload")
+       (eq_attr "cpu" "700")) 2 0)
+(define_function_unit "pa700memory" 1 0 
+  (and (eq_attr "type" "store,fpstore")
+       (eq_attr "cpu" "700")) 3 3)
 
-;; The Timex has two floating-point units: ALU, and MUL/DIV/SQRT unit.
+;; The Timex (aka 700) has two floating-point units: ALU, and MUL/DIV/SQRT.
 ;; Timings:
 ;; Instruction Time    Unit    Minimum Distance (unit contention)
 ;; fcpy                3       ALU     2
 ;; fsqrt,sgl   14      MPY     14
 ;; fsqrt,dbl   18      MPY     18
 
-(define_function_unit "fp_alu" 1 0 (eq_attr "type" "fpcc") 4 2)
-(define_function_unit "fp_alu" 1 0 (eq_attr "type" "fpalu") 3 2)
-(define_function_unit "fp_mpy" 1 0 (eq_attr "type" "fpmul") 3 2)
-(define_function_unit "fp_mpy" 1 0 (eq_attr "type" "fpdivsgl") 10 10)
-(define_function_unit "fp_mpy" 1 0 (eq_attr "type" "fpdivdbl") 12 12)
-(define_function_unit "fp_mpy" 1 0 (eq_attr "type" "fpsqrtsgl") 14 14)
-(define_function_unit "fp_mpy" 1 0 (eq_attr "type" "fpsqrtdbl") 18 18)
+(define_function_unit "pa700fp_alu" 1 0
+  (and (eq_attr "type" "fpcc")
+       (eq_attr "cpu" "700")) 4 2)
+(define_function_unit "pa700fp_alu" 1 0
+  (and (eq_attr "type" "fpalu")
+       (eq_attr "cpu" "700")) 3 2)
+(define_function_unit "pa700fp_mpy" 1 0
+  (and (eq_attr "type" "fpmulsgl,fpmuldbl")
+       (eq_attr "cpu" "700")) 3 2)
+(define_function_unit "pa700fp_mpy" 1 0
+  (and (eq_attr "type" "fpdivsgl")
+       (eq_attr "cpu" "700")) 10 10)
+(define_function_unit "pa700fp_mpy" 1 0
+  (and (eq_attr "type" "fpdivdbl")
+       (eq_attr "cpu" "700")) 12 12)
+(define_function_unit "pa700fp_mpy" 1 0
+  (and (eq_attr "type" "fpsqrtsgl")
+       (eq_attr "cpu" "700")) 14 14)
+(define_function_unit "pa700fp_mpy" 1 0
+  (and (eq_attr "type" "fpsqrtdbl")
+       (eq_attr "cpu" "700")) 18 18)
+
+;; Function units for the 7100 and 7150.  The 7100/7150 can dual-issue
+;; floating point computations with non-floating point computations (fp loads
+;; and stores are not fp computations).
+;;
+;; As with the alpha we multiply the ready delay by two to encourage
+;; schedules which will allow the 7100/7150 to dual issue as many instructions
+;; as possible.
+
+;; Memory. Disregarding Cache misses, memory loads take two cycles; stores also
+;; take two cycles, during which no Dcache operations should be scheduled.
+;; Any special cases are handled in pa_adjust_cost.  The 7100, 7150 and 7100LC
+;; all have the same memory characteristics if one disregards cache misses.
+(define_function_unit "pa7100memory" 1 0
+  (and (eq_attr "type" "load,fpload")
+       (eq_attr "cpu" "7100,7100LC")) 4 0)
+(define_function_unit "pa7100memory" 1 0 
+  (and (eq_attr "type" "store,fpstore")
+       (eq_attr "cpu" "7100,7100LC")) 4 4)
+
+;; The 7100/7150 has three floating-point units: ALU, MUL, and DIV.
+;; Timings:
+;; Instruction Time    Unit    Minimum Distance (unit contention)
+;; fcpy                2       ALU     1
+;; fabs                2       ALU     1
+;; fadd                2       ALU     1
+;; fsub                2       ALU     1
+;; fcmp                2       ALU     1
+;; fcnv                2       ALU     1
+;; fmpyadd     2       ALU,MPY 1
+;; fmpysub     2       ALU,MPY 1
+;; fmpycfxt    2       ALU,MPY 1
+;; fmpy                2       MPY     1
+;; fmpyi       2       MPY     1
+;; fdiv,sgl    8       DIV     8
+;; fdiv,dbl    15      DIV     15
+;; fsqrt,sgl   8       DIV     8
+;; fsqrt,dbl   15      DIV     15
+
+(define_function_unit "pa7100fp_alu" 1 0
+  (and (eq_attr "type" "fpcc,fpalu")
+       (eq_attr "cpu" "7100")) 4 2)
+(define_function_unit "pa7100fp_mpy" 1 0
+  (and (eq_attr "type" "fpmulsgl,fpmuldbl")
+       (eq_attr "cpu" "7100")) 4 2)
+(define_function_unit "pa7100fp_div" 1 0
+  (and (eq_attr "type" "fpdivsgl,fpsqrtsgl")
+       (eq_attr "cpu" "7100")) 16 16)
+(define_function_unit "pa7100fp_div" 1 0
+  (and (eq_attr "type" "fpdivdbl,fpsqrtdbl")
+       (eq_attr "cpu" "7100")) 30 30)
+
+;; To encourage dual issue we define function units corresponding to
+;; the instructions which can be dual issued.    This is a rather crude
+;; approximation, the "pa7100nonflop" test in particular could be refined.
+(define_function_unit "pa7100flop" 1 1
+  (and
+    (eq_attr "type" "fpcc,fpalu,fpmulsgl,fpmuldbl,fpdivsgl,fpsqrtsgl,fpdivdbl,fpsqrtdbl")
+    (eq_attr "cpu" "7100,7100LC")) 2 2)
+
+(define_function_unit "pa7100nonflop" 1 1
+  (and
+    (eq_attr "type" "!fpcc,fpalu,fpmulsgl,fpmuldbl,fpdivsgl,fpsqrtsgl,fpdivdbl,fpsqrtdbl")
+    (eq_attr "cpu" "7100")) 2 2)
+
+
+;; Memory subsystem works just like 7100/7150 (except for cache miss times which
+;; we don't model here).  
+
+;; The 7100LC has three floating-point units: ALU, MUL, and DIV.
+;; Note divides and sqrt flops lock the cpu until the flop is
+;; finished.  fmpy and xmpyu (fmpyi) lock the cpu for one cycle.
+;; There's no way to avoid the penalty.
+;; Timings:
+;; Instruction Time    Unit    Minimum Distance (unit contention)
+;; fcpy                2       ALU     1
+;; fabs                2       ALU     1
+;; fadd                2       ALU     1
+;; fsub                2       ALU     1
+;; fcmp                2       ALU     1
+;; fcnv                2       ALU     1
+;; fmpyadd,sgl 2       ALU,MPY 1
+;; fmpyadd,dbl 3       ALU,MPY 2
+;; fmpysub,sgl 2       ALU,MPY 1
+;; fmpysub,dbl 3       ALU,MPY 2
+;; fmpycfxt,sgl        2       ALU,MPY 1
+;; fmpycfxt,dbl        3       ALU,MPY 2
+;; fmpy,sgl    2       MPY     1
+;; fmpy,dbl    3       MPY     2
+;; fmpyi       3       MPY     2
+;; fdiv,sgl    8       DIV     8
+;; fdiv,dbl    15      DIV     15
+;; fsqrt,sgl   8       DIV     8
+;; fsqrt,dbl   15      DIV     15
+
+(define_function_unit "pa7100LCfp_alu" 1 0
+  (and (eq_attr "type" "fpcc,fpalu")
+       (eq_attr "cpu" "7100LC")) 4 2)
+(define_function_unit "pa7100LCfp_mpy" 1 0
+  (and (eq_attr "type" "fpmulsgl")
+       (eq_attr "cpu" "7100LC")) 4 2)
+(define_function_unit "pa7100LCfp_mpy" 1 0
+  (and (eq_attr "type" "fpmuldbl")
+       (eq_attr "cpu" "7100LC")) 6 4)
+(define_function_unit "pa7100LCfp_div" 1 0
+  (and (eq_attr "type" "fpdivsgl,fpsqrtsgl")
+       (eq_attr "cpu" "7100LC")) 16 16)
+(define_function_unit "pa7100LCfp_div" 1 0
+  (and (eq_attr "type" "fpdivdbl,fpsqrtdbl")
+       (eq_attr "cpu" "7100LC")) 30 30)
+
+;; Define the various functional units for dual-issue.
+;; The 7100LC shares the generic "flop" unit specification with the 7100/7150.
+
+;; The 7100LC has two basic integer which allow dual issue of most integer
+;; instructions.  This needs further refinement to deal with the nullify,
+;; carry/borrow possible the ldw/ldw stw/stw special dual issue cases, and
+;; of course it needs to know about hte 2nd alu.
+(define_function_unit "pa7100LCnonflop" 1 1
+  (and
+    (eq_attr "type" "!fpcc,fpalu,fpmulsgl,fpmuldbl,fpdivsgl,fpsqrtsgl,fpdivdbl,fpsqrtdbl,load,fpload,store,fpstore,shift,nullshift")
+    (eq_attr "cpu" "7100LC")) 2 2)
+
+(define_function_unit "pa7100LCshifter" 1 1
+  (and
+    (eq_attr "type" "shift,nullshift")
+    (eq_attr "cpu" "7100LC")) 2 2)
+
+(define_function_unit "pa7100LCmem" 1 1
+  (and
+    (eq_attr "type" "load,fpload,store,fpstore")
+    (eq_attr "cpu" "7100LC")) 2 2)
+
 \f
 ;; Compare instructions.
 ;; This controls RTL generation and register allocation.
                              (match_operand:SF 1 "reg_or_0_operand" "fG")]))]
   ""
   "fcmp,sgl,%Y2 %r0,%r1"
-  [(set_attr "type" "fpcc")])
+  [(set_attr "length" "4")
+   (set_attr "type" "fpcc")])
 
 (define_insn ""
   [(set (reg:CCFP 0)
                              (match_operand:DF 1 "reg_or_0_operand" "fG")]))]
   ""
   "fcmp,dbl,%Y2 %r0,%r1"
-  [(set_attr "type" "fpcc")])
+  [(set_attr "length" "4")
+   (set_attr "type" "fpcc")])
 
 ;; scc insns.
 
   ""
   "com%I2clr,%S3 %2,%1,0\;com%I5clr,%B6 %5,%4,%0\;ldi 1,%0"
   [(set_attr "type" "binary")
-   (set_attr "length" "8")])
+   (set_attr "length" "12")])
 
 ;; Combiner patterns for common operations performed with the output
 ;; from an scc insn (negscc and incscc).
    com%I4clr,%B5 %4,%3,%0\;ldi %1,%0
    com%I4clr,%B5 %4,%3,%0\;ldil L'%1,%0
    com%I4clr,%B5 %4,%3,%0\;zdepi %Z1,%0"
-  [(set_attr "type" "multi,multi,multi,multi,multi")
+  [(set_attr "type" "multi,multi,multi,multi,nullshift")
    (set_attr "length" "8,8,8,8,8")])
 
 (define_insn ""
    com%I4clr,%B5 %4,%3,0\;ldi %1,%0
    com%I4clr,%B5 %4,%3,0\;ldil L'%1,%0
    com%I4clr,%B5 %4,%3,0\;zdepi %Z1,%0"
-  [(set_attr "type" "multi,multi,multi,multi,multi,multi,multi,multi")
+  [(set_attr "type" "multi,multi,multi,nullshift,multi,multi,multi,nullshift")
    (set_attr "length" "8,8,8,8,8,8,8,8")])
 
 ;; Conditional Branches
    fcpy,sgl %r1,%0
    fldws%F1 %1,%0
    fstws%F0 %1,%0"
-  [(set_attr "type" "move,move,move,move,load,store,move,fpalu,fpload,fpstore")
+  [(set_attr "type" "move,move,move,shift,load,store,move,fpalu,fpload,fpstore")
    (set_attr "length" "4,4,4,4,4,4,4,4,4,4")])
 
 ;; Load indexed.  We don't use unscaled modes since they can't be used
 ;; has constraints allowing a register.  I don't know how this works,
 ;; but it somehow makes sure that out-of-range constants are placed
 ;; in a register which somehow magically is a "const_int_operand".
-;; (this was stolen from alpha.md, I'm not going to try and change it.
+;; (this was stolen from alpha.md, I'm not going to try and change it.)
 (define_insn ""
   [(set (match_operand:SI 0 "register_operand" "&=r")
        (mem:SI (plus:SI (plus:SI
   if (flag_pic != 2)
     abort ();
   return \"ldw RT'%G2(%1),%0\";
-}")
+}"
+  [(set_attr "type" "load")
+   (set_attr "length" "4")])
 
 
 ;; Always use addil rather than ldil;add sequences.  This allows the
                   (match_operand:SI 2 "function_label_operand" "")))]
   "!TARGET_PORTABLE_RUNTIME"
   "ldo RP'%G2(%1),%0"
-  [(set_attr "length" "4")])
+  [(set_attr "type" "move")
+   (set_attr "length" "4")])
 
 ;; This version is used only for the portable runtime conventions model
 ;; (it does not use/support plabels)
                   (match_operand:SI 2 "function_label_operand" "")))]
   "TARGET_PORTABLE_RUNTIME"
   "ldo R'%G2(%1),%0"
-  [(set_attr "length" "4")])
+  [(set_attr "type" "move")
+   (set_attr "length" "4")])
 
 (define_insn ""
   [(set (match_operand:SI 0 "register_operand" "=r")
   else
     return \"ldo R'%G2(%1),%0\";
 }"
-  [(set_attr "length" "4")])
+  [(set_attr "type" "move")
+   (set_attr "length" "4")])
 
 ;; Now that a symbolic_address plus a constant is broken up early
 ;; in the compilation phase (for better CSE) we need a special
    sth%M0 %r1,%0
    mtsar %r1
    fcpy,sgl %r1,%0"
-  [(set_attr "type" "move,move,move,move,load,store,move,fpalu")
+  [(set_attr "type" "move,move,move,shift,load,store,move,fpalu")
    (set_attr "length" "4,4,4,4,4,4,4,4")])
 
 (define_insn ""
                   (match_operand 2 "const_int_operand" "")))]
   ""
   "ldo R'%G2(%1),%0"
-  [(set_attr "length" "4")])
+  [(set_attr "type" "move")
+   (set_attr "length" "4")])
 
 (define_expand "movqi"
   [(set (match_operand:QI 0 "general_operand" "")
    stb%M0 %r1,%0
    mtsar %r1
    fcpy,sgl %r1,%0"
-  [(set_attr "type" "move,move,move,move,load,store,move,fpalu")
+  [(set_attr "type" "move,move,move,shift,load,store,move,fpalu")
    (set_attr "length" "4,4,4,4,4,4,4,4")])
 
 (define_insn ""
     return output_fp_move_double (operands);
   return output_move_double (operands);
 }"
-  [(set_attr "type" "move,store,store,load,load,misc,fpalu,fpload,fpstore")
+  [(set_attr "type" "move,store,store,load,load,multi,fpalu,fpload,fpstore")
    (set_attr "length" "8,8,16,8,16,16,4,4,4")])
 
 (define_insn ""
     output_asm_insn (\"copy %1,%0\", operands);
   return \"ldo R'%G2(%R1),%R0\";
 }"
-  ;; Need to set length for this arith insn because operand2
-  ;; is not an "arith_operand".
-  [(set_attr "length" "4,8")])
+  [(set_attr "type" "move,move")
+   (set_attr "length" "4,8")])
 
 ;; This pattern forces (set (reg:SF ...) (const_double ...))
 ;; to be reloaded by putting the constant into memory when
   "@
    extru %1,31,16,%0
    ldh%M1 %1,%0"
-  [(set_attr "type" "unary,load")])
+  [(set_attr "type" "shift,load")
+   (set_attr "length" "4,4")])
 
 (define_insn "zero_extendqihi2"
   [(set (match_operand:HI 0 "register_operand" "=r,r")
   "@
    extru %1,31,8,%0
    ldb%M1 %1,%0"
-  [(set_attr "type" "unary,load")])
+  [(set_attr "type" "shift,load")
+   (set_attr "length" "4,4")])
 
 (define_insn "zero_extendqisi2"
   [(set (match_operand:SI 0 "register_operand" "=r,r")
   "@
    extru %1,31,8,%0
    ldb%M1 %1,%0"
-  [(set_attr "type" "unary,load")])
+  [(set_attr "type" "shift,load")
+   (set_attr "length" "4,4")])
 
 ;;- sign extension instructions
 
        (sign_extend:SI (match_operand:HI 1 "register_operand" "r")))]
   ""
   "extrs %1,31,16,%0"
-  [(set_attr "type" "unary")])
+  [(set_attr "type" "shift")
+   (set_attr "length" "4")])
 
 (define_insn "extendqihi2"
   [(set (match_operand:HI 0 "register_operand" "=r")
        (sign_extend:HI (match_operand:QI 1 "register_operand" "r")))]
   ""
   "extrs %1,31,8,%0"
-  [(set_attr "type" "unary")])
+  [(set_attr "type" "shift") 
+  (set_attr "length" "4")])
 
 (define_insn "extendqisi2"
   [(set (match_operand:SI 0 "register_operand" "=r")
        (sign_extend:SI (match_operand:QI 1 "register_operand" "r")))]
   ""
   "extrs %1,31,8,%0"
-  [(set_attr "type" "unary")])
+  [(set_attr "type" "shift")
+   (set_attr "length" "4")])
 \f
 ;; Conversions between float and double.
 
         (match_operand:SF 1 "register_operand" "f")))]
   ""
   "fcnvff,sgl,dbl %1,%0"
-  [(set_attr "type" "fpalu")])
+  [(set_attr "type" "fpalu")
+   (set_attr "length" "4")])
 
 (define_insn "truncdfsf2"
   [(set (match_operand:SF 0 "register_operand" "=f")
         (match_operand:DF 1 "register_operand" "f")))]
   ""
   "fcnvff,dbl,sgl %1,%0"
-  [(set_attr "type" "fpalu")])
+  [(set_attr "type" "fpalu")
+   (set_attr "length" "4")])
 
 ;; Conversion between fixed point and floating point.
 ;; Note that among the fix-to-float insns
        (float:SF (match_operand:SI 1 "register_operand" "f")))]
   ""
   "fcnvxf,sgl,sgl %1,%0"
-  [(set_attr "type" "fpalu")])
+  [(set_attr "type" "fpalu")
+   (set_attr "length" "4")])
 
 ;; This pattern forces (set (reg:DF ...) (float:DF (const_int ...)))
 ;; to be reloaded by putting the constant into memory.
        (float:DF (match_operand:SI 1 "register_operand" "f")))]
   ""
   "fcnvxf,sgl,dbl %1,%0"
-  [(set_attr "type" "fpalu")])
+  [(set_attr "type" "fpalu")
+   (set_attr "length" "4")])
 
 (define_expand "floatunssisf2"
   [(set (subreg:SI (match_dup 2) 1)
        (float:SF (match_operand:DI 1 "register_operand" "f")))]
   "TARGET_SNAKE"
   "fcnvxf,dbl,sgl %1,%0"
-  [(set_attr "type" "fpalu")])
+  [(set_attr "type" "fpalu")
+   (set_attr "length" "4")])
 
 (define_insn "floatdidf2"
   [(set (match_operand:DF 0 "general_operand" "=f")
        (float:DF (match_operand:DI 1 "register_operand" "f")))]
   "TARGET_SNAKE"
   "fcnvxf,dbl,dbl %1,%0"
-  [(set_attr "type" "fpalu")])
+  [(set_attr "type" "fpalu")
+   (set_attr "length" "4")])
 
 ;; Convert a float to an actual integer.
 ;; Truncation is performed as part of the conversion.
        (fix:SI (fix:SF (match_operand:SF 1 "register_operand" "f"))))]
   ""
   "fcnvfxt,sgl,sgl %1,%0"
-  [(set_attr "type" "fpalu")])
+  [(set_attr "type" "fpalu")
+   (set_attr "length" "4")])
 
 (define_insn "fix_truncdfsi2"
   [(set (match_operand:SI 0 "register_operand" "=f")
        (fix:SI (fix:DF (match_operand:DF 1 "register_operand" "f"))))]
   ""
   "fcnvfxt,dbl,sgl %1,%0"
-  [(set_attr "type" "fpalu")])
+  [(set_attr "type" "fpalu")
+   (set_attr "length" "4")])
 
 (define_insn "fix_truncsfdi2"
   [(set (match_operand:DI 0 "register_operand" "=f")
        (fix:DI (fix:SF (match_operand:SF 1 "register_operand" "f"))))]
   "TARGET_SNAKE"
   "fcnvfxt,sgl,dbl %1,%0"
-  [(set_attr "type" "fpalu")])
+  [(set_attr "type" "fpalu")
+   (set_attr "length" "4")])
 
 (define_insn "fix_truncdfdi2"
   [(set (match_operand:DI 0 "register_operand" "=f")
        (fix:DI (fix:DF (match_operand:DF 1 "register_operand" "f"))))]
   "TARGET_SNAKE"
   "fcnvfxt,dbl,dbl %1,%0"
-  [(set_attr "type" "fpalu")])
+  [(set_attr "type" "fpalu")
+   (set_attr "length" "4")])
 \f
 ;;- arithmetic instructions
 
   else
     return \"add %R2,%R1,%R0\;addc %2,%1,%0\";
 }"
-  [(set_attr "length" "8")])
+  [(set_attr "type" "binary")
+   (set_attr "length" "8")])
 
 (define_insn ""
   [(set (match_operand:SI 0 "register_operand" "=r")
        (plus:SI (not:SI (match_operand:SI 1 "register_operand" "r"))
                 (match_operand:SI 2 "register_operand" "r")))]
   ""
-  "uaddcm %2,%1,%0")
+  "uaddcm %2,%1,%0"
+  [(set_attr "type" "binary")
+   (set_attr "length" "4")])
 
 ;; define_splits to optimize cases of adding a constant integer
 ;; to a register when the constant does not fit in 14 bits.  */
   ""
   "@
    addl %1,%2,%0
-   ldo %2(%1),%0")
+   ldo %2(%1),%0"
+  [(set_attr "type" "binary,binary")
+   (set_attr "length" "4,4")])
 
 (define_insn "subdi3"
   [(set (match_operand:DI 0 "register_operand" "=r")
                  (match_operand:DI 2 "register_operand" "r")))]
   ""
   "sub %R1,%R2,%R0\;subb %1,%2,%0"
-  [(set_attr "length" "8")])
+  [(set_attr "type" "binary")
+  (set_attr "length" "8")])
 
 (define_insn "subsi3"
   [(set (match_operand:SI 0 "register_operand" "=r,r")
   ""
   "@
    sub %1,%2,%0
-   subi %1,%2,%0")
+   subi %1,%2,%0"
+  [(set_attr "type" "binary,binary")
+   (set_attr "length" "4,4")])
 
 ;; Clobbering a "register_operand" instead of a match_scratch
 ;; in operand3 of millicode calls avoids spilling %r1 and
                 (zero_extend:DI (match_operand:SI 2 "nonimmediate_operand" "f"))))]
   "TARGET_SNAKE && ! TARGET_DISABLE_FPREGS"
   "xmpyu %1,%2,%0"
-  [(set_attr "type" "fpmul")])
+  [(set_attr "type" "fpmuldbl")
+   (set_attr "length" "4")])
 
 (define_insn ""
   [(set (match_operand:DI 0 "nonimmediate_operand" "=f")
                 (match_operand:DI 2 "uint32_operand" "f")))]
   "TARGET_SNAKE && ! TARGET_DISABLE_FPREGS"
   "xmpyu %1,%R2,%0"
-  [(set_attr "type" "fpmul")])
+  [(set_attr "type" "fpmuldbl")
+   (set_attr "length" "4")])
 
 (define_insn ""
   [(set (reg:SI 29) (mult:SI (reg:SI 26) (reg:SI 25)))
                (match_operand:DI 2 "register_operand" "r")))]
   ""
   "and %1,%2,%0\;and %R1,%R2,%R0"
-  [(set_attr "length" "8")])
+  [(set_attr "type" "binary")
+   (set_attr "length" "8")])
 
 ; The ? for op1 makes reload prefer zdepi instead of loading a huge
 ; constant with ldil;ldo.
                (match_operand:SI 2 "and_operand" "rO,P")))]
   ""
   "* return output_and (operands); "
-  [(set_attr "type" "binary")
-   (set_attr "length" "4")])
+  [(set_attr "type" "binary,shift")
+   (set_attr "length" "4,4")])
 
 (define_insn ""
   [(set (match_operand:DI 0 "register_operand" "=r")
                (match_operand:DI 2 "register_operand" "r")))]
   ""
   "andcm %2,%1,%0\;andcm %R2,%R1,%R0"
-  [(set_attr "length" "8")])
+  [(set_attr "type" "binary")
+   (set_attr "length" "8")])
 
 (define_insn ""
   [(set (match_operand:SI 0 "register_operand" "=r")
        (and:SI (not:SI (match_operand:SI 1 "register_operand" "r"))
                (match_operand:SI 2 "register_operand" "r")))]
   ""
-  "andcm %2,%1,%0")
+  "andcm %2,%1,%0"
+  [(set_attr "type" "binary")
+  (set_attr "length" "4")])
 
 (define_expand "iordi3"
   [(set (match_operand:DI 0 "register_operand" "")
                (match_operand:DI 2 "register_operand" "r")))]
   ""
   "or %1,%2,%0\;or %R1,%R2,%R0"
-  [(set_attr "length" "8")])
+  [(set_attr "type" "binary")
+   (set_attr "length" "8")])
 
 ;; Need a define_expand because we've run out of CONST_OK... characters.
 (define_expand "iorsi3"
 }")
 
 (define_insn ""
-  [(set (match_operand:SI 0 "register_operand" "=r")
-       (ior:SI (match_operand:SI 1 "register_operand" "0")
-               (match_operand:SI 2 "ior_operand" "")))]
+  [(set (match_operand:SI 0 "register_operand" "=r,r")
+       (ior:SI (match_operand:SI 1 "register_operand" "0,0")
+               (match_operand:SI 2 "ior_operand" "M,i")))]
   ""
   "* return output_ior (operands); "
-  [(set_attr "type" "binary")
-   (set_attr "length" "4")])
+  [(set_attr "type" "binary,shift")
+   (set_attr "length" "4,4")])
 
 (define_insn ""
   [(set (match_operand:SI 0 "register_operand" "=r")
        (ior:SI (match_operand:SI 1 "register_operand" "%r")
                (match_operand:SI 2 "register_operand" "r")))]
   ""
-  "or %1,%2,%0")
+  "or %1,%2,%0"
+  [(set_attr "type" "binary")
+   (set_attr "length" "4")])
 
 (define_expand "xordi3"
   [(set (match_operand:DI 0 "register_operand" "")
                (match_operand:DI 2 "register_operand" "r")))]
   ""
   "xor %1,%2,%0\;xor %R1,%R2,%R0"
-  [(set_attr "length" "8")])
+  [(set_attr "type" "binary")
+   (set_attr "length" "8")])
 
 (define_insn "xorsi3"
   [(set (match_operand:SI 0 "register_operand" "=r")
        (xor:SI (match_operand:SI 1 "register_operand" "%r")
                (match_operand:SI 2 "register_operand" "r")))]
   ""
-  "xor %1,%2,%0")
+  "xor %1,%2,%0"
+  [(set_attr "type" "binary")
+   (set_attr "length" "4")])
 
 (define_insn "negdi2"
   [(set (match_operand:DI 0 "register_operand" "=r")
        (neg:SI (match_operand:SI 1 "register_operand" "r")))]
   ""
   "sub 0,%1,%0"
-  [(set_attr "type" "unary")])
+  [(set_attr "type" "unary")
+   (set_attr "length" "4")])
 
 (define_expand "one_cmpldi2"
   [(set (match_operand:DI 0 "register_operand" "")
        (not:SI (match_operand:SI 1 "register_operand" "r")))]
   ""
   "uaddcm 0,%1,%0"
-  [(set_attr "type" "unary")])
+  [(set_attr "type" "unary")
+   (set_attr "length" "4")])
 \f
 ;; Floating point arithmetic instructions.
 
                 (match_operand:DF 2 "register_operand" "f")))]
   ""
   "fadd,dbl %1,%2,%0"
-  [(set_attr "type" "fpalu")])
+  [(set_attr "type" "fpalu")
+   (set_attr "length" "4")])
 
 (define_insn "addsf3"
   [(set (match_operand:SF 0 "register_operand" "=f")
                 (match_operand:SF 2 "register_operand" "f")))]
   ""
   "fadd,sgl %1,%2,%0"
-  [(set_attr "type" "fpalu")])
+  [(set_attr "type" "fpalu")
+   (set_attr "length" "4")])
 
 (define_insn "subdf3"
   [(set (match_operand:DF 0 "register_operand" "=f")
                  (match_operand:DF 2 "register_operand" "f")))]
   ""
   "fsub,dbl %1,%2,%0"
-  [(set_attr "type" "fpalu")])
+  [(set_attr "type" "fpalu")
+   (set_attr "length" "4")])
 
 (define_insn "subsf3"
   [(set (match_operand:SF 0 "register_operand" "=f")
                  (match_operand:SF 2 "register_operand" "f")))]
   ""
   "fsub,sgl %1,%2,%0"
-  [(set_attr "type" "fpalu")])
+  [(set_attr "type" "fpalu")
+   (set_attr "length" "4")])
 
 (define_insn "muldf3"
   [(set (match_operand:DF 0 "register_operand" "=f")
                 (match_operand:DF 2 "register_operand" "f")))]
   ""
   "fmpy,dbl %1,%2,%0"
-  [(set_attr "type" "fpmul")])
+  [(set_attr "type" "fpmuldbl")
+   (set_attr "length" "4")])
 
 (define_insn "mulsf3"
   [(set (match_operand:SF 0 "register_operand" "=f")
                 (match_operand:SF 2 "register_operand" "f")))]
   ""
   "fmpy,sgl %1,%2,%0"
-  [(set_attr "type" "fpmul")])
+  [(set_attr "type" "fpmulsgl")
+   (set_attr "length" "4")])
 
 (define_insn "divdf3"
   [(set (match_operand:DF 0 "register_operand" "=f")
                (match_operand:DF 2 "register_operand" "f")))]
   ""
   "fdiv,dbl %1,%2,%0"
-  [(set_attr "type" "fpdivdbl")])
+  [(set_attr "type" "fpdivdbl")
+   (set_attr "length" "4")])
 
 (define_insn "divsf3"
   [(set (match_operand:SF 0 "register_operand" "=f")
                (match_operand:SF 2 "register_operand" "f")))]
   ""
   "fdiv,sgl %1,%2,%0"
-  [(set_attr "type" "fpdivsgl")])
+  [(set_attr "type" "fpdivsgl")
+   (set_attr "length" "4")])
 
 (define_insn "negdf2"
   [(set (match_operand:DF 0 "register_operand" "=f")
        (neg:DF (match_operand:DF 1 "register_operand" "f")))]
   ""
   "fsub,dbl 0,%1,%0"
-  [(set_attr "type" "fpalu")])
+  [(set_attr "type" "fpalu")
+   (set_attr "length" "4")])
 
 (define_insn "negsf2"
   [(set (match_operand:SF 0 "register_operand" "=f")
        (neg:SF (match_operand:SF 1 "register_operand" "f")))]
   ""
   "fsub,sgl 0,%1,%0"
-  [(set_attr "type" "fpalu")])
+  [(set_attr "type" "fpalu")
+   (set_attr "length" "4")])
 
 (define_insn "absdf2"
   [(set (match_operand:DF 0 "register_operand" "=f")
        (abs:DF (match_operand:DF 1 "register_operand" "f")))]
   ""
   "fabs,dbl %1,%0"
-  [(set_attr "type" "fpalu")])
+  [(set_attr "type" "fpalu")
+   (set_attr "length" "4")])
 
 (define_insn "abssf2"
   [(set (match_operand:SF 0 "register_operand" "=f")
        (abs:SF (match_operand:SF 1 "register_operand" "f")))]
   ""
   "fabs,sgl %1,%0"
-  [(set_attr "type" "fpalu")])
+  [(set_attr "type" "fpalu")
+   (set_attr "length" "4")])
 
 (define_insn "sqrtdf2"
   [(set (match_operand:DF 0 "register_operand" "=f")
        (sqrt:DF (match_operand:DF 1 "register_operand" "f")))]
   ""
   "fsqrt,dbl %1,%0"
-  [(set_attr "type" "fpsqrtdbl")])
+  [(set_attr "type" "fpsqrtdbl")
+   (set_attr "length" "4")])
 
 (define_insn "sqrtsf2"
   [(set (match_operand:SF 0 "register_operand" "=f")
        (sqrt:SF (match_operand:SF 1 "register_operand" "f")))]
   ""
   "fsqrt,sgl %1,%0"
-  [(set_attr "type" "fpsqrtsgl")])
+  [(set_attr "type" "fpsqrtsgl")
+   (set_attr "length" "4")])
 \f
 ;;- Shift instructions
 
                          (match_operand:SI 3 "shadd_operand" ""))
                 (match_operand:SI 1 "register_operand" "r")))]
   ""
-  "sh%O3addl %2,%1,%0")
+  "sh%O3addl %2,%1,%0"
+  [(set_attr "type" "binary")
+   (set_attr "length" "4")])
 
 ;; This variant of the above insn can occur if the first operand
 ;; is the frame pointer.  This is a kludge, but there doesn't
                   (match_operand:SI 2 "const_int_operand" "n")))]
   ""
   "zdep %1,%P2,%L2,%0"
-  [(set_attr "type" "binary")
+  [(set_attr "type" "shift")
    (set_attr "length" "4")])
 
 ; Match cases of op1 a CONST_INT here that zvdep_imm doesn't handle.
   ""
   "@
    zvdep %1,32,%0
-   zvdepi %1,32,%0")
+   zvdepi %1,32,%0"
+  [(set_attr "type" "shift,shift")
+   (set_attr "length" "4,4")])
 
 (define_insn "zvdep_imm"
   [(set (match_operand:SI 0 "register_operand" "=r")
   operands[2] = GEN_INT (4 + exact_log2 ((x >> 4) + 1));
   operands[1] = GEN_INT ((x & 0xf) - 0x10);
   return \"zvdepi %1,%2,%0\";
-}")
+}"
+  [(set_attr "type" "shift")
+   (set_attr "length" "4")])
 
 (define_insn "vdepi_ior"
   [(set (match_operand:SI 0 "register_operand" "=r")
   int x = INTVAL (operands[1]);
   operands[2] = GEN_INT (exact_log2 (x + 1));
   return \"vdepi -1,%2,%0\";
-}")
+}"
+  [(set_attr "type" "shift")
+   (set_attr "length" "4")])
 
 (define_insn "vdepi_and"
   [(set (match_operand:SI 0 "register_operand" "=r")
   int x = INTVAL (operands[1]);
   operands[2] = GEN_INT (exact_log2 ((~x) + 1));
   return \"vdepi 0,%2,%0\";
-}")
+}"
+  [(set_attr "type" "shift")
+   (set_attr "length" "4")])
 
 (define_expand "ashrsi3"
   [(set (match_operand:SI 0 "register_operand" "")
                     (match_operand:SI 2 "const_int_operand" "n")))]
   ""
   "extrs %1,%P2,%L2,%0"
-  [(set_attr "type" "binary")
+  [(set_attr "type" "shift")
    (set_attr "length" "4")])
 
 (define_insn "vextrs32"
                     (minus:SI (const_int 31)
                               (match_operand:SI 2 "register_operand" "q"))))]
   ""
-  "vextrs %1,32,%0")
+  "vextrs %1,32,%0"
+  [(set_attr "type" "shift")
+   (set_attr "length" "4")])
 
 (define_insn "lshrsi3"
   [(set (match_operand:SI 0 "register_operand" "=r,r")
   "@
    vshd 0,%1,%0
    extru %1,%P2,%L2,%0"
-  [(set_attr "type" "binary")
+  [(set_attr "type" "shift")
    (set_attr "length" "4")])
 
 (define_insn "rotrsi3"
   else
     return \"vshd %1,%1,%0\";
 }"
-  [(set_attr "type" "binary")
+  [(set_attr "type" "shift")
    (set_attr "length" "4")])
 
 (define_insn "rotlsi3"
   operands[2] = GEN_INT ((32 - INTVAL (operands[2])) & 31);
   return \"shd %1,%1,%2,%0\";
 }"
-  [(set_attr "type" "binary")
+  [(set_attr "type" "shift")
    (set_attr "length" "4")])
 
 (define_insn ""
                        (match_operand:SI 4 "const_int_operand" "n"))]))]
   "INTVAL (operands[3]) + INTVAL (operands[4]) == 32"
   "shd %1,%2,%4,%0"
-  [(set_attr "type" "binary")
+  [(set_attr "type" "shift")
    (set_attr "length" "4")])
 
 (define_insn ""
                      (match_operand:SI 3 "const_int_operand" "n"))]))]
   "INTVAL (operands[3]) + INTVAL (operands[4]) == 32"
   "shd %1,%2,%4,%0"
-  [(set_attr "type" "binary")
+  [(set_attr "type" "shift")
    (set_attr "length" "4")])
 
 (define_insn ""
   operands[2] = GEN_INT (31 - cnt);
   return \"zdep %1,%2,%3,%0\";
 }"
-  [(set_attr "type" "binary")
+  [(set_attr "type" "shift")
    (set_attr "length" "4")])
 \f
 ;; Unconditional and other jump instructions.
   [(return)]
   "hppa_can_use_return_insn_p ()"
   "bv%* 0(%%r2)"
-  [(set_attr "type" "branch")])
+  [(set_attr "type" "branch")
+   (set_attr "length" "4")])
 
 ;; Use a different pattern for functions which have non-trivial
 ;; epilogues so as not to confuse jump and reorg.
    (return)]
   ""
   "bv%* 0(%%r2)"
-  [(set_attr "type" "branch")])
+  [(set_attr "type" "branch")
+   (set_attr "length" "4")])
 
 (define_expand "prologue"
   [(const_int 0)]
    (use (match_operand:SI 0 "const_int_operand" ""))]
   ""
   "bl _mcount,%%r2\;ldo %0(%%r2),%%r25"
-  [(set_attr "length" "8")])
+  [(set_attr "type" "multi")
+   (set_attr "length" "8")])
 
 (define_insn "blockage"
   [(unspec_volatile [(const_int 2)] 0)]
       return \"sub,>> %0,%1,0\;blr,n %0,0\;b,n %l3\";
     }
 }"
-  [(set_attr "length" "12")])
+  [(set_attr "type" "multi")
+   (set_attr "length" "12")])
 
 ;; Need nops for the calls because execution is supposed to continue
 ;; past; we don't want to nullify an instruction that we need.
 (define_insn "nop"
   [(const_int 0)]
   ""
-  "nop")
+  "nop"
+  [(set_attr "type" "move")
+   (set_attr "length" "4")])
 
 ;;; Hope this is only within a function...
 (define_insn "indirect_jump"
   [(set (pc) (match_operand:SI 0 "register_operand" "r"))]
   ""
   "bv%* 0(%0)"
-  [(set_attr "type" "branch")])
+  [(set_attr "type" "branch")
+   (set_attr "length" "4")])
 
 (define_insn "extzv"
   [(set (match_operand:SI 0 "register_operand" "=r")
                         (match_operand:SI 2 "uint5_operand" "")
                         (match_operand:SI 3 "uint5_operand" "")))]
   ""
-  "extru %1,%3+%2-1,%2,%0")
+  "extru %1,%3+%2-1,%2,%0"
+  [(set_attr "type" "shift")
+   (set_attr "length" "4")])
 
 (define_insn ""
   [(set (match_operand:SI 0 "register_operand" "=r")
                         (const_int 1)
                         (match_operand:SI 3 "register_operand" "q")))]
   ""
-  "vextru %1,1,%0")
+  "vextru %1,1,%0"
+  [(set_attr "type" "shift")
+   (set_attr "length" "4")])
 
 (define_insn "extv"
   [(set (match_operand:SI 0 "register_operand" "=r")
                         (match_operand:SI 2 "uint5_operand" "")
                         (match_operand:SI 3 "uint5_operand" "")))]
   ""
-  "extrs %1,%3+%2-1,%2,%0")
+  "extrs %1,%3+%2-1,%2,%0"
+  [(set_attr "type" "shift")
+   (set_attr "length" "4")])
 
 (define_insn ""
   [(set (match_operand:SI 0 "register_operand" "=r")
                         (const_int 1)
                         (match_operand:SI 3 "register_operand" "q")))]
   ""
-  "vextrs %1,1,%0")
+  "vextrs %1,1,%0"
+  [(set_attr "type" "shift")
+   (set_attr "length" "4")])
 
 (define_insn "insv"
   [(set (zero_extract:SI (match_operand:SI 0 "register_operand" "+r,r")
   ""
   "@
    dep %3,%2+%1-1,%1,%0
-   depi %3,%2+%1-1,%1,%0")
+   depi %3,%2+%1-1,%1,%0"
+  [(set_attr "type" "shift,shift")
+   (set_attr "length" "4,4")])
 
 ;; Optimize insertion of const_int values of type 1...1xxxx.
 (define_insn ""
 {
   operands[3] = GEN_INT ((INTVAL (operands[3]) & 0xf) - 0x10);
   return \"depi %3,%2+%1-1,%1,%0\";
-}")
+}"
+  [(set_attr "type" "shift")
+   (set_attr "length" "4")])
 
 ;; This insn is used for some loop tests, typically loops reversed when
 ;; strength reduction is used.  It is actually created when the instruction
    (use (mem:SI (match_operand:SI 1 "register_operand" "r")))]
   ""
   "fdc 0(0,%0)\;fdc 0(0,%1)\;sync"
-  [(set_attr "length" "12")])
+  [(set_attr "type" "multi")
+   (set_attr "length" "12")])
 
 (define_insn "icacheflush"
   [(unspec_volatile [(const_int 2)] 0)
    (clobber (match_operand:SI 4 "register_operand" "=&r"))]
   ""
   "mfsp %%sr0,%4\;ldsid (0,%2),%3\;mtsp %3,%%sr0\;fic 0(%%sr0,%0)\;fic 0(%%sr0,%1)\;sync\;mtsp %4,%%sr0\;nop\;nop\;nop\;nop\;nop\;nop"
-  [(set_attr "length" "52")])
+  [(set_attr "type" "multi")
+   (set_attr "length" "52")])