add scheduling information for stores
authorDavid Edelsohn <edelsohn@gnu.org>
Wed, 6 Mar 1996 16:40:14 +0000 (16:40 +0000)
committerDavid Edelsohn <edelsohn@gnu.org>
Wed, 6 Mar 1996 16:40:14 +0000 (16:40 +0000)
From-SVN: r11481

gcc/config/rs6000/rs6000.md

index 830a637e299fe636cd75edb84676b1609db5e637..aa1b0fe6146c5c686ba21e77c31e25cec3ebff0b 100644 (file)
@@ -23,7 +23,7 @@
 \f
 ;; Define an insn type attribute.  This is used in function unit delay
 ;; computations.
-(define_attr "type" "integer,load,fpload,imul,idiv,branch,compare,delayed_compare,fpcompare,mtjmpr,fp,dmul,sdiv,ddiv,ssqrt,dsqrt,jmpreg"
+(define_attr "type" "integer,load,store,fpload,fpstore,imul,idiv,branch,compare,delayed_compare,fpcompare,mtjmpr,fp,dmul,sdiv,ddiv,ssqrt,dsqrt,jmpreg"
   (const_string "integer"))
 
 ;; Length (in bytes).
 ;; Processor type -- this attribute must exactly match the processor_type
 ;; enumeration in rs6000.h.
 
-(define_attr "cpu" "rios1,rios2,mpccore,ppc403,ppc601,ppc602,ppc603,ppc604,ppc620"
+(define_attr "cpu" "rios1,rios2,mpccore,ppc403,ppc601,ppc603,ppc604,ppc620"
   (const (symbol_ref "rs6000_cpu_attr")))
 
 ; (define_function_unit NAME MULTIPLICITY SIMULTANEITY
 ;                      TEST READY-DELAY ISSUE-DELAY [CONFLICT-LIST])
 
-; Load/Store Unit -- POWER/2 and pure PowerPC only
+; Load/Store Unit -- pure PowerPC only
 ; (POWER and 601 use Integer Unit)
 (define_function_unit "lsu" 1 0
   (and (eq_attr "type" "load")
-       (eq_attr "cpu" "mpccore,ppc602,ppc603,ppc604,ppc620"))
+       (eq_attr "cpu" "mpccore,ppc603,ppc604,ppc620"))
   2 1)
 
 (define_function_unit "lsu" 1 0
-  (and (eq_attr "type" "fpload")
-       (eq_attr "cpu" "ppc604,ppc620"))
-  3 1)
+  (and (eq_attr "type" "store,fpstore")
+       (eq_attr "cpu" "mpccore,ppc603,ppc604,ppc620"))
+  1 1)
 
 (define_function_unit "lsu" 1 0
   (and (eq_attr "type" "fpload")
-       (eq_attr "cpu" "mpccore,ppc602,ppc603"))
+       (eq_attr "cpu" "mpccore,ppc603"))
   2 1)
 
+(define_function_unit "lsu" 1 0
+  (and (eq_attr "type" "fpload")
+       (eq_attr "cpu" "ppc604,ppc620"))
+  3 1)
+
 (define_function_unit "iu" 1 0
   (and (eq_attr "type" "load")
-       (eq_attr "cpu" "rios1,ppc601,ppc403"))
+       (eq_attr "cpu" "rios1,ppc403,ppc601"))
   2 1)
 
 (define_function_unit "iu" 1 0
-  (and (eq_attr "type" "fpload")
+  (and (eq_attr "type" "store,fpstore")
+       (eq_attr "cpu" "rios1,ppc403,ppc601"))
+  1 1)
+
+(define_function_unit "fpu" 1 0
+  (and (eq_attr "type" "fpstore")
        (eq_attr "cpu" "rios1,ppc601"))
-  2 0)
+  0 1)
 
