diff --git a/gcc/ChangeLog b/gcc/ChangeLog index ecce3615016..d2560018b8e 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,16 @@ +2007-04-16 David Ung + Joseph Myers + + * config/mips/mips.h (PROCESSOR_74KC, PROCESSOR_74KF, + PROCESSOR_74KX, TUNE_74K, GENERATE_MADD_MSUB): Define. + * config/mips/mips.c (mips_cpu_info_table, mips_rtx_cost_data): + Add 74K processor information. + * config/mips/mips.md: Include 74k.md. + (cpu): Add 74kc,74kf,74kx. + (ISA_HAS_MADD_MSUB): Change to GENERATE_MADD_MSUB throughout. + * config/mips/74k.md: New. + * doc/invoke.texi (MIPS Options): Document 74K support. + 2007-04-16 Dorit Nuzman * tree-vect-analyze.c (vect_analyze_operations): Reorganize calls to diff --git a/gcc/config/mips/74k.md b/gcc/config/mips/74k.md new file mode 100644 index 00000000000..833b705bac0 --- /dev/null +++ b/gcc/config/mips/74k.md @@ -0,0 +1,323 @@ +;; 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") diff --git a/gcc/config/mips/mips.c b/gcc/config/mips/mips.c index 880934b949d..5b3b10de435 100644 --- a/gcc/config/mips/mips.c +++ b/gcc/config/mips/mips.c @@ -750,6 +750,9 @@ const struct mips_cpu_info mips_cpu_info_table[] = { { "34kc", PROCESSOR_24KC, 33 }, /* 34K with MT/DSP */ { "34kf", PROCESSOR_24KF, 33 }, { "34kx", PROCESSOR_24KX, 33 }, + { "74kc", PROCESSOR_74KC, 33 }, + { "74kf", PROCESSOR_74KF, 33 }, + { "74kx", PROCESSOR_74KX, 33 }, /* MIPS64 */ { "5kc", PROCESSOR_5KC, 64 }, @@ -894,6 +897,41 @@ static struct mips_rtx_cost_data const mips_rtx_cost_data[PROCESSOR_MAX] = 1, /* branch_cost */ 4 /* memory_latency */ }, + { /* 74KC */ + SOFT_FP_COSTS, + COSTS_N_INSNS (5), /* int_mult_si */ + COSTS_N_INSNS (5), /* int_mult_di */ + COSTS_N_INSNS (41), /* int_div_si */ + COSTS_N_INSNS (41), /* int_div_di */ + 1, /* branch_cost */ + 4 /* memory_latency */ + }, + { /* 74KF */ + COSTS_N_INSNS (8), /* fp_add */ + COSTS_N_INSNS (8), /* fp_mult_sf */ + COSTS_N_INSNS (10), /* fp_mult_df */ + COSTS_N_INSNS (34), /* fp_div_sf */ + COSTS_N_INSNS (64), /* fp_div_df */ + COSTS_N_INSNS (5), /* int_mult_si */ + COSTS_N_INSNS (5), /* int_mult_di */ + COSTS_N_INSNS (41), /* int_div_si */ + COSTS_N_INSNS (41), /* int_div_di */ + 1, /* branch_cost */ + 4 /* memory_latency */ + }, + { /* 74KX */ + COSTS_N_INSNS (4), /* fp_add */ + COSTS_N_INSNS (4), /* fp_mult_sf */ + COSTS_N_INSNS (5), /* fp_mult_df */ + COSTS_N_INSNS (17), /* fp_div_sf */ + COSTS_N_INSNS (32), /* fp_div_df */ + COSTS_N_INSNS (5), /* int_mult_si */ + COSTS_N_INSNS (5), /* int_mult_di */ + COSTS_N_INSNS (41), /* int_div_si */ + COSTS_N_INSNS (41), /* int_div_di */ + 1, /* branch_cost */ + 4 /* memory_latency */ + }, { /* M4k */ DEFAULT_COSTS }, @@ -9951,6 +9989,9 @@ mips_issue_rate (void) { switch (mips_tune) { + case PROCESSOR_74KC: + case PROCESSOR_74KF: + case PROCESSOR_74KX: case PROCESSOR_R4130: case PROCESSOR_R5400: case PROCESSOR_R5500: diff --git a/gcc/config/mips/mips.h b/gcc/config/mips/mips.h index 6cf42a7249f..f1773bcbaaa 100644 --- a/gcc/config/mips/mips.h +++ b/gcc/config/mips/mips.h @@ -43,6 +43,9 @@ enum processor_type { PROCESSOR_24KC, PROCESSOR_24KF, PROCESSOR_24KX, + PROCESSOR_74KC, + PROCESSOR_74KF, + PROCESSOR_74KX, PROCESSOR_M4K, PROCESSOR_R3900, PROCESSOR_R6000, @@ -243,6 +246,9 @@ extern const struct mips_rtx_cost_data *mips_cost; #define TUNE_MIPS9000 (mips_tune == PROCESSOR_R9000) #define TUNE_SB1 (mips_tune == PROCESSOR_SB1 \ || mips_tune == PROCESSOR_SB1A) +#define TUNE_74K (mips_tune == PROCESSOR_74KC \ + || mips_tune == PROCESSOR_74KF \ + || mips_tune == PROCESSOR_74KX) /* True if the pre-reload scheduler should try to create chains of multiply-add or multiply-subtract instructions. For example, @@ -639,6 +645,9 @@ extern const struct mips_rtx_cost_data *mips_cost; || ISA_MIPS64) \ && !TARGET_MIPS16) +/* Integer multiply-accumulate instructions should be generated. */ +#define GENERATE_MADD_MSUB (ISA_HAS_MADD_MSUB && !TUNE_74K) + /* ISA has floating-point nmadd and nmsub instructions. */ #define ISA_HAS_NMADD_NMSUB ((ISA_MIPS4 \ || ISA_MIPS64) \ diff --git a/gcc/config/mips/mips.md b/gcc/config/mips/mips.md index 2178481808d..12415e42f99 100644 --- a/gcc/config/mips/mips.md +++ b/gcc/config/mips/mips.md @@ -396,7 +396,7 @@ ;; Attribute describing the processor. This attribute must match exactly ;; with the processor_type enumeration in mips.h. (define_attr "cpu" - "r3000,4kc,4kp,5kc,5kf,20kc,24kc,24kf,24kx,m4k,r3900,r6000,r4000,r4100,r4111,r4120,r4130,r4300,r4600,r4650,r5000,r5400,r5500,r7000,r8000,r9000,sb1,sb1a,sr71000" + "r3000,4kc,4kp,5kc,5kf,20kc,24kc,24kf,24kx,74kc,74kf,74kx,m4k,r3900,r6000,r4000,r4100,r4111,r4120,r4130,r4300,r4600,r4650,r5000,r5400,r5500,r7000,r8000,r9000,sb1,sb1a,sr71000" (const (symbol_ref "mips_tune"))) ;; The type of hardware hazard associated with this instruction. @@ -633,6 +633,7 @@ (include "4k.md") (include "5k.md") (include "24k.md") +(include "74k.md") (include "3000.md") (include "4000.md") (include "4100.md") @@ -1208,13 +1209,13 @@ (clobber (match_scratch:SI 5 "=X,3,l")) (clobber (match_scratch:SI 6 "=X,X,&d"))] "(TARGET_MIPS3900 - || ISA_HAS_MADD_MSUB) + || GENERATE_MADD_MSUB) && !TARGET_MIPS16" { static const char *const madd[] = { "madd\t%1,%2", "madd\t%0,%1,%2" }; if (which_alternative == 2) return "#"; - if (ISA_HAS_MADD_MSUB && which_alternative != 0) + if (GENERATE_MADD_MSUB && which_alternative != 0) return "#"; return madd[which_alternative]; } @@ -1468,7 +1469,7 @@ (clobber (match_scratch:SI 4 "=h,h,h")) (clobber (match_scratch:SI 5 "=X,1,l")) (clobber (match_scratch:SI 6 "=X,X,&d"))] - "ISA_HAS_MADD_MSUB" + "GENERATE_MADD_MSUB" "@ msub\t%2,%3 # diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi index 9266b123ff1..842dcbfcbce 100644 --- a/gcc/doc/invoke.texi +++ b/gcc/doc/invoke.texi @@ -11191,6 +11191,7 @@ The processor names are: @samp{24kc}, @samp{24kf}, @samp{24kx}, @samp{24kec}, @samp{24kef}, @samp{24kex}, @samp{34kc}, @samp{34kf}, @samp{34kx}, +@samp{74kc}, @samp{74kf}, @samp{74kx}, @samp{m4k}, @samp{orion}, @samp{r2000}, @samp{r3000}, @samp{r3900}, @samp{r4000}, @samp{r4400},