pentium.md revision 117395
1260684Skaiw;; Pentium Scheduling
2260684Skaiw;; Copyright (C) 2002 Free Software Foundation, Inc.
3260684Skaiw;;
4260684Skaiw;; This file is part of GNU CC.
5260684Skaiw;;
6260684Skaiw;; GNU CC is free software; you can redistribute it and/or modify
7260684Skaiw;; it under the terms of the GNU General Public License as published by
8260684Skaiw;; the Free Software Foundation; either version 2, or (at your option)
9260684Skaiw;; any later version.
10260684Skaiw;;
11260684Skaiw;; GNU CC is distributed in the hope that it will be useful,
12260684Skaiw;; but WITHOUT ANY WARRANTY; without even the implied warranty of
13260684Skaiw;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14260684Skaiw;; GNU General Public License for more details.
15260684Skaiw;;
16260684Skaiw;; You should have received a copy of the GNU General Public License
17260684Skaiw;; along with GNU CC; see the file COPYING.  If not, write to
18260684Skaiw;; the Free Software Foundation, 59 Temple Place - Suite 330,
19260684Skaiw;; Boston, MA 02111-1307, USA.  */
20260684Skaiw;;
21260684Skaiw;; The Pentium is an in-order core with two integer pipelines.
22260684Skaiw
23260684Skaiw;; True for insns that behave like prefixed insns on the Pentium.
24260684Skaiw(define_attr "pent_prefix" "false,true"
25260684Skaiw  (if_then_else (ior (eq_attr "prefix_0f" "1")
26260684Skaiw  		     (ior (eq_attr "prefix_data16" "1")
27260684Skaiw			  (eq_attr "prefix_rep" "1")))
28295577Semaste    (const_string "true")
29260684Skaiw    (const_string "false")))
30260684Skaiw
31260684Skaiw;; Categorize how an instruction slots.
32260684Skaiw
33260684Skaiw;; The non-MMX Pentium slots an instruction with prefixes on U pipe only,
34260684Skaiw;; while MMX Pentium can slot it on either U or V.  Model non-MMX Pentium
35260684Skaiw;; rules, because it results in noticeably better code on non-MMX Pentium
36260684Skaiw;; and doesn't hurt much on MMX.  (Prefixed instructions are not very
37300311Semaste;; common, so the scheduler usualy has a non-prefixed insn to pair).
38260684Skaiw
39295577Semaste(define_attr "pent_pair" "uv,pu,pv,np"
40295577Semaste  (cond [(eq_attr "imm_disp" "true")
41295577Semaste	   (const_string "np")
42295577Semaste	 (ior (eq_attr "type" "alu1,alu,imov,icmp,test,lea,incdec")
43295577Semaste	      (and (eq_attr "type" "pop,push")
44295577Semaste		   (eq_attr "memory" "!both")))
45260684Skaiw	   (if_then_else (eq_attr "pent_prefix" "true")
46260684Skaiw	     (const_string "pu")
47260684Skaiw	     (const_string "uv"))
48260684Skaiw	 (eq_attr "type" "ibr")
49260684Skaiw	   (const_string "pv")
50260684Skaiw	 (and (eq_attr "type" "ishift")
51260684Skaiw	      (match_operand 2 "const_int_operand" ""))
52260684Skaiw	   (const_string "pu")
53260684Skaiw	 (and (eq_attr "type" "rotate")
54260684Skaiw	      (match_operand 2 "const_int_1_operand" ""))
55276398Semaste	   (const_string "pu")
56276398Semaste	 (and (eq_attr "type" "ishift1")
57276398Semaste	      (match_operand 1 "const_int_operand" ""))
58276398Semaste	   (const_string "pu")
59276398Semaste	 (and (eq_attr "type" "rotate1")
60276398Semaste	      (match_operand 1 "const_int_1_operand" ""))
61276398Semaste	   (const_string "pu")
62276398Semaste	 (and (eq_attr "type" "call")
63276398Semaste	      (match_operand 0 "constant_call_address_operand" ""))
64276398Semaste	   (const_string "pv")
65276398Semaste	 (and (eq_attr "type" "callv")
66276398Semaste	      (match_operand 1 "constant_call_address_operand" ""))
67276398Semaste	   (const_string "pv")
68276398Semaste	]
69276398Semaste	(const_string "np")))
70260684Skaiw
71260684Skaiw(define_automaton "pentium,pentium_fpu")
72276398Semaste
73276398Semaste;; Pentium do have U and V pipes.  Instruction to both pipes
74260684Skaiw;; are alwyas issued together, much like on VLIW.
75260684Skaiw;;
76260684Skaiw;;                    predecode
77260684Skaiw;;                   /         \
78260684Skaiw;;               decodeu     decodev
79260684Skaiw;;             /    |           |
80260684Skaiw;;           fpu executeu    executev
81260684Skaiw;;            |     |           |
82260684Skaiw;;           fpu  retire     retire
83260684Skaiw;;            |
84276398Semaste;;           fpu
85276398Semaste;; We add dummy "port" pipes allocated only first cycle of
86260684Skaiw;; instruction to specify this behavior.
87283616Semaste
88283616Semaste(define_cpu_unit "pentium-portu,pentium-portv" "pentium")
89276398Semaste(define_cpu_unit "pentium-u,pentium-v" "pentium")
90260684Skaiw(absence_set "pentium-portu" "pentium-u,pentium-v")
91260684Skaiw(presence_set "pentium-portv" "pentium-portu")
92260684Skaiw
93260684Skaiw;; Floating point instructions can overlap with new issue of integer
94260684Skaiw;; instructions.  We model only first cycle of FP pipeline, as it is
95260684Skaiw;; fully pipelined.
96260684Skaiw(define_cpu_unit "pentium-fp" "pentium_fpu")
97260684Skaiw
98260684Skaiw;; There is non-pipelined multiplier unit used for complex operations.
99260684Skaiw(define_cpu_unit "pentium-fmul" "pentium_fpu")
100260684Skaiw
101260684Skaiw;; Pentium preserves memory ordering, so when load-execute-store
102260684Skaiw;; instruction is executed together with other instruction loading
103260684Skaiw;; data, the execution of the other instruction is delayed to very
104260684Skaiw;; last cycle of first instruction, when data are bypassed.
105260684Skaiw;; We model this by allocating "memory" unit when store is pending
106260684Skaiw;; and using conflicting load units together.
107260684Skaiw
108260684Skaiw(define_cpu_unit "pentium-memory" "pentium")
109260684Skaiw(define_cpu_unit "pentium-load0" "pentium")
110260684Skaiw(define_cpu_unit "pentium-load1" "pentium")
111295577Semaste(absence_set "pentium-load0,pentium-load1" "pentium-memory")
112295577Semaste
113260684Skaiw(define_reservation "pentium-load" "(pentium-load0 | pentium-load1)")
114260684Skaiw(define_reservation "pentium-np" "(pentium-u + pentium-v)")
115260684Skaiw(define_reservation "pentium-uv" "(pentium-u | pentium-v)")
116260684Skaiw(define_reservation "pentium-portuv" "(pentium-portu | pentium-portv)")
117260684Skaiw(define_reservation "pentium-firstu" "(pentium-u + pentium-portu)")
118260684Skaiw(define_reservation "pentium-firstv" "(pentium-v + pentium-portuv)")
119260684Skaiw(define_reservation "pentium-firstuv" "(pentium-uv + pentium-portuv)")
120260684Skaiw(define_reservation "pentium-firstuload" "(pentium-load + pentium-firstu)")
121260684Skaiw(define_reservation "pentium-firstvload" "(pentium-load + pentium-firstv)")
122260684Skaiw(define_reservation "pentium-firstuvload" "(pentium-load + pentium-firstuv)
123260684Skaiw					   | (pentium-firstv,pentium-v,
124260684Skaiw					      (pentium-load+pentium-firstv))")
125260684Skaiw(define_reservation "pentium-firstuboth" "(pentium-load + pentium-firstu
126260684Skaiw					   + pentium-memory)")
127260684Skaiw(define_reservation "pentium-firstvboth" "(pentium-load + pentium-firstv
128260684Skaiw					   + pentium-memory)")
129260684Skaiw(define_reservation "pentium-firstuvboth" "(pentium-load + pentium-firstuv
130260684Skaiw					    + pentium-memory)
131260684Skaiw					   | (pentium-firstv,pentium-v,
132260684Skaiw					      (pentium-load+pentium-firstv))")
133260684Skaiw
134260684Skaiw;; Few common long latency instructions
135260684Skaiw(define_insn_reservation "pent_mul" 11
136260684Skaiw  (and (eq_attr "cpu" "pentium")
137260684Skaiw       (eq_attr "type" "imul"))
138260684Skaiw  "pentium-np*11")
139280932Semaste
140280932Semaste(define_insn_reservation "pent_str" 12
141280932Semaste  (and (eq_attr "cpu" "pentium")
142280932Semaste       (eq_attr "type" "str"))
143280932Semaste  "pentium-np*12")
144280932Semaste
145280932Semaste;; Integer division and some other long latency instruction block all
146280932Semaste;; units, including the FP pipe.  There is no value in modeling the
147280932Semaste;; latency of these instructions and not modeling the latency
148280932Semaste;; decreases the size of the DFA.
149280932Semaste(define_insn_reservation "pent_block" 1
150260684Skaiw  (and (eq_attr "cpu" "pentium")
151260684Skaiw       (eq_attr "type" "idiv"))
152260684Skaiw  "pentium-np+pentium-fp")
153260684Skaiw
154260684Skaiw(define_insn_reservation "pent_cld" 2
155260684Skaiw  (and (eq_attr "cpu" "pentium")
156260684Skaiw       (eq_attr "type" "cld"))
157260684Skaiw  "pentium-np*2")
158260684Skaiw
159260684Skaiw;;  Moves usually have one cycle penalty, but there are exceptions.
160260684Skaiw(define_insn_reservation "pent_fmov" 1
161260684Skaiw  (and (eq_attr "cpu" "pentium")
162260684Skaiw       (and (eq_attr "type" "fmov")
163260684Skaiw	    (eq_attr "memory" "none,load")))
164260684Skaiw  "(pentium-fp+pentium-np)")
165260684Skaiw
166260684Skaiw(define_insn_reservation "pent_fpmovxf" 3
167260684Skaiw  (and (eq_attr "cpu" "pentium")
168260684Skaiw       (and (eq_attr "type" "fmov")
169260684Skaiw	    (and (eq_attr "memory" "load,store")
170260684Skaiw		 (eq_attr "mode" "XF"))))
171300311Semaste  "(pentium-fp+pentium-np)*3")
172283616Semaste
173283616Semaste(define_insn_reservation "pent_fpstore" 2
174283616Semaste  (and (eq_attr "cpu" "pentium")
175260684Skaiw       (and (eq_attr "type" "fmov")
176260684Skaiw	    (ior (match_operand 1 "immediate_operand" "")
177260684Skaiw		 (eq_attr "memory" "store"))))
178260684Skaiw  "(pentium-fp+pentium-np)*2")
179260684Skaiw
180260684Skaiw(define_insn_reservation "pent_imov" 1
181260684Skaiw  (and (eq_attr "cpu" "pentium")
182260684Skaiw       (eq_attr "type" "imov"))
183260684Skaiw  "pentium-firstuv")
184260684Skaiw
185260684Skaiw;; Push and pop instructions have 1 cycle latency and special
186260684Skaiw;; hardware bypass allows them to be paired with other push,pop
187260684Skaiw;; and call instructions.
188260684Skaiw(define_bypass 0 "pent_push,pent_pop" "pent_push,pent_pop,pent_call")
189260684Skaiw(define_insn_reservation "pent_push" 1
190260684Skaiw  (and (eq_attr "cpu" "pentium")
191260684Skaiw       (and (eq_attr "type" "push")
192260684Skaiw	    (eq_attr "memory" "store")))
193260684Skaiw  "pentium-firstuv")
194260684Skaiw
195260684Skaiw(define_insn_reservation "pent_pop" 1
196260684Skaiw  (and (eq_attr "cpu" "pentium")
197260684Skaiw       (eq_attr "type" "pop"))
198260684Skaiw  "pentium-firstuv")
199260684Skaiw
200260684Skaiw;; Call and branch instruction can execute in either pipe, but
201260684Skaiw;; they are only pairable when in the v pipe.
202260684Skaiw(define_insn_reservation "pent_call" 10
203260684Skaiw  (and (eq_attr "cpu" "pentium")
204260684Skaiw       (eq_attr "type" "call,callv"))
205260684Skaiw  "pentium-firstv,pentium-v*9")
206260684Skaiw
207260684Skaiw(define_insn_reservation "pent_branch" 1
208260684Skaiw  (and (eq_attr "cpu" "pentium")
209260684Skaiw       (eq_attr "type" "ibr"))
210260684Skaiw  "pentium-firstv")
211260684Skaiw
212295577Semaste;; Floating point instruction dispatch in U pipe, but continue
213295577Semaste;; in FP pipeline allowing other isntructions to be executed.
214295577Semaste(define_insn_reservation "pent_fp" 3
215295577Semaste  (and (eq_attr "cpu" "pentium")
216260684Skaiw       (eq_attr "type" "fop,fistp"))
217260684Skaiw  "(pentium-firstu+pentium-fp),nothing,nothing")
218260684Skaiw
219295577Semaste;; First two cycles of fmul are not pipelined.
220260684Skaiw(define_insn_reservation "pent_fmul" 3
221283616Semaste  (and (eq_attr "cpu" "pentium")
222260684Skaiw       (eq_attr "type" "fmul"))
223295577Semaste  "(pentium-firstuv+pentium-fp+pentium-fmul),pentium-fmul,nothing")
224283616Semaste
225283616Semaste;; Long latency FP instructions overlap with integer instructions,
226283616Semaste;; but only last 2 cycles with FP ones.
227295577Semaste(define_insn_reservation "pent_fdiv" 39
228295577Semaste  (and (eq_attr "cpu" "pentium")
229295577Semaste       (eq_attr "type" "fdiv"))
230295577Semaste  "(pentium-np+pentium-fp+pentium-fmul),
231295577Semaste   (pentium-fp+pentium-fmul)*36,pentium-fmul*2")
232295577Semaste
233295577Semaste(define_insn_reservation "pent_fpspc" 70
234295577Semaste  (and (eq_attr "cpu" "pentium")
235295577Semaste       (eq_attr "type" "fpspc"))
236295577Semaste  "(pentium-np+pentium-fp+pentium-fmul),
237295577Semaste   (pentium-fp+pentium-fmul)*67,pentium-fmul*2")
238295577Semaste
239295577Semaste;; Integer instructions.  Load/execute/store takes 3 cycles,
240260684Skaiw;; load/execute 2 cycles and execute only one cycle.
241260684Skaiw(define_insn_reservation "pent_uv_both" 3
242260684Skaiw  (and (eq_attr "cpu" "pentium")
243260684Skaiw       (and (eq_attr "pent_pair" "uv")
244260684Skaiw	    (eq_attr "memory" "both")))
245260684Skaiw  "pentium-firstuvboth,pentium-uv+pentium-memory,pentium-uv")
246260684Skaiw
247260684Skaiw(define_insn_reservation "pent_u_both" 3
248260684Skaiw  (and (eq_attr "cpu" "pentium")
249260684Skaiw       (and (eq_attr "pent_pair" "pu")
250260684Skaiw	    (eq_attr "memory" "both")))
251260684Skaiw  "pentium-firstuboth,pentium-u+pentium-memory,pentium-u")
252260684Skaiw
253260684Skaiw(define_insn_reservation "pent_v_both" 3
254260684Skaiw  (and (eq_attr "cpu" "pentium")
255260684Skaiw       (and (eq_attr "pent_pair" "pv")
256260684Skaiw	    (eq_attr "memory" "both")))
257260684Skaiw  "pentium-firstvboth,pentium-v+pentium-memory,pentium-v")
258260684Skaiw
259260684Skaiw(define_insn_reservation "pent_np_both" 3
260260684Skaiw  (and (eq_attr "cpu" "pentium")
261300311Semaste       (and (eq_attr "pent_pair" "np")
262260684Skaiw	    (eq_attr "memory" "both")))
263260684Skaiw  "pentium-np,pentium-np,pentium-np")
264283616Semaste
265260684Skaiw(define_insn_reservation "pent_uv_load" 2
266260684Skaiw  (and (eq_attr "cpu" "pentium")
267260684Skaiw       (and (eq_attr "pent_pair" "uv")
268260684Skaiw	    (eq_attr "memory" "load")))
269260684Skaiw  "pentium-firstuvload,pentium-uv")
270260684Skaiw
271260684Skaiw(define_insn_reservation "pent_u_load" 2
272260684Skaiw  (and (eq_attr "cpu" "pentium")
273260684Skaiw       (and (eq_attr "pent_pair" "pu")
274260684Skaiw	    (eq_attr "memory" "load")))
275260684Skaiw  "pentium-firstuload,pentium-u")
276260684Skaiw
277260684Skaiw(define_insn_reservation "pent_v_load" 2
278260684Skaiw  (and (eq_attr "cpu" "pentium")
279260684Skaiw       (and (eq_attr "pent_pair" "pv")
280260684Skaiw	    (eq_attr "memory" "load")))
281260684Skaiw  "pentium-firstvload,pentium-v")
282260684Skaiw
283260684Skaiw(define_insn_reservation "pent_np_load" 2
284260684Skaiw  (and (eq_attr "cpu" "pentium")
285260684Skaiw       (and (eq_attr "pent_pair" "np")
286260684Skaiw	    (eq_attr "memory" "load")))
287260684Skaiw  "pentium-np,pentium-np")
288260684Skaiw
289260684Skaiw(define_insn_reservation "pent_uv" 1
290260684Skaiw  (and (eq_attr "cpu" "pentium")
291260684Skaiw       (and (eq_attr "pent_pair" "uv")
292260684Skaiw	    (eq_attr "memory" "none")))
293260684Skaiw  "pentium-firstuv")
294260684Skaiw
295260684Skaiw(define_insn_reservation "pent_u" 1
296260684Skaiw  (and (eq_attr "cpu" "pentium")
297260684Skaiw       (and (eq_attr "pent_pair" "pu")
298260684Skaiw	    (eq_attr "memory" "none")))
299260684Skaiw  "pentium-firstu")
300260684Skaiw
301260684Skaiw(define_insn_reservation "pent_v" 1
302260684Skaiw  (and (eq_attr "cpu" "pentium")
303260684Skaiw       (and (eq_attr "pent_pair" "pv")
304260684Skaiw	    (eq_attr "memory" "none")))
305260684Skaiw  "pentium-firstv")
306260684Skaiw
307260684Skaiw(define_insn_reservation "pent_np" 1
308260684Skaiw  (and (eq_attr "cpu" "pentium")
309260684Skaiw       (and (eq_attr "pent_pair" "np")
310260684Skaiw	    (eq_attr "memory" "none")))
311260684Skaiw  "pentium-np")
312260684Skaiw
313260684Skaiw