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 /* ------------------------------------------------------------------------ */