]> git.ipfire.org Git - thirdparty/gcc.git/blob - gcc/config/nds32/nds32-pipelines-auxiliary.c
[NDS32] Implement n7 pipeline.
[thirdparty/gcc.git] / gcc / config / nds32 / nds32-pipelines-auxiliary.c
1 /* Auxiliary functions for pipeline descriptions pattern of Andes
2 NDS32 cpu for GNU compiler
3 Copyright (C) 2012-2018 Free Software Foundation, Inc.
4 Contributed by Andes Technology Corporation.
5
6 This file is part of GCC.
7
8 GCC is free software; you can redistribute it and/or modify it
9 under the terms of the GNU General Public License as published
10 by the Free Software Foundation; either version 3, or (at your
11 option) any later version.
12
13 GCC is distributed in the hope that it will be useful, but WITHOUT
14 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
15 or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
16 License for more details.
17
18 You should have received a copy of the GNU General Public License
19 along with GCC; see the file COPYING3. If not see
20 <http://www.gnu.org/licenses/>. */
21
22 /* ------------------------------------------------------------------------ */
23
24 #define IN_TARGET_CODE 1
25
26 #include "config.h"
27 #include "system.h"
28 #include "coretypes.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"
36
37 /* ------------------------------------------------------------------------ */
38
39 namespace nds32 {
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 /* Check if INSN is a movd44 insn consuming DEF_REG. */
310 bool
311 movd44_even_dep_p (rtx_insn *insn, rtx def_reg)
312 {
313 if (!movd44_insn_p (insn))
314 return false;
315
316 rtx use_rtx = SET_SRC (PATTERN (insn));
317
318 if (REG_P (def_reg))
319 {
320 return rtx_equal_p (def_reg, use_rtx);
321 }
322 else if (GET_CODE (def_reg) == SUBREG
323 && GET_MODE (def_reg) == SImode
324 && rtx_equal_p (SUBREG_REG (def_reg), use_rtx))
325 {
326 if (TARGET_BIG_ENDIAN && SUBREG_BYTE (def_reg) == 4)
327 return true;
328
329 if (!TARGET_BIG_ENDIAN && SUBREG_BYTE (def_reg) == 0)
330 return true;
331
332 return false;
333 }
334
335 return false;
336 }
337
338 } // namespace scheduling
339 } // namespace nds32
340
341 /* ------------------------------------------------------------------------ */
342
343 using namespace nds32;
344 using namespace nds32::scheduling;
345
346 namespace { // anonymous namespace
347
348 /* Check the dependency between the producer defining DEF_REG and CONSUMER
349 requiring input operand at II. */
350 bool
351 n7_consumed_by_ii_dep_p (rtx_insn *consumer, rtx def_reg)
352 {
353 rtx use_rtx;
354
355 switch (get_attr_type (consumer))
356 {
357 /* MOVD44_E */
358 case TYPE_ALU:
359 if (movd44_even_dep_p (consumer, def_reg))
360 return true;
361
362 use_rtx = SET_SRC (PATTERN (consumer));
363 break;
364
365 case TYPE_MUL:
366 use_rtx = SET_SRC (PATTERN (consumer));
367 break;
368
369 case TYPE_MAC:
370 use_rtx = extract_mac_non_acc_rtx (consumer);
371 break;
372
373 /* Some special instructions, divmodsi4 and udivmodsi4, produce two
374 results, the quotient and the remainder. It requires two micro-
375 operations in order to write two registers. We have to check the
376 dependency from the producer to the first micro-operation. */
377 case TYPE_DIV:
378 if (INSN_CODE (consumer) == CODE_FOR_divmodsi4
379 || INSN_CODE (consumer) == CODE_FOR_udivmodsi4)
380 use_rtx = SET_SRC (parallel_element (consumer, 0));
381 else
382 use_rtx = SET_SRC (PATTERN (consumer));
383 break;
384
385 case TYPE_LOAD:
386 /* ADDR_IN_bi_Ra, ADDR_IN_!bi */
387 if (post_update_insn_p (consumer))
388 use_rtx = extract_base_reg (consumer);
389 else
390 use_rtx = extract_mem_rtx (consumer);
391 break;
392
393 case TYPE_STORE:
394 /* ADDR_IN_bi_Ra, ADDR_IN_!bi */
395 if (post_update_insn_p (consumer))
396 use_rtx = extract_base_reg (consumer);
397 else
398 use_rtx = extract_mem_rtx (consumer);
399
400 if (reg_overlap_p (def_reg, use_rtx))
401 return true;
402
403 /* ST_bi, ST_!bi_RI */
404 if (!post_update_insn_p (consumer)
405 && !immed_offset_p (extract_mem_rtx (consumer)))
406 return false;
407
408 use_rtx = SET_SRC (PATTERN (consumer));
409 break;
410
411 case TYPE_LOAD_MULTIPLE:
412 use_rtx = extract_base_reg (consumer);
413 break;
414
415 case TYPE_STORE_MULTIPLE:
416 /* ADDR_IN */
417 use_rtx = extract_base_reg (consumer);
418 if (reg_overlap_p (def_reg, use_rtx))
419 return true;
420
421 /* SMW (N, 1) */
422 use_rtx = extract_nth_access_rtx (consumer, 0);
423 break;
424
425 case TYPE_BRANCH:
426 use_rtx = PATTERN (consumer);
427 break;
428
429 default:
430 gcc_unreachable ();
431 }
432
433 if (reg_overlap_p (def_reg, use_rtx))
434 return true;
435
436 return false;
437 }
438
439 /* Check the dependency between the producer defining DEF_REG and CONSUMER
440 requiring input operand at AG (II). */
441 bool
442 n8_consumed_by_addr_in_p (rtx_insn *consumer, rtx def_reg)
443 {
444 rtx use_rtx;
445
446 switch (get_attr_type (consumer))
447 {
448 case TYPE_BRANCH:
449 use_rtx = extract_branch_target_rtx (consumer);
450 break;
451
452 case TYPE_LOAD:
453 if (load_single_p (consumer))
454 use_rtx = extract_mem_rtx (consumer);
455 else
456 use_rtx = extract_base_reg (consumer);
457 break;
458
459 case TYPE_STORE:
460 if (store_single_p (consumer)
461 && (!post_update_insn_p (consumer)
462 || immed_offset_p (extract_mem_rtx (consumer))))
463 use_rtx = extract_mem_rtx (consumer);
464 else
465 use_rtx = extract_base_reg (consumer);
466 break;
467
468 case TYPE_LOAD_MULTIPLE:
469 case TYPE_STORE_MULTIPLE:
470 use_rtx = extract_base_reg (consumer);
471 break;
472
473 default:
474 gcc_unreachable ();
475 }
476
477 return reg_overlap_p (def_reg, use_rtx);
478 }
479
480 /* Check the dependency between the producer defining DEF_REG and CONSUMER
481 requiring input operand at EX. */
482 bool
483 n8_consumed_by_ex_p (rtx_insn *consumer, rtx def_reg)
484 {
485 rtx use_rtx;
486
487 switch (get_attr_type (consumer))
488 {
489 case TYPE_ALU:
490 if (movd44_even_dep_p (consumer, def_reg))
491 return true;
492
493 use_rtx = SET_SRC (PATTERN (consumer));
494 break;
495
496 case TYPE_MUL:
497 use_rtx = SET_SRC (PATTERN (consumer));
498 break;
499
500 case TYPE_MAC:
501 use_rtx = extract_mac_non_acc_rtx (consumer);
502 break;
503
504 /* Some special instructions, divmodsi4 and udivmodsi4, produce two
505 results, the quotient and the remainder. It requires two micro-
506 operations in order to write two registers. We have to check the
507 dependency from the producer to the first micro-operation. */
508 case TYPE_DIV:
509 if (INSN_CODE (consumer) == CODE_FOR_divmodsi4
510 || INSN_CODE (consumer) == CODE_FOR_udivmodsi4)
511 use_rtx = SET_SRC (parallel_element (consumer, 0));
512 else
513 use_rtx = SET_SRC (PATTERN (consumer));
514 break;
515
516 case TYPE_BRANCH:
517 use_rtx = extract_branch_condition_rtx (consumer);
518 break;
519
520 case TYPE_STORE:
521 /* exclude ST_!bi_RR */
522 if (!post_update_insn_p (consumer)
523 && !immed_offset_p (extract_mem_rtx (consumer)))
524 return false;
525
526 use_rtx = SET_SRC (PATTERN (consumer));
527 break;
528
529 case TYPE_STORE_MULTIPLE:
530 use_rtx = extract_nth_access_rtx (consumer, 0);
531 break;
532
533 default:
534 gcc_unreachable ();
535 }
536
537 return reg_overlap_p (def_reg, use_rtx);
538 }
539
540 /* Check the dependency between the producer defining DEF_REG and CONSUMER
541 requiring input operand at AG (II). */
542 bool
543 e8_consumed_by_addr_in_p (rtx_insn *consumer, rtx def_reg)
544 {
545 return n8_consumed_by_addr_in_p (consumer, def_reg);
546 }
547
548 /* Check the dependency between the producer defining DEF_REG and CONSUMER
549 requiring input operand at EX. */
550 bool
551 e8_consumed_by_ex_p (rtx_insn *consumer, rtx def_reg)
552 {
553 rtx use_rtx;
554
555 switch (get_attr_type (consumer))
556 {
557 case TYPE_ALU:
558 case TYPE_STORE:
559 use_rtx = SET_SRC (PATTERN (consumer));
560 break;
561
562 case TYPE_MUL:
563 case TYPE_MAC:
564 case TYPE_DIV:
565 case TYPE_BRANCH:
566 case TYPE_STORE_MULTIPLE:
567 return n8_consumed_by_ex_p (consumer, def_reg);
568
569 default:
570 gcc_unreachable ();
571 }
572
573 return reg_overlap_p (def_reg, use_rtx);
574 }
575
576 /* Check the dependency between the producer defining DEF_REG and CONSUMER
577 requiring input operand at EX. */
578 bool
579 n9_2r1w_consumed_by_ex_dep_p (rtx_insn *consumer, rtx def_reg)
580 {
581 rtx use_rtx;
582
583 switch (get_attr_type (consumer))
584 {
585 case TYPE_ALU:
586 if (movd44_even_dep_p (consumer, def_reg))
587 return true;
588
589 use_rtx = SET_SRC (PATTERN (consumer));
590 break;
591
592 case TYPE_PBSAD:
593 case TYPE_MUL:
594 use_rtx = SET_SRC (PATTERN (consumer));
595 break;
596
597 case TYPE_ALU_SHIFT:
598 use_rtx = extract_shift_reg (consumer);
599 break;
600
601 case TYPE_PBSADA:
602 return pbsada_insn_ra_rb_dep_reg_p (consumer, def_reg);
603
604 case TYPE_MAC:
605 use_rtx = PATTERN (consumer);
606 break;
607
608 case TYPE_DIV:
609 if (INSN_CODE (consumer) == CODE_FOR_divmodsi4
610 || INSN_CODE (consumer) == CODE_FOR_udivmodsi4)
611 use_rtx = SET_SRC (parallel_element (consumer, 0));
612 else
613 use_rtx = SET_SRC (PATTERN (consumer));
614 break;
615
616 case TYPE_MMU:
617 if (GET_CODE (PATTERN (consumer)) == SET)
618 use_rtx = SET_SRC (PATTERN (consumer));
619 else
620 return true;
621 break;
622
623 case TYPE_LOAD:
624 /* ADDR_IN_bi_Ra, ADDR_IN_!bi */
625 if (post_update_insn_p (consumer))
626 use_rtx = extract_base_reg (consumer);
627 else
628 use_rtx = extract_mem_rtx (consumer);
629 break;
630
631 case TYPE_STORE:
632 /* ADDR_IN_bi_Ra, ADDR_IN_!bi */
633 if (post_update_insn_p (consumer))
634 use_rtx = extract_base_reg (consumer);
635 else
636 use_rtx = extract_mem_rtx (consumer);
637
638 if (reg_overlap_p (def_reg, use_rtx))
639 return true;
640
641 /* exclude ST_!bi_RR */
642 if (!post_update_insn_p (consumer)
643 && !immed_offset_p (extract_mem_rtx (consumer)))
644 return false;
645
646 use_rtx = SET_SRC (PATTERN (consumer));
647 break;
648
649 case TYPE_LOAD_MULTIPLE:
650 use_rtx = extract_base_reg (consumer);
651 break;
652
653 case TYPE_STORE_MULTIPLE:
654 /* ADDR_IN */
655 use_rtx = extract_base_reg (consumer);
656 if (reg_overlap_p (def_reg, use_rtx))
657 return true;
658
659 /* SMW (N, 1) */
660 use_rtx = extract_nth_access_rtx (consumer, 0);
661 break;
662
663 case TYPE_BRANCH:
664 use_rtx = PATTERN (consumer);
665 break;
666
667 default:
668 gcc_unreachable ();
669 }
670
671 if (reg_overlap_p (def_reg, use_rtx))
672 return true;
673
674 return false;
675 }
676
677 /* Check the dependency between the producer defining DEF_REG and CONSUMER
678 requiring input operand at EX. */
679 bool
680 n9_3r2w_consumed_by_ex_dep_p (rtx_insn *consumer, rtx def_reg)
681 {
682 rtx use_rtx;
683
684 switch (get_attr_type (consumer))
685 {
686 case TYPE_ALU:
687 case TYPE_PBSAD:
688 case TYPE_MUL:
689 use_rtx = SET_SRC (PATTERN (consumer));
690 break;
691
692 case TYPE_ALU_SHIFT:
693 use_rtx = extract_shift_reg (consumer);
694 break;
695
696 case TYPE_PBSADA:
697 return pbsada_insn_ra_rb_dep_reg_p (consumer, def_reg);
698
699 case TYPE_MAC:
700 use_rtx = extract_mac_non_acc_rtx (consumer);
701 break;
702
703 /* Some special instructions, divmodsi4 and udivmodsi4, produce two
704 results, the quotient and the remainder. In 2R1W configuration,
705 it requires two micro-operations in order to write two registers.
706 We have to check the dependency from the producer to the first
707 micro-operation. */
708 case TYPE_DIV:
709 if (INSN_CODE (consumer) == CODE_FOR_divmodsi4
710 || INSN_CODE (consumer) == CODE_FOR_udivmodsi4)
711 use_rtx = SET_SRC (parallel_element (consumer, 0));
712 else
713 use_rtx = SET_SRC (PATTERN (consumer));
714 break;
715
716 case TYPE_MMU:
717 if (GET_CODE (PATTERN (consumer)) == SET)
718 use_rtx = SET_SRC (PATTERN (consumer));
719 else
720 return true;
721 break;
722
723 case TYPE_LOAD:
724 case TYPE_STORE:
725 use_rtx = extract_mem_rtx (consumer);
726 break;
727
728 case TYPE_LOAD_MULTIPLE:
729 case TYPE_STORE_MULTIPLE:
730 use_rtx = extract_base_reg (consumer);
731 break;
732
733 case TYPE_BRANCH:
734 use_rtx = PATTERN (consumer);
735 break;
736
737 default:
738 gcc_unreachable ();
739 }
740
741 if (reg_overlap_p (def_reg, use_rtx))
742 return true;
743
744 return false;
745 }
746
747
748 } // anonymous namespace
749
750 /* ------------------------------------------------------------------------ */
751
752 /* Guard functions for N7 core. */
753
754 bool
755 nds32_n7_load_to_ii_p (rtx_insn *producer, rtx_insn *consumer)
756 {
757 if (post_update_insn_p (producer))
758 return false;
759
760 rtx def_reg = SET_DEST (PATTERN (producer));
761
762 return n7_consumed_by_ii_dep_p (consumer, def_reg);
763 }
764
765 bool
766 nds32_n7_last_load_to_ii_p (rtx_insn *producer, rtx_insn *consumer)
767 {
768 /* If PRODUCER is a post-update LMW insn, the last micro-operation updates
769 the base register and the result is ready in II stage, so we don't need
770 to handle that case in this guard function and the corresponding bypass
771 rule. */
772 if (post_update_insn_p (producer))
773 return false;
774
775 rtx last_def_reg = extract_nth_access_reg (producer, -1);
776
777 if (last_def_reg == NULL_RTX)
778 return false;
779
780 gcc_assert (REG_P (last_def_reg) || GET_CODE (last_def_reg) == SUBREG);
781
782 return n7_consumed_by_ii_dep_p (consumer, last_def_reg);
783 }
784
785 /* Guard functions for N8 core. */
786
787 bool
788 nds32_n8_load_to_ii_p (rtx_insn *producer, rtx_insn *consumer)
789 {
790 if (post_update_insn_p (producer))
791 return false;
792
793 rtx def_reg = SET_DEST (PATTERN (producer));
794
795 return n8_consumed_by_addr_in_p (consumer, def_reg);
796 }
797
798 bool
799 nds32_n8_load_bi_to_ii_p (rtx_insn *producer, rtx_insn *consumer)
800 {
801 if (!post_update_insn_p (producer))
802 return false;
803
804 rtx def_reg = SET_DEST (PATTERN (producer));
805
806 return n8_consumed_by_addr_in_p (consumer, def_reg);
807 }
808
809 bool
810 nds32_n8_load_to_ex_p (rtx_insn *producer, rtx_insn *consumer)
811 {
812 if (post_update_insn_p (producer))
813 return false;
814
815 rtx def_reg = SET_DEST (PATTERN (producer));
816
817 return n8_consumed_by_ex_p (consumer, def_reg);
818 }
819
820 bool
821 nds32_n8_ex_to_ii_p (rtx_insn *producer, rtx_insn *consumer)
822 {
823 rtx def_reg;
824
825 switch (get_attr_type (producer))
826 {
827 case TYPE_ALU:
828 if (movd44_insn_p (producer))
829 def_reg = extract_movd44_odd_reg (producer);
830 else
831 def_reg = SET_DEST (PATTERN (producer));
832 break;
833
834 case TYPE_MUL:
835 case TYPE_MAC:
836 def_reg = SET_DEST (PATTERN (producer));
837 break;
838
839 case TYPE_DIV:
840 if (INSN_CODE (producer) == CODE_FOR_divmodsi4
841 || INSN_CODE (producer) == CODE_FOR_udivmodsi4)
842 def_reg = SET_DEST (parallel_element (producer, 1));
843 else
844 def_reg = SET_DEST (PATTERN (producer));
845 break;
846
847 case TYPE_LOAD:
848 case TYPE_STORE:
849 case TYPE_LOAD_MULTIPLE:
850 case TYPE_STORE_MULTIPLE:
851 if (!post_update_insn_p (producer))
852 return false;
853
854 def_reg = extract_base_reg (producer);
855 break;
856
857 default:
858 gcc_unreachable ();
859 }
860
861 return n8_consumed_by_addr_in_p (consumer, def_reg);
862 }
863
864 bool
865 nds32_n8_last_load_to_ii_p (rtx_insn *producer, rtx_insn *consumer)
866 {
867 /* If PRODUCER is a post-update LMW insn, the last micro-operation updates
868 the base register and the result is ready in EX stage, so we don't need
869 to handle that case in this guard function and the corresponding bypass
870 rule. */
871 if (post_update_insn_p (producer))
872 return false;
873
874 rtx last_def_reg = extract_nth_access_reg (producer, -1);
875
876 if (last_def_reg == NULL_RTX)
877 return false;
878
879 gcc_assert (REG_P (last_def_reg) || GET_CODE (last_def_reg) == SUBREG);
880
881 return n8_consumed_by_addr_in_p (consumer, last_def_reg);
882 }
883
884 bool
885 nds32_n8_last_load_two_to_ii_p (rtx_insn *producer, rtx_insn *consumer)
886 {
887 int index = -2;
888
889 /* If PRODUCER is a post-update insn, there is an additional one micro-
890 operation inserted in the end, so the last memory access operation should
891 be handled by this guard function and the corresponding bypass rule. */
892 if (post_update_insn_p (producer))
893 index = -1;
894
895 rtx last_two_def_reg = extract_nth_access_reg (producer, index);
896
897 if (last_two_def_reg == NULL_RTX)
898 return false;
899
900 gcc_assert (REG_P (last_two_def_reg)
901 || GET_CODE (last_two_def_reg) == SUBREG);
902
903 return n8_consumed_by_addr_in_p (consumer, last_two_def_reg);
904 }
905
906 bool
907 nds32_n8_last_load_to_ex_p (rtx_insn *producer, rtx_insn *consumer)
908 {
909 /* If PRODUCER is a post-update LMW insn, the last micro-operation updates
910 the base register and the result is ready in EX stage, so we don't need
911 to handle that case in this guard function and the corresponding bypass
912 rule. */
913 if (post_update_insn_p (producer))
914 return false;
915
916 rtx last_def_reg = extract_nth_access_reg (producer, -1);
917
918 if (last_def_reg == NULL_RTX)
919 return false;
920
921 gcc_assert (REG_P (last_def_reg) || GET_CODE (last_def_reg) == SUBREG);
922
923 return n8_consumed_by_ex_p (consumer, last_def_reg);
924 }
925
926 /* Guard functions for E8 cores. */
927
928 bool
929 nds32_e8_load_to_ii_p (rtx_insn *producer, rtx_insn *consumer)
930 {
931 rtx def_reg = SET_DEST (PATTERN (producer));
932
933 return e8_consumed_by_addr_in_p (consumer, def_reg);
934 }
935
936 bool
937 nds32_e8_load_to_ex_p (rtx_insn *producer, rtx_insn *consumer)
938 {
939 rtx def_reg = SET_DEST (PATTERN (producer));
940
941 return e8_consumed_by_ex_p (consumer, def_reg);
942 }
943
944 bool
945 nds32_e8_ex_to_ii_p (rtx_insn *producer, rtx_insn *consumer)
946 {
947 rtx def_reg;
948
949 switch (get_attr_type (producer))
950 {
951 case TYPE_ALU:
952 /* No data hazards if AGEN's input is produced by MOVI or SETHI. */
953 if (GET_CODE (PATTERN (producer)) == SET)
954 {
955 rtx dest = SET_DEST (PATTERN (producer));
956 rtx src = SET_SRC (PATTERN (producer));
957
958 if ((REG_P (dest) || GET_CODE (dest) == SUBREG)
959 && (GET_CODE (src) == CONST_INT || GET_CODE (src) == HIGH))
960 return false;
961 }
962
963 def_reg = SET_DEST (PATTERN (producer));
964 break;
965
966 case TYPE_MUL:
967 case TYPE_MAC:
968 def_reg = SET_DEST (PATTERN (producer));
969 break;
970
971 case TYPE_DIV:
972 if (INSN_CODE (producer) == CODE_FOR_divmodsi4
973 || INSN_CODE (producer) == CODE_FOR_udivmodsi4)
974 {
975 rtx def_reg1 = SET_DEST (parallel_element (producer, 0));
976 rtx def_reg2 = SET_DEST (parallel_element (producer, 1));
977
978 return (e8_consumed_by_addr_in_p (consumer, def_reg1)
979 || e8_consumed_by_addr_in_p (consumer, def_reg2));
980 }
981
982 def_reg = SET_DEST (PATTERN (producer));
983 break;
984
985 case TYPE_LOAD:
986 case TYPE_STORE:
987 case TYPE_LOAD_MULTIPLE:
988 case TYPE_STORE_MULTIPLE:
989 if (!post_update_insn_p (producer))
990 return false;
991
992 def_reg = extract_base_reg (producer);
993 break;
994
995 default:
996 gcc_unreachable ();
997 }
998
999 return e8_consumed_by_addr_in_p (consumer, def_reg);
1000 }
1001
1002 bool
1003 nds32_e8_last_load_to_ii_p (rtx_insn *producer, rtx_insn *consumer)
1004 {
1005 rtx last_def_reg = extract_nth_access_reg (producer, -1);
1006
1007 if (last_def_reg == NULL_RTX)
1008 return false;
1009
1010 gcc_assert (REG_P (last_def_reg) || GET_CODE (last_def_reg) == SUBREG);
1011
1012 return e8_consumed_by_addr_in_p (consumer, last_def_reg);
1013 }
1014
1015 bool
1016 nds32_e8_last_load_to_ex_p (rtx_insn *producer, rtx_insn *consumer)
1017 {
1018 rtx last_def_reg = extract_nth_access_reg (producer, -1);
1019
1020 if (last_def_reg == NULL_RTX)
1021 return false;
1022
1023 gcc_assert (REG_P (last_def_reg) || GET_CODE (last_def_reg) == SUBREG);
1024
1025 return e8_consumed_by_ex_p (consumer, last_def_reg);
1026 }
1027
1028 /* Guard functions for N9 cores. */
1029
1030 /* Check dependencies from MM to EX. */
1031 bool
1032 nds32_n9_2r1w_mm_to_ex_p (rtx_insn *producer, rtx_insn *consumer)
1033 {
1034 rtx def_reg;
1035
1036 switch (get_attr_type (producer))
1037 {
1038 /* LD_!bi */
1039 case TYPE_LOAD:
1040 if (post_update_insn_p (producer))
1041 return false;
1042
1043 def_reg = SET_DEST (PATTERN (producer));
1044 break;
1045
1046 case TYPE_MUL:
1047 case TYPE_MAC:
1048 def_reg = SET_DEST (PATTERN (producer));
1049 break;
1050
1051 default:
1052 gcc_unreachable ();
1053 }
1054
1055 return n9_2r1w_consumed_by_ex_dep_p (consumer, def_reg);
1056 }
1057
1058 /* Check dependencies from MM to EX. */
1059 bool
1060 nds32_n9_3r2w_mm_to_ex_p (rtx_insn *producer, rtx_insn *consumer)
1061 {
1062 rtx def_reg;
1063
1064 switch (get_attr_type (producer))
1065 {
1066 case TYPE_LOAD:
1067 case TYPE_MUL:
1068 case TYPE_MAC:
1069 def_reg = SET_DEST (PATTERN (producer));
1070 break;
1071
1072 /* Some special instructions, divmodsi4 and udivmodsi4, produce two
1073 results, the quotient and the remainder. We have to handle them
1074 individually. */
1075 case TYPE_DIV:
1076 if (INSN_CODE (producer) == CODE_FOR_divmodsi4
1077 || INSN_CODE (producer) == CODE_FOR_udivmodsi4)
1078 {
1079 rtx def_reg1 = SET_DEST (parallel_element (producer, 0));
1080 rtx def_reg2 = SET_DEST (parallel_element (producer, 1));
1081
1082 return (n9_3r2w_consumed_by_ex_dep_p (consumer, def_reg1)
1083 || n9_3r2w_consumed_by_ex_dep_p (consumer, def_reg2));
1084 }
1085
1086 def_reg = SET_DEST (PATTERN (producer));
1087 break;
1088
1089 default:
1090 gcc_unreachable ();
1091 }
1092
1093 return n9_3r2w_consumed_by_ex_dep_p (consumer, def_reg);
1094 }
1095
1096 /* Check dependencies from LMW(N, N) to EX. */
1097 bool
1098 nds32_n9_last_load_to_ex_p (rtx_insn *producer, rtx_insn *consumer)
1099 {
1100 rtx last_def_reg = extract_nth_access_reg (producer, -1);
1101
1102 if (nds32_register_ports_config == REG_PORT_2R1W)
1103 {
1104 /* The base-update micro operation occupies the last cycle. */
1105 if (post_update_insn_p (producer))
1106 return false;
1107
1108 /* When the base register is in the list of a load multiple insn and the
1109 access order of the base register is not the last one, we need an
1110 additional micro operation to commit the load result to the base
1111 register -- we can treat the base register as the last defined
1112 register. */
1113 size_t i;
1114 size_t n_elems = parallel_elements (producer);
1115 rtx base_reg = extract_base_reg (producer);
1116
1117 for (i = 0; i < n_elems; ++i)
1118 {
1119 rtx load_rtx = extract_nth_access_rtx (producer, i);
1120 rtx list_element = SET_DEST (load_rtx);
1121
1122 if (rtx_equal_p (base_reg, list_element) && i != n_elems - 1)
1123 {
1124 last_def_reg = base_reg;
1125 break;
1126 }
1127 }
1128
1129 return n9_2r1w_consumed_by_ex_dep_p (consumer, last_def_reg);
1130 }
1131 else
1132 return n9_3r2w_consumed_by_ex_dep_p (consumer, last_def_reg);
1133 }
1134
1135 /* ------------------------------------------------------------------------ */