diff options
-rw-r--r-- | gcc/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/config/sparc/cypress.md | 51 | ||||
-rw-r--r-- | gcc/config/sparc/hypersparc.md | 83 | ||||
-rw-r--r-- | gcc/config/sparc/sparc.md | 526 | ||||
-rw-r--r-- | gcc/config/sparc/sparclet.md | 44 | ||||
-rw-r--r-- | gcc/config/sparc/supersparc.md | 93 | ||||
-rw-r--r-- | gcc/config/sparc/ultra1_2.md | 242 | ||||
-rw-r--r-- | gcc/config/sparc/ultra3.md | 158 |
8 files changed, 684 insertions, 518 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 121f1fa89d8..df9380a1f49 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,5 +1,10 @@ 2002-05-03 David S. Miller <davem@redhat.com> + * config/sparc/sparc.md (DFA schedulers): Split out... + * config/sparc/cypress.md, config/sparc/hypersparc.md, + config/sparc/sparclet.md, config/sparc/supersparc.md, + config/sparc/ultra1_2.md, config/sparc/ultra3.md: ... into here. + * config/sparc/sparc.c (LEAF_REGISTERS): Do not do ifdef checks on it, always defined for Sparc. diff --git a/gcc/config/sparc/cypress.md b/gcc/config/sparc/cypress.md new file mode 100644 index 00000000000..f871b1e0030 --- /dev/null +++ b/gcc/config/sparc/cypress.md @@ -0,0 +1,51 @@ +;; Scheduling description for Sparc Cypress. +;; Copyright (C) 2002 Free Software Foundation, Inc. +;; +;; This file is part of GNU CC. +;; +;; GNU CC 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. +;; +;; GNU CC 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 GNU CC; see the file COPYING. If not, write to +;; the Free Software Foundation, 59 Temple Place - Suite 330, +;; Boston, MA 02111-1307, USA. + +;; The Cypress is a pretty simple single-issue processor. + +(define_automaton "cypress_0,cypress_1") + +(define_cpu_unit "cyp_memory, cyp_fpalu" "cypress_0") +(define_cpu_unit "cyp_fpmds" "cypress_1") + +(define_insn_reservation "cyp_load" 2 + (and (eq_attr "cpu" "cypress") + (eq_attr "type" "load,sload,fpload")) + "cyp_memory, nothing") + +(define_insn_reservation "cyp_fp_alu" 5 + (and (eq_attr "cpu" "cypress") + (eq_attr "type" "fp,fpmove")) + "cyp_fpalu, nothing*3") + +(define_insn_reservation "cyp_fp_mult" 7 + (and (eq_attr "cpu" "cypress") + (eq_attr "type" "fpmul")) + "cyp_fpmds, nothing*5") + +(define_insn_reservation "cyp_fp_div" 37 + (and (eq_attr "cpu" "cypress") + (eq_attr "type" "fpdivs,fpdivd")) + "cyp_fpmds, nothing*35") + +(define_insn_reservation "cyp_fp_sqrt" 63 + (and (eq_attr "cpu" "cypress") + (eq_attr "type" "fpsqrts,fpsqrtd")) + "cyp_fpmds, nothing*61") diff --git a/gcc/config/sparc/hypersparc.md b/gcc/config/sparc/hypersparc.md new file mode 100644 index 00000000000..741f163234e --- /dev/null +++ b/gcc/config/sparc/hypersparc.md @@ -0,0 +1,83 @@ +;; Scheduling description for HyperSparc. +;; Copyright (C) 2002 Free Software Foundation, Inc. +;; +;; This file is part of GNU CC. +;; +;; GNU CC 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. +;; +;; GNU CC 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 GNU CC; see the file COPYING. If not, write to +;; the Free Software Foundation, 59 Temple Place - Suite 330, +;; Boston, MA 02111-1307, USA. + +;; The HyperSparc is a dual-issue processor. It is not all that fancy. + +;; ??? There are some things not modelled. For example, sethi+or +;; ??? coming right after each other are specifically identified and +;; ??? dual-issued by the processor. Similarly for sethi+ld[reg+lo]. +;; ??? Actually, to be more precise that rule is sort of modelled now. + +(define_automaton "hypersparc_0,hypersparc_1") + +;; HyperSPARC/sparclite86x scheduling + +(define_cpu_unit "hs_memory,hs_branch,hs_shift,hs_fpalu" "hypersparc_0") +(define_cpu_unit "hs_fpmds" "hypersparc_1") + +(define_insn_reservation "hs_load" 1 + (and (ior (eq_attr "cpu" "hypersparc") (eq_attr "cpu" "sparclite86x")) + (eq_attr "type" "load,sload,fpload")) + "hs_memory") + +(define_insn_reservation "hs_store" 2 + (and (ior (eq_attr "cpu" "hypersparc") (eq_attr "cpu" "sparclite86x")) + (eq_attr "type" "store,fpstore")) + "hs_memory, nothing") + +(define_insn_reservation "hs_slbranch" 1 + (and (eq_attr "cpu" "sparclite86x") + (eq_attr "type" "branch")) + "hs_branch") + +(define_insn_reservation "hs_slshift" 1 + (and (eq_attr "cpu" "sparclite86x") + (eq_attr "type" "shift")) + "hs_shift") + +(define_insn_reservation "hs_fp_alu" 1 + (and (ior (eq_attr "cpu" "hypersparc") (eq_attr "cpu" "sparclite86x")) + (eq_attr "type" "fp,fpmove,fpcmp")) + "hs_fpalu") + +(define_insn_reservation "hs_fp_mult" 1 + (and (ior (eq_attr "cpu" "hypersparc") (eq_attr "cpu" "sparclite86x")) + (eq_attr "type" "fpmul")) + "hs_fpmds") + +(define_insn_reservation "hs_fp_divs" 8 + (and (ior (eq_attr "cpu" "hypersparc") (eq_attr "cpu" "sparclite86x")) + (eq_attr "type" "fpdivs")) + "hs_fpmds*6, nothing*2") + +(define_insn_reservation "hs_fp_divd" 12 + (and (ior (eq_attr "cpu" "hypersparc") (eq_attr "cpu" "sparclite86x")) + (eq_attr "type" "fpdivd")) + "hs_fpmds*10, nothing*2") + +(define_insn_reservation "hs_fp_sqrt" 17 + (and (ior (eq_attr "cpu" "hypersparc") (eq_attr "cpu" "sparclite86x")) + (eq_attr "type" "fpsqrts,fpsqrtd")) + "hs_fpmds*15, nothing*2") + +(define_insn_reservation "hs_imul" 17 + (and (ior (eq_attr "cpu" "hypersparc") (eq_attr "cpu" "sparclite86x")) + (eq_attr "type" "imul")) + "hs_fpmds*15, nothing*2") diff --git a/gcc/config/sparc/sparc.md b/gcc/config/sparc/sparc.md index ed9da8bbefb..8f19dc7fd1d 100644 --- a/gcc/config/sparc/sparc.md +++ b/gcc/config/sparc/sparc.md @@ -247,524 +247,14 @@ [(eq_attr "in_uncond_branch_delay" "true") (nil) (nil)]) -;; DFA scheduling on the SPARC - -(define_automaton "cypress_0,cypress_1,supersparc_0,supersparc_1,hypersparc_0,hypersparc_1,sparclet,ultrasparc_0,ultrasparc_1,ultrasparc3_0,ultrasparc3_1") - -;; Cypress scheduling - -(define_cpu_unit "cyp_memory, cyp_fpalu" "cypress_0") -(define_cpu_unit "cyp_fpmds" "cypress_1") - -(define_insn_reservation "cyp_load" 2 - (and (eq_attr "cpu" "cypress") - (eq_attr "type" "load,sload,fpload")) - "cyp_memory, nothing") - -(define_insn_reservation "cyp_fp_alu" 5 - (and (eq_attr "cpu" "cypress") - (eq_attr "type" "fp,fpmove")) - "cyp_fpalu, nothing*3") - -(define_insn_reservation "cyp_fp_mult" 7 - (and (eq_attr "cpu" "cypress") - (eq_attr "type" "fpmul")) - "cyp_fpmds, nothing*5") - -(define_insn_reservation "cyp_fp_div" 37 - (and (eq_attr "cpu" "cypress") - (eq_attr "type" "fpdivs,fpdivd")) - "cyp_fpmds, nothing*35") - -(define_insn_reservation "cyp_fp_sqrt" 63 - (and (eq_attr "cpu" "cypress") - (eq_attr "type" "fpsqrts,fpsqrtd")) - "cyp_fpmds, nothing*61") - -;; SuperSPARC scheduling - -(define_cpu_unit "ss_memory, ss_shift, ss_iwport0, ss_iwport1" "supersparc_0") -(define_cpu_unit "ss_fpalu" "supersparc_0") -(define_cpu_unit "ss_fpmds" "supersparc_1") - -(define_reservation "ss_iwport" "(ss_iwport0 | ss_iwport1)") - -(define_insn_reservation "ss_iuload" 1 - (and (eq_attr "cpu" "supersparc") - (eq_attr "type" "load,sload")) - "ss_memory") - -;; Ok, fpu loads deliver the result in zero cycles. But we -;; have to show the ss_memory reservation somehow, thus... -(define_insn_reservation "ss_fpload" 0 - (and (eq_attr "cpu" "supersparc") - (eq_attr "type" "fpload")) - "ss_memory") - -(define_bypass 0 "ss_fpload" "ss_fp_alu,ss_fp_mult,ss_fp_divs,ss_fp_divd,ss_fp_sqrt") - -(define_insn_reservation "ss_store" 1 - (and (eq_attr "cpu" "supersparc") - (eq_attr "type" "store,fpstore")) - "ss_memory") - -(define_insn_reservation "ss_ialu_shift" 1 - (and (eq_attr "cpu" "supersparc") - (eq_attr "type" "shift")) - "ss_shift + ss_iwport") - -(define_insn_reservation "ss_ialu_any" 1 - (and (eq_attr "cpu" "supersparc") - (eq_attr "type" "load,sload,store,shift,ialu")) - "ss_iwport") - -(define_insn_reservation "ss_fp_alu" 3 - (and (eq_attr "cpu" "supersparc") - (eq_attr "type" "fp,fpmove,fpcmp")) - "ss_fpalu, nothing*2") - -(define_insn_reservation "ss_fp_mult" 3 - (and (eq_attr "cpu" "supersparc") - (eq_attr "type" "fpmul")) - "ss_fpmds, nothing*2") - -(define_insn_reservation "ss_fp_divs" 6 - (and (eq_attr "cpu" "supersparc") - (eq_attr "type" "fpdivs")) - "ss_fpmds*4, nothing*2") - -(define_insn_reservation "ss_fp_divd" 9 - (and (eq_attr "cpu" "supersparc") - (eq_attr "type" "fpdivd")) - "ss_fpmds*7, nothing*2") - -(define_insn_reservation "ss_fp_sqrt" 12 - (and (eq_attr "cpu" "supersparc") - (eq_attr "type" "fpsqrts,fpsqrtd")) - "ss_fpmds*10, nothing*2") - -(define_insn_reservation "ss_imul" 4 - (and (eq_attr "cpu" "supersparc") - (eq_attr "type" "imul")) - "ss_fpmds*4") - -;; HyperSPARC/sparclite86x scheduling - -(define_cpu_unit "hs_memory,hs_branch,hs_shift,hs_fpalu" "hypersparc_0") -(define_cpu_unit "hs_fpmds" "hypersparc_1") - -(define_insn_reservation "hs_load" 1 - (and (ior (eq_attr "cpu" "hypersparc") (eq_attr "cpu" "sparclite86x")) - (eq_attr "type" "load,sload,fpload")) - "hs_memory") - -(define_insn_reservation "hs_store" 2 - (and (ior (eq_attr "cpu" "hypersparc") (eq_attr "cpu" "sparclite86x")) - (eq_attr "type" "store,fpstore")) - "hs_memory, nothing") - -(define_insn_reservation "hs_slbranch" 1 - (and (eq_attr "cpu" "sparclite86x") - (eq_attr "type" "branch")) - "hs_branch") - -(define_insn_reservation "hs_slshift" 1 - (and (eq_attr "cpu" "sparclite86x") - (eq_attr "type" "shift")) - "hs_shift") - -(define_insn_reservation "hs_fp_alu" 1 - (and (ior (eq_attr "cpu" "hypersparc") (eq_attr "cpu" "sparclite86x")) - (eq_attr "type" "fp,fpmove,fpcmp")) - "hs_fpalu") - -(define_insn_reservation "hs_fp_mult" 1 - (and (ior (eq_attr "cpu" "hypersparc") (eq_attr "cpu" "sparclite86x")) - (eq_attr "type" "fpmul")) - "hs_fpmds") - -(define_insn_reservation "hs_fp_divs" 8 - (and (ior (eq_attr "cpu" "hypersparc") (eq_attr "cpu" "sparclite86x")) - (eq_attr "type" "fpdivs")) - "hs_fpmds*6, nothing*2") - -(define_insn_reservation "hs_fp_divd" 12 - (and (ior (eq_attr "cpu" "hypersparc") (eq_attr "cpu" "sparclite86x")) - (eq_attr "type" "fpdivd")) - "hs_fpmds*10, nothing*2") - -(define_insn_reservation "hs_fp_sqrt" 17 - (and (ior (eq_attr "cpu" "hypersparc") (eq_attr "cpu" "sparclite86x")) - (eq_attr "type" "fpsqrts,fpsqrtd")) - "hs_fpmds*15, nothing*2") - -(define_insn_reservation "hs_imul" 17 - (and (ior (eq_attr "cpu" "hypersparc") (eq_attr "cpu" "sparclite86x")) - (eq_attr "type" "imul")) - "hs_fpmds*15, nothing*2") - -;; Sparclet tsc701 scheduling - -(define_cpu_unit "sl_load0,sl_load1,sl_load2,sl_load3" "sparclet") -(define_cpu_unit "sl_store,sl_imul" "sparclet") - -(define_reservation "sl_load_any" "(sl_load0 | sl_load1 | sl_load2 | sl_load3)") -(define_reservation "sl_load_all" "(sl_load0 + sl_load1 + sl_load2 + sl_load3)") - -(define_insn_reservation "sl_ld" 3 - (and (eq_attr "cpu" "tsc701") - (eq_attr "type" "load,sload")) - "sl_load_any, sl_load_any, sl_load_any") - -(define_insn_reservation "sl_st" 3 - (and (eq_attr "cpu" "tsc701") - (eq_attr "type" "store")) - "(sl_store+sl_load_all)*3") - -(define_insn_reservation "sl_imul" 5 - (and (eq_attr "cpu" "tsc701") - (eq_attr "type" "imul")) - "sl_imul*5") - -;; UltraSPARC-I/II scheduling - -(define_cpu_unit "us1_fdivider,us1_fpm" "ultrasparc_0"); -(define_cpu_unit "us1_fpa,us1_load_writeback" "ultrasparc_1") -(define_cpu_unit "us1_fps_0,us1_fps_1,us1_fpd_0,us1_fpd_1" "ultrasparc_1") -(define_cpu_unit "us1_slot0,us1_slot1,us1_slot2,us1_slot3" "ultrasparc_1") -(define_cpu_unit "us1_ieu0,us1_ieu1,us1_cti,us1_lsu" "ultrasparc_1") - -(define_reservation "us1_slot012" "(us1_slot0 | us1_slot1 | us1_slot2)") -(define_reservation "us1_slotany" "(us1_slot0 | us1_slot1 | us1_slot2 | us1_slot3)") -(define_reservation "us1_single_issue" "us1_slot0 + us1_slot1 + us1_slot2 + us1_slot3") - -(define_reservation "us1_fp_single" "(us1_fps_0 | us1_fps_1)") -(define_reservation "us1_fp_double" "(us1_fpd_0 | us1_fpd_1)") -;; This is a simplified representation of the issue at hand. -;; For most cases, going from one FP precision type insn to another -;; just breaks up the insn group. However for some cases, such -;; a situation causes the second insn to stall 2 more cycles. -(exclusion_set "us1_fps_0,us1_fps_1" "us1_fpd_0,us1_fpd_1") - -;; If we have to schedule an ieu1 specific instruction and we want -;; to reserve the ieu0 unit as well, we must reserve it first. So for -;; example we could not schedule this sequence: -;; COMPARE IEU1 -;; IALU IEU0 -;; but we could schedule them together like this: -;; IALU IEU0 -;; COMPARE IEU1 -;; This basically requires that ieu0 is reserved before ieu1 when -;; it is required that both be reserved. -(absence_set "us1_ieu0" "us1_ieu1") - -;; This defines the slotting order. Most IEU instructions can only -;; execute in the first three slots, FPU and branches can go into -;; any slot. We represent instructions which "break the group" -;; as requiring reservation of us1_slot0. -(absence_set "us1_slot0" "us1_slot1,us1_slot2,us1_slot3") -(absence_set "us1_slot1" "us1_slot2,us1_slot3") -(absence_set "us1_slot2" "us1_slot3") - -(define_insn_reservation "us1_simple_ieuN" 1 - (and (eq_attr "cpu" "ultrasparc") - (eq_attr "type" "ialu")) - "(us1_ieu0 | us1_ieu1) + us1_slot012") - -(define_insn_reservation "us1_simple_ieu0" 1 - (and (eq_attr "cpu" "ultrasparc") - (eq_attr "type" "shift")) - "us1_ieu0 + us1_slot012") - -(define_insn_reservation "us1_simple_ieu1" 1 - (and (eq_attr "cpu" "ultrasparc") - (eq_attr "type" "compare")) - "us1_ieu1 + us1_slot012") - -(define_insn_reservation "us1_cmove" 2 - (and (eq_attr "cpu" "ultrasparc") - (eq_attr "type" "cmove")) - "us1_single_issue, nothing") - -(define_insn_reservation "us1_imul" 1 - (and (eq_attr "cpu" "ultrasparc") - (eq_attr "type" "imul")) - "us1_single_issue") - -(define_insn_reservation "us1_idiv" 1 - (and (eq_attr "cpu" "ultrasparc") - (eq_attr "type" "idiv")) - "us1_single_issue") - -;; For loads, the "delayed return mode" behavior of the chip -;; is represented using the us1_load_writeback resource. -(define_insn_reservation "us1_load" 2 - (and (eq_attr "cpu" "ultrasparc") - (eq_attr "type" "load,fpload")) - "us1_lsu + us1_slot012, us1_load_writeback") - -(define_insn_reservation "us1_load_signed" 3 - (and (eq_attr "cpu" "ultrasparc") - (eq_attr "type" "sload")) - "us1_lsu + us1_slot012, nothing, us1_load_writeback") - -(define_insn_reservation "us1_store" 1 - (and (eq_attr "cpu" "ultrasparc") - (eq_attr "type" "store,fpstore")) - "us1_lsu + us1_slot012") - -(define_insn_reservation "us1_branch" 1 - (and (eq_attr "cpu" "ultrasparc") - (eq_attr "type" "branch")) - "us1_cti + us1_slotany") - -(define_insn_reservation "us1_call_jmpl" 1 - (and (eq_attr "cpu" "ultrasparc") - (eq_attr "type" "call,sibcall,call_no_delay_slot,uncond_branch")) - "us1_cti + us1_ieu1 + us1_slot0") - -(define_insn_reservation "us1_fmov_single" 1 - (and (and (eq_attr "cpu" "ultrasparc") - (eq_attr "type" "fpmove")) - (eq_attr "fptype" "single")) - "us1_fpa + us1_fp_single + us1_slotany") - -(define_insn_reservation "us1_fmov_double" 1 - (and (and (eq_attr "cpu" "ultrasparc") - (eq_attr "type" "fpmove")) - (eq_attr "fptype" "double")) - "us1_fpa + us1_fp_double + us1_slotany") - -(define_insn_reservation "us1_fcmov_single" 2 - (and (and (eq_attr "cpu" "ultrasparc") - (eq_attr "type" "fpcmove,fpcrmove")) - (eq_attr "fptype" "single")) - "us1_fpa + us1_fp_single + us1_slotany, nothing") - -(define_insn_reservation "us1_fcmov_double" 2 - (and (and (eq_attr "cpu" "ultrasparc") - (eq_attr "type" "fpcmove,fpcrmove")) - (eq_attr "fptype" "double")) - "us1_fpa + us1_fp_double + us1_slotany, nothing") - -(define_insn_reservation "us1_faddsub_single" 4 - (and (and (eq_attr "cpu" "ultrasparc") - (eq_attr "type" "fp")) - (eq_attr "fptype" "single")) - "us1_fpa + us1_fp_single + us1_slotany, nothing*3") - -(define_insn_reservation "us1_faddsub_double" 4 - (and (and (eq_attr "cpu" "ultrasparc") - (eq_attr "type" "fp")) - (eq_attr "fptype" "double")) - "us1_fpa + us1_fp_double + us1_slotany, nothing*3") - -(define_insn_reservation "us1_fpcmp_single" 1 - (and (and (eq_attr "cpu" "ultrasparc") - (eq_attr "type" "fpcmp")) - (eq_attr "fptype" "single")) - "us1_fpa + us1_fp_single + us1_slotany") - -(define_insn_reservation "us1_fpcmp_double" 1 - (and (and (eq_attr "cpu" "ultrasparc") - (eq_attr "type" "fpcmp")) - (eq_attr "fptype" "double")) - "us1_fpa + us1_fp_double + us1_slotany") - -(define_insn_reservation "us1_fmult_single" 4 - (and (and (eq_attr "cpu" "ultrasparc") - (eq_attr "type" "fpmul")) - (eq_attr "fptype" "single")) - "us1_fpm + us1_fp_single + us1_slotany, nothing*3") - -(define_insn_reservation "us1_fmult_double" 4 - (and (and (eq_attr "cpu" "ultrasparc") - (eq_attr "type" "fpmul")) - (eq_attr "fptype" "double")) - "us1_fpm + us1_fp_double + us1_slotany, nothing*3") - -;; This is actually in theory dangerous, because it is possible -;; for the chip to prematurely dispatch the dependant instruction -;; in the G stage, resulting in a 9 cycle stall. However I have never -;; been able to trigger this case myself even with hand written code, -;; so it must require some rare complicated pipeline state. -(define_bypass 3 - "us1_faddsub_single,us1_faddsub_double,us1_fmult_single,us1_fmult_double" - "us1_faddsub_single,us1_faddsub_double,us1_fmult_single,us1_fmult_double") - -;; Floating point divide and square root use the multiplier unit -;; for final rounding 3 cycles before the divide/sqrt is complete. - -(define_insn_reservation "us1_fdivs" - 13 - (and (eq_attr "cpu" "ultrasparc") - (eq_attr "type" "fpdivs,fpsqrts")) - "(us1_fpm + us1_fdivider + us1_slot0), us1_fdivider*8, (us1_fpm + us1_fdivider), us1_fdivider*2" - ) - -(define_bypass - 12 - "us1_fdivs" - "us1_faddsub_single,us1_faddsub_double,us1_fmult_single,us1_fmult_double") - -(define_insn_reservation "us1_fdivd" - 23 - (and (eq_attr "cpu" "ultrasparc") - (eq_attr "type" "fpdivd,fpsqrtd")) - "(us1_fpm + us1_fdivider + us1_slot0), us1_fdivider*18, (us1_fpm + us1_fdivider), us1_fdivider*2" - ) -(define_bypass - 22 - "us1_fdivd" - "us1_faddsub_single,us1_faddsub_double,us1_fmult_single,us1_fmult_double") - -;; Any store may multi issue with the insn creating the source -;; data as long as that creating insn is not an FPU div/sqrt. -;; We need a special guard function because this bypass does -;; not apply to the address inputs of the store. -(define_bypass 0 "us1_simple_ieuN,us1_simple_ieu1,us1_simple_ieu0,us1_faddsub_single,us1_faddsub_double,us1_fmov_single,us1_fmov_double,us1_fcmov_single,us1_fcmov_double,us1_fmult_single,us1_fmult_double" "us1_store" - "store_data_bypass_p") - -;; An integer branch may execute in the same cycle as the compare -;; creating the condition codes. -(define_bypass 0 "us1_simple_ieu1" "us1_branch") - -;; UltraSPARC-III scheduling -;; -;; A much simpler beast, no silly slotting rules and both -;; integer units are fully symmetric. It does still have -;; single-issue instructions though. - -(define_cpu_unit "us3_a0,us3_a1,us3_ms,us3_br,us3_fpm" "ultrasparc3_0") -(define_cpu_unit "us3_slot0,us3_slot1,us3_slot2,us3_slot3,us3_fpa" "ultrasparc3_1") -(define_cpu_unit "us3_load_writeback" "ultrasparc3_1") - -(define_reservation "us3_slotany" "(us3_slot0 | us3_slot1 | us3_slot2 | us3_slot3)") -(define_reservation "us3_single_issue" "us3_slot0 + us3_slot1 + us3_slot2 + us3_slot3") -(define_reservation "us3_ax" "(us3_a0 | us3_a1)") - -(define_insn_reservation "us3_integer" 1 - (and (eq_attr "cpu" "ultrasparc3") - (eq_attr "type" "ialu,shift,compare")) - "us3_ax + us3_slotany") - -(define_insn_reservation "us3_cmove" 2 - (and (eq_attr "cpu" "ultrasparc3") - (eq_attr "type" "cmove")) - "us3_ms + us3_br + us3_slotany, nothing") - -;; ??? Not entirely accurate. -;; ??? It can run from 6 to 9 cycles. The first cycle the MS pipe -;; ??? is needed, and the instruction group is broken right after -;; ??? the imul. Then 'helper' instructions are generated to perform -;; ??? each further stage of the multiplication, each such 'helper' is -;; ??? single group. So, the reservation aspect is represented accurately -;; ??? here, but the variable cycles are not. -;; ??? Currently I have no idea how to determine the variability, but once -;; ??? known we can simply add a define_bypass or similar to model it. -(define_insn_reservation "us3_imul" 6 - (and (eq_attr "cpu" "ultrasparc3") - (eq_attr "type" "imul")) - "us3_ms + us3_slotany, us3_single_issue*5") - -(define_insn_reservation "us3_idiv" 71 - (and (eq_attr "cpu" "ultrasparc3") - (eq_attr "type" "idiv")) - "us3_ms + us3_slotany, us3_single_issue*70") - -;; UltraSPARC-III has a similar load delay as UltraSPARC-I/II except -;; that all loads except 32-bit/64-bit unsigned loads take the extra -;; delay for sign/zero extension. -(define_insn_reservation "us3_2cycle_load" 2 - (and (eq_attr "cpu" "ultrasparc3") - (and (eq_attr "type" "load,fpload") - (eq_attr "us3load_type" "2cycle"))) - "us3_ms + us3_slotany, us3_load_writeback") - -(define_insn_reservation "us3_load_delayed" 3 - (and (eq_attr "cpu" "ultrasparc3") - (and (eq_attr "type" "load,sload") - (eq_attr "us3load_type" "3cycle"))) - "us3_ms + us3_slotany, nothing, us3_load_writeback") - -(define_insn_reservation "us3_store" 1 - (and (eq_attr "cpu" "ultrasparc3") - (eq_attr "type" "store,fpstore")) - "us3_ms + us3_slotany") - -(define_insn_reservation "us3_branch" 1 - (and (eq_attr "cpu" "ultrasparc3") - (eq_attr "type" "branch")) - "us3_br + us3_slotany") - -(define_insn_reservation "us3_call_jmpl" 1 - (and (eq_attr "cpu" "ultrasparc3") - (eq_attr "type" "call,sibcall,call_no_delay_slot,uncond_branch")) - "us3_br + us3_ms + us3_slotany") - -(define_insn_reservation "us3_fmov" 3 - (and (eq_attr "cpu" "ultrasparc3") - (eq_attr "type" "fpmove")) - "us3_fpa + us3_slotany, nothing*2") - -(define_insn_reservation "us3_fcmov" 3 - (and (eq_attr "cpu" "ultrasparc3") - (eq_attr "type" "fpcmove")) - "us3_fpa + us3_br + us3_slotany, nothing*2") - -(define_insn_reservation "us3_fcrmov" 3 - (and (eq_attr "cpu" "ultrasparc3") - (eq_attr "type" "fpcrmove")) - "us3_fpa + us3_ms + us3_slotany, nothing*2") - -(define_insn_reservation "us3_faddsub" 4 - (and (eq_attr "cpu" "ultrasparc3") - (eq_attr "type" "fp")) - "us3_fpa + us3_slotany, nothing*3") - -(define_insn_reservation "us3_fpcmp" 5 - (and (eq_attr "cpu" "ultrasparc3") - (eq_attr "type" "fpcmp")) - "us3_fpa + us3_slotany, nothing*4") - -(define_insn_reservation "us3_fmult" 4 - (and (eq_attr "cpu" "ultrasparc3") - (eq_attr "type" "fpmul")) - "us3_fpm + us3_slotany, nothing*3") - -(define_insn_reservation "us3_fdivs" 17 - (and (eq_attr "cpu" "ultrasparc3") - (eq_attr "type" "fpdivs")) - "(us3_fpm + us3_slotany), us3_fpm*14, nothing*2") - -(define_insn_reservation "us3_fsqrts" 20 - (and (eq_attr "cpu" "ultrasparc3") - (eq_attr "type" "fpsqrts")) - "(us3_fpm + us3_slotany), us3_fpm*17, nothing*2") - -(define_insn_reservation "us3_fdivd" 20 - (and (eq_attr "cpu" "ultrasparc3") - (eq_attr "type" "fpdivd")) - "(us3_fpm + us3_slotany), us3_fpm*17, nothing*2") - -(define_insn_reservation "us3_fsqrtd" 29 - (and (eq_attr "cpu" "ultrasparc3") - (eq_attr "type" "fpsqrtd")) - "(us3_fpm + us3_slotany), us3_fpm*26, nothing*2") - -;; Any store may multi issue with the insn creating the source -;; data as long as that creating insn is not an FPU div/sqrt. -;; We need a special guard function because this bypass does -;; not apply to the address inputs of the store. -(define_bypass 0 "us3_integer,us3_faddsub,us3_fmov,us3_fcmov,us3_fmult" "us3_store" - "store_data_bypass_p") - -;; An integer branch may execute in the same cycle as the compare -;; creating the condition codes. -(define_bypass 0 "us3_integer" "us3_branch") - -;; If FMOVfcc is user of FPCMP, latency is only 1 cycle. -(define_bypass 1 "us3_fpcmp" "us3_fcmov") +;; Include SPARC DFA schedulers + +(include "cypress.md") +(include "supersparc.md") +(include "hypersparc.md") +(include "sparclet.md") +(include "ultra1_2.md") +(include "ultra3.md") ;; Compare instructions. diff --git a/gcc/config/sparc/sparclet.md b/gcc/config/sparc/sparclet.md new file mode 100644 index 00000000000..805bd29f92f --- /dev/null +++ b/gcc/config/sparc/sparclet.md @@ -0,0 +1,44 @@ +;; Scheduling description for Sparclet. +;; Copyright (C) 2002 Free Software Foundation, Inc. +;; +;; This file is part of GNU CC. +;; +;; GNU CC 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. +;; +;; GNU CC 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 GNU CC; see the file COPYING. If not, write to +;; the Free Software Foundation, 59 Temple Place - Suite 330, +;; Boston, MA 02111-1307, USA. + +;; The Sparclet is a single-issue processor. + +(define_automaton "sparclet") + +(define_cpu_unit "sl_load0,sl_load1,sl_load2,sl_load3" "sparclet") +(define_cpu_unit "sl_store,sl_imul" "sparclet") + +(define_reservation "sl_load_any" "(sl_load0 | sl_load1 | sl_load2 | sl_load3)") +(define_reservation "sl_load_all" "(sl_load0 + sl_load1 + sl_load2 + sl_load3)") + +(define_insn_reservation "sl_ld" 3 + (and (eq_attr "cpu" "tsc701") + (eq_attr "type" "load,sload")) + "sl_load_any, sl_load_any, sl_load_any") + +(define_insn_reservation "sl_st" 3 + (and (eq_attr "cpu" "tsc701") + (eq_attr "type" "store")) + "(sl_store+sl_load_all)*3") + +(define_insn_reservation "sl_imul" 5 + (and (eq_attr "cpu" "tsc701") + (eq_attr "type" "imul")) + "sl_imul*5") diff --git a/gcc/config/sparc/supersparc.md b/gcc/config/sparc/supersparc.md new file mode 100644 index 00000000000..21eadf492d6 --- /dev/null +++ b/gcc/config/sparc/supersparc.md @@ -0,0 +1,93 @@ +;; Scheduling description for SuperSparc. +;; Copyright (C) 2002 Free Software Foundation, Inc. +;; +;; This file is part of GNU CC. +;; +;; GNU CC 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. +;; +;; GNU CC 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 GNU CC; see the file COPYING. If not, write to +;; the Free Software Foundation, 59 Temple Place - Suite 330, +;; Boston, MA 02111-1307, USA. + +;; The SuperSparc is a tri-issue, which was considered quite parallel +;; at the time it was released. Much like UltraSPARC-I and UltraSPARC-II +;; there are two integer units but only one of them may take shifts. +;; +;; ??? If SuperSPARC has the same slotting rules as ultrasparc for these +;; ??? shifts, we should model that. + +(define_automaton "supersparc_0,supersparc_1") + +(define_cpu_unit "ss_memory, ss_shift, ss_iwport0, ss_iwport1" "supersparc_0") +(define_cpu_unit "ss_fpalu" "supersparc_0") +(define_cpu_unit "ss_fpmds" "supersparc_1") + +(define_reservation "ss_iwport" "(ss_iwport0 | ss_iwport1)") + +(define_insn_reservation "ss_iuload" 1 + (and (eq_attr "cpu" "supersparc") + (eq_attr "type" "load,sload")) + "ss_memory") + +;; Ok, fpu loads deliver the result in zero cycles. But we +;; have to show the ss_memory reservation somehow, thus... +(define_insn_reservation "ss_fpload" 0 + (and (eq_attr "cpu" "supersparc") + (eq_attr "type" "fpload")) + "ss_memory") + +(define_bypass 0 "ss_fpload" "ss_fp_alu,ss_fp_mult,ss_fp_divs,ss_fp_divd,ss_fp_sqrt") + +(define_insn_reservation "ss_store" 1 + (and (eq_attr "cpu" "supersparc") + (eq_attr "type" "store,fpstore")) + "ss_memory") + +(define_insn_reservation "ss_ialu_shift" 1 + (and (eq_attr "cpu" "supersparc") + (eq_attr "type" "shift")) + "ss_shift + ss_iwport") + +(define_insn_reservation "ss_ialu_any" 1 + (and (eq_attr "cpu" "supersparc") + (eq_attr "type" "load,sload,store,shift,ialu")) + "ss_iwport") + +(define_insn_reservation "ss_fp_alu" 3 + (and (eq_attr "cpu" "supersparc") + (eq_attr "type" "fp,fpmove,fpcmp")) + "ss_fpalu, nothing*2") + +(define_insn_reservation "ss_fp_mult" 3 + (and (eq_attr "cpu" "supersparc") + (eq_attr "type" "fpmul")) + "ss_fpmds, nothing*2") + +(define_insn_reservation "ss_fp_divs" 6 + (and (eq_attr "cpu" "supersparc") + (eq_attr "type" "fpdivs")) + "ss_fpmds*4, nothing*2") + +(define_insn_reservation "ss_fp_divd" 9 + (and (eq_attr "cpu" "supersparc") + (eq_attr "type" "fpdivd")) + "ss_fpmds*7, nothing*2") + +(define_insn_reservation "ss_fp_sqrt" 12 + (and (eq_attr "cpu" "supersparc") + (eq_attr "type" "fpsqrts,fpsqrtd")) + "ss_fpmds*10, nothing*2") + +(define_insn_reservation "ss_imul" 4 + (and (eq_attr "cpu" "supersparc") + (eq_attr "type" "imul")) + "ss_fpmds*4") diff --git a/gcc/config/sparc/ultra1_2.md b/gcc/config/sparc/ultra1_2.md new file mode 100644 index 00000000000..873421534ea --- /dev/null +++ b/gcc/config/sparc/ultra1_2.md @@ -0,0 +1,242 @@ +;; Scheduling description for UltraSPARC-I/II. +;; Copyright (C) 2002 Free Software Foundation, Inc. +;; +;; This file is part of GNU CC. +;; +;; GNU CC 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. +;; +;; GNU CC 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 GNU CC; see the file COPYING. If not, write to +;; the Free Software Foundation, 59 Temple Place - Suite 330, +;; Boston, MA 02111-1307, USA. + +;; UltraSPARC-I and II are quad-issue processors. Interesting features +;; to note: +;; +;; - Buffered loads, they can queue waiting for the actual data until +;; an instruction actually tries to reference the destination register +;; as an input +;; - Two integer units. Only one of them can do shifts, and the other +;; is the only one which may do condition code setting instructions. +;; Complicating things further, a shift may go only into the first +;; slot in a dispatched group. And if you have a non-condition code +;; setting instruction and one that does set the condition codes. The +;; former must be issued first in order for both of them to issue. +;; - Stores can issue before the value being stored is available. As long +;; as the input data becomes ready before the store is to move out of the +;; store buffer, it will not cause a stall. +;; - Branches may issue in the same cycle as an instruction setting the +;; condition codes being tested by that branch. This does not apply +;; to floating point, only integer. + +(define_automaton "ultrasparc_0,ultrasparc_1") + +(define_cpu_unit "us1_fdivider,us1_fpm" "ultrasparc_0"); +(define_cpu_unit "us1_fpa,us1_load_writeback" "ultrasparc_1") +(define_cpu_unit "us1_fps_0,us1_fps_1,us1_fpd_0,us1_fpd_1" "ultrasparc_1") +(define_cpu_unit "us1_slot0,us1_slot1,us1_slot2,us1_slot3" "ultrasparc_1") +(define_cpu_unit "us1_ieu0,us1_ieu1,us1_cti,us1_lsu" "ultrasparc_1") + +(define_reservation "us1_slot012" "(us1_slot0 | us1_slot1 | us1_slot2)") +(define_reservation "us1_slotany" "(us1_slot0 | us1_slot1 | us1_slot2 | us1_slot3)") +(define_reservation "us1_single_issue" "us1_slot0 + us1_slot1 + us1_slot2 + us1_slot3") + +(define_reservation "us1_fp_single" "(us1_fps_0 | us1_fps_1)") +(define_reservation "us1_fp_double" "(us1_fpd_0 | us1_fpd_1)") + +;; This is a simplified representation of the issue at hand. +;; For most cases, going from one FP precision type insn to another +;; just breaks up the insn group. However for some cases, such +;; a situation causes the second insn to stall 2 more cycles. +(exclusion_set "us1_fps_0,us1_fps_1" "us1_fpd_0,us1_fpd_1") + +;; If we have to schedule an ieu1 specific instruction and we want +;; to reserve the ieu0 unit as well, we must reserve it first. So for +;; example we could not schedule this sequence: +;; COMPARE IEU1 +;; IALU IEU0 +;; but we could schedule them together like this: +;; IALU IEU0 +;; COMPARE IEU1 +;; This basically requires that ieu0 is reserved before ieu1 when +;; it is required that both be reserved. +(absence_set "us1_ieu0" "us1_ieu1") + +;; This defines the slotting order. Most IEU instructions can only +;; execute in the first three slots, FPU and branches can go into +;; any slot. We represent instructions which "break the group" +;; as requiring reservation of us1_slot0. +(absence_set "us1_slot0" "us1_slot1,us1_slot2,us1_slot3") +(absence_set "us1_slot1" "us1_slot2,us1_slot3") +(absence_set "us1_slot2" "us1_slot3") + +(define_insn_reservation "us1_simple_ieuN" 1 + (and (eq_attr "cpu" "ultrasparc") + (eq_attr "type" "ialu")) + "(us1_ieu0 | us1_ieu1) + us1_slot012") + +(define_insn_reservation "us1_simple_ieu0" 1 + (and (eq_attr "cpu" "ultrasparc") + (eq_attr "type" "shift")) + "us1_ieu0 + us1_slot012") + +(define_insn_reservation "us1_simple_ieu1" 1 + (and (eq_attr "cpu" "ultrasparc") + (eq_attr "type" "compare")) + "us1_ieu1 + us1_slot012") + +(define_insn_reservation "us1_cmove" 2 + (and (eq_attr "cpu" "ultrasparc") + (eq_attr "type" "cmove")) + "us1_single_issue, nothing") + +(define_insn_reservation "us1_imul" 1 + (and (eq_attr "cpu" "ultrasparc") + (eq_attr "type" "imul")) + "us1_single_issue") + +(define_insn_reservation "us1_idiv" 1 + (and (eq_attr "cpu" "ultrasparc") + (eq_attr "type" "idiv")) + "us1_single_issue") + +;; For loads, the "delayed return mode" behavior of the chip +;; is represented using the us1_load_writeback resource. +(define_insn_reservation "us1_load" 2 + (and (eq_attr "cpu" "ultrasparc") + (eq_attr "type" "load,fpload")) + "us1_lsu + us1_slot012, us1_load_writeback") + +(define_insn_reservation "us1_load_signed" 3 + (and (eq_attr "cpu" "ultrasparc") + (eq_attr "type" "sload")) + "us1_lsu + us1_slot012, nothing, us1_load_writeback") + +(define_insn_reservation "us1_store" 1 + (and (eq_attr "cpu" "ultrasparc") + (eq_attr "type" "store,fpstore")) + "us1_lsu + us1_slot012") + +(define_insn_reservation "us1_branch" 1 + (and (eq_attr "cpu" "ultrasparc") + (eq_attr "type" "branch")) + "us1_cti + us1_slotany") + +(define_insn_reservation "us1_call_jmpl" 1 + (and (eq_attr "cpu" "ultrasparc") + (eq_attr "type" "call,sibcall,call_no_delay_slot,uncond_branch")) + "us1_cti + us1_ieu1 + us1_slot0") + +(define_insn_reservation "us1_fmov_single" 1 + (and (and (eq_attr "cpu" "ultrasparc") + (eq_attr "type" "fpmove")) + (eq_attr "fptype" "single")) + "us1_fpa + us1_fp_single + us1_slotany") + +(define_insn_reservation "us1_fmov_double" 1 + (and (and (eq_attr "cpu" "ultrasparc") + (eq_attr "type" "fpmove")) + (eq_attr "fptype" "double")) + "us1_fpa + us1_fp_double + us1_slotany") + +(define_insn_reservation "us1_fcmov_single" 2 + (and (and (eq_attr "cpu" "ultrasparc") + (eq_attr "type" "fpcmove,fpcrmove")) + (eq_attr "fptype" "single")) + "us1_fpa + us1_fp_single + us1_slotany, nothing") + +(define_insn_reservation "us1_fcmov_double" 2 + (and (and (eq_attr "cpu" "ultrasparc") + (eq_attr "type" "fpcmove,fpcrmove")) + (eq_attr "fptype" "double")) + "us1_fpa + us1_fp_double + us1_slotany, nothing") + +(define_insn_reservation "us1_faddsub_single" 4 + (and (and (eq_attr "cpu" "ultrasparc") + (eq_attr "type" "fp")) + (eq_attr "fptype" "single")) + "us1_fpa + us1_fp_single + us1_slotany, nothing*3") + +(define_insn_reservation "us1_faddsub_double" 4 + (and (and (eq_attr "cpu" "ultrasparc") + (eq_attr "type" "fp")) + (eq_attr "fptype" "double")) + "us1_fpa + us1_fp_double + us1_slotany, nothing*3") + +(define_insn_reservation "us1_fpcmp_single" 1 + (and (and (eq_attr "cpu" "ultrasparc") + (eq_attr "type" "fpcmp")) + (eq_attr "fptype" "single")) + "us1_fpa + us1_fp_single + us1_slotany") + +(define_insn_reservation "us1_fpcmp_double" 1 + (and (and (eq_attr "cpu" "ultrasparc") + (eq_attr "type" "fpcmp")) + (eq_attr "fptype" "double")) + "us1_fpa + us1_fp_double + us1_slotany") + +(define_insn_reservation "us1_fmult_single" 4 + (and (and (eq_attr "cpu" "ultrasparc") + (eq_attr "type" "fpmul")) + (eq_attr "fptype" "single")) + "us1_fpm + us1_fp_single + us1_slotany, nothing*3") + +(define_insn_reservation "us1_fmult_double" 4 + (and (and (eq_attr "cpu" "ultrasparc") + (eq_attr "type" "fpmul")) + (eq_attr "fptype" "double")) + "us1_fpm + us1_fp_double + us1_slotany, nothing*3") + +;; This is actually in theory dangerous, because it is possible +;; for the chip to prematurely dispatch the dependant instruction +;; in the G stage, resulting in a 9 cycle stall. However I have never +;; been able to trigger this case myself even with hand written code, +;; so it must require some rare complicated pipeline state. +(define_bypass 3 + "us1_faddsub_single,us1_faddsub_double,us1_fmult_single,us1_fmult_double" + "us1_faddsub_single,us1_faddsub_double,us1_fmult_single,us1_fmult_double") + +;; Floating point divide and square root use the multiplier unit +;; for final rounding 3 cycles before the divide/sqrt is complete. + +(define_insn_reservation "us1_fdivs" + 13 + (and (eq_attr "cpu" "ultrasparc") + (eq_attr "type" "fpdivs,fpsqrts")) + "(us1_fpm + us1_fdivider + us1_slot0), us1_fdivider*8, (us1_fpm + us1_fdivider), us1_fdivider*2" + ) + +(define_bypass + 12 + "us1_fdivs" + "us1_faddsub_single,us1_faddsub_double,us1_fmult_single,us1_fmult_double") + +(define_insn_reservation "us1_fdivd" + 23 + (and (eq_attr "cpu" "ultrasparc") + (eq_attr "type" "fpdivd,fpsqrtd")) + "(us1_fpm + us1_fdivider + us1_slot0), us1_fdivider*18, (us1_fpm + us1_fdivider), us1_fdivider*2" + ) +(define_bypass + 22 + "us1_fdivd" + "us1_faddsub_single,us1_faddsub_double,us1_fmult_single,us1_fmult_double") + +;; Any store may multi issue with the insn creating the source +;; data as long as that creating insn is not an FPU div/sqrt. +;; We need a special guard function because this bypass does +;; not apply to the address inputs of the store. +(define_bypass 0 "us1_simple_ieuN,us1_simple_ieu1,us1_simple_ieu0,us1_faddsub_single,us1_faddsub_double,us1_fmov_single,us1_fmov_double,us1_fcmov_single,us1_fcmov_double,us1_fmult_single,us1_fmult_double" "us1_store" + "store_data_bypass_p") + +;; An integer branch may execute in the same cycle as the compare +;; creating the condition codes. +(define_bypass 0 "us1_simple_ieu1" "us1_branch") diff --git a/gcc/config/sparc/ultra3.md b/gcc/config/sparc/ultra3.md new file mode 100644 index 00000000000..72cd33eafa4 --- /dev/null +++ b/gcc/config/sparc/ultra3.md @@ -0,0 +1,158 @@ +;; Scheduling description for UltraSPARC-III. +;; Copyright (C) 2002 Free Software Foundation, Inc. +;; +;; This file is part of GNU CC. +;; +;; GNU CC 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. +;; +;; GNU CC 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 GNU CC; see the file COPYING. If not, write to +;; the Free Software Foundation, 59 Temple Place - Suite 330, +;; Boston, MA 02111-1307, USA. + +;; UltraSPARC-III is a quad-issue processor. +;; +;; It is also a much simpler beast than Ultra-I/II, no silly +;; slotting rules and both integer units are fully symmetric. +;; It does still have single-issue instructions though. + +(define_automaton "ultrasparc3_0,ultrasparc3_1") + +(define_cpu_unit "us3_a0,us3_a1,us3_ms,us3_br,us3_fpm" "ultrasparc3_0") +(define_cpu_unit "us3_slot0,us3_slot1,us3_slot2,us3_slot3,us3_fpa" "ultrasparc3_1") +(define_cpu_unit "us3_load_writeback" "ultrasparc3_1") + +(define_reservation "us3_slotany" "(us3_slot0 | us3_slot1 | us3_slot2 | us3_slot3)") +(define_reservation "us3_single_issue" "us3_slot0 + us3_slot1 + us3_slot2 + us3_slot3") +(define_reservation "us3_ax" "(us3_a0 | us3_a1)") + +(define_insn_reservation "us3_integer" 1 + (and (eq_attr "cpu" "ultrasparc3") + (eq_attr "type" "ialu,shift,compare")) + "us3_ax + us3_slotany") + +(define_insn_reservation "us3_cmove" 2 + (and (eq_attr "cpu" "ultrasparc3") + (eq_attr "type" "cmove")) + "us3_ms + us3_br + us3_slotany, nothing") + +;; ??? Not entirely accurate. +;; ??? It can run from 6 to 9 cycles. The first cycle the MS pipe +;; ??? is needed, and the instruction group is broken right after +;; ??? the imul. Then 'helper' instructions are generated to perform +;; ??? each further stage of the multiplication, each such 'helper' is +;; ??? single group. So, the reservation aspect is represented accurately +;; ??? here, but the variable cycles are not. +;; ??? Currently I have no idea how to determine the variability, but once +;; ??? known we can simply add a define_bypass or similar to model it. +(define_insn_reservation "us3_imul" 6 + (and (eq_attr "cpu" "ultrasparc3") + (eq_attr "type" "imul")) + "us3_ms + us3_slotany, us3_single_issue*5") + +(define_insn_reservation "us3_idiv" 71 + (and (eq_attr "cpu" "ultrasparc3") + (eq_attr "type" "idiv")) + "us3_ms + us3_slotany, us3_single_issue*70") + +;; UltraSPARC-III has a similar load delay as UltraSPARC-I/II except +;; that all loads except 32-bit/64-bit unsigned loads take the extra +;; delay for sign/zero extension. +(define_insn_reservation "us3_2cycle_load" 2 + (and (eq_attr "cpu" "ultrasparc3") + (and (eq_attr "type" "load,fpload") + (eq_attr "us3load_type" "2cycle"))) + "us3_ms + us3_slotany, us3_load_writeback") + +(define_insn_reservation "us3_load_delayed" 3 + (and (eq_attr "cpu" "ultrasparc3") + (and (eq_attr "type" "load,sload") + (eq_attr "us3load_type" "3cycle"))) + "us3_ms + us3_slotany, nothing, us3_load_writeback") + +(define_insn_reservation "us3_store" 1 + (and (eq_attr "cpu" "ultrasparc3") + (eq_attr "type" "store,fpstore")) + "us3_ms + us3_slotany") + +(define_insn_reservation "us3_branch" 1 + (and (eq_attr "cpu" "ultrasparc3") + (eq_attr "type" "branch")) + "us3_br + us3_slotany") + +(define_insn_reservation "us3_call_jmpl" 1 + (and (eq_attr "cpu" "ultrasparc3") + (eq_attr "type" "call,sibcall,call_no_delay_slot,uncond_branch")) + "us3_br + us3_ms + us3_slotany") + +(define_insn_reservation "us3_fmov" 3 + (and (eq_attr "cpu" "ultrasparc3") + (eq_attr "type" "fpmove")) + "us3_fpa + us3_slotany, nothing*2") + +(define_insn_reservation "us3_fcmov" 3 + (and (eq_attr "cpu" "ultrasparc3") + (eq_attr "type" "fpcmove")) + "us3_fpa + us3_br + us3_slotany, nothing*2") + +(define_insn_reservation "us3_fcrmov" 3 + (and (eq_attr "cpu" "ultrasparc3") + (eq_attr "type" "fpcrmove")) + "us3_fpa + us3_ms + us3_slotany, nothing*2") + +(define_insn_reservation "us3_faddsub" 4 + (and (eq_attr "cpu" "ultrasparc3") + (eq_attr "type" "fp")) + "us3_fpa + us3_slotany, nothing*3") + +(define_insn_reservation "us3_fpcmp" 5 + (and (eq_attr "cpu" "ultrasparc3") + (eq_attr "type" "fpcmp")) + "us3_fpa + us3_slotany, nothing*4") + +(define_insn_reservation "us3_fmult" 4 + (and (eq_attr "cpu" "ultrasparc3") + (eq_attr "type" "fpmul")) + "us3_fpm + us3_slotany, nothing*3") + +(define_insn_reservation "us3_fdivs" 17 + (and (eq_attr "cpu" "ultrasparc3") + (eq_attr "type" "fpdivs")) + "(us3_fpm + us3_slotany), us3_fpm*14, nothing*2") + +(define_insn_reservation "us3_fsqrts" 20 + (and (eq_attr "cpu" "ultrasparc3") + (eq_attr "type" "fpsqrts")) + "(us3_fpm + us3_slotany), us3_fpm*17, nothing*2") + +(define_insn_reservation "us3_fdivd" 20 + (and (eq_attr "cpu" "ultrasparc3") + (eq_attr "type" "fpdivd")) + "(us3_fpm + us3_slotany), us3_fpm*17, nothing*2") + +(define_insn_reservation "us3_fsqrtd" 29 + (and (eq_attr "cpu" "ultrasparc3") + (eq_attr "type" "fpsqrtd")) + "(us3_fpm + us3_slotany), us3_fpm*26, nothing*2") + +;; Any store may multi issue with the insn creating the source +;; data as long as that creating insn is not an FPU div/sqrt. +;; We need a special guard function because this bypass does +;; not apply to the address inputs of the store. +(define_bypass 0 "us3_integer,us3_faddsub,us3_fmov,us3_fcmov,us3_fmult" "us3_store" + "store_data_bypass_p") + +;; An integer branch may execute in the same cycle as the compare +;; creating the condition codes. +(define_bypass 0 "us3_integer" "us3_branch") + +;; If FMOVfcc is user of FPCMP, latency is only 1 cycle. +(define_bypass 1 "us3_fpcmp" "us3_fcmov") |