+ "fr400_m2")
+
+;; ::::::::::::::::::::
+;; ::
+;; :: FR450 media scheduler description
+;; ::
+;; ::::::::::::::::::::
+
+;; The FR451 media restrictions are similar to the FR400's, but not as
+;; strict and not as regular. There are 6 categories with the following
+;; restrictions:
+;;
+;; M1
+;; M-1 M-2 M-3 M-4 M-5 M-6
+;; M-1: x x x
+;; M-2: x x x x x x
+;; M0 M-3: x x x
+;; M-4: x x x x
+;; M-5: x x x
+;; M-6: x x x x x x
+;;
+;; where "x" indicates a conflict.
+;;
+;; There is no difference between M-1 and M-3 as far as issue
+;; restrictions are concerned, so they are combined as "m13".
+
+;; Units for odd-numbered categories. There can be two of these
+;; in a packet.
+(define_cpu_unit "fr450_m13a,fr450_m13b" "float_media")
+(define_cpu_unit "fr450_m5a,fr450_m5b" "float_media")
+
+;; Units for even-numbered categories. There can only be one per packet.
+(define_cpu_unit "fr450_m2a,fr450_m4a,fr450_m6a" "float_media")
+
+;; Enforce the restriction matrix above.
+(exclusion_set "fr450_m2a,fr450_m4a,fr450_m6a" "fr450_m13a,fr450_m13b")
+(exclusion_set "fr450_m2a,fr450_m6a" "fr450_m5a,fr450_m5b")
+(exclusion_set "fr450_m4a,fr450_m6a" "fr450_m2a")
+
+(define_reservation "fr450_m13" "(f1|f0) + (fr450_m13a|fr450_m13b)")
+(define_reservation "fr450_m2" "f0 + fr450_m2a")
+(define_reservation "fr450_m4" "f0 + fr450_m4a")
+(define_reservation "fr450_m5" "(f1|f0) + (fr450_m5a|fr450_m5b)")
+(define_reservation "fr450_m6" "(f0|f1) + fr450_m6a")
+
+;; MD-1, MD-3 and MD-8 instructions, which are the same as far
+;; as scheduling is concerned. The inputs and outputs are FPRs.
+;; Instructions that have 32-bit inputs and outputs belong to M-1 while
+;; the rest belong to M-2.
+;;
+;; ??? Arithmetic shifts (MD-6) have an extra cycle latency, but we don't
+;; make the distinction between them and logical shifts.
+(define_insn_reservation "fr450_md138_1" 1
+ (and (eq_attr "cpu" "fr450")
+ (eq_attr "type" "fsconv,mnop,mlogic,maveh,msath,maddh,mabsh,mset,
+ mrot,mshift,mexpdhw,mpackh"))
+ "fr450_m13")
+
+(define_insn_reservation "fr450_md138_2" 1
+ (and (eq_attr "cpu" "fr450")
+ (eq_attr "type" "mqaddh,mqsath,mqlimh,
+ mdrot,mwcut,mqshift,mexpdhd,
+ munpackh,mdpackh,mbhconv,mcpl"))
+ "fr450_m2")
+
+;; MD-2 instructions. These take FPR or ACC inputs and produce an ACC output.
+;; Instructions that write to double ACCs belong to M-3 while those that write
+;; to quad ACCs belong to M-4.
+(define_insn_reservation "fr450_md2_3" 2
+ (and (eq_attr "cpu" "fr450")
+ (eq_attr "type" "mmulh,mmach,mcpx,mmulxh,mmrdh,maddacc"))
+ "fr450_m13")
+
+(define_insn_reservation "fr450_md2_4" 2
+ (and (eq_attr "cpu" "fr450")
+ (eq_attr "type" "mqmulh,mqmach,mqcpx,mqmulxh,mdaddacc"))
+ "fr450_m4")
+
+;; Another MD-2 instruction can use the result on the following cycle.
+(define_bypass 1 "fr450_md2_3,fr450_md2_4" "fr450_md2_3,fr450_md2_4")
+
+;; MD-4 instructions that write to ACCs.
+(define_insn_reservation "fr450_md4_3" 2
+ (and (eq_attr "cpu" "fr450")
+ (eq_attr "type" "mclracc"))
+ "fr450_m13")
+
+(define_insn_reservation "fr450_md4_4" 3
+ (and (eq_attr "cpu" "fr450")
+ (eq_attr "type" "mclracca"))
+ "fr450_m4")
+
+;; MD-4 instructions that write to FPRs.
+(define_insn_reservation "fr450_md4_1" 2
+ (and (eq_attr "cpu" "fr450")
+ (eq_attr "type" "mcut"))
+ "fr450_m13")
+
+(define_insn_reservation "fr450_md4_5" 2
+ (and (eq_attr "cpu" "fr450")
+ (eq_attr "type" "mrdacc"))
+ "fr450_m5")
+
+(define_insn_reservation "fr450_md4_6" 2
+ (and (eq_attr "cpu" "fr450")
+ (eq_attr "type" "mdcut"))
+ "fr450_m6")
+
+;; Integer instructions can read the FPR result of an MD-4 instruction on
+;; the following cycle.
+(define_bypass 1 "fr450_md4_1,fr450_md4_5,fr450_md4_6"
+ "fr400_i3,fr450_i4_movfg")
+
+;; MD-5 instructions, which belong to M-3. They take FPR inputs and
+;; write to ACCs.
+(define_insn_reservation "fr450_md5_3" 2
+ (and (eq_attr "cpu" "fr450")
+ (eq_attr "type" "mwtacc"))
+ "fr450_m13")
+
+;; ::::::::::::::::::::
+;; ::
+;; :: FR550 scheduler description
+;; ::
+;; ::::::::::::::::::::
+
+;; Prevent loads and stores from being issued in the same packet.
+;; These units must go into the generic "integer" reservation because
+;; of the constraints on fr550_store0 and fr550_store1.
+(define_cpu_unit "fr550_load0,fr550_load1" "integer")
+(define_cpu_unit "fr550_store0,fr550_store1" "integer")
+(exclusion_set "fr550_load0,fr550_load1" "fr550_store0,fr550_store1")
+
+;; A store can only issue to I1 if one has also been issued to I0.
+(presence_set "fr550_store1" "fr550_store0")
+
+(define_bypass 0 "fr550_sethi" "fr550_setlo")
+(define_insn_reservation "fr550_sethi" 1
+ (and (eq_attr "cpu" "fr550")
+ (eq_attr "type" "sethi"))
+ "i3|i2|i1|i0")
+
+(define_insn_reservation "fr550_setlo" 1
+ (and (eq_attr "cpu" "fr550")
+ (eq_attr "type" "setlo"))
+ "i3|i2|i1|i0")
+
+(define_insn_reservation "fr550_int" 1
+ (and (eq_attr "cpu" "fr550")
+ (eq_attr "type" "int"))
+ "i3|i2|i1|i0")
+
+(define_insn_reservation "fr550_mul" 2
+ (and (eq_attr "cpu" "fr550")
+ (eq_attr "type" "mul"))
+ "i1|i0")
+
+(define_insn_reservation "fr550_div" 19
+ (and (eq_attr "cpu" "fr550")
+ (eq_attr "type" "div"))
+ "(i1|i0),(idiv1*18 | idiv2*18)")
+
+(define_insn_reservation "fr550_load" 3
+ (and (eq_attr "cpu" "fr550")
+ (eq_attr "type" "gload,fload"))
+ "(i1|i0)+(fr550_load0|fr550_load1)")
+
+;; We can only issue a store to I1 if one was also issued to I0.
+;; This means that, as far as frv_reorder_packet is concerned,
+;; the instruction has the same priority as an I0-only instruction.
+(define_insn_reservation "fr550_store" 1
+ (and (eq_attr "cpu" "fr550")
+ (eq_attr "type" "gstore,fstore"))
+ "(i0+fr550_store0)|(i1+fr550_store1)")
+
+(define_insn_reservation "fr550_transfer" 2
+ (and (eq_attr "cpu" "fr550")
+ (eq_attr "type" "movgf,movfg"))
+ "i0")
+
+(define_insn_reservation "fr550_jumpl" 0
+ (and (eq_attr "cpu" "fr550")
+ (eq_attr "type" "jumpl"))
+ "i0")
+
+(define_cpu_unit "fr550_ccr0,fr550_ccr1" "float_media")
+
+(define_insn_reservation "fr550_branch" 0
+ (and (eq_attr "cpu" "fr550")
+ (eq_attr "type" "jump,branch"))
+ "b1|b0")
+
+(define_insn_reservation "fr550_ccr" 0
+ (and (eq_attr "cpu" "fr550")
+ (eq_attr "type" "ccr"))
+ "(b1|b0) + (fr550_ccr1|fr550_ccr0)")
+
+(define_insn_reservation "fr550_call" 0
+ (and (eq_attr "cpu" "fr550")
+ (eq_attr "type" "call"))
+ "b0")
+
+(define_automaton "fr550_float_media")
+(define_cpu_unit "fr550_add0,fr550_add1" "fr550_float_media")
+
+;; There are three possible combinations of floating-point/media instructions:
+;;
+;; - one media and one float
+;; - up to four float, no media
+;; - up to four media, no float
+(define_cpu_unit "fr550_f0,fr550_f1,fr550_f2,fr550_f3" "fr550_float_media")
+(define_cpu_unit "fr550_m0,fr550_m1,fr550_m2,fr550_m3" "fr550_float_media")
+(exclusion_set "fr550_f1,fr550_f2,fr550_f3" "fr550_m1,fr550_m2,fr550_m3")
+
+(define_reservation "fr550_float" "fr550_f0|fr550_f1|fr550_f2|fr550_f3")
+(define_reservation "fr550_media" "fr550_m0|fr550_m1|fr550_m2|fr550_m3")
+
+(define_insn_reservation "fr550_f1" 0
+ (and (eq_attr "cpu" "fr550")
+ (eq_attr "type" "fnop"))
+ "(f3|f2|f1|f0) + fr550_float")
+
+(define_insn_reservation "fr550_f2" 3
+ (and (eq_attr "cpu" "fr550")
+ (eq_attr "type" "fsconv,fsadd,fscmp"))
+ "(f3|f2|f1|f0) + (fr550_add0|fr550_add1) + fr550_float")
+
+(define_insn_reservation "fr550_f3_mul" 3
+ (and (eq_attr "cpu" "fr550")
+ (eq_attr "type" "fsmul"))
+ "(f1|f0) + fr550_float")
+
+(define_insn_reservation "fr550_f3_div" 10
+ (and (eq_attr "cpu" "fr550")
+ (eq_attr "type" "fsdiv"))
+ "(f1|f0) + fr550_float")
+
+(define_insn_reservation "fr550_f3_sqrt" 15
+ (and (eq_attr "cpu" "fr550")
+ (eq_attr "type" "sqrt_single"))
+ "(f1|f0) + fr550_float")
+
+;; Synthetic units for enforcing media issue restructions. Certain types
+;; of insn in M2 conflict with certain types in M0:
+;;
+;; M2
+;; MNOP MALU MSFT MMAC MSET
+;; MNOP - - x - -
+;; MALU - x x - -
+;; M0 MSFT - - x - x
+;; MMAC - - x x -
+;; MSET - - x - -
+;;
+;; where "x" indicates a conflict. The same restrictions apply to
+;; M3 and M1.
+;;
+;; In addition -- and this is the awkward bit! -- instructions that
+;; access ACC0-3 can only issue to M0 or M2. Those that access ACC4-7
+;; can only issue to M1 or M3. We refer to such instructions as "even"
+;; and "odd" respectively.
+(define_cpu_unit "fr550_malu0,fr550_malu1" "float_media")
+(define_cpu_unit "fr550_malu2,fr550_malu3" "float_media")
+(define_cpu_unit "fr550_msft0,fr550_msft1" "float_media")
+(define_cpu_unit "fr550_mmac0,fr550_mmac1" "float_media")
+(define_cpu_unit "fr550_mmac2,fr550_mmac3" "float_media")
+(define_cpu_unit "fr550_mset0,fr550_mset1" "float_media")
+(define_cpu_unit "fr550_mset2,fr550_mset3" "float_media")
+
+(exclusion_set "fr550_malu0" "fr550_malu2")
+(exclusion_set "fr550_malu1" "fr550_malu3")
+
+(exclusion_set "fr550_msft0" "fr550_mset2")
+(exclusion_set "fr550_msft1" "fr550_mset3")
+
+(exclusion_set "fr550_mmac0" "fr550_mmac2")
+(exclusion_set "fr550_mmac1" "fr550_mmac3")
+
+;; If an MSFT or MMAC instruction issues to a unit other than M0, we may
+;; need to insert some nops. In the worst case, the packet will end up
+;; having 4 integer instructions and 4 media instructions, leaving no
+;; room for any branch instructions that the DFA might have accepted.
+;;
+;; This doesn't matter for JUMP_INSNs and CALL_INSNs because they are
+;; always the last instructions to be passed to the DFA, and could be
+;; pushed out to a separate packet once the nops have been added.
+;; However, it does cause problems for ccr instructions since they
+;; can occur anywhere in the unordered packet.
+(exclusion_set "fr550_msft1,fr550_mmac1,fr550_mmac2,fr550_mmac3"
+ "fr550_ccr0,fr550_ccr1")
+
+(define_reservation "fr550_malu"
+ "(f3 + fr550_malu3) | (f2 + fr550_malu2)
+ | (f1 + fr550_malu1) | (f0 + fr550_malu0)")
+
+(define_reservation "fr550_msft_even"
+ "f0 + fr550_msft0")
+
+(define_reservation "fr550_msft_odd"
+ "f1 + fr550_msft1")
+
+(define_reservation "fr550_msft_either"
+ "(f1 + fr550_msft1) | (f0 + fr550_msft0)")
+
+(define_reservation "fr550_mmac_even"
+ "(f2 + fr550_mmac2) | (f0 + fr550_mmac0)")
+
+(define_reservation "fr550_mmac_odd"
+ "(f3 + fr550_mmac3) | (f1 + fr550_mmac1)")
+
+(define_reservation "fr550_mset"
+ "(f3 + fr550_mset3) | (f2 + fr550_mset2)
+ | (f1 + fr550_mset1) | (f0 + fr550_mset0)")
+
+(define_insn_reservation "fr550_mnop" 0
+ (and (eq_attr "cpu" "fr550")
+ (eq_attr "type" "mnop"))
+ "fr550_media + (f3|f2|f1|f0)")
+
+(define_insn_reservation "fr550_malu" 2
+ (and (eq_attr "cpu" "fr550")
+ (eq_attr "type" "mlogic,maveh,msath,mabsh,maddh,mqaddh,mqsath"))
+ "fr550_media + fr550_malu")
+
+;; These insns only operate on FPRs and so don't need to be classified
+;; as even/odd.
+(define_insn_reservation "fr550_msft_1_either" 2
+ (and (eq_attr "cpu" "fr550")
+ (eq_attr "type" "mrot,mwcut,mshift,mexpdhw,mexpdhd,mpackh,
+ munpackh,mdpackh,mbhconv,mdrot,mcpl"))
+ "fr550_media + fr550_msft_either")
+
+;; These insns read from ACC0-3.
+(define_insn_reservation "fr550_msft_1_even" 2
+ (and (eq_attr "cpu" "fr550")
+ (and (eq_attr "type" "mcut,mrdacc,mdcut")
+ (eq_attr "acc_group" "even")))
+ "fr550_media + fr550_msft_even")
+
+;; These insns read from ACC4-7.
+(define_insn_reservation "fr550_msft_1_odd" 2
+ (and (eq_attr "cpu" "fr550")
+ (and (eq_attr "type" "mcut,mrdacc,mdcut")
+ (eq_attr "acc_group" "odd")))
+ "fr550_media + fr550_msft_odd")
+
+;; MCLRACC with A=1 can issue to either M0 or M1.
+(define_insn_reservation "fr550_msft_2_either" 2
+ (and (eq_attr "cpu" "fr550")
+ (eq_attr "type" "mclracca"))
+ "fr550_media + fr550_msft_either")
+
+;; These insns write to ACC0-3.
+(define_insn_reservation "fr550_msft_2_even" 2
+ (and (eq_attr "cpu" "fr550")
+ (and (eq_attr "type" "mclracc,mwtacc")
+ (eq_attr "acc_group" "even")))
+ "fr550_media + fr550_msft_even")
+
+;; These insns write to ACC4-7.
+(define_insn_reservation "fr550_msft_2_odd" 2
+ (and (eq_attr "cpu" "fr550")
+ (and (eq_attr "type" "mclracc,mwtacc")
+ (eq_attr "acc_group" "odd")))
+ "fr550_media + fr550_msft_odd")
+
+;; These insns read from and write to ACC0-3.
+(define_insn_reservation "fr550_mmac_even" 2
+ (and (eq_attr "cpu" "fr550")
+ (and (eq_attr "type" "mmulh,mmulxh,mmach,mmrdh,mqmulh,mqmulxh,mqmach,
+ maddacc,mdaddacc,mcpx,mqcpx")
+ (eq_attr "acc_group" "even")))
+ "fr550_media + fr550_mmac_even")
+
+;; These insns read from and write to ACC4-7.
+(define_insn_reservation "fr550_mmac_odd" 2
+ (and (eq_attr "cpu" "fr550")
+ (and (eq_attr "type" "mmulh,mmulxh,mmach,mmrdh,mqmulh,mqmulxh,mqmach,
+ maddacc,mdaddacc,mcpx,mqcpx")
+ (eq_attr "acc_group" "odd")))
+ "fr550_media + fr550_mmac_odd")
+
+(define_insn_reservation "fr550_mset" 1
+ (and (eq_attr "cpu" "fr550")
+ (eq_attr "type" "mset"))
+ "fr550_media + fr550_mset")