Mercurial > hg > CbC > CbC_gcc
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") |