1;; Pipeline descriptions of Andes NDS32 cpu for GNU compiler
2;; Copyright (C) 2012-2021 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 E8 pipeline settings.
24;; ------------------------------------------------------------------------
25
26(define_automaton "nds32_e8_machine")
27
28;; ------------------------------------------------------------------------
29;; Pipeline Stages
30;; ------------------------------------------------------------------------
31;; IF - Instruction Fetch
32;; II - Instruction Issue / Address Generation
33;; EX - Instruction Execution
34;; EXD - Psuedo Stage / Load Data Completion
35
36(define_cpu_unit "e8_ii" "nds32_e8_machine")
37(define_cpu_unit "e8_ex" "nds32_e8_machine")
38
39(define_insn_reservation "nds_e8_unknown" 1
40  (and (eq_attr "type" "unknown")
41       (eq_attr "pipeline_model" "e8"))
42  "e8_ii, e8_ex")
43
44(define_insn_reservation "nds_e8_misc" 1
45  (and (eq_attr "type" "misc")
46       (eq_attr "pipeline_model" "e8"))
47  "e8_ii, e8_ex")
48
49(define_insn_reservation "nds_e8_alu" 1
50  (and (eq_attr "type" "alu")
51       (eq_attr "pipeline_model" "e8"))
52  "e8_ii, e8_ex")
53
54(define_insn_reservation "nds_e8_load" 1
55  (and (match_test "nds32::load_single_p (insn)")
56       (eq_attr "pipeline_model" "e8"))
57  "e8_ii, e8_ex")
58
59(define_insn_reservation "nds_e8_store" 1
60  (and (match_test "nds32::store_single_p (insn)")
61       (eq_attr "pipeline_model" "e8"))
62  "e8_ii, e8_ex")
63
64(define_insn_reservation "nds_e8_load_multiple_1" 1
65  (and (and (eq_attr "type" "load_multiple")
66	    (eq_attr "combo" "1"))
67       (eq_attr "pipeline_model" "e8"))
68  "e8_ii, e8_ex")
69
70(define_insn_reservation "nds_e8_load_multiple_2" 1
71  (and (ior (and (eq_attr "type" "load_multiple")
72		 (eq_attr "combo" "2"))
73	    (match_test "nds32::load_double_p (insn)"))
74       (eq_attr "pipeline_model" "e8"))
75  "e8_ii, e8_ii+e8_ex, e8_ex")
76
77(define_insn_reservation "nds_e8_load_multiple_3" 1
78  (and (and (eq_attr "type" "load_multiple")
79	    (eq_attr "combo" "3"))
80       (eq_attr "pipeline_model" "e8"))
81  "e8_ii, (e8_ii+e8_ex)*2, e8_ex")
82
83(define_insn_reservation "nds_e8_load_multiple_4" 1
84  (and (and (eq_attr "type" "load_multiple")
85	    (eq_attr "combo" "4"))
86       (eq_attr "pipeline_model" "e8"))
87  "e8_ii, (e8_ii+e8_ex)*3, e8_ex")
88
89(define_insn_reservation "nds_e8_load_multiple_5" 1
90  (and (and (eq_attr "type" "load_multiple")
91	    (eq_attr "combo" "5"))
92       (eq_attr "pipeline_model" "e8"))
93  "e8_ii, (e8_ii+e8_ex)*4, e8_ex")
94
95(define_insn_reservation "nds_e8_load_multiple_6" 1
96  (and (and (eq_attr "type" "load_multiple")
97	    (eq_attr "combo" "6"))
98       (eq_attr "pipeline_model" "e8"))
99  "e8_ii, (e8_ii+e8_ex)*5, e8_ex")
100
101(define_insn_reservation "nds_e8_load_multiple_7" 1
102  (and (and (eq_attr "type" "load_multiple")
103	    (eq_attr "combo" "7"))
104       (eq_attr "pipeline_model" "e8"))
105  "e8_ii, (e8_ii+e8_ex)*6, e8_ex")
106
107(define_insn_reservation "nds_e8_load_multiple_8" 1
108  (and (and (eq_attr "type" "load_multiple")
109	    (eq_attr "combo" "8"))
110       (eq_attr "pipeline_model" "e8"))
111  "e8_ii, (e8_ii+e8_ex)*7, e8_ex")
112
113(define_insn_reservation "nds_e8_load_multiple_12" 1
114  (and (and (eq_attr "type" "load_multiple")
115	    (eq_attr "combo" "12"))
116       (eq_attr "pipeline_model" "e8"))
117  "e8_ii, (e8_ii+e8_ex)*11, e8_ex")
118
119(define_insn_reservation "nds_e8_store_multiple_1" 1
120  (and (and (eq_attr "type" "store_multiple")
121	    (eq_attr "combo" "1"))
122       (eq_attr "pipeline_model" "e8"))
123  "e8_ii, e8_ex")
124
125(define_insn_reservation "nds_e8_store_multiple_2" 1
126  (and (ior (and (eq_attr "type" "store_multiple")
127		 (eq_attr "combo" "2"))
128	    (match_test "nds32::store_double_p (insn)"))
129       (eq_attr "pipeline_model" "e8"))
130  "e8_ii, e8_ii+e8_ex, e8_ex")
131
132(define_insn_reservation "nds_e8_store_multiple_3" 1
133  (and (and (eq_attr "type" "store_multiple")
134	    (eq_attr "combo" "3"))
135       (eq_attr "pipeline_model" "e8"))
136  "e8_ii, (e8_ii+e8_ex)*2, e8_ex")
137
138(define_insn_reservation "nds_e8_store_multiple_4" 1
139  (and (and (eq_attr "type" "store_multiple")
140	    (eq_attr "combo" "4"))
141       (eq_attr "pipeline_model" "e8"))
142  "e8_ii, (e8_ii+e8_ex)*3, e8_ex")
143
144(define_insn_reservation "nds_e8_store_multiple_5" 1
145  (and (and (eq_attr "type" "store_multiple")
146	    (eq_attr "combo" "5"))
147       (eq_attr "pipeline_model" "e8"))
148  "e8_ii, (e8_ii+e8_ex)*4, e8_ex")
149
150(define_insn_reservation "nds_e8_store_multiple_6" 1
151  (and (and (eq_attr "type" "store_multiple")
152	    (eq_attr "combo" "6"))
153       (eq_attr "pipeline_model" "e8"))
154  "e8_ii, (e8_ii+e8_ex)*5, e8_ex")
155
156(define_insn_reservation "nds_e8_store_multiple_7" 1
157  (and (and (eq_attr "type" "store_multiple")
158	    (eq_attr "combo" "7"))
159       (eq_attr "pipeline_model" "e8"))
160  "e8_ii, (e8_ii+e8_ex)*6, e8_ex")
161
162(define_insn_reservation "nds_e8_store_multiple_8" 1
163  (and (and (eq_attr "type" "store_multiple")
164	    (eq_attr "combo" "8"))
165       (eq_attr "pipeline_model" "e8"))
166  "e8_ii, (e8_ii+e8_ex)*7, e8_ex")
167
168(define_insn_reservation "nds_e8_store_multiple_12" 1
169  (and (and (eq_attr "type" "store_multiple")
170	    (eq_attr "combo" "12"))
171       (eq_attr "pipeline_model" "e8"))
172  "e8_ii, (e8_ii+e8_ex)*11, e8_ex")
173
174(define_insn_reservation "nds_e8_mul_fast" 1
175  (and (match_test "nds32_mul_config != MUL_TYPE_SLOW")
176       (and (eq_attr "type" "mul")
177	    (eq_attr "pipeline_model" "e8")))
178  "e8_ii, e8_ex")
179
180(define_insn_reservation "nds_e8_mul_slow" 1
181  (and (match_test "nds32_mul_config == MUL_TYPE_SLOW")
182       (and (eq_attr "type" "mul")
183	    (eq_attr "pipeline_model" "e8")))
184  "e8_ii, e8_ex*16")
185
186(define_insn_reservation "nds_e8_mac_fast" 1
187  (and (match_test "nds32_mul_config != MUL_TYPE_SLOW")
188       (and (eq_attr "type" "mac")
189	    (eq_attr "pipeline_model" "e8")))
190  "e8_ii, e8_ii+e8_ex, e8_ex")
191
192(define_insn_reservation "nds_e8_mac_slow" 1
193  (and (match_test "nds32_mul_config == MUL_TYPE_SLOW")
194       (and (eq_attr "type" "mac")
195	    (eq_attr "pipeline_model" "e8")))
196  "e8_ii, (e8_ii+e8_ex)*16, e8_ex")
197
198(define_insn_reservation "nds_e8_div" 1
199  (and (eq_attr "type" "div")
200       (eq_attr "pipeline_model" "e8"))
201  "e8_ii, (e8_ii+e8_ex)*36, e8_ex")
202
203(define_insn_reservation "nds_e8_branch" 1
204  (and (eq_attr "type" "branch")
205       (eq_attr "pipeline_model" "e8"))
206  "e8_ii, e8_ex")
207
208;; ------------------------------------------------------------------------
209;; Comment Notations and Bypass Rules
210;; ------------------------------------------------------------------------
211;; Producers (LHS)
212;;   LD
213;;     Load data from the memory and produce the loaded data. The result is
214;;     ready at EXD.
215;;   LMW(N, M)
216;;     There are N micro-operations within an instruction that loads multiple
217;;     words. The result produced by the M-th micro-operation is sent to
218;;     consumers. The result is ready at EXD.
219;;   ADDR_OUT
220;;     Most load/store instructions can produce an address output if updating
221;;     the base register is required. The result is ready at EX, which is
222;;     produced by ALU.
223;;   ALU, MOVD44, MUL, MAC
224;;     The result is ready at EX.
225;;   DIV_Rs
226;;     A division instruction saves the quotient result to Rt and saves the
227;;     remainder result to Rs. The instruction is separated into two micro-
228;;     operations. The first micro-operation writes to Rt, and the seconde
229;;     one writes to Rs. Each of the results is ready at EX.
230;;
231;; Consumers (RHS)
232;;   ALU, MUL, DIV
233;;     Require operands at EX.
234;;   ADDR_IN_MOP(N)
235;;      N denotes the address input is required by the N-th micro-operation.
236;;      Such operand is required at II.
237;;   ST
238;;     A store instruction requires its data at EX.
239;;   SMW(N, M)
240;;     There are N micro-operations within an instruction that stores multiple
241;;     words. Each M-th micro-operation requires its data at EX.
242;;   BR_COND
243;;     If a branch instruction is conditional, its input data is required at EX.
244
245;; LD -> ADDR_IN_MOP(1)
246(define_bypass 2
247  "nds_e8_load"
248  "nds_e8_branch,\
249   nds_e8_load, nds_e8_store,\
250   nds_e8_load_multiple_1,nds_e8_load_multiple_2, nds_e8_load_multiple_3,\
251   nds_e8_load_multiple_4,nds_e8_load_multiple_5, nds_e8_load_multiple_6,\
252   nds_e8_load_multiple_7,nds_e8_load_multiple_8, nds_e8_load_multiple_12,\
253   nds_e8_store_multiple_1,nds_e8_store_multiple_2, nds_e8_store_multiple_3,\
254   nds_e8_store_multiple_4,nds_e8_store_multiple_5, nds_e8_store_multiple_6,\
255   nds_e8_store_multiple_7,nds_e8_store_multiple_8, nds_e8_store_multiple_12"
256  "nds32_e8_load_to_ii_p"
257)
258
259;; LD -> ALU, MUL, MAC, DIV, BR_COND, ST, SMW(N, 1)
260(define_bypass 2
261  "nds_e8_load"
262  "nds_e8_alu,
263   nds_e8_mul_fast, nds_e8_mul_slow,\
264   nds_e8_mac_fast, nds_e8_mac_slow,\
265   nds_e8_div,\
266   nds_e8_branch,\
267   nds_e8_store,\
268   nds_e8_store_multiple_1,nds_e8_store_multiple_2, nds_e8_store_multiple_3,\
269   nds_e8_store_multiple_4,nds_e8_store_multiple_5, nds_e8_store_multiple_6,\
270   nds_e8_store_multiple_7,nds_e8_store_multiple_8, nds_e8_store_multiple_12"
271  "nds32_e8_load_to_ex_p"
272)
273
274;; ALU, MOVD44, MUL, MAC, DIV_Rs, LD_bi, ADDR_OUT -> ADDR_IN_MOP(1)
275(define_bypass 2
276  "nds_e8_alu,
277   nds_e8_mul_fast, nds_e8_mul_slow,\
278   nds_e8_mac_fast, nds_e8_mac_slow,\
279   nds_e8_div,\
280   nds_e8_load, nds_e8_store,\
281   nds_e8_load_multiple_1,nds_e8_load_multiple_2, nds_e8_load_multiple_3,\
282   nds_e8_load_multiple_4,nds_e8_load_multiple_5, nds_e8_load_multiple_6,\
283   nds_e8_load_multiple_7,nds_e8_load_multiple_8, nds_e8_load_multiple_12,\
284   nds_e8_store_multiple_1,nds_e8_store_multiple_2, nds_e8_store_multiple_3,\
285   nds_e8_store_multiple_4,nds_e8_store_multiple_5, nds_e8_store_multiple_6,\
286   nds_e8_store_multiple_7,nds_e8_store_multiple_8, nds_e8_store_multiple_12"
287  "nds_e8_branch,\
288   nds_e8_load, nds_e8_store,\
289   nds_e8_load_multiple_1,nds_e8_load_multiple_2, nds_e8_load_multiple_3,\
290   nds_e8_load_multiple_4,nds_e8_load_multiple_5, nds_e8_load_multiple_6,\
291   nds_e8_load_multiple_7,nds_e8_load_multiple_8, nds_e8_load_multiple_12,\
292   nds_e8_store_multiple_1,nds_e8_store_multiple_2, nds_e8_store_multiple_3,\
293   nds_e8_store_multiple_4,nds_e8_store_multiple_5, nds_e8_store_multiple_6,\
294   nds_e8_store_multiple_7,nds_e8_store_multiple_8, nds_e8_store_multiple_12"
295  "nds32_e8_ex_to_ii_p"
296)
297
298;; LMW(N, N) -> ADDR_IN_MOP(1)
299(define_bypass 2
300  "nds_e8_load_multiple_1,nds_e8_load_multiple_2, nds_e8_load_multiple_3,\
301   nds_e8_load_multiple_4,nds_e8_load_multiple_5, nds_e8_load_multiple_6,\
302   nds_e8_load_multiple_7,nds_e8_load_multiple_8, nds_e8_load_multiple_12"
303  "nds_e8_branch,\
304   nds_e8_load, nds_e8_store,\
305   nds_e8_load_multiple_1,nds_e8_load_multiple_2, nds_e8_load_multiple_3,\
306   nds_e8_load_multiple_4,nds_e8_load_multiple_5, nds_e8_load_multiple_6,\
307   nds_e8_load_multiple_7,nds_e8_load_multiple_8, nds_e8_load_multiple_12,\
308   nds_e8_store_multiple_1,nds_e8_store_multiple_2, nds_e8_store_multiple_3,\
309   nds_e8_store_multiple_4,nds_e8_store_multiple_5, nds_e8_store_multiple_6,\
310   nds_e8_store_multiple_7,nds_e8_store_multiple_8, nds_e8_store_multiple_12"
311  "nds32_e8_last_load_to_ii_p"
312)
313
314;; LMW(N, N) -> ALU, MUL, MAC, DIV, BR_COND, ST, SMW(N, 1)
315(define_bypass 2
316  "nds_e8_load_multiple_1,nds_e8_load_multiple_2, nds_e8_load_multiple_3,\
317   nds_e8_load_multiple_4,nds_e8_load_multiple_5, nds_e8_load_multiple_6,\
318   nds_e8_load_multiple_7,nds_e8_load_multiple_8, nds_e8_load_multiple_12"
319  "nds_e8_alu,
320   nds_e8_mul_fast, nds_e8_mul_slow,\
321   nds_e8_mac_fast, nds_e8_mac_slow,\
322   nds_e8_div,\
323   nds_e8_branch,\
324   nds_e8_store,\
325   nds_e8_store_multiple_1,nds_e8_store_multiple_2, nds_e8_store_multiple_3,\
326   nds_e8_store_multiple_4,nds_e8_store_multiple_5, nds_e8_store_multiple_6,\
327   nds_e8_store_multiple_7,nds_e8_store_multiple_8, nds_e8_store_multiple_12"
328  "nds32_e8_last_load_to_ex_p"
329)
330