OSDN Git Service

* config/mips/mips.c (mips_final_postscan_insn): Make it static.
[pf3gnuchains/gcc-fork.git] / gcc / config / mips / 20kc.md
1 ;; .........................
2 ;;
3 ;; DFA-based pipeline description for MIPS64 model R20Kc.
4 ;; Contributed by Jason Eckhardt (jle@cygnus.com).
5 ;;
6 ;; The R20Kc is a dual-issue processor that can generally bundle
7 ;; instructions as follows:
8 ;;   1. integer with integer
9 ;;   2. integer with fp
10 ;;   3. fp with fpload/fpstore 
11 ;;
12 ;; Of course, there are various restrictions.
13 ;; Reference:
14 ;;   "Ruby (R20K) Technical Specification Rev. 1.2, December 28, 1999."
15 ;;
16 ;; .........................
17
18 ;; Use three automata to isolate long latency operations, reducing space.
19 (define_automaton "r20kc_other, r20kc_fdiv, r20kc_idiv")
20
21 ;;
22 ;; Describe the resources.
23 ;;
24
25 ;; Global.
26 (define_cpu_unit "r20kc_iss0, r20kc_iss1" "r20kc_other")
27
28 ;; Integer execution unit (pipeline A).
29 (define_cpu_unit "r20kc_ixua_addsub_agen" "r20kc_other")
30 (define_cpu_unit "r20kc_ixua_shift"       "r20kc_other")
31
32 (exclusion_set "r20kc_ixua_addsub_agen" "r20kc_ixua_shift")
33
34 ;; Integer execution unit (pipeline B).
35 (define_cpu_unit "r20kc_ixub_addsub"      "r20kc_other")
36 (define_cpu_unit "r20kc_ixub_branch"      "r20kc_other")
37 (define_cpu_unit "r20kc_ixub_mpydiv"      "r20kc_other")
38 (define_cpu_unit "r20kc_ixub_mpydiv_iter" "r20kc_idiv")
39
40 (exclusion_set "r20kc_ixub_addsub" "r20kc_ixub_branch, r20kc_ixub_mpydiv")
41 (exclusion_set "r20kc_ixub_branch" "r20kc_ixub_mpydiv")
42
43 ;; Cache / memory interface.
44 (define_cpu_unit "r20kc_cache"      "r20kc_other")
45
46 ;; Floating-point unit.
47 (define_cpu_unit "r20kc_fpu_add"          "r20kc_other")
48 (define_cpu_unit "r20kc_fpu_mpy"          "r20kc_other")
49 (define_cpu_unit "r20kc_fpu_mpy_iter"     "r20kc_fdiv")
50 (define_cpu_unit "r20kc_fpu_divsqrt"      "r20kc_other")
51 (define_cpu_unit "r20kc_fpu_divsqrt_iter" "r20kc_fdiv")
52
53 (exclusion_set "r20kc_fpu_add" "r20kc_fpu_mpy, r20kc_fpu_divsqrt")
54 (exclusion_set "r20kc_fpu_mpy" "r20kc_fpu_divsqrt")
55
56 ;; After branch any insn can not be issued.
57 (absence_set "r20kc_iss0,r20kc_iss1" "r20kc_ixub_branch")
58
59 ;;
60 ;; Define reservations for unit name mnemonics or combinations.
61 ;;
62
63 (define_reservation "r20kc_iss"
64   "r20kc_iss0|r20kc_iss1")
65 (define_reservation "r20kc_single_dispatch"
66   "r20kc_iss0+r20kc_iss1")
67 (define_reservation "r20kc_iaddsub"
68   "r20kc_iss+(r20kc_ixua_addsub_agen|r20kc_ixub_addsub)")
69 (define_reservation "r20kc_ishift"
70   "r20kc_iss+r20kc_ixua_shift")
71 (define_reservation "r20kc_fpmove"
72   "r20kc_iss+r20kc_ixua_addsub_agen")
73 (define_reservation "r20kc_imem"
74   "r20kc_iss+r20kc_ixua_addsub_agen+r20kc_cache")
75 (define_reservation "r20kc_icache"
76   "r20kc_cache")
77 (define_reservation "r20kc_impydiv"
78   "r20kc_iss+r20kc_ixub_mpydiv")
79 (define_reservation "r20kc_impydiv_iter"
80   "r20kc_ixub_mpydiv_iter")
81 (define_reservation "r20kc_ibranch"
82   "r20kc_iss+r20kc_ixub_branch")
83
84 (define_reservation "r20kc_fpadd"
85   "r20kc_iss+r20kc_fpu_add")
86 (define_reservation "r20kc_fpmpy"
87   "r20kc_iss+r20kc_fpu_mpy")
88 (define_reservation "r20kc_fpmpy_iter"
89   "r20kc_fpu_mpy_iter")
90 (define_reservation "r20kc_fpdivsqrt"
91   "r20kc_iss+r20kc_fpu_divsqrt")
92 (define_reservation "r20kc_fpdivsqrt_iter"
93   "r20kc_fpu_divsqrt_iter")
94
95 ;;
96 ;; Describe instruction reservations for integer operations.
97 ;;
98
99 ;; Conditional moves always force single-dispatch.
100 (define_insn_reservation "r20kc_cond_move_int" 1 
101                          (and (eq_attr "cpu" "20kc")
102                               (and (eq_attr "type" "condmove")
103                                    (eq_attr "mode" "!SF,DF")))
104                          "r20kc_single_dispatch")
105
106 (define_insn_reservation "r20kc_cond_move_fp" 4 
107                          (and (eq_attr "cpu" "20kc")
108                               (and (eq_attr "type" "condmove")
109                                    (eq_attr "mode" "SF,DF")))
110                          "r20kc_single_dispatch")
111
112 (define_insn_reservation "r20kc_int_other" 1
113                           (and (eq_attr "cpu" "20kc")
114                                (eq_attr "type" "move,arith,const,nop"))
115                           "r20kc_iaddsub")
116
117 ;; Shifts can only execute on ixu pipeline A.
118 (define_insn_reservation "r20kc_int_shift" 1
119                           (and (eq_attr "cpu" "20kc")
120                                (eq_attr "type" "shift"))
121                           "r20kc_ishift")
122
123 (define_insn_reservation "r20kc_ld" 2 
124                          (and (eq_attr "cpu" "20kc")
125                               (eq_attr "type" "load,prefetch,prefetchx"))
126                          "r20kc_imem")
127
128
129 ;; A load immediately following a store will stall, so
130 ;; say that a store uses the cache for an extra cycle.
131 (define_insn_reservation "r20kc_st" 2 
132                           (and (eq_attr "cpu" "20kc")
133                                (eq_attr "type" "store"))
134                           "r20kc_imem,r20kc_icache")
135
136 (define_insn_reservation "r20kc_fld" 3 
137                          (and (eq_attr "cpu" "20kc")
138                               (eq_attr "type" "fpload"))
139                          "r20kc_imem")
140
141 (define_insn_reservation "r20kc_ffst" 3 
142                          (and (eq_attr "cpu" "20kc")
143                               (eq_attr "type" "fpstore"))
144                          "r20kc_imem,r20kc_icache*2")
145
146 ;; Integer divide latency is between 13 and 42 cycles for DIV[U] and between
147 ;; 13 and 72 cycles for DDIV[U]. This depends on the value of the inputs
148 ;; so we just choose the worst case latency.
149 (define_insn_reservation "r20kc_idiv_si" 42 
150                          (and (eq_attr "cpu" "20kc")
151                               (and (eq_attr "type" "idiv")
152                                    (eq_attr "mode" "SI")))
153                          "r20kc_impydiv+(r20kc_impydiv_iter*42)")
154
155 (define_insn_reservation "r20kc_idiv_di" 72 
156                          (and (eq_attr "cpu" "20kc")
157                               (and (eq_attr "type" "idiv")
158                                    (eq_attr "mode" "DI")))
159                          "r20kc_impydiv+(r20kc_impydiv_iter*72)")
160
161 ;; Integer multiply latency is 4 or 7 cycles for word and double-word
162 ;; respectively.
163 (define_insn_reservation "r20kc_impy_si" 4 
164                          (and (eq_attr "cpu" "20kc")
165                               (and (eq_attr "type" "imadd,imul,imul3")
166                                    (eq_attr "mode" "SI")))
167                          "r20kc_impydiv+(r20kc_impydiv_iter*2)")
168
169 (define_insn_reservation "r20kc_impy_di" 7 
170                          (and (eq_attr "cpu" "20kc")
171                               (and (eq_attr "type" "imadd,imul,imul3")
172                                    (eq_attr "mode" "DI")))
173                          "r20kc_impydiv+(r20kc_impydiv_iter*7)")
174
175 ;; Move to/from HI/LO.
176 ;; Moving to HI/LO has a 3 cycle latency while moving from only has a 1
177 ;; cycle latency.  Repeat rate is 3 for both.
178 (define_insn_reservation "r20kc_imthilo" 3 
179                          (and (eq_attr "cpu" "20kc")
180                               (eq_attr "type" "mthilo"))
181                          "r20kc_impydiv+(r20kc_impydiv_iter*3)")
182
183 (define_insn_reservation "r20kc_imfhilo" 1
184                          (and (eq_attr "cpu" "20kc")
185                               (eq_attr "type" "mfhilo"))
186                          "r20kc_impydiv+(r20kc_impydiv_iter*3)")
187
188 ;; Move to fp coprocessor.
189 (define_insn_reservation "r20kc_ixfer_mt" 3 
190                          (and (eq_attr "cpu" "20kc")
191                               (eq_attr "type" "mtc"))
192                          "r20kc_fpmove")
193
194 ;; Move from fp coprocessor.
195 (define_insn_reservation "r20kc_ixfer_mf" 2 
196                           (and (eq_attr "cpu" "20kc")
197                                (eq_attr "type" "mfc"))
198                         "r20kc_fpmove")
199
200 ;; Assume branch predicted correctly.
201 (define_insn_reservation "r20kc_ibr" 1 
202                          (and (eq_attr "cpu" "20kc")
203                               (eq_attr "type" "branch,jump,call"))
204                          "r20kc_ibranch")
205
206 ;;
207 ;; Describe instruction reservations for the floating-point operations.
208 ;;
209 (define_insn_reservation "r20kc_fp_other" 4
210                          (and (eq_attr "cpu" "20kc")
211                               (eq_attr "type" "fmove,fadd,fabs,fneg,fcmp"))
212                          "r20kc_fpadd")
213
214 (define_insn_reservation "r20kc_fp_cvt_a" 4
215                          (and (eq_attr "cpu" "20kc")
216                               (and (eq_attr "type" "fcvt")
217                                    (eq_attr "cnv_mode" "I2S,I2D,S2D")))
218                          "r20kc_fpadd")
219
220 (define_insn_reservation "r20kc_fp_cvt_b" 5
221                          (and (eq_attr "cpu" "20kc")
222                               (and (eq_attr "type" "fcvt")
223                                    (eq_attr "cnv_mode" "D2S,S2I")))
224                          "r20kc_fpadd")
225
226 (define_insn_reservation "r20kc_fp_divsqrt_df" 32
227                          (and (eq_attr "cpu" "20kc")
228                               (and (eq_attr "type" "fdiv,fsqrt")
229                                    (eq_attr "mode" "DF")))
230                          "r20kc_fpdivsqrt+(r20kc_fpdivsqrt_iter*32)")
231
232 (define_insn_reservation "r20kc_fp_divsqrt_sf" 17
233                          (and (eq_attr "cpu" "20kc")
234                               (and (eq_attr "type" "fdiv,fsqrt")
235                                    (eq_attr "mode" "SF")))
236                          "r20kc_fpdivsqrt+(r20kc_fpdivsqrt_iter*17)")
237
238 (define_insn_reservation "r20kc_fp_rsqrt_df" 35 
239                          (and (eq_attr "cpu" "20kc")
240                               (and (eq_attr "type" "frsqrt")
241                                    (eq_attr "mode" "DF")))
242                          "r20kc_fpdivsqrt+(r20kc_fpdivsqrt_iter*35)")
243
244 (define_insn_reservation "r20kc_fp_rsqrt_sf" 17
245                          (and (eq_attr "cpu" "20kc")
246                               (and (eq_attr "type" "frsqrt")
247                                    (eq_attr "mode" "SF")))
248                          "r20kc_fpdivsqrt+(r20kc_fpdivsqrt_iter*17)")
249
250 (define_insn_reservation "r20kc_fp_mpy_sf" 4
251                          (and (eq_attr "cpu" "20kc")
252                               (and (eq_attr "type" "fmul,fmadd")
253                                    (eq_attr "mode" "SF")))
254                          "r20kc_fpmpy+r20kc_fpmpy_iter")
255
256 (define_insn_reservation "r20kc_fp_mpy_df" 5
257                          (and (eq_attr "cpu" "20kc")
258                               (and (eq_attr "type" "fmul,fmadd")
259                                    (eq_attr "mode" "DF")))
260                          "r20kc_fpmpy+(r20kc_fpmpy_iter*2)")
261
262 ;; Force single-dispatch for unknown or multi.
263 (define_insn_reservation "r20kc_unknown" 1 
264                          (and (eq_attr "cpu" "20kc")
265                               (eq_attr "type" "unknown,multi"))
266                          "r20kc_single_dispatch")