sparc.md (DFA schedulers): Split out...
authorDavid S. Miller <davem@redhat.com>
Sat, 4 May 2002 05:03:45 +0000 (22:03 -0700)
committerDavid S. Miller <davem@gcc.gnu.org>
Sat, 4 May 2002 05:03:45 +0000 (22:03 -0700)
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.

From-SVN: r53146

gcc/ChangeLog
gcc/config/sparc/cypress.md [new file with mode: 0644]
gcc/config/sparc/hypersparc.md [new file with mode: 0644]
gcc/config/sparc/sparc.md
gcc/config/sparc/sparclet.md [new file with mode: 0644]
gcc/config/sparc/supersparc.md [new file with mode: 0644]
gcc/config/sparc/ultra1_2.md [new file with mode: 0644]
gcc/config/sparc/ultra3.md [new file with mode: 0644]

index 121f1fa89d88eab5333bb1433c8c1238d27933d3..df9380a1f49f6c340ee5e6106f80bf81e18b0378 100644 (file)
@@ -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 (file)
index 0000000..f871b1e
--- /dev/null
@@ -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 (file)
index 0000000..741f163
--- /dev/null
@@ -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")
index ed9da8bbefb110c1e2a99a9372ae36b299ddad23..8f19dc7fd1d6e9671d1f62318d53a703070616c6 100644 (file)
   [(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")
 
 \f
 ;; Compare instructions.
diff --git a/gcc/config/sparc/sparclet.md b/gcc/config/sparc/sparclet.md
new file mode 100644 (file)
index 0000000..805bd29
--- /dev/null
@@ -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 (file)
index 0000000..21eadf4
--- /dev/null
@@ -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 (file)
index 0000000..8734215
--- /dev/null
@@ -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 (file)
index 0000000..72cd33e
--- /dev/null
@@ -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")