📄 frv.md
字号:
(and (eq_attr "cpu" "generic,fr500,tomcat") (eq_attr "type" "fsdiv,fddiv")) "(f0|f1),(div1*9|div2*9)")(define_bypass 16 "f4_root" "m1,m2,m3,m4,m5,m6,m7")(define_insn_reservation "f4_root" 15 (and (eq_attr "cpu" "generic,fr500,tomcat") (eq_attr "type" "sqrt_single,sqrt_double")) "(f0|f1)+root*15")(define_bypass 4 "f5" "m1,m2,m3,m4,m5,m6,m7")(define_insn_reservation "f5" 3 (and (eq_attr "cpu" "generic,fr500,tomcat") (eq_attr "type" "fmas")) "(f0|f1)+(add0|add1)+(mul0|mul1)");; The following insns are not generated by gcc now:(define_insn_reservation "f6" 0 (const_int 0) "(f0|f1)+add0+add1")(define_insn_reservation "f7" 0 (const_int 0) "(f0|f1)+mul0+mul1");; Media insns. Now they are all not generated now.(define_cpu_unit "m1_0" "nodiv")(define_cpu_unit "m1_1" "nodiv")(define_cpu_unit "m2_0" "nodiv")(define_cpu_unit "m2_1" "nodiv")(define_cpu_unit "m3_0" "nodiv")(define_cpu_unit "m3_1" "nodiv")(define_cpu_unit "m4_0" "nodiv")(define_cpu_unit "m4_1" "nodiv")(define_cpu_unit "m5" "nodiv")(define_cpu_unit "m6" "nodiv")(define_cpu_unit "m7" "nodiv")(exclusion_set "m5,m6,m7" "m2_0,m2_1,m3_0,m3_1")(exclusion_set "m5" "m6,m7")(exclusion_set "m6" "m4_0,m4_1,m7")(exclusion_set "m7" "m1_0,m1_1,add0,add1,mul0,mul1")(define_bypass 2 "m1" "m1,m2,m3,m4,m5,m6,m7")(define_bypass 4 "m1" "f1,f2,f3,f4_div,f4_root,f5,f6,f7")(define_insn_reservation "m1" 3 (and (eq_attr "cpu" "generic,fr500,tomcat") (eq_attr "type" "mlogic,maveh,msath,maddh,mqaddh")) "(m0|m1)+(m1_0|m1_1)")(define_bypass 2 "m2" "m1,m2,m3,m4,m5,m6,m7")(define_bypass 4 "m2" "f1,f2,f3,f4_div,f4_root,f5,f6,f7")(define_insn_reservation "m2" 3 (and (eq_attr "cpu" "generic,fr500,tomcat") (eq_attr "type" "mrdacc,mpackh,munpackh,mbhconv,mrot,mshift,mexpdhw,mexpdhd,mwcut,mcut,mdunpackh,mbhconve")) "(m0|m1)+(m2_0|m2_1)")(define_bypass 1 "m3" "m4")(define_insn_reservation "m3" 2 (and (eq_attr "cpu" "generic,fr500,tomcat") (eq_attr "type" "mclracc,mwtacc")) "(m0|m1)+(m3_0|m3_1)")(define_bypass 1 "m4" "m4")(define_insn_reservation "m4" 2 (and (eq_attr "cpu" "generic,fr500,tomcat") (eq_attr "type" "mmulh,mmulxh,mmach,mmrdh,mqmulh,mqmulxh,mqmach,mcpx,mqcpx")) "(m0|m1)+(m4_0|m4_1)")(define_bypass 2 "m5" "m1,m2,m3,m4,m5,m6,m7")(define_bypass 4 "m5" "f1,f2,f3,f4_div,f4_root,f5,f6,f7")(define_insn_reservation "m5" 3 (and (eq_attr "cpu" "generic,fr500,tomcat") (eq_attr "type" "mdpackh")) "(m0|m1)+m5")(define_bypass 1 "m6" "m4")(define_insn_reservation "m6" 2 (and (eq_attr "cpu" "generic,fr500,tomcat") (eq_attr "type" "mclracca")) "(m0|m1)+m6")(define_bypass 2 "m7" "m1,m2,m3,m4,m5,m6,m7")(define_bypass 4 "m7" "f1,f2,f3,f4_div,f4_root,f5,f6,f7")(define_insn_reservation "m7" 3 (and (eq_attr "cpu" "generic,fr500,tomcat") (eq_attr "type" "m7")) "(m0|m1)+m7");; Unknown & multi insns starts on new cycle and the next insn starts;; on new cycle. To describe this we consider as a control insn.(define_insn_reservation "unknown" 1 (and (eq_attr "cpu" "generic,fr500,tomcat") (eq_attr "type" "unknown,multi")) "c");; ::::::::::::::::::::;; ::;; :: FR400 scheduler description;; ::;; ::::::::::::::::::::;; Category 2 media instructions use both media units, but can be packed;; with non-media instructions. Use fr400_m1unit to claim the M1 unit;; without claiming a slot.(define_cpu_unit "fr400_m1unit" "nodiv")(define_reservation "fr400_i0" "sl0_i0")(define_reservation "fr400_i1" "sl1_i1")(define_reservation "fr400_m0" "sl0_fm0|sl1_fm0")(define_reservation "fr400_m1" "sl1_fm1")(define_reservation "fr400_meither" "fr400_m0|(fr400_m1+fr400_m1unit)")(define_reservation "fr400_mboth" "fr400_m0+fr400_m1unit")(define_reservation "fr400_b" "sl0_b0|sl1_b0")(define_reservation "fr400_c" "sl0_c");; Name Class Units Latency;; ==== ===== ===== =======;; int I1 I0/I1 1;; sethi I1 I0/I1 0 -- does not interfere with setlo;; setlo I1 I0/I1 1;; mul I1 I0 3 (*);; div I1 I0 20 (*);; gload I2 I0 4 (*);; fload I2 I0 4 -- only 3 if read by a media insn;; gstore I3 I0 0 -- provides no result;; fstore I3 I0 0 -- provides no result;; movfg I4 I0 3 (*);; movgf I4 I0 3 (*);; jumpl I5 I0 0 -- provides no result;;;; (*) The results of these instructions can be read one cycle earlier;; than indicated. The penalty given is for instructions with write-after-;; write dependencies.;; The FR400 can only do loads and stores in I0, so we there's no danger;; of memory unit collision in the same packet. There's only one divide;; unit too.(define_insn_reservation "fr400_i1_int" 1 (and (eq_attr "cpu" "fr400") (eq_attr "type" "int")) "fr400_i0|fr400_i1")(define_insn_reservation "fr400_i1_sethi" 0 (and (eq_attr "cpu" "fr400") (eq_attr "type" "sethi")) "fr400_i0|fr400_i1")(define_insn_reservation "fr400_i1_setlo" 1 (and (eq_attr "cpu" "fr400") (eq_attr "type" "setlo")) "fr400_i0|fr400_i1")(define_insn_reservation "fr400_i1_mul" 3 (and (eq_attr "cpu" "fr400") (eq_attr "type" "mul")) "fr400_i0")(define_insn_reservation "fr400_i1_div" 20 (and (eq_attr "cpu" "fr400") (eq_attr "type" "div")) "fr400_i0+idiv1*19")(define_insn_reservation "fr400_i2_gload" 4 (and (eq_attr "cpu" "fr400") (eq_attr "type" "gload")) "fr400_i0")(define_insn_reservation "fr400_i2_fload" 4 (and (eq_attr "cpu" "fr400") (eq_attr "type" "fload")) "fr400_i0")(define_insn_reservation "fr400_i3_gstore" 0 (and (eq_attr "cpu" "fr400") (eq_attr "type" "gstore")) "fr400_i0")(define_insn_reservation "fr400_i3_fstore" 0 (and (eq_attr "cpu" "fr400") (eq_attr "type" "fstore")) "fr400_i0")(define_insn_reservation "fr400_i4_movfg" 3 (and (eq_attr "cpu" "fr400") (eq_attr "type" "movfg")) "fr400_i0")(define_insn_reservation "fr400_i4_movgf" 3 (and (eq_attr "cpu" "fr400") (eq_attr "type" "movgf")) "fr400_i0")(define_insn_reservation "fr400_i5_jumpl" 0 (and (eq_attr "cpu" "fr400") (eq_attr "type" "jumpl")) "fr400_i0");; The bypass between FPR loads and media instructions, described above.(define_bypass 3 "fr400_i2_fload" "fr400_m1_1,fr400_m1_2,\ fr400_m2_1,fr400_m2_2,\ fr400_m3_1,fr400_m3_2,\ fr400_m4_1,fr400_m4_2,\ fr400_m5");; The branch instructions all use the B unit and produce no result.(define_insn_reservation "fr400_b" 0 (and (eq_attr "cpu" "fr400") (eq_attr "type" "jump,branch,ccr,call")) "fr400_b");; Control instructions use the C unit, which excludes all the others.(define_insn_reservation "fr400_c" 0 (and (eq_attr "cpu" "fr400") (eq_attr "type" "spr,trap")) "fr400_c");; Unknown instructions use the C unit, since it requires single-operation;; packets.(define_insn_reservation "fr400_unknown" 1 (and (eq_attr "cpu" "fr400") (eq_attr "type" "unknown,multi")) "fr400_c");; FP->FP moves are marked as "fsconv" instructions in the define_insns;; below, but are implemented on the FR400 using "mlogic" instructions.;; It's easier to class "fsconv" as a "m1:1" instruction than provide;; separate define_insns for the FR400.;; M1 instructions store their results in FPRs. Any instruction can read;; the result in the following cycle, so no penalty occurs.(define_insn_reservation "fr400_m1_1" 1 (and (eq_attr "cpu" "fr400") (eq_attr "type" "fsconv,mlogic,maveh,msath,maddh,mabsh,mset")) "fr400_meither")(define_insn_reservation "fr400_m1_2" 1 (and (eq_attr "cpu" "fr400") (eq_attr "type" "mqaddh,mqsath")) "fr400_mboth");; M2 instructions store their results in accumulators, which are read;; by M2 or M4 media commands. M2 instructions can read the results in;; the following cycle, but M4 instructions must wait a cycle more.(define_bypass 1 "fr400_m2_1,fr400_m2_2" "fr400_m2_1,fr400_m2_2")(define_insn_reservation "fr400_m2_1" 2 (and (eq_attr "cpu" "fr400") (eq_attr "type" "mmulh,mmulxh,mmach,mmrdh,mcpx,maddacc")) "fr400_meither")(define_insn_reservation "fr400_m2_2" 2 (and (eq_attr "cpu" "fr400") (eq_attr "type" "mqmulh,mqmulxh,mqmach,mqcpx,mdaddacc")) "fr400_mboth");; For our purposes, there seems to be little real difference between;; M1 and M3 instructions. Keep them separate anyway in case the distinction;; is needed later.(define_insn_reservation "fr400_m3_1" 1 (and (eq_attr "cpu" "fr400") (eq_attr "type" "mpackh,mrot,mshift,mexpdhw")) "fr400_meither")(define_insn_reservation "fr400_m3_2" 1 (and (eq_attr "cpu" "fr400") (eq_attr "type" "munpackh,mdpackh,mbhconv,mexpdhd,mwcut,mdrot,mcpl")) "fr400_mboth");; M4 instructions write to accumulators or FPRs. MOVFG and STF;; instructions can read an FPR result in the following cycle, but;; M-unit instructions must wait a cycle more for either kind of result.(define_bypass 1 "fr400_m4_1,fr400_m4_2" "fr400_i3_fstore,fr400_i4_movfg")(define_insn_reservation "fr400_m4_1" 2 (and (eq_attr "cpu" "fr400") (eq_attr "type" "mrdacc,mcut,mclracc")) "fr400_meither")(define_insn_reservation "fr400_m4_2" 2 (and (eq_attr "cpu" "fr400") (eq_attr "type" "mclracca,mdcut")) "fr400_mboth");; M5 instructions always incur a 1-cycle penalty.(define_insn_reservation "fr400_m5" 2 (and (eq_attr "cpu" "fr400") (eq_attr "type" "mwtacc")) "fr400_mboth");; ::::::::::::::::::::;; ::;; :: Simple/FR300 scheduler description;; ::;; ::::::::::::::::::::;; Fr300 or simple processor. To describe it as 1 insn issue;; processor, we use control unit.(define_insn_reservation "fr300_lat1" 1 (and (eq_attr "cpu" "fr300,simple") (eq_attr "type" "!gload,fload,movfg,movgf")) "c")(define_insn_reservation "fr300_lat2" 2 (and (eq_attr "cpu" "fr300,simple") (eq_attr "type" "gload,fload,movfg,movgf")) "c");; ::::::::::::::::::::;; ::;; :: Delay Slots;; ::;; ::::::::::::::::::::;; The insn attribute mechanism can be used to specify the requirements for;; delay slots, if any, on a target machine. An instruction is said to require;; a "delay slot" if some instructions that are physically after the;; instruction are executed as if they were located before it. Classic;; examples are branch and call instructions, which often execute the following;; instruction before the branch or call is performed.;; On some machines, conditional branch instructions can optionally "annul";; instructions in the delay slot. This means that the instruction will not be;; executed for certain branch outcomes. Both instructions that annul if the;; branch is true and instructions that annul if the branch is false are;; supported.;; Delay slot scheduling differs from instruction scheduling in that;; determining whether an instruction needs a delay slot is dependent only;; on the type of instruction being generated, not on data flow between the;; instructions. See the next section for a discussion of data-dependent;; instruction scheduling.;; The requirement of an insn needing one or more delay slots is indicated via;; the `define_delay' expression. It has the following form:;;;; (define_delay TEST;; [DELAY-1 ANNUL-TRUE-1 ANNUL-FALSE-1;; DELAY-2 ANNUL-TRUE-2 ANNUL-FALSE-2;; ...]);; TEST is an attribute test that indicates whether this `define_delay' applies;; to a particular insn. If so, the number of required delay slots is;; determined by the length of the vector specified as the second argument. An;; insn placed in delay slot N must satisfy attribute test DELAY-N.;; ANNUL-TRUE-N is an attribute test that specifies which insns may be annulled;; if the branch is true. Similarly, ANNUL-FALSE-N specifies which insns in;; the delay slot may be annulled if the branch is false. If annulling is not;; supported for that delay slot, `(nil)' should be coded.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -