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]%&\", &reg); 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")