;; DFA-based pipeline description for MIPS32 model 74k. ;; Contributed by MIPS Technologies and CodeSourcery. ;; ;; Reference: ;; "MIPS32 74K Microarchitecure Specification Rev. 01.02 Jun 15, 2006" ;; "MIPS32 74Kf Processor Core Datasheet Jun 2, 2006" ;; ;; Copyright (C) 2007 Free Software Foundation, Inc. ;; ;; This file is part of GCC. ;; ;; GCC is free software; you can redistribute it and/or modify it ;; under the terms of the GNU General Public License as published ;; by the Free Software Foundation; either version 2, or (at your ;; option) any later version. ;; GCC is distributed in the hope that it will be useful, but WITHOUT ;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY ;; or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public ;; License for more details. ;; You should have received a copy of the GNU General Public License ;; along with GCC; see the file COPYING. If not, write to the ;; Free Software Foundation, 51 Franklin Street, Fifth Floor, Boston, ;; MA 02110-1301, USA. (define_automaton "r74k_mdu_pipe, r74k_alu_pipe, r74k_agen_pipe, r74k_fpu") (define_cpu_unit "r74k_mul" "r74k_mdu_pipe") (define_cpu_unit "r74k_alu" "r74k_alu_pipe") (define_cpu_unit "r74k_agen" "r74k_agen_pipe") (define_cpu_unit "r74k_fpu_arith" "r74k_fpu") (define_cpu_unit "r74k_fpu_ldst" "r74k_fpu") ;; -------------------------------------------------------------- ;; Producers ;; -------------------------------------------------------------- ;; Arithmetic: add, addi, addiu, addiupc, addu, and, andi, clo, clz, ;; ext, ins, lui, movn, movz, nor, or, ori, rotr, rotrv, seb, seh, sll, ;; sllv, slt, slti, sltiu, sltu, sra, srav, srl, srlv, sub, subu, wsbh, ;; xor, xori (define_insn_reservation "r74k_int_arith" 2 (and (eq_attr "cpu" "74kc,74kf,74kx") (eq_attr "type" "arith,const,shift,slt,clz")) "r74k_alu") (define_insn_reservation "r74k_int_nop" 0 (and (eq_attr "cpu" "74kc,74kf,74kx") (eq_attr "type" "nop")) "nothing") (define_insn_reservation "r74k_int_cmove" 4 (and (eq_attr "cpu" "74kc,74kf,74kx") (eq_attr "type" "condmove")) "r74k_agen*2") ;; MDU: fully pipelined multiplier ;; mult, madd, msub - delivers result to hi/lo in 4 cycle (pipelined) (define_insn_reservation "r74k_int_mult" 4 (and (eq_attr "cpu" "74kc,74kf,74kx") (eq_attr "type" "imul,imadd")) "r74k_alu+r74k_mul") ;; mul - delivers result to general register in 7 cycles (define_insn_reservation "r74k_int_mul3" 7 (and (eq_attr "cpu" "74kc,74kf,74kx") (eq_attr "type" "imul3")) "r74k_alu+r74k_mul") ;; mfhi, mflo, mflhxu - deliver result to gpr in 7 cycles (define_insn_reservation "r74k_int_mfhilo" 7 (and (eq_attr "cpu" "74kc,74kf,74kx") (eq_attr "type" "mfhilo")) "r74k_alu+r74k_mul") ;; mthi, mtlo, mtlhx - deliver result to hi/lo, thence madd, handled as bypass (define_insn_reservation "r74k_int_mthilo" 7 (and (eq_attr "cpu" "74kc,74kf,74kx") (eq_attr "type" "mthilo")) "r74k_alu+r74k_mul") ;; div - default to 50 cycles for 32bit operands. Faster for 8 bit, ;; but is tricky to identify. (define_insn_reservation "r74k_int_div" 50 (and (eq_attr "cpu" "74kc,74kf,74kx") (eq_attr "type" "idiv")) "r74k_alu+r74k_mul*50") ;; call (define_insn_reservation "r74k_int_call" 1 (and (eq_attr "cpu" "74kc,74kf,74kx") (eq_attr "type" "call")) "r74k_agen") ;; branch/jump (define_insn_reservation "r74k_int_jump" 1 (and (eq_attr "cpu" "74kc,74kf,74kx") (eq_attr "type" "branch,jump")) "r74k_agen") ;; loads: lb, lbu, lh, lhu, ll, lw, lwl, lwr, lwpc, lwxs ;; prefetch: prefetch, prefetchx (define_insn_reservation "r74k_int_load" 3 (and (eq_attr "cpu" "74kc,74kf,74kx") (eq_attr "type" "load,prefetch,prefetchx")) "r74k_agen") ;; stores (define_insn_reservation "r74k_int_store" 1 (and (eq_attr "cpu" "74kc,74kf,74kx") (and (eq_attr "type" "store") (eq_attr "mode" "!unknown"))) "r74k_agen") ;; Unknowns - Currently these include blockage, consttable and alignment ;; rtls. They do not really affect scheduling latency, (blockage ;; affects scheduling via log links, but not used here). ;; (define_insn_reservation "r74k_unknown" 1 (and (eq_attr "cpu" "74kc,74kf,74kx") (eq_attr "type" "unknown")) "r74k_alu") (define_insn_reservation "r74k_multi" 10 (and (eq_attr "cpu" "74kc,74kf,74kx") (eq_attr "type" "multi")) "(r74k_alu+r74k_agen)*10") ;; -------------------------------------------------------------- ;; Bypass to Consumer ;; -------------------------------------------------------------- ;; load->next use : 3 cycles (Default) ;; load->load base: 4 cycles ;; load->store base: 4 cycles (define_bypass 4 "r74k_int_load" "r74k_int_load") (define_bypass 4 "r74k_int_load" "r74k_int_store" "!store_data_bypass_p") ;; arith->next use : 2 cycles (Default) ;; arith->load base: 3 cycles ;; arith->store base: 3 cycles (define_bypass 3 "r74k_int_arith" "r74k_int_load") (define_bypass 3 "r74k_int_arith" "r74k_int_store" "!store_data_bypass_p") ;; cmove->next use : 4 cycles (Default) ;; cmove->load base: 5 cycles ;; cmove->store base: 5 cycles (define_bypass 5 "r74k_int_cmove" "r74k_int_load") (define_bypass 5 "r74k_int_cmove" "r74k_int_store" "!store_data_bypass_p") ;; mult/madd->int_mfhilo : 4 cycles (default) ;; mult/madd->mult/madd : 1 cycles (define_bypass 1 "r74k_int_mult" "r74k_int_mult") ;; -------------------------------------------------------------- ;; Floating Point Instructions ;; -------------------------------------------------------------- ;; 74Kf has FPU at 1/2 speed of CPU; 74Kx is the name used by GCC for ;; a version with 1:1 speed FPU. ;; fadd, fabs, fneg, (define_insn_reservation "r74kx_fadd" 4 (and (eq_attr "cpu" "74kx") (eq_attr "type" "fadd,fabs,fneg")) "r74k_fpu_arith") (define_insn_reservation "r74kf_fadd" 8 (and (eq_attr "cpu" "74kf") (eq_attr "type" "fadd,fabs,fneg")) "r74k_fpu_arith*2") ;; fmove, fcmove (define_insn_reservation "r74kx_fmove" 4 (and (eq_attr "cpu" "74kx") (eq_attr "type" "fmove")) "r74k_fpu_arith") (define_insn_reservation "r74kf_fmove" 8 (and (eq_attr "cpu" "74kf") (eq_attr "type" "fmove")) "r74k_fpu_arith*2") ;; fload (define_insn_reservation "r74kx_fload" 4 (and (eq_attr "cpu" "74kx") (eq_attr "type" "fpload,fpidxload")) "r74k_agen+r74k_fpu_ldst") (define_insn_reservation "r74kf_fload" 8 (and (eq_attr "cpu" "74kf") (eq_attr "type" "fpload,fpidxload")) "r74k_agen+(r74k_fpu_ldst*2)") ;; fstore (define_insn_reservation "r74kx_fstore" 1 (and (eq_attr "cpu" "74kx") (eq_attr "type" "fpstore,fpidxstore")) "r74k_agen+r74k_fpu_ldst") (define_insn_reservation "r74kf_fstore" 2 (and (eq_attr "cpu" "74kf") (eq_attr "type" "fpstore,fpidxstore")) "r74k_agen+(r74k_fpu_ldst*2)") ;; fmul, fmadd (define_insn_reservation "r74kx_fmul_sf" 4 (and (eq_attr "cpu" "74kx") (and (eq_attr "type" "fmul,fmadd") (eq_attr "mode" "SF"))) "r74k_fpu_arith") (define_insn_reservation "r74kf_fmul_sf" 8 (and (eq_attr "cpu" "74kf") (and (eq_attr "type" "fmul,fmadd") (eq_attr "mode" "SF"))) "r74k_fpu_arith*2") (define_insn_reservation "r74kx_fmul_df" 5 (and (eq_attr "cpu" "74kx") (and (eq_attr "type" "fmul,fmadd") (eq_attr "mode" "DF"))) "r74k_fpu_arith*2") (define_insn_reservation "r74kf_fmul_df" 10 (and (eq_attr "cpu" "74kf") (and (eq_attr "type" "fmul,fmadd") (eq_attr "mode" "DF"))) "r74k_fpu_arith*4") ;; fdiv, fsqrt (define_insn_reservation "r74kx_fdiv_sf" 17 (and (eq_attr "cpu" "74kx") (and (eq_attr "type" "fdiv,fsqrt") (eq_attr "mode" "SF"))) "r74k_fpu_arith*14") (define_insn_reservation "r74kf_fdiv_sf" 34 (and (eq_attr "cpu" "74kf") (and (eq_attr "type" "fdiv,fsqrt") (eq_attr "mode" "SF"))) "r74k_fpu_arith*28") (define_insn_reservation "r74kx_fdiv_df" 32 (and (eq_attr "cpu" "74kx") (and (eq_attr "type" "fdiv,fsqrt") (eq_attr "mode" "DF"))) "r74k_fpu_arith*29") (define_insn_reservation "r74kf_fdiv_df" 64 (and (eq_attr "cpu" "74kf") (and (eq_attr "type" "fdiv,fsqrt") (eq_attr "mode" "DF"))) "r74k_fpu_arith*58") ;; frsqrt (define_insn_reservation "r74kx_frsqrt_sf" 17 (and (eq_attr "cpu" "74kx") (and (eq_attr "type" "frsqrt") (eq_attr "mode" "SF"))) "r74k_fpu_arith*14") (define_insn_reservation "r74kf_frsqrt_sf" 34 (and (eq_attr "cpu" "74kf") (and (eq_attr "type" "frsqrt") (eq_attr "mode" "SF"))) "r74k_fpu_arith*28") (define_insn_reservation "r74kx_frsqrt_df" 36 (and (eq_attr "cpu" "74kx") (and (eq_attr "type" "frsqrt") (eq_attr "mode" "DF"))) "r74k_fpu_arith*31") (define_insn_reservation "r74kf_frsqrt_df" 72 (and (eq_attr "cpu" "74kf") (and (eq_attr "type" "frsqrt") (eq_attr "mode" "DF"))) "r74k_fpu_arith*62") ;; fcmp (define_insn_reservation "r74kx_fcmp" 4 (and (eq_attr "cpu" "74kx") (eq_attr "type" "fcmp")) "r74k_fpu_arith") (define_insn_reservation "r74kf_fcmp" 8 (and (eq_attr "cpu" "74kf") (eq_attr "type" "fcmp")) "r74k_fpu_arith*2") ;; fcvt (define_insn_reservation "r74kx_fcvt" 4 (and (eq_attr "cpu" "74kx") (eq_attr "type" "fcvt")) "r74k_fpu_arith") (define_insn_reservation "r74kf_fcvt" 8 (and (eq_attr "cpu" "74kf") (eq_attr "type" "fcvt")) "r74k_fpu_arith*2") ;; fxfer (MTC1, DMTC1: latency is 4) (MFC1, DMFC1: latency is 1) (define_insn_reservation "r74kx_fxfer_to_c1" 4 (and (eq_attr "cpu" "74kx") (eq_attr "type" "mtc")) "r74k_fpu_arith") (define_insn_reservation "r74kf_fxfer_to_c1" 8 (and (eq_attr "cpu" "74kf") (eq_attr "type" "mtc")) "r74k_fpu_arith*2") (define_insn_reservation "r74kx_fxfer_from_c1" 1 (and (eq_attr "cpu" "74kx") (eq_attr "type" "mfc")) "r74k_fpu_arith") (define_insn_reservation "r74kf_fxfer_from_c1" 2 (and (eq_attr "cpu" "74kf") (eq_attr "type" "mfc")) "r74k_fpu_arith*2")