aarch64-sve.md revision 1.1.1.2 1 1.1 mrg ;; Machine description for AArch64 SVE.
2 1.1.1.2 mrg ;; Copyright (C) 2009-2019 Free Software Foundation, Inc.
3 1.1 mrg ;; Contributed by ARM Ltd.
4 1.1 mrg ;;
5 1.1 mrg ;; This file is part of GCC.
6 1.1 mrg ;;
7 1.1 mrg ;; GCC is free software; you can redistribute it and/or modify it
8 1.1 mrg ;; under the terms of the GNU General Public License as published by
9 1.1 mrg ;; the Free Software Foundation; either version 3, or (at your option)
10 1.1 mrg ;; any later version.
11 1.1 mrg ;;
12 1.1 mrg ;; GCC is distributed in the hope that it will be useful, but
13 1.1 mrg ;; WITHOUT ANY WARRANTY; without even the implied warranty of
14 1.1 mrg ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 1.1 mrg ;; General Public License for more details.
16 1.1 mrg ;;
17 1.1 mrg ;; You should have received a copy of the GNU General Public License
18 1.1 mrg ;; along with GCC; see the file COPYING3. If not see
19 1.1 mrg ;; <http://www.gnu.org/licenses/>.
20 1.1 mrg
21 1.1 mrg ;; Note on the handling of big-endian SVE
22 1.1 mrg ;; --------------------------------------
23 1.1 mrg ;;
24 1.1 mrg ;; On big-endian systems, Advanced SIMD mov<mode> patterns act in the
25 1.1 mrg ;; same way as movdi or movti would: the first byte of memory goes
26 1.1 mrg ;; into the most significant byte of the register and the last byte
27 1.1 mrg ;; of memory goes into the least significant byte of the register.
28 1.1 mrg ;; This is the most natural ordering for Advanced SIMD and matches
29 1.1 mrg ;; the ABI layout for 64-bit and 128-bit vector types.
30 1.1 mrg ;;
31 1.1 mrg ;; As a result, the order of bytes within the register is what GCC
32 1.1 mrg ;; expects for a big-endian target, and subreg offsets therefore work
33 1.1 mrg ;; as expected, with the first element in memory having subreg offset 0
34 1.1 mrg ;; and the last element in memory having the subreg offset associated
35 1.1 mrg ;; with a big-endian lowpart. However, this ordering also means that
36 1.1 mrg ;; GCC's lane numbering does not match the architecture's numbering:
37 1.1 mrg ;; GCC always treats the element at the lowest address in memory
38 1.1 mrg ;; (subreg offset 0) as element 0, while the architecture treats
39 1.1 mrg ;; the least significant end of the register as element 0.
40 1.1 mrg ;;
41 1.1 mrg ;; The situation for SVE is different. We want the layout of the
42 1.1 mrg ;; SVE register to be same for mov<mode> as it is for maskload<mode>:
43 1.1 mrg ;; logically, a mov<mode> load must be indistinguishable from a
44 1.1 mrg ;; maskload<mode> whose mask is all true. We therefore need the
45 1.1 mrg ;; register layout to match LD1 rather than LDR. The ABI layout of
46 1.1 mrg ;; SVE types also matches LD1 byte ordering rather than LDR byte ordering.
47 1.1 mrg ;;
48 1.1 mrg ;; As a result, the architecture lane numbering matches GCC's lane
49 1.1 mrg ;; numbering, with element 0 always being the first in memory.
50 1.1 mrg ;; However:
51 1.1 mrg ;;
52 1.1 mrg ;; - Applying a subreg offset to a register does not give the element
53 1.1 mrg ;; that GCC expects: the first element in memory has the subreg offset
54 1.1 mrg ;; associated with a big-endian lowpart while the last element in memory
55 1.1 mrg ;; has subreg offset 0. We handle this via TARGET_CAN_CHANGE_MODE_CLASS.
56 1.1 mrg ;;
57 1.1 mrg ;; - We cannot use LDR and STR for spill slots that might be accessed
58 1.1 mrg ;; via subregs, since although the elements have the order GCC expects,
59 1.1 mrg ;; the order of the bytes within the elements is different. We instead
60 1.1 mrg ;; access spill slots via LD1 and ST1, using secondary reloads to
61 1.1 mrg ;; reserve a predicate register.
62 1.1 mrg
63 1.1 mrg
64 1.1 mrg ;; SVE data moves.
65 1.1 mrg (define_expand "mov<mode>"
66 1.1 mrg [(set (match_operand:SVE_ALL 0 "nonimmediate_operand")
67 1.1 mrg (match_operand:SVE_ALL 1 "general_operand"))]
68 1.1 mrg "TARGET_SVE"
69 1.1 mrg {
70 1.1 mrg /* Use the predicated load and store patterns where possible.
71 1.1 mrg This is required for big-endian targets (see the comment at the
72 1.1 mrg head of the file) and increases the addressing choices for
73 1.1 mrg little-endian. */
74 1.1 mrg if ((MEM_P (operands[0]) || MEM_P (operands[1]))
75 1.1 mrg && can_create_pseudo_p ())
76 1.1 mrg {
77 1.1 mrg aarch64_expand_sve_mem_move (operands[0], operands[1], <VPRED>mode);
78 1.1 mrg DONE;
79 1.1 mrg }
80 1.1 mrg
81 1.1 mrg if (CONSTANT_P (operands[1]))
82 1.1 mrg {
83 1.1 mrg aarch64_expand_mov_immediate (operands[0], operands[1],
84 1.1 mrg gen_vec_duplicate<mode>);
85 1.1 mrg DONE;
86 1.1 mrg }
87 1.1 mrg
88 1.1 mrg /* Optimize subregs on big-endian targets: we can use REV[BHW]
89 1.1 mrg instead of going through memory. */
90 1.1 mrg if (BYTES_BIG_ENDIAN
91 1.1 mrg && aarch64_maybe_expand_sve_subreg_move (operands[0], operands[1]))
92 1.1 mrg DONE;
93 1.1 mrg }
94 1.1 mrg )
95 1.1 mrg
96 1.1 mrg ;; A pattern for optimizing SUBREGs that have a reinterpreting effect
97 1.1 mrg ;; on big-endian targets; see aarch64_maybe_expand_sve_subreg_move
98 1.1 mrg ;; for details. We use a special predicate for operand 2 to reduce
99 1.1 mrg ;; the number of patterns.
100 1.1 mrg (define_insn_and_split "*aarch64_sve_mov<mode>_subreg_be"
101 1.1 mrg [(set (match_operand:SVE_ALL 0 "aarch64_sve_nonimmediate_operand" "=w")
102 1.1 mrg (unspec:SVE_ALL
103 1.1 mrg [(match_operand:VNx16BI 1 "register_operand" "Upl")
104 1.1 mrg (match_operand 2 "aarch64_any_register_operand" "w")]
105 1.1 mrg UNSPEC_REV_SUBREG))]
106 1.1 mrg "TARGET_SVE && BYTES_BIG_ENDIAN"
107 1.1 mrg "#"
108 1.1 mrg "&& reload_completed"
109 1.1 mrg [(const_int 0)]
110 1.1 mrg {
111 1.1 mrg aarch64_split_sve_subreg_move (operands[0], operands[1], operands[2]);
112 1.1 mrg DONE;
113 1.1 mrg }
114 1.1 mrg )
115 1.1 mrg
116 1.1 mrg ;; Unpredicated moves (little-endian). Only allow memory operations
117 1.1 mrg ;; during and after RA; before RA we want the predicated load and
118 1.1 mrg ;; store patterns to be used instead.
119 1.1 mrg (define_insn "*aarch64_sve_mov<mode>_le"
120 1.1 mrg [(set (match_operand:SVE_ALL 0 "aarch64_sve_nonimmediate_operand" "=w, Utr, w, w")
121 1.1 mrg (match_operand:SVE_ALL 1 "aarch64_sve_general_operand" "Utr, w, w, Dn"))]
122 1.1 mrg "TARGET_SVE
123 1.1 mrg && !BYTES_BIG_ENDIAN
124 1.1 mrg && ((lra_in_progress || reload_completed)
125 1.1 mrg || (register_operand (operands[0], <MODE>mode)
126 1.1 mrg && nonmemory_operand (operands[1], <MODE>mode)))"
127 1.1 mrg "@
128 1.1 mrg ldr\t%0, %1
129 1.1 mrg str\t%1, %0
130 1.1 mrg mov\t%0.d, %1.d
131 1.1 mrg * return aarch64_output_sve_mov_immediate (operands[1]);"
132 1.1 mrg )
133 1.1 mrg
134 1.1 mrg ;; Unpredicated moves (big-endian). Memory accesses require secondary
135 1.1 mrg ;; reloads.
136 1.1 mrg (define_insn "*aarch64_sve_mov<mode>_be"
137 1.1 mrg [(set (match_operand:SVE_ALL 0 "register_operand" "=w, w")
138 1.1 mrg (match_operand:SVE_ALL 1 "aarch64_nonmemory_operand" "w, Dn"))]
139 1.1 mrg "TARGET_SVE && BYTES_BIG_ENDIAN"
140 1.1 mrg "@
141 1.1 mrg mov\t%0.d, %1.d
142 1.1 mrg * return aarch64_output_sve_mov_immediate (operands[1]);"
143 1.1 mrg )
144 1.1 mrg
145 1.1 mrg ;; Handle big-endian memory reloads. We use byte PTRUE for all modes
146 1.1 mrg ;; to try to encourage reuse.
147 1.1 mrg (define_expand "aarch64_sve_reload_be"
148 1.1 mrg [(parallel
149 1.1 mrg [(set (match_operand 0)
150 1.1 mrg (match_operand 1))
151 1.1 mrg (clobber (match_operand:VNx16BI 2 "register_operand" "=Upl"))])]
152 1.1 mrg "TARGET_SVE && BYTES_BIG_ENDIAN"
153 1.1 mrg {
154 1.1 mrg /* Create a PTRUE. */
155 1.1 mrg emit_move_insn (operands[2], CONSTM1_RTX (VNx16BImode));
156 1.1 mrg
157 1.1 mrg /* Refer to the PTRUE in the appropriate mode for this move. */
158 1.1 mrg machine_mode mode = GET_MODE (operands[0]);
159 1.1 mrg machine_mode pred_mode
160 1.1 mrg = aarch64_sve_pred_mode (GET_MODE_UNIT_SIZE (mode)).require ();
161 1.1 mrg rtx pred = gen_lowpart (pred_mode, operands[2]);
162 1.1 mrg
163 1.1 mrg /* Emit a predicated load or store. */
164 1.1 mrg aarch64_emit_sve_pred_move (operands[0], pred, operands[1]);
165 1.1 mrg DONE;
166 1.1 mrg }
167 1.1 mrg )
168 1.1 mrg
169 1.1 mrg ;; A predicated load or store for which the predicate is known to be
170 1.1 mrg ;; all-true. Note that this pattern is generated directly by
171 1.1 mrg ;; aarch64_emit_sve_pred_move, so changes to this pattern will
172 1.1 mrg ;; need changes there as well.
173 1.1.1.2 mrg (define_insn_and_split "@aarch64_pred_mov<mode>"
174 1.1.1.2 mrg [(set (match_operand:SVE_ALL 0 "nonimmediate_operand" "=w, w, m")
175 1.1 mrg (unspec:SVE_ALL
176 1.1.1.2 mrg [(match_operand:<VPRED> 1 "register_operand" "Upl, Upl, Upl")
177 1.1.1.2 mrg (match_operand:SVE_ALL 2 "nonimmediate_operand" "w, m, w")]
178 1.1 mrg UNSPEC_MERGE_PTRUE))]
179 1.1 mrg "TARGET_SVE
180 1.1 mrg && (register_operand (operands[0], <MODE>mode)
181 1.1 mrg || register_operand (operands[2], <MODE>mode))"
182 1.1 mrg "@
183 1.1.1.2 mrg #
184 1.1 mrg ld1<Vesize>\t%0.<Vetype>, %1/z, %2
185 1.1 mrg st1<Vesize>\t%2.<Vetype>, %1, %0"
186 1.1.1.2 mrg "&& register_operand (operands[0], <MODE>mode)
187 1.1.1.2 mrg && register_operand (operands[2], <MODE>mode)"
188 1.1.1.2 mrg [(set (match_dup 0) (match_dup 2))]
189 1.1 mrg )
190 1.1 mrg
191 1.1 mrg (define_expand "movmisalign<mode>"
192 1.1 mrg [(set (match_operand:SVE_ALL 0 "nonimmediate_operand")
193 1.1 mrg (match_operand:SVE_ALL 1 "general_operand"))]
194 1.1 mrg "TARGET_SVE"
195 1.1 mrg {
196 1.1 mrg /* Equivalent to a normal move for our purpooses. */
197 1.1 mrg emit_move_insn (operands[0], operands[1]);
198 1.1 mrg DONE;
199 1.1 mrg }
200 1.1 mrg )
201 1.1 mrg
202 1.1 mrg (define_insn "maskload<mode><vpred>"
203 1.1 mrg [(set (match_operand:SVE_ALL 0 "register_operand" "=w")
204 1.1 mrg (unspec:SVE_ALL
205 1.1 mrg [(match_operand:<VPRED> 2 "register_operand" "Upl")
206 1.1 mrg (match_operand:SVE_ALL 1 "memory_operand" "m")]
207 1.1 mrg UNSPEC_LD1_SVE))]
208 1.1 mrg "TARGET_SVE"
209 1.1 mrg "ld1<Vesize>\t%0.<Vetype>, %2/z, %1"
210 1.1 mrg )
211 1.1 mrg
212 1.1 mrg (define_insn "maskstore<mode><vpred>"
213 1.1 mrg [(set (match_operand:SVE_ALL 0 "memory_operand" "+m")
214 1.1 mrg (unspec:SVE_ALL [(match_operand:<VPRED> 2 "register_operand" "Upl")
215 1.1 mrg (match_operand:SVE_ALL 1 "register_operand" "w")
216 1.1 mrg (match_dup 0)]
217 1.1 mrg UNSPEC_ST1_SVE))]
218 1.1 mrg "TARGET_SVE"
219 1.1 mrg "st1<Vesize>\t%1.<Vetype>, %2, %0"
220 1.1 mrg )
221 1.1 mrg
222 1.1 mrg ;; Unpredicated gather loads.
223 1.1 mrg (define_expand "gather_load<mode>"
224 1.1 mrg [(set (match_operand:SVE_SD 0 "register_operand")
225 1.1 mrg (unspec:SVE_SD
226 1.1 mrg [(match_dup 5)
227 1.1 mrg (match_operand:DI 1 "aarch64_reg_or_zero")
228 1.1 mrg (match_operand:<V_INT_EQUIV> 2 "register_operand")
229 1.1 mrg (match_operand:DI 3 "const_int_operand")
230 1.1 mrg (match_operand:DI 4 "aarch64_gather_scale_operand_<Vesize>")
231 1.1 mrg (mem:BLK (scratch))]
232 1.1 mrg UNSPEC_LD1_GATHER))]
233 1.1 mrg "TARGET_SVE"
234 1.1 mrg {
235 1.1 mrg operands[5] = force_reg (<VPRED>mode, CONSTM1_RTX (<VPRED>mode));
236 1.1 mrg }
237 1.1 mrg )
238 1.1 mrg
239 1.1 mrg ;; Predicated gather loads for 32-bit elements. Operand 3 is true for
240 1.1 mrg ;; unsigned extension and false for signed extension.
241 1.1 mrg (define_insn "mask_gather_load<mode>"
242 1.1 mrg [(set (match_operand:SVE_S 0 "register_operand" "=w, w, w, w, w")
243 1.1 mrg (unspec:SVE_S
244 1.1 mrg [(match_operand:<VPRED> 5 "register_operand" "Upl, Upl, Upl, Upl, Upl")
245 1.1 mrg (match_operand:DI 1 "aarch64_reg_or_zero" "Z, rk, rk, rk, rk")
246 1.1 mrg (match_operand:<V_INT_EQUIV> 2 "register_operand" "w, w, w, w, w")
247 1.1 mrg (match_operand:DI 3 "const_int_operand" "i, Z, Ui1, Z, Ui1")
248 1.1 mrg (match_operand:DI 4 "aarch64_gather_scale_operand_w" "Ui1, Ui1, Ui1, i, i")
249 1.1 mrg (mem:BLK (scratch))]
250 1.1 mrg UNSPEC_LD1_GATHER))]
251 1.1 mrg "TARGET_SVE"
252 1.1 mrg "@
253 1.1 mrg ld1w\t%0.s, %5/z, [%2.s]
254 1.1 mrg ld1w\t%0.s, %5/z, [%1, %2.s, sxtw]
255 1.1 mrg ld1w\t%0.s, %5/z, [%1, %2.s, uxtw]
256 1.1 mrg ld1w\t%0.s, %5/z, [%1, %2.s, sxtw %p4]
257 1.1 mrg ld1w\t%0.s, %5/z, [%1, %2.s, uxtw %p4]"
258 1.1 mrg )
259 1.1 mrg
260 1.1 mrg ;; Predicated gather loads for 64-bit elements. The value of operand 3
261 1.1 mrg ;; doesn't matter in this case.
262 1.1 mrg (define_insn "mask_gather_load<mode>"
263 1.1 mrg [(set (match_operand:SVE_D 0 "register_operand" "=w, w, w")
264 1.1 mrg (unspec:SVE_D
265 1.1 mrg [(match_operand:<VPRED> 5 "register_operand" "Upl, Upl, Upl")
266 1.1 mrg (match_operand:DI 1 "aarch64_reg_or_zero" "Z, rk, rk")
267 1.1 mrg (match_operand:<V_INT_EQUIV> 2 "register_operand" "w, w, w")
268 1.1 mrg (match_operand:DI 3 "const_int_operand")
269 1.1 mrg (match_operand:DI 4 "aarch64_gather_scale_operand_d" "Ui1, Ui1, i")
270 1.1 mrg (mem:BLK (scratch))]
271 1.1 mrg UNSPEC_LD1_GATHER))]
272 1.1 mrg "TARGET_SVE"
273 1.1 mrg "@
274 1.1 mrg ld1d\t%0.d, %5/z, [%2.d]
275 1.1 mrg ld1d\t%0.d, %5/z, [%1, %2.d]
276 1.1 mrg ld1d\t%0.d, %5/z, [%1, %2.d, lsl %p4]"
277 1.1 mrg )
278 1.1 mrg
279 1.1 mrg ;; Unpredicated scatter store.
280 1.1 mrg (define_expand "scatter_store<mode>"
281 1.1 mrg [(set (mem:BLK (scratch))
282 1.1 mrg (unspec:BLK
283 1.1 mrg [(match_dup 5)
284 1.1 mrg (match_operand:DI 0 "aarch64_reg_or_zero")
285 1.1 mrg (match_operand:<V_INT_EQUIV> 1 "register_operand")
286 1.1 mrg (match_operand:DI 2 "const_int_operand")
287 1.1 mrg (match_operand:DI 3 "aarch64_gather_scale_operand_<Vesize>")
288 1.1 mrg (match_operand:SVE_SD 4 "register_operand")]
289 1.1 mrg UNSPEC_ST1_SCATTER))]
290 1.1 mrg "TARGET_SVE"
291 1.1 mrg {
292 1.1 mrg operands[5] = force_reg (<VPRED>mode, CONSTM1_RTX (<VPRED>mode));
293 1.1 mrg }
294 1.1 mrg )
295 1.1 mrg
296 1.1 mrg ;; Predicated scatter stores for 32-bit elements. Operand 2 is true for
297 1.1 mrg ;; unsigned extension and false for signed extension.
298 1.1 mrg (define_insn "mask_scatter_store<mode>"
299 1.1 mrg [(set (mem:BLK (scratch))
300 1.1 mrg (unspec:BLK
301 1.1 mrg [(match_operand:<VPRED> 5 "register_operand" "Upl, Upl, Upl, Upl, Upl")
302 1.1 mrg (match_operand:DI 0 "aarch64_reg_or_zero" "Z, rk, rk, rk, rk")
303 1.1 mrg (match_operand:<V_INT_EQUIV> 1 "register_operand" "w, w, w, w, w")
304 1.1 mrg (match_operand:DI 2 "const_int_operand" "i, Z, Ui1, Z, Ui1")
305 1.1 mrg (match_operand:DI 3 "aarch64_gather_scale_operand_w" "Ui1, Ui1, Ui1, i, i")
306 1.1 mrg (match_operand:SVE_S 4 "register_operand" "w, w, w, w, w")]
307 1.1 mrg UNSPEC_ST1_SCATTER))]
308 1.1 mrg "TARGET_SVE"
309 1.1 mrg "@
310 1.1 mrg st1w\t%4.s, %5, [%1.s]
311 1.1 mrg st1w\t%4.s, %5, [%0, %1.s, sxtw]
312 1.1 mrg st1w\t%4.s, %5, [%0, %1.s, uxtw]
313 1.1 mrg st1w\t%4.s, %5, [%0, %1.s, sxtw %p3]
314 1.1 mrg st1w\t%4.s, %5, [%0, %1.s, uxtw %p3]"
315 1.1 mrg )
316 1.1 mrg
317 1.1 mrg ;; Predicated scatter stores for 64-bit elements. The value of operand 2
318 1.1 mrg ;; doesn't matter in this case.
319 1.1 mrg (define_insn "mask_scatter_store<mode>"
320 1.1 mrg [(set (mem:BLK (scratch))
321 1.1 mrg (unspec:BLK
322 1.1 mrg [(match_operand:<VPRED> 5 "register_operand" "Upl, Upl, Upl")
323 1.1 mrg (match_operand:DI 0 "aarch64_reg_or_zero" "Z, rk, rk")
324 1.1 mrg (match_operand:<V_INT_EQUIV> 1 "register_operand" "w, w, w")
325 1.1 mrg (match_operand:DI 2 "const_int_operand")
326 1.1 mrg (match_operand:DI 3 "aarch64_gather_scale_operand_d" "Ui1, Ui1, i")
327 1.1 mrg (match_operand:SVE_D 4 "register_operand" "w, w, w")]
328 1.1 mrg UNSPEC_ST1_SCATTER))]
329 1.1 mrg "TARGET_SVE"
330 1.1 mrg "@
331 1.1 mrg st1d\t%4.d, %5, [%1.d]
332 1.1 mrg st1d\t%4.d, %5, [%0, %1.d]
333 1.1 mrg st1d\t%4.d, %5, [%0, %1.d, lsl %p3]"
334 1.1 mrg )
335 1.1 mrg
336 1.1 mrg ;; SVE structure moves.
337 1.1 mrg (define_expand "mov<mode>"
338 1.1 mrg [(set (match_operand:SVE_STRUCT 0 "nonimmediate_operand")
339 1.1 mrg (match_operand:SVE_STRUCT 1 "general_operand"))]
340 1.1 mrg "TARGET_SVE"
341 1.1 mrg {
342 1.1 mrg /* Big-endian loads and stores need to be done via LD1 and ST1;
343 1.1 mrg see the comment at the head of the file for details. */
344 1.1 mrg if ((MEM_P (operands[0]) || MEM_P (operands[1]))
345 1.1 mrg && BYTES_BIG_ENDIAN)
346 1.1 mrg {
347 1.1 mrg gcc_assert (can_create_pseudo_p ());
348 1.1 mrg aarch64_expand_sve_mem_move (operands[0], operands[1], <VPRED>mode);
349 1.1 mrg DONE;
350 1.1 mrg }
351 1.1 mrg
352 1.1 mrg if (CONSTANT_P (operands[1]))
353 1.1 mrg {
354 1.1 mrg aarch64_expand_mov_immediate (operands[0], operands[1]);
355 1.1 mrg DONE;
356 1.1 mrg }
357 1.1 mrg }
358 1.1 mrg )
359 1.1 mrg
360 1.1 mrg ;; Unpredicated structure moves (little-endian).
361 1.1 mrg (define_insn "*aarch64_sve_mov<mode>_le"
362 1.1 mrg [(set (match_operand:SVE_STRUCT 0 "aarch64_sve_nonimmediate_operand" "=w, Utr, w, w")
363 1.1 mrg (match_operand:SVE_STRUCT 1 "aarch64_sve_general_operand" "Utr, w, w, Dn"))]
364 1.1 mrg "TARGET_SVE && !BYTES_BIG_ENDIAN"
365 1.1 mrg "#"
366 1.1 mrg [(set_attr "length" "<insn_length>")]
367 1.1 mrg )
368 1.1 mrg
369 1.1 mrg ;; Unpredicated structure moves (big-endian). Memory accesses require
370 1.1 mrg ;; secondary reloads.
371 1.1 mrg (define_insn "*aarch64_sve_mov<mode>_le"
372 1.1 mrg [(set (match_operand:SVE_STRUCT 0 "register_operand" "=w, w")
373 1.1 mrg (match_operand:SVE_STRUCT 1 "aarch64_nonmemory_operand" "w, Dn"))]
374 1.1 mrg "TARGET_SVE && BYTES_BIG_ENDIAN"
375 1.1 mrg "#"
376 1.1 mrg [(set_attr "length" "<insn_length>")]
377 1.1 mrg )
378 1.1 mrg
379 1.1 mrg ;; Split unpredicated structure moves into pieces. This is the same
380 1.1 mrg ;; for both big-endian and little-endian code, although it only needs
381 1.1 mrg ;; to handle memory operands for little-endian code.
382 1.1 mrg (define_split
383 1.1 mrg [(set (match_operand:SVE_STRUCT 0 "aarch64_sve_nonimmediate_operand")
384 1.1 mrg (match_operand:SVE_STRUCT 1 "aarch64_sve_general_operand"))]
385 1.1 mrg "TARGET_SVE && reload_completed"
386 1.1 mrg [(const_int 0)]
387 1.1 mrg {
388 1.1 mrg rtx dest = operands[0];
389 1.1 mrg rtx src = operands[1];
390 1.1 mrg if (REG_P (dest) && REG_P (src))
391 1.1 mrg aarch64_simd_emit_reg_reg_move (operands, <VSINGLE>mode, <vector_count>);
392 1.1 mrg else
393 1.1 mrg for (unsigned int i = 0; i < <vector_count>; ++i)
394 1.1 mrg {
395 1.1 mrg rtx subdest = simplify_gen_subreg (<VSINGLE>mode, dest, <MODE>mode,
396 1.1 mrg i * BYTES_PER_SVE_VECTOR);
397 1.1 mrg rtx subsrc = simplify_gen_subreg (<VSINGLE>mode, src, <MODE>mode,
398 1.1 mrg i * BYTES_PER_SVE_VECTOR);
399 1.1 mrg emit_insn (gen_rtx_SET (subdest, subsrc));
400 1.1 mrg }
401 1.1 mrg DONE;
402 1.1 mrg }
403 1.1 mrg )
404 1.1 mrg
405 1.1 mrg ;; Predicated structure moves. This works for both endiannesses but in
406 1.1 mrg ;; practice is only useful for big-endian.
407 1.1.1.2 mrg (define_insn_and_split "@aarch64_pred_mov<mode>"
408 1.1.1.2 mrg [(set (match_operand:SVE_STRUCT 0 "aarch64_sve_struct_nonimmediate_operand" "=w, w, Utx")
409 1.1 mrg (unspec:SVE_STRUCT
410 1.1.1.2 mrg [(match_operand:<VPRED> 1 "register_operand" "Upl, Upl, Upl")
411 1.1.1.2 mrg (match_operand:SVE_STRUCT 2 "aarch64_sve_struct_nonimmediate_operand" "w, Utx, w")]
412 1.1 mrg UNSPEC_MERGE_PTRUE))]
413 1.1 mrg "TARGET_SVE
414 1.1 mrg && (register_operand (operands[0], <MODE>mode)
415 1.1 mrg || register_operand (operands[2], <MODE>mode))"
416 1.1 mrg "#"
417 1.1 mrg "&& reload_completed"
418 1.1 mrg [(const_int 0)]
419 1.1 mrg {
420 1.1 mrg for (unsigned int i = 0; i < <vector_count>; ++i)
421 1.1 mrg {
422 1.1 mrg rtx subdest = simplify_gen_subreg (<VSINGLE>mode, operands[0],
423 1.1 mrg <MODE>mode,
424 1.1 mrg i * BYTES_PER_SVE_VECTOR);
425 1.1 mrg rtx subsrc = simplify_gen_subreg (<VSINGLE>mode, operands[2],
426 1.1 mrg <MODE>mode,
427 1.1 mrg i * BYTES_PER_SVE_VECTOR);
428 1.1 mrg aarch64_emit_sve_pred_move (subdest, operands[1], subsrc);
429 1.1 mrg }
430 1.1 mrg DONE;
431 1.1 mrg }
432 1.1 mrg [(set_attr "length" "<insn_length>")]
433 1.1 mrg )
434 1.1 mrg
435 1.1 mrg (define_expand "mov<mode>"
436 1.1 mrg [(set (match_operand:PRED_ALL 0 "nonimmediate_operand")
437 1.1 mrg (match_operand:PRED_ALL 1 "general_operand"))]
438 1.1 mrg "TARGET_SVE"
439 1.1 mrg {
440 1.1 mrg if (GET_CODE (operands[0]) == MEM)
441 1.1 mrg operands[1] = force_reg (<MODE>mode, operands[1]);
442 1.1 mrg }
443 1.1 mrg )
444 1.1 mrg
445 1.1 mrg (define_insn "*aarch64_sve_mov<mode>"
446 1.1 mrg [(set (match_operand:PRED_ALL 0 "nonimmediate_operand" "=Upa, m, Upa, Upa, Upa")
447 1.1 mrg (match_operand:PRED_ALL 1 "general_operand" "Upa, Upa, m, Dz, Dm"))]
448 1.1 mrg "TARGET_SVE
449 1.1 mrg && (register_operand (operands[0], <MODE>mode)
450 1.1 mrg || register_operand (operands[1], <MODE>mode))"
451 1.1 mrg "@
452 1.1 mrg mov\t%0.b, %1.b
453 1.1 mrg str\t%1, %0
454 1.1 mrg ldr\t%0, %1
455 1.1 mrg pfalse\t%0.b
456 1.1 mrg * return aarch64_output_ptrue (<MODE>mode, '<Vetype>');"
457 1.1 mrg )
458 1.1 mrg
459 1.1 mrg ;; Handle extractions from a predicate by converting to an integer vector
460 1.1 mrg ;; and extracting from there.
461 1.1 mrg (define_expand "vec_extract<vpred><Vel>"
462 1.1 mrg [(match_operand:<VEL> 0 "register_operand")
463 1.1 mrg (match_operand:<VPRED> 1 "register_operand")
464 1.1 mrg (match_operand:SI 2 "nonmemory_operand")
465 1.1 mrg ;; Dummy operand to which we can attach the iterator.
466 1.1 mrg (reg:SVE_I V0_REGNUM)]
467 1.1 mrg "TARGET_SVE"
468 1.1 mrg {
469 1.1 mrg rtx tmp = gen_reg_rtx (<MODE>mode);
470 1.1 mrg emit_insn (gen_aarch64_sve_dup<mode>_const (tmp, operands[1],
471 1.1 mrg CONST1_RTX (<MODE>mode),
472 1.1 mrg CONST0_RTX (<MODE>mode)));
473 1.1 mrg emit_insn (gen_vec_extract<mode><Vel> (operands[0], tmp, operands[2]));
474 1.1 mrg DONE;
475 1.1 mrg }
476 1.1 mrg )
477 1.1 mrg
478 1.1 mrg (define_expand "vec_extract<mode><Vel>"
479 1.1 mrg [(set (match_operand:<VEL> 0 "register_operand")
480 1.1 mrg (vec_select:<VEL>
481 1.1 mrg (match_operand:SVE_ALL 1 "register_operand")
482 1.1 mrg (parallel [(match_operand:SI 2 "nonmemory_operand")])))]
483 1.1 mrg "TARGET_SVE"
484 1.1 mrg {
485 1.1 mrg poly_int64 val;
486 1.1 mrg if (poly_int_rtx_p (operands[2], &val)
487 1.1 mrg && known_eq (val, GET_MODE_NUNITS (<MODE>mode) - 1))
488 1.1 mrg {
489 1.1 mrg /* The last element can be extracted with a LASTB and a false
490 1.1 mrg predicate. */
491 1.1 mrg rtx sel = force_reg (<VPRED>mode, CONST0_RTX (<VPRED>mode));
492 1.1 mrg emit_insn (gen_extract_last_<mode> (operands[0], sel, operands[1]));
493 1.1 mrg DONE;
494 1.1 mrg }
495 1.1 mrg if (!CONST_INT_P (operands[2]))
496 1.1 mrg {
497 1.1 mrg /* Create an index with operand[2] as the base and -1 as the step.
498 1.1 mrg It will then be zero for the element we care about. */
499 1.1 mrg rtx index = gen_lowpart (<VEL_INT>mode, operands[2]);
500 1.1 mrg index = force_reg (<VEL_INT>mode, index);
501 1.1 mrg rtx series = gen_reg_rtx (<V_INT_EQUIV>mode);
502 1.1 mrg emit_insn (gen_vec_series<v_int_equiv> (series, index, constm1_rtx));
503 1.1 mrg
504 1.1 mrg /* Get a predicate that is true for only that element. */
505 1.1 mrg rtx zero = CONST0_RTX (<V_INT_EQUIV>mode);
506 1.1 mrg rtx cmp = gen_rtx_EQ (<V_INT_EQUIV>mode, series, zero);
507 1.1 mrg rtx sel = gen_reg_rtx (<VPRED>mode);
508 1.1 mrg emit_insn (gen_vec_cmp<v_int_equiv><vpred> (sel, cmp, series, zero));
509 1.1 mrg
510 1.1 mrg /* Select the element using LASTB. */
511 1.1 mrg emit_insn (gen_extract_last_<mode> (operands[0], sel, operands[1]));
512 1.1 mrg DONE;
513 1.1 mrg }
514 1.1 mrg }
515 1.1 mrg )
516 1.1 mrg
517 1.1 mrg ;; Extract element zero. This is a special case because we want to force
518 1.1 mrg ;; the registers to be the same for the second alternative, and then
519 1.1 mrg ;; split the instruction into nothing after RA.
520 1.1 mrg (define_insn_and_split "*vec_extract<mode><Vel>_0"
521 1.1 mrg [(set (match_operand:<VEL> 0 "aarch64_simd_nonimmediate_operand" "=r, w, Utv")
522 1.1 mrg (vec_select:<VEL>
523 1.1 mrg (match_operand:SVE_ALL 1 "register_operand" "w, 0, w")
524 1.1 mrg (parallel [(const_int 0)])))]
525 1.1 mrg "TARGET_SVE"
526 1.1 mrg {
527 1.1 mrg operands[1] = gen_rtx_REG (<V128>mode, REGNO (operands[1]));
528 1.1 mrg switch (which_alternative)
529 1.1 mrg {
530 1.1 mrg case 0:
531 1.1 mrg return "umov\\t%<vwcore>0, %1.<Vetype>[0]";
532 1.1 mrg case 1:
533 1.1 mrg return "#";
534 1.1 mrg case 2:
535 1.1 mrg return "st1\\t{%1.<Vetype>}[0], %0";
536 1.1 mrg default:
537 1.1 mrg gcc_unreachable ();
538 1.1 mrg }
539 1.1 mrg }
540 1.1 mrg "&& reload_completed
541 1.1 mrg && REG_P (operands[0])
542 1.1 mrg && REGNO (operands[0]) == REGNO (operands[1])"
543 1.1 mrg [(const_int 0)]
544 1.1 mrg {
545 1.1 mrg emit_note (NOTE_INSN_DELETED);
546 1.1 mrg DONE;
547 1.1 mrg }
548 1.1 mrg [(set_attr "type" "neon_to_gp_q, untyped, neon_store1_one_lane_q")]
549 1.1 mrg )
550 1.1 mrg
551 1.1 mrg ;; Extract an element from the Advanced SIMD portion of the register.
552 1.1 mrg ;; We don't just reuse the aarch64-simd.md pattern because we don't
553 1.1 mrg ;; want any change in lane number on big-endian targets.
554 1.1 mrg (define_insn "*vec_extract<mode><Vel>_v128"
555 1.1 mrg [(set (match_operand:<VEL> 0 "aarch64_simd_nonimmediate_operand" "=r, w, Utv")
556 1.1 mrg (vec_select:<VEL>
557 1.1 mrg (match_operand:SVE_ALL 1 "register_operand" "w, w, w")
558 1.1 mrg (parallel [(match_operand:SI 2 "const_int_operand")])))]
559 1.1 mrg "TARGET_SVE
560 1.1 mrg && IN_RANGE (INTVAL (operands[2]) * GET_MODE_SIZE (<VEL>mode), 1, 15)"
561 1.1 mrg {
562 1.1 mrg operands[1] = gen_rtx_REG (<V128>mode, REGNO (operands[1]));
563 1.1 mrg switch (which_alternative)
564 1.1 mrg {
565 1.1 mrg case 0:
566 1.1 mrg return "umov\\t%<vwcore>0, %1.<Vetype>[%2]";
567 1.1 mrg case 1:
568 1.1 mrg return "dup\\t%<Vetype>0, %1.<Vetype>[%2]";
569 1.1 mrg case 2:
570 1.1 mrg return "st1\\t{%1.<Vetype>}[%2], %0";
571 1.1 mrg default:
572 1.1 mrg gcc_unreachable ();
573 1.1 mrg }
574 1.1 mrg }
575 1.1 mrg [(set_attr "type" "neon_to_gp_q, neon_dup_q, neon_store1_one_lane_q")]
576 1.1 mrg )
577 1.1 mrg
578 1.1 mrg ;; Extract an element in the range of DUP. This pattern allows the
579 1.1 mrg ;; source and destination to be different.
580 1.1 mrg (define_insn "*vec_extract<mode><Vel>_dup"
581 1.1 mrg [(set (match_operand:<VEL> 0 "register_operand" "=w")
582 1.1 mrg (vec_select:<VEL>
583 1.1 mrg (match_operand:SVE_ALL 1 "register_operand" "w")
584 1.1 mrg (parallel [(match_operand:SI 2 "const_int_operand")])))]
585 1.1 mrg "TARGET_SVE
586 1.1 mrg && IN_RANGE (INTVAL (operands[2]) * GET_MODE_SIZE (<VEL>mode), 16, 63)"
587 1.1 mrg {
588 1.1 mrg operands[0] = gen_rtx_REG (<MODE>mode, REGNO (operands[0]));
589 1.1 mrg return "dup\t%0.<Vetype>, %1.<Vetype>[%2]";
590 1.1 mrg }
591 1.1 mrg )
592 1.1 mrg
593 1.1 mrg ;; Extract an element outside the range of DUP. This pattern requires the
594 1.1 mrg ;; source and destination to be the same.
595 1.1 mrg (define_insn "*vec_extract<mode><Vel>_ext"
596 1.1 mrg [(set (match_operand:<VEL> 0 "register_operand" "=w")
597 1.1 mrg (vec_select:<VEL>
598 1.1 mrg (match_operand:SVE_ALL 1 "register_operand" "0")
599 1.1 mrg (parallel [(match_operand:SI 2 "const_int_operand")])))]
600 1.1 mrg "TARGET_SVE && INTVAL (operands[2]) * GET_MODE_SIZE (<VEL>mode) >= 64"
601 1.1 mrg {
602 1.1 mrg operands[0] = gen_rtx_REG (<MODE>mode, REGNO (operands[0]));
603 1.1 mrg operands[2] = GEN_INT (INTVAL (operands[2]) * GET_MODE_SIZE (<VEL>mode));
604 1.1 mrg return "ext\t%0.b, %0.b, %0.b, #%2";
605 1.1 mrg }
606 1.1 mrg )
607 1.1 mrg
608 1.1 mrg ;; Extract the last active element of operand 1 into operand 0.
609 1.1 mrg ;; If no elements are active, extract the last inactive element instead.
610 1.1 mrg (define_insn "extract_last_<mode>"
611 1.1 mrg [(set (match_operand:<VEL> 0 "register_operand" "=r, w")
612 1.1 mrg (unspec:<VEL>
613 1.1 mrg [(match_operand:<VPRED> 1 "register_operand" "Upl, Upl")
614 1.1 mrg (match_operand:SVE_ALL 2 "register_operand" "w, w")]
615 1.1 mrg UNSPEC_LASTB))]
616 1.1 mrg "TARGET_SVE"
617 1.1 mrg "@
618 1.1 mrg lastb\t%<vwcore>0, %1, %2.<Vetype>
619 1.1 mrg lastb\t%<Vetype>0, %1, %2.<Vetype>"
620 1.1 mrg )
621 1.1 mrg
622 1.1 mrg (define_expand "vec_duplicate<mode>"
623 1.1 mrg [(parallel
624 1.1 mrg [(set (match_operand:SVE_ALL 0 "register_operand")
625 1.1 mrg (vec_duplicate:SVE_ALL
626 1.1 mrg (match_operand:<VEL> 1 "aarch64_sve_dup_operand")))
627 1.1 mrg (clobber (scratch:<VPRED>))])]
628 1.1 mrg "TARGET_SVE"
629 1.1 mrg {
630 1.1 mrg if (MEM_P (operands[1]))
631 1.1 mrg {
632 1.1 mrg rtx ptrue = force_reg (<VPRED>mode, CONSTM1_RTX (<VPRED>mode));
633 1.1 mrg emit_insn (gen_sve_ld1r<mode> (operands[0], ptrue, operands[1],
634 1.1 mrg CONST0_RTX (<MODE>mode)));
635 1.1 mrg DONE;
636 1.1 mrg }
637 1.1 mrg }
638 1.1 mrg )
639 1.1 mrg
640 1.1 mrg ;; Accept memory operands for the benefit of combine, and also in case
641 1.1 mrg ;; the scalar input gets spilled to memory during RA. We want to split
642 1.1 mrg ;; the load at the first opportunity in order to allow the PTRUE to be
643 1.1 mrg ;; optimized with surrounding code.
644 1.1 mrg (define_insn_and_split "*vec_duplicate<mode>_reg"
645 1.1 mrg [(set (match_operand:SVE_ALL 0 "register_operand" "=w, w, w")
646 1.1 mrg (vec_duplicate:SVE_ALL
647 1.1 mrg (match_operand:<VEL> 1 "aarch64_sve_dup_operand" "r, w, Uty")))
648 1.1 mrg (clobber (match_scratch:<VPRED> 2 "=X, X, Upl"))]
649 1.1 mrg "TARGET_SVE"
650 1.1 mrg "@
651 1.1 mrg mov\t%0.<Vetype>, %<vwcore>1
652 1.1 mrg mov\t%0.<Vetype>, %<Vetype>1
653 1.1 mrg #"
654 1.1 mrg "&& MEM_P (operands[1])"
655 1.1 mrg [(const_int 0)]
656 1.1 mrg {
657 1.1 mrg if (GET_CODE (operands[2]) == SCRATCH)
658 1.1 mrg operands[2] = gen_reg_rtx (<VPRED>mode);
659 1.1 mrg emit_move_insn (operands[2], CONSTM1_RTX (<VPRED>mode));
660 1.1 mrg emit_insn (gen_sve_ld1r<mode> (operands[0], operands[2], operands[1],
661 1.1 mrg CONST0_RTX (<MODE>mode)));
662 1.1 mrg DONE;
663 1.1 mrg }
664 1.1 mrg [(set_attr "length" "4,4,8")]
665 1.1 mrg )
666 1.1 mrg
667 1.1 mrg ;; This is used for vec_duplicate<mode>s from memory, but can also
668 1.1 mrg ;; be used by combine to optimize selects of a a vec_duplicate<mode>
669 1.1 mrg ;; with zero.
670 1.1 mrg (define_insn "sve_ld1r<mode>"
671 1.1 mrg [(set (match_operand:SVE_ALL 0 "register_operand" "=w")
672 1.1 mrg (unspec:SVE_ALL
673 1.1 mrg [(match_operand:<VPRED> 1 "register_operand" "Upl")
674 1.1 mrg (vec_duplicate:SVE_ALL
675 1.1 mrg (match_operand:<VEL> 2 "aarch64_sve_ld1r_operand" "Uty"))
676 1.1 mrg (match_operand:SVE_ALL 3 "aarch64_simd_imm_zero")]
677 1.1 mrg UNSPEC_SEL))]
678 1.1 mrg "TARGET_SVE"
679 1.1 mrg "ld1r<Vesize>\t%0.<Vetype>, %1/z, %2"
680 1.1 mrg )
681 1.1 mrg
682 1.1 mrg ;; Load 128 bits from memory and duplicate to fill a vector. Since there
683 1.1 mrg ;; are so few operations on 128-bit "elements", we don't define a VNx1TI
684 1.1 mrg ;; and simply use vectors of bytes instead.
685 1.1 mrg (define_insn "*sve_ld1rq<Vesize>"
686 1.1 mrg [(set (match_operand:SVE_ALL 0 "register_operand" "=w")
687 1.1 mrg (unspec:SVE_ALL
688 1.1 mrg [(match_operand:<VPRED> 1 "register_operand" "Upl")
689 1.1 mrg (match_operand:TI 2 "aarch64_sve_ld1r_operand" "Uty")]
690 1.1 mrg UNSPEC_LD1RQ))]
691 1.1 mrg "TARGET_SVE"
692 1.1 mrg "ld1rq<Vesize>\t%0.<Vetype>, %1/z, %2"
693 1.1 mrg )
694 1.1 mrg
695 1.1 mrg ;; Implement a predicate broadcast by shifting the low bit of the scalar
696 1.1 mrg ;; input into the top bit and using a WHILELO. An alternative would be to
697 1.1 mrg ;; duplicate the input and do a compare with zero.
698 1.1 mrg (define_expand "vec_duplicate<mode>"
699 1.1 mrg [(set (match_operand:PRED_ALL 0 "register_operand")
700 1.1 mrg (vec_duplicate:PRED_ALL (match_operand 1 "register_operand")))]
701 1.1 mrg "TARGET_SVE"
702 1.1 mrg {
703 1.1 mrg rtx tmp = gen_reg_rtx (DImode);
704 1.1 mrg rtx op1 = gen_lowpart (DImode, operands[1]);
705 1.1 mrg emit_insn (gen_ashldi3 (tmp, op1, gen_int_mode (63, DImode)));
706 1.1 mrg emit_insn (gen_while_ultdi<mode> (operands[0], const0_rtx, tmp));
707 1.1 mrg DONE;
708 1.1 mrg }
709 1.1 mrg )
710 1.1 mrg
711 1.1 mrg (define_insn "vec_series<mode>"
712 1.1 mrg [(set (match_operand:SVE_I 0 "register_operand" "=w, w, w")
713 1.1 mrg (vec_series:SVE_I
714 1.1 mrg (match_operand:<VEL> 1 "aarch64_sve_index_operand" "Usi, r, r")
715 1.1 mrg (match_operand:<VEL> 2 "aarch64_sve_index_operand" "r, Usi, r")))]
716 1.1 mrg "TARGET_SVE"
717 1.1 mrg "@
718 1.1 mrg index\t%0.<Vetype>, #%1, %<vw>2
719 1.1 mrg index\t%0.<Vetype>, %<vw>1, #%2
720 1.1 mrg index\t%0.<Vetype>, %<vw>1, %<vw>2"
721 1.1 mrg )
722 1.1 mrg
723 1.1 mrg ;; Optimize {x, x, x, x, ...} + {0, n, 2*n, 3*n, ...} if n is in range
724 1.1 mrg ;; of an INDEX instruction.
725 1.1 mrg (define_insn "*vec_series<mode>_plus"
726 1.1 mrg [(set (match_operand:SVE_I 0 "register_operand" "=w")
727 1.1 mrg (plus:SVE_I
728 1.1 mrg (vec_duplicate:SVE_I
729 1.1 mrg (match_operand:<VEL> 1 "register_operand" "r"))
730 1.1 mrg (match_operand:SVE_I 2 "immediate_operand")))]
731 1.1 mrg "TARGET_SVE && aarch64_check_zero_based_sve_index_immediate (operands[2])"
732 1.1 mrg {
733 1.1 mrg operands[2] = aarch64_check_zero_based_sve_index_immediate (operands[2]);
734 1.1 mrg return "index\t%0.<Vetype>, %<vw>1, #%2";
735 1.1 mrg }
736 1.1 mrg )
737 1.1 mrg
738 1.1 mrg ;; Unpredicated LD[234].
739 1.1 mrg (define_expand "vec_load_lanes<mode><vsingle>"
740 1.1 mrg [(set (match_operand:SVE_STRUCT 0 "register_operand")
741 1.1 mrg (unspec:SVE_STRUCT
742 1.1 mrg [(match_dup 2)
743 1.1 mrg (match_operand:SVE_STRUCT 1 "memory_operand")]
744 1.1 mrg UNSPEC_LDN))]
745 1.1 mrg "TARGET_SVE"
746 1.1 mrg {
747 1.1 mrg operands[2] = force_reg (<VPRED>mode, CONSTM1_RTX (<VPRED>mode));
748 1.1 mrg }
749 1.1 mrg )
750 1.1 mrg
751 1.1 mrg ;; Predicated LD[234].
752 1.1 mrg (define_insn "vec_mask_load_lanes<mode><vsingle>"
753 1.1 mrg [(set (match_operand:SVE_STRUCT 0 "register_operand" "=w")
754 1.1 mrg (unspec:SVE_STRUCT
755 1.1 mrg [(match_operand:<VPRED> 2 "register_operand" "Upl")
756 1.1 mrg (match_operand:SVE_STRUCT 1 "memory_operand" "m")]
757 1.1 mrg UNSPEC_LDN))]
758 1.1 mrg "TARGET_SVE"
759 1.1 mrg "ld<vector_count><Vesize>\t%0, %2/z, %1"
760 1.1 mrg )
761 1.1 mrg
762 1.1 mrg ;; Unpredicated ST[234]. This is always a full update, so the dependence
763 1.1 mrg ;; on the old value of the memory location (via (match_dup 0)) is redundant.
764 1.1 mrg ;; There doesn't seem to be any obvious benefit to treating the all-true
765 1.1 mrg ;; case differently though. In particular, it's very unlikely that we'll
766 1.1 mrg ;; only find out during RTL that a store_lanes is dead.
767 1.1 mrg (define_expand "vec_store_lanes<mode><vsingle>"
768 1.1 mrg [(set (match_operand:SVE_STRUCT 0 "memory_operand")
769 1.1 mrg (unspec:SVE_STRUCT
770 1.1 mrg [(match_dup 2)
771 1.1 mrg (match_operand:SVE_STRUCT 1 "register_operand")
772 1.1 mrg (match_dup 0)]
773 1.1 mrg UNSPEC_STN))]
774 1.1 mrg "TARGET_SVE"
775 1.1 mrg {
776 1.1 mrg operands[2] = force_reg (<VPRED>mode, CONSTM1_RTX (<VPRED>mode));
777 1.1 mrg }
778 1.1 mrg )
779 1.1 mrg
780 1.1 mrg ;; Predicated ST[234].
781 1.1 mrg (define_insn "vec_mask_store_lanes<mode><vsingle>"
782 1.1 mrg [(set (match_operand:SVE_STRUCT 0 "memory_operand" "+m")
783 1.1 mrg (unspec:SVE_STRUCT
784 1.1 mrg [(match_operand:<VPRED> 2 "register_operand" "Upl")
785 1.1 mrg (match_operand:SVE_STRUCT 1 "register_operand" "w")
786 1.1 mrg (match_dup 0)]
787 1.1 mrg UNSPEC_STN))]
788 1.1 mrg "TARGET_SVE"
789 1.1 mrg "st<vector_count><Vesize>\t%1, %2, %0"
790 1.1 mrg )
791 1.1 mrg
792 1.1 mrg (define_expand "vec_perm<mode>"
793 1.1 mrg [(match_operand:SVE_ALL 0 "register_operand")
794 1.1 mrg (match_operand:SVE_ALL 1 "register_operand")
795 1.1 mrg (match_operand:SVE_ALL 2 "register_operand")
796 1.1 mrg (match_operand:<V_INT_EQUIV> 3 "aarch64_sve_vec_perm_operand")]
797 1.1 mrg "TARGET_SVE && GET_MODE_NUNITS (<MODE>mode).is_constant ()"
798 1.1 mrg {
799 1.1 mrg aarch64_expand_sve_vec_perm (operands[0], operands[1],
800 1.1 mrg operands[2], operands[3]);
801 1.1 mrg DONE;
802 1.1 mrg }
803 1.1 mrg )
804 1.1 mrg
805 1.1 mrg (define_insn "*aarch64_sve_tbl<mode>"
806 1.1 mrg [(set (match_operand:SVE_ALL 0 "register_operand" "=w")
807 1.1 mrg (unspec:SVE_ALL
808 1.1 mrg [(match_operand:SVE_ALL 1 "register_operand" "w")
809 1.1 mrg (match_operand:<V_INT_EQUIV> 2 "register_operand" "w")]
810 1.1 mrg UNSPEC_TBL))]
811 1.1 mrg "TARGET_SVE"
812 1.1 mrg "tbl\t%0.<Vetype>, %1.<Vetype>, %2.<Vetype>"
813 1.1 mrg )
814 1.1 mrg
815 1.1 mrg (define_insn "*aarch64_sve_<perm_insn><perm_hilo><mode>"
816 1.1 mrg [(set (match_operand:PRED_ALL 0 "register_operand" "=Upa")
817 1.1 mrg (unspec:PRED_ALL [(match_operand:PRED_ALL 1 "register_operand" "Upa")
818 1.1 mrg (match_operand:PRED_ALL 2 "register_operand" "Upa")]
819 1.1 mrg PERMUTE))]
820 1.1 mrg "TARGET_SVE"
821 1.1 mrg "<perm_insn><perm_hilo>\t%0.<Vetype>, %1.<Vetype>, %2.<Vetype>"
822 1.1 mrg )
823 1.1 mrg
824 1.1 mrg (define_insn "aarch64_sve_<perm_insn><perm_hilo><mode>"
825 1.1 mrg [(set (match_operand:SVE_ALL 0 "register_operand" "=w")
826 1.1 mrg (unspec:SVE_ALL [(match_operand:SVE_ALL 1 "register_operand" "w")
827 1.1 mrg (match_operand:SVE_ALL 2 "register_operand" "w")]
828 1.1 mrg PERMUTE))]
829 1.1 mrg "TARGET_SVE"
830 1.1 mrg "<perm_insn><perm_hilo>\t%0.<Vetype>, %1.<Vetype>, %2.<Vetype>"
831 1.1 mrg )
832 1.1 mrg
833 1.1 mrg (define_insn "*aarch64_sve_rev64<mode>"
834 1.1 mrg [(set (match_operand:SVE_BHS 0 "register_operand" "=w")
835 1.1 mrg (unspec:SVE_BHS
836 1.1 mrg [(match_operand:VNx2BI 1 "register_operand" "Upl")
837 1.1 mrg (unspec:SVE_BHS [(match_operand:SVE_BHS 2 "register_operand" "w")]
838 1.1 mrg UNSPEC_REV64)]
839 1.1 mrg UNSPEC_MERGE_PTRUE))]
840 1.1 mrg "TARGET_SVE"
841 1.1 mrg "rev<Vesize>\t%0.d, %1/m, %2.d"
842 1.1 mrg )
843 1.1 mrg
844 1.1 mrg (define_insn "*aarch64_sve_rev32<mode>"
845 1.1 mrg [(set (match_operand:SVE_BH 0 "register_operand" "=w")
846 1.1 mrg (unspec:SVE_BH
847 1.1 mrg [(match_operand:VNx4BI 1 "register_operand" "Upl")
848 1.1 mrg (unspec:SVE_BH [(match_operand:SVE_BH 2 "register_operand" "w")]
849 1.1 mrg UNSPEC_REV32)]
850 1.1 mrg UNSPEC_MERGE_PTRUE))]
851 1.1 mrg "TARGET_SVE"
852 1.1 mrg "rev<Vesize>\t%0.s, %1/m, %2.s"
853 1.1 mrg )
854 1.1 mrg
855 1.1 mrg (define_insn "*aarch64_sve_rev16vnx16qi"
856 1.1 mrg [(set (match_operand:VNx16QI 0 "register_operand" "=w")
857 1.1 mrg (unspec:VNx16QI
858 1.1 mrg [(match_operand:VNx8BI 1 "register_operand" "Upl")
859 1.1 mrg (unspec:VNx16QI [(match_operand:VNx16QI 2 "register_operand" "w")]
860 1.1 mrg UNSPEC_REV16)]
861 1.1 mrg UNSPEC_MERGE_PTRUE))]
862 1.1 mrg "TARGET_SVE"
863 1.1 mrg "revb\t%0.h, %1/m, %2.h"
864 1.1 mrg )
865 1.1 mrg
866 1.1 mrg (define_insn "*aarch64_sve_rev<mode>"
867 1.1 mrg [(set (match_operand:SVE_ALL 0 "register_operand" "=w")
868 1.1 mrg (unspec:SVE_ALL [(match_operand:SVE_ALL 1 "register_operand" "w")]
869 1.1 mrg UNSPEC_REV))]
870 1.1 mrg "TARGET_SVE"
871 1.1 mrg "rev\t%0.<Vetype>, %1.<Vetype>")
872 1.1 mrg
873 1.1 mrg (define_insn "*aarch64_sve_dup_lane<mode>"
874 1.1 mrg [(set (match_operand:SVE_ALL 0 "register_operand" "=w")
875 1.1 mrg (vec_duplicate:SVE_ALL
876 1.1 mrg (vec_select:<VEL>
877 1.1 mrg (match_operand:SVE_ALL 1 "register_operand" "w")
878 1.1 mrg (parallel [(match_operand:SI 2 "const_int_operand")]))))]
879 1.1 mrg "TARGET_SVE
880 1.1 mrg && IN_RANGE (INTVAL (operands[2]) * GET_MODE_SIZE (<VEL>mode), 0, 63)"
881 1.1 mrg "dup\t%0.<Vetype>, %1.<Vetype>[%2]"
882 1.1 mrg )
883 1.1 mrg
884 1.1 mrg ;; Note that the immediate (third) operand is the lane index not
885 1.1 mrg ;; the byte index.
886 1.1 mrg (define_insn "*aarch64_sve_ext<mode>"
887 1.1 mrg [(set (match_operand:SVE_ALL 0 "register_operand" "=w")
888 1.1 mrg (unspec:SVE_ALL [(match_operand:SVE_ALL 1 "register_operand" "0")
889 1.1 mrg (match_operand:SVE_ALL 2 "register_operand" "w")
890 1.1 mrg (match_operand:SI 3 "const_int_operand")]
891 1.1 mrg UNSPEC_EXT))]
892 1.1 mrg "TARGET_SVE
893 1.1 mrg && IN_RANGE (INTVAL (operands[3]) * GET_MODE_SIZE (<VEL>mode), 0, 255)"
894 1.1 mrg {
895 1.1 mrg operands[3] = GEN_INT (INTVAL (operands[3]) * GET_MODE_SIZE (<VEL>mode));
896 1.1 mrg return "ext\\t%0.b, %0.b, %2.b, #%3";
897 1.1 mrg }
898 1.1 mrg )
899 1.1 mrg
900 1.1 mrg (define_insn "add<mode>3"
901 1.1 mrg [(set (match_operand:SVE_I 0 "register_operand" "=w, w, w, w")
902 1.1 mrg (plus:SVE_I
903 1.1 mrg (match_operand:SVE_I 1 "register_operand" "%0, 0, 0, w")
904 1.1 mrg (match_operand:SVE_I 2 "aarch64_sve_add_operand" "vsa, vsn, vsi, w")))]
905 1.1 mrg "TARGET_SVE"
906 1.1 mrg "@
907 1.1 mrg add\t%0.<Vetype>, %0.<Vetype>, #%D2
908 1.1 mrg sub\t%0.<Vetype>, %0.<Vetype>, #%N2
909 1.1 mrg * return aarch64_output_sve_inc_dec_immediate (\"%0.<Vetype>\", operands[2]);
910 1.1 mrg add\t%0.<Vetype>, %1.<Vetype>, %2.<Vetype>"
911 1.1 mrg )
912 1.1 mrg
913 1.1 mrg (define_insn "sub<mode>3"
914 1.1 mrg [(set (match_operand:SVE_I 0 "register_operand" "=w, w")
915 1.1 mrg (minus:SVE_I
916 1.1 mrg (match_operand:SVE_I 1 "aarch64_sve_arith_operand" "w, vsa")
917 1.1 mrg (match_operand:SVE_I 2 "register_operand" "w, 0")))]
918 1.1 mrg "TARGET_SVE"
919 1.1 mrg "@
920 1.1 mrg sub\t%0.<Vetype>, %1.<Vetype>, %2.<Vetype>
921 1.1 mrg subr\t%0.<Vetype>, %0.<Vetype>, #%D1"
922 1.1 mrg )
923 1.1 mrg
924 1.1 mrg ;; Unpredicated multiplication.
925 1.1 mrg (define_expand "mul<mode>3"
926 1.1 mrg [(set (match_operand:SVE_I 0 "register_operand")
927 1.1 mrg (unspec:SVE_I
928 1.1 mrg [(match_dup 3)
929 1.1 mrg (mult:SVE_I
930 1.1 mrg (match_operand:SVE_I 1 "register_operand")
931 1.1 mrg (match_operand:SVE_I 2 "aarch64_sve_mul_operand"))]
932 1.1 mrg UNSPEC_MERGE_PTRUE))]
933 1.1 mrg "TARGET_SVE"
934 1.1 mrg {
935 1.1 mrg operands[3] = force_reg (<VPRED>mode, CONSTM1_RTX (<VPRED>mode));
936 1.1 mrg }
937 1.1 mrg )
938 1.1 mrg
939 1.1 mrg ;; Multiplication predicated with a PTRUE. We don't actually need the
940 1.1 mrg ;; predicate for the first alternative, but using Upa or X isn't likely
941 1.1 mrg ;; to gain much and would make the instruction seem less uniform to the
942 1.1 mrg ;; register allocator.
943 1.1.1.2 mrg (define_insn_and_split "*mul<mode>3"
944 1.1.1.2 mrg [(set (match_operand:SVE_I 0 "register_operand" "=w, w, ?&w")
945 1.1 mrg (unspec:SVE_I
946 1.1.1.2 mrg [(match_operand:<VPRED> 1 "register_operand" "Upl, Upl, Upl")
947 1.1 mrg (mult:SVE_I
948 1.1.1.2 mrg (match_operand:SVE_I 2 "register_operand" "%0, 0, w")
949 1.1.1.2 mrg (match_operand:SVE_I 3 "aarch64_sve_mul_operand" "vsm, w, w"))]
950 1.1 mrg UNSPEC_MERGE_PTRUE))]
951 1.1 mrg "TARGET_SVE"
952 1.1 mrg "@
953 1.1.1.2 mrg #
954 1.1.1.2 mrg mul\t%0.<Vetype>, %1/m, %0.<Vetype>, %3.<Vetype>
955 1.1.1.2 mrg movprfx\t%0, %2\;mul\t%0.<Vetype>, %1/m, %0.<Vetype>, %3.<Vetype>"
956 1.1.1.2 mrg ; Split the unpredicated form after reload, so that we don't have
957 1.1.1.2 mrg ; the unnecessary PTRUE.
958 1.1.1.2 mrg "&& reload_completed
959 1.1.1.2 mrg && !register_operand (operands[3], <MODE>mode)"
960 1.1.1.2 mrg [(set (match_dup 0) (mult:SVE_I (match_dup 2) (match_dup 3)))]
961 1.1.1.2 mrg ""
962 1.1.1.2 mrg [(set_attr "movprfx" "*,*,yes")]
963 1.1.1.2 mrg )
964 1.1.1.2 mrg
965 1.1.1.2 mrg ;; Unpredicated multiplications by a constant (post-RA only).
966 1.1.1.2 mrg ;; These are generated by splitting a predicated instruction whose
967 1.1.1.2 mrg ;; predicate is unused.
968 1.1.1.2 mrg (define_insn "*post_ra_mul<mode>3"
969 1.1.1.2 mrg [(set (match_operand:SVE_I 0 "register_operand" "=w")
970 1.1.1.2 mrg (mult:SVE_I
971 1.1.1.2 mrg (match_operand:SVE_I 1 "register_operand" "0")
972 1.1.1.2 mrg (match_operand:SVE_I 2 "aarch64_sve_mul_immediate")))]
973 1.1.1.2 mrg "TARGET_SVE && reload_completed"
974 1.1.1.2 mrg "mul\t%0.<Vetype>, %0.<Vetype>, #%2"
975 1.1 mrg )
976 1.1 mrg
977 1.1 mrg (define_insn "*madd<mode>"
978 1.1.1.2 mrg [(set (match_operand:SVE_I 0 "register_operand" "=w, w, ?&w")
979 1.1 mrg (plus:SVE_I
980 1.1 mrg (unspec:SVE_I
981 1.1.1.2 mrg [(match_operand:<VPRED> 1 "register_operand" "Upl, Upl, Upl")
982 1.1.1.2 mrg (mult:SVE_I (match_operand:SVE_I 2 "register_operand" "%0, w, w")
983 1.1.1.2 mrg (match_operand:SVE_I 3 "register_operand" "w, w, w"))]
984 1.1 mrg UNSPEC_MERGE_PTRUE)
985 1.1.1.2 mrg (match_operand:SVE_I 4 "register_operand" "w, 0, w")))]
986 1.1 mrg "TARGET_SVE"
987 1.1 mrg "@
988 1.1 mrg mad\t%0.<Vetype>, %1/m, %3.<Vetype>, %4.<Vetype>
989 1.1.1.2 mrg mla\t%0.<Vetype>, %1/m, %2.<Vetype>, %3.<Vetype>
990 1.1.1.2 mrg movprfx\t%0, %4\;mla\t%0.<Vetype>, %1/m, %2.<Vetype>, %3.<Vetype>"
991 1.1.1.2 mrg [(set_attr "movprfx" "*,*,yes")]
992 1.1 mrg )
993 1.1 mrg
994 1.1 mrg (define_insn "*msub<mode>3"
995 1.1.1.2 mrg [(set (match_operand:SVE_I 0 "register_operand" "=w, w, ?&w")
996 1.1 mrg (minus:SVE_I
997 1.1.1.2 mrg (match_operand:SVE_I 4 "register_operand" "w, 0, w")
998 1.1 mrg (unspec:SVE_I
999 1.1.1.2 mrg [(match_operand:<VPRED> 1 "register_operand" "Upl, Upl, Upl")
1000 1.1.1.2 mrg (mult:SVE_I (match_operand:SVE_I 2 "register_operand" "%0, w, w")
1001 1.1.1.2 mrg (match_operand:SVE_I 3 "register_operand" "w, w, w"))]
1002 1.1 mrg UNSPEC_MERGE_PTRUE)))]
1003 1.1 mrg "TARGET_SVE"
1004 1.1 mrg "@
1005 1.1 mrg msb\t%0.<Vetype>, %1/m, %3.<Vetype>, %4.<Vetype>
1006 1.1.1.2 mrg mls\t%0.<Vetype>, %1/m, %2.<Vetype>, %3.<Vetype>
1007 1.1.1.2 mrg movprfx\t%0, %4\;mls\t%0.<Vetype>, %1/m, %2.<Vetype>, %3.<Vetype>"
1008 1.1.1.2 mrg [(set_attr "movprfx" "*,*,yes")]
1009 1.1 mrg )
1010 1.1 mrg
1011 1.1 mrg ;; Unpredicated highpart multiplication.
1012 1.1 mrg (define_expand "<su>mul<mode>3_highpart"
1013 1.1 mrg [(set (match_operand:SVE_I 0 "register_operand")
1014 1.1 mrg (unspec:SVE_I
1015 1.1 mrg [(match_dup 3)
1016 1.1 mrg (unspec:SVE_I [(match_operand:SVE_I 1 "register_operand")
1017 1.1 mrg (match_operand:SVE_I 2 "register_operand")]
1018 1.1 mrg MUL_HIGHPART)]
1019 1.1 mrg UNSPEC_MERGE_PTRUE))]
1020 1.1 mrg "TARGET_SVE"
1021 1.1 mrg {
1022 1.1 mrg operands[3] = force_reg (<VPRED>mode, CONSTM1_RTX (<VPRED>mode));
1023 1.1 mrg }
1024 1.1 mrg )
1025 1.1 mrg
1026 1.1 mrg ;; Predicated highpart multiplication.
1027 1.1 mrg (define_insn "*<su>mul<mode>3_highpart"
1028 1.1.1.2 mrg [(set (match_operand:SVE_I 0 "register_operand" "=w, ?&w")
1029 1.1 mrg (unspec:SVE_I
1030 1.1.1.2 mrg [(match_operand:<VPRED> 1 "register_operand" "Upl, Upl")
1031 1.1.1.2 mrg (unspec:SVE_I [(match_operand:SVE_I 2 "register_operand" "%0, w")
1032 1.1.1.2 mrg (match_operand:SVE_I 3 "register_operand" "w, w")]
1033 1.1 mrg MUL_HIGHPART)]
1034 1.1 mrg UNSPEC_MERGE_PTRUE))]
1035 1.1 mrg "TARGET_SVE"
1036 1.1.1.2 mrg "@
1037 1.1.1.2 mrg <su>mulh\t%0.<Vetype>, %1/m, %0.<Vetype>, %3.<Vetype>
1038 1.1.1.2 mrg movprfx\t%0, %2\;<su>mulh\t%0.<Vetype>, %1/m, %0.<Vetype>, %3.<Vetype>"
1039 1.1.1.2 mrg [(set_attr "movprfx" "*,yes")]
1040 1.1.1.2 mrg )
1041 1.1.1.2 mrg
1042 1.1.1.2 mrg ;; Unpredicated division.
1043 1.1.1.2 mrg (define_expand "<optab><mode>3"
1044 1.1.1.2 mrg [(set (match_operand:SVE_SDI 0 "register_operand")
1045 1.1.1.2 mrg (unspec:SVE_SDI
1046 1.1.1.2 mrg [(match_dup 3)
1047 1.1.1.2 mrg (SVE_INT_BINARY_SD:SVE_SDI
1048 1.1.1.2 mrg (match_operand:SVE_SDI 1 "register_operand")
1049 1.1.1.2 mrg (match_operand:SVE_SDI 2 "register_operand"))]
1050 1.1.1.2 mrg UNSPEC_MERGE_PTRUE))]
1051 1.1.1.2 mrg "TARGET_SVE"
1052 1.1.1.2 mrg {
1053 1.1.1.2 mrg operands[3] = force_reg (<VPRED>mode, CONSTM1_RTX (<VPRED>mode));
1054 1.1.1.2 mrg }
1055 1.1.1.2 mrg )
1056 1.1.1.2 mrg
1057 1.1.1.2 mrg ;; Division predicated with a PTRUE.
1058 1.1.1.2 mrg (define_insn "*<optab><mode>3"
1059 1.1.1.2 mrg [(set (match_operand:SVE_SDI 0 "register_operand" "=w, w, ?&w")
1060 1.1.1.2 mrg (unspec:SVE_SDI
1061 1.1.1.2 mrg [(match_operand:<VPRED> 1 "register_operand" "Upl, Upl, Upl")
1062 1.1.1.2 mrg (SVE_INT_BINARY_SD:SVE_SDI
1063 1.1.1.2 mrg (match_operand:SVE_SDI 2 "register_operand" "0, w, w")
1064 1.1.1.2 mrg (match_operand:SVE_SDI 3 "aarch64_sve_mul_operand" "w, 0, w"))]
1065 1.1.1.2 mrg UNSPEC_MERGE_PTRUE))]
1066 1.1.1.2 mrg "TARGET_SVE"
1067 1.1.1.2 mrg "@
1068 1.1.1.2 mrg <sve_int_op>\t%0.<Vetype>, %1/m, %0.<Vetype>, %3.<Vetype>
1069 1.1.1.2 mrg <sve_int_op>r\t%0.<Vetype>, %1/m, %0.<Vetype>, %2.<Vetype>
1070 1.1.1.2 mrg movprfx\t%0, %2\;<sve_int_op>\t%0.<Vetype>, %1/m, %0.<Vetype>, %3.<Vetype>"
1071 1.1.1.2 mrg [(set_attr "movprfx" "*,*,yes")]
1072 1.1 mrg )
1073 1.1 mrg
1074 1.1 mrg ;; Unpredicated NEG, NOT and POPCOUNT.
1075 1.1 mrg (define_expand "<optab><mode>2"
1076 1.1 mrg [(set (match_operand:SVE_I 0 "register_operand")
1077 1.1 mrg (unspec:SVE_I
1078 1.1 mrg [(match_dup 2)
1079 1.1 mrg (SVE_INT_UNARY:SVE_I (match_operand:SVE_I 1 "register_operand"))]
1080 1.1 mrg UNSPEC_MERGE_PTRUE))]
1081 1.1 mrg "TARGET_SVE"
1082 1.1 mrg {
1083 1.1 mrg operands[2] = force_reg (<VPRED>mode, CONSTM1_RTX (<VPRED>mode));
1084 1.1 mrg }
1085 1.1 mrg )
1086 1.1 mrg
1087 1.1 mrg ;; NEG, NOT and POPCOUNT predicated with a PTRUE.
1088 1.1 mrg (define_insn "*<optab><mode>2"
1089 1.1 mrg [(set (match_operand:SVE_I 0 "register_operand" "=w")
1090 1.1 mrg (unspec:SVE_I
1091 1.1 mrg [(match_operand:<VPRED> 1 "register_operand" "Upl")
1092 1.1 mrg (SVE_INT_UNARY:SVE_I
1093 1.1 mrg (match_operand:SVE_I 2 "register_operand" "w"))]
1094 1.1 mrg UNSPEC_MERGE_PTRUE))]
1095 1.1 mrg "TARGET_SVE"
1096 1.1 mrg "<sve_int_op>\t%0.<Vetype>, %1/m, %2.<Vetype>"
1097 1.1 mrg )
1098 1.1 mrg
1099 1.1 mrg ;; Vector AND, ORR and XOR.
1100 1.1 mrg (define_insn "<optab><mode>3"
1101 1.1 mrg [(set (match_operand:SVE_I 0 "register_operand" "=w, w")
1102 1.1 mrg (LOGICAL:SVE_I
1103 1.1 mrg (match_operand:SVE_I 1 "register_operand" "%0, w")
1104 1.1 mrg (match_operand:SVE_I 2 "aarch64_sve_logical_operand" "vsl, w")))]
1105 1.1 mrg "TARGET_SVE"
1106 1.1 mrg "@
1107 1.1 mrg <logical>\t%0.<Vetype>, %0.<Vetype>, #%C2
1108 1.1 mrg <logical>\t%0.d, %1.d, %2.d"
1109 1.1 mrg )
1110 1.1 mrg
1111 1.1 mrg ;; Vector AND, ORR and XOR on floating-point modes. We avoid subregs
1112 1.1 mrg ;; by providing this, but we need to use UNSPECs since rtx logical ops
1113 1.1 mrg ;; aren't defined for floating-point modes.
1114 1.1 mrg (define_insn "*<optab><mode>3"
1115 1.1 mrg [(set (match_operand:SVE_F 0 "register_operand" "=w")
1116 1.1 mrg (unspec:SVE_F [(match_operand:SVE_F 1 "register_operand" "w")
1117 1.1 mrg (match_operand:SVE_F 2 "register_operand" "w")]
1118 1.1 mrg LOGICALF))]
1119 1.1 mrg "TARGET_SVE"
1120 1.1 mrg "<logicalf_op>\t%0.d, %1.d, %2.d"
1121 1.1 mrg )
1122 1.1 mrg
1123 1.1 mrg ;; REG_EQUAL notes on "not<mode>3" should ensure that we can generate
1124 1.1 mrg ;; this pattern even though the NOT instruction itself is predicated.
1125 1.1 mrg (define_insn "bic<mode>3"
1126 1.1 mrg [(set (match_operand:SVE_I 0 "register_operand" "=w")
1127 1.1 mrg (and:SVE_I
1128 1.1 mrg (not:SVE_I (match_operand:SVE_I 1 "register_operand" "w"))
1129 1.1 mrg (match_operand:SVE_I 2 "register_operand" "w")))]
1130 1.1 mrg "TARGET_SVE"
1131 1.1 mrg "bic\t%0.d, %2.d, %1.d"
1132 1.1 mrg )
1133 1.1 mrg
1134 1.1 mrg ;; Predicate AND. We can reuse one of the inputs as the GP.
1135 1.1 mrg (define_insn "and<mode>3"
1136 1.1 mrg [(set (match_operand:PRED_ALL 0 "register_operand" "=Upa")
1137 1.1 mrg (and:PRED_ALL (match_operand:PRED_ALL 1 "register_operand" "Upa")
1138 1.1 mrg (match_operand:PRED_ALL 2 "register_operand" "Upa")))]
1139 1.1 mrg "TARGET_SVE"
1140 1.1 mrg "and\t%0.b, %1/z, %1.b, %2.b"
1141 1.1 mrg )
1142 1.1 mrg
1143 1.1 mrg ;; Unpredicated predicate ORR and XOR.
1144 1.1 mrg (define_expand "<optab><mode>3"
1145 1.1 mrg [(set (match_operand:PRED_ALL 0 "register_operand")
1146 1.1 mrg (and:PRED_ALL
1147 1.1 mrg (LOGICAL_OR:PRED_ALL
1148 1.1 mrg (match_operand:PRED_ALL 1 "register_operand")
1149 1.1 mrg (match_operand:PRED_ALL 2 "register_operand"))
1150 1.1 mrg (match_dup 3)))]
1151 1.1 mrg "TARGET_SVE"
1152 1.1 mrg {
1153 1.1 mrg operands[3] = force_reg (<MODE>mode, CONSTM1_RTX (<MODE>mode));
1154 1.1 mrg }
1155 1.1 mrg )
1156 1.1 mrg
1157 1.1 mrg ;; Predicated predicate ORR and XOR.
1158 1.1 mrg (define_insn "pred_<optab><mode>3"
1159 1.1 mrg [(set (match_operand:PRED_ALL 0 "register_operand" "=Upa")
1160 1.1 mrg (and:PRED_ALL
1161 1.1 mrg (LOGICAL:PRED_ALL
1162 1.1 mrg (match_operand:PRED_ALL 2 "register_operand" "Upa")
1163 1.1 mrg (match_operand:PRED_ALL 3 "register_operand" "Upa"))
1164 1.1 mrg (match_operand:PRED_ALL 1 "register_operand" "Upa")))]
1165 1.1 mrg "TARGET_SVE"
1166 1.1 mrg "<logical>\t%0.b, %1/z, %2.b, %3.b"
1167 1.1 mrg )
1168 1.1 mrg
1169 1.1 mrg ;; Perform a logical operation on operands 2 and 3, using operand 1 as
1170 1.1 mrg ;; the GP (which is known to be a PTRUE). Store the result in operand 0
1171 1.1 mrg ;; and set the flags in the same way as for PTEST. The (and ...) in the
1172 1.1 mrg ;; UNSPEC_PTEST_PTRUE is logically redundant, but means that the tested
1173 1.1 mrg ;; value is structurally equivalent to rhs of the second set.
1174 1.1 mrg (define_insn "*<optab><mode>3_cc"
1175 1.1 mrg [(set (reg:CC CC_REGNUM)
1176 1.1 mrg (compare:CC
1177 1.1 mrg (unspec:SI [(match_operand:PRED_ALL 1 "register_operand" "Upa")
1178 1.1 mrg (and:PRED_ALL
1179 1.1 mrg (LOGICAL:PRED_ALL
1180 1.1 mrg (match_operand:PRED_ALL 2 "register_operand" "Upa")
1181 1.1 mrg (match_operand:PRED_ALL 3 "register_operand" "Upa"))
1182 1.1 mrg (match_dup 1))]
1183 1.1 mrg UNSPEC_PTEST_PTRUE)
1184 1.1 mrg (const_int 0)))
1185 1.1 mrg (set (match_operand:PRED_ALL 0 "register_operand" "=Upa")
1186 1.1 mrg (and:PRED_ALL (LOGICAL:PRED_ALL (match_dup 2) (match_dup 3))
1187 1.1 mrg (match_dup 1)))]
1188 1.1 mrg "TARGET_SVE"
1189 1.1 mrg "<logical>s\t%0.b, %1/z, %2.b, %3.b"
1190 1.1 mrg )
1191 1.1 mrg
1192 1.1 mrg ;; Unpredicated predicate inverse.
1193 1.1 mrg (define_expand "one_cmpl<mode>2"
1194 1.1 mrg [(set (match_operand:PRED_ALL 0 "register_operand")
1195 1.1 mrg (and:PRED_ALL
1196 1.1 mrg (not:PRED_ALL (match_operand:PRED_ALL 1 "register_operand"))
1197 1.1 mrg (match_dup 2)))]
1198 1.1 mrg "TARGET_SVE"
1199 1.1 mrg {
1200 1.1 mrg operands[2] = force_reg (<MODE>mode, CONSTM1_RTX (<MODE>mode));
1201 1.1 mrg }
1202 1.1 mrg )
1203 1.1 mrg
1204 1.1 mrg ;; Predicated predicate inverse.
1205 1.1 mrg (define_insn "*one_cmpl<mode>3"
1206 1.1 mrg [(set (match_operand:PRED_ALL 0 "register_operand" "=Upa")
1207 1.1 mrg (and:PRED_ALL
1208 1.1 mrg (not:PRED_ALL (match_operand:PRED_ALL 2 "register_operand" "Upa"))
1209 1.1 mrg (match_operand:PRED_ALL 1 "register_operand" "Upa")))]
1210 1.1 mrg "TARGET_SVE"
1211 1.1 mrg "not\t%0.b, %1/z, %2.b"
1212 1.1 mrg )
1213 1.1 mrg
1214 1.1 mrg ;; Predicated predicate BIC and ORN.
1215 1.1 mrg (define_insn "*<nlogical><mode>3"
1216 1.1 mrg [(set (match_operand:PRED_ALL 0 "register_operand" "=Upa")
1217 1.1 mrg (and:PRED_ALL
1218 1.1 mrg (NLOGICAL:PRED_ALL
1219 1.1 mrg (not:PRED_ALL (match_operand:PRED_ALL 2 "register_operand" "Upa"))
1220 1.1 mrg (match_operand:PRED_ALL 3 "register_operand" "Upa"))
1221 1.1 mrg (match_operand:PRED_ALL 1 "register_operand" "Upa")))]
1222 1.1 mrg "TARGET_SVE"
1223 1.1 mrg "<nlogical>\t%0.b, %1/z, %3.b, %2.b"
1224 1.1 mrg )
1225 1.1 mrg
1226 1.1 mrg ;; Predicated predicate NAND and NOR.
1227 1.1 mrg (define_insn "*<logical_nn><mode>3"
1228 1.1 mrg [(set (match_operand:PRED_ALL 0 "register_operand" "=Upa")
1229 1.1 mrg (and:PRED_ALL
1230 1.1 mrg (NLOGICAL:PRED_ALL
1231 1.1 mrg (not:PRED_ALL (match_operand:PRED_ALL 2 "register_operand" "Upa"))
1232 1.1 mrg (not:PRED_ALL (match_operand:PRED_ALL 3 "register_operand" "Upa")))
1233 1.1 mrg (match_operand:PRED_ALL 1 "register_operand" "Upa")))]
1234 1.1 mrg "TARGET_SVE"
1235 1.1 mrg "<logical_nn>\t%0.b, %1/z, %2.b, %3.b"
1236 1.1 mrg )
1237 1.1 mrg
1238 1.1 mrg ;; Unpredicated LSL, LSR and ASR by a vector.
1239 1.1 mrg (define_expand "v<optab><mode>3"
1240 1.1 mrg [(set (match_operand:SVE_I 0 "register_operand")
1241 1.1 mrg (unspec:SVE_I
1242 1.1 mrg [(match_dup 3)
1243 1.1 mrg (ASHIFT:SVE_I
1244 1.1 mrg (match_operand:SVE_I 1 "register_operand")
1245 1.1 mrg (match_operand:SVE_I 2 "aarch64_sve_<lr>shift_operand"))]
1246 1.1 mrg UNSPEC_MERGE_PTRUE))]
1247 1.1 mrg "TARGET_SVE"
1248 1.1 mrg {
1249 1.1 mrg operands[3] = force_reg (<VPRED>mode, CONSTM1_RTX (<VPRED>mode));
1250 1.1 mrg }
1251 1.1 mrg )
1252 1.1 mrg
1253 1.1 mrg ;; LSL, LSR and ASR by a vector, predicated with a PTRUE. We don't
1254 1.1 mrg ;; actually need the predicate for the first alternative, but using Upa
1255 1.1 mrg ;; or X isn't likely to gain much and would make the instruction seem
1256 1.1 mrg ;; less uniform to the register allocator.
1257 1.1.1.2 mrg (define_insn_and_split "*v<optab><mode>3"
1258 1.1.1.2 mrg [(set (match_operand:SVE_I 0 "register_operand" "=w, w, ?&w")
1259 1.1 mrg (unspec:SVE_I
1260 1.1.1.2 mrg [(match_operand:<VPRED> 1 "register_operand" "Upl, Upl, Upl")
1261 1.1 mrg (ASHIFT:SVE_I
1262 1.1.1.2 mrg (match_operand:SVE_I 2 "register_operand" "w, 0, w")
1263 1.1.1.2 mrg (match_operand:SVE_I 3 "aarch64_sve_<lr>shift_operand" "D<lr>, w, w"))]
1264 1.1 mrg UNSPEC_MERGE_PTRUE))]
1265 1.1 mrg "TARGET_SVE"
1266 1.1 mrg "@
1267 1.1.1.2 mrg #
1268 1.1.1.2 mrg <shift>\t%0.<Vetype>, %1/m, %0.<Vetype>, %3.<Vetype>
1269 1.1.1.2 mrg movprfx\t%0, %2\;<shift>\t%0.<Vetype>, %1/m, %0.<Vetype>, %3.<Vetype>"
1270 1.1.1.2 mrg "&& reload_completed
1271 1.1.1.2 mrg && !register_operand (operands[3], <MODE>mode)"
1272 1.1.1.2 mrg [(set (match_dup 0) (ASHIFT:SVE_I (match_dup 2) (match_dup 3)))]
1273 1.1.1.2 mrg ""
1274 1.1.1.2 mrg [(set_attr "movprfx" "*,*,yes")]
1275 1.1.1.2 mrg )
1276 1.1.1.2 mrg
1277 1.1.1.2 mrg ;; Unpredicated shift operations by a constant (post-RA only).
1278 1.1.1.2 mrg ;; These are generated by splitting a predicated instruction whose
1279 1.1.1.2 mrg ;; predicate is unused.
1280 1.1.1.2 mrg (define_insn "*post_ra_v<optab><mode>3"
1281 1.1.1.2 mrg [(set (match_operand:SVE_I 0 "register_operand" "=w")
1282 1.1.1.2 mrg (ASHIFT:SVE_I
1283 1.1.1.2 mrg (match_operand:SVE_I 1 "register_operand" "w")
1284 1.1.1.2 mrg (match_operand:SVE_I 2 "aarch64_simd_<lr>shift_imm")))]
1285 1.1.1.2 mrg "TARGET_SVE && reload_completed"
1286 1.1.1.2 mrg "<shift>\t%0.<Vetype>, %1.<Vetype>, #%2"
1287 1.1 mrg )
1288 1.1 mrg
1289 1.1 mrg ;; LSL, LSR and ASR by a scalar, which expands into one of the vector
1290 1.1 mrg ;; shifts above.
1291 1.1 mrg (define_expand "<ASHIFT:optab><mode>3"
1292 1.1 mrg [(set (match_operand:SVE_I 0 "register_operand")
1293 1.1 mrg (ASHIFT:SVE_I (match_operand:SVE_I 1 "register_operand")
1294 1.1 mrg (match_operand:<VEL> 2 "general_operand")))]
1295 1.1 mrg "TARGET_SVE"
1296 1.1 mrg {
1297 1.1 mrg rtx amount;
1298 1.1 mrg if (CONST_INT_P (operands[2]))
1299 1.1 mrg {
1300 1.1 mrg amount = gen_const_vec_duplicate (<MODE>mode, operands[2]);
1301 1.1 mrg if (!aarch64_sve_<lr>shift_operand (operands[2], <MODE>mode))
1302 1.1 mrg amount = force_reg (<MODE>mode, amount);
1303 1.1 mrg }
1304 1.1 mrg else
1305 1.1 mrg {
1306 1.1 mrg amount = gen_reg_rtx (<MODE>mode);
1307 1.1 mrg emit_insn (gen_vec_duplicate<mode> (amount,
1308 1.1 mrg convert_to_mode (<VEL>mode,
1309 1.1 mrg operands[2], 0)));
1310 1.1 mrg }
1311 1.1 mrg emit_insn (gen_v<optab><mode>3 (operands[0], operands[1], amount));
1312 1.1 mrg DONE;
1313 1.1 mrg }
1314 1.1 mrg )
1315 1.1 mrg
1316 1.1 mrg ;; Test all bits of operand 1. Operand 0 is a GP that is known to hold PTRUE.
1317 1.1 mrg ;;
1318 1.1 mrg ;; Using UNSPEC_PTEST_PTRUE allows combine patterns to assume that the GP
1319 1.1 mrg ;; is a PTRUE even if the optimizers haven't yet been able to propagate
1320 1.1 mrg ;; the constant. We would use a separate unspec code for PTESTs involving
1321 1.1 mrg ;; GPs that might not be PTRUEs.
1322 1.1 mrg (define_insn "ptest_ptrue<mode>"
1323 1.1 mrg [(set (reg:CC CC_REGNUM)
1324 1.1 mrg (compare:CC
1325 1.1 mrg (unspec:SI [(match_operand:PRED_ALL 0 "register_operand" "Upa")
1326 1.1 mrg (match_operand:PRED_ALL 1 "register_operand" "Upa")]
1327 1.1 mrg UNSPEC_PTEST_PTRUE)
1328 1.1 mrg (const_int 0)))]
1329 1.1 mrg "TARGET_SVE"
1330 1.1 mrg "ptest\t%0, %1.b"
1331 1.1 mrg )
1332 1.1 mrg
1333 1.1 mrg ;; Set element I of the result if operand1 + J < operand2 for all J in [0, I].
1334 1.1 mrg ;; with the comparison being unsigned.
1335 1.1 mrg (define_insn "while_ult<GPI:mode><PRED_ALL:mode>"
1336 1.1 mrg [(set (match_operand:PRED_ALL 0 "register_operand" "=Upa")
1337 1.1 mrg (unspec:PRED_ALL [(match_operand:GPI 1 "aarch64_reg_or_zero" "rZ")
1338 1.1 mrg (match_operand:GPI 2 "aarch64_reg_or_zero" "rZ")]
1339 1.1 mrg UNSPEC_WHILE_LO))
1340 1.1 mrg (clobber (reg:CC CC_REGNUM))]
1341 1.1 mrg "TARGET_SVE"
1342 1.1 mrg "whilelo\t%0.<PRED_ALL:Vetype>, %<w>1, %<w>2"
1343 1.1 mrg )
1344 1.1 mrg
1345 1.1 mrg ;; WHILELO sets the flags in the same way as a PTEST with a PTRUE GP.
1346 1.1 mrg ;; Handle the case in which both results are useful. The GP operand
1347 1.1 mrg ;; to the PTEST isn't needed, so we allow it to be anything.
1348 1.1 mrg (define_insn_and_split "while_ult<GPI:mode><PRED_ALL:mode>_cc"
1349 1.1 mrg [(set (reg:CC CC_REGNUM)
1350 1.1 mrg (compare:CC
1351 1.1 mrg (unspec:SI [(match_operand:PRED_ALL 1)
1352 1.1 mrg (unspec:PRED_ALL
1353 1.1 mrg [(match_operand:GPI 2 "aarch64_reg_or_zero" "rZ")
1354 1.1 mrg (match_operand:GPI 3 "aarch64_reg_or_zero" "rZ")]
1355 1.1 mrg UNSPEC_WHILE_LO)]
1356 1.1 mrg UNSPEC_PTEST_PTRUE)
1357 1.1 mrg (const_int 0)))
1358 1.1 mrg (set (match_operand:PRED_ALL 0 "register_operand" "=Upa")
1359 1.1 mrg (unspec:PRED_ALL [(match_dup 2)
1360 1.1 mrg (match_dup 3)]
1361 1.1 mrg UNSPEC_WHILE_LO))]
1362 1.1 mrg "TARGET_SVE"
1363 1.1 mrg "whilelo\t%0.<PRED_ALL:Vetype>, %<w>2, %<w>3"
1364 1.1 mrg ;; Force the compiler to drop the unused predicate operand, so that we
1365 1.1 mrg ;; don't have an unnecessary PTRUE.
1366 1.1 mrg "&& !CONSTANT_P (operands[1])"
1367 1.1 mrg [(const_int 0)]
1368 1.1 mrg {
1369 1.1 mrg emit_insn (gen_while_ult<GPI:mode><PRED_ALL:mode>_cc
1370 1.1 mrg (operands[0], CONSTM1_RTX (<MODE>mode),
1371 1.1 mrg operands[2], operands[3]));
1372 1.1 mrg DONE;
1373 1.1 mrg }
1374 1.1 mrg )
1375 1.1 mrg
1376 1.1.1.2 mrg ;; Integer comparisons predicated with a PTRUE.
1377 1.1.1.2 mrg (define_insn "*cmp<cmp_op><mode>"
1378 1.1 mrg [(set (match_operand:<VPRED> 0 "register_operand" "=Upa, Upa")
1379 1.1 mrg (unspec:<VPRED>
1380 1.1 mrg [(match_operand:<VPRED> 1 "register_operand" "Upl, Upl")
1381 1.1.1.2 mrg (SVE_INT_CMP:<VPRED>
1382 1.1.1.2 mrg (match_operand:SVE_I 2 "register_operand" "w, w")
1383 1.1.1.2 mrg (match_operand:SVE_I 3 "aarch64_sve_cmp_<sve_imm_con>_operand" "<sve_imm_con>, w"))]
1384 1.1.1.2 mrg UNSPEC_MERGE_PTRUE))
1385 1.1 mrg (clobber (reg:CC CC_REGNUM))]
1386 1.1 mrg "TARGET_SVE"
1387 1.1 mrg "@
1388 1.1 mrg cmp<cmp_op>\t%0.<Vetype>, %1/z, %2.<Vetype>, #%3
1389 1.1 mrg cmp<cmp_op>\t%0.<Vetype>, %1/z, %2.<Vetype>, %3.<Vetype>"
1390 1.1 mrg )
1391 1.1 mrg
1392 1.1.1.2 mrg ;; Integer comparisons predicated with a PTRUE in which only the flags result
1393 1.1.1.2 mrg ;; is interesting.
1394 1.1.1.2 mrg (define_insn "*cmp<cmp_op><mode>_ptest"
1395 1.1 mrg [(set (reg:CC CC_REGNUM)
1396 1.1 mrg (compare:CC
1397 1.1 mrg (unspec:SI
1398 1.1 mrg [(match_operand:<VPRED> 1 "register_operand" "Upl, Upl")
1399 1.1 mrg (unspec:<VPRED>
1400 1.1 mrg [(match_dup 1)
1401 1.1.1.2 mrg (SVE_INT_CMP:<VPRED>
1402 1.1.1.2 mrg (match_operand:SVE_I 2 "register_operand" "w, w")
1403 1.1.1.2 mrg (match_operand:SVE_I 3 "aarch64_sve_cmp_<sve_imm_con>_operand" "<sve_imm_con>, w"))]
1404 1.1.1.2 mrg UNSPEC_MERGE_PTRUE)]
1405 1.1 mrg UNSPEC_PTEST_PTRUE)
1406 1.1 mrg (const_int 0)))
1407 1.1 mrg (clobber (match_scratch:<VPRED> 0 "=Upa, Upa"))]
1408 1.1 mrg "TARGET_SVE"
1409 1.1 mrg "@
1410 1.1 mrg cmp<cmp_op>\t%0.<Vetype>, %1/z, %2.<Vetype>, #%3
1411 1.1 mrg cmp<cmp_op>\t%0.<Vetype>, %1/z, %2.<Vetype>, %3.<Vetype>"
1412 1.1 mrg )
1413 1.1 mrg
1414 1.1.1.2 mrg ;; Integer comparisons predicated with a PTRUE in which both the flag and
1415 1.1.1.2 mrg ;; predicate results are interesting.
1416 1.1.1.2 mrg (define_insn "*cmp<cmp_op><mode>_cc"
1417 1.1 mrg [(set (reg:CC CC_REGNUM)
1418 1.1 mrg (compare:CC
1419 1.1 mrg (unspec:SI
1420 1.1 mrg [(match_operand:<VPRED> 1 "register_operand" "Upl, Upl")
1421 1.1 mrg (unspec:<VPRED>
1422 1.1 mrg [(match_dup 1)
1423 1.1.1.2 mrg (SVE_INT_CMP:<VPRED>
1424 1.1.1.2 mrg (match_operand:SVE_I 2 "register_operand" "w, w")
1425 1.1.1.2 mrg (match_operand:SVE_I 3 "aarch64_sve_cmp_<sve_imm_con>_operand" "<sve_imm_con>, w"))]
1426 1.1.1.2 mrg UNSPEC_MERGE_PTRUE)]
1427 1.1 mrg UNSPEC_PTEST_PTRUE)
1428 1.1 mrg (const_int 0)))
1429 1.1 mrg (set (match_operand:<VPRED> 0 "register_operand" "=Upa, Upa")
1430 1.1 mrg (unspec:<VPRED>
1431 1.1 mrg [(match_dup 1)
1432 1.1.1.2 mrg (SVE_INT_CMP:<VPRED>
1433 1.1.1.2 mrg (match_dup 2)
1434 1.1.1.2 mrg (match_dup 3))]
1435 1.1.1.2 mrg UNSPEC_MERGE_PTRUE))]
1436 1.1 mrg "TARGET_SVE"
1437 1.1 mrg "@
1438 1.1 mrg cmp<cmp_op>\t%0.<Vetype>, %1/z, %2.<Vetype>, #%3
1439 1.1 mrg cmp<cmp_op>\t%0.<Vetype>, %1/z, %2.<Vetype>, %3.<Vetype>"
1440 1.1 mrg )
1441 1.1 mrg
1442 1.1.1.2 mrg ;; Predicated integer comparisons, formed by combining a PTRUE-predicated
1443 1.1.1.2 mrg ;; comparison with an AND. Split the instruction into its preferred form
1444 1.1.1.2 mrg ;; (below) at the earliest opportunity, in order to get rid of the
1445 1.1.1.2 mrg ;; redundant operand 1.
1446 1.1.1.2 mrg (define_insn_and_split "*pred_cmp<cmp_op><mode>_combine"
1447 1.1.1.2 mrg [(set (match_operand:<VPRED> 0 "register_operand" "=Upa, Upa")
1448 1.1.1.2 mrg (and:<VPRED>
1449 1.1.1.2 mrg (unspec:<VPRED>
1450 1.1.1.2 mrg [(match_operand:<VPRED> 1)
1451 1.1.1.2 mrg (SVE_INT_CMP:<VPRED>
1452 1.1.1.2 mrg (match_operand:SVE_I 2 "register_operand" "w, w")
1453 1.1.1.2 mrg (match_operand:SVE_I 3 "aarch64_sve_cmp_<sve_imm_con>_operand" "<sve_imm_con>, w"))]
1454 1.1.1.2 mrg UNSPEC_MERGE_PTRUE)
1455 1.1.1.2 mrg (match_operand:<VPRED> 4 "register_operand" "Upl, Upl")))
1456 1.1.1.2 mrg (clobber (reg:CC CC_REGNUM))]
1457 1.1.1.2 mrg "TARGET_SVE"
1458 1.1.1.2 mrg "#"
1459 1.1.1.2 mrg "&& 1"
1460 1.1.1.2 mrg [(parallel
1461 1.1.1.2 mrg [(set (match_dup 0)
1462 1.1.1.2 mrg (and:<VPRED>
1463 1.1.1.2 mrg (SVE_INT_CMP:<VPRED>
1464 1.1.1.2 mrg (match_dup 2)
1465 1.1.1.2 mrg (match_dup 3))
1466 1.1.1.2 mrg (match_dup 4)))
1467 1.1.1.2 mrg (clobber (reg:CC CC_REGNUM))])]
1468 1.1.1.2 mrg )
1469 1.1.1.2 mrg
1470 1.1.1.2 mrg ;; Predicated integer comparisons.
1471 1.1.1.2 mrg (define_insn "*pred_cmp<cmp_op><mode>"
1472 1.1.1.2 mrg [(set (match_operand:<VPRED> 0 "register_operand" "=Upa, Upa")
1473 1.1.1.2 mrg (and:<VPRED>
1474 1.1.1.2 mrg (SVE_INT_CMP:<VPRED>
1475 1.1.1.2 mrg (match_operand:SVE_I 2 "register_operand" "w, w")
1476 1.1.1.2 mrg (match_operand:SVE_I 3 "aarch64_sve_cmp_<sve_imm_con>_operand" "<sve_imm_con>, w"))
1477 1.1.1.2 mrg (match_operand:<VPRED> 1 "register_operand" "Upl, Upl")))
1478 1.1.1.2 mrg (clobber (reg:CC CC_REGNUM))]
1479 1.1.1.2 mrg "TARGET_SVE"
1480 1.1.1.2 mrg "@
1481 1.1.1.2 mrg cmp<cmp_op>\t%0.<Vetype>, %1/z, %2.<Vetype>, #%3
1482 1.1.1.2 mrg cmp<cmp_op>\t%0.<Vetype>, %1/z, %2.<Vetype>, %3.<Vetype>"
1483 1.1.1.2 mrg )
1484 1.1.1.2 mrg
1485 1.1.1.2 mrg ;; Floating-point comparisons predicated with a PTRUE.
1486 1.1.1.2 mrg (define_insn "*fcm<cmp_op><mode>"
1487 1.1 mrg [(set (match_operand:<VPRED> 0 "register_operand" "=Upa, Upa")
1488 1.1 mrg (unspec:<VPRED>
1489 1.1 mrg [(match_operand:<VPRED> 1 "register_operand" "Upl, Upl")
1490 1.1.1.2 mrg (SVE_FP_CMP:<VPRED>
1491 1.1.1.2 mrg (match_operand:SVE_F 2 "register_operand" "w, w")
1492 1.1.1.2 mrg (match_operand:SVE_F 3 "aarch64_simd_reg_or_zero" "Dz, w"))]
1493 1.1.1.2 mrg UNSPEC_MERGE_PTRUE))]
1494 1.1 mrg "TARGET_SVE"
1495 1.1 mrg "@
1496 1.1 mrg fcm<cmp_op>\t%0.<Vetype>, %1/z, %2.<Vetype>, #0.0
1497 1.1 mrg fcm<cmp_op>\t%0.<Vetype>, %1/z, %2.<Vetype>, %3.<Vetype>"
1498 1.1 mrg )
1499 1.1 mrg
1500 1.1.1.2 mrg (define_insn "*fcmuo<mode>"
1501 1.1 mrg [(set (match_operand:<VPRED> 0 "register_operand" "=Upa")
1502 1.1 mrg (unspec:<VPRED>
1503 1.1 mrg [(match_operand:<VPRED> 1 "register_operand" "Upl")
1504 1.1.1.2 mrg (unordered:<VPRED>
1505 1.1.1.2 mrg (match_operand:SVE_F 2 "register_operand" "w")
1506 1.1.1.2 mrg (match_operand:SVE_F 3 "register_operand" "w"))]
1507 1.1.1.2 mrg UNSPEC_MERGE_PTRUE))]
1508 1.1 mrg "TARGET_SVE"
1509 1.1 mrg "fcmuo\t%0.<Vetype>, %1/z, %2.<Vetype>, %3.<Vetype>"
1510 1.1 mrg )
1511 1.1 mrg
1512 1.1.1.2 mrg ;; Floating-point comparisons predicated on a PTRUE, with the results ANDed
1513 1.1.1.2 mrg ;; with another predicate P. This does not have the same trapping behavior
1514 1.1.1.2 mrg ;; as predicating the comparison itself on P, but it's a legitimate fold,
1515 1.1.1.2 mrg ;; since we can drop any potentially-trapping operations whose results
1516 1.1.1.2 mrg ;; are not needed.
1517 1.1.1.2 mrg ;;
1518 1.1.1.2 mrg ;; Split the instruction into its preferred form (below) at the earliest
1519 1.1.1.2 mrg ;; opportunity, in order to get rid of the redundant operand 1.
1520 1.1.1.2 mrg (define_insn_and_split "*fcm<cmp_op><mode>_and_combine"
1521 1.1.1.2 mrg [(set (match_operand:<VPRED> 0 "register_operand" "=Upa, Upa")
1522 1.1.1.2 mrg (and:<VPRED>
1523 1.1.1.2 mrg (unspec:<VPRED>
1524 1.1.1.2 mrg [(match_operand:<VPRED> 1)
1525 1.1.1.2 mrg (SVE_FP_CMP
1526 1.1.1.2 mrg (match_operand:SVE_F 2 "register_operand" "w, w")
1527 1.1.1.2 mrg (match_operand:SVE_F 3 "aarch64_simd_reg_or_zero" "Dz, w"))]
1528 1.1.1.2 mrg UNSPEC_MERGE_PTRUE)
1529 1.1.1.2 mrg (match_operand:<VPRED> 4 "register_operand" "Upl, Upl")))]
1530 1.1.1.2 mrg "TARGET_SVE"
1531 1.1.1.2 mrg "#"
1532 1.1.1.2 mrg "&& 1"
1533 1.1.1.2 mrg [(set (match_dup 0)
1534 1.1.1.2 mrg (and:<VPRED>
1535 1.1.1.2 mrg (SVE_FP_CMP:<VPRED>
1536 1.1.1.2 mrg (match_dup 2)
1537 1.1.1.2 mrg (match_dup 3))
1538 1.1.1.2 mrg (match_dup 4)))]
1539 1.1.1.2 mrg )
1540 1.1.1.2 mrg
1541 1.1.1.2 mrg (define_insn_and_split "*fcmuo<mode>_and_combine"
1542 1.1.1.2 mrg [(set (match_operand:<VPRED> 0 "register_operand" "=Upa")
1543 1.1.1.2 mrg (and:<VPRED>
1544 1.1.1.2 mrg (unspec:<VPRED>
1545 1.1.1.2 mrg [(match_operand:<VPRED> 1)
1546 1.1.1.2 mrg (unordered
1547 1.1.1.2 mrg (match_operand:SVE_F 2 "register_operand" "w")
1548 1.1.1.2 mrg (match_operand:SVE_F 3 "register_operand" "w"))]
1549 1.1.1.2 mrg UNSPEC_MERGE_PTRUE)
1550 1.1.1.2 mrg (match_operand:<VPRED> 4 "register_operand" "Upl")))]
1551 1.1.1.2 mrg "TARGET_SVE"
1552 1.1.1.2 mrg "#"
1553 1.1.1.2 mrg "&& 1"
1554 1.1.1.2 mrg [(set (match_dup 0)
1555 1.1.1.2 mrg (and:<VPRED>
1556 1.1.1.2 mrg (unordered:<VPRED>
1557 1.1.1.2 mrg (match_dup 2)
1558 1.1.1.2 mrg (match_dup 3))
1559 1.1.1.2 mrg (match_dup 4)))]
1560 1.1.1.2 mrg )
1561 1.1.1.2 mrg
1562 1.1.1.2 mrg ;; Unpredicated floating-point comparisons, with the results ANDed
1563 1.1.1.2 mrg ;; with another predicate. This is a valid fold for the same reasons
1564 1.1.1.2 mrg ;; as above.
1565 1.1.1.2 mrg (define_insn "*fcm<cmp_op><mode>_and"
1566 1.1.1.2 mrg [(set (match_operand:<VPRED> 0 "register_operand" "=Upa, Upa")
1567 1.1.1.2 mrg (and:<VPRED>
1568 1.1.1.2 mrg (SVE_FP_CMP:<VPRED>
1569 1.1.1.2 mrg (match_operand:SVE_F 2 "register_operand" "w, w")
1570 1.1.1.2 mrg (match_operand:SVE_F 3 "aarch64_simd_reg_or_zero" "Dz, w"))
1571 1.1.1.2 mrg (match_operand:<VPRED> 1 "register_operand" "Upl, Upl")))]
1572 1.1.1.2 mrg "TARGET_SVE"
1573 1.1.1.2 mrg "@
1574 1.1.1.2 mrg fcm<cmp_op>\t%0.<Vetype>, %1/z, %2.<Vetype>, #0.0
1575 1.1.1.2 mrg fcm<cmp_op>\t%0.<Vetype>, %1/z, %2.<Vetype>, %3.<Vetype>"
1576 1.1.1.2 mrg )
1577 1.1.1.2 mrg
1578 1.1.1.2 mrg (define_insn "*fcmuo<mode>_and"
1579 1.1.1.2 mrg [(set (match_operand:<VPRED> 0 "register_operand" "=Upa")
1580 1.1.1.2 mrg (and:<VPRED>
1581 1.1.1.2 mrg (unordered:<VPRED>
1582 1.1.1.2 mrg (match_operand:SVE_F 2 "register_operand" "w")
1583 1.1.1.2 mrg (match_operand:SVE_F 3 "register_operand" "w"))
1584 1.1.1.2 mrg (match_operand:<VPRED> 1 "register_operand" "Upl")))]
1585 1.1.1.2 mrg "TARGET_SVE"
1586 1.1.1.2 mrg "fcmuo\t%0.<Vetype>, %1/z, %2.<Vetype>, %3.<Vetype>"
1587 1.1.1.2 mrg )
1588 1.1.1.2 mrg
1589 1.1.1.2 mrg ;; Predicated floating-point comparisons. We don't need a version
1590 1.1.1.2 mrg ;; of this for unordered comparisons.
1591 1.1.1.2 mrg (define_insn "*pred_fcm<cmp_op><mode>"
1592 1.1.1.2 mrg [(set (match_operand:<VPRED> 0 "register_operand" "=Upa, Upa")
1593 1.1.1.2 mrg (unspec:<VPRED>
1594 1.1.1.2 mrg [(match_operand:<VPRED> 1 "register_operand" "Upl, Upl")
1595 1.1.1.2 mrg (match_operand:SVE_F 2 "register_operand" "w, w")
1596 1.1.1.2 mrg (match_operand:SVE_F 3 "aarch64_simd_reg_or_zero" "Dz, w")]
1597 1.1.1.2 mrg SVE_COND_FP_CMP))]
1598 1.1.1.2 mrg "TARGET_SVE"
1599 1.1.1.2 mrg "@
1600 1.1.1.2 mrg fcm<cmp_op>\t%0.<Vetype>, %1/z, %2.<Vetype>, #0.0
1601 1.1.1.2 mrg fcm<cmp_op>\t%0.<Vetype>, %1/z, %2.<Vetype>, %3.<Vetype>"
1602 1.1.1.2 mrg )
1603 1.1.1.2 mrg
1604 1.1 mrg ;; vcond_mask operand order: true, false, mask
1605 1.1 mrg ;; UNSPEC_SEL operand order: mask, true, false (as for VEC_COND_EXPR)
1606 1.1 mrg ;; SEL operand order: mask, true, false
1607 1.1 mrg (define_insn "vcond_mask_<mode><vpred>"
1608 1.1 mrg [(set (match_operand:SVE_ALL 0 "register_operand" "=w")
1609 1.1 mrg (unspec:SVE_ALL
1610 1.1 mrg [(match_operand:<VPRED> 3 "register_operand" "Upa")
1611 1.1 mrg (match_operand:SVE_ALL 1 "register_operand" "w")
1612 1.1 mrg (match_operand:SVE_ALL 2 "register_operand" "w")]
1613 1.1 mrg UNSPEC_SEL))]
1614 1.1 mrg "TARGET_SVE"
1615 1.1 mrg "sel\t%0.<Vetype>, %3, %1.<Vetype>, %2.<Vetype>"
1616 1.1 mrg )
1617 1.1 mrg
1618 1.1 mrg ;; Selects between a duplicated immediate and zero.
1619 1.1 mrg (define_insn "aarch64_sve_dup<mode>_const"
1620 1.1 mrg [(set (match_operand:SVE_I 0 "register_operand" "=w")
1621 1.1 mrg (unspec:SVE_I
1622 1.1 mrg [(match_operand:<VPRED> 1 "register_operand" "Upl")
1623 1.1 mrg (match_operand:SVE_I 2 "aarch64_sve_dup_immediate")
1624 1.1 mrg (match_operand:SVE_I 3 "aarch64_simd_imm_zero")]
1625 1.1 mrg UNSPEC_SEL))]
1626 1.1 mrg "TARGET_SVE"
1627 1.1 mrg "mov\t%0.<Vetype>, %1/z, #%2"
1628 1.1 mrg )
1629 1.1 mrg
1630 1.1 mrg ;; Integer (signed) vcond. Don't enforce an immediate range here, since it
1631 1.1 mrg ;; depends on the comparison; leave it to aarch64_expand_sve_vcond instead.
1632 1.1 mrg (define_expand "vcond<mode><v_int_equiv>"
1633 1.1 mrg [(set (match_operand:SVE_ALL 0 "register_operand")
1634 1.1 mrg (if_then_else:SVE_ALL
1635 1.1 mrg (match_operator 3 "comparison_operator"
1636 1.1 mrg [(match_operand:<V_INT_EQUIV> 4 "register_operand")
1637 1.1 mrg (match_operand:<V_INT_EQUIV> 5 "nonmemory_operand")])
1638 1.1 mrg (match_operand:SVE_ALL 1 "register_operand")
1639 1.1 mrg (match_operand:SVE_ALL 2 "register_operand")))]
1640 1.1 mrg "TARGET_SVE"
1641 1.1 mrg {
1642 1.1 mrg aarch64_expand_sve_vcond (<MODE>mode, <V_INT_EQUIV>mode, operands);
1643 1.1 mrg DONE;
1644 1.1 mrg }
1645 1.1 mrg )
1646 1.1 mrg
1647 1.1 mrg ;; Integer vcondu. Don't enforce an immediate range here, since it
1648 1.1 mrg ;; depends on the comparison; leave it to aarch64_expand_sve_vcond instead.
1649 1.1 mrg (define_expand "vcondu<mode><v_int_equiv>"
1650 1.1 mrg [(set (match_operand:SVE_ALL 0 "register_operand")
1651 1.1 mrg (if_then_else:SVE_ALL
1652 1.1 mrg (match_operator 3 "comparison_operator"
1653 1.1 mrg [(match_operand:<V_INT_EQUIV> 4 "register_operand")
1654 1.1 mrg (match_operand:<V_INT_EQUIV> 5 "nonmemory_operand")])
1655 1.1 mrg (match_operand:SVE_ALL 1 "register_operand")
1656 1.1 mrg (match_operand:SVE_ALL 2 "register_operand")))]
1657 1.1 mrg "TARGET_SVE"
1658 1.1 mrg {
1659 1.1 mrg aarch64_expand_sve_vcond (<MODE>mode, <V_INT_EQUIV>mode, operands);
1660 1.1 mrg DONE;
1661 1.1 mrg }
1662 1.1 mrg )
1663 1.1 mrg
1664 1.1 mrg ;; Floating-point vcond. All comparisons except FCMUO allow a zero
1665 1.1 mrg ;; operand; aarch64_expand_sve_vcond handles the case of an FCMUO
1666 1.1 mrg ;; with zero.
1667 1.1 mrg (define_expand "vcond<mode><v_fp_equiv>"
1668 1.1 mrg [(set (match_operand:SVE_SD 0 "register_operand")
1669 1.1 mrg (if_then_else:SVE_SD
1670 1.1 mrg (match_operator 3 "comparison_operator"
1671 1.1 mrg [(match_operand:<V_FP_EQUIV> 4 "register_operand")
1672 1.1 mrg (match_operand:<V_FP_EQUIV> 5 "aarch64_simd_reg_or_zero")])
1673 1.1 mrg (match_operand:SVE_SD 1 "register_operand")
1674 1.1 mrg (match_operand:SVE_SD 2 "register_operand")))]
1675 1.1 mrg "TARGET_SVE"
1676 1.1 mrg {
1677 1.1 mrg aarch64_expand_sve_vcond (<MODE>mode, <V_FP_EQUIV>mode, operands);
1678 1.1 mrg DONE;
1679 1.1 mrg }
1680 1.1 mrg )
1681 1.1 mrg
1682 1.1 mrg ;; Signed integer comparisons. Don't enforce an immediate range here, since
1683 1.1 mrg ;; it depends on the comparison; leave it to aarch64_expand_sve_vec_cmp_int
1684 1.1 mrg ;; instead.
1685 1.1 mrg (define_expand "vec_cmp<mode><vpred>"
1686 1.1 mrg [(parallel
1687 1.1 mrg [(set (match_operand:<VPRED> 0 "register_operand")
1688 1.1 mrg (match_operator:<VPRED> 1 "comparison_operator"
1689 1.1 mrg [(match_operand:SVE_I 2 "register_operand")
1690 1.1 mrg (match_operand:SVE_I 3 "nonmemory_operand")]))
1691 1.1 mrg (clobber (reg:CC CC_REGNUM))])]
1692 1.1 mrg "TARGET_SVE"
1693 1.1 mrg {
1694 1.1 mrg aarch64_expand_sve_vec_cmp_int (operands[0], GET_CODE (operands[1]),
1695 1.1 mrg operands[2], operands[3]);
1696 1.1 mrg DONE;
1697 1.1 mrg }
1698 1.1 mrg )
1699 1.1 mrg
1700 1.1 mrg ;; Unsigned integer comparisons. Don't enforce an immediate range here, since
1701 1.1 mrg ;; it depends on the comparison; leave it to aarch64_expand_sve_vec_cmp_int
1702 1.1 mrg ;; instead.
1703 1.1 mrg (define_expand "vec_cmpu<mode><vpred>"
1704 1.1 mrg [(parallel
1705 1.1 mrg [(set (match_operand:<VPRED> 0 "register_operand")
1706 1.1 mrg (match_operator:<VPRED> 1 "comparison_operator"
1707 1.1 mrg [(match_operand:SVE_I 2 "register_operand")
1708 1.1 mrg (match_operand:SVE_I 3 "nonmemory_operand")]))
1709 1.1 mrg (clobber (reg:CC CC_REGNUM))])]
1710 1.1 mrg "TARGET_SVE"
1711 1.1 mrg {
1712 1.1 mrg aarch64_expand_sve_vec_cmp_int (operands[0], GET_CODE (operands[1]),
1713 1.1 mrg operands[2], operands[3]);
1714 1.1 mrg DONE;
1715 1.1 mrg }
1716 1.1 mrg )
1717 1.1 mrg
1718 1.1 mrg ;; Floating-point comparisons. All comparisons except FCMUO allow a zero
1719 1.1 mrg ;; operand; aarch64_expand_sve_vec_cmp_float handles the case of an FCMUO
1720 1.1 mrg ;; with zero.
1721 1.1 mrg (define_expand "vec_cmp<mode><vpred>"
1722 1.1 mrg [(set (match_operand:<VPRED> 0 "register_operand")
1723 1.1 mrg (match_operator:<VPRED> 1 "comparison_operator"
1724 1.1 mrg [(match_operand:SVE_F 2 "register_operand")
1725 1.1 mrg (match_operand:SVE_F 3 "aarch64_simd_reg_or_zero")]))]
1726 1.1 mrg "TARGET_SVE"
1727 1.1 mrg {
1728 1.1 mrg aarch64_expand_sve_vec_cmp_float (operands[0], GET_CODE (operands[1]),
1729 1.1 mrg operands[2], operands[3], false);
1730 1.1 mrg DONE;
1731 1.1 mrg }
1732 1.1 mrg )
1733 1.1 mrg
1734 1.1 mrg ;; Branch based on predicate equality or inequality.
1735 1.1 mrg (define_expand "cbranch<mode>4"
1736 1.1 mrg [(set (pc)
1737 1.1 mrg (if_then_else
1738 1.1 mrg (match_operator 0 "aarch64_equality_operator"
1739 1.1 mrg [(match_operand:PRED_ALL 1 "register_operand")
1740 1.1 mrg (match_operand:PRED_ALL 2 "aarch64_simd_reg_or_zero")])
1741 1.1 mrg (label_ref (match_operand 3 ""))
1742 1.1 mrg (pc)))]
1743 1.1 mrg ""
1744 1.1 mrg {
1745 1.1 mrg rtx ptrue = force_reg (<MODE>mode, CONSTM1_RTX (<MODE>mode));
1746 1.1 mrg rtx pred;
1747 1.1 mrg if (operands[2] == CONST0_RTX (<MODE>mode))
1748 1.1 mrg pred = operands[1];
1749 1.1 mrg else
1750 1.1 mrg {
1751 1.1 mrg pred = gen_reg_rtx (<MODE>mode);
1752 1.1 mrg emit_insn (gen_pred_xor<mode>3 (pred, ptrue, operands[1],
1753 1.1 mrg operands[2]));
1754 1.1 mrg }
1755 1.1 mrg emit_insn (gen_ptest_ptrue<mode> (ptrue, pred));
1756 1.1 mrg operands[1] = gen_rtx_REG (CCmode, CC_REGNUM);
1757 1.1 mrg operands[2] = const0_rtx;
1758 1.1 mrg }
1759 1.1 mrg )
1760 1.1 mrg
1761 1.1 mrg ;; Unpredicated integer MIN/MAX.
1762 1.1 mrg (define_expand "<su><maxmin><mode>3"
1763 1.1 mrg [(set (match_operand:SVE_I 0 "register_operand")
1764 1.1 mrg (unspec:SVE_I
1765 1.1 mrg [(match_dup 3)
1766 1.1 mrg (MAXMIN:SVE_I (match_operand:SVE_I 1 "register_operand")
1767 1.1 mrg (match_operand:SVE_I 2 "register_operand"))]
1768 1.1 mrg UNSPEC_MERGE_PTRUE))]
1769 1.1 mrg "TARGET_SVE"
1770 1.1 mrg {
1771 1.1 mrg operands[3] = force_reg (<VPRED>mode, CONSTM1_RTX (<VPRED>mode));
1772 1.1 mrg }
1773 1.1 mrg )
1774 1.1 mrg
1775 1.1 mrg ;; Integer MIN/MAX predicated with a PTRUE.
1776 1.1 mrg (define_insn "*<su><maxmin><mode>3"
1777 1.1.1.2 mrg [(set (match_operand:SVE_I 0 "register_operand" "=w, ?&w")
1778 1.1 mrg (unspec:SVE_I
1779 1.1.1.2 mrg [(match_operand:<VPRED> 1 "register_operand" "Upl, Upl")
1780 1.1.1.2 mrg (MAXMIN:SVE_I (match_operand:SVE_I 2 "register_operand" "%0, w")
1781 1.1.1.2 mrg (match_operand:SVE_I 3 "register_operand" "w, w"))]
1782 1.1 mrg UNSPEC_MERGE_PTRUE))]
1783 1.1 mrg "TARGET_SVE"
1784 1.1.1.2 mrg "@
1785 1.1.1.2 mrg <su><maxmin>\t%0.<Vetype>, %1/m, %0.<Vetype>, %3.<Vetype>
1786 1.1.1.2 mrg movprfx\t%0, %2\;<su><maxmin>\t%0.<Vetype>, %1/m, %0.<Vetype>, %3.<Vetype>"
1787 1.1.1.2 mrg [(set_attr "movprfx" "*,yes")]
1788 1.1 mrg )
1789 1.1 mrg
1790 1.1 mrg ;; Unpredicated floating-point MIN/MAX.
1791 1.1 mrg (define_expand "<su><maxmin><mode>3"
1792 1.1 mrg [(set (match_operand:SVE_F 0 "register_operand")
1793 1.1 mrg (unspec:SVE_F
1794 1.1 mrg [(match_dup 3)
1795 1.1 mrg (FMAXMIN:SVE_F (match_operand:SVE_F 1 "register_operand")
1796 1.1 mrg (match_operand:SVE_F 2 "register_operand"))]
1797 1.1 mrg UNSPEC_MERGE_PTRUE))]
1798 1.1 mrg "TARGET_SVE"
1799 1.1 mrg {
1800 1.1 mrg operands[3] = force_reg (<VPRED>mode, CONSTM1_RTX (<VPRED>mode));
1801 1.1 mrg }
1802 1.1 mrg )
1803 1.1 mrg
1804 1.1 mrg ;; Floating-point MIN/MAX predicated with a PTRUE.
1805 1.1 mrg (define_insn "*<su><maxmin><mode>3"
1806 1.1.1.2 mrg [(set (match_operand:SVE_F 0 "register_operand" "=w, ?&w")
1807 1.1 mrg (unspec:SVE_F
1808 1.1.1.2 mrg [(match_operand:<VPRED> 1 "register_operand" "Upl, Upl")
1809 1.1.1.2 mrg (FMAXMIN:SVE_F (match_operand:SVE_F 2 "register_operand" "%0, w")
1810 1.1.1.2 mrg (match_operand:SVE_F 3 "register_operand" "w, w"))]
1811 1.1 mrg UNSPEC_MERGE_PTRUE))]
1812 1.1 mrg "TARGET_SVE"
1813 1.1.1.2 mrg "@
1814 1.1.1.2 mrg f<maxmin>nm\t%0.<Vetype>, %1/m, %0.<Vetype>, %3.<Vetype>
1815 1.1.1.2 mrg movprfx\t%0, %2\;f<maxmin>nm\t%0.<Vetype>, %1/m, %0.<Vetype>, %3.<Vetype>"
1816 1.1.1.2 mrg [(set_attr "movprfx" "*,yes")]
1817 1.1 mrg )
1818 1.1 mrg
1819 1.1 mrg ;; Unpredicated fmin/fmax.
1820 1.1 mrg (define_expand "<maxmin_uns><mode>3"
1821 1.1 mrg [(set (match_operand:SVE_F 0 "register_operand")
1822 1.1 mrg (unspec:SVE_F
1823 1.1 mrg [(match_dup 3)
1824 1.1 mrg (unspec:SVE_F [(match_operand:SVE_F 1 "register_operand")
1825 1.1 mrg (match_operand:SVE_F 2 "register_operand")]
1826 1.1 mrg FMAXMIN_UNS)]
1827 1.1 mrg UNSPEC_MERGE_PTRUE))]
1828 1.1 mrg "TARGET_SVE"
1829 1.1 mrg {
1830 1.1 mrg operands[3] = force_reg (<VPRED>mode, CONSTM1_RTX (<VPRED>mode));
1831 1.1 mrg }
1832 1.1 mrg )
1833 1.1 mrg
1834 1.1 mrg ;; fmin/fmax predicated with a PTRUE.
1835 1.1 mrg (define_insn "*<maxmin_uns><mode>3"
1836 1.1.1.2 mrg [(set (match_operand:SVE_F 0 "register_operand" "=w, ?&w")
1837 1.1 mrg (unspec:SVE_F
1838 1.1.1.2 mrg [(match_operand:<VPRED> 1 "register_operand" "Upl, Upl")
1839 1.1.1.2 mrg (unspec:SVE_F [(match_operand:SVE_F 2 "register_operand" "%0, w")
1840 1.1.1.2 mrg (match_operand:SVE_F 3 "register_operand" "w, w")]
1841 1.1 mrg FMAXMIN_UNS)]
1842 1.1 mrg UNSPEC_MERGE_PTRUE))]
1843 1.1 mrg "TARGET_SVE"
1844 1.1.1.2 mrg "@
1845 1.1.1.2 mrg <maxmin_uns_op>\t%0.<Vetype>, %1/m, %0.<Vetype>, %3.<Vetype>
1846 1.1.1.2 mrg movprfx\t%0, %2\;<maxmin_uns_op>\t%0.<Vetype>, %1/m, %0.<Vetype>, %3.<Vetype>"
1847 1.1.1.2 mrg [(set_attr "movprfx" "*,yes")]
1848 1.1 mrg )
1849 1.1 mrg
1850 1.1.1.2 mrg ;; Predicated integer operations with select.
1851 1.1.1.2 mrg (define_expand "cond_<optab><mode>"
1852 1.1.1.2 mrg [(set (match_operand:SVE_I 0 "register_operand")
1853 1.1.1.2 mrg (unspec:SVE_I
1854 1.1.1.2 mrg [(match_operand:<VPRED> 1 "register_operand")
1855 1.1.1.2 mrg (SVE_INT_BINARY:SVE_I
1856 1.1.1.2 mrg (match_operand:SVE_I 2 "register_operand")
1857 1.1.1.2 mrg (match_operand:SVE_I 3 "register_operand"))
1858 1.1.1.2 mrg (match_operand:SVE_I 4 "aarch64_simd_reg_or_zero")]
1859 1.1.1.2 mrg UNSPEC_SEL))]
1860 1.1.1.2 mrg "TARGET_SVE"
1861 1.1.1.2 mrg )
1862 1.1.1.2 mrg
1863 1.1.1.2 mrg (define_expand "cond_<optab><mode>"
1864 1.1.1.2 mrg [(set (match_operand:SVE_SDI 0 "register_operand")
1865 1.1.1.2 mrg (unspec:SVE_SDI
1866 1.1.1.2 mrg [(match_operand:<VPRED> 1 "register_operand")
1867 1.1.1.2 mrg (SVE_INT_BINARY_SD:SVE_SDI
1868 1.1.1.2 mrg (match_operand:SVE_SDI 2 "register_operand")
1869 1.1.1.2 mrg (match_operand:SVE_SDI 3 "register_operand"))
1870 1.1.1.2 mrg (match_operand:SVE_SDI 4 "aarch64_simd_reg_or_zero")]
1871 1.1.1.2 mrg UNSPEC_SEL))]
1872 1.1.1.2 mrg "TARGET_SVE"
1873 1.1.1.2 mrg )
1874 1.1.1.2 mrg
1875 1.1.1.2 mrg ;; Predicated integer operations with select matching the output operand.
1876 1.1.1.2 mrg (define_insn "*cond_<optab><mode>_0"
1877 1.1.1.2 mrg [(set (match_operand:SVE_I 0 "register_operand" "+w, w, ?&w")
1878 1.1.1.2 mrg (unspec:SVE_I
1879 1.1.1.2 mrg [(match_operand:<VPRED> 1 "register_operand" "Upl, Upl, Upl")
1880 1.1.1.2 mrg (SVE_INT_BINARY:SVE_I
1881 1.1.1.2 mrg (match_operand:SVE_I 2 "register_operand" "0, w, w")
1882 1.1.1.2 mrg (match_operand:SVE_I 3 "register_operand" "w, 0, w"))
1883 1.1.1.2 mrg (match_dup 0)]
1884 1.1.1.2 mrg UNSPEC_SEL))]
1885 1.1.1.2 mrg "TARGET_SVE"
1886 1.1.1.2 mrg "@
1887 1.1.1.2 mrg <sve_int_op>\t%0.<Vetype>, %1/m, %0.<Vetype>, %3.<Vetype>
1888 1.1.1.2 mrg <sve_int_op_rev>\t%0.<Vetype>, %1/m, %0.<Vetype>, %2.<Vetype>
1889 1.1.1.2 mrg movprfx\t%0, %1/m, %2\;<sve_int_op>\t%0.<Vetype>, %1/m, %0.<Vetype>, %3.<Vetype>"
1890 1.1.1.2 mrg [(set_attr "movprfx" "*,*,yes")]
1891 1.1.1.2 mrg )
1892 1.1.1.2 mrg
1893 1.1.1.2 mrg (define_insn "*cond_<optab><mode>_0"
1894 1.1.1.2 mrg [(set (match_operand:SVE_SDI 0 "register_operand" "+w, w, ?&w")
1895 1.1.1.2 mrg (unspec:SVE_SDI
1896 1.1.1.2 mrg [(match_operand:<VPRED> 1 "register_operand" "Upl, Upl, Upl")
1897 1.1.1.2 mrg (SVE_INT_BINARY_SD:SVE_SDI
1898 1.1.1.2 mrg (match_operand:SVE_SDI 2 "register_operand" "0, w, w")
1899 1.1.1.2 mrg (match_operand:SVE_SDI 3 "register_operand" "w, 0, w"))
1900 1.1.1.2 mrg (match_dup 0)]
1901 1.1.1.2 mrg UNSPEC_SEL))]
1902 1.1.1.2 mrg "TARGET_SVE"
1903 1.1.1.2 mrg "@
1904 1.1.1.2 mrg <sve_int_op>\t%0.<Vetype>, %1/m, %0.<Vetype>, %3.<Vetype>
1905 1.1.1.2 mrg <sve_int_op_rev>\t%0.<Vetype>, %1/m, %0.<Vetype>, %2.<Vetype>
1906 1.1.1.2 mrg movprfx\t%0, %1/m, %2\;<sve_int_op>\t%0.<Vetype>, %1/m, %0.<Vetype>, %3.<Vetype>"
1907 1.1.1.2 mrg [(set_attr "movprfx" "*,*,yes")]
1908 1.1.1.2 mrg )
1909 1.1.1.2 mrg
1910 1.1.1.2 mrg ;; Predicated integer operations with select matching the first operand.
1911 1.1.1.2 mrg (define_insn "*cond_<optab><mode>_2"
1912 1.1.1.2 mrg [(set (match_operand:SVE_I 0 "register_operand" "=w, ?&w")
1913 1.1.1.2 mrg (unspec:SVE_I
1914 1.1.1.2 mrg [(match_operand:<VPRED> 1 "register_operand" "Upl, Upl")
1915 1.1.1.2 mrg (SVE_INT_BINARY:SVE_I
1916 1.1.1.2 mrg (match_operand:SVE_I 2 "register_operand" "0, w")
1917 1.1.1.2 mrg (match_operand:SVE_I 3 "register_operand" "w, w"))
1918 1.1.1.2 mrg (match_dup 2)]
1919 1.1.1.2 mrg UNSPEC_SEL))]
1920 1.1.1.2 mrg "TARGET_SVE"
1921 1.1.1.2 mrg "@
1922 1.1.1.2 mrg <sve_int_op>\t%0.<Vetype>, %1/m, %0.<Vetype>, %3.<Vetype>
1923 1.1.1.2 mrg movprfx\t%0, %2\;<sve_int_op>\t%0.<Vetype>, %1/m, %0.<Vetype>, %3.<Vetype>"
1924 1.1.1.2 mrg [(set_attr "movprfx" "*,yes")]
1925 1.1.1.2 mrg )
1926 1.1.1.2 mrg
1927 1.1.1.2 mrg (define_insn "*cond_<optab><mode>_2"
1928 1.1.1.2 mrg [(set (match_operand:SVE_SDI 0 "register_operand" "=w, ?&w")
1929 1.1.1.2 mrg (unspec:SVE_SDI
1930 1.1.1.2 mrg [(match_operand:<VPRED> 1 "register_operand" "Upl, Upl")
1931 1.1.1.2 mrg (SVE_INT_BINARY_SD:SVE_SDI
1932 1.1.1.2 mrg (match_operand:SVE_SDI 2 "register_operand" "0, w")
1933 1.1.1.2 mrg (match_operand:SVE_SDI 3 "register_operand" "w, w"))
1934 1.1.1.2 mrg (match_dup 2)]
1935 1.1.1.2 mrg UNSPEC_SEL))]
1936 1.1.1.2 mrg "TARGET_SVE"
1937 1.1.1.2 mrg "@
1938 1.1.1.2 mrg <sve_int_op>\t%0.<Vetype>, %1/m, %0.<Vetype>, %3.<Vetype>
1939 1.1.1.2 mrg movprfx\t%0, %2\;<sve_int_op>\t%0.<Vetype>, %1/m, %0.<Vetype>, %3.<Vetype>"
1940 1.1.1.2 mrg [(set_attr "movprfx" "*,yes")]
1941 1.1.1.2 mrg )
1942 1.1.1.2 mrg
1943 1.1.1.2 mrg ;; Predicated integer operations with select matching the second operand.
1944 1.1.1.2 mrg (define_insn "*cond_<optab><mode>_3"
1945 1.1.1.2 mrg [(set (match_operand:SVE_I 0 "register_operand" "=w, ?&w")
1946 1.1.1.2 mrg (unspec:SVE_I
1947 1.1.1.2 mrg [(match_operand:<VPRED> 1 "register_operand" "Upl, Upl")
1948 1.1.1.2 mrg (SVE_INT_BINARY:SVE_I
1949 1.1.1.2 mrg (match_operand:SVE_I 2 "register_operand" "w, w")
1950 1.1.1.2 mrg (match_operand:SVE_I 3 "register_operand" "0, w"))
1951 1.1.1.2 mrg (match_dup 3)]
1952 1.1.1.2 mrg UNSPEC_SEL))]
1953 1.1.1.2 mrg "TARGET_SVE"
1954 1.1.1.2 mrg "@
1955 1.1.1.2 mrg <sve_int_op_rev>\t%0.<Vetype>, %1/m, %0.<Vetype>, %2.<Vetype>
1956 1.1.1.2 mrg movprfx\t%0, %3\;<sve_int_op_rev>\t%0.<Vetype>, %1/m, %0.<Vetype>, %2.<Vetype>"
1957 1.1.1.2 mrg [(set_attr "movprfx" "*,yes")]
1958 1.1.1.2 mrg )
1959 1.1.1.2 mrg
1960 1.1.1.2 mrg (define_insn "*cond_<optab><mode>_3"
1961 1.1.1.2 mrg [(set (match_operand:SVE_SDI 0 "register_operand" "=w, ?&w")
1962 1.1.1.2 mrg (unspec:SVE_SDI
1963 1.1.1.2 mrg [(match_operand:<VPRED> 1 "register_operand" "Upl, Upl")
1964 1.1.1.2 mrg (SVE_INT_BINARY_SD:SVE_SDI
1965 1.1.1.2 mrg (match_operand:SVE_SDI 2 "register_operand" "w, w")
1966 1.1.1.2 mrg (match_operand:SVE_SDI 3 "register_operand" "0, w"))
1967 1.1.1.2 mrg (match_dup 3)]
1968 1.1.1.2 mrg UNSPEC_SEL))]
1969 1.1.1.2 mrg "TARGET_SVE"
1970 1.1.1.2 mrg "@
1971 1.1.1.2 mrg <sve_int_op_rev>\t%0.<Vetype>, %1/m, %0.<Vetype>, %2.<Vetype>
1972 1.1.1.2 mrg movprfx\t%0, %3\;<sve_int_op_rev>\t%0.<Vetype>, %1/m, %0.<Vetype>, %2.<Vetype>"
1973 1.1.1.2 mrg [(set_attr "movprfx" "*,yes")]
1974 1.1.1.2 mrg )
1975 1.1.1.2 mrg
1976 1.1.1.2 mrg ;; Predicated integer operations with select matching zero.
1977 1.1.1.2 mrg (define_insn "*cond_<optab><mode>_z"
1978 1.1.1.2 mrg [(set (match_operand:SVE_I 0 "register_operand" "=&w")
1979 1.1 mrg (unspec:SVE_I
1980 1.1 mrg [(match_operand:<VPRED> 1 "register_operand" "Upl")
1981 1.1.1.2 mrg (SVE_INT_BINARY:SVE_I
1982 1.1.1.2 mrg (match_operand:SVE_I 2 "register_operand" "w")
1983 1.1.1.2 mrg (match_operand:SVE_I 3 "register_operand" "w"))
1984 1.1.1.2 mrg (match_operand:SVE_I 4 "aarch64_simd_imm_zero")]
1985 1.1.1.2 mrg UNSPEC_SEL))]
1986 1.1 mrg "TARGET_SVE"
1987 1.1.1.2 mrg "movprfx\t%0.<Vetype>, %1/z, %2.<Vetype>\;<sve_int_op>\t%0.<Vetype>, %1/m, %0.<Vetype>, %3.<Vetype>"
1988 1.1.1.2 mrg [(set_attr "movprfx" "yes")]
1989 1.1.1.2 mrg )
1990 1.1.1.2 mrg
1991 1.1.1.2 mrg (define_insn "*cond_<optab><mode>_z"
1992 1.1.1.2 mrg [(set (match_operand:SVE_SDI 0 "register_operand" "=&w")
1993 1.1.1.2 mrg (unspec:SVE_SDI
1994 1.1.1.2 mrg [(match_operand:<VPRED> 1 "register_operand" "Upl")
1995 1.1.1.2 mrg (SVE_INT_BINARY_SD:SVE_SDI
1996 1.1.1.2 mrg (match_operand:SVE_SDI 2 "register_operand" "w")
1997 1.1.1.2 mrg (match_operand:SVE_SDI 3 "register_operand" "w"))
1998 1.1.1.2 mrg (match_operand:SVE_SDI 4 "aarch64_simd_imm_zero")]
1999 1.1.1.2 mrg UNSPEC_SEL))]
2000 1.1.1.2 mrg "TARGET_SVE"
2001 1.1.1.2 mrg "movprfx\t%0.<Vetype>, %1/z, %2.<Vetype>\;<sve_int_op>\t%0.<Vetype>, %1/m, %0.<Vetype>, %3.<Vetype>"
2002 1.1.1.2 mrg [(set_attr "movprfx" "yes")]
2003 1.1.1.2 mrg )
2004 1.1.1.2 mrg
2005 1.1.1.2 mrg ;; Synthetic predications with select unmatched.
2006 1.1.1.2 mrg (define_insn "*cond_<optab><mode>_any"
2007 1.1.1.2 mrg [(set (match_operand:SVE_I 0 "register_operand" "=&w")
2008 1.1.1.2 mrg (unspec:SVE_I
2009 1.1.1.2 mrg [(match_operand:<VPRED> 1 "register_operand" "Upl")
2010 1.1.1.2 mrg (SVE_INT_BINARY:SVE_I
2011 1.1.1.2 mrg (match_operand:SVE_I 2 "register_operand" "w")
2012 1.1.1.2 mrg (match_operand:SVE_I 3 "register_operand" "w"))
2013 1.1.1.2 mrg (match_operand:SVE_I 4 "register_operand" "w")]
2014 1.1.1.2 mrg UNSPEC_SEL))]
2015 1.1.1.2 mrg "TARGET_SVE"
2016 1.1.1.2 mrg "#"
2017 1.1.1.2 mrg )
2018 1.1.1.2 mrg
2019 1.1.1.2 mrg (define_insn "*cond_<optab><mode>_any"
2020 1.1.1.2 mrg [(set (match_operand:SVE_SDI 0 "register_operand" "=&w")
2021 1.1.1.2 mrg (unspec:SVE_SDI
2022 1.1.1.2 mrg [(match_operand:<VPRED> 1 "register_operand" "Upl")
2023 1.1.1.2 mrg (SVE_INT_BINARY_SD:SVE_I
2024 1.1.1.2 mrg (match_operand:SVE_SDI 2 "register_operand" "w")
2025 1.1.1.2 mrg (match_operand:SVE_SDI 3 "register_operand" "w"))
2026 1.1.1.2 mrg (match_operand:SVE_SDI 4 "register_operand" "w")]
2027 1.1.1.2 mrg UNSPEC_SEL))]
2028 1.1.1.2 mrg "TARGET_SVE"
2029 1.1.1.2 mrg "#"
2030 1.1.1.2 mrg )
2031 1.1.1.2 mrg
2032 1.1.1.2 mrg (define_split
2033 1.1.1.2 mrg [(set (match_operand:SVE_I 0 "register_operand")
2034 1.1.1.2 mrg (unspec:SVE_I
2035 1.1.1.2 mrg [(match_operand:<VPRED> 1 "register_operand")
2036 1.1.1.2 mrg (match_operator:SVE_I 5 "aarch64_sve_any_binary_operator"
2037 1.1.1.2 mrg [(match_operand:SVE_I 2 "register_operand")
2038 1.1.1.2 mrg (match_operand:SVE_I 3 "register_operand")])
2039 1.1.1.2 mrg (match_operand:SVE_I 4 "register_operand")]
2040 1.1.1.2 mrg UNSPEC_SEL))]
2041 1.1.1.2 mrg "TARGET_SVE && reload_completed
2042 1.1.1.2 mrg && !(rtx_equal_p (operands[0], operands[4])
2043 1.1.1.2 mrg || rtx_equal_p (operands[2], operands[4])
2044 1.1.1.2 mrg || rtx_equal_p (operands[3], operands[4]))"
2045 1.1.1.2 mrg ; Not matchable by any one insn or movprfx insn. We need a separate select.
2046 1.1.1.2 mrg [(set (match_dup 0)
2047 1.1.1.2 mrg (unspec:SVE_I [(match_dup 1) (match_dup 2) (match_dup 4)]
2048 1.1.1.2 mrg UNSPEC_SEL))
2049 1.1.1.2 mrg (set (match_dup 0)
2050 1.1.1.2 mrg (unspec:SVE_I
2051 1.1.1.2 mrg [(match_dup 1)
2052 1.1.1.2 mrg (match_op_dup 5 [(match_dup 0) (match_dup 3)])
2053 1.1.1.2 mrg (match_dup 0)]
2054 1.1.1.2 mrg UNSPEC_SEL))]
2055 1.1 mrg )
2056 1.1 mrg
2057 1.1 mrg ;; Set operand 0 to the last active element in operand 3, or to tied
2058 1.1 mrg ;; operand 1 if no elements are active.
2059 1.1 mrg (define_insn "fold_extract_last_<mode>"
2060 1.1 mrg [(set (match_operand:<VEL> 0 "register_operand" "=r, w")
2061 1.1 mrg (unspec:<VEL>
2062 1.1 mrg [(match_operand:<VEL> 1 "register_operand" "0, 0")
2063 1.1 mrg (match_operand:<VPRED> 2 "register_operand" "Upl, Upl")
2064 1.1 mrg (match_operand:SVE_ALL 3 "register_operand" "w, w")]
2065 1.1 mrg UNSPEC_CLASTB))]
2066 1.1 mrg "TARGET_SVE"
2067 1.1 mrg "@
2068 1.1 mrg clastb\t%<vwcore>0, %2, %<vwcore>0, %3.<Vetype>
2069 1.1 mrg clastb\t%<vw>0, %2, %<vw>0, %3.<Vetype>"
2070 1.1 mrg )
2071 1.1 mrg
2072 1.1 mrg ;; Unpredicated integer add reduction.
2073 1.1 mrg (define_expand "reduc_plus_scal_<mode>"
2074 1.1 mrg [(set (match_operand:<VEL> 0 "register_operand")
2075 1.1 mrg (unspec:<VEL> [(match_dup 2)
2076 1.1 mrg (match_operand:SVE_I 1 "register_operand")]
2077 1.1 mrg UNSPEC_ADDV))]
2078 1.1 mrg "TARGET_SVE"
2079 1.1 mrg {
2080 1.1 mrg operands[2] = force_reg (<VPRED>mode, CONSTM1_RTX (<VPRED>mode));
2081 1.1 mrg }
2082 1.1 mrg )
2083 1.1 mrg
2084 1.1 mrg ;; Predicated integer add reduction. The result is always 64-bits.
2085 1.1 mrg (define_insn "*reduc_plus_scal_<mode>"
2086 1.1 mrg [(set (match_operand:<VEL> 0 "register_operand" "=w")
2087 1.1 mrg (unspec:<VEL> [(match_operand:<VPRED> 1 "register_operand" "Upl")
2088 1.1 mrg (match_operand:SVE_I 2 "register_operand" "w")]
2089 1.1 mrg UNSPEC_ADDV))]
2090 1.1 mrg "TARGET_SVE"
2091 1.1 mrg "uaddv\t%d0, %1, %2.<Vetype>"
2092 1.1 mrg )
2093 1.1 mrg
2094 1.1 mrg ;; Unpredicated floating-point add reduction.
2095 1.1 mrg (define_expand "reduc_plus_scal_<mode>"
2096 1.1 mrg [(set (match_operand:<VEL> 0 "register_operand")
2097 1.1 mrg (unspec:<VEL> [(match_dup 2)
2098 1.1 mrg (match_operand:SVE_F 1 "register_operand")]
2099 1.1 mrg UNSPEC_FADDV))]
2100 1.1 mrg "TARGET_SVE"
2101 1.1 mrg {
2102 1.1 mrg operands[2] = force_reg (<VPRED>mode, CONSTM1_RTX (<VPRED>mode));
2103 1.1 mrg }
2104 1.1 mrg )
2105 1.1 mrg
2106 1.1 mrg ;; Predicated floating-point add reduction.
2107 1.1 mrg (define_insn "*reduc_plus_scal_<mode>"
2108 1.1 mrg [(set (match_operand:<VEL> 0 "register_operand" "=w")
2109 1.1 mrg (unspec:<VEL> [(match_operand:<VPRED> 1 "register_operand" "Upl")
2110 1.1 mrg (match_operand:SVE_F 2 "register_operand" "w")]
2111 1.1 mrg UNSPEC_FADDV))]
2112 1.1 mrg "TARGET_SVE"
2113 1.1 mrg "faddv\t%<Vetype>0, %1, %2.<Vetype>"
2114 1.1 mrg )
2115 1.1 mrg
2116 1.1 mrg ;; Unpredicated integer MIN/MAX reduction.
2117 1.1 mrg (define_expand "reduc_<maxmin_uns>_scal_<mode>"
2118 1.1 mrg [(set (match_operand:<VEL> 0 "register_operand")
2119 1.1 mrg (unspec:<VEL> [(match_dup 2)
2120 1.1 mrg (match_operand:SVE_I 1 "register_operand")]
2121 1.1 mrg MAXMINV))]
2122 1.1 mrg "TARGET_SVE"
2123 1.1 mrg {
2124 1.1 mrg operands[2] = force_reg (<VPRED>mode, CONSTM1_RTX (<VPRED>mode));
2125 1.1 mrg }
2126 1.1 mrg )
2127 1.1 mrg
2128 1.1 mrg ;; Predicated integer MIN/MAX reduction.
2129 1.1 mrg (define_insn "*reduc_<maxmin_uns>_scal_<mode>"
2130 1.1 mrg [(set (match_operand:<VEL> 0 "register_operand" "=w")
2131 1.1 mrg (unspec:<VEL> [(match_operand:<VPRED> 1 "register_operand" "Upl")
2132 1.1 mrg (match_operand:SVE_I 2 "register_operand" "w")]
2133 1.1 mrg MAXMINV))]
2134 1.1 mrg "TARGET_SVE"
2135 1.1 mrg "<maxmin_uns_op>v\t%<Vetype>0, %1, %2.<Vetype>"
2136 1.1 mrg )
2137 1.1 mrg
2138 1.1 mrg ;; Unpredicated floating-point MIN/MAX reduction.
2139 1.1 mrg (define_expand "reduc_<maxmin_uns>_scal_<mode>"
2140 1.1 mrg [(set (match_operand:<VEL> 0 "register_operand")
2141 1.1 mrg (unspec:<VEL> [(match_dup 2)
2142 1.1 mrg (match_operand:SVE_F 1 "register_operand")]
2143 1.1 mrg FMAXMINV))]
2144 1.1 mrg "TARGET_SVE"
2145 1.1 mrg {
2146 1.1 mrg operands[2] = force_reg (<VPRED>mode, CONSTM1_RTX (<VPRED>mode));
2147 1.1 mrg }
2148 1.1 mrg )
2149 1.1 mrg
2150 1.1 mrg ;; Predicated floating-point MIN/MAX reduction.
2151 1.1 mrg (define_insn "*reduc_<maxmin_uns>_scal_<mode>"
2152 1.1 mrg [(set (match_operand:<VEL> 0 "register_operand" "=w")
2153 1.1 mrg (unspec:<VEL> [(match_operand:<VPRED> 1 "register_operand" "Upl")
2154 1.1 mrg (match_operand:SVE_F 2 "register_operand" "w")]
2155 1.1 mrg FMAXMINV))]
2156 1.1 mrg "TARGET_SVE"
2157 1.1 mrg "<maxmin_uns_op>v\t%<Vetype>0, %1, %2.<Vetype>"
2158 1.1 mrg )
2159 1.1 mrg
2160 1.1 mrg (define_expand "reduc_<optab>_scal_<mode>"
2161 1.1 mrg [(set (match_operand:<VEL> 0 "register_operand")
2162 1.1 mrg (unspec:<VEL> [(match_dup 2)
2163 1.1 mrg (match_operand:SVE_I 1 "register_operand")]
2164 1.1 mrg BITWISEV))]
2165 1.1 mrg "TARGET_SVE"
2166 1.1 mrg {
2167 1.1 mrg operands[2] = force_reg (<VPRED>mode, CONSTM1_RTX (<VPRED>mode));
2168 1.1 mrg }
2169 1.1 mrg )
2170 1.1 mrg
2171 1.1 mrg (define_insn "*reduc_<optab>_scal_<mode>"
2172 1.1 mrg [(set (match_operand:<VEL> 0 "register_operand" "=w")
2173 1.1 mrg (unspec:<VEL> [(match_operand:<VPRED> 1 "register_operand" "Upl")
2174 1.1 mrg (match_operand:SVE_I 2 "register_operand" "w")]
2175 1.1 mrg BITWISEV))]
2176 1.1 mrg "TARGET_SVE"
2177 1.1 mrg "<bit_reduc_op>\t%<Vetype>0, %1, %2.<Vetype>"
2178 1.1 mrg )
2179 1.1 mrg
2180 1.1 mrg ;; Unpredicated in-order FP reductions.
2181 1.1 mrg (define_expand "fold_left_plus_<mode>"
2182 1.1 mrg [(set (match_operand:<VEL> 0 "register_operand")
2183 1.1 mrg (unspec:<VEL> [(match_dup 3)
2184 1.1 mrg (match_operand:<VEL> 1 "register_operand")
2185 1.1 mrg (match_operand:SVE_F 2 "register_operand")]
2186 1.1 mrg UNSPEC_FADDA))]
2187 1.1 mrg "TARGET_SVE"
2188 1.1 mrg {
2189 1.1 mrg operands[3] = force_reg (<VPRED>mode, CONSTM1_RTX (<VPRED>mode));
2190 1.1 mrg }
2191 1.1 mrg )
2192 1.1 mrg
2193 1.1 mrg ;; In-order FP reductions predicated with PTRUE.
2194 1.1 mrg (define_insn "*fold_left_plus_<mode>"
2195 1.1 mrg [(set (match_operand:<VEL> 0 "register_operand" "=w")
2196 1.1 mrg (unspec:<VEL> [(match_operand:<VPRED> 1 "register_operand" "Upl")
2197 1.1 mrg (match_operand:<VEL> 2 "register_operand" "0")
2198 1.1 mrg (match_operand:SVE_F 3 "register_operand" "w")]
2199 1.1 mrg UNSPEC_FADDA))]
2200 1.1 mrg "TARGET_SVE"
2201 1.1 mrg "fadda\t%<Vetype>0, %1, %<Vetype>0, %3.<Vetype>"
2202 1.1 mrg )
2203 1.1 mrg
2204 1.1 mrg ;; Predicated form of the above in-order reduction.
2205 1.1 mrg (define_insn "*pred_fold_left_plus_<mode>"
2206 1.1 mrg [(set (match_operand:<VEL> 0 "register_operand" "=w")
2207 1.1 mrg (unspec:<VEL>
2208 1.1 mrg [(match_operand:<VEL> 1 "register_operand" "0")
2209 1.1 mrg (unspec:SVE_F
2210 1.1 mrg [(match_operand:<VPRED> 2 "register_operand" "Upl")
2211 1.1 mrg (match_operand:SVE_F 3 "register_operand" "w")
2212 1.1 mrg (match_operand:SVE_F 4 "aarch64_simd_imm_zero")]
2213 1.1 mrg UNSPEC_SEL)]
2214 1.1 mrg UNSPEC_FADDA))]
2215 1.1 mrg "TARGET_SVE"
2216 1.1 mrg "fadda\t%<Vetype>0, %2, %<Vetype>0, %3.<Vetype>"
2217 1.1 mrg )
2218 1.1 mrg
2219 1.1 mrg ;; Unpredicated floating-point addition.
2220 1.1 mrg (define_expand "add<mode>3"
2221 1.1 mrg [(set (match_operand:SVE_F 0 "register_operand")
2222 1.1 mrg (unspec:SVE_F
2223 1.1 mrg [(match_dup 3)
2224 1.1 mrg (plus:SVE_F
2225 1.1 mrg (match_operand:SVE_F 1 "register_operand")
2226 1.1 mrg (match_operand:SVE_F 2 "aarch64_sve_float_arith_with_sub_operand"))]
2227 1.1 mrg UNSPEC_MERGE_PTRUE))]
2228 1.1 mrg "TARGET_SVE"
2229 1.1 mrg {
2230 1.1 mrg operands[3] = force_reg (<VPRED>mode, CONSTM1_RTX (<VPRED>mode));
2231 1.1 mrg }
2232 1.1 mrg )
2233 1.1 mrg
2234 1.1 mrg ;; Floating-point addition predicated with a PTRUE.
2235 1.1.1.2 mrg (define_insn_and_split "*add<mode>3"
2236 1.1 mrg [(set (match_operand:SVE_F 0 "register_operand" "=w, w, w")
2237 1.1 mrg (unspec:SVE_F
2238 1.1 mrg [(match_operand:<VPRED> 1 "register_operand" "Upl, Upl, Upl")
2239 1.1 mrg (plus:SVE_F
2240 1.1 mrg (match_operand:SVE_F 2 "register_operand" "%0, 0, w")
2241 1.1 mrg (match_operand:SVE_F 3 "aarch64_sve_float_arith_with_sub_operand" "vsA, vsN, w"))]
2242 1.1 mrg UNSPEC_MERGE_PTRUE))]
2243 1.1 mrg "TARGET_SVE"
2244 1.1 mrg "@
2245 1.1 mrg fadd\t%0.<Vetype>, %1/m, %0.<Vetype>, #%3
2246 1.1 mrg fsub\t%0.<Vetype>, %1/m, %0.<Vetype>, #%N3
2247 1.1.1.2 mrg #"
2248 1.1.1.2 mrg ; Split the unpredicated form after reload, so that we don't have
2249 1.1.1.2 mrg ; the unnecessary PTRUE.
2250 1.1.1.2 mrg "&& reload_completed
2251 1.1.1.2 mrg && register_operand (operands[3], <MODE>mode)"
2252 1.1.1.2 mrg [(set (match_dup 0) (plus:SVE_F (match_dup 2) (match_dup 3)))]
2253 1.1 mrg )
2254 1.1 mrg
2255 1.1 mrg ;; Unpredicated floating-point subtraction.
2256 1.1 mrg (define_expand "sub<mode>3"
2257 1.1 mrg [(set (match_operand:SVE_F 0 "register_operand")
2258 1.1 mrg (unspec:SVE_F
2259 1.1 mrg [(match_dup 3)
2260 1.1 mrg (minus:SVE_F
2261 1.1 mrg (match_operand:SVE_F 1 "aarch64_sve_float_arith_operand")
2262 1.1 mrg (match_operand:SVE_F 2 "register_operand"))]
2263 1.1 mrg UNSPEC_MERGE_PTRUE))]
2264 1.1 mrg "TARGET_SVE"
2265 1.1 mrg {
2266 1.1 mrg operands[3] = force_reg (<VPRED>mode, CONSTM1_RTX (<VPRED>mode));
2267 1.1 mrg }
2268 1.1 mrg )
2269 1.1 mrg
2270 1.1 mrg ;; Floating-point subtraction predicated with a PTRUE.
2271 1.1.1.2 mrg (define_insn_and_split "*sub<mode>3"
2272 1.1 mrg [(set (match_operand:SVE_F 0 "register_operand" "=w, w, w, w")
2273 1.1 mrg (unspec:SVE_F
2274 1.1 mrg [(match_operand:<VPRED> 1 "register_operand" "Upl, Upl, Upl, Upl")
2275 1.1 mrg (minus:SVE_F
2276 1.1 mrg (match_operand:SVE_F 2 "aarch64_sve_float_arith_operand" "0, 0, vsA, w")
2277 1.1 mrg (match_operand:SVE_F 3 "aarch64_sve_float_arith_with_sub_operand" "vsA, vsN, 0, w"))]
2278 1.1 mrg UNSPEC_MERGE_PTRUE))]
2279 1.1 mrg "TARGET_SVE
2280 1.1 mrg && (register_operand (operands[2], <MODE>mode)
2281 1.1 mrg || register_operand (operands[3], <MODE>mode))"
2282 1.1 mrg "@
2283 1.1 mrg fsub\t%0.<Vetype>, %1/m, %0.<Vetype>, #%3
2284 1.1 mrg fadd\t%0.<Vetype>, %1/m, %0.<Vetype>, #%N3
2285 1.1 mrg fsubr\t%0.<Vetype>, %1/m, %0.<Vetype>, #%2
2286 1.1.1.2 mrg #"
2287 1.1.1.2 mrg ; Split the unpredicated form after reload, so that we don't have
2288 1.1.1.2 mrg ; the unnecessary PTRUE.
2289 1.1.1.2 mrg "&& reload_completed
2290 1.1.1.2 mrg && register_operand (operands[2], <MODE>mode)
2291 1.1.1.2 mrg && register_operand (operands[3], <MODE>mode)"
2292 1.1.1.2 mrg [(set (match_dup 0) (minus:SVE_F (match_dup 2) (match_dup 3)))]
2293 1.1 mrg )
2294 1.1 mrg
2295 1.1 mrg ;; Unpredicated floating-point multiplication.
2296 1.1 mrg (define_expand "mul<mode>3"
2297 1.1 mrg [(set (match_operand:SVE_F 0 "register_operand")
2298 1.1 mrg (unspec:SVE_F
2299 1.1 mrg [(match_dup 3)
2300 1.1 mrg (mult:SVE_F
2301 1.1 mrg (match_operand:SVE_F 1 "register_operand")
2302 1.1 mrg (match_operand:SVE_F 2 "aarch64_sve_float_mul_operand"))]
2303 1.1 mrg UNSPEC_MERGE_PTRUE))]
2304 1.1 mrg "TARGET_SVE"
2305 1.1 mrg {
2306 1.1 mrg operands[3] = force_reg (<VPRED>mode, CONSTM1_RTX (<VPRED>mode));
2307 1.1 mrg }
2308 1.1 mrg )
2309 1.1 mrg
2310 1.1 mrg ;; Floating-point multiplication predicated with a PTRUE.
2311 1.1.1.2 mrg (define_insn_and_split "*mul<mode>3"
2312 1.1 mrg [(set (match_operand:SVE_F 0 "register_operand" "=w, w")
2313 1.1 mrg (unspec:SVE_F
2314 1.1 mrg [(match_operand:<VPRED> 1 "register_operand" "Upl, Upl")
2315 1.1 mrg (mult:SVE_F
2316 1.1 mrg (match_operand:SVE_F 2 "register_operand" "%0, w")
2317 1.1 mrg (match_operand:SVE_F 3 "aarch64_sve_float_mul_operand" "vsM, w"))]
2318 1.1 mrg UNSPEC_MERGE_PTRUE))]
2319 1.1 mrg "TARGET_SVE"
2320 1.1 mrg "@
2321 1.1 mrg fmul\t%0.<Vetype>, %1/m, %0.<Vetype>, #%3
2322 1.1.1.2 mrg #"
2323 1.1.1.2 mrg ; Split the unpredicated form after reload, so that we don't have
2324 1.1.1.2 mrg ; the unnecessary PTRUE.
2325 1.1.1.2 mrg "&& reload_completed
2326 1.1.1.2 mrg && register_operand (operands[3], <MODE>mode)"
2327 1.1.1.2 mrg [(set (match_dup 0) (mult:SVE_F (match_dup 2) (match_dup 3)))]
2328 1.1 mrg )
2329 1.1 mrg
2330 1.1.1.2 mrg ;; Unpredicated floating-point binary operations (post-RA only).
2331 1.1.1.2 mrg ;; These are generated by splitting a predicated instruction whose
2332 1.1.1.2 mrg ;; predicate is unused.
2333 1.1.1.2 mrg (define_insn "*post_ra_<sve_fp_op><mode>3"
2334 1.1.1.2 mrg [(set (match_operand:SVE_F 0 "register_operand" "=w")
2335 1.1.1.2 mrg (SVE_UNPRED_FP_BINARY:SVE_F
2336 1.1.1.2 mrg (match_operand:SVE_F 1 "register_operand" "w")
2337 1.1.1.2 mrg (match_operand:SVE_F 2 "register_operand" "w")))]
2338 1.1.1.2 mrg "TARGET_SVE && reload_completed"
2339 1.1.1.2 mrg "<sve_fp_op>\t%0.<Vetype>, %1.<Vetype>, %2.<Vetype>")
2340 1.1.1.2 mrg
2341 1.1 mrg ;; Unpredicated fma (%0 = (%1 * %2) + %3).
2342 1.1 mrg (define_expand "fma<mode>4"
2343 1.1 mrg [(set (match_operand:SVE_F 0 "register_operand")
2344 1.1 mrg (unspec:SVE_F
2345 1.1 mrg [(match_dup 4)
2346 1.1 mrg (fma:SVE_F (match_operand:SVE_F 1 "register_operand")
2347 1.1 mrg (match_operand:SVE_F 2 "register_operand")
2348 1.1 mrg (match_operand:SVE_F 3 "register_operand"))]
2349 1.1 mrg UNSPEC_MERGE_PTRUE))]
2350 1.1 mrg "TARGET_SVE"
2351 1.1 mrg {
2352 1.1 mrg operands[4] = force_reg (<VPRED>mode, CONSTM1_RTX (<VPRED>mode));
2353 1.1 mrg }
2354 1.1 mrg )
2355 1.1 mrg
2356 1.1 mrg ;; fma predicated with a PTRUE.
2357 1.1 mrg (define_insn "*fma<mode>4"
2358 1.1.1.2 mrg [(set (match_operand:SVE_F 0 "register_operand" "=w, w, ?&w")
2359 1.1 mrg (unspec:SVE_F
2360 1.1.1.2 mrg [(match_operand:<VPRED> 1 "register_operand" "Upl, Upl, Upl")
2361 1.1.1.2 mrg (fma:SVE_F (match_operand:SVE_F 3 "register_operand" "%0, w, w")
2362 1.1.1.2 mrg (match_operand:SVE_F 4 "register_operand" "w, w, w")
2363 1.1.1.2 mrg (match_operand:SVE_F 2 "register_operand" "w, 0, w"))]
2364 1.1 mrg UNSPEC_MERGE_PTRUE))]
2365 1.1 mrg "TARGET_SVE"
2366 1.1 mrg "@
2367 1.1 mrg fmad\t%0.<Vetype>, %1/m, %4.<Vetype>, %2.<Vetype>
2368 1.1.1.2 mrg fmla\t%0.<Vetype>, %1/m, %3.<Vetype>, %4.<Vetype>
2369 1.1.1.2 mrg movprfx\t%0, %2\;fmla\t%0.<Vetype>, %1/m, %3.<Vetype>, %4.<Vetype>"
2370 1.1.1.2 mrg [(set_attr "movprfx" "*,*,yes")]
2371 1.1 mrg )
2372 1.1 mrg
2373 1.1 mrg ;; Unpredicated fnma (%0 = (-%1 * %2) + %3).
2374 1.1 mrg (define_expand "fnma<mode>4"
2375 1.1 mrg [(set (match_operand:SVE_F 0 "register_operand")
2376 1.1 mrg (unspec:SVE_F
2377 1.1 mrg [(match_dup 4)
2378 1.1 mrg (fma:SVE_F (neg:SVE_F
2379 1.1 mrg (match_operand:SVE_F 1 "register_operand"))
2380 1.1 mrg (match_operand:SVE_F 2 "register_operand")
2381 1.1 mrg (match_operand:SVE_F 3 "register_operand"))]
2382 1.1 mrg UNSPEC_MERGE_PTRUE))]
2383 1.1 mrg "TARGET_SVE"
2384 1.1 mrg {
2385 1.1 mrg operands[4] = force_reg (<VPRED>mode, CONSTM1_RTX (<VPRED>mode));
2386 1.1 mrg }
2387 1.1 mrg )
2388 1.1 mrg
2389 1.1 mrg ;; fnma predicated with a PTRUE.
2390 1.1 mrg (define_insn "*fnma<mode>4"
2391 1.1.1.2 mrg [(set (match_operand:SVE_F 0 "register_operand" "=w, w, ?&w")
2392 1.1 mrg (unspec:SVE_F
2393 1.1.1.2 mrg [(match_operand:<VPRED> 1 "register_operand" "Upl, Upl, Upl")
2394 1.1 mrg (fma:SVE_F (neg:SVE_F
2395 1.1.1.2 mrg (match_operand:SVE_F 3 "register_operand" "%0, w, w"))
2396 1.1.1.2 mrg (match_operand:SVE_F 4 "register_operand" "w, w, w")
2397 1.1.1.2 mrg (match_operand:SVE_F 2 "register_operand" "w, 0, w"))]
2398 1.1 mrg UNSPEC_MERGE_PTRUE))]
2399 1.1 mrg "TARGET_SVE"
2400 1.1 mrg "@
2401 1.1 mrg fmsb\t%0.<Vetype>, %1/m, %4.<Vetype>, %2.<Vetype>
2402 1.1.1.2 mrg fmls\t%0.<Vetype>, %1/m, %3.<Vetype>, %4.<Vetype>
2403 1.1.1.2 mrg movprfx\t%0, %2\;fmls\t%0.<Vetype>, %1/m, %3.<Vetype>, %4.<Vetype>"
2404 1.1.1.2 mrg [(set_attr "movprfx" "*,*,yes")]
2405 1.1 mrg )
2406 1.1 mrg
2407 1.1 mrg ;; Unpredicated fms (%0 = (%1 * %2) - %3).
2408 1.1 mrg (define_expand "fms<mode>4"
2409 1.1 mrg [(set (match_operand:SVE_F 0 "register_operand")
2410 1.1 mrg (unspec:SVE_F
2411 1.1 mrg [(match_dup 4)
2412 1.1 mrg (fma:SVE_F (match_operand:SVE_F 1 "register_operand")
2413 1.1 mrg (match_operand:SVE_F 2 "register_operand")
2414 1.1 mrg (neg:SVE_F
2415 1.1 mrg (match_operand:SVE_F 3 "register_operand")))]
2416 1.1 mrg UNSPEC_MERGE_PTRUE))]
2417 1.1 mrg "TARGET_SVE"
2418 1.1 mrg {
2419 1.1 mrg operands[4] = force_reg (<VPRED>mode, CONSTM1_RTX (<VPRED>mode));
2420 1.1 mrg }
2421 1.1 mrg )
2422 1.1 mrg
2423 1.1 mrg ;; fms predicated with a PTRUE.
2424 1.1 mrg (define_insn "*fms<mode>4"
2425 1.1.1.2 mrg [(set (match_operand:SVE_F 0 "register_operand" "=w, w, ?&w")
2426 1.1 mrg (unspec:SVE_F
2427 1.1.1.2 mrg [(match_operand:<VPRED> 1 "register_operand" "Upl, Upl, Upl")
2428 1.1.1.2 mrg (fma:SVE_F (match_operand:SVE_F 3 "register_operand" "%0, w, w")
2429 1.1.1.2 mrg (match_operand:SVE_F 4 "register_operand" "w, w, w")
2430 1.1 mrg (neg:SVE_F
2431 1.1.1.2 mrg (match_operand:SVE_F 2 "register_operand" "w, 0, w")))]
2432 1.1 mrg UNSPEC_MERGE_PTRUE))]
2433 1.1 mrg "TARGET_SVE"
2434 1.1 mrg "@
2435 1.1 mrg fnmsb\t%0.<Vetype>, %1/m, %4.<Vetype>, %2.<Vetype>
2436 1.1.1.2 mrg fnmls\t%0.<Vetype>, %1/m, %3.<Vetype>, %4.<Vetype>
2437 1.1.1.2 mrg movprfx\t%0, %2\;fnmls\t%0.<Vetype>, %1/m, %3.<Vetype>, %4.<Vetype>"
2438 1.1.1.2 mrg [(set_attr "movprfx" "*,*,yes")]
2439 1.1 mrg )
2440 1.1 mrg
2441 1.1 mrg ;; Unpredicated fnms (%0 = (-%1 * %2) - %3).
2442 1.1 mrg (define_expand "fnms<mode>4"
2443 1.1 mrg [(set (match_operand:SVE_F 0 "register_operand")
2444 1.1 mrg (unspec:SVE_F
2445 1.1 mrg [(match_dup 4)
2446 1.1 mrg (fma:SVE_F (neg:SVE_F
2447 1.1 mrg (match_operand:SVE_F 1 "register_operand"))
2448 1.1 mrg (match_operand:SVE_F 2 "register_operand")
2449 1.1 mrg (neg:SVE_F
2450 1.1 mrg (match_operand:SVE_F 3 "register_operand")))]
2451 1.1 mrg UNSPEC_MERGE_PTRUE))]
2452 1.1 mrg "TARGET_SVE"
2453 1.1 mrg {
2454 1.1 mrg operands[4] = force_reg (<VPRED>mode, CONSTM1_RTX (<VPRED>mode));
2455 1.1 mrg }
2456 1.1 mrg )
2457 1.1 mrg
2458 1.1 mrg ;; fnms predicated with a PTRUE.
2459 1.1 mrg (define_insn "*fnms<mode>4"
2460 1.1.1.2 mrg [(set (match_operand:SVE_F 0 "register_operand" "=w, w, ?&w")
2461 1.1 mrg (unspec:SVE_F
2462 1.1.1.2 mrg [(match_operand:<VPRED> 1 "register_operand" "Upl, Upl, Upl")
2463 1.1 mrg (fma:SVE_F (neg:SVE_F
2464 1.1.1.2 mrg (match_operand:SVE_F 3 "register_operand" "%0, w, w"))
2465 1.1.1.2 mrg (match_operand:SVE_F 4 "register_operand" "w, w, w")
2466 1.1 mrg (neg:SVE_F
2467 1.1.1.2 mrg (match_operand:SVE_F 2 "register_operand" "w, 0, w")))]
2468 1.1 mrg UNSPEC_MERGE_PTRUE))]
2469 1.1 mrg "TARGET_SVE"
2470 1.1 mrg "@
2471 1.1 mrg fnmad\t%0.<Vetype>, %1/m, %4.<Vetype>, %2.<Vetype>
2472 1.1.1.2 mrg fnmla\t%0.<Vetype>, %1/m, %3.<Vetype>, %4.<Vetype>
2473 1.1.1.2 mrg movprfx\t%0, %2\;fnmla\t%0.<Vetype>, %1/m, %3.<Vetype>, %4.<Vetype>"
2474 1.1.1.2 mrg [(set_attr "movprfx" "*,*,yes")]
2475 1.1 mrg )
2476 1.1 mrg
2477 1.1 mrg ;; Unpredicated floating-point division.
2478 1.1 mrg (define_expand "div<mode>3"
2479 1.1 mrg [(set (match_operand:SVE_F 0 "register_operand")
2480 1.1 mrg (unspec:SVE_F
2481 1.1 mrg [(match_dup 3)
2482 1.1 mrg (div:SVE_F (match_operand:SVE_F 1 "register_operand")
2483 1.1 mrg (match_operand:SVE_F 2 "register_operand"))]
2484 1.1 mrg UNSPEC_MERGE_PTRUE))]
2485 1.1 mrg "TARGET_SVE"
2486 1.1 mrg {
2487 1.1 mrg operands[3] = force_reg (<VPRED>mode, CONSTM1_RTX (<VPRED>mode));
2488 1.1 mrg }
2489 1.1 mrg )
2490 1.1 mrg
2491 1.1 mrg ;; Floating-point division predicated with a PTRUE.
2492 1.1 mrg (define_insn "*div<mode>3"
2493 1.1.1.2 mrg [(set (match_operand:SVE_F 0 "register_operand" "=w, w, ?&w")
2494 1.1 mrg (unspec:SVE_F
2495 1.1.1.2 mrg [(match_operand:<VPRED> 1 "register_operand" "Upl, Upl, Upl")
2496 1.1.1.2 mrg (div:SVE_F (match_operand:SVE_F 2 "register_operand" "0, w, w")
2497 1.1.1.2 mrg (match_operand:SVE_F 3 "register_operand" "w, 0, w"))]
2498 1.1 mrg UNSPEC_MERGE_PTRUE))]
2499 1.1 mrg "TARGET_SVE"
2500 1.1 mrg "@
2501 1.1 mrg fdiv\t%0.<Vetype>, %1/m, %0.<Vetype>, %3.<Vetype>
2502 1.1.1.2 mrg fdivr\t%0.<Vetype>, %1/m, %0.<Vetype>, %2.<Vetype>
2503 1.1.1.2 mrg movprfx\t%0, %2\;fdiv\t%0.<Vetype>, %1/m, %0.<Vetype>, %3.<Vetype>"
2504 1.1.1.2 mrg [(set_attr "movprfx" "*,*,yes")]
2505 1.1 mrg )
2506 1.1 mrg
2507 1.1 mrg ;; Unpredicated FNEG, FABS and FSQRT.
2508 1.1 mrg (define_expand "<optab><mode>2"
2509 1.1 mrg [(set (match_operand:SVE_F 0 "register_operand")
2510 1.1 mrg (unspec:SVE_F
2511 1.1 mrg [(match_dup 2)
2512 1.1 mrg (SVE_FP_UNARY:SVE_F (match_operand:SVE_F 1 "register_operand"))]
2513 1.1 mrg UNSPEC_MERGE_PTRUE))]
2514 1.1 mrg "TARGET_SVE"
2515 1.1 mrg {
2516 1.1 mrg operands[2] = force_reg (<VPRED>mode, CONSTM1_RTX (<VPRED>mode));
2517 1.1 mrg }
2518 1.1 mrg )
2519 1.1 mrg
2520 1.1 mrg ;; FNEG, FABS and FSQRT predicated with a PTRUE.
2521 1.1 mrg (define_insn "*<optab><mode>2"
2522 1.1 mrg [(set (match_operand:SVE_F 0 "register_operand" "=w")
2523 1.1 mrg (unspec:SVE_F
2524 1.1 mrg [(match_operand:<VPRED> 1 "register_operand" "Upl")
2525 1.1 mrg (SVE_FP_UNARY:SVE_F (match_operand:SVE_F 2 "register_operand" "w"))]
2526 1.1 mrg UNSPEC_MERGE_PTRUE))]
2527 1.1 mrg "TARGET_SVE"
2528 1.1 mrg "<sve_fp_op>\t%0.<Vetype>, %1/m, %2.<Vetype>"
2529 1.1 mrg )
2530 1.1 mrg
2531 1.1 mrg ;; Unpredicated FRINTy.
2532 1.1 mrg (define_expand "<frint_pattern><mode>2"
2533 1.1 mrg [(set (match_operand:SVE_F 0 "register_operand")
2534 1.1 mrg (unspec:SVE_F
2535 1.1 mrg [(match_dup 2)
2536 1.1 mrg (unspec:SVE_F [(match_operand:SVE_F 1 "register_operand")]
2537 1.1 mrg FRINT)]
2538 1.1 mrg UNSPEC_MERGE_PTRUE))]
2539 1.1 mrg "TARGET_SVE"
2540 1.1 mrg {
2541 1.1 mrg operands[2] = force_reg (<VPRED>mode, CONSTM1_RTX (<VPRED>mode));
2542 1.1 mrg }
2543 1.1 mrg )
2544 1.1 mrg
2545 1.1 mrg ;; FRINTy predicated with a PTRUE.
2546 1.1 mrg (define_insn "*<frint_pattern><mode>2"
2547 1.1 mrg [(set (match_operand:SVE_F 0 "register_operand" "=w")
2548 1.1 mrg (unspec:SVE_F
2549 1.1 mrg [(match_operand:<VPRED> 1 "register_operand" "Upl")
2550 1.1 mrg (unspec:SVE_F [(match_operand:SVE_F 2 "register_operand" "w")]
2551 1.1 mrg FRINT)]
2552 1.1 mrg UNSPEC_MERGE_PTRUE))]
2553 1.1 mrg "TARGET_SVE"
2554 1.1 mrg "frint<frint_suffix>\t%0.<Vetype>, %1/m, %2.<Vetype>"
2555 1.1 mrg )
2556 1.1 mrg
2557 1.1 mrg ;; Unpredicated conversion of floats to integers of the same size (HF to HI,
2558 1.1 mrg ;; SF to SI or DF to DI).
2559 1.1 mrg (define_expand "<fix_trunc_optab><mode><v_int_equiv>2"
2560 1.1 mrg [(set (match_operand:<V_INT_EQUIV> 0 "register_operand")
2561 1.1 mrg (unspec:<V_INT_EQUIV>
2562 1.1 mrg [(match_dup 2)
2563 1.1 mrg (FIXUORS:<V_INT_EQUIV>
2564 1.1 mrg (match_operand:SVE_F 1 "register_operand"))]
2565 1.1 mrg UNSPEC_MERGE_PTRUE))]
2566 1.1 mrg "TARGET_SVE"
2567 1.1 mrg {
2568 1.1 mrg operands[2] = force_reg (<VPRED>mode, CONSTM1_RTX (<VPRED>mode));
2569 1.1 mrg }
2570 1.1 mrg )
2571 1.1 mrg
2572 1.1 mrg ;; Conversion of SF to DI, SI or HI, predicated with a PTRUE.
2573 1.1 mrg (define_insn "*<fix_trunc_optab>v16hsf<mode>2"
2574 1.1 mrg [(set (match_operand:SVE_HSDI 0 "register_operand" "=w")
2575 1.1 mrg (unspec:SVE_HSDI
2576 1.1 mrg [(match_operand:<VPRED> 1 "register_operand" "Upl")
2577 1.1 mrg (FIXUORS:SVE_HSDI
2578 1.1 mrg (match_operand:VNx8HF 2 "register_operand" "w"))]
2579 1.1 mrg UNSPEC_MERGE_PTRUE))]
2580 1.1 mrg "TARGET_SVE"
2581 1.1 mrg "fcvtz<su>\t%0.<Vetype>, %1/m, %2.h"
2582 1.1 mrg )
2583 1.1 mrg
2584 1.1 mrg ;; Conversion of SF to DI or SI, predicated with a PTRUE.
2585 1.1 mrg (define_insn "*<fix_trunc_optab>vnx4sf<mode>2"
2586 1.1 mrg [(set (match_operand:SVE_SDI 0 "register_operand" "=w")
2587 1.1 mrg (unspec:SVE_SDI
2588 1.1 mrg [(match_operand:<VPRED> 1 "register_operand" "Upl")
2589 1.1 mrg (FIXUORS:SVE_SDI
2590 1.1 mrg (match_operand:VNx4SF 2 "register_operand" "w"))]
2591 1.1 mrg UNSPEC_MERGE_PTRUE))]
2592 1.1 mrg "TARGET_SVE"
2593 1.1 mrg "fcvtz<su>\t%0.<Vetype>, %1/m, %2.s"
2594 1.1 mrg )
2595 1.1 mrg
2596 1.1 mrg ;; Conversion of DF to DI or SI, predicated with a PTRUE.
2597 1.1 mrg (define_insn "*<fix_trunc_optab>vnx2df<mode>2"
2598 1.1 mrg [(set (match_operand:SVE_SDI 0 "register_operand" "=w")
2599 1.1 mrg (unspec:SVE_SDI
2600 1.1 mrg [(match_operand:VNx2BI 1 "register_operand" "Upl")
2601 1.1 mrg (FIXUORS:SVE_SDI
2602 1.1 mrg (match_operand:VNx2DF 2 "register_operand" "w"))]
2603 1.1 mrg UNSPEC_MERGE_PTRUE))]
2604 1.1 mrg "TARGET_SVE"
2605 1.1 mrg "fcvtz<su>\t%0.<Vetype>, %1/m, %2.d"
2606 1.1 mrg )
2607 1.1 mrg
2608 1.1 mrg ;; Unpredicated conversion of integers to floats of the same size
2609 1.1 mrg ;; (HI to HF, SI to SF or DI to DF).
2610 1.1 mrg (define_expand "<optab><v_int_equiv><mode>2"
2611 1.1 mrg [(set (match_operand:SVE_F 0 "register_operand")
2612 1.1 mrg (unspec:SVE_F
2613 1.1 mrg [(match_dup 2)
2614 1.1 mrg (FLOATUORS:SVE_F
2615 1.1 mrg (match_operand:<V_INT_EQUIV> 1 "register_operand"))]
2616 1.1 mrg UNSPEC_MERGE_PTRUE))]
2617 1.1 mrg "TARGET_SVE"
2618 1.1 mrg {
2619 1.1 mrg operands[2] = force_reg (<VPRED>mode, CONSTM1_RTX (<VPRED>mode));
2620 1.1 mrg }
2621 1.1 mrg )
2622 1.1 mrg
2623 1.1 mrg ;; Conversion of DI, SI or HI to the same number of HFs, predicated
2624 1.1 mrg ;; with a PTRUE.
2625 1.1 mrg (define_insn "*<optab><mode>vnx8hf2"
2626 1.1 mrg [(set (match_operand:VNx8HF 0 "register_operand" "=w")
2627 1.1 mrg (unspec:VNx8HF
2628 1.1 mrg [(match_operand:<VPRED> 1 "register_operand" "Upl")
2629 1.1 mrg (FLOATUORS:VNx8HF
2630 1.1 mrg (match_operand:SVE_HSDI 2 "register_operand" "w"))]
2631 1.1 mrg UNSPEC_MERGE_PTRUE))]
2632 1.1 mrg "TARGET_SVE"
2633 1.1 mrg "<su_optab>cvtf\t%0.h, %1/m, %2.<Vetype>"
2634 1.1 mrg )
2635 1.1 mrg
2636 1.1 mrg ;; Conversion of DI or SI to the same number of SFs, predicated with a PTRUE.
2637 1.1 mrg (define_insn "*<optab><mode>vnx4sf2"
2638 1.1 mrg [(set (match_operand:VNx4SF 0 "register_operand" "=w")
2639 1.1 mrg (unspec:VNx4SF
2640 1.1 mrg [(match_operand:<VPRED> 1 "register_operand" "Upl")
2641 1.1 mrg (FLOATUORS:VNx4SF
2642 1.1 mrg (match_operand:SVE_SDI 2 "register_operand" "w"))]
2643 1.1 mrg UNSPEC_MERGE_PTRUE))]
2644 1.1 mrg "TARGET_SVE"
2645 1.1 mrg "<su_optab>cvtf\t%0.s, %1/m, %2.<Vetype>"
2646 1.1 mrg )
2647 1.1 mrg
2648 1.1 mrg ;; Conversion of DI or SI to DF, predicated with a PTRUE.
2649 1.1 mrg (define_insn "aarch64_sve_<optab><mode>vnx2df2"
2650 1.1 mrg [(set (match_operand:VNx2DF 0 "register_operand" "=w")
2651 1.1 mrg (unspec:VNx2DF
2652 1.1 mrg [(match_operand:VNx2BI 1 "register_operand" "Upl")
2653 1.1 mrg (FLOATUORS:VNx2DF
2654 1.1 mrg (match_operand:SVE_SDI 2 "register_operand" "w"))]
2655 1.1 mrg UNSPEC_MERGE_PTRUE))]
2656 1.1 mrg "TARGET_SVE"
2657 1.1 mrg "<su_optab>cvtf\t%0.d, %1/m, %2.<Vetype>"
2658 1.1 mrg )
2659 1.1 mrg
2660 1.1 mrg ;; Conversion of DFs to the same number of SFs, or SFs to the same number
2661 1.1 mrg ;; of HFs.
2662 1.1 mrg (define_insn "*trunc<Vwide><mode>2"
2663 1.1 mrg [(set (match_operand:SVE_HSF 0 "register_operand" "=w")
2664 1.1 mrg (unspec:SVE_HSF
2665 1.1 mrg [(match_operand:<VWIDE_PRED> 1 "register_operand" "Upl")
2666 1.1 mrg (unspec:SVE_HSF
2667 1.1 mrg [(match_operand:<VWIDE> 2 "register_operand" "w")]
2668 1.1 mrg UNSPEC_FLOAT_CONVERT)]
2669 1.1 mrg UNSPEC_MERGE_PTRUE))]
2670 1.1 mrg "TARGET_SVE"
2671 1.1 mrg "fcvt\t%0.<Vetype>, %1/m, %2.<Vewtype>"
2672 1.1 mrg )
2673 1.1 mrg
2674 1.1 mrg ;; Conversion of SFs to the same number of DFs, or HFs to the same number
2675 1.1 mrg ;; of SFs.
2676 1.1 mrg (define_insn "aarch64_sve_extend<mode><Vwide>2"
2677 1.1 mrg [(set (match_operand:<VWIDE> 0 "register_operand" "=w")
2678 1.1 mrg (unspec:<VWIDE>
2679 1.1 mrg [(match_operand:<VWIDE_PRED> 1 "register_operand" "Upl")
2680 1.1 mrg (unspec:<VWIDE>
2681 1.1 mrg [(match_operand:SVE_HSF 2 "register_operand" "w")]
2682 1.1 mrg UNSPEC_FLOAT_CONVERT)]
2683 1.1 mrg UNSPEC_MERGE_PTRUE))]
2684 1.1 mrg "TARGET_SVE"
2685 1.1 mrg "fcvt\t%0.<Vewtype>, %1/m, %2.<Vetype>"
2686 1.1 mrg )
2687 1.1 mrg
2688 1.1 mrg ;; Unpack the low or high half of a predicate, where "high" refers to
2689 1.1 mrg ;; the low-numbered lanes for big-endian and the high-numbered lanes
2690 1.1 mrg ;; for little-endian.
2691 1.1 mrg (define_expand "vec_unpack<su>_<perm_hilo>_<mode>"
2692 1.1 mrg [(match_operand:<VWIDE> 0 "register_operand")
2693 1.1 mrg (unspec:<VWIDE> [(match_operand:PRED_BHS 1 "register_operand")]
2694 1.1 mrg UNPACK)]
2695 1.1 mrg "TARGET_SVE"
2696 1.1 mrg {
2697 1.1 mrg emit_insn ((<hi_lanes_optab>
2698 1.1 mrg ? gen_aarch64_sve_punpkhi_<PRED_BHS:mode>
2699 1.1 mrg : gen_aarch64_sve_punpklo_<PRED_BHS:mode>)
2700 1.1 mrg (operands[0], operands[1]));
2701 1.1 mrg DONE;
2702 1.1 mrg }
2703 1.1 mrg )
2704 1.1 mrg
2705 1.1 mrg ;; PUNPKHI and PUNPKLO.
2706 1.1 mrg (define_insn "aarch64_sve_punpk<perm_hilo>_<mode>"
2707 1.1 mrg [(set (match_operand:<VWIDE> 0 "register_operand" "=Upa")
2708 1.1 mrg (unspec:<VWIDE> [(match_operand:PRED_BHS 1 "register_operand" "Upa")]
2709 1.1 mrg UNPACK_UNSIGNED))]
2710 1.1 mrg "TARGET_SVE"
2711 1.1 mrg "punpk<perm_hilo>\t%0.h, %1.b"
2712 1.1 mrg )
2713 1.1 mrg
2714 1.1 mrg ;; Unpack the low or high half of a vector, where "high" refers to
2715 1.1 mrg ;; the low-numbered lanes for big-endian and the high-numbered lanes
2716 1.1 mrg ;; for little-endian.
2717 1.1 mrg (define_expand "vec_unpack<su>_<perm_hilo>_<SVE_BHSI:mode>"
2718 1.1 mrg [(match_operand:<VWIDE> 0 "register_operand")
2719 1.1 mrg (unspec:<VWIDE> [(match_operand:SVE_BHSI 1 "register_operand")] UNPACK)]
2720 1.1 mrg "TARGET_SVE"
2721 1.1 mrg {
2722 1.1 mrg emit_insn ((<hi_lanes_optab>
2723 1.1 mrg ? gen_aarch64_sve_<su>unpkhi_<SVE_BHSI:mode>
2724 1.1 mrg : gen_aarch64_sve_<su>unpklo_<SVE_BHSI:mode>)
2725 1.1 mrg (operands[0], operands[1]));
2726 1.1 mrg DONE;
2727 1.1 mrg }
2728 1.1 mrg )
2729 1.1 mrg
2730 1.1 mrg ;; SUNPKHI, UUNPKHI, SUNPKLO and UUNPKLO.
2731 1.1 mrg (define_insn "aarch64_sve_<su>unpk<perm_hilo>_<SVE_BHSI:mode>"
2732 1.1 mrg [(set (match_operand:<VWIDE> 0 "register_operand" "=w")
2733 1.1 mrg (unspec:<VWIDE> [(match_operand:SVE_BHSI 1 "register_operand" "w")]
2734 1.1 mrg UNPACK))]
2735 1.1 mrg "TARGET_SVE"
2736 1.1 mrg "<su>unpk<perm_hilo>\t%0.<Vewtype>, %1.<Vetype>"
2737 1.1 mrg )
2738 1.1 mrg
2739 1.1 mrg ;; Unpack one half of a VNx4SF to VNx2DF, or one half of a VNx8HF to VNx4SF.
2740 1.1 mrg ;; First unpack the source without conversion, then float-convert the
2741 1.1 mrg ;; unpacked source.
2742 1.1 mrg (define_expand "vec_unpacks_<perm_hilo>_<mode>"
2743 1.1 mrg [(match_operand:<VWIDE> 0 "register_operand")
2744 1.1 mrg (unspec:SVE_HSF [(match_operand:SVE_HSF 1 "register_operand")]
2745 1.1 mrg UNPACK_UNSIGNED)]
2746 1.1 mrg "TARGET_SVE"
2747 1.1 mrg {
2748 1.1 mrg /* Use ZIP to do the unpack, since we don't care about the upper halves
2749 1.1 mrg and since it has the nice property of not needing any subregs.
2750 1.1 mrg If using UUNPK* turns out to be preferable, we could model it as
2751 1.1 mrg a ZIP whose first operand is zero. */
2752 1.1 mrg rtx temp = gen_reg_rtx (<MODE>mode);
2753 1.1 mrg emit_insn ((<hi_lanes_optab>
2754 1.1 mrg ? gen_aarch64_sve_zip2<mode>
2755 1.1 mrg : gen_aarch64_sve_zip1<mode>)
2756 1.1 mrg (temp, operands[1], operands[1]));
2757 1.1 mrg rtx ptrue = force_reg (<VWIDE_PRED>mode, CONSTM1_RTX (<VWIDE_PRED>mode));
2758 1.1 mrg emit_insn (gen_aarch64_sve_extend<mode><Vwide>2 (operands[0],
2759 1.1 mrg ptrue, temp));
2760 1.1 mrg DONE;
2761 1.1 mrg }
2762 1.1 mrg )
2763 1.1 mrg
2764 1.1 mrg ;; Unpack one half of a VNx4SI to VNx2DF. First unpack from VNx4SI
2765 1.1 mrg ;; to VNx2DI, reinterpret the VNx2DI as a VNx4SI, then convert the
2766 1.1 mrg ;; unpacked VNx4SI to VNx2DF.
2767 1.1 mrg (define_expand "vec_unpack<su_optab>_float_<perm_hilo>_vnx4si"
2768 1.1 mrg [(match_operand:VNx2DF 0 "register_operand")
2769 1.1 mrg (FLOATUORS:VNx2DF
2770 1.1 mrg (unspec:VNx2DI [(match_operand:VNx4SI 1 "register_operand")]
2771 1.1 mrg UNPACK_UNSIGNED))]
2772 1.1 mrg "TARGET_SVE"
2773 1.1 mrg {
2774 1.1 mrg /* Use ZIP to do the unpack, since we don't care about the upper halves
2775 1.1 mrg and since it has the nice property of not needing any subregs.
2776 1.1 mrg If using UUNPK* turns out to be preferable, we could model it as
2777 1.1 mrg a ZIP whose first operand is zero. */
2778 1.1 mrg rtx temp = gen_reg_rtx (VNx4SImode);
2779 1.1 mrg emit_insn ((<hi_lanes_optab>
2780 1.1 mrg ? gen_aarch64_sve_zip2vnx4si
2781 1.1 mrg : gen_aarch64_sve_zip1vnx4si)
2782 1.1 mrg (temp, operands[1], operands[1]));
2783 1.1 mrg rtx ptrue = force_reg (VNx2BImode, CONSTM1_RTX (VNx2BImode));
2784 1.1 mrg emit_insn (gen_aarch64_sve_<FLOATUORS:optab>vnx4sivnx2df2 (operands[0],
2785 1.1 mrg ptrue, temp));
2786 1.1 mrg DONE;
2787 1.1 mrg }
2788 1.1 mrg )
2789 1.1 mrg
2790 1.1 mrg ;; Predicate pack. Use UZP1 on the narrower type, which discards
2791 1.1 mrg ;; the high part of each wide element.
2792 1.1 mrg (define_insn "vec_pack_trunc_<Vwide>"
2793 1.1 mrg [(set (match_operand:PRED_BHS 0 "register_operand" "=Upa")
2794 1.1 mrg (unspec:PRED_BHS
2795 1.1 mrg [(match_operand:<VWIDE> 1 "register_operand" "Upa")
2796 1.1 mrg (match_operand:<VWIDE> 2 "register_operand" "Upa")]
2797 1.1 mrg UNSPEC_PACK))]
2798 1.1 mrg "TARGET_SVE"
2799 1.1 mrg "uzp1\t%0.<Vetype>, %1.<Vetype>, %2.<Vetype>"
2800 1.1 mrg )
2801 1.1 mrg
2802 1.1 mrg ;; Integer pack. Use UZP1 on the narrower type, which discards
2803 1.1 mrg ;; the high part of each wide element.
2804 1.1 mrg (define_insn "vec_pack_trunc_<Vwide>"
2805 1.1 mrg [(set (match_operand:SVE_BHSI 0 "register_operand" "=w")
2806 1.1 mrg (unspec:SVE_BHSI
2807 1.1 mrg [(match_operand:<VWIDE> 1 "register_operand" "w")
2808 1.1 mrg (match_operand:<VWIDE> 2 "register_operand" "w")]
2809 1.1 mrg UNSPEC_PACK))]
2810 1.1 mrg "TARGET_SVE"
2811 1.1 mrg "uzp1\t%0.<Vetype>, %1.<Vetype>, %2.<Vetype>"
2812 1.1 mrg )
2813 1.1 mrg
2814 1.1 mrg ;; Convert two vectors of DF to SF, or two vectors of SF to HF, and pack
2815 1.1 mrg ;; the results into a single vector.
2816 1.1 mrg (define_expand "vec_pack_trunc_<Vwide>"
2817 1.1 mrg [(set (match_dup 4)
2818 1.1 mrg (unspec:SVE_HSF
2819 1.1 mrg [(match_dup 3)
2820 1.1 mrg (unspec:SVE_HSF [(match_operand:<VWIDE> 1 "register_operand")]
2821 1.1 mrg UNSPEC_FLOAT_CONVERT)]
2822 1.1 mrg UNSPEC_MERGE_PTRUE))
2823 1.1 mrg (set (match_dup 5)
2824 1.1 mrg (unspec:SVE_HSF
2825 1.1 mrg [(match_dup 3)
2826 1.1 mrg (unspec:SVE_HSF [(match_operand:<VWIDE> 2 "register_operand")]
2827 1.1 mrg UNSPEC_FLOAT_CONVERT)]
2828 1.1 mrg UNSPEC_MERGE_PTRUE))
2829 1.1 mrg (set (match_operand:SVE_HSF 0 "register_operand")
2830 1.1 mrg (unspec:SVE_HSF [(match_dup 4) (match_dup 5)] UNSPEC_UZP1))]
2831 1.1 mrg "TARGET_SVE"
2832 1.1 mrg {
2833 1.1 mrg operands[3] = force_reg (<VWIDE_PRED>mode, CONSTM1_RTX (<VWIDE_PRED>mode));
2834 1.1 mrg operands[4] = gen_reg_rtx (<MODE>mode);
2835 1.1 mrg operands[5] = gen_reg_rtx (<MODE>mode);
2836 1.1 mrg }
2837 1.1 mrg )
2838 1.1 mrg
2839 1.1 mrg ;; Convert two vectors of DF to SI and pack the results into a single vector.
2840 1.1 mrg (define_expand "vec_pack_<su>fix_trunc_vnx2df"
2841 1.1 mrg [(set (match_dup 4)
2842 1.1 mrg (unspec:VNx4SI
2843 1.1 mrg [(match_dup 3)
2844 1.1 mrg (FIXUORS:VNx4SI (match_operand:VNx2DF 1 "register_operand"))]
2845 1.1 mrg UNSPEC_MERGE_PTRUE))
2846 1.1 mrg (set (match_dup 5)
2847 1.1 mrg (unspec:VNx4SI
2848 1.1 mrg [(match_dup 3)
2849 1.1 mrg (FIXUORS:VNx4SI (match_operand:VNx2DF 2 "register_operand"))]
2850 1.1 mrg UNSPEC_MERGE_PTRUE))
2851 1.1 mrg (set (match_operand:VNx4SI 0 "register_operand")
2852 1.1 mrg (unspec:VNx4SI [(match_dup 4) (match_dup 5)] UNSPEC_UZP1))]
2853 1.1 mrg "TARGET_SVE"
2854 1.1 mrg {
2855 1.1 mrg operands[3] = force_reg (VNx2BImode, CONSTM1_RTX (VNx2BImode));
2856 1.1 mrg operands[4] = gen_reg_rtx (VNx4SImode);
2857 1.1 mrg operands[5] = gen_reg_rtx (VNx4SImode);
2858 1.1 mrg }
2859 1.1 mrg )
2860 1.1 mrg
2861 1.1.1.2 mrg ;; Predicated floating-point operations with select.
2862 1.1.1.2 mrg (define_expand "cond_<optab><mode>"
2863 1.1.1.2 mrg [(set (match_operand:SVE_F 0 "register_operand")
2864 1.1.1.2 mrg (unspec:SVE_F
2865 1.1.1.2 mrg [(match_operand:<VPRED> 1 "register_operand")
2866 1.1.1.2 mrg (unspec:SVE_F
2867 1.1.1.2 mrg [(match_operand:SVE_F 2 "register_operand")
2868 1.1.1.2 mrg (match_operand:SVE_F 3 "register_operand")]
2869 1.1.1.2 mrg SVE_COND_FP_BINARY)
2870 1.1.1.2 mrg (match_operand:SVE_F 4 "aarch64_simd_reg_or_zero")]
2871 1.1.1.2 mrg UNSPEC_SEL))]
2872 1.1.1.2 mrg "TARGET_SVE"
2873 1.1.1.2 mrg )
2874 1.1.1.2 mrg
2875 1.1.1.2 mrg ;; Predicated floating-point operations with select matching output.
2876 1.1.1.2 mrg (define_insn "*cond_<optab><mode>_0"
2877 1.1.1.2 mrg [(set (match_operand:SVE_F 0 "register_operand" "+w, w, ?&w")
2878 1.1.1.2 mrg (unspec:SVE_F
2879 1.1.1.2 mrg [(match_operand:<VPRED> 1 "register_operand" "Upl, Upl, Upl")
2880 1.1.1.2 mrg (unspec:SVE_F
2881 1.1.1.2 mrg [(match_operand:SVE_F 2 "register_operand" "0, w, w")
2882 1.1.1.2 mrg (match_operand:SVE_F 3 "register_operand" "w, 0, w")]
2883 1.1.1.2 mrg SVE_COND_FP_BINARY)
2884 1.1.1.2 mrg (match_dup 0)]
2885 1.1.1.2 mrg UNSPEC_SEL))]
2886 1.1.1.2 mrg "TARGET_SVE"
2887 1.1.1.2 mrg "@
2888 1.1.1.2 mrg <sve_fp_op>\t%0.<Vetype>, %1/m, %0.<Vetype>, %3.<Vetype>
2889 1.1.1.2 mrg <sve_fp_op_rev>\t%0.<Vetype>, %1/m, %0.<Vetype>, %2.<Vetype>
2890 1.1.1.2 mrg movprfx\t%0, %1/m, %2\;<sve_fp_op>\t%0.<Vetype>, %1/m, %0.<Vetype>, %3.<Vetype>"
2891 1.1.1.2 mrg [(set_attr "movprfx" "*,*,yes")]
2892 1.1.1.2 mrg )
2893 1.1.1.2 mrg
2894 1.1.1.2 mrg ;; Predicated floating-point operations with select matching first operand.
2895 1.1.1.2 mrg (define_insn "*cond_<optab><mode>_2"
2896 1.1.1.2 mrg [(set (match_operand:SVE_F 0 "register_operand" "=w, ?&w")
2897 1.1.1.2 mrg (unspec:SVE_F
2898 1.1.1.2 mrg [(match_operand:<VPRED> 1 "register_operand" "Upl, Upl")
2899 1.1.1.2 mrg (unspec:SVE_F
2900 1.1.1.2 mrg [(match_operand:SVE_F 2 "register_operand" "0, w")
2901 1.1.1.2 mrg (match_operand:SVE_F 3 "register_operand" "w, w")]
2902 1.1.1.2 mrg SVE_COND_FP_BINARY)
2903 1.1.1.2 mrg (match_dup 2)]
2904 1.1.1.2 mrg UNSPEC_SEL))]
2905 1.1.1.2 mrg "TARGET_SVE"
2906 1.1.1.2 mrg "@
2907 1.1.1.2 mrg <sve_fp_op>\t%0.<Vetype>, %1/m, %0.<Vetype>, %3.<Vetype>
2908 1.1.1.2 mrg movprfx\t%0, %2\;<sve_fp_op>\t%0.<Vetype>, %1/m, %0.<Vetype>, %3.<Vetype>"
2909 1.1.1.2 mrg [(set_attr "movprfx" "*,yes")]
2910 1.1.1.2 mrg )
2911 1.1.1.2 mrg
2912 1.1.1.2 mrg ;; Predicated floating-point operations with select matching second operand.
2913 1.1.1.2 mrg (define_insn "*cond_<optab><mode>_3"
2914 1.1.1.2 mrg [(set (match_operand:SVE_F 0 "register_operand" "=w, ?&w")
2915 1.1.1.2 mrg (unspec:SVE_F
2916 1.1.1.2 mrg [(match_operand:<VPRED> 1 "register_operand" "Upl, Upl")
2917 1.1.1.2 mrg (unspec:SVE_F
2918 1.1.1.2 mrg [(match_operand:SVE_F 2 "register_operand" "w, w")
2919 1.1.1.2 mrg (match_operand:SVE_F 3 "register_operand" "0, w")]
2920 1.1.1.2 mrg SVE_COND_FP_BINARY)
2921 1.1.1.2 mrg (match_dup 3)]
2922 1.1.1.2 mrg UNSPEC_SEL))]
2923 1.1.1.2 mrg "TARGET_SVE"
2924 1.1.1.2 mrg "@
2925 1.1.1.2 mrg <sve_fp_op_rev>\t%0.<Vetype>, %1/m, %0.<Vetype>, %2.<Vetype>
2926 1.1.1.2 mrg movprfx\t%0, %3\;<sve_fp_op_rev>\t%0.<Vetype>, %1/m, %0.<Vetype>, %2.<Vetype>"
2927 1.1.1.2 mrg [(set_attr "movprfx" "*,yes")]
2928 1.1.1.2 mrg )
2929 1.1.1.2 mrg
2930 1.1.1.2 mrg ;; Predicated floating-point operations with select matching zero.
2931 1.1.1.2 mrg (define_insn "*cond_<optab><mode>_z"
2932 1.1.1.2 mrg [(set (match_operand:SVE_F 0 "register_operand" "=&w")
2933 1.1.1.2 mrg (unspec:SVE_F
2934 1.1.1.2 mrg [(match_operand:<VPRED> 1 "register_operand" "Upl")
2935 1.1.1.2 mrg (unspec:SVE_F
2936 1.1.1.2 mrg [(match_operand:SVE_F 2 "register_operand" "w")
2937 1.1.1.2 mrg (match_operand:SVE_F 3 "register_operand" "w")]
2938 1.1.1.2 mrg SVE_COND_FP_BINARY)
2939 1.1.1.2 mrg (match_operand:SVE_F 4 "aarch64_simd_imm_zero")]
2940 1.1.1.2 mrg UNSPEC_SEL))]
2941 1.1.1.2 mrg "TARGET_SVE"
2942 1.1.1.2 mrg "movprfx\t%0.<Vetype>, %1/z, %2.<Vetype>\;<sve_fp_op>\t%0.<Vetype>, %1/m, %0.<Vetype>, %3.<Vetype>"
2943 1.1.1.2 mrg [(set_attr "movprfx" "yes")]
2944 1.1.1.2 mrg )
2945 1.1.1.2 mrg
2946 1.1.1.2 mrg ;; Synthetic predication of floating-point operations with select unmatched.
2947 1.1.1.2 mrg (define_insn_and_split "*cond_<optab><mode>_any"
2948 1.1.1.2 mrg [(set (match_operand:SVE_F 0 "register_operand" "=&w")
2949 1.1 mrg (unspec:SVE_F
2950 1.1 mrg [(match_operand:<VPRED> 1 "register_operand" "Upl")
2951 1.1.1.2 mrg (unspec:SVE_F
2952 1.1.1.2 mrg [(match_operand:SVE_F 2 "register_operand" "w")
2953 1.1.1.2 mrg (match_operand:SVE_F 3 "register_operand" "w")]
2954 1.1.1.2 mrg SVE_COND_FP_BINARY)
2955 1.1.1.2 mrg (match_operand:SVE_F 4 "register_operand" "w")]
2956 1.1.1.2 mrg UNSPEC_SEL))]
2957 1.1 mrg "TARGET_SVE"
2958 1.1.1.2 mrg "#"
2959 1.1.1.2 mrg "&& reload_completed
2960 1.1.1.2 mrg && !(rtx_equal_p (operands[0], operands[4])
2961 1.1.1.2 mrg || rtx_equal_p (operands[2], operands[4])
2962 1.1.1.2 mrg || rtx_equal_p (operands[3], operands[4]))"
2963 1.1.1.2 mrg ; Not matchable by any one insn or movprfx insn. We need a separate select.
2964 1.1.1.2 mrg [(set (match_dup 0)
2965 1.1.1.2 mrg (unspec:SVE_F [(match_dup 1) (match_dup 2) (match_dup 4)] UNSPEC_SEL))
2966 1.1.1.2 mrg (set (match_dup 0)
2967 1.1.1.2 mrg (unspec:SVE_F
2968 1.1.1.2 mrg [(match_dup 1)
2969 1.1.1.2 mrg (unspec:SVE_F [(match_dup 0) (match_dup 3)] SVE_COND_FP_BINARY)
2970 1.1.1.2 mrg (match_dup 0)]
2971 1.1.1.2 mrg UNSPEC_SEL))]
2972 1.1.1.2 mrg )
2973 1.1.1.2 mrg
2974 1.1.1.2 mrg ;; Predicated floating-point ternary operations with select.
2975 1.1.1.2 mrg (define_expand "cond_<optab><mode>"
2976 1.1.1.2 mrg [(set (match_operand:SVE_F 0 "register_operand")
2977 1.1.1.2 mrg (unspec:SVE_F
2978 1.1.1.2 mrg [(match_operand:<VPRED> 1 "register_operand")
2979 1.1.1.2 mrg (unspec:SVE_F
2980 1.1.1.2 mrg [(match_operand:SVE_F 2 "register_operand")
2981 1.1.1.2 mrg (match_operand:SVE_F 3 "register_operand")
2982 1.1.1.2 mrg (match_operand:SVE_F 4 "register_operand")]
2983 1.1.1.2 mrg SVE_COND_FP_TERNARY)
2984 1.1.1.2 mrg (match_operand:SVE_F 5 "aarch64_simd_reg_or_zero")]
2985 1.1.1.2 mrg UNSPEC_SEL))]
2986 1.1.1.2 mrg "TARGET_SVE"
2987 1.1.1.2 mrg {
2988 1.1.1.2 mrg /* Swap the multiplication operands if the fallback value is the
2989 1.1.1.2 mrg second of the two. */
2990 1.1.1.2 mrg if (rtx_equal_p (operands[3], operands[5]))
2991 1.1.1.2 mrg std::swap (operands[2], operands[3]);
2992 1.1.1.2 mrg })
2993 1.1.1.2 mrg
2994 1.1.1.2 mrg ;; Predicated floating-point ternary operations using the FMAD-like form.
2995 1.1.1.2 mrg (define_insn "*cond_<optab><mode>_2"
2996 1.1.1.2 mrg [(set (match_operand:SVE_F 0 "register_operand" "=w, ?&w")
2997 1.1.1.2 mrg (unspec:SVE_F
2998 1.1.1.2 mrg [(match_operand:<VPRED> 1 "register_operand" "Upl, Upl")
2999 1.1.1.2 mrg (unspec:SVE_F
3000 1.1.1.2 mrg [(match_operand:SVE_F 2 "register_operand" "0, w")
3001 1.1.1.2 mrg (match_operand:SVE_F 3 "register_operand" "w, w")
3002 1.1.1.2 mrg (match_operand:SVE_F 4 "register_operand" "w, w")]
3003 1.1.1.2 mrg SVE_COND_FP_TERNARY)
3004 1.1.1.2 mrg (match_dup 2)]
3005 1.1.1.2 mrg UNSPEC_SEL))]
3006 1.1.1.2 mrg "TARGET_SVE"
3007 1.1.1.2 mrg "@
3008 1.1.1.2 mrg <sve_fmad_op>\t%0.<Vetype>, %1/m, %3.<Vetype>, %4.<Vetype>
3009 1.1.1.2 mrg movprfx\t%0, %2\;<sve_fmad_op>\t%0.<Vetype>, %1/m, %3.<Vetype>, %4.<Vetype>"
3010 1.1.1.2 mrg [(set_attr "movprfx" "*,yes")]
3011 1.1.1.2 mrg )
3012 1.1.1.2 mrg
3013 1.1.1.2 mrg ;; Predicated floating-point ternary operations using the FMLA-like form.
3014 1.1.1.2 mrg (define_insn "*cond_<optab><mode>_4"
3015 1.1.1.2 mrg [(set (match_operand:SVE_F 0 "register_operand" "=w, ?&w")
3016 1.1.1.2 mrg (unspec:SVE_F
3017 1.1.1.2 mrg [(match_operand:<VPRED> 1 "register_operand" "Upl, Upl")
3018 1.1.1.2 mrg (unspec:SVE_F
3019 1.1.1.2 mrg [(match_operand:SVE_F 2 "register_operand" "w, w")
3020 1.1.1.2 mrg (match_operand:SVE_F 3 "register_operand" "w, w")
3021 1.1.1.2 mrg (match_operand:SVE_F 4 "register_operand" "0, w")]
3022 1.1.1.2 mrg SVE_COND_FP_TERNARY)
3023 1.1.1.2 mrg (match_dup 4)]
3024 1.1.1.2 mrg UNSPEC_SEL))]
3025 1.1.1.2 mrg "TARGET_SVE"
3026 1.1.1.2 mrg "@
3027 1.1.1.2 mrg <sve_fmla_op>\t%0.<Vetype>, %1/m, %2.<Vetype>, %3.<Vetype>
3028 1.1.1.2 mrg movprfx\t%0, %4\;<sve_fmla_op>\t%0.<Vetype>, %1/m, %2.<Vetype>, %3.<Vetype>"
3029 1.1.1.2 mrg [(set_attr "movprfx" "*,yes")]
3030 1.1.1.2 mrg )
3031 1.1.1.2 mrg
3032 1.1.1.2 mrg ;; Predicated floating-point ternary operations in which the value for
3033 1.1.1.2 mrg ;; inactive lanes is distinct from the other inputs.
3034 1.1.1.2 mrg (define_insn_and_split "*cond_<optab><mode>_any"
3035 1.1.1.2 mrg [(set (match_operand:SVE_F 0 "register_operand" "=&w, &w, ?&w")
3036 1.1.1.2 mrg (unspec:SVE_F
3037 1.1.1.2 mrg [(match_operand:<VPRED> 1 "register_operand" "Upl, Upl, Upl")
3038 1.1.1.2 mrg (unspec:SVE_F
3039 1.1.1.2 mrg [(match_operand:SVE_F 2 "register_operand" "w, w, w")
3040 1.1.1.2 mrg (match_operand:SVE_F 3 "register_operand" "w, w, w")
3041 1.1.1.2 mrg (match_operand:SVE_F 4 "register_operand" "w, w, w")]
3042 1.1.1.2 mrg SVE_COND_FP_TERNARY)
3043 1.1.1.2 mrg (match_operand:SVE_F 5 "aarch64_simd_reg_or_zero" "Dz, 0, w")]
3044 1.1.1.2 mrg UNSPEC_SEL))]
3045 1.1.1.2 mrg "TARGET_SVE
3046 1.1.1.2 mrg && !rtx_equal_p (operands[2], operands[5])
3047 1.1.1.2 mrg && !rtx_equal_p (operands[3], operands[5])
3048 1.1.1.2 mrg && !rtx_equal_p (operands[4], operands[5])"
3049 1.1.1.2 mrg "@
3050 1.1.1.2 mrg movprfx\t%0.<Vetype>, %1/z, %4.<Vetype>\;<sve_fmla_op>\t%0.<Vetype>, %1/m, %2.<Vetype>, %3.<Vetype>
3051 1.1.1.2 mrg movprfx\t%0.<Vetype>, %1/m, %4.<Vetype>\;<sve_fmla_op>\t%0.<Vetype>, %1/m, %2.<Vetype>, %3.<Vetype>
3052 1.1.1.2 mrg #"
3053 1.1.1.2 mrg "&& reload_completed
3054 1.1.1.2 mrg && !CONSTANT_P (operands[5])
3055 1.1.1.2 mrg && !rtx_equal_p (operands[0], operands[5])"
3056 1.1.1.2 mrg [(set (match_dup 0)
3057 1.1.1.2 mrg (unspec:SVE_F [(match_dup 1) (match_dup 4) (match_dup 5)] UNSPEC_SEL))
3058 1.1.1.2 mrg (set (match_dup 0)
3059 1.1.1.2 mrg (unspec:SVE_F
3060 1.1.1.2 mrg [(match_dup 1)
3061 1.1.1.2 mrg (unspec:SVE_F [(match_dup 2) (match_dup 3) (match_dup 0)]
3062 1.1.1.2 mrg SVE_COND_FP_TERNARY)
3063 1.1.1.2 mrg (match_dup 0)]
3064 1.1.1.2 mrg UNSPEC_SEL))]
3065 1.1.1.2 mrg ""
3066 1.1.1.2 mrg [(set_attr "movprfx" "yes")]
3067 1.1 mrg )
3068 1.1 mrg
3069 1.1 mrg ;; Shift an SVE vector left and insert a scalar into element 0.
3070 1.1 mrg (define_insn "vec_shl_insert_<mode>"
3071 1.1 mrg [(set (match_operand:SVE_ALL 0 "register_operand" "=w, w")
3072 1.1 mrg (unspec:SVE_ALL
3073 1.1 mrg [(match_operand:SVE_ALL 1 "register_operand" "0, 0")
3074 1.1 mrg (match_operand:<VEL> 2 "register_operand" "rZ, w")]
3075 1.1 mrg UNSPEC_INSR))]
3076 1.1 mrg "TARGET_SVE"
3077 1.1 mrg "@
3078 1.1 mrg insr\t%0.<Vetype>, %<vwcore>2
3079 1.1 mrg insr\t%0.<Vetype>, %<Vetype>2"
3080 1.1 mrg )
3081 1.1.1.2 mrg
3082 1.1.1.2 mrg (define_expand "copysign<mode>3"
3083 1.1.1.2 mrg [(match_operand:SVE_F 0 "register_operand")
3084 1.1.1.2 mrg (match_operand:SVE_F 1 "register_operand")
3085 1.1.1.2 mrg (match_operand:SVE_F 2 "register_operand")]
3086 1.1.1.2 mrg "TARGET_SVE"
3087 1.1.1.2 mrg {
3088 1.1.1.2 mrg rtx sign = gen_reg_rtx (<V_INT_EQUIV>mode);
3089 1.1.1.2 mrg rtx mant = gen_reg_rtx (<V_INT_EQUIV>mode);
3090 1.1.1.2 mrg rtx int_res = gen_reg_rtx (<V_INT_EQUIV>mode);
3091 1.1.1.2 mrg int bits = GET_MODE_UNIT_BITSIZE (<MODE>mode) - 1;
3092 1.1.1.2 mrg
3093 1.1.1.2 mrg rtx arg1 = lowpart_subreg (<V_INT_EQUIV>mode, operands[1], <MODE>mode);
3094 1.1.1.2 mrg rtx arg2 = lowpart_subreg (<V_INT_EQUIV>mode, operands[2], <MODE>mode);
3095 1.1.1.2 mrg
3096 1.1.1.2 mrg emit_insn (gen_and<v_int_equiv>3
3097 1.1.1.2 mrg (sign, arg2,
3098 1.1.1.2 mrg aarch64_simd_gen_const_vector_dup (<V_INT_EQUIV>mode,
3099 1.1.1.2 mrg HOST_WIDE_INT_M1U
3100 1.1.1.2 mrg << bits)));
3101 1.1.1.2 mrg emit_insn (gen_and<v_int_equiv>3
3102 1.1.1.2 mrg (mant, arg1,
3103 1.1.1.2 mrg aarch64_simd_gen_const_vector_dup (<V_INT_EQUIV>mode,
3104 1.1.1.2 mrg ~(HOST_WIDE_INT_M1U
3105 1.1.1.2 mrg << bits))));
3106 1.1.1.2 mrg emit_insn (gen_ior<v_int_equiv>3 (int_res, sign, mant));
3107 1.1.1.2 mrg emit_move_insn (operands[0], gen_lowpart (<MODE>mode, int_res));
3108 1.1.1.2 mrg DONE;
3109 1.1.1.2 mrg }
3110 1.1.1.2 mrg )
3111 1.1.1.2 mrg
3112 1.1.1.2 mrg (define_expand "xorsign<mode>3"
3113 1.1.1.2 mrg [(match_operand:SVE_F 0 "register_operand")
3114 1.1.1.2 mrg (match_operand:SVE_F 1 "register_operand")
3115 1.1.1.2 mrg (match_operand:SVE_F 2 "register_operand")]
3116 1.1.1.2 mrg "TARGET_SVE"
3117 1.1.1.2 mrg {
3118 1.1.1.2 mrg rtx sign = gen_reg_rtx (<V_INT_EQUIV>mode);
3119 1.1.1.2 mrg rtx int_res = gen_reg_rtx (<V_INT_EQUIV>mode);
3120 1.1.1.2 mrg int bits = GET_MODE_UNIT_BITSIZE (<MODE>mode) - 1;
3121 1.1.1.2 mrg
3122 1.1.1.2 mrg rtx arg1 = lowpart_subreg (<V_INT_EQUIV>mode, operands[1], <MODE>mode);
3123 1.1.1.2 mrg rtx arg2 = lowpart_subreg (<V_INT_EQUIV>mode, operands[2], <MODE>mode);
3124 1.1.1.2 mrg
3125 1.1.1.2 mrg emit_insn (gen_and<v_int_equiv>3
3126 1.1.1.2 mrg (sign, arg2,
3127 1.1.1.2 mrg aarch64_simd_gen_const_vector_dup (<V_INT_EQUIV>mode,
3128 1.1.1.2 mrg HOST_WIDE_INT_M1U
3129 1.1.1.2 mrg << bits)));
3130 1.1.1.2 mrg emit_insn (gen_xor<v_int_equiv>3 (int_res, arg1, sign));
3131 1.1.1.2 mrg emit_move_insn (operands[0], gen_lowpart (<MODE>mode, int_res));
3132 1.1.1.2 mrg DONE;
3133 1.1.1.2 mrg }
3134 1.1.1.2 mrg )
3135