-; Integer Unit (RIOS1, PPC601, PPC603)
-; Trivial operations take one cycle which need not be listed here.
 (define_function_unit "iu" 1 0
-  (and (eq_attr "type" "imul")
+  (and (eq_attr "type" "fpload")
        (eq_attr "cpu" "rios1"))
-  3 3)
+  2 1)
+
+(define_function_unit "iu" 1 0
+  (and (eq_attr "type" "fpload")
+       (eq_attr "cpu" "ppc601"))
+  3 1)
+
+(define_function_unit "iu2" 2 0
+  (and (eq_attr "type" "load,fpload")
+       (eq_attr "cpu" "rios2"))
+  2 1)
+
+(define_function_unit "iu2" 2 0
+  (and (eq_attr "type" "store,fpstore")
+       (eq_attr "cpu" "rios2"))
+  1 1)
+
+; Integer Unit (RIOS1, PPC601, PPC603)
+(define_function_unit "iu" 1 0
+  (and (eq_attr "type" "integer")
+       (eq_attr "cpu" "rios1,mpccore,ppc403,ppc601,ppc603"))
+  1 1)
 
 (define_function_unit "iu" 1 0
   (and (eq_attr "type" "imul")
 
 (define_function_unit "iu" 1 0
   (and (eq_attr "type" "imul")
-       (eq_attr "cpu" "ppc601,ppc602,ppc603"))
+       (eq_attr "cpu" "rios1,ppc601,ppc603"))
   5 5)
 
 (define_function_unit "iu" 1 0
 
 (define_function_unit "iu" 1 0
   (and (eq_attr "type" "idiv")
-       (eq_attr "cpu" "ppc601"))
-  36 36)
+       (eq_attr "cpu" "ppc403"))
+  33 33)
 
 (define_function_unit "iu" 1 0
   (and (eq_attr "type" "idiv")
-       (eq_attr "cpu" "ppc403"))
-  33 33)
+       (eq_attr "cpu" "ppc601"))
+  36 36)
 
 (define_function_unit "iu" 1 0
   (and (eq_attr "type" "idiv")
-       (eq_attr "cpu" "ppc602,ppc603"))
+       (eq_attr "cpu" "ppc603"))
   37 36)
 
 ; RIOS2 has two integer units: a primary one which can perform all
 (define_function_unit "iu2" 2 0
   (and (eq_attr "type" "integer")
        (eq_attr "cpu" "rios2"))
-  1 0)
+  1 1)
 
 (define_function_unit "iu2" 2 0
   (and (eq_attr "type" "imul")
        (eq_attr "cpu" "rios2"))
   2 2)
 
-
 (define_function_unit "imuldiv" 1 0
   (and (eq_attr "type" "idiv")
        (eq_attr "cpu" "rios2"))
 (define_function_unit "iu2" 2 0
   (and (eq_attr "type" "integer")
        (eq_attr "cpu" "ppc604,ppc620"))
-  1 1
-  [(eq_attr "type" "imul,idiv")])
+  1 1)
 
 (define_function_unit "imuldiv" 1 0
   (and (eq_attr "type" "imul")
        (eq_attr "cpu" "ppc604,ppc620"))
-  4 2
-  [(eq_attr "type" "integer")])
+  4 2)
 
 (define_function_unit "imuldiv" 1 0
   (and (eq_attr "type" "idiv")
        (eq_attr "cpu" "ppc604,ppc620"))
-  20 19
-  [(eq_attr "type" "integer")])
+  20 19)
 
 ; compare is done on integer unit, but feeds insns which
 ; execute on the branch unit.  Ready-delay of the compare 
 ; able to fill the compare-branch delay, with insns on iu/fpu.
 (define_function_unit "iu" 1 0   
   (and (eq_attr "type" "compare")
-       (eq_attr "cpu" "rios1,mpccore,ppc601"))
-  1 1)
+       (eq_attr "cpu" "rios1"))
+  4 1)
+
+(define_function_unit "iu" 1 0   
+  (and (eq_attr "type" "delayed_compare")
+       (eq_attr "cpu" "rios1"))
+  5 1)
+
+(define_function_unit "iu" 1 0
+  (and (eq_attr "type" "compare,delayed_compare")
+       (eq_attr "cpu" "mpccore,ppc403,ppc601,ppc603,ppc604,ppc620"))
+  3 1)
 
 (define_function_unit "iu2" 2 0   
-  (and (eq_attr "type" "compare")
+  (and (eq_attr "type" "compare,delayed_compare")
        (eq_attr "cpu" "rios2"))
-  1 1)
-
-(define_function_unit "bpu" 1 0   
-  (and (eq_attr "type" "compare")
-       (eq_attr "cpu" "rios1,rios2,ppc403,mpccore,ppc601,ppc603,ppc604,ppc620"))
-  4 1)
+  3 1)
 
