1;; DFA-based pipeline description for I6400.
2;;
3;; Copyright (C) 2015-2021 Free Software Foundation, Inc.
4;;
5;; This file is part of GCC.
6;;
7;; GCC is free software; you can redistribute it and/or modify it
8;; under the terms of the GNU General Public License as published
9;; by the Free Software Foundation; either version 3, or (at your
10;; option) any later version.
11
12;; GCC is distributed in the hope that it will be useful, but WITHOUT
13;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
14;; or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
15;; License for more details.
16
17;; You should have received a copy of the GNU General Public License
18;; along with GCC; see the file COPYING3.  If not see
19;; <http://www.gnu.org/licenses/>.
20
21(define_automaton "i6400_int_pipe, i6400_mdu_pipe, i6400_fpu_short_pipe,
22		   i6400_fpu_long_pipe")
23
24(define_cpu_unit "i6400_gpmul, i6400_gpdiv" "i6400_mdu_pipe")
25(define_cpu_unit "i6400_agen, i6400_alu1, i6400_lsu" "i6400_int_pipe")
26(define_cpu_unit "i6400_control, i6400_ctu, i6400_alu0" "i6400_int_pipe")
27
28;; Short FPU pipeline.
29(define_cpu_unit "i6400_fpu_short, i6400_fpu_intadd, i6400_fpu_logic,
30		  i6400_fpu_div, i6400_fpu_cmp, i6400_fpu_float,
31		  i6400_fpu_store" "i6400_fpu_short_pipe")
32
33;; Long FPU pipeline.
34(define_cpu_unit "i6400_fpu_long, i6400_fpu_logic_l, i6400_fpu_float_l,
35		  i6400_fpu_mult, i6400_fpu_apu" "i6400_fpu_long_pipe")
36
37(define_reservation "i6400_control_ctu" "i6400_control, i6400_ctu")
38(define_reservation "i6400_control_alu0" "i6400_control, i6400_alu0")
39(define_reservation "i6400_agen_lsu" "i6400_agen, i6400_lsu")
40(define_reservation "i6400_agen_alu1" "i6400_agen, i6400_alu1")
41
42;;
43;; FPU-MSA pipe
44;;
45
46;; Short pipe
47
48;; addv, subv
49(define_insn_reservation "i6400_msa_add_d" 1
50  (and (eq_attr "cpu" "i6400")
51       (and (eq_attr "mode" "!V2DI")
52	    (eq_attr "alu_type" "simd_add")))
53  "i6400_fpu_short+i6400_fpu_intadd*2")
54
55;; add, hadd, sub, hsub, average, min, max, compare
56(define_insn_reservation "i6400_msa_int_add" 2
57  (and (eq_attr "cpu" "i6400")
58       (eq_attr "type" "simd_int_arith"))
59  "i6400_fpu_short+i6400_fpu_intadd*2")
60
61;; sat, pcnt
62(define_insn_reservation "i6400_msa_short_logic3" 3
63  (and (eq_attr "cpu" "i6400")
64       (eq_attr "type" "simd_sat,simd_pcnt"))
65  "i6400_fpu_short+i6400_fpu_logic*2")
66
67;; shifts, nloc, nlzc, bneg, bclr, shf
68(define_insn_reservation "i6400_msa_short_logic2" 2
69  (and (eq_attr "cpu" "i6400")
70       (eq_attr "type" "simd_shift,simd_shf,simd_bit"))
71  "i6400_fpu_short+i6400_fpu_logic*2")
72
73;; and, or, xor, ilv, pck, fill, splat
74(define_insn_reservation "i6400_msa_short_logic" 1
75  (and (eq_attr "cpu" "i6400")
76       (eq_attr "type" "simd_permute,simd_logic,simd_splat,simd_fill"))
77  "i6400_fpu_short+i6400_fpu_logic*2")
78
79;; move.v, ldi
80(define_insn_reservation "i6400_msa_move" 1
81  (and (eq_attr "cpu" "i6400")
82       (eq_attr "type" "simd_move"))
83  "i6400_fpu_short+i6400_fpu_logic*2")
84
85;; Float compare New: CMP.cond.fmt
86(define_insn_reservation "i6400_msa_cmp" 2
87  (and (eq_attr "cpu" "i6400")
88       (eq_attr "type" "simd_fcmp"))
89  "i6400_fpu_short+i6400_fpu_cmp*2")
90
91;; Float min, max, class
92(define_insn_reservation "i6400_msa_short_float2" 2
93  (and (eq_attr "cpu" "i6400")
94       (eq_attr "type" "simd_fminmax,simd_fclass"))
95  "i6400_fpu_short+i6400_fpu_float*2")
96
97;; div.d, mod.d (non-pipelined)
98(define_insn_reservation "i6400_msa_div_d" 36
99  (and (eq_attr "cpu" "i6400")
100       (and (eq_attr "mode" "V2DI")
101	    (eq_attr "type" "simd_div")))
102  "i6400_fpu_short+i6400_fpu_div*36")
103
104;; div.w, mod.w (non-pipelined)
105(define_insn_reservation "i6400_msa_div_w" 20
106  (and (eq_attr "cpu" "i6400")
107       (and (eq_attr "mode" "V4SI")
108	    (eq_attr "type" "simd_div")))
109  "i6400_fpu_short+i6400_fpu_div*20")
110
111;; div.h, mod.h (non-pipelined)
112(define_insn_reservation "i6400_msa_div_h" 12
113  (and (eq_attr "cpu" "i6400")
114       (and (eq_attr "mode" "V8HI")
115	    (eq_attr "type" "simd_div")))
116  "i6400_fpu_short+i6400_fpu_div*12")
117
118;; div.b, mod.b (non-pipelined)
119(define_insn_reservation "i6400_msa_div_b" 8
120  (and (eq_attr "cpu" "i6400")
121       (and (eq_attr "mode" "V16QI")
122	    (eq_attr "type" "simd_div")))
123  "i6400_fpu_short+i6400_fpu_div*8")
124
125;; Vector copy
126(define_insn_reservation "i6400_msa_copy" 1
127  (and (eq_attr "cpu" "i6400")
128       (eq_attr "type" "simd_copy"))
129  "i6400_fpu_short, i6400_fpu_store")
130
131;; Vector bz, bnz
132(define_insn_reservation "i6400_msa_branch" 1
133  (and (eq_attr "cpu" "i6400")
134       (eq_attr "type" "simd_branch"))
135  "i6400_control_ctu")
136
137;; Vector store
138(define_insn_reservation "i6400_fpu_msa_store" 1
139  (and (eq_attr "cpu" "i6400")
140       (eq_attr "type" "simd_store"))
141  "i6400_agen_lsu")
142
143;; Vector load
144(define_insn_reservation "i6400_fpu_msa_load" 3
145  (and (eq_attr "cpu" "i6400")
146       (eq_attr "type" "simd_load"))
147  "i6400_agen_lsu")
148
149;; cfcmsa, ctcmsa
150(define_insn_reservation "i6400_fpu_msa_move" 1
151  (and (eq_attr "cpu" "i6400")
152       (eq_attr "type" "simd_cmsa"))
153  "i6400_control_alu0 | i6400_agen_alu1")
154
155;; Long pipe
156
157;; bmz, bmnz, bsel, insert, insve
158(define_insn_reservation "i6400_msa_long_logic1" 1
159  (and (eq_attr "cpu" "i6400")
160       (eq_attr "type" "simd_bitmov,simd_insert"))
161  "i6400_fpu_long+i6400_fpu_logic_l*2")
162
163;; binsl, binsr, vshf, sld
164(define_insn_reservation "i6400_msa_long_logic2" 2
165  (and (eq_attr "cpu" "i6400")
166       (eq_attr "type" "simd_bitins,simd_sld"))
167  "i6400_fpu_long+i6400_fpu_logic_l*2")
168
169;; Vector mul, dotp, madd, msub
170(define_insn_reservation "i6400_msa_mult" 5
171  (and (eq_attr "cpu" "i6400")
172       (eq_attr "type" "simd_mul"))
173  "i6400_fpu_long+i6400_fpu_mult*2")
174
175;; Float flog2
176(define_insn_reservation "i6400_msa_long_float2" 2
177  (and (eq_attr "cpu" "i6400")
178       (eq_attr "type" "simd_flog2"))
179  "i6400_fpu_long+i6400_fpu_float_l*2")
180
181;; fadd, fsub
182(define_insn_reservation "i6400_msa_long_float4" 4
183  (and (eq_attr "cpu" "i6400")
184       (eq_attr "type" "simd_fadd,simd_fcvt"))
185  "i6400_fpu_long+i6400_fpu_float_l*2")
186
187;; fmul, fexp2
188(define_insn_reservation "i6400_msa_long_float5" 5
189  (and (eq_attr "cpu" "i6400")
190       (eq_attr "type" "simd_fmul,simd_fexp2"))
191  "i6400_fpu_long+i6400_fpu_float_l*2")
192
193;; fmadd, fmsub
194(define_insn_reservation "i6400_msa_long_float8" 8
195  (and (eq_attr "cpu" "i6400")
196       (eq_attr "type" "simd_fmadd"))
197  "i6400_fpu_long+i6400_fpu_float_l*2")
198
199;; fdiv.d
200(define_insn_reservation "i6400_msa_fdiv_df" 30
201  (and (eq_attr "cpu" "i6400")
202       (and (eq_attr "mode" "V2DF")
203	    (eq_attr "type" "simd_fdiv")))
204  "i6400_fpu_long+i6400_fpu_float_l*30")
205
206;; fdiv.w
207(define_insn_reservation "i6400_msa_fdiv_sf" 22
208  (and (eq_attr "cpu" "i6400")
209       (eq_attr "type" "simd_fdiv"))
210  "i6400_fpu_long+i6400_fpu_float_l*22")
211
212;;
213;; FPU pipe
214;;
215
216;; fabs, fneg
217(define_insn_reservation "i6400_fpu_fabs" 1
218  (and (eq_attr "cpu" "i6400")
219       (eq_attr "type" "fabs,fneg,fmove"))
220  "i6400_fpu_short, i6400_fpu_apu")
221
222;; fadd, fsub, fcvt
223(define_insn_reservation "i6400_fpu_fadd" 4
224  (and (eq_attr "cpu" "i6400")
225       (eq_attr "type" "fadd,fcvt"))
226  "i6400_fpu_long, i6400_fpu_apu")
227
228;; fmul
229(define_insn_reservation "i6400_fpu_fmul" 5
230  (and (eq_attr "cpu" "i6400")
231       (eq_attr "type" "fmul"))
232  "i6400_fpu_long, i6400_fpu_apu")
233
234;; div, sqrt (Double Precision)
235(define_insn_reservation "i6400_fpu_div_df" 30
236  (and (eq_attr "cpu" "i6400")
237       (and (eq_attr "mode" "DF")
238	    (eq_attr "type" "fdiv,frdiv,fsqrt,frsqrt")))
239  "i6400_fpu_long+i6400_fpu_apu*30")
240
241;; div, sqrt (Single Precision)
242(define_insn_reservation "i6400_fpu_div_sf" 22
243  (and (eq_attr "cpu" "i6400")
244       (eq_attr "type" "fdiv,frdiv,fsqrt,frsqrt"))
245  "i6400_fpu_long+i6400_fpu_apu*22")
246
247;; sdc1, swc1
248(define_insn_reservation "i6400_fpu_store" 1
249  (and (eq_attr "cpu" "i6400")
250       (eq_attr "type" "fpstore"))
251  "i6400_agen_lsu")
252
253;; ldc1, lwc1
254(define_insn_reservation "i6400_fpu_load" 3
255  (and (eq_attr "cpu" "i6400")
256       (eq_attr "type" "fpload"))
257  "i6400_agen_lsu")
258
259;; mfc, mtc
260(define_insn_reservation "i6400_fpu_move" 1
261  (and (eq_attr "cpu" "i6400")
262       (eq_attr "move_type" "mfc, mtc"))
263  "i6400_control_alu0 | i6400_agen_alu1")
264
265;; fcmp
266(define_insn_reservation "i6400_fpu_fcmp" 2
267  (and (eq_attr "cpu" "i6400")
268       (eq_attr "type" "fcmp"))
269  "i6400_fpu_short, i6400_fpu_apu")
270
271;; fmadd
272(define_insn_reservation "i6400_fpu_fmadd" 8
273  (and (eq_attr "cpu" "i6400")
274       (eq_attr "type" "fmadd"))
275  "i6400_fpu_long, i6400_fpu_apu")
276
277;;
278;; Integer pipe
279;;
280
281;; and, lui, shifts, seb, seh
282(define_insn_reservation "i6400_int_logical" 1
283  (and (eq_attr "cpu" "i6400")
284       (eq_attr "move_type" "logical,const,andi,sll0,signext"))
285  "i6400_control_alu0 | i6400_agen_alu1")
286
287;; addi, addiu, ori, xori, add, addu, sub, nor
288(define_insn_reservation "i6400_int_add" 1
289  (and (eq_attr "cpu" "i6400")
290       (eq_attr "alu_type" "add,sub,or,xor,nor"))
291  "i6400_control_alu0 | i6400_agen_alu1")
292
293;; shifts, clo, clz, cond move, arith
294(define_insn_reservation "i6400_int_arith" 1
295  (and (eq_attr "cpu" "i6400")
296       (eq_attr "type" "shift,slt,move,clz,condmove,arith"))
297  "i6400_control_alu0 | i6400_agen_alu1")
298
299;; nop
300(define_insn_reservation "i6400_int_nop" 0
301  (and (eq_attr "cpu" "i6400")
302       (eq_attr "type" "nop"))
303  "nothing")
304
305;; mul, mulu, muh, muhu
306(define_insn_reservation "i6400_int_mult" 4
307  (and (eq_attr "cpu" "i6400")
308       (eq_attr "type" "imul3,imul,imul3nc"))
309  "i6400_gpmul")
310
311;; divide
312(define_insn_reservation "i6400_int_div" 32
313  (and (eq_attr "cpu" "i6400")
314       (eq_attr "type" "idiv,idiv3"))
315  "i6400_gpdiv*32")
316
317;; Load lb, lbu, lh, lhu, lq, lw, lw_i2f, lwxs
318(define_insn_reservation "i6400_int_load" 3
319  (and (eq_attr "cpu" "i6400")
320       (eq_attr "type" "load"))
321  "i6400_agen_lsu")
322
323;; store
324(define_insn_reservation "i6400_int_store" 1
325  (and (eq_attr "cpu" "i6400")
326       (eq_attr "type" "store"))
327  "i6400_agen_lsu")
328
329;; prefetch
330(define_insn_reservation "i6400_int_prefetch" 0
331  (and (eq_attr "cpu" "i6400")
332       (eq_attr "type" "prefetch"))
333  "i6400_agen_lsu")
334
335;; branch and jump
336(define_insn_reservation "i6400_int_branch" 1
337  (and (eq_attr "cpu" "i6400")
338       (eq_attr "type" "branch,jump"))
339  "i6400_control_ctu")
340
341;; call
342(define_insn_reservation "i6400_int_call" 1
343  (and (eq_attr "cpu" "i6400")
344       (eq_attr "jal" "indirect,direct"))
345  "i6400_control_ctu")
346