1;; Pipeline descriptions of Andes NDS32 cpu for GNU compiler
2;; Copyright (C) 2012-2020 Free Software Foundation, Inc.
3;; Contributed by Andes Technology Corporation.
4;;
5;; This file is part of GCC.
6;;
7;; GCC is free software; you can redistribute it and/or modify it
8;; under the terms of the GNU General Public License as published
9;; by the Free Software Foundation; either version 3, or (at your
10;; option) any later version.
11;;
12;; GCC is distributed in the hope that it will be useful, but WITHOUT
13;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
14;; or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
15;; 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;; ------------------------------------------------------------------------
23;; Define N8 pipeline settings.
24;; ------------------------------------------------------------------------
25
26(define_automaton "nds32_n7_machine")
27
28;; ------------------------------------------------------------------------
29;; Pipeline Stages
30;; ------------------------------------------------------------------------
31;; IF - Instruction Fetch
32;;   Instruction Alignment
33;;   Instruction Pre-decode
34;; II - Instruction Issue
35;;   Instruction Decode
36;;   Register File Access
37;;   Instruction Execution
38;;   Interrupt Handling
39;; EXD - Psuedo Stage
40;;   Load Data Completion
41
42(define_cpu_unit "n7_ii" "nds32_n7_machine")
43
44(define_insn_reservation "nds_n7_unknown" 1
45  (and (eq_attr "type" "unknown")
46       (eq_attr "pipeline_model" "n7"))
47  "n7_ii")
48
49(define_insn_reservation "nds_n7_misc" 1
50  (and (eq_attr "type" "misc")
51       (eq_attr "pipeline_model" "n7"))
52  "n7_ii")
53
54(define_insn_reservation "nds_n7_alu" 1
55  (and (eq_attr "type" "alu")
56       (eq_attr "pipeline_model" "n7"))
57  "n7_ii")
58
59(define_insn_reservation "nds_n7_load" 1
60  (and (match_test "nds32::load_single_p (insn)")
61       (eq_attr "pipeline_model" "n7"))
62  "n7_ii")
63
64(define_insn_reservation "nds_n7_store" 1
65  (and (match_test "nds32::store_single_p (insn)")
66       (eq_attr "pipeline_model" "n7"))
67  "n7_ii")
68
69(define_insn_reservation "nds_n7_load_multiple_1" 1
70  (and (and (eq_attr "type" "load_multiple")
71	    (eq_attr "combo" "1"))
72       (eq_attr "pipeline_model" "n7"))
73  "n7_ii")
74
75(define_insn_reservation "nds_n7_load_multiple_2" 1
76  (and (ior (and (eq_attr "type" "load_multiple")
77		 (eq_attr "combo" "2"))
78	    (match_test "nds32::load_double_p (insn)"))
79       (eq_attr "pipeline_model" "n7"))
80  "n7_ii*2")
81
82(define_insn_reservation "nds_n7_load_multiple_3" 1
83  (and (and (eq_attr "type" "load_multiple")
84	    (eq_attr "combo" "3"))
85       (eq_attr "pipeline_model" "n7"))
86  "n7_ii*3")
87
88(define_insn_reservation "nds_n7_load_multiple_4" 1
89  (and (and (eq_attr "type" "load_multiple")
90	    (eq_attr "combo" "4"))
91       (eq_attr "pipeline_model" "n7"))
92  "n7_ii*4")
93
94(define_insn_reservation "nds_n7_load_multiple_5" 1
95  (and (and (eq_attr "type" "load_multiple")
96	    (eq_attr "combo" "5"))
97       (eq_attr "pipeline_model" "n7"))
98  "n7_ii*5")
99
100(define_insn_reservation "nds_n7_load_multiple_6" 1
101  (and (and (eq_attr "type" "load_multiple")
102	    (eq_attr "combo" "6"))
103       (eq_attr "pipeline_model" "n7"))
104  "n7_ii*6")
105
106(define_insn_reservation "nds_n7_load_multiple_7" 1
107  (and (and (eq_attr "type" "load_multiple")
108	    (eq_attr "combo" "7"))
109       (eq_attr "pipeline_model" "n7"))
110  "n7_ii*7")
111
112(define_insn_reservation "nds_n7_load_multiple_8" 1
113  (and (and (eq_attr "type" "load_multiple")
114	    (eq_attr "combo" "8"))
115       (eq_attr "pipeline_model" "n7"))
116  "n7_ii*8")
117
118(define_insn_reservation "nds_n7_load_multiple_12" 1
119  (and (and (eq_attr "type" "load_multiple")
120	    (eq_attr "combo" "12"))
121       (eq_attr "pipeline_model" "n7"))
122  "n7_ii*12")
123
124(define_insn_reservation "nds_n7_store_multiple_1" 1
125  (and (and (eq_attr "type" "store_multiple")
126	    (eq_attr "combo" "1"))
127       (eq_attr "pipeline_model" "n7"))
128  "n7_ii")
129
130(define_insn_reservation "nds_n7_store_multiple_2" 1
131  (and (ior (and (eq_attr "type" "store_multiple")
132		 (eq_attr "combo" "2"))
133	    (match_test "nds32::store_double_p (insn)"))
134       (eq_attr "pipeline_model" "n7"))
135  "n7_ii*2")
136
137(define_insn_reservation "nds_n7_store_multiple_3" 1
138  (and (and (eq_attr "type" "store_multiple")
139	    (eq_attr "combo" "3"))
140       (eq_attr "pipeline_model" "n7"))
141  "n7_ii*3")
142
143(define_insn_reservation "nds_n7_store_multiple_4" 1
144  (and (and (eq_attr "type" "store_multiple")
145	    (eq_attr "combo" "4"))
146       (eq_attr "pipeline_model" "n7"))
147  "n7_ii*4")
148
149(define_insn_reservation "nds_n7_store_multiple_5" 1
150  (and (and (eq_attr "type" "store_multiple")
151	    (eq_attr "combo" "5"))
152       (eq_attr "pipeline_model" "n7"))
153  "n7_ii*5")
154
155(define_insn_reservation "nds_n7_store_multiple_6" 1
156  (and (and (eq_attr "type" "store_multiple")
157	    (eq_attr "combo" "6"))
158       (eq_attr "pipeline_model" "n7"))
159  "n7_ii*6")
160
161(define_insn_reservation "nds_n7_store_multiple_7" 1
162  (and (and (eq_attr "type" "store_multiple")
163	    (eq_attr "combo" "7"))
164       (eq_attr "pipeline_model" "n7"))
165  "n7_ii*7")
166
167(define_insn_reservation "nds_n7_store_multiple_8" 1
168  (and (and (eq_attr "type" "store_multiple")
169	    (eq_attr "combo" "8"))
170       (eq_attr "pipeline_model" "n7"))
171  "n7_ii*8")
172
173(define_insn_reservation "nds_n7_store_multiple_12" 1
174  (and (and (eq_attr "type" "store_multiple")
175	    (eq_attr "combo" "12"))
176       (eq_attr "pipeline_model" "n7"))
177  "n7_ii*12")
178
179(define_insn_reservation "nds_n7_mul_fast" 1
180  (and (match_test "nds32_mul_config != MUL_TYPE_SLOW")
181       (and (eq_attr "type" "mul")
182	    (eq_attr "pipeline_model" "n7")))
183  "n7_ii")
184
185(define_insn_reservation "nds_n7_mul_slow" 1
186  (and (match_test "nds32_mul_config == MUL_TYPE_SLOW")
187       (and (eq_attr "type" "mul")
188	    (eq_attr "pipeline_model" "n7")))
189  "n7_ii*17")
190
191(define_insn_reservation "nds_n7_mac_fast" 1
192  (and (match_test "nds32_mul_config != MUL_TYPE_SLOW")
193       (and (eq_attr "type" "mac")
194	    (eq_attr "pipeline_model" "n7")))
195  "n7_ii*2")
196
197(define_insn_reservation "nds_n7_mac_slow" 1
198  (and (match_test "nds32_mul_config == MUL_TYPE_SLOW")
199       (and (eq_attr "type" "mac")
200	    (eq_attr "pipeline_model" "n7")))
201  "n7_ii*18")
202
203(define_insn_reservation "nds_n7_div" 1
204  (and (eq_attr "type" "div")
205       (eq_attr "pipeline_model" "n7"))
206  "n7_ii*37")
207
208(define_insn_reservation "nds_n7_branch" 1
209  (and (eq_attr "type" "branch")
210       (eq_attr "pipeline_model" "n7"))
211  "n7_ii")
212
213;; ------------------------------------------------------------------------
214;; Comment Notations and Bypass Rules
215;; ------------------------------------------------------------------------
216;; Producers (LHS)
217;;   LD_!bi
218;;     Load data from the memory (without updating the base register) and
219;;     produce the loaded data. The result is ready at EXD.
220;;   LMW(N, M)
221;;     There are N micro-operations within an instruction that loads multiple
222;;     words. The result produced by the M-th micro-operation is sent to
223;;     consumers. The result is ready at EXD. If the base register should be
224;;     updated, an extra micro-operation is inserted to the sequence, and the
225;;     result is ready at II.
226;;
227;; Consumers (RHS)
228;;   ALU, MUL, DIV
229;;     Require operands at II.
230;;   MOVD44_E
231;;     A double-word move instruction needs two micro-operations because the
232;;     reigster ports is 2R1W. The first micro-operation writes an even number
233;;     register, and the second micro-operation writes an odd number register.
234;;     Each input operand is required at II for each micro-operation. The letter
235;;     'E' stands for even.
236;;   MAC_RaRb
237;;     A MAC instruction is separated into two micro-operations. The first
238;;     micro-operation does the multiplication, which requires operands Ra
239;;     and Rb at II. The second micro-options does the accumulation, which
240;;     requires the operand Rt at II.
241;;   ADDR_IN_MOP(N)
242;;     Because the reigster port is 2R1W, some load/store instructions are
243;;     separated into many micro-operations. N denotes the address input is
244;;     required by the N-th micro-operation. Such operand is required at II.
245;;   ST_bi
246;;     A post-increment store instruction requires its data at II.
247;;   ST_!bi_RI
248;;     A store instruction with an immediate offset requires its data at II.
249;;     If the offset field is a register (ST_!bi_RR), the instruction will be
250;;     separated into two micro-operations, and the second one requires the
251;;     input operand at II in order to store it to the memory.
252;;   SMW(N, M)
253;;     There are N micro-operations within an instruction that stores multiple
254;;     words. Each M-th micro-operation requires its data at II. If the base
255;;     register should be updated, an extra micro-operation is inserted to the
256;;     sequence.
257;;   BR_COND
258;;     If a branch instruction is conditional, its input data is required at II.
259
260;; LD_!bi
261;;   -> ALU, MOVD44_E, MUL, MAC_RaRb, DIV, BR, ADDR_IN_MOP(1), ST_bi, ST_!bi_RI, SMW(N, 1)
262(define_bypass 2
263  "nds_n7_load"
264  "nds_n7_alu,\
265   nds_n7_mul_fast, nds_n7_mul_slow,\
266   nds_n7_mac_fast, nds_n7_mac_slow,\
267   nds_n7_div,\
268   nds_n7_branch,\
269   nds_n7_load, nds_n7_store,\
270   nds_n7_load_multiple_1,nds_n7_load_multiple_2, nds_n7_load_multiple_3,\
271   nds_n7_load_multiple_4,nds_n7_load_multiple_5, nds_n7_load_multiple_6,\
272   nds_n7_load_multiple_7,nds_n7_load_multiple_8, nds_n7_load_multiple_12,\
273   nds_n7_store_multiple_1,nds_n7_store_multiple_2, nds_n7_store_multiple_3,\
274   nds_n7_store_multiple_4,nds_n7_store_multiple_5, nds_n7_store_multiple_6,\
275   nds_n7_store_multiple_7,nds_n7_store_multiple_8, nds_n7_store_multiple_12"
276  "nds32_n7_load_to_ii_p"
277)
278
279;; LMW(N, N)
280;;   -> ALU, MOVD44_E, MUL, MAC_RaRb, DIV, BR, AADR_IN_MOP(1), ST_bi, ST_!bi_RI, SMW(N, 1)
281(define_bypass 2
282  "nds_n7_load_multiple_1,nds_n7_load_multiple_2, nds_n7_load_multiple_3,\
283   nds_n7_load_multiple_4,nds_n7_load_multiple_5, nds_n7_load_multiple_6,\
284   nds_n7_load_multiple_7,nds_n7_load_multiple_8, nds_n7_load_multiple_12"
285  "nds_n7_alu,\
286   nds_n7_mul_fast, nds_n7_mul_slow,\
287   nds_n7_mac_fast, nds_n7_mac_slow,\
288   nds_n7_div,\
289   nds_n7_branch,\
290   nds_n7_load, nds_n7_store,\
291   nds_n7_load_multiple_1,nds_n7_load_multiple_2, nds_n7_load_multiple_3,\
292   nds_n7_load_multiple_4,nds_n7_load_multiple_5, nds_n7_load_multiple_6,\
293   nds_n7_load_multiple_7,nds_n7_load_multiple_8, nds_n7_load_multiple_12,\
294   nds_n7_store_multiple_1,nds_n7_store_multiple_2, nds_n7_store_multiple_3,\
295   nds_n7_store_multiple_4,nds_n7_store_multiple_5, nds_n7_store_multiple_6,\
296   nds_n7_store_multiple_7,nds_n7_store_multiple_8, nds_n7_store_multiple_12"
297  "nds32_n7_last_load_to_ii_p"
298)
299