comparison gcc/config/aarch64/aarch64.md @ 131:84e7813d76e9

gcc-8.2
author mir3636
date Thu, 25 Oct 2018 07:37:49 +0900
parents 04ced10e8804
children 1830386684a0
comparison
equal deleted inserted replaced
111:04ced10e8804 131:84e7813d76e9
1 ;; Machine description for AArch64 architecture. 1 ;; Machine description for AArch64 architecture.
2 ;; Copyright (C) 2009-2017 Free Software Foundation, Inc. 2 ;; Copyright (C) 2009-2018 Free Software Foundation, Inc.
3 ;; Contributed by ARM Ltd. 3 ;; Contributed by ARM Ltd.
4 ;; 4 ;;
5 ;; This file is part of GCC. 5 ;; This file is part of GCC.
6 ;; 6 ;;
7 ;; GCC is free software; you can redistribute it and/or modify it 7 ;; GCC is free software; you can redistribute it and/or modify it
55 (R29_REGNUM 29) 55 (R29_REGNUM 29)
56 (R30_REGNUM 30) 56 (R30_REGNUM 30)
57 (LR_REGNUM 30) 57 (LR_REGNUM 30)
58 (SP_REGNUM 31) 58 (SP_REGNUM 31)
59 (V0_REGNUM 32) 59 (V0_REGNUM 32)
60 (V1_REGNUM 33)
61 (V2_REGNUM 34)
62 (V3_REGNUM 35)
63 (V4_REGNUM 36)
64 (V5_REGNUM 37)
65 (V6_REGNUM 38)
66 (V7_REGNUM 39)
67 (V8_REGNUM 40)
68 (V9_REGNUM 41)
69 (V10_REGNUM 42)
70 (V11_REGNUM 43)
71 (V12_REGNUM 44)
72 (V13_REGNUM 45)
73 (V14_REGNUM 46)
60 (V15_REGNUM 47) 74 (V15_REGNUM 47)
75 (V16_REGNUM 48)
76 (V17_REGNUM 49)
77 (V18_REGNUM 50)
78 (V19_REGNUM 51)
79 (V20_REGNUM 52)
80 (V21_REGNUM 53)
81 (V22_REGNUM 54)
82 (V23_REGNUM 55)
83 (V24_REGNUM 56)
84 (V25_REGNUM 57)
85 (V26_REGNUM 58)
86 (V27_REGNUM 59)
87 (V28_REGNUM 60)
88 (V29_REGNUM 61)
89 (V30_REGNUM 62)
61 (V31_REGNUM 63) 90 (V31_REGNUM 63)
62 (LAST_SAVED_REGNUM 63) 91 (LAST_SAVED_REGNUM 63)
63 (SFP_REGNUM 64) 92 (SFP_REGNUM 64)
64 (AP_REGNUM 65) 93 (AP_REGNUM 65)
65 (CC_REGNUM 66) 94 (CC_REGNUM 66)
95 ;; Defined only to make the DWARF description simpler.
96 (VG_REGNUM 67)
97 (P0_REGNUM 68)
98 (P1_REGNUM 69)
99 (P2_REGNUM 70)
100 (P3_REGNUM 71)
101 (P4_REGNUM 72)
102 (P5_REGNUM 73)
103 (P6_REGNUM 74)
104 (P7_REGNUM 75)
105 (P8_REGNUM 76)
106 (P9_REGNUM 77)
107 (P10_REGNUM 78)
108 (P11_REGNUM 79)
109 (P12_REGNUM 80)
110 (P13_REGNUM 81)
111 (P14_REGNUM 82)
112 (P15_REGNUM 83)
113 ;; A couple of call-clobbered registers that we need to reserve when
114 ;; tracking speculation this is not ABI, so is subject to change.
115 (SPECULATION_TRACKER_REGNUM 15)
116 (SPECULATION_SCRATCH_REGNUM 14)
66 ] 117 ]
67 ) 118 )
68 119
69 (define_c_enum "unspec" [ 120 (define_c_enum "unspec" [
70 UNSPEC_AUTI1716 121 UNSPEC_AUTI1716
112 UNSPEC_MB 163 UNSPEC_MB
113 UNSPEC_NOP 164 UNSPEC_NOP
114 UNSPEC_PACI1716 165 UNSPEC_PACI1716
115 UNSPEC_PACISP 166 UNSPEC_PACISP
116 UNSPEC_PRLG_STK 167 UNSPEC_PRLG_STK
168 UNSPEC_REV
117 UNSPEC_RBIT 169 UNSPEC_RBIT
170 UNSPEC_SABAL
171 UNSPEC_SABDL2
172 UNSPEC_SADALP
118 UNSPEC_SCVTF 173 UNSPEC_SCVTF
119 UNSPEC_SISD_NEG 174 UNSPEC_SISD_NEG
120 UNSPEC_SISD_SSHL 175 UNSPEC_SISD_SSHL
121 UNSPEC_SISD_USHL 176 UNSPEC_SISD_USHL
122 UNSPEC_SSHL_2S 177 UNSPEC_SSHL_2S
131 UNSPEC_TLSDESC 186 UNSPEC_TLSDESC
132 UNSPEC_TLSLE12 187 UNSPEC_TLSLE12
133 UNSPEC_TLSLE24 188 UNSPEC_TLSLE24
134 UNSPEC_TLSLE32 189 UNSPEC_TLSLE32
135 UNSPEC_TLSLE48 190 UNSPEC_TLSLE48
191 UNSPEC_UABAL
192 UNSPEC_UABDL2
193 UNSPEC_UADALP
136 UNSPEC_UCVTF 194 UNSPEC_UCVTF
137 UNSPEC_USHL_2S 195 UNSPEC_USHL_2S
138 UNSPEC_VSTRUCTDUMMY 196 UNSPEC_VSTRUCTDUMMY
139 UNSPEC_SP_SET 197 UNSPEC_SP_SET
140 UNSPEC_SP_TEST 198 UNSPEC_SP_TEST
141 UNSPEC_RSQRT 199 UNSPEC_RSQRT
142 UNSPEC_RSQRTE 200 UNSPEC_RSQRTE
143 UNSPEC_RSQRTS 201 UNSPEC_RSQRTS
144 UNSPEC_NZCV 202 UNSPEC_NZCV
145 UNSPEC_XPACLRI 203 UNSPEC_XPACLRI
204 UNSPEC_LD1_SVE
205 UNSPEC_ST1_SVE
206 UNSPEC_LD1RQ
207 UNSPEC_LD1_GATHER
208 UNSPEC_ST1_SCATTER
209 UNSPEC_MERGE_PTRUE
210 UNSPEC_PTEST_PTRUE
211 UNSPEC_UNPACKSHI
212 UNSPEC_UNPACKUHI
213 UNSPEC_UNPACKSLO
214 UNSPEC_UNPACKULO
215 UNSPEC_PACK
216 UNSPEC_FLOAT_CONVERT
217 UNSPEC_WHILE_LO
218 UNSPEC_LDN
219 UNSPEC_STN
220 UNSPEC_INSR
221 UNSPEC_CLASTB
222 UNSPEC_FADDA
223 UNSPEC_REV_SUBREG
224 UNSPEC_SPECULATION_TRACKER
146 ]) 225 ])
147 226
148 (define_c_enum "unspecv" [ 227 (define_c_enum "unspecv" [
149 UNSPECV_EH_RETURN ; Represent EH_RETURN 228 UNSPECV_EH_RETURN ; Represent EH_RETURN
150 UNSPECV_GET_FPCR ; Represent fetch of FPCR content. 229 UNSPECV_GET_FPCR ; Represent fetch of FPCR content.
151 UNSPECV_SET_FPCR ; Represent assign of FPCR content. 230 UNSPECV_SET_FPCR ; Represent assign of FPCR content.
152 UNSPECV_GET_FPSR ; Represent fetch of FPSR content. 231 UNSPECV_GET_FPSR ; Represent fetch of FPSR content.
153 UNSPECV_SET_FPSR ; Represent assign of FPSR content. 232 UNSPECV_SET_FPSR ; Represent assign of FPSR content.
154 UNSPECV_BLOCKAGE ; Represent a blockage 233 UNSPECV_BLOCKAGE ; Represent a blockage
155 UNSPECV_PROBE_STACK_RANGE ; Represent stack range probing. 234 UNSPECV_PROBE_STACK_RANGE ; Represent stack range probing.
235 UNSPECV_SPECULATION_BARRIER ; Represent speculation barrier.
156 ] 236 ]
157 ) 237 )
158 238
159 ;; If further include files are added the defintion of MD_INCLUDES 239 ;; If further include files are added the defintion of MD_INCLUDES
160 ;; must be updated. 240 ;; must be updated.
177 ;; disabled when compiling with -mgeneral-regs-only or with the +nofp/+nosimd 257 ;; disabled when compiling with -mgeneral-regs-only or with the +nofp/+nosimd
178 ;; architecture extensions. If all the alternatives in a pattern use the 258 ;; architecture extensions. If all the alternatives in a pattern use the
179 ;; FP or SIMD registers then the pattern predicate should include TARGET_FLOAT 259 ;; FP or SIMD registers then the pattern predicate should include TARGET_FLOAT
180 ;; or TARGET_SIMD. 260 ;; or TARGET_SIMD.
181 261
262 ;; Attributes of the architecture required to support the instruction (or
263 ;; alternative). This attribute is used to compute attribute "enabled", use type
264 ;; "any" to enable an alternative in all cases.
265
266 (define_enum "arches" [ any rcpc8_4 fp simd sve fp16])
267
268 (define_enum_attr "arch" "arches" (const_string "any"))
269
270 ;; [For compatibility with Arm in pipeline models]
182 ;; Attribute that specifies whether or not the instruction touches fp 271 ;; Attribute that specifies whether or not the instruction touches fp
183 ;; registers. When this is set to yes for an alternative, that alternative 272 ;; registers.
184 ;; will be disabled when !TARGET_FLOAT. 273 ;; Note that this attribute is not used anywhere in either the arm or aarch64
185 (define_attr "fp" "no,yes" (const_string "no")) 274 ;; backends except in the scheduling description for xgene1. In that
186 275 ;; scheduling description this attribute is used to subclass the load_4 and
187 ;; Attribute that specifies whether or not the instruction touches half 276 ;; load_8 types.
188 ;; precision fp registers. When this is set to yes for an alternative, 277 (define_attr "fp" "no,yes"
189 ;; that alternative will be disabled when !TARGET_FP_F16INST. 278 (if_then_else
190 (define_attr "fp16" "no,yes" (const_string "no")) 279 (eq_attr "arch" "fp")
191 280 (const_string "yes")
192 ;; Attribute that specifies whether or not the instruction touches simd 281 (const_string "no")))
193 ;; registers. When this is set to yes for an alternative, that alternative 282
194 ;; will be disabled when !TARGET_SIMD. 283 (define_attr "arch_enabled" "no,yes"
195 (define_attr "simd" "no,yes" (const_string "no")) 284 (if_then_else
196 285 (ior
197 (define_attr "length" "" 286 (eq_attr "arch" "any")
198 (const_int 4)) 287
288 (and (eq_attr "arch" "rcpc8_4")
289 (match_test "AARCH64_ISA_RCPC8_4"))
290
291 (and (eq_attr "arch" "fp")
292 (match_test "TARGET_FLOAT"))
293
294 (and (eq_attr "arch" "simd")
295 (match_test "TARGET_SIMD"))
296
297 (and (eq_attr "arch" "fp16")
298 (match_test "TARGET_FP_F16INST"))
299
300 (and (eq_attr "arch" "sve")
301 (match_test "TARGET_SVE")))
302 (const_string "yes")
303 (const_string "no")))
199 304
200 ;; Attribute that controls whether an alternative is enabled or not. 305 ;; Attribute that controls whether an alternative is enabled or not.
201 ;; Currently it is only used to disable alternatives which touch fp or simd 306 ;; Currently it is only used to disable alternatives which touch fp or simd
202 ;; registers when -mgeneral-regs-only is specified. 307 ;; registers when -mgeneral-regs-only is specified or to require a special
203 (define_attr "enabled" "no,yes" 308 ;; architecture support.
204 (cond [(ior 309 (define_attr "enabled" "no,yes" (attr "arch_enabled"))
205 (ior
206 (and (eq_attr "fp" "yes")
207 (eq (symbol_ref "TARGET_FLOAT") (const_int 0)))
208 (and (eq_attr "simd" "yes")
209 (eq (symbol_ref "TARGET_SIMD") (const_int 0))))
210 (and (eq_attr "fp16" "yes")
211 (eq (symbol_ref "TARGET_FP_F16INST") (const_int 0))))
212 (const_string "no")
213 ] (const_string "yes")))
214 310
215 ;; Attribute that specifies whether we are dealing with a branch to a 311 ;; Attribute that specifies whether we are dealing with a branch to a
216 ;; label that is far away, i.e. further away than the maximum/minimum 312 ;; label that is far away, i.e. further away than the maximum/minimum
217 ;; representable in a signed 21-bits number. 313 ;; representable in a signed 21-bits number.
218 ;; 0 :=: no 314 ;; 0 :=: no
219 ;; 1 :=: yes 315 ;; 1 :=: yes
220 (define_attr "far_branch" "" (const_int 0)) 316 (define_attr "far_branch" "" (const_int 0))
221 317
318 ;; Attribute that specifies whether the alternative uses MOVPRFX.
319 (define_attr "movprfx" "no,yes" (const_string "no"))
320
321 (define_attr "length" ""
322 (cond [(eq_attr "movprfx" "yes")
323 (const_int 8)
324 ] (const_int 4)))
325
222 ;; Strictly for compatibility with AArch32 in pipeline models, since AArch64 has 326 ;; Strictly for compatibility with AArch32 in pipeline models, since AArch64 has
223 ;; no predicated insns. 327 ;; no predicated insns.
224 (define_attr "predicated" "yes,no" (const_string "no")) 328 (define_attr "predicated" "yes,no" (const_string "no"))
329
330 ;; Set to true on an insn that requires the speculation tracking state to be
331 ;; in the tracking register before the insn issues. Otherwise the compiler
332 ;; may chose to hold the tracking state encoded in SP.
333 (define_attr "speculation_barrier" "true,false" (const_string "false"))
225 334
226 ;; ------------------------------------------------------------------- 335 ;; -------------------------------------------------------------------
227 ;; Pipeline descriptions and scheduling 336 ;; Pipeline descriptions and scheduling
228 ;; ------------------------------------------------------------------- 337 ;; -------------------------------------------------------------------
229 338
624 (define_insn "*cb<optab><mode>1" 733 (define_insn "*cb<optab><mode>1"
625 [(set (pc) (if_then_else (EQL (match_operand:GPI 0 "register_operand" "r") 734 [(set (pc) (if_then_else (EQL (match_operand:GPI 0 "register_operand" "r")
626 (const_int 0)) 735 (const_int 0))
627 (label_ref (match_operand 1 "" "")) 736 (label_ref (match_operand 1 "" ""))
628 (pc)))] 737 (pc)))]
629 "" 738 "!aarch64_track_speculation"
630 { 739 {
631 if (get_attr_length (insn) == 8) 740 if (get_attr_length (insn) == 8)
632 return aarch64_gen_far_branch (operands, 1, "Lcb", "<inv_cb>\\t%<w>0, "); 741 return aarch64_gen_far_branch (operands, 1, "Lcb", "<inv_cb>\\t%<w>0, ");
633 else 742 else
634 return "<cbz>\\t%<w>0, %l1"; 743 return "<cbz>\\t%<w>0, %l1";
654 "aarch64_simd_shift_imm_<mode>" "n")) 763 "aarch64_simd_shift_imm_<mode>" "n"))
655 (const_int 0)) 764 (const_int 0))
656 (label_ref (match_operand 2 "" "")) 765 (label_ref (match_operand 2 "" ""))
657 (pc))) 766 (pc)))
658 (clobber (reg:CC CC_REGNUM))] 767 (clobber (reg:CC CC_REGNUM))]
659 "" 768 "!aarch64_track_speculation"
660 { 769 {
661 if (get_attr_length (insn) == 8) 770 if (get_attr_length (insn) == 8)
662 { 771 {
663 if (get_attr_far_branch (insn) == 1) 772 if (get_attr_far_branch (insn) == 1)
664 return aarch64_gen_far_branch (operands, 2, "Ltb", 773 return aarch64_gen_far_branch (operands, 2, "Ltb",
690 [(set (pc) (if_then_else (LTGE (match_operand:ALLI 0 "register_operand" "r") 799 [(set (pc) (if_then_else (LTGE (match_operand:ALLI 0 "register_operand" "r")
691 (const_int 0)) 800 (const_int 0))
692 (label_ref (match_operand 1 "" "")) 801 (label_ref (match_operand 1 "" ""))
693 (pc))) 802 (pc)))
694 (clobber (reg:CC CC_REGNUM))] 803 (clobber (reg:CC CC_REGNUM))]
695 "" 804 "!aarch64_track_speculation"
696 { 805 {
697 if (get_attr_length (insn) == 8) 806 if (get_attr_length (insn) == 8)
698 { 807 {
699 if (get_attr_far_branch (insn) == 1) 808 if (get_attr_far_branch (insn) == 1)
700 return aarch64_gen_far_branch (operands, 1, "Ltb", 809 return aarch64_gen_far_branch (operands, 1, "Ltb",
747 (match_operand 1 "" "")) 856 (match_operand 1 "" ""))
748 (clobber (reg:DI LR_REGNUM))] 857 (clobber (reg:DI LR_REGNUM))]
749 "" 858 ""
750 "@ 859 "@
751 blr\\t%0 860 blr\\t%0
752 bl\\t%a0" 861 bl\\t%c0"
753 [(set_attr "type" "call, call")] 862 [(set_attr "type" "call, call")]
754 ) 863 )
755 864
756 (define_expand "call_value" 865 (define_expand "call_value"
757 [(parallel [(set (match_operand 0 "" "") 866 [(parallel [(set (match_operand 0 "" "")
773 (match_operand 2 "" ""))) 882 (match_operand 2 "" "")))
774 (clobber (reg:DI LR_REGNUM))] 883 (clobber (reg:DI LR_REGNUM))]
775 "" 884 ""
776 "@ 885 "@
777 blr\\t%1 886 blr\\t%1
778 bl\\t%a1" 887 bl\\t%c1"
779 [(set_attr "type" "call, call")] 888 [(set_attr "type" "call, call")]
780 ) 889 )
781 890
782 (define_expand "sibcall" 891 (define_expand "sibcall"
783 [(parallel [(call (match_operand 0 "memory_operand" "") 892 [(parallel [(call (match_operand 0 "memory_operand" "")
809 (match_operand 1 "" "")) 918 (match_operand 1 "" ""))
810 (return)] 919 (return)]
811 "SIBLING_CALL_P (insn)" 920 "SIBLING_CALL_P (insn)"
812 "@ 921 "@
813 br\\t%0 922 br\\t%0
814 b\\t%a0" 923 b\\t%c0"
815 [(set_attr "type" "branch, branch")] 924 [(set_attr "type" "branch, branch")]
816 ) 925 )
817 926
818 (define_insn "*sibcall_value_insn" 927 (define_insn "*sibcall_value_insn"
819 [(set (match_operand 0 "" "") 928 [(set (match_operand 0 "" "")
822 (match_operand 2 "" ""))) 931 (match_operand 2 "" "")))
823 (return)] 932 (return)]
824 "SIBLING_CALL_P (insn)" 933 "SIBLING_CALL_P (insn)"
825 "@ 934 "@
826 br\\t%1 935 br\\t%1
827 b\\t%a1" 936 b\\t%c1"
828 [(set_attr "type" "branch, branch")] 937 [(set_attr "type" "branch, branch")]
829 ) 938 )
830 939
831 ;; Call subroutine returning any type. 940 ;; Call subroutine returning any type.
832 941
864 (match_operand:SHORT 1 "general_operand" ""))] 973 (match_operand:SHORT 1 "general_operand" ""))]
865 "" 974 ""
866 " 975 "
867 if (GET_CODE (operands[0]) == MEM && operands[1] != const0_rtx) 976 if (GET_CODE (operands[0]) == MEM && operands[1] != const0_rtx)
868 operands[1] = force_reg (<MODE>mode, operands[1]); 977 operands[1] = force_reg (<MODE>mode, operands[1]);
978
979 if (GET_CODE (operands[1]) == CONST_POLY_INT)
980 {
981 aarch64_expand_mov_immediate (operands[0], operands[1]);
982 DONE;
983 }
869 " 984 "
870 ) 985 )
871 986
872 (define_insn "*mov<mode>_aarch64" 987 (define_insn "*mov<mode>_aarch64"
873 [(set (match_operand:SHORT 0 "nonimmediate_operand" "=r,r, *w,r,*w, m, m, r,*w,*w") 988 [(set (match_operand:SHORT 0 "nonimmediate_operand" "=r,r, w,r ,r,w, m,m,r,w,w")
874 (match_operand:SHORT 1 "general_operand" " r,M,D<hq>,m, m,rZ,*w,*w, r,*w"))] 989 (match_operand:SHORT 1 "aarch64_mov_operand" " r,M,D<hq>,Usv,m,m,rZ,w,w,r,w"))]
875 "(register_operand (operands[0], <MODE>mode) 990 "(register_operand (operands[0], <MODE>mode)
876 || aarch64_reg_or_zero (operands[1], <MODE>mode))" 991 || aarch64_reg_or_zero (operands[1], <MODE>mode))"
877 { 992 {
878 switch (which_alternative) 993 switch (which_alternative)
879 { 994 {
883 return "mov\t%w0, %1"; 998 return "mov\t%w0, %1";
884 case 2: 999 case 2:
885 return aarch64_output_scalar_simd_mov_immediate (operands[1], 1000 return aarch64_output_scalar_simd_mov_immediate (operands[1],
886 <MODE>mode); 1001 <MODE>mode);
887 case 3: 1002 case 3:
1003 return aarch64_output_sve_cnt_immediate (\"cnt\", \"%x0\", operands[1]);
1004 case 4:
888 return "ldr<size>\t%w0, %1"; 1005 return "ldr<size>\t%w0, %1";
889 case 4: 1006 case 5:
890 return "ldr\t%<size>0, %1"; 1007 return "ldr\t%<size>0, %1";
891 case 5: 1008 case 6:
892 return "str<size>\t%w1, %0"; 1009 return "str<size>\t%w1, %0";
893 case 6: 1010 case 7:
894 return "str\t%<size>1, %0"; 1011 return "str\t%<size>1, %0";
895 case 7: 1012 case 8:
896 return "umov\t%w0, %1.<v>[0]"; 1013 return "umov\t%w0, %1.<v>[0]";
897 case 8: 1014 case 9:
898 return "dup\t%0.<Vallxd>, %w1"; 1015 return "dup\t%0.<Vallxd>, %w1";
899 case 9: 1016 case 10:
900 return "dup\t%<Vetype>0, %1.<v>[0]"; 1017 return "dup\t%<Vetype>0, %1.<v>[0]";
901 default: 1018 default:
902 gcc_unreachable (); 1019 gcc_unreachable ();
903 } 1020 }
904 } 1021 }
905 [(set_attr "type" "mov_reg,mov_imm,neon_move,load_4,load_4,store_4,store_4,\ 1022 ;; The "mov_imm" type for CNT is just a placeholder.
906 neon_to_gp<q>,neon_from_gp<q>,neon_dup") 1023 [(set_attr "type" "mov_reg,mov_imm,neon_move,mov_imm,load_4,load_4,store_4,
907 (set_attr "simd" "*,*,yes,*,*,*,*,yes,yes,yes")] 1024 store_4,neon_to_gp<q>,neon_from_gp<q>,neon_dup")
1025 (set_attr "arch" "*,*,simd,sve,*,*,*,*,simd,simd,simd")]
908 ) 1026 )
909 1027
910 (define_expand "mov<mode>" 1028 (define_expand "mov<mode>"
911 [(set (match_operand:GPI 0 "nonimmediate_operand" "") 1029 [(set (match_operand:GPI 0 "nonimmediate_operand" "")
912 (match_operand:GPI 1 "general_operand" ""))] 1030 (match_operand:GPI 1 "general_operand" ""))]
930 } 1048 }
931 " 1049 "
932 ) 1050 )
933 1051
934 (define_insn_and_split "*movsi_aarch64" 1052 (define_insn_and_split "*movsi_aarch64"
935 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,k,r,r,r,r,w, m, m, r, r, w,r,w, w") 1053 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,k,r,r,r,r, r,w, m, m, r, r, w,r,w, w")
936 (match_operand:SI 1 "aarch64_mov_operand" " r,r,k,M,n,m,m,rZ,*w,Usa,Ush,rZ,w,w,Ds"))] 1054 (match_operand:SI 1 "aarch64_mov_operand" " r,r,k,M,n,Usv,m,m,rZ,w,Usa,Ush,rZ,w,w,Ds"))]
937 "(register_operand (operands[0], SImode) 1055 "(register_operand (operands[0], SImode)
938 || aarch64_reg_or_zero (operands[1], SImode))" 1056 || aarch64_reg_or_zero (operands[1], SImode))"
939 "@ 1057 "@
940 mov\\t%w0, %w1 1058 mov\\t%w0, %w1
941 mov\\t%w0, %w1 1059 mov\\t%w0, %w1
942 mov\\t%w0, %w1 1060 mov\\t%w0, %w1
943 mov\\t%w0, %1 1061 mov\\t%w0, %1
944 # 1062 #
1063 * return aarch64_output_sve_cnt_immediate (\"cnt\", \"%x0\", operands[1]);
945 ldr\\t%w0, %1 1064 ldr\\t%w0, %1
946 ldr\\t%s0, %1 1065 ldr\\t%s0, %1
947 str\\t%w1, %0 1066 str\\t%w1, %0
948 str\\t%s1, %0 1067 str\\t%s1, %0
949 adr\\t%x0, %a1 1068 adr\\t%x0, %c1
950 adrp\\t%x0, %A1 1069 adrp\\t%x0, %A1
951 fmov\\t%s0, %w1 1070 fmov\\t%s0, %w1
952 fmov\\t%w0, %s1 1071 fmov\\t%w0, %s1
953 fmov\\t%s0, %s1 1072 fmov\\t%s0, %s1
954 * return aarch64_output_scalar_simd_mov_immediate (operands[1], SImode);" 1073 * return aarch64_output_scalar_simd_mov_immediate (operands[1], SImode);"
957 [(const_int 0)] 1076 [(const_int 0)]
958 "{ 1077 "{
959 aarch64_expand_mov_immediate (operands[0], operands[1]); 1078 aarch64_expand_mov_immediate (operands[0], operands[1]);
960 DONE; 1079 DONE;
961 }" 1080 }"
962 [(set_attr "type" "mov_reg,mov_reg,mov_reg,mov_imm,mov_imm,load_4,load_4,store_4,store_4,\ 1081 ;; The "mov_imm" type for CNT is just a placeholder.
963 adr,adr,f_mcr,f_mrc,fmov,neon_move") 1082 [(set_attr "type" "mov_reg,mov_reg,mov_reg,mov_imm,mov_imm,mov_imm,load_4,
964 (set_attr "fp" "*,*,*,*,*,*,yes,*,yes,*,*,yes,yes,yes,*") 1083 load_4,store_4,store_4,adr,adr,f_mcr,f_mrc,fmov,neon_move")
965 (set_attr "simd" "*,*,*,*,*,*,*,*,*,*,*,*,*,*,yes")] 1084 (set_attr "arch" "*,*,*,*,*,sve,*,fp,*,fp,*,*,fp,fp,fp,simd")]
966 ) 1085 )
967 1086
968 (define_insn_and_split "*movdi_aarch64" 1087 (define_insn_and_split "*movdi_aarch64"
969 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,k,r,r,r,r,r,w, m,m, r, r, w,r,w, w") 1088 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,k,r,r,r,r,r, r,w, m,m, r, r, w,r,w, w")
970 (match_operand:DI 1 "aarch64_mov_operand" " r,r,k,N,M,n,m,m,rZ,w,Usa,Ush,rZ,w,w,Dd"))] 1089 (match_operand:DI 1 "aarch64_mov_operand" " r,r,k,N,M,n,Usv,m,m,rZ,w,Usa,Ush,rZ,w,w,Dd"))]
971 "(register_operand (operands[0], DImode) 1090 "(register_operand (operands[0], DImode)
972 || aarch64_reg_or_zero (operands[1], DImode))" 1091 || aarch64_reg_or_zero (operands[1], DImode))"
973 "@ 1092 "@
974 mov\\t%x0, %x1 1093 mov\\t%x0, %x1
975 mov\\t%0, %x1 1094 mov\\t%0, %x1
976 mov\\t%x0, %1 1095 mov\\t%x0, %1
977 mov\\t%x0, %1 1096 mov\\t%x0, %1
978 mov\\t%w0, %1 1097 mov\\t%w0, %1
979 # 1098 #
1099 * return aarch64_output_sve_cnt_immediate (\"cnt\", \"%x0\", operands[1]);
980 ldr\\t%x0, %1 1100 ldr\\t%x0, %1
981 ldr\\t%d0, %1 1101 ldr\\t%d0, %1
982 str\\t%x1, %0 1102 str\\t%x1, %0
983 str\\t%d1, %0 1103 str\\t%d1, %0
984 adr\\t%x0, %a1 1104 adr\\t%x0, %c1
985 adrp\\t%x0, %A1 1105 adrp\\t%x0, %A1
986 fmov\\t%d0, %x1 1106 fmov\\t%d0, %x1
987 fmov\\t%x0, %d1 1107 fmov\\t%x0, %d1
988 fmov\\t%d0, %d1 1108 fmov\\t%d0, %d1
989 * return aarch64_output_scalar_simd_mov_immediate (operands[1], DImode);" 1109 * return aarch64_output_scalar_simd_mov_immediate (operands[1], DImode);"
992 [(const_int 0)] 1112 [(const_int 0)]
993 "{ 1113 "{
994 aarch64_expand_mov_immediate (operands[0], operands[1]); 1114 aarch64_expand_mov_immediate (operands[0], operands[1]);
995 DONE; 1115 DONE;
996 }" 1116 }"
997 [(set_attr "type" "mov_reg,mov_reg,mov_reg,mov_imm,mov_imm,mov_imm,load_8,\ 1117 ;; The "mov_imm" type for CNTD is just a placeholder.
998 load_8,store_8,store_8,adr,adr,f_mcr,f_mrc,fmov,neon_move") 1118 [(set_attr "type" "mov_reg,mov_reg,mov_reg,mov_imm,mov_imm,mov_imm,mov_imm,
999 (set_attr "fp" "*,*,*,*,*,*,*,yes,*,yes,*,*,yes,yes,yes,*") 1119 load_8,load_8,store_8,store_8,adr,adr,f_mcr,f_mrc,fmov,
1000 (set_attr "simd" "*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,yes")] 1120 neon_move")
1121 (set_attr "arch" "*,*,*,*,*,*,sve,*,fp,*,fp,*,*,fp,fp,fp,simd")]
1001 ) 1122 )
1002 1123
1003 (define_insn "insv_imm<mode>" 1124 (define_insn "insv_imm<mode>"
1004 [(set (zero_extract:GPI (match_operand:GPI 0 "register_operand" "+r") 1125 [(set (zero_extract:GPI (match_operand:GPI 0 "register_operand" "+r")
1005 (const_int 16) 1126 (const_int 16)
1016 (match_operand:TI 1 "general_operand" ""))] 1137 (match_operand:TI 1 "general_operand" ""))]
1017 "" 1138 ""
1018 " 1139 "
1019 if (GET_CODE (operands[0]) == MEM && operands[1] != const0_rtx) 1140 if (GET_CODE (operands[0]) == MEM && operands[1] != const0_rtx)
1020 operands[1] = force_reg (TImode, operands[1]); 1141 operands[1] = force_reg (TImode, operands[1]);
1142
1143 if (GET_CODE (operands[1]) == CONST_POLY_INT)
1144 {
1145 emit_move_insn (gen_lowpart (DImode, operands[0]),
1146 gen_lowpart (DImode, operands[1]));
1147 emit_move_insn (gen_highpart (DImode, operands[0]), const0_rtx);
1148 DONE;
1149 }
1021 " 1150 "
1022 ) 1151 )
1023 1152
1024 (define_insn "*movti_aarch64" 1153 (define_insn "*movti_aarch64"
1025 [(set (match_operand:TI 0 1154 [(set (match_operand:TI 0
1026 "nonimmediate_operand" "=r, w,r,w,r,m,m,w,m") 1155 "nonimmediate_operand" "= r,w, r,w,r,m,m,w,m")
1027 (match_operand:TI 1 1156 (match_operand:TI 1
1028 "aarch64_movti_operand" " rn,r,w,w,m,r,Z,m,w"))] 1157 "aarch64_movti_operand" " rUti,r, w,w,m,r,Z,m,w"))]
1029 "(register_operand (operands[0], TImode) 1158 "(register_operand (operands[0], TImode)
1030 || aarch64_reg_or_zero (operands[1], TImode))" 1159 || aarch64_reg_or_zero (operands[1], TImode))"
1031 "@ 1160 "@
1032 # 1161 #
1033 # 1162 #
1040 str\\t%q1, %0" 1169 str\\t%q1, %0"
1041 [(set_attr "type" "multiple,f_mcr,f_mrc,neon_logic_q, \ 1170 [(set_attr "type" "multiple,f_mcr,f_mrc,neon_logic_q, \
1042 load_16,store_16,store_16,\ 1171 load_16,store_16,store_16,\
1043 load_16,store_16") 1172 load_16,store_16")
1044 (set_attr "length" "8,8,8,4,4,4,4,4,4") 1173 (set_attr "length" "8,8,8,4,4,4,4,4,4")
1045 (set_attr "simd" "*,*,*,yes,*,*,*,*,*") 1174 (set_attr "arch" "*,*,*,simd,*,*,*,fp,fp")]
1046 (set_attr "fp" "*,*,*,*,*,*,*,yes,yes")]
1047 ) 1175 )
1048 1176
1049 ;; Split a TImode register-register or register-immediate move into 1177 ;; Split a TImode register-register or register-immediate move into
1050 ;; its component DImode pieces, taking care to handle overlapping 1178 ;; its component DImode pieces, taking care to handle overlapping
1051 ;; source and dest registers. 1179 ;; source and dest registers.
1064 (match_operand:GPF_TF_F16 1 "general_operand" ""))] 1192 (match_operand:GPF_TF_F16 1 "general_operand" ""))]
1065 "" 1193 ""
1066 { 1194 {
1067 if (!TARGET_FLOAT) 1195 if (!TARGET_FLOAT)
1068 { 1196 {
1069 aarch64_err_no_fpadvsimd (<MODE>mode, "code"); 1197 aarch64_err_no_fpadvsimd (<MODE>mode);
1070 FAIL; 1198 FAIL;
1071 } 1199 }
1072 1200
1073 if (GET_CODE (operands[0]) == MEM 1201 if (GET_CODE (operands[0]) == MEM
1074 && ! (GET_CODE (operands[1]) == CONST_DOUBLE 1202 && ! (GET_CODE (operands[1]) == CONST_DOUBLE
1076 operands[1] = force_reg (<MODE>mode, operands[1]); 1204 operands[1] = force_reg (<MODE>mode, operands[1]);
1077 } 1205 }
1078 ) 1206 )
1079 1207
1080 (define_insn "*movhf_aarch64" 1208 (define_insn "*movhf_aarch64"
1081 [(set (match_operand:HF 0 "nonimmediate_operand" "=w,w ,?r,w,w ,w ,w,m,r,m ,r") 1209 [(set (match_operand:HF 0 "nonimmediate_operand" "=w,w , w,?r,w,w ,w ,w,m,r,m ,r")
1082 (match_operand:HF 1 "general_operand" "Y ,?rY, w,w,Ufc,Uvi,m,w,m,rY,r"))] 1210 (match_operand:HF 1 "general_operand" "Y ,?rY,?r, w,w,Ufc,Uvi,m,w,m,rY,r"))]
1083 "TARGET_FLOAT && (register_operand (operands[0], HFmode) 1211 "TARGET_FLOAT && (register_operand (operands[0], HFmode)
1084 || aarch64_reg_or_fp_zero (operands[1], HFmode))" 1212 || aarch64_reg_or_fp_zero (operands[1], HFmode))"
1085 "@ 1213 "@
1086 movi\\t%0.4h, #0 1214 movi\\t%0.4h, #0
1087 fmov\\t%h0, %w1 1215 fmov\\t%h0, %w1
1216 dup\\t%w0.4h, %w1
1088 umov\\t%w0, %1.h[0] 1217 umov\\t%w0, %1.h[0]
1089 mov\\t%0.h[0], %1.h[0] 1218 mov\\t%0.h[0], %1.h[0]
1090 fmov\\t%h0, %1 1219 fmov\\t%h0, %1
1091 * return aarch64_output_scalar_simd_mov_immediate (operands[1], SImode); 1220 * return aarch64_output_scalar_simd_mov_immediate (operands[1], HImode);
1092 ldr\\t%h0, %1 1221 ldr\\t%h0, %1
1093 str\\t%h1, %0 1222 str\\t%h1, %0
1094 ldrh\\t%w0, %1 1223 ldrh\\t%w0, %1
1095 strh\\t%w1, %0 1224 strh\\t%w1, %0
1096 mov\\t%w0, %w1" 1225 mov\\t%w0, %w1"
1097 [(set_attr "type" "neon_move,f_mcr,neon_to_gp,neon_move,fconsts, \ 1226 [(set_attr "type" "neon_move,f_mcr,neon_move,neon_to_gp, neon_move,fconsts, \
1098 neon_move,f_loads,f_stores,load_4,store_4,mov_reg") 1227 neon_move,f_loads,f_stores,load_4,store_4,mov_reg")
1099 (set_attr "simd" "yes,*,yes,yes,*,yes,*,*,*,*,*") 1228 (set_attr "arch" "simd,fp16,simd,simd,simd,fp16,simd,*,*,*,*,*")]
1100 (set_attr "fp16" "*,yes,*,*,yes,*,*,*,*,*,*")]
1101 ) 1229 )
1102 1230
1103 (define_insn "*movsf_aarch64" 1231 (define_insn "*movsf_aarch64"
1104 [(set (match_operand:SF 0 "nonimmediate_operand" "=w,w ,?r,w,w ,w ,w,m,r,m ,r,r") 1232 [(set (match_operand:SF 0 "nonimmediate_operand" "=w,w ,?r,w,w ,w ,w,m,r,m ,r,r")
1105 (match_operand:SF 1 "general_operand" "Y ,?rY, w,w,Ufc,Uvi,m,w,m,rY,r,M"))] 1233 (match_operand:SF 1 "general_operand" "Y ,?rY, w,w,Ufc,Uvi,m,w,m,rY,r,M"))]
1119 mov\\t%w0, %w1 1247 mov\\t%w0, %w1
1120 mov\\t%w0, %1" 1248 mov\\t%w0, %1"
1121 [(set_attr "type" "neon_move,f_mcr,f_mrc,fmov,fconsts,neon_move,\ 1249 [(set_attr "type" "neon_move,f_mcr,f_mrc,fmov,fconsts,neon_move,\
1122 f_loads,f_stores,load_4,store_4,mov_reg,\ 1250 f_loads,f_stores,load_4,store_4,mov_reg,\
1123 fconsts") 1251 fconsts")
1124 (set_attr "simd" "yes,*,*,*,*,yes,*,*,*,*,*,*")] 1252 (set_attr "arch" "simd,*,*,*,*,simd,*,*,*,*,*,*")]
1125 ) 1253 )
1126 1254
1127 (define_insn "*movdf_aarch64" 1255 (define_insn "*movdf_aarch64"
1128 [(set (match_operand:DF 0 "nonimmediate_operand" "=w, w ,?r,w,w ,w ,w,m,r,m ,r,r") 1256 [(set (match_operand:DF 0 "nonimmediate_operand" "=w, w ,?r,w,w ,w ,w,m,r,m ,r,r")
1129 (match_operand:DF 1 "general_operand" "Y , ?rY, w,w,Ufc,Uvi,m,w,m,rY,r,N"))] 1257 (match_operand:DF 1 "general_operand" "Y , ?rY, w,w,Ufc,Uvi,m,w,m,rY,r,N"))]
1143 mov\\t%x0, %x1 1271 mov\\t%x0, %x1
1144 mov\\t%x0, %1" 1272 mov\\t%x0, %1"
1145 [(set_attr "type" "neon_move,f_mcr,f_mrc,fmov,fconstd,neon_move,\ 1273 [(set_attr "type" "neon_move,f_mcr,f_mrc,fmov,fconstd,neon_move,\
1146 f_loadd,f_stored,load_8,store_8,mov_reg,\ 1274 f_loadd,f_stored,load_8,store_8,mov_reg,\
1147 fconstd") 1275 fconstd")
1148 (set_attr "simd" "yes,*,*,*,*,yes,*,*,*,*,*,*")] 1276 (set_attr "arch" "simd,*,*,*,*,simd,*,*,*,*,*,*")]
1149 ) 1277 )
1150 1278
1151 (define_split 1279 (define_split
1152 [(set (match_operand:GPF_HF 0 "nonimmediate_operand") 1280 [(set (match_operand:GPF_HF 0 "nonimmediate_operand")
1153 (match_operand:GPF_HF 1 "general_operand"))] 1281 (match_operand:GPF_HF 1 "general_operand"))]
1188 stp\\t%1, %H1, %0 1316 stp\\t%1, %H1, %0
1189 stp\\txzr, xzr, %0" 1317 stp\\txzr, xzr, %0"
1190 [(set_attr "type" "logic_reg,multiple,f_mcr,f_mrc,neon_move_q,f_mcr,\ 1318 [(set_attr "type" "logic_reg,multiple,f_mcr,f_mrc,neon_move_q,f_mcr,\
1191 f_loadd,f_stored,load_16,store_16,store_16") 1319 f_loadd,f_stored,load_16,store_16,store_16")
1192 (set_attr "length" "4,8,8,8,4,4,4,4,4,4,4") 1320 (set_attr "length" "4,8,8,8,4,4,4,4,4,4,4")
1193 (set_attr "simd" "yes,*,*,*,yes,*,*,*,*,*,*")] 1321 (set_attr "arch" "simd,*,*,*,simd,*,*,*,*,*,*")]
1194 ) 1322 )
1195 1323
1196 (define_split 1324 (define_split
1197 [(set (match_operand:TF 0 "register_operand" "") 1325 [(set (match_operand:TF 0 "register_operand" "")
1198 (match_operand:TF 1 "aarch64_reg_or_imm" ""))] 1326 (match_operand:TF 1 "aarch64_reg_or_imm" ""))]
1222 } 1350 }
1223 ) 1351 )
1224 1352
1225 ;; Operands 1 and 3 are tied together by the final condition; so we allow 1353 ;; Operands 1 and 3 are tied together by the final condition; so we allow
1226 ;; fairly lax checking on the second memory operation. 1354 ;; fairly lax checking on the second memory operation.
1227 (define_insn "load_pairsi" 1355 (define_insn "load_pair_sw_<SX:mode><SX2:mode>"
1228 [(set (match_operand:SI 0 "register_operand" "=r,*w") 1356 [(set (match_operand:SX 0 "register_operand" "=r,w")
1229 (match_operand:SI 1 "aarch64_mem_pair_operand" "Ump,Ump")) 1357 (match_operand:SX 1 "aarch64_mem_pair_operand" "Ump,Ump"))
1230 (set (match_operand:SI 2 "register_operand" "=r,*w") 1358 (set (match_operand:SX2 2 "register_operand" "=r,w")
1231 (match_operand:SI 3 "memory_operand" "m,m"))] 1359 (match_operand:SX2 3 "memory_operand" "m,m"))]
1232 "rtx_equal_p (XEXP (operands[3], 0), 1360 "rtx_equal_p (XEXP (operands[3], 0),
1233 plus_constant (Pmode, 1361 plus_constant (Pmode,
1234 XEXP (operands[1], 0), 1362 XEXP (operands[1], 0),
1235 GET_MODE_SIZE (SImode)))" 1363 GET_MODE_SIZE (<SX:MODE>mode)))"
1236 "@ 1364 "@
1237 ldp\\t%w0, %w2, %1 1365 ldp\\t%w0, %w2, %1
1238 ldp\\t%s0, %s2, %1" 1366 ldp\\t%s0, %s2, %1"
1239 [(set_attr "type" "load_8,neon_load1_2reg") 1367 [(set_attr "type" "load_8,neon_load1_2reg")
1240 (set_attr "fp" "*,yes")] 1368 (set_attr "arch" "*,fp")]
1241 ) 1369 )
1242 1370
1243 (define_insn "load_pairdi" 1371 ;; Storing different modes that can still be merged
1244 [(set (match_operand:DI 0 "register_operand" "=r,*w") 1372 (define_insn "load_pair_dw_<DX:mode><DX2:mode>"
1245 (match_operand:DI 1 "aarch64_mem_pair_operand" "Ump,Ump")) 1373 [(set (match_operand:DX 0 "register_operand" "=r,w")
1246 (set (match_operand:DI 2 "register_operand" "=r,*w") 1374 (match_operand:DX 1 "aarch64_mem_pair_operand" "Ump,Ump"))
1247 (match_operand:DI 3 "memory_operand" "m,m"))] 1375 (set (match_operand:DX2 2 "register_operand" "=r,w")
1248 "rtx_equal_p (XEXP (operands[3], 0), 1376 (match_operand:DX2 3 "memory_operand" "m,m"))]
1249 plus_constant (Pmode, 1377 "rtx_equal_p (XEXP (operands[3], 0),
1250 XEXP (operands[1], 0), 1378 plus_constant (Pmode,
1251 GET_MODE_SIZE (DImode)))" 1379 XEXP (operands[1], 0),
1380 GET_MODE_SIZE (<DX:MODE>mode)))"
1252 "@ 1381 "@
1253 ldp\\t%x0, %x2, %1 1382 ldp\\t%x0, %x2, %1
1254 ldp\\t%d0, %d2, %1" 1383 ldp\\t%d0, %d2, %1"
1255 [(set_attr "type" "load_16,neon_load1_2reg") 1384 [(set_attr "type" "load_16,neon_load1_2reg")
1256 (set_attr "fp" "*,yes")] 1385 (set_attr "arch" "*,fp")]
1257 ) 1386 )
1258
1259 1387
1260 ;; Operands 0 and 2 are tied together by the final condition; so we allow 1388 ;; Operands 0 and 2 are tied together by the final condition; so we allow
1261 ;; fairly lax checking on the second memory operation. 1389 ;; fairly lax checking on the second memory operation.
1262 (define_insn "store_pairsi" 1390 (define_insn "store_pair_sw_<SX:mode><SX2:mode>"
1263 [(set (match_operand:SI 0 "aarch64_mem_pair_operand" "=Ump,Ump") 1391 [(set (match_operand:SX 0 "aarch64_mem_pair_operand" "=Ump,Ump")
1264 (match_operand:SI 1 "aarch64_reg_or_zero" "rZ,*w")) 1392 (match_operand:SX 1 "aarch64_reg_zero_or_fp_zero" "rYZ,w"))
1265 (set (match_operand:SI 2 "memory_operand" "=m,m") 1393 (set (match_operand:SX2 2 "memory_operand" "=m,m")
1266 (match_operand:SI 3 "aarch64_reg_or_zero" "rZ,*w"))] 1394 (match_operand:SX2 3 "aarch64_reg_zero_or_fp_zero" "rYZ,w"))]
1267 "rtx_equal_p (XEXP (operands[2], 0), 1395 "rtx_equal_p (XEXP (operands[2], 0),
1268 plus_constant (Pmode, 1396 plus_constant (Pmode,
1269 XEXP (operands[0], 0), 1397 XEXP (operands[0], 0),
1270 GET_MODE_SIZE (SImode)))" 1398 GET_MODE_SIZE (<SX:MODE>mode)))"
1271 "@ 1399 "@
1272 stp\\t%w1, %w3, %0 1400 stp\\t%w1, %w3, %0
1273 stp\\t%s1, %s3, %0" 1401 stp\\t%s1, %s3, %0"
1274 [(set_attr "type" "store_8,neon_store1_2reg") 1402 [(set_attr "type" "store_8,neon_store1_2reg")
1275 (set_attr "fp" "*,yes")] 1403 (set_attr "arch" "*,fp")]
1276 ) 1404 )
1277 1405
1278 (define_insn "store_pairdi" 1406 ;; Storing different modes that can still be merged
1279 [(set (match_operand:DI 0 "aarch64_mem_pair_operand" "=Ump,Ump") 1407 (define_insn "store_pair_dw_<DX:mode><DX2:mode>"
1280 (match_operand:DI 1 "aarch64_reg_or_zero" "rZ,*w")) 1408 [(set (match_operand:DX 0 "aarch64_mem_pair_operand" "=Ump,Ump")
1281 (set (match_operand:DI 2 "memory_operand" "=m,m") 1409 (match_operand:DX 1 "aarch64_reg_zero_or_fp_zero" "rYZ,w"))
1282 (match_operand:DI 3 "aarch64_reg_or_zero" "rZ,*w"))] 1410 (set (match_operand:DX2 2 "memory_operand" "=m,m")
1283 "rtx_equal_p (XEXP (operands[2], 0), 1411 (match_operand:DX2 3 "aarch64_reg_zero_or_fp_zero" "rYZ,w"))]
1284 plus_constant (Pmode, 1412 "rtx_equal_p (XEXP (operands[2], 0),
1285 XEXP (operands[0], 0), 1413 plus_constant (Pmode,
1286 GET_MODE_SIZE (DImode)))" 1414 XEXP (operands[0], 0),
1415 GET_MODE_SIZE (<DX:MODE>mode)))"
1287 "@ 1416 "@
1288 stp\\t%x1, %x3, %0 1417 stp\\t%x1, %x3, %0
1289 stp\\t%d1, %d3, %0" 1418 stp\\t%d1, %d3, %0"
1290 [(set_attr "type" "store_16,neon_store1_2reg") 1419 [(set_attr "type" "store_16,neon_store1_2reg")
1291 (set_attr "fp" "*,yes")] 1420 (set_attr "arch" "*,fp")]
1292 )
1293
1294 ;; Operands 1 and 3 are tied together by the final condition; so we allow
1295 ;; fairly lax checking on the second memory operation.
1296 (define_insn "load_pairsf"
1297 [(set (match_operand:SF 0 "register_operand" "=w,*r")
1298 (match_operand:SF 1 "aarch64_mem_pair_operand" "Ump,Ump"))
1299 (set (match_operand:SF 2 "register_operand" "=w,*r")
1300 (match_operand:SF 3 "memory_operand" "m,m"))]
1301 "rtx_equal_p (XEXP (operands[3], 0),
1302 plus_constant (Pmode,
1303 XEXP (operands[1], 0),
1304 GET_MODE_SIZE (SFmode)))"
1305 "@
1306 ldp\\t%s0, %s2, %1
1307 ldp\\t%w0, %w2, %1"
1308 [(set_attr "type" "neon_load1_2reg,load_8")
1309 (set_attr "fp" "yes,*")]
1310 )
1311
1312 (define_insn "load_pairdf"
1313 [(set (match_operand:DF 0 "register_operand" "=w,*r")
1314 (match_operand:DF 1 "aarch64_mem_pair_operand" "Ump,Ump"))
1315 (set (match_operand:DF 2 "register_operand" "=w,*r")
1316 (match_operand:DF 3 "memory_operand" "m,m"))]
1317 "rtx_equal_p (XEXP (operands[3], 0),
1318 plus_constant (Pmode,
1319 XEXP (operands[1], 0),
1320 GET_MODE_SIZE (DFmode)))"
1321 "@
1322 ldp\\t%d0, %d2, %1
1323 ldp\\t%x0, %x2, %1"
1324 [(set_attr "type" "neon_load1_2reg,load_16")
1325 (set_attr "fp" "yes,*")]
1326 )
1327
1328 ;; Operands 0 and 2 are tied together by the final condition; so we allow
1329 ;; fairly lax checking on the second memory operation.
1330 (define_insn "store_pairsf"
1331 [(set (match_operand:SF 0 "aarch64_mem_pair_operand" "=Ump,Ump")
1332 (match_operand:SF 1 "aarch64_reg_or_fp_zero" "w,*rY"))
1333 (set (match_operand:SF 2 "memory_operand" "=m,m")
1334 (match_operand:SF 3 "aarch64_reg_or_fp_zero" "w,*rY"))]
1335 "rtx_equal_p (XEXP (operands[2], 0),
1336 plus_constant (Pmode,
1337 XEXP (operands[0], 0),
1338 GET_MODE_SIZE (SFmode)))"
1339 "@
1340 stp\\t%s1, %s3, %0
1341 stp\\t%w1, %w3, %0"
1342 [(set_attr "type" "neon_store1_2reg,store_8")
1343 (set_attr "fp" "yes,*")]
1344 )
1345
1346 (define_insn "store_pairdf"
1347 [(set (match_operand:DF 0 "aarch64_mem_pair_operand" "=Ump,Ump")
1348 (match_operand:DF 1 "aarch64_reg_or_fp_zero" "w,*rY"))
1349 (set (match_operand:DF 2 "memory_operand" "=m,m")
1350 (match_operand:DF 3 "aarch64_reg_or_fp_zero" "w,*rY"))]
1351 "rtx_equal_p (XEXP (operands[2], 0),
1352 plus_constant (Pmode,
1353 XEXP (operands[0], 0),
1354 GET_MODE_SIZE (DFmode)))"
1355 "@
1356 stp\\t%d1, %d3, %0
1357 stp\\t%x1, %x3, %0"
1358 [(set_attr "type" "neon_store1_2reg,store_16")
1359 (set_attr "fp" "yes,*")]
1360 ) 1421 )
1361 1422
1362 ;; Load pair with post-index writeback. This is primarily used in function 1423 ;; Load pair with post-index writeback. This is primarily used in function
1363 ;; epilogues. 1424 ;; epilogues.
1364 (define_insn "loadwb_pair<GPI:mode>_<P:mode>" 1425 (define_insn "loadwb_pair<GPI:mode>_<P:mode>"
1457 "ldpsw\\t%0, %2, %1" 1518 "ldpsw\\t%0, %2, %1"
1458 [(set_attr "type" "load_8")] 1519 [(set_attr "type" "load_8")]
1459 ) 1520 )
1460 1521
1461 (define_insn "*zero_extendsidi2_aarch64" 1522 (define_insn "*zero_extendsidi2_aarch64"
1462 [(set (match_operand:DI 0 "register_operand" "=r,r") 1523 [(set (match_operand:DI 0 "register_operand" "=r,r,w,w,r,w")
1463 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "r,m")))] 1524 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "r,m,r,m,w,w")))]
1464 "" 1525 ""
1465 "@ 1526 "@
1466 uxtw\t%0, %w1 1527 uxtw\t%0, %w1
1467 ldr\t%w0, %1" 1528 ldr\t%w0, %1
1468 [(set_attr "type" "extend,load_4")] 1529 fmov\t%s0, %w1
1530 ldr\t%s0, %1
1531 fmov\t%w0, %s1
1532 fmov\t%s0, %s1"
1533 [(set_attr "type" "extend,load_4,f_mcr,f_loads,f_mrc,fmov")
1534 (set_attr "arch" "*,*,fp,fp,fp,fp")]
1469 ) 1535 )
1470 1536
1471 (define_insn "*load_pair_zero_extendsidi2_aarch64" 1537 (define_insn "*load_pair_zero_extendsidi2_aarch64"
1472 [(set (match_operand:DI 0 "register_operand" "=r") 1538 [(set (match_operand:DI 0 "register_operand" "=r,w")
1473 (zero_extend:DI (match_operand:SI 1 "aarch64_mem_pair_operand" "Ump"))) 1539 (zero_extend:DI (match_operand:SI 1 "aarch64_mem_pair_operand" "Ump,Ump")))
1474 (set (match_operand:DI 2 "register_operand" "=r") 1540 (set (match_operand:DI 2 "register_operand" "=r,w")
1475 (zero_extend:DI (match_operand:SI 3 "memory_operand" "m")))] 1541 (zero_extend:DI (match_operand:SI 3 "memory_operand" "m,m")))]
1476 "rtx_equal_p (XEXP (operands[3], 0), 1542 "rtx_equal_p (XEXP (operands[3], 0),
1477 plus_constant (Pmode, 1543 plus_constant (Pmode,
1478 XEXP (operands[1], 0), 1544 XEXP (operands[1], 0),
1479 GET_MODE_SIZE (SImode)))" 1545 GET_MODE_SIZE (SImode)))"
1480 "ldp\\t%w0, %w2, %1" 1546 "@
1481 [(set_attr "type" "load_8")] 1547 ldp\t%w0, %w2, %1
1548 ldp\t%s0, %s2, %1"
1549 [(set_attr "type" "load_8,neon_load1_2reg")
1550 (set_attr "arch" "*,fp")]
1482 ) 1551 )
1483 1552
1484 (define_expand "<ANY_EXTEND:optab><SHORT:mode><GPI:mode>2" 1553 (define_expand "<ANY_EXTEND:optab><SHORT:mode><GPI:mode>2"
1485 [(set (match_operand:GPI 0 "register_operand") 1554 [(set (match_operand:GPI 0 "register_operand")
1486 (ANY_EXTEND:GPI (match_operand:SHORT 1 "nonimmediate_operand")))] 1555 (ANY_EXTEND:GPI (match_operand:SHORT 1 "nonimmediate_operand")))]
1496 ldrs<SHORT:size>\t%<GPI:w>0, %1" 1565 ldrs<SHORT:size>\t%<GPI:w>0, %1"
1497 [(set_attr "type" "extend,load_4")] 1566 [(set_attr "type" "extend,load_4")]
1498 ) 1567 )
1499 1568
1500 (define_insn "*zero_extend<SHORT:mode><GPI:mode>2_aarch64" 1569 (define_insn "*zero_extend<SHORT:mode><GPI:mode>2_aarch64"
1501 [(set (match_operand:GPI 0 "register_operand" "=r,r,*w") 1570 [(set (match_operand:GPI 0 "register_operand" "=r,r,w")
1502 (zero_extend:GPI (match_operand:SHORT 1 "nonimmediate_operand" "r,m,m")))] 1571 (zero_extend:GPI (match_operand:SHORT 1 "nonimmediate_operand" "r,m,m")))]
1503 "" 1572 ""
1504 "@ 1573 "@
1505 and\t%<GPI:w>0, %<GPI:w>1, <SHORT:short_mask> 1574 and\t%<GPI:w>0, %<GPI:w>1, <SHORT:short_mask>
1506 ldr<SHORT:size>\t%w0, %1 1575 ldr<SHORT:size>\t%w0, %1
1507 ldr\t%<SHORT:size>0, %1" 1576 ldr\t%<SHORT:size>0, %1"
1508 [(set_attr "type" "logic_imm,load_4,load_4")] 1577 [(set_attr "type" "logic_imm,load_4,f_loads")
1578 (set_attr "arch" "*,*,fp")]
1509 ) 1579 )
1510 1580
1511 (define_expand "<optab>qihi2" 1581 (define_expand "<optab>qihi2"
1512 [(set (match_operand:HI 0 "register_operand") 1582 [(set (match_operand:HI 0 "register_operand")
1513 (ANY_EXTEND:HI (match_operand:QI 1 "nonimmediate_operand")))] 1583 (ANY_EXTEND:HI (match_operand:QI 1 "nonimmediate_operand")))]
1540 1610
1541 (define_expand "add<mode>3" 1611 (define_expand "add<mode>3"
1542 [(set 1612 [(set
1543 (match_operand:GPI 0 "register_operand" "") 1613 (match_operand:GPI 0 "register_operand" "")
1544 (plus:GPI (match_operand:GPI 1 "register_operand" "") 1614 (plus:GPI (match_operand:GPI 1 "register_operand" "")
1545 (match_operand:GPI 2 "aarch64_pluslong_operand" "")))] 1615 (match_operand:GPI 2 "aarch64_pluslong_or_poly_operand" "")))]
1546 "" 1616 ""
1547 { 1617 {
1548 /* If operands[1] is a subreg extract the inner RTX. */ 1618 /* If operands[1] is a subreg extract the inner RTX. */
1549 rtx op1 = REG_P (operands[1]) ? operands[1] : SUBREG_REG (operands[1]); 1619 rtx op1 = REG_P (operands[1]) ? operands[1] : SUBREG_REG (operands[1]);
1550 1620
1553 if (!aarch64_plus_immediate (operands[2], <MODE>mode) 1623 if (!aarch64_plus_immediate (operands[2], <MODE>mode)
1554 && can_create_pseudo_p () 1624 && can_create_pseudo_p ()
1555 && (!REG_P (op1) 1625 && (!REG_P (op1)
1556 || !REGNO_PTR_FRAME_P (REGNO (op1)))) 1626 || !REGNO_PTR_FRAME_P (REGNO (op1))))
1557 operands[2] = force_reg (<MODE>mode, operands[2]); 1627 operands[2] = force_reg (<MODE>mode, operands[2]);
1628 /* Expand polynomial additions now if the destination is the stack
1629 pointer, since we don't want to use that as a temporary. */
1630 else if (operands[0] == stack_pointer_rtx
1631 && aarch64_split_add_offset_immediate (operands[2], <MODE>mode))
1632 {
1633 aarch64_split_add_offset (<MODE>mode, operands[0], operands[1],
1634 operands[2], NULL_RTX, NULL_RTX);
1635 DONE;
1636 }
1558 }) 1637 })
1559 1638
1560 (define_insn "*add<mode>3_aarch64" 1639 (define_insn "*add<mode>3_aarch64"
1561 [(set 1640 [(set
1562 (match_operand:GPI 0 "register_operand" "=rk,rk,w,rk,r") 1641 (match_operand:GPI 0 "register_operand" "=rk,rk,w,rk,r,rk")
1563 (plus:GPI 1642 (plus:GPI
1564 (match_operand:GPI 1 "register_operand" "%rk,rk,w,rk,rk") 1643 (match_operand:GPI 1 "register_operand" "%rk,rk,w,rk,rk,rk")
1565 (match_operand:GPI 2 "aarch64_pluslong_operand" "I,r,w,J,Upl")))] 1644 (match_operand:GPI 2 "aarch64_pluslong_operand" "I,r,w,J,Uaa,Uav")))]
1566 "" 1645 ""
1567 "@ 1646 "@
1568 add\\t%<w>0, %<w>1, %2 1647 add\\t%<w>0, %<w>1, %2
1569 add\\t%<w>0, %<w>1, %<w>2 1648 add\\t%<w>0, %<w>1, %<w>2
1570 add\\t%<rtn>0<vas>, %<rtn>1<vas>, %<rtn>2<vas> 1649 add\\t%<rtn>0<vas>, %<rtn>1<vas>, %<rtn>2<vas>
1571 sub\\t%<w>0, %<w>1, #%n2 1650 sub\\t%<w>0, %<w>1, #%n2
1572 #" 1651 #
1573 [(set_attr "type" "alu_imm,alu_sreg,neon_add,alu_imm,multiple") 1652 * return aarch64_output_sve_addvl_addpl (operands[0], operands[1], operands[2]);"
1574 (set_attr "simd" "*,*,yes,*,*")] 1653 ;; The "alu_imm" type for ADDVL/ADDPL is just a placeholder.
1654 [(set_attr "type" "alu_imm,alu_sreg,neon_add,alu_imm,multiple,alu_imm")
1655 (set_attr "arch" "*,*,simd,*,*,*")]
1575 ) 1656 )
1576 1657
1577 ;; zero_extend version of above 1658 ;; zero_extend version of above
1578 (define_insn "*addsi3_aarch64_uxtw" 1659 (define_insn "*addsi3_aarch64_uxtw"
1579 [(set 1660 [(set
1580 (match_operand:DI 0 "register_operand" "=rk,rk,rk,r") 1661 (match_operand:DI 0 "register_operand" "=rk,rk,rk,r")
1581 (zero_extend:DI 1662 (zero_extend:DI
1582 (plus:SI (match_operand:SI 1 "register_operand" "%rk,rk,rk,rk") 1663 (plus:SI (match_operand:SI 1 "register_operand" "%rk,rk,rk,rk")
1583 (match_operand:SI 2 "aarch64_pluslong_operand" "I,r,J,Upl"))))] 1664 (match_operand:SI 2 "aarch64_pluslong_operand" "I,r,J,Uaa"))))]
1584 "" 1665 ""
1585 "@ 1666 "@
1586 add\\t%w0, %w1, %2 1667 add\\t%w0, %w1, %2
1587 add\\t%w0, %w1, %w2 1668 add\\t%w0, %w1, %w2
1588 sub\\t%w0, %w1, #%n2 1669 sub\\t%w0, %w1, #%n2
1631 operands[3] = GEN_INT (i - s); 1712 operands[3] = GEN_INT (i - s);
1632 operands[4] = GEN_INT (s); 1713 operands[4] = GEN_INT (s);
1633 } 1714 }
1634 ) 1715 )
1635 1716
1717 ;; Match addition of polynomial offsets that require one temporary, for which
1718 ;; we can use the early-clobbered destination register. This is a separate
1719 ;; pattern so that the early clobber doesn't affect register allocation
1720 ;; for other forms of addition. However, we still need to provide an
1721 ;; all-register alternative, in case the offset goes out of range after
1722 ;; elimination. For completeness we might as well provide all GPR-based
1723 ;; alternatives from the main pattern.
1724 ;;
1725 ;; We don't have a pattern for additions requiring two temporaries since at
1726 ;; present LRA doesn't allow new scratches to be added during elimination.
1727 ;; Such offsets should be rare anyway.
1728 ;;
1729 ;; ??? But if we added LRA support for new scratches, much of the ugliness
1730 ;; here would go away. We could just handle all polynomial constants in
1731 ;; this pattern.
1732 (define_insn_and_split "*add<mode>3_poly_1"
1733 [(set
1734 (match_operand:GPI 0 "register_operand" "=r,r,r,r,r,&r")
1735 (plus:GPI
1736 (match_operand:GPI 1 "register_operand" "%rk,rk,rk,rk,rk,rk")
1737 (match_operand:GPI 2 "aarch64_pluslong_or_poly_operand" "I,r,J,Uaa,Uav,Uat")))]
1738 "TARGET_SVE && operands[0] != stack_pointer_rtx"
1739 "@
1740 add\\t%<w>0, %<w>1, %2
1741 add\\t%<w>0, %<w>1, %<w>2
1742 sub\\t%<w>0, %<w>1, #%n2
1743 #
1744 * return aarch64_output_sve_addvl_addpl (operands[0], operands[1], operands[2]);
1745 #"
1746 "&& epilogue_completed
1747 && !reg_overlap_mentioned_p (operands[0], operands[1])
1748 && aarch64_split_add_offset_immediate (operands[2], <MODE>mode)"
1749 [(const_int 0)]
1750 {
1751 aarch64_split_add_offset (<MODE>mode, operands[0], operands[1],
1752 operands[2], operands[0], NULL_RTX);
1753 DONE;
1754 }
1755 ;; The "alu_imm" type for ADDVL/ADDPL is just a placeholder.
1756 [(set_attr "type" "alu_imm,alu_sreg,alu_imm,multiple,alu_imm,multiple")]
1757 )
1758
1636 (define_split 1759 (define_split
1637 [(set (match_operand:DI 0 "register_operand") 1760 [(set (match_operand:DI 0 "register_operand")
1638 (zero_extend:DI 1761 (zero_extend:DI
1639 (plus:SI 1762 (plus:SI
1640 (match_operand:SI 1 "register_operand") 1763 (match_operand:SI 1 "register_operand")
1649 operands[4] = GEN_INT (s); 1772 operands[4] = GEN_INT (s);
1650 operands[5] = gen_lowpart (SImode, operands[0]); 1773 operands[5] = gen_lowpart (SImode, operands[0]);
1651 } 1774 }
1652 ) 1775 )
1653 1776
1777 (define_expand "addv<mode>4"
1778 [(match_operand:GPI 0 "register_operand")
1779 (match_operand:GPI 1 "register_operand")
1780 (match_operand:GPI 2 "register_operand")
1781 (label_ref (match_operand 3 "" ""))]
1782 ""
1783 {
1784 emit_insn (gen_add<mode>3_compareV (operands[0], operands[1], operands[2]));
1785 aarch64_gen_unlikely_cbranch (NE, CC_Vmode, operands[3]);
1786
1787 DONE;
1788 })
1789
1790 (define_expand "uaddv<mode>4"
1791 [(match_operand:GPI 0 "register_operand")
1792 (match_operand:GPI 1 "register_operand")
1793 (match_operand:GPI 2 "register_operand")
1794 (label_ref (match_operand 3 "" ""))]
1795 ""
1796 {
1797 emit_insn (gen_add<mode>3_compareC (operands[0], operands[1], operands[2]));
1798 aarch64_gen_unlikely_cbranch (NE, CC_Cmode, operands[3]);
1799
1800 DONE;
1801 })
1802
1654 (define_expand "addti3" 1803 (define_expand "addti3"
1655 [(set (match_operand:TI 0 "register_operand" "") 1804 [(set (match_operand:TI 0 "register_operand" "")
1656 (plus:TI (match_operand:TI 1 "register_operand" "") 1805 (plus:TI (match_operand:TI 1 "register_operand" "")
1657 (match_operand:TI 2 "register_operand" "")))] 1806 (match_operand:TI 2 "aarch64_reg_or_imm" "")))]
1658 "" 1807 ""
1659 { 1808 {
1660 rtx low = gen_reg_rtx (DImode); 1809 rtx low_dest, op1_low, op2_low, high_dest, op1_high, op2_high;
1661 emit_insn (gen_adddi3_compareC (low, gen_lowpart (DImode, operands[1]), 1810
1662 gen_lowpart (DImode, operands[2]))); 1811 aarch64_addti_scratch_regs (operands[1], operands[2],
1663 1812 &low_dest, &op1_low, &op2_low,
1664 rtx high = gen_reg_rtx (DImode); 1813 &high_dest, &op1_high, &op2_high);
1665 emit_insn (gen_adddi3_carryin (high, gen_highpart (DImode, operands[1]), 1814
1666 gen_highpart (DImode, operands[2]))); 1815 if (op2_low == const0_rtx)
1667 1816 {
1668 emit_move_insn (gen_lowpart (DImode, operands[0]), low); 1817 low_dest = op1_low;
1669 emit_move_insn (gen_highpart (DImode, operands[0]), high); 1818 if (!aarch64_pluslong_operand (op2_high, DImode))
1819 op2_high = force_reg (DImode, op2_high);
1820 emit_insn (gen_adddi3 (high_dest, op1_high, op2_high));
1821 }
1822 else
1823 {
1824 emit_insn (gen_adddi3_compareC (low_dest, op1_low,
1825 force_reg (DImode, op2_low)));
1826 emit_insn (gen_adddi3_carryin (high_dest, op1_high,
1827 force_reg (DImode, op2_high)));
1828 }
1829
1830 emit_move_insn (gen_lowpart (DImode, operands[0]), low_dest);
1831 emit_move_insn (gen_highpart (DImode, operands[0]), high_dest);
1832
1670 DONE; 1833 DONE;
1671 }) 1834 })
1835
1836 (define_expand "addvti4"
1837 [(match_operand:TI 0 "register_operand" "")
1838 (match_operand:TI 1 "register_operand" "")
1839 (match_operand:TI 2 "aarch64_reg_or_imm" "")
1840 (label_ref (match_operand 3 "" ""))]
1841 ""
1842 {
1843 rtx low_dest, op1_low, op2_low, high_dest, op1_high, op2_high;
1844
1845 aarch64_addti_scratch_regs (operands[1], operands[2],
1846 &low_dest, &op1_low, &op2_low,
1847 &high_dest, &op1_high, &op2_high);
1848
1849 if (op2_low == const0_rtx)
1850 {
1851 low_dest = op1_low;
1852 emit_insn (gen_adddi3_compareV (high_dest, op1_high,
1853 force_reg (DImode, op2_high)));
1854 }
1855 else
1856 {
1857 emit_insn (gen_adddi3_compareC (low_dest, op1_low,
1858 force_reg (DImode, op2_low)));
1859 emit_insn (gen_adddi3_carryinV (high_dest, op1_high,
1860 force_reg (DImode, op2_high)));
1861 }
1862
1863 emit_move_insn (gen_lowpart (DImode, operands[0]), low_dest);
1864 emit_move_insn (gen_highpart (DImode, operands[0]), high_dest);
1865
1866 aarch64_gen_unlikely_cbranch (NE, CC_Vmode, operands[3]);
1867 DONE;
1868 })
1869
1870 (define_expand "uaddvti4"
1871 [(match_operand:TI 0 "register_operand" "")
1872 (match_operand:TI 1 "register_operand" "")
1873 (match_operand:TI 2 "aarch64_reg_or_imm" "")
1874 (label_ref (match_operand 3 "" ""))]
1875 ""
1876 {
1877 rtx low_dest, op1_low, op2_low, high_dest, op1_high, op2_high;
1878
1879 aarch64_addti_scratch_regs (operands[1], operands[2],
1880 &low_dest, &op1_low, &op2_low,
1881 &high_dest, &op1_high, &op2_high);
1882
1883 if (op2_low == const0_rtx)
1884 {
1885 low_dest = op1_low;
1886 emit_insn (gen_adddi3_compareC (high_dest, op1_high,
1887 force_reg (DImode, op2_high)));
1888 }
1889 else
1890 {
1891 emit_insn (gen_adddi3_compareC (low_dest, op1_low,
1892 force_reg (DImode, op2_low)));
1893 emit_insn (gen_adddi3_carryinC (high_dest, op1_high,
1894 force_reg (DImode, op2_high)));
1895 }
1896
1897 emit_move_insn (gen_lowpart (DImode, operands[0]), low_dest);
1898 emit_move_insn (gen_highpart (DImode, operands[0]), high_dest);
1899
1900 aarch64_gen_unlikely_cbranch (NE, CC_Cmode, operands[3]);
1901 DONE;
1902 })
1672 1903
1673 (define_insn "add<mode>3_compare0" 1904 (define_insn "add<mode>3_compare0"
1674 [(set (reg:CC_NZ CC_REGNUM) 1905 [(set (reg:CC_NZ CC_REGNUM)
1675 (compare:CC_NZ 1906 (compare:CC_NZ
1676 (plus:GPI (match_operand:GPI 1 "register_operand" "%r,r,r") 1907 (plus:GPI (match_operand:GPI 1 "register_operand" "%r,r,r")
1753 [(set_attr "type" "alus_imm")] 1984 [(set_attr "type" "alus_imm")]
1754 ) 1985 )
1755 1986
1756 (define_insn "add<mode>3_compareC" 1987 (define_insn "add<mode>3_compareC"
1757 [(set (reg:CC_C CC_REGNUM) 1988 [(set (reg:CC_C CC_REGNUM)
1758 (ne:CC_C 1989 (compare:CC_C
1759 (plus:<DWI> 1990 (plus:<DWI>
1760 (zero_extend:<DWI> (match_operand:GPI 1 "register_operand" "r")) 1991 (zero_extend:<DWI> (match_operand:GPI 1 "register_operand" "r"))
1761 (zero_extend:<DWI> (match_operand:GPI 2 "register_operand" "r"))) 1992 (zero_extend:<DWI> (match_operand:GPI 2 "register_operand" "r")))
1762 (zero_extend:<DWI> 1993 (zero_extend:<DWI>
1763 (plus:GPI (match_dup 1) (match_dup 2))))) 1994 (plus:GPI (match_dup 1) (match_dup 2)))))
1766 "" 1997 ""
1767 "adds\\t%<w>0, %<w>1, %<w>2" 1998 "adds\\t%<w>0, %<w>1, %<w>2"
1768 [(set_attr "type" "alus_sreg")] 1999 [(set_attr "type" "alus_sreg")]
1769 ) 2000 )
1770 2001
2002 (define_insn "*add<mode>3_compareV_cconly_imm"
2003 [(set (reg:CC_V CC_REGNUM)
2004 (compare:CC_V
2005 (plus:<DWI>
2006 (sign_extend:<DWI> (match_operand:GPI 0 "register_operand" "r,r"))
2007 (match_operand:<DWI> 1 "const_scalar_int_operand" ""))
2008 (sign_extend:<DWI>
2009 (plus:GPI
2010 (match_dup 0)
2011 (match_operand:GPI 2 "aarch64_plus_immediate" "I,J")))))]
2012 "INTVAL (operands[1]) == INTVAL (operands[2])"
2013 "@
2014 cmn\\t%<w>0, %<w>1
2015 cmp\\t%<w>0, #%n1"
2016 [(set_attr "type" "alus_imm")]
2017 )
2018
2019 (define_insn "*add<mode>3_compareV_cconly"
2020 [(set (reg:CC_V CC_REGNUM)
2021 (compare:CC_V
2022 (plus:<DWI>
2023 (sign_extend:<DWI> (match_operand:GPI 0 "register_operand" "r"))
2024 (sign_extend:<DWI> (match_operand:GPI 1 "register_operand" "r")))
2025 (sign_extend:<DWI> (plus:GPI (match_dup 0) (match_dup 1)))))]
2026 ""
2027 "cmn\\t%<w>0, %<w>1"
2028 [(set_attr "type" "alus_sreg")]
2029 )
2030
2031 (define_insn "*add<mode>3_compareV_imm"
2032 [(set (reg:CC_V CC_REGNUM)
2033 (compare:CC_V
2034 (plus:<DWI>
2035 (sign_extend:<DWI>
2036 (match_operand:GPI 1 "register_operand" "r,r"))
2037 (match_operand:GPI 2 "aarch64_plus_immediate" "I,J"))
2038 (sign_extend:<DWI>
2039 (plus:GPI (match_dup 1) (match_dup 2)))))
2040 (set (match_operand:GPI 0 "register_operand" "=r,r")
2041 (plus:GPI (match_dup 1) (match_dup 2)))]
2042 ""
2043 "@
2044 adds\\t%<w>0, %<w>1, %<w>2
2045 subs\\t%<w>0, %<w>1, #%n2"
2046 [(set_attr "type" "alus_imm,alus_imm")]
2047 )
2048
2049 (define_insn "add<mode>3_compareV"
2050 [(set (reg:CC_V CC_REGNUM)
2051 (compare:CC_V
2052 (plus:<DWI>
2053 (sign_extend:<DWI> (match_operand:GPI 1 "register_operand" "r"))
2054 (sign_extend:<DWI> (match_operand:GPI 2 "register_operand" "r")))
2055 (sign_extend:<DWI> (plus:GPI (match_dup 1) (match_dup 2)))))
2056 (set (match_operand:GPI 0 "register_operand" "=r")
2057 (plus:GPI (match_dup 1) (match_dup 2)))]
2058 ""
2059 "adds\\t%<w>0, %<w>1, %<w>2"
2060 [(set_attr "type" "alus_sreg")]
2061 )
2062
1771 (define_insn "*adds_shift_imm_<mode>" 2063 (define_insn "*adds_shift_imm_<mode>"
1772 [(set (reg:CC_NZ CC_REGNUM) 2064 [(set (reg:CC_NZ CC_REGNUM)
1773 (compare:CC_NZ 2065 (compare:CC_NZ
1774 (plus:GPI (ASHIFT:GPI 2066 (plus:GPI (ASHIFT:GPI
1775 (match_operand:GPI 1 "register_operand" "r") 2067 (match_operand:GPI 1 "register_operand" "r")
1776 (match_operand:QI 2 "aarch64_shift_imm_<mode>" "n")) 2068 (match_operand:QI 2 "aarch64_shift_imm_<mode>" "n"))
1777 (match_operand:GPI 3 "register_operand" "r")) 2069 (match_operand:GPI 3 "register_operand" "r"))
1778 (const_int 0))) 2070 (const_int 0)))
1779 (set (match_operand:GPI 0 "register_operand" "=r") 2071 (set (match_operand:GPI 0 "register_operand" "=r")
2136 "" 2428 ""
2137 "adc\\t%w0, %w1, %w2" 2429 "adc\\t%w0, %w1, %w2"
2138 [(set_attr "type" "adc_reg")] 2430 [(set_attr "type" "adc_reg")]
2139 ) 2431 )
2140 2432
2433 (define_expand "add<mode>3_carryinC"
2434 [(parallel
2435 [(set (match_dup 3)
2436 (compare:CC_C
2437 (plus:<DWI>
2438 (plus:<DWI>
2439 (match_dup 4)
2440 (zero_extend:<DWI>
2441 (match_operand:GPI 1 "register_operand" "")))
2442 (zero_extend:<DWI>
2443 (match_operand:GPI 2 "register_operand" "")))
2444 (zero_extend:<DWI>
2445 (plus:GPI
2446 (plus:GPI (match_dup 5) (match_dup 1))
2447 (match_dup 2)))))
2448 (set (match_operand:GPI 0 "register_operand")
2449 (plus:GPI
2450 (plus:GPI (match_dup 5) (match_dup 1))
2451 (match_dup 2)))])]
2452 ""
2453 {
2454 operands[3] = gen_rtx_REG (CC_Cmode, CC_REGNUM);
2455 operands[4] = gen_rtx_NE (<DWI>mode, operands[3], const0_rtx);
2456 operands[5] = gen_rtx_NE (<MODE>mode, operands[3], const0_rtx);
2457 })
2458
2459 (define_insn "*add<mode>3_carryinC_zero"
2460 [(set (reg:CC_C CC_REGNUM)
2461 (compare:CC_C
2462 (plus:<DWI>
2463 (match_operand:<DWI> 2 "aarch64_carry_operation" "")
2464 (zero_extend:<DWI> (match_operand:GPI 1 "register_operand" "r")))
2465 (zero_extend:<DWI>
2466 (plus:GPI
2467 (match_operand:GPI 3 "aarch64_carry_operation" "")
2468 (match_dup 1)))))
2469 (set (match_operand:GPI 0 "register_operand" "=r")
2470 (plus:GPI (match_dup 3) (match_dup 1)))]
2471 ""
2472 "adcs\\t%<w>0, %<w>1, <w>zr"
2473 [(set_attr "type" "adc_reg")]
2474 )
2475
2476 (define_insn "*add<mode>3_carryinC"
2477 [(set (reg:CC_C CC_REGNUM)
2478 (compare:CC_C
2479 (plus:<DWI>
2480 (plus:<DWI>
2481 (match_operand:<DWI> 3 "aarch64_carry_operation" "")
2482 (zero_extend:<DWI> (match_operand:GPI 1 "register_operand" "r")))
2483 (zero_extend:<DWI> (match_operand:GPI 2 "register_operand" "r")))
2484 (zero_extend:<DWI>
2485 (plus:GPI
2486 (plus:GPI
2487 (match_operand:GPI 4 "aarch64_carry_operation" "")
2488 (match_dup 1))
2489 (match_dup 2)))))
2490 (set (match_operand:GPI 0 "register_operand" "=r")
2491 (plus:GPI
2492 (plus:GPI (match_dup 4) (match_dup 1))
2493 (match_dup 2)))]
2494 ""
2495 "adcs\\t%<w>0, %<w>1, %<w>2"
2496 [(set_attr "type" "adc_reg")]
2497 )
2498
2499 (define_expand "add<mode>3_carryinV"
2500 [(parallel
2501 [(set (reg:CC_V CC_REGNUM)
2502 (compare:CC_V
2503 (plus:<DWI>
2504 (plus:<DWI>
2505 (match_dup 3)
2506 (sign_extend:<DWI>
2507 (match_operand:GPI 1 "register_operand" "")))
2508 (sign_extend:<DWI>
2509 (match_operand:GPI 2 "register_operand" "")))
2510 (sign_extend:<DWI>
2511 (plus:GPI
2512 (plus:GPI (match_dup 4) (match_dup 1))
2513 (match_dup 2)))))
2514 (set (match_operand:GPI 0 "register_operand")
2515 (plus:GPI
2516 (plus:GPI (match_dup 4) (match_dup 1))
2517 (match_dup 2)))])]
2518 ""
2519 {
2520 rtx cc = gen_rtx_REG (CC_Cmode, CC_REGNUM);
2521 operands[3] = gen_rtx_NE (<DWI>mode, cc, const0_rtx);
2522 operands[4] = gen_rtx_NE (<MODE>mode, cc, const0_rtx);
2523 })
2524
2525 (define_insn "*add<mode>3_carryinV_zero"
2526 [(set (reg:CC_V CC_REGNUM)
2527 (compare:CC_V
2528 (plus:<DWI>
2529 (match_operand:<DWI> 2 "aarch64_carry_operation" "")
2530 (sign_extend:<DWI> (match_operand:GPI 1 "register_operand" "r")))
2531 (sign_extend:<DWI>
2532 (plus:GPI
2533 (match_operand:GPI 3 "aarch64_carry_operation" "")
2534 (match_dup 1)))))
2535 (set (match_operand:GPI 0 "register_operand" "=r")
2536 (plus:GPI (match_dup 3) (match_dup 1)))]
2537 ""
2538 "adcs\\t%<w>0, %<w>1, <w>zr"
2539 [(set_attr "type" "adc_reg")]
2540 )
2541
2542 (define_insn "*add<mode>3_carryinV"
2543 [(set (reg:CC_V CC_REGNUM)
2544 (compare:CC_V
2545 (plus:<DWI>
2546 (plus:<DWI>
2547 (match_operand:<DWI> 3 "aarch64_carry_operation" "")
2548 (sign_extend:<DWI> (match_operand:GPI 1 "register_operand" "r")))
2549 (sign_extend:<DWI> (match_operand:GPI 2 "register_operand" "r")))
2550 (sign_extend:<DWI>
2551 (plus:GPI
2552 (plus:GPI
2553 (match_operand:GPI 4 "aarch64_carry_operation" "")
2554 (match_dup 1))
2555 (match_dup 2)))))
2556 (set (match_operand:GPI 0 "register_operand" "=r")
2557 (plus:GPI
2558 (plus:GPI (match_dup 4) (match_dup 1))
2559 (match_dup 2)))]
2560 ""
2561 "adcs\\t%<w>0, %<w>1, %<w>2"
2562 [(set_attr "type" "adc_reg")]
2563 )
2564
2141 (define_insn "*add_uxt<mode>_shift2" 2565 (define_insn "*add_uxt<mode>_shift2"
2142 [(set (match_operand:GPI 0 "register_operand" "=rk") 2566 [(set (match_operand:GPI 0 "register_operand" "=rk")
2143 (plus:GPI (and:GPI 2567 (plus:GPI (and:GPI
2144 (ashift:GPI (match_operand:GPI 1 "register_operand" "r") 2568 (ashift:GPI (match_operand:GPI 1 "register_operand" "r")
2145 (match_operand 2 "aarch64_imm3" "Ui3")) 2569 (match_operand 2 "aarch64_imm3" "Ui3"))
2229 "" 2653 ""
2230 "@ 2654 "@
2231 sub\\t%x0, %x1, %x2 2655 sub\\t%x0, %x1, %x2
2232 sub\\t%d0, %d1, %d2" 2656 sub\\t%d0, %d1, %d2"
2233 [(set_attr "type" "alu_sreg, neon_sub") 2657 [(set_attr "type" "alu_sreg, neon_sub")
2234 (set_attr "simd" "*,yes")] 2658 (set_attr "arch" "*,simd")]
2235 ) 2659 )
2660
2661 (define_expand "subv<mode>4"
2662 [(match_operand:GPI 0 "register_operand")
2663 (match_operand:GPI 1 "aarch64_reg_or_zero")
2664 (match_operand:GPI 2 "aarch64_reg_or_zero")
2665 (label_ref (match_operand 3 "" ""))]
2666 ""
2667 {
2668 emit_insn (gen_sub<mode>3_compare1 (operands[0], operands[1], operands[2]));
2669 aarch64_gen_unlikely_cbranch (NE, CC_Vmode, operands[3]);
2670
2671 DONE;
2672 })
2673
2674 (define_expand "usubv<mode>4"
2675 [(match_operand:GPI 0 "register_operand")
2676 (match_operand:GPI 1 "aarch64_reg_or_zero")
2677 (match_operand:GPI 2 "aarch64_reg_or_zero")
2678 (label_ref (match_operand 3 "" ""))]
2679 ""
2680 {
2681 emit_insn (gen_sub<mode>3_compare1 (operands[0], operands[1], operands[2]));
2682 aarch64_gen_unlikely_cbranch (LTU, CCmode, operands[3]);
2683
2684 DONE;
2685 })
2236 2686
2237 (define_expand "subti3" 2687 (define_expand "subti3"
2238 [(set (match_operand:TI 0 "register_operand" "") 2688 [(set (match_operand:TI 0 "register_operand" "")
2239 (minus:TI (match_operand:TI 1 "register_operand" "") 2689 (minus:TI (match_operand:TI 1 "aarch64_reg_or_zero" "")
2240 (match_operand:TI 2 "register_operand" "")))] 2690 (match_operand:TI 2 "register_operand" "")))]
2241 "" 2691 ""
2242 { 2692 {
2243 rtx low = gen_reg_rtx (DImode); 2693 rtx low_dest, op1_low, op2_low, high_dest, op1_high, op2_high;
2244 emit_insn (gen_subdi3_compare1 (low, gen_lowpart (DImode, operands[1]), 2694
2245 gen_lowpart (DImode, operands[2]))); 2695 aarch64_subvti_scratch_regs (operands[1], operands[2],
2246 2696 &low_dest, &op1_low, &op2_low,
2247 rtx high = gen_reg_rtx (DImode); 2697 &high_dest, &op1_high, &op2_high);
2248 emit_insn (gen_subdi3_carryin (high, gen_highpart (DImode, operands[1]), 2698
2249 gen_highpart (DImode, operands[2]))); 2699 emit_insn (gen_subdi3_compare1 (low_dest, op1_low, op2_low));
2250 2700 emit_insn (gen_subdi3_carryin (high_dest, op1_high, op2_high));
2251 emit_move_insn (gen_lowpart (DImode, operands[0]), low); 2701
2252 emit_move_insn (gen_highpart (DImode, operands[0]), high); 2702 emit_move_insn (gen_lowpart (DImode, operands[0]), low_dest);
2703 emit_move_insn (gen_highpart (DImode, operands[0]), high_dest);
2704 DONE;
2705 })
2706
2707 (define_expand "subvti4"
2708 [(match_operand:TI 0 "register_operand")
2709 (match_operand:TI 1 "aarch64_reg_or_zero")
2710 (match_operand:TI 2 "aarch64_reg_or_imm")
2711 (label_ref (match_operand 3 "" ""))]
2712 ""
2713 {
2714 rtx low_dest, op1_low, op2_low, high_dest, op1_high, op2_high;
2715
2716 aarch64_subvti_scratch_regs (operands[1], operands[2],
2717 &low_dest, &op1_low, &op2_low,
2718 &high_dest, &op1_high, &op2_high);
2719 aarch64_expand_subvti (operands[0], low_dest, op1_low, op2_low,
2720 high_dest, op1_high, op2_high);
2721
2722 aarch64_gen_unlikely_cbranch (NE, CC_Vmode, operands[3]);
2723 DONE;
2724 })
2725
2726 (define_expand "usubvti4"
2727 [(match_operand:TI 0 "register_operand")
2728 (match_operand:TI 1 "aarch64_reg_or_zero")
2729 (match_operand:TI 2 "aarch64_reg_or_imm")
2730 (label_ref (match_operand 3 "" ""))]
2731 ""
2732 {
2733 rtx low_dest, op1_low, op2_low, high_dest, op1_high, op2_high;
2734
2735 aarch64_subvti_scratch_regs (operands[1], operands[2],
2736 &low_dest, &op1_low, &op2_low,
2737 &high_dest, &op1_high, &op2_high);
2738 aarch64_expand_subvti (operands[0], low_dest, op1_low, op2_low,
2739 high_dest, op1_high, op2_high);
2740
2741 aarch64_gen_unlikely_cbranch (LTU, CCmode, operands[3]);
2253 DONE; 2742 DONE;
2254 }) 2743 })
2255 2744
2256 (define_insn "*sub<mode>3_compare0" 2745 (define_insn "*sub<mode>3_compare0"
2257 [(set (reg:CC_NZ CC_REGNUM) 2746 [(set (reg:CC_NZ CC_REGNUM)
2274 (set (match_operand:DI 0 "register_operand" "=r") 2763 (set (match_operand:DI 0 "register_operand" "=r")
2275 (zero_extend:DI (minus:SI (match_dup 1) (match_dup 2))))] 2764 (zero_extend:DI (minus:SI (match_dup 1) (match_dup 2))))]
2276 "" 2765 ""
2277 "subs\\t%w0, %w1, %w2" 2766 "subs\\t%w0, %w1, %w2"
2278 [(set_attr "type" "alus_sreg")] 2767 [(set_attr "type" "alus_sreg")]
2768 )
2769
2770 (define_insn "*sub<mode>3_compare1_imm"
2771 [(set (reg:CC CC_REGNUM)
2772 (compare:CC
2773 (match_operand:GPI 1 "aarch64_reg_or_zero" "rZ,rZ")
2774 (match_operand:GPI 2 "aarch64_plus_immediate" "I,J")))
2775 (set (match_operand:GPI 0 "register_operand" "=r,r")
2776 (plus:GPI
2777 (match_dup 1)
2778 (match_operand:GPI 3 "aarch64_plus_immediate" "J,I")))]
2779 "UINTVAL (operands[2]) == -UINTVAL (operands[3])"
2780 "@
2781 subs\\t%<w>0, %<w>1, #%n3
2782 adds\\t%<w>0, %<w>1, %3"
2783 [(set_attr "type" "alus_imm")]
2279 ) 2784 )
2280 2785
2281 (define_insn "sub<mode>3_compare1" 2786 (define_insn "sub<mode>3_compare1"
2282 [(set (reg:CC CC_REGNUM) 2787 [(set (reg:CC CC_REGNUM)
2283 (compare:CC 2788 (compare:CC
2319 operands[2])); 2824 operands[2]));
2320 DONE; 2825 DONE;
2321 } 2826 }
2322 ) 2827 )
2323 2828
2829 ;; Same as the above peephole but with the compare and minus in
2830 ;; swapped order. The restriction on overlap between operand 0
2831 ;; and operands 1 and 2 doesn't apply here.
2832 (define_peephole2
2833 [(set (reg:CC CC_REGNUM)
2834 (compare:CC
2835 (match_operand:GPI 1 "aarch64_reg_or_zero")
2836 (match_operand:GPI 2 "aarch64_reg_or_zero")))
2837 (set (match_operand:GPI 0 "register_operand")
2838 (minus:GPI (match_dup 1)
2839 (match_dup 2)))]
2840 ""
2841 [(const_int 0)]
2842 {
2843 emit_insn (gen_sub<mode>3_compare1 (operands[0], operands[1],
2844 operands[2]));
2845 DONE;
2846 }
2847 )
2848
2324 (define_peephole2 2849 (define_peephole2
2325 [(set (match_operand:GPI 0 "register_operand") 2850 [(set (match_operand:GPI 0 "register_operand")
2326 (plus:GPI (match_operand:GPI 1 "register_operand") 2851 (plus:GPI (match_operand:GPI 1 "register_operand")
2327 (match_operand:GPI 2 "aarch64_sub_immediate"))) 2852 (match_operand:GPI 2 "aarch64_sub_immediate")))
2328 (set (reg:CC CC_REGNUM) 2853 (set (reg:CC CC_REGNUM)
2337 operands[2], operands[3])); 2862 operands[2], operands[3]));
2338 DONE; 2863 DONE;
2339 } 2864 }
2340 ) 2865 )
2341 2866
2867 ;; Same as the above peephole but with the compare and minus in
2868 ;; swapped order. The restriction on overlap between operand 0
2869 ;; and operands 1 doesn't apply here.
2870 (define_peephole2
2871 [(set (reg:CC CC_REGNUM)
2872 (compare:CC
2873 (match_operand:GPI 1 "register_operand")
2874 (match_operand:GPI 3 "const_int_operand")))
2875 (set (match_operand:GPI 0 "register_operand")
2876 (plus:GPI (match_dup 1)
2877 (match_operand:GPI 2 "aarch64_sub_immediate")))]
2878 "INTVAL (operands[3]) == -INTVAL (operands[2])"
2879 [(const_int 0)]
2880 {
2881 emit_insn (gen_sub<mode>3_compare1_imm (operands[0], operands[1],
2882 operands[2], operands[3]));
2883 DONE;
2884 }
2885 )
2886
2342 (define_insn "*sub_<shift>_<mode>" 2887 (define_insn "*sub_<shift>_<mode>"
2343 [(set (match_operand:GPI 0 "register_operand" "=r") 2888 [(set (match_operand:GPI 0 "register_operand" "=r")
2344 (minus:GPI (match_operand:GPI 3 "register_operand" "r") 2889 (minus:GPI (match_operand:GPI 3 "register_operand" "r")
2345 (ASHIFT:GPI 2890 (ASHIFT:GPI
2346 (match_operand:GPI 1 "register_operand" "r") 2891 (match_operand:GPI 1 "register_operand" "r")
2549 (match_operand:SI 1 "aarch64_reg_or_zero" "rZ") 3094 (match_operand:SI 1 "aarch64_reg_or_zero" "rZ")
2550 (match_operand:SI 3 "aarch64_borrow_operation" "")) 3095 (match_operand:SI 3 "aarch64_borrow_operation" ""))
2551 (match_operand:SI 2 "register_operand" "r"))))] 3096 (match_operand:SI 2 "register_operand" "r"))))]
2552 "" 3097 ""
2553 "sbc\\t%w0, %w1, %w2" 3098 "sbc\\t%w0, %w1, %w2"
3099 [(set_attr "type" "adc_reg")]
3100 )
3101
3102 (define_expand "sub<mode>3_carryinCV"
3103 [(parallel
3104 [(set (reg:CC CC_REGNUM)
3105 (compare:CC
3106 (sign_extend:<DWI>
3107 (match_operand:GPI 1 "aarch64_reg_or_zero" ""))
3108 (plus:<DWI>
3109 (sign_extend:<DWI>
3110 (match_operand:GPI 2 "register_operand" ""))
3111 (ltu:<DWI> (reg:CC CC_REGNUM) (const_int 0)))))
3112 (set (match_operand:GPI 0 "register_operand" "")
3113 (minus:GPI
3114 (minus:GPI (match_dup 1) (match_dup 2))
3115 (ltu:GPI (reg:CC CC_REGNUM) (const_int 0))))])]
3116 ""
3117 )
3118
3119 (define_insn "*sub<mode>3_carryinCV_z1_z2"
3120 [(set (reg:CC CC_REGNUM)
3121 (compare:CC
3122 (const_int 0)
3123 (match_operand:<DWI> 2 "aarch64_borrow_operation" "")))
3124 (set (match_operand:GPI 0 "register_operand" "=r")
3125 (neg:GPI (match_operand:GPI 1 "aarch64_borrow_operation" "")))]
3126 ""
3127 "sbcs\\t%<w>0, <w>zr, <w>zr"
3128 [(set_attr "type" "adc_reg")]
3129 )
3130
3131 (define_insn "*sub<mode>3_carryinCV_z1"
3132 [(set (reg:CC CC_REGNUM)
3133 (compare:CC
3134 (const_int 0)
3135 (plus:<DWI>
3136 (sign_extend:<DWI>
3137 (match_operand:GPI 1 "register_operand" "r"))
3138 (match_operand:<DWI> 2 "aarch64_borrow_operation" ""))))
3139 (set (match_operand:GPI 0 "register_operand" "=r")
3140 (minus:GPI
3141 (neg:GPI (match_dup 1))
3142 (match_operand:GPI 3 "aarch64_borrow_operation" "")))]
3143 ""
3144 "sbcs\\t%<w>0, <w>zr, %<w>1"
3145 [(set_attr "type" "adc_reg")]
3146 )
3147
3148 (define_insn "*sub<mode>3_carryinCV_z2"
3149 [(set (reg:CC CC_REGNUM)
3150 (compare:CC
3151 (sign_extend:<DWI>
3152 (match_operand:GPI 1 "register_operand" "r"))
3153 (match_operand:<DWI> 2 "aarch64_borrow_operation" "")))
3154 (set (match_operand:GPI 0 "register_operand" "=r")
3155 (minus:GPI
3156 (match_dup 1)
3157 (match_operand:GPI 3 "aarch64_borrow_operation" "")))]
3158 ""
3159 "sbcs\\t%<w>0, %<w>1, <w>zr"
3160 [(set_attr "type" "adc_reg")]
3161 )
3162
3163 (define_insn "*sub<mode>3_carryinCV"
3164 [(set (reg:CC CC_REGNUM)
3165 (compare:CC
3166 (sign_extend:<DWI>
3167 (match_operand:GPI 1 "register_operand" "r"))
3168 (plus:<DWI>
3169 (sign_extend:<DWI>
3170 (match_operand:GPI 2 "register_operand" "r"))
3171 (match_operand:<DWI> 3 "aarch64_borrow_operation" ""))))
3172 (set (match_operand:GPI 0 "register_operand" "=r")
3173 (minus:GPI
3174 (minus:GPI (match_dup 1) (match_dup 2))
3175 (match_operand:GPI 4 "aarch64_borrow_operation" "")))]
3176 ""
3177 "sbcs\\t%<w>0, %<w>1, %<w>2"
2554 [(set_attr "type" "adc_reg")] 3178 [(set_attr "type" "adc_reg")]
2555 ) 3179 )
2556 3180
2557 (define_insn "*sub_uxt<mode>_shift2" 3181 (define_insn "*sub_uxt<mode>_shift2"
2558 [(set (match_operand:GPI 0 "register_operand" "=rk") 3182 [(set (match_operand:GPI 0 "register_operand" "=rk")
2636 "" 3260 ""
2637 "@ 3261 "@
2638 neg\\t%<w>0, %<w>1 3262 neg\\t%<w>0, %<w>1
2639 neg\\t%<rtn>0<vas>, %<rtn>1<vas>" 3263 neg\\t%<rtn>0<vas>, %<rtn>1<vas>"
2640 [(set_attr "type" "alu_sreg, neon_neg<q>") 3264 [(set_attr "type" "alu_sreg, neon_neg<q>")
2641 (set_attr "simd" "*,yes")] 3265 (set_attr "arch" "*,simd")]
2642 ) 3266 )
2643 3267
2644 ;; zero_extend version of above 3268 ;; zero_extend version of above
2645 (define_insn "*negsi2_uxtw" 3269 (define_insn "*negsi2_uxtw"
2646 [(set (match_operand:DI 0 "register_operand" "=r") 3270 [(set (match_operand:DI 0 "register_operand" "=r")
2961 ;; Comparison insns 3585 ;; Comparison insns
2962 ;; ------------------------------------------------------------------- 3586 ;; -------------------------------------------------------------------
2963 3587
2964 (define_insn "cmp<mode>" 3588 (define_insn "cmp<mode>"
2965 [(set (reg:CC CC_REGNUM) 3589 [(set (reg:CC CC_REGNUM)
2966 (compare:CC (match_operand:GPI 0 "register_operand" "r,r,r") 3590 (compare:CC (match_operand:GPI 0 "register_operand" "rk,rk,rk")
2967 (match_operand:GPI 1 "aarch64_plus_operand" "r,I,J")))] 3591 (match_operand:GPI 1 "aarch64_plus_operand" "r,I,J")))]
2968 "" 3592 ""
2969 "@ 3593 "@
2970 cmp\\t%<w>0, %<w>1 3594 cmp\\t%<w>0, %<w>1
2971 cmp\\t%<w>0, %1 3595 cmp\\t%<w>0, %1
3090 ;; subs x0, x0, #(CST & 0x000fff) 3714 ;; subs x0, x0, #(CST & 0x000fff)
3091 ;; cset x2, <ne, eq>. 3715 ;; cset x2, <ne, eq>.
3092 (define_insn_and_split "*compare_cstore<mode>_insn" 3716 (define_insn_and_split "*compare_cstore<mode>_insn"
3093 [(set (match_operand:GPI 0 "register_operand" "=r") 3717 [(set (match_operand:GPI 0 "register_operand" "=r")
3094 (EQL:GPI (match_operand:GPI 1 "register_operand" "r") 3718 (EQL:GPI (match_operand:GPI 1 "register_operand" "r")
3095 (match_operand:GPI 2 "aarch64_imm24" "n")))] 3719 (match_operand:GPI 2 "aarch64_imm24" "n")))
3720 (clobber (reg:CC CC_REGNUM))]
3096 "!aarch64_move_imm (INTVAL (operands[2]), <MODE>mode) 3721 "!aarch64_move_imm (INTVAL (operands[2]), <MODE>mode)
3097 && !aarch64_plus_operand (operands[2], <MODE>mode) 3722 && !aarch64_plus_operand (operands[2], <MODE>mode)
3098 && !reload_completed" 3723 && !reload_completed"
3099 "#" 3724 "#"
3100 "&& true" 3725 "&& true"
3326 (unspec:SI [(match_operand:SI 1 "register_operand" "r") 3951 (unspec:SI [(match_operand:SI 1 "register_operand" "r")
3327 (match_operand:<crc_mode> 2 "register_operand" "r")] 3952 (match_operand:<crc_mode> 2 "register_operand" "r")]
3328 CRC))] 3953 CRC))]
3329 "TARGET_CRC32" 3954 "TARGET_CRC32"
3330 { 3955 {
3331 if (GET_MODE_BITSIZE (GET_MODE (operands[2])) >= 64) 3956 if (GET_MODE_BITSIZE (<crc_mode>mode) >= 64)
3332 return "<crc_variant>\\t%w0, %w1, %x2"; 3957 return "<crc_variant>\\t%w0, %w1, %x2";
3333 else 3958 else
3334 return "<crc_variant>\\t%w0, %w1, %w2"; 3959 return "<crc_variant>\\t%w0, %w1, %w2";
3335 } 3960 }
3336 [(set_attr "type" "crc")] 3961 [(set_attr "type" "crc")]
3389 "" 4014 ""
3390 "csneg\\t%<w>0, %<w>3, %<w>2, %M1" 4015 "csneg\\t%<w>0, %<w>3, %<w>2, %M1"
3391 [(set_attr "type" "csel")] 4016 [(set_attr "type" "csel")]
3392 ) 4017 )
3393 4018
4019 ;; If X can be loaded by a single CNT[BHWD] instruction,
4020 ;;
4021 ;; A = UMAX (B, X)
4022 ;;
4023 ;; is equivalent to:
4024 ;;
4025 ;; TMP = UQDEC[BHWD] (B, X)
4026 ;; A = TMP + X
4027 ;;
4028 ;; Defining the pattern this way means that:
4029 ;;
4030 ;; A = UMAX (B, X) - X
4031 ;;
4032 ;; becomes:
4033 ;;
4034 ;; TMP1 = UQDEC[BHWD] (B, X)
4035 ;; TMP2 = TMP1 + X
4036 ;; A = TMP2 - X
4037 ;;
4038 ;; which combine can optimize to:
4039 ;;
4040 ;; A = UQDEC[BHWD] (B, X)
4041 ;;
4042 ;; We don't use match_operand predicates because the order of the operands
4043 ;; can vary: the CNT[BHWD] constant will come first if the other operand is
4044 ;; a simpler constant (such as a CONST_INT), otherwise it will come second.
4045 (define_expand "umax<mode>3"
4046 [(set (match_operand:GPI 0 "register_operand")
4047 (umax:GPI (match_operand:GPI 1 "")
4048 (match_operand:GPI 2 "")))]
4049 "TARGET_SVE"
4050 {
4051 if (aarch64_sve_cnt_immediate (operands[1], <MODE>mode))
4052 std::swap (operands[1], operands[2]);
4053 else if (!aarch64_sve_cnt_immediate (operands[2], <MODE>mode))
4054 FAIL;
4055 rtx temp = gen_reg_rtx (<MODE>mode);
4056 operands[1] = force_reg (<MODE>mode, operands[1]);
4057 emit_insn (gen_aarch64_uqdec<mode> (temp, operands[1], operands[2]));
4058 emit_insn (gen_add<mode>3 (operands[0], temp, operands[2]));
4059 DONE;
4060 }
4061 )
4062
4063 ;; Saturating unsigned subtraction of a CNT[BHWD] immediate.
4064 (define_insn "aarch64_uqdec<mode>"
4065 [(set (match_operand:GPI 0 "register_operand" "=r")
4066 (minus:GPI
4067 (umax:GPI (match_operand:GPI 1 "register_operand" "0")
4068 (match_operand:GPI 2 "aarch64_sve_cnt_immediate" "Usv"))
4069 (match_dup 2)))]
4070 "TARGET_SVE"
4071 {
4072 return aarch64_output_sve_cnt_immediate ("uqdec", "%<w>0", operands[2]);
4073 }
4074 )
4075
3394 ;; ------------------------------------------------------------------- 4076 ;; -------------------------------------------------------------------
3395 ;; Logical operations 4077 ;; Logical operations
3396 ;; ------------------------------------------------------------------- 4078 ;; -------------------------------------------------------------------
3397 4079
3398 4080
3423 "@ 4105 "@
3424 <logical>\\t%<w>0, %<w>1, %<w>2 4106 <logical>\\t%<w>0, %<w>1, %<w>2
3425 <logical>\\t%<w>0, %<w>1, %2 4107 <logical>\\t%<w>0, %<w>1, %2
3426 <logical>\\t%0.<Vbtype>, %1.<Vbtype>, %2.<Vbtype>" 4108 <logical>\\t%0.<Vbtype>, %1.<Vbtype>, %2.<Vbtype>"
3427 [(set_attr "type" "logic_reg,logic_imm,neon_logic") 4109 [(set_attr "type" "logic_reg,logic_imm,neon_logic")
3428 (set_attr "simd" "*,*,yes")] 4110 (set_attr "arch" "*,*,simd")]
3429 ) 4111 )
3430 4112
3431 ;; zero_extend version of above 4113 ;; zero_extend version of above
3432 (define_insn "*<optab>si3_uxtw" 4114 (define_insn "*<optab>si3_uxtw"
3433 [(set (match_operand:DI 0 "register_operand" "=r,rk") 4115 [(set (match_operand:DI 0 "register_operand" "=r,rk")
3557 "" 4239 ""
3558 "@ 4240 "@
3559 mvn\\t%<w>0, %<w>1 4241 mvn\\t%<w>0, %<w>1
3560 mvn\\t%0.8b, %1.8b" 4242 mvn\\t%0.8b, %1.8b"
3561 [(set_attr "type" "logic_reg,neon_logic") 4243 [(set_attr "type" "logic_reg,neon_logic")
3562 (set_attr "simd" "*,yes")] 4244 (set_attr "arch" "*,simd")]
3563 ) 4245 )
3564 4246
3565 (define_insn "*one_cmpl_<optab><mode>2" 4247 (define_insn "*one_cmpl_<optab><mode>2"
3566 [(set (match_operand:GPI 0 "register_operand" "=r") 4248 [(set (match_operand:GPI 0 "register_operand" "=r")
3567 (not:GPI (SHIFT:GPI (match_operand:GPI 1 "register_operand" "r") 4249 (not:GPI (SHIFT:GPI (match_operand:GPI 1 "register_operand" "r")
3580 "" 4262 ""
3581 "@ 4263 "@
3582 <NLOGICAL:nlogical>\\t%<w>0, %<w>2, %<w>1 4264 <NLOGICAL:nlogical>\\t%<w>0, %<w>2, %<w>1
3583 <NLOGICAL:nlogical>\\t%0.<Vbtype>, %2.<Vbtype>, %1.<Vbtype>" 4265 <NLOGICAL:nlogical>\\t%0.<Vbtype>, %2.<Vbtype>, %1.<Vbtype>"
3584 [(set_attr "type" "logic_reg,neon_logic") 4266 [(set_attr "type" "logic_reg,neon_logic")
3585 (set_attr "simd" "*,yes")] 4267 (set_attr "arch" "*,simd")]
3586 ) 4268 )
3587 4269
3588 (define_insn "*<NLOGICAL:optab>_one_cmplsidi3_ze" 4270 (define_insn "*<NLOGICAL:optab>_one_cmplsidi3_ze"
3589 [(set (match_operand:DI 0 "register_operand" "=r") 4271 [(set (match_operand:DI 0 "register_operand" "=r")
3590 (zero_extend:DI 4272 (zero_extend:DI
3620 (xor:GPI (match_operand:GPI 1 "register_operand" "w") 4302 (xor:GPI (match_operand:GPI 1 "register_operand" "w")
3621 (match_operand:GPI 2 "register_operand" "w"))) 4303 (match_operand:GPI 2 "register_operand" "w")))
3622 (set (match_dup 0) (not:GPI (match_dup 0)))] 4304 (set (match_dup 0) (not:GPI (match_dup 0)))]
3623 "" 4305 ""
3624 [(set_attr "type" "logic_reg,multiple") 4306 [(set_attr "type" "logic_reg,multiple")
3625 (set_attr "simd" "*,yes")] 4307 (set_attr "arch" "*,simd")]
3626 ) 4308 )
3627 4309
3628 (define_insn "*and_one_cmpl<mode>3_compare0" 4310 (define_insn "*and_one_cmpl<mode>3_compare0"
3629 [(set (reg:CC_NZ CC_REGNUM) 4311 [(set (reg:CC_NZ CC_REGNUM)
3630 (compare:CC_NZ 4312 (compare:CC_NZ
3956 ;; ------------------------------------------------------------------- 4638 ;; -------------------------------------------------------------------
3957 4639
3958 (define_expand "<optab><mode>3" 4640 (define_expand "<optab><mode>3"
3959 [(set (match_operand:GPI 0 "register_operand") 4641 [(set (match_operand:GPI 0 "register_operand")
3960 (ASHIFT:GPI (match_operand:GPI 1 "register_operand") 4642 (ASHIFT:GPI (match_operand:GPI 1 "register_operand")
3961 (match_operand:QI 2 "nonmemory_operand")))] 4643 (match_operand:QI 2 "aarch64_reg_or_imm")))]
3962 "" 4644 ""
3963 { 4645 {
3964 if (CONST_INT_P (operands[2])) 4646 if (CONST_INT_P (operands[2]))
3965 { 4647 {
3966 operands[2] = GEN_INT (INTVAL (operands[2]) 4648 operands[2] = GEN_INT (INTVAL (operands[2])
3992 ) 4674 )
3993 4675
3994 (define_expand "rotr<mode>3" 4676 (define_expand "rotr<mode>3"
3995 [(set (match_operand:GPI 0 "register_operand") 4677 [(set (match_operand:GPI 0 "register_operand")
3996 (rotatert:GPI (match_operand:GPI 1 "register_operand") 4678 (rotatert:GPI (match_operand:GPI 1 "register_operand")
3997 (match_operand:QI 2 "nonmemory_operand")))] 4679 (match_operand:QI 2 "aarch64_reg_or_imm")))]
3998 "" 4680 ""
3999 { 4681 {
4000 if (CONST_INT_P (operands[2])) 4682 if (CONST_INT_P (operands[2]))
4001 { 4683 {
4002 operands[2] = GEN_INT (INTVAL (operands[2]) 4684 operands[2] = GEN_INT (INTVAL (operands[2])
4012 ) 4694 )
4013 4695
4014 (define_expand "rotl<mode>3" 4696 (define_expand "rotl<mode>3"
4015 [(set (match_operand:GPI 0 "register_operand") 4697 [(set (match_operand:GPI 0 "register_operand")
4016 (rotatert:GPI (match_operand:GPI 1 "register_operand") 4698 (rotatert:GPI (match_operand:GPI 1 "register_operand")
4017 (match_operand:QI 2 "nonmemory_operand")))] 4699 (match_operand:QI 2 "aarch64_reg_or_imm")))]
4018 "" 4700 ""
4019 { 4701 {
4020 /* (SZ - cnt) % SZ == -cnt % SZ */ 4702 /* (SZ - cnt) % SZ == -cnt % SZ */
4021 if (CONST_INT_P (operands[2])) 4703 if (CONST_INT_P (operands[2]))
4022 { 4704 {
4052 "(~INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode) - 1)) == 0" 4734 "(~INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode) - 1)) == 0"
4053 "<shift>\t%<w>0, %<w>1, %<w>2" 4735 "<shift>\t%<w>0, %<w>1, %<w>2"
4054 [(set_attr "type" "shift_reg")] 4736 [(set_attr "type" "shift_reg")]
4055 ) 4737 )
4056 4738
4057 (define_insn_and_split "*aarch64_reg_<mode>3_neg_mask2" 4739 (define_insn_and_split "*aarch64_<optab>_reg_<mode>3_neg_mask2"
4058 [(set (match_operand:GPI 0 "register_operand" "=&r") 4740 [(set (match_operand:GPI 0 "register_operand" "=&r")
4059 (SHIFT:GPI 4741 (SHIFT:GPI
4060 (match_operand:GPI 1 "register_operand" "r") 4742 (match_operand:GPI 1 "register_operand" "r")
4061 (match_operator 4 "subreg_lowpart_operator" 4743 (match_operator 4 "subreg_lowpart_operator"
4062 [(neg:SI (and:SI (match_operand:SI 2 "register_operand" "r") 4744 [(neg:SI (and:SI (match_operand:SI 2 "register_operand" "r")
4065 "#" 4747 "#"
4066 "&& true" 4748 "&& true"
4067 [(const_int 0)] 4749 [(const_int 0)]
4068 { 4750 {
4069 rtx tmp = (can_create_pseudo_p () ? gen_reg_rtx (SImode) 4751 rtx tmp = (can_create_pseudo_p () ? gen_reg_rtx (SImode)
4070 : operands[0]); 4752 : lowpart_subreg (SImode, operands[0], <MODE>mode));
4071 emit_insn (gen_negsi2 (tmp, operands[2])); 4753 emit_insn (gen_negsi2 (tmp, operands[2]));
4072 4754
4073 rtx and_op = gen_rtx_AND (SImode, tmp, operands[3]); 4755 rtx and_op = gen_rtx_AND (SImode, tmp, operands[3]);
4074 rtx subreg_tmp = gen_rtx_SUBREG (GET_MODE (operands[4]), and_op, 4756 rtx subreg_tmp = gen_rtx_SUBREG (GET_MODE (operands[4]), and_op,
4075 SUBREG_BYTE (operands[4])); 4757 SUBREG_BYTE (operands[4]));
4076 emit_insn (gen_<optab><mode>3 (operands[0], operands[1], subreg_tmp)); 4758 emit_insn (gen_<optab><mode>3 (operands[0], operands[1], subreg_tmp));
4077 DONE; 4759 DONE;
4078 } 4760 }
4079 ) 4761 )
4080 4762
4081 (define_insn_and_split "*aarch64_reg_<mode>3_minus_mask" 4763 (define_insn_and_split "*aarch64_ashl_reg_<mode>3_minus_mask"
4082 [(set (match_operand:GPI 0 "register_operand" "=&r") 4764 [(set (match_operand:GPI 0 "register_operand" "=&r")
4083 (ashift:GPI 4765 (ashift:GPI
4084 (match_operand:GPI 1 "register_operand" "r") 4766 (match_operand:GPI 1 "register_operand" "r")
4085 (minus:QI (match_operand 2 "const_int_operand" "n") 4767 (minus:QI (match_operand 2 "const_int_operand" "n")
4086 (match_operator 5 "subreg_lowpart_operator" 4768 (match_operator 5 "subreg_lowpart_operator"
4110 [(set (match_operand:DI 0 "register_operand" "=r") 4792 [(set (match_operand:DI 0 "register_operand" "=r")
4111 (SHIFT:DI 4793 (SHIFT:DI
4112 (match_operand:DI 1 "register_operand" "r") 4794 (match_operand:DI 1 "register_operand" "r")
4113 (match_operator 4 "subreg_lowpart_operator" 4795 (match_operator 4 "subreg_lowpart_operator"
4114 [(and:SI (match_operand:SI 2 "register_operand" "r") 4796 [(and:SI (match_operand:SI 2 "register_operand" "r")
4115 (match_operand 3 "aarch64_shift_imm_di" "Usd"))])))] 4797 (match_operand 3 "const_int_operand" "n"))])))]
4116 "((~INTVAL (operands[3]) & (GET_MODE_BITSIZE (DImode)-1)) == 0)" 4798 "((~INTVAL (operands[3]) & (GET_MODE_BITSIZE (DImode) - 1)) == 0)"
4117 { 4799 {
4118 rtx xop[3]; 4800 rtx xop[3];
4119 xop[0] = operands[0]; 4801 xop[0] = operands[0];
4120 xop[1] = operands[1]; 4802 xop[1] = operands[1];
4121 xop[2] = gen_lowpart (GET_MODE (operands[4]), operands[2]); 4803 xop[2] = gen_lowpart (GET_MODE (operands[4]), operands[2]);
4123 return ""; 4805 return "";
4124 } 4806 }
4125 [(set_attr "type" "shift_reg")] 4807 [(set_attr "type" "shift_reg")]
4126 ) 4808 )
4127 4809
4128 (define_insn_and_split "*aarch64_reg_<optab>_minus<mode>3" 4810 (define_insn_and_split "*aarch64_<optab>_reg_minus<mode>3"
4129 [(set (match_operand:GPI 0 "register_operand" "=&r") 4811 [(set (match_operand:GPI 0 "register_operand" "=&r")
4130 (ASHIFT:GPI 4812 (ASHIFT:GPI
4131 (match_operand:GPI 1 "register_operand" "r") 4813 (match_operand:GPI 1 "register_operand" "r")
4132 (minus:QI (match_operand 2 "const_int_operand" "n") 4814 (minus:QI (match_operand 2 "const_int_operand" "n")
4133 (match_operand:QI 3 "register_operand" "r"))))] 4815 (match_operand:QI 3 "register_operand" "r"))))]
4164 "@ 4846 "@
4165 lsl\t%<w>0, %<w>1, %2 4847 lsl\t%<w>0, %<w>1, %2
4166 lsl\t%<w>0, %<w>1, %<w>2 4848 lsl\t%<w>0, %<w>1, %<w>2
4167 shl\t%<rtn>0<vas>, %<rtn>1<vas>, %2 4849 shl\t%<rtn>0<vas>, %<rtn>1<vas>, %2
4168 ushl\t%<rtn>0<vas>, %<rtn>1<vas>, %<rtn>2<vas>" 4850 ushl\t%<rtn>0<vas>, %<rtn>1<vas>, %<rtn>2<vas>"
4169 [(set_attr "simd" "no,no,yes,yes") 4851 [(set_attr "type" "bfx,shift_reg,neon_shift_imm<q>, neon_shift_reg<q>")
4170 (set_attr "type" "bfx,shift_reg,neon_shift_imm<q>, neon_shift_reg<q>")] 4852 (set_attr "arch" "*,*,simd,simd")]
4171 ) 4853 )
4172 4854
4173 ;; Logical right shift using SISD or Integer instruction 4855 ;; Logical right shift using SISD or Integer instruction
4174 (define_insn "*aarch64_lshr_sisd_or_int_<mode>3" 4856 (define_insn "*aarch64_lshr_sisd_or_int_<mode>3"
4175 [(set (match_operand:GPI 0 "register_operand" "=r,r,w,&w,&w") 4857 [(set (match_operand:GPI 0 "register_operand" "=r,r,w,&w,&w")
4176 (lshiftrt:GPI 4858 (lshiftrt:GPI
4177 (match_operand:GPI 1 "register_operand" "r,r,w,w,w") 4859 (match_operand:GPI 1 "register_operand" "r,r,w,w,w")
4178 (match_operand:QI 2 "aarch64_reg_or_shift_imm_<mode>" "Us<cmode>,r,Us<cmode>,w,0")))] 4860 (match_operand:QI 2 "aarch64_reg_or_shift_imm_<mode>"
4861 "Us<cmode>,r,Us<cmode_simd>,w,0")))]
4179 "" 4862 ""
4180 "@ 4863 "@
4181 lsr\t%<w>0, %<w>1, %2 4864 lsr\t%<w>0, %<w>1, %2
4182 lsr\t%<w>0, %<w>1, %<w>2 4865 lsr\t%<w>0, %<w>1, %<w>2
4183 ushr\t%<rtn>0<vas>, %<rtn>1<vas>, %2 4866 ushr\t%<rtn>0<vas>, %<rtn>1<vas>, %2
4184 # 4867 #
4185 #" 4868 #"
4186 [(set_attr "simd" "no,no,yes,yes,yes") 4869 [(set_attr "type" "bfx,shift_reg,neon_shift_imm<q>,neon_shift_reg<q>,neon_shift_reg<q>")
4187 (set_attr "type" "bfx,shift_reg,neon_shift_imm<q>,neon_shift_reg<q>,neon_shift_reg<q>")] 4870 (set_attr "arch" "*,*,simd,simd,simd")]
4188 ) 4871 )
4189 4872
4190 (define_split 4873 (define_split
4191 [(set (match_operand:DI 0 "aarch64_simd_register") 4874 [(set (match_operand:DI 0 "aarch64_simd_register")
4192 (lshiftrt:DI 4875 (lshiftrt:DI
4218 ) 4901 )
4219 4902
4220 ;; Arithmetic right shift using SISD or Integer instruction 4903 ;; Arithmetic right shift using SISD or Integer instruction
4221 (define_insn "*aarch64_ashr_sisd_or_int_<mode>3" 4904 (define_insn "*aarch64_ashr_sisd_or_int_<mode>3"
4222 [(set (match_operand:GPI 0 "register_operand" "=r,r,w,&w,&w") 4905 [(set (match_operand:GPI 0 "register_operand" "=r,r,w,&w,&w")
4223 (ashiftrt:GPI 4906 (ashiftrt:GPI
4224 (match_operand:GPI 1 "register_operand" "r,r,w,w,w") 4907 (match_operand:GPI 1 "register_operand" "r,r,w,w,w")
4225 (match_operand:QI 2 "aarch64_reg_or_shift_imm_di" "Us<cmode>,r,Us<cmode>,w,0")))] 4908 (match_operand:QI 2 "aarch64_reg_or_shift_imm_di"
4909 "Us<cmode>,r,Us<cmode_simd>,w,0")))]
4226 "" 4910 ""
4227 "@ 4911 "@
4228 asr\t%<w>0, %<w>1, %2 4912 asr\t%<w>0, %<w>1, %2
4229 asr\t%<w>0, %<w>1, %<w>2 4913 asr\t%<w>0, %<w>1, %<w>2
4230 sshr\t%<rtn>0<vas>, %<rtn>1<vas>, %2 4914 sshr\t%<rtn>0<vas>, %<rtn>1<vas>, %2
4231 # 4915 #
4232 #" 4916 #"
4233 [(set_attr "simd" "no,no,yes,yes,yes") 4917 [(set_attr "type" "bfx,shift_reg,neon_shift_imm<q>,neon_shift_reg<q>,neon_shift_reg<q>")
4234 (set_attr "type" "bfx,shift_reg,neon_shift_imm<q>,neon_shift_reg<q>,neon_shift_reg<q>")] 4918 (set_attr "arch" "*,*,simd,simd,simd")]
4235 ) 4919 )
4236 4920
4237 (define_split 4921 (define_split
4238 [(set (match_operand:DI 0 "aarch64_simd_register") 4922 [(set (match_operand:DI 0 "aarch64_simd_register")
4239 (ashiftrt:DI 4923 (ashiftrt:DI
4269 (unspec:DI [(match_operand:DI 1 "register_operand" "w") 4953 (unspec:DI [(match_operand:DI 1 "register_operand" "w")
4270 (match_operand:QI 2 "register_operand" "w")] 4954 (match_operand:QI 2 "register_operand" "w")]
4271 UNSPEC_SISD_USHL))] 4955 UNSPEC_SISD_USHL))]
4272 "TARGET_SIMD" 4956 "TARGET_SIMD"
4273 "ushl\t%d0, %d1, %d2" 4957 "ushl\t%d0, %d1, %d2"
4274 [(set_attr "simd" "yes") 4958 [(set_attr "type" "neon_shift_reg")]
4275 (set_attr "type" "neon_shift_reg")]
4276 ) 4959 )
4277 4960
4278 (define_insn "*aarch64_ushl_2s" 4961 (define_insn "*aarch64_ushl_2s"
4279 [(set (match_operand:SI 0 "register_operand" "=w") 4962 [(set (match_operand:SI 0 "register_operand" "=w")
4280 (unspec:SI [(match_operand:SI 1 "register_operand" "w") 4963 (unspec:SI [(match_operand:SI 1 "register_operand" "w")
4281 (match_operand:QI 2 "register_operand" "w")] 4964 (match_operand:QI 2 "register_operand" "w")]
4282 UNSPEC_USHL_2S))] 4965 UNSPEC_USHL_2S))]
4283 "TARGET_SIMD" 4966 "TARGET_SIMD"
4284 "ushl\t%0.2s, %1.2s, %2.2s" 4967 "ushl\t%0.2s, %1.2s, %2.2s"
4285 [(set_attr "simd" "yes") 4968 [(set_attr "type" "neon_shift_reg")]
4286 (set_attr "type" "neon_shift_reg")]
4287 ) 4969 )
4288 4970
4289 (define_insn "*aarch64_sisd_sshl" 4971 (define_insn "*aarch64_sisd_sshl"
4290 [(set (match_operand:DI 0 "register_operand" "=w") 4972 [(set (match_operand:DI 0 "register_operand" "=w")
4291 (unspec:DI [(match_operand:DI 1 "register_operand" "w") 4973 (unspec:DI [(match_operand:DI 1 "register_operand" "w")
4292 (match_operand:QI 2 "register_operand" "w")] 4974 (match_operand:QI 2 "register_operand" "w")]
4293 UNSPEC_SISD_SSHL))] 4975 UNSPEC_SISD_SSHL))]
4294 "TARGET_SIMD" 4976 "TARGET_SIMD"
4295 "sshl\t%d0, %d1, %d2" 4977 "sshl\t%d0, %d1, %d2"
4296 [(set_attr "simd" "yes") 4978 [(set_attr "type" "neon_shift_reg")]
4297 (set_attr "type" "neon_shift_reg")]
4298 ) 4979 )
4299 4980
4300 (define_insn "*aarch64_sshl_2s" 4981 (define_insn "*aarch64_sshl_2s"
4301 [(set (match_operand:SI 0 "register_operand" "=w") 4982 [(set (match_operand:SI 0 "register_operand" "=w")
4302 (unspec:SI [(match_operand:SI 1 "register_operand" "w") 4983 (unspec:SI [(match_operand:SI 1 "register_operand" "w")
4303 (match_operand:QI 2 "register_operand" "w")] 4984 (match_operand:QI 2 "register_operand" "w")]
4304 UNSPEC_SSHL_2S))] 4985 UNSPEC_SSHL_2S))]
4305 "TARGET_SIMD" 4986 "TARGET_SIMD"
4306 "sshl\t%0.2s, %1.2s, %2.2s" 4987 "sshl\t%0.2s, %1.2s, %2.2s"
4307 [(set_attr "simd" "yes") 4988 [(set_attr "type" "neon_shift_reg")]
4308 (set_attr "type" "neon_shift_reg")]
4309 ) 4989 )
4310 4990
4311 (define_insn "*aarch64_sisd_neg_qi" 4991 (define_insn "*aarch64_sisd_neg_qi"
4312 [(set (match_operand:QI 0 "register_operand" "=w") 4992 [(set (match_operand:QI 0 "register_operand" "=w")
4313 (unspec:QI [(match_operand:QI 1 "register_operand" "w")] 4993 (unspec:QI [(match_operand:QI 1 "register_operand" "w")]
4314 UNSPEC_SISD_NEG))] 4994 UNSPEC_SISD_NEG))]
4315 "TARGET_SIMD" 4995 "TARGET_SIMD"
4316 "neg\t%d0, %d1" 4996 "neg\t%d0, %d1"
4317 [(set_attr "simd" "yes") 4997 [(set_attr "type" "neon_neg")]
4318 (set_attr "type" "neon_neg")]
4319 ) 4998 )
4320 4999
4321 ;; Rotate right 5000 ;; Rotate right
4322 (define_insn "*ror<mode>3_insn" 5001 (define_insn "*ror<mode>3_insn"
4323 [(set (match_operand:GPI 0 "register_operand" "=r,r") 5002 [(set (match_operand:GPI 0 "register_operand" "=r,r")
4619 "aarch64_mask_and_shift_for_ubfiz_p (<MODE>mode, operands[3], operands[2])" 5298 "aarch64_mask_and_shift_for_ubfiz_p (<MODE>mode, operands[3], operands[2])"
4620 "ubfiz\\t%<w>0, %<w>1, %2, %P3" 5299 "ubfiz\\t%<w>0, %<w>1, %2, %P3"
4621 [(set_attr "type" "bfx")] 5300 [(set_attr "type" "bfx")]
4622 ) 5301 )
4623 5302
5303 ;; Match sbfiz pattern in a shift left + shift right operation.
5304
5305 (define_insn "*ashift<mode>_extv_bfiz"
5306 [(set (match_operand:GPI 0 "register_operand" "=r")
5307 (ashift:GPI (sign_extract:GPI (match_operand:GPI 1 "register_operand" "r")
5308 (match_operand 2 "aarch64_simd_shift_imm_offset_<mode>" "n")
5309 (const_int 0))
5310 (match_operand 3 "aarch64_simd_shift_imm_<mode>" "n")))]
5311 "IN_RANGE (INTVAL (operands[2]) + INTVAL (operands[3]),
5312 1, GET_MODE_BITSIZE (<MODE>mode) - 1)"
5313 "sbfiz\\t%<w>0, %<w>1, %3, %2"
5314 [(set_attr "type" "bfx")]
5315 )
5316
4624 ;; When the bit position and width of the equivalent extraction add up to 32 5317 ;; When the bit position and width of the equivalent extraction add up to 32
4625 ;; we can use a W-reg LSL instruction taking advantage of the implicit 5318 ;; we can use a W-reg LSL instruction taking advantage of the implicit
4626 ;; zero-extension of the X-reg. 5319 ;; zero-extension of the X-reg.
4627 (define_split 5320 (define_split
4628 [(set (match_operand:DI 0 "register_operand") 5321 [(set (match_operand:DI 0 "register_operand")
4651 [(set (match_operand:HI 0 "register_operand" "=r") 5344 [(set (match_operand:HI 0 "register_operand" "=r")
4652 (bswap:HI (match_operand:HI 1 "register_operand" "r")))] 5345 (bswap:HI (match_operand:HI 1 "register_operand" "r")))]
4653 "" 5346 ""
4654 "rev16\\t%w0, %w1" 5347 "rev16\\t%w0, %w1"
4655 [(set_attr "type" "rev")] 5348 [(set_attr "type" "rev")]
5349 )
5350
5351 (define_insn "*aarch64_bfxil<mode>"
5352 [(set (match_operand:GPI 0 "register_operand" "=r,r")
5353 (ior:GPI (and:GPI (match_operand:GPI 1 "register_operand" "r,0")
5354 (match_operand:GPI 3 "const_int_operand" "n, Ulc"))
5355 (and:GPI (match_operand:GPI 2 "register_operand" "0,r")
5356 (match_operand:GPI 4 "const_int_operand" "Ulc, n"))))]
5357 "(INTVAL (operands[3]) == ~INTVAL (operands[4]))
5358 && (aarch64_high_bits_all_ones_p (INTVAL (operands[3]))
5359 || aarch64_high_bits_all_ones_p (INTVAL (operands[4])))"
5360 {
5361 switch (which_alternative)
5362 {
5363 case 0:
5364 operands[3] = GEN_INT (ctz_hwi (~INTVAL (operands[3])));
5365 return "bfxil\\t%<w>0, %<w>1, 0, %3";
5366 case 1:
5367 operands[3] = GEN_INT (ctz_hwi (~INTVAL (operands[4])));
5368 return "bfxil\\t%<w>0, %<w>2, 0, %3";
5369 default:
5370 gcc_unreachable ();
5371 }
5372 }
5373 [(set_attr "type" "bfm")]
5374 )
5375
5376 ; Zero-extended version of above (aarch64_bfxil)
5377 (define_insn "*aarch64_bfxilsi_uxtw"
5378 [(set (match_operand:DI 0 "register_operand" "=r,r")
5379 (zero_extend:DI (ior:SI (and:SI (match_operand:SI 1 "register_operand"
5380 "r,0")
5381 (match_operand:SI 3 "const_int_operand" "n, Ulc"))
5382 (and:SI (match_operand:SI 2 "register_operand" "0,r")
5383 (match_operand:SI 4 "const_int_operand" "Ulc, n")))))]
5384 "(INTVAL (operands[3]) == ~INTVAL (operands[4]))
5385 && (aarch64_high_bits_all_ones_p (INTVAL (operands[3]))
5386 || aarch64_high_bits_all_ones_p (INTVAL (operands[4])))"
5387 {
5388 switch (which_alternative)
5389 {
5390 case 0:
5391 operands[3] = GEN_INT (ctz_hwi (~INTVAL (operands[3])));
5392 return "bfxil\\t%0, %1, 0, %3";
5393 case 1:
5394 operands[3] = GEN_INT (ctz_hwi (~INTVAL (operands[4])));
5395 return "bfxil\\t%0, %2, 0, %3";
5396 default:
5397 gcc_unreachable ();
5398 }
5399 }
5400 [(set_attr "type" "bfm")]
4656 ) 5401 )
4657 5402
4658 ;; There are no canonicalisation rules for the position of the lshiftrt, ashift 5403 ;; There are no canonicalisation rules for the position of the lshiftrt, ashift
4659 ;; operations within an IOR/AND RTX, therefore we have two patterns matching 5404 ;; operations within an IOR/AND RTX, therefore we have two patterns matching
4660 ;; each valid permutation. 5405 ;; each valid permutation.
4741 return ""; 5486 return "";
4742 } 5487 }
4743 [(set_attr "type" "f_cvtf2i")] 5488 [(set_attr "type" "f_cvtf2i")]
4744 ) 5489 )
4745 5490
4746 ;; fma - no throw 5491 ;; fma - expand fma into patterns with the accumulator operand first since
4747 5492 ;; reusing the accumulator results in better register allocation.
4748 (define_insn "fma<mode>4" 5493 ;; The register allocator considers copy preferences in operand order,
5494 ;; so this prefers fmadd s0, s1, s2, s0 over fmadd s1, s1, s2, s0.
5495
5496 (define_expand "fma<mode>4"
5497 [(set (match_operand:GPF_F16 0 "register_operand")
5498 (fma:GPF_F16 (match_operand:GPF_F16 1 "register_operand")
5499 (match_operand:GPF_F16 2 "register_operand")
5500 (match_operand:GPF_F16 3 "register_operand")))]
5501 "TARGET_FLOAT"
5502 )
5503
5504 (define_insn "*aarch64_fma<mode>4"
4749 [(set (match_operand:GPF_F16 0 "register_operand" "=w") 5505 [(set (match_operand:GPF_F16 0 "register_operand" "=w")
4750 (fma:GPF_F16 (match_operand:GPF_F16 1 "register_operand" "w") 5506 (fma:GPF_F16 (match_operand:GPF_F16 2 "register_operand" "w")
4751 (match_operand:GPF_F16 2 "register_operand" "w") 5507 (match_operand:GPF_F16 3 "register_operand" "w")
4752 (match_operand:GPF_F16 3 "register_operand" "w")))] 5508 (match_operand:GPF_F16 1 "register_operand" "w")))]
4753 "TARGET_FLOAT" 5509 "TARGET_FLOAT"
4754 "fmadd\\t%<s>0, %<s>1, %<s>2, %<s>3" 5510 "fmadd\\t%<s>0, %<s>2, %<s>3, %<s>1"
4755 [(set_attr "type" "fmac<stype>")] 5511 [(set_attr "type" "fmac<stype>")]
4756 ) 5512 )
4757 5513
4758 (define_insn "fnma<mode>4" 5514 (define_expand "fnma<mode>4"
5515 [(set (match_operand:GPF_F16 0 "register_operand")
5516 (fma:GPF_F16
5517 (neg:GPF_F16 (match_operand:GPF_F16 1 "register_operand"))
5518 (match_operand:GPF_F16 2 "register_operand")
5519 (match_operand:GPF_F16 3 "register_operand")))]
5520 "TARGET_FLOAT"
5521 )
5522
5523 (define_insn "*aarch64_fnma<mode>4"
4759 [(set (match_operand:GPF_F16 0 "register_operand" "=w") 5524 [(set (match_operand:GPF_F16 0 "register_operand" "=w")
4760 (fma:GPF_F16 5525 (fma:GPF_F16
4761 (neg:GPF_F16 (match_operand:GPF_F16 1 "register_operand" "w")) 5526 (neg:GPF_F16 (match_operand:GPF_F16 2 "register_operand" "w"))
4762 (match_operand:GPF_F16 2 "register_operand" "w") 5527 (match_operand:GPF_F16 3 "register_operand" "w")
4763 (match_operand:GPF_F16 3 "register_operand" "w")))] 5528 (match_operand:GPF_F16 1 "register_operand" "w")))]
4764 "TARGET_FLOAT" 5529 "TARGET_FLOAT"
4765 "fmsub\\t%<s>0, %<s>1, %<s>2, %<s>3" 5530 "fmsub\\t%<s>0, %<s>2, %<s>3, %<s>1"
4766 [(set_attr "type" "fmac<stype>")] 5531 [(set_attr "type" "fmac<stype>")]
4767 ) 5532 )
4768 5533
4769 (define_insn "fms<mode>4" 5534
5535 (define_expand "fms<mode>4"
5536 [(set (match_operand:GPF 0 "register_operand")
5537 (fma:GPF (match_operand:GPF 1 "register_operand")
5538 (match_operand:GPF 2 "register_operand")
5539 (neg:GPF (match_operand:GPF 3 "register_operand"))))]
5540 "TARGET_FLOAT"
5541 )
5542
5543 (define_insn "*aarch64_fms<mode>4"
4770 [(set (match_operand:GPF 0 "register_operand" "=w") 5544 [(set (match_operand:GPF 0 "register_operand" "=w")
4771 (fma:GPF (match_operand:GPF 1 "register_operand" "w") 5545 (fma:GPF (match_operand:GPF 2 "register_operand" "w")
4772 (match_operand:GPF 2 "register_operand" "w") 5546 (match_operand:GPF 3 "register_operand" "w")
4773 (neg:GPF (match_operand:GPF 3 "register_operand" "w"))))] 5547 (neg:GPF (match_operand:GPF 1 "register_operand" "w"))))]
4774 "TARGET_FLOAT" 5548 "TARGET_FLOAT"
4775 "fnmsub\\t%<s>0, %<s>1, %<s>2, %<s>3" 5549 "fnmsub\\t%<s>0, %<s>2, %<s>3, %<s>1"
4776 [(set_attr "type" "fmac<s>")] 5550 [(set_attr "type" "fmac<s>")]
4777 ) 5551 )
4778 5552
4779 (define_insn "fnms<mode>4" 5553 (define_expand "fnms<mode>4"
5554 [(set (match_operand:GPF 0 "register_operand")
5555 (fma:GPF (neg:GPF (match_operand:GPF 1 "register_operand"))
5556 (match_operand:GPF 2 "register_operand")
5557 (neg:GPF (match_operand:GPF 3 "register_operand"))))]
5558 "TARGET_FLOAT"
5559 )
5560
5561 (define_insn "*aarch64_fnms<mode>4"
4780 [(set (match_operand:GPF 0 "register_operand" "=w") 5562 [(set (match_operand:GPF 0 "register_operand" "=w")
4781 (fma:GPF (neg:GPF (match_operand:GPF 1 "register_operand" "w")) 5563 (fma:GPF (neg:GPF (match_operand:GPF 2 "register_operand" "w"))
4782 (match_operand:GPF 2 "register_operand" "w") 5564 (match_operand:GPF 3 "register_operand" "w")
4783 (neg:GPF (match_operand:GPF 3 "register_operand" "w"))))] 5565 (neg:GPF (match_operand:GPF 1 "register_operand" "w"))))]
4784 "TARGET_FLOAT" 5566 "TARGET_FLOAT"
4785 "fnmadd\\t%<s>0, %<s>1, %<s>2, %<s>3" 5567 "fnmadd\\t%<s>0, %<s>2, %<s>3, %<s>1"
4786 [(set_attr "type" "fmac<s>")] 5568 [(set_attr "type" "fmac<s>")]
4787 ) 5569 )
4788 5570
4789 ;; If signed zeros are ignored, -(a * b + c) = -a * b - c. 5571 ;; If signed zeros are ignored, -(a * b + c) = -a * b - c.
4790 (define_insn "*fnmadd<mode>4" 5572 (define_insn "*aarch64_fnmadd<mode>4"
4791 [(set (match_operand:GPF 0 "register_operand" "=w") 5573 [(set (match_operand:GPF 0 "register_operand" "=w")
4792 (neg:GPF (fma:GPF (match_operand:GPF 1 "register_operand" "w") 5574 (neg:GPF (fma:GPF (match_operand:GPF 2 "register_operand" "w")
4793 (match_operand:GPF 2 "register_operand" "w") 5575 (match_operand:GPF 3 "register_operand" "w")
4794 (match_operand:GPF 3 "register_operand" "w"))))] 5576 (match_operand:GPF 1 "register_operand" "w"))))]
4795 "!HONOR_SIGNED_ZEROS (<MODE>mode) && TARGET_FLOAT" 5577 "!HONOR_SIGNED_ZEROS (<MODE>mode) && TARGET_FLOAT"
4796 "fnmadd\\t%<s>0, %<s>1, %<s>2, %<s>3" 5578 "fnmadd\\t%<s>0, %<s>2, %<s>3, %<s>1"
4797 [(set_attr "type" "fmac<s>")] 5579 [(set_attr "type" "fmac<s>")]
4798 ) 5580 )
4799 5581
4800 ;; ------------------------------------------------------------------- 5582 ;; -------------------------------------------------------------------
4801 ;; Floating-point conversions 5583 ;; Floating-point conversions
4847 "TARGET_FLOAT" 5629 "TARGET_FLOAT"
4848 "fcvt\\t%h0, %d1" 5630 "fcvt\\t%h0, %d1"
4849 [(set_attr "type" "f_cvt")] 5631 [(set_attr "type" "f_cvt")]
4850 ) 5632 )
4851 5633
4852 (define_insn "<optab>_trunc<GPF_F16:mode><GPI:mode>2" 5634 ;; Convert SF -> SI or DF -> DI while preferring w = w register constraints
5635 ;; and making r = w more expensive
5636
5637 (define_insn "<optab>_trunc<fcvt_target><GPI:mode>2"
5638 [(set (match_operand:GPI 0 "register_operand" "=w,?r")
5639 (FIXUORS:GPI (match_operand:<FCVT_TARGET> 1 "register_operand" "w,w")))]
5640 "TARGET_FLOAT"
5641 "@
5642 fcvtz<su>\t%<s>0, %<s>1
5643 fcvtz<su>\t%<w>0, %<s>1"
5644 [(set_attr "type" "neon_fp_to_int_s,f_cvtf2i")]
5645 )
5646
5647 ;; Convert HF -> SI or DI
5648
5649 (define_insn "<optab>_trunchf<GPI:mode>2"
4853 [(set (match_operand:GPI 0 "register_operand" "=r") 5650 [(set (match_operand:GPI 0 "register_operand" "=r")
4854 (FIXUORS:GPI (match_operand:GPF_F16 1 "register_operand" "w")))] 5651 (FIXUORS:GPI (match_operand:HF 1 "register_operand" "w")))]
5652 "TARGET_FP_F16INST"
5653 "fcvtz<su>\t%<w>0, %h1"
5654 [(set_attr "type" "f_cvtf2i")]
5655 )
5656
5657 ;; Convert DF -> SI or SF -> DI which can only be accomplished with
5658 ;; input in a fp register and output in a integer register
5659
5660 (define_insn "<optab>_trunc<fcvt_change_mode><GPI:mode>2"
5661 [(set (match_operand:GPI 0 "register_operand" "=r")
5662 (FIXUORS:GPI (match_operand:<FCVT_CHANGE_MODE> 1 "register_operand" "w")))]
4855 "TARGET_FLOAT" 5663 "TARGET_FLOAT"
4856 "fcvtz<su>\t%<GPI:w>0, %<GPF_F16:s>1" 5664 "fcvtz<su>\t%<w>0, %<fpw>1"
5665 [(set_attr "type" "f_cvtf2i")]
5666 )
5667
5668 (define_insn "*fix_to_zero_extend<mode>di2"
5669 [(set (match_operand:DI 0 "register_operand" "=r")
5670 (zero_extend:DI
5671 (unsigned_fix:SI
5672 (match_operand:GPF 1 "register_operand" "w"))))]
5673 "TARGET_FLOAT"
5674 "fcvtzu\t%w0, %<s>1"
4857 [(set_attr "type" "f_cvtf2i")] 5675 [(set_attr "type" "f_cvtf2i")]
4858 ) 5676 )
4859 5677
4860 (define_insn "<optab><fcvt_target><GPF:mode>2" 5678 (define_insn "<optab><fcvt_target><GPF:mode>2"
4861 [(set (match_operand:GPF 0 "register_operand" "=w,w") 5679 [(set (match_operand:GPF 0 "register_operand" "=w,w")
4862 (FLOATUORS:GPF (match_operand:<FCVT_TARGET> 1 "register_operand" "w,r")))] 5680 (FLOATUORS:GPF (match_operand:<FCVT_TARGET> 1 "register_operand" "w,?r")))]
4863 "TARGET_FLOAT" 5681 "TARGET_FLOAT"
4864 "@ 5682 "@
4865 <su_optab>cvtf\t%<GPF:s>0, %<s>1 5683 <su_optab>cvtf\t%<GPF:s>0, %<s>1
4866 <su_optab>cvtf\t%<GPF:s>0, %<w1>1" 5684 <su_optab>cvtf\t%<GPF:s>0, %<w1>1"
4867 [(set_attr "simd" "yes,no") 5685 [(set_attr "type" "neon_int_to_fp_<Vetype>,f_cvti2f")
4868 (set_attr "fp" "no,yes") 5686 (set_attr "arch" "simd,fp")]
4869 (set_attr "type" "neon_int_to_fp_<Vetype>,f_cvti2f")]
4870 ) 5687 )
4871 5688
4872 (define_insn "<optab><fcvt_iesize><GPF:mode>2" 5689 (define_insn "<optab><fcvt_iesize><GPF:mode>2"
4873 [(set (match_operand:GPF 0 "register_operand" "=w") 5690 [(set (match_operand:GPF 0 "register_operand" "=w")
4874 (FLOATUORS:GPF (match_operand:<FCVT_IESIZE> 1 "register_operand" "r")))] 5691 (FLOATUORS:GPF (match_operand:<FCVT_IESIZE> 1 "register_operand" "r")))]
4949 "" 5766 ""
4950 "@ 5767 "@
4951 <FCVT_F2FIXED:fcvt_fixed_insn>\t%<GPF:w1>0, %<GPF:s>1, #%2 5768 <FCVT_F2FIXED:fcvt_fixed_insn>\t%<GPF:w1>0, %<GPF:s>1, #%2
4952 <FCVT_F2FIXED:fcvt_fixed_insn>\t%<GPF:s>0, %<GPF:s>1, #%2" 5769 <FCVT_F2FIXED:fcvt_fixed_insn>\t%<GPF:s>0, %<GPF:s>1, #%2"
4953 [(set_attr "type" "f_cvtf2i, neon_fp_to_int_<GPF:Vetype>") 5770 [(set_attr "type" "f_cvtf2i, neon_fp_to_int_<GPF:Vetype>")
4954 (set_attr "fp" "yes, *") 5771 (set_attr "arch" "fp,simd")]
4955 (set_attr "simd" "*, yes")]
4956 ) 5772 )
4957 5773
4958 (define_insn "<FCVT_FIXED2F:fcvt_fixed_insn><GPI:mode>3" 5774 (define_insn "<FCVT_FIXED2F:fcvt_fixed_insn><GPI:mode>3"
4959 [(set (match_operand:<GPI:FCVT_TARGET> 0 "register_operand" "=w, w") 5775 [(set (match_operand:<GPI:FCVT_TARGET> 0 "register_operand" "=w, w")
4960 (unspec:<GPI:FCVT_TARGET> [(match_operand:GPI 1 "register_operand" "r, w") 5776 (unspec:<GPI:FCVT_TARGET> [(match_operand:GPI 1 "register_operand" "r, w")
4963 "" 5779 ""
4964 "@ 5780 "@
4965 <FCVT_FIXED2F:fcvt_fixed_insn>\t%<GPI:v>0, %<GPI:w>1, #%2 5781 <FCVT_FIXED2F:fcvt_fixed_insn>\t%<GPI:v>0, %<GPI:w>1, #%2
4966 <FCVT_FIXED2F:fcvt_fixed_insn>\t%<GPI:v>0, %<GPI:v>1, #%2" 5782 <FCVT_FIXED2F:fcvt_fixed_insn>\t%<GPI:v>0, %<GPI:v>1, #%2"
4967 [(set_attr "type" "f_cvti2f, neon_int_to_fp_<GPI:Vetype>") 5783 [(set_attr "type" "f_cvti2f, neon_int_to_fp_<GPI:Vetype>")
4968 (set_attr "fp" "yes, *") 5784 (set_attr "arch" "fp,simd")]
4969 (set_attr "simd" "*, yes")]
4970 ) 5785 )
4971 5786
4972 (define_insn "<FCVT_F2FIXED:fcvt_fixed_insn>hf<mode>3" 5787 (define_insn "<FCVT_F2FIXED:fcvt_fixed_insn>hf<mode>3"
4973 [(set (match_operand:GPI 0 "register_operand" "=r") 5788 [(set (match_operand:GPI 0 "register_operand" "=r")
4974 (unspec:GPI [(match_operand:HF 1 "register_operand" "w") 5789 (unspec:GPI [(match_operand:HF 1 "register_operand" "w")
5065 5880
5066 (define_expand "div<mode>3" 5881 (define_expand "div<mode>3"
5067 [(set (match_operand:GPF_F16 0 "register_operand") 5882 [(set (match_operand:GPF_F16 0 "register_operand")
5068 (div:GPF_F16 (match_operand:GPF_F16 1 "general_operand") 5883 (div:GPF_F16 (match_operand:GPF_F16 1 "general_operand")
5069 (match_operand:GPF_F16 2 "register_operand")))] 5884 (match_operand:GPF_F16 2 "register_operand")))]
5070 "TARGET_SIMD" 5885 "TARGET_FLOAT"
5071 { 5886 {
5072 if (aarch64_emit_approx_div (operands[0], operands[1], operands[2])) 5887 if (aarch64_emit_approx_div (operands[0], operands[1], operands[2]))
5073 DONE; 5888 DONE;
5074 5889
5075 operands[1] = force_reg (<MODE>mode, operands[1]); 5890 operands[1] = force_reg (<MODE>mode, operands[1]);
5253 ;; ------------------------------------------------------------------- 6068 ;; -------------------------------------------------------------------
5254 ;; Reload support 6069 ;; Reload support
5255 ;; ------------------------------------------------------------------- 6070 ;; -------------------------------------------------------------------
5256 ;; Reload Scalar Floating point modes from constant pool. 6071 ;; Reload Scalar Floating point modes from constant pool.
5257 ;; The AArch64 port doesn't have __int128 constant move support. 6072 ;; The AArch64 port doesn't have __int128 constant move support.
5258 (define_expand "aarch64_reload_movcp<GPF_TF:mode><P:mode>" 6073 (define_expand "@aarch64_reload_movcp<GPF_TF:mode><P:mode>"
5259 [(set (match_operand:GPF_TF 0 "register_operand" "=w") 6074 [(set (match_operand:GPF_TF 0 "register_operand" "=w")
5260 (mem:GPF_TF (match_operand 1 "aarch64_constant_pool_symref" "S"))) 6075 (mem:GPF_TF (match_operand 1 "aarch64_constant_pool_symref" "S")))
5261 (clobber (match_operand:P 2 "register_operand" "=&r"))] 6076 (clobber (match_operand:P 2 "register_operand" "=&r"))]
5262 "TARGET_FLOAT" 6077 "TARGET_FLOAT"
5263 { 6078 {
5266 DONE; 6081 DONE;
5267 } 6082 }
5268 ) 6083 )
5269 6084
5270 ;; Reload Vector modes from constant pool. 6085 ;; Reload Vector modes from constant pool.
5271 (define_expand "aarch64_reload_movcp<VALL:mode><P:mode>" 6086 (define_expand "@aarch64_reload_movcp<VALL:mode><P:mode>"
5272 [(set (match_operand:VALL 0 "register_operand" "=w") 6087 [(set (match_operand:VALL 0 "register_operand" "=w")
5273 (mem:VALL (match_operand 1 "aarch64_constant_pool_symref" "S"))) 6088 (mem:VALL (match_operand 1 "aarch64_constant_pool_symref" "S")))
5274 (clobber (match_operand:P 2 "register_operand" "=&r"))] 6089 (clobber (match_operand:P 2 "register_operand" "=&r"))]
5275 "TARGET_FLOAT" 6090 "TARGET_FLOAT"
5276 { 6091 {
5278 emit_move_insn (operands[0], gen_rtx_MEM (<VALL:MODE>mode, operands[2])); 6093 emit_move_insn (operands[0], gen_rtx_MEM (<VALL:MODE>mode, operands[2]));
5279 DONE; 6094 DONE;
5280 } 6095 }
5281 ) 6096 )
5282 6097
5283 (define_expand "aarch64_reload_mov<mode>" 6098 (define_expand "@aarch64_reload_mov<mode>"
5284 [(set (match_operand:TX 0 "register_operand" "=w") 6099 [(set (match_operand:TX 0 "register_operand" "=w")
5285 (match_operand:TX 1 "register_operand" "w")) 6100 (match_operand:TX 1 "register_operand" "w"))
5286 (clobber (match_operand:DI 2 "register_operand" "=&r")) 6101 (clobber (match_operand:DI 2 "register_operand" "=&r"))
5287 ] 6102 ]
5288 "TARGET_FLOAT" 6103 "TARGET_FLOAT"
5298 6113
5299 ;; The following secondary reload helpers patterns are invoked 6114 ;; The following secondary reload helpers patterns are invoked
5300 ;; after or during reload as we don't want these patterns to start 6115 ;; after or during reload as we don't want these patterns to start
5301 ;; kicking in during the combiner. 6116 ;; kicking in during the combiner.
5302 6117
5303 (define_insn "aarch64_movdi_<mode>low" 6118 (define_insn "@aarch64_movdi_<mode>low"
5304 [(set (match_operand:DI 0 "register_operand" "=r") 6119 [(set (match_operand:DI 0 "register_operand" "=r")
5305 (zero_extract:DI (match_operand:TX 1 "register_operand" "w") 6120 (zero_extract:DI (match_operand:TX 1 "register_operand" "w")
5306 (const_int 64) (const_int 0)))] 6121 (const_int 64) (const_int 0)))]
5307 "TARGET_FLOAT && (reload_completed || reload_in_progress)" 6122 "TARGET_FLOAT && (reload_completed || reload_in_progress)"
5308 "fmov\\t%x0, %d1" 6123 "fmov\\t%x0, %d1"
5309 [(set_attr "type" "f_mrc") 6124 [(set_attr "type" "f_mrc")
5310 (set_attr "length" "4") 6125 (set_attr "length" "4")
5311 ]) 6126 ])
5312 6127
5313 (define_insn "aarch64_movdi_<mode>high" 6128 (define_insn "@aarch64_movdi_<mode>high"
5314 [(set (match_operand:DI 0 "register_operand" "=r") 6129 [(set (match_operand:DI 0 "register_operand" "=r")
5315 (zero_extract:DI (match_operand:TX 1 "register_operand" "w") 6130 (zero_extract:DI (match_operand:TX 1 "register_operand" "w")
5316 (const_int 64) (const_int 64)))] 6131 (const_int 64) (const_int 64)))]
5317 "TARGET_FLOAT && (reload_completed || reload_in_progress)" 6132 "TARGET_FLOAT && (reload_completed || reload_in_progress)"
5318 "fmov\\t%x0, %1.d[1]" 6133 "fmov\\t%x0, %1.d[1]"
5319 [(set_attr "type" "f_mrc") 6134 [(set_attr "type" "f_mrc")
5320 (set_attr "length" "4") 6135 (set_attr "length" "4")
5321 ]) 6136 ])
5322 6137
5323 (define_insn "aarch64_mov<mode>high_di" 6138 (define_insn "@aarch64_mov<mode>high_di"
5324 [(set (zero_extract:TX (match_operand:TX 0 "register_operand" "+w") 6139 [(set (zero_extract:TX (match_operand:TX 0 "register_operand" "+w")
5325 (const_int 64) (const_int 64)) 6140 (const_int 64) (const_int 64))
5326 (zero_extend:TX (match_operand:DI 1 "register_operand" "r")))] 6141 (zero_extend:TX (match_operand:DI 1 "register_operand" "r")))]
5327 "TARGET_FLOAT && (reload_completed || reload_in_progress)" 6142 "TARGET_FLOAT && (reload_completed || reload_in_progress)"
5328 "fmov\\t%0.d[1], %x1" 6143 "fmov\\t%0.d[1], %x1"
5329 [(set_attr "type" "f_mcr") 6144 [(set_attr "type" "f_mcr")
5330 (set_attr "length" "4") 6145 (set_attr "length" "4")
5331 ]) 6146 ])
5332 6147
5333 (define_insn "aarch64_mov<mode>low_di" 6148 (define_insn "@aarch64_mov<mode>low_di"
5334 [(set (match_operand:TX 0 "register_operand" "=w") 6149 [(set (match_operand:TX 0 "register_operand" "=w")
5335 (zero_extend:TX (match_operand:DI 1 "register_operand" "r")))] 6150 (zero_extend:TX (match_operand:DI 1 "register_operand" "r")))]
5336 "TARGET_FLOAT && (reload_completed || reload_in_progress)" 6151 "TARGET_FLOAT && (reload_completed || reload_in_progress)"
5337 "fmov\\t%d0, %x1" 6152 "fmov\\t%d0, %x1"
5338 [(set_attr "type" "f_mcr") 6153 [(set_attr "type" "f_mcr")
5373 (define_insn "add_losym_<mode>" 6188 (define_insn "add_losym_<mode>"
5374 [(set (match_operand:P 0 "register_operand" "=r") 6189 [(set (match_operand:P 0 "register_operand" "=r")
5375 (lo_sum:P (match_operand:P 1 "register_operand" "r") 6190 (lo_sum:P (match_operand:P 1 "register_operand" "r")
5376 (match_operand 2 "aarch64_valid_symref" "S")))] 6191 (match_operand 2 "aarch64_valid_symref" "S")))]
5377 "" 6192 ""
5378 "add\\t%<w>0, %<w>1, :lo12:%a2" 6193 "add\\t%<w>0, %<w>1, :lo12:%c2"
5379 [(set_attr "type" "alu_imm")] 6194 [(set_attr "type" "alu_imm")]
5380 ) 6195 )
5381 6196
5382 (define_insn "ldr_got_small_<mode>" 6197 (define_insn "ldr_got_small_<mode>"
5383 [(set (match_operand:PTR 0 "register_operand" "=r") 6198 [(set (match_operand:PTR 0 "register_operand" "=r")
5384 (unspec:PTR [(mem:PTR (lo_sum:PTR 6199 (unspec:PTR [(mem:PTR (lo_sum:PTR
5385 (match_operand:PTR 1 "register_operand" "r") 6200 (match_operand:PTR 1 "register_operand" "r")
5386 (match_operand:PTR 2 "aarch64_valid_symref" "S")))] 6201 (match_operand:PTR 2 "aarch64_valid_symref" "S")))]
5387 UNSPEC_GOTSMALLPIC))] 6202 UNSPEC_GOTSMALLPIC))]
5388 "" 6203 ""
5389 "ldr\\t%<w>0, [%1, #:got_lo12:%a2]" 6204 "ldr\\t%<w>0, [%1, #:got_lo12:%c2]"
5390 [(set_attr "type" "load_<ldst_sz>")] 6205 [(set_attr "type" "load_<ldst_sz>")]
5391 ) 6206 )
5392 6207
5393 (define_insn "ldr_got_small_sidi" 6208 (define_insn "ldr_got_small_sidi"
5394 [(set (match_operand:DI 0 "register_operand" "=r") 6209 [(set (match_operand:DI 0 "register_operand" "=r")
5396 (unspec:SI [(mem:SI (lo_sum:DI 6211 (unspec:SI [(mem:SI (lo_sum:DI
5397 (match_operand:DI 1 "register_operand" "r") 6212 (match_operand:DI 1 "register_operand" "r")
5398 (match_operand:DI 2 "aarch64_valid_symref" "S")))] 6213 (match_operand:DI 2 "aarch64_valid_symref" "S")))]
5399 UNSPEC_GOTSMALLPIC)))] 6214 UNSPEC_GOTSMALLPIC)))]
5400 "TARGET_ILP32" 6215 "TARGET_ILP32"
5401 "ldr\\t%w0, [%1, #:got_lo12:%a2]" 6216 "ldr\\t%w0, [%1, #:got_lo12:%c2]"
5402 [(set_attr "type" "load_4")] 6217 [(set_attr "type" "load_4")]
5403 ) 6218 )
5404 6219
5405 (define_insn "ldr_got_small_28k_<mode>" 6220 (define_insn "ldr_got_small_28k_<mode>"
5406 [(set (match_operand:PTR 0 "register_operand" "=r") 6221 [(set (match_operand:PTR 0 "register_operand" "=r")
5407 (unspec:PTR [(mem:PTR (lo_sum:PTR 6222 (unspec:PTR [(mem:PTR (lo_sum:PTR
5408 (match_operand:PTR 1 "register_operand" "r") 6223 (match_operand:PTR 1 "register_operand" "r")
5409 (match_operand:PTR 2 "aarch64_valid_symref" "S")))] 6224 (match_operand:PTR 2 "aarch64_valid_symref" "S")))]
5410 UNSPEC_GOTSMALLPIC28K))] 6225 UNSPEC_GOTSMALLPIC28K))]
5411 "" 6226 ""
5412 "ldr\\t%<w>0, [%1, #:<got_modifier>:%a2]" 6227 "ldr\\t%<w>0, [%1, #:<got_modifier>:%c2]"
5413 [(set_attr "type" "load_<ldst_sz>")] 6228 [(set_attr "type" "load_<ldst_sz>")]
5414 ) 6229 )
5415 6230
5416 (define_insn "ldr_got_small_28k_sidi" 6231 (define_insn "ldr_got_small_28k_sidi"
5417 [(set (match_operand:DI 0 "register_operand" "=r") 6232 [(set (match_operand:DI 0 "register_operand" "=r")
5419 (unspec:SI [(mem:SI (lo_sum:DI 6234 (unspec:SI [(mem:SI (lo_sum:DI
5420 (match_operand:DI 1 "register_operand" "r") 6235 (match_operand:DI 1 "register_operand" "r")
5421 (match_operand:DI 2 "aarch64_valid_symref" "S")))] 6236 (match_operand:DI 2 "aarch64_valid_symref" "S")))]
5422 UNSPEC_GOTSMALLPIC28K)))] 6237 UNSPEC_GOTSMALLPIC28K)))]
5423 "TARGET_ILP32" 6238 "TARGET_ILP32"
5424 "ldr\\t%w0, [%1, #:gotpage_lo14:%a2]" 6239 "ldr\\t%w0, [%1, #:gotpage_lo14:%c2]"
5425 [(set_attr "type" "load_4")] 6240 [(set_attr "type" "load_4")]
5426 ) 6241 )
5427 6242
5428 (define_insn "ldr_got_tiny" 6243 (define_insn "ldr_got_tiny"
5429 [(set (match_operand:DI 0 "register_operand" "=r") 6244 [(set (match_operand:DI 0 "register_operand" "=r")
5551 "movz\\t%<w>0, #:tprel_g2:%1\;movk\\t%<w>0, #:tprel_g1_nc:%1\;movk\\t%<w>0, #:tprel_g0_nc:%1" 6366 "movz\\t%<w>0, #:tprel_g2:%1\;movk\\t%<w>0, #:tprel_g1_nc:%1\;movk\\t%<w>0, #:tprel_g0_nc:%1"
5552 [(set_attr "type" "multiple") 6367 [(set_attr "type" "multiple")
5553 (set_attr "length" "12")] 6368 (set_attr "length" "12")]
5554 ) 6369 )
5555 6370
5556 (define_insn "tlsdesc_small_<mode>" 6371 (define_expand "tlsdesc_small_<mode>"
6372 [(unspec:PTR [(match_operand 0 "aarch64_valid_symref")] UNSPEC_TLSDESC)]
6373 "TARGET_TLS_DESC"
6374 {
6375 if (TARGET_SVE)
6376 emit_insn (gen_tlsdesc_small_sve_<mode> (operands[0]));
6377 else
6378 emit_insn (gen_tlsdesc_small_advsimd_<mode> (operands[0]));
6379 DONE;
6380 }
6381 )
6382
6383 ;; tlsdesc calls preserve all core and Advanced SIMD registers except
6384 ;; R0 and LR.
6385 (define_insn "tlsdesc_small_advsimd_<mode>"
5557 [(set (reg:PTR R0_REGNUM) 6386 [(set (reg:PTR R0_REGNUM)
5558 (unspec:PTR [(match_operand 0 "aarch64_valid_symref" "S")] 6387 (unspec:PTR [(match_operand 0 "aarch64_valid_symref" "S")]
5559 UNSPEC_TLSDESC)) 6388 UNSPEC_TLSDESC))
5560 (clobber (reg:DI LR_REGNUM)) 6389 (clobber (reg:DI LR_REGNUM))
5561 (clobber (reg:CC CC_REGNUM)) 6390 (clobber (reg:CC CC_REGNUM))
5562 (clobber (match_scratch:DI 1 "=r"))] 6391 (clobber (match_scratch:DI 1 "=r"))]
5563 "TARGET_TLS_DESC" 6392 "TARGET_TLS_DESC && !TARGET_SVE"
6393 "adrp\\tx0, %A0\;ldr\\t%<w>1, [x0, #%L0]\;add\\t<w>0, <w>0, %L0\;.tlsdesccall\\t%0\;blr\\t%1"
6394 [(set_attr "type" "call")
6395 (set_attr "length" "16")])
6396
6397 ;; For SVE, model tlsdesc calls as clobbering the lower 128 bits of
6398 ;; all vector registers, and clobber all predicate registers, on
6399 ;; top of the usual R0 and LR.
6400 (define_insn "tlsdesc_small_sve_<mode>"
6401 [(set (reg:PTR R0_REGNUM)
6402 (unspec:PTR [(match_operand 0 "aarch64_valid_symref" "S")]
6403 UNSPEC_TLSDESC))
6404 (clobber (reg:DI LR_REGNUM))
6405 (clobber (reg:CC CC_REGNUM))
6406 (clobber_high (reg:TI V0_REGNUM))
6407 (clobber_high (reg:TI V1_REGNUM))
6408 (clobber_high (reg:TI V2_REGNUM))
6409 (clobber_high (reg:TI V3_REGNUM))
6410 (clobber_high (reg:TI V4_REGNUM))
6411 (clobber_high (reg:TI V5_REGNUM))
6412 (clobber_high (reg:TI V6_REGNUM))
6413 (clobber_high (reg:TI V7_REGNUM))
6414 (clobber_high (reg:TI V8_REGNUM))
6415 (clobber_high (reg:TI V9_REGNUM))
6416 (clobber_high (reg:TI V10_REGNUM))
6417 (clobber_high (reg:TI V11_REGNUM))
6418 (clobber_high (reg:TI V12_REGNUM))
6419 (clobber_high (reg:TI V13_REGNUM))
6420 (clobber_high (reg:TI V14_REGNUM))
6421 (clobber_high (reg:TI V15_REGNUM))
6422 (clobber_high (reg:TI V16_REGNUM))
6423 (clobber_high (reg:TI V17_REGNUM))
6424 (clobber_high (reg:TI V18_REGNUM))
6425 (clobber_high (reg:TI V19_REGNUM))
6426 (clobber_high (reg:TI V20_REGNUM))
6427 (clobber_high (reg:TI V21_REGNUM))
6428 (clobber_high (reg:TI V22_REGNUM))
6429 (clobber_high (reg:TI V23_REGNUM))
6430 (clobber_high (reg:TI V24_REGNUM))
6431 (clobber_high (reg:TI V25_REGNUM))
6432 (clobber_high (reg:TI V26_REGNUM))
6433 (clobber_high (reg:TI V27_REGNUM))
6434 (clobber_high (reg:TI V28_REGNUM))
6435 (clobber_high (reg:TI V29_REGNUM))
6436 (clobber_high (reg:TI V30_REGNUM))
6437 (clobber_high (reg:TI V31_REGNUM))
6438 (clobber (reg:VNx2BI P0_REGNUM))
6439 (clobber (reg:VNx2BI P1_REGNUM))
6440 (clobber (reg:VNx2BI P2_REGNUM))
6441 (clobber (reg:VNx2BI P3_REGNUM))
6442 (clobber (reg:VNx2BI P4_REGNUM))
6443 (clobber (reg:VNx2BI P5_REGNUM))
6444 (clobber (reg:VNx2BI P6_REGNUM))
6445 (clobber (reg:VNx2BI P7_REGNUM))
6446 (clobber (reg:VNx2BI P8_REGNUM))
6447 (clobber (reg:VNx2BI P9_REGNUM))
6448 (clobber (reg:VNx2BI P10_REGNUM))
6449 (clobber (reg:VNx2BI P11_REGNUM))
6450 (clobber (reg:VNx2BI P12_REGNUM))
6451 (clobber (reg:VNx2BI P13_REGNUM))
6452 (clobber (reg:VNx2BI P14_REGNUM))
6453 (clobber (reg:VNx2BI P15_REGNUM))
6454 (clobber (match_scratch:DI 1 "=r"))]
6455 "TARGET_TLS_DESC && TARGET_SVE"
5564 "adrp\\tx0, %A0\;ldr\\t%<w>1, [x0, #%L0]\;add\\t<w>0, <w>0, %L0\;.tlsdesccall\\t%0\;blr\\t%1" 6456 "adrp\\tx0, %A0\;ldr\\t%<w>1, [x0, #%L0]\;add\\t<w>0, <w>0, %L0\;.tlsdesccall\\t%0\;blr\\t%1"
5565 [(set_attr "type" "call") 6457 [(set_attr "type" "call")
5566 (set_attr "length" "16")]) 6458 (set_attr "length" "16")])
5567 6459
5568 (define_insn "stack_tie" 6460 (define_insn "stack_tie"
5618 [(set_attr "length" "0") 6510 [(set_attr "length" "0")
5619 (set_attr "type" "block")] 6511 (set_attr "type" "block")]
5620 ) 6512 )
5621 6513
5622 (define_insn "probe_stack_range" 6514 (define_insn "probe_stack_range"
5623 [(set (match_operand:DI 0 "register_operand" "=r") 6515 [(set (match_operand:DI 0 "register_operand" "=rk")
5624 (unspec_volatile:DI [(match_operand:DI 1 "register_operand" "0") 6516 (unspec_volatile:DI [(match_operand:DI 1 "register_operand" "0")
5625 (match_operand:DI 2 "register_operand" "r")] 6517 (match_operand:DI 2 "register_operand" "r")]
5626 UNSPECV_PROBE_STACK_RANGE))] 6518 UNSPECV_PROBE_STACK_RANGE))]
5627 "" 6519 ""
5628 { 6520 {
5629 return aarch64_output_probe_stack_range (operands[0], operands[2]); 6521 return aarch64_output_probe_stack_range (operands[0], operands[2]);
5630 } 6522 }
5631 [(set_attr "length" "32")] 6523 [(set_attr "length" "32")]
6524 )
6525
6526 ;; This instruction is used to generate the stack clash stack adjustment and
6527 ;; probing loop. We can't change the control flow during prologue and epilogue
6528 ;; code generation. So we must emit a volatile unspec and expand it later on.
6529
6530 (define_insn "@probe_sve_stack_clash_<mode>"
6531 [(set (match_operand:P 0 "register_operand" "=rk")
6532 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")
6533 (match_operand:P 2 "register_operand" "r")
6534 (match_operand:P 3 "const_int_operand" "n")
6535 (match_operand:P 4 "aarch64_plus_immediate" "L")]
6536 UNSPECV_PROBE_STACK_RANGE))]
6537 "TARGET_SVE"
6538 {
6539 return aarch64_output_probe_sve_stack_clash (operands[0], operands[2],
6540 operands[3], operands[4]);
6541 }
6542 [(set_attr "length" "28")]
5632 ) 6543 )
5633 6544
5634 ;; Named pattern for expanding thread pointer reference. 6545 ;; Named pattern for expanding thread pointer reference.
5635 (define_expand "get_thread_pointerdi" 6546 (define_expand "get_thread_pointerdi"
5636 [(match_operand:DI 0 "register_operand" "=r")] 6547 [(match_operand:DI 0 "register_operand" "=r")]
5769 gen_rtx_IF_THEN_ELSE (VOIDmode, bcomp, 6680 gen_rtx_IF_THEN_ELSE (VOIDmode, bcomp,
5770 loc_ref, pc_rtx))); 6681 loc_ref, pc_rtx)));
5771 DONE; 6682 DONE;
5772 }) 6683 })
5773 6684
6685 ;; Track speculation through conditional branches. We assume that
6686 ;; SPECULATION_TRACKER_REGNUM is reserved for this purpose when necessary.
6687 (define_insn "speculation_tracker"
6688 [(set (reg:DI SPECULATION_TRACKER_REGNUM)
6689 (unspec [(reg:DI SPECULATION_TRACKER_REGNUM) (match_operand 0)]
6690 UNSPEC_SPECULATION_TRACKER))]
6691 ""
6692 {
6693 operands[1] = gen_rtx_REG (DImode, SPECULATION_TRACKER_REGNUM);
6694 output_asm_insn ("csel\\t%1, %1, xzr, %m0", operands);
6695 return "";
6696 }
6697 [(set_attr "type" "csel")]
6698 )
6699
6700 ;; Helper for aarch64.c code.
6701 (define_expand "set_clobber_cc"
6702 [(parallel [(set (match_operand 0)
6703 (match_operand 1))
6704 (clobber (reg:CC CC_REGNUM))])])
6705
6706 ;; Hard speculation barrier.
6707 (define_insn "speculation_barrier"
6708 [(unspec_volatile [(const_int 0)] UNSPECV_SPECULATION_BARRIER)]
6709 ""
6710 "isb\;dsb\\tsy"
6711 [(set_attr "length" "8")
6712 (set_attr "type" "block")
6713 (set_attr "speculation_barrier" "true")]
6714 )
6715
6716 ;; Support for __builtin_speculation_safe_value when we have speculation
6717 ;; tracking enabled. Use the speculation tracker to decide whether to
6718 ;; copy operand 1 to the target, or to copy the fail value (operand 2).
6719 (define_expand "@despeculate_copy<ALLI_TI:mode>"
6720 [(set (match_operand:ALLI_TI 0 "register_operand" "=r")
6721 (unspec_volatile:ALLI_TI
6722 [(match_operand:ALLI_TI 1 "register_operand" "r")
6723 (match_operand:ALLI_TI 2 "aarch64_reg_or_zero" "rZ")
6724 (use (reg:DI SPECULATION_TRACKER_REGNUM))
6725 (clobber (reg:CC CC_REGNUM))] UNSPECV_SPECULATION_BARRIER))]
6726 ""
6727 "
6728 {
6729 if (operands[2] == const0_rtx)
6730 {
6731 rtx tracker;
6732 if (<MODE>mode == TImode)
6733 tracker = gen_rtx_REG (DImode, SPECULATION_TRACKER_REGNUM);
6734 else
6735 tracker = gen_rtx_REG (<MODE>mode, SPECULATION_TRACKER_REGNUM);
6736
6737 emit_insn (gen_despeculate_simple<mode> (operands[0], operands[1],
6738 tracker));
6739 DONE;
6740 }
6741 }
6742 "
6743 )
6744
6745 ;; Patterns to match despeculate_copy<mode>. Note that "hint 0x14" is the
6746 ;; encoding for CSDB, but will work in older versions of the assembler.
6747 (define_insn "*despeculate_copy<ALLI:mode>_insn"
6748 [(set (match_operand:ALLI 0 "register_operand" "=r")
6749 (unspec_volatile:ALLI
6750 [(match_operand:ALLI 1 "register_operand" "r")
6751 (match_operand:ALLI 2 "aarch64_reg_or_zero" "rZ")
6752 (use (reg:DI SPECULATION_TRACKER_REGNUM))
6753 (clobber (reg:CC CC_REGNUM))] UNSPECV_SPECULATION_BARRIER))]
6754 ""
6755 {
6756 operands[3] = gen_rtx_REG (DImode, SPECULATION_TRACKER_REGNUM);
6757 output_asm_insn ("cmp\\t%3, #0\;csel\\t%<w>0, %<w>1, %<w>2, ne\;hint\t0x14 // csdb",
6758 operands);
6759 return "";
6760 }
6761 [(set_attr "length" "12")
6762 (set_attr "type" "block")
6763 (set_attr "speculation_barrier" "true")]
6764 )
6765
6766 ;; Pattern to match despeculate_copyti
6767 (define_insn "*despeculate_copyti_insn"
6768 [(set (match_operand:TI 0 "register_operand" "=r")
6769 (unspec_volatile:TI
6770 [(match_operand:TI 1 "register_operand" "r")
6771 (match_operand:TI 2 "aarch64_reg_or_zero" "rZ")
6772 (use (reg:DI SPECULATION_TRACKER_REGNUM))
6773 (clobber (reg:CC CC_REGNUM))] UNSPECV_SPECULATION_BARRIER))]
6774 ""
6775 {
6776 operands[3] = gen_rtx_REG (DImode, SPECULATION_TRACKER_REGNUM);
6777 output_asm_insn
6778 ("cmp\\t%3, #0\;csel\\t%0, %1, %2, ne\;csel\\t%H0, %H1, %H2, ne\;hint\t0x14 // csdb",
6779 operands);
6780 return "";
6781 }
6782 [(set_attr "length" "16")
6783 (set_attr "type" "block")
6784 (set_attr "speculation_barrier" "true")]
6785 )
6786
6787 (define_insn "despeculate_simple<ALLI:mode>"
6788 [(set (match_operand:ALLI 0 "register_operand" "=r")
6789 (unspec_volatile:ALLI
6790 [(match_operand:ALLI 1 "register_operand" "r")
6791 (use (match_operand:ALLI 2 "register_operand" ""))]
6792 UNSPECV_SPECULATION_BARRIER))]
6793 ""
6794 "and\\t%<w>0, %<w>1, %<w>2\;hint\t0x14 // csdb"
6795 [(set_attr "type" "block")
6796 (set_attr "length" "8")
6797 (set_attr "speculation_barrier" "true")]
6798 )
6799
6800 (define_insn "despeculate_simpleti"
6801 [(set (match_operand:TI 0 "register_operand" "=r")
6802 (unspec_volatile:TI
6803 [(match_operand:TI 1 "register_operand" "r")
6804 (use (match_operand:DI 2 "register_operand" ""))]
6805 UNSPECV_SPECULATION_BARRIER))]
6806 ""
6807 "and\\t%0, %1, %2\;and\\t%H0, %H1, %2\;hint\t0x14 // csdb"
6808 [(set_attr "type" "block")
6809 (set_attr "length" "12")
6810 (set_attr "speculation_barrier" "true")]
6811 )
6812
5774 ;; AdvSIMD Stuff 6813 ;; AdvSIMD Stuff
5775 (include "aarch64-simd.md") 6814 (include "aarch64-simd.md")
5776 6815
5777 ;; Atomic Operations 6816 ;; Atomic Operations
5778 (include "atomics.md") 6817 (include "atomics.md")
5779 6818
5780 ;; ldp/stp peephole patterns 6819 ;; ldp/stp peephole patterns
5781 (include "aarch64-ldpstp.md") 6820 (include "aarch64-ldpstp.md")
6821
6822 ;; SVE.
6823 (include "aarch64-sve.md")