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.
6 This file is part of GCC.
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.
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.
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/>. */
22 /* ------------------------------------------------------------------------ */
24 #define IN_TARGET_CODE 1
28 #include "coretypes.h"
31 #include "insn-attr.h"
32 #include "insn-codes.h"
35 #include "nds32-protos.h"
37 /* ------------------------------------------------------------------------ */
40 namespace scheduling
{
42 /* Classify the memory access direction. It's unknown if the offset register
43 is not a constant value. */
44 enum memory_access_direction
48 MEM_ACCESS_DIR_UNKNOWN
51 /* A safe wrapper to the function reg_overlap_mentioned_p (). */
53 reg_overlap_p (rtx x
, rtx in
)
55 if (x
== NULL_RTX
|| in
== NULL_RTX
)
58 return static_cast <bool> (reg_overlap_mentioned_p (x
, in
));
62 /* Determine the memory access direction of a load/store insn. */
63 memory_access_direction
64 determine_access_direction (rtx_insn
*insn
)
66 int post_update_rtx_index
;
71 switch (get_attr_type (insn
))
73 case TYPE_LOAD_MULTIPLE
:
74 gcc_assert (parallel_elements (insn
) >= 2);
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
));
82 [(set (reg) (mem (reg))) : index 0
83 (set (reg) (mem (plus (reg) (...)))) : index 1
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);
93 case TYPE_STORE_MULTIPLE
:
94 gcc_assert (parallel_elements (insn
) >= 2);
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
));
102 [(set (mem (reg)) (reg)) : index 0
103 (set (mem (plus (reg) (...))) (reg)) : index 1
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);
115 mem_rtx
= extract_mem_rtx (insn
);
117 switch (GET_CODE (XEXP (mem_rtx
, 0)))
120 /* (mem (post_inc (...))) */
121 return MEM_ACCESS_DIR_POS
;
124 /* (mem (post_dec (...))) */
125 return MEM_ACCESS_DIR_NEG
;
128 /* (mem (plus (reg) (...))) */
129 plus_rtx
= XEXP (mem_rtx
, 0);
133 /* (mem (post_modify (reg) (plus (reg) (...)))) */
134 plus_rtx
= XEXP (XEXP (mem_rtx
, 0), 1);
146 gcc_assert (GET_CODE (plus_rtx
) == PLUS
);
148 offset_rtx
= XEXP (plus_rtx
, 1);
149 if (GET_CODE (offset_rtx
) == CONST_INT
)
151 if (INTVAL (offset_rtx
) < 0)
152 return MEM_ACCESS_DIR_NEG
;
154 return MEM_ACCESS_DIR_POS
;
157 return MEM_ACCESS_DIR_UNKNOWN
;
160 /* Return the nth load/store operation in the real micro-operation
163 extract_nth_access_rtx (rtx_insn
*insn
, int n
)
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
);
169 gcc_assert (direction
!= MEM_ACCESS_DIR_UNKNOWN
);
171 /* Reverse the order if the direction negative. */
172 if (direction
== MEM_ACCESS_DIR_NEG
)
175 if (post_update_rtx_index
!= -1)
177 if (n
>= 0 && post_update_rtx_index
<= n
)
179 else if (n
< 0 && post_update_rtx_index
>= n
+ n_elems
)
183 return parallel_element (insn
, n
);
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. */
190 extract_nth_lmsw_access_reg (rtx_insn
*insn
, int n
)
192 rtx nth_rtx
= extract_nth_access_rtx (insn
, n
);
194 if (nth_rtx
== NULL_RTX
)
197 switch (get_attr_type (insn
))
199 case TYPE_LOAD_MULTIPLE
:
200 return SET_DEST (nth_rtx
);
202 case TYPE_STORE_MULTIPLE
:
203 return SET_SRC (nth_rtx
);
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. */
214 extract_nth_ls2_access_reg (rtx_insn
*insn
, int n
)
219 if (post_update_insn_p (insn
))
221 memory_access_direction direction
= determine_access_direction (insn
);
222 gcc_assert (direction
!= MEM_ACCESS_DIR_UNKNOWN
);
224 /* Reverse the order if the direction negative. */
225 if (direction
== MEM_ACCESS_DIR_NEG
)
229 /* Handle the out-of-range case. */
233 /* Convert the index to a positive one. */
237 switch (get_attr_type (insn
))
240 reg
= SET_DEST (PATTERN (insn
));
244 reg
= SET_SRC (PATTERN (insn
));
251 gcc_assert (REG_P (reg
) || GET_CODE (reg
) == SUBREG
);
253 switch (GET_MODE (reg
))
268 return gen_lowpart (mode
, reg
);
270 return gen_highpart (mode
, reg
);
273 /* Returns the register operated by the nth load/store operation in the real
274 micro-operation accessing order. */
276 extract_nth_access_reg (rtx_insn
*insn
, int index
)
278 switch (GET_CODE (PATTERN (insn
)))
281 return extract_nth_lmsw_access_reg (insn
, index
);
284 return extract_nth_ls2_access_reg (insn
, index
);
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. */
294 pbsada_insn_ra_rb_dep_reg_p (rtx pbsada_insn
, rtx def_reg
)
296 rtx unspec_rtx
= SET_SRC (PATTERN (pbsada_insn
));
297 gcc_assert (GET_CODE (unspec_rtx
) == UNSPEC
);
299 rtx pbsada_ra
= XVECEXP (unspec_rtx
, 0, 0);
300 rtx pbsada_rb
= XVECEXP (unspec_rtx
, 0, 1);
302 if (rtx_equal_p (def_reg
, pbsada_ra
)
303 || rtx_equal_p (def_reg
, pbsada_rb
))
309 /* Check if INSN is a movd44 insn consuming DEF_REG. */
311 movd44_even_dep_p (rtx_insn
*insn
, rtx def_reg
)
313 if (!movd44_insn_p (insn
))
316 rtx use_rtx
= SET_SRC (PATTERN (insn
));
320 return rtx_equal_p (def_reg
, use_rtx
);
322 else if (GET_CODE (def_reg
) == SUBREG
323 && GET_MODE (def_reg
) == SImode
324 && rtx_equal_p (SUBREG_REG (def_reg
), use_rtx
))
326 if (TARGET_BIG_ENDIAN
&& SUBREG_BYTE (def_reg
) == 4)
329 if (!TARGET_BIG_ENDIAN
&& SUBREG_BYTE (def_reg
) == 0)
338 } // namespace scheduling
341 /* ------------------------------------------------------------------------ */
343 using namespace nds32
;
344 using namespace nds32::scheduling
;
346 namespace { // anonymous namespace
348 /* Check the dependency between the producer defining DEF_REG and CONSUMER
349 requiring input operand at II. */
351 n7_consumed_by_ii_dep_p (rtx_insn
*consumer
, rtx def_reg
)
355 switch (get_attr_type (consumer
))
359 if (movd44_even_dep_p (consumer
, def_reg
))
362 use_rtx
= SET_SRC (PATTERN (consumer
));
366 use_rtx
= SET_SRC (PATTERN (consumer
));
370 use_rtx
= extract_mac_non_acc_rtx (consumer
);
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. */
378 if (INSN_CODE (consumer
) == CODE_FOR_divmodsi4
379 || INSN_CODE (consumer
) == CODE_FOR_udivmodsi4
)
380 use_rtx
= SET_SRC (parallel_element (consumer
, 0));
382 use_rtx
= SET_SRC (PATTERN (consumer
));
386 /* ADDR_IN_bi_Ra, ADDR_IN_!bi */
387 if (post_update_insn_p (consumer
))
388 use_rtx
= extract_base_reg (consumer
);
390 use_rtx
= extract_mem_rtx (consumer
);
394 /* ADDR_IN_bi_Ra, ADDR_IN_!bi */
395 if (post_update_insn_p (consumer
))
396 use_rtx
= extract_base_reg (consumer
);
398 use_rtx
= extract_mem_rtx (consumer
);
400 if (reg_overlap_p (def_reg
, use_rtx
))
403 /* ST_bi, ST_!bi_RI */
404 if (!post_update_insn_p (consumer
)
405 && !immed_offset_p (extract_mem_rtx (consumer
)))
408 use_rtx
= SET_SRC (PATTERN (consumer
));
411 case TYPE_LOAD_MULTIPLE
:
412 use_rtx
= extract_base_reg (consumer
);
415 case TYPE_STORE_MULTIPLE
:
417 use_rtx
= extract_base_reg (consumer
);
418 if (reg_overlap_p (def_reg
, use_rtx
))
422 use_rtx
= extract_nth_access_rtx (consumer
, 0);
426 use_rtx
= PATTERN (consumer
);
433 if (reg_overlap_p (def_reg
, use_rtx
))
439 /* Check the dependency between the producer defining DEF_REG and CONSUMER
440 requiring input operand at AG (II). */
442 n8_consumed_by_addr_in_p (rtx_insn
*consumer
, rtx def_reg
)
446 switch (get_attr_type (consumer
))
449 use_rtx
= extract_branch_target_rtx (consumer
);
453 if (load_single_p (consumer
))
454 use_rtx
= extract_mem_rtx (consumer
);
456 use_rtx
= extract_base_reg (consumer
);
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
);
465 use_rtx
= extract_base_reg (consumer
);
468 case TYPE_LOAD_MULTIPLE
:
469 case TYPE_STORE_MULTIPLE
:
470 use_rtx
= extract_base_reg (consumer
);
477 return reg_overlap_p (def_reg
, use_rtx
);
480 /* Check the dependency between the producer defining DEF_REG and CONSUMER
481 requiring input operand at EX. */
483 n8_consumed_by_ex_p (rtx_insn
*consumer
, rtx def_reg
)
487 switch (get_attr_type (consumer
))
490 if (movd44_even_dep_p (consumer
, def_reg
))
493 use_rtx
= SET_SRC (PATTERN (consumer
));
497 use_rtx
= SET_SRC (PATTERN (consumer
));
501 use_rtx
= extract_mac_non_acc_rtx (consumer
);
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. */
509 if (INSN_CODE (consumer
) == CODE_FOR_divmodsi4
510 || INSN_CODE (consumer
) == CODE_FOR_udivmodsi4
)
511 use_rtx
= SET_SRC (parallel_element (consumer
, 0));
513 use_rtx
= SET_SRC (PATTERN (consumer
));
517 use_rtx
= extract_branch_condition_rtx (consumer
);
521 /* exclude ST_!bi_RR */
522 if (!post_update_insn_p (consumer
)
523 && !immed_offset_p (extract_mem_rtx (consumer
)))
526 use_rtx
= SET_SRC (PATTERN (consumer
));
529 case TYPE_STORE_MULTIPLE
:
530 use_rtx
= extract_nth_access_rtx (consumer
, 0);
537 return reg_overlap_p (def_reg
, use_rtx
);
540 /* Check the dependency between the producer defining DEF_REG and CONSUMER
541 requiring input operand at AG (II). */
543 e8_consumed_by_addr_in_p (rtx_insn
*consumer
, rtx def_reg
)
545 return n8_consumed_by_addr_in_p (consumer
, def_reg
);
548 /* Check the dependency between the producer defining DEF_REG and CONSUMER
549 requiring input operand at EX. */
551 e8_consumed_by_ex_p (rtx_insn
*consumer
, rtx def_reg
)
555 switch (get_attr_type (consumer
))
559 use_rtx
= SET_SRC (PATTERN (consumer
));
566 case TYPE_STORE_MULTIPLE
:
567 return n8_consumed_by_ex_p (consumer
, def_reg
);
573 return reg_overlap_p (def_reg
, use_rtx
);
576 /* Check the dependency between the producer defining DEF_REG and CONSUMER
577 requiring input operand at EX. */
579 n9_2r1w_consumed_by_ex_dep_p (rtx_insn
*consumer
, rtx def_reg
)
583 switch (get_attr_type (consumer
))
586 if (movd44_even_dep_p (consumer
, def_reg
))
589 use_rtx
= SET_SRC (PATTERN (consumer
));
594 use_rtx
= SET_SRC (PATTERN (consumer
));
598 use_rtx
= extract_shift_reg (consumer
);
602 return pbsada_insn_ra_rb_dep_reg_p (consumer
, def_reg
);
605 use_rtx
= PATTERN (consumer
);
609 if (INSN_CODE (consumer
) == CODE_FOR_divmodsi4
610 || INSN_CODE (consumer
) == CODE_FOR_udivmodsi4
)
611 use_rtx
= SET_SRC (parallel_element (consumer
, 0));
613 use_rtx
= SET_SRC (PATTERN (consumer
));
617 if (GET_CODE (PATTERN (consumer
)) == SET
)
618 use_rtx
= SET_SRC (PATTERN (consumer
));
624 /* ADDR_IN_bi_Ra, ADDR_IN_!bi */
625 if (post_update_insn_p (consumer
))
626 use_rtx
= extract_base_reg (consumer
);
628 use_rtx
= extract_mem_rtx (consumer
);
632 /* ADDR_IN_bi_Ra, ADDR_IN_!bi */
633 if (post_update_insn_p (consumer
))
634 use_rtx
= extract_base_reg (consumer
);
636 use_rtx
= extract_mem_rtx (consumer
);
638 if (reg_overlap_p (def_reg
, use_rtx
))
641 /* exclude ST_!bi_RR */
642 if (!post_update_insn_p (consumer
)
643 && !immed_offset_p (extract_mem_rtx (consumer
)))
646 use_rtx
= SET_SRC (PATTERN (consumer
));
649 case TYPE_LOAD_MULTIPLE
:
650 use_rtx
= extract_base_reg (consumer
);
653 case TYPE_STORE_MULTIPLE
:
655 use_rtx
= extract_base_reg (consumer
);
656 if (reg_overlap_p (def_reg
, use_rtx
))
660 use_rtx
= extract_nth_access_rtx (consumer
, 0);
664 use_rtx
= PATTERN (consumer
);
671 if (reg_overlap_p (def_reg
, use_rtx
))
677 /* Check the dependency between the producer defining DEF_REG and CONSUMER
678 requiring input operand at EX. */
680 n9_3r2w_consumed_by_ex_dep_p (rtx_insn
*consumer
, rtx def_reg
)
684 switch (get_attr_type (consumer
))
689 use_rtx
= SET_SRC (PATTERN (consumer
));
693 use_rtx
= extract_shift_reg (consumer
);
697 return pbsada_insn_ra_rb_dep_reg_p (consumer
, def_reg
);
700 use_rtx
= extract_mac_non_acc_rtx (consumer
);
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
709 if (INSN_CODE (consumer
) == CODE_FOR_divmodsi4
710 || INSN_CODE (consumer
) == CODE_FOR_udivmodsi4
)
711 use_rtx
= SET_SRC (parallel_element (consumer
, 0));
713 use_rtx
= SET_SRC (PATTERN (consumer
));
717 if (GET_CODE (PATTERN (consumer
)) == SET
)
718 use_rtx
= SET_SRC (PATTERN (consumer
));
725 use_rtx
= extract_mem_rtx (consumer
);
728 case TYPE_LOAD_MULTIPLE
:
729 case TYPE_STORE_MULTIPLE
:
730 use_rtx
= extract_base_reg (consumer
);
734 use_rtx
= PATTERN (consumer
);
741 if (reg_overlap_p (def_reg
, use_rtx
))
748 } // anonymous namespace
750 /* ------------------------------------------------------------------------ */
752 /* Guard functions for N7 core. */
755 nds32_n7_load_to_ii_p (rtx_insn
*producer
, rtx_insn
*consumer
)
757 if (post_update_insn_p (producer
))
760 rtx def_reg
= SET_DEST (PATTERN (producer
));
762 return n7_consumed_by_ii_dep_p (consumer
, def_reg
);
766 nds32_n7_last_load_to_ii_p (rtx_insn
*producer
, rtx_insn
*consumer
)
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
772 if (post_update_insn_p (producer
))
775 rtx last_def_reg
= extract_nth_access_reg (producer
, -1);
777 if (last_def_reg
== NULL_RTX
)
780 gcc_assert (REG_P (last_def_reg
) || GET_CODE (last_def_reg
) == SUBREG
);
782 return n7_consumed_by_ii_dep_p (consumer
, last_def_reg
);
785 /* Guard functions for N8 core. */
788 nds32_n8_load_to_ii_p (rtx_insn
*producer
, rtx_insn
*consumer
)
790 if (post_update_insn_p (producer
))
793 rtx def_reg
= SET_DEST (PATTERN (producer
));
795 return n8_consumed_by_addr_in_p (consumer
, def_reg
);
799 nds32_n8_load_bi_to_ii_p (rtx_insn
*producer
, rtx_insn
*consumer
)
801 if (!post_update_insn_p (producer
))
804 rtx def_reg
= SET_DEST (PATTERN (producer
));
806 return n8_consumed_by_addr_in_p (consumer
, def_reg
);
810 nds32_n8_load_to_ex_p (rtx_insn
*producer
, rtx_insn
*consumer
)
812 if (post_update_insn_p (producer
))
815 rtx def_reg
= SET_DEST (PATTERN (producer
));
817 return n8_consumed_by_ex_p (consumer
, def_reg
);
821 nds32_n8_ex_to_ii_p (rtx_insn
*producer
, rtx_insn
*consumer
)
825 switch (get_attr_type (producer
))
828 if (movd44_insn_p (producer
))
829 def_reg
= extract_movd44_odd_reg (producer
);
831 def_reg
= SET_DEST (PATTERN (producer
));
836 def_reg
= SET_DEST (PATTERN (producer
));
840 if (INSN_CODE (producer
) == CODE_FOR_divmodsi4
841 || INSN_CODE (producer
) == CODE_FOR_udivmodsi4
)
842 def_reg
= SET_DEST (parallel_element (producer
, 1));
844 def_reg
= SET_DEST (PATTERN (producer
));
849 case TYPE_LOAD_MULTIPLE
:
850 case TYPE_STORE_MULTIPLE
:
851 if (!post_update_insn_p (producer
))
854 def_reg
= extract_base_reg (producer
);
861 return n8_consumed_by_addr_in_p (consumer
, def_reg
);
865 nds32_n8_last_load_to_ii_p (rtx_insn
*producer
, rtx_insn
*consumer
)
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
871 if (post_update_insn_p (producer
))
874 rtx last_def_reg
= extract_nth_access_reg (producer
, -1);
876 if (last_def_reg
== NULL_RTX
)
879 gcc_assert (REG_P (last_def_reg
) || GET_CODE (last_def_reg
) == SUBREG
);
881 return n8_consumed_by_addr_in_p (consumer
, last_def_reg
);
885 nds32_n8_last_load_two_to_ii_p (rtx_insn
*producer
, rtx_insn
*consumer
)
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
))
895 rtx last_two_def_reg
= extract_nth_access_reg (producer
, index
);
897 if (last_two_def_reg
== NULL_RTX
)
900 gcc_assert (REG_P (last_two_def_reg
)
901 || GET_CODE (last_two_def_reg
) == SUBREG
);
903 return n8_consumed_by_addr_in_p (consumer
, last_two_def_reg
);
907 nds32_n8_last_load_to_ex_p (rtx_insn
*producer
, rtx_insn
*consumer
)
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
913 if (post_update_insn_p (producer
))
916 rtx last_def_reg
= extract_nth_access_reg (producer
, -1);
918 if (last_def_reg
== NULL_RTX
)
921 gcc_assert (REG_P (last_def_reg
) || GET_CODE (last_def_reg
) == SUBREG
);
923 return n8_consumed_by_ex_p (consumer
, last_def_reg
);
926 /* Guard functions for E8 cores. */
929 nds32_e8_load_to_ii_p (rtx_insn
*producer
, rtx_insn
*consumer
)
931 rtx def_reg
= SET_DEST (PATTERN (producer
));
933 return e8_consumed_by_addr_in_p (consumer
, def_reg
);
937 nds32_e8_load_to_ex_p (rtx_insn
*producer
, rtx_insn
*consumer
)
939 rtx def_reg
= SET_DEST (PATTERN (producer
));
941 return e8_consumed_by_ex_p (consumer
, def_reg
);
945 nds32_e8_ex_to_ii_p (rtx_insn
*producer
, rtx_insn
*consumer
)
949 switch (get_attr_type (producer
))
952 /* No data hazards if AGEN's input is produced by MOVI or SETHI. */
953 if (GET_CODE (PATTERN (producer
)) == SET
)
955 rtx dest
= SET_DEST (PATTERN (producer
));
956 rtx src
= SET_SRC (PATTERN (producer
));
958 if ((REG_P (dest
) || GET_CODE (dest
) == SUBREG
)
959 && (GET_CODE (src
) == CONST_INT
|| GET_CODE (src
) == HIGH
))
963 def_reg
= SET_DEST (PATTERN (producer
));
968 def_reg
= SET_DEST (PATTERN (producer
));
972 if (INSN_CODE (producer
) == CODE_FOR_divmodsi4
973 || INSN_CODE (producer
) == CODE_FOR_udivmodsi4
)
975 rtx def_reg1
= SET_DEST (parallel_element (producer
, 0));
976 rtx def_reg2
= SET_DEST (parallel_element (producer
, 1));
978 return (e8_consumed_by_addr_in_p (consumer
, def_reg1
)
979 || e8_consumed_by_addr_in_p (consumer
, def_reg2
));
982 def_reg
= SET_DEST (PATTERN (producer
));
987 case TYPE_LOAD_MULTIPLE
:
988 case TYPE_STORE_MULTIPLE
:
989 if (!post_update_insn_p (producer
))
992 def_reg
= extract_base_reg (producer
);
999 return e8_consumed_by_addr_in_p (consumer
, def_reg
);
1003 nds32_e8_last_load_to_ii_p (rtx_insn
*producer
, rtx_insn
*consumer
)
1005 rtx last_def_reg
= extract_nth_access_reg (producer
, -1);
1007 if (last_def_reg
== NULL_RTX
)
1010 gcc_assert (REG_P (last_def_reg
) || GET_CODE (last_def_reg
) == SUBREG
);
1012 return e8_consumed_by_addr_in_p (consumer
, last_def_reg
);
1016 nds32_e8_last_load_to_ex_p (rtx_insn
*producer
, rtx_insn
*consumer
)
1018 rtx last_def_reg
= extract_nth_access_reg (producer
, -1);
1020 if (last_def_reg
== NULL_RTX
)
1023 gcc_assert (REG_P (last_def_reg
) || GET_CODE (last_def_reg
) == SUBREG
);
1025 return e8_consumed_by_ex_p (consumer
, last_def_reg
);
1028 /* Guard functions for N9 cores. */
1030 /* Check dependencies from MM to EX. */
1032 nds32_n9_2r1w_mm_to_ex_p (rtx_insn
*producer
, rtx_insn
*consumer
)
1036 switch (get_attr_type (producer
))
1040 if (post_update_insn_p (producer
))
1043 def_reg
= SET_DEST (PATTERN (producer
));
1048 def_reg
= SET_DEST (PATTERN (producer
));
1055 return n9_2r1w_consumed_by_ex_dep_p (consumer
, def_reg
);
1058 /* Check dependencies from MM to EX. */
1060 nds32_n9_3r2w_mm_to_ex_p (rtx_insn
*producer
, rtx_insn
*consumer
)
1064 switch (get_attr_type (producer
))
1069 def_reg
= SET_DEST (PATTERN (producer
));
1072 /* Some special instructions, divmodsi4 and udivmodsi4, produce two
1073 results, the quotient and the remainder. We have to handle them
1076 if (INSN_CODE (producer
) == CODE_FOR_divmodsi4
1077 || INSN_CODE (producer
) == CODE_FOR_udivmodsi4
)
1079 rtx def_reg1
= SET_DEST (parallel_element (producer
, 0));
1080 rtx def_reg2
= SET_DEST (parallel_element (producer
, 1));
1082 return (n9_3r2w_consumed_by_ex_dep_p (consumer
, def_reg1
)
1083 || n9_3r2w_consumed_by_ex_dep_p (consumer
, def_reg2
));
1086 def_reg
= SET_DEST (PATTERN (producer
));
1093 return n9_3r2w_consumed_by_ex_dep_p (consumer
, def_reg
);
1096 /* Check dependencies from LMW(N, N) to EX. */
1098 nds32_n9_last_load_to_ex_p (rtx_insn
*producer
, rtx_insn
*consumer
)
1100 rtx last_def_reg
= extract_nth_access_reg (producer
, -1);
1102 if (nds32_register_ports_config
== REG_PORT_2R1W
)
1104 /* The base-update micro operation occupies the last cycle. */
1105 if (post_update_insn_p (producer
))
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
1114 size_t n_elems
= parallel_elements (producer
);
1115 rtx base_reg
= extract_base_reg (producer
);
1117 for (i
= 0; i
< n_elems
; ++i
)
1119 rtx load_rtx
= extract_nth_access_rtx (producer
, i
);
1120 rtx list_element
= SET_DEST (load_rtx
);
1122 if (rtx_equal_p (base_reg
, list_element
) && i
!= n_elems
- 1)
1124 last_def_reg
= base_reg
;
1129 return n9_2r1w_consumed_by_ex_dep_p (consumer
, last_def_reg
);
1132 return n9_3r2w_consumed_by_ex_dep_p (consumer
, last_def_reg
);
1135 /* ------------------------------------------------------------------------ */