-; different machines have different compare timings
-; in ppc604, compare is done on the one of the two
-; main integer units.
 (define_function_unit "iu2" 2 0
-  (and (eq_attr "type" "compare")
+  (and (eq_attr "type" "compare,delayed_compare")
        (eq_attr "cpu" "ppc604,ppc620"))
   1 1)
 
-(define_function_unit "bpu" 1 0
-  (eq_attr "type" "delayed_compare")
-  5 0)
-
 ; fp compare uses fp unit
 (define_function_unit "fpu" 1 0
   (and (eq_attr "type" "fpcompare")
        (eq_attr "cpu" "rios1"))
-  8 1)
+  9 1)
 
 ; rios1 and rios2 have different fpcompare delays
 (define_function_unit "fpu2" 2 0
 ; on ppc601 and ppc603, fpcompare takes also 2 cycles from
 ; the integer unit
 ; here we do not define delays, just occupy the unit. The dependencies
-; will be signed by the fpcompare definition in the fpu.
+; will be assigned by the fpcompare definition in the fpu.
 (define_function_unit "iu" 1 0
   (and (eq_attr "type" "fpcompare")
-       (eq_attr "cpu" "ppc601,ppc602,ppc603"))
+       (eq_attr "cpu" "ppc601,ppc603"))
   0 2)
 
 ; fp compare uses fp unit
 (define_function_unit "fpu" 1 0
   (and (eq_attr "type" "fpcompare")
-       (eq_attr "cpu" "ppc601,ppc602,ppc603,ppc604,ppc620"))
+       (eq_attr "cpu" "ppc601,ppc603,ppc604,ppc620"))
   5 1)
 
 (define_function_unit "fpu" 1 0
 (define_function_unit "bpu" 1 0
   (and (eq_attr "type" "mtjmpr")
        (eq_attr "cpu" "rios1,rios2"))
-  5 0)
+  5 1)
 
 (define_function_unit "bpu" 1 0
   (and (eq_attr "type" "mtjmpr")
-       (eq_attr "cpu" "ppc403,mpccore,ppc601,ppc602,ppc603,ppc604,ppc620"))
-  4 0)
+       (eq_attr "cpu" "mpccore,ppc403,ppc601,ppc603,ppc604,ppc620"))
+  4 1)
 
 ; all jumps/branches are executing on the bpu, in 1 cycle, for all machines.
 (define_function_unit "bpu" 1 0
   (eq_attr "type" "jmpreg")
-  1 0)
+  1 1)
 
 (define_function_unit "bpu" 1 0
   (eq_attr "type" "branch")
-  1 0)
+  1 1)
 
 ; Floating Point Unit
 (define_function_unit "fpu" 1 0
   (and (eq_attr "type" "fp,dmul")
        (eq_attr "cpu" "rios1"))
-  2 0)
+  2 1)
 
 (define_function_unit "fpu" 1 0
   (and (eq_attr "type" "fp")
 (define_function_unit "fpu" 1 0
   (and (eq_attr "type" "fp")
        (eq_attr "cpu" "ppc601"))
-  4 0)
+  4 1)
 
 (define_function_unit "fpu" 1 0
   (and (eq_attr "type" "fp")
-       (eq_attr "cpu" "ppc602,ppc603,ppc604,ppc620"))
+       (eq_attr "cpu" "ppc603,ppc604,ppc620"))
   3 1)
 
 (define_function_unit "fpu" 1 0
 ; is this true?
 (define_function_unit "fpu" 1 0
   (and (eq_attr "type" "dmul")
-       (eq_attr "cpu" "ppc602,ppc603"))
+       (eq_attr "cpu" "ppc603"))
   4 2)
 
 (define_function_unit "fpu" 1 0
 
 (define_function_unit "fpu" 1 0
   (and (eq_attr "type" "sdiv")
-       (eq_attr "cpu" "ppc602,ppc603,ppc604,ppc620"))
+       (eq_attr "cpu" "ppc603,ppc604,ppc620"))
   18 18)
 
 (define_function_unit "fpu" 1 0
 
 (define_function_unit "fpu" 1 0
   (and (eq_attr "type" "ddiv")
-       (eq_attr "cpu" "ppc602,ppc603"))
+       (eq_attr "cpu" "ppc603"))
   33 33)
 
 (define_function_unit "fpu" 1 0
 (define_function_unit "fpu2" 2 0
   (and (eq_attr "type" "fp")
        (eq_attr "cpu" "rios2"))
-  2 0)
+  2 1)
 
 (define_function_unit "fpu2" 2 0
   (and (eq_attr "type" "dmul")
        (eq_attr "cpu" "rios2"))
-  2 0)
+  2 1)
 
 (define_function_unit "fpu2" 2 0
   (and (eq_attr "type" "sdiv,ddiv")
                      (const_int 32))))
    (clobber (match_scratch:SI 0 "=l"))]
   "! TARGET_POWER && ! TARGET_POWERPC"
