1;; DFA-based pipeline description for the RM7000.
2;;   Copyright (C) 2003, 2004, 2005 Free Software Foundation, Inc.
3;;
4;; This file is part of GCC.
5
6;; GCC is free software; you can redistribute it and/or modify it
7;; under the terms of the GNU General Public License as published
8;; by the Free Software Foundation; either version 2, or (at your
9;; option) any later version.
10
11;; GCC is distributed in the hope that it will be useful, but WITHOUT
12;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
13;; or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
14;; License for more details.
15
16;; You should have received a copy of the GNU General Public License
17;; along with GCC; see the file COPYING.  If not, write to the
18;; Free Software Foundation, 51 Franklin Street, Fifth Floor, Boston,
19;; MA 02110-1301, USA.
20
21;; .........................
22;;
23;; The RM7000 is a dual-issue processor that can bundle instructions as:
24;; {arith|load|store}{arith|imul|idiv|branch|float}
25;;
26;; Reference:
27;;   "RM7000 Family User Manual, PMC-2002296"
28;;
29;; .........................
30
31;; Use three automata to isolate long latency operations, reducing space.
32(define_automaton "rm7000_other, rm7000_fdiv, rm7000_idiv")
33
34;;
35;; Describe the resources.
36;;
37
38;; Global
39(define_cpu_unit "rm7_iss0,rm7_iss1" "rm7000_other")
40
41;; Integer execution unit (M-Pipe).
42(define_cpu_unit "ixum_addsub_agen" "rm7000_other")
43
44;; Integer execution unit (F-Pipe).
45(define_cpu_unit "ixuf_addsub" "rm7000_other")
46(define_cpu_unit "ixuf_branch" "rm7000_other")
47(define_cpu_unit "ixuf_mpydiv" "rm7000_other")
48(define_cpu_unit "ixuf_mpydiv_iter" "rm7000_idiv")
49;; Floating-point unit (F-Pipe).
50(define_cpu_unit "fxuf_add" "rm7000_other")
51(define_cpu_unit "fxuf_mpy" "rm7000_other")
52(define_cpu_unit "fxuf_mpy_iter" "rm7000_fdiv")
53(define_cpu_unit "fxuf_divsqrt" "rm7000_other")
54(define_cpu_unit "fxuf_divsqrt_iter" "rm7000_fdiv")
55
56(exclusion_set "ixuf_addsub"
57	       "ixuf_branch,ixuf_mpydiv,fxuf_add,fxuf_mpy,fxuf_divsqrt")
58(exclusion_set "ixuf_branch" "ixuf_mpydiv,fxuf_add,fxuf_mpy,fxuf_divsqrt")
59(exclusion_set "ixuf_mpydiv" "fxuf_add,fxuf_mpy,fxuf_divsqrt")
60(exclusion_set "fxuf_add" "fxuf_mpy,fxuf_divsqrt")
61(exclusion_set "fxuf_mpy" "fxuf_divsqrt")
62
63;; After branch any insn cannot be issued.
64(absence_set "rm7_iss0,rm7_iss1" "ixuf_branch")
65
66;;
67;; Define reservations for unit name mnemonics or combinations.
68;;
69
70(define_reservation "rm7_iss" "rm7_iss0|rm7_iss1")
71(define_reservation "rm7_single_dispatch" "rm7_iss0+rm7_iss1")
72
73(define_reservation "rm7_iaddsub" "rm7_iss+(ixum_addsub_agen|ixuf_addsub)")
74(define_reservation "rm7_imem" "rm7_iss+ixum_addsub_agen")
75(define_reservation "rm7_impydiv" "rm7_iss+ixuf_mpydiv")
76(define_reservation "rm7_impydiv_iter" "ixuf_mpydiv_iter")
77(define_reservation "rm7_branch" "rm7_iss+ixuf_branch")
78
79(define_reservation "rm7_fpadd"	"rm7_iss+fxuf_add")
80(define_reservation "rm7_fpmpy"	"rm7_iss+fxuf_mpy")
81(define_reservation "rm7_fpmpy_iter" "fxuf_mpy_iter")
82(define_reservation "rm7_fpdivsqr" "rm7_iss+fxuf_divsqrt")
83(define_reservation "rm7_fpdivsqr_iter" "fxuf_divsqrt_iter")
84
85;;
86;; Describe instruction reservations for integer operations.
87;;
88
89(define_insn_reservation "rm7_int_other" 1
90  (and (eq_attr "cpu" "r7000")
91       (eq_attr "type" "arith,shift,slt,clz,const,condmove,nop,trap"))
92  "rm7_iaddsub")
93
94(define_insn_reservation "rm7_ld" 2
95  (and (eq_attr "cpu" "r7000")
96       (eq_attr "type" "load,fpload,fpidxload"))
97  "rm7_imem")
98
99(define_insn_reservation "rm7_st" 1
100  (and (eq_attr "cpu" "r7000")
101       (eq_attr "type" "store,fpstore,fpidxstore"))
102  "rm7_imem")
103
104(define_insn_reservation "rm7_idiv_si" 36
105  (and (eq_attr "cpu" "r7000")
106       (and (eq_attr "type" "idiv")
107	    (eq_attr "mode" "SI")))
108  "rm7_impydiv+(rm7_impydiv_iter*36)")
109
110(define_insn_reservation "rm7_idiv_di" 68
111  (and (eq_attr "cpu" "r7000")
112       (and (eq_attr "type" "idiv")
113	    (eq_attr "mode" "DI")))
114  "rm7_impydiv+(rm7_impydiv_iter*68)")
115
116(define_insn_reservation "rm7_impy_si_mult" 5
117  (and (eq_attr "cpu" "r7000")
118       (and (eq_attr "type" "imul,imadd")
119	    (eq_attr "mode" "SI")))
120  "rm7_impydiv+(rm7_impydiv_iter*3)")
121
122;; There are an additional 2 stall cycles.
123(define_insn_reservation "rm7_impy_si_mul" 2
124  (and (eq_attr "cpu" "r7000")
125       (and (eq_attr "type" "imul3")
126	    (eq_attr "mode" "SI")))
127  "rm7_impydiv")
128
129(define_insn_reservation "rm7_impy_di" 9
130  (and (eq_attr "cpu" "r7000")
131       (and (eq_attr "type" "imul,imul3")
132	    (eq_attr "mode" "DI")))
133  "rm7_impydiv+(rm7_impydiv_iter*8)")
134
135;; Move to/from HI/LO.
136(define_insn_reservation "rm7_mthilo" 3
137  (and (eq_attr "cpu" "r7000")
138       (eq_attr "type" "mthilo"))
139  "rm7_impydiv")
140
141(define_insn_reservation "rm7_mfhilo" 1
142  (and (eq_attr "cpu" "r7000")
143       (eq_attr "type" "mfhilo"))
144  "rm7_impydiv")
145
146;; Move to/from fp coprocessor.
147(define_insn_reservation "rm7_ixfer" 2
148  (and (eq_attr "cpu" "r7000")
149       (eq_attr "type" "xfer"))
150  "rm7_iaddsub")
151
152(define_insn_reservation "rm7_ibr" 3
153  (and (eq_attr "cpu" "r7000")
154       (eq_attr "type" "branch,jump,call"))
155  "rm7_branch")
156
157;;
158;; Describe instruction reservations for the floating-point operations.
159;;
160(define_insn_reservation "rm7_fp_quick" 4
161  (and (eq_attr "cpu" "r7000")
162       (eq_attr "type" "fneg,fcmp,fabs,fmove"))
163  "rm7_fpadd")
164
165(define_insn_reservation "rm7_fp_other" 4
166  (and (eq_attr "cpu" "r7000")
167       (eq_attr "type" "fadd"))
168  "rm7_fpadd")
169
170(define_insn_reservation "rm7_fp_cvt" 4
171  (and (eq_attr "cpu" "r7000")
172       (eq_attr "type" "fcvt"))
173  "rm7_fpadd")
174
175(define_insn_reservation "rm7_fp_divsqrt_df" 36
176  (and (eq_attr "cpu" "r7000")
177       (and (eq_attr "type" "fdiv,frdiv,fsqrt")
178	    (eq_attr "mode" "DF")))
179  "rm7_fpdivsqr+(rm7_fpdivsqr_iter*36)")
180
181(define_insn_reservation "rm7_fp_divsqrt_sf" 21
182  (and (eq_attr "cpu" "r7000")
183       (and (eq_attr "type" "fdiv,frdiv,fsqrt")
184	    (eq_attr "mode" "SF")))
185  "rm7_fpdivsqr+(rm7_fpdivsqr_iter*21)")
186
187(define_insn_reservation "rm7_fp_rsqrt_df" 68
188  (and (eq_attr "cpu" "r7000")
189       (and (eq_attr "type" "frsqrt")
190	    (eq_attr "mode" "DF")))
191  "rm7_fpdivsqr+(rm7_fpdivsqr_iter*68)")
192
193(define_insn_reservation "rm7_fp_rsqrt_sf" 38
194  (and (eq_attr "cpu" "r7000")
195       (and (eq_attr "type" "frsqrt")
196	    (eq_attr "mode" "SF")))
197  "rm7_fpdivsqr+(rm7_fpdivsqr_iter*38)")
198
199(define_insn_reservation "rm7_fp_mpy_sf" 4
200  (and (eq_attr "cpu" "r7000")
201       (and (eq_attr "type" "fmul,fmadd")
202	    (eq_attr "mode" "SF")))
203  "rm7_fpmpy+rm7_fpmpy_iter")
204
205(define_insn_reservation "rm7_fp_mpy_df" 5
206  (and (eq_attr "cpu" "r7000")
207       (and (eq_attr "type" "fmul,fmadd")
208	    (eq_attr "mode" "DF")))
209  "rm7_fpmpy+(rm7_fpmpy_iter*2)")
210
211;; Force single-dispatch for unknown or multi.
212(define_insn_reservation "rm7_unknown" 1
213  (and (eq_attr "cpu" "r7000")
214       (eq_attr "type" "unknown,multi"))
215  "rm7_single_dispatch")
216