]>
Commit | Line | Data |
---|---|---|
58684fa0 MK |
1 | ;; Pipeline model for ST Microelectronics Loongson-2E/2F cores. |
2 | ||
7adcbafe | 3 | ;; Copyright (C) 2008-2022 Free Software Foundation, Inc. |
58684fa0 MK |
4 | ;; Contributed by CodeSourcery. |
5 | ;; | |
6 | ;; GCC is free software; you can redistribute it and/or modify | |
7 | ;; it under the terms of the GNU General Public License as published by | |
8 | ;; the Free Software Foundation; either version 3, or (at your option) | |
9 | ;; any later version. | |
10 | ;; | |
11 | ;; GCC is distributed in the hope that it will be useful, | |
12 | ;; but WITHOUT ANY WARRANTY; without even the implied warranty of | |
13 | ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
14 | ;; GNU General Public License for more details. | |
15 | ;; | |
16 | ;; You should have received a copy of the GNU General Public License | |
17 | ;; along with GCC; see the file COPYING3. If not see | |
18 | ;; <http://www.gnu.org/licenses/>. | |
19 | ||
24609606 RS |
20 | (define_c_enum "unspec" [ |
21 | UNSPEC_LOONGSON_ALU1_TURN_ENABLED_INSN | |
22 | UNSPEC_LOONGSON_ALU2_TURN_ENABLED_INSN | |
23 | UNSPEC_LOONGSON_FALU1_TURN_ENABLED_INSN | |
24 | UNSPEC_LOONGSON_FALU2_TURN_ENABLED_INSN | |
25 | ]) | |
26 | ||
58684fa0 MK |
27 | ;; Automaton for integer instructions. |
28 | (define_automaton "ls2_alu") | |
29 | ||
30 | ;; ALU1 and ALU2. | |
31 | ;; We need to query these units to adjust round-robin counter. | |
32 | (define_query_cpu_unit "ls2_alu1_core,ls2_alu2_core" "ls2_alu") | |
33 | ||
34 | ;; Pseudo units to help modeling of ALU1/2 round-robin dispatch strategy. | |
35 | (define_cpu_unit "ls2_alu1_turn,ls2_alu2_turn" "ls2_alu") | |
36 | ||
37 | ;; Pseudo units to enable/disable ls2_alu[12]_turn units. | |
38 | ;; ls2_alu[12]_turn unit can be subscribed only after ls2_alu[12]_turn_enabled | |
39 | ;; unit is subscribed. | |
40 | (define_cpu_unit "ls2_alu1_turn_enabled,ls2_alu2_turn_enabled" "ls2_alu") | |
41 | (presence_set "ls2_alu1_turn" "ls2_alu1_turn_enabled") | |
42 | (presence_set "ls2_alu2_turn" "ls2_alu2_turn_enabled") | |
43 | ||
44 | ;; Reservations for ALU1 (ALU2) instructions. | |
45 | ;; Instruction goes to ALU1 (ALU2) and makes next ALU1/2 instruction to | |
46 | ;; be dispatched to ALU2 (ALU1). | |
47 | (define_reservation "ls2_alu1" | |
48 | "(ls2_alu1_core+ls2_alu2_turn_enabled)|ls2_alu1_core") | |
49 | (define_reservation "ls2_alu2" | |
50 | "(ls2_alu2_core+ls2_alu1_turn_enabled)|ls2_alu2_core") | |
51 | ||
52 | ;; Reservation for ALU1/2 instructions. | |
53 | ;; Instruction will go to ALU1 iff ls2_alu1_turn_enabled is subscribed and | |
54 | ;; switch the turn to ALU2 by subscribing ls2_alu2_turn_enabled. | |
55 | ;; Or to ALU2 otherwise. | |
56 | (define_reservation "ls2_alu" | |
57 | "(ls2_alu1_core+ls2_alu1_turn+ls2_alu2_turn_enabled) | |
58 | |(ls2_alu1_core+ls2_alu1_turn) | |
59 | |(ls2_alu2_core+ls2_alu2_turn+ls2_alu1_turn_enabled) | |
60 | |(ls2_alu2_core+ls2_alu2_turn)") | |
61 | ||
62 | ;; Automaton for floating-point instructions. | |
63 | (define_automaton "ls2_falu") | |
64 | ||
65 | ;; FALU1 and FALU2. | |
66 | ;; We need to query these units to adjust round-robin counter. | |
67 | (define_query_cpu_unit "ls2_falu1_core,ls2_falu2_core" "ls2_falu") | |
68 | ||
69 | ;; Pseudo units to help modeling of FALU1/2 round-robin dispatch strategy. | |
70 | (define_cpu_unit "ls2_falu1_turn,ls2_falu2_turn" "ls2_falu") | |
71 | ||
72 | ;; Pseudo units to enable/disable ls2_falu[12]_turn units. | |
73 | ;; ls2_falu[12]_turn unit can be subscribed only after | |
74 | ;; ls2_falu[12]_turn_enabled unit is subscribed. | |
75 | (define_cpu_unit "ls2_falu1_turn_enabled,ls2_falu2_turn_enabled" "ls2_falu") | |
76 | (presence_set "ls2_falu1_turn" "ls2_falu1_turn_enabled") | |
77 | (presence_set "ls2_falu2_turn" "ls2_falu2_turn_enabled") | |
78 | ||
79 | ;; Reservations for FALU1 (FALU2) instructions. | |
80 | ;; Instruction goes to FALU1 (FALU2) and makes next FALU1/2 instruction to | |
81 | ;; be dispatched to FALU2 (FALU1). | |
82 | (define_reservation "ls2_falu1" | |
83 | "(ls2_falu1_core+ls2_falu2_turn_enabled)|ls2_falu1_core") | |
84 | (define_reservation "ls2_falu2" | |
85 | "(ls2_falu2_core+ls2_falu1_turn_enabled)|ls2_falu2_core") | |
86 | ||
87 | ;; Reservation for FALU1/2 instructions. | |
88 | ;; Instruction will go to FALU1 iff ls2_falu1_turn_enabled is subscribed and | |
89 | ;; switch the turn to FALU2 by subscribing ls2_falu2_turn_enabled. | |
90 | ;; Or to FALU2 otherwise. | |
91 | (define_reservation "ls2_falu" | |
92 | "(ls2_falu1+ls2_falu1_turn+ls2_falu2_turn_enabled) | |
93 | |(ls2_falu1+ls2_falu1_turn) | |
94 | |(ls2_falu2+ls2_falu2_turn+ls2_falu1_turn_enabled) | |
95 | |(ls2_falu2+ls2_falu2_turn)") | |
96 | ||
97 | ;; The following 4 instructions each subscribe one of | |
98 | ;; ls2_[f]alu{1,2}_turn_enabled units according to this attribute. | |
e53b6e56 | 99 | ;; These instructions are used in mips.cc: sched_ls2_dfa_post_advance_cycle. |
58684fa0 | 100 | |
3088716e | 101 | (define_attr "ls2_turn_type" "alu1,alu2,falu1,falu2,unknown,atomic,syncloop" |
58684fa0 MK |
102 | (const_string "unknown")) |
103 | ||
104 | ;; Subscribe ls2_alu1_turn_enabled. | |
105 | (define_insn "ls2_alu1_turn_enabled_insn" | |
106 | [(unspec [(const_int 0)] UNSPEC_LOONGSON_ALU1_TURN_ENABLED_INSN)] | |
107 | "TUNE_LOONGSON_2EF" | |
108 | { gcc_unreachable (); } | |
109 | [(set_attr "ls2_turn_type" "alu1")]) | |
110 | ||
111 | (define_insn_reservation "ls2_alu1_turn_enabled" 0 | |
112 | (eq_attr "ls2_turn_type" "alu1") | |
113 | "ls2_alu1_turn_enabled") | |
114 | ||
115 | ;; Subscribe ls2_alu2_turn_enabled. | |
116 | (define_insn "ls2_alu2_turn_enabled_insn" | |
117 | [(unspec [(const_int 0)] UNSPEC_LOONGSON_ALU2_TURN_ENABLED_INSN)] | |
118 | "TUNE_LOONGSON_2EF" | |
119 | { gcc_unreachable (); } | |
120 | [(set_attr "ls2_turn_type" "alu2")]) | |
121 | ||
122 | (define_insn_reservation "ls2_alu2_turn_enabled" 0 | |
123 | (eq_attr "ls2_turn_type" "alu2") | |
124 | "ls2_alu2_turn_enabled") | |
125 | ||
126 | ;; Subscribe ls2_falu1_turn_enabled. | |
127 | (define_insn "ls2_falu1_turn_enabled_insn" | |
128 | [(unspec [(const_int 0)] UNSPEC_LOONGSON_FALU1_TURN_ENABLED_INSN)] | |
129 | "TUNE_LOONGSON_2EF" | |
130 | { gcc_unreachable (); } | |
131 | [(set_attr "ls2_turn_type" "falu1")]) | |
132 | ||
133 | (define_insn_reservation "ls2_falu1_turn_enabled" 0 | |
134 | (eq_attr "ls2_turn_type" "falu1") | |
135 | "ls2_falu1_turn_enabled") | |
136 | ||
137 | ;; Subscribe ls2_falu2_turn_enabled. | |
138 | (define_insn "ls2_falu2_turn_enabled_insn" | |
139 | [(unspec [(const_int 0)] UNSPEC_LOONGSON_FALU2_TURN_ENABLED_INSN)] | |
140 | "TUNE_LOONGSON_2EF" | |
141 | { gcc_unreachable (); } | |
142 | [(set_attr "ls2_turn_type" "falu2")]) | |
143 | ||
144 | (define_insn_reservation "ls2_falu2_turn_enabled" 0 | |
145 | (eq_attr "ls2_turn_type" "falu2") | |
146 | "ls2_falu2_turn_enabled") | |
147 | ||
148 | ;; Automaton for memory operations. | |
149 | (define_automaton "ls2_mem") | |
150 | ||
151 | ;; Memory unit. | |
152 | (define_query_cpu_unit "ls2_mem" "ls2_mem") | |
153 | ||
154 | ;; Reservation for integer instructions. | |
155 | (define_insn_reservation "ls2_alu" 2 | |
156 | (and (eq_attr "cpu" "loongson_2e,loongson_2f") | |
cb00489c RS |
157 | (eq_attr "type" "arith,condmove,const,logical,mfhi,mflo,move, |
158 | mthi,mtlo,nop,shift,signext,slt")) | |
58684fa0 MK |
159 | "ls2_alu") |
160 | ||
161 | ;; Reservation for branch instructions. | |
162 | (define_insn_reservation "ls2_branch" 2 | |
163 | (and (eq_attr "cpu" "loongson_2e,loongson_2f") | |
164 | (eq_attr "type" "branch,jump,call,trap")) | |
165 | "ls2_alu1") | |
166 | ||
167 | ;; Reservation for integer multiplication instructions. | |
168 | (define_insn_reservation "ls2_imult" 5 | |
169 | (and (eq_attr "cpu" "loongson_2e,loongson_2f") | |
1a0f175d | 170 | (eq_attr "type" "imul,imul3nc")) |
58684fa0 MK |
171 | "ls2_alu2,ls2_alu2_core") |
172 | ||
173 | ;; Reservation for integer division / remainder instructions. | |
174 | ;; These instructions use the SRT algorithm and hence take 2-38 cycles. | |
175 | (define_insn_reservation "ls2_idiv" 20 | |
176 | (and (eq_attr "cpu" "loongson_2e,loongson_2f") | |
1a0f175d | 177 | (eq_attr "type" "idiv,idiv3")) |
58684fa0 MK |
178 | "ls2_alu2,ls2_alu2_core*18") |
179 | ||
180 | ;; Reservation for memory load instructions. | |
181 | (define_insn_reservation "ls2_load" 5 | |
182 | (and (eq_attr "cpu" "loongson_2e,loongson_2f") | |
183 | (eq_attr "type" "load,fpload,mfc,mtc")) | |
184 | "ls2_mem") | |
185 | ||
1a0f175d RB |
186 | (define_insn_reservation "ls2_prefetch" 0 |
187 | (and (eq_attr "cpu" "loongson_2e,loongson_2f") | |
188 | (eq_attr "type" "prefetch,prefetchx")) | |
189 | "ls2_mem") | |
190 | ||
58684fa0 MK |
191 | ;; Reservation for memory store instructions. |
192 | ;; With stores we assume they don't alias with dependent loads. | |
193 | ;; Therefore we set the latency to zero. | |
194 | (define_insn_reservation "ls2_store" 0 | |
195 | (and (eq_attr "cpu" "loongson_2e,loongson_2f") | |
196 | (eq_attr "type" "store,fpstore")) | |
197 | "ls2_mem") | |
198 | ||
199 | ;; Reservation for floating-point instructions of latency 3. | |
200 | (define_insn_reservation "ls2_fp3" 3 | |
201 | (and (eq_attr "cpu" "loongson_2e,loongson_2f") | |
202 | (eq_attr "type" "fabs,fneg,fcmp,fmove")) | |
203 | "ls2_falu1") | |
204 | ||
205 | ;; Reservation for floating-point instructions of latency 5. | |
206 | (define_insn_reservation "ls2_fp5" 5 | |
207 | (and (eq_attr "cpu" "loongson_2e,loongson_2f") | |
208 | (eq_attr "type" "fcvt")) | |
209 | "ls2_falu1") | |
210 | ||
211 | ;; Reservation for floating-point instructions that can go | |
212 | ;; to either of FALU1/2 units. | |
213 | (define_insn_reservation "ls2_falu" 7 | |
214 | (and (eq_attr "cpu" "loongson_2e,loongson_2f") | |
215 | (eq_attr "type" "fadd,fmul,fmadd")) | |
216 | "ls2_falu") | |
217 | ||
218 | ;; Reservation for floating-point division / remainder instructions. | |
219 | ;; These instructions use the SRT algorithm and hence take a variable amount | |
220 | ;; of cycles: | |
221 | ;; div.s takes 5-11 cycles | |
222 | ;; div.d takes 5-18 cycles | |
223 | (define_insn_reservation "ls2_fdiv" 9 | |
224 | (and (eq_attr "cpu" "loongson_2e,loongson_2f") | |
225 | (eq_attr "type" "fdiv")) | |
226 | "ls2_falu2,ls2_falu2_core*7") | |
227 | ||
228 | ;; Reservation for floating-point sqrt instructions. | |
229 | ;; These instructions use the SRT algorithm and hence take a variable amount | |
230 | ;; of cycles: | |
231 | ;; sqrt.s takes 5-17 cycles | |
232 | ;; sqrt.d takes 5-32 cycles | |
233 | (define_insn_reservation "ls2_fsqrt" 15 | |
234 | (and (eq_attr "cpu" "loongson_2e,loongson_2f") | |
235 | (eq_attr "type" "fsqrt")) | |
236 | "ls2_falu2,ls2_falu2_core*13") | |
237 | ||
238 | ;; Two consecutive ALU instructions. | |
239 | (define_insn_reservation "ls2_multi" 4 | |
240 | (and (eq_attr "cpu" "loongson_2e,loongson_2f") | |
241 | (eq_attr "type" "multi")) | |
242 | "(ls2_alu1,ls2_alu2_core)|(ls2_alu2,ls2_alu1_core)") | |
243 | ||
244 | ;; Reservation for everything else. Normally, this reservation | |
245 | ;; will only be used to handle cases like compiling for non-loongson | |
246 | ;; CPUs with -mtune=loongson2?. | |
247 | ;; | |
248 | ;; This reservation depends upon the fact that DFA will check | |
249 | ;; reservations in the same order as they appear in the file. | |
250 | (define_insn_reservation "ls2_unknown" 1 | |
251 | (eq_attr "cpu" "loongson_2e,loongson_2f") | |
252 | "ls2_alu1_core+ls2_alu2_core+ls2_falu1_core+ls2_falu2_core+ls2_mem") |