-  "bla __mulh")
+  "bla __mulh"
+  [(set_attr "type" "imul")])
 
 (define_insn "mull_call"
   [(set (reg:DI 3)
    (clobber (match_scratch:SI 0 "=l"))
    (clobber (reg:SI 0))]
   "! TARGET_POWER && ! TARGET_POWERPC"
-  "bla __mull")
+  "bla __mull"
+  [(set_attr "type" "imul")])
 
 (define_insn "divss_call"
   [(set (reg:SI 3)
    (clobber (match_scratch:SI 0 "=l"))
    (clobber (reg:SI 0))]
   "! TARGET_POWER && ! TARGET_POWERPC"
-  "bla __divss")
+  "bla __divss"
+  [(set_attr "type" "idiv")])
 
 (define_insn "divus_call"
   [(set (reg:SI 3)
    (clobber (match_scratch:CC 1 "=x"))
    (clobber (reg:CC 69))]
   "! TARGET_POWER && ! TARGET_POWERPC"
-  "bla __divus")
+  "bla __divus"
+  [(set_attr "type" "idiv")])
 
 (define_insn "quoss_call"
   [(set (reg:SI 3)
        (div:SI (reg:SI 3) (reg:SI 4)))
    (clobber (match_scratch:SI 0 "=l"))]
   "! TARGET_POWER && ! TARGET_POWERPC"
-  "bla __quoss")
+  "bla __quoss"
+  [(set_attr "type" "idiv")])
 
 (define_insn "quous_call"
   [(set (reg:SI 3)
    (clobber (match_scratch:CC 1 "=x"))
    (clobber (reg:CC 69))]
   "! TARGET_POWER && ! TARGET_POWERPC"
-  "bla __quous")
+  "bla __quous"
+  [(set_attr "type" "idiv")])
 \f
 (define_insn "andsi3"
   [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r,r,r")
    mt%0 %1
    mt%0 %1
    cror 0,0,0"
-  [(set_attr "type" "*,load,load,*,load,*,*,*,*,*,*,*,mtjmpr,*")
+  [(set_attr "type" "*,load,load,*,load,store,*,*,*,*,*,*,mtjmpr,*")
    (set_attr "length" "4,4,4,4,4,4,4,4,8,4,4,4,4,4")])
 
 ;; Split a load of a large constant into the appropriate two-insn
    mt%0 %1
    mt%0 %1
    cror 0,0,0"
-  [(set_attr "type" "*,load,*,*,*,*,mtjmpr,*")])
+  [(set_attr "type" "*,load,store,*,*,*,mtjmpr,*")])
 
 (define_expand "movqi"
   [(set (match_operand:QI 0 "general_operand" "")
    mt%0 %1
    mt%0 %1
    cror 0,0,0"
-  [(set_attr "type" "*,load,*,*,*,*,mtjmpr,*")])
+  [(set_attr "type" "*,load,store,*,*,*,mtjmpr,*")])
 \f
 ;; Here is how to move condition codes around.  When we store CC data in
 ;; an integer register or memory, we store just the high-order 4 bits.
    mr %0,%1
    {l%U1%X1|lwz%U1%X1} %0,%1
    {st%U0%U1|stw%U0%U1} %1,%0"
-  [(set_attr "type" "*,*,*,compare,*,*,load,*")
+  [(set_attr "type" "*,*,*,compare,*,*,load,store")
    (set_attr "length" "*,*,12,*,8,*,*,*")])
 \f
 ;; For floating-point, we normally deal with the floating-point registers
    fmr %0,%1
    lfs%U1%X1 %0,%1
    stfs%U0%X0 %1,%0"
-  [(set_attr "type" "fp,fpload,*")])
+  [(set_attr "type" "fp,fpload,fpstore")])
 
 (define_insn ""
   [(set (match_operand:SF 0 "nonimmediate_operand" "=r,r,m,r,r,r")
    {lil|li} %0,%1
    {liu|lis} %0,%u1
    {cal|la} %0,%1(%*)"
-  [(set_attr "type" "*,load,*,*,*,*")])
+  [(set_attr "type" "*,load,store,*,*,*")])
 
 \f
 (define_expand "movdf"
       return \"stfd%U0%X0 %1,%0\";
     }
 }"
