Mercurial > hg > CbC > CbC_gcc
comparison gcc/config/arc/arc.md @ 145:1830386684a0
gcc-9.2.0
author | anatofuz |
---|---|
date | Thu, 13 Feb 2020 11:34:05 +0900 |
parents | 84e7813d76e9 |
children |
comparison
equal
deleted
inserted
replaced
131:84e7813d76e9 | 145:1830386684a0 |
---|---|
1 ;; Machine description of the Synopsys DesignWare ARC cpu for GNU C compiler | 1 ;; Machine description of the Synopsys DesignWare ARC cpu for GNU C compiler |
2 ;; Copyright (C) 1994-2018 Free Software Foundation, Inc. | 2 ;; Copyright (C) 1994-2020 Free Software Foundation, Inc. |
3 | 3 |
4 ;; Sources derived from work done by Sankhya Technologies (www.sankhya.com) on | 4 ;; Sources derived from work done by Sankhya Technologies (www.sankhya.com) on |
5 ;; behalf of Synopsys Inc. | 5 ;; behalf of Synopsys Inc. |
6 | 6 |
7 ;; Position Independent Code support added,Code cleaned up, | 7 ;; Position Independent Code support added,Code cleaned up, |
134 UNSPEC_ARC_QMPYHU | 134 UNSPEC_ARC_QMPYHU |
135 UNSPEC_ARC_VMAC2H | 135 UNSPEC_ARC_VMAC2H |
136 UNSPEC_ARC_VMAC2HU | 136 UNSPEC_ARC_VMAC2HU |
137 UNSPEC_ARC_VMPY2H | 137 UNSPEC_ARC_VMPY2H |
138 UNSPEC_ARC_VMPY2HU | 138 UNSPEC_ARC_VMPY2HU |
139 UNSPEC_ARC_STKTIE | |
140 | 139 |
141 VUNSPEC_ARC_RTIE | 140 VUNSPEC_ARC_RTIE |
142 VUNSPEC_ARC_SYNC | 141 VUNSPEC_ARC_SYNC |
143 VUNSPEC_ARC_BRK | 142 VUNSPEC_ARC_BRK |
144 VUNSPEC_ARC_FLAG | 143 VUNSPEC_ARC_FLAG |
161 VUNSPEC_ARC_EX | 160 VUNSPEC_ARC_EX |
162 VUNSPEC_ARC_CAS | 161 VUNSPEC_ARC_CAS |
163 VUNSPEC_ARC_SC | 162 VUNSPEC_ARC_SC |
164 VUNSPEC_ARC_LL | 163 VUNSPEC_ARC_LL |
165 VUNSPEC_ARC_BLOCKAGE | 164 VUNSPEC_ARC_BLOCKAGE |
165 VUNSPEC_ARC_EH_RETURN | |
166 VUNSPEC_ARC_ARC600_RTIE | |
167 VUNSPEC_ARC_ARC600_STALL | |
168 VUNSPEC_ARC_LDDI | |
169 VUNSPEC_ARC_STDI | |
166 ]) | 170 ]) |
167 | 171 |
168 (define_constants | 172 (define_constants |
169 [(R0_REG 0) | 173 [(R0_REG 0) |
170 (R1_REG 1) | 174 (R1_REG 1) |
171 (R2_REG 2) | 175 (R2_REG 2) |
172 (R3_REG 3) | 176 (R3_REG 3) |
177 (R4_REG 4) | |
178 | |
179 (R9_REG 9) | |
173 (R10_REG 10) | 180 (R10_REG 10) |
181 | |
174 (R12_REG 12) | 182 (R12_REG 12) |
183 | |
184 (R15_REG 15) | |
185 (R16_REG 16) | |
186 | |
187 (R25_REG 25) | |
175 (SP_REG 28) | 188 (SP_REG 28) |
176 (ILINK1_REGNUM 29) | 189 (ILINK1_REG 29) |
177 (ILINK2_REGNUM 30) | 190 (ILINK2_REG 30) |
191 (R30_REG 30) | |
178 (RETURN_ADDR_REGNUM 31) | 192 (RETURN_ADDR_REGNUM 31) |
193 (R32_REG 32) | |
194 (R33_REG 33) | |
195 (R34_REG 34) | |
196 (R35_REG 35) | |
197 (R36_REG 36) | |
198 (R37_REG 37) | |
199 (R38_REG 38) | |
200 (R39_REG 39) | |
201 (R40_REG 40) | |
202 (R41_REG 41) | |
203 (R42_REG 42) | |
204 (R43_REG 43) | |
205 (R44_REG 44) | |
206 (R45_REG 45) | |
207 (R46_REG 46) | |
208 (R47_REG 47) | |
209 (R48_REG 48) | |
210 (R49_REG 49) | |
211 (R50_REG 50) | |
212 (R51_REG 51) | |
213 (R52_REG 52) | |
214 (R53_REG 53) | |
215 (R54_REG 54) | |
216 (R55_REG 55) | |
217 (R56_REG 56) | |
218 (R57_REG 57) | |
219 (R58_REG 58) | |
220 (R59_REG 59) | |
221 | |
179 (MUL64_OUT_REG 58) | 222 (MUL64_OUT_REG 58) |
180 (MUL32x16_REG 56) | 223 (MUL32x16_REG 56) |
181 (ARCV2_ACC 58) | 224 (ARCV2_ACC 58) |
182 | |
183 (LP_COUNT 60) | 225 (LP_COUNT 60) |
184 (CC_REG 61) | 226 (CC_REG 61) |
185 (LP_START 144) | 227 (PCL_REG 63) |
186 (LP_END 145) | |
187 ] | 228 ] |
188 ) | 229 ) |
189 | 230 |
190 (define_attr "is_sfunc" "no,yes" (const_string "no")) | 231 (define_attr "is_sfunc" "no,yes" (const_string "no")) |
191 | 232 |
195 ; that loads the (pc-relative) function address into r12 and then calls | 236 ; that loads the (pc-relative) function address into r12 and then calls |
196 ; via r12. | 237 ; via r12. |
197 | 238 |
198 (define_attr "type" | 239 (define_attr "type" |
199 "move,load,store,cmove,unary,binary,compare,shift,uncond_branch,jump,branch, | 240 "move,load,store,cmove,unary,binary,compare,shift,uncond_branch,jump,branch, |
200 brcc,brcc_no_delay_slot,call,sfunc,call_no_delay_slot, | 241 brcc,brcc_no_delay_slot,call,sfunc,call_no_delay_slot,rtie, |
201 multi,umulti, two_cycle_core,lr,sr,divaw,loop_setup,loop_end,return, | 242 multi,umulti, two_cycle_core,lr,sr,divaw,loop_setup,loop_end,return, |
202 misc,spfp,dpfp_mult,dpfp_addsub,mulmac_600,cc_arith, | 243 misc,spfp,dpfp_mult,dpfp_addsub,mulmac_600,cc_arith, |
203 simd_vload, simd_vload128, simd_vstore, simd_vmove, simd_vmove_else_zero, | 244 simd_vload, simd_vload128, simd_vstore, simd_vmove, simd_vmove_else_zero, |
204 simd_vmove_with_acc, simd_varith_1cycle, simd_varith_2cycle, | 245 simd_vmove_with_acc, simd_varith_1cycle, simd_varith_2cycle, |
205 simd_varith_with_acc, simd_vlogic, simd_vlogic_with_acc, | 246 simd_varith_with_acc, simd_vlogic, simd_vlogic_with_acc, |
512 | 553 |
513 (define_attr "in_ret_delay_slot" "no,yes" | 554 (define_attr "in_ret_delay_slot" "no,yes" |
514 (cond [(eq_attr "in_delay_slot" "false") | 555 (cond [(eq_attr "in_delay_slot" "false") |
515 (const_string "no") | 556 (const_string "no") |
516 (match_test "regno_clobbered_p | 557 (match_test "regno_clobbered_p |
517 (arc_return_address_register | 558 (RETURN_ADDR_REGNUM, insn, SImode, 1)") |
518 (arc_compute_function_type (cfun)), | |
519 insn, SImode, 1)") | |
520 (const_string "no")] | 559 (const_string "no")] |
521 (const_string "yes"))) | 560 (const_string "yes"))) |
522 | 561 |
523 (define_attr "cond_ret_delay_insn" "no,yes" | 562 (define_attr "cond_ret_delay_insn" "no,yes" |
524 (cond [(eq_attr "in_ret_delay_slot" "no") (const_string "no") | 563 (cond [(eq_attr "in_ret_delay_slot" "no") (const_string "no") |
598 ;; - either canuse_limm is not eligible for delay slots, and has no | 637 ;; - either canuse_limm is not eligible for delay slots, and has no |
599 ;; delay slots, or arc_reorg has to treat them as nocond, or it has to | 638 ;; delay slots, or arc_reorg has to treat them as nocond, or it has to |
600 ;; somehow modify them to become inelegible for delay slots if a decision | 639 ;; somehow modify them to become inelegible for delay slots if a decision |
601 ;; is made that makes conditional execution required. | 640 ;; is made that makes conditional execution required. |
602 | 641 |
603 (define_attr "tune" "none,arc600,arc700_4_2_std,arc700_4_2_xmac, core_3, \ | 642 (define_attr "tune" "none,arc600,arc7xx,arc700_4_2_std,arc700_4_2_xmac, \ |
604 archs4x, archs4xd, archs4xd_slow" | 643 core_3, archs4x, archs4xd, archs4xd_slow" |
605 (const | 644 (const |
606 (cond [(symbol_ref "arc_tune == TUNE_ARC600") | 645 (cond [(symbol_ref "arc_tune == TUNE_ARC600") |
607 (const_string "arc600") | 646 (const_string "arc600") |
647 (symbol_ref "arc_tune == ARC_TUNE_ARC7XX") | |
648 (const_string "arc7xx") | |
608 (symbol_ref "arc_tune == TUNE_ARC700_4_2_STD") | 649 (symbol_ref "arc_tune == TUNE_ARC700_4_2_STD") |
609 (const_string "arc700_4_2_std") | 650 (const_string "arc700_4_2_std") |
610 (symbol_ref "arc_tune == TUNE_ARC700_4_2_XMAC") | 651 (symbol_ref "arc_tune == TUNE_ARC700_4_2_XMAC") |
611 (const_string "arc700_4_2_xmac") | 652 (const_string "arc700_4_2_xmac") |
612 (symbol_ref "arc_tune == ARC_TUNE_CORE_3") | 653 (symbol_ref "arc_tune == ARC_TUNE_CORE_3") |
617 (symbol_ref "arc_tune == TUNE_ARCHS4XD_SLOW")) | 658 (symbol_ref "arc_tune == TUNE_ARCHS4XD_SLOW")) |
618 (const_string "archs4xd")] | 659 (const_string "archs4xd")] |
619 (const_string "none")))) | 660 (const_string "none")))) |
620 | 661 |
621 (define_attr "tune_arc700" "false,true" | 662 (define_attr "tune_arc700" "false,true" |
622 (if_then_else (eq_attr "tune" "arc700_4_2_std, arc700_4_2_xmac") | 663 (if_then_else (eq_attr "tune" "arc7xx, arc700_4_2_std, arc700_4_2_xmac") |
623 (const_string "true") | 664 (const_string "true") |
624 (const_string "false"))) | 665 (const_string "false"))) |
625 | 666 |
626 (define_attr "tune_dspmpy" "none, slow, fast" | 667 (define_attr "tune_dspmpy" "none, slow, fast" |
627 (const | 668 (const |
647 ; Likewise, the length of an alternative that might be shifted to conditional | 688 ; Likewise, the length of an alternative that might be shifted to conditional |
648 ; execution must reflect this, lest out-of-range branches are created. | 689 ; execution must reflect this, lest out-of-range branches are created. |
649 ; The iscompact attribute allows the epilogue expander to know for which | 690 ; The iscompact attribute allows the epilogue expander to know for which |
650 ; insns it should lengthen the return insn. | 691 ; insns it should lengthen the return insn. |
651 (define_insn "*movqi_insn" | 692 (define_insn "*movqi_insn" |
652 [(set (match_operand:QI 0 "move_dest_operand" "=Rcq,Rcq#q, w,Rcq#q, h,w*l,w*l,???w,h,w*l,Rcq, S,!*x, r,r, Ucm,m,???m, m,Usc") | 693 [(set (match_operand:QI 0 "move_dest_operand" "=Rcq,Rcq#q, w,Rcq#q, h, w, w,???w,h, w,Rcq, S,!*x, r,r, Ucm,m,???m, m,Usc") |
653 (match_operand:QI 1 "move_src_operand" " cL, cP,Rcq#q, P,hCm1, cL, I,?Rac,i, ?i, T,Rcq,Usd,Ucm,m,?Rac,c,?Rac,Cm3,i"))] | 694 (match_operand:QI 1 "move_src_operand" " cL, cP,Rcq#q, P,hCm1,cL, I,?Rac,i,?i, T,Rcq,Usd,Ucm,m,?Rac,c,?Rac,Cm3,i"))] |
654 "register_operand (operands[0], QImode) | 695 "register_operand (operands[0], QImode) |
655 || register_operand (operands[1], QImode)" | 696 || register_operand (operands[1], QImode) |
697 || (satisfies_constraint_Cm3 (operands[1]) | |
698 && memory_operand (operands[0], QImode))" | |
656 "@ | 699 "@ |
657 mov%? %0,%1%& | 700 mov%? %0,%1%& |
658 mov%? %0,%1%& | 701 mov%? %0,%1%& |
659 mov%? %0,%1%& | 702 mov%? %0,%1%& |
660 mov%? %0,%1%& | 703 mov%? %0,%1%& |
684 (match_operand:HI 1 "general_operand" ""))] | 727 (match_operand:HI 1 "general_operand" ""))] |
685 "" | 728 "" |
686 "if (prepare_move_operands (operands, HImode)) DONE;") | 729 "if (prepare_move_operands (operands, HImode)) DONE;") |
687 | 730 |
688 (define_insn "*movhi_insn" | 731 (define_insn "*movhi_insn" |
689 [(set (match_operand:HI 0 "move_dest_operand" "=Rcq,Rcq#q, w,Rcq#q, h,w*l,w*l,???w,Rcq#q,h,w*l,Rcq, S, r,r, Ucm,m,???m, m,VUsc") | 732 [(set (match_operand:HI 0 "move_dest_operand" "=Rcq,Rcq#q, w,Rcq#q, h, w, w,???w,Rcq#q,h, w,Rcq, S, r,r, Ucm,m,???m, m,VUsc") |
690 (match_operand:HI 1 "move_src_operand" " cL, cP,Rcq#q, P,hCm1, cL, I,?Rac, i,i, ?i, T,Rcq,Ucm,m,?Rac,c,?Rac,Cm3,i"))] | 733 (match_operand:HI 1 "move_src_operand" " cL, cP,Rcq#q, P,hCm1,cL, I,?Rac, i,i,?i, T,Rcq,Ucm,m,?Rac,c,?Rac,Cm3,i"))] |
691 "register_operand (operands[0], HImode) | 734 "register_operand (operands[0], HImode) |
692 || register_operand (operands[1], HImode) | 735 || register_operand (operands[1], HImode) |
693 || (CONSTANT_P (operands[1]) | 736 || (CONSTANT_P (operands[1]) |
694 /* Don't use a LIMM that we could load with a single insn - we loose | 737 /* Don't use a LIMM that we could load with a single insn - we loose |
695 delay-slot filling opportunities. */ | 738 delay-slot filling opportunities. */ |
696 && !satisfies_constraint_I (operands[1]) | 739 && !satisfies_constraint_I (operands[1]) |
697 && satisfies_constraint_Usc (operands[0]))" | 740 && satisfies_constraint_Usc (operands[0])) |
741 || (satisfies_constraint_Cm3 (operands[1]) | |
742 && memory_operand (operands[0], HImode))" | |
698 "@ | 743 "@ |
699 mov%? %0,%1%& | 744 mov%? %0,%1%& |
700 mov%? %0,%1%& | 745 mov%? %0,%1%& |
701 mov%? %0,%1%& | 746 mov%? %0,%1%& |
702 mov%? %0,%1%& | 747 mov%? %0,%1%& |
728 "if (prepare_move_operands (operands, SImode)) DONE;") | 773 "if (prepare_move_operands (operands, SImode)) DONE;") |
729 | 774 |
730 ; In order to allow the ccfsm machinery to do its work, the leading compact | 775 ; In order to allow the ccfsm machinery to do its work, the leading compact |
731 ; alternatives say 'canuse' - there is another alternative that will match | 776 ; alternatives say 'canuse' - there is another alternative that will match |
732 ; when the condition codes are used. | 777 ; when the condition codes are used. |
733 ; Rcq won't match if the condition is actually used; to avoid a spurious match | 778 ; The length of an alternative that might be shifted to conditional |
734 ; via q, q is inactivated as constraint there. | |
735 ; Likewise, the length of an alternative that might be shifted to conditional | |
736 ; execution must reflect this, lest out-of-range branches are created. | 779 ; execution must reflect this, lest out-of-range branches are created. |
737 ; the iscompact attribute allows the epilogue expander to know for which | 780 ; the iscompact attribute allows the epilogue expander to know for which |
738 ; insns it should lengthen the return insn. | 781 ; insns it should lengthen the return insn. |
739 ; N.B. operand 1 of alternative 7 expands into pcl,symbol@gotpc . | 782 (define_insn_and_split "*movsi_insn" ; 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 |
740 (define_insn "*movsi_insn" ; 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 | 783 [(set (match_operand:SI 0 "move_dest_operand" "=q, q,r,q, h, rl,r, r, r, r, ?r, r, q, h, rl, q, S, Us<,RcqRck,!*x, r,!*Rsd,!*Rcd,r,Ucm, Usd,m, m,VUsc") |
741 [(set (match_operand:SI 0 "move_dest_operand" "=Rcq,Rcq#q, w,Rcq#q, h,w*l,w*l, w, w, w, w, ???w, ?w, w,Rcq#q, h, w*l,Rcq, S, Us<,RcqRck,!*x, r,!*Rsd,!*Rcd,r,Ucm, Usd,m,???m, m,VUsc") | 784 (match_operand:SI 1 "move_src_operand" "rL,rP,q,P,hCm1,rLl,I,Clo,Chi,Cbi,Cpc,Clb,Cax,Cal,Cal,Uts,Rcq,RcqRck, Us>,Usd,Ucm, Usd, Ucd,m, r,!*Rzd,r,Cm3, C32"))] |
742 (match_operand:SI 1 "move_src_operand" " cL, cP,Rcq#q, P,hCm1, cL, I,Crr,Clo,Chi,Cbi,?Rac*l,Cpc,Clb, ?Cal,Cal,?Cal,Uts,Rcq,RcqRck, Us>,Usd,Ucm, Usd, Ucd,m, w,!*Rzd,c,?Rac,Cm3, C32"))] | |
743 "register_operand (operands[0], SImode) | 785 "register_operand (operands[0], SImode) |
744 || register_operand (operands[1], SImode) | 786 || register_operand (operands[1], SImode) |
745 || (CONSTANT_P (operands[1]) | 787 || (CONSTANT_P (operands[1]) |
746 /* Don't use a LIMM that we could load with a single insn - we loose | 788 && (!satisfies_constraint_I (operands[1]) || !optimize_size) |
747 delay-slot filling opportunities. */ | |
748 && !satisfies_constraint_I (operands[1]) | |
749 && satisfies_constraint_Usc (operands[0])) | 789 && satisfies_constraint_Usc (operands[0])) |
750 || (satisfies_constraint_Cm3 (operands[1]) | 790 || (satisfies_constraint_Cm3 (operands[1]) |
751 && memory_operand (operands[0], SImode))" | 791 && memory_operand (operands[0], SImode))" |
752 "@ | 792 "@ |
753 mov%? %0,%1%& ;0 | 793 mov%?\\t%0,%1 ;0 |
754 mov%? %0,%1%& ;1 | 794 mov%?\\t%0,%1 ;1 |
755 mov%? %0,%1%& ;2 | 795 mov%?\\t%0,%1 ;2 |
756 mov%? %0,%1%& ;3 | 796 mov%?\\t%0,%1 ;3 |
757 mov%? %0,%1%& ;4 | 797 mov%?\\t%0,%1 ;4 |
758 mov%? %0,%1 ;5 | 798 mov%?\\t%0,%1 ;5 |
759 mov%? %0,%1 ;6 | 799 mov%?\\t%0,%1 ;6 |
760 ror %0,((%1*2+1) & 0x3f) ;7 | 800 movl.cl\\t%0,%1 ;7 |
761 movl.cl %0,%1 ;8 | 801 movh.cl\\t%0,%L1>>16 ;8 |
762 movh.cl %0,%L1>>16 ;9 | 802 * return INTVAL (operands[1]) & 0xffffff ? \"movbi.cl\\t%0,%1 >> %p1,%p1,8;9\" : \"movbi.cl\\t%0,%L1 >> 24,24,8;9\"; |
763 * return INTVAL (operands[1]) & 0xffffff ? \"movbi.cl %0,%1 >> %p1,%p1,8;10\" : \"movbi.cl %0,%L1 >> 24,24,8;10\"; | 803 add\\t%0,%1 ;10 |
764 mov%? %0,%1 ;11 | 804 add\\t%0,pcl,%1@pcl ;11 |
765 add %0,%1 ;12 | 805 # |
766 add %0,pcl,%1@pcl ;13 | 806 mov%?\\t%0,%j1 ;13 |
767 mov%? %0,%j1 ;14 | 807 mov%?\\t%0,%j1 ;14 |
768 mov%? %0,%j1 ;15 | 808 ld%?\\t%0,%1 ;15 |
769 mov%? %0,%j1 ;16 | 809 st%?\\t%1,%0 ;16 |
770 ld%? %0,%1 ;17 | 810 * return arc_short_long (insn, \"push%?\\t%1%&\", \"st%U0\\t%1,%0%&\"); |
771 st%? %1,%0%& ;18 | 811 * return arc_short_long (insn, \"pop%?\\t%0%&\", \"ld%U1\\t%0,%1%&\"); |
772 * return arc_short_long (insn, \"push%? %1%&\", \"st%U0 %1,%0%&\"); | 812 ld%?\\t%0,%1 ;19 |
773 * return arc_short_long (insn, \"pop%? %0%&\", \"ld%U1 %0,%1%&\"); | 813 xld%U1\\t%0,%1 ;20 |
774 ld%? %0,%1%& ;21 | 814 ld%?\\t%0,%1 ;21 |
775 xld%U1 %0,%1 ;22 | 815 ld%?\\t%0,%1 ;22 |
776 ld%? %0,%1%& ;23 | 816 ld%U1%V1\\t%0,%1 ;23 |
777 ld%? %0,%1%& ;24 | 817 xst%U0\\t%1,%0 ;24 |
778 ld%U1%V1 %0,%1 ;25 | 818 st%?\\t%1,%0%& ;25 |
779 xst%U0 %1,%0 ;26 | 819 st%U0%V0\\t%1,%0 ;26 |
780 st%? %1,%0%& ;27 | 820 st%U0%V0\\t%1,%0 ;37 |
781 st%U0%V0 %1,%0 ;28 | 821 st%U0%V0\\t%1,%0 ;28" |
782 st%U0%V0 %1,%0 ;29 | 822 "reload_completed |
783 st%U0%V0 %1,%0 ;30 | 823 && GET_CODE (PATTERN (insn)) != COND_EXEC |
784 st%U0%V0 %1,%0 ;31" | 824 && register_operand (operands[0], SImode) |
785 ; 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 | 825 && IN_RANGE (REGNO (operands[0]) ^ 4, 4, 11) |
786 [(set_attr "type" "move, move, move,move,move, move, move,two_cycle_core,shift,shift,shift, move,binary,binary, move, move, move,load,store,store,load,load, load,load,load, load,store,store,store,store,store,store") | 826 && satisfies_constraint_Cax (operands[1])" |
787 (set_attr "iscompact" "maybe,maybe,maybe,true,true,false,false, false,false,false,false,false, false, false,maybe_limm,maybe_limm,false,true, true, true,true,true,false,true,true,false,false, true,false,false,false,false") | 827 [(const_int 0)] |
788 ; Use default length for iscompact to allow for COND_EXEC. But set length | 828 " |
789 ; of Crr to 4. | 829 arc_split_mov_const (operands); |
790 (set_attr "length" "*,*,*,*,*,4,4,4,4,4,4,4,8,8,*,*,*,*,*,*,*,*,4,*,4,*,*,*,*,*,*,8") | 830 DONE; |
791 (set_attr "predicable" "yes,no,yes,no,no,yes,no,no,no,no,no,yes,no,no,yes,yes,yes,no,no,no,no,no,no,no,no,no,no,no,no,no,no,no") | 831 " |
792 (set_attr "cpu_facility" "av1,av1,av1,av2,av2,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,av2,av2,*,*,av2,*,*,av2,*")]) | 832 ; 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 |
833 [(set_attr "type" "move, move, move,move,move, move, move,shift,shift,shift,binary,binary,multi,move, move,load,store,store,load,load, load,load,load, load,store,store,store,store,store") | |
834 (set_attr "iscompact" "maybe,maybe,maybe,true,true,false,false,false,false,false, false, false,false,true,false,true, true, true,true,true,false,true,true,false,false, true,false,false,false") | |
835 (set_attr "length" "*,*,*,*,*,4,4,4,4,4,8,8,*,6,*,*,*,*,*,*,4,*,4,*,*,*,*,*,8") | |
836 (set_attr "predicable" "yes,no,yes,no,no,yes,no,no,no,yes,no,no,no,yes,yes,no,no,no,no,no,no,no,no,no,no,no,no,no,no") | |
837 (set_attr "cpu_facility" "av1,av1,av1,av2,av2,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,av2,av2,*,*,av2,*,av2,*")]) | |
793 | 838 |
794 ;; Sometimes generated by the epilogue code. We don't want to | 839 ;; Sometimes generated by the epilogue code. We don't want to |
795 ;; recognize these addresses in general, because the limm is costly, | 840 ;; recognize these addresses in general, because the limm is costly, |
796 ;; and we can't use them for stores. */ | 841 ;; and we can't use them for stores. */ |
797 (define_insn "*movsi_pre_mod" | 842 (define_insn "*movsi_pre_mod" |
936 (define_insn_and_split "*tst_movb" | 981 (define_insn_and_split "*tst_movb" |
937 [(set | 982 [(set |
938 (match_operand 0 "cc_register" "") | 983 (match_operand 0 "cc_register" "") |
939 (match_operator 4 "zn_compare_operator" | 984 (match_operator 4 "zn_compare_operator" |
940 [(and:SI | 985 [(and:SI |
941 (match_operand:SI 1 "register_operand" "%Rcq,Rcq, c, c, c, c,Rrq, 3, c") | 986 (match_operand:SI 1 "register_operand" "%Rcq,Rcq, c, c, c, c,Rrq,Rrq, c") |
942 (match_operand:SI 2 "nonmemory_operand" "Rcq,C0p,cI,C1p,Ccp,Chs,Cbf,Cbf,???Cal")) | 987 (match_operand:SI 2 "nonmemory_operand" "Rcq,C0p,cI,C1p,Ccp,Chs,Cbf,Cbf,???Cal")) |
943 (const_int 0)])) | 988 (const_int 0)])) |
944 (clobber (match_scratch:SI 3 "=X,X,X,X,X,X,Rrq,Rrq,c"))] | 989 (clobber (match_scratch:SI 3 "=X,X,X,X,X,X,Rrq,1,c"))] |
945 "TARGET_NPS_BITOPS" | 990 "TARGET_NPS_BITOPS" |
946 "movb.f.cl %3,%1,%p2,%p2,%s2" | 991 "movb.f.cl %3,%1,%p2,%p2,%s2" |
947 "TARGET_NPS_BITOPS && reload_completed | 992 "TARGET_NPS_BITOPS && reload_completed |
948 && (extract_constrain_insn_cached (insn), (which_alternative & ~1) != 6)" | 993 && (extract_constrain_insn_cached (insn), (which_alternative & ~1) != 6)" |
949 [(set (match_dup 0) (match_dup 4))]) | 994 [(set (match_dup 0) (match_dup 4))]) |
1219 (set (match_operand:SI 0 "register_operand" "") | 1264 (set (match_operand:SI 0 "register_operand" "") |
1220 (and:SI (match_dup 1) (not:SI (match_dup 2))))])] | 1265 (and:SI (match_dup 1) (not:SI (match_dup 2))))])] |
1221 "") | 1266 "") |
1222 | 1267 |
1223 (define_insn "*bic_f" | 1268 (define_insn "*bic_f" |
1224 [(set (match_operand 3 "cc_register" "=Rcc,Rcc,Rcc") | 1269 [(set (match_operand 3 "cc_set_register" "") |
1225 (match_operator 4 "zn_compare_operator" | 1270 (match_operator 4 "zn_compare_operator" |
1226 [(and:SI (match_operand:SI 1 "register_operand" "c,0,c") | 1271 [(and:SI (match_operand:SI 1 "register_operand" "c,0,c") |
1227 (not:SI | 1272 (not:SI |
1228 (match_operand:SI 2 "nonmemory_operand" "cL,I,?Cal"))) | 1273 (match_operand:SI 2 "nonmemory_operand" "cL,I,?Cal"))) |
1229 (const_int 0)])) | 1274 (const_int 0)])) |
1232 "" | 1277 "" |
1233 "bic.f %0,%1,%2" | 1278 "bic.f %0,%1,%2" |
1234 [(set_attr "type" "compare,compare,compare") | 1279 [(set_attr "type" "compare,compare,compare") |
1235 (set_attr "cond" "set_zn,set_zn,set_zn") | 1280 (set_attr "cond" "set_zn,set_zn,set_zn") |
1236 (set_attr "length" "4,4,8")]) | 1281 (set_attr "length" "4,4,8")]) |
1282 | |
1283 (define_insn "*bic_cmp0_noout" | |
1284 [(set (match_operand 0 "cc_set_register" "") | |
1285 (compare:CC_ZN | |
1286 (and:SI (not:SI (match_operand:SI 1 "nonmemory_operand" "Lr,Cal,r")) | |
1287 (match_operand:SI 2 "nonmemory_operand" "r,r,Cal")) | |
1288 (const_int 0)))] | |
1289 "register_operand (operands[1], SImode) | |
1290 || register_operand (operands[2], SImode)" | |
1291 "bic.f\\t0,%2,%1" | |
1292 [(set_attr "type" "unary") | |
1293 (set_attr "cond" "set_zn") | |
1294 (set_attr "length" "4,8,8")]) | |
1295 | |
1296 (define_insn "*bic_cmp0" | |
1297 [(set (match_operand 0 "cc_set_register" "") | |
1298 (compare:CC_ZN | |
1299 (and:SI (not:SI (match_operand:SI 1 "nonmemory_operand" "Lr,Cal,r")) | |
1300 (match_operand:SI 2 "nonmemory_operand" "r,r,Cal")) | |
1301 (const_int 0))) | |
1302 (set (match_operand:SI 3 "register_operand" "=r,r,r") | |
1303 (and:SI (not:SI (match_dup 1)) (match_dup 2)))] | |
1304 "register_operand (operands[1], SImode) | |
1305 || register_operand (operands[2], SImode)" | |
1306 "bic.f\\t%3,%2,%1" | |
1307 [(set_attr "type" "unary") | |
1308 (set_attr "cond" "set_zn") | |
1309 (set_attr "length" "4,8,8")]) | |
1237 | 1310 |
1238 (define_expand "movdi" | 1311 (define_expand "movdi" |
1239 [(set (match_operand:DI 0 "move_dest_operand" "") | 1312 [(set (match_operand:DI 0 "move_dest_operand" "") |
1240 (match_operand:DI 1 "general_operand" ""))] | 1313 (match_operand:DI 1 "general_operand" ""))] |
1241 "" | 1314 "" |
1760 } | 1833 } |
1761 }" | 1834 }" |
1762 [(set_attr "type" "cmove,cmove") | 1835 [(set_attr "type" "cmove,cmove") |
1763 (set_attr "length" "8,16")]) | 1836 (set_attr "length" "8,16")]) |
1764 | 1837 |
1838 ;; ------------------------------------------------------------------- | |
1839 ;; Sign/Zero extension | |
1840 ;; ------------------------------------------------------------------- | |
1765 | 1841 |
1766 (define_insn "*zero_extendqihi2_i" | 1842 (define_insn "*zero_extendqihi2_i" |
1767 [(set (match_operand:HI 0 "dest_reg_operand" "=Rcq,Rcq#q,Rcw,w,r,r") | 1843 [(set (match_operand:HI 0 "dest_reg_operand" "=q,q,r,r,r,r") |
1768 (zero_extend:HI (match_operand:QI 1 "nonvol_nonimm_operand" "0,Rcq#q,0,c,Ucm,m")))] | 1844 (zero_extend:HI |
1845 (match_operand:QI 1 "nonvol_nonimm_operand" "0,q,0,r,Ucm,m")))] | |
1769 "" | 1846 "" |
1770 "@ | 1847 "@ |
1771 extb%? %0,%1%& | 1848 extb%?\\t%0,%1 |
1772 extb%? %0,%1%& | 1849 extb%?\\t%0,%1 |
1773 bmsk%? %0,%1,7 | 1850 bmsk%?\\t%0,%1,7 |
1774 extb %0,%1 | 1851 extb\\t%0,%1 |
1775 xldb%U1 %0,%1 | 1852 xldb%U1\\t%0,%1 |
1776 ldb%U1 %0,%1" | 1853 ldb%U1\\t%0,%1" |
1777 [(set_attr "type" "unary,unary,unary,unary,load,load") | 1854 [(set_attr "type" "unary,unary,unary,unary,load,load") |
1778 (set_attr "iscompact" "maybe,true,false,false,false,false") | 1855 (set_attr "iscompact" "maybe,true,false,false,false,false") |
1779 (set_attr "predicable" "no,no,yes,no,no,no")]) | 1856 (set_attr "predicable" "no,no,yes,no,no,no")]) |
1780 | 1857 |
1781 (define_expand "zero_extendqihi2" | 1858 (define_expand "zero_extendqihi2" |
1784 "" | 1861 "" |
1785 "" | 1862 "" |
1786 ) | 1863 ) |
1787 | 1864 |
1788 (define_insn "*zero_extendqisi2_ac" | 1865 (define_insn "*zero_extendqisi2_ac" |
1789 [(set (match_operand:SI 0 "dest_reg_operand" "=Rcq,Rcq#q,Rcw,w,qRcq,!*x,r,r") | 1866 [(set (match_operand:SI 0 "dest_reg_operand" "=q,q,r,r,q,!*x,r,r") |
1790 (zero_extend:SI (match_operand:QI 1 "nonvol_nonimm_operand" "0,Rcq#q,0,c,T,Usd,Ucm,m")))] | 1867 (zero_extend:SI |
1868 (match_operand:QI 1 "nonvol_nonimm_operand" "0,q,0,r,T,Usd,Ucm,m")))] | |
1791 "" | 1869 "" |
1792 "@ | 1870 "@ |
1793 extb%? %0,%1%& | 1871 extb%?\\t%0,%1 |
1794 extb%? %0,%1%& | 1872 extb%?\\t%0,%1 |
1795 bmsk%? %0,%1,7 | 1873 bmsk%?\\t%0,%1,7 |
1796 extb %0,%1 | 1874 extb\\t%0,%1 |
1797 ldb%? %0,%1%& | 1875 ldb%?\\t%0,%1 |
1798 ldb%? %0,%1%& | 1876 ldb%?\\t%0,%1 |
1799 xldb%U1 %0,%1 | 1877 xldb%U1\\t%0,%1 |
1800 ldb%U1 %0,%1" | 1878 ldb%U1\\t%0,%1" |
1801 [(set_attr "type" "unary,unary,unary,unary,load,load,load,load") | 1879 [(set_attr "type" "unary,unary,unary,unary,load,load,load,load") |
1802 (set_attr "iscompact" "maybe,true,false,false,true,true,false,false") | 1880 (set_attr "iscompact" "maybe,true,false,false,true,true,false,false") |
1803 (set_attr "predicable" "no,no,yes,no,no,no,no,no")]) | 1881 (set_attr "predicable" "no,no,yes,no,no,no,no,no")]) |
1804 | 1882 |
1805 (define_expand "zero_extendqisi2" | 1883 (define_expand "zero_extendqisi2" |
1808 "" | 1886 "" |
1809 "" | 1887 "" |
1810 ) | 1888 ) |
1811 | 1889 |
1812 (define_insn "*zero_extendhisi2_i" | 1890 (define_insn "*zero_extendhisi2_i" |
1813 [(set (match_operand:SI 0 "dest_reg_operand" "=Rcq,q,Rcw,w,!x,Rcqq,r,r") | 1891 [(set (match_operand:SI 0 "dest_reg_operand" "=q,q,r,r,!x,q,r,r") |
1814 (zero_extend:SI (match_operand:HI 1 "nonvol_nonimm_operand" "0,q,0,c,Usd,T,Ucm,m")))] | 1892 (zero_extend:SI |
1893 (match_operand:HI 1 "nonvol_nonimm_operand" "0,q,0,r,Usd,T,Ucm,m")))] | |
1815 "" | 1894 "" |
1816 "@ | 1895 "@ |
1817 ext%_%? %0,%1%& | 1896 ext%_%?\\t%0,%1 |
1818 ext%_%? %0,%1%& | 1897 ext%_%?\\t%0,%1 |
1819 bmsk%? %0,%1,15 | 1898 bmsk%?\\t%0,%1,15 |
1820 ext%_ %0,%1 | 1899 ext%_\\t%0,%1 |
1821 ld%_%? %0,%1 | 1900 ld%_%?\\t%0,%1 |
1822 ld%_%? %0,%1 | 1901 ld%_%?\\t%0,%1 |
1823 * return TARGET_EM ? \"xldh%U1%V1 %0,%1\" : \"xldw%U1 %0,%1\"; | 1902 xldw%U1\\t%0,%1 |
1824 ld%_%U1%V1 %0,%1" | 1903 ld%_%U1%V1\\t%0,%1" |
1825 [(set_attr "type" "unary,unary,unary,unary,load,load,load,load") | 1904 [(set_attr "type" "unary,unary,unary,unary,load,load,load,load") |
1826 (set_attr "iscompact" "maybe,true,false,false,true,true,false,false") | 1905 (set_attr "iscompact" "maybe,true,false,false,true,true,false,false") |
1827 (set_attr "predicable" "no,no,yes,no,no,no,no,no")]) | 1906 (set_attr "predicable" "no,no,yes,no,no,no,no,no")]) |
1828 | 1907 |
1829 | |
1830 (define_expand "zero_extendhisi2" | 1908 (define_expand "zero_extendhisi2" |
1831 [(set (match_operand:SI 0 "dest_reg_operand" "") | 1909 [(set (match_operand:SI 0 "dest_reg_operand" "") |
1832 (zero_extend:SI (match_operand:HI 1 "nonvol_nonimm_operand" "")))] | 1910 (zero_extend:SI (match_operand:HI 1 "nonvol_nonimm_operand" "")))] |
1833 "" | 1911 "" |
1834 "" | 1912 "" |
1835 ) | 1913 ) |
1836 | 1914 |
1837 ;; Sign extension instructions. | 1915 ;; Sign extension instructions. |
1838 | 1916 |
1839 (define_insn "*extendqihi2_i" | 1917 (define_insn "*extendqihi2_i" |
1840 [(set (match_operand:HI 0 "dest_reg_operand" "=Rcqq,r,r,r") | 1918 [(set (match_operand:HI 0 "dest_reg_operand" "=q,r,r,r") |
1841 (sign_extend:HI (match_operand:QI 1 "nonvol_nonimm_operand" "Rcqq,r,Uex,m")))] | 1919 (sign_extend:HI |
1920 (match_operand:QI 1 "nonvol_nonimm_operand" "q,r,Uex,m")))] | |
1842 "" | 1921 "" |
1843 "@ | 1922 "@ |
1844 sexb%? %0,%1%& | 1923 sexb%?\\t%0,%1 |
1845 sexb %0,%1 | 1924 sexb\\t%0,%1 |
1846 ldb.x%U1 %0,%1 | 1925 ldb.x%U1\\t%0,%1 |
1847 ldb.x%U1 %0,%1" | 1926 ldb.x%U1\\t%0,%1" |
1848 [(set_attr "type" "unary,unary,load,load") | 1927 [(set_attr "type" "unary,unary,load,load") |
1849 (set_attr "iscompact" "true,false,false,false") | 1928 (set_attr "iscompact" "true,false,false,false") |
1850 (set_attr "length" "*,*,*,8")]) | 1929 (set_attr "length" "*,*,*,8")]) |
1851 | 1930 |
1852 | |
1853 (define_expand "extendqihi2" | 1931 (define_expand "extendqihi2" |
1854 [(set (match_operand:HI 0 "dest_reg_operand" "") | 1932 [(set (match_operand:HI 0 "dest_reg_operand" "") |
1855 (sign_extend:HI (match_operand:QI 1 "nonvol_nonimm_operand" "")))] | 1933 (sign_extend:HI (match_operand:QI 1 "nonvol_nonimm_operand" "")))] |
1856 "" | 1934 "" |
1857 "" | 1935 "" |
1858 ) | 1936 ) |
1859 | 1937 |
1860 (define_insn "*extendqisi2_ac" | 1938 (define_insn "*extendqisi2_ac" |
1861 [(set (match_operand:SI 0 "dest_reg_operand" "=Rcqq,w,r,r") | 1939 [(set (match_operand:SI 0 "dest_reg_operand" "=q,r,r,r") |
1862 (sign_extend:SI (match_operand:QI 1 "nonvol_nonimm_operand" "Rcqq,c,Uex,m")))] | 1940 (sign_extend:SI |
1941 (match_operand:QI 1 "nonvol_nonimm_operand" "q,r,Uex,m")))] | |
1863 "" | 1942 "" |
1864 "@ | 1943 "@ |
1865 sexb%? %0,%1%& | 1944 sexb%?\\t%0,%1 |
1866 sexb %0,%1 | 1945 sexb\\t%0,%1 |
1867 ldb.x%U1 %0,%1 | 1946 ldb.x%U1\\t%0,%1 |
1868 ldb.x%U1 %0,%1" | 1947 ldb.x%U1\\t%0,%1" |
1869 [(set_attr "type" "unary,unary,load,load") | 1948 [(set_attr "type" "unary,unary,load,load") |
1870 (set_attr "iscompact" "true,false,false,false") | 1949 (set_attr "iscompact" "true,false,false,false") |
1871 (set_attr "length" "*,*,*,8")]) | 1950 (set_attr "length" "*,*,*,8")]) |
1872 | 1951 |
1873 (define_expand "extendqisi2" | 1952 (define_expand "extendqisi2" |
1876 "" | 1955 "" |
1877 "" | 1956 "" |
1878 ) | 1957 ) |
1879 | 1958 |
1880 (define_insn "*extendhisi2_i" | 1959 (define_insn "*extendhisi2_i" |
1881 [(set (match_operand:SI 0 "dest_reg_operand" "=Rcqq,w,Rcqq,r,r") | 1960 [(set (match_operand:SI 0 "dest_reg_operand" "=q,r,q,r,r") |
1882 (sign_extend:SI (match_operand:HI 1 "nonvol_nonimm_operand" "Rcqq,c,Ucd,Uex,m")))] | 1961 (sign_extend:SI |
1962 (match_operand:HI 1 "nonvol_nonimm_operand" "q,r,Ucd,Uex,m")))] | |
1883 "" | 1963 "" |
1884 "@ | 1964 "@ |
1885 sex%_%? %0,%1%& | 1965 sex%_%?\\t%0,%1 |
1886 sex%_ %0,%1 | 1966 sex%_\\t%0,%1 |
1887 ldh%?.x %0,%1%& | 1967 ldh%?.x\\t%0,%1%& |
1888 ld%_.x%U1%V1 %0,%1 | 1968 ld%_.x%U1%V1\\t%0,%1 |
1889 ld%_.x%U1%V1 %0,%1" | 1969 ld%_.x%U1%V1\\t%0,%1" |
1890 [(set_attr "type" "unary,unary,load,load,load") | 1970 [(set_attr "type" "unary,unary,load,load,load") |
1891 (set_attr "iscompact" "true,false,true,false,false") | 1971 (set_attr "iscompact" "true,false,true,false,false") |
1892 (set_attr "length" "*,*,*,4,8")]) | 1972 (set_attr "length" "*,*,*,4,8")]) |
1893 | 1973 |
1894 (define_expand "extendhisi2" | 1974 (define_expand "extendhisi2" |
2074 | 2154 |
2075 ;; ARC700/ARC600/V2 multiply | 2155 ;; ARC700/ARC600/V2 multiply |
2076 ;; SI <- SI * SI | 2156 ;; SI <- SI * SI |
2077 | 2157 |
2078 (define_expand "mulsi3" | 2158 (define_expand "mulsi3" |
2079 [(set (match_operand:SI 0 "nonimmediate_operand" "") | 2159 [(set (match_operand:SI 0 "register_operand" "") |
2080 (mult:SI (match_operand:SI 1 "register_operand" "") | 2160 (mult:SI (match_operand:SI 1 "register_operand" "") |
2081 (match_operand:SI 2 "nonmemory_operand" "")))] | 2161 (match_operand:SI 2 "nonmemory_operand" "")))] |
2082 "" | 2162 "TARGET_ANY_MPY" |
2083 { | 2163 { |
2084 if (TARGET_MPY) | 2164 if (TARGET_MUL64_SET) |
2085 { | 2165 { |
2086 if (!register_operand (operands[0], SImode)) | 2166 emit_insn (gen_mulsi64 (operands[0], operands[1], operands[2])); |
2087 { | |
2088 rtx result = gen_reg_rtx (SImode); | |
2089 | |
2090 emit_insn (gen_mulsi3 (result, operands[1], operands[2])); | |
2091 emit_move_insn (operands[0], result); | |
2092 DONE; | |
2093 } | |
2094 } | |
2095 else if (TARGET_MUL64_SET) | |
2096 { | |
2097 rtx tmp = gen_reg_rtx (SImode); | |
2098 emit_insn (gen_mulsi64 (tmp, operands[1], operands[2])); | |
2099 emit_move_insn (operands[0], tmp); | |
2100 DONE; | 2167 DONE; |
2101 } | 2168 } |
2102 else if (TARGET_MULMAC_32BY16_SET) | 2169 else if (TARGET_MULMAC_32BY16_SET) |
2103 { | 2170 { |
2104 rtx tmp = gen_reg_rtx (SImode); | 2171 emit_insn (gen_mulsi32x16 (operands[0], operands[1], operands[2])); |
2105 emit_insn (gen_mulsi32x16 (tmp, operands[1], operands[2])); | |
2106 emit_move_insn (operands[0], tmp); | |
2107 DONE; | 2172 DONE; |
2108 } | |
2109 else | |
2110 { | |
2111 emit_move_insn (gen_rtx_REG (SImode, R0_REG), operands[1]); | |
2112 emit_move_insn (gen_rtx_REG (SImode, R1_REG), operands[2]); | |
2113 emit_insn (gen_mulsi3_600_lib ()); | |
2114 emit_move_insn (operands[0], gen_rtx_REG (SImode, R0_REG)); | |
2115 DONE; | |
2116 } | 2173 } |
2117 }) | 2174 }) |
2118 | 2175 |
2119 (define_insn_and_split "mulsi32x16" | 2176 (define_insn_and_split "mulsi32x16" |
2120 [(set (match_operand:SI 0 "register_operand" "=w") | 2177 [(set (match_operand:SI 0 "register_operand" "=w") |
2180 [(set_attr "length" "4,4,8") | 2237 [(set_attr "length" "4,4,8") |
2181 (set_attr "type" "mulmac_600, mulmac_600, mulmac_600") | 2238 (set_attr "type" "mulmac_600, mulmac_600, mulmac_600") |
2182 (set_attr "predicable" "no, no, yes") | 2239 (set_attr "predicable" "no, no, yes") |
2183 (set_attr "cond" "nocond, canuse_limm, canuse")]) | 2240 (set_attr "cond" "nocond, canuse_limm, canuse")]) |
2184 | 2241 |
2242 ; The gcc-internal representation may differ from the hardware | |
2243 ; register number in order to allow the generic code to correctly | |
2244 ; split the concatenation of mhi and mlo. | |
2185 (define_insn_and_split "mulsi64" | 2245 (define_insn_and_split "mulsi64" |
2186 [(set (match_operand:SI 0 "register_operand" "=w") | 2246 [(set (match_operand:SI 0 "register_operand" "=w") |
2187 (mult:SI (match_operand:SI 1 "register_operand" "%c") | 2247 (mult:SI (match_operand:SI 1 "register_operand" "%c") |
2188 (match_operand:SI 2 "nonmemory_operand" "ci"))) | 2248 (match_operand:SI 2 "nonmemory_operand" "ci"))) |
2189 (clobber (reg:DI MUL64_OUT_REG))] | 2249 (clobber (reg:DI MUL64_OUT_REG))] |
2190 "TARGET_MUL64_SET" | 2250 "TARGET_MUL64_SET" |
2191 "#" | 2251 "#" |
2192 "TARGET_MUL64_SET && reload_completed" | 2252 "TARGET_MUL64_SET && reload_completed" |
2193 [(const_int 0)] | 2253 [(const_int 0)] |
2194 { | 2254 { |
2195 emit_insn (gen_mulsi_600 (operands[1], operands[2], | 2255 rtx mhi = gen_rtx_REG (SImode, R59_REG); |
2196 gen_mlo (), gen_mhi ())); | 2256 rtx mlo = gen_rtx_REG (SImode, R58_REG); |
2197 emit_move_insn (operands[0], gen_mlo ()); | 2257 emit_insn (gen_mulsi_600 (operands[1], operands[2], mlo, mhi)); |
2198 DONE; | 2258 emit_move_insn (operands[0], mlo); |
2199 } | 2259 DONE; |
2260 } | |
2200 [(set_attr "type" "multi") | 2261 [(set_attr "type" "multi") |
2201 (set_attr "length" "8")]) | 2262 (set_attr "length" "8")]) |
2202 | 2263 |
2203 (define_insn "mulsi_600" | 2264 (define_insn "mulsi_600" |
2204 [(set (match_operand:SI 2 "mlo_operand" "") | 2265 [(set (match_operand:SI 2 "mlo_operand" "") |
2205 (mult:SI (match_operand:SI 0 "register_operand" "%Rcq#q,c,c,c") | 2266 (mult:SI (match_operand:SI 0 "register_operand" "%Rcq#q,c,c,c") |
2206 (match_operand:SI 1 "nonmemory_operand" "Rcq#q,cL,I,Cal"))) | 2267 (match_operand:SI 1 "nonmemory_operand" "Rcq#q,cL,I,Cal"))) |
2207 (clobber (match_operand:SI 3 "mhi_operand" ""))] | 2268 (clobber (match_operand:SI 3 "mhi_operand" ""))] |
2208 "TARGET_MUL64_SET" | 2269 "TARGET_MUL64_SET" |
2209 ; The assembler mis-assembles mul64 / mulu64 with "I" constraint constants, | 2270 "mul64%?\\t0,%0,%1" |
2210 ; using a machine code pattern that only allows "L" constraint constants. | |
2211 ; "mul64%? \t0, %0, %1%&" | |
2212 { | |
2213 if (satisfies_constraint_I (operands[1]) | |
2214 && !satisfies_constraint_L (operands[1])) | |
2215 { | |
2216 /* MUL64 <0,>b,s12 00101bbb10000100 0BBBssssssSSSSSS */ | |
2217 int n = true_regnum (operands[0]); | |
2218 int i = INTVAL (operands[1]); | |
2219 asm_fprintf (asm_out_file, "\t.short %d`", 0x2884 + ((n & 7) << 8)); | |
2220 asm_fprintf (asm_out_file, "\t.short %d`", | |
2221 ((i & 0x3f) << 6) + ((i >> 6) & 0x3f) + ((n & 070) << 9)); | |
2222 return "; mul64%? \t0, %0, %1%&"; | |
2223 } | |
2224 return "mul64%? \t0, %0, %1%&"; | |
2225 } | |
2226 [(set_attr "length" "*,4,4,8") | 2271 [(set_attr "length" "*,4,4,8") |
2227 (set_attr "iscompact" "maybe,false,false,false") | 2272 (set_attr "iscompact" "maybe,false,false,false") |
2228 (set_attr "type" "multi,multi,multi,multi") | 2273 (set_attr "type" "multi,multi,multi,multi") |
2229 (set_attr "predicable" "yes,yes,no,yes") | 2274 (set_attr "predicable" "yes,yes,no,yes") |
2230 (set_attr "cond" "canuse,canuse,canuse_limm,canuse")]) | 2275 (set_attr "cond" "canuse,canuse,canuse_limm,canuse")]) |
2231 | |
2232 ; If we compile without an mul option enabled, but link with libraries | |
2233 ; for a mul option, we'll see clobbers of multiplier output registers. | |
2234 ; There is also an implementation using norm that clobbers the loop registers. | |
2235 (define_insn "mulsi3_600_lib" | |
2236 [(set (reg:SI R0_REG) | |
2237 (mult:SI (reg:SI R0_REG) (reg:SI R1_REG))) | |
2238 (clobber (reg:SI RETURN_ADDR_REGNUM)) | |
2239 (clobber (reg:SI R1_REG)) | |
2240 (clobber (reg:SI R2_REG)) | |
2241 (clobber (reg:SI R3_REG)) | |
2242 (clobber (reg:DI MUL64_OUT_REG)) | |
2243 (clobber (reg:SI LP_COUNT)) | |
2244 (clobber (reg:SI LP_START)) | |
2245 (clobber (reg:SI LP_END)) | |
2246 (clobber (reg:CC CC_REG))] | |
2247 "!TARGET_ANY_MPY | |
2248 && SFUNC_CHECK_PREDICABLE" | |
2249 "*return arc_output_libcall (\"__mulsi3\");" | |
2250 [(set_attr "is_sfunc" "yes") | |
2251 (set_attr "predicable" "yes")]) | |
2252 | 2276 |
2253 (define_insn_and_split "mulsidi_600" | 2277 (define_insn_and_split "mulsidi_600" |
2254 [(set (match_operand:DI 0 "register_operand" "=c, c,c, c") | 2278 [(set (match_operand:DI 0 "register_operand" "=c, c,c, c") |
2255 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "%Rcq#q, c,c, c")) | 2279 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "%Rcq#q, c,c, c")) |
2256 (sign_extend:DI (match_operand:SI 2 "nonmemory_operand" "Rcq#q,cL,L,C32")))) | 2280 (sign_extend:DI (match_operand:SI 2 "nonmemory_operand" "Rcq#q,cL,L,C32")))) |
2326 (set_attr "cond" "canuse,nocond,canuse_limm,canuse,nocond")]) | 2350 (set_attr "cond" "canuse,nocond,canuse_limm,canuse,nocond")]) |
2327 | 2351 |
2328 ; ARCv2 has no penalties between mpy and mpyu. So, we use mpy because of its | 2352 ; ARCv2 has no penalties between mpy and mpyu. So, we use mpy because of its |
2329 ; short variant. LP_COUNT constraints are still valid. | 2353 ; short variant. LP_COUNT constraints are still valid. |
2330 (define_insn "mulsi3_v2" | 2354 (define_insn "mulsi3_v2" |
2331 [(set (match_operand:SI 0 "mpy_dest_reg_operand" "=Rcqq,Rcr, r,r,Rcr, r") | 2355 [(set (match_operand:SI 0 "mpy_dest_reg_operand" "=q,q, r, r,r, r, r") |
2332 (mult:SI (match_operand:SI 1 "register_operand" "%0, 0, c,0, 0, c") | 2356 (mult:SI (match_operand:SI 1 "register_operand" "%0,q, 0, r,0, 0, c") |
2333 (match_operand:SI 2 "nonmemory_operand" " Rcqq, cL,cL,I,Cal,Cal")))] | 2357 (match_operand:SI 2 "nonmemory_operand" "q,0,rL,rL,I,Cal,Cal")))] |
2334 "TARGET_MULTI" | 2358 "TARGET_MULTI" |
2335 "mpy%? %0,%1,%2" | 2359 "@ |
2336 [(set_attr "length" "*,4,4,4,8,8") | 2360 mpy%?\\t%0,%1,%2 |
2337 (set_attr "iscompact" "maybe,false,false,false,false,false") | 2361 mpy%?\\t%0,%2,%1 |
2362 mpy%?\\t%0,%1,%2 | |
2363 mpy%?\\t%0,%1,%2 | |
2364 mpy%?\\t%0,%1,%2 | |
2365 mpy%?\\t%0,%1,%2 | |
2366 mpy%?\\t%0,%1,%2" | |
2367 [(set_attr "length" "*,*,4,4,4,8,8") | |
2368 (set_attr "iscompact" "maybe,maybe,false,false,false,false,false") | |
2338 (set_attr "type" "umulti") | 2369 (set_attr "type" "umulti") |
2339 (set_attr "predicable" "no,yes,no,no,yes,no") | 2370 (set_attr "predicable" "no,no,yes,no,no,yes,no") |
2340 (set_attr "cond" "nocond,canuse,nocond,canuse_limm,canuse,nocond")]) | 2371 (set_attr "cond" "nocond,nocond,canuse,nocond,canuse_limm,canuse,nocond")]) |
2341 | 2372 |
2342 (define_expand "mulsidi3" | 2373 (define_expand "mulsidi3" |
2343 [(set (match_operand:DI 0 "register_operand" "") | 2374 [(set (match_operand:DI 0 "register_operand" "") |
2344 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "")) | 2375 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "")) |
2345 (sign_extend:DI (match_operand:SI 2 "nonmemory_operand" ""))))] | 2376 (sign_extend:DI (match_operand:SI 2 "nonmemory_operand" ""))))] |
2502 [(set_attr "length" "4,4,8,8") | 2533 [(set_attr "length" "4,4,8,8") |
2503 (set_attr "type" "multi") | 2534 (set_attr "type" "multi") |
2504 (set_attr "predicable" "yes,no,yes,no") | 2535 (set_attr "predicable" "yes,no,yes,no") |
2505 (set_attr "cond" "canuse,nocond,canuse,nocond")]) | 2536 (set_attr "cond" "canuse,nocond,canuse,nocond")]) |
2506 | 2537 |
2507 ; Implementations include additional labels for umulsidi3, so we got all | |
2508 ; the same clobbers - plus one for the result low part. */ | |
2509 (define_insn "umulsi3_highpart_600_lib_le" | |
2510 [(set (reg:SI R1_REG) | |
2511 (truncate:SI | |
2512 (lshiftrt:DI | |
2513 (mult:DI (zero_extend:DI (reg:SI R0_REG)) | |
2514 (zero_extend:DI (reg:SI R1_REG))) | |
2515 (const_int 32)))) | |
2516 (clobber (reg:SI RETURN_ADDR_REGNUM)) | |
2517 (clobber (reg:SI R0_REG)) | |
2518 (clobber (reg:DI R2_REG)) | |
2519 (clobber (reg:SI R12_REG)) | |
2520 (clobber (reg:DI MUL64_OUT_REG)) | |
2521 (clobber (reg:CC CC_REG))] | |
2522 "!TARGET_BIG_ENDIAN | |
2523 && !TARGET_ANY_MPY | |
2524 && SFUNC_CHECK_PREDICABLE" | |
2525 "*return arc_output_libcall (\"__umulsi3_highpart\");" | |
2526 [(set_attr "is_sfunc" "yes") | |
2527 (set_attr "predicable" "yes")]) | |
2528 | |
2529 (define_insn "umulsi3_highpart_600_lib_be" | |
2530 [(set (reg:SI R0_REG) | |
2531 (truncate:SI | |
2532 (lshiftrt:DI | |
2533 (mult:DI (zero_extend:DI (reg:SI R0_REG)) | |
2534 (zero_extend:DI (reg:SI R1_REG))) | |
2535 (const_int 32)))) | |
2536 (clobber (reg:SI RETURN_ADDR_REGNUM)) | |
2537 (clobber (reg:SI R1_REG)) | |
2538 (clobber (reg:DI R2_REG)) | |
2539 (clobber (reg:SI R12_REG)) | |
2540 (clobber (reg:DI MUL64_OUT_REG)) | |
2541 (clobber (reg:CC CC_REG))] | |
2542 "TARGET_BIG_ENDIAN | |
2543 && !TARGET_ANY_MPY | |
2544 && SFUNC_CHECK_PREDICABLE" | |
2545 "*return arc_output_libcall (\"__umulsi3_highpart\");" | |
2546 [(set_attr "is_sfunc" "yes") | |
2547 (set_attr "predicable" "yes")]) | |
2548 | |
2549 ;; (zero_extend:DI (const_int)) leads to internal errors in combine, so we | 2538 ;; (zero_extend:DI (const_int)) leads to internal errors in combine, so we |
2550 ;; need a separate pattern for immediates | 2539 ;; need a separate pattern for immediates |
2551 ;; ??? This is fine for combine, but not for reload. | 2540 ;; ??? This is fine for combine, but not for reload. |
2552 (define_insn "umulsi3_highpart_int" | 2541 (define_insn "umulsi3_highpart_int" |
2553 [(set (match_operand:SI 0 "register_operand" "=Rcr, r, r,Rcr, r") | 2542 [(set (match_operand:SI 0 "register_operand" "=Rcr, r, r,Rcr, r") |
2570 (lshiftrt:DI | 2559 (lshiftrt:DI |
2571 (mult:DI | 2560 (mult:DI |
2572 (zero_extend:DI (match_operand:SI 1 "register_operand" "")) | 2561 (zero_extend:DI (match_operand:SI 1 "register_operand" "")) |
2573 (zero_extend:DI (match_operand:SI 2 "nonmemory_operand" ""))) | 2562 (zero_extend:DI (match_operand:SI 2 "nonmemory_operand" ""))) |
2574 (const_int 32))))] | 2563 (const_int 32))))] |
2575 "!TARGET_MUL64_SET && !TARGET_MULMAC_32BY16_SET" | 2564 "TARGET_MPY" |
2576 " | 2565 " |
2577 { | 2566 { |
2578 rtx target = operands[0]; | 2567 rtx target = operands[0]; |
2579 | |
2580 if (!TARGET_MPY) | |
2581 { | |
2582 emit_move_insn (gen_rtx_REG (SImode, 0), operands[1]); | |
2583 emit_move_insn (gen_rtx_REG (SImode, 1), operands[2]); | |
2584 if (TARGET_BIG_ENDIAN) | |
2585 emit_insn (gen_umulsi3_highpart_600_lib_be ()); | |
2586 else | |
2587 emit_insn (gen_umulsi3_highpart_600_lib_le ()); | |
2588 emit_move_insn (target, gen_rtx_REG (SImode, 0)); | |
2589 DONE; | |
2590 } | |
2591 | 2568 |
2592 if (!register_operand (target, SImode)) | 2569 if (!register_operand (target, SImode)) |
2593 target = gen_reg_rtx (SImode); | 2570 target = gen_reg_rtx (SImode); |
2594 | 2571 |
2595 if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) < 0) | 2572 if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) < 0) |
2605 | 2582 |
2606 (define_expand "umulsidi3" | 2583 (define_expand "umulsidi3" |
2607 [(set (match_operand:DI 0 "register_operand" "") | 2584 [(set (match_operand:DI 0 "register_operand" "") |
2608 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "")) | 2585 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "")) |
2609 (zero_extend:DI (match_operand:SI 2 "nonmemory_operand" ""))))] | 2586 (zero_extend:DI (match_operand:SI 2 "nonmemory_operand" ""))))] |
2610 "" | 2587 "TARGET_ANY_MPY" |
2611 { | 2588 { |
2612 if (TARGET_PLUS_MACD) | 2589 if (TARGET_PLUS_MACD) |
2613 { | 2590 { |
2614 if (CONST_INT_P (operands[2])) | 2591 if (CONST_INT_P (operands[2])) |
2615 { | 2592 { |
2644 operands[2] = force_reg (SImode, operands[2]); | 2621 operands[2] = force_reg (SImode, operands[2]); |
2645 emit_insn (gen_umulsidi64 (operands[0], operands[1], operands[2])); | 2622 emit_insn (gen_umulsidi64 (operands[0], operands[1], operands[2])); |
2646 DONE; | 2623 DONE; |
2647 } | 2624 } |
2648 else | 2625 else |
2649 { | 2626 { |
2650 emit_move_insn (gen_rtx_REG (SImode, R0_REG), operands[1]); | 2627 gcc_unreachable (); |
2651 emit_move_insn (gen_rtx_REG (SImode, R1_REG), operands[2]); | |
2652 emit_insn (gen_umulsidi3_600_lib ()); | |
2653 emit_move_insn (operands[0], gen_rtx_REG (DImode, R0_REG)); | |
2654 DONE; | |
2655 } | 2628 } |
2656 }) | 2629 }) |
2657 | 2630 |
2658 (define_insn_and_split "umulsidi64" | 2631 (define_insn_and_split "umulsidi64" |
2659 [(set (match_operand:DI 0 "register_operand" "=w") | 2632 [(set (match_operand:DI 0 "register_operand" "=w") |
2727 [(set (match_operand:DI 0 "dest_reg_operand" "=&r") | 2700 [(set (match_operand:DI 0 "dest_reg_operand" "=&r") |
2728 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%c")) | 2701 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%c")) |
2729 (zero_extend:DI (match_operand:SI 2 "extend_operand" "cL"))))] | 2702 (zero_extend:DI (match_operand:SI 2 "extend_operand" "cL"))))] |
2730 "TARGET_MPY && !TARGET_PLUS_MACD" | 2703 "TARGET_MPY && !TARGET_PLUS_MACD" |
2731 "#" | 2704 "#" |
2732 "reload_completed" | 2705 "TARGET_MPY && !TARGET_PLUS_MACD && reload_completed" |
2733 [(const_int 0)] | 2706 [(const_int 0)] |
2734 { | 2707 { |
2735 int hi = !TARGET_BIG_ENDIAN; | 2708 int hi = !TARGET_BIG_ENDIAN; |
2736 int lo = !hi; | 2709 int lo = !hi; |
2737 rtx l0 = operand_subword (operands[0], lo, 0, DImode); | 2710 rtx l0 = operand_subword (operands[0], lo, 0, DImode); |
2740 emit_insn (gen_mulsi3 (l0, operands[1], operands[2])); | 2713 emit_insn (gen_mulsi3 (l0, operands[1], operands[2])); |
2741 DONE; | 2714 DONE; |
2742 } | 2715 } |
2743 [(set_attr "type" "umulti") | 2716 [(set_attr "type" "umulti") |
2744 (set_attr "length" "8")]) | 2717 (set_attr "length" "8")]) |
2745 | |
2746 (define_insn "umulsidi3_600_lib" | |
2747 [(set (reg:DI R0_REG) | |
2748 (mult:DI (zero_extend:DI (reg:SI R0_REG)) | |
2749 (zero_extend:DI (reg:SI R1_REG)))) | |
2750 (clobber (reg:SI RETURN_ADDR_REGNUM)) | |
2751 (clobber (reg:DI R2_REG)) | |
2752 (clobber (reg:SI R12_REG)) | |
2753 (clobber (reg:DI MUL64_OUT_REG)) | |
2754 (clobber (reg:CC CC_REG))] | |
2755 "!TARGET_ANY_MPY | |
2756 && SFUNC_CHECK_PREDICABLE" | |
2757 "*return arc_output_libcall (\"__umulsidi3\");" | |
2758 [(set_attr "is_sfunc" "yes") | |
2759 (set_attr "predicable" "yes")]) | |
2760 | |
2761 (define_peephole2 | |
2762 [(parallel | |
2763 [(set (reg:DI R0_REG) | |
2764 (mult:DI (zero_extend:DI (reg:SI R0_REG)) | |
2765 (zero_extend:DI (reg:SI R1_REG)))) | |
2766 (clobber (reg:SI RETURN_ADDR_REGNUM)) | |
2767 (clobber (reg:DI R2_REG)) | |
2768 (clobber (reg:SI R12_REG)) | |
2769 (clobber (reg:DI MUL64_OUT_REG)) | |
2770 (clobber (reg:CC CC_REG))])] | |
2771 "!TARGET_ANY_MPY | |
2772 && peep2_regno_dead_p (1, TARGET_BIG_ENDIAN ? R1_REG : R0_REG)" | |
2773 [(pc)] | |
2774 { | |
2775 if (TARGET_BIG_ENDIAN) | |
2776 emit_insn (gen_umulsi3_highpart_600_lib_be ()); | |
2777 else | |
2778 emit_insn (gen_umulsi3_highpart_600_lib_le ()); | |
2779 DONE; | |
2780 }) | |
2781 | 2718 |
2782 (define_expand "addsi3" | 2719 (define_expand "addsi3" |
2783 [(set (match_operand:SI 0 "dest_reg_operand" "") | 2720 [(set (match_operand:SI 0 "dest_reg_operand" "") |
2784 (plus:SI (match_operand:SI 1 "register_operand" "") | 2721 (plus:SI (match_operand:SI 1 "register_operand" "") |
2785 (match_operand:SI 2 "nonmemory_operand" "")))] | 2722 (match_operand:SI 2 "nonmemory_operand" "")))] |
3333 "" | 3270 "" |
3334 "if (!satisfies_constraint_Cux (operands[2])) | 3271 "if (!satisfies_constraint_Cux (operands[2])) |
3335 operands[1] = force_reg (SImode, operands[1]); | 3272 operands[1] = force_reg (SImode, operands[1]); |
3336 ") | 3273 ") |
3337 | 3274 |
3338 (define_insn "andsi3_i" | 3275 (define_insn "andsi3_i" ;0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
3339 [(set (match_operand:SI 0 "dest_reg_operand" "=Rcqq,Rcq,Rcqq,Rcqq,Rcqq,Rcw,Rcw, Rcw,Rcw,Rcw,Rcw, w, w, w, w,Rrq,w,Rcw, w,W") | 3276 [(set (match_operand:SI 0 "dest_reg_operand" "=q,q, q, q, q, r,r, r, r, r,r, r, r, r, r, q,r, r, r, W") |
3340 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,Rcq, 0, 0,Rcqq, 0, c, 0, 0, 0, 0, c, c, c, c,Rrq,0, 0, c,o") | 3277 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,q, 0, 0, q, 0,r, 0, 0, 0,0, r, r, r, r, q,0, 0, r, o") |
3341 (match_operand:SI 2 "nonmemory_operand" "Rcqq, 0, C1p, Ccp, Cux, cL, 0,C2pC1p,Ccp,CnL, I,Lc,C2pC1p,Ccp,CnL,Cbf,I,Cal,Cal,Cux")))] | 3278 (match_operand:SI 2 "nonmemory_operand" "q,0,C1p,Ccp,Cux,rL,0,C2pC1p,Ccp,CnL,I,rL,C2pC1p,Ccp,CnL,Cbf,I,Cal,Cal,Cux")))] |
3342 "(register_operand (operands[1], SImode) | 3279 "(register_operand (operands[1], SImode) |
3343 && nonmemory_operand (operands[2], SImode)) | 3280 && nonmemory_operand (operands[2], SImode)) |
3344 || (memory_operand (operands[1], SImode) | 3281 || (memory_operand (operands[1], SImode) |
3345 && satisfies_constraint_Cux (operands[2]))" | 3282 && satisfies_constraint_Cux (operands[2]))" |
3346 { | 3283 { |
3434 [(set_attr "length" "*,4,4,8,4,8,8") | 3371 [(set_attr "length" "*,4,4,8,4,8,8") |
3435 (set_attr "iscompact" "maybe, false, false, false, false, false, false") | 3372 (set_attr "iscompact" "maybe, false, false, false, false, false, false") |
3436 (set_attr "predicable" "no,yes,no,yes,no,no,no") | 3373 (set_attr "predicable" "no,yes,no,yes,no,no,no") |
3437 (set_attr "cond" "canuse,canuse,canuse_limm,canuse,nocond,nocond,nocond")]) | 3374 (set_attr "cond" "canuse,canuse,canuse_limm,canuse,nocond,nocond,nocond")]) |
3438 | 3375 |
3439 (define_insn "iorsi3" | 3376 (define_insn_and_split "iorsi3" |
3440 [(set (match_operand:SI 0 "dest_reg_operand" "=Rcqq,Rcq,Rcqq,Rcw,Rcw,Rcw,Rcw,w, w,w,Rcw, w") | 3377 [(set (match_operand:SI 0 "dest_reg_operand" "=q,q, q, r,r, r,r, r, r,r, q, r, r") |
3441 (ior:SI (match_operand:SI 1 "nonmemory_operand" "% 0,Rcq, 0, 0, c, 0, 0, c, c,0, 0, c") | 3378 (ior:SI (match_operand:SI 1 "register_operand" "%0,q, 0, 0,r, 0,0, r, r,0, r, 0, r") |
3442 (match_operand:SI 2 "nonmemory_operand" "Rcqq, 0, C0p, cL, 0,C0p, I,cL,C0p,I,Cal,Cal")))] | 3379 (match_operand:SI 2 "nonmemory_operand" "q,0,C0p,rL,0,C0p,I,rL,C0p,I,C0x,Cal,Cal")))] |
3443 "" | 3380 "" |
3444 "* | 3381 "@ |
3445 switch (which_alternative) | 3382 or%?\\t%0,%1,%2 |
3446 { | 3383 or%?\\t%0,%2,%1 |
3447 case 0: case 3: case 6: case 7: case 9: case 10: case 11: | 3384 bset%?\\t%0,%1,%z2 |
3448 return \"or%? %0,%1,%2%&\"; | 3385 or%?\\t%0,%1,%2 |
3449 case 1: case 4: | 3386 or%?\\t%0,%2,%1 |
3450 return \"or%? %0,%2,%1%&\"; | 3387 bset%?\\t%0,%1,%z2 |
3451 case 2: case 5: case 8: | 3388 or%?\\t%0,%1,%2 |
3452 return \"bset%? %0,%1,%z2%&\"; | 3389 or%?\\t%0,%1,%2 |
3453 default: | 3390 bset%?\\t%0,%1,%z2 |
3454 gcc_unreachable (); | 3391 or%?\\t%0,%1,%2 |
3455 }" | 3392 # |
3456 [(set_attr "iscompact" "maybe,maybe,maybe,false,false,false,false,false,false,false,false,false") | 3393 or%?\\t%0,%1,%2 |
3457 (set_attr "length" "*,*,*,4,4,4,4,4,4,4,8,8") | 3394 or%?\\t%0,%1,%2" |
3458 (set_attr "predicable" "no,no,no,yes,yes,yes,no,no,no,no,yes,no") | 3395 "reload_completed |
3459 (set_attr "cond" "canuse,canuse,canuse,canuse,canuse,canuse,canuse_limm,nocond,nocond,canuse_limm,canuse,nocond")]) | 3396 && GET_CODE (PATTERN (insn)) != COND_EXEC |
3397 && register_operand (operands[0], SImode) | |
3398 && IN_RANGE (REGNO (operands[0]) ^ 4, 4, 11) | |
3399 && satisfies_constraint_C0x (operands[2])" | |
3400 [(const_int 0)] | |
3401 " | |
3402 arc_split_ior (operands); | |
3403 DONE; | |
3404 " | |
3405 [(set_attr "iscompact" "maybe,maybe,maybe,false,false,false,false,false,false,false,false,false,false") | |
3406 (set_attr "length" "*,*,*,4,4,4,4,4,4,4,*,8,8") | |
3407 (set_attr "predicable" "no,no,no,yes,yes,yes,no,no,no,no,no,yes,no") | |
3408 (set_attr "cond" "canuse,canuse,canuse,canuse,canuse,canuse,canuse_limm,nocond,nocond,canuse_limm,nocond,canuse,nocond")]) | |
3460 | 3409 |
3461 (define_insn "xorsi3" | 3410 (define_insn "xorsi3" |
3462 [(set (match_operand:SI 0 "dest_reg_operand" "=Rcqq,Rcq,Rcw,Rcw,Rcw,Rcw, w, w,w, w, w") | 3411 [(set (match_operand:SI 0 "dest_reg_operand" "=Rcqq,Rcq,Rcw,Rcw,Rcw,Rcw, w, w,w, w, w") |
3463 (xor:SI (match_operand:SI 1 "register_operand" "%0, Rcq, 0, c, 0, 0, c, c,0, 0, c") | 3412 (xor:SI (match_operand:SI 1 "register_operand" "%0, Rcq, 0, c, 0, 0, c, c,0, 0, c") |
3464 (match_operand:SI 2 "nonmemory_operand" " Rcqq, 0, cL, 0,C0p, I,cL,C0p,I,Cal,Cal")))] | 3413 (match_operand:SI 2 "nonmemory_operand" " Rcqq, 0, cL, 0,C0p, I,cL,C0p,I,Cal,Cal")))] |
3581 (match_operator:SI 3 "shift_operator" | 3530 (match_operator:SI 3 "shift_operator" |
3582 [(match_operand:SI 1 "register_operand" "0,0") | 3531 [(match_operand:SI 1 "register_operand" "0,0") |
3583 (match_operand:SI 2 "nonmemory_operand" "rn,Cal")])) | 3532 (match_operand:SI 2 "nonmemory_operand" "rn,Cal")])) |
3584 (clobber (match_scratch:SI 4 "=X,X")) | 3533 (clobber (match_scratch:SI 4 "=X,X")) |
3585 (clobber (reg:SI LP_COUNT)) | 3534 (clobber (reg:SI LP_COUNT)) |
3586 (clobber (reg:SI LP_START)) | |
3587 (clobber (reg:SI LP_END)) | |
3588 (clobber (reg:CC CC_REG)) | 3535 (clobber (reg:CC CC_REG)) |
3589 ] | 3536 ] |
3590 "!TARGET_BARREL_SHIFTER" | 3537 "!TARGET_BARREL_SHIFTER" |
3591 "* return output_shift (operands);" | 3538 "* return output_shift (operands);" |
3592 [(set_attr "type" "shift") | 3539 [(set_attr "type" "shift") |
3789 operands[2] = force_reg (SImode, operands[2]); | 3736 operands[2] = force_reg (SImode, operands[2]); |
3790 | 3737 |
3791 }) | 3738 }) |
3792 | 3739 |
3793 (define_mode_iterator SDF [(SF "TARGET_FP_SP_BASE || TARGET_OPTFPE") | 3740 (define_mode_iterator SDF [(SF "TARGET_FP_SP_BASE || TARGET_OPTFPE") |
3794 (DF "TARGET_OPTFPE")]) | 3741 (DF "TARGET_FP_DP_BASE || TARGET_OPTFPE")]) |
3795 | 3742 |
3796 (define_expand "cstore<mode>4" | 3743 (define_expand "cstore<mode>4" |
3797 [(set (reg:CC CC_REG) | 3744 [(set (reg:CC CC_REG) |
3798 (compare:CC (match_operand:SDF 2 "register_operand" "") | 3745 (compare:CC (match_operand:SDF 2 "register_operand" "") |
3799 (match_operand:SDF 3 "register_operand" ""))) | 3746 (match_operand:SDF 3 "register_operand" ""))) |
3800 (set (match_operand:SI 0 "dest_reg_operand" "") | 3747 (set (match_operand:SI 0 "dest_reg_operand" "") |
3801 (match_operator:SI 1 "comparison_operator" [(reg CC_REG) | 3748 (match_operator:SI 1 "comparison_operator" [(reg CC_REG) |
3802 (const_int 0)]))] | 3749 (const_int 0)]))] |
3803 | 3750 |
3804 "TARGET_FP_SP_BASE || TARGET_OPTFPE" | 3751 "TARGET_HARD_FLOAT || TARGET_OPTFPE" |
3805 { | 3752 { |
3806 gcc_assert (XEXP (operands[1], 0) == operands[2]); | 3753 gcc_assert (XEXP (operands[1], 0) == operands[2]); |
3807 gcc_assert (XEXP (operands[1], 1) == operands[3]); | 3754 gcc_assert (XEXP (operands[1], 1) == operands[3]); |
3808 operands[1] = gen_compare_reg (operands[1], SImode); | 3755 operands[1] = gen_compare_reg (operands[1], SImode); |
3809 emit_insn (gen_scc_insn (operands[0], operands[1])); | 3756 emit_insn (gen_scc_insn (operands[0], operands[1])); |
3832 VOIDmode, | 3779 VOIDmode, |
3833 XEXP (operands[1], 0), XEXP (operands[1], 1)); | 3780 XEXP (operands[1], 0), XEXP (operands[1], 1)); |
3834 } | 3781 } |
3835 [(set_attr "type" "unary")]) | 3782 [(set_attr "type" "unary")]) |
3836 | 3783 |
3837 ;; ??? At least for ARC600, we should use sbc b,b,s12 if we want a value | |
3838 ;; that is one lower if the carry flag is set. | |
3839 | |
3840 ;; ??? Look up negscc insn. See pa.md for example. | |
3841 (define_insn "*neg_scc_insn" | |
3842 [(set (match_operand:SI 0 "dest_reg_operand" "=w") | |
3843 (neg:SI (match_operator:SI 1 "proper_comparison_operator" | |
3844 [(reg CC_REG) (const_int 0)])))] | |
3845 "" | |
3846 "mov %0,-1\;sub.%D1 %0,%0,%0" | |
3847 [(set_attr "type" "unary") | |
3848 (set_attr "length" "8")]) | |
3849 | |
3850 (define_insn "*not_scc_insn" | |
3851 [(set (match_operand:SI 0 "dest_reg_operand" "=w") | |
3852 (not:SI (match_operator:SI 1 "proper_comparison_operator" | |
3853 [(reg CC_REG) (const_int 0)])))] | |
3854 "" | |
3855 "mov %0,1\;sub.%d1 %0,%0,%0" | |
3856 [(set_attr "type" "unary") | |
3857 (set_attr "length" "8")]) | |
3858 | |
3859 ; cond_exec patterns | 3784 ; cond_exec patterns |
3860 (define_insn "*movsi_ne" | 3785 (define_insn "*movsi_ne" |
3861 [(cond_exec | 3786 [(cond_exec |
3862 (ne (match_operand:CC_Z 2 "cc_use_register" "Rcc, Rcc, Rcc,Rcc,Rcc") (const_int 0)) | 3787 (ne (match_operand:CC_Z 2 "cc_use_register" "Rcc,Rcc,Rcc,Rcc,Rcc") (const_int 0)) |
3863 (set (match_operand:SI 0 "dest_reg_operand" "=Rcq#q,Rcq#q,Rcq#q, w,w") | 3788 (set (match_operand:SI 0 "dest_reg_operand" "=q, q, r, q, r") |
3864 (match_operand:SI 1 "nonmemory_operand" "C_0, h, ?Cal, Lc,?Cal")))] | 3789 (match_operand:SI 1 "nonmemory_operand" "C_0, h, Lr,Cal,Cal")))] |
3865 "" | 3790 "" |
3866 "@ | 3791 "@ |
3867 * current_insn_predicate = 0; return \"sub%?.ne %0,%0,%0%&\"; | 3792 * current_insn_predicate = 0; return \"sub%?.ne\\t%0,%0,%0\"; |
3868 * current_insn_predicate = 0; return \"mov%?.ne %0,%1\"; | 3793 * current_insn_predicate = 0; return \"mov%?.ne\\t%0,%1\"; |
3869 * current_insn_predicate = 0; return \"mov%?.ne %0,%1\"; | 3794 mov.ne\\t%0,%1 |
3870 mov.ne %0,%1 | 3795 * current_insn_predicate = 0; return \"mov%?.ne\\t%0,%1\"; |
3871 mov.ne %0,%1" | 3796 mov.ne\\t%0,%1" |
3872 [(set_attr "type" "cmove") | 3797 [(set_attr "type" "cmove") |
3873 (set_attr "iscompact" "true,true,true_limm,false,false") | 3798 (set_attr "iscompact" "true,true,false,true_limm,false") |
3874 (set_attr "length" "2,2,6,4,8") | 3799 (set_attr "length" "2,2,4,6,8") |
3875 (set_attr "cpu_facility" "*,av2,av2,*,*")]) | 3800 (set_attr "cpu_facility" "*,av2,*,av2,*")]) |
3876 | 3801 |
3877 (define_insn "*movsi_cond_exec" | 3802 (define_insn "*movsi_cond_exec" |
3878 [(cond_exec | 3803 [(cond_exec |
3879 (match_operator 3 "proper_comparison_operator" | 3804 (match_operator 3 "proper_comparison_operator" |
3880 [(match_operand 2 "cc_register" "Rcc,Rcc") (const_int 0)]) | 3805 [(match_operand 2 "cc_register" "Rcc,Rcc") (const_int 0)]) |
4104 [(set_attr "type" "jump") | 4029 [(set_attr "type" "jump") |
4105 (set_attr "iscompact" "false,false,false,maybe,false") | 4030 (set_attr "iscompact" "false,false,false,maybe,false") |
4106 (set_attr "cond" "canuse,canuse_limm,canuse,canuse,canuse")]) | 4031 (set_attr "cond" "canuse,canuse_limm,canuse,canuse,canuse")]) |
4107 | 4032 |
4108 ;; Implement a switch statement. | 4033 ;; Implement a switch statement. |
4109 | |
4110 (define_expand "casesi" | 4034 (define_expand "casesi" |
4111 [(set (match_dup 5) | 4035 [(match_operand:SI 0 "register_operand" "") ; Index |
4112 (minus:SI (match_operand:SI 0 "register_operand" "") | 4036 (match_operand:SI 1 "const_int_operand" "") ; Lower bound |
4113 (match_operand:SI 1 "nonmemory_operand" ""))) | 4037 (match_operand:SI 2 "const_int_operand" "") ; Total range |
4114 (set (reg:CC CC_REG) | 4038 (match_operand:SI 3 "" "") ; Table label |
4115 (compare:CC (match_dup 5) | 4039 (match_operand:SI 4 "" "")] ; Out of range label |
4116 (match_operand:SI 2 "nonmemory_operand" ""))) | 4040 "" |
4117 (set (pc) | |
4118 (if_then_else (gtu (reg:CC CC_REG) | |
4119 (const_int 0)) | |
4120 (label_ref (match_operand 4 "" "")) | |
4121 (pc))) | |
4122 (set (match_dup 6) | |
4123 (unspec:SI [(match_operand 3 "" "") | |
4124 (match_dup 5) (match_dup 7)] UNSPEC_ARC_CASESI)) | |
4125 (parallel [(set (pc) (match_dup 6)) (use (match_dup 7))])] | |
4126 "" | |
4127 " | |
4128 { | 4041 { |
4129 rtx x; | 4042 if (operands[1] != const0_rtx) |
4130 | |
4131 operands[5] = gen_reg_rtx (SImode); | |
4132 operands[6] = gen_reg_rtx (SImode); | |
4133 operands[7] = operands[3]; | |
4134 emit_insn (gen_subsi3 (operands[5], operands[0], operands[1])); | |
4135 emit_insn (gen_cmpsi_cc_insn_mixed (operands[5], operands[2])); | |
4136 x = gen_rtx_GTU (VOIDmode, gen_rtx_REG (CCmode, CC_REG), const0_rtx); | |
4137 x = gen_rtx_IF_THEN_ELSE (VOIDmode, x, | |
4138 gen_rtx_LABEL_REF (VOIDmode, operands[4]), pc_rtx); | |
4139 emit_jump_insn (gen_rtx_SET (pc_rtx, x)); | |
4140 if (TARGET_COMPACT_CASESI) | |
4141 { | 4043 { |
4142 emit_jump_insn (gen_casesi_compact_jump (operands[5], operands[7])); | 4044 rtx reg = gen_reg_rtx (SImode); |
4045 emit_insn (gen_subsi3 (reg, operands[0], operands[1])); | |
4046 operands[0] = reg; | |
4143 } | 4047 } |
4048 emit_jump_insn (gen_cbranchsi4 (gen_rtx_GTU (SImode, operands[0], | |
4049 operands[2]), | |
4050 operands[0], operands[2], operands[4])); | |
4051 if (TARGET_BI_BIH) | |
4052 emit_jump_insn (gen_casesi_dispatch (operands[0], operands[3])); | |
4144 else | 4053 else |
4145 { | 4054 { |
4055 rtx reg = gen_reg_rtx (SImode); | |
4056 rtx lbl = operands[3]; | |
4146 operands[3] = gen_rtx_LABEL_REF (VOIDmode, operands[3]); | 4057 operands[3] = gen_rtx_LABEL_REF (VOIDmode, operands[3]); |
4147 if (flag_pic || !cse_not_expected) | 4058 if (flag_pic) |
4148 operands[3] = force_reg (Pmode, operands[3]); | 4059 operands[3] = force_reg (Pmode, operands[3]); |
4149 emit_insn (gen_casesi_load (operands[6], | 4060 emit_insn (gen_casesi_load (reg, |
4150 operands[3], operands[5], operands[7])); | 4061 operands[3], operands[0], lbl)); |
4151 if (CASE_VECTOR_PC_RELATIVE || flag_pic) | 4062 if (CASE_VECTOR_PC_RELATIVE || flag_pic) |
4152 emit_insn (gen_addsi3 (operands[6], operands[6], operands[3])); | 4063 emit_insn (gen_addsi3 (reg, reg, operands[3])); |
4153 emit_jump_insn (gen_casesi_jump (operands[6], operands[7])); | 4064 emit_jump_insn (gen_casesi_jump (reg, lbl)); |
4154 } | 4065 } |
4155 DONE; | 4066 DONE; |
4156 }") | 4067 }) |
4068 | |
4069 (define_insn "casesi_dispatch" | |
4070 [(set (pc) | |
4071 (unspec:SI [(match_operand:SI 0 "register_operand" "r") | |
4072 (label_ref (match_operand 1 "" ""))] | |
4073 UNSPEC_ARC_CASESI))] | |
4074 "TARGET_BI_BIH" | |
4075 { | |
4076 rtx diff_vec = PATTERN (next_nonnote_insn (as_a<rtx_insn *> (operands[1]))); | |
4077 gcc_assert (GET_CODE (diff_vec) == ADDR_DIFF_VEC); | |
4078 switch (GET_MODE (diff_vec)) | |
4079 { | |
4080 case E_SImode: | |
4081 return \"bi\\t[%0]\"; | |
4082 case E_HImode: | |
4083 case E_QImode: | |
4084 return \"bih\\t[%0]\"; | |
4085 default: gcc_unreachable (); | |
4086 } | |
4087 } | |
4088 [(set_attr "type" "brcc_no_delay_slot") | |
4089 (set_attr "iscompact" "false") | |
4090 (set_attr "length" "4")]) | |
4157 | 4091 |
4158 (define_insn "casesi_load" | 4092 (define_insn "casesi_load" |
4159 [(set (match_operand:SI 0 "register_operand" "=Rcq,r,r") | 4093 [(set (match_operand:SI 0 "register_operand" "=q,r,r") |
4160 (unspec:SI [(match_operand:SI 1 "nonmemory_operand" "Rcq,c,Cal") | 4094 (mem:SI (unspec:SI [(match_operand:SI 1 "nonmemory_operand" "q,r,Cal") |
4161 (match_operand:SI 2 "register_operand" "Rcq,c,c") | 4095 (match_operand:SI 2 "register_operand" "q,r,r")] |
4162 (label_ref (match_operand 3 "" ""))] UNSPEC_ARC_CASESI))] | 4096 UNSPEC_ARC_CASESI))) |
4097 (use (label_ref (match_operand 3 "" "")))] | |
4163 "" | 4098 "" |
4164 "* | 4099 "* |
4165 { | 4100 { |
4166 rtx diff_vec = PATTERN (next_nonnote_insn (as_a<rtx_insn *> (operands[3]))); | 4101 rtx diff_vec = PATTERN (next_nonnote_insn (as_a<rtx_insn *> (operands[3]))); |
4167 | 4102 |
4173 } | 4108 } |
4174 | 4109 |
4175 switch (GET_MODE (diff_vec)) | 4110 switch (GET_MODE (diff_vec)) |
4176 { | 4111 { |
4177 case E_SImode: | 4112 case E_SImode: |
4178 return \"ld.as %0,[%1,%2]%&\"; | 4113 return \"ld.as\\t%0,[%1,%2]%&\"; |
4179 case E_HImode: | 4114 case E_HImode: |
4180 if (ADDR_DIFF_VEC_FLAGS (diff_vec).offset_unsigned) | 4115 if (ADDR_DIFF_VEC_FLAGS (diff_vec).offset_unsigned) |
4181 return \"ld%_.as %0,[%1,%2]\"; | 4116 return \"ld%_.as\\t%0,[%1,%2]\"; |
4182 return \"ld%_.x.as %0,[%1,%2]\"; | 4117 return \"ld%_.x.as\\t%0,[%1,%2]\"; |
4183 case E_QImode: | 4118 case E_QImode: |
4184 if (ADDR_DIFF_VEC_FLAGS (diff_vec).offset_unsigned) | 4119 if (ADDR_DIFF_VEC_FLAGS (diff_vec).offset_unsigned) |
4185 return \"ldb%? %0,[%1,%2]%&\"; | 4120 return \"ldb%?\\t%0,[%1,%2]%&\"; |
4186 return \"ldb.x %0,[%1,%2]\"; | 4121 return \"ldb.x\\t%0,[%1,%2]\"; |
4187 default: | 4122 default: |
4188 gcc_unreachable (); | 4123 gcc_unreachable (); |
4189 } | 4124 } |
4190 }" | 4125 }" |
4191 [(set_attr "type" "load") | 4126 [(set_attr "type" "load") |
4221 "j%!%* [%0]%&" | 4156 "j%!%* [%0]%&" |
4222 [(set_attr "type" "jump") | 4157 [(set_attr "type" "jump") |
4223 (set_attr "iscompact" "false,maybe,false") | 4158 (set_attr "iscompact" "false,maybe,false") |
4224 (set_attr "cond" "canuse")]) | 4159 (set_attr "cond" "canuse")]) |
4225 | 4160 |
4226 (define_insn "casesi_compact_jump" | |
4227 [(set (pc) | |
4228 (unspec:SI [(match_operand:SI 0 "register_operand" "c,q")] | |
4229 UNSPEC_ARC_CASESI)) | |
4230 (use (label_ref (match_operand 1 "" ""))) | |
4231 (clobber (match_scratch:SI 2 "=q,0"))] | |
4232 "TARGET_COMPACT_CASESI" | |
4233 "* | |
4234 { | |
4235 rtx diff_vec = PATTERN (next_nonnote_insn (as_a<rtx_insn *> (operands[1]))); | |
4236 int unalign = arc_get_unalign (); | |
4237 rtx xop[3]; | |
4238 const char *s; | |
4239 | |
4240 xop[0] = operands[0]; | |
4241 xop[2] = operands[2]; | |
4242 gcc_assert (GET_CODE (diff_vec) == ADDR_DIFF_VEC); | |
4243 | |
4244 switch (GET_MODE (diff_vec)) | |
4245 { | |
4246 case E_SImode: | |
4247 /* Max length can be 12 in this case, but this is OK because | |
4248 2 of these are for alignment, and are anticipated in the length | |
4249 of the ADDR_DIFF_VEC. */ | |
4250 if (unalign && !satisfies_constraint_Rcq (xop[0])) | |
4251 s = \"add2 %2,pcl,%0\n\tld_s %2,[%2,12]\"; | |
4252 else if (unalign) | |
4253 s = \"add_s %2,%0,2\n\tld.as %2,[pcl,%2]\"; | |
4254 else | |
4255 s = \"add %2,%0,2\n\tld.as %2,[pcl,%2]\"; | |
4256 arc_clear_unalign (); | |
4257 break; | |
4258 case E_HImode: | |
4259 if (ADDR_DIFF_VEC_FLAGS (diff_vec).offset_unsigned) | |
4260 { | |
4261 if (satisfies_constraint_Rcq (xop[0])) | |
4262 { | |
4263 s = \"add_s %2,%0,%1\n\tld%_.as %2,[pcl,%2]\"; | |
4264 xop[1] = GEN_INT ((10 - unalign) / 2U); | |
4265 } | |
4266 else | |
4267 { | |
4268 s = \"add1 %2,pcl,%0\n\tld%__s %2,[%2,%1]\"; | |
4269 xop[1] = GEN_INT (10 + unalign); | |
4270 } | |
4271 } | |
4272 else | |
4273 { | |
4274 if (satisfies_constraint_Rcq (xop[0])) | |
4275 { | |
4276 s = \"add_s %2,%0,%1\n\tld%_.x.as %2,[pcl,%2]\"; | |
4277 xop[1] = GEN_INT ((10 - unalign) / 2U); | |
4278 } | |
4279 else | |
4280 { | |
4281 s = \"add1 %2,pcl,%0\n\tld%__s.x %2,[%2,%1]\"; | |
4282 xop[1] = GEN_INT (10 + unalign); | |
4283 } | |
4284 } | |
4285 arc_toggle_unalign (); | |
4286 break; | |
4287 case E_QImode: | |
4288 if (ADDR_DIFF_VEC_FLAGS (diff_vec).offset_unsigned) | |
4289 { | |
4290 if ((rtx_equal_p (xop[2], xop[0]) | |
4291 || find_reg_note (insn, REG_DEAD, xop[0])) | |
4292 && satisfies_constraint_Rcq (xop[0])) | |
4293 { | |
4294 s = \"add_s %0,%0,pcl\n\tldb_s %2,[%0,%1]\"; | |
4295 xop[1] = GEN_INT (8 + unalign); | |
4296 } | |
4297 else | |
4298 { | |
4299 s = \"add %2,%0,pcl\n\tldb_s %2,[%2,%1]\"; | |
4300 xop[1] = GEN_INT (10 + unalign); | |
4301 arc_toggle_unalign (); | |
4302 } | |
4303 } | |
4304 else if ((rtx_equal_p (xop[0], xop[2]) | |
4305 || find_reg_note (insn, REG_DEAD, xop[0])) | |
4306 && satisfies_constraint_Rcq (xop[0])) | |
4307 { | |
4308 s = \"add_s %0,%0,%1\n\tldb.x %2,[pcl,%0]\"; | |
4309 xop[1] = GEN_INT (10 - unalign); | |
4310 arc_toggle_unalign (); | |
4311 } | |
4312 else | |
4313 { | |
4314 /* ??? Length is 12. */ | |
4315 s = \"add %2,%0,%1\n\tldb.x %2,[pcl,%2]\"; | |
4316 xop[1] = GEN_INT (8 + unalign); | |
4317 } | |
4318 break; | |
4319 default: | |
4320 gcc_unreachable (); | |
4321 } | |
4322 output_asm_insn (s, xop); | |
4323 return \"add_s %2,%2,pcl\n\tj_s%* [%2]\"; | |
4324 }" | |
4325 [(set_attr "length" "10") | |
4326 (set_attr "type" "jump") | |
4327 (set_attr "iscompact" "true") | |
4328 (set_attr "cond" "nocond")]) | |
4329 | |
4330 (define_expand "call" | 4161 (define_expand "call" |
4331 ;; operands[1] is stack_size_rtx | 4162 ;; operands[1] is stack_size_rtx |
4332 ;; operands[2] is next_arg_register | 4163 ;; operands[2] is next_arg_register |
4333 [(parallel [(call (match_operand:SI 0 "call_operand" "") | 4164 [(parallel [(call (match_operand:SI 0 "call_operand" "") |
4334 (match_operand 1 "" "")) | 4165 (match_operand 1 "" "")) |
4452 [(unspec_volatile [(const_int 0)] VUNSPEC_ARC_BLOCKAGE)] | 4283 [(unspec_volatile [(const_int 0)] VUNSPEC_ARC_BLOCKAGE)] |
4453 "" | 4284 "" |
4454 "" | 4285 "" |
4455 [(set_attr "length" "0") | 4286 [(set_attr "length" "0") |
4456 (set_attr "type" "block")] | 4287 (set_attr "type" "block")] |
4288 ) | |
4289 | |
4290 (define_insn "arc600_stall" | |
4291 [(unspec_volatile [(const_int 0)] VUNSPEC_ARC_ARC600_STALL)] | |
4292 "TARGET_MUL64_SET" | |
4293 "mov\\t0,mlo\t;wait until multiply complete." | |
4294 [(set_attr "length" "4") | |
4295 (set_attr "type" "move")] | |
4457 ) | 4296 ) |
4458 | 4297 |
4459 ;; Split up troublesome insns for better scheduling. | 4298 ;; Split up troublesome insns for better scheduling. |
4460 | 4299 |
4461 ;; Peepholes go at the end. | 4300 ;; Peepholes go at the end. |
4757 "brk" | 4596 "brk" |
4758 [(set_attr "length" "4") | 4597 [(set_attr "length" "4") |
4759 (set_attr "type" "misc")]) | 4598 (set_attr "type" "misc")]) |
4760 | 4599 |
4761 (define_insn "rtie" | 4600 (define_insn "rtie" |
4762 [(unspec_volatile [(match_operand:SI 0 "immediate_operand" "N")] | 4601 [(return) |
4763 VUNSPEC_ARC_RTIE)] | 4602 (unspec_volatile [(const_int 0)] VUNSPEC_ARC_RTIE)] |
4764 "" | 4603 "!TARGET_ARC600_FAMILY" |
4765 "rtie" | 4604 "rtie" |
4766 [(set_attr "length" "4") | 4605 [(set_attr "length" "4") |
4767 (set_attr "type" "misc") | 4606 (set_attr "type" "rtie") |
4768 (set_attr "cond" "clob")]) | 4607 (set_attr "cond" "clob")]) |
4769 | 4608 |
4770 (define_insn "sync" | 4609 (define_insn "sync" |
4771 [(unspec_volatile [(match_operand:SI 0 "immediate_operand" "N")] | 4610 [(unspec_volatile [(match_operand:SI 0 "immediate_operand" "N")] |
4772 VUNSPEC_ARC_SYNC)] | 4611 VUNSPEC_ARC_SYNC)] |
4773 "" | 4612 "" |
4839 VUNSPEC_ARC_SR)] | 4678 VUNSPEC_ARC_SR)] |
4840 "" | 4679 "" |
4841 "sr\t%0, [%1]" | 4680 "sr\t%0, [%1]" |
4842 [(set_attr "length" "8,4,8,4") | 4681 [(set_attr "length" "8,4,8,4") |
4843 (set_attr "type" "sr,sr,sr,sr")]) | 4682 (set_attr "type" "sr,sr,sr,sr")]) |
4683 | |
4684 (define_mode_iterator ALLI [QI HI SI (DI "TARGET_LL64")]) | |
4685 (define_mode_attr mALLI [(QI "b") (HI "%_") (SI "") (DI "d")]) | |
4686 | |
4687 (define_insn "lddi<mode>" | |
4688 [(set (match_operand:ALLI 0 "register_operand" "=r") | |
4689 (unspec_volatile:ALLI [(match_operand:ALLI 1 "memory_operand" "m")] | |
4690 VUNSPEC_ARC_LDDI))] | |
4691 "" | |
4692 "ld<mALLI>%U1.di\\t%0,%1" | |
4693 [(set_attr "type" "load")]) | |
4694 | |
4695 (define_insn "stdi<mode>" | |
4696 [(unspec_volatile [(match_operand:ALLI 0 "memory_operand" "m,m,Usc") | |
4697 (match_operand:ALLI 1 "nonmemory_operand" "r,Cm3,i")] | |
4698 VUNSPEC_ARC_STDI)] | |
4699 "" | |
4700 "st<mALLI>%U0.di\\t%1,%0" | |
4701 [(set_attr "length" "*,*,8") | |
4702 (set_attr "type" "store")]) | |
4703 | |
4704 (define_insn_and_split "*stdidi_split" | |
4705 [(unspec_volatile [(match_operand:DI 0 "memory_operand" "m") | |
4706 (match_operand:DI 1 "register_operand" "r")] | |
4707 VUNSPEC_ARC_STDI)] | |
4708 "!TARGET_LL64" | |
4709 "#" | |
4710 "&& reload_completed" | |
4711 [(unspec_volatile:SI [(match_dup 2) (match_dup 3)] VUNSPEC_ARC_STDI) | |
4712 (unspec_volatile:SI [(match_dup 4) (match_dup 5)] VUNSPEC_ARC_STDI)] | |
4713 " | |
4714 { | |
4715 operands[3] = gen_lowpart (SImode, operands[1]); | |
4716 operands[5] = gen_highpart_mode (SImode, DImode, operands[1]); | |
4717 operands[2] = gen_lowpart (SImode, operands[0]); | |
4718 operands[4] = gen_highpart (SImode, operands[0]); | |
4719 } | |
4720 " | |
4721 ) | |
4722 | |
4723 (define_insn_and_split "*lddidi_split" | |
4724 [(set (match_operand:DI 0 "register_operand" "=r") | |
4725 (unspec_volatile:DI [(match_operand:DI 1 "memory_operand" "m")] | |
4726 VUNSPEC_ARC_LDDI))] | |
4727 "!TARGET_LL64" | |
4728 "#" | |
4729 "&& reload_completed" | |
4730 [(set (match_dup 2) (unspec_volatile:SI [(match_dup 3)] VUNSPEC_ARC_LDDI)) | |
4731 (set (match_dup 4) (unspec_volatile:SI [(match_dup 5)] VUNSPEC_ARC_LDDI))] | |
4732 " | |
4733 { | |
4734 operands[3] = gen_lowpart (SImode, operands[1]); | |
4735 operands[5] = gen_highpart (SImode, operands[1]); | |
4736 operands[2] = gen_lowpart (SImode, operands[0]); | |
4737 operands[4] = gen_highpart (SImode, operands[0]); | |
4738 } | |
4739 " | |
4740 ) | |
4844 | 4741 |
4845 (define_insn "trap_s" | 4742 (define_insn "trap_s" |
4846 [(unspec_volatile [(match_operand:SI 0 "immediate_operand" "L,Cal")] | 4743 [(unspec_volatile [(match_operand:SI 0 "immediate_operand" "L,Cal")] |
4847 VUNSPEC_ARC_TRAP_S)] | 4744 VUNSPEC_ARC_TRAP_S)] |
4848 "!TARGET_ARC600_FAMILY" | 4745 "!TARGET_ARC600_FAMILY" |
4915 }" | 4812 }" |
4916 ) | 4813 ) |
4917 | 4814 |
4918 (define_insn "*sibcall_insn" | 4815 (define_insn "*sibcall_insn" |
4919 [(call (mem:SI (match_operand:SI 0 "call_address_operand" | 4816 [(call (mem:SI (match_operand:SI 0 "call_address_operand" |
4920 "Cbp,Cbr,Rs5,Rsc,Cal")) | 4817 "Cbp,Cbr,!Rcd,Rsc,Cal")) |
4921 (match_operand 1 "" "")) | 4818 (match_operand 1 "" "")) |
4922 (simple_return) | 4819 (simple_return) |
4923 (use (match_operand 2 "" ""))] | 4820 (use (match_operand 2 "" ""))] |
4924 "" | 4821 "" |
4925 "@ | 4822 "@ |
4926 b%!%* %P0 | 4823 b%!%*\\t%P0 |
4927 b%!%* %P0 | 4824 b%!%*\\t%P0 |
4928 j%!%* [%0]%& | 4825 j%!%*\\t[%0] |
4929 j%!%* [%0] | 4826 j%!%*\\t[%0] |
4930 j%! %P0" | 4827 j%!\\t%P0" |
4931 [(set_attr "type" "call,call,call,call,call_no_delay_slot") | 4828 [(set_attr "type" "call,call,call,call,call_no_delay_slot") |
4932 (set_attr "predicable" "yes,no,no,yes,yes") | 4829 (set_attr "predicable" "yes,no,no,yes,yes") |
4933 (set_attr "iscompact" "false,false,maybe,false,false") | 4830 (set_attr "iscompact" "false,false,maybe,false,false") |
4934 (set_attr "is_SIBCALL" "yes")] | 4831 (set_attr "is_SIBCALL" "yes")] |
4935 ) | 4832 ) |
4936 | 4833 |
4937 (define_insn "*sibcall_value_insn" | 4834 (define_insn "*sibcall_value_insn" |
4938 [(set (match_operand 0 "dest_reg_operand" "") | 4835 [(set (match_operand 0 "dest_reg_operand" "") |
4939 (call (mem:SI (match_operand:SI 1 "call_address_operand" | 4836 (call (mem:SI (match_operand:SI 1 "call_address_operand" |
4940 "Cbp,Cbr,Rs5,Rsc,Cal")) | 4837 "Cbp,Cbr,!Rcd,Rsc,Cal")) |
4941 (match_operand 2 "" ""))) | 4838 (match_operand 2 "" ""))) |
4942 (simple_return) | 4839 (simple_return) |
4943 (use (match_operand 3 "" ""))] | 4840 (use (match_operand 3 "" ""))] |
4944 "" | 4841 "" |
4945 "@ | 4842 "@ |
4946 b%!%* %P1 | 4843 b%!%*\\t%P1 |
4947 b%!%* %P1 | 4844 b%!%*\\t%P1 |
4948 j%!%* [%1]%& | 4845 j%!%*\\t[%1] |
4949 j%!%* [%1] | 4846 j%!%*\\t[%1] |
4950 j%! %P1" | 4847 j%!\\t%P1" |
4951 [(set_attr "type" "call,call,call,call,call_no_delay_slot") | 4848 [(set_attr "type" "call,call,call,call,call_no_delay_slot") |
4952 (set_attr "predicable" "yes,no,no,yes,yes") | 4849 (set_attr "predicable" "yes,no,no,yes,yes") |
4953 (set_attr "iscompact" "false,false,maybe,false,false") | 4850 (set_attr "iscompact" "false,false,maybe,false,false") |
4954 (set_attr "is_SIBCALL" "yes")] | 4851 (set_attr "is_SIBCALL" "yes")] |
4955 ) | 4852 ) |
4985 ; represent the blink use in return / sibcall instructions themselves, and | 4882 ; represent the blink use in return / sibcall instructions themselves, and |
4986 ; instead have to show it in EPILOGUE_USES and must explicitly | 4883 ; instead have to show it in EPILOGUE_USES and must explicitly |
4987 ; forbid instructions that change blink in the return / sibcall delay slot. | 4884 ; forbid instructions that change blink in the return / sibcall delay slot. |
4988 (define_insn "simple_return" | 4885 (define_insn "simple_return" |
4989 [(simple_return)] | 4886 [(simple_return)] |
4990 "reload_completed" | 4887 "" |
4991 { | 4888 "j%!%*\\t[blink]" |
4992 rtx reg | 4889 [(set_attr "type" "return") |
4993 = gen_rtx_REG (Pmode, | 4890 (set_attr "cond" "canuse") |
4994 arc_return_address_register (arc_compute_function_type | 4891 (set_attr "iscompact" "maybe") |
4995 (cfun))); | 4892 (set_attr "length" "*")]) |
4996 | 4893 |
4997 if (TARGET_V2 | 4894 (define_insn "arc600_rtie" |
4998 && ARC_INTERRUPT_P (arc_compute_function_type (cfun))) | 4895 [(return) |
4999 { | 4896 (unspec_volatile [(match_operand 0 "pmode_register_operand" "")] |
5000 return \"rtie\"; | 4897 VUNSPEC_ARC_ARC600_RTIE)] |
5001 } | 4898 "TARGET_ARC600_FAMILY" |
5002 output_asm_insn (\"j%!%* [%0]%&\", ®); | 4899 "j.f\\t[%0]" |
5003 return \"\"; | 4900 [(set_attr "length" "4") |
5004 } | 4901 (set_attr "type" "rtie") |
5005 [(set (attr "type") | 4902 (set_attr "cond" "clob")]) |
5006 (cond [(and (match_test "ARC_INTERRUPT_P (arc_compute_function_type (cfun))") | |
5007 (match_test "TARGET_V2")) | |
5008 (const_string "brcc_no_delay_slot")] | |
5009 (const_string "return"))) | |
5010 ; predicable won't help here since the canonical rtl looks different | |
5011 ; for branches. | |
5012 (set (attr "cond") | |
5013 (cond [(and (eq (symbol_ref "arc_compute_function_type (cfun)") | |
5014 (symbol_ref "ARC_FUNCTION_ILINK1")) | |
5015 (match_test "TARGET_V2")) | |
5016 (const_string "nocond")] | |
5017 (const_string "canuse"))) | |
5018 (set (attr "iscompact") | |
5019 (cond [(eq (symbol_ref "arc_compute_function_type (cfun)") | |
5020 (symbol_ref "ARC_FUNCTION_NORMAL")) | |
5021 (const_string "maybe")] | |
5022 (const_string "false"))) | |
5023 (set (attr "length") | |
5024 (cond [(ne (symbol_ref "arc_compute_function_type (cfun)") | |
5025 (symbol_ref "ARC_FUNCTION_NORMAL")) | |
5026 (const_int 4)] | |
5027 (const_int 2)))]) | |
5028 | 4903 |
5029 (define_insn "p_return_i" | 4904 (define_insn "p_return_i" |
5030 [(set (pc) | 4905 [(set (pc) |
5031 (if_then_else (match_operator 0 "proper_comparison_operator" | 4906 (if_then_else (match_operator 0 "proper_comparison_operator" |
5032 [(reg CC_REG) (const_int 0)]) | 4907 [(reg CC_REG) (const_int 0)]) |
5033 (simple_return) (pc)))] | 4908 (simple_return) (pc)))] |
5034 "reload_completed | 4909 "reload_completed" |
5035 && !(TARGET_V2 | |
5036 && ARC_INTERRUPT_P (arc_compute_function_type (cfun)))" | |
5037 { | 4910 { |
5038 rtx xop[2]; | 4911 output_asm_insn (\"j%d0%!%#\\t[blink]\", operands); |
5039 xop[0] = operands[0]; | |
5040 xop[1] | |
5041 = gen_rtx_REG (Pmode, | |
5042 arc_return_address_register (arc_compute_function_type | |
5043 (cfun))); | |
5044 | |
5045 output_asm_insn (\"j%d0%!%# [%1]%&\", xop); | |
5046 /* record the condition in case there is a delay insn. */ | 4912 /* record the condition in case there is a delay insn. */ |
5047 arc_ccfsm_record_condition (xop[0], false, insn, 0); | 4913 arc_ccfsm_record_condition (operands[0], false, insn, 0); |
5048 return \"\"; | 4914 return \"\"; |
5049 } | 4915 } |
5050 [(set_attr "type" "return") | 4916 [(set_attr "type" "return") |
5051 (set_attr "cond" "use") | 4917 (set_attr "cond" "use") |
5052 (set (attr "iscompact") | 4918 (set_attr "iscompact" "maybe" ) |
5053 (cond [(eq (symbol_ref "arc_compute_function_type (cfun)") | |
5054 (symbol_ref "ARC_FUNCTION_NORMAL")) | |
5055 (const_string "maybe")] | |
5056 (const_string "false"))) | |
5057 (set (attr "length") | 4919 (set (attr "length") |
5058 (cond [(ne (symbol_ref "arc_compute_function_type (cfun)") | 4920 (cond [(not (match_operand 0 "equality_comparison_operator" "")) |
5059 (symbol_ref "ARC_FUNCTION_NORMAL")) | |
5060 (const_int 4) | |
5061 (not (match_operand 0 "equality_comparison_operator" "")) | |
5062 (const_int 4) | 4921 (const_int 4) |
5063 (eq_attr "delay_slot_filled" "yes") | 4922 (eq_attr "delay_slot_filled" "yes") |
5064 (const_int 4)] | 4923 (const_int 4)] |
5065 (const_int 2)))]) | 4924 (const_int 2)))]) |
5066 | 4925 |
5067 ;; ??? #ifdefs in function.c require the presence of this pattern, with a | 4926 ;; Return nonzero if this function is known to have a null epilogue. |
5068 ;; non-constant predicate. | 4927 ;; This allows the optimizer to omit jumps to jumps if no stack |
4928 ;; was created. | |
5069 (define_expand "return" | 4929 (define_expand "return" |
5070 [(return)] | 4930 [(return)] |
5071 "optimize < 0") | 4931 "arc_can_use_return_insn ()" |
4932 "") | |
5072 | 4933 |
5073 ;; Comment in final.c (insn_current_reference_address) says | 4934 ;; Comment in final.c (insn_current_reference_address) says |
5074 ;; forward branch addresses are calculated from the next insn after branch | 4935 ;; forward branch addresses are calculated from the next insn after branch |
5075 ;; and for backward branches, it is calculated from the branch insn start. | 4936 ;; and for backward branches, it is calculated from the branch insn start. |
5076 ;; The shortening logic here is tuned to accomodate this behavior | 4937 ;; The shortening logic here is tuned to accomodate this behavior |
5229 FAIL; | 5090 FAIL; |
5230 operands[2] = gen_rtx_SCRATCH (SImode); | 5091 operands[2] = gen_rtx_SCRATCH (SImode); |
5231 }) | 5092 }) |
5232 | 5093 |
5233 (define_insn "arc_lp" | 5094 (define_insn "arc_lp" |
5234 [(unspec:SI [(match_operand:SI 0 "register_operand" "l")] | 5095 [(unspec:SI [(reg:SI LP_COUNT)] |
5235 UNSPEC_ARC_LP) | 5096 UNSPEC_ARC_LP) |
5236 (use (label_ref (match_operand 1 "" ""))) | 5097 (use (label_ref (match_operand 0 "" ""))) |
5237 (use (label_ref (match_operand 2 "" "")))] | 5098 (use (label_ref (match_operand 1 "" "")))] |
5238 "" | 5099 "" |
5239 "lp\\t@%l2\\t; %0:@%l1->@%l2" | 5100 "lp\\t@%l1\\t; lp_count:@%l0->@%l1" |
5240 [(set_attr "type" "loop_setup") | 5101 [(set_attr "type" "loop_setup") |
5241 (set_attr "length" "4")]) | 5102 (set_attr "length" "4")]) |
5242 | 5103 |
5243 ;; if by any chance the lp_count is not used, then use an 'r' | 5104 ;; if by any chance the lp_count is not used, then use an 'r' |
5244 ;; register, instead of going to memory. | 5105 ;; register, instead of going to memory. |
5245 (define_insn "loop_end" | 5106 (define_insn "loop_end" |
5246 [(set (pc) | 5107 [(set (pc) |
5247 (if_then_else (ne (match_operand:SI 2 "nonimmediate_operand" "0,0") | 5108 (if_then_else (ne (match_operand:SI 2 "nonimmediate_operand" "0,m") |
5248 (const_int 1)) | 5109 (const_int 1)) |
5249 (label_ref (match_operand 1 "" "")) | 5110 (label_ref (match_operand 1 "" "")) |
5250 (pc))) | 5111 (pc))) |
5251 (set (match_operand:SI 0 "nonimmediate_operand" "=l!r,m") | 5112 (set (match_operand:SI 0 "nonimmediate_operand" "=r,m") |
5252 (plus (match_dup 2) (const_int -1))) | 5113 (plus (match_dup 2) (const_int -1))) |
5253 (unspec [(const_int 0)] UNSPEC_ARC_LP) | 5114 (unspec [(const_int 0)] UNSPEC_ARC_LP) |
5254 (clobber (match_scratch:SI 3 "=X,&r"))] | 5115 (clobber (match_scratch:SI 3 "=X,&r"))] |
5255 "" | 5116 "" |
5256 "\\t;%0 %1 %2" | 5117 "; ZOL_END, begins @%l1" |
5257 [(set_attr "length" "0") | 5118 [(set_attr "length" "0") |
5258 (set_attr "predicable" "no") | 5119 (set_attr "predicable" "no") |
5259 (set_attr "type" "loop_end")]) | 5120 (set_attr "type" "loop_end")]) |
5260 | 5121 |
5261 ;; split pattern for the very slim chance when the loop register is | 5122 ;; split pattern for the very slim chance when the loop register is |
5296 (set_attr "predicable" "yes")]) | 5157 (set_attr "predicable" "yes")]) |
5297 | 5158 |
5298 (define_insn_and_split "dbnz" | 5159 (define_insn_and_split "dbnz" |
5299 [(set (pc) | 5160 [(set (pc) |
5300 (if_then_else | 5161 (if_then_else |
5301 (ne (plus:SI (match_operand:SI 0 "nonimmediate_operand" "+r!l,m") | 5162 (ne (plus:SI (match_operand:SI 0 "nonimmediate_operand" "+rl,m") |
5302 (const_int -1)) | 5163 (const_int -1)) |
5303 (const_int 0)) | 5164 (const_int 0)) |
5304 (label_ref (match_operand 1 "" "")) | 5165 (label_ref (match_operand 1 "" "")) |
5305 (pc))) | 5166 (pc))) |
5306 (set (match_dup 0) | 5167 (set (match_dup 0) |
5323 "" | 5184 "" |
5324 [(set_attr "iscompact" "false") | 5185 [(set_attr "iscompact" "false") |
5325 (set_attr "type" "loop_end") | 5186 (set_attr "type" "loop_end") |
5326 (set_attr "length" "4,20")]) | 5187 (set_attr "length" "4,20")]) |
5327 | 5188 |
5328 (define_expand "movmemsi" | 5189 (define_expand "cpymemsi" |
5329 [(match_operand:BLK 0 "" "") | 5190 [(match_operand:BLK 0 "" "") |
5330 (match_operand:BLK 1 "" "") | 5191 (match_operand:BLK 1 "" "") |
5331 (match_operand:SI 2 "nonmemory_operand" "") | 5192 (match_operand:SI 2 "nonmemory_operand" "") |
5332 (match_operand 3 "immediate_operand" "")] | 5193 (match_operand 3 "immediate_operand" "")] |
5333 "" | 5194 "" |
5334 "if (arc_expand_movmem (operands)) DONE; else FAIL;") | 5195 "if (arc_expand_cpymem (operands)) DONE; else FAIL;") |
5335 | 5196 |
5336 ;; Close http://gcc.gnu.org/bugzilla/show_bug.cgi?id=35803 if this works | 5197 ;; Close http://gcc.gnu.org/bugzilla/show_bug.cgi?id=35803 if this works |
5337 ;; to the point that we can generate cmove instructions. | 5198 ;; to the point that we can generate cmove instructions. |
5338 (define_expand "cbranch<mode>4" | 5199 (define_expand "cbranch<mode>4" |
5339 [(set (reg:CC CC_REG) | 5200 [(set (reg:CC CC_REG) |
5445 XVECLEN (operands[0], 0) - 1))); | 5306 XVECLEN (operands[0], 0) - 1))); |
5446 return ""; | 5307 return ""; |
5447 } | 5308 } |
5448 [(set_attr "type" "call") | 5309 [(set_attr "type" "call") |
5449 (set_attr "is_SIBCALL" "yes")]) | 5310 (set_attr "is_SIBCALL" "yes")]) |
5450 | |
5451 (define_insn "tls_load_tp_soft" | |
5452 [(set (reg:SI R0_REG) (unspec:SI [(const_int 0)] UNSPEC_TLS_OFF)) | |
5453 (clobber (reg:SI RETURN_ADDR_REGNUM))] | |
5454 "" | |
5455 "*return arc_output_libcall (\"__read_tp\");" | |
5456 [(set_attr "is_sfunc" "yes") | |
5457 (set_attr "predicable" "yes")]) | |
5458 | |
5459 (define_insn "tls_gd_get_addr" | |
5460 [(set (reg:SI R0_REG) | |
5461 (call:SI (mem:SI (unspec:SI [(match_operand:SI 0 | |
5462 "symbolic_operand" "X,X")] | |
5463 UNSPEC_TLS_GD)) | |
5464 (const_int 0))) | |
5465 (clobber (reg:SI RETURN_ADDR_REGNUM))] | |
5466 "" | |
5467 ".tls_gd_ld %0`bl%* __tls_get_addr@plt" | |
5468 [(set_attr "type" "call") | |
5469 ; With TARGET_MEDIUM_CALLS, plt calls are not predicable. | |
5470 (set_attr "predicable" "no")]) | |
5471 | 5311 |
5472 ;; For thread pointer builtins | 5312 ;; For thread pointer builtins |
5473 (define_expand "get_thread_pointersi" | 5313 (define_expand "get_thread_pointersi" |
5474 [(set (match_operand:SI 0 "register_operand") (match_dup 1))] | 5314 [(set (match_operand:SI 0 "register_operand") (match_dup 1))] |
5475 "" | 5315 "" |
6206 (set (zero_extract:SI (match_dup 0) (match_dup 5) (match_dup 6)) | 6046 (set (zero_extract:SI (match_dup 0) (match_dup 5) (match_dup 6)) |
6207 (zero_extract:SI (match_dup 1) (match_dup 5) (match_dup 7)))]) | 6047 (zero_extract:SI (match_dup 1) (match_dup 5) (match_dup 7)))]) |
6208 (match_dup 1)]) | 6048 (match_dup 1)]) |
6209 | 6049 |
6210 (define_insn "*rotrsi3_cnt1" | 6050 (define_insn "*rotrsi3_cnt1" |
6211 [(set (match_operand:SI 0 "dest_reg_operand" "=w") | 6051 [(set (match_operand:SI 0 "dest_reg_operand" "=r") |
6212 (rotatert:SI (match_operand:SI 1 "register_operand" "c") | 6052 (rotatert:SI (match_operand:SI 1 "nonmemory_operand" "rL") |
6213 (const_int 1)))] | 6053 (const_int 1)))] |
6214 "" | 6054 "" |
6215 "ror %0,%1%&" | 6055 "ror\\t%0,%1" |
6056 [(set_attr "type" "shift") | |
6057 (set_attr "predicable" "no") | |
6058 (set_attr "length" "4")]) | |
6059 | |
6060 (define_insn "*rotrsi3_cnt8" | |
6061 [(set (match_operand:SI 0 "register_operand" "=r") | |
6062 (rotatert:SI (match_operand:SI 1 "nonmemory_operand" "rL") | |
6063 (const_int 8)))] | |
6064 "TARGET_BARREL_SHIFTER && TARGET_V2" | |
6065 "ror8\\t%0,%1" | |
6216 [(set_attr "type" "shift") | 6066 [(set_attr "type" "shift") |
6217 (set_attr "predicable" "no") | 6067 (set_attr "predicable" "no") |
6218 (set_attr "length" "4")]) | 6068 (set_attr "length" "4")]) |
6219 | 6069 |
6220 (define_insn "*ashlsi2_cnt1" | 6070 (define_insn "*ashlsi2_cnt1" |
6223 (const_int 1)))] | 6073 (const_int 1)))] |
6224 "" | 6074 "" |
6225 "asl%? %0,%1%&" | 6075 "asl%? %0,%1%&" |
6226 [(set_attr "type" "shift") | 6076 [(set_attr "type" "shift") |
6227 (set_attr "iscompact" "maybe,false") | 6077 (set_attr "iscompact" "maybe,false") |
6078 (set_attr "length" "4") | |
6228 (set_attr "predicable" "no,no")]) | 6079 (set_attr "predicable" "no,no")]) |
6080 | |
6081 (define_insn "*ashlsi2_cnt8" | |
6082 [(set (match_operand:SI 0 "register_operand" "=r") | |
6083 (ashift:SI (match_operand:SI 1 "nonmemory_operand" "rL") | |
6084 (const_int 8)))] | |
6085 "TARGET_BARREL_SHIFTER && TARGET_V2" | |
6086 "lsl8\\t%0,%1" | |
6087 [(set_attr "type" "shift") | |
6088 (set_attr "iscompact" "false") | |
6089 (set_attr "length" "4") | |
6090 (set_attr "predicable" "no")]) | |
6091 | |
6092 (define_insn "*ashlsi2_cnt16" | |
6093 [(set (match_operand:SI 0 "register_operand" "=r") | |
6094 (ashift:SI (match_operand:SI 1 "nonmemory_operand" "rL") | |
6095 (const_int 16)))] | |
6096 "TARGET_BARREL_SHIFTER && TARGET_V2" | |
6097 "lsl16\\t%0,%1" | |
6098 [(set_attr "type" "shift") | |
6099 (set_attr "iscompact" "false") | |
6100 (set_attr "length" "4") | |
6101 (set_attr "predicable" "no")]) | |
6229 | 6102 |
6230 (define_insn "*lshrsi3_cnt1" | 6103 (define_insn "*lshrsi3_cnt1" |
6231 [(set (match_operand:SI 0 "dest_reg_operand" "=Rcqq,w") | 6104 [(set (match_operand:SI 0 "dest_reg_operand" "=Rcqq,w") |
6232 (lshiftrt:SI (match_operand:SI 1 "register_operand" "Rcqq,c") | 6105 (lshiftrt:SI (match_operand:SI 1 "register_operand" "Rcqq,c") |
6233 (const_int 1)))] | 6106 (const_int 1)))] |
6529 (set_attr "iscompact" "false") | 6402 (set_attr "iscompact" "false") |
6530 (set_attr "type" "multi") | 6403 (set_attr "type" "multi") |
6531 (set_attr "predicable" "yes,no,no,yes,no") | 6404 (set_attr "predicable" "yes,no,no,yes,no") |
6532 (set_attr "cond" "canuse,nocond,nocond,canuse_limm,nocond")]) | 6405 (set_attr "cond" "canuse,nocond,nocond,canuse_limm,nocond")]) |
6533 | 6406 |
6534 (define_insn "stack_tie" | |
6535 [(set (mem:BLK (scratch)) | |
6536 (unspec:BLK [(match_operand:SI 0 "register_operand" "rb") | |
6537 (match_operand:SI 1 "register_operand" "rb")] | |
6538 UNSPEC_ARC_STKTIE))] | |
6539 "" | |
6540 "" | |
6541 [(set_attr "length" "0") | |
6542 (set_attr "iscompact" "false") | |
6543 (set_attr "type" "block")] | |
6544 ) | |
6545 | |
6546 (define_insn "*add_shift" | 6407 (define_insn "*add_shift" |
6547 [(set (match_operand:SI 0 "register_operand" "=q,r,r") | 6408 [(set (match_operand:SI 0 "register_operand" "=q,r,r") |
6548 (plus:SI (ashift:SI (match_operand:SI 1 "register_operand" "q,r,r") | 6409 (plus:SI (ashift:SI (match_operand:SI 1 "register_operand" "q,r,r") |
6549 (match_operand:SI 2 "_1_2_3_operand" "")) | 6410 (match_operand:SI 2 "_1_2_3_operand" "")) |
6550 (match_operand:SI 3 "nonmemory_operand" "0,r,Csz")))] | 6411 (match_operand:SI 3 "nonmemory_operand" "0,r,Csz")))] |
6612 (match_dup 0)))] | 6473 (match_dup 0)))] |
6613 "peep2_reg_dead_p (2, operands[0])" | 6474 "peep2_reg_dead_p (2, operands[0])" |
6614 [(set (reg:CC CC_REG) (compare:CC (match_dup 3) | 6475 [(set (reg:CC CC_REG) (compare:CC (match_dup 3) |
6615 (ashift:SI (match_dup 1) (match_dup 2))))]) | 6476 (ashift:SI (match_dup 1) (match_dup 2))))]) |
6616 | 6477 |
6478 (define_peephole2 ; std | |
6479 [(set (match_operand:SI 2 "memory_operand" "") | |
6480 (match_operand:SI 0 "register_operand" "")) | |
6481 (set (match_operand:SI 3 "memory_operand" "") | |
6482 (match_operand:SI 1 "register_operand" ""))] | |
6483 "TARGET_LL64" | |
6484 [(const_int 0)] | |
6485 { | |
6486 if (!gen_operands_ldd_std (operands, false, false)) | |
6487 FAIL; | |
6488 operands[0] = gen_rtx_REG (DImode, REGNO (operands[0])); | |
6489 operands[2] = adjust_address (operands[2], DImode, 0); | |
6490 emit_insn (gen_rtx_SET (operands[2], operands[0])); | |
6491 DONE; | |
6492 }) | |
6493 | |
6494 (define_peephole2 ; ldd | |
6495 [(set (match_operand:SI 0 "register_operand" "") | |
6496 (match_operand:SI 2 "memory_operand" "")) | |
6497 (set (match_operand:SI 1 "register_operand" "") | |
6498 (match_operand:SI 3 "memory_operand" ""))] | |
6499 "TARGET_LL64" | |
6500 [(const_int 0)] | |
6501 { | |
6502 if (!gen_operands_ldd_std (operands, true, false)) | |
6503 FAIL; | |
6504 operands[0] = gen_rtx_REG (DImode, REGNO (operands[0])); | |
6505 operands[2] = adjust_address (operands[2], DImode, 0); | |
6506 emit_insn (gen_rtx_SET (operands[0], operands[2])); | |
6507 DONE; | |
6508 }) | |
6509 | |
6510 ;; We require consecutive registers for LDD instruction. Check if we | |
6511 ;; can reorder them and use an LDD. | |
6512 | |
6513 (define_peephole2 ; swap the destination registers of two loads | |
6514 ; before a commutative operation. | |
6515 [(set (match_operand:SI 0 "register_operand" "") | |
6516 (match_operand:SI 2 "memory_operand" "")) | |
6517 (set (match_operand:SI 1 "register_operand" "") | |
6518 (match_operand:SI 3 "memory_operand" "")) | |
6519 (set (match_operand:SI 4 "register_operand" "") | |
6520 (match_operator:SI 5 "commutative_operator" | |
6521 [(match_operand 6 "register_operand" "") | |
6522 (match_operand 7 "register_operand" "") ]))] | |
6523 "TARGET_LL64 | |
6524 && (((rtx_equal_p (operands[0], operands[6])) | |
6525 && (rtx_equal_p (operands[1], operands[7]))) | |
6526 || ((rtx_equal_p (operands[0], operands[7])) | |
6527 && (rtx_equal_p (operands[1], operands[6])))) | |
6528 && (peep2_reg_dead_p (3, operands[0]) | |
6529 || rtx_equal_p (operands[0], operands[4])) | |
6530 && (peep2_reg_dead_p (3, operands[1]) | |
6531 || rtx_equal_p (operands[1], operands[4]))" | |
6532 [(set (match_dup 0) (match_dup 2)) | |
6533 (set (match_dup 4) (match_op_dup 5 [(match_dup 6) (match_dup 7)]))] | |
6534 { | |
6535 if (!gen_operands_ldd_std (operands, true, true)) | |
6536 { | |
6537 FAIL; | |
6538 } | |
6539 else | |
6540 { | |
6541 operands[0] = gen_rtx_REG (DImode, REGNO (operands[0])); | |
6542 operands[2] = adjust_address (operands[2], DImode, 0); | |
6543 } | |
6544 } | |
6545 ) | |
6546 | |
6547 (define_insn "*push_multi_fp" | |
6548 [(match_parallel 0 "push_multi_operand" | |
6549 [(set (reg:SI SP_REG) | |
6550 (plus:SI (reg:SI SP_REG) | |
6551 (match_operand 1 "immediate_operand" ""))) | |
6552 (set (mem:SI (plus:SI (reg:SI SP_REG) | |
6553 (match_operand 2 "immediate_operand" | |
6554 ""))) | |
6555 (reg:SI 13))])] | |
6556 "TARGET_CODE_DENSITY" | |
6557 { | |
6558 int len = XVECLEN (operands[0], 0); | |
6559 rtx tmp = XVECEXP (operands[0], 0, len - 1); | |
6560 if (MEM_P (XEXP (tmp, 0))) | |
6561 { | |
6562 operands[3] = XEXP (tmp, 1); | |
6563 return "enter_s\\t{r13-%3} ; sp=sp+(%1)"; | |
6564 } | |
6565 else | |
6566 { | |
6567 tmp = XVECEXP (operands[0], 0, len - 3); | |
6568 operands[3] = XEXP (tmp, 1); | |
6569 return "enter_s\\t{r13-%3, fp} ; sp=sp+(%1)"; | |
6570 } | |
6571 } | |
6572 [(set_attr "type" "call_no_delay_slot") | |
6573 (set_attr "length" "2")]) | |
6574 | |
6575 (define_insn "*push_multi_fp_blink" | |
6576 [(match_parallel 0 "push_multi_operand" | |
6577 [(set (reg:SI SP_REG) | |
6578 (plus:SI (reg:SI SP_REG) | |
6579 (match_operand 1 "immediate_operand" ""))) | |
6580 (set (mem:SI (plus:SI (reg:SI SP_REG) | |
6581 (match_operand 2 "immediate_operand" | |
6582 ""))) | |
6583 (reg:SI RETURN_ADDR_REGNUM))])] | |
6584 "TARGET_CODE_DENSITY" | |
6585 { | |
6586 int len = XVECLEN (operands[0], 0); | |
6587 rtx tmp = XVECEXP (operands[0], 0, len - 1); | |
6588 if (MEM_P (XEXP (tmp, 0))) | |
6589 { | |
6590 operands[3] = XEXP (tmp, 1); | |
6591 return "enter_s\\t{r13-%3, blink} ; sp=sp+(%1)"; | |
6592 } | |
6593 else | |
6594 { | |
6595 tmp = XVECEXP (operands[0], 0, len - 3); | |
6596 operands[3] = XEXP (tmp, 1); | |
6597 return "enter_s\\t{r13-%3, fp, blink} ; sp=sp+(%1)"; | |
6598 } | |
6599 } | |
6600 [(set_attr "type" "call_no_delay_slot") | |
6601 (set_attr "length" "2")]) | |
6602 | |
6603 (define_insn "*pop_multi_fp" | |
6604 [(match_parallel 0 "pop_multi_operand" | |
6605 [(set (reg:SI SP_REG) | |
6606 (plus:SI (reg:SI SP_REG) | |
6607 (match_operand 1 "immediate_operand" ""))) | |
6608 (set (reg:SI 13) | |
6609 (mem:SI | |
6610 (plus:SI | |
6611 (reg:SI SP_REG) | |
6612 (match_operand 2 "immediate_operand" ""))))])] | |
6613 "TARGET_CODE_DENSITY" | |
6614 { | |
6615 int len = XVECLEN (operands[0], 0); | |
6616 rtx tmp = XVECEXP (operands[0], 0, len - 1); | |
6617 if (XEXP (tmp, 0) != hard_frame_pointer_rtx) | |
6618 { | |
6619 operands[3] = XEXP (tmp, 0); | |
6620 gcc_assert (INTVAL (operands[1]) == INTVAL (operands[2])); | |
6621 return "leave_s\\t{r13-%3} ; sp=sp+%1"; | |
6622 } | |
6623 else | |
6624 { | |
6625 tmp = XVECEXP (operands[0], 0, len - 2); | |
6626 operands[3] = XEXP (tmp, 0); | |
6627 return "leave_s\\t{r13-%3, fp} ; sp=sp+%1"; | |
6628 } | |
6629 } | |
6630 [(set_attr "type" "call_no_delay_slot") | |
6631 (set_attr "length" "2")]) | |
6632 | |
6633 (define_insn "*pop_multi_fp_blink" | |
6634 [(match_parallel 0 "pop_multi_operand" | |
6635 [(set (reg:SI SP_REG) | |
6636 (plus:SI (reg:SI SP_REG) | |
6637 (match_operand 1 "immediate_operand" ""))) | |
6638 (set (reg:SI RETURN_ADDR_REGNUM) | |
6639 (mem:SI | |
6640 (plus:SI | |
6641 (reg:SI SP_REG) | |
6642 (match_operand 2 "immediate_operand" ""))))])] | |
6643 "TARGET_CODE_DENSITY" | |
6644 { | |
6645 int len = XVECLEN (operands[0], 0); | |
6646 rtx tmp = XVECEXP (operands[0], 0, len - 1); | |
6647 if (XEXP (tmp, 0) != hard_frame_pointer_rtx) | |
6648 { | |
6649 operands[3] = XEXP (tmp, 0); | |
6650 gcc_assert (INTVAL (operands[1]) == INTVAL (operands[2])); | |
6651 return "leave_s\\t{r13-%3, blink} ; sp=sp+%1"; | |
6652 } | |
6653 else | |
6654 { | |
6655 tmp = XVECEXP (operands[0], 0, len - 2); | |
6656 operands[3] = XEXP (tmp, 0); | |
6657 return "leave_s\\t{r13-%3, fp, blink} ; sp=sp+%1"; | |
6658 } | |
6659 } | |
6660 [(set_attr "type" "call_no_delay_slot") | |
6661 (set_attr "length" "2")]) | |
6662 | |
6663 (define_insn "*pop_multi_fp_ret" | |
6664 [(match_parallel 0 "pop_multi_operand" | |
6665 [(return) | |
6666 (set (reg:SI SP_REG) | |
6667 (plus:SI (reg:SI SP_REG) | |
6668 (match_operand 1 "immediate_operand" ""))) | |
6669 (set (reg:SI 13) | |
6670 (mem:SI | |
6671 (plus:SI | |
6672 (reg:SI SP_REG) | |
6673 (match_operand 2 "immediate_operand" ""))))])] | |
6674 "TARGET_CODE_DENSITY" | |
6675 { | |
6676 int len = XVECLEN (operands[0], 0); | |
6677 rtx tmp = XVECEXP (operands[0], 0, len - 1); | |
6678 if (XEXP (tmp, 0) != hard_frame_pointer_rtx) | |
6679 { | |
6680 operands[3] = XEXP (tmp, 0); | |
6681 gcc_assert (INTVAL (operands[1]) == INTVAL (operands[2])); | |
6682 return "leave_s\\t{r13-%3, pcl} ; sp=sp+%1"; | |
6683 } | |
6684 else | |
6685 { | |
6686 tmp = XVECEXP (operands[0], 0, len - 2); | |
6687 operands[3] = XEXP (tmp, 0); | |
6688 return "leave_s\\t{r13-%3, fp, pcl} ; sp=sp+%1"; | |
6689 } | |
6690 } | |
6691 [(set_attr "type" "call_no_delay_slot") | |
6692 (set_attr "length" "2")]) | |
6693 | |
6694 (define_insn "*pop_multi_fp_blink_ret" | |
6695 [(match_parallel 0 "pop_multi_operand" | |
6696 [(return) | |
6697 (set (reg:SI SP_REG) | |
6698 (plus:SI (reg:SI SP_REG) | |
6699 (match_operand 1 "immediate_operand" ""))) | |
6700 (set (reg:SI RETURN_ADDR_REGNUM) | |
6701 (mem:SI | |
6702 (plus:SI | |
6703 (reg:SI SP_REG) | |
6704 (match_operand 2 "immediate_operand" ""))))])] | |
6705 "TARGET_CODE_DENSITY" | |
6706 { | |
6707 int len = XVECLEN (operands[0], 0); | |
6708 rtx tmp = XVECEXP (operands[0], 0, len - 1); | |
6709 if (XEXP (tmp, 0) != hard_frame_pointer_rtx) | |
6710 { | |
6711 operands[3] = XEXP (tmp, 0); | |
6712 gcc_assert (INTVAL (operands[1]) == INTVAL (operands[2])); | |
6713 return "leave_s\\t{r13-%3, blink, pcl} ; sp=sp+%1"; | |
6714 } | |
6715 else | |
6716 { | |
6717 tmp = XVECEXP (operands[0], 0, len - 2); | |
6718 operands[3] = XEXP (tmp, 0); | |
6719 return "leave_s\\t{r13-%3, fp, blink, pcl} ; sp=sp+%1"; | |
6720 } | |
6721 } | |
6722 [(set_attr "type" "call_no_delay_slot") | |
6723 (set_attr "length" "2")]) | |
6724 | |
6725 ;; Patterns for exception handling | |
6726 (define_insn_and_split "eh_return" | |
6727 [(unspec_volatile [(match_operand:SI 0 "register_operand" "r")] | |
6728 VUNSPEC_ARC_EH_RETURN)] | |
6729 "" | |
6730 "#" | |
6731 "reload_completed" | |
6732 [(const_int 0)] | |
6733 " | |
6734 { | |
6735 arc_eh_return_address_location (operands[0]); | |
6736 DONE; | |
6737 }" | |
6738 ) | |
6617 ;; include the arc-FPX instructions | 6739 ;; include the arc-FPX instructions |
6618 (include "fpx.md") | 6740 (include "fpx.md") |
6619 | 6741 |
6620 ;; include the arc-FPU instructions | 6742 ;; include the arc-FPU instructions |
6621 (include "fpu.md") | 6743 (include "fpu.md") |