pentium.md revision 169689
1117395Skan;; Pentium Scheduling 2117395Skan;; Copyright (C) 2002 Free Software Foundation, Inc. 3117395Skan;; 4132718Skan;; This file is part of GCC. 5117395Skan;; 6132718Skan;; GCC is free software; you can redistribute it and/or modify 7117395Skan;; it under the terms of the GNU General Public License as published by 8117395Skan;; the Free Software Foundation; either version 2, or (at your option) 9117395Skan;; any later version. 10117395Skan;; 11132718Skan;; GCC is distributed in the hope that it will be useful, 12117395Skan;; but WITHOUT ANY WARRANTY; without even the implied warranty of 13117395Skan;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14117395Skan;; GNU General Public License for more details. 15117395Skan;; 16117395Skan;; You should have received a copy of the GNU General Public License 17132718Skan;; along with GCC; see the file COPYING. If not, write to 18169689Skan;; the Free Software Foundation, 51 Franklin Street, Fifth Floor, 19169689Skan;; Boston, MA 02110-1301, USA. */ 20117395Skan;; 21117395Skan;; The Pentium is an in-order core with two integer pipelines. 22117395Skan 23117395Skan;; True for insns that behave like prefixed insns on the Pentium. 24117395Skan(define_attr "pent_prefix" "false,true" 25117395Skan (if_then_else (ior (eq_attr "prefix_0f" "1") 26117395Skan (ior (eq_attr "prefix_data16" "1") 27117395Skan (eq_attr "prefix_rep" "1"))) 28117395Skan (const_string "true") 29117395Skan (const_string "false"))) 30117395Skan 31117395Skan;; Categorize how an instruction slots. 32117395Skan 33117395Skan;; The non-MMX Pentium slots an instruction with prefixes on U pipe only, 34117395Skan;; while MMX Pentium can slot it on either U or V. Model non-MMX Pentium 35117395Skan;; rules, because it results in noticeably better code on non-MMX Pentium 36117395Skan;; and doesn't hurt much on MMX. (Prefixed instructions are not very 37132718Skan;; common, so the scheduler usually has a non-prefixed insn to pair). 38117395Skan 39117395Skan(define_attr "pent_pair" "uv,pu,pv,np" 40117395Skan (cond [(eq_attr "imm_disp" "true") 41117395Skan (const_string "np") 42117395Skan (ior (eq_attr "type" "alu1,alu,imov,icmp,test,lea,incdec") 43117395Skan (and (eq_attr "type" "pop,push") 44117395Skan (eq_attr "memory" "!both"))) 45117395Skan (if_then_else (eq_attr "pent_prefix" "true") 46117395Skan (const_string "pu") 47117395Skan (const_string "uv")) 48117395Skan (eq_attr "type" "ibr") 49117395Skan (const_string "pv") 50117395Skan (and (eq_attr "type" "ishift") 51117395Skan (match_operand 2 "const_int_operand" "")) 52117395Skan (const_string "pu") 53117395Skan (and (eq_attr "type" "rotate") 54132718Skan (match_operand 2 "const1_operand" "")) 55117395Skan (const_string "pu") 56117395Skan (and (eq_attr "type" "ishift1") 57117395Skan (match_operand 1 "const_int_operand" "")) 58117395Skan (const_string "pu") 59117395Skan (and (eq_attr "type" "rotate1") 60132718Skan (match_operand 1 "const1_operand" "")) 61117395Skan (const_string "pu") 62117395Skan (and (eq_attr "type" "call") 63117395Skan (match_operand 0 "constant_call_address_operand" "")) 64117395Skan (const_string "pv") 65117395Skan (and (eq_attr "type" "callv") 66117395Skan (match_operand 1 "constant_call_address_operand" "")) 67117395Skan (const_string "pv") 68117395Skan ] 69117395Skan (const_string "np"))) 70117395Skan 71117395Skan(define_automaton "pentium,pentium_fpu") 72117395Skan 73117395Skan;; Pentium do have U and V pipes. Instruction to both pipes 74132718Skan;; are always issued together, much like on VLIW. 75117395Skan;; 76117395Skan;; predecode 77117395Skan;; / \ 78117395Skan;; decodeu decodev 79117395Skan;; / | | 80117395Skan;; fpu executeu executev 81117395Skan;; | | | 82117395Skan;; fpu retire retire 83117395Skan;; | 84117395Skan;; fpu 85117395Skan;; We add dummy "port" pipes allocated only first cycle of 86117395Skan;; instruction to specify this behavior. 87117395Skan 88117395Skan(define_cpu_unit "pentium-portu,pentium-portv" "pentium") 89117395Skan(define_cpu_unit "pentium-u,pentium-v" "pentium") 90117395Skan(absence_set "pentium-portu" "pentium-u,pentium-v") 91117395Skan(presence_set "pentium-portv" "pentium-portu") 92117395Skan 93117395Skan;; Floating point instructions can overlap with new issue of integer 94117395Skan;; instructions. We model only first cycle of FP pipeline, as it is 95117395Skan;; fully pipelined. 96117395Skan(define_cpu_unit "pentium-fp" "pentium_fpu") 97117395Skan 98117395Skan;; There is non-pipelined multiplier unit used for complex operations. 99117395Skan(define_cpu_unit "pentium-fmul" "pentium_fpu") 100117395Skan 101117395Skan;; Pentium preserves memory ordering, so when load-execute-store 102117395Skan;; instruction is executed together with other instruction loading 103117395Skan;; data, the execution of the other instruction is delayed to very 104117395Skan;; last cycle of first instruction, when data are bypassed. 105117395Skan;; We model this by allocating "memory" unit when store is pending 106117395Skan;; and using conflicting load units together. 107117395Skan 108117395Skan(define_cpu_unit "pentium-memory" "pentium") 109117395Skan(define_cpu_unit "pentium-load0" "pentium") 110117395Skan(define_cpu_unit "pentium-load1" "pentium") 111117395Skan(absence_set "pentium-load0,pentium-load1" "pentium-memory") 112117395Skan 113117395Skan(define_reservation "pentium-load" "(pentium-load0 | pentium-load1)") 114117395Skan(define_reservation "pentium-np" "(pentium-u + pentium-v)") 115117395Skan(define_reservation "pentium-uv" "(pentium-u | pentium-v)") 116117395Skan(define_reservation "pentium-portuv" "(pentium-portu | pentium-portv)") 117117395Skan(define_reservation "pentium-firstu" "(pentium-u + pentium-portu)") 118117395Skan(define_reservation "pentium-firstv" "(pentium-v + pentium-portuv)") 119117395Skan(define_reservation "pentium-firstuv" "(pentium-uv + pentium-portuv)") 120117395Skan(define_reservation "pentium-firstuload" "(pentium-load + pentium-firstu)") 121117395Skan(define_reservation "pentium-firstvload" "(pentium-load + pentium-firstv)") 122117395Skan(define_reservation "pentium-firstuvload" "(pentium-load + pentium-firstuv) 123117395Skan | (pentium-firstv,pentium-v, 124117395Skan (pentium-load+pentium-firstv))") 125117395Skan(define_reservation "pentium-firstuboth" "(pentium-load + pentium-firstu 126117395Skan + pentium-memory)") 127117395Skan(define_reservation "pentium-firstvboth" "(pentium-load + pentium-firstv 128117395Skan + pentium-memory)") 129117395Skan(define_reservation "pentium-firstuvboth" "(pentium-load + pentium-firstuv 130117395Skan + pentium-memory) 131117395Skan | (pentium-firstv,pentium-v, 132117395Skan (pentium-load+pentium-firstv))") 133117395Skan 134117395Skan;; Few common long latency instructions 135117395Skan(define_insn_reservation "pent_mul" 11 136117395Skan (and (eq_attr "cpu" "pentium") 137117395Skan (eq_attr "type" "imul")) 138117395Skan "pentium-np*11") 139117395Skan 140117395Skan(define_insn_reservation "pent_str" 12 141117395Skan (and (eq_attr "cpu" "pentium") 142117395Skan (eq_attr "type" "str")) 143117395Skan "pentium-np*12") 144117395Skan 145117395Skan;; Integer division and some other long latency instruction block all 146117395Skan;; units, including the FP pipe. There is no value in modeling the 147117395Skan;; latency of these instructions and not modeling the latency 148117395Skan;; decreases the size of the DFA. 149117395Skan(define_insn_reservation "pent_block" 1 150117395Skan (and (eq_attr "cpu" "pentium") 151117395Skan (eq_attr "type" "idiv")) 152117395Skan "pentium-np+pentium-fp") 153117395Skan 154117395Skan(define_insn_reservation "pent_cld" 2 155117395Skan (and (eq_attr "cpu" "pentium") 156117395Skan (eq_attr "type" "cld")) 157117395Skan "pentium-np*2") 158117395Skan 159117395Skan;; Moves usually have one cycle penalty, but there are exceptions. 160117395Skan(define_insn_reservation "pent_fmov" 1 161117395Skan (and (eq_attr "cpu" "pentium") 162117395Skan (and (eq_attr "type" "fmov") 163117395Skan (eq_attr "memory" "none,load"))) 164117395Skan "(pentium-fp+pentium-np)") 165117395Skan 166117395Skan(define_insn_reservation "pent_fpmovxf" 3 167117395Skan (and (eq_attr "cpu" "pentium") 168117395Skan (and (eq_attr "type" "fmov") 169117395Skan (and (eq_attr "memory" "load,store") 170117395Skan (eq_attr "mode" "XF")))) 171117395Skan "(pentium-fp+pentium-np)*3") 172117395Skan 173117395Skan(define_insn_reservation "pent_fpstore" 2 174117395Skan (and (eq_attr "cpu" "pentium") 175117395Skan (and (eq_attr "type" "fmov") 176117395Skan (ior (match_operand 1 "immediate_operand" "") 177117395Skan (eq_attr "memory" "store")))) 178117395Skan "(pentium-fp+pentium-np)*2") 179117395Skan 180117395Skan(define_insn_reservation "pent_imov" 1 181117395Skan (and (eq_attr "cpu" "pentium") 182117395Skan (eq_attr "type" "imov")) 183117395Skan "pentium-firstuv") 184117395Skan 185117395Skan;; Push and pop instructions have 1 cycle latency and special 186117395Skan;; hardware bypass allows them to be paired with other push,pop 187117395Skan;; and call instructions. 188117395Skan(define_bypass 0 "pent_push,pent_pop" "pent_push,pent_pop,pent_call") 189117395Skan(define_insn_reservation "pent_push" 1 190117395Skan (and (eq_attr "cpu" "pentium") 191117395Skan (and (eq_attr "type" "push") 192117395Skan (eq_attr "memory" "store"))) 193117395Skan "pentium-firstuv") 194117395Skan 195117395Skan(define_insn_reservation "pent_pop" 1 196117395Skan (and (eq_attr "cpu" "pentium") 197132718Skan (eq_attr "type" "pop,leave")) 198117395Skan "pentium-firstuv") 199117395Skan 200117395Skan;; Call and branch instruction can execute in either pipe, but 201117395Skan;; they are only pairable when in the v pipe. 202117395Skan(define_insn_reservation "pent_call" 10 203117395Skan (and (eq_attr "cpu" "pentium") 204117395Skan (eq_attr "type" "call,callv")) 205117395Skan "pentium-firstv,pentium-v*9") 206117395Skan 207117395Skan(define_insn_reservation "pent_branch" 1 208117395Skan (and (eq_attr "cpu" "pentium") 209117395Skan (eq_attr "type" "ibr")) 210117395Skan "pentium-firstv") 211117395Skan 212117395Skan;; Floating point instruction dispatch in U pipe, but continue 213132718Skan;; in FP pipeline allowing other instructions to be executed. 214117395Skan(define_insn_reservation "pent_fp" 3 215117395Skan (and (eq_attr "cpu" "pentium") 216117395Skan (eq_attr "type" "fop,fistp")) 217117395Skan "(pentium-firstu+pentium-fp),nothing,nothing") 218117395Skan 219117395Skan;; First two cycles of fmul are not pipelined. 220117395Skan(define_insn_reservation "pent_fmul" 3 221117395Skan (and (eq_attr "cpu" "pentium") 222117395Skan (eq_attr "type" "fmul")) 223117395Skan "(pentium-firstuv+pentium-fp+pentium-fmul),pentium-fmul,nothing") 224117395Skan 225117395Skan;; Long latency FP instructions overlap with integer instructions, 226117395Skan;; but only last 2 cycles with FP ones. 227117395Skan(define_insn_reservation "pent_fdiv" 39 228117395Skan (and (eq_attr "cpu" "pentium") 229117395Skan (eq_attr "type" "fdiv")) 230117395Skan "(pentium-np+pentium-fp+pentium-fmul), 231117395Skan (pentium-fp+pentium-fmul)*36,pentium-fmul*2") 232117395Skan 233117395Skan(define_insn_reservation "pent_fpspc" 70 234117395Skan (and (eq_attr "cpu" "pentium") 235117395Skan (eq_attr "type" "fpspc")) 236117395Skan "(pentium-np+pentium-fp+pentium-fmul), 237117395Skan (pentium-fp+pentium-fmul)*67,pentium-fmul*2") 238117395Skan 239117395Skan;; Integer instructions. Load/execute/store takes 3 cycles, 240117395Skan;; load/execute 2 cycles and execute only one cycle. 241117395Skan(define_insn_reservation "pent_uv_both" 3 242117395Skan (and (eq_attr "cpu" "pentium") 243117395Skan (and (eq_attr "pent_pair" "uv") 244117395Skan (eq_attr "memory" "both"))) 245117395Skan "pentium-firstuvboth,pentium-uv+pentium-memory,pentium-uv") 246117395Skan 247117395Skan(define_insn_reservation "pent_u_both" 3 248117395Skan (and (eq_attr "cpu" "pentium") 249117395Skan (and (eq_attr "pent_pair" "pu") 250117395Skan (eq_attr "memory" "both"))) 251117395Skan "pentium-firstuboth,pentium-u+pentium-memory,pentium-u") 252117395Skan 253117395Skan(define_insn_reservation "pent_v_both" 3 254117395Skan (and (eq_attr "cpu" "pentium") 255117395Skan (and (eq_attr "pent_pair" "pv") 256117395Skan (eq_attr "memory" "both"))) 257117395Skan "pentium-firstvboth,pentium-v+pentium-memory,pentium-v") 258117395Skan 259117395Skan(define_insn_reservation "pent_np_both" 3 260117395Skan (and (eq_attr "cpu" "pentium") 261117395Skan (and (eq_attr "pent_pair" "np") 262117395Skan (eq_attr "memory" "both"))) 263117395Skan "pentium-np,pentium-np,pentium-np") 264117395Skan 265117395Skan(define_insn_reservation "pent_uv_load" 2 266117395Skan (and (eq_attr "cpu" "pentium") 267117395Skan (and (eq_attr "pent_pair" "uv") 268117395Skan (eq_attr "memory" "load"))) 269117395Skan "pentium-firstuvload,pentium-uv") 270117395Skan 271117395Skan(define_insn_reservation "pent_u_load" 2 272117395Skan (and (eq_attr "cpu" "pentium") 273117395Skan (and (eq_attr "pent_pair" "pu") 274117395Skan (eq_attr "memory" "load"))) 275117395Skan "pentium-firstuload,pentium-u") 276117395Skan 277117395Skan(define_insn_reservation "pent_v_load" 2 278117395Skan (and (eq_attr "cpu" "pentium") 279117395Skan (and (eq_attr "pent_pair" "pv") 280117395Skan (eq_attr "memory" "load"))) 281117395Skan "pentium-firstvload,pentium-v") 282117395Skan 283117395Skan(define_insn_reservation "pent_np_load" 2 284117395Skan (and (eq_attr "cpu" "pentium") 285117395Skan (and (eq_attr "pent_pair" "np") 286117395Skan (eq_attr "memory" "load"))) 287117395Skan "pentium-np,pentium-np") 288117395Skan 289117395Skan(define_insn_reservation "pent_uv" 1 290117395Skan (and (eq_attr "cpu" "pentium") 291117395Skan (and (eq_attr "pent_pair" "uv") 292117395Skan (eq_attr "memory" "none"))) 293117395Skan "pentium-firstuv") 294117395Skan 295117395Skan(define_insn_reservation "pent_u" 1 296117395Skan (and (eq_attr "cpu" "pentium") 297117395Skan (and (eq_attr "pent_pair" "pu") 298117395Skan (eq_attr "memory" "none"))) 299117395Skan "pentium-firstu") 300117395Skan 301117395Skan(define_insn_reservation "pent_v" 1 302117395Skan (and (eq_attr "cpu" "pentium") 303117395Skan (and (eq_attr "pent_pair" "pv") 304117395Skan (eq_attr "memory" "none"))) 305117395Skan "pentium-firstv") 306117395Skan 307117395Skan(define_insn_reservation "pent_np" 1 308117395Skan (and (eq_attr "cpu" "pentium") 309117395Skan (and (eq_attr "pent_pair" "np") 310117395Skan (eq_attr "memory" "none"))) 311117395Skan "pentium-np") 312117395Skan 313