-  [(set_attr "type" "*,load,*,*,fp,fpload,*")
+  [(set_attr "type" "*,load,store,*,fp,fpload,fpstore")
    (set_attr "length" "8,8,8,8,*,*,*")])
 
 (define_insn ""
       return \"#\";
     }
 }"
-  [(set_attr "type" "*,load,*,*")
+  [(set_attr "type" "*,load,store,*")
    (set_attr "length" "8,8,8,8")])
 
 (define_insn ""
    fmr %0,%1
    lfd%U1%X1 %0,%1
    stfd%U0%X0 %1,%0"
-  [(set_attr "type" "*,load,*,*,fp,fpload,*")])
+  [(set_attr "type" "*,load,store,*,fp,fpload,fpstore")])
 
 (define_insn ""
   [(set (match_operand:DF 0 "nonimmediate_operand" "=r,r,o,r")
    ld%U1%X1 %0,%1
    std%U0%X0 %1,%0
    #"
-  [(set_attr "type" "*,load,*,*")])
+  [(set_attr "type" "*,load,store,*")])
 \f
 ;; Next come the multi-word integer load and store and the load and store
 ;; multiple insns.
       return \"stfd%U0%X0 %1,%0\";
     }
 }"
-  [(set_attr "type" "*,load,*,fp,fpload,*")
+  [(set_attr "type" "*,load,store,fp,fpload,fpstore")
    (set_attr "length" "8,8,8,*,*,*")])
 
 (define_insn ""
    mf%1 %0
    mt%0 %1
    cror 0,0,0"
-  [(set_attr "type" "*,load,*,*,*,*,*,fp,fpload,*,*,mtjmpr,*")
+  [(set_attr "type" "*,load,store,*,*,*,*,fp,fpload,fpstore,*,mtjmpr,*")
    (set_attr "length" "4,4,4,4,4,20,4,4,4,4,4,4,4")])
 
 ;; Split a load of a large constant into the appropriate five-instruction
        return \"{l%U1|lwz%U1} %0,%1\;{l|lwz} %L0,%L1\;{l|lwz} %Y0,%Y1\;{l|lwz} %Z0,%Z1\";
     }
 }"
-  [(set_attr "type" "*,load,load,*,*")
+  [(set_attr "type" "store,store,*,load,load")
    (set_attr "length" "*,16,16,*,16")])
 
 (define_insn ""
        return \"{l%U1|lwz%U1} %0,%1\;{l|lwz} %L0,%L1\;{l|lwz} %Y0,%Y1\;{l|lwz} %Z0,%Z1\";
     }
 }"
-  [(set_attr "type" "load,*,*")
+  [(set_attr "type" "store,*,load")
    (set_attr "length" "16,16,16")])
 
 (define_insn ""
       return \"std%U0 %1,%0\;std %L1,%L0\";
     }
 }"
-  [(set_attr "type" "*,load,*")
+  [(set_attr "type" "*,load,store")
    (set_attr "length" "8,8,8")])
 \f
 (define_expand "load_multiple"
 }"
   [(set_attr "type" "load")
    (set_attr "length" "32")])
-\f
 
+\f
 (define_expand "store_multiple"
   [(match_par_dup 3 [(set (match_operand:SI 0 "" "")
                          (match_operand:SI 1 "" ""))
                         (match_operand:SI 2 "gpc_reg_operand" "r"))
                    (clobber (match_scratch:SI 3 "=q"))])]
   "TARGET_STRING && TARGET_POWER"
-  "{stsi|stswi} %2,%P1,%O0")
+  "{stsi|stswi} %2,%P1,%O0"
+  [(set_attr "type" "store")])
 
 (define_insn ""
   [(match_parallel 0 "store_multiple_operation"
                         (match_operand:SI 2 "gpc_reg_operand" "r"))
                    (clobber (match_scratch:SI 3 "X"))])]
   "TARGET_STRING && !TARGET_POWER"
