Mercurial > hg > CbC > CbC_gcc
comparison gcc/config/nds32/nds32-pipelines-auxiliary.c @ 131:84e7813d76e9
gcc-8.2
author | mir3636 |
---|---|
date | Thu, 25 Oct 2018 07:37:49 +0900 |
parents | 04ced10e8804 |
children | 1830386684a0 |
comparison
equal
deleted
inserted
replaced
111:04ced10e8804 | 131:84e7813d76e9 |
---|---|
1 /* Auxiliary functions for pipeline descriptions pattern of Andes | 1 /* Auxiliary functions for pipeline descriptions pattern of Andes |
2 NDS32 cpu for GNU compiler | 2 NDS32 cpu for GNU compiler |
3 Copyright (C) 2012-2017 Free Software Foundation, Inc. | 3 Copyright (C) 2012-2018 Free Software Foundation, Inc. |
4 Contributed by Andes Technology Corporation. | 4 Contributed by Andes Technology Corporation. |
5 | 5 |
6 This file is part of GCC. | 6 This file is part of GCC. |
7 | 7 |
8 GCC is free software; you can redistribute it and/or modify it | 8 GCC is free software; you can redistribute it and/or modify it |
19 along with GCC; see the file COPYING3. If not see | 19 along with GCC; see the file COPYING3. If not see |
20 <http://www.gnu.org/licenses/>. */ | 20 <http://www.gnu.org/licenses/>. */ |
21 | 21 |
22 /* ------------------------------------------------------------------------ */ | 22 /* ------------------------------------------------------------------------ */ |
23 | 23 |
24 #define IN_TARGET_CODE 1 | |
25 | |
24 #include "config.h" | 26 #include "config.h" |
25 #include "system.h" | 27 #include "system.h" |
26 #include "coretypes.h" | 28 #include "coretypes.h" |
27 #include "backend.h" | 29 #include "backend.h" |
30 #include "rtl.h" | |
31 #include "insn-attr.h" | |
32 #include "insn-codes.h" | |
33 #include "target.h" | |
34 | |
35 #include "nds32-protos.h" | |
28 | 36 |
29 /* ------------------------------------------------------------------------ */ | 37 /* ------------------------------------------------------------------------ */ |
30 | 38 |
31 /* This file is prepared for future implementation of precise | 39 namespace nds32 { |
32 pipeline description for nds32 target. */ | 40 namespace scheduling { |
41 | |
42 /* Classify the memory access direction. It's unknown if the offset register | |
43 is not a constant value. */ | |
44 enum memory_access_direction | |
45 { | |
46 MEM_ACCESS_DIR_POS, | |
47 MEM_ACCESS_DIR_NEG, | |
48 MEM_ACCESS_DIR_UNKNOWN | |
49 }; | |
50 | |
51 /* A safe wrapper to the function reg_overlap_mentioned_p (). */ | |
52 bool | |
53 reg_overlap_p (rtx x, rtx in) | |
54 { | |
55 if (x == NULL_RTX || in == NULL_RTX) | |
56 return false; | |
57 | |
58 return static_cast <bool> (reg_overlap_mentioned_p (x, in)); | |
59 } | |
60 | |
61 | |
62 /* Determine the memory access direction of a load/store insn. */ | |
63 memory_access_direction | |
64 determine_access_direction (rtx_insn *insn) | |
65 { | |
66 int post_update_rtx_index; | |
67 rtx plus_rtx; | |
68 rtx mem_rtx; | |
69 rtx offset_rtx; | |
70 | |
71 switch (get_attr_type (insn)) | |
72 { | |
73 case TYPE_LOAD_MULTIPLE: | |
74 gcc_assert (parallel_elements (insn) >= 2); | |
75 | |
76 post_update_rtx_index = find_post_update_rtx (insn); | |
77 if (post_update_rtx_index != -1) | |
78 plus_rtx = SET_SRC (parallel_element (insn, post_update_rtx_index)); | |
79 else | |
80 { | |
81 /* (parallel | |
82 [(set (reg) (mem (reg))) : index 0 | |
83 (set (reg) (mem (plus (reg) (...)))) : index 1 | |
84 ...]) */ | |
85 mem_rtx = SET_SRC (parallel_element (insn, 1)); | |
86 if (GET_CODE (mem_rtx) == UNSPEC) | |
87 mem_rtx = XVECEXP (mem_rtx, 0, 0); | |
88 gcc_assert (MEM_P (mem_rtx)); | |
89 plus_rtx = XEXP (mem_rtx, 0); | |
90 } | |
91 break; | |
92 | |
93 case TYPE_STORE_MULTIPLE: | |
94 gcc_assert (parallel_elements (insn) >= 2); | |
95 | |
96 post_update_rtx_index = find_post_update_rtx (insn); | |
97 if (post_update_rtx_index != -1) | |
98 plus_rtx = SET_SRC (parallel_element (insn, post_update_rtx_index)); | |
99 else | |
100 { | |
101 /* (parallel | |
102 [(set (mem (reg)) (reg)) : index 0 | |
103 (set (mem (plus (reg) (...))) (reg)) : index 1 | |
104 ...]) */ | |
105 mem_rtx = SET_DEST (parallel_element (insn, 1)); | |
106 if (GET_CODE (mem_rtx) == UNSPEC) | |
107 mem_rtx = XVECEXP (mem_rtx, 0, 0); | |
108 gcc_assert (MEM_P (mem_rtx)); | |
109 plus_rtx = XEXP (mem_rtx, 0); | |
110 } | |
111 break; | |
112 | |
113 case TYPE_LOAD: | |
114 case TYPE_STORE: | |
115 mem_rtx = extract_mem_rtx (insn); | |
116 | |
117 switch (GET_CODE (XEXP (mem_rtx, 0))) | |
118 { | |
119 case POST_INC: | |
120 /* (mem (post_inc (...))) */ | |
121 return MEM_ACCESS_DIR_POS; | |
122 | |
123 case POST_DEC: | |
124 /* (mem (post_dec (...))) */ | |
125 return MEM_ACCESS_DIR_NEG; | |
126 | |
127 case PLUS: | |
128 /* (mem (plus (reg) (...))) */ | |
129 plus_rtx = XEXP (mem_rtx, 0); | |
130 break; | |
131 | |
132 case POST_MODIFY: | |
133 /* (mem (post_modify (reg) (plus (reg) (...)))) */ | |
134 plus_rtx = XEXP (XEXP (mem_rtx, 0), 1); | |
135 break; | |
136 | |
137 default: | |
138 gcc_unreachable (); | |
139 } | |
140 break; | |
141 | |
142 default: | |
143 gcc_unreachable (); | |
144 } | |
145 | |
146 gcc_assert (GET_CODE (plus_rtx) == PLUS); | |
147 | |
148 offset_rtx = XEXP (plus_rtx, 1); | |
149 if (GET_CODE (offset_rtx) == CONST_INT) | |
150 { | |
151 if (INTVAL (offset_rtx) < 0) | |
152 return MEM_ACCESS_DIR_NEG; | |
153 else | |
154 return MEM_ACCESS_DIR_POS; | |
155 } | |
156 | |
157 return MEM_ACCESS_DIR_UNKNOWN; | |
158 } | |
159 | |
160 /* Return the nth load/store operation in the real micro-operation | |
161 accessing order. */ | |
162 rtx | |
163 extract_nth_access_rtx (rtx_insn *insn, int n) | |
164 { | |
165 int n_elems = parallel_elements (insn); | |
166 int post_update_rtx_index = find_post_update_rtx (insn); | |
167 memory_access_direction direction = determine_access_direction (insn); | |
168 | |
169 gcc_assert (direction != MEM_ACCESS_DIR_UNKNOWN); | |
170 | |
171 /* Reverse the order if the direction negative. */ | |
172 if (direction == MEM_ACCESS_DIR_NEG) | |
173 n = -1 * n - 1; | |
174 | |
175 if (post_update_rtx_index != -1) | |
176 { | |
177 if (n >= 0 && post_update_rtx_index <= n) | |
178 ++n; | |
179 else if (n < 0 && post_update_rtx_index >= n + n_elems) | |
180 --n; | |
181 } | |
182 | |
183 return parallel_element (insn, n); | |
184 } | |
185 | |
186 /* Returns the register operated by the nth load/store operation in the real | |
187 micro-operation accessing order. This function assumes INSN must be a | |
188 multiple-word load/store insn. */ | |
189 rtx | |
190 extract_nth_lmsw_access_reg (rtx_insn *insn, int n) | |
191 { | |
192 rtx nth_rtx = extract_nth_access_rtx (insn, n); | |
193 | |
194 if (nth_rtx == NULL_RTX) | |
195 return NULL_RTX; | |
196 | |
197 switch (get_attr_type (insn)) | |
198 { | |
199 case TYPE_LOAD_MULTIPLE: | |
200 return SET_DEST (nth_rtx); | |
201 | |
202 case TYPE_STORE_MULTIPLE: | |
203 return SET_SRC (nth_rtx); | |
204 | |
205 default: | |
206 gcc_unreachable (); | |
207 } | |
208 } | |
209 | |
210 /* Returns the register operated by the nth load/store operation in the real | |
211 micro-operation accessing order. This function assumes INSN must be a | |
212 double-word load/store insn. */ | |
213 rtx | |
214 extract_nth_ls2_access_reg (rtx_insn *insn, int n) | |
215 { | |
216 rtx reg; | |
217 machine_mode mode; | |
218 | |
219 if (post_update_insn_p (insn)) | |
220 { | |
221 memory_access_direction direction = determine_access_direction (insn); | |
222 gcc_assert (direction != MEM_ACCESS_DIR_UNKNOWN); | |
223 | |
224 /* Reverse the order if the direction negative. */ | |
225 if (direction == MEM_ACCESS_DIR_NEG) | |
226 n = -1 * n - 1; | |
227 } | |
228 | |
229 /* Handle the out-of-range case. */ | |
230 if (n < -2 || n > 1) | |
231 return NULL_RTX; | |
232 | |
233 /* Convert the index to a positive one. */ | |
234 if (n < 0) | |
235 n = 2 + n; | |
236 | |
237 switch (get_attr_type (insn)) | |
238 { | |
239 case TYPE_LOAD: | |
240 reg = SET_DEST (PATTERN (insn)); | |
241 break; | |
242 | |
243 case TYPE_STORE: | |
244 reg = SET_SRC (PATTERN (insn)); | |
245 break; | |
246 | |
247 default: | |
248 gcc_unreachable (); | |
249 } | |
250 | |
251 gcc_assert (REG_P (reg) || GET_CODE (reg) == SUBREG); | |
252 | |
253 switch (GET_MODE (reg)) | |
254 { | |
255 case E_DImode: | |
256 mode = SImode; | |
257 break; | |
258 | |
259 case E_DFmode: | |
260 mode = SFmode; | |
261 break; | |
262 | |
263 default: | |
264 gcc_unreachable (); | |
265 } | |
266 | |
267 if (n == 0) | |
268 return gen_lowpart (mode, reg); | |
269 else | |
270 return gen_highpart (mode, reg); | |
271 } | |
272 | |
273 /* Returns the register operated by the nth load/store operation in the real | |
274 micro-operation accessing order. */ | |
275 rtx | |
276 extract_nth_access_reg (rtx_insn *insn, int index) | |
277 { | |
278 switch (GET_CODE (PATTERN (insn))) | |
279 { | |
280 case PARALLEL: | |
281 return extract_nth_lmsw_access_reg (insn, index); | |
282 | |
283 case SET: | |
284 return extract_nth_ls2_access_reg (insn, index); | |
285 | |
286 default: | |
287 gcc_unreachable (); | |
288 } | |
289 } | |
290 | |
291 /* Determine if the latency is occured when the consumer PBSADA_INSN uses the | |
292 value of DEF_REG in its Ra or Rb fields. */ | |
293 bool | |
294 pbsada_insn_ra_rb_dep_reg_p (rtx pbsada_insn, rtx def_reg) | |
295 { | |
296 rtx unspec_rtx = SET_SRC (PATTERN (pbsada_insn)); | |
297 gcc_assert (GET_CODE (unspec_rtx) == UNSPEC); | |
298 | |
299 rtx pbsada_ra = XVECEXP (unspec_rtx, 0, 0); | |
300 rtx pbsada_rb = XVECEXP (unspec_rtx, 0, 1); | |
301 | |
302 if (rtx_equal_p (def_reg, pbsada_ra) | |
303 || rtx_equal_p (def_reg, pbsada_rb)) | |
304 return true; | |
305 | |
306 return false; | |
307 } | |
308 | |
309 /* Determine if the latency is occured when the consumer PBSADA_INSN uses the | |
310 value of DEF_REG in its Rt field. */ | |
311 bool | |
312 pbsada_insn_rt_dep_reg_p (rtx pbsada_insn, rtx def_reg) | |
313 { | |
314 rtx pbsada_rt = SET_DEST (PATTERN (pbsada_insn)); | |
315 | |
316 if (rtx_equal_p (def_reg, pbsada_rt)) | |
317 return true; | |
318 | |
319 return false; | |
320 } | |
321 | |
322 /* Check if INSN is a movd44 insn consuming DEF_REG. */ | |
323 bool | |
324 movd44_even_dep_p (rtx_insn *insn, rtx def_reg) | |
325 { | |
326 if (!movd44_insn_p (insn)) | |
327 return false; | |
328 | |
329 rtx use_rtx = SET_SRC (PATTERN (insn)); | |
330 | |
331 if (REG_P (def_reg)) | |
332 { | |
333 return rtx_equal_p (def_reg, use_rtx); | |
334 } | |
335 else if (GET_CODE (def_reg) == SUBREG | |
336 && GET_MODE (def_reg) == SImode | |
337 && rtx_equal_p (SUBREG_REG (def_reg), use_rtx)) | |
338 { | |
339 if (TARGET_BIG_ENDIAN && SUBREG_BYTE (def_reg) == 4) | |
340 return true; | |
341 | |
342 if (!TARGET_BIG_ENDIAN && SUBREG_BYTE (def_reg) == 0) | |
343 return true; | |
344 | |
345 return false; | |
346 } | |
347 | |
348 return false; | |
349 } | |
350 | |
351 /* Check if INSN is a wext insn consuming DEF_REG. */ | |
352 bool | |
353 wext_odd_dep_p (rtx insn, rtx def_reg) | |
354 { | |
355 rtx shift_rtx = XEXP (SET_SRC (PATTERN (insn)), 0); | |
356 rtx use_reg = XEXP (shift_rtx, 0); | |
357 rtx pos_rtx = XEXP (shift_rtx, 1); | |
358 | |
359 if (REG_P (pos_rtx) && reg_overlap_p (def_reg, pos_rtx)) | |
360 return true; | |
361 | |
362 if (GET_MODE (def_reg) == DImode) | |
363 return reg_overlap_p (def_reg, use_reg); | |
364 | |
365 gcc_assert (REG_P (def_reg) || GET_CODE (def_reg) == SUBREG); | |
366 gcc_assert (REG_P (use_reg)); | |
367 | |
368 if (REG_P (def_reg)) | |
369 { | |
370 if (!TARGET_BIG_ENDIAN) | |
371 return REGNO (def_reg) == REGNO (use_reg) + 1; | |
372 else | |
373 return REGNO (def_reg) == REGNO (use_reg); | |
374 } | |
375 | |
376 if (GET_CODE (def_reg) == SUBREG) | |
377 { | |
378 if (!reg_overlap_p (def_reg, use_reg)) | |
379 return false; | |
380 | |
381 if (!TARGET_BIG_ENDIAN) | |
382 return SUBREG_BYTE (def_reg) == 4; | |
383 else | |
384 return SUBREG_BYTE (def_reg) == 0; | |
385 } | |
386 | |
387 return false; | |
388 } | |
389 | |
390 /* Check if INSN is a bpick insn consuming DEF_REG. */ | |
391 bool | |
392 bpick_ra_rb_dep_p (rtx insn, rtx def_reg) | |
393 { | |
394 rtx ior_rtx = SET_SRC (PATTERN (insn)); | |
395 rtx and1_rtx = XEXP (ior_rtx, 0); | |
396 rtx and2_rtx = XEXP (ior_rtx, 1); | |
397 rtx reg1_0 = XEXP (and1_rtx, 0); | |
398 rtx reg1_1 = XEXP (and1_rtx, 1); | |
399 rtx reg2_0 = XEXP (and2_rtx, 0); | |
400 rtx reg2_1 = XEXP (and2_rtx, 1); | |
401 | |
402 if (GET_CODE (reg1_0) == NOT) | |
403 { | |
404 if (rtx_equal_p (reg1_0, reg2_0)) | |
405 return reg_overlap_p (def_reg, reg1_1) | |
406 || reg_overlap_p (def_reg, reg2_1); | |
407 | |
408 if (rtx_equal_p (reg1_0, reg2_1)) | |
409 return reg_overlap_p (def_reg, reg1_1) | |
410 || reg_overlap_p (def_reg, reg2_0); | |
411 } | |
412 | |
413 if (GET_CODE (reg1_1) == NOT) | |
414 { | |
415 if (rtx_equal_p (reg1_1, reg2_0)) | |
416 return reg_overlap_p (def_reg, reg1_0) | |
417 || reg_overlap_p (def_reg, reg2_1); | |
418 | |
419 if (rtx_equal_p (reg1_1, reg2_1)) | |
420 return reg_overlap_p (def_reg, reg1_0) | |
421 || reg_overlap_p (def_reg, reg2_0); | |
422 } | |
423 | |
424 if (GET_CODE (reg2_0) == NOT) | |
425 { | |
426 if (rtx_equal_p (reg2_0, reg1_0)) | |
427 return reg_overlap_p (def_reg, reg2_1) | |
428 || reg_overlap_p (def_reg, reg1_1); | |
429 | |
430 if (rtx_equal_p (reg2_0, reg1_1)) | |
431 return reg_overlap_p (def_reg, reg2_1) | |
432 || reg_overlap_p (def_reg, reg1_0); | |
433 } | |
434 | |
435 if (GET_CODE (reg2_1) == NOT) | |
436 { | |
437 if (rtx_equal_p (reg2_1, reg1_0)) | |
438 return reg_overlap_p (def_reg, reg2_0) | |
439 || reg_overlap_p (def_reg, reg1_1); | |
440 | |
441 if (rtx_equal_p (reg2_1, reg1_1)) | |
442 return reg_overlap_p (def_reg, reg2_0) | |
443 || reg_overlap_p (def_reg, reg1_0); | |
444 } | |
445 | |
446 gcc_unreachable (); | |
447 } | |
448 } // namespace scheduling | |
449 } // namespace nds32 | |
33 | 450 |
34 /* ------------------------------------------------------------------------ */ | 451 /* ------------------------------------------------------------------------ */ |
452 | |
453 using namespace nds32; | |
454 using namespace nds32::scheduling; | |
455 | |
456 namespace { // anonymous namespace | |
457 | |
458 /* Check the dependency between the producer defining DEF_REG and CONSUMER | |
459 requiring input operand at II. */ | |
460 bool | |
461 n7_consumed_by_ii_dep_p (rtx_insn *consumer, rtx def_reg) | |
462 { | |
463 rtx use_rtx; | |
464 | |
465 switch (get_attr_type (consumer)) | |
466 { | |
467 /* MOVD44_E */ | |
468 case TYPE_ALU: | |
469 if (movd44_even_dep_p (consumer, def_reg)) | |
470 return true; | |
471 | |
472 use_rtx = SET_SRC (PATTERN (consumer)); | |
473 break; | |
474 | |
475 case TYPE_MUL: | |
476 use_rtx = SET_SRC (PATTERN (consumer)); | |
477 break; | |
478 | |
479 case TYPE_MAC: | |
480 use_rtx = extract_mac_non_acc_rtx (consumer); | |
481 break; | |
482 | |
483 /* Some special instructions, divmodsi4 and udivmodsi4, produce two | |
484 results, the quotient and the remainder. It requires two micro- | |
485 operations in order to write two registers. We have to check the | |
486 dependency from the producer to the first micro-operation. */ | |
487 case TYPE_DIV: | |
488 if (divmod_p (consumer)) | |
489 use_rtx = SET_SRC (parallel_element (consumer, 0)); | |
490 else | |
491 use_rtx = SET_SRC (PATTERN (consumer)); | |
492 break; | |
493 | |
494 case TYPE_LOAD: | |
495 /* ADDR_IN_bi_Ra, ADDR_IN_!bi */ | |
496 if (post_update_insn_p (consumer)) | |
497 use_rtx = extract_base_reg (consumer); | |
498 else | |
499 use_rtx = extract_mem_rtx (consumer); | |
500 break; | |
501 | |
502 case TYPE_STORE: | |
503 /* ADDR_IN_bi_Ra, ADDR_IN_!bi */ | |
504 if (post_update_insn_p (consumer)) | |
505 use_rtx = extract_base_reg (consumer); | |
506 else | |
507 use_rtx = extract_mem_rtx (consumer); | |
508 | |
509 if (reg_overlap_p (def_reg, use_rtx)) | |
510 return true; | |
511 | |
512 /* ST_bi, ST_!bi_RI */ | |
513 if (!post_update_insn_p (consumer) | |
514 && !immed_offset_p (extract_mem_rtx (consumer))) | |
515 return false; | |
516 | |
517 use_rtx = SET_SRC (PATTERN (consumer)); | |
518 break; | |
519 | |
520 case TYPE_LOAD_MULTIPLE: | |
521 use_rtx = extract_base_reg (consumer); | |
522 break; | |
523 | |
524 case TYPE_STORE_MULTIPLE: | |
525 /* ADDR_IN */ | |
526 use_rtx = extract_base_reg (consumer); | |
527 if (reg_overlap_p (def_reg, use_rtx)) | |
528 return true; | |
529 | |
530 /* SMW (N, 1) */ | |
531 use_rtx = extract_nth_access_rtx (consumer, 0); | |
532 break; | |
533 | |
534 case TYPE_BRANCH: | |
535 use_rtx = PATTERN (consumer); | |
536 break; | |
537 | |
538 default: | |
539 gcc_unreachable (); | |
540 } | |
541 | |
542 if (reg_overlap_p (def_reg, use_rtx)) | |
543 return true; | |
544 | |
545 return false; | |
546 } | |
547 | |
548 /* Check the dependency between the producer defining DEF_REG and CONSUMER | |
549 requiring input operand at AG (II). */ | |
550 bool | |
551 n8_consumed_by_addr_in_p (rtx_insn *consumer, rtx def_reg) | |
552 { | |
553 rtx use_rtx; | |
554 | |
555 switch (get_attr_type (consumer)) | |
556 { | |
557 case TYPE_BRANCH: | |
558 use_rtx = extract_branch_target_rtx (consumer); | |
559 break; | |
560 | |
561 case TYPE_LOAD: | |
562 if (load_single_p (consumer)) | |
563 use_rtx = extract_mem_rtx (consumer); | |
564 else | |
565 use_rtx = extract_base_reg (consumer); | |
566 break; | |
567 | |
568 case TYPE_STORE: | |
569 if (store_single_p (consumer) | |
570 && (!post_update_insn_p (consumer) | |
571 || immed_offset_p (extract_mem_rtx (consumer)))) | |
572 use_rtx = extract_mem_rtx (consumer); | |
573 else | |
574 use_rtx = extract_base_reg (consumer); | |
575 break; | |
576 | |
577 case TYPE_LOAD_MULTIPLE: | |
578 case TYPE_STORE_MULTIPLE: | |
579 use_rtx = extract_base_reg (consumer); | |
580 break; | |
581 | |
582 default: | |
583 gcc_unreachable (); | |
584 } | |
585 | |
586 return reg_overlap_p (def_reg, use_rtx); | |
587 } | |
588 | |
589 /* Check the dependency between the producer defining DEF_REG and CONSUMER | |
590 requiring input operand at EX. */ | |
591 bool | |
592 n8_consumed_by_ex_p (rtx_insn *consumer, rtx def_reg) | |
593 { | |
594 rtx use_rtx; | |
595 | |
596 switch (get_attr_type (consumer)) | |
597 { | |
598 case TYPE_ALU: | |
599 if (movd44_even_dep_p (consumer, def_reg)) | |
600 return true; | |
601 | |
602 use_rtx = SET_SRC (PATTERN (consumer)); | |
603 break; | |
604 | |
605 case TYPE_MUL: | |
606 use_rtx = SET_SRC (PATTERN (consumer)); | |
607 break; | |
608 | |
609 case TYPE_MAC: | |
610 use_rtx = extract_mac_non_acc_rtx (consumer); | |
611 break; | |
612 | |
613 /* Some special instructions, divmodsi4 and udivmodsi4, produce two | |
614 results, the quotient and the remainder. It requires two micro- | |
615 operations in order to write two registers. We have to check the | |
616 dependency from the producer to the first micro-operation. */ | |
617 case TYPE_DIV: | |
618 if (divmod_p (consumer)) | |
619 use_rtx = SET_SRC (parallel_element (consumer, 0)); | |
620 else | |
621 use_rtx = SET_SRC (PATTERN (consumer)); | |
622 break; | |
623 | |
624 case TYPE_BRANCH: | |
625 use_rtx = extract_branch_condition_rtx (consumer); | |
626 break; | |
627 | |
628 case TYPE_STORE: | |
629 /* exclude ST_!bi_RR */ | |
630 if (!post_update_insn_p (consumer) | |
631 && !immed_offset_p (extract_mem_rtx (consumer))) | |
632 return false; | |
633 | |
634 use_rtx = SET_SRC (PATTERN (consumer)); | |
635 break; | |
636 | |
637 case TYPE_STORE_MULTIPLE: | |
638 use_rtx = extract_nth_access_rtx (consumer, 0); | |
639 break; | |
640 | |
641 default: | |
642 gcc_unreachable (); | |
643 } | |
644 | |
645 return reg_overlap_p (def_reg, use_rtx); | |
646 } | |
647 | |
648 /* Check the dependency between the producer defining DEF_REG and CONSUMER | |
649 requiring input operand at AG (II). */ | |
650 bool | |
651 e8_consumed_by_addr_in_p (rtx_insn *consumer, rtx def_reg) | |
652 { | |
653 return n8_consumed_by_addr_in_p (consumer, def_reg); | |
654 } | |
655 | |
656 /* Check the dependency between the producer defining DEF_REG and CONSUMER | |
657 requiring input operand at EX. */ | |
658 bool | |
659 e8_consumed_by_ex_p (rtx_insn *consumer, rtx def_reg) | |
660 { | |
661 rtx use_rtx; | |
662 | |
663 switch (get_attr_type (consumer)) | |
664 { | |
665 case TYPE_ALU: | |
666 case TYPE_STORE: | |
667 use_rtx = SET_SRC (PATTERN (consumer)); | |
668 break; | |
669 | |
670 case TYPE_MUL: | |
671 case TYPE_MAC: | |
672 case TYPE_DIV: | |
673 case TYPE_BRANCH: | |
674 case TYPE_STORE_MULTIPLE: | |
675 return n8_consumed_by_ex_p (consumer, def_reg); | |
676 | |
677 default: | |
678 gcc_unreachable (); | |
679 } | |
680 | |
681 return reg_overlap_p (def_reg, use_rtx); | |
682 } | |
683 | |
684 /* Check the dependency between the producer defining DEF_REG and CONSUMER | |
685 requiring input operand at EX. */ | |
686 bool | |
687 n9_2r1w_consumed_by_ex_dep_p (rtx_insn *consumer, rtx def_reg) | |
688 { | |
689 rtx use_rtx; | |
690 | |
691 switch (get_attr_type (consumer)) | |
692 { | |
693 case TYPE_ALU: | |
694 if (movd44_even_dep_p (consumer, def_reg)) | |
695 return true; | |
696 | |
697 use_rtx = SET_SRC (PATTERN (consumer)); | |
698 break; | |
699 | |
700 case TYPE_PBSAD: | |
701 case TYPE_MUL: | |
702 use_rtx = SET_SRC (PATTERN (consumer)); | |
703 break; | |
704 | |
705 case TYPE_ALU_SHIFT: | |
706 use_rtx = extract_shift_reg (consumer); | |
707 break; | |
708 | |
709 case TYPE_PBSADA: | |
710 return pbsada_insn_ra_rb_dep_reg_p (consumer, def_reg); | |
711 | |
712 case TYPE_MAC: | |
713 use_rtx = PATTERN (consumer); | |
714 break; | |
715 | |
716 case TYPE_DIV: | |
717 if (divmod_p (consumer)) | |
718 use_rtx = SET_SRC (parallel_element (consumer, 0)); | |
719 else | |
720 use_rtx = SET_SRC (PATTERN (consumer)); | |
721 break; | |
722 | |
723 case TYPE_MMU: | |
724 if (GET_CODE (PATTERN (consumer)) == SET) | |
725 use_rtx = SET_SRC (PATTERN (consumer)); | |
726 else | |
727 return true; | |
728 break; | |
729 | |
730 case TYPE_LOAD: | |
731 /* ADDR_IN_bi_Ra, ADDR_IN_!bi */ | |
732 if (post_update_insn_p (consumer)) | |
733 use_rtx = extract_base_reg (consumer); | |
734 else | |
735 use_rtx = extract_mem_rtx (consumer); | |
736 break; | |
737 | |
738 case TYPE_STORE: | |
739 /* ADDR_IN_bi_Ra, ADDR_IN_!bi */ | |
740 if (post_update_insn_p (consumer)) | |
741 use_rtx = extract_base_reg (consumer); | |
742 else | |
743 use_rtx = extract_mem_rtx (consumer); | |
744 | |
745 if (reg_overlap_p (def_reg, use_rtx)) | |
746 return true; | |
747 | |
748 /* exclude ST_!bi_RR */ | |
749 if (!post_update_insn_p (consumer) | |
750 && !immed_offset_p (extract_mem_rtx (consumer))) | |
751 return false; | |
752 | |
753 use_rtx = SET_SRC (PATTERN (consumer)); | |
754 break; | |
755 | |
756 case TYPE_LOAD_MULTIPLE: | |
757 use_rtx = extract_base_reg (consumer); | |
758 break; | |
759 | |
760 case TYPE_STORE_MULTIPLE: | |
761 /* ADDR_IN */ | |
762 use_rtx = extract_base_reg (consumer); | |
763 if (reg_overlap_p (def_reg, use_rtx)) | |
764 return true; | |
765 | |
766 /* SMW (N, 1) */ | |
767 use_rtx = extract_nth_access_rtx (consumer, 0); | |
768 break; | |
769 | |
770 case TYPE_BRANCH: | |
771 use_rtx = PATTERN (consumer); | |
772 break; | |
773 | |
774 default: | |
775 gcc_unreachable (); | |
776 } | |
777 | |
778 if (reg_overlap_p (def_reg, use_rtx)) | |
779 return true; | |
780 | |
781 return false; | |
782 } | |
783 | |
784 /* Check the dependency between the producer defining DEF_REG and CONSUMER | |
785 requiring input operand at EX. */ | |
786 bool | |
787 n9_3r2w_consumed_by_ex_dep_p (rtx_insn *consumer, rtx def_reg) | |
788 { | |
789 rtx use_rtx; | |
790 | |
791 switch (get_attr_type (consumer)) | |
792 { | |
793 case TYPE_ALU: | |
794 case TYPE_PBSAD: | |
795 case TYPE_MUL: | |
796 use_rtx = SET_SRC (PATTERN (consumer)); | |
797 break; | |
798 | |
799 case TYPE_ALU_SHIFT: | |
800 use_rtx = extract_shift_reg (consumer); | |
801 break; | |
802 | |
803 case TYPE_PBSADA: | |
804 return pbsada_insn_ra_rb_dep_reg_p (consumer, def_reg); | |
805 | |
806 case TYPE_MAC: | |
807 use_rtx = extract_mac_non_acc_rtx (consumer); | |
808 break; | |
809 | |
810 /* Some special instructions, divmodsi4 and udivmodsi4, produce two | |
811 results, the quotient and the remainder. In 2R1W configuration, | |
812 it requires two micro-operations in order to write two registers. | |
813 We have to check the dependency from the producer to the first | |
814 micro-operation. */ | |
815 case TYPE_DIV: | |
816 if (divmod_p (consumer)) | |
817 use_rtx = SET_SRC (parallel_element (consumer, 0)); | |
818 else | |
819 use_rtx = SET_SRC (PATTERN (consumer)); | |
820 break; | |
821 | |
822 case TYPE_MMU: | |
823 if (GET_CODE (PATTERN (consumer)) == SET) | |
824 use_rtx = SET_SRC (PATTERN (consumer)); | |
825 else | |
826 return true; | |
827 break; | |
828 | |
829 case TYPE_LOAD: | |
830 case TYPE_STORE: | |
831 use_rtx = extract_mem_rtx (consumer); | |
832 break; | |
833 | |
834 case TYPE_LOAD_MULTIPLE: | |
835 case TYPE_STORE_MULTIPLE: | |
836 use_rtx = extract_base_reg (consumer); | |
837 break; | |
838 | |
839 case TYPE_BRANCH: | |
840 use_rtx = PATTERN (consumer); | |
841 break; | |
842 | |
843 default: | |
844 gcc_unreachable (); | |
845 } | |
846 | |
847 if (reg_overlap_p (def_reg, use_rtx)) | |
848 return true; | |
849 | |
850 return false; | |
851 } | |
852 | |
853 /* Check the dependency between the producer defining DEF_REG and CONSUMER | |
854 requiring input operand at EX. */ | |
855 bool | |
856 n10_consumed_by_ex_dep_p (rtx_insn *consumer, rtx def_reg) | |
857 { | |
858 rtx use_rtx; | |
859 | |
860 switch (get_attr_type (consumer)) | |
861 { | |
862 case TYPE_ALU: | |
863 case TYPE_PBSAD: | |
864 case TYPE_MUL: | |
865 case TYPE_DALU: | |
866 case TYPE_DALU64: | |
867 case TYPE_DMUL: | |
868 case TYPE_DPACK: | |
869 case TYPE_DINSB: | |
870 case TYPE_DCMP: | |
871 case TYPE_DCLIP: | |
872 case TYPE_DALUROUND: | |
873 use_rtx = SET_SRC (PATTERN (consumer)); | |
874 break; | |
875 | |
876 case TYPE_ALU_SHIFT: | |
877 use_rtx = extract_shift_reg (consumer); | |
878 break; | |
879 | |
880 case TYPE_PBSADA: | |
881 return pbsada_insn_ra_rb_dep_reg_p (consumer, def_reg); | |
882 | |
883 case TYPE_MAC: | |
884 case TYPE_DMAC: | |
885 use_rtx = extract_mac_non_acc_rtx (consumer); | |
886 break; | |
887 | |
888 /* Some special instructions, divmodsi4 and udivmodsi4, produce two | |
889 results, the quotient and the remainder. */ | |
890 case TYPE_DIV: | |
891 if (divmod_p (consumer)) | |
892 use_rtx = SET_SRC (parallel_element (consumer, 0)); | |
893 else | |
894 use_rtx = SET_SRC (PATTERN (consumer)); | |
895 break; | |
896 | |
897 case TYPE_DWEXT: | |
898 return wext_odd_dep_p (consumer, def_reg); | |
899 | |
900 case TYPE_DBPICK: | |
901 return bpick_ra_rb_dep_p (consumer, def_reg); | |
902 | |
903 case TYPE_MMU: | |
904 if (GET_CODE (PATTERN (consumer)) == SET) | |
905 use_rtx = SET_SRC (PATTERN (consumer)); | |
906 else | |
907 return true; | |
908 break; | |
909 | |
910 case TYPE_LOAD: | |
911 case TYPE_STORE: | |
912 use_rtx = extract_mem_rtx (consumer); | |
913 break; | |
914 | |
915 case TYPE_LOAD_MULTIPLE: | |
916 case TYPE_STORE_MULTIPLE: | |
917 use_rtx = extract_base_reg (consumer); | |
918 break; | |
919 | |
920 case TYPE_BRANCH: | |
921 use_rtx = PATTERN (consumer); | |
922 break; | |
923 | |
924 default: | |
925 gcc_unreachable (); | |
926 } | |
927 | |
928 if (reg_overlap_p (def_reg, use_rtx)) | |
929 return true; | |
930 | |
931 return false; | |
932 } | |
933 | |
934 /* Check the dependency between the producer defining DEF_REG and CONSUMER | |
935 requiring input operand at EX. */ | |
936 bool | |
937 gw_consumed_by_ex_dep_p (rtx_insn *consumer, rtx def_reg) | |
938 { | |
939 rtx use_rtx; | |
940 | |
941 switch (get_attr_type (consumer)) | |
942 { | |
943 case TYPE_ALU: | |
944 case TYPE_PBSAD: | |
945 case TYPE_MUL: | |
946 case TYPE_DALU: | |
947 case TYPE_DALU64: | |
948 case TYPE_DMUL: | |
949 case TYPE_DPACK: | |
950 case TYPE_DINSB: | |
951 case TYPE_DCMP: | |
952 case TYPE_DCLIP: | |
953 case TYPE_DALUROUND: | |
954 use_rtx = SET_SRC (PATTERN (consumer)); | |
955 break; | |
956 | |
957 case TYPE_ALU_SHIFT: | |
958 use_rtx = extract_shift_reg (consumer); | |
959 break; | |
960 | |
961 case TYPE_PBSADA: | |
962 return pbsada_insn_ra_rb_dep_reg_p (consumer, def_reg); | |
963 | |
964 case TYPE_MAC: | |
965 case TYPE_DMAC: | |
966 use_rtx = extract_mac_non_acc_rtx (consumer); | |
967 break; | |
968 | |
969 /* Some special instructions, divmodsi4 and udivmodsi4, produce two | |
970 results, the quotient and the remainder. We have to check the | |
971 dependency from the producer to the first micro-operation. */ | |
972 case TYPE_DIV: | |
973 if (divmod_p (consumer)) | |
974 use_rtx = SET_SRC (parallel_element (consumer, 0)); | |
975 else | |
976 use_rtx = SET_SRC (PATTERN (consumer)); | |
977 break; | |
978 | |
979 case TYPE_DWEXT: | |
980 return wext_odd_dep_p (consumer, def_reg); | |
981 | |
982 case TYPE_DBPICK: | |
983 return bpick_ra_rb_dep_p (consumer, def_reg); | |
984 | |
985 case TYPE_MMU: | |
986 if (GET_CODE (PATTERN (consumer)) == SET) | |
987 use_rtx = SET_SRC (PATTERN (consumer)); | |
988 else | |
989 return true; | |
990 break; | |
991 | |
992 case TYPE_LOAD: | |
993 case TYPE_STORE: | |
994 use_rtx = extract_mem_rtx (consumer); | |
995 break; | |
996 | |
997 case TYPE_LOAD_MULTIPLE: | |
998 case TYPE_STORE_MULTIPLE: | |
999 use_rtx = extract_base_reg (consumer); | |
1000 break; | |
1001 | |
1002 case TYPE_BRANCH: | |
1003 use_rtx = PATTERN (consumer); | |
1004 break; | |
1005 | |
1006 default: | |
1007 gcc_unreachable (); | |
1008 } | |
1009 | |
1010 if (reg_overlap_p (def_reg, use_rtx)) | |
1011 return true; | |
1012 | |
1013 return false; | |
1014 } | |
1015 | |
1016 /* Check dependencies from any stages to ALU_E1 (E1). This is a helper | |
1017 function of n13_consumed_by_e1_dep_p (). */ | |
1018 bool | |
1019 n13_alu_e1_insn_dep_reg_p (rtx_insn *alu_e1_insn, rtx def_reg) | |
1020 { | |
1021 rtx unspec_rtx, operand_ra, operand_rb; | |
1022 rtx src_rtx, dst_rtx; | |
1023 | |
1024 switch (INSN_CODE (alu_e1_insn)) | |
1025 { | |
1026 /* BSP and BSE are supported by built-in functions, the corresponding | |
1027 patterns are formed by UNSPEC RTXs. We have to handle them | |
1028 individually. */ | |
1029 case CODE_FOR_unspec_bsp: | |
1030 case CODE_FOR_unspec_bse: | |
1031 unspec_rtx = SET_SRC (parallel_element (alu_e1_insn, 0)); | |
1032 gcc_assert (GET_CODE (unspec_rtx) == UNSPEC); | |
1033 | |
1034 operand_ra = XVECEXP (unspec_rtx, 0, 0); | |
1035 operand_rb = XVECEXP (unspec_rtx, 0, 1); | |
1036 | |
1037 if (rtx_equal_p (def_reg, operand_ra) | |
1038 || rtx_equal_p (def_reg, operand_rb)) | |
1039 return true; | |
1040 | |
1041 return false; | |
1042 | |
1043 /* Unlink general ALU instructions, MOVD44 requires operands at E1. */ | |
1044 case CODE_FOR_move_di: | |
1045 case CODE_FOR_move_df: | |
1046 src_rtx = SET_SRC (PATTERN (alu_e1_insn)); | |
1047 dst_rtx = SET_DEST (PATTERN (alu_e1_insn)); | |
1048 | |
1049 if (REG_P (dst_rtx) && REG_P (src_rtx) | |
1050 && rtx_equal_p (src_rtx, def_reg)) | |
1051 return true; | |
1052 | |
1053 return false; | |
1054 | |
1055 default: | |
1056 return false; | |
1057 } | |
1058 } | |
1059 | |
1060 /* Check the dependency between the producer defining DEF_REG and CONSUMER | |
1061 requiring input operand at E1. Because the address generation unti is | |
1062 at E1, the address input should be ready at E1. Note that the branch | |
1063 target is also a kind of addresses, so we have to check it. */ | |
1064 bool | |
1065 n13_consumed_by_e1_dep_p (rtx_insn *consumer, rtx def_reg) | |
1066 { | |
1067 rtx use_rtx; | |
1068 | |
1069 switch (get_attr_type (consumer)) | |
1070 { | |
1071 /* ALU_E1 */ | |
1072 case TYPE_ALU: | |
1073 return n13_alu_e1_insn_dep_reg_p (consumer, def_reg); | |
1074 | |
1075 case TYPE_PBSADA: | |
1076 return pbsada_insn_ra_rb_dep_reg_p (consumer, def_reg); | |
1077 | |
1078 case TYPE_PBSAD: | |
1079 case TYPE_MUL: | |
1080 use_rtx = SET_SRC (PATTERN (consumer)); | |
1081 break; | |
1082 | |
1083 case TYPE_MAC: | |
1084 use_rtx = extract_mac_non_acc_rtx (consumer); | |
1085 break; | |
1086 | |
1087 case TYPE_DIV: | |
1088 if (divmod_p (consumer)) | |
1089 use_rtx = SET_SRC (parallel_element (consumer, 0)); | |
1090 else | |
1091 use_rtx = SET_SRC (PATTERN (consumer)); | |
1092 break; | |
1093 | |
1094 case TYPE_MMU: | |
1095 if (GET_CODE (PATTERN (consumer)) == SET) | |
1096 use_rtx = SET_SRC (PATTERN (consumer)); | |
1097 else | |
1098 return true; | |
1099 break; | |
1100 | |
1101 case TYPE_BRANCH: | |
1102 use_rtx = extract_branch_target_rtx (consumer); | |
1103 break; | |
1104 | |
1105 case TYPE_LOAD: | |
1106 case TYPE_STORE: | |
1107 use_rtx = extract_mem_rtx (consumer); | |
1108 break; | |
1109 | |
1110 case TYPE_LOAD_MULTIPLE: | |
1111 case TYPE_STORE_MULTIPLE: | |
1112 use_rtx = extract_base_reg (consumer); | |
1113 break; | |
1114 | |
1115 default: | |
1116 return false; | |
1117 } | |
1118 | |
1119 if (reg_overlap_p (def_reg, use_rtx)) | |
1120 return true; | |
1121 | |
1122 return false; | |
1123 } | |
1124 | |
1125 /* Check the dependency between the producer defining DEF_REG and CONSUMER | |
1126 requiring input operand at E2. */ | |
1127 bool | |
1128 n13_consumed_by_e2_dep_p (rtx_insn *consumer, rtx def_reg) | |
1129 { | |
1130 rtx use_rtx; | |
1131 | |
1132 switch (get_attr_type (consumer)) | |
1133 { | |
1134 case TYPE_ALU: | |
1135 case TYPE_STORE: | |
1136 use_rtx = SET_SRC (PATTERN (consumer)); | |
1137 break; | |
1138 | |
1139 case TYPE_ALU_SHIFT: | |
1140 use_rtx = extract_shift_reg (consumer); | |
1141 break; | |
1142 | |
1143 case TYPE_PBSADA: | |
1144 return pbsada_insn_rt_dep_reg_p (consumer, def_reg); | |
1145 | |
1146 case TYPE_STORE_MULTIPLE: | |
1147 use_rtx = extract_nth_access_rtx (consumer, 0); | |
1148 break; | |
1149 | |
1150 case TYPE_BRANCH: | |
1151 use_rtx = extract_branch_condition_rtx (consumer); | |
1152 break; | |
1153 | |
1154 default: | |
1155 gcc_unreachable(); | |
1156 } | |
1157 | |
1158 if (reg_overlap_p (def_reg, use_rtx)) | |
1159 return true; | |
1160 | |
1161 return false; | |
1162 } | |
1163 } // anonymous namespace | |
1164 | |
1165 /* ------------------------------------------------------------------------ */ | |
1166 | |
1167 /* Guard functions for N7 core. */ | |
1168 | |
1169 bool | |
1170 nds32_n7_load_to_ii_p (rtx_insn *producer, rtx_insn *consumer) | |
1171 { | |
1172 if (post_update_insn_p (producer)) | |
1173 return false; | |
1174 | |
1175 rtx def_reg = SET_DEST (PATTERN (producer)); | |
1176 | |
1177 return n7_consumed_by_ii_dep_p (consumer, def_reg); | |
1178 } | |
1179 | |
1180 bool | |
1181 nds32_n7_last_load_to_ii_p (rtx_insn *producer, rtx_insn *consumer) | |
1182 { | |
1183 /* If PRODUCER is a post-update LMW insn, the last micro-operation updates | |
1184 the base register and the result is ready in II stage, so we don't need | |
1185 to handle that case in this guard function and the corresponding bypass | |
1186 rule. */ | |
1187 if (post_update_insn_p (producer)) | |
1188 return false; | |
1189 | |
1190 rtx last_def_reg = extract_nth_access_reg (producer, -1); | |
1191 | |
1192 if (last_def_reg == NULL_RTX) | |
1193 return false; | |
1194 | |
1195 gcc_assert (REG_P (last_def_reg) || GET_CODE (last_def_reg) == SUBREG); | |
1196 | |
1197 return n7_consumed_by_ii_dep_p (consumer, last_def_reg); | |
1198 } | |
1199 | |
1200 /* Guard functions for N8 core. */ | |
1201 | |
1202 bool | |
1203 nds32_n8_load_to_ii_p (rtx_insn *producer, rtx_insn *consumer) | |
1204 { | |
1205 if (post_update_insn_p (producer)) | |
1206 return false; | |
1207 | |
1208 rtx def_reg = SET_DEST (PATTERN (producer)); | |
1209 | |
1210 return n8_consumed_by_addr_in_p (consumer, def_reg); | |
1211 } | |
1212 | |
1213 bool | |
1214 nds32_n8_load_bi_to_ii_p (rtx_insn *producer, rtx_insn *consumer) | |
1215 { | |
1216 if (!post_update_insn_p (producer)) | |
1217 return false; | |
1218 | |
1219 rtx def_reg = SET_DEST (PATTERN (producer)); | |
1220 | |
1221 return n8_consumed_by_addr_in_p (consumer, def_reg); | |
1222 } | |
1223 | |
1224 bool | |
1225 nds32_n8_load_to_ex_p (rtx_insn *producer, rtx_insn *consumer) | |
1226 { | |
1227 if (post_update_insn_p (producer)) | |
1228 return false; | |
1229 | |
1230 rtx def_reg = SET_DEST (PATTERN (producer)); | |
1231 | |
1232 return n8_consumed_by_ex_p (consumer, def_reg); | |
1233 } | |
1234 | |
1235 bool | |
1236 nds32_n8_ex_to_ii_p (rtx_insn *producer, rtx_insn *consumer) | |
1237 { | |
1238 rtx def_reg; | |
1239 | |
1240 switch (get_attr_type (producer)) | |
1241 { | |
1242 case TYPE_ALU: | |
1243 if (movd44_insn_p (producer)) | |
1244 def_reg = extract_movd44_odd_reg (producer); | |
1245 else | |
1246 def_reg = SET_DEST (PATTERN (producer)); | |
1247 break; | |
1248 | |
1249 case TYPE_MUL: | |
1250 case TYPE_MAC: | |
1251 def_reg = SET_DEST (PATTERN (producer)); | |
1252 break; | |
1253 | |
1254 case TYPE_DIV: | |
1255 if (divmod_p (producer)) | |
1256 def_reg = SET_DEST (parallel_element (producer, 1)); | |
1257 else | |
1258 def_reg = SET_DEST (PATTERN (producer)); | |
1259 break; | |
1260 | |
1261 case TYPE_LOAD: | |
1262 case TYPE_STORE: | |
1263 case TYPE_LOAD_MULTIPLE: | |
1264 case TYPE_STORE_MULTIPLE: | |
1265 if (!post_update_insn_p (producer)) | |
1266 return false; | |
1267 | |
1268 def_reg = extract_base_reg (producer); | |
1269 break; | |
1270 | |
1271 default: | |
1272 gcc_unreachable (); | |
1273 } | |
1274 | |
1275 return n8_consumed_by_addr_in_p (consumer, def_reg); | |
1276 } | |
1277 | |
1278 bool | |
1279 nds32_n8_last_load_to_ii_p (rtx_insn *producer, rtx_insn *consumer) | |
1280 { | |
1281 /* If PRODUCER is a post-update LMW insn, the last micro-operation updates | |
1282 the base register and the result is ready in EX stage, so we don't need | |
1283 to handle that case in this guard function and the corresponding bypass | |
1284 rule. */ | |
1285 if (post_update_insn_p (producer)) | |
1286 return false; | |
1287 | |
1288 rtx last_def_reg = extract_nth_access_reg (producer, -1); | |
1289 | |
1290 if (last_def_reg == NULL_RTX) | |
1291 return false; | |
1292 | |
1293 gcc_assert (REG_P (last_def_reg) || GET_CODE (last_def_reg) == SUBREG); | |
1294 | |
1295 return n8_consumed_by_addr_in_p (consumer, last_def_reg); | |
1296 } | |
1297 | |
1298 bool | |
1299 nds32_n8_last_load_two_to_ii_p (rtx_insn *producer, rtx_insn *consumer) | |
1300 { | |
1301 int index = -2; | |
1302 | |
1303 /* If PRODUCER is a post-update insn, there is an additional one micro- | |
1304 operation inserted in the end, so the last memory access operation should | |
1305 be handled by this guard function and the corresponding bypass rule. */ | |
1306 if (post_update_insn_p (producer)) | |
1307 index = -1; | |
1308 | |
1309 rtx last_two_def_reg = extract_nth_access_reg (producer, index); | |
1310 | |
1311 if (last_two_def_reg == NULL_RTX) | |
1312 return false; | |
1313 | |
1314 gcc_assert (REG_P (last_two_def_reg) | |
1315 || GET_CODE (last_two_def_reg) == SUBREG); | |
1316 | |
1317 return n8_consumed_by_addr_in_p (consumer, last_two_def_reg); | |
1318 } | |
1319 | |
1320 bool | |
1321 nds32_n8_last_load_to_ex_p (rtx_insn *producer, rtx_insn *consumer) | |
1322 { | |
1323 /* If PRODUCER is a post-update LMW insn, the last micro-operation updates | |
1324 the base register and the result is ready in EX stage, so we don't need | |
1325 to handle that case in this guard function and the corresponding bypass | |
1326 rule. */ | |
1327 if (post_update_insn_p (producer)) | |
1328 return false; | |
1329 | |
1330 rtx last_def_reg = extract_nth_access_reg (producer, -1); | |
1331 | |
1332 if (last_def_reg == NULL_RTX) | |
1333 return false; | |
1334 | |
1335 gcc_assert (REG_P (last_def_reg) || GET_CODE (last_def_reg) == SUBREG); | |
1336 | |
1337 return n8_consumed_by_ex_p (consumer, last_def_reg); | |
1338 } | |
1339 | |
1340 /* Guard functions for E8 cores. */ | |
1341 | |
1342 bool | |
1343 nds32_e8_load_to_ii_p (rtx_insn *producer, rtx_insn *consumer) | |
1344 { | |
1345 rtx def_reg = SET_DEST (PATTERN (producer)); | |
1346 | |
1347 return e8_consumed_by_addr_in_p (consumer, def_reg); | |
1348 } | |
1349 | |
1350 bool | |
1351 nds32_e8_load_to_ex_p (rtx_insn *producer, rtx_insn *consumer) | |
1352 { | |
1353 rtx def_reg = SET_DEST (PATTERN (producer)); | |
1354 | |
1355 return e8_consumed_by_ex_p (consumer, def_reg); | |
1356 } | |
1357 | |
1358 bool | |
1359 nds32_e8_ex_to_ii_p (rtx_insn *producer, rtx_insn *consumer) | |
1360 { | |
1361 rtx def_reg; | |
1362 | |
1363 switch (get_attr_type (producer)) | |
1364 { | |
1365 case TYPE_ALU: | |
1366 /* No data hazards if AGEN's input is produced by MOVI or SETHI. */ | |
1367 if (GET_CODE (PATTERN (producer)) == SET) | |
1368 { | |
1369 rtx dest = SET_DEST (PATTERN (producer)); | |
1370 rtx src = SET_SRC (PATTERN (producer)); | |
1371 | |
1372 if ((REG_P (dest) || GET_CODE (dest) == SUBREG) | |
1373 && (GET_CODE (src) == CONST_INT || GET_CODE (src) == HIGH)) | |
1374 return false; | |
1375 } | |
1376 | |
1377 def_reg = SET_DEST (PATTERN (producer)); | |
1378 break; | |
1379 | |
1380 case TYPE_MUL: | |
1381 case TYPE_MAC: | |
1382 def_reg = SET_DEST (PATTERN (producer)); | |
1383 break; | |
1384 | |
1385 case TYPE_DIV: | |
1386 if (divmod_p (producer)) | |
1387 { | |
1388 rtx def_reg1 = SET_DEST (parallel_element (producer, 0)); | |
1389 rtx def_reg2 = SET_DEST (parallel_element (producer, 1)); | |
1390 | |
1391 return (e8_consumed_by_addr_in_p (consumer, def_reg1) | |
1392 || e8_consumed_by_addr_in_p (consumer, def_reg2)); | |
1393 } | |
1394 | |
1395 def_reg = SET_DEST (PATTERN (producer)); | |
1396 break; | |
1397 | |
1398 case TYPE_LOAD: | |
1399 case TYPE_STORE: | |
1400 case TYPE_LOAD_MULTIPLE: | |
1401 case TYPE_STORE_MULTIPLE: | |
1402 if (!post_update_insn_p (producer)) | |
1403 return false; | |
1404 | |
1405 def_reg = extract_base_reg (producer); | |
1406 break; | |
1407 | |
1408 default: | |
1409 gcc_unreachable (); | |
1410 } | |
1411 | |
1412 return e8_consumed_by_addr_in_p (consumer, def_reg); | |
1413 } | |
1414 | |
1415 bool | |
1416 nds32_e8_last_load_to_ii_p (rtx_insn *producer, rtx_insn *consumer) | |
1417 { | |
1418 rtx last_def_reg = extract_nth_access_reg (producer, -1); | |
1419 | |
1420 if (last_def_reg == NULL_RTX) | |
1421 return false; | |
1422 | |
1423 gcc_assert (REG_P (last_def_reg) || GET_CODE (last_def_reg) == SUBREG); | |
1424 | |
1425 return e8_consumed_by_addr_in_p (consumer, last_def_reg); | |
1426 } | |
1427 | |
1428 bool | |
1429 nds32_e8_last_load_to_ex_p (rtx_insn *producer, rtx_insn *consumer) | |
1430 { | |
1431 rtx last_def_reg = extract_nth_access_reg (producer, -1); | |
1432 | |
1433 if (last_def_reg == NULL_RTX) | |
1434 return false; | |
1435 | |
1436 gcc_assert (REG_P (last_def_reg) || GET_CODE (last_def_reg) == SUBREG); | |
1437 | |
1438 return e8_consumed_by_ex_p (consumer, last_def_reg); | |
1439 } | |
1440 | |
1441 /* Guard functions for N9 cores. */ | |
1442 | |
1443 /* Check dependencies from MM to EX. */ | |
1444 bool | |
1445 nds32_n9_2r1w_mm_to_ex_p (rtx_insn *producer, rtx_insn *consumer) | |
1446 { | |
1447 rtx def_reg; | |
1448 | |
1449 switch (get_attr_type (producer)) | |
1450 { | |
1451 /* LD_!bi */ | |
1452 case TYPE_LOAD: | |
1453 if (post_update_insn_p (producer)) | |
1454 return false; | |
1455 | |
1456 def_reg = SET_DEST (PATTERN (producer)); | |
1457 break; | |
1458 | |
1459 case TYPE_MUL: | |
1460 case TYPE_MAC: | |
1461 def_reg = SET_DEST (PATTERN (producer)); | |
1462 break; | |
1463 | |
1464 default: | |
1465 gcc_unreachable (); | |
1466 } | |
1467 | |
1468 return n9_2r1w_consumed_by_ex_dep_p (consumer, def_reg); | |
1469 } | |
1470 | |
1471 /* Check dependencies from MM to EX. */ | |
1472 bool | |
1473 nds32_n9_3r2w_mm_to_ex_p (rtx_insn *producer, rtx_insn *consumer) | |
1474 { | |
1475 rtx def_reg; | |
1476 | |
1477 switch (get_attr_type (producer)) | |
1478 { | |
1479 case TYPE_LOAD: | |
1480 case TYPE_MUL: | |
1481 case TYPE_MAC: | |
1482 def_reg = SET_DEST (PATTERN (producer)); | |
1483 break; | |
1484 | |
1485 /* Some special instructions, divmodsi4 and udivmodsi4, produce two | |
1486 results, the quotient and the remainder. We have to handle them | |
1487 individually. */ | |
1488 case TYPE_DIV: | |
1489 if (divmod_p (producer)) | |
1490 { | |
1491 rtx def_reg1 = SET_DEST (parallel_element (producer, 0)); | |
1492 rtx def_reg2 = SET_DEST (parallel_element (producer, 1)); | |
1493 | |
1494 return (n9_3r2w_consumed_by_ex_dep_p (consumer, def_reg1) | |
1495 || n9_3r2w_consumed_by_ex_dep_p (consumer, def_reg2)); | |
1496 } | |
1497 | |
1498 def_reg = SET_DEST (PATTERN (producer)); | |
1499 break; | |
1500 | |
1501 default: | |
1502 gcc_unreachable (); | |
1503 } | |
1504 | |
1505 return n9_3r2w_consumed_by_ex_dep_p (consumer, def_reg); | |
1506 } | |
1507 | |
1508 /* Check dependencies from LMW(N, N) to EX. */ | |
1509 bool | |
1510 nds32_n9_last_load_to_ex_p (rtx_insn *producer, rtx_insn *consumer) | |
1511 { | |
1512 rtx last_def_reg = extract_nth_access_reg (producer, -1); | |
1513 | |
1514 if (nds32_register_ports_config == REG_PORT_2R1W) | |
1515 { | |
1516 /* The base-update micro operation occupies the last cycle. */ | |
1517 if (post_update_insn_p (producer)) | |
1518 return false; | |
1519 | |
1520 /* When the base register is in the list of a load multiple insn and the | |
1521 access order of the base register is not the last one, we need an | |
1522 additional micro operation to commit the load result to the base | |
1523 register -- we can treat the base register as the last defined | |
1524 register. */ | |
1525 size_t i; | |
1526 size_t n_elems = parallel_elements (producer); | |
1527 rtx base_reg = extract_base_reg (producer); | |
1528 | |
1529 for (i = 0; i < n_elems; ++i) | |
1530 { | |
1531 rtx load_rtx = extract_nth_access_rtx (producer, i); | |
1532 rtx list_element = SET_DEST (load_rtx); | |
1533 | |
1534 if (rtx_equal_p (base_reg, list_element) && i != n_elems - 1) | |
1535 { | |
1536 last_def_reg = base_reg; | |
1537 break; | |
1538 } | |
1539 } | |
1540 | |
1541 return n9_2r1w_consumed_by_ex_dep_p (consumer, last_def_reg); | |
1542 } | |
1543 else | |
1544 return n9_3r2w_consumed_by_ex_dep_p (consumer, last_def_reg); | |
1545 } | |
1546 | |
1547 /* Guard functions for N10 cores. */ | |
1548 | |
1549 /* Check dependencies from EX to EX (ADDR_OUT -> ADDR_IN). */ | |
1550 bool | |
1551 nds32_n10_ex_to_ex_p (rtx_insn *producer, rtx_insn *consumer) | |
1552 { | |
1553 gcc_assert (get_attr_type (producer) == TYPE_FLOAD | |
1554 || get_attr_type (producer) == TYPE_FSTORE); | |
1555 gcc_assert (get_attr_type (consumer) == TYPE_FLOAD | |
1556 || get_attr_type (consumer) == TYPE_FSTORE); | |
1557 | |
1558 if (!post_update_insn_p (producer)) | |
1559 return false; | |
1560 | |
1561 return reg_overlap_p (extract_base_reg (producer), | |
1562 extract_mem_rtx (consumer)); | |
1563 } | |
1564 | |
1565 /* Check dependencies from MM to EX. */ | |
1566 bool | |
1567 nds32_n10_mm_to_ex_p (rtx_insn *producer, rtx_insn *consumer) | |
1568 { | |
1569 rtx def_reg; | |
1570 | |
1571 switch (get_attr_type (producer)) | |
1572 { | |
1573 case TYPE_LOAD: | |
1574 case TYPE_MUL: | |
1575 case TYPE_MAC: | |
1576 case TYPE_DALU64: | |
1577 case TYPE_DMUL: | |
1578 case TYPE_DMAC: | |
1579 case TYPE_DALUROUND: | |
1580 case TYPE_DBPICK: | |
1581 case TYPE_DWEXT: | |
1582 def_reg = SET_DEST (PATTERN (producer)); | |
1583 break; | |
1584 | |
1585 /* Some special instructions, divmodsi4 and udivmodsi4, produce two | |
1586 results, the quotient and the remainder. We have to handle them | |
1587 individually. */ | |
1588 case TYPE_DIV: | |
1589 if (divmod_p (producer)) | |
1590 { | |
1591 rtx def_reg1 = SET_DEST (parallel_element (producer, 0)); | |
1592 rtx def_reg2 = SET_DEST (parallel_element (producer, 1)); | |
1593 | |
1594 return (n10_consumed_by_ex_dep_p (consumer, def_reg1) | |
1595 || n10_consumed_by_ex_dep_p (consumer, def_reg2)); | |
1596 } | |
1597 | |
1598 def_reg = SET_DEST (PATTERN (producer)); | |
1599 break; | |
1600 | |
1601 default: | |
1602 gcc_unreachable (); | |
1603 } | |
1604 | |
1605 return n10_consumed_by_ex_dep_p (consumer, def_reg); | |
1606 } | |
1607 | |
1608 /* Check dependencies from LMW(N, N) to EX. */ | |
1609 bool | |
1610 nds32_n10_last_load_to_ex_p (rtx_insn *producer, rtx_insn *consumer) | |
1611 { | |
1612 rtx last_def_reg = extract_nth_access_reg (producer, -1); | |
1613 | |
1614 return n10_consumed_by_ex_dep_p (consumer, last_def_reg); | |
1615 } | |
1616 | |
1617 /* Guard functions for Graywolf cores. */ | |
1618 | |
1619 /* Check dependencies from EX to EX (ADDR_OUT -> ADDR_IN). */ | |
1620 bool | |
1621 nds32_gw_ex_to_ex_p (rtx_insn *producer, rtx_insn *consumer) | |
1622 { | |
1623 return nds32_n10_ex_to_ex_p (producer, consumer); | |
1624 } | |
1625 | |
1626 /* Check dependencies from MM to EX. */ | |
1627 bool | |
1628 nds32_gw_mm_to_ex_p (rtx_insn *producer, rtx_insn *consumer) | |
1629 { | |
1630 rtx def_reg; | |
1631 | |
1632 switch (get_attr_type (producer)) | |
1633 { | |
1634 case TYPE_LOAD: | |
1635 case TYPE_MUL: | |
1636 case TYPE_MAC: | |
1637 case TYPE_DALU64: | |
1638 case TYPE_DMUL: | |
1639 case TYPE_DMAC: | |
1640 case TYPE_DALUROUND: | |
1641 case TYPE_DBPICK: | |
1642 case TYPE_DWEXT: | |
1643 def_reg = SET_DEST (PATTERN (producer)); | |
1644 break; | |
1645 | |
1646 /* Some special instructions, divmodsi4 and udivmodsi4, produce two | |
1647 results, the quotient and the remainder. We have to handle them | |
1648 individually. */ | |
1649 case TYPE_DIV: | |
1650 if (divmod_p (producer)) | |
1651 { | |
1652 rtx def_reg1 = SET_DEST (parallel_element (producer, 0)); | |
1653 rtx def_reg2 = SET_DEST (parallel_element (producer, 1)); | |
1654 | |
1655 return (gw_consumed_by_ex_dep_p (consumer, def_reg1) | |
1656 || gw_consumed_by_ex_dep_p (consumer, def_reg2)); | |
1657 } | |
1658 | |
1659 def_reg = SET_DEST (PATTERN (producer)); | |
1660 break; | |
1661 | |
1662 default: | |
1663 gcc_unreachable (); | |
1664 } | |
1665 | |
1666 return gw_consumed_by_ex_dep_p (consumer, def_reg); | |
1667 } | |
1668 | |
1669 /* Check dependencies from LMW(N, N) to EX. */ | |
1670 bool | |
1671 nds32_gw_last_load_to_ex_p (rtx_insn *producer, rtx_insn *consumer) | |
1672 { | |
1673 rtx last_def_reg = extract_nth_access_reg (producer, -1); | |
1674 | |
1675 return gw_consumed_by_ex_dep_p (consumer, last_def_reg); | |
1676 } | |
1677 | |
1678 /* Guard functions for N12/N13 cores. */ | |
1679 | |
1680 /* Check dependencies from E2 to E1. */ | |
1681 bool | |
1682 nds32_n13_e2_to_e1_p (rtx_insn *producer, rtx_insn *consumer) | |
1683 { | |
1684 rtx def_reg; | |
1685 | |
1686 switch (get_attr_type (producer)) | |
1687 { | |
1688 /* Only post-update load/store instructions are considered. These | |
1689 instructions produces address output at E2. */ | |
1690 case TYPE_LOAD: | |
1691 case TYPE_STORE: | |
1692 case TYPE_LOAD_MULTIPLE: | |
1693 case TYPE_STORE_MULTIPLE: | |
1694 if (!post_update_insn_p (producer)) | |
1695 return false; | |
1696 | |
1697 def_reg = extract_base_reg (producer); | |
1698 break; | |
1699 | |
1700 case TYPE_ALU: | |
1701 case TYPE_ALU_SHIFT: | |
1702 case TYPE_PBSAD: | |
1703 case TYPE_PBSADA: | |
1704 case TYPE_MUL: | |
1705 case TYPE_MAC: | |
1706 def_reg = SET_DEST (PATTERN (producer)); | |
1707 break; | |
1708 | |
1709 case TYPE_BRANCH: | |
1710 return true; | |
1711 | |
1712 case TYPE_DIV: | |
1713 /* Some special instructions, divmodsi4 and udivmodsi4, produce two | |
1714 results, the quotient and the remainder. We have to handle them | |
1715 individually. */ | |
1716 if (divmod_p (producer)) | |
1717 { | |
1718 rtx def_reg1 = SET_DEST (parallel_element (producer, 0)); | |
1719 rtx def_reg2 = SET_DEST (parallel_element (producer, 1)); | |
1720 | |
1721 return (n13_consumed_by_e1_dep_p (consumer, def_reg1) | |
1722 || n13_consumed_by_e1_dep_p (consumer, def_reg2)); | |
1723 } | |
1724 | |
1725 def_reg = SET_DEST (PATTERN (producer)); | |
1726 break; | |
1727 | |
1728 default: | |
1729 gcc_unreachable (); | |
1730 } | |
1731 | |
1732 return n13_consumed_by_e1_dep_p (consumer, def_reg); | |
1733 } | |
1734 | |
1735 /* Check dependencies from Load-Store Unit (E3) to E1. */ | |
1736 bool | |
1737 nds32_n13_load_to_e1_p (rtx_insn *producer, rtx_insn *consumer) | |
1738 { | |
1739 rtx def_reg = SET_DEST (PATTERN (producer)); | |
1740 | |
1741 gcc_assert (get_attr_type (producer) == TYPE_LOAD); | |
1742 gcc_assert (REG_P (def_reg) || GET_CODE (def_reg) == SUBREG); | |
1743 | |
1744 return n13_consumed_by_e1_dep_p (consumer, def_reg); | |
1745 } | |
1746 | |
1747 /* Check dependencies from Load-Store Unit (E3) to E2. */ | |
1748 bool | |
1749 nds32_n13_load_to_e2_p (rtx_insn *producer, rtx_insn *consumer) | |
1750 { | |
1751 rtx def_reg = SET_DEST (PATTERN (producer)); | |
1752 | |
1753 gcc_assert (get_attr_type (producer) == TYPE_LOAD); | |
1754 gcc_assert (REG_P (def_reg) || GET_CODE (def_reg) == SUBREG); | |
1755 | |
1756 return n13_consumed_by_e2_dep_p (consumer, def_reg); | |
1757 } | |
1758 | |
1759 /* Check dependencies from LMW(N, N) to E1. */ | |
1760 bool | |
1761 nds32_n13_last_load_to_e1_p (rtx_insn *producer, rtx_insn *consumer) | |
1762 { | |
1763 rtx last_def_reg = extract_nth_access_reg (producer, -1); | |
1764 | |
1765 return n13_consumed_by_e1_dep_p (consumer, last_def_reg); | |
1766 } | |
1767 | |
1768 /* Check dependencies from LMW(N, N) to E2. */ | |
1769 bool | |
1770 nds32_n13_last_load_to_e2_p (rtx_insn *producer, rtx_insn *consumer) | |
1771 { | |
1772 rtx last_def_reg = extract_nth_access_reg (producer, -1); | |
1773 | |
1774 return n13_consumed_by_e2_dep_p (consumer, last_def_reg); | |
1775 } | |
1776 | |
1777 /* Check dependencies from LMW(N, N-1) to E2. */ | |
1778 bool | |
1779 nds32_n13_last_two_load_to_e1_p (rtx_insn *producer, rtx_insn *consumer) | |
1780 { | |
1781 rtx last_two_def_reg = extract_nth_access_reg (producer, -2); | |
1782 | |
1783 if (last_two_def_reg == NULL_RTX) | |
1784 return false; | |
1785 | |
1786 return n13_consumed_by_e1_dep_p (consumer, last_two_def_reg); | |
1787 } | |
1788 /* ------------------------------------------------------------------------ */ |