1;; Scheduling description for the Xilinx PowerPC 405 APU Floating Point Unit.
2;; Copyright (C) 2008-2014 Free Software Foundation, Inc.
3;; Contributed by Michael Eager (eager@eagercon.com).
4;;
5;; This file is part of GCC.
6;;
7;; GCC is free software; you can redistribute it and/or modify
8;; it under the terms of the GNU General Public License as published by
9;; the Free Software Foundation; either version 3, or (at your option)
10;; any later version.
11;;
12;; GCC is distributed in the hope that it will be useful,
13;; but WITHOUT ANY WARRANTY; without even the implied warranty of
14;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15;; GNU General Public License for more details.
16;;
17;; You should have received a copy of the GNU General Public License
18;; along with GCC; see the file COPYING3.  If not see
19;; <http://www.gnu.org/licenses/>.
20
21;;----------------------------------------------------
22;; Xilinx APU FPU Pipeline Description
23;;
24;;  - attr 'type' and 'fp_type' should definitely
25;;    be cleaned up at some point in the future.
26;;    ddiv,sdiv,dmul,smul etc are quite confusing.
27;;    Should use consistent fp* attrs. 'fp_type'
28;;    should also go away, leaving us only with 'fp'
29;;
30;;----------------------------------------------------
31
32;; -------------------------------------------------------------------------
33;; Latencies
34;; Latest latency figures (all in FCB cycles). PowerPC to FPU frequency ratio
35;; assumed to be 1/2. (most common deployment)
36;; Add 2 PPC cycles for (register file access + wb) and 2 PPC cycles
37;; for issue (from PPC)
38;;                          SP          DP
39;; Loads:                    4           6
40;; Stores:                   1           2      (from availability of data)
41;; Move/Abs/Neg:             1           1
42;; Add/Subtract:             5           7
43;; Multiply:                 4          11
44;; Multiply-add:            10          19
45;; Convert (any):            4           6
46;; Divide/Sqrt:             27          56
47;; Compares:                 1           2
48;;
49;; bypasses needed for forwarding capability of the FPU.
50;; Add this at some future time.
51;; -------------------------------------------------------------------------
52(define_automaton "Xfpu")
53(define_cpu_unit "Xfpu_issue,Xfpu_addsub,Xfpu_mul,Xfpu_div,Xfpu_sqrt" "Xfpu")
54
55
56(define_insn_reservation "fp-default" 2
57  (and (and
58        (eq_attr "type" "fp")
59        (eq_attr "fp_type" "fp_default"))
60       (eq_attr "cpu" "ppc405"))
61  "Xfpu_issue*2")
62
63(define_insn_reservation "fp-compare" 6
64  (and (eq_attr "type" "fpcompare")                     ;; Inconsistent naming
65       (eq_attr "cpu" "ppc405"))
66  "Xfpu_issue*2,Xfpu_addsub")
67
68(define_insn_reservation "fp-addsub-s" 14
69  (and (and
70        (eq_attr "type" "fp")
71        (eq_attr "fp_type" "fp_addsub_s"))
72       (eq_attr "cpu" "ppc405"))
73  "Xfpu_issue*2,Xfpu_addsub")
74
75(define_insn_reservation "fp-addsub-d" 18
76  (and (and
77        (eq_attr "type" "fp")
78        (eq_attr "fp_type" "fp_addsub_d"))
79       (eq_attr "cpu" "ppc405"))
80  "Xfpu_issue*2,Xfpu_addsub")
81
82(define_insn_reservation "fp-mul-s" 12
83  (and (and
84        (eq_attr "type" "fp")
85        (eq_attr "fp_type" "fp_mul_s"))
86       (eq_attr "cpu" "ppc405"))
87  "Xfpu_issue*2,Xfpu_mul")
88
89(define_insn_reservation "fp-mul-d" 16    ;; Actually 28. Long latencies are killing the automaton formation. Need to figure out why.
90  (and (and
91        (eq_attr "type" "fp")
92        (eq_attr "fp_type" "fp_mul_d"))
93       (eq_attr "cpu" "ppc405"))
94  "Xfpu_issue*2,Xfpu_mul")
95
96(define_insn_reservation "fp-div-s" 24                   ;; Actually 34
97   (and (eq_attr "type" "sdiv")                          ;; Inconsistent attr naming
98        (eq_attr "cpu" "ppc405"))
99   "Xfpu_issue*2,Xfpu_div*10")                           ;; Unpipelined
100
101(define_insn_reservation "fp-div-d" 34                   ;; Actually 116
102  (and (eq_attr "type" "ddiv")
103       (eq_attr "cpu" "ppc405"))                         ;; Inconsistent attr naming
104  "Xfpu_issue*2,Xfpu_div*10")                            ;; Unpipelined
105
106(define_insn_reservation "fp-maddsub-s" 24
107  (and (and
108        (eq_attr "type" "fp")
109        (eq_attr "fp_type" "fp_maddsub_s"))
110       (eq_attr "cpu" "ppc405"))
111  "Xfpu_issue*2,Xfpu_mul,nothing*7,Xfpu_addsub")
112
113(define_insn_reservation "fp-maddsub-d" 34              ;; Actually 42
114  (and (and
115        (eq_attr "type" "dmul")                         ;; Inconsistent attr naming
116        (eq_attr "fp_type" "fp_maddsub_d"))
117       (eq_attr "cpu" "ppc405"))
118  "Xfpu_issue*2,Xfpu_mul,nothing*7,Xfpu_addsub")
119
120(define_insn_reservation "fp-load" 10                   ;; FIXME. Is double/single precision the same ?
121  (and (eq_attr "type" "fpload, fpload_ux, fpload_u")
122       (eq_attr "cpu" "ppc405"))
123  "Xfpu_issue*10")
124
125(define_insn_reservation "fp-store" 4
126  (and (eq_attr "type" "fpstore, fpstore_ux, fpstore_u")
127       (eq_attr "cpu" "ppc405"))
128  "Xfpu_issue*4")
129
130(define_insn_reservation "fp-sqrt-s" 24         ;; Actually 56
131  (and (eq_attr "type" "ssqrt")
132       (eq_attr "cpu" "ppc405"))
133  "Xfpu_issue*2,Xfpu_sqrt*10")                  ;; Unpipelined
134
135
136(define_insn_reservation "fp-sqrt-d" 34         ;; Actually 116
137  (and (eq_attr "type" "dsqrt")
138       (eq_attr "cpu" "ppc405"))
139  "Xfpu_issue*2,Xfpu_sqrt*10")                  ;; Unpipelined
140
141