24k.md revision 169689
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." 10;; 11;; Copyright (C) 2005 Free Software Foundation, Inc. 12;; 13;; This file is part of GCC. 14;; 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. 19 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. 24 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. 29 30(define_automaton "r24k_cpu, r24k_mdu, r24k_fpu") 31 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") 38 39;; -------------------------------------------------------------- 40;; Producers 41;; -------------------------------------------------------------- 42 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") 48 49 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") 60 61 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") 68 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") 74 75 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)") 82 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)") 88 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") 94 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)") 100 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)") 106 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") 113 114 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") 121 122 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") 129 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") 139 140 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)") 146 147 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") 155 156 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") 162 163 164;; -------------------------------------------------------------- 165;; Bypass to Consumer 166;; -------------------------------------------------------------- 167 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") 175 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") 183 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") 190 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") 199 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") 204 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") 211 212 213;; -------------------------------------------------------------- 214;; Floating Point Instructions 215;; -------------------------------------------------------------- 216 217(define_cpu_unit "r24k_fpu_arith" "r24k_fpu") 218 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. 222;; 223;; These timings are therefore twice the values in the 24K manual, 224;; which are quoted in fpu clocks. 225;; 226;; The 24kx is a 24k configured with 1:1 cpu and fpu, so use 227;; the unscaled timings 228 229(define_reservation "r24k_fpu_iss" "r24k_iss+(r24k_fpu_arith*2)") 230 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") 236 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") 242 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") 248 249;; fstore 250(define_insn_reservation "r24k_fstore" 2 251 (and (eq_attr "cpu" "24k") 252 (eq_attr "type" "fpstore")) 253 "r24k_fpu_iss") 254 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") 261 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)") 267 268 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)") 275 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)") 281 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)") 288 289;; fcmp 290(define_insn_reservation "r24k_fcmp" 4 291 (and (eq_attr "cpu" "24k") 292 (eq_attr "type" "fcmp")) 293 "r24k_fpu_iss") 294 295;; fcmp -> movf.fmt & movt.fmt bypass (dependency must be on the condition) 296(define_bypass 2 "r24k_fcmp" "r24k_fmove") 297 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") 304 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") 311 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") 318 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") 324 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") 333 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") 339 340;; -------------------------------------------------------------- 341;; The 24kx is a 24k configured with 1:1 cpu and fpu, so use 342;; the unscaled timings 343;; -------------------------------------------------------------- 344 345(define_reservation "r24kx_fpu_iss" "r24k_iss+r24k_fpu_arith") 346 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") 352 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") 358 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") 364 365;; fstore 366(define_insn_reservation "r24kx_fstore" 1 367 (and (eq_attr "cpu" "24kx") 368 (eq_attr "type" "fpstore")) 369 "r24kx_fpu_iss") 370 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") 377 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") 383 384 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)") 391 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)") 397 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)") 404 405;; fcmp 406(define_insn_reservation "r24kx_fcmp" 2 407 (and (eq_attr "cpu" "24kx") 408 (eq_attr "type" "fcmp")) 409 "r24kx_fpu_iss") 410 411;; fcmp -> movf.fmt & movt.fmt bypass (dependency must be on the condition) 412(define_bypass 1 "r24kx_fcmp" "r24kx_fmove") 413 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") 420 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") 427 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") 434 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") 440 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") 449 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") 455 456