-  "{stsi|stswi} %2,%1,%O0")
+  "{stsi|stswi} %2,%1,%O0"
+  [(set_attr "type" "store")])
 
 \f
 ;; String/block move insn.
    && (REGNO (operands[1]) < 5 || REGNO (operands[1]) > 12)
    && REGNO (operands[4]) == 5"
   "{lsi|lswi} %4,%1,%2\;{stsi|stswi} %4,%0,%2"
-  [(set_attr "length" "8")])
+  [(set_attr "type" "load")
+   (set_attr "length" "8")])
 
 (define_insn ""
   [(set (mem:BLK (match_operand:SI 0 "register_operand" "b"))
    && (REGNO (operands[1]) < 5 || REGNO (operands[1]) > 12)
    && REGNO (operands[4]) == 5"
   "{lsi|lswi} %4,%1,%2\;{stsi|stswi} %4,%0,%2"
-  [(set_attr "length" "8")])
+  [(set_attr "type" "load")
+   (set_attr "length" "8")])
 
 ;; Move up to 24 bytes at a time.  The fixed registers are needed because the
 ;; register allocator doesn't have a clue about allocating 6 word registers
    && (REGNO (operands[1]) < 7 || REGNO (operands[1]) > 12)
    && REGNO (operands[4]) == 7"
   "{lsi|lswi} %4,%1,%2\;{stsi|stswi} %4,%0,%2"
-  [(set_attr "length" "8")])
+  [(set_attr "type" "load")
+   (set_attr "length" "8")])
 
 (define_insn ""
   [(set (mem:BLK (match_operand:SI 0 "register_operand" "b"))
    && (REGNO (operands[1]) < 7 || REGNO (operands[1]) > 12)
    && REGNO (operands[4]) == 7"
   "{lsi|lswi} %4,%1,%2\;{stsi|stswi} %4,%0,%2"
-  [(set_attr "length" "8")])
+  [(set_attr "type" "load")
+   (set_attr "length" "8")])
 
 ;; Move up to 16 bytes at a time, using 4 fixed registers to avoid spill problems
 ;; with TImode
    && (REGNO (operands[1]) < 9 || REGNO (operands[1]) > 12)
    && REGNO (operands[4]) == 9"
   "{lsi|lswi} %4,%1,%2\;{stsi|stswi} %4,%0,%2"
-  [(set_attr "length" "8")])
+  [(set_attr "type" "load")
+   (set_attr "length" "8")])
 
 (define_insn ""
   [(set (mem:BLK (match_operand:SI 0 "register_operand" "b"))
    && (REGNO (operands[1]) < 9 || REGNO (operands[1]) > 12)
    && REGNO (operands[4]) == 9"
   "{lsi|lswi} %4,%1,%2\;{stsi|stswi} %4,%0,%2"
-  [(set_attr "length" "8")])
+  [(set_attr "type" "load")
+   (set_attr "length" "8")])
 
 ;; Move up to 8 bytes at a time.
 (define_expand "movstrsi_2reg"
   "TARGET_STRING && TARGET_POWER && !TARGET_64BIT
    && INTVAL (operands[2]) > 4 && INTVAL (operands[2]) <= 8"
   "{lsi|lswi} %4,%1,%2\;{stsi|stswi} %4,%0,%2"
-  [(set_attr "length" "8")])
+  [(set_attr "type" "load")
+   (set_attr "length" "8")])
 
 (define_insn ""
   [(set (mem:BLK (match_operand:SI 0 "register_operand" "b"))
   "TARGET_STRING && !TARGET_POWER && !TARGET_64BIT
    && INTVAL (operands[2]) > 4 && INTVAL (operands[2]) <= 8"
   "{lsi|lswi} %4,%1,%2\;{stsi|stswi} %4,%0,%2"
-  [(set_attr "length" "8")])
+  [(set_attr "type" "load")
+   (set_attr "length" "8")])
 
 ;; Move up to 4 bytes at a time.
 (define_expand "movstrsi_1reg"
   "TARGET_STRING && TARGET_POWER
    && INTVAL (operands[2]) > 0 && INTVAL (operands[2]) <= 4"
   "{lsi|lswi} %4,%1,%2\;{stsi|stswi} %4,%0,%2"
-  [(set_attr "length" "8")])
+  [(set_attr "type" "load")
+   (set_attr "length" "8")])
 
 (define_insn ""
   [(set (mem:BLK (match_operand:SI 0 "register_operand" "b"))
   "TARGET_STRING && !TARGET_POWER
    && INTVAL (operands[2]) > 0 && INTVAL (operands[2]) <= 4"
   "{lsi|lswi} %4,%1,%2\;{stsi|stswi} %4,%0,%2"
-  [(set_attr "length" "8")])
+  [(set_attr "type" "load")
+   (set_attr "length" "8")])
 
 \f
 ;; Define insns that do load or store with update.  Some of these we can
   "TARGET_POWERPC64"
   "@
    stdux %3,%0,%2
-   stdu %3,%2(%0)")
+   stdu %3,%2(%0)"
+  [(set_attr "type" "store")])
 
 (define_insn ""
   [(set (match_operand:SI 3 "gpc_reg_operand" "=r,r")
   ""
   "@
    {stux|stwux} %3,%0,%2
-   {stu|stwu} %3,%2(%0)")
+   {stu|stwu} %3,%2(%0)"
+  [(set_attr "type" "store")])
 
 (define_insn ""
   [(set (match_operand:HI 3 "gpc_reg_operand" "=r,r")
   ""
   "@
    sthux %3,%0,%2
-   sthu %3,%2(%0)")
+   sthu %3,%2(%0)"
+  [(set_attr "type" "store")])
 
 (define_insn ""
   [(set (match_operand:QI 3 "gpc_reg_operand" "=r,r")
   ""
   "@
    stbux %3,%0,%2
-   stbu %3,%2(%0)")
+   stbu %3,%2(%0)"
+  [(set_attr "type" "store")])
 
 (define_insn ""
   [(set (match_operand:SF 3 "gpc_reg_operand" "=f,f")
   "TARGET_HARD_FLOAT"
   "@
    stfsux %3,%0,%2
-   stfsu %3,%2(%0)")
+   stfsu %3,%2(%0)"
+  [(set_attr "type" "fpstore")])
 
 (define_insn ""
   [(set (match_operand:DF 3 "gpc_reg_operand" "=f,f")
   "TARGET_HARD_FLOAT"
   "@
    stfdux %3,%0,%2
-   stfdu %3,%2(%0)")
+   stfdu %3,%2(%0)"
+  [(set_attr "type" "fpstore")])
 
 ;; Peephole to convert two consecutive FP loads or stores into lfq/stfq.
 
   emit_move_insn (gen_rtx (MEM, SImode, operands[0]), temp);
   DONE;
 }")
-\f
 
+\f
 ;; A function pointer under AIX is a pointer to a data area whose first word
 ;; contains the actual address of the function, whose second word contains a
 ;; pointer to its TOC, and whose third word contains a value to place in the
   "DEFAULT_ABI == ABI_AIX
    && (INTVAL (operands[2]) == CALL_NORMAL || (INTVAL (operands[2]) & CALL_LONG) != 0)"
   "{st|stw} %4,%a3\;{l|lwz} %6,0(%0)\;{l|lwz} %4,4(%0)\;mt%7 %6\;{l|lwz} %5,8(%0)\;{brl|blrl}\;{l|lwz} %4,%a3"
-  [(set_attr "length" "28")])
+  [(set_attr "type" "load")
+   (set_attr "length" "28")])
 
 (define_insn "call_value_indirect_aix"
   [(set (match_operand 0 "register_operand" "fg")
   "DEFAULT_ABI == ABI_AIX
    && (INTVAL (operands[3]) == CALL_NORMAL || (INTVAL (operands[3]) & CALL_LONG) != 0)"
   "{st|stw} %5,%a4\;{l|lwz} %7,0(%1)\;{l|lwz} %5,4(%1);\;mt%8 %7\;{l|lwz} %6,8(%1)\;{brl|blrl}\;{l|lwz} %5,%a4"
-  [(set_attr "length" "28")])
+  [(set_attr "type" "load")
+   (set_attr "length" "28")])
 
 ;; A function pointer undef NT is a pointer to a data area whose first word
 ;; contains the actual address of the function, whose second word contains a
   "DEFAULT_ABI == ABI_NT
    && (INTVAL (operands[2]) == CALL_NORMAL || (INTVAL (operands[2]) & CALL_LONG) != 0)"
   "{st|stw} %4,%a3\;{l|lwz} %5,0(%0)\;{l|lwz} %4,4(%0)\;mt%6 %5\;{brl|blrl}\;{l|lwz} %4,%a3"
-  [(set_attr "length" "24")])
+  [(set_attr "type" "load")
+   (set_attr "length" "24")])
 
 (define_insn "call_value_indirect_nt"
   [(set (match_operand 0 "register_operand" "fg")
   "DEFAULT_ABI == ABI_NT
    && (INTVAL (operands[3]) == CALL_NORMAL || (INTVAL (operands[3]) & CALL_LONG) != 0)"
   "{st|stw} %5,%a4\;{l|lwz} %6,0(%1)\;{l|lwz} %5,4(%1)\;mt%7 %6\;{brl|blrl}\;{l|lwz} %5,%a4"
-  [(set_attr "length" "24")])
+  [(set_attr "type" "load")
+   (set_attr "length" "24")])
 
 ;; A function pointer under System V is just a normal pointer
 ;; operands[0] is the function pointer
 
   return \"{brl|blrl}\";
 }"
-  [(set_attr "length" "4,8")])
+  [(set_attr "type" "jmpreg")
+   (set_attr "length" "4,8")])
 
 (define_insn "call_value_indirect_sysv"
   [(set (match_operand 0 "register_operand" "=fg,fg")
 
   return \"{brl|blrl}\";
 }"
-  [(set_attr "length" "4,8")])
+  [(set_attr "type" "jmpreg")
+   (set_attr "length" "4,8")])
 
 ;; Now the definitions for the call and call_value insns
 (define_expand "call"
 
   return \"bl %z0\";
 }"
-  [(set_attr "length" "4,8")])
+  [(set_attr "type" "branch")
+   (set_attr "length" "4,8")])
 
 ;; Call to function which may be in another module.  Restore the TOC
 ;; pointer (r2) after the call unless this is System V.
 
   return (TARGET_WINDOWS_NT) ? \"bl %z0\;.znop %z0\" : \"bl %z0\;%.\";
 }"
-  [(set_attr "length" "8,12")])
+  [(set_attr "type" "branch")
+   (set_attr "length" "8,12")])
 
 (define_insn ""
   [(call (mem:SI (match_operand:SI 0 "call_operand" "s,s"))
 
   return \"bl %z0\";
 }"
-  [(set_attr "length" "4,8")])
+  [(set_attr "type" "branch")
+   (set_attr "length" "4,8")])
 
 (define_insn ""
   [(set (match_operand 0 "" "=fg,fg")
 
   return \"bl %z1\";
 }"
-  [(set_attr "length" "4,8")])
+  [(set_attr "type" "branch")
+   (set_attr "length" "4,8")])
 
 (define_insn ""
   [(set (match_operand 0 "" "=fg,fg")
 
   return (TARGET_WINDOWS_NT) ? \"bl %z1\;.znop %z1\" : \"bl %z1\;%.\";
 }"
-  [(set_attr "length" "8,12")])
+  [(set_attr "type" "branch")
+   (set_attr "length" "8,12")])
 
 (define_insn ""
   [(set (match_operand 0 "" "=fg,fg")
 
   return \"bl %z1\";
 }"
-  [(set_attr "length" "4,8")])
-
+  [(set_attr "type" "branch")
+   (set_attr "length" "4,8")])
 
 ;; Call subroutine returning any type.
-
 (define_expand "untyped_call"
   [(parallel [(call (match_operand 0 "" "")
                    (const_int 0))
                      (pc)))]
   "direct_return ()"
   "{%C0bcr|%C0bclr} %t0,%j0"
-  [(set_attr "length" "8")])
+  [(set_attr "type" "branch")
+   (set_attr "length" "8")])
 
 (define_insn ""
   [(set (pc)
                      (return)))]
   "direct_return ()"
   "{%C0bcr|%C0bclr} %T0,%j0"
-  [(set_attr "length" "8")])
+  [(set_attr "type" "branch")
+   (set_attr "length" "8")])
 
 ;; Unconditional branch and return.
 
   [(set (pc)
        (label_ref (match_operand 0 "" "")))]
   ""
-  "b %l0")
+  "b %l0"
+  [(set_attr "type" "branch")])
 
 (define_insn "return"
   [(return)]