]>
Commit | Line | Data |
---|---|---|
af2728a4 | 1 | ;; Pentium Scheduling |
8d9254fc | 2 | ;; Copyright (C) 2002-2020 Free Software Foundation, Inc. |
af2728a4 | 3 | ;; |
a805d35f | 4 | ;; This file is part of GCC. |
af2728a4 | 5 | ;; |
a805d35f | 6 | ;; GCC is free software; you can redistribute it and/or modify |
af2728a4 | 7 | ;; it under the terms of the GNU General Public License as published by |
2f83c7d6 | 8 | ;; the Free Software Foundation; either version 3, or (at your option) |
af2728a4 JL |
9 | ;; any later version. |
10 | ;; | |
a805d35f | 11 | ;; GCC is distributed in the hope that it will be useful, |
af2728a4 JL |
12 | ;; but WITHOUT ANY WARRANTY; without even the implied warranty of |
13 | ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
14 | ;; GNU General Public License for more details. | |
15 | ;; | |
16 | ;; You should have received a copy of the GNU General Public License | |
2f83c7d6 NC |
17 | ;; along with GCC; see the file COPYING3. If not see |
18 | ;; <http://www.gnu.org/licenses/>. */ | |
af2728a4 JL |
19 | ;; |
20 | ;; The Pentium is an in-order core with two integer pipelines. | |
21 | ||
22 | ;; True for insns that behave like prefixed insns on the Pentium. | |
23 | (define_attr "pent_prefix" "false,true" | |
24 | (if_then_else (ior (eq_attr "prefix_0f" "1") | |
25 | (ior (eq_attr "prefix_data16" "1") | |
26 | (eq_attr "prefix_rep" "1"))) | |
27 | (const_string "true") | |
28 | (const_string "false"))) | |
29 | ||
30 | ;; Categorize how an instruction slots. | |
31 | ||
32 | ;; The non-MMX Pentium slots an instruction with prefixes on U pipe only, | |
33 | ;; while MMX Pentium can slot it on either U or V. Model non-MMX Pentium | |
34 | ;; rules, because it results in noticeably better code on non-MMX Pentium | |
35 | ;; and doesn't hurt much on MMX. (Prefixed instructions are not very | |
d1f87653 | 36 | ;; common, so the scheduler usually has a non-prefixed insn to pair). |
af2728a4 JL |
37 | |
38 | (define_attr "pent_pair" "uv,pu,pv,np" | |
39 | (cond [(eq_attr "imm_disp" "true") | |
40 | (const_string "np") | |
41 | (ior (eq_attr "type" "alu1,alu,imov,icmp,test,lea,incdec") | |
42 | (and (eq_attr "type" "pop,push") | |
43 | (eq_attr "memory" "!both"))) | |
44 | (if_then_else (eq_attr "pent_prefix" "true") | |
45 | (const_string "pu") | |
46 | (const_string "uv")) | |
47 | (eq_attr "type" "ibr") | |
48 | (const_string "pv") | |
49 | (and (eq_attr "type" "ishift") | |
82e86dc6 | 50 | (match_operand 2 "const_int_operand")) |
af2728a4 JL |
51 | (const_string "pu") |
52 | (and (eq_attr "type" "rotate") | |
82e86dc6 | 53 | (match_operand 2 "const1_operand")) |
af2728a4 | 54 | (const_string "pu") |
1b245ade | 55 | (and (eq_attr "type" "ishift1") |
82e86dc6 | 56 | (match_operand 1 "const_int_operand")) |
1b245ade JH |
57 | (const_string "pu") |
58 | (and (eq_attr "type" "rotate1") | |
82e86dc6 | 59 | (match_operand 1 "const1_operand")) |
1b245ade | 60 | (const_string "pu") |
af2728a4 | 61 | (and (eq_attr "type" "call") |
82e86dc6 | 62 | (match_operand 0 "constant_call_address_operand")) |
af2728a4 JL |
63 | (const_string "pv") |
64 | (and (eq_attr "type" "callv") | |
82e86dc6 | 65 | (match_operand 1 "constant_call_address_operand")) |
af2728a4 JL |
66 | (const_string "pv") |
67 | ] | |
68 | (const_string "np"))) | |
69 | ||
70 | (define_automaton "pentium,pentium_fpu") | |
71 | ||
72 | ;; Pentium do have U and V pipes. Instruction to both pipes | |
d1f87653 | 73 | ;; are always issued together, much like on VLIW. |
af2728a4 JL |
74 | ;; |
75 | ;; predecode | |
76 | ;; / \ | |
77 | ;; decodeu decodev | |
78 | ;; / | | | |
79 | ;; fpu executeu executev | |
80 | ;; | | | | |
81 | ;; fpu retire retire | |
82 | ;; | | |
83 | ;; fpu | |
84 | ;; We add dummy "port" pipes allocated only first cycle of | |
9cd10576 | 85 | ;; instruction to specify this behavior. |
af2728a4 JL |
86 | |
87 | (define_cpu_unit "pentium-portu,pentium-portv" "pentium") | |
88 | (define_cpu_unit "pentium-u,pentium-v" "pentium") | |
89 | (absence_set "pentium-portu" "pentium-u,pentium-v") | |
90 | (presence_set "pentium-portv" "pentium-portu") | |
91 | ||
92 | ;; Floating point instructions can overlap with new issue of integer | |
93 | ;; instructions. We model only first cycle of FP pipeline, as it is | |
94 | ;; fully pipelined. | |
95 | (define_cpu_unit "pentium-fp" "pentium_fpu") | |
96 | ||
97 | ;; There is non-pipelined multiplier unit used for complex operations. | |
98 | (define_cpu_unit "pentium-fmul" "pentium_fpu") | |
99 | ||
100 | ;; Pentium preserves memory ordering, so when load-execute-store | |
101 | ;; instruction is executed together with other instruction loading | |
102 | ;; data, the execution of the other instruction is delayed to very | |
103 | ;; last cycle of first instruction, when data are bypassed. | |
104 | ;; We model this by allocating "memory" unit when store is pending | |
105 | ;; and using conflicting load units together. | |
106 | ||
107 | (define_cpu_unit "pentium-memory" "pentium") | |
108 | (define_cpu_unit "pentium-load0" "pentium") | |
109 | (define_cpu_unit "pentium-load1" "pentium") | |
110 | (absence_set "pentium-load0,pentium-load1" "pentium-memory") | |
111 | ||
112 | (define_reservation "pentium-load" "(pentium-load0 | pentium-load1)") | |
113 | (define_reservation "pentium-np" "(pentium-u + pentium-v)") | |
114 | (define_reservation "pentium-uv" "(pentium-u | pentium-v)") | |
115 | (define_reservation "pentium-portuv" "(pentium-portu | pentium-portv)") | |
116 | (define_reservation "pentium-firstu" "(pentium-u + pentium-portu)") | |
117 | (define_reservation "pentium-firstv" "(pentium-v + pentium-portuv)") | |
118 | (define_reservation "pentium-firstuv" "(pentium-uv + pentium-portuv)") | |
119 | (define_reservation "pentium-firstuload" "(pentium-load + pentium-firstu)") | |
120 | (define_reservation "pentium-firstvload" "(pentium-load + pentium-firstv)") | |
121 | (define_reservation "pentium-firstuvload" "(pentium-load + pentium-firstuv) | |
122 | | (pentium-firstv,pentium-v, | |
123 | (pentium-load+pentium-firstv))") | |
124 | (define_reservation "pentium-firstuboth" "(pentium-load + pentium-firstu | |
125 | + pentium-memory)") | |
942579db | 126 | (define_reservation "pentium-firstvboth" "(pentium-load + pentium-firstv |
af2728a4 JL |
127 | + pentium-memory)") |
128 | (define_reservation "pentium-firstuvboth" "(pentium-load + pentium-firstuv | |
129 | + pentium-memory) | |
130 | | (pentium-firstv,pentium-v, | |
131 | (pentium-load+pentium-firstv))") | |
132 | ||
133 | ;; Few common long latency instructions | |
134 | (define_insn_reservation "pent_mul" 11 | |
135 | (and (eq_attr "cpu" "pentium") | |
136 | (eq_attr "type" "imul")) | |
137 | "pentium-np*11") | |
138 | ||
139 | (define_insn_reservation "pent_str" 12 | |
140 | (and (eq_attr "cpu" "pentium") | |
141 | (eq_attr "type" "str")) | |
142 | "pentium-np*12") | |
143 | ||
144 | ;; Integer division and some other long latency instruction block all | |
145 | ;; units, including the FP pipe. There is no value in modeling the | |
146 | ;; latency of these instructions and not modeling the latency | |
147 | ;; decreases the size of the DFA. | |
148 | (define_insn_reservation "pent_block" 1 | |
149 | (and (eq_attr "cpu" "pentium") | |
150 | (eq_attr "type" "idiv")) | |
151 | "pentium-np+pentium-fp") | |
152 | ||
af2728a4 JL |
153 | ;; Moves usually have one cycle penalty, but there are exceptions. |
154 | (define_insn_reservation "pent_fmov" 1 | |
155 | (and (eq_attr "cpu" "pentium") | |
156 | (and (eq_attr "type" "fmov") | |
157 | (eq_attr "memory" "none,load"))) | |
158 | "(pentium-fp+pentium-np)") | |
159 | ||
160 | (define_insn_reservation "pent_fpmovxf" 3 | |
161 | (and (eq_attr "cpu" "pentium") | |
162 | (and (eq_attr "type" "fmov") | |
163 | (and (eq_attr "memory" "load,store") | |
164 | (eq_attr "mode" "XF")))) | |
165 | "(pentium-fp+pentium-np)*3") | |
166 | ||
167 | (define_insn_reservation "pent_fpstore" 2 | |
168 | (and (eq_attr "cpu" "pentium") | |
169 | (and (eq_attr "type" "fmov") | |
82e86dc6 | 170 | (ior (match_operand 1 "immediate_operand") |
af2728a4 JL |
171 | (eq_attr "memory" "store")))) |
172 | "(pentium-fp+pentium-np)*2") | |
173 | ||
174 | (define_insn_reservation "pent_imov" 1 | |
175 | (and (eq_attr "cpu" "pentium") | |
176 | (eq_attr "type" "imov")) | |
177 | "pentium-firstuv") | |
178 | ||
179 | ;; Push and pop instructions have 1 cycle latency and special | |
180 | ;; hardware bypass allows them to be paired with other push,pop | |
181 | ;; and call instructions. | |
182 | (define_bypass 0 "pent_push,pent_pop" "pent_push,pent_pop,pent_call") | |
183 | (define_insn_reservation "pent_push" 1 | |
184 | (and (eq_attr "cpu" "pentium") | |
185 | (and (eq_attr "type" "push") | |
186 | (eq_attr "memory" "store"))) | |
187 | "pentium-firstuv") | |
188 | ||
189 | (define_insn_reservation "pent_pop" 1 | |
190 | (and (eq_attr "cpu" "pentium") | |
4977bab6 | 191 | (eq_attr "type" "pop,leave")) |
af2728a4 JL |
192 | "pentium-firstuv") |
193 | ||
194 | ;; Call and branch instruction can execute in either pipe, but | |
195 | ;; they are only pairable when in the v pipe. | |
196 | (define_insn_reservation "pent_call" 10 | |
197 | (and (eq_attr "cpu" "pentium") | |
198 | (eq_attr "type" "call,callv")) | |
199 | "pentium-firstv,pentium-v*9") | |
200 | ||
201 | (define_insn_reservation "pent_branch" 1 | |
202 | (and (eq_attr "cpu" "pentium") | |
203 | (eq_attr "type" "ibr")) | |
204 | "pentium-firstv") | |
205 | ||
206 | ;; Floating point instruction dispatch in U pipe, but continue | |
2a43945f | 207 | ;; in FP pipeline allowing other instructions to be executed. |
af2728a4 JL |
208 | (define_insn_reservation "pent_fp" 3 |
209 | (and (eq_attr "cpu" "pentium") | |
210 | (eq_attr "type" "fop,fistp")) | |
211 | "(pentium-firstu+pentium-fp),nothing,nothing") | |
212 | ||
213 | ;; First two cycles of fmul are not pipelined. | |
214 | (define_insn_reservation "pent_fmul" 3 | |
215 | (and (eq_attr "cpu" "pentium") | |
216 | (eq_attr "type" "fmul")) | |
217 | "(pentium-firstuv+pentium-fp+pentium-fmul),pentium-fmul,nothing") | |
218 | ||
219 | ;; Long latency FP instructions overlap with integer instructions, | |
220 | ;; but only last 2 cycles with FP ones. | |
221 | (define_insn_reservation "pent_fdiv" 39 | |
222 | (and (eq_attr "cpu" "pentium") | |
223 | (eq_attr "type" "fdiv")) | |
224 | "(pentium-np+pentium-fp+pentium-fmul), | |
225 | (pentium-fp+pentium-fmul)*36,pentium-fmul*2") | |
226 | ||
227 | (define_insn_reservation "pent_fpspc" 70 | |
228 | (and (eq_attr "cpu" "pentium") | |
229 | (eq_attr "type" "fpspc")) | |
230 | "(pentium-np+pentium-fp+pentium-fmul), | |
231 | (pentium-fp+pentium-fmul)*67,pentium-fmul*2") | |
232 | ||
233 | ;; Integer instructions. Load/execute/store takes 3 cycles, | |
234 | ;; load/execute 2 cycles and execute only one cycle. | |
235 | (define_insn_reservation "pent_uv_both" 3 | |
236 | (and (eq_attr "cpu" "pentium") | |
237 | (and (eq_attr "pent_pair" "uv") | |
238 | (eq_attr "memory" "both"))) | |
239 | "pentium-firstuvboth,pentium-uv+pentium-memory,pentium-uv") | |
240 | ||
241 | (define_insn_reservation "pent_u_both" 3 | |
242 | (and (eq_attr "cpu" "pentium") | |
243 | (and (eq_attr "pent_pair" "pu") | |
244 | (eq_attr "memory" "both"))) | |
245 | "pentium-firstuboth,pentium-u+pentium-memory,pentium-u") | |
246 | ||
247 | (define_insn_reservation "pent_v_both" 3 | |
248 | (and (eq_attr "cpu" "pentium") | |
249 | (and (eq_attr "pent_pair" "pv") | |
250 | (eq_attr "memory" "both"))) | |
251 | "pentium-firstvboth,pentium-v+pentium-memory,pentium-v") | |
252 | ||
253 | (define_insn_reservation "pent_np_both" 3 | |
254 | (and (eq_attr "cpu" "pentium") | |
255 | (and (eq_attr "pent_pair" "np") | |
256 | (eq_attr "memory" "both"))) | |
257 | "pentium-np,pentium-np,pentium-np") | |
258 | ||
259 | (define_insn_reservation "pent_uv_load" 2 | |
260 | (and (eq_attr "cpu" "pentium") | |
261 | (and (eq_attr "pent_pair" "uv") | |
262 | (eq_attr "memory" "load"))) | |
263 | "pentium-firstuvload,pentium-uv") | |
264 | ||
265 | (define_insn_reservation "pent_u_load" 2 | |
266 | (and (eq_attr "cpu" "pentium") | |
267 | (and (eq_attr "pent_pair" "pu") | |
268 | (eq_attr "memory" "load"))) | |
269 | "pentium-firstuload,pentium-u") | |
270 | ||
271 | (define_insn_reservation "pent_v_load" 2 | |
272 | (and (eq_attr "cpu" "pentium") | |
273 | (and (eq_attr "pent_pair" "pv") | |
274 | (eq_attr "memory" "load"))) | |
275 | "pentium-firstvload,pentium-v") | |
276 | ||
277 | (define_insn_reservation "pent_np_load" 2 | |
278 | (and (eq_attr "cpu" "pentium") | |
279 | (and (eq_attr "pent_pair" "np") | |
280 | (eq_attr "memory" "load"))) | |
281 | "pentium-np,pentium-np") | |
282 | ||
283 | (define_insn_reservation "pent_uv" 1 | |
284 | (and (eq_attr "cpu" "pentium") | |
285 | (and (eq_attr "pent_pair" "uv") | |
286 | (eq_attr "memory" "none"))) | |
287 | "pentium-firstuv") | |
288 | ||
289 | (define_insn_reservation "pent_u" 1 | |
290 | (and (eq_attr "cpu" "pentium") | |
291 | (and (eq_attr "pent_pair" "pu") | |
292 | (eq_attr "memory" "none"))) | |
293 | "pentium-firstu") | |
294 | ||
295 | (define_insn_reservation "pent_v" 1 | |
296 | (and (eq_attr "cpu" "pentium") | |
297 | (and (eq_attr "pent_pair" "pv") | |
298 | (eq_attr "memory" "none"))) | |
299 | "pentium-firstv") | |
300 | ||
301 | (define_insn_reservation "pent_np" 1 | |
302 | (and (eq_attr "cpu" "pentium") | |
303 | (and (eq_attr "pent_pair" "np") | |
304 | (eq_attr "memory" "none"))) | |
305 | "pentium-np") | |
306 |