* config/arm/arm.c (arm_legitimize_address): Limit the value passed
[official-gcc.git] / gcc / config / mips / 24k.md
blob0dbb9f04f099427a5970fb1d13dce998cacedccd
1 ;; DFA-based pipeline descriptions for MIPS Technologies 24K core.
2 ;; Contributed by Chao-ying Fu (fu@mips.com), Nigel Stephens (nigel@mips.com)
3 ;;   and David Ung (davidu@mips.com)
4 ;;
5 ;; The 24K is a single-issue processor with a half-clocked fpu.
6 ;; The 24Kx is 24k with 1:1 clocked fpu.
7 ;;
8 ;; References:
9 ;;   "MIPS32 24K Processor Core Family Software User's Manual, Rev 3.04."
11 ;; Copyright (C) 2005 Free Software Foundation, Inc.
13 ;; This file is part of GCC.
15 ;; GCC is free software; you can redistribute it and/or modify it
16 ;; under the terms of the GNU General Public License as published
17 ;; by the Free Software Foundation; either version 2, or (at your
18 ;; option) any later version.
20 ;; GCC is distributed in the hope that it will be useful, but WITHOUT
21 ;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
22 ;; or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
23 ;; License for more details.
25 ;; You should have received a copy of the GNU General Public License
26 ;; along with GCC; see the file COPYING.  If not, write to the
27 ;; Free Software Foundation, 51 Franklin Street, Fifth Floor, Boston,
28 ;; MA 02110-1301, USA.
30 (define_automaton "r24k_cpu, r24k_mdu, r24k_fpu")
32 ;; Integer execution unit.
33 (define_cpu_unit "r24k_iss"             "r24k_cpu")
34 (define_cpu_unit "r24k_ixu_arith"       "r24k_cpu")
35 (define_cpu_unit "r24k_mul3a"           "r24k_mdu")
36 (define_cpu_unit "r24k_mul3b"           "r24k_mdu")
37 (define_cpu_unit "r24k_mul3c"           "r24k_mdu")
39 ;; --------------------------------------------------------------
40 ;; Producers
41 ;; --------------------------------------------------------------
43 ;; 1. Loads: lb, lbu, lh, lhu, ll, lw, lwl, lwr, lwpc, lwxs
44 (define_insn_reservation "r24k_int_load" 2
45   (and (eq_attr "cpu" "24k,24kx")
46        (eq_attr "type" "load"))
47   "r24k_iss+r24k_ixu_arith")
50 ;; 2. Arithmetic: add, addi, addiu, addiupc, addu, and, andi, clo, clz,
51 ;;    ext, ins, lui, movn, movz, nor, or, ori, rotr, rotrv, seb, seh, sll,
52 ;;    sllv, slt, slti, sltiu, sltu, sra, srav, srl, srlv, sub, subu, wsbh,
53 ;;    xor, xori
54 ;; (movn/movz is not matched, we'll need to split condmov to
55 ;;  differentiate between integer/float moves)
56 (define_insn_reservation "r24k_int_arith" 1
57   (and (eq_attr "cpu" "24k,24kx")
58        (eq_attr "type" "arith,const,nop,shift,slt"))
59   "r24k_iss+r24k_ixu_arith")
62 ;; 3. Links: bgezal, bgezall, bltzal, bltzall, jal, jalr, jalx
63 ;; 3a. jr/jalr consumer
64 (define_insn_reservation "r24k_int_jump" 1
65   (and (eq_attr "cpu" "24k,24kx")
66        (eq_attr "type" "call,jump"))
67   "r24k_iss+r24k_ixu_arith")
69 ;; 3b. branch consumer
70 (define_insn_reservation "r24k_int_branch" 1
71   (and (eq_attr "cpu" "24k,24kx")
72        (eq_attr "type" "branch"))
73   "r24k_iss+r24k_ixu_arith")
76 ;; 4. MDU: fully pipelined multiplier
77 ;; mult - delivers result to hi/lo in 1 cycle (pipelined)
78 (define_insn_reservation "r24k_int_mult" 1
79   (and (eq_attr "cpu" "24k,24kx")
80        (eq_attr "type" "imul"))
81   "r24k_iss+(r24k_mul3a|r24k_mul3b|r24k_mul3c)")
83 ;; madd, msub - delivers result to hi/lo in 1 cycle (pipelined)
84 (define_insn_reservation "r24k_int_madd" 1
85   (and (eq_attr "cpu" "24k,24kx")
86        (eq_attr "type" "imadd"))
87   "r24k_iss+(r24k_mul3a|r24k_mul3b|r24k_mul3c)")
89 ;; mul - delivers result to gpr in 5 cycles
90 (define_insn_reservation "r24k_int_mul3" 5
91   (and (eq_attr "cpu" "24k,24kx")
92        (eq_attr "type" "imul3"))
93   "r24k_iss+(r24k_mul3a|r24k_mul3b|r24k_mul3c)*5")
95 ;; mfhi, mflo, mflhxu - deliver result to gpr in 5 cycles
96 (define_insn_reservation "r24k_int_mfhilo" 5
97   (and (eq_attr "cpu" "24k,24kx")
98        (eq_attr "type" "mfhilo"))
99   "r24k_iss+(r24k_mul3a|r24k_mul3b|r24k_mul3c)")
101 ;; mthi, mtlo, mtlhx - deliver result to hi/lo, thence madd, handled as bypass
102 (define_insn_reservation "r24k_int_mthilo" 1
103   (and (eq_attr "cpu" "24k,24kx")
104        (eq_attr "type" "mthilo"))
105   "r24k_iss+(r24k_mul3a|r24k_mul3b|r24k_mul3c)")
107 ;; div - default to 36 cycles for 32bit operands.  Faster for 24bit, 16bit and
108 ;; 8bit, but is tricky to identify.
109 (define_insn_reservation "r24k_int_div" 36
110   (and (eq_attr "cpu" "24k,24kx")
111        (eq_attr "type" "idiv"))
112   "r24k_iss+(r24k_mul3a+r24k_mul3b+r24k_mul3c)*36")
115 ;; 5. Cop: cfc1, di, ei, mfc0, mtc0
116 ;; (Disabled until we add proper cop0 support)
117 ;;(define_insn_reservation "r24k_int_cop" 3
118 ;;  (and (eq_attr "cpu" "24k,24kx")
119 ;;       (eq_attr "type" "cop0"))
120 ;;  "r24k_iss+r24k_ixu_arith")
123 ;; 6. Store
124 (define_insn_reservation "r24k_int_store" 1
125   (and (eq_attr "cpu" "24k,24kx")
126        (and (eq_attr "type" "store")
127             (eq_attr "mode" "!unknown")))
128   "r24k_iss+r24k_ixu_arith")
130 ;; 6.1 Special case - matches the cprestore pattern which don't set the mode
131 ;;     attrib. This avoids being set as r24k_int_store and have it checked
132 ;;     against store_data_bypass_p, which would then fail because cprestore
133 ;;     does not have a normal SET pattern.
134 (define_insn_reservation "r24k_unknown_store" 1
135   (and (eq_attr "cpu" "24k,24kx")
136        (and (eq_attr "type" "store")
137             (eq_attr "mode" "unknown")))
138   "r24k_iss+r24k_ixu_arith")
141 ;; 7. Multiple instructions
142 (define_insn_reservation "r24k_int_multi" 1
143   (and (eq_attr "cpu" "24k,24kx")
144        (eq_attr "type" "multi"))
145   "r24k_iss+r24k_ixu_arith+r24k_fpu_arith+(r24k_mul3a+r24k_mul3b+r24k_mul3c)")
148 ;; 8. Unknowns - Currently these include blockage, consttable and alignment
149 ;;    rtls. They do not really affect scheduling latency, (blockage affects
150 ;;    scheduling via log links, but not used here).
151 (define_insn_reservation "r24k_int_unknown" 0
152   (and (eq_attr "cpu" "24k,24kx")
153        (eq_attr "type" "unknown"))
154   "r24k_iss")
157 ;; 9. Prefetch
158 (define_insn_reservation "r24k_int_prefetch" 1
159   (and (eq_attr "cpu" "24k,24kx")
160        (eq_attr "type" "prefetch,prefetchx"))
161   "r24k_iss+r24k_ixu_arith")
164 ;; --------------------------------------------------------------
165 ;; Bypass to Consumer
166 ;; --------------------------------------------------------------
168 ;; load->next use :  2 cycles (Default)
169 ;; load->load base:  3 cycles
170 ;; load->store base: 3 cycles
171 ;; load->prefetch:   3 cycles
172 (define_bypass 3 "r24k_int_load" "r24k_int_load")
173 (define_bypass 3 "r24k_int_load" "r24k_int_store" "!store_data_bypass_p")
174 (define_bypass 3 "r24k_int_load" "r24k_int_prefetch")
176 ;; arith->next use :  1 cycles (Default)
177 ;; arith->load base:  2 cycles
178 ;; arith->store base: 2 cycles
179 ;; arith->prefetch:   2 cycles
180 (define_bypass 2 "r24k_int_arith" "r24k_int_load")
181 (define_bypass 2 "r24k_int_arith" "r24k_int_store" "!store_data_bypass_p")
182 (define_bypass 2 "r24k_int_arith" "r24k_int_prefetch")
184 ;; mul3->next use : 5 cycles (default)
185 ;; mul3->l/s base : 6 cycles
186 ;; mul3->prefetch : 6 cycles
187 (define_bypass 6 "r24k_int_mul3" "r24k_int_load")
188 (define_bypass 6 "r24k_int_mul3" "r24k_int_store" "!store_data_bypass_p")
189 (define_bypass 6 "r24k_int_mul3" "r24k_int_prefetch")
191 ;; mfhilo->next use  : 5 cycles (default)
192 ;; mfhilo->l/s base  : 6 cycles
193 ;; mfhilo->prefetch  : 6 cycles
194 ;; mthilo->madd/msub : 2 cycle (only for mthi/lo not mfhi/lo)
195 (define_bypass 6 "r24k_int_mfhilo" "r24k_int_load")
196 (define_bypass 6 "r24k_int_mfhilo" "r24k_int_store" "!store_data_bypass_p")
197 (define_bypass 6 "r24k_int_mfhilo" "r24k_int_prefetch")
198 (define_bypass 2 "r24k_int_mthilo" "r24k_int_madd")
200 ;; cop->next use : 3 cycles (Default)
201 ;; cop->l/s base : 4 cycles
202 ;; (define_bypass 4 "r24k_int_cop" "r24k_int_load")
203 ;; (define_bypass 4 "r24k_int_cop" "r24k_int_store" "!store_data_bypass_p")
205 ;; multi->next use : 1 cycles (Default)
206 ;; multi->l/s base : 2 cycles
207 ;; multi->prefetch : 2 cycles
208 (define_bypass 2 "r24k_int_multi" "r24k_int_load")
209 (define_bypass 2 "r24k_int_multi" "r24k_int_store" "!store_data_bypass_p")
210 (define_bypass 2 "r24k_int_multi" "r24k_int_prefetch")
213 ;; --------------------------------------------------------------
214 ;; Floating Point Instructions
215 ;; --------------------------------------------------------------
217 (define_cpu_unit "r24k_fpu_arith" "r24k_fpu")
219 ;; The 24k is a single issue cpu, and the fpu runs at half clock speed,
220 ;; so each fpu instruction ties up the shared instruction scheduler for
221 ;; 1 cycle, and the fpu scheduler for 2 cycles.
223 ;; These timings are therefore twice the values in the 24K manual,
224 ;; which are quoted in fpu clocks.
226 ;; The 24kx is a 24k configured with 1:1 cpu and fpu, so use
227 ;; the unscaled timings
229 (define_reservation "r24k_fpu_iss"      "r24k_iss+(r24k_fpu_arith*2)")
231 ;; fadd, fabs, fneg
232 (define_insn_reservation "r24k_fadd" 8
233   (and (eq_attr "cpu" "24k")
234        (eq_attr "type" "fadd,fabs,fneg"))
235   "r24k_fpu_iss")
237 ;; fmove, fcmove
238 (define_insn_reservation "r24k_fmove" 8
239   (and (eq_attr "cpu" "24k")
240        (eq_attr "type" "fmove,condmove"))
241   "r24k_fpu_iss")
243 ;; fload
244 (define_insn_reservation "r24k_fload" 6
245   (and (eq_attr "cpu" "24k")
246        (eq_attr "type" "fpload,fpidxload"))
247   "r24k_fpu_iss")
249 ;; fstore
250 (define_insn_reservation "r24k_fstore" 2
251   (and (eq_attr "cpu" "24k")
252        (eq_attr "type" "fpstore"))
253   "r24k_fpu_iss")
255 ;; fmul, fmadd
256 (define_insn_reservation "r24k_fmul_sf" 8
257   (and (eq_attr "cpu" "24k")
258        (and (eq_attr "type" "fmul,fmadd")
259             (eq_attr "mode" "SF")))
260   "r24k_fpu_iss")
262 (define_insn_reservation "r24k_fmul_df" 10
263   (and (eq_attr "cpu" "24k")
264        (and (eq_attr "type" "fmul,fmadd")
265             (eq_attr "mode" "DF")))
266   "r24k_fpu_iss,(r24k_fpu_arith*2)")
269 ;; fdiv, fsqrt, frsqrt
270 (define_insn_reservation "r24k_fdiv_sf" 34
271   (and (eq_attr "cpu" "24k")
272        (and (eq_attr "type" "fdiv,fsqrt,frsqrt")
273             (eq_attr "mode" "SF")))
274   "r24k_fpu_iss,(r24k_fpu_arith*26)")
276 (define_insn_reservation "r24k_fdiv_df" 64
277   (and (eq_attr "cpu" "24k")
278        (and (eq_attr "type" "fdiv,fsqrt")
279             (eq_attr "mode" "DF")))
280   "r24k_fpu_iss,(r24k_fpu_arith*56)")
282 ;; frsqrt
283 (define_insn_reservation "r24k_frsqrt_df" 70
284   (and (eq_attr "cpu" "24k")
285        (and (eq_attr "type" "frsqrt")
286             (eq_attr "mode" "DF")))
287   "r24k_fpu_iss,(r24k_fpu_arith*60)")
289 ;; fcmp
290 (define_insn_reservation "r24k_fcmp" 4
291   (and (eq_attr "cpu" "24k")
292        (eq_attr "type" "fcmp"))
293   "r24k_fpu_iss")
295 ;; fcmp -> movf.fmt & movt.fmt bypass (dependency must be on the condition)
296 (define_bypass 2 "r24k_fcmp" "r24k_fmove")
298 ;; fcvt (cvt.d.s, cvt.[sd].[wl])
299 (define_insn_reservation "r24k_fcvt_i2f_s2d" 8
300   (and (eq_attr "cpu" "24k")
301        (and (eq_attr "type" "fcvt")
302             (eq_attr "cnv_mode" "I2S,I2D,S2D")))
303   "r24k_fpu_iss")
305 ;; fcvt (cvt.s.d)
306 (define_insn_reservation "r24k_fcvt_s2d" 12
307   (and (eq_attr "cpu" "24k")
308        (and (eq_attr "type" "fcvt")
309             (eq_attr "cnv_mode" "D2S")))
310   "r24k_fpu_iss")
312 ;; fcvt (cvt.[wl].[sd], etc)
313 (define_insn_reservation "r24k_fcvt_f2i" 10
314   (and (eq_attr "cpu" "24k")
315        (and (eq_attr "type" "fcvt")
316             (eq_attr "cnv_mode" "S2I,D2I")))
317   "r24k_fpu_iss")
319 ;; fxfer (mfc1, mfhc1, mtc1, mthc1)
320 (define_insn_reservation "r24k_fxfer" 4
321   (and (eq_attr "cpu" "24k")
322        (eq_attr "type" "xfer"))
323   "r24k_fpu_iss")
325 ;; --------------------------------------------------------------
326 ;; Bypass to Consumer
327 ;; --------------------------------------------------------------
328 ;; r24k_fcvt_f2i->l/s base : 11 cycles
329 ;; r24k_fcvt_f2i->prefetch : 11 cycles
330 (define_bypass 11 "r24k_fcvt_f2i" "r24k_int_load")
331 (define_bypass 11 "r24k_fcvt_f2i" "r24k_int_store" "!store_data_bypass_p")
332 (define_bypass 11 "r24k_fcvt_f2i" "r24k_int_prefetch")
334 ;; r24k_fxfer->l/s base : 5 cycles
335 ;; r24k_fxfer->prefetch : 5 cycles
336 (define_bypass 5 "r24k_fxfer" "r24k_int_load")
337 (define_bypass 5 "r24k_fxfer" "r24k_int_store" "!store_data_bypass_p")
338 (define_bypass 5 "r24k_fxfer" "r24k_int_prefetch")
340 ;; --------------------------------------------------------------
341 ;; The 24kx is a 24k configured with 1:1 cpu and fpu, so use
342 ;; the unscaled timings
343 ;; --------------------------------------------------------------
345 (define_reservation "r24kx_fpu_iss"     "r24k_iss+r24k_fpu_arith")
347 ;; fadd, fabs, fneg
348 (define_insn_reservation "r24kx_fadd" 4
349   (and (eq_attr "cpu" "24kx")
350        (eq_attr "type" "fadd,fabs,fneg"))
351   "r24kx_fpu_iss")
353 ;; fmove, fcmove
354 (define_insn_reservation "r24kx_fmove" 4
355   (and (eq_attr "cpu" "24kx")
356        (eq_attr "type" "fmove,condmove"))
357   "r24kx_fpu_iss")
359 ;; fload
360 (define_insn_reservation "r24kx_fload" 3
361   (and (eq_attr "cpu" "24kx")
362        (eq_attr "type" "fpload,fpidxload"))
363   "r24kx_fpu_iss")
365 ;; fstore
366 (define_insn_reservation "r24kx_fstore" 1
367   (and (eq_attr "cpu" "24kx")
368        (eq_attr "type" "fpstore"))
369   "r24kx_fpu_iss")
371 ;; fmul, fmadd
372 (define_insn_reservation "r24kx_fmul_sf" 4
373   (and (eq_attr "cpu" "24kx")
374        (and (eq_attr "type" "fmul,fmadd")
375             (eq_attr "mode" "SF")))
376   "r24kx_fpu_iss")
378 (define_insn_reservation "r24kx_fmul_df" 5
379   (and (eq_attr "cpu" "24kx")
380        (and (eq_attr "type" "fmul,fmadd")
381             (eq_attr "mode" "DF")))
382   "r24kx_fpu_iss,r24k_fpu_arith")
385 ;; fdiv, fsqrt, frsqrt
386 (define_insn_reservation "r24kx_fdiv_sf" 17
387   (and (eq_attr "cpu" "24kx")
388        (and (eq_attr "type" "fdiv,fsqrt,frsqrt")
389             (eq_attr "mode" "SF")))
390   "r24kx_fpu_iss,(r24k_fpu_arith*13)")
392 (define_insn_reservation "r24kx_fdiv_df" 32
393   (and (eq_attr "cpu" "24kx")
394        (and (eq_attr "type" "fdiv,fsqrt")
395             (eq_attr "mode" "DF")))
396   "r24kx_fpu_iss,(r24k_fpu_arith*28)")
398 ;; frsqrt
399 (define_insn_reservation "r24kx_frsqrt_df" 35
400   (and (eq_attr "cpu" "24kx")
401        (and (eq_attr "type" "frsqrt")
402             (eq_attr "mode" "DF")))
403   "r24kx_fpu_iss,(r24k_fpu_arith*30)")
405 ;; fcmp
406 (define_insn_reservation "r24kx_fcmp" 2
407   (and (eq_attr "cpu" "24kx")
408        (eq_attr "type" "fcmp"))
409   "r24kx_fpu_iss")
411 ;; fcmp -> movf.fmt & movt.fmt bypass (dependency must be on the condition)
412 (define_bypass 1 "r24kx_fcmp" "r24kx_fmove")
414 ;; fcvt (cvt.d.s, cvt.[sd].[wl])
415 (define_insn_reservation "r24kx_fcvt_i2f_s2d" 4
416   (and (eq_attr "cpu" "24kx")
417        (and (eq_attr "type" "fcvt")
418             (eq_attr "cnv_mode" "I2S,I2D,S2D")))
419   "r24kx_fpu_iss")
421 ;; fcvt (cvt.s.d)
422 (define_insn_reservation "r24kx_fcvt_s2d" 6
423   (and (eq_attr "cpu" "24kx")
424        (and (eq_attr "type" "fcvt")
425             (eq_attr "cnv_mode" "D2S")))
426   "r24kx_fpu_iss")
428 ;; fcvt (cvt.[wl].[sd], etc)
429 (define_insn_reservation "r24kx_fcvt_f2i" 5
430   (and (eq_attr "cpu" "24kx")
431        (and (eq_attr "type" "fcvt")
432             (eq_attr "cnv_mode" "S2I,D2I")))
433   "r24kx_fpu_iss")
435 ;; fxfer (mfc1, mfhc1, mtc1, mthc1)
436 (define_insn_reservation "r24kx_fxfer" 2
437   (and (eq_attr "cpu" "24kx")
438        (eq_attr "type" "xfer"))
439   "r24kx_fpu_iss")
441 ;; --------------------------------------------------------------
442 ;; Bypass to Consumer
443 ;; --------------------------------------------------------------
444 ;; r24kx_fcvt_f2i->l/s base : 6 cycles
445 ;; r24kx_fcvt_f2i->prefetch : 6 cycles
446 (define_bypass 6 "r24kx_fcvt_f2i" "r24k_int_load")
447 (define_bypass 6 "r24kx_fcvt_f2i" "r24k_int_store" "!store_data_bypass_p")
448 (define_bypass 6 "r24kx_fcvt_f2i" "r24k_int_prefetch")
450 ;; r24kx_fxfer->l/s base : 3 cycles
451 ;; r24kx_fxfer->prefetch : 3 cycles
452 (define_bypass 3 "r24kx_fxfer" "r24k_int_load")
453 (define_bypass 3 "r24kx_fxfer" "r24k_int_store" "!store_data_bypass_p")
454 (define_bypass 3 "r24kx_fxfer" "r24k_int_prefetch")