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
reg_overlap_p(rtx x,rtx in)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
determine_access_direction(rtx_insn * insn)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
extract_nth_access_rtx(rtx_insn * insn,int n)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
extract_nth_lmsw_access_reg(rtx_insn * insn,int n)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
extract_nth_ls2_access_reg(rtx_insn * insn,int n)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
extract_nth_access_reg(rtx_insn * insn,int index)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
pbsada_insn_ra_rb_dep_reg_p(rtx pbsada_insn,rtx def_reg)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
movd44_even_dep_p(rtx_insn * insn,rtx def_reg)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
n7_consumed_by_ii_dep_p(rtx_insn * consumer,rtx def_reg)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
n8_consumed_by_addr_in_p(rtx_insn * consumer,rtx def_reg)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
n8_consumed_by_ex_p(rtx_insn * consumer,rtx def_reg)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
e8_consumed_by_addr_in_p(rtx_insn * consumer,rtx def_reg)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
e8_consumed_by_ex_p(rtx_insn * consumer,rtx def_reg)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
n9_2r1w_consumed_by_ex_dep_p(rtx_insn * consumer,rtx def_reg)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
n9_3r2w_consumed_by_ex_dep_p(rtx_insn * consumer,rtx def_reg)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
nds32_n7_load_to_ii_p(rtx_insn * producer,rtx_insn * consumer)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
nds32_n7_last_load_to_ii_p(rtx_insn * producer,rtx_insn * consumer)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
nds32_n8_load_to_ii_p(rtx_insn * producer,rtx_insn * consumer)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
nds32_n8_load_bi_to_ii_p(rtx_insn * producer,rtx_insn * consumer)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
nds32_n8_load_to_ex_p(rtx_insn * producer,rtx_insn * consumer)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
nds32_n8_ex_to_ii_p(rtx_insn * producer,rtx_insn * consumer)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
nds32_n8_last_load_to_ii_p(rtx_insn * producer,rtx_insn * consumer)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
nds32_n8_last_load_two_to_ii_p(rtx_insn * producer,rtx_insn * consumer)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
nds32_n8_last_load_to_ex_p(rtx_insn * producer,rtx_insn * consumer)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
nds32_e8_load_to_ii_p(rtx_insn * producer,rtx_insn * consumer)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
nds32_e8_load_to_ex_p(rtx_insn * producer,rtx_insn * consumer)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
nds32_e8_ex_to_ii_p(rtx_insn * producer,rtx_insn * consumer)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
nds32_e8_last_load_to_ii_p(rtx_insn * producer,rtx_insn * consumer)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
nds32_e8_last_load_to_ex_p(rtx_insn * producer,rtx_insn * consumer)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
nds32_n9_2r1w_mm_to_ex_p(rtx_insn * producer,rtx_insn * consumer)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
nds32_n9_3r2w_mm_to_ex_p(rtx_insn * producer,rtx_insn * consumer)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
nds32_n9_last_load_to_ex_p(rtx_insn * producer,rtx_insn * consumer)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 /* ------------------------------------------------------------------------ */
1136