aarch64-sve.md revision 1.1.1.5 1 1.1 mrg ;; Machine description for AArch64 SVE.
2 1.1.1.5 mrg ;; Copyright (C) 2009-2022 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.1.3 mrg ;; The file is organised into the following sections (search for the full
22 1.1.1.3 mrg ;; line):
23 1.1.1.3 mrg ;;
24 1.1.1.3 mrg ;; == General notes
25 1.1.1.3 mrg ;; ---- Note on the handling of big-endian SVE
26 1.1.1.3 mrg ;; ---- Description of UNSPEC_PTEST
27 1.1.1.3 mrg ;; ---- Description of UNSPEC_PRED_Z
28 1.1.1.3 mrg ;; ---- Note on predicated integer arithemtic and UNSPEC_PRED_X
29 1.1.1.3 mrg ;; ---- Note on predicated FP arithmetic patterns and GP "strictness"
30 1.1.1.3 mrg ;; ---- Note on FFR handling
31 1.1.1.3 mrg ;;
32 1.1.1.3 mrg ;; == Moves
33 1.1.1.3 mrg ;; ---- Moves of single vectors
34 1.1.1.3 mrg ;; ---- Moves of multiple vectors
35 1.1.1.3 mrg ;; ---- Moves of predicates
36 1.1.1.3 mrg ;; ---- Moves relating to the FFR
37 1.1.1.3 mrg ;;
38 1.1.1.3 mrg ;; == Loads
39 1.1.1.3 mrg ;; ---- Normal contiguous loads
40 1.1.1.3 mrg ;; ---- Extending contiguous loads
41 1.1.1.3 mrg ;; ---- First-faulting contiguous loads
42 1.1.1.3 mrg ;; ---- First-faulting extending contiguous loads
43 1.1.1.3 mrg ;; ---- Non-temporal contiguous loads
44 1.1.1.3 mrg ;; ---- Normal gather loads
45 1.1.1.3 mrg ;; ---- Extending gather loads
46 1.1.1.3 mrg ;; ---- First-faulting gather loads
47 1.1.1.3 mrg ;; ---- First-faulting extending gather loads
48 1.1.1.3 mrg ;;
49 1.1.1.3 mrg ;; == Prefetches
50 1.1.1.3 mrg ;; ---- Contiguous prefetches
51 1.1.1.3 mrg ;; ---- Gather prefetches
52 1.1.1.3 mrg ;;
53 1.1.1.3 mrg ;; == Stores
54 1.1.1.3 mrg ;; ---- Normal contiguous stores
55 1.1.1.3 mrg ;; ---- Truncating contiguous stores
56 1.1.1.3 mrg ;; ---- Non-temporal contiguous stores
57 1.1.1.3 mrg ;; ---- Normal scatter stores
58 1.1.1.3 mrg ;; ---- Truncating scatter stores
59 1.1.1.3 mrg ;;
60 1.1.1.3 mrg ;; == Vector creation
61 1.1.1.3 mrg ;; ---- [INT,FP] Duplicate element
62 1.1.1.3 mrg ;; ---- [INT,FP] Initialize from individual elements
63 1.1.1.3 mrg ;; ---- [INT] Linear series
64 1.1.1.3 mrg ;; ---- [PRED] Duplicate element
65 1.1.1.3 mrg ;;
66 1.1.1.3 mrg ;; == Vector decomposition
67 1.1.1.3 mrg ;; ---- [INT,FP] Extract index
68 1.1.1.3 mrg ;; ---- [INT,FP] Extract active element
69 1.1.1.3 mrg ;; ---- [PRED] Extract index
70 1.1.1.3 mrg ;;
71 1.1.1.3 mrg ;; == Unary arithmetic
72 1.1.1.3 mrg ;; ---- [INT] General unary arithmetic corresponding to rtx codes
73 1.1.1.3 mrg ;; ---- [INT] General unary arithmetic corresponding to unspecs
74 1.1.1.3 mrg ;; ---- [INT] Sign and zero extension
75 1.1.1.3 mrg ;; ---- [INT] Truncation
76 1.1.1.3 mrg ;; ---- [INT] Logical inverse
77 1.1.1.3 mrg ;; ---- [FP<-INT] General unary arithmetic that maps to unspecs
78 1.1.1.3 mrg ;; ---- [FP] General unary arithmetic corresponding to unspecs
79 1.1.1.3 mrg ;; ---- [FP] Square root
80 1.1.1.3 mrg ;; ---- [FP] Reciprocal square root
81 1.1.1.3 mrg ;; ---- [PRED] Inverse
82 1.1.1.3 mrg
83 1.1.1.3 mrg ;; == Binary arithmetic
84 1.1.1.3 mrg ;; ---- [INT] General binary arithmetic corresponding to rtx codes
85 1.1.1.3 mrg ;; ---- [INT] Addition
86 1.1.1.3 mrg ;; ---- [INT] Subtraction
87 1.1.1.3 mrg ;; ---- [INT] Take address
88 1.1.1.3 mrg ;; ---- [INT] Absolute difference
89 1.1.1.3 mrg ;; ---- [INT] Saturating addition and subtraction
90 1.1.1.3 mrg ;; ---- [INT] Highpart multiplication
91 1.1.1.3 mrg ;; ---- [INT] Division
92 1.1.1.3 mrg ;; ---- [INT] Binary logical operations
93 1.1.1.3 mrg ;; ---- [INT] Binary logical operations (inverted second input)
94 1.1.1.3 mrg ;; ---- [INT] Shifts (rounding towards -Inf)
95 1.1.1.3 mrg ;; ---- [INT] Shifts (rounding towards 0)
96 1.1.1.3 mrg ;; ---- [FP<-INT] General binary arithmetic corresponding to unspecs
97 1.1.1.3 mrg ;; ---- [FP] General binary arithmetic corresponding to rtx codes
98 1.1.1.3 mrg ;; ---- [FP] General binary arithmetic corresponding to unspecs
99 1.1.1.3 mrg ;; ---- [FP] Addition
100 1.1.1.3 mrg ;; ---- [FP] Complex addition
101 1.1.1.3 mrg ;; ---- [FP] Subtraction
102 1.1.1.3 mrg ;; ---- [FP] Absolute difference
103 1.1.1.3 mrg ;; ---- [FP] Multiplication
104 1.1.1.3 mrg ;; ---- [FP] Division
105 1.1.1.3 mrg ;; ---- [FP] Binary logical operations
106 1.1.1.3 mrg ;; ---- [FP] Sign copying
107 1.1.1.3 mrg ;; ---- [FP] Maximum and minimum
108 1.1.1.3 mrg ;; ---- [PRED] Binary logical operations
109 1.1.1.3 mrg ;; ---- [PRED] Binary logical operations (inverted second input)
110 1.1.1.3 mrg ;; ---- [PRED] Binary logical operations (inverted result)
111 1.1.1.3 mrg ;;
112 1.1.1.3 mrg ;; == Ternary arithmetic
113 1.1.1.3 mrg ;; ---- [INT] MLA and MAD
114 1.1.1.3 mrg ;; ---- [INT] MLS and MSB
115 1.1.1.3 mrg ;; ---- [INT] Dot product
116 1.1.1.3 mrg ;; ---- [INT] Sum of absolute differences
117 1.1.1.3 mrg ;; ---- [INT] Matrix multiply-accumulate
118 1.1.1.3 mrg ;; ---- [FP] General ternary arithmetic corresponding to unspecs
119 1.1.1.3 mrg ;; ---- [FP] Complex multiply-add
120 1.1.1.3 mrg ;; ---- [FP] Trigonometric multiply-add
121 1.1.1.3 mrg ;; ---- [FP] Bfloat16 long ternary arithmetic (SF,BF,BF)
122 1.1.1.3 mrg ;; ---- [FP] Matrix multiply-accumulate
123 1.1.1.3 mrg ;;
124 1.1.1.3 mrg ;; == Comparisons and selects
125 1.1.1.3 mrg ;; ---- [INT,FP] Select based on predicates
126 1.1.1.3 mrg ;; ---- [INT,FP] Compare and select
127 1.1.1.3 mrg ;; ---- [INT] Comparisons
128 1.1.1.3 mrg ;; ---- [INT] While tests
129 1.1.1.3 mrg ;; ---- [FP] Direct comparisons
130 1.1.1.3 mrg ;; ---- [FP] Absolute comparisons
131 1.1.1.3 mrg ;; ---- [PRED] Select
132 1.1.1.3 mrg ;; ---- [PRED] Test bits
133 1.1.1.3 mrg ;;
134 1.1.1.3 mrg ;; == Reductions
135 1.1.1.3 mrg ;; ---- [INT,FP] Conditional reductions
136 1.1.1.3 mrg ;; ---- [INT] Tree reductions
137 1.1.1.3 mrg ;; ---- [FP] Tree reductions
138 1.1.1.3 mrg ;; ---- [FP] Left-to-right reductions
139 1.1.1.3 mrg ;;
140 1.1.1.3 mrg ;; == Permutes
141 1.1.1.3 mrg ;; ---- [INT,FP] General permutes
142 1.1.1.3 mrg ;; ---- [INT,FP] Special-purpose unary permutes
143 1.1.1.3 mrg ;; ---- [INT,FP] Special-purpose binary permutes
144 1.1.1.3 mrg ;; ---- [PRED] Special-purpose unary permutes
145 1.1.1.3 mrg ;; ---- [PRED] Special-purpose binary permutes
146 1.1.1.3 mrg ;;
147 1.1.1.3 mrg ;; == Conversions
148 1.1.1.3 mrg ;; ---- [INT<-INT] Packs
149 1.1.1.3 mrg ;; ---- [INT<-INT] Unpacks
150 1.1.1.3 mrg ;; ---- [INT<-FP] Conversions
151 1.1.1.3 mrg ;; ---- [INT<-FP] Packs
152 1.1.1.3 mrg ;; ---- [INT<-FP] Unpacks
153 1.1.1.3 mrg ;; ---- [FP<-INT] Conversions
154 1.1.1.3 mrg ;; ---- [FP<-INT] Packs
155 1.1.1.3 mrg ;; ---- [FP<-INT] Unpacks
156 1.1.1.3 mrg ;; ---- [FP<-FP] Packs
157 1.1.1.3 mrg ;; ---- [FP<-FP] Packs (bfloat16)
158 1.1.1.3 mrg ;; ---- [FP<-FP] Unpacks
159 1.1.1.3 mrg ;; ---- [PRED<-PRED] Packs
160 1.1.1.3 mrg ;; ---- [PRED<-PRED] Unpacks
161 1.1.1.3 mrg ;;
162 1.1.1.3 mrg ;; == Vector partitioning
163 1.1.1.3 mrg ;; ---- [PRED] Unary partitioning
164 1.1.1.3 mrg ;; ---- [PRED] Binary partitioning
165 1.1.1.3 mrg ;; ---- [PRED] Scalarization
166 1.1.1.3 mrg ;;
167 1.1.1.3 mrg ;; == Counting elements
168 1.1.1.3 mrg ;; ---- [INT] Count elements in a pattern (scalar)
169 1.1.1.3 mrg ;; ---- [INT] Increment by the number of elements in a pattern (scalar)
170 1.1.1.3 mrg ;; ---- [INT] Increment by the number of elements in a pattern (vector)
171 1.1.1.3 mrg ;; ---- [INT] Decrement by the number of elements in a pattern (scalar)
172 1.1.1.3 mrg ;; ---- [INT] Decrement by the number of elements in a pattern (vector)
173 1.1.1.3 mrg ;; ---- [INT] Count elements in a predicate (scalar)
174 1.1.1.3 mrg ;; ---- [INT] Increment by the number of elements in a predicate (scalar)
175 1.1.1.3 mrg ;; ---- [INT] Increment by the number of elements in a predicate (vector)
176 1.1.1.3 mrg ;; ---- [INT] Decrement by the number of elements in a predicate (scalar)
177 1.1.1.3 mrg ;; ---- [INT] Decrement by the number of elements in a predicate (vector)
178 1.1.1.3 mrg
179 1.1.1.3 mrg ;; =========================================================================
180 1.1.1.3 mrg ;; == General notes
181 1.1.1.3 mrg ;; =========================================================================
182 1.1.1.3 mrg ;;
183 1.1.1.3 mrg ;; -------------------------------------------------------------------------
184 1.1.1.3 mrg ;; ---- Note on the handling of big-endian SVE
185 1.1.1.3 mrg ;; -------------------------------------------------------------------------
186 1.1 mrg ;;
187 1.1 mrg ;; On big-endian systems, Advanced SIMD mov<mode> patterns act in the
188 1.1 mrg ;; same way as movdi or movti would: the first byte of memory goes
189 1.1 mrg ;; into the most significant byte of the register and the last byte
190 1.1 mrg ;; of memory goes into the least significant byte of the register.
191 1.1 mrg ;; This is the most natural ordering for Advanced SIMD and matches
192 1.1 mrg ;; the ABI layout for 64-bit and 128-bit vector types.
193 1.1 mrg ;;
194 1.1 mrg ;; As a result, the order of bytes within the register is what GCC
195 1.1 mrg ;; expects for a big-endian target, and subreg offsets therefore work
196 1.1 mrg ;; as expected, with the first element in memory having subreg offset 0
197 1.1 mrg ;; and the last element in memory having the subreg offset associated
198 1.1 mrg ;; with a big-endian lowpart. However, this ordering also means that
199 1.1 mrg ;; GCC's lane numbering does not match the architecture's numbering:
200 1.1 mrg ;; GCC always treats the element at the lowest address in memory
201 1.1 mrg ;; (subreg offset 0) as element 0, while the architecture treats
202 1.1 mrg ;; the least significant end of the register as element 0.
203 1.1 mrg ;;
204 1.1 mrg ;; The situation for SVE is different. We want the layout of the
205 1.1 mrg ;; SVE register to be same for mov<mode> as it is for maskload<mode>:
206 1.1 mrg ;; logically, a mov<mode> load must be indistinguishable from a
207 1.1 mrg ;; maskload<mode> whose mask is all true. We therefore need the
208 1.1 mrg ;; register layout to match LD1 rather than LDR. The ABI layout of
209 1.1 mrg ;; SVE types also matches LD1 byte ordering rather than LDR byte ordering.
210 1.1 mrg ;;
211 1.1 mrg ;; As a result, the architecture lane numbering matches GCC's lane
212 1.1 mrg ;; numbering, with element 0 always being the first in memory.
213 1.1 mrg ;; However:
214 1.1 mrg ;;
215 1.1 mrg ;; - Applying a subreg offset to a register does not give the element
216 1.1 mrg ;; that GCC expects: the first element in memory has the subreg offset
217 1.1 mrg ;; associated with a big-endian lowpart while the last element in memory
218 1.1 mrg ;; has subreg offset 0. We handle this via TARGET_CAN_CHANGE_MODE_CLASS.
219 1.1 mrg ;;
220 1.1 mrg ;; - We cannot use LDR and STR for spill slots that might be accessed
221 1.1 mrg ;; via subregs, since although the elements have the order GCC expects,
222 1.1 mrg ;; the order of the bytes within the elements is different. We instead
223 1.1 mrg ;; access spill slots via LD1 and ST1, using secondary reloads to
224 1.1 mrg ;; reserve a predicate register.
225 1.1.1.3 mrg ;;
226 1.1.1.3 mrg ;; -------------------------------------------------------------------------
227 1.1.1.3 mrg ;; ---- Description of UNSPEC_PTEST
228 1.1.1.3 mrg ;; -------------------------------------------------------------------------
229 1.1.1.3 mrg ;;
230 1.1.1.3 mrg ;; SVE provides a PTEST instruction for testing the active lanes of a
231 1.1.1.3 mrg ;; predicate and setting the flags based on the result. The associated
232 1.1.1.3 mrg ;; condition code tests are:
233 1.1.1.3 mrg ;;
234 1.1.1.3 mrg ;; - any (= ne): at least one active bit is set
235 1.1.1.3 mrg ;; - none (= eq): all active bits are clear (*)
236 1.1.1.3 mrg ;; - first (= mi): the first active bit is set
237 1.1.1.3 mrg ;; - nfrst (= pl): the first active bit is clear (*)
238 1.1.1.3 mrg ;; - last (= cc): the last active bit is set
239 1.1.1.3 mrg ;; - nlast (= cs): the last active bit is clear (*)
240 1.1.1.3 mrg ;;
241 1.1.1.3 mrg ;; where the conditions marked (*) are also true when there are no active
242 1.1.1.3 mrg ;; lanes (i.e. when the governing predicate is a PFALSE). The flags results
243 1.1.1.3 mrg ;; of a PTEST use the condition code mode CC_NZC.
244 1.1.1.3 mrg ;;
245 1.1.1.3 mrg ;; PTEST is always a .B operation (i.e. it always operates on VNx16BI).
246 1.1.1.3 mrg ;; This means that for other predicate modes, we need a governing predicate
247 1.1.1.3 mrg ;; in which all bits are defined.
248 1.1.1.3 mrg ;;
249 1.1.1.3 mrg ;; For example, most predicated .H operations ignore the odd bits of the
250 1.1.1.3 mrg ;; governing predicate, so that an active lane is represented by the
251 1.1.1.3 mrg ;; bits "1x" and an inactive lane by the bits "0x", where "x" can be
252 1.1.1.3 mrg ;; any value. To test a .H predicate, we instead need "10" and "00"
253 1.1.1.3 mrg ;; respectively, so that the condition only tests the even bits of the
254 1.1.1.3 mrg ;; predicate.
255 1.1.1.3 mrg ;;
256 1.1.1.3 mrg ;; Several instructions set the flags as a side-effect, in the same way
257 1.1.1.3 mrg ;; that a separate PTEST would. It's important for code quality that we
258 1.1.1.3 mrg ;; use these flags results as often as possible, particularly in the case
259 1.1.1.3 mrg ;; of WHILE* and RDFFR.
260 1.1.1.3 mrg ;;
261 1.1.1.3 mrg ;; Also, some of the instructions that set the flags are unpredicated
262 1.1.1.3 mrg ;; and instead implicitly test all .B, .H, .S or .D elements, as though
263 1.1.1.3 mrg ;; they were predicated on a PTRUE of that size. For example, a .S
264 1.1.1.3 mrg ;; WHILELO sets the flags in the same way as a PTEST with a .S PTRUE
265 1.1.1.3 mrg ;; would.
266 1.1.1.3 mrg ;;
267 1.1.1.3 mrg ;; We therefore need to represent PTEST operations in a way that
268 1.1.1.3 mrg ;; makes it easy to combine them with both predicated and unpredicated
269 1.1.1.3 mrg ;; operations, while using a VNx16BI governing predicate for all
270 1.1.1.3 mrg ;; predicate modes. We do this using:
271 1.1.1.3 mrg ;;
272 1.1.1.3 mrg ;; (unspec:CC_NZC [gp cast_gp ptrue_flag op] UNSPEC_PTEST)
273 1.1.1.3 mrg ;;
274 1.1.1.3 mrg ;; where:
275 1.1.1.3 mrg ;;
276 1.1.1.3 mrg ;; - GP is the real VNx16BI governing predicate
277 1.1.1.3 mrg ;;
278 1.1.1.3 mrg ;; - CAST_GP is GP cast to the mode of OP. All bits dropped by casting
279 1.1.1.3 mrg ;; GP to CAST_GP are guaranteed to be clear in GP.
280 1.1.1.3 mrg ;;
281 1.1.1.3 mrg ;; - PTRUE_FLAG is a CONST_INT (conceptually of mode SI) that has the value
282 1.1.1.3 mrg ;; SVE_KNOWN_PTRUE if we know that CAST_GP (rather than GP) is all-true and
283 1.1.1.3 mrg ;; SVE_MAYBE_NOT_PTRUE otherwise.
284 1.1.1.3 mrg ;;
285 1.1.1.3 mrg ;; - OP is the predicate we want to test, of the same mode as CAST_GP.
286 1.1.1.3 mrg ;;
287 1.1.1.3 mrg ;; -------------------------------------------------------------------------
288 1.1.1.3 mrg ;; ---- Description of UNSPEC_PRED_Z
289 1.1.1.3 mrg ;; -------------------------------------------------------------------------
290 1.1.1.3 mrg ;;
291 1.1.1.3 mrg ;; SVE integer comparisons are predicated and return zero for inactive
292 1.1.1.3 mrg ;; lanes. Sometimes we use them with predicates that are all-true and
293 1.1.1.3 mrg ;; sometimes we use them with general predicates.
294 1.1.1.3 mrg ;;
295 1.1.1.3 mrg ;; The integer comparisons also set the flags and so build-in the effect
296 1.1.1.3 mrg ;; of a PTEST. We therefore want to be able to combine integer comparison
297 1.1.1.3 mrg ;; patterns with PTESTs of the result. One difficulty with doing this is
298 1.1.1.3 mrg ;; that (as noted above) the PTEST is always a .B operation and so can place
299 1.1.1.3 mrg ;; stronger requirements on the governing predicate than the comparison does.
300 1.1.1.3 mrg ;;
301 1.1.1.3 mrg ;; For example, when applying a separate PTEST to the result of a full-vector
302 1.1.1.3 mrg ;; .H comparison, the PTEST must be predicated on a .H PTRUE instead of a
303 1.1.1.3 mrg ;; .B PTRUE. In constrast, the comparison might be predicated on either
304 1.1.1.3 mrg ;; a .H PTRUE or a .B PTRUE, since the values of odd-indexed predicate
305 1.1.1.3 mrg ;; bits don't matter for .H operations.
306 1.1.1.3 mrg ;;
307 1.1.1.3 mrg ;; We therefore can't rely on a full-vector comparison using the same
308 1.1.1.3 mrg ;; predicate register as a following PTEST. We instead need to remember
309 1.1.1.3 mrg ;; whether a comparison is known to be a full-vector comparison and use
310 1.1.1.3 mrg ;; this information in addition to a check for equal predicate registers.
311 1.1.1.3 mrg ;; At the same time, it's useful to have a common representation for all
312 1.1.1.3 mrg ;; integer comparisons, so that they can be handled by a single set of
313 1.1.1.3 mrg ;; patterns.
314 1.1.1.3 mrg ;;
315 1.1.1.3 mrg ;; We therefore take a similar approach to UNSPEC_PTEST above and use:
316 1.1.1.3 mrg ;;
317 1.1.1.3 mrg ;; (unspec:<M:VPRED> [gp ptrue_flag (code:M op0 op1)] UNSPEC_PRED_Z)
318 1.1.1.3 mrg ;;
319 1.1.1.3 mrg ;; where:
320 1.1.1.3 mrg ;;
321 1.1.1.3 mrg ;; - GP is the governing predicate, of mode <M:VPRED>
322 1.1.1.3 mrg ;;
323 1.1.1.3 mrg ;; - PTRUE_FLAG is a CONST_INT (conceptually of mode SI) that has the value
324 1.1.1.3 mrg ;; SVE_KNOWN_PTRUE if we know that GP is all-true and SVE_MAYBE_NOT_PTRUE
325 1.1.1.3 mrg ;; otherwise
326 1.1.1.3 mrg ;;
327 1.1.1.3 mrg ;; - CODE is the comparison code
328 1.1.1.3 mrg ;;
329 1.1.1.3 mrg ;; - OP0 and OP1 are the values being compared, of mode M
330 1.1.1.3 mrg ;;
331 1.1.1.3 mrg ;; The "Z" in UNSPEC_PRED_Z indicates that inactive lanes are zero.
332 1.1.1.3 mrg ;;
333 1.1.1.3 mrg ;; -------------------------------------------------------------------------
334 1.1.1.3 mrg ;; ---- Note on predicated integer arithemtic and UNSPEC_PRED_X
335 1.1.1.3 mrg ;; -------------------------------------------------------------------------
336 1.1.1.3 mrg ;;
337 1.1.1.3 mrg ;; Many SVE integer operations are predicated. We can generate them
338 1.1.1.3 mrg ;; from four sources:
339 1.1.1.3 mrg ;;
340 1.1.1.3 mrg ;; (1) Using normal unpredicated optabs. In this case we need to create
341 1.1.1.3 mrg ;; an all-true predicate register to act as the governing predicate
342 1.1.1.3 mrg ;; for the SVE instruction. There are no inactive lanes, and thus
343 1.1.1.3 mrg ;; the values of inactive lanes don't matter.
344 1.1.1.3 mrg ;;
345 1.1.1.3 mrg ;; (2) Using _x ACLE functions. In this case the function provides a
346 1.1.1.3 mrg ;; specific predicate and some lanes might be inactive. However,
347 1.1.1.3 mrg ;; as for (1), the values of the inactive lanes don't matter.
348 1.1.1.3 mrg ;; We can make extra lanes active without changing the behavior
349 1.1.1.3 mrg ;; (although for code-quality reasons we should avoid doing so
350 1.1.1.3 mrg ;; needlessly).
351 1.1.1.3 mrg ;;
352 1.1.1.3 mrg ;; (3) Using cond_* optabs that correspond to IFN_COND_* internal functions.
353 1.1.1.3 mrg ;; These optabs have a predicate operand that specifies which lanes are
354 1.1.1.3 mrg ;; active and another operand that provides the values of inactive lanes.
355 1.1.1.3 mrg ;;
356 1.1.1.3 mrg ;; (4) Using _m and _z ACLE functions. These functions map to the same
357 1.1.1.3 mrg ;; patterns as (3), with the _z functions setting inactive lanes to zero
358 1.1.1.3 mrg ;; and the _m functions setting the inactive lanes to one of the function
359 1.1.1.3 mrg ;; arguments.
360 1.1.1.3 mrg ;;
361 1.1.1.3 mrg ;; For (1) and (2) we need a way of attaching the predicate to a normal
362 1.1.1.3 mrg ;; unpredicated integer operation. We do this using:
363 1.1.1.3 mrg ;;
364 1.1.1.3 mrg ;; (unspec:M [pred (code:M (op0 op1 ...))] UNSPEC_PRED_X)
365 1.1.1.3 mrg ;;
366 1.1.1.3 mrg ;; where (code:M (op0 op1 ...)) is the normal integer operation and PRED
367 1.1.1.3 mrg ;; is a predicate of mode <M:VPRED>. PRED might or might not be a PTRUE;
368 1.1.1.3 mrg ;; it always is for (1), but might not be for (2).
369 1.1.1.3 mrg ;;
370 1.1.1.3 mrg ;; The unspec as a whole has the same value as (code:M ...) when PRED is
371 1.1.1.3 mrg ;; all-true. It is always semantically valid to replace PRED with a PTRUE,
372 1.1.1.3 mrg ;; but as noted above, we should only do so if there's a specific benefit.
373 1.1.1.3 mrg ;;
374 1.1.1.3 mrg ;; (The "_X" in the unspec is named after the ACLE functions in (2).)
375 1.1.1.3 mrg ;;
376 1.1.1.3 mrg ;; For (3) and (4) we can simply use the SVE port's normal representation
377 1.1.1.3 mrg ;; of a predicate-based select:
378 1.1.1.3 mrg ;;
379 1.1.1.3 mrg ;; (unspec:M [pred (code:M (op0 op1 ...)) inactive] UNSPEC_SEL)
380 1.1.1.3 mrg ;;
381 1.1.1.3 mrg ;; where INACTIVE specifies the values of inactive lanes.
382 1.1.1.3 mrg ;;
383 1.1.1.3 mrg ;; We can also use the UNSPEC_PRED_X wrapper in the UNSPEC_SEL rather
384 1.1.1.3 mrg ;; than inserting the integer operation directly. This is mostly useful
385 1.1.1.3 mrg ;; if we want the combine pass to merge an integer operation with an explicit
386 1.1.1.3 mrg ;; vcond_mask (in other words, with a following SEL instruction). However,
387 1.1.1.3 mrg ;; it's generally better to merge such operations at the gimple level
388 1.1.1.3 mrg ;; using (3).
389 1.1.1.3 mrg ;;
390 1.1.1.3 mrg ;; -------------------------------------------------------------------------
391 1.1.1.3 mrg ;; ---- Note on predicated FP arithmetic patterns and GP "strictness"
392 1.1.1.3 mrg ;; -------------------------------------------------------------------------
393 1.1.1.3 mrg ;;
394 1.1.1.3 mrg ;; Most SVE floating-point operations are predicated. We can generate
395 1.1.1.3 mrg ;; them from four sources:
396 1.1.1.3 mrg ;;
397 1.1.1.3 mrg ;; (1) Using normal unpredicated optabs. In this case we need to create
398 1.1.1.3 mrg ;; an all-true predicate register to act as the governing predicate
399 1.1.1.3 mrg ;; for the SVE instruction. There are no inactive lanes, and thus
400 1.1.1.3 mrg ;; the values of inactive lanes don't matter.
401 1.1.1.3 mrg ;;
402 1.1.1.3 mrg ;; (2) Using _x ACLE functions. In this case the function provides a
403 1.1.1.3 mrg ;; specific predicate and some lanes might be inactive. However,
404 1.1.1.3 mrg ;; as for (1), the values of the inactive lanes don't matter.
405 1.1.1.3 mrg ;;
406 1.1.1.3 mrg ;; The instruction must have the same exception behavior as the
407 1.1.1.3 mrg ;; function call unless things like command-line flags specifically
408 1.1.1.3 mrg ;; allow otherwise. For example, with -ffast-math, it is OK to
409 1.1.1.3 mrg ;; raise exceptions for inactive lanes, but normally it isn't.
410 1.1.1.3 mrg ;;
411 1.1.1.3 mrg ;; (3) Using cond_* optabs that correspond to IFN_COND_* internal functions.
412 1.1.1.3 mrg ;; These optabs have a predicate operand that specifies which lanes are
413 1.1.1.3 mrg ;; active and another operand that provides the values of inactive lanes.
414 1.1.1.3 mrg ;;
415 1.1.1.3 mrg ;; (4) Using _m and _z ACLE functions. These functions map to the same
416 1.1.1.3 mrg ;; patterns as (3), with the _z functions setting inactive lanes to zero
417 1.1.1.3 mrg ;; and the _m functions setting the inactive lanes to one of the function
418 1.1.1.3 mrg ;; arguments.
419 1.1.1.3 mrg ;;
420 1.1.1.3 mrg ;; So:
421 1.1.1.3 mrg ;;
422 1.1.1.3 mrg ;; - In (1), the predicate is known to be all true and the pattern can use
423 1.1.1.3 mrg ;; unpredicated operations where available.
424 1.1.1.3 mrg ;;
425 1.1.1.3 mrg ;; - In (2), the predicate might or might not be all true. The pattern can
426 1.1.1.3 mrg ;; use unpredicated instructions if the predicate is all-true or if things
427 1.1.1.3 mrg ;; like command-line flags allow exceptions for inactive lanes.
428 1.1.1.3 mrg ;;
429 1.1.1.3 mrg ;; - (3) and (4) represent a native SVE predicated operation. Some lanes
430 1.1.1.3 mrg ;; might be inactive and inactive lanes of the result must have specific
431 1.1.1.3 mrg ;; values. There is no scope for using unpredicated instructions (and no
432 1.1.1.3 mrg ;; reason to want to), so the question about command-line flags doesn't
433 1.1.1.3 mrg ;; arise.
434 1.1.1.3 mrg ;;
435 1.1.1.3 mrg ;; It would be inaccurate to model (2) as an rtx code like (sqrt ...)
436 1.1.1.3 mrg ;; in combination with a separate predicate operand, e.g.
437 1.1.1.3 mrg ;;
438 1.1.1.3 mrg ;; (unspec [(match_operand:<VPRED> 1 "register_operand" "Upl")
439 1.1.1.3 mrg ;; (sqrt:SVE_FULL_F 2 "register_operand" "w")]
440 1.1.1.3 mrg ;; ....)
441 1.1.1.3 mrg ;;
442 1.1.1.3 mrg ;; because (sqrt ...) can raise an exception for any lane, including
443 1.1.1.3 mrg ;; inactive ones. We therefore need to use an unspec instead.
444 1.1.1.3 mrg ;;
445 1.1.1.3 mrg ;; Also, (2) requires some way of distinguishing the case in which the
446 1.1.1.3 mrg ;; predicate might have inactive lanes and cannot be changed from the
447 1.1.1.3 mrg ;; case in which the predicate has no inactive lanes or can be changed.
448 1.1.1.3 mrg ;; This information is also useful when matching combined FP patterns
449 1.1.1.3 mrg ;; in which the predicates might not be equal.
450 1.1.1.3 mrg ;;
451 1.1.1.3 mrg ;; We therefore model FP operations as an unspec of the form:
452 1.1.1.3 mrg ;;
453 1.1.1.3 mrg ;; (unspec [pred strictness op0 op1 ...] UNSPEC_COND_<MNEMONIC>)
454 1.1.1.3 mrg ;;
455 1.1.1.3 mrg ;; where:
456 1.1.1.3 mrg ;;
457 1.1.1.3 mrg ;; - PRED is the governing predicate.
458 1.1.1.3 mrg ;;
459 1.1.1.3 mrg ;; - STRICTNESS is a CONST_INT that conceptually has mode SI. It has the
460 1.1.1.3 mrg ;; value SVE_STRICT_GP if PRED might have inactive lanes and if those
461 1.1.1.3 mrg ;; lanes must remain inactive. It has the value SVE_RELAXED_GP otherwise.
462 1.1.1.3 mrg ;;
463 1.1.1.3 mrg ;; - OP0 OP1 ... are the normal input operands to the operation.
464 1.1.1.3 mrg ;;
465 1.1.1.3 mrg ;; - MNEMONIC is the mnemonic of the associated SVE instruction.
466 1.1.1.3 mrg ;;
467 1.1.1.3 mrg ;; For (3) and (4), we combine these operations with an UNSPEC_SEL
468 1.1.1.3 mrg ;; that selects between the result of the FP operation and the "else"
469 1.1.1.3 mrg ;; value. (This else value is a merge input for _m ACLE functions
470 1.1.1.3 mrg ;; and zero for _z ACLE functions.) The outer pattern then has the form:
471 1.1.1.3 mrg ;;
472 1.1.1.3 mrg ;; (unspec [pred fp_operation else_value] UNSPEC_SEL)
473 1.1.1.3 mrg ;;
474 1.1.1.3 mrg ;; This means that the patterns for (3) and (4) have two predicates:
475 1.1.1.3 mrg ;; one for the FP operation itself and one for the UNSPEC_SEL.
476 1.1.1.3 mrg ;; This pattern is equivalent to the result of combining an instance
477 1.1.1.3 mrg ;; of (1) or (2) with a separate vcond instruction, so these patterns
478 1.1.1.3 mrg ;; are useful as combine targets too.
479 1.1.1.3 mrg ;;
480 1.1.1.3 mrg ;; However, in the combine case, the instructions that we want to
481 1.1.1.3 mrg ;; combine might use different predicates. Then:
482 1.1.1.3 mrg ;;
483 1.1.1.3 mrg ;; - Some of the active lanes of the FP operation might be discarded
484 1.1.1.3 mrg ;; by the UNSPEC_SEL. It's OK to drop the FP operation on those lanes,
485 1.1.1.3 mrg ;; even for SVE_STRICT_GP, since the operations on those lanes are
486 1.1.1.3 mrg ;; effectively dead code.
487 1.1.1.3 mrg ;;
488 1.1.1.3 mrg ;; - Some of the inactive lanes of the FP operation might be selected
489 1.1.1.3 mrg ;; by the UNSPEC_SEL, giving unspecified values for those lanes.
490 1.1.1.3 mrg ;; SVE_RELAXED_GP lets us extend the FP operation to cover these
491 1.1.1.3 mrg ;; extra lanes, but SVE_STRICT_GP does not.
492 1.1.1.3 mrg ;;
493 1.1.1.3 mrg ;; Thus SVE_RELAXED_GP allows us to ignore the predicate on the FP operation
494 1.1.1.3 mrg ;; and operate on exactly the lanes selected by the UNSPEC_SEL predicate.
495 1.1.1.3 mrg ;; This typically leads to patterns like:
496 1.1.1.3 mrg ;;
497 1.1.1.3 mrg ;; (unspec [(match_operand 1 "register_operand" "Upl")
498 1.1.1.3 mrg ;; (unspec [(match_operand N)
499 1.1.1.3 mrg ;; (const_int SVE_RELAXED_GP)
500 1.1.1.3 mrg ;; ...]
501 1.1.1.3 mrg ;; UNSPEC_COND_<MNEMONIC>)
502 1.1.1.3 mrg ;; ...])
503 1.1.1.3 mrg ;;
504 1.1.1.3 mrg ;; where operand N is allowed to be anything. These instructions then
505 1.1.1.3 mrg ;; have rewrite rules to replace operand N with operand 1, which gives the
506 1.1.1.3 mrg ;; instructions a canonical form and means that the original operand N is
507 1.1.1.3 mrg ;; not kept live unnecessarily.
508 1.1.1.3 mrg ;;
509 1.1.1.3 mrg ;; In contrast, SVE_STRICT_GP only allows the UNSPEC_SEL predicate to be
510 1.1.1.3 mrg ;; a subset of the FP operation predicate. This case isn't interesting
511 1.1.1.3 mrg ;; for FP operations that have an all-true predicate, since such operations
512 1.1.1.3 mrg ;; use SVE_RELAXED_GP instead. And it is not possible for instruction
513 1.1.1.3 mrg ;; conditions to track the subset relationship for arbitrary registers.
514 1.1.1.3 mrg ;; So in practice, the only useful case for SVE_STRICT_GP is the one
515 1.1.1.3 mrg ;; in which the predicates match:
516 1.1.1.3 mrg ;;
517 1.1.1.3 mrg ;; (unspec [(match_operand 1 "register_operand" "Upl")
518 1.1.1.3 mrg ;; (unspec [(match_dup 1)
519 1.1.1.3 mrg ;; (const_int SVE_STRICT_GP)
520 1.1.1.3 mrg ;; ...]
521 1.1.1.3 mrg ;; UNSPEC_COND_<MNEMONIC>)
522 1.1.1.3 mrg ;; ...])
523 1.1.1.3 mrg ;;
524 1.1.1.3 mrg ;; This pattern would also be correct for SVE_RELAXED_GP, but it would
525 1.1.1.3 mrg ;; be redundant with the one above. However, if the combine pattern
526 1.1.1.3 mrg ;; has multiple FP operations, using a match_operand allows combinations
527 1.1.1.3 mrg ;; of SVE_STRICT_GP and SVE_RELAXED_GP in the same operation, provided
528 1.1.1.3 mrg ;; that the predicates are the same:
529 1.1.1.3 mrg ;;
530 1.1.1.3 mrg ;; (unspec [(match_operand 1 "register_operand" "Upl")
531 1.1.1.3 mrg ;; (...
532 1.1.1.3 mrg ;; (unspec [(match_dup 1)
533 1.1.1.3 mrg ;; (match_operand:SI N "aarch64_sve_gp_strictness")
534 1.1.1.3 mrg ;; ...]
535 1.1.1.3 mrg ;; UNSPEC_COND_<MNEMONIC1>)
536 1.1.1.3 mrg ;; (unspec [(match_dup 1)
537 1.1.1.3 mrg ;; (match_operand:SI M "aarch64_sve_gp_strictness")
538 1.1.1.3 mrg ;; ...]
539 1.1.1.3 mrg ;; UNSPEC_COND_<MNEMONIC2>) ...)
540 1.1.1.3 mrg ;; ...])
541 1.1.1.3 mrg ;;
542 1.1.1.3 mrg ;; The fully-relaxed version of this pattern is:
543 1.1.1.3 mrg ;;
544 1.1.1.3 mrg ;; (unspec [(match_operand 1 "register_operand" "Upl")
545 1.1.1.3 mrg ;; (...
546 1.1.1.3 mrg ;; (unspec [(match_operand:SI N)
547 1.1.1.3 mrg ;; (const_int SVE_RELAXED_GP)
548 1.1.1.3 mrg ;; ...]
549 1.1.1.3 mrg ;; UNSPEC_COND_<MNEMONIC1>)
550 1.1.1.3 mrg ;; (unspec [(match_operand:SI M)
551 1.1.1.3 mrg ;; (const_int SVE_RELAXED_GP)
552 1.1.1.3 mrg ;; ...]
553 1.1.1.3 mrg ;; UNSPEC_COND_<MNEMONIC2>) ...)
554 1.1.1.3 mrg ;; ...])
555 1.1.1.3 mrg ;;
556 1.1.1.3 mrg ;; -------------------------------------------------------------------------
557 1.1.1.3 mrg ;; ---- Note on FFR handling
558 1.1.1.3 mrg ;; -------------------------------------------------------------------------
559 1.1.1.3 mrg ;;
560 1.1.1.3 mrg ;; Logically we want to divide FFR-related instructions into regions
561 1.1.1.3 mrg ;; that contain exactly one of:
562 1.1.1.3 mrg ;;
563 1.1.1.3 mrg ;; - a single write to the FFR
564 1.1.1.3 mrg ;; - any number of reads from the FFR (but only one read is likely)
565 1.1.1.3 mrg ;; - any number of LDFF1 and LDNF1 instructions
566 1.1.1.3 mrg ;;
567 1.1.1.3 mrg ;; However, LDFF1 and LDNF1 instructions should otherwise behave like
568 1.1.1.3 mrg ;; normal loads as far as possible. This means that they should be
569 1.1.1.3 mrg ;; schedulable within a region in the same way that LD1 would be,
570 1.1.1.3 mrg ;; and they should be deleted as dead if the result is unused. The loads
571 1.1.1.3 mrg ;; should therefore not write to the FFR, since that would both serialize
572 1.1.1.3 mrg ;; the loads with respect to each other and keep the loads live for any
573 1.1.1.3 mrg ;; later RDFFR.
574 1.1.1.3 mrg ;;
575 1.1.1.3 mrg ;; We get around this by using a fake "FFR token" (FFRT) to help describe
576 1.1.1.3 mrg ;; the dependencies. Writing to the FFRT starts a new "FFRT region",
577 1.1.1.3 mrg ;; while using the FFRT keeps the instruction within its region.
578 1.1.1.3 mrg ;; Specifically:
579 1.1.1.3 mrg ;;
580 1.1.1.3 mrg ;; - Writes start a new FFRT region as well as setting the FFR:
581 1.1.1.3 mrg ;;
582 1.1.1.3 mrg ;; W1: parallel (FFRT = <new value>, FFR = <actual FFR value>)
583 1.1.1.3 mrg ;;
584 1.1.1.3 mrg ;; - Loads use an LD1-like instruction that also uses the FFRT, so that the
585 1.1.1.3 mrg ;; loads stay within the same FFRT region:
586 1.1.1.3 mrg ;;
587 1.1.1.3 mrg ;; L1: load data while using the FFRT
588 1.1.1.3 mrg ;;
589 1.1.1.3 mrg ;; In addition, any FFRT region that includes a load also has at least one
590 1.1.1.3 mrg ;; instance of:
591 1.1.1.3 mrg ;;
592 1.1.1.3 mrg ;; L2: FFR = update(FFR, FFRT) [type == no_insn]
593 1.1.1.3 mrg ;;
594 1.1.1.3 mrg ;; to make it clear that the region both reads from and writes to the FFR.
595 1.1.1.3 mrg ;;
596 1.1.1.3 mrg ;; - Reads do the following:
597 1.1.1.3 mrg ;;
598 1.1.1.3 mrg ;; R1: FFRT = FFR [type == no_insn]
599 1.1.1.3 mrg ;; R2: read from the FFRT
600 1.1.1.3 mrg ;; R3: FFRT = update(FFRT) [type == no_insn]
601 1.1.1.3 mrg ;;
602 1.1.1.3 mrg ;; R1 and R3 both create new FFRT regions, so that previous LDFF1s and
603 1.1.1.3 mrg ;; LDNF1s cannot move forwards across R1 and later LDFF1s and LDNF1s
604 1.1.1.3 mrg ;; cannot move backwards across R3.
605 1.1.1.3 mrg ;;
606 1.1.1.3 mrg ;; This way, writes are only kept alive by later loads or reads,
607 1.1.1.3 mrg ;; and write/read pairs fold normally. For two consecutive reads,
608 1.1.1.3 mrg ;; the first R3 is made dead by the second R1, which in turn becomes
609 1.1.1.3 mrg ;; redundant with the first R1. We then have:
610 1.1.1.3 mrg ;;
611 1.1.1.3 mrg ;; first R1: FFRT = FFR
612 1.1.1.3 mrg ;; first read from the FFRT
613 1.1.1.3 mrg ;; second read from the FFRT
614 1.1.1.3 mrg ;; second R3: FFRT = update(FFRT)
615 1.1.1.3 mrg ;;
616 1.1.1.3 mrg ;; i.e. the two FFRT regions collapse into a single one with two
617 1.1.1.3 mrg ;; independent reads.
618 1.1.1.3 mrg ;;
619 1.1.1.3 mrg ;; The model still prevents some valid optimizations though. For example,
620 1.1.1.3 mrg ;; if all loads in an FFRT region are deleted as dead, nothing would remove
621 1.1.1.3 mrg ;; the L2 instructions.
622 1.1.1.3 mrg
623 1.1.1.3 mrg ;; =========================================================================
624 1.1.1.3 mrg ;; == Moves
625 1.1.1.3 mrg ;; =========================================================================
626 1.1.1.3 mrg
627 1.1.1.3 mrg ;; -------------------------------------------------------------------------
628 1.1.1.3 mrg ;; ---- Moves of single vectors
629 1.1.1.3 mrg ;; -------------------------------------------------------------------------
630 1.1.1.3 mrg ;; Includes:
631 1.1.1.3 mrg ;; - MOV (including aliases)
632 1.1.1.3 mrg ;; - LD1B (contiguous form)
633 1.1.1.3 mrg ;; - LD1D ( " " )
634 1.1.1.3 mrg ;; - LD1H ( " " )
635 1.1.1.3 mrg ;; - LD1W ( " " )
636 1.1.1.3 mrg ;; - LDR
637 1.1.1.3 mrg ;; - ST1B (contiguous form)
638 1.1.1.3 mrg ;; - ST1D ( " " )
639 1.1.1.3 mrg ;; - ST1H ( " " )
640 1.1.1.3 mrg ;; - ST1W ( " " )
641 1.1.1.3 mrg ;; - STR
642 1.1.1.3 mrg ;; -------------------------------------------------------------------------
643 1.1 mrg
644 1.1 mrg (define_expand "mov<mode>"
645 1.1 mrg [(set (match_operand:SVE_ALL 0 "nonimmediate_operand")
646 1.1 mrg (match_operand:SVE_ALL 1 "general_operand"))]
647 1.1 mrg "TARGET_SVE"
648 1.1 mrg {
649 1.1 mrg /* Use the predicated load and store patterns where possible.
650 1.1 mrg This is required for big-endian targets (see the comment at the
651 1.1 mrg head of the file) and increases the addressing choices for
652 1.1 mrg little-endian. */
653 1.1 mrg if ((MEM_P (operands[0]) || MEM_P (operands[1]))
654 1.1.1.3 mrg && can_create_pseudo_p ())
655 1.1 mrg {
656 1.1 mrg aarch64_expand_sve_mem_move (operands[0], operands[1], <VPRED>mode);
657 1.1 mrg DONE;
658 1.1 mrg }
659 1.1 mrg
660 1.1 mrg if (CONSTANT_P (operands[1]))
661 1.1 mrg {
662 1.1.1.3 mrg aarch64_expand_mov_immediate (operands[0], operands[1]);
663 1.1 mrg DONE;
664 1.1 mrg }
665 1.1 mrg
666 1.1 mrg /* Optimize subregs on big-endian targets: we can use REV[BHW]
667 1.1 mrg instead of going through memory. */
668 1.1 mrg if (BYTES_BIG_ENDIAN
669 1.1.1.3 mrg && aarch64_maybe_expand_sve_subreg_move (operands[0], operands[1]))
670 1.1 mrg DONE;
671 1.1 mrg }
672 1.1 mrg )
673 1.1 mrg
674 1.1.1.3 mrg (define_expand "movmisalign<mode>"
675 1.1.1.3 mrg [(set (match_operand:SVE_ALL 0 "nonimmediate_operand")
676 1.1.1.3 mrg (match_operand:SVE_ALL 1 "general_operand"))]
677 1.1.1.3 mrg "TARGET_SVE"
678 1.1 mrg {
679 1.1.1.3 mrg /* Equivalent to a normal move for our purpooses. */
680 1.1.1.3 mrg emit_move_insn (operands[0], operands[1]);
681 1.1 mrg DONE;
682 1.1 mrg }
683 1.1 mrg )
684 1.1 mrg
685 1.1.1.3 mrg ;; Unpredicated moves that can use LDR and STR, i.e. full vectors for which
686 1.1.1.3 mrg ;; little-endian ordering is acceptable. Only allow memory operations during
687 1.1.1.3 mrg ;; and after RA; before RA we want the predicated load and store patterns to
688 1.1.1.3 mrg ;; be used instead.
689 1.1.1.3 mrg (define_insn "*aarch64_sve_mov<mode>_ldr_str"
690 1.1.1.3 mrg [(set (match_operand:SVE_FULL 0 "aarch64_sve_nonimmediate_operand" "=w, Utr, w, w")
691 1.1.1.3 mrg (match_operand:SVE_FULL 1 "aarch64_sve_general_operand" "Utr, w, w, Dn"))]
692 1.1 mrg "TARGET_SVE
693 1.1.1.3 mrg && (<MODE>mode == VNx16QImode || !BYTES_BIG_ENDIAN)
694 1.1 mrg && ((lra_in_progress || reload_completed)
695 1.1 mrg || (register_operand (operands[0], <MODE>mode)
696 1.1 mrg && nonmemory_operand (operands[1], <MODE>mode)))"
697 1.1 mrg "@
698 1.1 mrg ldr\t%0, %1
699 1.1 mrg str\t%1, %0
700 1.1 mrg mov\t%0.d, %1.d
701 1.1 mrg * return aarch64_output_sve_mov_immediate (operands[1]);"
702 1.1 mrg )
703 1.1 mrg
704 1.1.1.3 mrg ;; Unpredicated moves that cannot use LDR and STR, i.e. partial vectors
705 1.1.1.3 mrg ;; or vectors for which little-endian ordering isn't acceptable. Memory
706 1.1.1.3 mrg ;; accesses require secondary reloads.
707 1.1.1.3 mrg (define_insn "*aarch64_sve_mov<mode>_no_ldr_str"
708 1.1 mrg [(set (match_operand:SVE_ALL 0 "register_operand" "=w, w")
709 1.1 mrg (match_operand:SVE_ALL 1 "aarch64_nonmemory_operand" "w, Dn"))]
710 1.1.1.3 mrg "TARGET_SVE
711 1.1.1.3 mrg && <MODE>mode != VNx16QImode
712 1.1.1.3 mrg && (BYTES_BIG_ENDIAN
713 1.1.1.3 mrg || maybe_ne (BYTES_PER_SVE_VECTOR, GET_MODE_SIZE (<MODE>mode)))"
714 1.1 mrg "@
715 1.1 mrg mov\t%0.d, %1.d
716 1.1 mrg * return aarch64_output_sve_mov_immediate (operands[1]);"
717 1.1 mrg )
718 1.1 mrg
719 1.1.1.3 mrg ;; Handle memory reloads for modes that can't use LDR and STR. We use
720 1.1.1.3 mrg ;; byte PTRUE for all modes to try to encourage reuse. This pattern
721 1.1.1.3 mrg ;; needs constraints because it is returned by TARGET_SECONDARY_RELOAD.
722 1.1.1.3 mrg (define_expand "aarch64_sve_reload_mem"
723 1.1 mrg [(parallel
724 1.1 mrg [(set (match_operand 0)
725 1.1.1.3 mrg (match_operand 1))
726 1.1 mrg (clobber (match_operand:VNx16BI 2 "register_operand" "=Upl"))])]
727 1.1.1.3 mrg "TARGET_SVE"
728 1.1 mrg {
729 1.1 mrg /* Create a PTRUE. */
730 1.1 mrg emit_move_insn (operands[2], CONSTM1_RTX (VNx16BImode));
731 1.1 mrg
732 1.1 mrg /* Refer to the PTRUE in the appropriate mode for this move. */
733 1.1 mrg machine_mode mode = GET_MODE (operands[0]);
734 1.1.1.3 mrg rtx pred = gen_lowpart (aarch64_sve_pred_mode (mode), operands[2]);
735 1.1 mrg
736 1.1 mrg /* Emit a predicated load or store. */
737 1.1 mrg aarch64_emit_sve_pred_move (operands[0], pred, operands[1]);
738 1.1 mrg DONE;
739 1.1 mrg }
740 1.1 mrg )
741 1.1 mrg
742 1.1.1.3 mrg ;; A predicated move in which the predicate is known to be all-true.
743 1.1.1.3 mrg ;; Note that this pattern is generated directly by aarch64_emit_sve_pred_move,
744 1.1.1.3 mrg ;; so changes to this pattern will need changes there as well.
745 1.1.1.2 mrg (define_insn_and_split "@aarch64_pred_mov<mode>"
746 1.1.1.2 mrg [(set (match_operand:SVE_ALL 0 "nonimmediate_operand" "=w, w, m")
747 1.1 mrg (unspec:SVE_ALL
748 1.1.1.2 mrg [(match_operand:<VPRED> 1 "register_operand" "Upl, Upl, Upl")
749 1.1.1.2 mrg (match_operand:SVE_ALL 2 "nonimmediate_operand" "w, m, w")]
750 1.1.1.3 mrg UNSPEC_PRED_X))]
751 1.1 mrg "TARGET_SVE
752 1.1 mrg && (register_operand (operands[0], <MODE>mode)
753 1.1 mrg || register_operand (operands[2], <MODE>mode))"
754 1.1 mrg "@
755 1.1.1.2 mrg #
756 1.1.1.3 mrg ld1<Vesize>\t%0.<Vctype>, %1/z, %2
757 1.1.1.3 mrg st1<Vesize>\t%2.<Vctype>, %1, %0"
758 1.1.1.2 mrg "&& register_operand (operands[0], <MODE>mode)
759 1.1.1.2 mrg && register_operand (operands[2], <MODE>mode)"
760 1.1.1.2 mrg [(set (match_dup 0) (match_dup 2))]
761 1.1 mrg )
762 1.1 mrg
763 1.1.1.3 mrg ;; A pattern for optimizing SUBREGs that have a reinterpreting effect
764 1.1.1.3 mrg ;; on big-endian targets; see aarch64_maybe_expand_sve_subreg_move
765 1.1.1.3 mrg ;; for details. We use a special predicate for operand 2 to reduce
766 1.1.1.3 mrg ;; the number of patterns.
767 1.1.1.3 mrg (define_insn_and_split "*aarch64_sve_mov<mode>_subreg_be"
768 1.1.1.3 mrg [(set (match_operand:SVE_ALL 0 "aarch64_sve_nonimmediate_operand" "=w")
769 1.1.1.3 mrg (unspec:SVE_ALL
770 1.1.1.3 mrg [(match_operand:VNx16BI 1 "register_operand" "Upl")
771 1.1.1.3 mrg (match_operand 2 "aarch64_any_register_operand" "w")]
772 1.1.1.3 mrg UNSPEC_REV_SUBREG))]
773 1.1.1.3 mrg "TARGET_SVE && BYTES_BIG_ENDIAN"
774 1.1.1.3 mrg "#"
775 1.1.1.3 mrg "&& reload_completed"
776 1.1.1.3 mrg [(const_int 0)]
777 1.1 mrg {
778 1.1.1.3 mrg aarch64_split_sve_subreg_move (operands[0], operands[1], operands[2]);
779 1.1 mrg DONE;
780 1.1 mrg }
781 1.1 mrg )
782 1.1 mrg
783 1.1.1.3 mrg ;; Reinterpret operand 1 in operand 0's mode, without changing its contents.
784 1.1.1.3 mrg ;; This is equivalent to a subreg on little-endian targets but not for
785 1.1.1.3 mrg ;; big-endian; see the comment at the head of the file for details.
786 1.1.1.3 mrg (define_expand "@aarch64_sve_reinterpret<mode>"
787 1.1.1.3 mrg [(set (match_operand:SVE_ALL 0 "register_operand")
788 1.1 mrg (unspec:SVE_ALL
789 1.1.1.3 mrg [(match_operand 1 "aarch64_any_register_operand")]
790 1.1.1.3 mrg UNSPEC_REINTERPRET))]
791 1.1 mrg "TARGET_SVE"
792 1.1 mrg {
793 1.1.1.3 mrg machine_mode src_mode = GET_MODE (operands[1]);
794 1.1.1.3 mrg if (targetm.can_change_mode_class (<MODE>mode, src_mode, FP_REGS))
795 1.1.1.3 mrg {
796 1.1.1.3 mrg emit_move_insn (operands[0], gen_lowpart (<MODE>mode, operands[1]));
797 1.1.1.3 mrg DONE;
798 1.1.1.3 mrg }
799 1.1 mrg }
800 1.1 mrg )
801 1.1 mrg
802 1.1.1.3 mrg ;; A pattern for handling type punning on big-endian targets. We use a
803 1.1.1.3 mrg ;; special predicate for operand 1 to reduce the number of patterns.
804 1.1.1.3 mrg (define_insn_and_split "*aarch64_sve_reinterpret<mode>"
805 1.1.1.3 mrg [(set (match_operand:SVE_ALL 0 "register_operand" "=w")
806 1.1.1.3 mrg (unspec:SVE_ALL
807 1.1.1.3 mrg [(match_operand 1 "aarch64_any_register_operand" "w")]
808 1.1.1.3 mrg UNSPEC_REINTERPRET))]
809 1.1 mrg "TARGET_SVE"
810 1.1.1.3 mrg "#"
811 1.1.1.3 mrg "&& reload_completed"
812 1.1.1.3 mrg [(set (match_dup 0) (match_dup 1))]
813 1.1 mrg {
814 1.1.1.3 mrg operands[1] = aarch64_replace_reg_mode (operands[1], <MODE>mode);
815 1.1 mrg }
816 1.1 mrg )
817 1.1 mrg
818 1.1.1.3 mrg ;; -------------------------------------------------------------------------
819 1.1.1.3 mrg ;; ---- Moves of multiple vectors
820 1.1.1.3 mrg ;; -------------------------------------------------------------------------
821 1.1.1.3 mrg ;; All patterns in this section are synthetic and split to real
822 1.1.1.3 mrg ;; instructions after reload.
823 1.1.1.3 mrg ;; -------------------------------------------------------------------------
824 1.1 mrg
825 1.1 mrg (define_expand "mov<mode>"
826 1.1 mrg [(set (match_operand:SVE_STRUCT 0 "nonimmediate_operand")
827 1.1 mrg (match_operand:SVE_STRUCT 1 "general_operand"))]
828 1.1 mrg "TARGET_SVE"
829 1.1 mrg {
830 1.1 mrg /* Big-endian loads and stores need to be done via LD1 and ST1;
831 1.1 mrg see the comment at the head of the file for details. */
832 1.1 mrg if ((MEM_P (operands[0]) || MEM_P (operands[1]))
833 1.1 mrg && BYTES_BIG_ENDIAN)
834 1.1 mrg {
835 1.1 mrg gcc_assert (can_create_pseudo_p ());
836 1.1 mrg aarch64_expand_sve_mem_move (operands[0], operands[1], <VPRED>mode);
837 1.1 mrg DONE;
838 1.1 mrg }
839 1.1 mrg
840 1.1 mrg if (CONSTANT_P (operands[1]))
841 1.1 mrg {
842 1.1 mrg aarch64_expand_mov_immediate (operands[0], operands[1]);
843 1.1 mrg DONE;
844 1.1 mrg }
845 1.1 mrg }
846 1.1 mrg )
847 1.1 mrg
848 1.1 mrg ;; Unpredicated structure moves (little-endian).
849 1.1 mrg (define_insn "*aarch64_sve_mov<mode>_le"
850 1.1 mrg [(set (match_operand:SVE_STRUCT 0 "aarch64_sve_nonimmediate_operand" "=w, Utr, w, w")
851 1.1 mrg (match_operand:SVE_STRUCT 1 "aarch64_sve_general_operand" "Utr, w, w, Dn"))]
852 1.1 mrg "TARGET_SVE && !BYTES_BIG_ENDIAN"
853 1.1 mrg "#"
854 1.1 mrg [(set_attr "length" "<insn_length>")]
855 1.1 mrg )
856 1.1 mrg
857 1.1 mrg ;; Unpredicated structure moves (big-endian). Memory accesses require
858 1.1 mrg ;; secondary reloads.
859 1.1.1.3 mrg (define_insn "*aarch64_sve_mov<mode>_be"
860 1.1 mrg [(set (match_operand:SVE_STRUCT 0 "register_operand" "=w, w")
861 1.1 mrg (match_operand:SVE_STRUCT 1 "aarch64_nonmemory_operand" "w, Dn"))]
862 1.1 mrg "TARGET_SVE && BYTES_BIG_ENDIAN"
863 1.1 mrg "#"
864 1.1 mrg [(set_attr "length" "<insn_length>")]
865 1.1 mrg )
866 1.1 mrg
867 1.1 mrg ;; Split unpredicated structure moves into pieces. This is the same
868 1.1 mrg ;; for both big-endian and little-endian code, although it only needs
869 1.1 mrg ;; to handle memory operands for little-endian code.
870 1.1 mrg (define_split
871 1.1 mrg [(set (match_operand:SVE_STRUCT 0 "aarch64_sve_nonimmediate_operand")
872 1.1 mrg (match_operand:SVE_STRUCT 1 "aarch64_sve_general_operand"))]
873 1.1 mrg "TARGET_SVE && reload_completed"
874 1.1 mrg [(const_int 0)]
875 1.1 mrg {
876 1.1 mrg rtx dest = operands[0];
877 1.1 mrg rtx src = operands[1];
878 1.1 mrg if (REG_P (dest) && REG_P (src))
879 1.1 mrg aarch64_simd_emit_reg_reg_move (operands, <VSINGLE>mode, <vector_count>);
880 1.1 mrg else
881 1.1 mrg for (unsigned int i = 0; i < <vector_count>; ++i)
882 1.1 mrg {
883 1.1 mrg rtx subdest = simplify_gen_subreg (<VSINGLE>mode, dest, <MODE>mode,
884 1.1 mrg i * BYTES_PER_SVE_VECTOR);
885 1.1 mrg rtx subsrc = simplify_gen_subreg (<VSINGLE>mode, src, <MODE>mode,
886 1.1 mrg i * BYTES_PER_SVE_VECTOR);
887 1.1 mrg emit_insn (gen_rtx_SET (subdest, subsrc));
888 1.1 mrg }
889 1.1 mrg DONE;
890 1.1 mrg }
891 1.1 mrg )
892 1.1 mrg
893 1.1 mrg ;; Predicated structure moves. This works for both endiannesses but in
894 1.1 mrg ;; practice is only useful for big-endian.
895 1.1.1.2 mrg (define_insn_and_split "@aarch64_pred_mov<mode>"
896 1.1.1.2 mrg [(set (match_operand:SVE_STRUCT 0 "aarch64_sve_struct_nonimmediate_operand" "=w, w, Utx")
897 1.1 mrg (unspec:SVE_STRUCT
898 1.1.1.2 mrg [(match_operand:<VPRED> 1 "register_operand" "Upl, Upl, Upl")
899 1.1.1.2 mrg (match_operand:SVE_STRUCT 2 "aarch64_sve_struct_nonimmediate_operand" "w, Utx, w")]
900 1.1.1.3 mrg UNSPEC_PRED_X))]
901 1.1 mrg "TARGET_SVE
902 1.1 mrg && (register_operand (operands[0], <MODE>mode)
903 1.1 mrg || register_operand (operands[2], <MODE>mode))"
904 1.1 mrg "#"
905 1.1 mrg "&& reload_completed"
906 1.1 mrg [(const_int 0)]
907 1.1 mrg {
908 1.1 mrg for (unsigned int i = 0; i < <vector_count>; ++i)
909 1.1 mrg {
910 1.1 mrg rtx subdest = simplify_gen_subreg (<VSINGLE>mode, operands[0],
911 1.1 mrg <MODE>mode,
912 1.1 mrg i * BYTES_PER_SVE_VECTOR);
913 1.1 mrg rtx subsrc = simplify_gen_subreg (<VSINGLE>mode, operands[2],
914 1.1 mrg <MODE>mode,
915 1.1 mrg i * BYTES_PER_SVE_VECTOR);
916 1.1 mrg aarch64_emit_sve_pred_move (subdest, operands[1], subsrc);
917 1.1 mrg }
918 1.1 mrg DONE;
919 1.1 mrg }
920 1.1 mrg [(set_attr "length" "<insn_length>")]
921 1.1 mrg )
922 1.1 mrg
923 1.1.1.3 mrg ;; -------------------------------------------------------------------------
924 1.1.1.3 mrg ;; ---- Moves of predicates
925 1.1.1.3 mrg ;; -------------------------------------------------------------------------
926 1.1.1.3 mrg ;; Includes:
927 1.1.1.3 mrg ;; - MOV
928 1.1.1.3 mrg ;; - LDR
929 1.1.1.3 mrg ;; - PFALSE
930 1.1.1.3 mrg ;; - PTRUE
931 1.1.1.3 mrg ;; - PTRUES
932 1.1.1.3 mrg ;; - STR
933 1.1.1.3 mrg ;; -------------------------------------------------------------------------
934 1.1.1.3 mrg
935 1.1 mrg (define_expand "mov<mode>"
936 1.1 mrg [(set (match_operand:PRED_ALL 0 "nonimmediate_operand")
937 1.1 mrg (match_operand:PRED_ALL 1 "general_operand"))]
938 1.1 mrg "TARGET_SVE"
939 1.1 mrg {
940 1.1 mrg if (GET_CODE (operands[0]) == MEM)
941 1.1 mrg operands[1] = force_reg (<MODE>mode, operands[1]);
942 1.1.1.3 mrg
943 1.1.1.3 mrg if (CONSTANT_P (operands[1]))
944 1.1.1.3 mrg {
945 1.1.1.3 mrg aarch64_expand_mov_immediate (operands[0], operands[1]);
946 1.1.1.3 mrg DONE;
947 1.1.1.3 mrg }
948 1.1 mrg }
949 1.1 mrg )
950 1.1 mrg
951 1.1 mrg (define_insn "*aarch64_sve_mov<mode>"
952 1.1.1.3 mrg [(set (match_operand:PRED_ALL 0 "nonimmediate_operand" "=Upa, m, Upa, Upa")
953 1.1.1.3 mrg (match_operand:PRED_ALL 1 "aarch64_mov_operand" "Upa, Upa, m, Dn"))]
954 1.1 mrg "TARGET_SVE
955 1.1 mrg && (register_operand (operands[0], <MODE>mode)
956 1.1 mrg || register_operand (operands[1], <MODE>mode))"
957 1.1 mrg "@
958 1.1 mrg mov\t%0.b, %1.b
959 1.1 mrg str\t%1, %0
960 1.1 mrg ldr\t%0, %1
961 1.1.1.3 mrg * return aarch64_output_sve_mov_immediate (operands[1]);"
962 1.1 mrg )
963 1.1 mrg
964 1.1.1.3 mrg ;; Match PTRUES Pn.B when both the predicate and flags are useful.
965 1.1.1.3 mrg (define_insn_and_rewrite "*aarch64_sve_ptruevnx16bi_cc"
966 1.1.1.3 mrg [(set (reg:CC_NZC CC_REGNUM)
967 1.1.1.3 mrg (unspec:CC_NZC
968 1.1.1.3 mrg [(match_operand 2)
969 1.1.1.3 mrg (match_operand 3)
970 1.1.1.3 mrg (const_int SVE_KNOWN_PTRUE)
971 1.1.1.3 mrg (match_operator:VNx16BI 1 "aarch64_sve_ptrue_svpattern_immediate"
972 1.1.1.3 mrg [(unspec:VNx16BI
973 1.1.1.3 mrg [(match_operand:SI 4 "const_int_operand")
974 1.1.1.3 mrg (match_operand:VNx16BI 5 "aarch64_simd_imm_zero")]
975 1.1.1.3 mrg UNSPEC_PTRUE)])]
976 1.1.1.3 mrg UNSPEC_PTEST))
977 1.1.1.3 mrg (set (match_operand:VNx16BI 0 "register_operand" "=Upa")
978 1.1.1.3 mrg (match_dup 1))]
979 1.1 mrg "TARGET_SVE"
980 1.1 mrg {
981 1.1.1.3 mrg return aarch64_output_sve_ptrues (operands[1]);
982 1.1.1.3 mrg }
983 1.1.1.3 mrg "&& (!CONSTANT_P (operands[2]) || !CONSTANT_P (operands[3]))"
984 1.1.1.3 mrg {
985 1.1.1.3 mrg operands[2] = operands[3] = CONSTM1_RTX (VNx16BImode);
986 1.1 mrg }
987 1.1 mrg )
988 1.1 mrg
989 1.1.1.3 mrg ;; Match PTRUES Pn.[HSD] when both the predicate and flags are useful.
990 1.1.1.3 mrg (define_insn_and_rewrite "*aarch64_sve_ptrue<mode>_cc"
991 1.1.1.3 mrg [(set (reg:CC_NZC CC_REGNUM)
992 1.1.1.3 mrg (unspec:CC_NZC
993 1.1.1.3 mrg [(match_operand 2)
994 1.1.1.3 mrg (match_operand 3)
995 1.1.1.3 mrg (const_int SVE_KNOWN_PTRUE)
996 1.1.1.3 mrg (subreg:PRED_HSD
997 1.1.1.3 mrg (match_operator:VNx16BI 1 "aarch64_sve_ptrue_svpattern_immediate"
998 1.1.1.3 mrg [(unspec:VNx16BI
999 1.1.1.3 mrg [(match_operand:SI 4 "const_int_operand")
1000 1.1.1.3 mrg (match_operand:PRED_HSD 5 "aarch64_simd_imm_zero")]
1001 1.1.1.3 mrg UNSPEC_PTRUE)]) 0)]
1002 1.1.1.3 mrg UNSPEC_PTEST))
1003 1.1.1.3 mrg (set (match_operand:VNx16BI 0 "register_operand" "=Upa")
1004 1.1.1.3 mrg (match_dup 1))]
1005 1.1 mrg "TARGET_SVE"
1006 1.1 mrg {
1007 1.1.1.3 mrg return aarch64_output_sve_ptrues (operands[1]);
1008 1.1.1.3 mrg }
1009 1.1.1.3 mrg "&& (!CONSTANT_P (operands[2]) || !CONSTANT_P (operands[3]))"
1010 1.1.1.3 mrg {
1011 1.1.1.3 mrg operands[2] = CONSTM1_RTX (VNx16BImode);
1012 1.1.1.3 mrg operands[3] = CONSTM1_RTX (<MODE>mode);
1013 1.1 mrg }
1014 1.1 mrg )
1015 1.1 mrg
1016 1.1.1.3 mrg ;; Match PTRUES Pn.B when only the flags result is useful (which is
1017 1.1.1.3 mrg ;; a way of testing VL).
1018 1.1.1.3 mrg (define_insn_and_rewrite "*aarch64_sve_ptruevnx16bi_ptest"
1019 1.1.1.3 mrg [(set (reg:CC_NZC CC_REGNUM)
1020 1.1.1.3 mrg (unspec:CC_NZC
1021 1.1.1.3 mrg [(match_operand 2)
1022 1.1.1.3 mrg (match_operand 3)
1023 1.1.1.3 mrg (const_int SVE_KNOWN_PTRUE)
1024 1.1.1.3 mrg (match_operator:VNx16BI 1 "aarch64_sve_ptrue_svpattern_immediate"
1025 1.1.1.3 mrg [(unspec:VNx16BI
1026 1.1.1.3 mrg [(match_operand:SI 4 "const_int_operand")
1027 1.1.1.3 mrg (match_operand:VNx16BI 5 "aarch64_simd_imm_zero")]
1028 1.1.1.3 mrg UNSPEC_PTRUE)])]
1029 1.1.1.3 mrg UNSPEC_PTEST))
1030 1.1.1.3 mrg (clobber (match_scratch:VNx16BI 0 "=Upa"))]
1031 1.1 mrg "TARGET_SVE"
1032 1.1 mrg {
1033 1.1.1.3 mrg return aarch64_output_sve_ptrues (operands[1]);
1034 1.1 mrg }
1035 1.1.1.3 mrg "&& (!CONSTANT_P (operands[2]) || !CONSTANT_P (operands[3]))"
1036 1.1 mrg {
1037 1.1.1.3 mrg operands[2] = operands[3] = CONSTM1_RTX (VNx16BImode);
1038 1.1 mrg }
1039 1.1 mrg )
1040 1.1 mrg
1041 1.1.1.3 mrg ;; Match PTRUES Pn.[HWD] when only the flags result is useful (which is
1042 1.1.1.3 mrg ;; a way of testing VL).
1043 1.1.1.3 mrg (define_insn_and_rewrite "*aarch64_sve_ptrue<mode>_ptest"
1044 1.1.1.3 mrg [(set (reg:CC_NZC CC_REGNUM)
1045 1.1.1.3 mrg (unspec:CC_NZC
1046 1.1.1.3 mrg [(match_operand 2)
1047 1.1.1.3 mrg (match_operand 3)
1048 1.1.1.3 mrg (const_int SVE_KNOWN_PTRUE)
1049 1.1.1.3 mrg (subreg:PRED_HSD
1050 1.1.1.3 mrg (match_operator:VNx16BI 1 "aarch64_sve_ptrue_svpattern_immediate"
1051 1.1.1.3 mrg [(unspec:VNx16BI
1052 1.1.1.3 mrg [(match_operand:SI 4 "const_int_operand")
1053 1.1.1.3 mrg (match_operand:PRED_HSD 5 "aarch64_simd_imm_zero")]
1054 1.1.1.3 mrg UNSPEC_PTRUE)]) 0)]
1055 1.1.1.3 mrg UNSPEC_PTEST))
1056 1.1.1.3 mrg (clobber (match_scratch:VNx16BI 0 "=Upa"))]
1057 1.1.1.3 mrg "TARGET_SVE"
1058 1.1 mrg {
1059 1.1.1.3 mrg return aarch64_output_sve_ptrues (operands[1]);
1060 1.1 mrg }
1061 1.1.1.3 mrg "&& (!CONSTANT_P (operands[2]) || !CONSTANT_P (operands[3]))"
1062 1.1 mrg {
1063 1.1.1.3 mrg operands[2] = CONSTM1_RTX (VNx16BImode);
1064 1.1.1.3 mrg operands[3] = CONSTM1_RTX (<MODE>mode);
1065 1.1 mrg }
1066 1.1 mrg )
1067 1.1 mrg
1068 1.1.1.3 mrg ;; -------------------------------------------------------------------------
1069 1.1.1.3 mrg ;; ---- Moves relating to the FFR
1070 1.1.1.3 mrg ;; -------------------------------------------------------------------------
1071 1.1.1.3 mrg ;; RDFFR
1072 1.1.1.3 mrg ;; RDFFRS
1073 1.1.1.3 mrg ;; SETFFR
1074 1.1.1.3 mrg ;; WRFFR
1075 1.1.1.3 mrg ;; -------------------------------------------------------------------------
1076 1.1 mrg
1077 1.1.1.3 mrg ;; [W1 in the block comment above about FFR handling]
1078 1.1.1.3 mrg ;;
1079 1.1.1.3 mrg ;; Write to the FFR and start a new FFRT scheduling region.
1080 1.1.1.3 mrg (define_insn "aarch64_wrffr"
1081 1.1.1.3 mrg [(set (reg:VNx16BI FFR_REGNUM)
1082 1.1.1.3 mrg (match_operand:VNx16BI 0 "aarch64_simd_reg_or_minus_one" "Dm, Upa"))
1083 1.1.1.3 mrg (set (reg:VNx16BI FFRT_REGNUM)
1084 1.1.1.3 mrg (unspec:VNx16BI [(match_dup 0)] UNSPEC_WRFFR))]
1085 1.1 mrg "TARGET_SVE"
1086 1.1 mrg "@
1087 1.1.1.3 mrg setffr
1088 1.1.1.3 mrg wrffr\t%0.b"
1089 1.1 mrg )
1090 1.1 mrg
1091 1.1.1.3 mrg ;; [L2 in the block comment above about FFR handling]
1092 1.1.1.3 mrg ;;
1093 1.1.1.3 mrg ;; Introduce a read from and write to the FFR in the current FFRT region,
1094 1.1.1.3 mrg ;; so that the FFR value is live on entry to the region and so that the FFR
1095 1.1.1.3 mrg ;; value visibly changes within the region. This is used (possibly multiple
1096 1.1.1.3 mrg ;; times) in an FFRT region that includes LDFF1 or LDNF1 instructions.
1097 1.1.1.3 mrg (define_insn "aarch64_update_ffr_for_load"
1098 1.1.1.3 mrg [(set (reg:VNx16BI FFR_REGNUM)
1099 1.1.1.3 mrg (unspec:VNx16BI [(reg:VNx16BI FFRT_REGNUM)
1100 1.1.1.3 mrg (reg:VNx16BI FFR_REGNUM)] UNSPEC_UPDATE_FFR))]
1101 1.1 mrg "TARGET_SVE"
1102 1.1.1.3 mrg ""
1103 1.1.1.3 mrg [(set_attr "type" "no_insn")]
1104 1.1 mrg )
1105 1.1 mrg
1106 1.1.1.3 mrg ;; [R1 in the block comment above about FFR handling]
1107 1.1.1.3 mrg ;;
1108 1.1.1.3 mrg ;; Notionally copy the FFR to the FFRT, so that the current FFR value
1109 1.1.1.3 mrg ;; can be read from there by the RDFFR instructions below. This acts
1110 1.1.1.3 mrg ;; as a scheduling barrier for earlier LDFF1 and LDNF1 instructions and
1111 1.1.1.3 mrg ;; creates a natural dependency with earlier writes.
1112 1.1.1.3 mrg (define_insn "aarch64_copy_ffr_to_ffrt"
1113 1.1.1.3 mrg [(set (reg:VNx16BI FFRT_REGNUM)
1114 1.1.1.3 mrg (reg:VNx16BI FFR_REGNUM))]
1115 1.1 mrg "TARGET_SVE"
1116 1.1.1.3 mrg ""
1117 1.1.1.3 mrg [(set_attr "type" "no_insn")]
1118 1.1 mrg )
1119 1.1 mrg
1120 1.1.1.3 mrg ;; [R2 in the block comment above about FFR handling]
1121 1.1.1.3 mrg ;;
1122 1.1.1.3 mrg ;; Read the FFR via the FFRT.
1123 1.1.1.3 mrg (define_insn "aarch64_rdffr"
1124 1.1.1.3 mrg [(set (match_operand:VNx16BI 0 "register_operand" "=Upa")
1125 1.1.1.3 mrg (reg:VNx16BI FFRT_REGNUM))]
1126 1.1.1.3 mrg "TARGET_SVE"
1127 1.1.1.3 mrg "rdffr\t%0.b"
1128 1.1.1.3 mrg )
1129 1.1.1.3 mrg
1130 1.1.1.3 mrg ;; Likewise with zero predication.
1131 1.1.1.3 mrg (define_insn "aarch64_rdffr_z"
1132 1.1.1.3 mrg [(set (match_operand:VNx16BI 0 "register_operand" "=Upa")
1133 1.1.1.3 mrg (and:VNx16BI
1134 1.1.1.3 mrg (reg:VNx16BI FFRT_REGNUM)
1135 1.1.1.3 mrg (match_operand:VNx16BI 1 "register_operand" "Upa")))]
1136 1.1.1.3 mrg "TARGET_SVE"
1137 1.1.1.3 mrg "rdffr\t%0.b, %1/z"
1138 1.1.1.3 mrg )
1139 1.1.1.3 mrg
1140 1.1.1.3 mrg ;; Read the FFR to test for a fault, without using the predicate result.
1141 1.1.1.3 mrg (define_insn "*aarch64_rdffr_z_ptest"
1142 1.1.1.3 mrg [(set (reg:CC_NZC CC_REGNUM)
1143 1.1.1.3 mrg (unspec:CC_NZC
1144 1.1.1.3 mrg [(match_operand:VNx16BI 1 "register_operand" "Upa")
1145 1.1.1.3 mrg (match_dup 1)
1146 1.1.1.3 mrg (match_operand:SI 2 "aarch64_sve_ptrue_flag")
1147 1.1.1.3 mrg (and:VNx16BI
1148 1.1.1.3 mrg (reg:VNx16BI FFRT_REGNUM)
1149 1.1.1.3 mrg (match_dup 1))]
1150 1.1.1.3 mrg UNSPEC_PTEST))
1151 1.1.1.3 mrg (clobber (match_scratch:VNx16BI 0 "=Upa"))]
1152 1.1.1.3 mrg "TARGET_SVE"
1153 1.1.1.3 mrg "rdffrs\t%0.b, %1/z"
1154 1.1.1.3 mrg )
1155 1.1.1.3 mrg
1156 1.1.1.3 mrg ;; Same for unpredicated RDFFR when tested with a known PTRUE.
1157 1.1.1.3 mrg (define_insn "*aarch64_rdffr_ptest"
1158 1.1.1.3 mrg [(set (reg:CC_NZC CC_REGNUM)
1159 1.1.1.3 mrg (unspec:CC_NZC
1160 1.1.1.3 mrg [(match_operand:VNx16BI 1 "register_operand" "Upa")
1161 1.1.1.3 mrg (match_dup 1)
1162 1.1.1.3 mrg (const_int SVE_KNOWN_PTRUE)
1163 1.1.1.3 mrg (reg:VNx16BI FFRT_REGNUM)]
1164 1.1.1.3 mrg UNSPEC_PTEST))
1165 1.1.1.3 mrg (clobber (match_scratch:VNx16BI 0 "=Upa"))]
1166 1.1.1.3 mrg "TARGET_SVE"
1167 1.1.1.3 mrg "rdffrs\t%0.b, %1/z"
1168 1.1.1.3 mrg )
1169 1.1.1.3 mrg
1170 1.1.1.3 mrg ;; Read the FFR with zero predication and test the result.
1171 1.1.1.3 mrg (define_insn "*aarch64_rdffr_z_cc"
1172 1.1.1.3 mrg [(set (reg:CC_NZC CC_REGNUM)
1173 1.1.1.3 mrg (unspec:CC_NZC
1174 1.1.1.3 mrg [(match_operand:VNx16BI 1 "register_operand" "Upa")
1175 1.1.1.3 mrg (match_dup 1)
1176 1.1.1.3 mrg (match_operand:SI 2 "aarch64_sve_ptrue_flag")
1177 1.1.1.3 mrg (and:VNx16BI
1178 1.1.1.3 mrg (reg:VNx16BI FFRT_REGNUM)
1179 1.1.1.3 mrg (match_dup 1))]
1180 1.1.1.3 mrg UNSPEC_PTEST))
1181 1.1.1.3 mrg (set (match_operand:VNx16BI 0 "register_operand" "=Upa")
1182 1.1.1.3 mrg (and:VNx16BI
1183 1.1.1.3 mrg (reg:VNx16BI FFRT_REGNUM)
1184 1.1.1.3 mrg (match_dup 1)))]
1185 1.1.1.3 mrg "TARGET_SVE"
1186 1.1.1.3 mrg "rdffrs\t%0.b, %1/z"
1187 1.1.1.3 mrg )
1188 1.1.1.3 mrg
1189 1.1.1.3 mrg ;; Same for unpredicated RDFFR when tested with a known PTRUE.
1190 1.1.1.3 mrg (define_insn "*aarch64_rdffr_cc"
1191 1.1.1.3 mrg [(set (reg:CC_NZC CC_REGNUM)
1192 1.1.1.3 mrg (unspec:CC_NZC
1193 1.1.1.3 mrg [(match_operand:VNx16BI 1 "register_operand" "Upa")
1194 1.1.1.3 mrg (match_dup 1)
1195 1.1.1.3 mrg (const_int SVE_KNOWN_PTRUE)
1196 1.1.1.3 mrg (reg:VNx16BI FFRT_REGNUM)]
1197 1.1.1.3 mrg UNSPEC_PTEST))
1198 1.1.1.3 mrg (set (match_operand:VNx16BI 0 "register_operand" "=Upa")
1199 1.1.1.3 mrg (reg:VNx16BI FFRT_REGNUM))]
1200 1.1 mrg "TARGET_SVE"
1201 1.1.1.3 mrg "rdffrs\t%0.b, %1/z"
1202 1.1 mrg )
1203 1.1 mrg
1204 1.1.1.3 mrg ;; [R3 in the block comment above about FFR handling]
1205 1.1.1.3 mrg ;;
1206 1.1.1.3 mrg ;; Arbitrarily update the FFRT after a read from the FFR. This acts as
1207 1.1.1.3 mrg ;; a scheduling barrier for later LDFF1 and LDNF1 instructions.
1208 1.1.1.3 mrg (define_insn "aarch64_update_ffrt"
1209 1.1.1.3 mrg [(set (reg:VNx16BI FFRT_REGNUM)
1210 1.1.1.3 mrg (unspec:VNx16BI [(reg:VNx16BI FFRT_REGNUM)] UNSPEC_UPDATE_FFRT))]
1211 1.1 mrg "TARGET_SVE"
1212 1.1.1.3 mrg ""
1213 1.1.1.3 mrg [(set_attr "type" "no_insn")]
1214 1.1 mrg )
1215 1.1 mrg
1216 1.1.1.3 mrg ;; =========================================================================
1217 1.1.1.3 mrg ;; == Loads
1218 1.1.1.3 mrg ;; =========================================================================
1219 1.1.1.3 mrg
1220 1.1.1.3 mrg ;; -------------------------------------------------------------------------
1221 1.1.1.3 mrg ;; ---- Normal contiguous loads
1222 1.1.1.3 mrg ;; -------------------------------------------------------------------------
1223 1.1.1.3 mrg ;; Includes contiguous forms of:
1224 1.1.1.3 mrg ;; - LD1B
1225 1.1.1.3 mrg ;; - LD1D
1226 1.1.1.3 mrg ;; - LD1H
1227 1.1.1.3 mrg ;; - LD1W
1228 1.1.1.3 mrg ;; - LD2B
1229 1.1.1.3 mrg ;; - LD2D
1230 1.1.1.3 mrg ;; - LD2H
1231 1.1.1.3 mrg ;; - LD2W
1232 1.1.1.3 mrg ;; - LD3B
1233 1.1.1.3 mrg ;; - LD3D
1234 1.1.1.3 mrg ;; - LD3H
1235 1.1.1.3 mrg ;; - LD3W
1236 1.1.1.3 mrg ;; - LD4B
1237 1.1.1.3 mrg ;; - LD4D
1238 1.1.1.3 mrg ;; - LD4H
1239 1.1.1.3 mrg ;; - LD4W
1240 1.1.1.3 mrg ;; -------------------------------------------------------------------------
1241 1.1 mrg
1242 1.1.1.3 mrg ;; Predicated LD1.
1243 1.1.1.3 mrg (define_insn "maskload<mode><vpred>"
1244 1.1.1.3 mrg [(set (match_operand:SVE_ALL 0 "register_operand" "=w")
1245 1.1.1.3 mrg (unspec:SVE_ALL
1246 1.1.1.3 mrg [(match_operand:<VPRED> 2 "register_operand" "Upl")
1247 1.1.1.3 mrg (match_operand:SVE_ALL 1 "memory_operand" "m")]
1248 1.1.1.3 mrg UNSPEC_LD1_SVE))]
1249 1.1 mrg "TARGET_SVE"
1250 1.1.1.3 mrg "ld1<Vesize>\t%0.<Vctype>, %2/z, %1"
1251 1.1 mrg )
1252 1.1 mrg
1253 1.1 mrg ;; Unpredicated LD[234].
1254 1.1 mrg (define_expand "vec_load_lanes<mode><vsingle>"
1255 1.1 mrg [(set (match_operand:SVE_STRUCT 0 "register_operand")
1256 1.1 mrg (unspec:SVE_STRUCT
1257 1.1 mrg [(match_dup 2)
1258 1.1 mrg (match_operand:SVE_STRUCT 1 "memory_operand")]
1259 1.1 mrg UNSPEC_LDN))]
1260 1.1 mrg "TARGET_SVE"
1261 1.1 mrg {
1262 1.1.1.3 mrg operands[2] = aarch64_ptrue_reg (<VPRED>mode);
1263 1.1 mrg }
1264 1.1 mrg )
1265 1.1 mrg
1266 1.1 mrg ;; Predicated LD[234].
1267 1.1 mrg (define_insn "vec_mask_load_lanes<mode><vsingle>"
1268 1.1 mrg [(set (match_operand:SVE_STRUCT 0 "register_operand" "=w")
1269 1.1 mrg (unspec:SVE_STRUCT
1270 1.1 mrg [(match_operand:<VPRED> 2 "register_operand" "Upl")
1271 1.1 mrg (match_operand:SVE_STRUCT 1 "memory_operand" "m")]
1272 1.1 mrg UNSPEC_LDN))]
1273 1.1 mrg "TARGET_SVE"
1274 1.1 mrg "ld<vector_count><Vesize>\t%0, %2/z, %1"
1275 1.1 mrg )
1276 1.1 mrg
1277 1.1.1.3 mrg ;; -------------------------------------------------------------------------
1278 1.1.1.3 mrg ;; ---- Extending contiguous loads
1279 1.1.1.3 mrg ;; -------------------------------------------------------------------------
1280 1.1.1.3 mrg ;; Includes contiguous forms of:
1281 1.1.1.3 mrg ;; LD1B
1282 1.1.1.3 mrg ;; LD1H
1283 1.1.1.3 mrg ;; LD1SB
1284 1.1.1.3 mrg ;; LD1SH
1285 1.1.1.3 mrg ;; LD1SW
1286 1.1.1.3 mrg ;; LD1W
1287 1.1.1.3 mrg ;; -------------------------------------------------------------------------
1288 1.1.1.3 mrg
1289 1.1.1.3 mrg ;; Predicated load and extend, with 8 elements per 128-bit block.
1290 1.1.1.5 mrg (define_insn_and_rewrite "@aarch64_load<SVE_PRED_LOAD:pred_load>_<ANY_EXTEND:optab><SVE_HSDI:mode><SVE_PARTIAL_I:mode>"
1291 1.1.1.3 mrg [(set (match_operand:SVE_HSDI 0 "register_operand" "=w")
1292 1.1.1.3 mrg (unspec:SVE_HSDI
1293 1.1.1.3 mrg [(match_operand:<SVE_HSDI:VPRED> 3 "general_operand" "UplDnm")
1294 1.1.1.3 mrg (ANY_EXTEND:SVE_HSDI
1295 1.1.1.3 mrg (unspec:SVE_PARTIAL_I
1296 1.1.1.3 mrg [(match_operand:<SVE_PARTIAL_I:VPRED> 2 "register_operand" "Upl")
1297 1.1.1.3 mrg (match_operand:SVE_PARTIAL_I 1 "memory_operand" "m")]
1298 1.1.1.5 mrg SVE_PRED_LOAD))]
1299 1.1.1.3 mrg UNSPEC_PRED_X))]
1300 1.1.1.3 mrg "TARGET_SVE && (~<SVE_HSDI:narrower_mask> & <SVE_PARTIAL_I:self_mask>) == 0"
1301 1.1.1.3 mrg "ld1<ANY_EXTEND:s><SVE_PARTIAL_I:Vesize>\t%0.<SVE_HSDI:Vctype>, %2/z, %1"
1302 1.1.1.3 mrg "&& !CONSTANT_P (operands[3])"
1303 1.1.1.3 mrg {
1304 1.1.1.3 mrg operands[3] = CONSTM1_RTX (<SVE_HSDI:VPRED>mode);
1305 1.1 mrg }
1306 1.1 mrg )
1307 1.1 mrg
1308 1.1.1.3 mrg ;; -------------------------------------------------------------------------
1309 1.1.1.3 mrg ;; ---- First-faulting contiguous loads
1310 1.1.1.3 mrg ;; -------------------------------------------------------------------------
1311 1.1.1.3 mrg ;; Includes contiguous forms of:
1312 1.1.1.3 mrg ;; - LDFF1B
1313 1.1.1.3 mrg ;; - LDFF1D
1314 1.1.1.3 mrg ;; - LDFF1H
1315 1.1.1.3 mrg ;; - LDFF1W
1316 1.1.1.3 mrg ;; - LDNF1B
1317 1.1.1.3 mrg ;; - LDNF1D
1318 1.1.1.3 mrg ;; - LDNF1H
1319 1.1.1.3 mrg ;; - LDNF1W
1320 1.1.1.3 mrg ;; -------------------------------------------------------------------------
1321 1.1.1.3 mrg
1322 1.1.1.3 mrg ;; Contiguous non-extending first-faulting or non-faulting loads.
1323 1.1.1.3 mrg (define_insn "@aarch64_ld<fn>f1<mode>"
1324 1.1.1.3 mrg [(set (match_operand:SVE_FULL 0 "register_operand" "=w")
1325 1.1.1.3 mrg (unspec:SVE_FULL
1326 1.1 mrg [(match_operand:<VPRED> 2 "register_operand" "Upl")
1327 1.1.1.3 mrg (match_operand:SVE_FULL 1 "aarch64_sve_ld<fn>f1_operand" "Ut<fn>")
1328 1.1.1.3 mrg (reg:VNx16BI FFRT_REGNUM)]
1329 1.1.1.3 mrg SVE_LDFF1_LDNF1))]
1330 1.1.1.3 mrg "TARGET_SVE"
1331 1.1.1.3 mrg "ld<fn>f1<Vesize>\t%0.<Vetype>, %2/z, %1"
1332 1.1.1.3 mrg )
1333 1.1.1.3 mrg
1334 1.1.1.3 mrg ;; -------------------------------------------------------------------------
1335 1.1.1.3 mrg ;; ---- First-faulting extending contiguous loads
1336 1.1.1.3 mrg ;; -------------------------------------------------------------------------
1337 1.1.1.3 mrg ;; Includes contiguous forms of:
1338 1.1.1.3 mrg ;; - LDFF1B
1339 1.1.1.3 mrg ;; - LDFF1H
1340 1.1.1.3 mrg ;; - LDFF1SB
1341 1.1.1.3 mrg ;; - LDFF1SH
1342 1.1.1.3 mrg ;; - LDFF1SW
1343 1.1.1.3 mrg ;; - LDFF1W
1344 1.1.1.3 mrg ;; - LDNF1B
1345 1.1.1.3 mrg ;; - LDNF1H
1346 1.1.1.3 mrg ;; - LDNF1SB
1347 1.1.1.3 mrg ;; - LDNF1SH
1348 1.1.1.3 mrg ;; - LDNF1SW
1349 1.1.1.3 mrg ;; - LDNF1W
1350 1.1.1.3 mrg ;; -------------------------------------------------------------------------
1351 1.1 mrg
1352 1.1.1.3 mrg ;; Predicated first-faulting or non-faulting load and extend.
1353 1.1.1.3 mrg (define_insn_and_rewrite "@aarch64_ld<fn>f1_<ANY_EXTEND:optab><SVE_HSDI:mode><SVE_PARTIAL_I:mode>"
1354 1.1.1.3 mrg [(set (match_operand:SVE_HSDI 0 "register_operand" "=w")
1355 1.1.1.3 mrg (unspec:SVE_HSDI
1356 1.1.1.3 mrg [(match_operand:<SVE_HSDI:VPRED> 3 "general_operand" "UplDnm")
1357 1.1.1.3 mrg (ANY_EXTEND:SVE_HSDI
1358 1.1.1.3 mrg (unspec:SVE_PARTIAL_I
1359 1.1.1.3 mrg [(match_operand:<SVE_PARTIAL_I:VPRED> 2 "register_operand" "Upl")
1360 1.1.1.3 mrg (match_operand:SVE_PARTIAL_I 1 "aarch64_sve_ld<fn>f1_operand" "Ut<fn>")
1361 1.1.1.3 mrg (reg:VNx16BI FFRT_REGNUM)]
1362 1.1.1.3 mrg SVE_LDFF1_LDNF1))]
1363 1.1.1.3 mrg UNSPEC_PRED_X))]
1364 1.1.1.3 mrg "TARGET_SVE && (~<SVE_HSDI:narrower_mask> & <SVE_PARTIAL_I:self_mask>) == 0"
1365 1.1.1.3 mrg "ld<fn>f1<ANY_EXTEND:s><SVE_PARTIAL_I:Vesize>\t%0.<SVE_HSDI:Vctype>, %2/z, %1"
1366 1.1.1.3 mrg "&& !CONSTANT_P (operands[3])"
1367 1.1.1.3 mrg {
1368 1.1.1.3 mrg operands[3] = CONSTM1_RTX (<SVE_HSDI:VPRED>mode);
1369 1.1 mrg }
1370 1.1 mrg )
1371 1.1 mrg
1372 1.1.1.3 mrg ;; -------------------------------------------------------------------------
1373 1.1.1.3 mrg ;; ---- Non-temporal contiguous loads
1374 1.1.1.3 mrg ;; -------------------------------------------------------------------------
1375 1.1.1.3 mrg ;; Includes:
1376 1.1.1.3 mrg ;; - LDNT1B
1377 1.1.1.3 mrg ;; - LDNT1D
1378 1.1.1.3 mrg ;; - LDNT1H
1379 1.1.1.3 mrg ;; - LDNT1W
1380 1.1.1.3 mrg ;; -------------------------------------------------------------------------
1381 1.1.1.3 mrg
1382 1.1.1.3 mrg ;; Predicated contiguous non-temporal load.
1383 1.1.1.3 mrg (define_insn "@aarch64_ldnt1<mode>"
1384 1.1.1.3 mrg [(set (match_operand:SVE_FULL 0 "register_operand" "=w")
1385 1.1.1.3 mrg (unspec:SVE_FULL
1386 1.1.1.3 mrg [(match_operand:<VPRED> 2 "register_operand" "Upl")
1387 1.1.1.3 mrg (match_operand:SVE_FULL 1 "memory_operand" "m")]
1388 1.1.1.3 mrg UNSPEC_LDNT1_SVE))]
1389 1.1 mrg "TARGET_SVE"
1390 1.1.1.3 mrg "ldnt1<Vesize>\t%0.<Vetype>, %2/z, %1"
1391 1.1 mrg )
1392 1.1 mrg
1393 1.1.1.3 mrg ;; -------------------------------------------------------------------------
1394 1.1.1.3 mrg ;; ---- Normal gather loads
1395 1.1.1.3 mrg ;; -------------------------------------------------------------------------
1396 1.1.1.3 mrg ;; Includes gather forms of:
1397 1.1.1.3 mrg ;; - LD1D
1398 1.1.1.3 mrg ;; - LD1W
1399 1.1.1.3 mrg ;; -------------------------------------------------------------------------
1400 1.1 mrg
1401 1.1.1.3 mrg ;; Unpredicated gather loads.
1402 1.1.1.3 mrg (define_expand "gather_load<mode><v_int_container>"
1403 1.1.1.3 mrg [(set (match_operand:SVE_24 0 "register_operand")
1404 1.1.1.3 mrg (unspec:SVE_24
1405 1.1.1.3 mrg [(match_dup 5)
1406 1.1.1.3 mrg (match_operand:DI 1 "aarch64_sve_gather_offset_<Vesize>")
1407 1.1.1.3 mrg (match_operand:<V_INT_CONTAINER> 2 "register_operand")
1408 1.1.1.3 mrg (match_operand:DI 3 "const_int_operand")
1409 1.1.1.3 mrg (match_operand:DI 4 "aarch64_gather_scale_operand_<Vesize>")
1410 1.1.1.3 mrg (mem:BLK (scratch))]
1411 1.1.1.3 mrg UNSPEC_LD1_GATHER))]
1412 1.1 mrg "TARGET_SVE"
1413 1.1 mrg {
1414 1.1.1.3 mrg operands[5] = aarch64_ptrue_reg (<VPRED>mode);
1415 1.1 mrg }
1416 1.1 mrg )
1417 1.1 mrg
1418 1.1.1.3 mrg ;; Predicated gather loads for 32-bit elements. Operand 3 is true for
1419 1.1.1.3 mrg ;; unsigned extension and false for signed extension.
1420 1.1.1.3 mrg (define_insn "mask_gather_load<mode><v_int_container>"
1421 1.1.1.3 mrg [(set (match_operand:SVE_4 0 "register_operand" "=w, w, w, w, w, w")
1422 1.1.1.3 mrg (unspec:SVE_4
1423 1.1.1.3 mrg [(match_operand:VNx4BI 5 "register_operand" "Upl, Upl, Upl, Upl, Upl, Upl")
1424 1.1.1.3 mrg (match_operand:DI 1 "aarch64_sve_gather_offset_<Vesize>" "Z, vgw, rk, rk, rk, rk")
1425 1.1.1.3 mrg (match_operand:VNx4SI 2 "register_operand" "w, w, w, w, w, w")
1426 1.1.1.3 mrg (match_operand:DI 3 "const_int_operand" "Ui1, Ui1, Z, Ui1, Z, Ui1")
1427 1.1.1.3 mrg (match_operand:DI 4 "aarch64_gather_scale_operand_<Vesize>" "Ui1, Ui1, Ui1, Ui1, i, i")
1428 1.1.1.3 mrg (mem:BLK (scratch))]
1429 1.1.1.3 mrg UNSPEC_LD1_GATHER))]
1430 1.1 mrg "TARGET_SVE"
1431 1.1 mrg "@
1432 1.1.1.3 mrg ld1<Vesize>\t%0.s, %5/z, [%2.s]
1433 1.1.1.3 mrg ld1<Vesize>\t%0.s, %5/z, [%2.s, #%1]
1434 1.1.1.3 mrg ld1<Vesize>\t%0.s, %5/z, [%1, %2.s, sxtw]
1435 1.1.1.3 mrg ld1<Vesize>\t%0.s, %5/z, [%1, %2.s, uxtw]
1436 1.1.1.3 mrg ld1<Vesize>\t%0.s, %5/z, [%1, %2.s, sxtw %p4]
1437 1.1.1.3 mrg ld1<Vesize>\t%0.s, %5/z, [%1, %2.s, uxtw %p4]"
1438 1.1 mrg )
1439 1.1 mrg
1440 1.1.1.3 mrg ;; Predicated gather loads for 64-bit elements. The value of operand 3
1441 1.1.1.3 mrg ;; doesn't matter in this case.
1442 1.1.1.3 mrg (define_insn "mask_gather_load<mode><v_int_container>"
1443 1.1.1.3 mrg [(set (match_operand:SVE_2 0 "register_operand" "=w, w, w, w")
1444 1.1.1.3 mrg (unspec:SVE_2
1445 1.1.1.3 mrg [(match_operand:VNx2BI 5 "register_operand" "Upl, Upl, Upl, Upl")
1446 1.1.1.3 mrg (match_operand:DI 1 "aarch64_sve_gather_offset_<Vesize>" "Z, vgd, rk, rk")
1447 1.1.1.3 mrg (match_operand:VNx2DI 2 "register_operand" "w, w, w, w")
1448 1.1.1.3 mrg (match_operand:DI 3 "const_int_operand")
1449 1.1.1.3 mrg (match_operand:DI 4 "aarch64_gather_scale_operand_<Vesize>" "Ui1, Ui1, Ui1, i")
1450 1.1.1.3 mrg (mem:BLK (scratch))]
1451 1.1.1.3 mrg UNSPEC_LD1_GATHER))]
1452 1.1 mrg "TARGET_SVE"
1453 1.1 mrg "@
1454 1.1.1.3 mrg ld1<Vesize>\t%0.d, %5/z, [%2.d]
1455 1.1.1.3 mrg ld1<Vesize>\t%0.d, %5/z, [%2.d, #%1]
1456 1.1.1.3 mrg ld1<Vesize>\t%0.d, %5/z, [%1, %2.d]
1457 1.1.1.3 mrg ld1<Vesize>\t%0.d, %5/z, [%1, %2.d, lsl %p4]"
1458 1.1.1.3 mrg )
1459 1.1.1.3 mrg
1460 1.1.1.3 mrg ;; Likewise, but with the offset being extended from 32 bits.
1461 1.1.1.3 mrg (define_insn_and_rewrite "*mask_gather_load<mode><v_int_container>_<su>xtw_unpacked"
1462 1.1.1.3 mrg [(set (match_operand:SVE_2 0 "register_operand" "=w, w")
1463 1.1.1.3 mrg (unspec:SVE_2
1464 1.1.1.3 mrg [(match_operand:VNx2BI 5 "register_operand" "Upl, Upl")
1465 1.1.1.3 mrg (match_operand:DI 1 "register_operand" "rk, rk")
1466 1.1.1.3 mrg (unspec:VNx2DI
1467 1.1.1.3 mrg [(match_operand 6)
1468 1.1.1.3 mrg (ANY_EXTEND:VNx2DI
1469 1.1.1.3 mrg (match_operand:VNx2SI 2 "register_operand" "w, w"))]
1470 1.1.1.3 mrg UNSPEC_PRED_X)
1471 1.1.1.3 mrg (match_operand:DI 3 "const_int_operand")
1472 1.1.1.3 mrg (match_operand:DI 4 "aarch64_gather_scale_operand_<Vesize>" "Ui1, i")
1473 1.1.1.3 mrg (mem:BLK (scratch))]
1474 1.1.1.3 mrg UNSPEC_LD1_GATHER))]
1475 1.1 mrg "TARGET_SVE"
1476 1.1.1.3 mrg "@
1477 1.1.1.3 mrg ld1<Vesize>\t%0.d, %5/z, [%1, %2.d, <su>xtw]
1478 1.1.1.3 mrg ld1<Vesize>\t%0.d, %5/z, [%1, %2.d, <su>xtw %p4]"
1479 1.1.1.3 mrg "&& !CONSTANT_P (operands[6])"
1480 1.1.1.3 mrg {
1481 1.1.1.3 mrg operands[6] = CONSTM1_RTX (VNx2BImode);
1482 1.1 mrg }
1483 1.1 mrg )
1484 1.1 mrg
1485 1.1.1.3 mrg ;; Likewise, but with the offset being truncated to 32 bits and then
1486 1.1.1.3 mrg ;; sign-extended.
1487 1.1.1.3 mrg (define_insn_and_rewrite "*mask_gather_load<mode><v_int_container>_sxtw"
1488 1.1.1.3 mrg [(set (match_operand:SVE_2 0 "register_operand" "=w, w")
1489 1.1.1.3 mrg (unspec:SVE_2
1490 1.1.1.3 mrg [(match_operand:VNx2BI 5 "register_operand" "Upl, Upl")
1491 1.1.1.3 mrg (match_operand:DI 1 "register_operand" "rk, rk")
1492 1.1.1.3 mrg (unspec:VNx2DI
1493 1.1.1.3 mrg [(match_operand 6)
1494 1.1.1.3 mrg (sign_extend:VNx2DI
1495 1.1.1.3 mrg (truncate:VNx2SI
1496 1.1.1.3 mrg (match_operand:VNx2DI 2 "register_operand" "w, w")))]
1497 1.1.1.3 mrg UNSPEC_PRED_X)
1498 1.1.1.3 mrg (match_operand:DI 3 "const_int_operand")
1499 1.1.1.3 mrg (match_operand:DI 4 "aarch64_gather_scale_operand_<Vesize>" "Ui1, i")
1500 1.1.1.3 mrg (mem:BLK (scratch))]
1501 1.1.1.3 mrg UNSPEC_LD1_GATHER))]
1502 1.1 mrg "TARGET_SVE"
1503 1.1 mrg "@
1504 1.1.1.3 mrg ld1<Vesize>\t%0.d, %5/z, [%1, %2.d, sxtw]
1505 1.1.1.3 mrg ld1<Vesize>\t%0.d, %5/z, [%1, %2.d, sxtw %p4]"
1506 1.1.1.3 mrg "&& !CONSTANT_P (operands[6])"
1507 1.1.1.3 mrg {
1508 1.1.1.3 mrg operands[6] = CONSTM1_RTX (VNx2BImode);
1509 1.1.1.3 mrg }
1510 1.1 mrg )
1511 1.1 mrg
1512 1.1.1.3 mrg ;; Likewise, but with the offset being truncated to 32 bits and then
1513 1.1.1.3 mrg ;; zero-extended.
1514 1.1.1.3 mrg (define_insn "*mask_gather_load<mode><v_int_container>_uxtw"
1515 1.1.1.3 mrg [(set (match_operand:SVE_2 0 "register_operand" "=w, w")
1516 1.1.1.3 mrg (unspec:SVE_2
1517 1.1.1.3 mrg [(match_operand:VNx2BI 5 "register_operand" "Upl, Upl")
1518 1.1.1.3 mrg (match_operand:DI 1 "register_operand" "rk, rk")
1519 1.1.1.3 mrg (and:VNx2DI
1520 1.1.1.3 mrg (match_operand:VNx2DI 2 "register_operand" "w, w")
1521 1.1.1.3 mrg (match_operand:VNx2DI 6 "aarch64_sve_uxtw_immediate"))
1522 1.1.1.3 mrg (match_operand:DI 3 "const_int_operand")
1523 1.1.1.3 mrg (match_operand:DI 4 "aarch64_gather_scale_operand_<Vesize>" "Ui1, i")
1524 1.1.1.3 mrg (mem:BLK (scratch))]
1525 1.1.1.3 mrg UNSPEC_LD1_GATHER))]
1526 1.1 mrg "TARGET_SVE"
1527 1.1 mrg "@
1528 1.1.1.3 mrg ld1<Vesize>\t%0.d, %5/z, [%1, %2.d, uxtw]
1529 1.1.1.3 mrg ld1<Vesize>\t%0.d, %5/z, [%1, %2.d, uxtw %p4]"
1530 1.1 mrg )
1531 1.1 mrg
1532 1.1.1.3 mrg ;; -------------------------------------------------------------------------
1533 1.1.1.3 mrg ;; ---- Extending gather loads
1534 1.1.1.3 mrg ;; -------------------------------------------------------------------------
1535 1.1.1.3 mrg ;; Includes gather forms of:
1536 1.1.1.3 mrg ;; - LD1B
1537 1.1.1.3 mrg ;; - LD1H
1538 1.1.1.3 mrg ;; - LD1SB
1539 1.1.1.3 mrg ;; - LD1SH
1540 1.1.1.3 mrg ;; - LD1SW
1541 1.1.1.3 mrg ;; - LD1W
1542 1.1.1.3 mrg ;; -------------------------------------------------------------------------
1543 1.1.1.3 mrg
1544 1.1.1.3 mrg ;; Predicated extending gather loads for 32-bit elements. Operand 3 is
1545 1.1.1.3 mrg ;; true for unsigned extension and false for signed extension.
1546 1.1.1.3 mrg (define_insn_and_rewrite "@aarch64_gather_load_<ANY_EXTEND:optab><SVE_4HSI:mode><SVE_4BHI:mode>"
1547 1.1.1.3 mrg [(set (match_operand:SVE_4HSI 0 "register_operand" "=w, w, w, w, w, w")
1548 1.1.1.3 mrg (unspec:SVE_4HSI
1549 1.1.1.3 mrg [(match_operand:VNx4BI 6 "general_operand" "UplDnm, UplDnm, UplDnm, UplDnm, UplDnm, UplDnm")
1550 1.1.1.3 mrg (ANY_EXTEND:SVE_4HSI
1551 1.1.1.3 mrg (unspec:SVE_4BHI
1552 1.1.1.3 mrg [(match_operand:VNx4BI 5 "register_operand" "Upl, Upl, Upl, Upl, Upl, Upl")
1553 1.1.1.3 mrg (match_operand:DI 1 "aarch64_sve_gather_offset_<SVE_4BHI:Vesize>" "Z, vg<SVE_4BHI:Vesize>, rk, rk, rk, rk")
1554 1.1.1.3 mrg (match_operand:VNx4SI 2 "register_operand" "w, w, w, w, w, w")
1555 1.1.1.3 mrg (match_operand:DI 3 "const_int_operand" "Ui1, Ui1, Z, Ui1, Z, Ui1")
1556 1.1.1.3 mrg (match_operand:DI 4 "aarch64_gather_scale_operand_<SVE_4BHI:Vesize>" "Ui1, Ui1, Ui1, Ui1, i, i")
1557 1.1.1.3 mrg (mem:BLK (scratch))]
1558 1.1.1.3 mrg UNSPEC_LD1_GATHER))]
1559 1.1.1.3 mrg UNSPEC_PRED_X))]
1560 1.1.1.3 mrg "TARGET_SVE && (~<SVE_4HSI:narrower_mask> & <SVE_4BHI:self_mask>) == 0"
1561 1.1.1.3 mrg "@
1562 1.1.1.3 mrg ld1<ANY_EXTEND:s><SVE_4BHI:Vesize>\t%0.s, %5/z, [%2.s]
1563 1.1.1.3 mrg ld1<ANY_EXTEND:s><SVE_4BHI:Vesize>\t%0.s, %5/z, [%2.s, #%1]
1564 1.1.1.3 mrg ld1<ANY_EXTEND:s><SVE_4BHI:Vesize>\t%0.s, %5/z, [%1, %2.s, sxtw]
1565 1.1.1.3 mrg ld1<ANY_EXTEND:s><SVE_4BHI:Vesize>\t%0.s, %5/z, [%1, %2.s, uxtw]
1566 1.1.1.3 mrg ld1<ANY_EXTEND:s><SVE_4BHI:Vesize>\t%0.s, %5/z, [%1, %2.s, sxtw %p4]
1567 1.1.1.3 mrg ld1<ANY_EXTEND:s><SVE_4BHI:Vesize>\t%0.s, %5/z, [%1, %2.s, uxtw %p4]"
1568 1.1.1.3 mrg "&& !CONSTANT_P (operands[6])"
1569 1.1.1.3 mrg {
1570 1.1.1.3 mrg operands[6] = CONSTM1_RTX (VNx4BImode);
1571 1.1.1.3 mrg }
1572 1.1.1.3 mrg )
1573 1.1.1.3 mrg
1574 1.1.1.3 mrg ;; Predicated extending gather loads for 64-bit elements. The value of
1575 1.1.1.3 mrg ;; operand 3 doesn't matter in this case.
1576 1.1.1.3 mrg (define_insn_and_rewrite "@aarch64_gather_load_<ANY_EXTEND:optab><SVE_2HSDI:mode><SVE_2BHSI:mode>"
1577 1.1.1.3 mrg [(set (match_operand:SVE_2HSDI 0 "register_operand" "=w, w, w, w")
1578 1.1.1.3 mrg (unspec:SVE_2HSDI
1579 1.1.1.3 mrg [(match_operand:VNx2BI 6 "general_operand" "UplDnm, UplDnm, UplDnm, UplDnm")
1580 1.1.1.3 mrg (ANY_EXTEND:SVE_2HSDI
1581 1.1.1.3 mrg (unspec:SVE_2BHSI
1582 1.1.1.3 mrg [(match_operand:VNx2BI 5 "register_operand" "Upl, Upl, Upl, Upl")
1583 1.1.1.3 mrg (match_operand:DI 1 "aarch64_sve_gather_offset_<SVE_2BHSI:Vesize>" "Z, vg<SVE_2BHSI:Vesize>, rk, rk")
1584 1.1.1.3 mrg (match_operand:VNx2DI 2 "register_operand" "w, w, w, w")
1585 1.1.1.3 mrg (match_operand:DI 3 "const_int_operand")
1586 1.1.1.3 mrg (match_operand:DI 4 "aarch64_gather_scale_operand_<SVE_2BHSI:Vesize>" "Ui1, Ui1, Ui1, i")
1587 1.1.1.3 mrg (mem:BLK (scratch))]
1588 1.1.1.3 mrg UNSPEC_LD1_GATHER))]
1589 1.1.1.3 mrg UNSPEC_PRED_X))]
1590 1.1.1.3 mrg "TARGET_SVE && (~<SVE_2HSDI:narrower_mask> & <SVE_2BHSI:self_mask>) == 0"
1591 1.1.1.3 mrg "@
1592 1.1.1.3 mrg ld1<ANY_EXTEND:s><SVE_2BHSI:Vesize>\t%0.d, %5/z, [%2.d]
1593 1.1.1.3 mrg ld1<ANY_EXTEND:s><SVE_2BHSI:Vesize>\t%0.d, %5/z, [%2.d, #%1]
1594 1.1.1.3 mrg ld1<ANY_EXTEND:s><SVE_2BHSI:Vesize>\t%0.d, %5/z, [%1, %2.d]
1595 1.1.1.3 mrg ld1<ANY_EXTEND:s><SVE_2BHSI:Vesize>\t%0.d, %5/z, [%1, %2.d, lsl %p4]"
1596 1.1.1.3 mrg "&& !CONSTANT_P (operands[6])"
1597 1.1.1.3 mrg {
1598 1.1.1.3 mrg operands[6] = CONSTM1_RTX (VNx2BImode);
1599 1.1.1.3 mrg }
1600 1.1.1.3 mrg )
1601 1.1.1.3 mrg
1602 1.1.1.3 mrg ;; Likewise, but with the offset being extended from 32 bits.
1603 1.1.1.3 mrg (define_insn_and_rewrite "*aarch64_gather_load_<ANY_EXTEND:optab><SVE_2HSDI:mode><SVE_2BHSI:mode>_<ANY_EXTEND2:su>xtw_unpacked"
1604 1.1.1.3 mrg [(set (match_operand:SVE_2HSDI 0 "register_operand" "=w, w")
1605 1.1.1.3 mrg (unspec:SVE_2HSDI
1606 1.1.1.3 mrg [(match_operand 6)
1607 1.1.1.3 mrg (ANY_EXTEND:SVE_2HSDI
1608 1.1.1.3 mrg (unspec:SVE_2BHSI
1609 1.1.1.3 mrg [(match_operand:VNx2BI 5 "register_operand" "Upl, Upl")
1610 1.1.1.3 mrg (match_operand:DI 1 "aarch64_reg_or_zero" "rk, rk")
1611 1.1.1.3 mrg (unspec:VNx2DI
1612 1.1.1.3 mrg [(match_operand 7)
1613 1.1.1.3 mrg (ANY_EXTEND2:VNx2DI
1614 1.1.1.3 mrg (match_operand:VNx2SI 2 "register_operand" "w, w"))]
1615 1.1.1.3 mrg UNSPEC_PRED_X)
1616 1.1.1.3 mrg (match_operand:DI 3 "const_int_operand")
1617 1.1.1.3 mrg (match_operand:DI 4 "aarch64_gather_scale_operand_<SVE_2BHSI:Vesize>" "Ui1, i")
1618 1.1.1.3 mrg (mem:BLK (scratch))]
1619 1.1.1.3 mrg UNSPEC_LD1_GATHER))]
1620 1.1.1.3 mrg UNSPEC_PRED_X))]
1621 1.1.1.3 mrg "TARGET_SVE && (~<SVE_2HSDI:narrower_mask> & <SVE_2BHSI:self_mask>) == 0"
1622 1.1.1.3 mrg "@
1623 1.1.1.3 mrg ld1<ANY_EXTEND:s><SVE_2BHSI:Vesize>\t%0.d, %5/z, [%1, %2.d, <ANY_EXTEND2:su>xtw]
1624 1.1.1.3 mrg ld1<ANY_EXTEND:s><SVE_2BHSI:Vesize>\t%0.d, %5/z, [%1, %2.d, <ANY_EXTEND2:su>xtw %p4]"
1625 1.1.1.3 mrg "&& (!CONSTANT_P (operands[6]) || !CONSTANT_P (operands[7]))"
1626 1.1.1.3 mrg {
1627 1.1.1.3 mrg operands[6] = CONSTM1_RTX (VNx2BImode);
1628 1.1.1.3 mrg operands[7] = CONSTM1_RTX (VNx2BImode);
1629 1.1.1.3 mrg }
1630 1.1.1.3 mrg )
1631 1.1.1.3 mrg
1632 1.1.1.3 mrg ;; Likewise, but with the offset being truncated to 32 bits and then
1633 1.1.1.3 mrg ;; sign-extended.
1634 1.1.1.3 mrg (define_insn_and_rewrite "*aarch64_gather_load_<ANY_EXTEND:optab><SVE_2HSDI:mode><SVE_2BHSI:mode>_sxtw"
1635 1.1.1.3 mrg [(set (match_operand:SVE_2HSDI 0 "register_operand" "=w, w")
1636 1.1.1.3 mrg (unspec:SVE_2HSDI
1637 1.1.1.3 mrg [(match_operand 6)
1638 1.1.1.3 mrg (ANY_EXTEND:SVE_2HSDI
1639 1.1.1.3 mrg (unspec:SVE_2BHSI
1640 1.1.1.3 mrg [(match_operand:VNx2BI 5 "register_operand" "Upl, Upl")
1641 1.1.1.3 mrg (match_operand:DI 1 "aarch64_reg_or_zero" "rk, rk")
1642 1.1.1.3 mrg (unspec:VNx2DI
1643 1.1.1.3 mrg [(match_operand 7)
1644 1.1.1.3 mrg (sign_extend:VNx2DI
1645 1.1.1.3 mrg (truncate:VNx2SI
1646 1.1.1.3 mrg (match_operand:VNx2DI 2 "register_operand" "w, w")))]
1647 1.1.1.3 mrg UNSPEC_PRED_X)
1648 1.1.1.3 mrg (match_operand:DI 3 "const_int_operand")
1649 1.1.1.3 mrg (match_operand:DI 4 "aarch64_gather_scale_operand_<SVE_2BHSI:Vesize>" "Ui1, i")
1650 1.1.1.3 mrg (mem:BLK (scratch))]
1651 1.1.1.3 mrg UNSPEC_LD1_GATHER))]
1652 1.1.1.3 mrg UNSPEC_PRED_X))]
1653 1.1.1.3 mrg "TARGET_SVE && (~<SVE_2HSDI:narrower_mask> & <SVE_2BHSI:self_mask>) == 0"
1654 1.1.1.3 mrg "@
1655 1.1.1.3 mrg ld1<ANY_EXTEND:s><SVE_2BHSI:Vesize>\t%0.d, %5/z, [%1, %2.d, sxtw]
1656 1.1.1.3 mrg ld1<ANY_EXTEND:s><SVE_2BHSI:Vesize>\t%0.d, %5/z, [%1, %2.d, sxtw %p4]"
1657 1.1.1.3 mrg "&& (!CONSTANT_P (operands[6]) || !CONSTANT_P (operands[7]))"
1658 1.1.1.3 mrg {
1659 1.1.1.3 mrg operands[6] = CONSTM1_RTX (VNx2BImode);
1660 1.1.1.3 mrg operands[7] = CONSTM1_RTX (VNx2BImode);
1661 1.1.1.3 mrg }
1662 1.1.1.3 mrg )
1663 1.1.1.3 mrg
1664 1.1.1.3 mrg ;; Likewise, but with the offset being truncated to 32 bits and then
1665 1.1.1.3 mrg ;; zero-extended.
1666 1.1.1.3 mrg (define_insn_and_rewrite "*aarch64_gather_load_<ANY_EXTEND:optab><SVE_2HSDI:mode><SVE_2BHSI:mode>_uxtw"
1667 1.1.1.3 mrg [(set (match_operand:SVE_2HSDI 0 "register_operand" "=w, w")
1668 1.1.1.3 mrg (unspec:SVE_2HSDI
1669 1.1.1.3 mrg [(match_operand 7)
1670 1.1.1.3 mrg (ANY_EXTEND:SVE_2HSDI
1671 1.1.1.3 mrg (unspec:SVE_2BHSI
1672 1.1.1.3 mrg [(match_operand:VNx2BI 5 "register_operand" "Upl, Upl")
1673 1.1.1.3 mrg (match_operand:DI 1 "aarch64_reg_or_zero" "rk, rk")
1674 1.1.1.3 mrg (and:VNx2DI
1675 1.1.1.3 mrg (match_operand:VNx2DI 2 "register_operand" "w, w")
1676 1.1.1.3 mrg (match_operand:VNx2DI 6 "aarch64_sve_uxtw_immediate"))
1677 1.1.1.3 mrg (match_operand:DI 3 "const_int_operand")
1678 1.1.1.3 mrg (match_operand:DI 4 "aarch64_gather_scale_operand_<SVE_2BHSI:Vesize>" "Ui1, i")
1679 1.1.1.3 mrg (mem:BLK (scratch))]
1680 1.1.1.3 mrg UNSPEC_LD1_GATHER))]
1681 1.1.1.3 mrg UNSPEC_PRED_X))]
1682 1.1.1.3 mrg "TARGET_SVE && (~<SVE_2HSDI:narrower_mask> & <SVE_2BHSI:self_mask>) == 0"
1683 1.1.1.3 mrg "@
1684 1.1.1.3 mrg ld1<ANY_EXTEND:s><SVE_2BHSI:Vesize>\t%0.d, %5/z, [%1, %2.d, uxtw]
1685 1.1.1.3 mrg ld1<ANY_EXTEND:s><SVE_2BHSI:Vesize>\t%0.d, %5/z, [%1, %2.d, uxtw %p4]"
1686 1.1.1.3 mrg "&& !CONSTANT_P (operands[7])"
1687 1.1.1.3 mrg {
1688 1.1.1.3 mrg operands[7] = CONSTM1_RTX (VNx2BImode);
1689 1.1.1.3 mrg }
1690 1.1.1.3 mrg )
1691 1.1.1.3 mrg
1692 1.1.1.3 mrg ;; -------------------------------------------------------------------------
1693 1.1.1.3 mrg ;; ---- First-faulting gather loads
1694 1.1.1.3 mrg ;; -------------------------------------------------------------------------
1695 1.1.1.3 mrg ;; Includes gather forms of:
1696 1.1.1.3 mrg ;; - LDFF1D
1697 1.1.1.3 mrg ;; - LDFF1W
1698 1.1.1.3 mrg ;; -------------------------------------------------------------------------
1699 1.1.1.3 mrg
1700 1.1.1.3 mrg ;; Predicated first-faulting gather loads for 32-bit elements. Operand
1701 1.1.1.3 mrg ;; 3 is true for unsigned extension and false for signed extension.
1702 1.1.1.3 mrg (define_insn "@aarch64_ldff1_gather<mode>"
1703 1.1.1.3 mrg [(set (match_operand:SVE_FULL_S 0 "register_operand" "=w, w, w, w, w, w")
1704 1.1.1.3 mrg (unspec:SVE_FULL_S
1705 1.1.1.3 mrg [(match_operand:VNx4BI 5 "register_operand" "Upl, Upl, Upl, Upl, Upl, Upl")
1706 1.1.1.3 mrg (match_operand:DI 1 "aarch64_sve_gather_offset_w" "Z, vgw, rk, rk, rk, rk")
1707 1.1.1.3 mrg (match_operand:VNx4SI 2 "register_operand" "w, w, w, w, w, w")
1708 1.1.1.3 mrg (match_operand:DI 3 "const_int_operand" "i, i, Z, Ui1, Z, Ui1")
1709 1.1.1.3 mrg (match_operand:DI 4 "aarch64_gather_scale_operand_w" "Ui1, Ui1, Ui1, Ui1, i, i")
1710 1.1.1.3 mrg (mem:BLK (scratch))
1711 1.1.1.3 mrg (reg:VNx16BI FFRT_REGNUM)]
1712 1.1.1.3 mrg UNSPEC_LDFF1_GATHER))]
1713 1.1.1.3 mrg "TARGET_SVE"
1714 1.1.1.3 mrg "@
1715 1.1.1.3 mrg ldff1w\t%0.s, %5/z, [%2.s]
1716 1.1.1.3 mrg ldff1w\t%0.s, %5/z, [%2.s, #%1]
1717 1.1.1.3 mrg ldff1w\t%0.s, %5/z, [%1, %2.s, sxtw]
1718 1.1.1.3 mrg ldff1w\t%0.s, %5/z, [%1, %2.s, uxtw]
1719 1.1.1.3 mrg ldff1w\t%0.s, %5/z, [%1, %2.s, sxtw %p4]
1720 1.1.1.3 mrg ldff1w\t%0.s, %5/z, [%1, %2.s, uxtw %p4]"
1721 1.1.1.3 mrg )
1722 1.1.1.3 mrg
1723 1.1.1.3 mrg ;; Predicated first-faulting gather loads for 64-bit elements. The value
1724 1.1.1.3 mrg ;; of operand 3 doesn't matter in this case.
1725 1.1.1.3 mrg (define_insn "@aarch64_ldff1_gather<mode>"
1726 1.1.1.3 mrg [(set (match_operand:SVE_FULL_D 0 "register_operand" "=w, w, w, w")
1727 1.1.1.3 mrg (unspec:SVE_FULL_D
1728 1.1.1.3 mrg [(match_operand:VNx2BI 5 "register_operand" "Upl, Upl, Upl, Upl")
1729 1.1.1.3 mrg (match_operand:DI 1 "aarch64_sve_gather_offset_d" "Z, vgd, rk, rk")
1730 1.1.1.3 mrg (match_operand:VNx2DI 2 "register_operand" "w, w, w, w")
1731 1.1.1.3 mrg (match_operand:DI 3 "const_int_operand")
1732 1.1.1.3 mrg (match_operand:DI 4 "aarch64_gather_scale_operand_d" "Ui1, Ui1, Ui1, i")
1733 1.1.1.3 mrg (mem:BLK (scratch))
1734 1.1.1.3 mrg (reg:VNx16BI FFRT_REGNUM)]
1735 1.1.1.3 mrg UNSPEC_LDFF1_GATHER))]
1736 1.1.1.3 mrg "TARGET_SVE"
1737 1.1.1.3 mrg "@
1738 1.1.1.3 mrg ldff1d\t%0.d, %5/z, [%2.d]
1739 1.1.1.3 mrg ldff1d\t%0.d, %5/z, [%2.d, #%1]
1740 1.1.1.3 mrg ldff1d\t%0.d, %5/z, [%1, %2.d]
1741 1.1.1.3 mrg ldff1d\t%0.d, %5/z, [%1, %2.d, lsl %p4]"
1742 1.1.1.3 mrg )
1743 1.1.1.3 mrg
1744 1.1.1.3 mrg ;; Likewise, but with the offset being sign-extended from 32 bits.
1745 1.1.1.3 mrg (define_insn_and_rewrite "*aarch64_ldff1_gather<mode>_sxtw"
1746 1.1.1.3 mrg [(set (match_operand:SVE_FULL_D 0 "register_operand" "=w, w")
1747 1.1.1.3 mrg (unspec:SVE_FULL_D
1748 1.1.1.3 mrg [(match_operand:VNx2BI 5 "register_operand" "Upl, Upl")
1749 1.1.1.3 mrg (match_operand:DI 1 "register_operand" "rk, rk")
1750 1.1.1.3 mrg (unspec:VNx2DI
1751 1.1.1.3 mrg [(match_operand 6)
1752 1.1.1.3 mrg (sign_extend:VNx2DI
1753 1.1.1.3 mrg (truncate:VNx2SI
1754 1.1.1.3 mrg (match_operand:VNx2DI 2 "register_operand" "w, w")))]
1755 1.1.1.3 mrg UNSPEC_PRED_X)
1756 1.1.1.3 mrg (match_operand:DI 3 "const_int_operand")
1757 1.1.1.3 mrg (match_operand:DI 4 "aarch64_gather_scale_operand_d" "Ui1, i")
1758 1.1.1.3 mrg (mem:BLK (scratch))
1759 1.1.1.3 mrg (reg:VNx16BI FFRT_REGNUM)]
1760 1.1.1.3 mrg UNSPEC_LDFF1_GATHER))]
1761 1.1 mrg "TARGET_SVE"
1762 1.1 mrg "@
1763 1.1.1.3 mrg ldff1d\t%0.d, %5/z, [%1, %2.d, sxtw]
1764 1.1.1.3 mrg ldff1d\t%0.d, %5/z, [%1, %2.d, sxtw %p4]"
1765 1.1.1.3 mrg "&& !CONSTANT_P (operands[6])"
1766 1.1 mrg {
1767 1.1.1.3 mrg operands[6] = CONSTM1_RTX (VNx2BImode);
1768 1.1 mrg }
1769 1.1 mrg )
1770 1.1 mrg
1771 1.1.1.3 mrg ;; Likewise, but with the offset being zero-extended from 32 bits.
1772 1.1.1.3 mrg (define_insn "*aarch64_ldff1_gather<mode>_uxtw"
1773 1.1.1.3 mrg [(set (match_operand:SVE_FULL_D 0 "register_operand" "=w, w")
1774 1.1.1.3 mrg (unspec:SVE_FULL_D
1775 1.1.1.3 mrg [(match_operand:VNx2BI 5 "register_operand" "Upl, Upl")
1776 1.1.1.3 mrg (match_operand:DI 1 "register_operand" "rk, rk")
1777 1.1.1.3 mrg (and:VNx2DI
1778 1.1.1.3 mrg (match_operand:VNx2DI 2 "register_operand" "w, w")
1779 1.1.1.3 mrg (match_operand:VNx2DI 6 "aarch64_sve_uxtw_immediate"))
1780 1.1.1.3 mrg (match_operand:DI 3 "const_int_operand")
1781 1.1.1.3 mrg (match_operand:DI 4 "aarch64_gather_scale_operand_d" "Ui1, i")
1782 1.1.1.3 mrg (mem:BLK (scratch))
1783 1.1.1.3 mrg (reg:VNx16BI FFRT_REGNUM)]
1784 1.1.1.3 mrg UNSPEC_LDFF1_GATHER))]
1785 1.1.1.3 mrg "TARGET_SVE"
1786 1.1.1.3 mrg "@
1787 1.1.1.3 mrg ldff1d\t%0.d, %5/z, [%1, %2.d, uxtw]
1788 1.1.1.3 mrg ldff1d\t%0.d, %5/z, [%1, %2.d, uxtw %p4]"
1789 1.1.1.3 mrg )
1790 1.1.1.3 mrg
1791 1.1.1.3 mrg ;; -------------------------------------------------------------------------
1792 1.1.1.3 mrg ;; ---- First-faulting extending gather loads
1793 1.1.1.3 mrg ;; -------------------------------------------------------------------------
1794 1.1.1.3 mrg ;; Includes gather forms of:
1795 1.1.1.3 mrg ;; - LDFF1B
1796 1.1.1.3 mrg ;; - LDFF1H
1797 1.1.1.3 mrg ;; - LDFF1SB
1798 1.1.1.3 mrg ;; - LDFF1SH
1799 1.1.1.3 mrg ;; - LDFF1SW
1800 1.1.1.3 mrg ;; - LDFF1W
1801 1.1.1.3 mrg ;; -------------------------------------------------------------------------
1802 1.1.1.3 mrg
1803 1.1.1.3 mrg ;; Predicated extending first-faulting gather loads for 32-bit elements.
1804 1.1.1.3 mrg ;; Operand 3 is true for unsigned extension and false for signed extension.
1805 1.1.1.3 mrg (define_insn_and_rewrite "@aarch64_ldff1_gather_<ANY_EXTEND:optab><VNx4_WIDE:mode><VNx4_NARROW:mode>"
1806 1.1.1.3 mrg [(set (match_operand:VNx4_WIDE 0 "register_operand" "=w, w, w, w, w, w")
1807 1.1.1.3 mrg (unspec:VNx4_WIDE
1808 1.1.1.3 mrg [(match_operand:VNx4BI 6 "general_operand" "UplDnm, UplDnm, UplDnm, UplDnm, UplDnm, UplDnm")
1809 1.1.1.3 mrg (ANY_EXTEND:VNx4_WIDE
1810 1.1.1.3 mrg (unspec:VNx4_NARROW
1811 1.1.1.3 mrg [(match_operand:VNx4BI 5 "register_operand" "Upl, Upl, Upl, Upl, Upl, Upl")
1812 1.1.1.3 mrg (match_operand:DI 1 "aarch64_sve_gather_offset_<VNx4_NARROW:Vesize>" "Z, vg<VNx4_NARROW:Vesize>, rk, rk, rk, rk")
1813 1.1.1.3 mrg (match_operand:VNx4_WIDE 2 "register_operand" "w, w, w, w, w, w")
1814 1.1.1.3 mrg (match_operand:DI 3 "const_int_operand" "i, i, Z, Ui1, Z, Ui1")
1815 1.1.1.3 mrg (match_operand:DI 4 "aarch64_gather_scale_operand_<VNx4_NARROW:Vesize>" "Ui1, Ui1, Ui1, Ui1, i, i")
1816 1.1.1.3 mrg (mem:BLK (scratch))
1817 1.1.1.3 mrg (reg:VNx16BI FFRT_REGNUM)]
1818 1.1.1.3 mrg UNSPEC_LDFF1_GATHER))]
1819 1.1.1.3 mrg UNSPEC_PRED_X))]
1820 1.1.1.3 mrg "TARGET_SVE"
1821 1.1.1.3 mrg "@
1822 1.1.1.3 mrg ldff1<ANY_EXTEND:s><VNx4_NARROW:Vesize>\t%0.s, %5/z, [%2.s]
1823 1.1.1.3 mrg ldff1<ANY_EXTEND:s><VNx4_NARROW:Vesize>\t%0.s, %5/z, [%2.s, #%1]
1824 1.1.1.3 mrg ldff1<ANY_EXTEND:s><VNx4_NARROW:Vesize>\t%0.s, %5/z, [%1, %2.s, sxtw]
1825 1.1.1.3 mrg ldff1<ANY_EXTEND:s><VNx4_NARROW:Vesize>\t%0.s, %5/z, [%1, %2.s, uxtw]
1826 1.1.1.3 mrg ldff1<ANY_EXTEND:s><VNx4_NARROW:Vesize>\t%0.s, %5/z, [%1, %2.s, sxtw %p4]
1827 1.1.1.3 mrg ldff1<ANY_EXTEND:s><VNx4_NARROW:Vesize>\t%0.s, %5/z, [%1, %2.s, uxtw %p4]"
1828 1.1.1.3 mrg "&& !CONSTANT_P (operands[6])"
1829 1.1.1.3 mrg {
1830 1.1.1.3 mrg operands[6] = CONSTM1_RTX (VNx4BImode);
1831 1.1.1.3 mrg }
1832 1.1.1.3 mrg )
1833 1.1.1.3 mrg
1834 1.1.1.3 mrg ;; Predicated extending first-faulting gather loads for 64-bit elements.
1835 1.1.1.3 mrg ;; The value of operand 3 doesn't matter in this case.
1836 1.1.1.3 mrg (define_insn_and_rewrite "@aarch64_ldff1_gather_<ANY_EXTEND:optab><VNx2_WIDE:mode><VNx2_NARROW:mode>"
1837 1.1.1.3 mrg [(set (match_operand:VNx2_WIDE 0 "register_operand" "=w, w, w, w")
1838 1.1.1.3 mrg (unspec:VNx2_WIDE
1839 1.1.1.3 mrg [(match_operand:VNx2BI 6 "general_operand" "UplDnm, UplDnm, UplDnm, UplDnm")
1840 1.1.1.3 mrg (ANY_EXTEND:VNx2_WIDE
1841 1.1.1.3 mrg (unspec:VNx2_NARROW
1842 1.1.1.3 mrg [(match_operand:VNx2BI 5 "register_operand" "Upl, Upl, Upl, Upl")
1843 1.1.1.3 mrg (match_operand:DI 1 "aarch64_sve_gather_offset_<VNx2_NARROW:Vesize>" "Z, vg<VNx2_NARROW:Vesize>, rk, rk")
1844 1.1.1.3 mrg (match_operand:VNx2_WIDE 2 "register_operand" "w, w, w, w")
1845 1.1.1.3 mrg (match_operand:DI 3 "const_int_operand")
1846 1.1.1.3 mrg (match_operand:DI 4 "aarch64_gather_scale_operand_<VNx2_NARROW:Vesize>" "Ui1, Ui1, Ui1, i")
1847 1.1.1.3 mrg (mem:BLK (scratch))
1848 1.1.1.3 mrg (reg:VNx16BI FFRT_REGNUM)]
1849 1.1.1.3 mrg UNSPEC_LDFF1_GATHER))]
1850 1.1.1.3 mrg UNSPEC_PRED_X))]
1851 1.1.1.3 mrg "TARGET_SVE"
1852 1.1.1.3 mrg "@
1853 1.1.1.3 mrg ldff1<ANY_EXTEND:s><VNx2_NARROW:Vesize>\t%0.d, %5/z, [%2.d]
1854 1.1.1.3 mrg ldff1<ANY_EXTEND:s><VNx2_NARROW:Vesize>\t%0.d, %5/z, [%2.d, #%1]
1855 1.1.1.3 mrg ldff1<ANY_EXTEND:s><VNx2_NARROW:Vesize>\t%0.d, %5/z, [%1, %2.d]
1856 1.1.1.3 mrg ldff1<ANY_EXTEND:s><VNx2_NARROW:Vesize>\t%0.d, %5/z, [%1, %2.d, lsl %p4]"
1857 1.1.1.3 mrg "&& !CONSTANT_P (operands[6])"
1858 1.1.1.3 mrg {
1859 1.1.1.3 mrg operands[6] = CONSTM1_RTX (VNx2BImode);
1860 1.1.1.3 mrg }
1861 1.1.1.3 mrg )
1862 1.1.1.3 mrg
1863 1.1.1.3 mrg ;; Likewise, but with the offset being sign-extended from 32 bits.
1864 1.1.1.3 mrg (define_insn_and_rewrite "*aarch64_ldff1_gather_<ANY_EXTEND:optab><VNx2_WIDE:mode><VNx2_NARROW:mode>_sxtw"
1865 1.1.1.3 mrg [(set (match_operand:VNx2_WIDE 0 "register_operand" "=w, w")
1866 1.1.1.3 mrg (unspec:VNx2_WIDE
1867 1.1.1.3 mrg [(match_operand 6)
1868 1.1.1.3 mrg (ANY_EXTEND:VNx2_WIDE
1869 1.1.1.3 mrg (unspec:VNx2_NARROW
1870 1.1.1.3 mrg [(match_operand:VNx2BI 5 "register_operand" "Upl, Upl")
1871 1.1.1.3 mrg (match_operand:DI 1 "aarch64_reg_or_zero" "rk, rk")
1872 1.1.1.3 mrg (unspec:VNx2DI
1873 1.1.1.3 mrg [(match_operand 7)
1874 1.1.1.3 mrg (sign_extend:VNx2DI
1875 1.1.1.3 mrg (truncate:VNx2SI
1876 1.1.1.3 mrg (match_operand:VNx2DI 2 "register_operand" "w, w")))]
1877 1.1.1.3 mrg UNSPEC_PRED_X)
1878 1.1.1.3 mrg (match_operand:DI 3 "const_int_operand")
1879 1.1.1.3 mrg (match_operand:DI 4 "aarch64_gather_scale_operand_<VNx2_NARROW:Vesize>" "Ui1, i")
1880 1.1.1.3 mrg (mem:BLK (scratch))
1881 1.1.1.3 mrg (reg:VNx16BI FFRT_REGNUM)]
1882 1.1.1.3 mrg UNSPEC_LDFF1_GATHER))]
1883 1.1.1.3 mrg UNSPEC_PRED_X))]
1884 1.1.1.3 mrg "TARGET_SVE"
1885 1.1.1.3 mrg "@
1886 1.1.1.3 mrg ldff1<ANY_EXTEND:s><VNx2_NARROW:Vesize>\t%0.d, %5/z, [%1, %2.d, sxtw]
1887 1.1.1.3 mrg ldff1<ANY_EXTEND:s><VNx2_NARROW:Vesize>\t%0.d, %5/z, [%1, %2.d, sxtw %p4]"
1888 1.1.1.3 mrg "&& (!CONSTANT_P (operands[6]) || !CONSTANT_P (operands[7]))"
1889 1.1.1.3 mrg {
1890 1.1.1.3 mrg operands[6] = CONSTM1_RTX (VNx2BImode);
1891 1.1.1.3 mrg operands[7] = CONSTM1_RTX (VNx2BImode);
1892 1.1.1.3 mrg }
1893 1.1.1.3 mrg )
1894 1.1.1.3 mrg
1895 1.1.1.3 mrg ;; Likewise, but with the offset being zero-extended from 32 bits.
1896 1.1.1.3 mrg (define_insn_and_rewrite "*aarch64_ldff1_gather_<ANY_EXTEND:optab><VNx2_WIDE:mode><VNx2_NARROW:mode>_uxtw"
1897 1.1.1.3 mrg [(set (match_operand:VNx2_WIDE 0 "register_operand" "=w, w")
1898 1.1.1.3 mrg (unspec:VNx2_WIDE
1899 1.1.1.3 mrg [(match_operand 7)
1900 1.1.1.3 mrg (ANY_EXTEND:VNx2_WIDE
1901 1.1.1.3 mrg (unspec:VNx2_NARROW
1902 1.1.1.3 mrg [(match_operand:VNx2BI 5 "register_operand" "Upl, Upl")
1903 1.1.1.3 mrg (match_operand:DI 1 "aarch64_reg_or_zero" "rk, rk")
1904 1.1.1.3 mrg (and:VNx2DI
1905 1.1.1.3 mrg (match_operand:VNx2DI 2 "register_operand" "w, w")
1906 1.1.1.3 mrg (match_operand:VNx2DI 6 "aarch64_sve_uxtw_immediate"))
1907 1.1.1.3 mrg (match_operand:DI 3 "const_int_operand")
1908 1.1.1.3 mrg (match_operand:DI 4 "aarch64_gather_scale_operand_<VNx2_NARROW:Vesize>" "Ui1, i")
1909 1.1.1.3 mrg (mem:BLK (scratch))
1910 1.1.1.3 mrg (reg:VNx16BI FFRT_REGNUM)]
1911 1.1.1.3 mrg UNSPEC_LDFF1_GATHER))]
1912 1.1.1.3 mrg UNSPEC_PRED_X))]
1913 1.1.1.3 mrg "TARGET_SVE"
1914 1.1.1.3 mrg "@
1915 1.1.1.3 mrg ldff1<ANY_EXTEND:s><VNx2_NARROW:Vesize>\t%0.d, %5/z, [%1, %2.d, uxtw]
1916 1.1.1.3 mrg ldff1<ANY_EXTEND:s><VNx2_NARROW:Vesize>\t%0.d, %5/z, [%1, %2.d, uxtw %p4]"
1917 1.1.1.3 mrg "&& !CONSTANT_P (operands[7])"
1918 1.1.1.3 mrg {
1919 1.1.1.3 mrg operands[7] = CONSTM1_RTX (VNx2BImode);
1920 1.1.1.3 mrg }
1921 1.1.1.3 mrg )
1922 1.1.1.3 mrg
1923 1.1.1.3 mrg ;; =========================================================================
1924 1.1.1.3 mrg ;; == Prefetches
1925 1.1.1.3 mrg ;; =========================================================================
1926 1.1.1.3 mrg
1927 1.1.1.3 mrg ;; -------------------------------------------------------------------------
1928 1.1.1.3 mrg ;; ---- Contiguous prefetches
1929 1.1.1.3 mrg ;; -------------------------------------------------------------------------
1930 1.1.1.3 mrg ;; Includes contiguous forms of:
1931 1.1.1.3 mrg ;; - PRFB
1932 1.1.1.3 mrg ;; - PRFD
1933 1.1.1.3 mrg ;; - PRFH
1934 1.1.1.3 mrg ;; - PRFW
1935 1.1.1.3 mrg ;; -------------------------------------------------------------------------
1936 1.1.1.3 mrg
1937 1.1.1.3 mrg ;; Contiguous predicated prefetches. Operand 2 gives the real prefetch
1938 1.1.1.3 mrg ;; operation (as an svprfop), with operands 3 and 4 providing distilled
1939 1.1.1.3 mrg ;; information.
1940 1.1.1.3 mrg (define_insn "@aarch64_sve_prefetch<mode>"
1941 1.1.1.3 mrg [(prefetch (unspec:DI
1942 1.1.1.3 mrg [(match_operand:<VPRED> 0 "register_operand" "Upl")
1943 1.1.1.3 mrg (match_operand:SVE_FULL_I 1 "aarch64_sve_prefetch_operand" "UP<Vesize>")
1944 1.1.1.3 mrg (match_operand:DI 2 "const_int_operand")]
1945 1.1.1.3 mrg UNSPEC_SVE_PREFETCH)
1946 1.1.1.3 mrg (match_operand:DI 3 "const_int_operand")
1947 1.1.1.3 mrg (match_operand:DI 4 "const_int_operand"))]
1948 1.1.1.3 mrg "TARGET_SVE"
1949 1.1.1.3 mrg {
1950 1.1.1.3 mrg operands[1] = gen_rtx_MEM (<MODE>mode, operands[1]);
1951 1.1.1.3 mrg return aarch64_output_sve_prefetch ("prf<Vesize>", operands[2], "%0, %1");
1952 1.1.1.3 mrg }
1953 1.1.1.3 mrg )
1954 1.1.1.3 mrg
1955 1.1.1.3 mrg ;; -------------------------------------------------------------------------
1956 1.1.1.3 mrg ;; ---- Gather prefetches
1957 1.1.1.3 mrg ;; -------------------------------------------------------------------------
1958 1.1.1.3 mrg ;; Includes gather forms of:
1959 1.1.1.3 mrg ;; - PRFB
1960 1.1.1.3 mrg ;; - PRFD
1961 1.1.1.3 mrg ;; - PRFH
1962 1.1.1.3 mrg ;; - PRFW
1963 1.1.1.3 mrg ;; -------------------------------------------------------------------------
1964 1.1.1.3 mrg
1965 1.1.1.3 mrg ;; Predicated gather prefetches for 32-bit bases and offsets. The operands
1966 1.1.1.3 mrg ;; are:
1967 1.1.1.3 mrg ;; 0: the governing predicate
1968 1.1.1.3 mrg ;; 1: the scalar component of the address
1969 1.1.1.3 mrg ;; 2: the vector component of the address
1970 1.1.1.3 mrg ;; 3: 1 for zero extension, 0 for sign extension
1971 1.1.1.3 mrg ;; 4: the scale multiplier
1972 1.1.1.3 mrg ;; 5: a vector zero that identifies the mode of data being accessed
1973 1.1.1.3 mrg ;; 6: the prefetch operator (an svprfop)
1974 1.1.1.3 mrg ;; 7: the normal RTL prefetch rw flag
1975 1.1.1.3 mrg ;; 8: the normal RTL prefetch locality value
1976 1.1.1.3 mrg (define_insn "@aarch64_sve_gather_prefetch<SVE_FULL_I:mode><VNx4SI_ONLY:mode>"
1977 1.1.1.3 mrg [(prefetch (unspec:DI
1978 1.1.1.3 mrg [(match_operand:VNx4BI 0 "register_operand" "Upl, Upl, Upl, Upl, Upl, Upl")
1979 1.1.1.3 mrg (match_operand:DI 1 "aarch64_sve_gather_offset_<SVE_FULL_I:Vesize>" "Z, vg<SVE_FULL_I:Vesize>, rk, rk, rk, rk")
1980 1.1.1.3 mrg (match_operand:VNx4SI_ONLY 2 "register_operand" "w, w, w, w, w, w")
1981 1.1.1.3 mrg (match_operand:DI 3 "const_int_operand" "i, i, Z, Ui1, Z, Ui1")
1982 1.1.1.3 mrg (match_operand:DI 4 "aarch64_gather_scale_operand_<SVE_FULL_I:Vesize>" "Ui1, Ui1, Ui1, Ui1, i, i")
1983 1.1.1.3 mrg (match_operand:SVE_FULL_I 5 "aarch64_simd_imm_zero")
1984 1.1.1.3 mrg (match_operand:DI 6 "const_int_operand")]
1985 1.1.1.3 mrg UNSPEC_SVE_PREFETCH_GATHER)
1986 1.1.1.3 mrg (match_operand:DI 7 "const_int_operand")
1987 1.1.1.3 mrg (match_operand:DI 8 "const_int_operand"))]
1988 1.1.1.3 mrg "TARGET_SVE"
1989 1.1.1.3 mrg {
1990 1.1.1.3 mrg static const char *const insns[][2] = {
1991 1.1.1.3 mrg "prf<SVE_FULL_I:Vesize>", "%0, [%2.s]",
1992 1.1.1.3 mrg "prf<SVE_FULL_I:Vesize>", "%0, [%2.s, #%1]",
1993 1.1.1.3 mrg "prfb", "%0, [%1, %2.s, sxtw]",
1994 1.1.1.3 mrg "prfb", "%0, [%1, %2.s, uxtw]",
1995 1.1.1.3 mrg "prf<SVE_FULL_I:Vesize>", "%0, [%1, %2.s, sxtw %p4]",
1996 1.1.1.3 mrg "prf<SVE_FULL_I:Vesize>", "%0, [%1, %2.s, uxtw %p4]"
1997 1.1.1.3 mrg };
1998 1.1.1.3 mrg const char *const *parts = insns[which_alternative];
1999 1.1.1.3 mrg return aarch64_output_sve_prefetch (parts[0], operands[6], parts[1]);
2000 1.1.1.2 mrg }
2001 1.1.1.2 mrg )
2002 1.1.1.2 mrg
2003 1.1.1.3 mrg ;; Predicated gather prefetches for 64-bit elements. The value of operand 3
2004 1.1.1.3 mrg ;; doesn't matter in this case.
2005 1.1.1.3 mrg (define_insn "@aarch64_sve_gather_prefetch<SVE_FULL_I:mode><VNx2DI_ONLY:mode>"
2006 1.1.1.3 mrg [(prefetch (unspec:DI
2007 1.1.1.3 mrg [(match_operand:VNx2BI 0 "register_operand" "Upl, Upl, Upl, Upl")
2008 1.1.1.3 mrg (match_operand:DI 1 "aarch64_sve_gather_offset_<SVE_FULL_I:Vesize>" "Z, vg<SVE_FULL_I:Vesize>, rk, rk")
2009 1.1.1.3 mrg (match_operand:VNx2DI_ONLY 2 "register_operand" "w, w, w, w")
2010 1.1.1.3 mrg (match_operand:DI 3 "const_int_operand")
2011 1.1.1.3 mrg (match_operand:DI 4 "aarch64_gather_scale_operand_<SVE_FULL_I:Vesize>" "Ui1, Ui1, Ui1, i")
2012 1.1.1.3 mrg (match_operand:SVE_FULL_I 5 "aarch64_simd_imm_zero")
2013 1.1.1.3 mrg (match_operand:DI 6 "const_int_operand")]
2014 1.1.1.3 mrg UNSPEC_SVE_PREFETCH_GATHER)
2015 1.1.1.3 mrg (match_operand:DI 7 "const_int_operand")
2016 1.1.1.3 mrg (match_operand:DI 8 "const_int_operand"))]
2017 1.1.1.3 mrg "TARGET_SVE"
2018 1.1.1.3 mrg {
2019 1.1.1.3 mrg static const char *const insns[][2] = {
2020 1.1.1.3 mrg "prf<SVE_FULL_I:Vesize>", "%0, [%2.d]",
2021 1.1.1.3 mrg "prf<SVE_FULL_I:Vesize>", "%0, [%2.d, #%1]",
2022 1.1.1.3 mrg "prfb", "%0, [%1, %2.d]",
2023 1.1.1.3 mrg "prf<SVE_FULL_I:Vesize>", "%0, [%1, %2.d, lsl %p4]"
2024 1.1.1.3 mrg };
2025 1.1.1.3 mrg const char *const *parts = insns[which_alternative];
2026 1.1.1.3 mrg return aarch64_output_sve_prefetch (parts[0], operands[6], parts[1]);
2027 1.1.1.3 mrg }
2028 1.1.1.3 mrg )
2029 1.1.1.3 mrg
2030 1.1.1.3 mrg ;; Likewise, but with the offset being sign-extended from 32 bits.
2031 1.1.1.3 mrg (define_insn_and_rewrite "*aarch64_sve_gather_prefetch<SVE_FULL_I:mode><VNx2DI_ONLY:mode>_sxtw"
2032 1.1.1.3 mrg [(prefetch (unspec:DI
2033 1.1.1.3 mrg [(match_operand:VNx2BI 0 "register_operand" "Upl, Upl")
2034 1.1.1.3 mrg (match_operand:DI 1 "register_operand" "rk, rk")
2035 1.1.1.3 mrg (unspec:VNx2DI_ONLY
2036 1.1.1.3 mrg [(match_operand 9)
2037 1.1.1.3 mrg (sign_extend:VNx2DI
2038 1.1.1.3 mrg (truncate:VNx2SI
2039 1.1.1.3 mrg (match_operand:VNx2DI 2 "register_operand" "w, w")))]
2040 1.1.1.3 mrg UNSPEC_PRED_X)
2041 1.1.1.3 mrg (match_operand:DI 3 "const_int_operand")
2042 1.1.1.3 mrg (match_operand:DI 4 "aarch64_gather_scale_operand_<SVE_FULL_I:Vesize>" "Ui1, i")
2043 1.1.1.3 mrg (match_operand:SVE_FULL_I 5 "aarch64_simd_imm_zero")
2044 1.1.1.3 mrg (match_operand:DI 6 "const_int_operand")]
2045 1.1.1.3 mrg UNSPEC_SVE_PREFETCH_GATHER)
2046 1.1.1.3 mrg (match_operand:DI 7 "const_int_operand")
2047 1.1.1.3 mrg (match_operand:DI 8 "const_int_operand"))]
2048 1.1.1.3 mrg "TARGET_SVE"
2049 1.1.1.3 mrg {
2050 1.1.1.3 mrg static const char *const insns[][2] = {
2051 1.1.1.3 mrg "prfb", "%0, [%1, %2.d, sxtw]",
2052 1.1.1.3 mrg "prf<SVE_FULL_I:Vesize>", "%0, [%1, %2.d, sxtw %p4]"
2053 1.1.1.3 mrg };
2054 1.1.1.3 mrg const char *const *parts = insns[which_alternative];
2055 1.1.1.3 mrg return aarch64_output_sve_prefetch (parts[0], operands[6], parts[1]);
2056 1.1.1.3 mrg }
2057 1.1.1.3 mrg "&& !rtx_equal_p (operands[0], operands[9])"
2058 1.1.1.3 mrg {
2059 1.1.1.3 mrg operands[9] = copy_rtx (operands[0]);
2060 1.1.1.3 mrg }
2061 1.1.1.3 mrg )
2062 1.1.1.3 mrg
2063 1.1.1.3 mrg ;; Likewise, but with the offset being zero-extended from 32 bits.
2064 1.1.1.3 mrg (define_insn "*aarch64_sve_gather_prefetch<SVE_FULL_I:mode><VNx2DI_ONLY:mode>_uxtw"
2065 1.1.1.3 mrg [(prefetch (unspec:DI
2066 1.1.1.3 mrg [(match_operand:VNx2BI 0 "register_operand" "Upl, Upl")
2067 1.1.1.3 mrg (match_operand:DI 1 "register_operand" "rk, rk")
2068 1.1.1.3 mrg (and:VNx2DI_ONLY
2069 1.1.1.3 mrg (match_operand:VNx2DI 2 "register_operand" "w, w")
2070 1.1.1.3 mrg (match_operand:VNx2DI 9 "aarch64_sve_uxtw_immediate"))
2071 1.1.1.3 mrg (match_operand:DI 3 "const_int_operand")
2072 1.1.1.3 mrg (match_operand:DI 4 "aarch64_gather_scale_operand_<SVE_FULL_I:Vesize>" "Ui1, i")
2073 1.1.1.3 mrg (match_operand:SVE_FULL_I 5 "aarch64_simd_imm_zero")
2074 1.1.1.3 mrg (match_operand:DI 6 "const_int_operand")]
2075 1.1.1.3 mrg UNSPEC_SVE_PREFETCH_GATHER)
2076 1.1.1.3 mrg (match_operand:DI 7 "const_int_operand")
2077 1.1.1.3 mrg (match_operand:DI 8 "const_int_operand"))]
2078 1.1.1.3 mrg "TARGET_SVE"
2079 1.1.1.3 mrg {
2080 1.1.1.3 mrg static const char *const insns[][2] = {
2081 1.1.1.3 mrg "prfb", "%0, [%1, %2.d, uxtw]",
2082 1.1.1.3 mrg "prf<SVE_FULL_I:Vesize>", "%0, [%1, %2.d, uxtw %p4]"
2083 1.1.1.3 mrg };
2084 1.1.1.3 mrg const char *const *parts = insns[which_alternative];
2085 1.1.1.3 mrg return aarch64_output_sve_prefetch (parts[0], operands[6], parts[1]);
2086 1.1.1.3 mrg }
2087 1.1.1.3 mrg )
2088 1.1.1.3 mrg
2089 1.1.1.3 mrg ;; =========================================================================
2090 1.1.1.3 mrg ;; == Stores
2091 1.1.1.3 mrg ;; =========================================================================
2092 1.1.1.3 mrg
2093 1.1.1.3 mrg ;; -------------------------------------------------------------------------
2094 1.1.1.3 mrg ;; ---- Normal contiguous stores
2095 1.1.1.3 mrg ;; -------------------------------------------------------------------------
2096 1.1.1.3 mrg ;; Includes contiguous forms of:
2097 1.1.1.3 mrg ;; - ST1B
2098 1.1.1.3 mrg ;; - ST1D
2099 1.1.1.3 mrg ;; - ST1H
2100 1.1.1.3 mrg ;; - ST1W
2101 1.1.1.3 mrg ;; - ST2B
2102 1.1.1.3 mrg ;; - ST2D
2103 1.1.1.3 mrg ;; - ST2H
2104 1.1.1.3 mrg ;; - ST2W
2105 1.1.1.3 mrg ;; - ST3B
2106 1.1.1.3 mrg ;; - ST3D
2107 1.1.1.3 mrg ;; - ST3H
2108 1.1.1.3 mrg ;; - ST3W
2109 1.1.1.3 mrg ;; - ST4B
2110 1.1.1.3 mrg ;; - ST4D
2111 1.1.1.3 mrg ;; - ST4H
2112 1.1.1.3 mrg ;; - ST4W
2113 1.1.1.3 mrg ;; -------------------------------------------------------------------------
2114 1.1.1.3 mrg
2115 1.1.1.3 mrg ;; Predicated ST1.
2116 1.1.1.3 mrg (define_insn "maskstore<mode><vpred>"
2117 1.1.1.3 mrg [(set (match_operand:SVE_ALL 0 "memory_operand" "+m")
2118 1.1.1.3 mrg (unspec:SVE_ALL
2119 1.1.1.3 mrg [(match_operand:<VPRED> 2 "register_operand" "Upl")
2120 1.1.1.3 mrg (match_operand:SVE_ALL 1 "register_operand" "w")
2121 1.1.1.3 mrg (match_dup 0)]
2122 1.1.1.3 mrg UNSPEC_ST1_SVE))]
2123 1.1.1.2 mrg "TARGET_SVE"
2124 1.1.1.3 mrg "st1<Vesize>\t%1.<Vctype>, %2, %0"
2125 1.1 mrg )
2126 1.1 mrg
2127 1.1.1.3 mrg ;; Unpredicated ST[234]. This is always a full update, so the dependence
2128 1.1.1.3 mrg ;; on the old value of the memory location (via (match_dup 0)) is redundant.
2129 1.1.1.3 mrg ;; There doesn't seem to be any obvious benefit to treating the all-true
2130 1.1.1.3 mrg ;; case differently though. In particular, it's very unlikely that we'll
2131 1.1.1.3 mrg ;; only find out during RTL that a store_lanes is dead.
2132 1.1.1.3 mrg (define_expand "vec_store_lanes<mode><vsingle>"
2133 1.1.1.3 mrg [(set (match_operand:SVE_STRUCT 0 "memory_operand")
2134 1.1.1.3 mrg (unspec:SVE_STRUCT
2135 1.1 mrg [(match_dup 2)
2136 1.1.1.3 mrg (match_operand:SVE_STRUCT 1 "register_operand")
2137 1.1.1.3 mrg (match_dup 0)]
2138 1.1.1.3 mrg UNSPEC_STN))]
2139 1.1 mrg "TARGET_SVE"
2140 1.1 mrg {
2141 1.1.1.3 mrg operands[2] = aarch64_ptrue_reg (<VPRED>mode);
2142 1.1 mrg }
2143 1.1 mrg )
2144 1.1 mrg
2145 1.1.1.3 mrg ;; Predicated ST[234].
2146 1.1.1.3 mrg (define_insn "vec_mask_store_lanes<mode><vsingle>"
2147 1.1.1.3 mrg [(set (match_operand:SVE_STRUCT 0 "memory_operand" "+m")
2148 1.1.1.3 mrg (unspec:SVE_STRUCT
2149 1.1.1.3 mrg [(match_operand:<VPRED> 2 "register_operand" "Upl")
2150 1.1.1.3 mrg (match_operand:SVE_STRUCT 1 "register_operand" "w")
2151 1.1.1.3 mrg (match_dup 0)]
2152 1.1.1.3 mrg UNSPEC_STN))]
2153 1.1 mrg "TARGET_SVE"
2154 1.1.1.3 mrg "st<vector_count><Vesize>\t%1, %2, %0"
2155 1.1 mrg )
2156 1.1 mrg
2157 1.1.1.3 mrg ;; -------------------------------------------------------------------------
2158 1.1.1.3 mrg ;; ---- Truncating contiguous stores
2159 1.1.1.3 mrg ;; -------------------------------------------------------------------------
2160 1.1.1.3 mrg ;; Includes:
2161 1.1.1.3 mrg ;; - ST1B
2162 1.1.1.3 mrg ;; - ST1H
2163 1.1.1.3 mrg ;; - ST1W
2164 1.1.1.3 mrg ;; -------------------------------------------------------------------------
2165 1.1.1.3 mrg
2166 1.1.1.3 mrg ;; Predicated truncate and store, with 8 elements per 128-bit block.
2167 1.1.1.3 mrg (define_insn "@aarch64_store_trunc<VNx8_NARROW:mode><VNx8_WIDE:mode>"
2168 1.1.1.3 mrg [(set (match_operand:VNx8_NARROW 0 "memory_operand" "+m")
2169 1.1.1.3 mrg (unspec:VNx8_NARROW
2170 1.1.1.3 mrg [(match_operand:VNx8BI 2 "register_operand" "Upl")
2171 1.1.1.3 mrg (truncate:VNx8_NARROW
2172 1.1.1.3 mrg (match_operand:VNx8_WIDE 1 "register_operand" "w"))
2173 1.1.1.3 mrg (match_dup 0)]
2174 1.1.1.3 mrg UNSPEC_ST1_SVE))]
2175 1.1 mrg "TARGET_SVE"
2176 1.1.1.3 mrg "st1<VNx8_NARROW:Vesize>\t%1.<VNx8_WIDE:Vetype>, %2, %0"
2177 1.1 mrg )
2178 1.1 mrg
2179 1.1.1.3 mrg ;; Predicated truncate and store, with 4 elements per 128-bit block.
2180 1.1.1.3 mrg (define_insn "@aarch64_store_trunc<VNx4_NARROW:mode><VNx4_WIDE:mode>"
2181 1.1.1.3 mrg [(set (match_operand:VNx4_NARROW 0 "memory_operand" "+m")
2182 1.1.1.3 mrg (unspec:VNx4_NARROW
2183 1.1.1.3 mrg [(match_operand:VNx4BI 2 "register_operand" "Upl")
2184 1.1.1.3 mrg (truncate:VNx4_NARROW
2185 1.1.1.3 mrg (match_operand:VNx4_WIDE 1 "register_operand" "w"))
2186 1.1.1.3 mrg (match_dup 0)]
2187 1.1.1.3 mrg UNSPEC_ST1_SVE))]
2188 1.1 mrg "TARGET_SVE"
2189 1.1.1.3 mrg "st1<VNx4_NARROW:Vesize>\t%1.<VNx4_WIDE:Vetype>, %2, %0"
2190 1.1 mrg )
2191 1.1 mrg
2192 1.1.1.3 mrg ;; Predicated truncate and store, with 2 elements per 128-bit block.
2193 1.1.1.3 mrg (define_insn "@aarch64_store_trunc<VNx2_NARROW:mode><VNx2_WIDE:mode>"
2194 1.1.1.3 mrg [(set (match_operand:VNx2_NARROW 0 "memory_operand" "+m")
2195 1.1.1.3 mrg (unspec:VNx2_NARROW
2196 1.1.1.3 mrg [(match_operand:VNx2BI 2 "register_operand" "Upl")
2197 1.1.1.3 mrg (truncate:VNx2_NARROW
2198 1.1.1.3 mrg (match_operand:VNx2_WIDE 1 "register_operand" "w"))
2199 1.1.1.3 mrg (match_dup 0)]
2200 1.1.1.3 mrg UNSPEC_ST1_SVE))]
2201 1.1 mrg "TARGET_SVE"
2202 1.1.1.3 mrg "st1<VNx2_NARROW:Vesize>\t%1.<VNx2_WIDE:Vetype>, %2, %0"
2203 1.1 mrg )
2204 1.1 mrg
2205 1.1.1.3 mrg ;; -------------------------------------------------------------------------
2206 1.1.1.3 mrg ;; ---- Non-temporal contiguous stores
2207 1.1.1.3 mrg ;; -------------------------------------------------------------------------
2208 1.1.1.3 mrg ;; Includes:
2209 1.1.1.3 mrg ;; - STNT1B
2210 1.1.1.3 mrg ;; - STNT1D
2211 1.1.1.3 mrg ;; - STNT1H
2212 1.1.1.3 mrg ;; - STNT1W
2213 1.1.1.3 mrg ;; -------------------------------------------------------------------------
2214 1.1.1.3 mrg
2215 1.1.1.3 mrg (define_insn "@aarch64_stnt1<mode>"
2216 1.1.1.3 mrg [(set (match_operand:SVE_FULL 0 "memory_operand" "+m")
2217 1.1.1.3 mrg (unspec:SVE_FULL
2218 1.1.1.3 mrg [(match_operand:<VPRED> 2 "register_operand" "Upl")
2219 1.1.1.3 mrg (match_operand:SVE_FULL 1 "register_operand" "w")
2220 1.1.1.3 mrg (match_dup 0)]
2221 1.1.1.3 mrg UNSPEC_STNT1_SVE))]
2222 1.1 mrg "TARGET_SVE"
2223 1.1.1.3 mrg "stnt1<Vesize>\t%1.<Vetype>, %2, %0"
2224 1.1 mrg )
2225 1.1 mrg
2226 1.1.1.3 mrg ;; -------------------------------------------------------------------------
2227 1.1.1.3 mrg ;; ---- Normal scatter stores
2228 1.1.1.3 mrg ;; -------------------------------------------------------------------------
2229 1.1.1.3 mrg ;; Includes scatter forms of:
2230 1.1.1.3 mrg ;; - ST1D
2231 1.1.1.3 mrg ;; - ST1W
2232 1.1.1.3 mrg ;; -------------------------------------------------------------------------
2233 1.1.1.3 mrg
2234 1.1.1.3 mrg ;; Unpredicated scatter stores.
2235 1.1.1.3 mrg (define_expand "scatter_store<mode><v_int_container>"
2236 1.1.1.3 mrg [(set (mem:BLK (scratch))
2237 1.1.1.3 mrg (unspec:BLK
2238 1.1.1.3 mrg [(match_dup 5)
2239 1.1.1.3 mrg (match_operand:DI 0 "aarch64_sve_gather_offset_<Vesize>")
2240 1.1.1.3 mrg (match_operand:<V_INT_CONTAINER> 1 "register_operand")
2241 1.1.1.3 mrg (match_operand:DI 2 "const_int_operand")
2242 1.1.1.3 mrg (match_operand:DI 3 "aarch64_gather_scale_operand_<Vesize>")
2243 1.1.1.3 mrg (match_operand:SVE_24 4 "register_operand")]
2244 1.1.1.3 mrg UNSPEC_ST1_SCATTER))]
2245 1.1 mrg "TARGET_SVE"
2246 1.1 mrg {
2247 1.1.1.3 mrg operands[5] = aarch64_ptrue_reg (<VPRED>mode);
2248 1.1 mrg }
2249 1.1 mrg )
2250 1.1 mrg
2251 1.1.1.3 mrg ;; Predicated scatter stores for 32-bit elements. Operand 2 is true for
2252 1.1.1.3 mrg ;; unsigned extension and false for signed extension.
2253 1.1.1.3 mrg (define_insn "mask_scatter_store<mode><v_int_container>"
2254 1.1.1.3 mrg [(set (mem:BLK (scratch))
2255 1.1.1.3 mrg (unspec:BLK
2256 1.1.1.3 mrg [(match_operand:VNx4BI 5 "register_operand" "Upl, Upl, Upl, Upl, Upl, Upl")
2257 1.1.1.3 mrg (match_operand:DI 0 "aarch64_sve_gather_offset_<Vesize>" "Z, vgw, rk, rk, rk, rk")
2258 1.1.1.3 mrg (match_operand:VNx4SI 1 "register_operand" "w, w, w, w, w, w")
2259 1.1.1.3 mrg (match_operand:DI 2 "const_int_operand" "Ui1, Ui1, Z, Ui1, Z, Ui1")
2260 1.1.1.3 mrg (match_operand:DI 3 "aarch64_gather_scale_operand_<Vesize>" "Ui1, Ui1, Ui1, Ui1, i, i")
2261 1.1.1.3 mrg (match_operand:SVE_4 4 "register_operand" "w, w, w, w, w, w")]
2262 1.1.1.3 mrg UNSPEC_ST1_SCATTER))]
2263 1.1 mrg "TARGET_SVE"
2264 1.1.1.3 mrg "@
2265 1.1.1.3 mrg st1<Vesize>\t%4.s, %5, [%1.s]
2266 1.1.1.3 mrg st1<Vesize>\t%4.s, %5, [%1.s, #%0]
2267 1.1.1.3 mrg st1<Vesize>\t%4.s, %5, [%0, %1.s, sxtw]
2268 1.1.1.3 mrg st1<Vesize>\t%4.s, %5, [%0, %1.s, uxtw]
2269 1.1.1.3 mrg st1<Vesize>\t%4.s, %5, [%0, %1.s, sxtw %p3]
2270 1.1.1.3 mrg st1<Vesize>\t%4.s, %5, [%0, %1.s, uxtw %p3]"
2271 1.1 mrg )
2272 1.1 mrg
2273 1.1.1.3 mrg ;; Predicated scatter stores for 64-bit elements. The value of operand 2
2274 1.1.1.3 mrg ;; doesn't matter in this case.
2275 1.1.1.3 mrg (define_insn "mask_scatter_store<mode><v_int_container>"
2276 1.1.1.3 mrg [(set (mem:BLK (scratch))
2277 1.1.1.3 mrg (unspec:BLK
2278 1.1.1.3 mrg [(match_operand:VNx2BI 5 "register_operand" "Upl, Upl, Upl, Upl")
2279 1.1.1.3 mrg (match_operand:DI 0 "aarch64_sve_gather_offset_<Vesize>" "Z, vgd, rk, rk")
2280 1.1.1.3 mrg (match_operand:VNx2DI 1 "register_operand" "w, w, w, w")
2281 1.1.1.3 mrg (match_operand:DI 2 "const_int_operand")
2282 1.1.1.3 mrg (match_operand:DI 3 "aarch64_gather_scale_operand_<Vesize>" "Ui1, Ui1, Ui1, i")
2283 1.1.1.3 mrg (match_operand:SVE_2 4 "register_operand" "w, w, w, w")]
2284 1.1.1.3 mrg UNSPEC_ST1_SCATTER))]
2285 1.1 mrg "TARGET_SVE"
2286 1.1.1.3 mrg "@
2287 1.1.1.3 mrg st1<Vesize>\t%4.d, %5, [%1.d]
2288 1.1.1.3 mrg st1<Vesize>\t%4.d, %5, [%1.d, #%0]
2289 1.1.1.3 mrg st1<Vesize>\t%4.d, %5, [%0, %1.d]
2290 1.1.1.3 mrg st1<Vesize>\t%4.d, %5, [%0, %1.d, lsl %p3]"
2291 1.1 mrg )
2292 1.1 mrg
2293 1.1.1.3 mrg ;; Likewise, but with the offset being extended from 32 bits.
2294 1.1.1.3 mrg (define_insn_and_rewrite "*mask_scatter_store<mode><v_int_container>_<su>xtw_unpacked"
2295 1.1.1.3 mrg [(set (mem:BLK (scratch))
2296 1.1.1.3 mrg (unspec:BLK
2297 1.1.1.3 mrg [(match_operand:VNx2BI 5 "register_operand" "Upl, Upl")
2298 1.1.1.3 mrg (match_operand:DI 0 "register_operand" "rk, rk")
2299 1.1.1.3 mrg (unspec:VNx2DI
2300 1.1.1.3 mrg [(match_operand 6)
2301 1.1.1.3 mrg (ANY_EXTEND:VNx2DI
2302 1.1.1.3 mrg (match_operand:VNx2SI 1 "register_operand" "w, w"))]
2303 1.1.1.3 mrg UNSPEC_PRED_X)
2304 1.1.1.3 mrg (match_operand:DI 2 "const_int_operand")
2305 1.1.1.3 mrg (match_operand:DI 3 "aarch64_gather_scale_operand_<Vesize>" "Ui1, i")
2306 1.1.1.3 mrg (match_operand:SVE_2 4 "register_operand" "w, w")]
2307 1.1.1.3 mrg UNSPEC_ST1_SCATTER))]
2308 1.1 mrg "TARGET_SVE"
2309 1.1.1.3 mrg "@
2310 1.1.1.3 mrg st1<Vesize>\t%4.d, %5, [%0, %1.d, <su>xtw]
2311 1.1.1.3 mrg st1<Vesize>\t%4.d, %5, [%0, %1.d, <su>xtw %p3]"
2312 1.1.1.3 mrg "&& !CONSTANT_P (operands[6])"
2313 1.1 mrg {
2314 1.1.1.3 mrg operands[6] = CONSTM1_RTX (<VPRED>mode);
2315 1.1 mrg }
2316 1.1 mrg )
2317 1.1 mrg
2318 1.1.1.3 mrg ;; Likewise, but with the offset being truncated to 32 bits and then
2319 1.1.1.3 mrg ;; sign-extended.
2320 1.1.1.3 mrg (define_insn_and_rewrite "*mask_scatter_store<mode><v_int_container>_sxtw"
2321 1.1.1.3 mrg [(set (mem:BLK (scratch))
2322 1.1.1.3 mrg (unspec:BLK
2323 1.1.1.3 mrg [(match_operand:VNx2BI 5 "register_operand" "Upl, Upl")
2324 1.1.1.3 mrg (match_operand:DI 0 "register_operand" "rk, rk")
2325 1.1.1.3 mrg (unspec:VNx2DI
2326 1.1.1.3 mrg [(match_operand 6)
2327 1.1.1.3 mrg (sign_extend:VNx2DI
2328 1.1.1.3 mrg (truncate:VNx2SI
2329 1.1.1.3 mrg (match_operand:VNx2DI 1 "register_operand" "w, w")))]
2330 1.1.1.3 mrg UNSPEC_PRED_X)
2331 1.1.1.3 mrg (match_operand:DI 2 "const_int_operand")
2332 1.1.1.3 mrg (match_operand:DI 3 "aarch64_gather_scale_operand_<Vesize>" "Ui1, i")
2333 1.1.1.3 mrg (match_operand:SVE_2 4 "register_operand" "w, w")]
2334 1.1.1.3 mrg UNSPEC_ST1_SCATTER))]
2335 1.1 mrg "TARGET_SVE"
2336 1.1.1.3 mrg "@
2337 1.1.1.3 mrg st1<Vesize>\t%4.d, %5, [%0, %1.d, sxtw]
2338 1.1.1.3 mrg st1<Vesize>\t%4.d, %5, [%0, %1.d, sxtw %p3]"
2339 1.1.1.3 mrg "&& !CONSTANT_P (operands[6])"
2340 1.1.1.3 mrg {
2341 1.1.1.3 mrg operands[6] = CONSTM1_RTX (<VPRED>mode);
2342 1.1.1.3 mrg }
2343 1.1 mrg )
2344 1.1 mrg
2345 1.1.1.3 mrg ;; Likewise, but with the offset being truncated to 32 bits and then
2346 1.1.1.3 mrg ;; zero-extended.
2347 1.1.1.3 mrg (define_insn "*mask_scatter_store<mode><v_int_container>_uxtw"
2348 1.1.1.3 mrg [(set (mem:BLK (scratch))
2349 1.1.1.3 mrg (unspec:BLK
2350 1.1.1.3 mrg [(match_operand:VNx2BI 5 "register_operand" "Upl, Upl")
2351 1.1.1.3 mrg (match_operand:DI 0 "aarch64_reg_or_zero" "rk, rk")
2352 1.1.1.3 mrg (and:VNx2DI
2353 1.1.1.3 mrg (match_operand:VNx2DI 1 "register_operand" "w, w")
2354 1.1.1.3 mrg (match_operand:VNx2DI 6 "aarch64_sve_uxtw_immediate"))
2355 1.1.1.3 mrg (match_operand:DI 2 "const_int_operand")
2356 1.1.1.3 mrg (match_operand:DI 3 "aarch64_gather_scale_operand_<Vesize>" "Ui1, i")
2357 1.1.1.3 mrg (match_operand:SVE_2 4 "register_operand" "w, w")]
2358 1.1.1.3 mrg UNSPEC_ST1_SCATTER))]
2359 1.1 mrg "TARGET_SVE"
2360 1.1.1.3 mrg "@
2361 1.1.1.3 mrg st1<Vesize>\t%4.d, %5, [%0, %1.d, uxtw]
2362 1.1.1.3 mrg st1<Vesize>\t%4.d, %5, [%0, %1.d, uxtw %p3]"
2363 1.1 mrg )
2364 1.1 mrg
2365 1.1.1.3 mrg ;; -------------------------------------------------------------------------
2366 1.1.1.3 mrg ;; ---- Truncating scatter stores
2367 1.1.1.3 mrg ;; -------------------------------------------------------------------------
2368 1.1.1.3 mrg ;; Includes scatter forms of:
2369 1.1.1.3 mrg ;; - ST1B
2370 1.1.1.3 mrg ;; - ST1H
2371 1.1.1.3 mrg ;; - ST1W
2372 1.1.1.3 mrg ;; -------------------------------------------------------------------------
2373 1.1.1.3 mrg
2374 1.1.1.3 mrg ;; Predicated truncating scatter stores for 32-bit elements. Operand 2 is
2375 1.1.1.3 mrg ;; true for unsigned extension and false for signed extension.
2376 1.1.1.3 mrg (define_insn "@aarch64_scatter_store_trunc<VNx4_NARROW:mode><VNx4_WIDE:mode>"
2377 1.1.1.3 mrg [(set (mem:BLK (scratch))
2378 1.1.1.3 mrg (unspec:BLK
2379 1.1.1.3 mrg [(match_operand:VNx4BI 5 "register_operand" "Upl, Upl, Upl, Upl, Upl, Upl")
2380 1.1.1.3 mrg (match_operand:DI 0 "aarch64_sve_gather_offset_<VNx4_NARROW:Vesize>" "Z, vg<VNx4_NARROW:Vesize>, rk, rk, rk, rk")
2381 1.1.1.3 mrg (match_operand:VNx4SI 1 "register_operand" "w, w, w, w, w, w")
2382 1.1.1.3 mrg (match_operand:DI 2 "const_int_operand" "Ui1, Ui1, Z, Ui1, Z, Ui1")
2383 1.1.1.3 mrg (match_operand:DI 3 "aarch64_gather_scale_operand_<VNx4_NARROW:Vesize>" "Ui1, Ui1, Ui1, Ui1, i, i")
2384 1.1.1.3 mrg (truncate:VNx4_NARROW
2385 1.1.1.3 mrg (match_operand:VNx4_WIDE 4 "register_operand" "w, w, w, w, w, w"))]
2386 1.1.1.3 mrg UNSPEC_ST1_SCATTER))]
2387 1.1 mrg "TARGET_SVE"
2388 1.1.1.3 mrg "@
2389 1.1.1.3 mrg st1<VNx4_NARROW:Vesize>\t%4.s, %5, [%1.s]
2390 1.1.1.3 mrg st1<VNx4_NARROW:Vesize>\t%4.s, %5, [%1.s, #%0]
2391 1.1.1.3 mrg st1<VNx4_NARROW:Vesize>\t%4.s, %5, [%0, %1.s, sxtw]
2392 1.1.1.3 mrg st1<VNx4_NARROW:Vesize>\t%4.s, %5, [%0, %1.s, uxtw]
2393 1.1.1.3 mrg st1<VNx4_NARROW:Vesize>\t%4.s, %5, [%0, %1.s, sxtw %p3]
2394 1.1.1.3 mrg st1<VNx4_NARROW:Vesize>\t%4.s, %5, [%0, %1.s, uxtw %p3]"
2395 1.1 mrg )
2396 1.1 mrg
2397 1.1.1.3 mrg ;; Predicated truncating scatter stores for 64-bit elements. The value of
2398 1.1.1.3 mrg ;; operand 2 doesn't matter in this case.
2399 1.1.1.3 mrg (define_insn "@aarch64_scatter_store_trunc<VNx2_NARROW:mode><VNx2_WIDE:mode>"
2400 1.1.1.3 mrg [(set (mem:BLK (scratch))
2401 1.1.1.3 mrg (unspec:BLK
2402 1.1.1.3 mrg [(match_operand:VNx2BI 5 "register_operand" "Upl, Upl, Upl, Upl")
2403 1.1.1.3 mrg (match_operand:DI 0 "aarch64_sve_gather_offset_<VNx2_NARROW:Vesize>" "Z, vg<VNx2_NARROW:Vesize>, rk, rk")
2404 1.1.1.3 mrg (match_operand:VNx2DI 1 "register_operand" "w, w, w, w")
2405 1.1.1.3 mrg (match_operand:DI 2 "const_int_operand")
2406 1.1.1.3 mrg (match_operand:DI 3 "aarch64_gather_scale_operand_<VNx2_NARROW:Vesize>" "Ui1, Ui1, Ui1, i")
2407 1.1.1.3 mrg (truncate:VNx2_NARROW
2408 1.1.1.3 mrg (match_operand:VNx2_WIDE 4 "register_operand" "w, w, w, w"))]
2409 1.1.1.3 mrg UNSPEC_ST1_SCATTER))]
2410 1.1.1.3 mrg "TARGET_SVE"
2411 1.1.1.3 mrg "@
2412 1.1.1.3 mrg st1<VNx2_NARROW:Vesize>\t%4.d, %5, [%1.d]
2413 1.1.1.3 mrg st1<VNx2_NARROW:Vesize>\t%4.d, %5, [%1.d, #%0]
2414 1.1.1.3 mrg st1<VNx2_NARROW:Vesize>\t%4.d, %5, [%0, %1.d]
2415 1.1.1.3 mrg st1<VNx2_NARROW:Vesize>\t%4.d, %5, [%0, %1.d, lsl %p3]"
2416 1.1.1.3 mrg )
2417 1.1.1.3 mrg
2418 1.1.1.3 mrg ;; Likewise, but with the offset being sign-extended from 32 bits.
2419 1.1.1.3 mrg (define_insn_and_rewrite "*aarch64_scatter_store_trunc<VNx2_NARROW:mode><VNx2_WIDE:mode>_sxtw"
2420 1.1.1.3 mrg [(set (mem:BLK (scratch))
2421 1.1.1.3 mrg (unspec:BLK
2422 1.1.1.3 mrg [(match_operand:VNx2BI 5 "register_operand" "Upl, Upl")
2423 1.1.1.3 mrg (match_operand:DI 0 "register_operand" "rk, rk")
2424 1.1.1.3 mrg (unspec:VNx2DI
2425 1.1.1.3 mrg [(match_operand 6)
2426 1.1.1.3 mrg (sign_extend:VNx2DI
2427 1.1.1.3 mrg (truncate:VNx2SI
2428 1.1.1.3 mrg (match_operand:VNx2DI 1 "register_operand" "w, w")))]
2429 1.1.1.3 mrg UNSPEC_PRED_X)
2430 1.1.1.3 mrg (match_operand:DI 2 "const_int_operand")
2431 1.1.1.3 mrg (match_operand:DI 3 "aarch64_gather_scale_operand_<VNx2_NARROW:Vesize>" "Ui1, i")
2432 1.1.1.3 mrg (truncate:VNx2_NARROW
2433 1.1.1.3 mrg (match_operand:VNx2_WIDE 4 "register_operand" "w, w"))]
2434 1.1.1.3 mrg UNSPEC_ST1_SCATTER))]
2435 1.1.1.3 mrg "TARGET_SVE"
2436 1.1.1.3 mrg "@
2437 1.1.1.3 mrg st1<VNx2_NARROW:Vesize>\t%4.d, %5, [%0, %1.d, sxtw]
2438 1.1.1.3 mrg st1<VNx2_NARROW:Vesize>\t%4.d, %5, [%0, %1.d, sxtw %p3]"
2439 1.1.1.3 mrg "&& !rtx_equal_p (operands[5], operands[6])"
2440 1.1.1.3 mrg {
2441 1.1.1.3 mrg operands[6] = copy_rtx (operands[5]);
2442 1.1.1.3 mrg }
2443 1.1.1.3 mrg )
2444 1.1.1.3 mrg
2445 1.1.1.3 mrg ;; Likewise, but with the offset being zero-extended from 32 bits.
2446 1.1.1.3 mrg (define_insn "*aarch64_scatter_store_trunc<VNx2_NARROW:mode><VNx2_WIDE:mode>_uxtw"
2447 1.1.1.3 mrg [(set (mem:BLK (scratch))
2448 1.1.1.3 mrg (unspec:BLK
2449 1.1.1.3 mrg [(match_operand:VNx2BI 5 "register_operand" "Upl, Upl")
2450 1.1.1.3 mrg (match_operand:DI 0 "aarch64_reg_or_zero" "rk, rk")
2451 1.1.1.3 mrg (and:VNx2DI
2452 1.1.1.3 mrg (match_operand:VNx2DI 1 "register_operand" "w, w")
2453 1.1.1.3 mrg (match_operand:VNx2DI 6 "aarch64_sve_uxtw_immediate"))
2454 1.1.1.3 mrg (match_operand:DI 2 "const_int_operand")
2455 1.1.1.3 mrg (match_operand:DI 3 "aarch64_gather_scale_operand_<VNx2_NARROW:Vesize>" "Ui1, i")
2456 1.1.1.3 mrg (truncate:VNx2_NARROW
2457 1.1.1.3 mrg (match_operand:VNx2_WIDE 4 "register_operand" "w, w"))]
2458 1.1.1.3 mrg UNSPEC_ST1_SCATTER))]
2459 1.1.1.3 mrg "TARGET_SVE"
2460 1.1.1.3 mrg "@
2461 1.1.1.3 mrg st1<VNx2_NARROW:Vesize>\t%4.d, %5, [%0, %1.d, uxtw]
2462 1.1.1.3 mrg st1<VNx2_NARROW:Vesize>\t%4.d, %5, [%0, %1.d, uxtw %p3]"
2463 1.1.1.3 mrg )
2464 1.1.1.3 mrg
2465 1.1.1.3 mrg ;; =========================================================================
2466 1.1.1.3 mrg ;; == Vector creation
2467 1.1.1.3 mrg ;; =========================================================================
2468 1.1.1.3 mrg
2469 1.1.1.3 mrg ;; -------------------------------------------------------------------------
2470 1.1.1.3 mrg ;; ---- [INT,FP] Duplicate element
2471 1.1.1.3 mrg ;; -------------------------------------------------------------------------
2472 1.1.1.3 mrg ;; Includes:
2473 1.1.1.3 mrg ;; - DUP
2474 1.1.1.3 mrg ;; - MOV
2475 1.1.1.3 mrg ;; - LD1RB
2476 1.1.1.3 mrg ;; - LD1RD
2477 1.1.1.3 mrg ;; - LD1RH
2478 1.1.1.3 mrg ;; - LD1RW
2479 1.1.1.3 mrg ;; - LD1ROB (F64MM)
2480 1.1.1.3 mrg ;; - LD1ROD (F64MM)
2481 1.1.1.3 mrg ;; - LD1ROH (F64MM)
2482 1.1.1.3 mrg ;; - LD1ROW (F64MM)
2483 1.1.1.3 mrg ;; - LD1RQB
2484 1.1.1.3 mrg ;; - LD1RQD
2485 1.1.1.3 mrg ;; - LD1RQH
2486 1.1.1.3 mrg ;; - LD1RQW
2487 1.1.1.3 mrg ;; -------------------------------------------------------------------------
2488 1.1.1.3 mrg
2489 1.1.1.3 mrg (define_expand "vec_duplicate<mode>"
2490 1.1.1.3 mrg [(parallel
2491 1.1.1.3 mrg [(set (match_operand:SVE_ALL 0 "register_operand")
2492 1.1.1.3 mrg (vec_duplicate:SVE_ALL
2493 1.1.1.3 mrg (match_operand:<VEL> 1 "aarch64_sve_dup_operand")))
2494 1.1.1.3 mrg (clobber (scratch:VNx16BI))])]
2495 1.1.1.3 mrg "TARGET_SVE"
2496 1.1.1.3 mrg {
2497 1.1.1.3 mrg if (MEM_P (operands[1]))
2498 1.1.1.3 mrg {
2499 1.1.1.3 mrg rtx ptrue = aarch64_ptrue_reg (<VPRED>mode);
2500 1.1.1.3 mrg emit_insn (gen_sve_ld1r<mode> (operands[0], ptrue, operands[1],
2501 1.1.1.3 mrg CONST0_RTX (<MODE>mode)));
2502 1.1.1.3 mrg DONE;
2503 1.1.1.3 mrg }
2504 1.1.1.3 mrg }
2505 1.1.1.3 mrg )
2506 1.1.1.3 mrg
2507 1.1.1.3 mrg ;; Accept memory operands for the benefit of combine, and also in case
2508 1.1.1.3 mrg ;; the scalar input gets spilled to memory during RA. We want to split
2509 1.1.1.3 mrg ;; the load at the first opportunity in order to allow the PTRUE to be
2510 1.1.1.3 mrg ;; optimized with surrounding code.
2511 1.1.1.3 mrg (define_insn_and_split "*vec_duplicate<mode>_reg"
2512 1.1.1.3 mrg [(set (match_operand:SVE_ALL 0 "register_operand" "=w, w, w")
2513 1.1.1.3 mrg (vec_duplicate:SVE_ALL
2514 1.1.1.3 mrg (match_operand:<VEL> 1 "aarch64_sve_dup_operand" "r, w, Uty")))
2515 1.1.1.3 mrg (clobber (match_scratch:VNx16BI 2 "=X, X, Upl"))]
2516 1.1.1.3 mrg "TARGET_SVE"
2517 1.1.1.3 mrg "@
2518 1.1.1.3 mrg mov\t%0.<Vetype>, %<vwcore>1
2519 1.1.1.3 mrg mov\t%0.<Vetype>, %<Vetype>1
2520 1.1.1.3 mrg #"
2521 1.1.1.3 mrg "&& MEM_P (operands[1])"
2522 1.1.1.3 mrg [(const_int 0)]
2523 1.1.1.3 mrg {
2524 1.1.1.3 mrg if (GET_CODE (operands[2]) == SCRATCH)
2525 1.1.1.3 mrg operands[2] = gen_reg_rtx (VNx16BImode);
2526 1.1.1.3 mrg emit_move_insn (operands[2], CONSTM1_RTX (VNx16BImode));
2527 1.1.1.3 mrg rtx gp = gen_lowpart (<VPRED>mode, operands[2]);
2528 1.1.1.3 mrg emit_insn (gen_sve_ld1r<mode> (operands[0], gp, operands[1],
2529 1.1.1.3 mrg CONST0_RTX (<MODE>mode)));
2530 1.1.1.3 mrg DONE;
2531 1.1.1.3 mrg }
2532 1.1.1.3 mrg [(set_attr "length" "4,4,8")]
2533 1.1.1.3 mrg )
2534 1.1.1.3 mrg
2535 1.1.1.3 mrg ;; Duplicate an Advanced SIMD vector to fill an SVE vector (LE version).
2536 1.1.1.3 mrg (define_insn "@aarch64_vec_duplicate_vq<mode>_le"
2537 1.1.1.3 mrg [(set (match_operand:SVE_FULL 0 "register_operand" "=w")
2538 1.1.1.3 mrg (vec_duplicate:SVE_FULL
2539 1.1.1.3 mrg (match_operand:<V128> 1 "register_operand" "w")))]
2540 1.1.1.3 mrg "TARGET_SVE && !BYTES_BIG_ENDIAN"
2541 1.1.1.3 mrg {
2542 1.1.1.3 mrg operands[1] = gen_rtx_REG (<MODE>mode, REGNO (operands[1]));
2543 1.1.1.3 mrg return "dup\t%0.q, %1.q[0]";
2544 1.1.1.3 mrg }
2545 1.1.1.3 mrg )
2546 1.1.1.3 mrg
2547 1.1.1.3 mrg ;; Duplicate an Advanced SIMD vector to fill an SVE vector (BE version).
2548 1.1.1.3 mrg ;; The SVE register layout puts memory lane N into (architectural)
2549 1.1.1.3 mrg ;; register lane N, whereas the Advanced SIMD layout puts the memory
2550 1.1.1.3 mrg ;; lsb into the register lsb. We therefore have to describe this in rtl
2551 1.1.1.3 mrg ;; terms as a reverse of the V128 vector followed by a duplicate.
2552 1.1.1.3 mrg (define_insn "@aarch64_vec_duplicate_vq<mode>_be"
2553 1.1.1.3 mrg [(set (match_operand:SVE_FULL 0 "register_operand" "=w")
2554 1.1.1.3 mrg (vec_duplicate:SVE_FULL
2555 1.1.1.3 mrg (vec_select:<V128>
2556 1.1.1.3 mrg (match_operand:<V128> 1 "register_operand" "w")
2557 1.1.1.3 mrg (match_operand 2 "descending_int_parallel"))))]
2558 1.1.1.3 mrg "TARGET_SVE
2559 1.1.1.3 mrg && BYTES_BIG_ENDIAN
2560 1.1.1.3 mrg && known_eq (INTVAL (XVECEXP (operands[2], 0, 0)),
2561 1.1.1.3 mrg GET_MODE_NUNITS (<V128>mode) - 1)"
2562 1.1.1.3 mrg {
2563 1.1.1.3 mrg operands[1] = gen_rtx_REG (<MODE>mode, REGNO (operands[1]));
2564 1.1.1.3 mrg return "dup\t%0.q, %1.q[0]";
2565 1.1.1.3 mrg }
2566 1.1.1.3 mrg )
2567 1.1.1.3 mrg
2568 1.1.1.3 mrg ;; This is used for vec_duplicate<mode>s from memory, but can also
2569 1.1.1.3 mrg ;; be used by combine to optimize selects of a vec_duplicate<mode>
2570 1.1.1.3 mrg ;; with zero.
2571 1.1.1.3 mrg (define_insn "sve_ld1r<mode>"
2572 1.1.1.3 mrg [(set (match_operand:SVE_ALL 0 "register_operand" "=w")
2573 1.1.1.3 mrg (unspec:SVE_ALL
2574 1.1.1.3 mrg [(match_operand:<VPRED> 1 "register_operand" "Upl")
2575 1.1.1.3 mrg (vec_duplicate:SVE_ALL
2576 1.1.1.3 mrg (match_operand:<VEL> 2 "aarch64_sve_ld1r_operand" "Uty"))
2577 1.1.1.3 mrg (match_operand:SVE_ALL 3 "aarch64_simd_imm_zero")]
2578 1.1.1.3 mrg UNSPEC_SEL))]
2579 1.1.1.3 mrg "TARGET_SVE"
2580 1.1.1.3 mrg "ld1r<Vesize>\t%0.<Vetype>, %1/z, %2"
2581 1.1.1.3 mrg )
2582 1.1.1.3 mrg
2583 1.1.1.3 mrg ;; Load 128 bits from memory under predicate control and duplicate to
2584 1.1.1.3 mrg ;; fill a vector.
2585 1.1.1.3 mrg (define_insn "@aarch64_sve_ld1rq<mode>"
2586 1.1.1.3 mrg [(set (match_operand:SVE_FULL 0 "register_operand" "=w")
2587 1.1.1.3 mrg (unspec:SVE_FULL
2588 1.1.1.3 mrg [(match_operand:<VPRED> 2 "register_operand" "Upl")
2589 1.1.1.3 mrg (match_operand:<V128> 1 "aarch64_sve_ld1rq_operand" "UtQ")]
2590 1.1.1.3 mrg UNSPEC_LD1RQ))]
2591 1.1.1.3 mrg "TARGET_SVE"
2592 1.1.1.3 mrg {
2593 1.1.1.3 mrg operands[1] = gen_rtx_MEM (<VEL>mode, XEXP (operands[1], 0));
2594 1.1.1.3 mrg return "ld1rq<Vesize>\t%0.<Vetype>, %2/z, %1";
2595 1.1.1.3 mrg }
2596 1.1.1.3 mrg )
2597 1.1.1.3 mrg
2598 1.1.1.3 mrg (define_insn "@aarch64_sve_ld1ro<mode>"
2599 1.1.1.3 mrg [(set (match_operand:SVE_FULL 0 "register_operand" "=w")
2600 1.1.1.3 mrg (unspec:SVE_FULL
2601 1.1.1.3 mrg [(match_operand:<VPRED> 2 "register_operand" "Upl")
2602 1.1.1.3 mrg (match_operand:OI 1 "aarch64_sve_ld1ro_operand_<Vesize>"
2603 1.1.1.3 mrg "UO<Vesize>")]
2604 1.1.1.3 mrg UNSPEC_LD1RO))]
2605 1.1.1.3 mrg "TARGET_SVE_F64MM"
2606 1.1.1.3 mrg {
2607 1.1.1.3 mrg operands[1] = gen_rtx_MEM (<VEL>mode, XEXP (operands[1], 0));
2608 1.1.1.3 mrg return "ld1ro<Vesize>\t%0.<Vetype>, %2/z, %1";
2609 1.1.1.3 mrg }
2610 1.1.1.3 mrg )
2611 1.1.1.3 mrg
2612 1.1.1.3 mrg ;; -------------------------------------------------------------------------
2613 1.1.1.3 mrg ;; ---- [INT,FP] Initialize from individual elements
2614 1.1.1.3 mrg ;; -------------------------------------------------------------------------
2615 1.1.1.3 mrg ;; Includes:
2616 1.1.1.3 mrg ;; - INSR
2617 1.1.1.3 mrg ;; -------------------------------------------------------------------------
2618 1.1.1.3 mrg
2619 1.1.1.3 mrg (define_expand "vec_init<mode><Vel>"
2620 1.1.1.3 mrg [(match_operand:SVE_FULL 0 "register_operand")
2621 1.1.1.3 mrg (match_operand 1 "")]
2622 1.1.1.3 mrg "TARGET_SVE"
2623 1.1.1.3 mrg {
2624 1.1.1.3 mrg aarch64_sve_expand_vector_init (operands[0], operands[1]);
2625 1.1.1.3 mrg DONE;
2626 1.1.1.3 mrg }
2627 1.1.1.3 mrg )
2628 1.1.1.3 mrg
2629 1.1.1.3 mrg ;; Shift an SVE vector left and insert a scalar into element 0.
2630 1.1.1.3 mrg (define_insn "vec_shl_insert_<mode>"
2631 1.1.1.3 mrg [(set (match_operand:SVE_FULL 0 "register_operand" "=?w, w, ??&w, ?&w")
2632 1.1.1.3 mrg (unspec:SVE_FULL
2633 1.1.1.3 mrg [(match_operand:SVE_FULL 1 "register_operand" "0, 0, w, w")
2634 1.1.1.3 mrg (match_operand:<VEL> 2 "aarch64_reg_or_zero" "rZ, w, rZ, w")]
2635 1.1.1.3 mrg UNSPEC_INSR))]
2636 1.1.1.3 mrg "TARGET_SVE"
2637 1.1.1.3 mrg "@
2638 1.1.1.3 mrg insr\t%0.<Vetype>, %<vwcore>2
2639 1.1.1.3 mrg insr\t%0.<Vetype>, %<Vetype>2
2640 1.1.1.3 mrg movprfx\t%0, %1\;insr\t%0.<Vetype>, %<vwcore>2
2641 1.1.1.3 mrg movprfx\t%0, %1\;insr\t%0.<Vetype>, %<Vetype>2"
2642 1.1.1.3 mrg [(set_attr "movprfx" "*,*,yes,yes")]
2643 1.1.1.3 mrg )
2644 1.1.1.3 mrg
2645 1.1.1.3 mrg ;; -------------------------------------------------------------------------
2646 1.1.1.3 mrg ;; ---- [INT] Linear series
2647 1.1.1.3 mrg ;; -------------------------------------------------------------------------
2648 1.1.1.3 mrg ;; Includes:
2649 1.1.1.3 mrg ;; - INDEX
2650 1.1.1.3 mrg ;; -------------------------------------------------------------------------
2651 1.1.1.3 mrg
2652 1.1.1.3 mrg (define_insn "vec_series<mode>"
2653 1.1.1.3 mrg [(set (match_operand:SVE_I 0 "register_operand" "=w, w, w")
2654 1.1.1.3 mrg (vec_series:SVE_I
2655 1.1.1.3 mrg (match_operand:<VEL> 1 "aarch64_sve_index_operand" "Usi, r, r")
2656 1.1.1.3 mrg (match_operand:<VEL> 2 "aarch64_sve_index_operand" "r, Usi, r")))]
2657 1.1.1.3 mrg "TARGET_SVE"
2658 1.1.1.3 mrg "@
2659 1.1.1.3 mrg index\t%0.<Vctype>, #%1, %<vccore>2
2660 1.1.1.3 mrg index\t%0.<Vctype>, %<vccore>1, #%2
2661 1.1.1.3 mrg index\t%0.<Vctype>, %<vccore>1, %<vccore>2"
2662 1.1.1.3 mrg )
2663 1.1.1.3 mrg
2664 1.1.1.3 mrg ;; Optimize {x, x, x, x, ...} + {0, n, 2*n, 3*n, ...} if n is in range
2665 1.1.1.3 mrg ;; of an INDEX instruction.
2666 1.1.1.3 mrg (define_insn "*vec_series<mode>_plus"
2667 1.1.1.3 mrg [(set (match_operand:SVE_I 0 "register_operand" "=w")
2668 1.1.1.3 mrg (plus:SVE_I
2669 1.1.1.3 mrg (vec_duplicate:SVE_I
2670 1.1.1.3 mrg (match_operand:<VEL> 1 "register_operand" "r"))
2671 1.1.1.3 mrg (match_operand:SVE_I 2 "immediate_operand")))]
2672 1.1.1.3 mrg "TARGET_SVE && aarch64_check_zero_based_sve_index_immediate (operands[2])"
2673 1.1.1.3 mrg {
2674 1.1.1.3 mrg operands[2] = aarch64_check_zero_based_sve_index_immediate (operands[2]);
2675 1.1.1.3 mrg return "index\t%0.<Vctype>, %<vccore>1, #%2";
2676 1.1.1.3 mrg }
2677 1.1.1.3 mrg )
2678 1.1.1.3 mrg
2679 1.1.1.3 mrg ;; -------------------------------------------------------------------------
2680 1.1.1.3 mrg ;; ---- [PRED] Duplicate element
2681 1.1.1.3 mrg ;; -------------------------------------------------------------------------
2682 1.1.1.3 mrg ;; The patterns in this section are synthetic.
2683 1.1.1.3 mrg ;; -------------------------------------------------------------------------
2684 1.1.1.3 mrg
2685 1.1.1.3 mrg ;; Implement a predicate broadcast by shifting the low bit of the scalar
2686 1.1.1.3 mrg ;; input into the top bit and using a WHILELO. An alternative would be to
2687 1.1.1.3 mrg ;; duplicate the input and do a compare with zero.
2688 1.1.1.3 mrg (define_expand "vec_duplicate<mode>"
2689 1.1.1.3 mrg [(set (match_operand:PRED_ALL 0 "register_operand")
2690 1.1.1.3 mrg (vec_duplicate:PRED_ALL (match_operand:QI 1 "register_operand")))]
2691 1.1.1.3 mrg "TARGET_SVE"
2692 1.1.1.3 mrg {
2693 1.1.1.3 mrg rtx tmp = gen_reg_rtx (DImode);
2694 1.1.1.3 mrg rtx op1 = gen_lowpart (DImode, operands[1]);
2695 1.1.1.3 mrg emit_insn (gen_ashldi3 (tmp, op1, gen_int_mode (63, DImode)));
2696 1.1.1.3 mrg emit_insn (gen_while_ultdi<mode> (operands[0], const0_rtx, tmp));
2697 1.1.1.3 mrg DONE;
2698 1.1.1.3 mrg }
2699 1.1.1.3 mrg )
2700 1.1.1.3 mrg
2701 1.1.1.3 mrg ;; =========================================================================
2702 1.1.1.3 mrg ;; == Vector decomposition
2703 1.1.1.3 mrg ;; =========================================================================
2704 1.1.1.3 mrg
2705 1.1.1.3 mrg ;; -------------------------------------------------------------------------
2706 1.1.1.3 mrg ;; ---- [INT,FP] Extract index
2707 1.1.1.3 mrg ;; -------------------------------------------------------------------------
2708 1.1.1.3 mrg ;; Includes:
2709 1.1.1.3 mrg ;; - DUP (Advanced SIMD)
2710 1.1.1.3 mrg ;; - DUP (SVE)
2711 1.1.1.3 mrg ;; - EXT (SVE)
2712 1.1.1.3 mrg ;; - ST1 (Advanced SIMD)
2713 1.1.1.3 mrg ;; - UMOV (Advanced SIMD)
2714 1.1.1.3 mrg ;; -------------------------------------------------------------------------
2715 1.1.1.3 mrg
2716 1.1.1.3 mrg (define_expand "vec_extract<mode><Vel>"
2717 1.1.1.3 mrg [(set (match_operand:<VEL> 0 "register_operand")
2718 1.1.1.3 mrg (vec_select:<VEL>
2719 1.1.1.3 mrg (match_operand:SVE_FULL 1 "register_operand")
2720 1.1.1.3 mrg (parallel [(match_operand:SI 2 "nonmemory_operand")])))]
2721 1.1.1.3 mrg "TARGET_SVE"
2722 1.1.1.3 mrg {
2723 1.1.1.3 mrg poly_int64 val;
2724 1.1.1.3 mrg if (poly_int_rtx_p (operands[2], &val)
2725 1.1.1.3 mrg && known_eq (val, GET_MODE_NUNITS (<MODE>mode) - 1))
2726 1.1.1.3 mrg {
2727 1.1.1.3 mrg /* The last element can be extracted with a LASTB and a false
2728 1.1.1.3 mrg predicate. */
2729 1.1.1.3 mrg rtx sel = aarch64_pfalse_reg (<VPRED>mode);
2730 1.1.1.3 mrg emit_insn (gen_extract_last_<mode> (operands[0], sel, operands[1]));
2731 1.1.1.3 mrg DONE;
2732 1.1.1.3 mrg }
2733 1.1.1.3 mrg if (!CONST_INT_P (operands[2]))
2734 1.1.1.3 mrg {
2735 1.1.1.3 mrg /* Create an index with operand[2] as the base and -1 as the step.
2736 1.1.1.3 mrg It will then be zero for the element we care about. */
2737 1.1.1.3 mrg rtx index = gen_lowpart (<VEL_INT>mode, operands[2]);
2738 1.1.1.3 mrg index = force_reg (<VEL_INT>mode, index);
2739 1.1.1.3 mrg rtx series = gen_reg_rtx (<V_INT_EQUIV>mode);
2740 1.1.1.3 mrg emit_insn (gen_vec_series<v_int_equiv> (series, index, constm1_rtx));
2741 1.1.1.3 mrg
2742 1.1.1.3 mrg /* Get a predicate that is true for only that element. */
2743 1.1.1.3 mrg rtx zero = CONST0_RTX (<V_INT_EQUIV>mode);
2744 1.1.1.3 mrg rtx cmp = gen_rtx_EQ (<V_INT_EQUIV>mode, series, zero);
2745 1.1.1.3 mrg rtx sel = gen_reg_rtx (<VPRED>mode);
2746 1.1.1.3 mrg emit_insn (gen_vec_cmp<v_int_equiv><vpred> (sel, cmp, series, zero));
2747 1.1.1.3 mrg
2748 1.1.1.3 mrg /* Select the element using LASTB. */
2749 1.1.1.3 mrg emit_insn (gen_extract_last_<mode> (operands[0], sel, operands[1]));
2750 1.1.1.3 mrg DONE;
2751 1.1.1.3 mrg }
2752 1.1.1.3 mrg }
2753 1.1.1.3 mrg )
2754 1.1.1.3 mrg
2755 1.1.1.3 mrg ;; Extract element zero. This is a special case because we want to force
2756 1.1.1.3 mrg ;; the registers to be the same for the second alternative, and then
2757 1.1.1.3 mrg ;; split the instruction into nothing after RA.
2758 1.1.1.3 mrg (define_insn_and_split "*vec_extract<mode><Vel>_0"
2759 1.1.1.3 mrg [(set (match_operand:<VEL> 0 "aarch64_simd_nonimmediate_operand" "=r, w, Utv")
2760 1.1.1.3 mrg (vec_select:<VEL>
2761 1.1.1.3 mrg (match_operand:SVE_FULL 1 "register_operand" "w, 0, w")
2762 1.1.1.3 mrg (parallel [(const_int 0)])))]
2763 1.1.1.3 mrg "TARGET_SVE"
2764 1.1.1.3 mrg {
2765 1.1.1.3 mrg operands[1] = gen_rtx_REG (<V128>mode, REGNO (operands[1]));
2766 1.1.1.3 mrg switch (which_alternative)
2767 1.1.1.3 mrg {
2768 1.1.1.3 mrg case 0:
2769 1.1.1.3 mrg return "umov\\t%<vwcore>0, %1.<Vetype>[0]";
2770 1.1.1.3 mrg case 1:
2771 1.1.1.3 mrg return "#";
2772 1.1.1.3 mrg case 2:
2773 1.1.1.3 mrg return "st1\\t{%1.<Vetype>}[0], %0";
2774 1.1.1.3 mrg default:
2775 1.1.1.3 mrg gcc_unreachable ();
2776 1.1.1.3 mrg }
2777 1.1.1.3 mrg }
2778 1.1.1.3 mrg "&& reload_completed
2779 1.1.1.3 mrg && REG_P (operands[0])
2780 1.1.1.3 mrg && REGNO (operands[0]) == REGNO (operands[1])"
2781 1.1.1.3 mrg [(const_int 0)]
2782 1.1.1.3 mrg {
2783 1.1.1.3 mrg emit_note (NOTE_INSN_DELETED);
2784 1.1.1.3 mrg DONE;
2785 1.1.1.3 mrg }
2786 1.1.1.3 mrg [(set_attr "type" "neon_to_gp_q, untyped, neon_store1_one_lane_q")]
2787 1.1.1.3 mrg )
2788 1.1.1.3 mrg
2789 1.1.1.3 mrg ;; Extract an element from the Advanced SIMD portion of the register.
2790 1.1.1.3 mrg ;; We don't just reuse the aarch64-simd.md pattern because we don't
2791 1.1.1.3 mrg ;; want any change in lane number on big-endian targets.
2792 1.1.1.3 mrg (define_insn "*vec_extract<mode><Vel>_v128"
2793 1.1.1.3 mrg [(set (match_operand:<VEL> 0 "aarch64_simd_nonimmediate_operand" "=r, w, Utv")
2794 1.1.1.3 mrg (vec_select:<VEL>
2795 1.1.1.3 mrg (match_operand:SVE_FULL 1 "register_operand" "w, w, w")
2796 1.1.1.3 mrg (parallel [(match_operand:SI 2 "const_int_operand")])))]
2797 1.1.1.3 mrg "TARGET_SVE
2798 1.1.1.3 mrg && IN_RANGE (INTVAL (operands[2]) * GET_MODE_SIZE (<VEL>mode), 1, 15)"
2799 1.1.1.3 mrg {
2800 1.1.1.3 mrg operands[1] = gen_rtx_REG (<V128>mode, REGNO (operands[1]));
2801 1.1.1.3 mrg switch (which_alternative)
2802 1.1.1.3 mrg {
2803 1.1.1.3 mrg case 0:
2804 1.1.1.3 mrg return "umov\\t%<vwcore>0, %1.<Vetype>[%2]";
2805 1.1.1.3 mrg case 1:
2806 1.1.1.3 mrg return "dup\\t%<Vetype>0, %1.<Vetype>[%2]";
2807 1.1.1.3 mrg case 2:
2808 1.1.1.3 mrg return "st1\\t{%1.<Vetype>}[%2], %0";
2809 1.1.1.3 mrg default:
2810 1.1.1.3 mrg gcc_unreachable ();
2811 1.1.1.3 mrg }
2812 1.1.1.3 mrg }
2813 1.1.1.3 mrg [(set_attr "type" "neon_to_gp_q, neon_dup_q, neon_store1_one_lane_q")]
2814 1.1.1.3 mrg )
2815 1.1.1.3 mrg
2816 1.1.1.3 mrg ;; Extract an element in the range of DUP. This pattern allows the
2817 1.1.1.3 mrg ;; source and destination to be different.
2818 1.1.1.3 mrg (define_insn "*vec_extract<mode><Vel>_dup"
2819 1.1.1.3 mrg [(set (match_operand:<VEL> 0 "register_operand" "=w")
2820 1.1.1.3 mrg (vec_select:<VEL>
2821 1.1.1.3 mrg (match_operand:SVE_FULL 1 "register_operand" "w")
2822 1.1.1.3 mrg (parallel [(match_operand:SI 2 "const_int_operand")])))]
2823 1.1.1.3 mrg "TARGET_SVE
2824 1.1.1.3 mrg && IN_RANGE (INTVAL (operands[2]) * GET_MODE_SIZE (<VEL>mode), 16, 63)"
2825 1.1.1.3 mrg {
2826 1.1.1.3 mrg operands[0] = gen_rtx_REG (<MODE>mode, REGNO (operands[0]));
2827 1.1.1.3 mrg return "dup\t%0.<Vetype>, %1.<Vetype>[%2]";
2828 1.1.1.3 mrg }
2829 1.1.1.3 mrg )
2830 1.1.1.3 mrg
2831 1.1.1.3 mrg ;; Extract an element outside the range of DUP. This pattern requires the
2832 1.1.1.3 mrg ;; source and destination to be the same.
2833 1.1.1.3 mrg (define_insn "*vec_extract<mode><Vel>_ext"
2834 1.1.1.3 mrg [(set (match_operand:<VEL> 0 "register_operand" "=w, ?&w")
2835 1.1.1.3 mrg (vec_select:<VEL>
2836 1.1.1.3 mrg (match_operand:SVE_FULL 1 "register_operand" "0, w")
2837 1.1.1.3 mrg (parallel [(match_operand:SI 2 "const_int_operand")])))]
2838 1.1.1.3 mrg "TARGET_SVE && INTVAL (operands[2]) * GET_MODE_SIZE (<VEL>mode) >= 64"
2839 1.1.1.3 mrg {
2840 1.1.1.3 mrg operands[0] = gen_rtx_REG (<MODE>mode, REGNO (operands[0]));
2841 1.1.1.3 mrg operands[2] = GEN_INT (INTVAL (operands[2]) * GET_MODE_SIZE (<VEL>mode));
2842 1.1.1.3 mrg return (which_alternative == 0
2843 1.1.1.3 mrg ? "ext\t%0.b, %0.b, %0.b, #%2"
2844 1.1.1.3 mrg : "movprfx\t%0, %1\;ext\t%0.b, %0.b, %1.b, #%2");
2845 1.1.1.3 mrg }
2846 1.1.1.3 mrg [(set_attr "movprfx" "*,yes")]
2847 1.1.1.3 mrg )
2848 1.1.1.3 mrg
2849 1.1.1.3 mrg ;; -------------------------------------------------------------------------
2850 1.1.1.3 mrg ;; ---- [INT,FP] Extract active element
2851 1.1.1.3 mrg ;; -------------------------------------------------------------------------
2852 1.1.1.3 mrg ;; Includes:
2853 1.1.1.3 mrg ;; - LASTA
2854 1.1.1.3 mrg ;; - LASTB
2855 1.1.1.3 mrg ;; -------------------------------------------------------------------------
2856 1.1.1.3 mrg
2857 1.1.1.3 mrg ;; Extract the last active element of operand 1 into operand 0.
2858 1.1.1.3 mrg ;; If no elements are active, extract the last inactive element instead.
2859 1.1.1.3 mrg (define_insn "@extract_<last_op>_<mode>"
2860 1.1.1.3 mrg [(set (match_operand:<VEL> 0 "register_operand" "=?r, w")
2861 1.1.1.3 mrg (unspec:<VEL>
2862 1.1.1.3 mrg [(match_operand:<VPRED> 1 "register_operand" "Upl, Upl")
2863 1.1.1.3 mrg (match_operand:SVE_FULL 2 "register_operand" "w, w")]
2864 1.1.1.3 mrg LAST))]
2865 1.1.1.3 mrg "TARGET_SVE"
2866 1.1.1.3 mrg "@
2867 1.1.1.3 mrg last<ab>\t%<vwcore>0, %1, %2.<Vetype>
2868 1.1.1.3 mrg last<ab>\t%<Vetype>0, %1, %2.<Vetype>"
2869 1.1.1.3 mrg )
2870 1.1.1.3 mrg
2871 1.1.1.3 mrg ;; -------------------------------------------------------------------------
2872 1.1.1.3 mrg ;; ---- [PRED] Extract index
2873 1.1.1.3 mrg ;; -------------------------------------------------------------------------
2874 1.1.1.3 mrg ;; The patterns in this section are synthetic.
2875 1.1.1.3 mrg ;; -------------------------------------------------------------------------
2876 1.1.1.3 mrg
2877 1.1.1.3 mrg ;; Handle extractions from a predicate by converting to an integer vector
2878 1.1.1.3 mrg ;; and extracting from there.
2879 1.1.1.3 mrg (define_expand "vec_extract<vpred><Vel>"
2880 1.1.1.3 mrg [(match_operand:<VEL> 0 "register_operand")
2881 1.1.1.3 mrg (match_operand:<VPRED> 1 "register_operand")
2882 1.1.1.3 mrg (match_operand:SI 2 "nonmemory_operand")
2883 1.1.1.3 mrg ;; Dummy operand to which we can attach the iterator.
2884 1.1.1.3 mrg (reg:SVE_FULL_I V0_REGNUM)]
2885 1.1.1.3 mrg "TARGET_SVE"
2886 1.1.1.3 mrg {
2887 1.1.1.3 mrg rtx tmp = gen_reg_rtx (<MODE>mode);
2888 1.1.1.3 mrg emit_insn (gen_vcond_mask_<mode><vpred> (tmp, operands[1],
2889 1.1.1.3 mrg CONST1_RTX (<MODE>mode),
2890 1.1.1.3 mrg CONST0_RTX (<MODE>mode)));
2891 1.1.1.3 mrg emit_insn (gen_vec_extract<mode><Vel> (operands[0], tmp, operands[2]));
2892 1.1.1.3 mrg DONE;
2893 1.1.1.3 mrg }
2894 1.1.1.3 mrg )
2895 1.1.1.3 mrg
2896 1.1.1.3 mrg ;; =========================================================================
2897 1.1.1.3 mrg ;; == Unary arithmetic
2898 1.1.1.3 mrg ;; =========================================================================
2899 1.1.1.3 mrg
2900 1.1.1.3 mrg ;; -------------------------------------------------------------------------
2901 1.1.1.3 mrg ;; ---- [INT] General unary arithmetic corresponding to rtx codes
2902 1.1.1.3 mrg ;; -------------------------------------------------------------------------
2903 1.1.1.3 mrg ;; Includes:
2904 1.1.1.3 mrg ;; - ABS
2905 1.1.1.3 mrg ;; - CLS (= clrsb)
2906 1.1.1.3 mrg ;; - CLZ
2907 1.1.1.3 mrg ;; - CNT (= popcount)
2908 1.1.1.3 mrg ;; - NEG
2909 1.1.1.3 mrg ;; - NOT
2910 1.1.1.3 mrg ;; -------------------------------------------------------------------------
2911 1.1.1.3 mrg
2912 1.1.1.3 mrg ;; Unpredicated integer unary arithmetic.
2913 1.1.1.3 mrg (define_expand "<optab><mode>2"
2914 1.1.1.5 mrg [(set (match_operand:SVE_I 0 "register_operand")
2915 1.1.1.5 mrg (unspec:SVE_I
2916 1.1.1.3 mrg [(match_dup 2)
2917 1.1.1.5 mrg (SVE_INT_UNARY:SVE_I
2918 1.1.1.5 mrg (match_operand:SVE_I 1 "register_operand"))]
2919 1.1.1.3 mrg UNSPEC_PRED_X))]
2920 1.1.1.3 mrg "TARGET_SVE"
2921 1.1.1.3 mrg {
2922 1.1.1.3 mrg operands[2] = aarch64_ptrue_reg (<VPRED>mode);
2923 1.1.1.3 mrg }
2924 1.1.1.3 mrg )
2925 1.1.1.3 mrg
2926 1.1.1.3 mrg ;; Integer unary arithmetic predicated with a PTRUE.
2927 1.1.1.3 mrg (define_insn "@aarch64_pred_<optab><mode>"
2928 1.1.1.5 mrg [(set (match_operand:SVE_I 0 "register_operand" "=w, ?&w")
2929 1.1.1.5 mrg (unspec:SVE_I
2930 1.1.1.3 mrg [(match_operand:<VPRED> 1 "register_operand" "Upl, Upl")
2931 1.1.1.5 mrg (SVE_INT_UNARY:SVE_I
2932 1.1.1.5 mrg (match_operand:SVE_I 2 "register_operand" "0, w"))]
2933 1.1.1.3 mrg UNSPEC_PRED_X))]
2934 1.1.1.3 mrg "TARGET_SVE"
2935 1.1.1.3 mrg "@
2936 1.1.1.3 mrg <sve_int_op>\t%0.<Vetype>, %1/m, %2.<Vetype>
2937 1.1.1.3 mrg movprfx\t%0, %2\;<sve_int_op>\t%0.<Vetype>, %1/m, %2.<Vetype>"
2938 1.1.1.3 mrg [(set_attr "movprfx" "*,yes")]
2939 1.1.1.3 mrg )
2940 1.1.1.3 mrg
2941 1.1.1.3 mrg ;; Predicated integer unary arithmetic with merging.
2942 1.1.1.3 mrg (define_expand "@cond_<optab><mode>"
2943 1.1.1.5 mrg [(set (match_operand:SVE_I 0 "register_operand")
2944 1.1.1.5 mrg (unspec:SVE_I
2945 1.1.1.3 mrg [(match_operand:<VPRED> 1 "register_operand")
2946 1.1.1.5 mrg (SVE_INT_UNARY:SVE_I
2947 1.1.1.5 mrg (match_operand:SVE_I 2 "register_operand"))
2948 1.1.1.5 mrg (match_operand:SVE_I 3 "aarch64_simd_reg_or_zero")]
2949 1.1.1.3 mrg UNSPEC_SEL))]
2950 1.1.1.3 mrg "TARGET_SVE"
2951 1.1.1.3 mrg )
2952 1.1.1.3 mrg
2953 1.1.1.3 mrg ;; Predicated integer unary arithmetic, merging with the first input.
2954 1.1.1.3 mrg (define_insn "*cond_<optab><mode>_2"
2955 1.1.1.5 mrg [(set (match_operand:SVE_I 0 "register_operand" "=w, ?&w")
2956 1.1.1.5 mrg (unspec:SVE_I
2957 1.1.1.3 mrg [(match_operand:<VPRED> 1 "register_operand" "Upl, Upl")
2958 1.1.1.5 mrg (SVE_INT_UNARY:SVE_I
2959 1.1.1.5 mrg (match_operand:SVE_I 2 "register_operand" "0, w"))
2960 1.1.1.3 mrg (match_dup 2)]
2961 1.1.1.3 mrg UNSPEC_SEL))]
2962 1.1.1.3 mrg "TARGET_SVE"
2963 1.1.1.3 mrg "@
2964 1.1.1.3 mrg <sve_int_op>\t%0.<Vetype>, %1/m, %0.<Vetype>
2965 1.1.1.3 mrg movprfx\t%0, %2\;<sve_int_op>\t%0.<Vetype>, %1/m, %2.<Vetype>"
2966 1.1.1.3 mrg [(set_attr "movprfx" "*,yes")]
2967 1.1.1.3 mrg )
2968 1.1.1.3 mrg
2969 1.1.1.3 mrg ;; Predicated integer unary arithmetic, merging with an independent value.
2970 1.1.1.3 mrg ;;
2971 1.1.1.3 mrg ;; The earlyclobber isn't needed for the first alternative, but omitting
2972 1.1.1.3 mrg ;; it would only help the case in which operands 2 and 3 are the same,
2973 1.1.1.3 mrg ;; which is handled above rather than here. Marking all the alternatives
2974 1.1.1.3 mrg ;; as earlyclobber helps to make the instruction more regular to the
2975 1.1.1.3 mrg ;; register allocator.
2976 1.1.1.3 mrg (define_insn "*cond_<optab><mode>_any"
2977 1.1.1.5 mrg [(set (match_operand:SVE_I 0 "register_operand" "=&w, ?&w, ?&w")
2978 1.1.1.5 mrg (unspec:SVE_I
2979 1.1.1.3 mrg [(match_operand:<VPRED> 1 "register_operand" "Upl, Upl, Upl")
2980 1.1.1.5 mrg (SVE_INT_UNARY:SVE_I
2981 1.1.1.5 mrg (match_operand:SVE_I 2 "register_operand" "w, w, w"))
2982 1.1.1.5 mrg (match_operand:SVE_I 3 "aarch64_simd_reg_or_zero" "0, Dz, w")]
2983 1.1.1.3 mrg UNSPEC_SEL))]
2984 1.1.1.3 mrg "TARGET_SVE && !rtx_equal_p (operands[2], operands[3])"
2985 1.1.1.3 mrg "@
2986 1.1.1.3 mrg <sve_int_op>\t%0.<Vetype>, %1/m, %2.<Vetype>
2987 1.1.1.3 mrg movprfx\t%0.<Vetype>, %1/z, %2.<Vetype>\;<sve_int_op>\t%0.<Vetype>, %1/m, %2.<Vetype>
2988 1.1.1.3 mrg movprfx\t%0, %3\;<sve_int_op>\t%0.<Vetype>, %1/m, %2.<Vetype>"
2989 1.1.1.3 mrg [(set_attr "movprfx" "*,yes,yes")]
2990 1.1.1.3 mrg )
2991 1.1.1.3 mrg
2992 1.1.1.3 mrg ;; -------------------------------------------------------------------------
2993 1.1.1.3 mrg ;; ---- [INT] General unary arithmetic corresponding to unspecs
2994 1.1.1.3 mrg ;; -------------------------------------------------------------------------
2995 1.1.1.3 mrg ;; Includes
2996 1.1.1.3 mrg ;; - RBIT
2997 1.1.1.3 mrg ;; - REVB
2998 1.1.1.3 mrg ;; - REVH
2999 1.1.1.3 mrg ;; - REVW
3000 1.1.1.3 mrg ;; -------------------------------------------------------------------------
3001 1.1.1.3 mrg
3002 1.1.1.3 mrg ;; Predicated integer unary operations.
3003 1.1.1.3 mrg (define_insn "@aarch64_pred_<optab><mode>"
3004 1.1.1.3 mrg [(set (match_operand:SVE_FULL_I 0 "register_operand" "=w, ?&w")
3005 1.1.1.3 mrg (unspec:SVE_FULL_I
3006 1.1.1.3 mrg [(match_operand:<VPRED> 1 "register_operand" "Upl, Upl")
3007 1.1.1.3 mrg (unspec:SVE_FULL_I
3008 1.1.1.3 mrg [(match_operand:SVE_FULL_I 2 "register_operand" "0, w")]
3009 1.1.1.3 mrg SVE_INT_UNARY)]
3010 1.1.1.3 mrg UNSPEC_PRED_X))]
3011 1.1.1.3 mrg "TARGET_SVE && <elem_bits> >= <min_elem_bits>"
3012 1.1.1.3 mrg "@
3013 1.1.1.3 mrg <sve_int_op>\t%0.<Vetype>, %1/m, %2.<Vetype>
3014 1.1.1.3 mrg movprfx\t%0, %2\;<sve_int_op>\t%0.<Vetype>, %1/m, %2.<Vetype>"
3015 1.1.1.3 mrg [(set_attr "movprfx" "*,yes")]
3016 1.1.1.3 mrg )
3017 1.1.1.3 mrg
3018 1.1.1.5 mrg ;; Another way of expressing the REVB, REVH and REVW patterns, with this
3019 1.1.1.5 mrg ;; form being easier for permutes. The predicate mode determines the number
3020 1.1.1.5 mrg ;; of lanes and the data mode decides the granularity of the reversal within
3021 1.1.1.5 mrg ;; each lane.
3022 1.1.1.5 mrg (define_insn "@aarch64_sve_revbhw_<SVE_ALL:mode><PRED_HSD:mode>"
3023 1.1.1.5 mrg [(set (match_operand:SVE_ALL 0 "register_operand" "=w, ?&w")
3024 1.1.1.5 mrg (unspec:SVE_ALL
3025 1.1.1.5 mrg [(match_operand:PRED_HSD 1 "register_operand" "Upl, Upl")
3026 1.1.1.5 mrg (unspec:SVE_ALL
3027 1.1.1.5 mrg [(match_operand:SVE_ALL 2 "register_operand" "0, w")]
3028 1.1.1.5 mrg UNSPEC_REVBHW)]
3029 1.1.1.5 mrg UNSPEC_PRED_X))]
3030 1.1.1.5 mrg "TARGET_SVE && <PRED_HSD:elem_bits> > <SVE_ALL:container_bits>"
3031 1.1.1.5 mrg "@
3032 1.1.1.5 mrg rev<SVE_ALL:Vcwtype>\t%0.<PRED_HSD:Vetype>, %1/m, %2.<PRED_HSD:Vetype>
3033 1.1.1.5 mrg movprfx\t%0, %2\;rev<SVE_ALL:Vcwtype>\t%0.<PRED_HSD:Vetype>, %1/m, %2.<PRED_HSD:Vetype>"
3034 1.1.1.5 mrg [(set_attr "movprfx" "*,yes")]
3035 1.1.1.5 mrg )
3036 1.1.1.5 mrg
3037 1.1.1.3 mrg ;; Predicated integer unary operations with merging.
3038 1.1.1.3 mrg (define_insn "@cond_<optab><mode>"
3039 1.1.1.3 mrg [(set (match_operand:SVE_FULL_I 0 "register_operand" "=w, ?&w, ?&w")
3040 1.1.1.3 mrg (unspec:SVE_FULL_I
3041 1.1.1.3 mrg [(match_operand:<VPRED> 1 "register_operand" "Upl, Upl, Upl")
3042 1.1.1.3 mrg (unspec:SVE_FULL_I
3043 1.1.1.3 mrg [(match_operand:SVE_FULL_I 2 "register_operand" "w, w, w")]
3044 1.1.1.3 mrg SVE_INT_UNARY)
3045 1.1.1.3 mrg (match_operand:SVE_FULL_I 3 "aarch64_simd_reg_or_zero" "0, Dz, w")]
3046 1.1.1.3 mrg UNSPEC_SEL))]
3047 1.1.1.3 mrg "TARGET_SVE && <elem_bits> >= <min_elem_bits>"
3048 1.1.1.3 mrg "@
3049 1.1.1.3 mrg <sve_int_op>\t%0.<Vetype>, %1/m, %2.<Vetype>
3050 1.1.1.3 mrg movprfx\t%0.<Vetype>, %1/z, %2.<Vetype>\;<sve_int_op>\t%0.<Vetype>, %1/m, %2.<Vetype>
3051 1.1.1.3 mrg movprfx\t%0, %3\;<sve_int_op>\t%0.<Vetype>, %1/m, %2.<Vetype>"
3052 1.1.1.3 mrg [(set_attr "movprfx" "*,yes,yes")]
3053 1.1.1.3 mrg )
3054 1.1.1.3 mrg
3055 1.1.1.3 mrg ;; -------------------------------------------------------------------------
3056 1.1.1.3 mrg ;; ---- [INT] Sign and zero extension
3057 1.1.1.3 mrg ;; -------------------------------------------------------------------------
3058 1.1.1.3 mrg ;; Includes:
3059 1.1.1.3 mrg ;; - SXTB
3060 1.1.1.3 mrg ;; - SXTH
3061 1.1.1.3 mrg ;; - SXTW
3062 1.1.1.3 mrg ;; - UXTB
3063 1.1.1.3 mrg ;; - UXTH
3064 1.1.1.3 mrg ;; - UXTW
3065 1.1.1.3 mrg ;; -------------------------------------------------------------------------
3066 1.1.1.3 mrg
3067 1.1.1.3 mrg ;; Unpredicated sign and zero extension from a narrower mode.
3068 1.1.1.3 mrg (define_expand "<optab><SVE_PARTIAL_I:mode><SVE_HSDI:mode>2"
3069 1.1.1.3 mrg [(set (match_operand:SVE_HSDI 0 "register_operand")
3070 1.1.1.3 mrg (unspec:SVE_HSDI
3071 1.1.1.3 mrg [(match_dup 2)
3072 1.1.1.3 mrg (ANY_EXTEND:SVE_HSDI
3073 1.1.1.3 mrg (match_operand:SVE_PARTIAL_I 1 "register_operand"))]
3074 1.1.1.3 mrg UNSPEC_PRED_X))]
3075 1.1.1.3 mrg "TARGET_SVE && (~<SVE_HSDI:narrower_mask> & <SVE_PARTIAL_I:self_mask>) == 0"
3076 1.1.1.3 mrg {
3077 1.1.1.3 mrg operands[2] = aarch64_ptrue_reg (<SVE_HSDI:VPRED>mode);
3078 1.1.1.3 mrg }
3079 1.1.1.3 mrg )
3080 1.1.1.3 mrg
3081 1.1.1.3 mrg ;; Predicated sign and zero extension from a narrower mode.
3082 1.1.1.3 mrg (define_insn "*<optab><SVE_PARTIAL_I:mode><SVE_HSDI:mode>2"
3083 1.1.1.3 mrg [(set (match_operand:SVE_HSDI 0 "register_operand" "=w, ?&w")
3084 1.1.1.3 mrg (unspec:SVE_HSDI
3085 1.1.1.3 mrg [(match_operand:<SVE_HSDI:VPRED> 1 "register_operand" "Upl, Upl")
3086 1.1.1.3 mrg (ANY_EXTEND:SVE_HSDI
3087 1.1.1.3 mrg (match_operand:SVE_PARTIAL_I 2 "register_operand" "0, w"))]
3088 1.1.1.3 mrg UNSPEC_PRED_X))]
3089 1.1.1.3 mrg "TARGET_SVE && (~<SVE_HSDI:narrower_mask> & <SVE_PARTIAL_I:self_mask>) == 0"
3090 1.1.1.3 mrg "@
3091 1.1.1.3 mrg <su>xt<SVE_PARTIAL_I:Vesize>\t%0.<SVE_HSDI:Vetype>, %1/m, %2.<SVE_HSDI:Vetype>
3092 1.1.1.3 mrg movprfx\t%0, %2\;<su>xt<SVE_PARTIAL_I:Vesize>\t%0.<SVE_HSDI:Vetype>, %1/m, %2.<SVE_HSDI:Vetype>"
3093 1.1.1.3 mrg [(set_attr "movprfx" "*,yes")]
3094 1.1.1.3 mrg )
3095 1.1.1.3 mrg
3096 1.1.1.3 mrg ;; Predicated truncate-and-sign-extend operations.
3097 1.1.1.3 mrg (define_insn "@aarch64_pred_sxt<SVE_FULL_HSDI:mode><SVE_PARTIAL_I:mode>"
3098 1.1.1.3 mrg [(set (match_operand:SVE_FULL_HSDI 0 "register_operand" "=w, ?&w")
3099 1.1.1.3 mrg (unspec:SVE_FULL_HSDI
3100 1.1.1.3 mrg [(match_operand:<SVE_FULL_HSDI:VPRED> 1 "register_operand" "Upl, Upl")
3101 1.1.1.3 mrg (sign_extend:SVE_FULL_HSDI
3102 1.1.1.3 mrg (truncate:SVE_PARTIAL_I
3103 1.1.1.3 mrg (match_operand:SVE_FULL_HSDI 2 "register_operand" "0, w")))]
3104 1.1.1.3 mrg UNSPEC_PRED_X))]
3105 1.1.1.3 mrg "TARGET_SVE
3106 1.1.1.3 mrg && (~<SVE_FULL_HSDI:narrower_mask> & <SVE_PARTIAL_I:self_mask>) == 0"
3107 1.1.1.3 mrg "@
3108 1.1.1.3 mrg sxt<SVE_PARTIAL_I:Vesize>\t%0.<SVE_FULL_HSDI:Vetype>, %1/m, %2.<SVE_FULL_HSDI:Vetype>
3109 1.1.1.3 mrg movprfx\t%0, %2\;sxt<SVE_PARTIAL_I:Vesize>\t%0.<SVE_FULL_HSDI:Vetype>, %1/m, %2.<SVE_FULL_HSDI:Vetype>"
3110 1.1.1.3 mrg [(set_attr "movprfx" "*,yes")]
3111 1.1.1.3 mrg )
3112 1.1.1.3 mrg
3113 1.1.1.3 mrg ;; Predicated truncate-and-sign-extend operations with merging.
3114 1.1.1.3 mrg (define_insn "@aarch64_cond_sxt<SVE_FULL_HSDI:mode><SVE_PARTIAL_I:mode>"
3115 1.1.1.3 mrg [(set (match_operand:SVE_FULL_HSDI 0 "register_operand" "=w, ?&w, ?&w")
3116 1.1.1.3 mrg (unspec:SVE_FULL_HSDI
3117 1.1.1.3 mrg [(match_operand:<SVE_FULL_HSDI:VPRED> 1 "register_operand" "Upl, Upl, Upl")
3118 1.1.1.3 mrg (sign_extend:SVE_FULL_HSDI
3119 1.1.1.3 mrg (truncate:SVE_PARTIAL_I
3120 1.1.1.3 mrg (match_operand:SVE_FULL_HSDI 2 "register_operand" "w, w, w")))
3121 1.1.1.3 mrg (match_operand:SVE_FULL_HSDI 3 "aarch64_simd_reg_or_zero" "0, Dz, w")]
3122 1.1.1.3 mrg UNSPEC_SEL))]
3123 1.1.1.3 mrg "TARGET_SVE
3124 1.1.1.3 mrg && (~<SVE_FULL_HSDI:narrower_mask> & <SVE_PARTIAL_I:self_mask>) == 0"
3125 1.1.1.3 mrg "@
3126 1.1.1.3 mrg sxt<SVE_PARTIAL_I:Vesize>\t%0.<SVE_FULL_HSDI:Vetype>, %1/m, %2.<SVE_FULL_HSDI:Vetype>
3127 1.1.1.3 mrg movprfx\t%0.<SVE_FULL_HSDI:Vetype>, %1/z, %2.<SVE_FULL_HSDI:Vetype>\;sxt<SVE_PARTIAL_I:Vesize>\t%0.<SVE_FULL_HSDI:Vetype>, %1/m, %2.<SVE_FULL_HSDI:Vetype>
3128 1.1.1.3 mrg movprfx\t%0, %3\;sxt<SVE_PARTIAL_I:Vesize>\t%0.<SVE_FULL_HSDI:Vetype>, %1/m, %2.<SVE_FULL_HSDI:Vetype>"
3129 1.1.1.3 mrg [(set_attr "movprfx" "*,yes,yes")]
3130 1.1.1.3 mrg )
3131 1.1.1.3 mrg
3132 1.1.1.3 mrg ;; Predicated truncate-and-zero-extend operations, merging with the
3133 1.1.1.3 mrg ;; first input.
3134 1.1.1.3 mrg ;;
3135 1.1.1.3 mrg ;; The canonical form of this operation is an AND of a constant rather
3136 1.1.1.3 mrg ;; than (zero_extend (truncate ...)).
3137 1.1.1.3 mrg (define_insn "*cond_uxt<mode>_2"
3138 1.1.1.5 mrg [(set (match_operand:SVE_I 0 "register_operand" "=w, ?&w")
3139 1.1.1.5 mrg (unspec:SVE_I
3140 1.1.1.3 mrg [(match_operand:<VPRED> 1 "register_operand" "Upl, Upl")
3141 1.1.1.5 mrg (and:SVE_I
3142 1.1.1.5 mrg (match_operand:SVE_I 2 "register_operand" "0, w")
3143 1.1.1.5 mrg (match_operand:SVE_I 3 "aarch64_sve_uxt_immediate"))
3144 1.1.1.3 mrg (match_dup 2)]
3145 1.1.1.3 mrg UNSPEC_SEL))]
3146 1.1.1.3 mrg "TARGET_SVE"
3147 1.1.1.3 mrg "@
3148 1.1.1.3 mrg uxt%e3\t%0.<Vetype>, %1/m, %0.<Vetype>
3149 1.1.1.3 mrg movprfx\t%0, %2\;uxt%e3\t%0.<Vetype>, %1/m, %2.<Vetype>"
3150 1.1.1.3 mrg [(set_attr "movprfx" "*,yes")]
3151 1.1.1.3 mrg )
3152 1.1.1.3 mrg
3153 1.1.1.3 mrg ;; Predicated truncate-and-zero-extend operations, merging with an
3154 1.1.1.3 mrg ;; independent value.
3155 1.1.1.3 mrg ;;
3156 1.1.1.3 mrg ;; The earlyclobber isn't needed for the first alternative, but omitting
3157 1.1.1.3 mrg ;; it would only help the case in which operands 2 and 4 are the same,
3158 1.1.1.3 mrg ;; which is handled above rather than here. Marking all the alternatives
3159 1.1.1.3 mrg ;; as early-clobber helps to make the instruction more regular to the
3160 1.1.1.3 mrg ;; register allocator.
3161 1.1.1.3 mrg (define_insn "*cond_uxt<mode>_any"
3162 1.1.1.5 mrg [(set (match_operand:SVE_I 0 "register_operand" "=&w, ?&w, ?&w")
3163 1.1.1.5 mrg (unspec:SVE_I
3164 1.1.1.3 mrg [(match_operand:<VPRED> 1 "register_operand" "Upl, Upl, Upl")
3165 1.1.1.5 mrg (and:SVE_I
3166 1.1.1.5 mrg (match_operand:SVE_I 2 "register_operand" "w, w, w")
3167 1.1.1.5 mrg (match_operand:SVE_I 3 "aarch64_sve_uxt_immediate"))
3168 1.1.1.5 mrg (match_operand:SVE_I 4 "aarch64_simd_reg_or_zero" "0, Dz, w")]
3169 1.1.1.3 mrg UNSPEC_SEL))]
3170 1.1.1.3 mrg "TARGET_SVE && !rtx_equal_p (operands[2], operands[4])"
3171 1.1.1.3 mrg "@
3172 1.1.1.3 mrg uxt%e3\t%0.<Vetype>, %1/m, %2.<Vetype>
3173 1.1.1.3 mrg movprfx\t%0.<Vetype>, %1/z, %2.<Vetype>\;uxt%e3\t%0.<Vetype>, %1/m, %2.<Vetype>
3174 1.1.1.3 mrg movprfx\t%0, %4\;uxt%e3\t%0.<Vetype>, %1/m, %2.<Vetype>"
3175 1.1.1.3 mrg [(set_attr "movprfx" "*,yes,yes")]
3176 1.1.1.3 mrg )
3177 1.1.1.3 mrg
3178 1.1.1.3 mrg ;; -------------------------------------------------------------------------
3179 1.1.1.3 mrg ;; ---- [INT] Truncation
3180 1.1.1.3 mrg ;; -------------------------------------------------------------------------
3181 1.1.1.3 mrg ;; The patterns in this section are synthetic.
3182 1.1.1.3 mrg ;; -------------------------------------------------------------------------
3183 1.1.1.3 mrg
3184 1.1.1.3 mrg ;; Truncate to a partial SVE vector from either a full vector or a
3185 1.1.1.3 mrg ;; wider partial vector. This is a no-op, because we can just ignore
3186 1.1.1.3 mrg ;; the unused upper bits of the source.
3187 1.1.1.3 mrg (define_insn_and_split "trunc<SVE_HSDI:mode><SVE_PARTIAL_I:mode>2"
3188 1.1.1.3 mrg [(set (match_operand:SVE_PARTIAL_I 0 "register_operand" "=w")
3189 1.1.1.3 mrg (truncate:SVE_PARTIAL_I
3190 1.1.1.3 mrg (match_operand:SVE_HSDI 1 "register_operand" "w")))]
3191 1.1.1.3 mrg "TARGET_SVE && (~<SVE_HSDI:narrower_mask> & <SVE_PARTIAL_I:self_mask>) == 0"
3192 1.1.1.3 mrg "#"
3193 1.1.1.3 mrg "&& reload_completed"
3194 1.1.1.3 mrg [(set (match_dup 0) (match_dup 1))]
3195 1.1.1.3 mrg {
3196 1.1.1.3 mrg operands[1] = aarch64_replace_reg_mode (operands[1],
3197 1.1.1.3 mrg <SVE_PARTIAL_I:MODE>mode);
3198 1.1.1.3 mrg }
3199 1.1.1.3 mrg )
3200 1.1.1.3 mrg
3201 1.1.1.3 mrg ;; -------------------------------------------------------------------------
3202 1.1.1.3 mrg ;; ---- [INT] Logical inverse
3203 1.1.1.3 mrg ;; -------------------------------------------------------------------------
3204 1.1.1.3 mrg ;; Includes:
3205 1.1.1.3 mrg ;; - CNOT
3206 1.1.1.3 mrg ;; -------------------------------------------------------------------------
3207 1.1.1.3 mrg
3208 1.1.1.5 mrg ;; Logical inverse, predicated with a ptrue.
3209 1.1.1.5 mrg (define_expand "@aarch64_ptrue_cnot<mode>"
3210 1.1.1.3 mrg [(set (match_operand:SVE_FULL_I 0 "register_operand")
3211 1.1.1.3 mrg (unspec:SVE_FULL_I
3212 1.1.1.3 mrg [(unspec:<VPRED>
3213 1.1.1.3 mrg [(match_operand:<VPRED> 1 "register_operand")
3214 1.1.1.5 mrg (const_int SVE_KNOWN_PTRUE)
3215 1.1.1.3 mrg (eq:<VPRED>
3216 1.1.1.5 mrg (match_operand:SVE_FULL_I 2 "register_operand")
3217 1.1.1.5 mrg (match_dup 3))]
3218 1.1.1.3 mrg UNSPEC_PRED_Z)
3219 1.1.1.5 mrg (match_dup 4)
3220 1.1.1.5 mrg (match_dup 3)]
3221 1.1.1.3 mrg UNSPEC_SEL))]
3222 1.1.1.3 mrg "TARGET_SVE"
3223 1.1.1.3 mrg {
3224 1.1.1.5 mrg operands[3] = CONST0_RTX (<MODE>mode);
3225 1.1.1.5 mrg operands[4] = CONST1_RTX (<MODE>mode);
3226 1.1.1.3 mrg }
3227 1.1.1.3 mrg )
3228 1.1.1.3 mrg
3229 1.1.1.3 mrg (define_insn "*cnot<mode>"
3230 1.1.1.5 mrg [(set (match_operand:SVE_I 0 "register_operand" "=w, ?&w")
3231 1.1.1.5 mrg (unspec:SVE_I
3232 1.1.1.3 mrg [(unspec:<VPRED>
3233 1.1.1.3 mrg [(match_operand:<VPRED> 1 "register_operand" "Upl, Upl")
3234 1.1.1.5 mrg (const_int SVE_KNOWN_PTRUE)
3235 1.1.1.3 mrg (eq:<VPRED>
3236 1.1.1.5 mrg (match_operand:SVE_I 2 "register_operand" "0, w")
3237 1.1.1.5 mrg (match_operand:SVE_I 3 "aarch64_simd_imm_zero"))]
3238 1.1.1.3 mrg UNSPEC_PRED_Z)
3239 1.1.1.5 mrg (match_operand:SVE_I 4 "aarch64_simd_imm_one")
3240 1.1.1.3 mrg (match_dup 3)]
3241 1.1.1.3 mrg UNSPEC_SEL))]
3242 1.1.1.3 mrg "TARGET_SVE"
3243 1.1.1.3 mrg "@
3244 1.1.1.3 mrg cnot\t%0.<Vetype>, %1/m, %2.<Vetype>
3245 1.1.1.3 mrg movprfx\t%0, %2\;cnot\t%0.<Vetype>, %1/m, %2.<Vetype>"
3246 1.1.1.3 mrg [(set_attr "movprfx" "*,yes")]
3247 1.1.1.3 mrg )
3248 1.1.1.3 mrg
3249 1.1.1.3 mrg ;; Predicated logical inverse with merging.
3250 1.1.1.3 mrg (define_expand "@cond_cnot<mode>"
3251 1.1.1.3 mrg [(set (match_operand:SVE_FULL_I 0 "register_operand")
3252 1.1.1.3 mrg (unspec:SVE_FULL_I
3253 1.1.1.3 mrg [(match_operand:<VPRED> 1 "register_operand")
3254 1.1.1.3 mrg (unspec:SVE_FULL_I
3255 1.1.1.3 mrg [(unspec:<VPRED>
3256 1.1.1.3 mrg [(match_dup 4)
3257 1.1.1.3 mrg (const_int SVE_KNOWN_PTRUE)
3258 1.1.1.3 mrg (eq:<VPRED>
3259 1.1.1.3 mrg (match_operand:SVE_FULL_I 2 "register_operand")
3260 1.1.1.3 mrg (match_dup 5))]
3261 1.1.1.3 mrg UNSPEC_PRED_Z)
3262 1.1.1.3 mrg (match_dup 6)
3263 1.1.1.3 mrg (match_dup 5)]
3264 1.1.1.3 mrg UNSPEC_SEL)
3265 1.1.1.3 mrg (match_operand:SVE_FULL_I 3 "aarch64_simd_reg_or_zero")]
3266 1.1.1.3 mrg UNSPEC_SEL))]
3267 1.1.1.3 mrg "TARGET_SVE"
3268 1.1.1.3 mrg {
3269 1.1.1.3 mrg operands[4] = CONSTM1_RTX (<VPRED>mode);
3270 1.1.1.3 mrg operands[5] = CONST0_RTX (<MODE>mode);
3271 1.1.1.3 mrg operands[6] = CONST1_RTX (<MODE>mode);
3272 1.1.1.3 mrg }
3273 1.1.1.3 mrg )
3274 1.1.1.3 mrg
3275 1.1.1.3 mrg ;; Predicated logical inverse, merging with the first input.
3276 1.1.1.3 mrg (define_insn_and_rewrite "*cond_cnot<mode>_2"
3277 1.1.1.5 mrg [(set (match_operand:SVE_I 0 "register_operand" "=w, ?&w")
3278 1.1.1.5 mrg (unspec:SVE_I
3279 1.1.1.3 mrg [(match_operand:<VPRED> 1 "register_operand" "Upl, Upl")
3280 1.1.1.3 mrg ;; Logical inverse of operand 2 (as above).
3281 1.1.1.5 mrg (unspec:SVE_I
3282 1.1.1.3 mrg [(unspec:<VPRED>
3283 1.1.1.3 mrg [(match_operand 5)
3284 1.1.1.3 mrg (const_int SVE_KNOWN_PTRUE)
3285 1.1.1.3 mrg (eq:<VPRED>
3286 1.1.1.5 mrg (match_operand:SVE_I 2 "register_operand" "0, w")
3287 1.1.1.5 mrg (match_operand:SVE_I 3 "aarch64_simd_imm_zero"))]
3288 1.1.1.3 mrg UNSPEC_PRED_Z)
3289 1.1.1.5 mrg (match_operand:SVE_I 4 "aarch64_simd_imm_one")
3290 1.1.1.3 mrg (match_dup 3)]
3291 1.1.1.3 mrg UNSPEC_SEL)
3292 1.1.1.3 mrg (match_dup 2)]
3293 1.1.1.3 mrg UNSPEC_SEL))]
3294 1.1.1.3 mrg "TARGET_SVE"
3295 1.1.1.3 mrg "@
3296 1.1.1.3 mrg cnot\t%0.<Vetype>, %1/m, %0.<Vetype>
3297 1.1.1.3 mrg movprfx\t%0, %2\;cnot\t%0.<Vetype>, %1/m, %2.<Vetype>"
3298 1.1.1.3 mrg "&& !CONSTANT_P (operands[5])"
3299 1.1.1.3 mrg {
3300 1.1.1.3 mrg operands[5] = CONSTM1_RTX (<VPRED>mode);
3301 1.1.1.3 mrg }
3302 1.1.1.3 mrg [(set_attr "movprfx" "*,yes")]
3303 1.1.1.3 mrg )
3304 1.1.1.3 mrg
3305 1.1.1.3 mrg ;; Predicated logical inverse, merging with an independent value.
3306 1.1.1.3 mrg ;;
3307 1.1.1.3 mrg ;; The earlyclobber isn't needed for the first alternative, but omitting
3308 1.1.1.3 mrg ;; it would only help the case in which operands 2 and 6 are the same,
3309 1.1.1.3 mrg ;; which is handled above rather than here. Marking all the alternatives
3310 1.1.1.3 mrg ;; as earlyclobber helps to make the instruction more regular to the
3311 1.1.1.3 mrg ;; register allocator.
3312 1.1.1.3 mrg (define_insn_and_rewrite "*cond_cnot<mode>_any"
3313 1.1.1.5 mrg [(set (match_operand:SVE_I 0 "register_operand" "=&w, ?&w, ?&w")
3314 1.1.1.5 mrg (unspec:SVE_I
3315 1.1.1.3 mrg [(match_operand:<VPRED> 1 "register_operand" "Upl, Upl, Upl")
3316 1.1.1.3 mrg ;; Logical inverse of operand 2 (as above).
3317 1.1.1.5 mrg (unspec:SVE_I
3318 1.1.1.3 mrg [(unspec:<VPRED>
3319 1.1.1.3 mrg [(match_operand 5)
3320 1.1.1.3 mrg (const_int SVE_KNOWN_PTRUE)
3321 1.1.1.3 mrg (eq:<VPRED>
3322 1.1.1.5 mrg (match_operand:SVE_I 2 "register_operand" "w, w, w")
3323 1.1.1.5 mrg (match_operand:SVE_I 3 "aarch64_simd_imm_zero"))]
3324 1.1.1.3 mrg UNSPEC_PRED_Z)
3325 1.1.1.5 mrg (match_operand:SVE_I 4 "aarch64_simd_imm_one")
3326 1.1.1.3 mrg (match_dup 3)]
3327 1.1.1.3 mrg UNSPEC_SEL)
3328 1.1.1.5 mrg (match_operand:SVE_I 6 "aarch64_simd_reg_or_zero" "0, Dz, w")]
3329 1.1.1.3 mrg UNSPEC_SEL))]
3330 1.1.1.3 mrg "TARGET_SVE && !rtx_equal_p (operands[2], operands[6])"
3331 1.1.1.3 mrg "@
3332 1.1.1.3 mrg cnot\t%0.<Vetype>, %1/m, %2.<Vetype>
3333 1.1.1.3 mrg movprfx\t%0.<Vetype>, %1/z, %2.<Vetype>\;cnot\t%0.<Vetype>, %1/m, %2.<Vetype>
3334 1.1.1.3 mrg movprfx\t%0, %6\;cnot\t%0.<Vetype>, %1/m, %2.<Vetype>"
3335 1.1.1.3 mrg "&& !CONSTANT_P (operands[5])"
3336 1.1.1.3 mrg {
3337 1.1.1.3 mrg operands[5] = CONSTM1_RTX (<VPRED>mode);
3338 1.1.1.3 mrg }
3339 1.1.1.3 mrg [(set_attr "movprfx" "*,yes,yes")]
3340 1.1.1.3 mrg )
3341 1.1.1.3 mrg
3342 1.1.1.3 mrg ;; -------------------------------------------------------------------------
3343 1.1.1.3 mrg ;; ---- [FP<-INT] General unary arithmetic that maps to unspecs
3344 1.1.1.3 mrg ;; -------------------------------------------------------------------------
3345 1.1.1.3 mrg ;; Includes:
3346 1.1.1.3 mrg ;; - FEXPA
3347 1.1.1.3 mrg ;; -------------------------------------------------------------------------
3348 1.1.1.3 mrg
3349 1.1.1.3 mrg ;; Unpredicated unary operations that take an integer and return a float.
3350 1.1.1.3 mrg (define_insn "@aarch64_sve_<optab><mode>"
3351 1.1.1.3 mrg [(set (match_operand:SVE_FULL_F 0 "register_operand" "=w")
3352 1.1.1.3 mrg (unspec:SVE_FULL_F
3353 1.1.1.3 mrg [(match_operand:<V_INT_EQUIV> 1 "register_operand" "w")]
3354 1.1.1.3 mrg SVE_FP_UNARY_INT))]
3355 1.1.1.3 mrg "TARGET_SVE"
3356 1.1.1.3 mrg "<sve_fp_op>\t%0.<Vetype>, %1.<Vetype>"
3357 1.1.1.3 mrg )
3358 1.1.1.3 mrg
3359 1.1.1.3 mrg ;; -------------------------------------------------------------------------
3360 1.1.1.3 mrg ;; ---- [FP] General unary arithmetic corresponding to unspecs
3361 1.1.1.3 mrg ;; -------------------------------------------------------------------------
3362 1.1.1.3 mrg ;; Includes:
3363 1.1.1.3 mrg ;; - FABS
3364 1.1.1.3 mrg ;; - FNEG
3365 1.1.1.3 mrg ;; - FRECPE
3366 1.1.1.3 mrg ;; - FRECPX
3367 1.1.1.3 mrg ;; - FRINTA
3368 1.1.1.3 mrg ;; - FRINTI
3369 1.1.1.3 mrg ;; - FRINTM
3370 1.1.1.3 mrg ;; - FRINTN
3371 1.1.1.3 mrg ;; - FRINTP
3372 1.1.1.3 mrg ;; - FRINTX
3373 1.1.1.3 mrg ;; - FRINTZ
3374 1.1.1.3 mrg ;; - FRSQRTE
3375 1.1.1.3 mrg ;; - FSQRT
3376 1.1.1.3 mrg ;; -------------------------------------------------------------------------
3377 1.1.1.3 mrg
3378 1.1.1.3 mrg ;; Unpredicated floating-point unary operations.
3379 1.1.1.3 mrg (define_insn "@aarch64_sve_<optab><mode>"
3380 1.1.1.3 mrg [(set (match_operand:SVE_FULL_F 0 "register_operand" "=w")
3381 1.1.1.3 mrg (unspec:SVE_FULL_F
3382 1.1.1.3 mrg [(match_operand:SVE_FULL_F 1 "register_operand" "w")]
3383 1.1.1.3 mrg SVE_FP_UNARY))]
3384 1.1.1.3 mrg "TARGET_SVE"
3385 1.1.1.3 mrg "<sve_fp_op>\t%0.<Vetype>, %1.<Vetype>"
3386 1.1.1.3 mrg )
3387 1.1.1.3 mrg
3388 1.1.1.3 mrg ;; Unpredicated floating-point unary operations.
3389 1.1.1.3 mrg (define_expand "<optab><mode>2"
3390 1.1.1.3 mrg [(set (match_operand:SVE_FULL_F 0 "register_operand")
3391 1.1.1.3 mrg (unspec:SVE_FULL_F
3392 1.1.1.3 mrg [(match_dup 2)
3393 1.1.1.3 mrg (const_int SVE_RELAXED_GP)
3394 1.1.1.3 mrg (match_operand:SVE_FULL_F 1 "register_operand")]
3395 1.1.1.3 mrg SVE_COND_FP_UNARY_OPTAB))]
3396 1.1.1.3 mrg "TARGET_SVE"
3397 1.1.1.3 mrg {
3398 1.1.1.3 mrg operands[2] = aarch64_ptrue_reg (<VPRED>mode);
3399 1.1.1.3 mrg }
3400 1.1.1.3 mrg )
3401 1.1.1.3 mrg
3402 1.1.1.3 mrg ;; Predicated floating-point unary operations.
3403 1.1.1.3 mrg (define_insn "@aarch64_pred_<optab><mode>"
3404 1.1.1.3 mrg [(set (match_operand:SVE_FULL_F 0 "register_operand" "=w, ?&w")
3405 1.1.1.3 mrg (unspec:SVE_FULL_F
3406 1.1.1.3 mrg [(match_operand:<VPRED> 1 "register_operand" "Upl, Upl")
3407 1.1.1.3 mrg (match_operand:SI 3 "aarch64_sve_gp_strictness")
3408 1.1.1.3 mrg (match_operand:SVE_FULL_F 2 "register_operand" "0, w")]
3409 1.1.1.3 mrg SVE_COND_FP_UNARY))]
3410 1.1.1.3 mrg "TARGET_SVE"
3411 1.1.1.3 mrg "@
3412 1.1.1.3 mrg <sve_fp_op>\t%0.<Vetype>, %1/m, %2.<Vetype>
3413 1.1.1.3 mrg movprfx\t%0, %2\;<sve_fp_op>\t%0.<Vetype>, %1/m, %2.<Vetype>"
3414 1.1.1.3 mrg [(set_attr "movprfx" "*,yes")]
3415 1.1.1.3 mrg )
3416 1.1.1.3 mrg
3417 1.1.1.3 mrg ;; Predicated floating-point unary arithmetic with merging.
3418 1.1.1.3 mrg (define_expand "@cond_<optab><mode>"
3419 1.1.1.3 mrg [(set (match_operand:SVE_FULL_F 0 "register_operand")
3420 1.1.1.3 mrg (unspec:SVE_FULL_F
3421 1.1.1.3 mrg [(match_operand:<VPRED> 1 "register_operand")
3422 1.1.1.3 mrg (unspec:SVE_FULL_F
3423 1.1.1.3 mrg [(match_dup 1)
3424 1.1.1.3 mrg (const_int SVE_STRICT_GP)
3425 1.1.1.3 mrg (match_operand:SVE_FULL_F 2 "register_operand")]
3426 1.1.1.3 mrg SVE_COND_FP_UNARY)
3427 1.1.1.3 mrg (match_operand:SVE_FULL_F 3 "aarch64_simd_reg_or_zero")]
3428 1.1.1.3 mrg UNSPEC_SEL))]
3429 1.1.1.3 mrg "TARGET_SVE"
3430 1.1.1.3 mrg )
3431 1.1.1.3 mrg
3432 1.1.1.3 mrg ;; Predicated floating-point unary arithmetic, merging with the first input.
3433 1.1.1.3 mrg (define_insn_and_rewrite "*cond_<optab><mode>_2_relaxed"
3434 1.1.1.3 mrg [(set (match_operand:SVE_FULL_F 0 "register_operand" "=w, ?&w")
3435 1.1.1.3 mrg (unspec:SVE_FULL_F
3436 1.1.1.3 mrg [(match_operand:<VPRED> 1 "register_operand" "Upl, Upl")
3437 1.1.1.3 mrg (unspec:SVE_FULL_F
3438 1.1.1.3 mrg [(match_operand 3)
3439 1.1.1.3 mrg (const_int SVE_RELAXED_GP)
3440 1.1.1.3 mrg (match_operand:SVE_FULL_F 2 "register_operand" "0, w")]
3441 1.1.1.3 mrg SVE_COND_FP_UNARY)
3442 1.1.1.3 mrg (match_dup 2)]
3443 1.1.1.3 mrg UNSPEC_SEL))]
3444 1.1.1.3 mrg "TARGET_SVE"
3445 1.1.1.3 mrg "@
3446 1.1.1.3 mrg <sve_fp_op>\t%0.<Vetype>, %1/m, %0.<Vetype>
3447 1.1.1.3 mrg movprfx\t%0, %2\;<sve_fp_op>\t%0.<Vetype>, %1/m, %2.<Vetype>"
3448 1.1.1.3 mrg "&& !rtx_equal_p (operands[1], operands[3])"
3449 1.1.1.3 mrg {
3450 1.1.1.3 mrg operands[3] = copy_rtx (operands[1]);
3451 1.1.1.3 mrg }
3452 1.1.1.3 mrg [(set_attr "movprfx" "*,yes")]
3453 1.1.1.3 mrg )
3454 1.1.1.3 mrg
3455 1.1.1.3 mrg (define_insn "*cond_<optab><mode>_2_strict"
3456 1.1.1.3 mrg [(set (match_operand:SVE_FULL_F 0 "register_operand" "=w, ?&w")
3457 1.1.1.3 mrg (unspec:SVE_FULL_F
3458 1.1.1.3 mrg [(match_operand:<VPRED> 1 "register_operand" "Upl, Upl")
3459 1.1.1.3 mrg (unspec:SVE_FULL_F
3460 1.1.1.3 mrg [(match_dup 1)
3461 1.1.1.3 mrg (const_int SVE_STRICT_GP)
3462 1.1.1.3 mrg (match_operand:SVE_FULL_F 2 "register_operand" "0, w")]
3463 1.1.1.3 mrg SVE_COND_FP_UNARY)
3464 1.1.1.3 mrg (match_dup 2)]
3465 1.1.1.3 mrg UNSPEC_SEL))]
3466 1.1.1.3 mrg "TARGET_SVE"
3467 1.1.1.3 mrg "@
3468 1.1.1.3 mrg <sve_fp_op>\t%0.<Vetype>, %1/m, %0.<Vetype>
3469 1.1.1.3 mrg movprfx\t%0, %2\;<sve_fp_op>\t%0.<Vetype>, %1/m, %2.<Vetype>"
3470 1.1.1.3 mrg [(set_attr "movprfx" "*,yes")]
3471 1.1.1.3 mrg )
3472 1.1.1.3 mrg
3473 1.1.1.3 mrg ;; Predicated floating-point unary arithmetic, merging with an independent
3474 1.1.1.3 mrg ;; value.
3475 1.1.1.3 mrg ;;
3476 1.1.1.3 mrg ;; The earlyclobber isn't needed for the first alternative, but omitting
3477 1.1.1.3 mrg ;; it would only help the case in which operands 2 and 3 are the same,
3478 1.1.1.3 mrg ;; which is handled above rather than here. Marking all the alternatives
3479 1.1.1.3 mrg ;; as earlyclobber helps to make the instruction more regular to the
3480 1.1.1.3 mrg ;; register allocator.
3481 1.1.1.3 mrg (define_insn_and_rewrite "*cond_<optab><mode>_any_relaxed"
3482 1.1.1.3 mrg [(set (match_operand:SVE_FULL_F 0 "register_operand" "=&w, ?&w, ?&w")
3483 1.1.1.3 mrg (unspec:SVE_FULL_F
3484 1.1.1.3 mrg [(match_operand:<VPRED> 1 "register_operand" "Upl, Upl, Upl")
3485 1.1.1.3 mrg (unspec:SVE_FULL_F
3486 1.1.1.3 mrg [(match_operand 4)
3487 1.1.1.3 mrg (const_int SVE_RELAXED_GP)
3488 1.1.1.3 mrg (match_operand:SVE_FULL_F 2 "register_operand" "w, w, w")]
3489 1.1.1.3 mrg SVE_COND_FP_UNARY)
3490 1.1.1.3 mrg (match_operand:SVE_FULL_F 3 "aarch64_simd_reg_or_zero" "0, Dz, w")]
3491 1.1.1.3 mrg UNSPEC_SEL))]
3492 1.1.1.3 mrg "TARGET_SVE && !rtx_equal_p (operands[2], operands[3])"
3493 1.1.1.3 mrg "@
3494 1.1.1.3 mrg <sve_fp_op>\t%0.<Vetype>, %1/m, %2.<Vetype>
3495 1.1.1.3 mrg movprfx\t%0.<Vetype>, %1/z, %2.<Vetype>\;<sve_fp_op>\t%0.<Vetype>, %1/m, %2.<Vetype>
3496 1.1.1.3 mrg movprfx\t%0, %3\;<sve_fp_op>\t%0.<Vetype>, %1/m, %2.<Vetype>"
3497 1.1.1.3 mrg "&& !rtx_equal_p (operands[1], operands[4])"
3498 1.1.1.3 mrg {
3499 1.1.1.3 mrg operands[4] = copy_rtx (operands[1]);
3500 1.1.1.3 mrg }
3501 1.1.1.3 mrg [(set_attr "movprfx" "*,yes,yes")]
3502 1.1.1.3 mrg )
3503 1.1.1.3 mrg
3504 1.1.1.3 mrg (define_insn "*cond_<optab><mode>_any_strict"
3505 1.1.1.3 mrg [(set (match_operand:SVE_FULL_F 0 "register_operand" "=&w, ?&w, ?&w")
3506 1.1.1.3 mrg (unspec:SVE_FULL_F
3507 1.1.1.3 mrg [(match_operand:<VPRED> 1 "register_operand" "Upl, Upl, Upl")
3508 1.1.1.3 mrg (unspec:SVE_FULL_F
3509 1.1.1.3 mrg [(match_dup 1)
3510 1.1.1.3 mrg (const_int SVE_STRICT_GP)
3511 1.1.1.3 mrg (match_operand:SVE_FULL_F 2 "register_operand" "w, w, w")]
3512 1.1.1.3 mrg SVE_COND_FP_UNARY)
3513 1.1.1.3 mrg (match_operand:SVE_FULL_F 3 "aarch64_simd_reg_or_zero" "0, Dz, w")]
3514 1.1.1.3 mrg UNSPEC_SEL))]
3515 1.1.1.3 mrg "TARGET_SVE && !rtx_equal_p (operands[2], operands[3])"
3516 1.1.1.3 mrg "@
3517 1.1.1.3 mrg <sve_fp_op>\t%0.<Vetype>, %1/m, %2.<Vetype>
3518 1.1.1.3 mrg movprfx\t%0.<Vetype>, %1/z, %2.<Vetype>\;<sve_fp_op>\t%0.<Vetype>, %1/m, %2.<Vetype>
3519 1.1.1.3 mrg movprfx\t%0, %3\;<sve_fp_op>\t%0.<Vetype>, %1/m, %2.<Vetype>"
3520 1.1.1.3 mrg [(set_attr "movprfx" "*,yes,yes")]
3521 1.1.1.3 mrg )
3522 1.1.1.3 mrg
3523 1.1.1.3 mrg ;; -------------------------------------------------------------------------
3524 1.1.1.3 mrg ;; ---- [FP] Square root
3525 1.1.1.3 mrg ;; -------------------------------------------------------------------------
3526 1.1.1.3 mrg
3527 1.1.1.3 mrg (define_expand "sqrt<mode>2"
3528 1.1.1.3 mrg [(set (match_operand:SVE_FULL_F 0 "register_operand")
3529 1.1.1.3 mrg (unspec:SVE_FULL_F
3530 1.1.1.3 mrg [(match_dup 2)
3531 1.1.1.3 mrg (const_int SVE_RELAXED_GP)
3532 1.1.1.3 mrg (match_operand:SVE_FULL_F 1 "register_operand")]
3533 1.1.1.3 mrg UNSPEC_COND_FSQRT))]
3534 1.1.1.3 mrg "TARGET_SVE"
3535 1.1.1.3 mrg {
3536 1.1.1.3 mrg if (aarch64_emit_approx_sqrt (operands[0], operands[1], false))
3537 1.1.1.3 mrg DONE;
3538 1.1.1.3 mrg operands[2] = aarch64_ptrue_reg (<VPRED>mode);
3539 1.1.1.3 mrg })
3540 1.1.1.3 mrg
3541 1.1.1.3 mrg ;; -------------------------------------------------------------------------
3542 1.1.1.3 mrg ;; ---- [FP] Reciprocal square root
3543 1.1.1.3 mrg ;; -------------------------------------------------------------------------
3544 1.1.1.3 mrg
3545 1.1.1.3 mrg (define_expand "rsqrt<mode>2"
3546 1.1.1.3 mrg [(set (match_operand:SVE_FULL_SDF 0 "register_operand")
3547 1.1.1.3 mrg (unspec:SVE_FULL_SDF
3548 1.1.1.3 mrg [(match_operand:SVE_FULL_SDF 1 "register_operand")]
3549 1.1.1.3 mrg UNSPEC_RSQRT))]
3550 1.1.1.3 mrg "TARGET_SVE"
3551 1.1.1.3 mrg {
3552 1.1.1.3 mrg aarch64_emit_approx_sqrt (operands[0], operands[1], true);
3553 1.1.1.3 mrg DONE;
3554 1.1.1.3 mrg })
3555 1.1.1.3 mrg
3556 1.1.1.3 mrg (define_expand "@aarch64_rsqrte<mode>"
3557 1.1.1.3 mrg [(set (match_operand:SVE_FULL_SDF 0 "register_operand")
3558 1.1.1.3 mrg (unspec:SVE_FULL_SDF
3559 1.1.1.3 mrg [(match_operand:SVE_FULL_SDF 1 "register_operand")]
3560 1.1.1.3 mrg UNSPEC_RSQRTE))]
3561 1.1.1.3 mrg "TARGET_SVE"
3562 1.1.1.3 mrg )
3563 1.1.1.3 mrg
3564 1.1.1.3 mrg (define_expand "@aarch64_rsqrts<mode>"
3565 1.1.1.3 mrg [(set (match_operand:SVE_FULL_SDF 0 "register_operand")
3566 1.1.1.3 mrg (unspec:SVE_FULL_SDF
3567 1.1.1.3 mrg [(match_operand:SVE_FULL_SDF 1 "register_operand")
3568 1.1.1.3 mrg (match_operand:SVE_FULL_SDF 2 "register_operand")]
3569 1.1.1.3 mrg UNSPEC_RSQRTS))]
3570 1.1.1.3 mrg "TARGET_SVE"
3571 1.1.1.3 mrg )
3572 1.1.1.3 mrg
3573 1.1.1.3 mrg ;; -------------------------------------------------------------------------
3574 1.1.1.3 mrg ;; ---- [PRED] Inverse
3575 1.1.1.3 mrg ;; -------------------------------------------------------------------------
3576 1.1.1.3 mrg ;; Includes:
3577 1.1.1.3 mrg ;; - NOT
3578 1.1.1.3 mrg ;; -------------------------------------------------------------------------
3579 1.1.1.3 mrg
3580 1.1.1.3 mrg ;; Unpredicated predicate inverse.
3581 1.1.1.3 mrg (define_expand "one_cmpl<mode>2"
3582 1.1.1.3 mrg [(set (match_operand:PRED_ALL 0 "register_operand")
3583 1.1.1.3 mrg (and:PRED_ALL
3584 1.1.1.3 mrg (not:PRED_ALL (match_operand:PRED_ALL 1 "register_operand"))
3585 1.1.1.3 mrg (match_dup 2)))]
3586 1.1.1.3 mrg "TARGET_SVE"
3587 1.1.1.3 mrg {
3588 1.1.1.3 mrg operands[2] = aarch64_ptrue_reg (<MODE>mode);
3589 1.1.1.3 mrg }
3590 1.1.1.3 mrg )
3591 1.1.1.3 mrg
3592 1.1.1.3 mrg ;; Predicated predicate inverse.
3593 1.1.1.3 mrg (define_insn "*one_cmpl<mode>3"
3594 1.1.1.3 mrg [(set (match_operand:PRED_ALL 0 "register_operand" "=Upa")
3595 1.1.1.3 mrg (and:PRED_ALL
3596 1.1.1.3 mrg (not:PRED_ALL (match_operand:PRED_ALL 2 "register_operand" "Upa"))
3597 1.1.1.3 mrg (match_operand:PRED_ALL 1 "register_operand" "Upa")))]
3598 1.1.1.3 mrg "TARGET_SVE"
3599 1.1.1.3 mrg "not\t%0.b, %1/z, %2.b"
3600 1.1.1.3 mrg )
3601 1.1.1.3 mrg
3602 1.1.1.3 mrg ;; =========================================================================
3603 1.1.1.3 mrg ;; == Binary arithmetic
3604 1.1.1.3 mrg ;; =========================================================================
3605 1.1.1.3 mrg
3606 1.1.1.3 mrg ;; -------------------------------------------------------------------------
3607 1.1.1.3 mrg ;; ---- [INT] General binary arithmetic corresponding to rtx codes
3608 1.1.1.3 mrg ;; -------------------------------------------------------------------------
3609 1.1.1.3 mrg ;; Includes:
3610 1.1.1.3 mrg ;; - ADD (merging form only)
3611 1.1.1.3 mrg ;; - AND (merging form only)
3612 1.1.1.3 mrg ;; - ASR (merging form only)
3613 1.1.1.3 mrg ;; - EOR (merging form only)
3614 1.1.1.3 mrg ;; - LSL (merging form only)
3615 1.1.1.3 mrg ;; - LSR (merging form only)
3616 1.1.1.3 mrg ;; - MUL
3617 1.1.1.3 mrg ;; - ORR (merging form only)
3618 1.1.1.3 mrg ;; - SMAX
3619 1.1.1.3 mrg ;; - SMIN
3620 1.1.1.3 mrg ;; - SQADD (SVE2 merging form only)
3621 1.1.1.3 mrg ;; - SQSUB (SVE2 merging form only)
3622 1.1.1.3 mrg ;; - SUB (merging form only)
3623 1.1.1.3 mrg ;; - UMAX
3624 1.1.1.3 mrg ;; - UMIN
3625 1.1.1.3 mrg ;; - UQADD (SVE2 merging form only)
3626 1.1.1.3 mrg ;; - UQSUB (SVE2 merging form only)
3627 1.1.1.3 mrg ;; -------------------------------------------------------------------------
3628 1.1.1.3 mrg
3629 1.1.1.3 mrg ;; Unpredicated integer binary operations that have an immediate form.
3630 1.1.1.3 mrg (define_expand "<optab><mode>3"
3631 1.1.1.5 mrg [(set (match_operand:SVE_I 0 "register_operand")
3632 1.1.1.5 mrg (unspec:SVE_I
3633 1.1.1.3 mrg [(match_dup 3)
3634 1.1.1.5 mrg (SVE_INT_BINARY_IMM:SVE_I
3635 1.1.1.5 mrg (match_operand:SVE_I 1 "register_operand")
3636 1.1.1.5 mrg (match_operand:SVE_I 2 "aarch64_sve_<sve_imm_con>_operand"))]
3637 1.1.1.3 mrg UNSPEC_PRED_X))]
3638 1.1.1.3 mrg "TARGET_SVE"
3639 1.1.1.3 mrg {
3640 1.1.1.3 mrg operands[3] = aarch64_ptrue_reg (<VPRED>mode);
3641 1.1.1.3 mrg }
3642 1.1.1.3 mrg )
3643 1.1.1.3 mrg
3644 1.1.1.3 mrg ;; Integer binary operations that have an immediate form, predicated
3645 1.1.1.3 mrg ;; with a PTRUE. We don't actually need the predicate for the first
3646 1.1.1.3 mrg ;; and third alternatives, but using Upa or X isn't likely to gain much
3647 1.1.1.3 mrg ;; and would make the instruction seem less uniform to the register
3648 1.1.1.3 mrg ;; allocator.
3649 1.1.1.3 mrg (define_insn_and_split "@aarch64_pred_<optab><mode>"
3650 1.1.1.5 mrg [(set (match_operand:SVE_I 0 "register_operand" "=w, w, ?&w, ?&w")
3651 1.1.1.5 mrg (unspec:SVE_I
3652 1.1.1.3 mrg [(match_operand:<VPRED> 1 "register_operand" "Upl, Upl, Upl, Upl")
3653 1.1.1.5 mrg (SVE_INT_BINARY_IMM:SVE_I
3654 1.1.1.5 mrg (match_operand:SVE_I 2 "register_operand" "%0, 0, w, w")
3655 1.1.1.5 mrg (match_operand:SVE_I 3 "aarch64_sve_<sve_imm_con>_operand" "<sve_imm_con>, w, <sve_imm_con>, w"))]
3656 1.1.1.3 mrg UNSPEC_PRED_X))]
3657 1.1.1.3 mrg "TARGET_SVE"
3658 1.1.1.3 mrg "@
3659 1.1.1.3 mrg #
3660 1.1.1.3 mrg <sve_int_op>\t%0.<Vetype>, %1/m, %0.<Vetype>, %3.<Vetype>
3661 1.1.1.3 mrg #
3662 1.1.1.3 mrg movprfx\t%0, %2\;<sve_int_op>\t%0.<Vetype>, %1/m, %0.<Vetype>, %3.<Vetype>"
3663 1.1.1.3 mrg ; Split the unpredicated form after reload, so that we don't have
3664 1.1.1.3 mrg ; the unnecessary PTRUE.
3665 1.1.1.3 mrg "&& reload_completed
3666 1.1.1.3 mrg && !register_operand (operands[3], <MODE>mode)"
3667 1.1.1.3 mrg [(set (match_dup 0)
3668 1.1.1.5 mrg (SVE_INT_BINARY_IMM:SVE_I (match_dup 2) (match_dup 3)))]
3669 1.1.1.3 mrg ""
3670 1.1.1.3 mrg [(set_attr "movprfx" "*,*,yes,yes")]
3671 1.1.1.3 mrg )
3672 1.1.1.3 mrg
3673 1.1.1.3 mrg ;; Unpredicated binary operations with a constant (post-RA only).
3674 1.1.1.3 mrg ;; These are generated by splitting a predicated instruction whose
3675 1.1.1.3 mrg ;; predicate is unused.
3676 1.1.1.3 mrg (define_insn "*post_ra_<optab><mode>3"
3677 1.1.1.5 mrg [(set (match_operand:SVE_I 0 "register_operand" "=w, ?&w")
3678 1.1.1.5 mrg (SVE_INT_BINARY_IMM:SVE_I
3679 1.1.1.5 mrg (match_operand:SVE_I 1 "register_operand" "0, w")
3680 1.1.1.5 mrg (match_operand:SVE_I 2 "aarch64_sve_<sve_imm_con>_immediate")))]
3681 1.1.1.3 mrg "TARGET_SVE && reload_completed"
3682 1.1.1.3 mrg "@
3683 1.1.1.3 mrg <sve_int_op>\t%0.<Vetype>, %0.<Vetype>, #%<sve_imm_prefix>2
3684 1.1.1.3 mrg movprfx\t%0, %1\;<sve_int_op>\t%0.<Vetype>, %0.<Vetype>, #%<sve_imm_prefix>2"
3685 1.1.1.3 mrg [(set_attr "movprfx" "*,yes")]
3686 1.1.1.3 mrg )
3687 1.1.1.3 mrg
3688 1.1.1.3 mrg ;; Predicated integer operations with merging.
3689 1.1.1.3 mrg (define_expand "@cond_<optab><mode>"
3690 1.1.1.5 mrg [(set (match_operand:SVE_I 0 "register_operand")
3691 1.1.1.5 mrg (unspec:SVE_I
3692 1.1.1.3 mrg [(match_operand:<VPRED> 1 "register_operand")
3693 1.1.1.5 mrg (SVE_INT_BINARY:SVE_I
3694 1.1.1.5 mrg (match_operand:SVE_I 2 "register_operand")
3695 1.1.1.5 mrg (match_operand:SVE_I 3 "<sve_pred_int_rhs2_operand>"))
3696 1.1.1.5 mrg (match_operand:SVE_I 4 "aarch64_simd_reg_or_zero")]
3697 1.1.1.3 mrg UNSPEC_SEL))]
3698 1.1.1.3 mrg "TARGET_SVE"
3699 1.1.1.3 mrg )
3700 1.1.1.3 mrg
3701 1.1.1.3 mrg ;; Predicated integer operations, merging with the first input.
3702 1.1.1.3 mrg (define_insn "*cond_<optab><mode>_2"
3703 1.1.1.5 mrg [(set (match_operand:SVE_I 0 "register_operand" "=w, ?&w")
3704 1.1.1.5 mrg (unspec:SVE_I
3705 1.1.1.3 mrg [(match_operand:<VPRED> 1 "register_operand" "Upl, Upl")
3706 1.1.1.5 mrg (SVE_INT_BINARY:SVE_I
3707 1.1.1.5 mrg (match_operand:SVE_I 2 "register_operand" "0, w")
3708 1.1.1.5 mrg (match_operand:SVE_I 3 "register_operand" "w, w"))
3709 1.1.1.3 mrg (match_dup 2)]
3710 1.1.1.3 mrg UNSPEC_SEL))]
3711 1.1.1.3 mrg "TARGET_SVE"
3712 1.1.1.3 mrg "@
3713 1.1.1.3 mrg <sve_int_op>\t%0.<Vetype>, %1/m, %0.<Vetype>, %3.<Vetype>
3714 1.1.1.3 mrg movprfx\t%0, %2\;<sve_int_op>\t%0.<Vetype>, %1/m, %0.<Vetype>, %3.<Vetype>"
3715 1.1.1.3 mrg [(set_attr "movprfx" "*,yes")]
3716 1.1.1.3 mrg )
3717 1.1.1.3 mrg
3718 1.1.1.3 mrg ;; Predicated integer operations, merging with the second input.
3719 1.1.1.3 mrg (define_insn "*cond_<optab><mode>_3"
3720 1.1.1.5 mrg [(set (match_operand:SVE_I 0 "register_operand" "=w, ?&w")
3721 1.1.1.5 mrg (unspec:SVE_I
3722 1.1.1.3 mrg [(match_operand:<VPRED> 1 "register_operand" "Upl, Upl")
3723 1.1.1.5 mrg (SVE_INT_BINARY:SVE_I
3724 1.1.1.5 mrg (match_operand:SVE_I 2 "register_operand" "w, w")
3725 1.1.1.5 mrg (match_operand:SVE_I 3 "register_operand" "0, w"))
3726 1.1.1.3 mrg (match_dup 3)]
3727 1.1.1.3 mrg UNSPEC_SEL))]
3728 1.1.1.3 mrg "TARGET_SVE"
3729 1.1.1.3 mrg "@
3730 1.1.1.3 mrg <sve_int_op_rev>\t%0.<Vetype>, %1/m, %0.<Vetype>, %2.<Vetype>
3731 1.1.1.3 mrg movprfx\t%0, %3\;<sve_int_op_rev>\t%0.<Vetype>, %1/m, %0.<Vetype>, %2.<Vetype>"
3732 1.1.1.3 mrg [(set_attr "movprfx" "*,yes")]
3733 1.1.1.3 mrg )
3734 1.1.1.3 mrg
3735 1.1.1.3 mrg ;; Predicated integer operations, merging with an independent value.
3736 1.1.1.3 mrg (define_insn_and_rewrite "*cond_<optab><mode>_any"
3737 1.1.1.5 mrg [(set (match_operand:SVE_I 0 "register_operand" "=&w, &w, &w, &w, ?&w")
3738 1.1.1.5 mrg (unspec:SVE_I
3739 1.1.1.3 mrg [(match_operand:<VPRED> 1 "register_operand" "Upl, Upl, Upl, Upl, Upl")
3740 1.1.1.5 mrg (SVE_INT_BINARY:SVE_I
3741 1.1.1.5 mrg (match_operand:SVE_I 2 "register_operand" "0, w, w, w, w")
3742 1.1.1.5 mrg (match_operand:SVE_I 3 "register_operand" "w, 0, w, w, w"))
3743 1.1.1.5 mrg (match_operand:SVE_I 4 "aarch64_simd_reg_or_zero" "Dz, Dz, Dz, 0, w")]
3744 1.1.1.3 mrg UNSPEC_SEL))]
3745 1.1.1.3 mrg "TARGET_SVE
3746 1.1.1.3 mrg && !rtx_equal_p (operands[2], operands[4])
3747 1.1.1.3 mrg && !rtx_equal_p (operands[3], operands[4])"
3748 1.1.1.3 mrg "@
3749 1.1.1.3 mrg movprfx\t%0.<Vetype>, %1/z, %0.<Vetype>\;<sve_int_op>\t%0.<Vetype>, %1/m, %0.<Vetype>, %3.<Vetype>
3750 1.1.1.3 mrg movprfx\t%0.<Vetype>, %1/z, %0.<Vetype>\;<sve_int_op_rev>\t%0.<Vetype>, %1/m, %0.<Vetype>, %2.<Vetype>
3751 1.1.1.3 mrg movprfx\t%0.<Vetype>, %1/z, %2.<Vetype>\;<sve_int_op>\t%0.<Vetype>, %1/m, %0.<Vetype>, %3.<Vetype>
3752 1.1.1.3 mrg movprfx\t%0.<Vetype>, %1/m, %2.<Vetype>\;<sve_int_op>\t%0.<Vetype>, %1/m, %0.<Vetype>, %3.<Vetype>
3753 1.1.1.3 mrg #"
3754 1.1.1.3 mrg "&& reload_completed
3755 1.1.1.3 mrg && register_operand (operands[4], <MODE>mode)
3756 1.1.1.3 mrg && !rtx_equal_p (operands[0], operands[4])"
3757 1.1.1.3 mrg {
3758 1.1.1.3 mrg emit_insn (gen_vcond_mask_<mode><vpred> (operands[0], operands[2],
3759 1.1.1.3 mrg operands[4], operands[1]));
3760 1.1.1.3 mrg operands[4] = operands[2] = operands[0];
3761 1.1.1.3 mrg }
3762 1.1.1.3 mrg [(set_attr "movprfx" "yes")]
3763 1.1.1.3 mrg )
3764 1.1.1.3 mrg
3765 1.1.1.3 mrg ;; -------------------------------------------------------------------------
3766 1.1.1.3 mrg ;; ---- [INT] Addition
3767 1.1.1.3 mrg ;; -------------------------------------------------------------------------
3768 1.1.1.3 mrg ;; Includes:
3769 1.1.1.3 mrg ;; - ADD
3770 1.1.1.3 mrg ;; - DECB
3771 1.1.1.3 mrg ;; - DECD
3772 1.1.1.3 mrg ;; - DECH
3773 1.1.1.3 mrg ;; - DECW
3774 1.1.1.3 mrg ;; - INCB
3775 1.1.1.3 mrg ;; - INCD
3776 1.1.1.3 mrg ;; - INCH
3777 1.1.1.3 mrg ;; - INCW
3778 1.1.1.3 mrg ;; - SUB
3779 1.1.1.3 mrg ;; -------------------------------------------------------------------------
3780 1.1.1.3 mrg
3781 1.1.1.3 mrg (define_insn "add<mode>3"
3782 1.1.1.3 mrg [(set (match_operand:SVE_I 0 "register_operand" "=w, w, w, ?w, ?w, w")
3783 1.1.1.3 mrg (plus:SVE_I
3784 1.1.1.3 mrg (match_operand:SVE_I 1 "register_operand" "%0, 0, 0, w, w, w")
3785 1.1.1.3 mrg (match_operand:SVE_I 2 "aarch64_sve_add_operand" "vsa, vsn, vsi, vsa, vsn, w")))]
3786 1.1.1.3 mrg "TARGET_SVE"
3787 1.1.1.3 mrg "@
3788 1.1.1.3 mrg add\t%0.<Vetype>, %0.<Vetype>, #%D2
3789 1.1.1.3 mrg sub\t%0.<Vetype>, %0.<Vetype>, #%N2
3790 1.1.1.3 mrg * return aarch64_output_sve_vector_inc_dec (\"%0.<Vetype>\", operands[2]);
3791 1.1.1.3 mrg movprfx\t%0, %1\;add\t%0.<Vetype>, %0.<Vetype>, #%D2
3792 1.1.1.3 mrg movprfx\t%0, %1\;sub\t%0.<Vetype>, %0.<Vetype>, #%N2
3793 1.1.1.3 mrg add\t%0.<Vetype>, %1.<Vetype>, %2.<Vetype>"
3794 1.1.1.3 mrg [(set_attr "movprfx" "*,*,*,yes,yes,*")]
3795 1.1.1.3 mrg )
3796 1.1.1.3 mrg
3797 1.1.1.3 mrg ;; Merging forms are handled through SVE_INT_BINARY.
3798 1.1.1.3 mrg
3799 1.1.1.3 mrg ;; -------------------------------------------------------------------------
3800 1.1.1.3 mrg ;; ---- [INT] Subtraction
3801 1.1.1.3 mrg ;; -------------------------------------------------------------------------
3802 1.1.1.3 mrg ;; Includes:
3803 1.1.1.3 mrg ;; - SUB
3804 1.1.1.3 mrg ;; - SUBR
3805 1.1.1.3 mrg ;; -------------------------------------------------------------------------
3806 1.1.1.3 mrg
3807 1.1.1.3 mrg (define_insn "sub<mode>3"
3808 1.1.1.5 mrg [(set (match_operand:SVE_I 0 "register_operand" "=w, w, ?&w")
3809 1.1.1.5 mrg (minus:SVE_I
3810 1.1.1.5 mrg (match_operand:SVE_I 1 "aarch64_sve_arith_operand" "w, vsa, vsa")
3811 1.1.1.5 mrg (match_operand:SVE_I 2 "register_operand" "w, 0, w")))]
3812 1.1.1.3 mrg "TARGET_SVE"
3813 1.1.1.3 mrg "@
3814 1.1.1.3 mrg sub\t%0.<Vetype>, %1.<Vetype>, %2.<Vetype>
3815 1.1.1.3 mrg subr\t%0.<Vetype>, %0.<Vetype>, #%D1
3816 1.1.1.3 mrg movprfx\t%0, %2\;subr\t%0.<Vetype>, %0.<Vetype>, #%D1"
3817 1.1.1.3 mrg [(set_attr "movprfx" "*,*,yes")]
3818 1.1.1.3 mrg )
3819 1.1.1.3 mrg
3820 1.1.1.3 mrg ;; Merging forms are handled through SVE_INT_BINARY.
3821 1.1.1.3 mrg
3822 1.1.1.3 mrg ;; -------------------------------------------------------------------------
3823 1.1.1.3 mrg ;; ---- [INT] Take address
3824 1.1.1.3 mrg ;; -------------------------------------------------------------------------
3825 1.1.1.3 mrg ;; Includes:
3826 1.1.1.3 mrg ;; - ADR
3827 1.1.1.3 mrg ;; -------------------------------------------------------------------------
3828 1.1.1.3 mrg
3829 1.1.1.3 mrg ;; An unshifted and unscaled ADR. This is functionally equivalent to an ADD,
3830 1.1.1.3 mrg ;; but the svadrb intrinsics should preserve the user's choice.
3831 1.1.1.3 mrg (define_insn "@aarch64_adr<mode>"
3832 1.1.1.3 mrg [(set (match_operand:SVE_FULL_SDI 0 "register_operand" "=w")
3833 1.1.1.3 mrg (unspec:SVE_FULL_SDI
3834 1.1.1.3 mrg [(match_operand:SVE_FULL_SDI 1 "register_operand" "w")
3835 1.1.1.3 mrg (match_operand:SVE_FULL_SDI 2 "register_operand" "w")]
3836 1.1.1.3 mrg UNSPEC_ADR))]
3837 1.1.1.3 mrg "TARGET_SVE"
3838 1.1.1.3 mrg "adr\t%0.<Vetype>, [%1.<Vetype>, %2.<Vetype>]"
3839 1.1.1.3 mrg )
3840 1.1.1.3 mrg
3841 1.1.1.3 mrg ;; Same, but with the offset being sign-extended from the low 32 bits.
3842 1.1.1.3 mrg (define_insn_and_rewrite "*aarch64_adr_sxtw"
3843 1.1.1.3 mrg [(set (match_operand:VNx2DI 0 "register_operand" "=w")
3844 1.1.1.3 mrg (unspec:VNx2DI
3845 1.1.1.3 mrg [(match_operand:VNx2DI 1 "register_operand" "w")
3846 1.1.1.3 mrg (unspec:VNx2DI
3847 1.1.1.3 mrg [(match_operand 3)
3848 1.1.1.3 mrg (sign_extend:VNx2DI
3849 1.1.1.3 mrg (truncate:VNx2SI
3850 1.1.1.3 mrg (match_operand:VNx2DI 2 "register_operand" "w")))]
3851 1.1.1.3 mrg UNSPEC_PRED_X)]
3852 1.1.1.3 mrg UNSPEC_ADR))]
3853 1.1.1.3 mrg "TARGET_SVE"
3854 1.1.1.3 mrg "adr\t%0.d, [%1.d, %2.d, sxtw]"
3855 1.1.1.3 mrg "&& !CONSTANT_P (operands[3])"
3856 1.1.1.3 mrg {
3857 1.1.1.3 mrg operands[3] = CONSTM1_RTX (VNx2BImode);
3858 1.1.1.3 mrg }
3859 1.1.1.3 mrg )
3860 1.1.1.3 mrg
3861 1.1.1.3 mrg ;; Same, but with the offset being zero-extended from the low 32 bits.
3862 1.1.1.3 mrg (define_insn "*aarch64_adr_uxtw_unspec"
3863 1.1.1.3 mrg [(set (match_operand:VNx2DI 0 "register_operand" "=w")
3864 1.1.1.3 mrg (unspec:VNx2DI
3865 1.1.1.3 mrg [(match_operand:VNx2DI 1 "register_operand" "w")
3866 1.1.1.3 mrg (and:VNx2DI
3867 1.1.1.3 mrg (match_operand:VNx2DI 2 "register_operand" "w")
3868 1.1.1.3 mrg (match_operand:VNx2DI 3 "aarch64_sve_uxtw_immediate"))]
3869 1.1.1.3 mrg UNSPEC_ADR))]
3870 1.1.1.3 mrg "TARGET_SVE"
3871 1.1.1.3 mrg "adr\t%0.d, [%1.d, %2.d, uxtw]"
3872 1.1.1.3 mrg )
3873 1.1.1.3 mrg
3874 1.1.1.3 mrg ;; Same, matching as a PLUS rather than unspec.
3875 1.1.1.3 mrg (define_insn "*aarch64_adr_uxtw_and"
3876 1.1.1.3 mrg [(set (match_operand:VNx2DI 0 "register_operand" "=w")
3877 1.1.1.3 mrg (plus:VNx2DI
3878 1.1.1.3 mrg (and:VNx2DI
3879 1.1.1.3 mrg (match_operand:VNx2DI 2 "register_operand" "w")
3880 1.1.1.3 mrg (match_operand:VNx2DI 3 "aarch64_sve_uxtw_immediate"))
3881 1.1.1.3 mrg (match_operand:VNx2DI 1 "register_operand" "w")))]
3882 1.1.1.3 mrg "TARGET_SVE"
3883 1.1.1.3 mrg "adr\t%0.d, [%1.d, %2.d, uxtw]"
3884 1.1.1.3 mrg )
3885 1.1.1.3 mrg
3886 1.1.1.3 mrg ;; ADR with a nonzero shift.
3887 1.1.1.3 mrg (define_expand "@aarch64_adr<mode>_shift"
3888 1.1.1.3 mrg [(set (match_operand:SVE_FULL_SDI 0 "register_operand")
3889 1.1.1.3 mrg (plus:SVE_FULL_SDI
3890 1.1.1.3 mrg (unspec:SVE_FULL_SDI
3891 1.1.1.3 mrg [(match_dup 4)
3892 1.1.1.3 mrg (ashift:SVE_FULL_SDI
3893 1.1.1.3 mrg (match_operand:SVE_FULL_SDI 2 "register_operand")
3894 1.1.1.3 mrg (match_operand:SVE_FULL_SDI 3 "const_1_to_3_operand"))]
3895 1.1.1.3 mrg UNSPEC_PRED_X)
3896 1.1.1.3 mrg (match_operand:SVE_FULL_SDI 1 "register_operand")))]
3897 1.1.1.3 mrg "TARGET_SVE"
3898 1.1.1.3 mrg {
3899 1.1.1.3 mrg operands[4] = CONSTM1_RTX (<VPRED>mode);
3900 1.1.1.3 mrg }
3901 1.1.1.3 mrg )
3902 1.1.1.3 mrg
3903 1.1.1.3 mrg (define_insn_and_rewrite "*aarch64_adr<mode>_shift"
3904 1.1.1.5 mrg [(set (match_operand:SVE_24I 0 "register_operand" "=w")
3905 1.1.1.5 mrg (plus:SVE_24I
3906 1.1.1.5 mrg (unspec:SVE_24I
3907 1.1.1.3 mrg [(match_operand 4)
3908 1.1.1.5 mrg (ashift:SVE_24I
3909 1.1.1.5 mrg (match_operand:SVE_24I 2 "register_operand" "w")
3910 1.1.1.5 mrg (match_operand:SVE_24I 3 "const_1_to_3_operand"))]
3911 1.1.1.3 mrg UNSPEC_PRED_X)
3912 1.1.1.5 mrg (match_operand:SVE_24I 1 "register_operand" "w")))]
3913 1.1.1.3 mrg "TARGET_SVE"
3914 1.1.1.5 mrg "adr\t%0.<Vctype>, [%1.<Vctype>, %2.<Vctype>, lsl %3]"
3915 1.1.1.3 mrg "&& !CONSTANT_P (operands[4])"
3916 1.1.1.3 mrg {
3917 1.1.1.3 mrg operands[4] = CONSTM1_RTX (<VPRED>mode);
3918 1.1.1.3 mrg }
3919 1.1.1.3 mrg )
3920 1.1.1.3 mrg
3921 1.1.1.3 mrg ;; Same, but with the index being sign-extended from the low 32 bits.
3922 1.1.1.3 mrg (define_insn_and_rewrite "*aarch64_adr_shift_sxtw"
3923 1.1.1.3 mrg [(set (match_operand:VNx2DI 0 "register_operand" "=w")
3924 1.1.1.3 mrg (plus:VNx2DI
3925 1.1.1.3 mrg (unspec:VNx2DI
3926 1.1.1.3 mrg [(match_operand 4)
3927 1.1.1.3 mrg (ashift:VNx2DI
3928 1.1.1.3 mrg (unspec:VNx2DI
3929 1.1.1.3 mrg [(match_operand 5)
3930 1.1.1.3 mrg (sign_extend:VNx2DI
3931 1.1.1.3 mrg (truncate:VNx2SI
3932 1.1.1.3 mrg (match_operand:VNx2DI 2 "register_operand" "w")))]
3933 1.1.1.3 mrg UNSPEC_PRED_X)
3934 1.1.1.3 mrg (match_operand:VNx2DI 3 "const_1_to_3_operand"))]
3935 1.1.1.3 mrg UNSPEC_PRED_X)
3936 1.1.1.3 mrg (match_operand:VNx2DI 1 "register_operand" "w")))]
3937 1.1.1.3 mrg "TARGET_SVE"
3938 1.1.1.3 mrg "adr\t%0.d, [%1.d, %2.d, sxtw %3]"
3939 1.1.1.3 mrg "&& (!CONSTANT_P (operands[4]) || !CONSTANT_P (operands[5]))"
3940 1.1.1.3 mrg {
3941 1.1.1.3 mrg operands[5] = operands[4] = CONSTM1_RTX (VNx2BImode);
3942 1.1.1.3 mrg }
3943 1.1.1.3 mrg )
3944 1.1.1.3 mrg
3945 1.1.1.3 mrg ;; Same, but with the index being zero-extended from the low 32 bits.
3946 1.1.1.3 mrg (define_insn_and_rewrite "*aarch64_adr_shift_uxtw"
3947 1.1.1.3 mrg [(set (match_operand:VNx2DI 0 "register_operand" "=w")
3948 1.1.1.3 mrg (plus:VNx2DI
3949 1.1.1.3 mrg (unspec:VNx2DI
3950 1.1.1.3 mrg [(match_operand 5)
3951 1.1.1.3 mrg (ashift:VNx2DI
3952 1.1.1.3 mrg (and:VNx2DI
3953 1.1.1.3 mrg (match_operand:VNx2DI 2 "register_operand" "w")
3954 1.1.1.3 mrg (match_operand:VNx2DI 4 "aarch64_sve_uxtw_immediate"))
3955 1.1.1.3 mrg (match_operand:VNx2DI 3 "const_1_to_3_operand"))]
3956 1.1.1.3 mrg UNSPEC_PRED_X)
3957 1.1.1.3 mrg (match_operand:VNx2DI 1 "register_operand" "w")))]
3958 1.1.1.3 mrg "TARGET_SVE"
3959 1.1.1.3 mrg "adr\t%0.d, [%1.d, %2.d, uxtw %3]"
3960 1.1.1.3 mrg "&& !CONSTANT_P (operands[5])"
3961 1.1.1.3 mrg {
3962 1.1.1.3 mrg operands[5] = CONSTM1_RTX (VNx2BImode);
3963 1.1.1.3 mrg }
3964 1.1.1.3 mrg )
3965 1.1.1.3 mrg
3966 1.1.1.3 mrg ;; -------------------------------------------------------------------------
3967 1.1.1.3 mrg ;; ---- [INT] Absolute difference
3968 1.1.1.3 mrg ;; -------------------------------------------------------------------------
3969 1.1.1.3 mrg ;; Includes:
3970 1.1.1.3 mrg ;; - SABD
3971 1.1.1.3 mrg ;; - UABD
3972 1.1.1.3 mrg ;; -------------------------------------------------------------------------
3973 1.1.1.3 mrg
3974 1.1.1.3 mrg ;; Unpredicated integer absolute difference.
3975 1.1.1.3 mrg (define_expand "<su>abd<mode>_3"
3976 1.1.1.5 mrg [(use (match_operand:SVE_I 0 "register_operand"))
3977 1.1.1.5 mrg (USMAX:SVE_I
3978 1.1.1.5 mrg (match_operand:SVE_I 1 "register_operand")
3979 1.1.1.5 mrg (match_operand:SVE_I 2 "register_operand"))]
3980 1.1.1.3 mrg "TARGET_SVE"
3981 1.1.1.3 mrg {
3982 1.1.1.3 mrg rtx pred = aarch64_ptrue_reg (<VPRED>mode);
3983 1.1.1.3 mrg emit_insn (gen_aarch64_pred_<su>abd<mode> (operands[0], pred, operands[1],
3984 1.1.1.3 mrg operands[2]));
3985 1.1.1.3 mrg DONE;
3986 1.1.1.3 mrg }
3987 1.1.1.3 mrg )
3988 1.1.1.3 mrg
3989 1.1.1.3 mrg ;; Predicated integer absolute difference.
3990 1.1.1.3 mrg (define_insn "@aarch64_pred_<su>abd<mode>"
3991 1.1.1.5 mrg [(set (match_operand:SVE_I 0 "register_operand" "=w, ?&w")
3992 1.1.1.5 mrg (minus:SVE_I
3993 1.1.1.5 mrg (unspec:SVE_I
3994 1.1.1.5 mrg [(match_operand:<VPRED> 1 "register_operand" "Upl, Upl")
3995 1.1.1.5 mrg (USMAX:SVE_I
3996 1.1.1.5 mrg (match_operand:SVE_I 2 "register_operand" "%0, w")
3997 1.1.1.5 mrg (match_operand:SVE_I 3 "register_operand" "w, w"))]
3998 1.1.1.5 mrg UNSPEC_PRED_X)
3999 1.1.1.5 mrg (unspec:SVE_I
4000 1.1.1.5 mrg [(match_dup 1)
4001 1.1.1.5 mrg (<max_opp>:SVE_I
4002 1.1.1.3 mrg (match_dup 2)
4003 1.1.1.5 mrg (match_dup 3))]
4004 1.1.1.5 mrg UNSPEC_PRED_X)))]
4005 1.1.1.3 mrg "TARGET_SVE"
4006 1.1.1.3 mrg "@
4007 1.1.1.3 mrg <su>abd\t%0.<Vetype>, %1/m, %0.<Vetype>, %3.<Vetype>
4008 1.1.1.3 mrg movprfx\t%0, %2\;<su>abd\t%0.<Vetype>, %1/m, %0.<Vetype>, %3.<Vetype>"
4009 1.1.1.3 mrg [(set_attr "movprfx" "*,yes")]
4010 1.1.1.3 mrg )
4011 1.1.1.3 mrg
4012 1.1.1.3 mrg (define_expand "@aarch64_cond_<su>abd<mode>"
4013 1.1.1.3 mrg [(set (match_operand:SVE_FULL_I 0 "register_operand")
4014 1.1.1.3 mrg (unspec:SVE_FULL_I
4015 1.1.1.3 mrg [(match_operand:<VPRED> 1 "register_operand")
4016 1.1.1.3 mrg (minus:SVE_FULL_I
4017 1.1.1.3 mrg (unspec:SVE_FULL_I
4018 1.1.1.3 mrg [(match_dup 1)
4019 1.1.1.3 mrg (USMAX:SVE_FULL_I
4020 1.1.1.3 mrg (match_operand:SVE_FULL_I 2 "register_operand")
4021 1.1.1.3 mrg (match_operand:SVE_FULL_I 3 "register_operand"))]
4022 1.1.1.3 mrg UNSPEC_PRED_X)
4023 1.1.1.3 mrg (unspec:SVE_FULL_I
4024 1.1.1.3 mrg [(match_dup 1)
4025 1.1.1.3 mrg (<max_opp>:SVE_FULL_I
4026 1.1.1.3 mrg (match_dup 2)
4027 1.1.1.3 mrg (match_dup 3))]
4028 1.1.1.3 mrg UNSPEC_PRED_X))
4029 1.1.1.3 mrg (match_operand:SVE_FULL_I 4 "aarch64_simd_reg_or_zero")]
4030 1.1.1.3 mrg UNSPEC_SEL))]
4031 1.1.1.3 mrg "TARGET_SVE"
4032 1.1.1.3 mrg {
4033 1.1.1.3 mrg if (rtx_equal_p (operands[3], operands[4]))
4034 1.1.1.3 mrg std::swap (operands[2], operands[3]);
4035 1.1.1.3 mrg })
4036 1.1.1.3 mrg
4037 1.1.1.3 mrg ;; Predicated integer absolute difference, merging with the first input.
4038 1.1.1.3 mrg (define_insn_and_rewrite "*aarch64_cond_<su>abd<mode>_2"
4039 1.1.1.5 mrg [(set (match_operand:SVE_I 0 "register_operand" "=w, ?&w")
4040 1.1.1.5 mrg (unspec:SVE_I
4041 1.1.1.3 mrg [(match_operand:<VPRED> 1 "register_operand" "Upl, Upl")
4042 1.1.1.5 mrg (minus:SVE_I
4043 1.1.1.5 mrg (unspec:SVE_I
4044 1.1.1.3 mrg [(match_operand 4)
4045 1.1.1.5 mrg (USMAX:SVE_I
4046 1.1.1.5 mrg (match_operand:SVE_I 2 "register_operand" "0, w")
4047 1.1.1.5 mrg (match_operand:SVE_I 3 "register_operand" "w, w"))]
4048 1.1.1.3 mrg UNSPEC_PRED_X)
4049 1.1.1.5 mrg (unspec:SVE_I
4050 1.1.1.3 mrg [(match_operand 5)
4051 1.1.1.5 mrg (<max_opp>:SVE_I
4052 1.1.1.3 mrg (match_dup 2)
4053 1.1.1.3 mrg (match_dup 3))]
4054 1.1.1.3 mrg UNSPEC_PRED_X))
4055 1.1.1.3 mrg (match_dup 2)]
4056 1.1.1.3 mrg UNSPEC_SEL))]
4057 1.1.1.3 mrg "TARGET_SVE"
4058 1.1.1.3 mrg "@
4059 1.1.1.3 mrg <su>abd\t%0.<Vetype>, %1/m, %0.<Vetype>, %3.<Vetype>
4060 1.1.1.3 mrg movprfx\t%0, %2\;<su>abd\t%0.<Vetype>, %1/m, %0.<Vetype>, %3.<Vetype>"
4061 1.1.1.3 mrg "&& (!CONSTANT_P (operands[4]) || !CONSTANT_P (operands[5]))"
4062 1.1.1.3 mrg {
4063 1.1.1.3 mrg operands[4] = operands[5] = CONSTM1_RTX (<VPRED>mode);
4064 1.1.1.3 mrg }
4065 1.1.1.3 mrg [(set_attr "movprfx" "*,yes")]
4066 1.1.1.3 mrg )
4067 1.1.1.3 mrg
4068 1.1.1.5 mrg ;; Predicated integer absolute difference, merging with the second input.
4069 1.1.1.5 mrg (define_insn_and_rewrite "*aarch64_cond_<su>abd<mode>_3"
4070 1.1.1.5 mrg [(set (match_operand:SVE_I 0 "register_operand" "=w, ?&w")
4071 1.1.1.5 mrg (unspec:SVE_I
4072 1.1.1.5 mrg [(match_operand:<VPRED> 1 "register_operand" "Upl, Upl")
4073 1.1.1.5 mrg (minus:SVE_I
4074 1.1.1.5 mrg (unspec:SVE_I
4075 1.1.1.5 mrg [(match_operand 4)
4076 1.1.1.5 mrg (USMAX:SVE_I
4077 1.1.1.5 mrg (match_operand:SVE_I 2 "register_operand" "w, w")
4078 1.1.1.5 mrg (match_operand:SVE_I 3 "register_operand" "0, w"))]
4079 1.1.1.5 mrg UNSPEC_PRED_X)
4080 1.1.1.5 mrg (unspec:SVE_I
4081 1.1.1.5 mrg [(match_operand 5)
4082 1.1.1.5 mrg (<max_opp>:SVE_I
4083 1.1.1.5 mrg (match_dup 2)
4084 1.1.1.5 mrg (match_dup 3))]
4085 1.1.1.5 mrg UNSPEC_PRED_X))
4086 1.1.1.5 mrg (match_dup 3)]
4087 1.1.1.5 mrg UNSPEC_SEL))]
4088 1.1.1.5 mrg "TARGET_SVE"
4089 1.1.1.5 mrg "@
4090 1.1.1.5 mrg <su>abd\t%0.<Vetype>, %1/m, %0.<Vetype>, %2.<Vetype>
4091 1.1.1.5 mrg movprfx\t%0, %3\;<su>abd\t%0.<Vetype>, %1/m, %0.<Vetype>, %2.<Vetype>"
4092 1.1.1.5 mrg "&& (!CONSTANT_P (operands[4]) || !CONSTANT_P (operands[5]))"
4093 1.1.1.5 mrg {
4094 1.1.1.5 mrg operands[4] = operands[5] = CONSTM1_RTX (<VPRED>mode);
4095 1.1.1.5 mrg }
4096 1.1.1.5 mrg [(set_attr "movprfx" "*,yes")]
4097 1.1.1.5 mrg )
4098 1.1.1.5 mrg
4099 1.1.1.3 mrg ;; Predicated integer absolute difference, merging with an independent value.
4100 1.1.1.3 mrg (define_insn_and_rewrite "*aarch64_cond_<su>abd<mode>_any"
4101 1.1.1.5 mrg [(set (match_operand:SVE_I 0 "register_operand" "=&w, &w, &w, &w, ?&w")
4102 1.1.1.5 mrg (unspec:SVE_I
4103 1.1.1.3 mrg [(match_operand:<VPRED> 1 "register_operand" "Upl, Upl, Upl, Upl, Upl")
4104 1.1.1.5 mrg (minus:SVE_I
4105 1.1.1.5 mrg (unspec:SVE_I
4106 1.1.1.3 mrg [(match_operand 5)
4107 1.1.1.5 mrg (USMAX:SVE_I
4108 1.1.1.5 mrg (match_operand:SVE_I 2 "register_operand" "0, w, w, w, w")
4109 1.1.1.5 mrg (match_operand:SVE_I 3 "register_operand" "w, 0, w, w, w"))]
4110 1.1.1.3 mrg UNSPEC_PRED_X)
4111 1.1.1.5 mrg (unspec:SVE_I
4112 1.1.1.3 mrg [(match_operand 6)
4113 1.1.1.5 mrg (<max_opp>:SVE_I
4114 1.1.1.3 mrg (match_dup 2)
4115 1.1.1.3 mrg (match_dup 3))]
4116 1.1.1.3 mrg UNSPEC_PRED_X))
4117 1.1.1.5 mrg (match_operand:SVE_I 4 "aarch64_simd_reg_or_zero" "Dz, Dz, Dz, 0, w")]
4118 1.1.1.3 mrg UNSPEC_SEL))]
4119 1.1.1.3 mrg "TARGET_SVE
4120 1.1.1.3 mrg && !rtx_equal_p (operands[2], operands[4])
4121 1.1.1.3 mrg && !rtx_equal_p (operands[3], operands[4])"
4122 1.1.1.3 mrg "@
4123 1.1.1.3 mrg movprfx\t%0.<Vetype>, %1/z, %0.<Vetype>\;<su>abd\t%0.<Vetype>, %1/m, %0.<Vetype>, %3.<Vetype>
4124 1.1.1.3 mrg movprfx\t%0.<Vetype>, %1/z, %0.<Vetype>\;<su>abd\t%0.<Vetype>, %1/m, %0.<Vetype>, %2.<Vetype>
4125 1.1.1.3 mrg movprfx\t%0.<Vetype>, %1/z, %2.<Vetype>\;<su>abd\t%0.<Vetype>, %1/m, %0.<Vetype>, %3.<Vetype>
4126 1.1.1.3 mrg movprfx\t%0.<Vetype>, %1/m, %2.<Vetype>\;<su>abd\t%0.<Vetype>, %1/m, %0.<Vetype>, %3.<Vetype>
4127 1.1.1.3 mrg #"
4128 1.1.1.3 mrg "&& 1"
4129 1.1.1.3 mrg {
4130 1.1.1.3 mrg if (!CONSTANT_P (operands[5]) || !CONSTANT_P (operands[6]))
4131 1.1.1.3 mrg operands[5] = operands[6] = CONSTM1_RTX (<VPRED>mode);
4132 1.1.1.3 mrg else if (reload_completed
4133 1.1.1.3 mrg && register_operand (operands[4], <MODE>mode)
4134 1.1.1.3 mrg && !rtx_equal_p (operands[0], operands[4]))
4135 1.1.1.3 mrg {
4136 1.1.1.3 mrg emit_insn (gen_vcond_mask_<mode><vpred> (operands[0], operands[2],
4137 1.1.1.3 mrg operands[4], operands[1]));
4138 1.1.1.3 mrg operands[4] = operands[2] = operands[0];
4139 1.1.1.3 mrg }
4140 1.1.1.3 mrg else
4141 1.1.1.3 mrg FAIL;
4142 1.1.1.3 mrg }
4143 1.1.1.3 mrg [(set_attr "movprfx" "yes")]
4144 1.1.1.3 mrg )
4145 1.1.1.3 mrg
4146 1.1.1.3 mrg ;; -------------------------------------------------------------------------
4147 1.1.1.3 mrg ;; ---- [INT] Saturating addition and subtraction
4148 1.1.1.3 mrg ;; -------------------------------------------------------------------------
4149 1.1.1.3 mrg ;; - SQADD
4150 1.1.1.3 mrg ;; - SQSUB
4151 1.1.1.3 mrg ;; - UQADD
4152 1.1.1.3 mrg ;; - UQSUB
4153 1.1.1.3 mrg ;; -------------------------------------------------------------------------
4154 1.1.1.3 mrg
4155 1.1.1.3 mrg ;; Unpredicated saturating signed addition and subtraction.
4156 1.1.1.3 mrg (define_insn "@aarch64_sve_<optab><mode>"
4157 1.1.1.3 mrg [(set (match_operand:SVE_FULL_I 0 "register_operand" "=w, w, ?&w, ?&w, w")
4158 1.1.1.3 mrg (SBINQOPS:SVE_FULL_I
4159 1.1.1.3 mrg (match_operand:SVE_FULL_I 1 "register_operand" "0, 0, w, w, w")
4160 1.1.1.3 mrg (match_operand:SVE_FULL_I 2 "aarch64_sve_sqadd_operand" "vsQ, vsS, vsQ, vsS, w")))]
4161 1.1.1.3 mrg "TARGET_SVE"
4162 1.1.1.3 mrg "@
4163 1.1.1.3 mrg <binqops_op>\t%0.<Vetype>, %0.<Vetype>, #%D2
4164 1.1.1.3 mrg <binqops_op_rev>\t%0.<Vetype>, %0.<Vetype>, #%N2
4165 1.1.1.3 mrg movprfx\t%0, %1\;<binqops_op>\t%0.<Vetype>, %0.<Vetype>, #%D2
4166 1.1.1.3 mrg movprfx\t%0, %1\;<binqops_op_rev>\t%0.<Vetype>, %0.<Vetype>, #%N2
4167 1.1.1.3 mrg <binqops_op>\t%0.<Vetype>, %1.<Vetype>, %2.<Vetype>"
4168 1.1.1.3 mrg [(set_attr "movprfx" "*,*,yes,yes,*")]
4169 1.1.1.3 mrg )
4170 1.1.1.3 mrg
4171 1.1.1.3 mrg ;; Unpredicated saturating unsigned addition and subtraction.
4172 1.1.1.3 mrg (define_insn "@aarch64_sve_<optab><mode>"
4173 1.1.1.3 mrg [(set (match_operand:SVE_FULL_I 0 "register_operand" "=w, ?&w, w")
4174 1.1.1.3 mrg (UBINQOPS:SVE_FULL_I
4175 1.1.1.3 mrg (match_operand:SVE_FULL_I 1 "register_operand" "0, w, w")
4176 1.1.1.3 mrg (match_operand:SVE_FULL_I 2 "aarch64_sve_arith_operand" "vsa, vsa, w")))]
4177 1.1.1.3 mrg "TARGET_SVE"
4178 1.1.1.3 mrg "@
4179 1.1.1.3 mrg <binqops_op>\t%0.<Vetype>, %0.<Vetype>, #%D2
4180 1.1.1.3 mrg movprfx\t%0, %1\;<binqops_op>\t%0.<Vetype>, %0.<Vetype>, #%D2
4181 1.1.1.3 mrg <binqops_op>\t%0.<Vetype>, %1.<Vetype>, %2.<Vetype>"
4182 1.1.1.3 mrg [(set_attr "movprfx" "*,yes,*")]
4183 1.1.1.3 mrg )
4184 1.1.1.3 mrg
4185 1.1.1.3 mrg ;; -------------------------------------------------------------------------
4186 1.1.1.3 mrg ;; ---- [INT] Highpart multiplication
4187 1.1.1.3 mrg ;; -------------------------------------------------------------------------
4188 1.1.1.3 mrg ;; Includes:
4189 1.1.1.3 mrg ;; - SMULH
4190 1.1.1.3 mrg ;; - UMULH
4191 1.1.1.3 mrg ;; -------------------------------------------------------------------------
4192 1.1.1.3 mrg
4193 1.1.1.3 mrg ;; Unpredicated highpart multiplication.
4194 1.1.1.3 mrg (define_expand "<su>mul<mode>3_highpart"
4195 1.1.1.5 mrg [(set (match_operand:SVE_I 0 "register_operand")
4196 1.1.1.5 mrg (unspec:SVE_I
4197 1.1.1.3 mrg [(match_dup 3)
4198 1.1.1.5 mrg (unspec:SVE_I
4199 1.1.1.5 mrg [(match_operand:SVE_I 1 "register_operand")
4200 1.1.1.5 mrg (match_operand:SVE_I 2 "register_operand")]
4201 1.1.1.3 mrg MUL_HIGHPART)]
4202 1.1.1.3 mrg UNSPEC_PRED_X))]
4203 1.1.1.3 mrg "TARGET_SVE"
4204 1.1.1.3 mrg {
4205 1.1.1.3 mrg operands[3] = aarch64_ptrue_reg (<VPRED>mode);
4206 1.1.1.3 mrg }
4207 1.1.1.3 mrg )
4208 1.1.1.3 mrg
4209 1.1.1.3 mrg ;; Predicated highpart multiplication.
4210 1.1.1.3 mrg (define_insn "@aarch64_pred_<optab><mode>"
4211 1.1.1.5 mrg [(set (match_operand:SVE_I 0 "register_operand" "=w, ?&w")
4212 1.1.1.5 mrg (unspec:SVE_I
4213 1.1.1.3 mrg [(match_operand:<VPRED> 1 "register_operand" "Upl, Upl")
4214 1.1.1.5 mrg (unspec:SVE_I
4215 1.1.1.5 mrg [(match_operand:SVE_I 2 "register_operand" "%0, w")
4216 1.1.1.5 mrg (match_operand:SVE_I 3 "register_operand" "w, w")]
4217 1.1.1.3 mrg MUL_HIGHPART)]
4218 1.1.1.3 mrg UNSPEC_PRED_X))]
4219 1.1.1.3 mrg "TARGET_SVE"
4220 1.1.1.3 mrg "@
4221 1.1.1.3 mrg <su>mulh\t%0.<Vetype>, %1/m, %0.<Vetype>, %3.<Vetype>
4222 1.1.1.3 mrg movprfx\t%0, %2\;<su>mulh\t%0.<Vetype>, %1/m, %0.<Vetype>, %3.<Vetype>"
4223 1.1.1.3 mrg [(set_attr "movprfx" "*,yes")]
4224 1.1.1.3 mrg )
4225 1.1.1.3 mrg
4226 1.1.1.3 mrg ;; Predicated highpart multiplications with merging.
4227 1.1.1.3 mrg (define_expand "@cond_<optab><mode>"
4228 1.1.1.3 mrg [(set (match_operand:SVE_FULL_I 0 "register_operand")
4229 1.1.1.3 mrg (unspec:SVE_FULL_I
4230 1.1.1.3 mrg [(match_operand:<VPRED> 1 "register_operand")
4231 1.1.1.3 mrg (unspec:SVE_FULL_I
4232 1.1.1.3 mrg [(match_operand:SVE_FULL_I 2 "register_operand")
4233 1.1.1.3 mrg (match_operand:SVE_FULL_I 3 "register_operand")]
4234 1.1.1.3 mrg MUL_HIGHPART)
4235 1.1.1.3 mrg (match_operand:SVE_FULL_I 4 "aarch64_simd_reg_or_zero")]
4236 1.1.1.3 mrg UNSPEC_SEL))]
4237 1.1.1.3 mrg "TARGET_SVE"
4238 1.1.1.3 mrg {
4239 1.1.1.3 mrg /* Only target code is aware of these operations, so we don't need
4240 1.1.1.3 mrg to handle the fully-general case. */
4241 1.1.1.3 mrg gcc_assert (rtx_equal_p (operands[2], operands[4])
4242 1.1.1.3 mrg || CONSTANT_P (operands[4]));
4243 1.1.1.3 mrg })
4244 1.1.1.3 mrg
4245 1.1.1.3 mrg ;; Predicated highpart multiplications, merging with the first input.
4246 1.1.1.3 mrg (define_insn "*cond_<optab><mode>_2"
4247 1.1.1.3 mrg [(set (match_operand:SVE_FULL_I 0 "register_operand" "=w, ?&w")
4248 1.1.1.3 mrg (unspec:SVE_FULL_I
4249 1.1.1.3 mrg [(match_operand:<VPRED> 1 "register_operand" "Upl, Upl")
4250 1.1.1.3 mrg (unspec:SVE_FULL_I
4251 1.1.1.3 mrg [(match_operand:SVE_FULL_I 2 "register_operand" "0, w")
4252 1.1.1.3 mrg (match_operand:SVE_FULL_I 3 "register_operand" "w, w")]
4253 1.1.1.3 mrg MUL_HIGHPART)
4254 1.1.1.3 mrg (match_dup 2)]
4255 1.1.1.3 mrg UNSPEC_SEL))]
4256 1.1.1.3 mrg "TARGET_SVE"
4257 1.1.1.3 mrg "@
4258 1.1.1.3 mrg <sve_int_op>\t%0.<Vetype>, %1/m, %0.<Vetype>, %3.<Vetype>
4259 1.1.1.3 mrg movprfx\t%0, %2\;<sve_int_op>\t%0.<Vetype>, %1/m, %0.<Vetype>, %3.<Vetype>"
4260 1.1.1.3 mrg [(set_attr "movprfx" "*,yes")])
4261 1.1.1.3 mrg
4262 1.1.1.3 mrg ;; Predicated highpart multiplications, merging with zero.
4263 1.1.1.3 mrg (define_insn "*cond_<optab><mode>_z"
4264 1.1.1.3 mrg [(set (match_operand:SVE_FULL_I 0 "register_operand" "=&w, &w")
4265 1.1.1.3 mrg (unspec:SVE_FULL_I
4266 1.1.1.3 mrg [(match_operand:<VPRED> 1 "register_operand" "Upl, Upl")
4267 1.1.1.3 mrg (unspec:SVE_FULL_I
4268 1.1.1.3 mrg [(match_operand:SVE_FULL_I 2 "register_operand" "%0, w")
4269 1.1.1.3 mrg (match_operand:SVE_FULL_I 3 "register_operand" "w, w")]
4270 1.1.1.3 mrg MUL_HIGHPART)
4271 1.1.1.3 mrg (match_operand:SVE_FULL_I 4 "aarch64_simd_imm_zero")]
4272 1.1.1.3 mrg UNSPEC_SEL))]
4273 1.1.1.3 mrg "TARGET_SVE"
4274 1.1.1.3 mrg "@
4275 1.1.1.3 mrg movprfx\t%0.<Vetype>, %1/z, %0.<Vetype>\;<sve_int_op>\t%0.<Vetype>, %1/m, %0.<Vetype>, %3.<Vetype>
4276 1.1.1.3 mrg movprfx\t%0.<Vetype>, %1/z, %2.<Vetype>\;<sve_int_op>\t%0.<Vetype>, %1/m, %0.<Vetype>, %3.<Vetype>"
4277 1.1.1.3 mrg [(set_attr "movprfx" "yes")])
4278 1.1.1.3 mrg
4279 1.1.1.3 mrg ;; -------------------------------------------------------------------------
4280 1.1.1.3 mrg ;; ---- [INT] Division
4281 1.1.1.3 mrg ;; -------------------------------------------------------------------------
4282 1.1.1.3 mrg ;; Includes:
4283 1.1.1.3 mrg ;; - SDIV
4284 1.1.1.3 mrg ;; - SDIVR
4285 1.1.1.3 mrg ;; - UDIV
4286 1.1.1.3 mrg ;; - UDIVR
4287 1.1.1.3 mrg ;; -------------------------------------------------------------------------
4288 1.1.1.3 mrg
4289 1.1.1.3 mrg ;; Unpredicated integer division.
4290 1.1.1.3 mrg (define_expand "<optab><mode>3"
4291 1.1.1.3 mrg [(set (match_operand:SVE_FULL_SDI 0 "register_operand")
4292 1.1.1.3 mrg (unspec:SVE_FULL_SDI
4293 1.1.1.3 mrg [(match_dup 3)
4294 1.1.1.3 mrg (SVE_INT_BINARY_SD:SVE_FULL_SDI
4295 1.1.1.3 mrg (match_operand:SVE_FULL_SDI 1 "register_operand")
4296 1.1.1.3 mrg (match_operand:SVE_FULL_SDI 2 "register_operand"))]
4297 1.1.1.3 mrg UNSPEC_PRED_X))]
4298 1.1.1.3 mrg "TARGET_SVE"
4299 1.1.1.3 mrg {
4300 1.1.1.3 mrg operands[3] = aarch64_ptrue_reg (<VPRED>mode);
4301 1.1.1.3 mrg }
4302 1.1.1.3 mrg )
4303 1.1.1.3 mrg
4304 1.1.1.3 mrg ;; Integer division predicated with a PTRUE.
4305 1.1.1.3 mrg (define_insn "@aarch64_pred_<optab><mode>"
4306 1.1.1.3 mrg [(set (match_operand:SVE_FULL_SDI 0 "register_operand" "=w, w, ?&w")
4307 1.1.1.3 mrg (unspec:SVE_FULL_SDI
4308 1.1.1.3 mrg [(match_operand:<VPRED> 1 "register_operand" "Upl, Upl, Upl")
4309 1.1.1.3 mrg (SVE_INT_BINARY_SD:SVE_FULL_SDI
4310 1.1.1.3 mrg (match_operand:SVE_FULL_SDI 2 "register_operand" "0, w, w")
4311 1.1.1.3 mrg (match_operand:SVE_FULL_SDI 3 "register_operand" "w, 0, w"))]
4312 1.1.1.3 mrg UNSPEC_PRED_X))]
4313 1.1.1.3 mrg "TARGET_SVE"
4314 1.1.1.3 mrg "@
4315 1.1.1.3 mrg <sve_int_op>\t%0.<Vetype>, %1/m, %0.<Vetype>, %3.<Vetype>
4316 1.1.1.3 mrg <sve_int_op>r\t%0.<Vetype>, %1/m, %0.<Vetype>, %2.<Vetype>
4317 1.1.1.3 mrg movprfx\t%0, %2\;<sve_int_op>\t%0.<Vetype>, %1/m, %0.<Vetype>, %3.<Vetype>"
4318 1.1.1.3 mrg [(set_attr "movprfx" "*,*,yes")]
4319 1.1.1.3 mrg )
4320 1.1.1.3 mrg
4321 1.1.1.3 mrg ;; Predicated integer division with merging.
4322 1.1.1.3 mrg (define_expand "@cond_<optab><mode>"
4323 1.1.1.3 mrg [(set (match_operand:SVE_FULL_SDI 0 "register_operand")
4324 1.1.1.3 mrg (unspec:SVE_FULL_SDI
4325 1.1.1.3 mrg [(match_operand:<VPRED> 1 "register_operand")
4326 1.1.1.3 mrg (SVE_INT_BINARY_SD:SVE_FULL_SDI
4327 1.1.1.3 mrg (match_operand:SVE_FULL_SDI 2 "register_operand")
4328 1.1.1.3 mrg (match_operand:SVE_FULL_SDI 3 "register_operand"))
4329 1.1.1.3 mrg (match_operand:SVE_FULL_SDI 4 "aarch64_simd_reg_or_zero")]
4330 1.1.1.3 mrg UNSPEC_SEL))]
4331 1.1.1.3 mrg "TARGET_SVE"
4332 1.1.1.3 mrg )
4333 1.1.1.3 mrg
4334 1.1.1.3 mrg ;; Predicated integer division, merging with the first input.
4335 1.1.1.3 mrg (define_insn "*cond_<optab><mode>_2"
4336 1.1.1.3 mrg [(set (match_operand:SVE_FULL_SDI 0 "register_operand" "=w, ?&w")
4337 1.1.1.3 mrg (unspec:SVE_FULL_SDI
4338 1.1.1.3 mrg [(match_operand:<VPRED> 1 "register_operand" "Upl, Upl")
4339 1.1.1.3 mrg (SVE_INT_BINARY_SD:SVE_FULL_SDI
4340 1.1.1.3 mrg (match_operand:SVE_FULL_SDI 2 "register_operand" "0, w")
4341 1.1.1.3 mrg (match_operand:SVE_FULL_SDI 3 "register_operand" "w, w"))
4342 1.1.1.3 mrg (match_dup 2)]
4343 1.1.1.3 mrg UNSPEC_SEL))]
4344 1.1.1.3 mrg "TARGET_SVE"
4345 1.1.1.3 mrg "@
4346 1.1.1.3 mrg <sve_int_op>\t%0.<Vetype>, %1/m, %0.<Vetype>, %3.<Vetype>
4347 1.1.1.3 mrg movprfx\t%0, %2\;<sve_int_op>\t%0.<Vetype>, %1/m, %0.<Vetype>, %3.<Vetype>"
4348 1.1.1.3 mrg [(set_attr "movprfx" "*,yes")]
4349 1.1.1.3 mrg )
4350 1.1.1.3 mrg
4351 1.1.1.3 mrg ;; Predicated integer division, merging with the second input.
4352 1.1.1.3 mrg (define_insn "*cond_<optab><mode>_3"
4353 1.1.1.3 mrg [(set (match_operand:SVE_FULL_SDI 0 "register_operand" "=w, ?&w")
4354 1.1.1.3 mrg (unspec:SVE_FULL_SDI
4355 1.1.1.3 mrg [(match_operand:<VPRED> 1 "register_operand" "Upl, Upl")
4356 1.1.1.3 mrg (SVE_INT_BINARY_SD:SVE_FULL_SDI
4357 1.1.1.3 mrg (match_operand:SVE_FULL_SDI 2 "register_operand" "w, w")
4358 1.1.1.3 mrg (match_operand:SVE_FULL_SDI 3 "register_operand" "0, w"))
4359 1.1.1.3 mrg (match_dup 3)]
4360 1.1.1.3 mrg UNSPEC_SEL))]
4361 1.1.1.3 mrg "TARGET_SVE"
4362 1.1.1.3 mrg "@
4363 1.1.1.3 mrg <sve_int_op_rev>\t%0.<Vetype>, %1/m, %0.<Vetype>, %2.<Vetype>
4364 1.1.1.3 mrg movprfx\t%0, %3\;<sve_int_op_rev>\t%0.<Vetype>, %1/m, %0.<Vetype>, %2.<Vetype>"
4365 1.1.1.3 mrg [(set_attr "movprfx" "*,yes")]
4366 1.1.1.3 mrg )
4367 1.1.1.3 mrg
4368 1.1.1.3 mrg ;; Predicated integer division, merging with an independent value.
4369 1.1.1.3 mrg (define_insn_and_rewrite "*cond_<optab><mode>_any"
4370 1.1.1.3 mrg [(set (match_operand:SVE_FULL_SDI 0 "register_operand" "=&w, &w, &w, &w, ?&w")
4371 1.1.1.3 mrg (unspec:SVE_FULL_SDI
4372 1.1.1.3 mrg [(match_operand:<VPRED> 1 "register_operand" "Upl, Upl, Upl, Upl, Upl")
4373 1.1.1.3 mrg (SVE_INT_BINARY_SD:SVE_FULL_SDI
4374 1.1.1.3 mrg (match_operand:SVE_FULL_SDI 2 "register_operand" "0, w, w, w, w")
4375 1.1.1.3 mrg (match_operand:SVE_FULL_SDI 3 "register_operand" "w, 0, w, w, w"))
4376 1.1.1.3 mrg (match_operand:SVE_FULL_SDI 4 "aarch64_simd_reg_or_zero" "Dz, Dz, Dz, 0, w")]
4377 1.1.1.3 mrg UNSPEC_SEL))]
4378 1.1.1.3 mrg "TARGET_SVE
4379 1.1.1.3 mrg && !rtx_equal_p (operands[2], operands[4])
4380 1.1.1.3 mrg && !rtx_equal_p (operands[3], operands[4])"
4381 1.1.1.3 mrg "@
4382 1.1.1.3 mrg movprfx\t%0.<Vetype>, %1/z, %0.<Vetype>\;<sve_int_op>\t%0.<Vetype>, %1/m, %0.<Vetype>, %3.<Vetype>
4383 1.1.1.3 mrg movprfx\t%0.<Vetype>, %1/z, %0.<Vetype>\;<sve_int_op_rev>\t%0.<Vetype>, %1/m, %0.<Vetype>, %2.<Vetype>
4384 1.1.1.3 mrg movprfx\t%0.<Vetype>, %1/z, %2.<Vetype>\;<sve_int_op>\t%0.<Vetype>, %1/m, %0.<Vetype>, %3.<Vetype>
4385 1.1.1.3 mrg movprfx\t%0.<Vetype>, %1/m, %2.<Vetype>\;<sve_int_op>\t%0.<Vetype>, %1/m, %0.<Vetype>, %3.<Vetype>
4386 1.1.1.3 mrg #"
4387 1.1.1.3 mrg "&& reload_completed
4388 1.1.1.3 mrg && register_operand (operands[4], <MODE>mode)
4389 1.1.1.3 mrg && !rtx_equal_p (operands[0], operands[4])"
4390 1.1.1.3 mrg {
4391 1.1.1.3 mrg emit_insn (gen_vcond_mask_<mode><vpred> (operands[0], operands[2],
4392 1.1.1.3 mrg operands[4], operands[1]));
4393 1.1.1.3 mrg operands[4] = operands[2] = operands[0];
4394 1.1.1.3 mrg }
4395 1.1.1.3 mrg [(set_attr "movprfx" "yes")]
4396 1.1.1.3 mrg )
4397 1.1.1.3 mrg
4398 1.1.1.3 mrg ;; -------------------------------------------------------------------------
4399 1.1.1.3 mrg ;; ---- [INT] Binary logical operations
4400 1.1.1.3 mrg ;; -------------------------------------------------------------------------
4401 1.1.1.3 mrg ;; Includes:
4402 1.1.1.3 mrg ;; - AND
4403 1.1.1.3 mrg ;; - EOR
4404 1.1.1.3 mrg ;; - ORR
4405 1.1.1.3 mrg ;; -------------------------------------------------------------------------
4406 1.1.1.3 mrg
4407 1.1.1.3 mrg ;; Unpredicated integer binary logical operations.
4408 1.1.1.3 mrg (define_insn "<optab><mode>3"
4409 1.1.1.5 mrg [(set (match_operand:SVE_I 0 "register_operand" "=w, ?w, w")
4410 1.1.1.5 mrg (LOGICAL:SVE_I
4411 1.1.1.5 mrg (match_operand:SVE_I 1 "register_operand" "%0, w, w")
4412 1.1.1.5 mrg (match_operand:SVE_I 2 "aarch64_sve_logical_operand" "vsl, vsl, w")))]
4413 1.1.1.3 mrg "TARGET_SVE"
4414 1.1.1.3 mrg "@
4415 1.1.1.3 mrg <logical>\t%0.<Vetype>, %0.<Vetype>, #%C2
4416 1.1.1.3 mrg movprfx\t%0, %1\;<logical>\t%0.<Vetype>, %0.<Vetype>, #%C2
4417 1.1.1.3 mrg <logical>\t%0.d, %1.d, %2.d"
4418 1.1.1.3 mrg [(set_attr "movprfx" "*,yes,*")]
4419 1.1.1.3 mrg )
4420 1.1.1.3 mrg
4421 1.1.1.3 mrg ;; Merging forms are handled through SVE_INT_BINARY.
4422 1.1.1.3 mrg
4423 1.1.1.3 mrg ;; -------------------------------------------------------------------------
4424 1.1.1.3 mrg ;; ---- [INT] Binary logical operations (inverted second input)
4425 1.1.1.3 mrg ;; -------------------------------------------------------------------------
4426 1.1.1.3 mrg ;; Includes:
4427 1.1.1.3 mrg ;; - BIC
4428 1.1.1.3 mrg ;; -------------------------------------------------------------------------
4429 1.1.1.3 mrg
4430 1.1.1.3 mrg ;; Unpredicated BIC.
4431 1.1.1.3 mrg (define_expand "@aarch64_bic<mode>"
4432 1.1.1.5 mrg [(set (match_operand:SVE_I 0 "register_operand")
4433 1.1.1.5 mrg (and:SVE_I
4434 1.1.1.5 mrg (unspec:SVE_I
4435 1.1.1.3 mrg [(match_dup 3)
4436 1.1.1.5 mrg (not:SVE_I (match_operand:SVE_I 2 "register_operand"))]
4437 1.1.1.3 mrg UNSPEC_PRED_X)
4438 1.1.1.5 mrg (match_operand:SVE_I 1 "register_operand")))]
4439 1.1.1.3 mrg "TARGET_SVE"
4440 1.1.1.3 mrg {
4441 1.1.1.3 mrg operands[3] = CONSTM1_RTX (<VPRED>mode);
4442 1.1.1.3 mrg }
4443 1.1.1.3 mrg )
4444 1.1.1.3 mrg
4445 1.1.1.3 mrg ;; Predicated BIC.
4446 1.1.1.3 mrg (define_insn_and_rewrite "*bic<mode>3"
4447 1.1.1.5 mrg [(set (match_operand:SVE_I 0 "register_operand" "=w")
4448 1.1.1.5 mrg (and:SVE_I
4449 1.1.1.5 mrg (unspec:SVE_I
4450 1.1.1.3 mrg [(match_operand 3)
4451 1.1.1.5 mrg (not:SVE_I
4452 1.1.1.5 mrg (match_operand:SVE_I 2 "register_operand" "w"))]
4453 1.1.1.3 mrg UNSPEC_PRED_X)
4454 1.1.1.5 mrg (match_operand:SVE_I 1 "register_operand" "w")))]
4455 1.1.1.3 mrg "TARGET_SVE"
4456 1.1.1.3 mrg "bic\t%0.d, %1.d, %2.d"
4457 1.1.1.3 mrg "&& !CONSTANT_P (operands[3])"
4458 1.1.1.3 mrg {
4459 1.1.1.3 mrg operands[3] = CONSTM1_RTX (<VPRED>mode);
4460 1.1.1.3 mrg }
4461 1.1.1.3 mrg )
4462 1.1.1.3 mrg
4463 1.1.1.3 mrg ;; Predicated BIC with merging.
4464 1.1.1.3 mrg (define_expand "@cond_bic<mode>"
4465 1.1.1.3 mrg [(set (match_operand:SVE_FULL_I 0 "register_operand")
4466 1.1.1.3 mrg (unspec:SVE_FULL_I
4467 1.1.1.3 mrg [(match_operand:<VPRED> 1 "register_operand")
4468 1.1.1.3 mrg (and:SVE_FULL_I
4469 1.1.1.3 mrg (not:SVE_FULL_I (match_operand:SVE_FULL_I 3 "register_operand"))
4470 1.1.1.3 mrg (match_operand:SVE_FULL_I 2 "register_operand"))
4471 1.1.1.3 mrg (match_operand:SVE_FULL_I 4 "aarch64_simd_reg_or_zero")]
4472 1.1.1.3 mrg UNSPEC_SEL))]
4473 1.1.1.3 mrg "TARGET_SVE"
4474 1.1.1.3 mrg )
4475 1.1.1.3 mrg
4476 1.1.1.3 mrg ;; Predicated integer BIC, merging with the first input.
4477 1.1.1.3 mrg (define_insn "*cond_bic<mode>_2"
4478 1.1.1.5 mrg [(set (match_operand:SVE_I 0 "register_operand" "=w, ?&w")
4479 1.1.1.5 mrg (unspec:SVE_I
4480 1.1.1.3 mrg [(match_operand:<VPRED> 1 "register_operand" "Upl, Upl")
4481 1.1.1.5 mrg (and:SVE_I
4482 1.1.1.5 mrg (not:SVE_I
4483 1.1.1.5 mrg (match_operand:SVE_I 3 "register_operand" "w, w"))
4484 1.1.1.5 mrg (match_operand:SVE_I 2 "register_operand" "0, w"))
4485 1.1.1.3 mrg (match_dup 2)]
4486 1.1.1.3 mrg UNSPEC_SEL))]
4487 1.1.1.3 mrg "TARGET_SVE"
4488 1.1.1.3 mrg "@
4489 1.1.1.3 mrg bic\t%0.<Vetype>, %1/m, %0.<Vetype>, %3.<Vetype>
4490 1.1.1.3 mrg movprfx\t%0, %2\;bic\t%0.<Vetype>, %1/m, %0.<Vetype>, %3.<Vetype>"
4491 1.1.1.3 mrg [(set_attr "movprfx" "*,yes")]
4492 1.1.1.3 mrg )
4493 1.1.1.3 mrg
4494 1.1.1.3 mrg ;; Predicated integer BIC, merging with an independent value.
4495 1.1.1.3 mrg (define_insn_and_rewrite "*cond_bic<mode>_any"
4496 1.1.1.5 mrg [(set (match_operand:SVE_I 0 "register_operand" "=&w, &w, &w, ?&w")
4497 1.1.1.5 mrg (unspec:SVE_I
4498 1.1.1.3 mrg [(match_operand:<VPRED> 1 "register_operand" "Upl, Upl, Upl, Upl")
4499 1.1.1.5 mrg (and:SVE_I
4500 1.1.1.5 mrg (not:SVE_I
4501 1.1.1.5 mrg (match_operand:SVE_I 3 "register_operand" "w, w, w, w"))
4502 1.1.1.5 mrg (match_operand:SVE_I 2 "register_operand" "0, w, w, w"))
4503 1.1.1.5 mrg (match_operand:SVE_I 4 "aarch64_simd_reg_or_zero" "Dz, Dz, 0, w")]
4504 1.1.1.3 mrg UNSPEC_SEL))]
4505 1.1.1.3 mrg "TARGET_SVE && !rtx_equal_p (operands[2], operands[4])"
4506 1.1.1.3 mrg "@
4507 1.1.1.3 mrg movprfx\t%0.<Vetype>, %1/z, %0.<Vetype>\;bic\t%0.<Vetype>, %1/m, %0.<Vetype>, %3.<Vetype>
4508 1.1.1.3 mrg movprfx\t%0.<Vetype>, %1/z, %2.<Vetype>\;bic\t%0.<Vetype>, %1/m, %0.<Vetype>, %3.<Vetype>
4509 1.1.1.3 mrg movprfx\t%0.<Vetype>, %1/m, %2.<Vetype>\;bic\t%0.<Vetype>, %1/m, %0.<Vetype>, %3.<Vetype>
4510 1.1.1.3 mrg #"
4511 1.1.1.3 mrg "&& reload_completed
4512 1.1.1.3 mrg && register_operand (operands[4], <MODE>mode)
4513 1.1.1.3 mrg && !rtx_equal_p (operands[0], operands[4])"
4514 1.1.1.3 mrg {
4515 1.1.1.3 mrg emit_insn (gen_vcond_mask_<mode><vpred> (operands[0], operands[2],
4516 1.1.1.3 mrg operands[4], operands[1]));
4517 1.1.1.3 mrg operands[4] = operands[2] = operands[0];
4518 1.1.1.3 mrg }
4519 1.1.1.3 mrg [(set_attr "movprfx" "yes")]
4520 1.1.1.3 mrg )
4521 1.1.1.3 mrg
4522 1.1.1.3 mrg ;; -------------------------------------------------------------------------
4523 1.1.1.3 mrg ;; ---- [INT] Shifts (rounding towards -Inf)
4524 1.1.1.3 mrg ;; -------------------------------------------------------------------------
4525 1.1.1.3 mrg ;; Includes:
4526 1.1.1.3 mrg ;; - ASR
4527 1.1.1.3 mrg ;; - ASRR
4528 1.1.1.3 mrg ;; - LSL
4529 1.1.1.3 mrg ;; - LSLR
4530 1.1.1.3 mrg ;; - LSR
4531 1.1.1.3 mrg ;; - LSRR
4532 1.1.1.3 mrg ;; -------------------------------------------------------------------------
4533 1.1.1.3 mrg
4534 1.1.1.3 mrg ;; Unpredicated shift by a scalar, which expands into one of the vector
4535 1.1.1.3 mrg ;; shifts below.
4536 1.1.1.3 mrg (define_expand "<ASHIFT:optab><mode>3"
4537 1.1.1.5 mrg [(set (match_operand:SVE_I 0 "register_operand")
4538 1.1.1.5 mrg (ASHIFT:SVE_I
4539 1.1.1.5 mrg (match_operand:SVE_I 1 "register_operand")
4540 1.1.1.3 mrg (match_operand:<VEL> 2 "general_operand")))]
4541 1.1.1.3 mrg "TARGET_SVE"
4542 1.1.1.3 mrg {
4543 1.1.1.3 mrg rtx amount;
4544 1.1.1.3 mrg if (CONST_INT_P (operands[2]))
4545 1.1.1.3 mrg {
4546 1.1.1.3 mrg amount = gen_const_vec_duplicate (<MODE>mode, operands[2]);
4547 1.1.1.3 mrg if (!aarch64_sve_<lr>shift_operand (operands[2], <MODE>mode))
4548 1.1.1.3 mrg amount = force_reg (<MODE>mode, amount);
4549 1.1.1.3 mrg }
4550 1.1.1.3 mrg else
4551 1.1.1.3 mrg {
4552 1.1.1.5 mrg amount = convert_to_mode (<VEL>mode, operands[2], 0);
4553 1.1.1.5 mrg amount = expand_vector_broadcast (<MODE>mode, amount);
4554 1.1.1.3 mrg }
4555 1.1.1.3 mrg emit_insn (gen_v<optab><mode>3 (operands[0], operands[1], amount));
4556 1.1.1.3 mrg DONE;
4557 1.1.1.3 mrg }
4558 1.1.1.3 mrg )
4559 1.1.1.3 mrg
4560 1.1.1.3 mrg ;; Unpredicated shift by a vector.
4561 1.1.1.3 mrg (define_expand "v<optab><mode>3"
4562 1.1.1.5 mrg [(set (match_operand:SVE_I 0 "register_operand")
4563 1.1.1.5 mrg (unspec:SVE_I
4564 1.1.1.3 mrg [(match_dup 3)
4565 1.1.1.5 mrg (ASHIFT:SVE_I
4566 1.1.1.5 mrg (match_operand:SVE_I 1 "register_operand")
4567 1.1.1.5 mrg (match_operand:SVE_I 2 "aarch64_sve_<lr>shift_operand"))]
4568 1.1.1.3 mrg UNSPEC_PRED_X))]
4569 1.1.1.3 mrg "TARGET_SVE"
4570 1.1.1.3 mrg {
4571 1.1.1.3 mrg operands[3] = aarch64_ptrue_reg (<VPRED>mode);
4572 1.1.1.3 mrg }
4573 1.1.1.3 mrg )
4574 1.1.1.3 mrg
4575 1.1.1.3 mrg ;; Shift by a vector, predicated with a PTRUE. We don't actually need
4576 1.1.1.3 mrg ;; the predicate for the first alternative, but using Upa or X isn't
4577 1.1.1.3 mrg ;; likely to gain much and would make the instruction seem less uniform
4578 1.1.1.3 mrg ;; to the register allocator.
4579 1.1.1.3 mrg (define_insn_and_split "@aarch64_pred_<optab><mode>"
4580 1.1.1.5 mrg [(set (match_operand:SVE_I 0 "register_operand" "=w, w, w, ?&w")
4581 1.1.1.5 mrg (unspec:SVE_I
4582 1.1.1.3 mrg [(match_operand:<VPRED> 1 "register_operand" "Upl, Upl, Upl, Upl")
4583 1.1.1.5 mrg (ASHIFT:SVE_I
4584 1.1.1.5 mrg (match_operand:SVE_I 2 "register_operand" "w, 0, w, w")
4585 1.1.1.5 mrg (match_operand:SVE_I 3 "aarch64_sve_<lr>shift_operand" "D<lr>, w, 0, w"))]
4586 1.1.1.3 mrg UNSPEC_PRED_X))]
4587 1.1.1.3 mrg "TARGET_SVE"
4588 1.1.1.3 mrg "@
4589 1.1.1.3 mrg #
4590 1.1.1.3 mrg <shift>\t%0.<Vetype>, %1/m, %0.<Vetype>, %3.<Vetype>
4591 1.1.1.3 mrg <shift>r\t%0.<Vetype>, %1/m, %3.<Vetype>, %2.<Vetype>
4592 1.1.1.3 mrg movprfx\t%0, %2\;<shift>\t%0.<Vetype>, %1/m, %0.<Vetype>, %3.<Vetype>"
4593 1.1.1.3 mrg "&& reload_completed
4594 1.1.1.3 mrg && !register_operand (operands[3], <MODE>mode)"
4595 1.1.1.5 mrg [(set (match_dup 0) (ASHIFT:SVE_I (match_dup 2) (match_dup 3)))]
4596 1.1.1.3 mrg ""
4597 1.1.1.3 mrg [(set_attr "movprfx" "*,*,*,yes")]
4598 1.1.1.3 mrg )
4599 1.1.1.3 mrg
4600 1.1.1.3 mrg ;; Unpredicated shift operations by a constant (post-RA only).
4601 1.1.1.3 mrg ;; These are generated by splitting a predicated instruction whose
4602 1.1.1.3 mrg ;; predicate is unused.
4603 1.1.1.3 mrg (define_insn "*post_ra_v<optab><mode>3"
4604 1.1.1.5 mrg [(set (match_operand:SVE_I 0 "register_operand" "=w")
4605 1.1.1.5 mrg (ASHIFT:SVE_I
4606 1.1.1.5 mrg (match_operand:SVE_I 1 "register_operand" "w")
4607 1.1.1.5 mrg (match_operand:SVE_I 2 "aarch64_simd_<lr>shift_imm")))]
4608 1.1.1.3 mrg "TARGET_SVE && reload_completed"
4609 1.1.1.3 mrg "<shift>\t%0.<Vetype>, %1.<Vetype>, #%2"
4610 1.1.1.3 mrg )
4611 1.1.1.3 mrg
4612 1.1.1.3 mrg ;; Predicated integer shift, merging with the first input.
4613 1.1.1.3 mrg (define_insn "*cond_<optab><mode>_2_const"
4614 1.1.1.5 mrg [(set (match_operand:SVE_I 0 "register_operand" "=w, ?&w")
4615 1.1.1.5 mrg (unspec:SVE_I
4616 1.1.1.3 mrg [(match_operand:<VPRED> 1 "register_operand" "Upl, Upl")
4617 1.1.1.5 mrg (ASHIFT:SVE_I
4618 1.1.1.5 mrg (match_operand:SVE_I 2 "register_operand" "0, w")
4619 1.1.1.5 mrg (match_operand:SVE_I 3 "aarch64_simd_<lr>shift_imm"))
4620 1.1.1.3 mrg (match_dup 2)]
4621 1.1.1.3 mrg UNSPEC_SEL))]
4622 1.1.1.3 mrg "TARGET_SVE"
4623 1.1.1.3 mrg "@
4624 1.1.1.3 mrg <shift>\t%0.<Vetype>, %1/m, %0.<Vetype>, #%3
4625 1.1.1.3 mrg movprfx\t%0, %2\;<shift>\t%0.<Vetype>, %1/m, %0.<Vetype>, #%3"
4626 1.1.1.3 mrg [(set_attr "movprfx" "*,yes")]
4627 1.1.1.3 mrg )
4628 1.1.1.3 mrg
4629 1.1.1.3 mrg ;; Predicated integer shift, merging with an independent value.
4630 1.1.1.3 mrg (define_insn_and_rewrite "*cond_<optab><mode>_any_const"
4631 1.1.1.5 mrg [(set (match_operand:SVE_I 0 "register_operand" "=w, &w, ?&w")
4632 1.1.1.5 mrg (unspec:SVE_I
4633 1.1.1.3 mrg [(match_operand:<VPRED> 1 "register_operand" "Upl, Upl, Upl")
4634 1.1.1.5 mrg (ASHIFT:SVE_I
4635 1.1.1.5 mrg (match_operand:SVE_I 2 "register_operand" "w, w, w")
4636 1.1.1.5 mrg (match_operand:SVE_I 3 "aarch64_simd_<lr>shift_imm"))
4637 1.1.1.5 mrg (match_operand:SVE_I 4 "aarch64_simd_reg_or_zero" "Dz, 0, w")]
4638 1.1.1.3 mrg UNSPEC_SEL))]
4639 1.1.1.3 mrg "TARGET_SVE && !rtx_equal_p (operands[2], operands[4])"
4640 1.1.1.3 mrg "@
4641 1.1.1.3 mrg movprfx\t%0.<Vetype>, %1/z, %2.<Vetype>\;<shift>\t%0.<Vetype>, %1/m, %0.<Vetype>, #%3
4642 1.1.1.3 mrg movprfx\t%0.<Vetype>, %1/m, %2.<Vetype>\;<shift>\t%0.<Vetype>, %1/m, %0.<Vetype>, #%3
4643 1.1.1.3 mrg #"
4644 1.1.1.3 mrg "&& reload_completed
4645 1.1.1.3 mrg && register_operand (operands[4], <MODE>mode)
4646 1.1.1.3 mrg && !rtx_equal_p (operands[0], operands[4])"
4647 1.1.1.3 mrg {
4648 1.1.1.3 mrg emit_insn (gen_vcond_mask_<mode><vpred> (operands[0], operands[2],
4649 1.1.1.3 mrg operands[4], operands[1]));
4650 1.1.1.3 mrg operands[4] = operands[2] = operands[0];
4651 1.1.1.3 mrg }
4652 1.1.1.3 mrg [(set_attr "movprfx" "yes")]
4653 1.1.1.3 mrg )
4654 1.1.1.3 mrg
4655 1.1.1.3 mrg ;; Unpredicated shifts of narrow elements by 64-bit amounts.
4656 1.1.1.3 mrg (define_insn "@aarch64_sve_<sve_int_op><mode>"
4657 1.1.1.3 mrg [(set (match_operand:SVE_FULL_BHSI 0 "register_operand" "=w")
4658 1.1.1.3 mrg (unspec:SVE_FULL_BHSI
4659 1.1.1.3 mrg [(match_operand:SVE_FULL_BHSI 1 "register_operand" "w")
4660 1.1.1.3 mrg (match_operand:VNx2DI 2 "register_operand" "w")]
4661 1.1.1.3 mrg SVE_SHIFT_WIDE))]
4662 1.1.1.3 mrg "TARGET_SVE"
4663 1.1.1.3 mrg "<sve_int_op>\t%0.<Vetype>, %1.<Vetype>, %2.d"
4664 1.1.1.3 mrg )
4665 1.1.1.3 mrg
4666 1.1.1.3 mrg ;; Merging predicated shifts of narrow elements by 64-bit amounts.
4667 1.1.1.3 mrg (define_expand "@cond_<sve_int_op><mode>"
4668 1.1.1.3 mrg [(set (match_operand:SVE_FULL_BHSI 0 "register_operand")
4669 1.1.1.3 mrg (unspec:SVE_FULL_BHSI
4670 1.1.1.3 mrg [(match_operand:<VPRED> 1 "register_operand")
4671 1.1.1.3 mrg (unspec:SVE_FULL_BHSI
4672 1.1.1.3 mrg [(match_operand:SVE_FULL_BHSI 2 "register_operand")
4673 1.1.1.3 mrg (match_operand:VNx2DI 3 "register_operand")]
4674 1.1.1.3 mrg SVE_SHIFT_WIDE)
4675 1.1.1.3 mrg (match_operand:SVE_FULL_BHSI 4 "aarch64_simd_reg_or_zero")]
4676 1.1.1.3 mrg UNSPEC_SEL))]
4677 1.1.1.3 mrg "TARGET_SVE"
4678 1.1.1.3 mrg )
4679 1.1.1.3 mrg
4680 1.1.1.3 mrg ;; Predicated shifts of narrow elements by 64-bit amounts, merging with
4681 1.1.1.3 mrg ;; the first input.
4682 1.1.1.3 mrg (define_insn "*cond_<sve_int_op><mode>_m"
4683 1.1.1.3 mrg [(set (match_operand:SVE_FULL_BHSI 0 "register_operand" "=w, ?&w")
4684 1.1.1.3 mrg (unspec:SVE_FULL_BHSI
4685 1.1.1.3 mrg [(match_operand:<VPRED> 1 "register_operand" "Upl, Upl")
4686 1.1.1.3 mrg (unspec:SVE_FULL_BHSI
4687 1.1.1.3 mrg [(match_operand:SVE_FULL_BHSI 2 "register_operand" "0, w")
4688 1.1.1.3 mrg (match_operand:VNx2DI 3 "register_operand" "w, w")]
4689 1.1.1.3 mrg SVE_SHIFT_WIDE)
4690 1.1.1.3 mrg (match_dup 2)]
4691 1.1.1.3 mrg UNSPEC_SEL))]
4692 1.1.1.3 mrg "TARGET_SVE"
4693 1.1.1.3 mrg "@
4694 1.1.1.3 mrg <sve_int_op>\t%0.<Vetype>, %1/m, %0.<Vetype>, %3.d
4695 1.1.1.3 mrg movprfx\t%0, %2\;<sve_int_op>\t%0.<Vetype>, %1/m, %0.<Vetype>, %3.d"
4696 1.1.1.3 mrg [(set_attr "movprfx" "*, yes")])
4697 1.1.1.3 mrg
4698 1.1.1.3 mrg ;; Predicated shifts of narrow elements by 64-bit amounts, merging with zero.
4699 1.1.1.3 mrg (define_insn "*cond_<sve_int_op><mode>_z"
4700 1.1.1.3 mrg [(set (match_operand:SVE_FULL_BHSI 0 "register_operand" "=&w, &w")
4701 1.1.1.3 mrg (unspec:SVE_FULL_BHSI
4702 1.1.1.3 mrg [(match_operand:<VPRED> 1 "register_operand" "Upl, Upl")
4703 1.1.1.3 mrg (unspec:SVE_FULL_BHSI
4704 1.1.1.3 mrg [(match_operand:SVE_FULL_BHSI 2 "register_operand" "0, w")
4705 1.1.1.3 mrg (match_operand:VNx2DI 3 "register_operand" "w, w")]
4706 1.1.1.3 mrg SVE_SHIFT_WIDE)
4707 1.1.1.3 mrg (match_operand:SVE_FULL_BHSI 4 "aarch64_simd_imm_zero")]
4708 1.1.1.3 mrg UNSPEC_SEL))]
4709 1.1.1.3 mrg "TARGET_SVE"
4710 1.1.1.3 mrg "@
4711 1.1.1.3 mrg movprfx\t%0.<Vetype>, %1/z, %0.<Vetype>\;<sve_int_op>\t%0.<Vetype>, %1/m, %0.<Vetype>, %3.d
4712 1.1.1.3 mrg movprfx\t%0.<Vetype>, %1/z, %2.<Vetype>\;<sve_int_op>\t%0.<Vetype>, %1/m, %0.<Vetype>, %3.d"
4713 1.1.1.3 mrg [(set_attr "movprfx" "yes")])
4714 1.1.1.3 mrg
4715 1.1.1.3 mrg ;; -------------------------------------------------------------------------
4716 1.1.1.3 mrg ;; ---- [INT] Shifts (rounding towards 0)
4717 1.1.1.3 mrg ;; -------------------------------------------------------------------------
4718 1.1.1.3 mrg ;; Includes:
4719 1.1.1.3 mrg ;; - ASRD
4720 1.1.1.3 mrg ;; - SQSHLU (SVE2)
4721 1.1.1.3 mrg ;; - SRSHR (SVE2)
4722 1.1.1.3 mrg ;; - URSHR (SVE2)
4723 1.1.1.3 mrg ;; -------------------------------------------------------------------------
4724 1.1.1.3 mrg
4725 1.1.1.5 mrg ;; Unpredicated ASRD.
4726 1.1.1.3 mrg (define_expand "sdiv_pow2<mode>3"
4727 1.1.1.5 mrg [(set (match_operand:SVE_I 0 "register_operand")
4728 1.1.1.5 mrg (unspec:SVE_I
4729 1.1.1.3 mrg [(match_dup 3)
4730 1.1.1.5 mrg (unspec:SVE_I
4731 1.1.1.5 mrg [(match_operand:SVE_I 1 "register_operand")
4732 1.1.1.3 mrg (match_operand 2 "aarch64_simd_rshift_imm")]
4733 1.1.1.5 mrg UNSPEC_ASRD)]
4734 1.1.1.5 mrg UNSPEC_PRED_X))]
4735 1.1.1.3 mrg "TARGET_SVE"
4736 1.1.1.3 mrg {
4737 1.1.1.3 mrg operands[3] = aarch64_ptrue_reg (<VPRED>mode);
4738 1.1.1.3 mrg }
4739 1.1.1.3 mrg )
4740 1.1.1.3 mrg
4741 1.1.1.5 mrg ;; Predicated ASRD.
4742 1.1.1.5 mrg (define_insn "*sdiv_pow2<mode>3"
4743 1.1.1.5 mrg [(set (match_operand:SVE_I 0 "register_operand" "=w, ?&w")
4744 1.1.1.5 mrg (unspec:SVE_I
4745 1.1.1.5 mrg [(match_operand:<VPRED> 1 "register_operand" "Upl, Upl")
4746 1.1.1.5 mrg (unspec:SVE_I
4747 1.1.1.5 mrg [(match_operand:SVE_I 2 "register_operand" "0, w")
4748 1.1.1.5 mrg (match_operand:SVE_I 3 "aarch64_simd_rshift_imm")]
4749 1.1.1.5 mrg UNSPEC_ASRD)]
4750 1.1.1.5 mrg UNSPEC_PRED_X))]
4751 1.1.1.5 mrg "TARGET_SVE"
4752 1.1.1.5 mrg "@
4753 1.1.1.5 mrg asrd\t%0.<Vetype>, %1/m, %0.<Vetype>, #%3
4754 1.1.1.5 mrg movprfx\t%0, %2\;asrd\t%0.<Vetype>, %1/m, %0.<Vetype>, #%3"
4755 1.1.1.5 mrg [(set_attr "movprfx" "*,yes")])
4756 1.1.1.5 mrg
4757 1.1.1.5 mrg ;; Predicated shift with merging.
4758 1.1.1.3 mrg (define_expand "@cond_<sve_int_op><mode>"
4759 1.1.1.5 mrg [(set (match_operand:SVE_I 0 "register_operand")
4760 1.1.1.5 mrg (unspec:SVE_I
4761 1.1.1.3 mrg [(match_operand:<VPRED> 1 "register_operand")
4762 1.1.1.5 mrg (unspec:SVE_I
4763 1.1.1.5 mrg [(match_dup 5)
4764 1.1.1.5 mrg (unspec:SVE_I
4765 1.1.1.5 mrg [(match_operand:SVE_I 2 "register_operand")
4766 1.1.1.5 mrg (match_operand:SVE_I 3 "aarch64_simd_<lr>shift_imm")]
4767 1.1.1.5 mrg SVE_INT_SHIFT_IMM)]
4768 1.1.1.5 mrg UNSPEC_PRED_X)
4769 1.1.1.5 mrg (match_operand:SVE_I 4 "aarch64_simd_reg_or_zero")]
4770 1.1.1.3 mrg UNSPEC_SEL))]
4771 1.1.1.3 mrg "TARGET_SVE"
4772 1.1.1.5 mrg {
4773 1.1.1.5 mrg operands[5] = aarch64_ptrue_reg (<VPRED>mode);
4774 1.1.1.5 mrg }
4775 1.1.1.3 mrg )
4776 1.1.1.3 mrg
4777 1.1.1.5 mrg ;; Predicated shift, merging with the first input.
4778 1.1.1.5 mrg (define_insn_and_rewrite "*cond_<sve_int_op><mode>_2"
4779 1.1.1.5 mrg [(set (match_operand:SVE_I 0 "register_operand" "=w, ?&w")
4780 1.1.1.5 mrg (unspec:SVE_I
4781 1.1.1.3 mrg [(match_operand:<VPRED> 1 "register_operand" "Upl, Upl")
4782 1.1.1.5 mrg (unspec:SVE_I
4783 1.1.1.5 mrg [(match_operand 4)
4784 1.1.1.5 mrg (unspec:SVE_I
4785 1.1.1.5 mrg [(match_operand:SVE_I 2 "register_operand" "0, w")
4786 1.1.1.5 mrg (match_operand:SVE_I 3 "aarch64_simd_<lr>shift_imm")]
4787 1.1.1.5 mrg SVE_INT_SHIFT_IMM)]
4788 1.1.1.5 mrg UNSPEC_PRED_X)
4789 1.1.1.3 mrg (match_dup 2)]
4790 1.1.1.3 mrg UNSPEC_SEL))]
4791 1.1.1.3 mrg "TARGET_SVE"
4792 1.1.1.3 mrg "@
4793 1.1.1.3 mrg <sve_int_op>\t%0.<Vetype>, %1/m, %0.<Vetype>, #%3
4794 1.1.1.3 mrg movprfx\t%0, %2\;<sve_int_op>\t%0.<Vetype>, %1/m, %0.<Vetype>, #%3"
4795 1.1.1.5 mrg "&& !CONSTANT_P (operands[4])"
4796 1.1.1.5 mrg {
4797 1.1.1.5 mrg operands[4] = CONSTM1_RTX (<VPRED>mode);
4798 1.1.1.5 mrg }
4799 1.1.1.3 mrg [(set_attr "movprfx" "*,yes")])
4800 1.1.1.3 mrg
4801 1.1.1.5 mrg ;; Predicated shift, merging with an independent value.
4802 1.1.1.5 mrg (define_insn_and_rewrite "*cond_<sve_int_op><mode>_any"
4803 1.1.1.5 mrg [(set (match_operand:SVE_I 0 "register_operand" "=w, &w, ?&w")
4804 1.1.1.5 mrg (unspec:SVE_I
4805 1.1.1.5 mrg [(match_operand:<VPRED> 1 "register_operand" "Upl, Upl, Upl")
4806 1.1.1.5 mrg (unspec:SVE_I
4807 1.1.1.5 mrg [(match_operand 5)
4808 1.1.1.5 mrg (unspec:SVE_I
4809 1.1.1.5 mrg [(match_operand:SVE_I 2 "register_operand" "w, w, w")
4810 1.1.1.5 mrg (match_operand:SVE_I 3 "aarch64_simd_<lr>shift_imm")]
4811 1.1.1.5 mrg SVE_INT_SHIFT_IMM)]
4812 1.1.1.5 mrg UNSPEC_PRED_X)
4813 1.1.1.5 mrg (match_operand:SVE_I 4 "aarch64_simd_reg_or_zero" "Dz, 0, w")]
4814 1.1.1.5 mrg UNSPEC_SEL))]
4815 1.1.1.5 mrg "TARGET_SVE && !rtx_equal_p (operands[2], operands[4])"
4816 1.1.1.5 mrg "@
4817 1.1.1.5 mrg movprfx\t%0.<Vetype>, %1/z, %2.<Vetype>\;<sve_int_op>\t%0.<Vetype>, %1/m, %0.<Vetype>, #%3
4818 1.1.1.5 mrg movprfx\t%0.<Vetype>, %1/m, %2.<Vetype>\;<sve_int_op>\t%0.<Vetype>, %1/m, %0.<Vetype>, #%3
4819 1.1.1.5 mrg #"
4820 1.1.1.5 mrg "&& reload_completed
4821 1.1.1.5 mrg && register_operand (operands[4], <MODE>mode)
4822 1.1.1.5 mrg && !rtx_equal_p (operands[0], operands[4])"
4823 1.1.1.5 mrg {
4824 1.1.1.5 mrg emit_insn (gen_vcond_mask_<mode><vpred> (operands[0], operands[2],
4825 1.1.1.5 mrg operands[4], operands[1]));
4826 1.1.1.5 mrg operands[4] = operands[2] = operands[0];
4827 1.1.1.5 mrg }
4828 1.1.1.5 mrg [(set_attr "movprfx" "yes")]
4829 1.1.1.5 mrg )
4830 1.1.1.3 mrg
4831 1.1.1.3 mrg ;; -------------------------------------------------------------------------
4832 1.1.1.3 mrg ;; ---- [FP<-INT] General binary arithmetic corresponding to unspecs
4833 1.1.1.3 mrg ;; -------------------------------------------------------------------------
4834 1.1.1.3 mrg ;; Includes:
4835 1.1.1.3 mrg ;; - FSCALE
4836 1.1.1.3 mrg ;; - FTSMUL
4837 1.1.1.3 mrg ;; - FTSSEL
4838 1.1.1.3 mrg ;; -------------------------------------------------------------------------
4839 1.1.1.3 mrg
4840 1.1.1.3 mrg ;; Unpredicated floating-point binary operations that take an integer as
4841 1.1.1.3 mrg ;; their second operand.
4842 1.1.1.3 mrg (define_insn "@aarch64_sve_<optab><mode>"
4843 1.1.1.3 mrg [(set (match_operand:SVE_FULL_F 0 "register_operand" "=w")
4844 1.1.1.3 mrg (unspec:SVE_FULL_F
4845 1.1.1.3 mrg [(match_operand:SVE_FULL_F 1 "register_operand" "w")
4846 1.1.1.3 mrg (match_operand:<V_INT_EQUIV> 2 "register_operand" "w")]
4847 1.1.1.3 mrg SVE_FP_BINARY_INT))]
4848 1.1.1.3 mrg "TARGET_SVE"
4849 1.1.1.3 mrg "<sve_fp_op>\t%0.<Vetype>, %1.<Vetype>, %2.<Vetype>"
4850 1.1.1.3 mrg )
4851 1.1.1.3 mrg
4852 1.1.1.3 mrg ;; Predicated floating-point binary operations that take an integer
4853 1.1.1.3 mrg ;; as their second operand.
4854 1.1.1.3 mrg (define_insn "@aarch64_pred_<optab><mode>"
4855 1.1.1.3 mrg [(set (match_operand:SVE_FULL_F 0 "register_operand" "=w, ?&w")
4856 1.1.1.3 mrg (unspec:SVE_FULL_F
4857 1.1.1.3 mrg [(match_operand:<VPRED> 1 "register_operand" "Upl, Upl")
4858 1.1.1.3 mrg (match_operand:SI 4 "aarch64_sve_gp_strictness")
4859 1.1.1.3 mrg (match_operand:SVE_FULL_F 2 "register_operand" "0, w")
4860 1.1.1.3 mrg (match_operand:<V_INT_EQUIV> 3 "register_operand" "w, w")]
4861 1.1.1.3 mrg SVE_COND_FP_BINARY_INT))]
4862 1.1.1.3 mrg "TARGET_SVE"
4863 1.1.1.3 mrg "@
4864 1.1.1.3 mrg <sve_fp_op>\t%0.<Vetype>, %1/m, %0.<Vetype>, %3.<Vetype>
4865 1.1.1.3 mrg movprfx\t%0, %2\;<sve_fp_op>\t%0.<Vetype>, %1/m, %0.<Vetype>, %3.<Vetype>"
4866 1.1.1.3 mrg [(set_attr "movprfx" "*,yes")]
4867 1.1.1.3 mrg )
4868 1.1.1.3 mrg
4869 1.1.1.3 mrg ;; Predicated floating-point binary operations with merging, taking an
4870 1.1.1.3 mrg ;; integer as their second operand.
4871 1.1.1.3 mrg (define_expand "@cond_<optab><mode>"
4872 1.1.1.3 mrg [(set (match_operand:SVE_FULL_F 0 "register_operand")
4873 1.1.1.3 mrg (unspec:SVE_FULL_F
4874 1.1.1.3 mrg [(match_operand:<VPRED> 1 "register_operand")
4875 1.1.1.3 mrg (unspec:SVE_FULL_F
4876 1.1.1.3 mrg [(match_dup 1)
4877 1.1.1.3 mrg (const_int SVE_STRICT_GP)
4878 1.1.1.3 mrg (match_operand:SVE_FULL_F 2 "register_operand")
4879 1.1.1.3 mrg (match_operand:<V_INT_EQUIV> 3 "register_operand")]
4880 1.1.1.3 mrg SVE_COND_FP_BINARY_INT)
4881 1.1.1.3 mrg (match_operand:SVE_FULL_F 4 "aarch64_simd_reg_or_zero")]
4882 1.1.1.3 mrg UNSPEC_SEL))]
4883 1.1.1.3 mrg "TARGET_SVE"
4884 1.1.1.3 mrg )
4885 1.1.1.3 mrg
4886 1.1.1.3 mrg ;; Predicated floating-point binary operations that take an integer as their
4887 1.1.1.3 mrg ;; second operand, with inactive lanes coming from the first operand.
4888 1.1.1.3 mrg (define_insn_and_rewrite "*cond_<optab><mode>_2_relaxed"
4889 1.1.1.3 mrg [(set (match_operand:SVE_FULL_F 0 "register_operand" "=w, ?&w")
4890 1.1.1.3 mrg (unspec:SVE_FULL_F
4891 1.1.1.3 mrg [(match_operand:<VPRED> 1 "register_operand" "Upl, Upl")
4892 1.1.1.3 mrg (unspec:SVE_FULL_F
4893 1.1.1.3 mrg [(match_operand 4)
4894 1.1.1.3 mrg (const_int SVE_RELAXED_GP)
4895 1.1.1.3 mrg (match_operand:SVE_FULL_F 2 "register_operand" "0, w")
4896 1.1.1.3 mrg (match_operand:<V_INT_EQUIV> 3 "register_operand" "w, w")]
4897 1.1.1.3 mrg SVE_COND_FP_BINARY_INT)
4898 1.1.1.3 mrg (match_dup 2)]
4899 1.1.1.3 mrg UNSPEC_SEL))]
4900 1.1.1.3 mrg "TARGET_SVE"
4901 1.1.1.3 mrg "@
4902 1.1.1.3 mrg <sve_fp_op>\t%0.<Vetype>, %1/m, %0.<Vetype>, %3.<Vetype>
4903 1.1.1.3 mrg movprfx\t%0, %2\;<sve_fp_op>\t%0.<Vetype>, %1/m, %0.<Vetype>, %3.<Vetype>"
4904 1.1.1.3 mrg "&& !rtx_equal_p (operands[1], operands[4])"
4905 1.1.1.3 mrg {
4906 1.1.1.3 mrg operands[4] = copy_rtx (operands[1]);
4907 1.1.1.3 mrg }
4908 1.1.1.3 mrg [(set_attr "movprfx" "*,yes")]
4909 1.1.1.3 mrg )
4910 1.1.1.3 mrg
4911 1.1.1.3 mrg (define_insn "*cond_<optab><mode>_2_strict"
4912 1.1.1.3 mrg [(set (match_operand:SVE_FULL_F 0 "register_operand" "=w, ?&w")
4913 1.1.1.3 mrg (unspec:SVE_FULL_F
4914 1.1.1.3 mrg [(match_operand:<VPRED> 1 "register_operand" "Upl, Upl")
4915 1.1.1.3 mrg (unspec:SVE_FULL_F
4916 1.1.1.3 mrg [(match_dup 1)
4917 1.1.1.3 mrg (const_int SVE_STRICT_GP)
4918 1.1.1.3 mrg (match_operand:SVE_FULL_F 2 "register_operand" "0, w")
4919 1.1.1.3 mrg (match_operand:<V_INT_EQUIV> 3 "register_operand" "w, w")]
4920 1.1.1.3 mrg SVE_COND_FP_BINARY_INT)
4921 1.1.1.3 mrg (match_dup 2)]
4922 1.1.1.3 mrg UNSPEC_SEL))]
4923 1.1.1.3 mrg "TARGET_SVE"
4924 1.1.1.3 mrg "@
4925 1.1.1.3 mrg <sve_fp_op>\t%0.<Vetype>, %1/m, %0.<Vetype>, %3.<Vetype>
4926 1.1.1.3 mrg movprfx\t%0, %2\;<sve_fp_op>\t%0.<Vetype>, %1/m, %0.<Vetype>, %3.<Vetype>"
4927 1.1.1.3 mrg [(set_attr "movprfx" "*,yes")]
4928 1.1.1.3 mrg )
4929 1.1.1.3 mrg
4930 1.1.1.3 mrg ;; Predicated floating-point binary operations that take an integer as
4931 1.1.1.3 mrg ;; their second operand, with the values of inactive lanes being distinct
4932 1.1.1.3 mrg ;; from the other inputs.
4933 1.1.1.3 mrg (define_insn_and_rewrite "*cond_<optab><mode>_any_relaxed"
4934 1.1.1.3 mrg [(set (match_operand:SVE_FULL_F 0 "register_operand" "=&w, &w, &w, ?&w")
4935 1.1.1.3 mrg (unspec:SVE_FULL_F
4936 1.1.1.3 mrg [(match_operand:<VPRED> 1 "register_operand" "Upl, Upl, Upl, Upl")
4937 1.1.1.3 mrg (unspec:SVE_FULL_F
4938 1.1.1.3 mrg [(match_operand 5)
4939 1.1.1.3 mrg (const_int SVE_RELAXED_GP)
4940 1.1.1.3 mrg (match_operand:SVE_FULL_F 2 "register_operand" "0, w, w, w")
4941 1.1.1.3 mrg (match_operand:<V_INT_EQUIV> 3 "register_operand" "w, w, w, w")]
4942 1.1.1.3 mrg SVE_COND_FP_BINARY_INT)
4943 1.1.1.3 mrg (match_operand:SVE_FULL_F 4 "aarch64_simd_reg_or_zero" "Dz, Dz, 0, w")]
4944 1.1.1.3 mrg UNSPEC_SEL))]
4945 1.1.1.3 mrg "TARGET_SVE && !rtx_equal_p (operands[2], operands[4])"
4946 1.1.1.3 mrg "@
4947 1.1.1.3 mrg movprfx\t%0.<Vetype>, %1/z, %2.<Vetype>\;<sve_fp_op>\t%0.<Vetype>, %1/m, %0.<Vetype>, %3.<Vetype>
4948 1.1.1.3 mrg movprfx\t%0.<Vetype>, %1/z, %2.<Vetype>\;<sve_fp_op>\t%0.<Vetype>, %1/m, %0.<Vetype>, %3.<Vetype>
4949 1.1.1.3 mrg movprfx\t%0.<Vetype>, %1/m, %2.<Vetype>\;<sve_fp_op>\t%0.<Vetype>, %1/m, %0.<Vetype>, %3.<Vetype>
4950 1.1.1.3 mrg #"
4951 1.1.1.3 mrg "&& 1"
4952 1.1.1.3 mrg {
4953 1.1.1.3 mrg if (reload_completed
4954 1.1.1.3 mrg && register_operand (operands[4], <MODE>mode)
4955 1.1.1.3 mrg && !rtx_equal_p (operands[0], operands[4]))
4956 1.1.1.3 mrg {
4957 1.1.1.3 mrg emit_insn (gen_vcond_mask_<mode><vpred> (operands[0], operands[2],
4958 1.1.1.3 mrg operands[4], operands[1]));
4959 1.1.1.3 mrg operands[4] = operands[2] = operands[0];
4960 1.1.1.3 mrg }
4961 1.1.1.3 mrg else if (!rtx_equal_p (operands[1], operands[5]))
4962 1.1.1.3 mrg operands[5] = copy_rtx (operands[1]);
4963 1.1.1.3 mrg else
4964 1.1.1.3 mrg FAIL;
4965 1.1.1.3 mrg }
4966 1.1.1.3 mrg [(set_attr "movprfx" "yes")]
4967 1.1.1.3 mrg )
4968 1.1.1.3 mrg
4969 1.1.1.3 mrg (define_insn_and_rewrite "*cond_<optab><mode>_any_strict"
4970 1.1.1.3 mrg [(set (match_operand:SVE_FULL_F 0 "register_operand" "=&w, &w, &w, ?&w")
4971 1.1.1.3 mrg (unspec:SVE_FULL_F
4972 1.1.1.3 mrg [(match_operand:<VPRED> 1 "register_operand" "Upl, Upl, Upl, Upl")
4973 1.1.1.3 mrg (unspec:SVE_FULL_F
4974 1.1.1.3 mrg [(match_dup 1)
4975 1.1.1.3 mrg (const_int SVE_STRICT_GP)
4976 1.1.1.3 mrg (match_operand:SVE_FULL_F 2 "register_operand" "0, w, w, w")
4977 1.1.1.3 mrg (match_operand:<V_INT_EQUIV> 3 "register_operand" "w, w, w, w")]
4978 1.1.1.3 mrg SVE_COND_FP_BINARY_INT)
4979 1.1.1.3 mrg (match_operand:SVE_FULL_F 4 "aarch64_simd_reg_or_zero" "Dz, Dz, 0, w")]
4980 1.1.1.3 mrg UNSPEC_SEL))]
4981 1.1.1.3 mrg "TARGET_SVE && !rtx_equal_p (operands[2], operands[4])"
4982 1.1.1.3 mrg "@
4983 1.1.1.3 mrg movprfx\t%0.<Vetype>, %1/z, %2.<Vetype>\;<sve_fp_op>\t%0.<Vetype>, %1/m, %0.<Vetype>, %3.<Vetype>
4984 1.1.1.3 mrg movprfx\t%0.<Vetype>, %1/z, %2.<Vetype>\;<sve_fp_op>\t%0.<Vetype>, %1/m, %0.<Vetype>, %3.<Vetype>
4985 1.1.1.3 mrg movprfx\t%0.<Vetype>, %1/m, %2.<Vetype>\;<sve_fp_op>\t%0.<Vetype>, %1/m, %0.<Vetype>, %3.<Vetype>
4986 1.1.1.3 mrg #"
4987 1.1.1.3 mrg "&& reload_completed
4988 1.1.1.3 mrg && register_operand (operands[4], <MODE>mode)
4989 1.1.1.3 mrg && !rtx_equal_p (operands[0], operands[4])"
4990 1.1.1.3 mrg {
4991 1.1.1.3 mrg emit_insn (gen_vcond_mask_<mode><vpred> (operands[0], operands[2],
4992 1.1.1.3 mrg operands[4], operands[1]));
4993 1.1.1.3 mrg operands[4] = operands[2] = operands[0];
4994 1.1.1.3 mrg }
4995 1.1.1.3 mrg [(set_attr "movprfx" "yes")]
4996 1.1.1.3 mrg )
4997 1.1.1.3 mrg
4998 1.1.1.3 mrg ;; -------------------------------------------------------------------------
4999 1.1.1.3 mrg ;; ---- [FP] General binary arithmetic corresponding to rtx codes
5000 1.1.1.3 mrg ;; -------------------------------------------------------------------------
5001 1.1.1.3 mrg ;; Includes post-RA forms of:
5002 1.1.1.3 mrg ;; - FADD
5003 1.1.1.3 mrg ;; - FMUL
5004 1.1.1.3 mrg ;; - FSUB
5005 1.1.1.3 mrg ;; -------------------------------------------------------------------------
5006 1.1.1.3 mrg
5007 1.1.1.3 mrg ;; Unpredicated floating-point binary operations (post-RA only).
5008 1.1.1.3 mrg ;; These are generated by splitting a predicated instruction whose
5009 1.1.1.3 mrg ;; predicate is unused.
5010 1.1.1.3 mrg (define_insn "*post_ra_<sve_fp_op><mode>3"
5011 1.1.1.3 mrg [(set (match_operand:SVE_FULL_F 0 "register_operand" "=w")
5012 1.1.1.3 mrg (SVE_UNPRED_FP_BINARY:SVE_FULL_F
5013 1.1.1.3 mrg (match_operand:SVE_FULL_F 1 "register_operand" "w")
5014 1.1.1.3 mrg (match_operand:SVE_FULL_F 2 "register_operand" "w")))]
5015 1.1.1.3 mrg "TARGET_SVE && reload_completed"
5016 1.1.1.3 mrg "<sve_fp_op>\t%0.<Vetype>, %1.<Vetype>, %2.<Vetype>")
5017 1.1.1.3 mrg
5018 1.1.1.3 mrg ;; -------------------------------------------------------------------------
5019 1.1.1.3 mrg ;; ---- [FP] General binary arithmetic corresponding to unspecs
5020 1.1.1.3 mrg ;; -------------------------------------------------------------------------
5021 1.1.1.3 mrg ;; Includes merging forms of:
5022 1.1.1.3 mrg ;; - FADD (constant forms handled in the "Addition" section)
5023 1.1.1.3 mrg ;; - FDIV
5024 1.1.1.3 mrg ;; - FDIVR
5025 1.1.1.3 mrg ;; - FMAX
5026 1.1.1.3 mrg ;; - FMAXNM (including #0.0 and #1.0)
5027 1.1.1.3 mrg ;; - FMIN
5028 1.1.1.3 mrg ;; - FMINNM (including #0.0 and #1.0)
5029 1.1.1.3 mrg ;; - FMUL (including #0.5 and #2.0)
5030 1.1.1.3 mrg ;; - FMULX
5031 1.1.1.3 mrg ;; - FRECPS
5032 1.1.1.3 mrg ;; - FRSQRTS
5033 1.1.1.3 mrg ;; - FSUB (constant forms handled in the "Addition" section)
5034 1.1.1.3 mrg ;; - FSUBR (constant forms handled in the "Subtraction" section)
5035 1.1.1.3 mrg ;; -------------------------------------------------------------------------
5036 1.1.1.3 mrg
5037 1.1.1.3 mrg ;; Unpredicated floating-point binary operations.
5038 1.1.1.3 mrg (define_insn "@aarch64_sve_<optab><mode>"
5039 1.1.1.3 mrg [(set (match_operand:SVE_FULL_F 0 "register_operand" "=w")
5040 1.1.1.3 mrg (unspec:SVE_FULL_F
5041 1.1.1.3 mrg [(match_operand:SVE_FULL_F 1 "register_operand" "w")
5042 1.1.1.3 mrg (match_operand:SVE_FULL_F 2 "register_operand" "w")]
5043 1.1.1.3 mrg SVE_FP_BINARY))]
5044 1.1.1.3 mrg "TARGET_SVE"
5045 1.1.1.3 mrg "<sve_fp_op>\t%0.<Vetype>, %1.<Vetype>, %2.<Vetype>"
5046 1.1.1.3 mrg )
5047 1.1.1.3 mrg
5048 1.1.1.3 mrg ;; Unpredicated floating-point binary operations that need to be predicated
5049 1.1.1.3 mrg ;; for SVE.
5050 1.1.1.3 mrg (define_expand "<optab><mode>3"
5051 1.1.1.3 mrg [(set (match_operand:SVE_FULL_F 0 "register_operand")
5052 1.1.1.3 mrg (unspec:SVE_FULL_F
5053 1.1.1.3 mrg [(match_dup 3)
5054 1.1.1.3 mrg (const_int SVE_RELAXED_GP)
5055 1.1.1.3 mrg (match_operand:SVE_FULL_F 1 "<sve_pred_fp_rhs1_operand>")
5056 1.1.1.3 mrg (match_operand:SVE_FULL_F 2 "<sve_pred_fp_rhs2_operand>")]
5057 1.1.1.3 mrg SVE_COND_FP_BINARY_OPTAB))]
5058 1.1.1.3 mrg "TARGET_SVE"
5059 1.1.1.3 mrg {
5060 1.1.1.3 mrg operands[3] = aarch64_ptrue_reg (<VPRED>mode);
5061 1.1.1.3 mrg }
5062 1.1.1.3 mrg )
5063 1.1.1.3 mrg
5064 1.1.1.3 mrg ;; Predicated floating-point binary operations that have no immediate forms.
5065 1.1.1.3 mrg (define_insn "@aarch64_pred_<optab><mode>"
5066 1.1.1.3 mrg [(set (match_operand:SVE_FULL_F 0 "register_operand" "=w, w, ?&w")
5067 1.1.1.3 mrg (unspec:SVE_FULL_F
5068 1.1.1.3 mrg [(match_operand:<VPRED> 1 "register_operand" "Upl, Upl, Upl")
5069 1.1.1.3 mrg (match_operand:SI 4 "aarch64_sve_gp_strictness")
5070 1.1.1.3 mrg (match_operand:SVE_FULL_F 2 "register_operand" "0, w, w")
5071 1.1.1.3 mrg (match_operand:SVE_FULL_F 3 "register_operand" "w, 0, w")]
5072 1.1.1.3 mrg SVE_COND_FP_BINARY_REG))]
5073 1.1.1.3 mrg "TARGET_SVE"
5074 1.1.1.3 mrg "@
5075 1.1.1.3 mrg <sve_fp_op>\t%0.<Vetype>, %1/m, %0.<Vetype>, %3.<Vetype>
5076 1.1.1.3 mrg <sve_fp_op_rev>\t%0.<Vetype>, %1/m, %0.<Vetype>, %2.<Vetype>
5077 1.1.1.3 mrg movprfx\t%0, %2\;<sve_fp_op>\t%0.<Vetype>, %1/m, %0.<Vetype>, %3.<Vetype>"
5078 1.1.1.3 mrg [(set_attr "movprfx" "*,*,yes")]
5079 1.1.1.3 mrg )
5080 1.1.1.3 mrg
5081 1.1.1.3 mrg ;; Predicated floating-point operations with merging.
5082 1.1.1.3 mrg (define_expand "@cond_<optab><mode>"
5083 1.1.1.3 mrg [(set (match_operand:SVE_FULL_F 0 "register_operand")
5084 1.1.1.3 mrg (unspec:SVE_FULL_F
5085 1.1.1.3 mrg [(match_operand:<VPRED> 1 "register_operand")
5086 1.1.1.3 mrg (unspec:SVE_FULL_F
5087 1.1.1.3 mrg [(match_dup 1)
5088 1.1.1.3 mrg (const_int SVE_STRICT_GP)
5089 1.1.1.3 mrg (match_operand:SVE_FULL_F 2 "<sve_pred_fp_rhs1_operand>")
5090 1.1.1.3 mrg (match_operand:SVE_FULL_F 3 "<sve_pred_fp_rhs2_operand>")]
5091 1.1.1.3 mrg SVE_COND_FP_BINARY)
5092 1.1.1.3 mrg (match_operand:SVE_FULL_F 4 "aarch64_simd_reg_or_zero")]
5093 1.1.1.3 mrg UNSPEC_SEL))]
5094 1.1.1.3 mrg "TARGET_SVE"
5095 1.1.1.3 mrg )
5096 1.1.1.3 mrg
5097 1.1.1.3 mrg ;; Predicated floating-point operations, merging with the first input.
5098 1.1.1.3 mrg (define_insn_and_rewrite "*cond_<optab><mode>_2_relaxed"
5099 1.1.1.3 mrg [(set (match_operand:SVE_FULL_F 0 "register_operand" "=w, ?&w")
5100 1.1.1.3 mrg (unspec:SVE_FULL_F
5101 1.1.1.3 mrg [(match_operand:<VPRED> 1 "register_operand" "Upl, Upl")
5102 1.1.1.3 mrg (unspec:SVE_FULL_F
5103 1.1.1.3 mrg [(match_operand 4)
5104 1.1.1.3 mrg (const_int SVE_RELAXED_GP)
5105 1.1.1.3 mrg (match_operand:SVE_FULL_F 2 "register_operand" "0, w")
5106 1.1.1.3 mrg (match_operand:SVE_FULL_F 3 "register_operand" "w, w")]
5107 1.1.1.3 mrg SVE_COND_FP_BINARY)
5108 1.1.1.3 mrg (match_dup 2)]
5109 1.1.1.3 mrg UNSPEC_SEL))]
5110 1.1.1.3 mrg "TARGET_SVE"
5111 1.1.1.3 mrg "@
5112 1.1.1.3 mrg <sve_fp_op>\t%0.<Vetype>, %1/m, %0.<Vetype>, %3.<Vetype>
5113 1.1.1.3 mrg movprfx\t%0, %2\;<sve_fp_op>\t%0.<Vetype>, %1/m, %0.<Vetype>, %3.<Vetype>"
5114 1.1.1.3 mrg "&& !rtx_equal_p (operands[1], operands[4])"
5115 1.1.1.3 mrg {
5116 1.1.1.3 mrg operands[4] = copy_rtx (operands[1]);
5117 1.1.1.3 mrg }
5118 1.1.1.3 mrg [(set_attr "movprfx" "*,yes")]
5119 1.1.1.3 mrg )
5120 1.1.1.3 mrg
5121 1.1.1.3 mrg (define_insn "*cond_<optab><mode>_2_strict"
5122 1.1.1.3 mrg [(set (match_operand:SVE_FULL_F 0 "register_operand" "=w, ?&w")
5123 1.1.1.3 mrg (unspec:SVE_FULL_F
5124 1.1.1.3 mrg [(match_operand:<VPRED> 1 "register_operand" "Upl, Upl")
5125 1.1.1.3 mrg (unspec:SVE_FULL_F
5126 1.1.1.3 mrg [(match_dup 1)
5127 1.1.1.3 mrg (const_int SVE_STRICT_GP)
5128 1.1.1.3 mrg (match_operand:SVE_FULL_F 2 "register_operand" "0, w")
5129 1.1.1.3 mrg (match_operand:SVE_FULL_F 3 "register_operand" "w, w")]
5130 1.1.1.3 mrg SVE_COND_FP_BINARY)
5131 1.1.1.3 mrg (match_dup 2)]
5132 1.1.1.3 mrg UNSPEC_SEL))]
5133 1.1.1.3 mrg "TARGET_SVE"
5134 1.1.1.3 mrg "@
5135 1.1.1.3 mrg <sve_fp_op>\t%0.<Vetype>, %1/m, %0.<Vetype>, %3.<Vetype>
5136 1.1.1.3 mrg movprfx\t%0, %2\;<sve_fp_op>\t%0.<Vetype>, %1/m, %0.<Vetype>, %3.<Vetype>"
5137 1.1.1.3 mrg [(set_attr "movprfx" "*,yes")]
5138 1.1.1.3 mrg )
5139 1.1.1.3 mrg
5140 1.1.1.3 mrg ;; Same for operations that take a 1-bit constant.
5141 1.1.1.3 mrg (define_insn_and_rewrite "*cond_<optab><mode>_2_const_relaxed"
5142 1.1.1.3 mrg [(set (match_operand:SVE_FULL_F 0 "register_operand" "=w, ?w")
5143 1.1.1.3 mrg (unspec:SVE_FULL_F
5144 1.1.1.3 mrg [(match_operand:<VPRED> 1 "register_operand" "Upl, Upl")
5145 1.1.1.3 mrg (unspec:SVE_FULL_F
5146 1.1.1.3 mrg [(match_operand 4)
5147 1.1.1.3 mrg (const_int SVE_RELAXED_GP)
5148 1.1.1.3 mrg (match_operand:SVE_FULL_F 2 "register_operand" "0, w")
5149 1.1.1.3 mrg (match_operand:SVE_FULL_F 3 "<sve_pred_fp_rhs2_immediate>")]
5150 1.1.1.3 mrg SVE_COND_FP_BINARY_I1)
5151 1.1.1.3 mrg (match_dup 2)]
5152 1.1.1.3 mrg UNSPEC_SEL))]
5153 1.1.1.3 mrg "TARGET_SVE"
5154 1.1.1.3 mrg "@
5155 1.1.1.3 mrg <sve_fp_op>\t%0.<Vetype>, %1/m, %0.<Vetype>, #%3
5156 1.1.1.3 mrg movprfx\t%0, %2\;<sve_fp_op>\t%0.<Vetype>, %1/m, %0.<Vetype>, #%3"
5157 1.1.1.3 mrg "&& !rtx_equal_p (operands[1], operands[4])"
5158 1.1.1.3 mrg {
5159 1.1.1.3 mrg operands[4] = copy_rtx (operands[1]);
5160 1.1.1.3 mrg }
5161 1.1.1.3 mrg [(set_attr "movprfx" "*,yes")]
5162 1.1.1.3 mrg )
5163 1.1.1.3 mrg
5164 1.1.1.3 mrg (define_insn "*cond_<optab><mode>_2_const_strict"
5165 1.1.1.3 mrg [(set (match_operand:SVE_FULL_F 0 "register_operand" "=w, ?w")
5166 1.1.1.3 mrg (unspec:SVE_FULL_F
5167 1.1.1.3 mrg [(match_operand:<VPRED> 1 "register_operand" "Upl, Upl")
5168 1.1.1.3 mrg (unspec:SVE_FULL_F
5169 1.1.1.3 mrg [(match_dup 1)
5170 1.1.1.3 mrg (const_int SVE_STRICT_GP)
5171 1.1.1.3 mrg (match_operand:SVE_FULL_F 2 "register_operand" "0, w")
5172 1.1.1.3 mrg (match_operand:SVE_FULL_F 3 "<sve_pred_fp_rhs2_immediate>")]
5173 1.1.1.3 mrg SVE_COND_FP_BINARY_I1)
5174 1.1.1.3 mrg (match_dup 2)]
5175 1.1.1.3 mrg UNSPEC_SEL))]
5176 1.1.1.3 mrg "TARGET_SVE"
5177 1.1.1.3 mrg "@
5178 1.1.1.3 mrg <sve_fp_op>\t%0.<Vetype>, %1/m, %0.<Vetype>, #%3
5179 1.1.1.3 mrg movprfx\t%0, %2\;<sve_fp_op>\t%0.<Vetype>, %1/m, %0.<Vetype>, #%3"
5180 1.1.1.3 mrg [(set_attr "movprfx" "*,yes")]
5181 1.1.1.3 mrg )
5182 1.1.1.3 mrg
5183 1.1.1.3 mrg ;; Predicated floating-point operations, merging with the second input.
5184 1.1.1.3 mrg (define_insn_and_rewrite "*cond_<optab><mode>_3_relaxed"
5185 1.1.1.3 mrg [(set (match_operand:SVE_FULL_F 0 "register_operand" "=w, ?&w")
5186 1.1.1.3 mrg (unspec:SVE_FULL_F
5187 1.1.1.3 mrg [(match_operand:<VPRED> 1 "register_operand" "Upl, Upl")
5188 1.1.1.3 mrg (unspec:SVE_FULL_F
5189 1.1.1.3 mrg [(match_operand 4)
5190 1.1.1.3 mrg (const_int SVE_RELAXED_GP)
5191 1.1.1.3 mrg (match_operand:SVE_FULL_F 2 "register_operand" "w, w")
5192 1.1.1.3 mrg (match_operand:SVE_FULL_F 3 "register_operand" "0, w")]
5193 1.1.1.3 mrg SVE_COND_FP_BINARY)
5194 1.1.1.3 mrg (match_dup 3)]
5195 1.1.1.3 mrg UNSPEC_SEL))]
5196 1.1.1.3 mrg "TARGET_SVE"
5197 1.1.1.3 mrg "@
5198 1.1.1.3 mrg <sve_fp_op_rev>\t%0.<Vetype>, %1/m, %0.<Vetype>, %2.<Vetype>
5199 1.1.1.3 mrg movprfx\t%0, %3\;<sve_fp_op_rev>\t%0.<Vetype>, %1/m, %0.<Vetype>, %2.<Vetype>"
5200 1.1.1.3 mrg "&& !rtx_equal_p (operands[1], operands[4])"
5201 1.1.1.3 mrg {
5202 1.1.1.3 mrg operands[4] = copy_rtx (operands[1]);
5203 1.1.1.3 mrg }
5204 1.1.1.3 mrg [(set_attr "movprfx" "*,yes")]
5205 1.1.1.3 mrg )
5206 1.1.1.3 mrg
5207 1.1.1.3 mrg (define_insn "*cond_<optab><mode>_3_strict"
5208 1.1.1.3 mrg [(set (match_operand:SVE_FULL_F 0 "register_operand" "=w, ?&w")
5209 1.1.1.3 mrg (unspec:SVE_FULL_F
5210 1.1.1.3 mrg [(match_operand:<VPRED> 1 "register_operand" "Upl, Upl")
5211 1.1.1.3 mrg (unspec:SVE_FULL_F
5212 1.1.1.3 mrg [(match_dup 1)
5213 1.1.1.3 mrg (const_int SVE_STRICT_GP)
5214 1.1.1.3 mrg (match_operand:SVE_FULL_F 2 "register_operand" "w, w")
5215 1.1.1.3 mrg (match_operand:SVE_FULL_F 3 "register_operand" "0, w")]
5216 1.1.1.3 mrg SVE_COND_FP_BINARY)
5217 1.1.1.3 mrg (match_dup 3)]
5218 1.1.1.3 mrg UNSPEC_SEL))]
5219 1.1.1.3 mrg "TARGET_SVE"
5220 1.1.1.3 mrg "@
5221 1.1.1.3 mrg <sve_fp_op_rev>\t%0.<Vetype>, %1/m, %0.<Vetype>, %2.<Vetype>
5222 1.1.1.3 mrg movprfx\t%0, %3\;<sve_fp_op_rev>\t%0.<Vetype>, %1/m, %0.<Vetype>, %2.<Vetype>"
5223 1.1.1.3 mrg [(set_attr "movprfx" "*,yes")]
5224 1.1.1.3 mrg )
5225 1.1.1.3 mrg
5226 1.1.1.3 mrg ;; Predicated floating-point operations, merging with an independent value.
5227 1.1.1.3 mrg (define_insn_and_rewrite "*cond_<optab><mode>_any_relaxed"
5228 1.1.1.3 mrg [(set (match_operand:SVE_FULL_F 0 "register_operand" "=&w, &w, &w, &w, ?&w")
5229 1.1.1.3 mrg (unspec:SVE_FULL_F
5230 1.1.1.3 mrg [(match_operand:<VPRED> 1 "register_operand" "Upl, Upl, Upl, Upl, Upl")
5231 1.1.1.3 mrg (unspec:SVE_FULL_F
5232 1.1.1.3 mrg [(match_operand 5)
5233 1.1.1.3 mrg (const_int SVE_RELAXED_GP)
5234 1.1.1.3 mrg (match_operand:SVE_FULL_F 2 "register_operand" "0, w, w, w, w")
5235 1.1.1.3 mrg (match_operand:SVE_FULL_F 3 "register_operand" "w, 0, w, w, w")]
5236 1.1.1.3 mrg SVE_COND_FP_BINARY)
5237 1.1.1.3 mrg (match_operand:SVE_FULL_F 4 "aarch64_simd_reg_or_zero" "Dz, Dz, Dz, 0, w")]
5238 1.1.1.3 mrg UNSPEC_SEL))]
5239 1.1.1.3 mrg "TARGET_SVE
5240 1.1.1.3 mrg && !rtx_equal_p (operands[2], operands[4])
5241 1.1.1.3 mrg && !rtx_equal_p (operands[3], operands[4])"
5242 1.1.1.3 mrg "@
5243 1.1.1.3 mrg movprfx\t%0.<Vetype>, %1/z, %0.<Vetype>\;<sve_fp_op>\t%0.<Vetype>, %1/m, %0.<Vetype>, %3.<Vetype>
5244 1.1.1.3 mrg movprfx\t%0.<Vetype>, %1/z, %0.<Vetype>\;<sve_fp_op_rev>\t%0.<Vetype>, %1/m, %0.<Vetype>, %2.<Vetype>
5245 1.1.1.3 mrg movprfx\t%0.<Vetype>, %1/z, %2.<Vetype>\;<sve_fp_op>\t%0.<Vetype>, %1/m, %0.<Vetype>, %3.<Vetype>
5246 1.1.1.3 mrg movprfx\t%0.<Vetype>, %1/m, %2.<Vetype>\;<sve_fp_op>\t%0.<Vetype>, %1/m, %0.<Vetype>, %3.<Vetype>
5247 1.1.1.3 mrg #"
5248 1.1.1.3 mrg "&& 1"
5249 1.1.1.3 mrg {
5250 1.1.1.3 mrg if (reload_completed
5251 1.1.1.3 mrg && register_operand (operands[4], <MODE>mode)
5252 1.1.1.3 mrg && !rtx_equal_p (operands[0], operands[4]))
5253 1.1.1.3 mrg {
5254 1.1.1.3 mrg emit_insn (gen_vcond_mask_<mode><vpred> (operands[0], operands[2],
5255 1.1.1.3 mrg operands[4], operands[1]));
5256 1.1.1.3 mrg operands[4] = operands[2] = operands[0];
5257 1.1.1.3 mrg }
5258 1.1.1.3 mrg else if (!rtx_equal_p (operands[1], operands[5]))
5259 1.1.1.3 mrg operands[5] = copy_rtx (operands[1]);
5260 1.1.1.3 mrg else
5261 1.1.1.3 mrg FAIL;
5262 1.1.1.3 mrg }
5263 1.1.1.3 mrg [(set_attr "movprfx" "yes")]
5264 1.1.1.3 mrg )
5265 1.1.1.3 mrg
5266 1.1.1.3 mrg (define_insn_and_rewrite "*cond_<optab><mode>_any_strict"
5267 1.1.1.3 mrg [(set (match_operand:SVE_FULL_F 0 "register_operand" "=&w, &w, &w, &w, ?&w")
5268 1.1.1.3 mrg (unspec:SVE_FULL_F
5269 1.1.1.3 mrg [(match_operand:<VPRED> 1 "register_operand" "Upl, Upl, Upl, Upl, Upl")
5270 1.1.1.3 mrg (unspec:SVE_FULL_F
5271 1.1.1.3 mrg [(match_dup 1)
5272 1.1.1.3 mrg (const_int SVE_STRICT_GP)
5273 1.1.1.3 mrg (match_operand:SVE_FULL_F 2 "register_operand" "0, w, w, w, w")
5274 1.1.1.3 mrg (match_operand:SVE_FULL_F 3 "register_operand" "w, 0, w, w, w")]
5275 1.1.1.3 mrg SVE_COND_FP_BINARY)
5276 1.1.1.3 mrg (match_operand:SVE_FULL_F 4 "aarch64_simd_reg_or_zero" "Dz, Dz, Dz, 0, w")]
5277 1.1.1.3 mrg UNSPEC_SEL))]
5278 1.1.1.3 mrg "TARGET_SVE
5279 1.1.1.3 mrg && !rtx_equal_p (operands[2], operands[4])
5280 1.1.1.3 mrg && !rtx_equal_p (operands[3], operands[4])"
5281 1.1.1.3 mrg "@
5282 1.1.1.3 mrg movprfx\t%0.<Vetype>, %1/z, %0.<Vetype>\;<sve_fp_op>\t%0.<Vetype>, %1/m, %0.<Vetype>, %3.<Vetype>
5283 1.1.1.3 mrg movprfx\t%0.<Vetype>, %1/z, %0.<Vetype>\;<sve_fp_op_rev>\t%0.<Vetype>, %1/m, %0.<Vetype>, %2.<Vetype>
5284 1.1.1.3 mrg movprfx\t%0.<Vetype>, %1/z, %2.<Vetype>\;<sve_fp_op>\t%0.<Vetype>, %1/m, %0.<Vetype>, %3.<Vetype>
5285 1.1.1.3 mrg movprfx\t%0.<Vetype>, %1/m, %2.<Vetype>\;<sve_fp_op>\t%0.<Vetype>, %1/m, %0.<Vetype>, %3.<Vetype>
5286 1.1.1.3 mrg #"
5287 1.1.1.3 mrg "&& reload_completed
5288 1.1.1.3 mrg && register_operand (operands[4], <MODE>mode)
5289 1.1.1.3 mrg && !rtx_equal_p (operands[0], operands[4])"
5290 1.1.1.3 mrg {
5291 1.1.1.3 mrg emit_insn (gen_vcond_mask_<mode><vpred> (operands[0], operands[2],
5292 1.1.1.3 mrg operands[4], operands[1]));
5293 1.1.1.3 mrg operands[4] = operands[2] = operands[0];
5294 1.1.1.3 mrg }
5295 1.1.1.3 mrg [(set_attr "movprfx" "yes")]
5296 1.1.1.3 mrg )
5297 1.1.1.3 mrg
5298 1.1.1.3 mrg ;; Same for operations that take a 1-bit constant.
5299 1.1.1.3 mrg (define_insn_and_rewrite "*cond_<optab><mode>_any_const_relaxed"
5300 1.1.1.3 mrg [(set (match_operand:SVE_FULL_F 0 "register_operand" "=w, w, ?w")
5301 1.1.1.3 mrg (unspec:SVE_FULL_F
5302 1.1.1.3 mrg [(match_operand:<VPRED> 1 "register_operand" "Upl, Upl, Upl")
5303 1.1.1.3 mrg (unspec:SVE_FULL_F
5304 1.1.1.3 mrg [(match_operand 5)
5305 1.1.1.3 mrg (const_int SVE_RELAXED_GP)
5306 1.1.1.3 mrg (match_operand:SVE_FULL_F 2 "register_operand" "w, w, w")
5307 1.1.1.3 mrg (match_operand:SVE_FULL_F 3 "<sve_pred_fp_rhs2_immediate>")]
5308 1.1.1.3 mrg SVE_COND_FP_BINARY_I1)
5309 1.1.1.3 mrg (match_operand:SVE_FULL_F 4 "aarch64_simd_reg_or_zero" "Dz, 0, w")]
5310 1.1.1.3 mrg UNSPEC_SEL))]
5311 1.1.1.3 mrg "TARGET_SVE && !rtx_equal_p (operands[2], operands[4])"
5312 1.1.1.3 mrg "@
5313 1.1.1.3 mrg movprfx\t%0.<Vetype>, %1/z, %2.<Vetype>\;<sve_fp_op>\t%0.<Vetype>, %1/m, %0.<Vetype>, #%3
5314 1.1.1.3 mrg movprfx\t%0.<Vetype>, %1/m, %2.<Vetype>\;<sve_fp_op>\t%0.<Vetype>, %1/m, %0.<Vetype>, #%3
5315 1.1.1.3 mrg #"
5316 1.1.1.3 mrg "&& 1"
5317 1.1.1.3 mrg {
5318 1.1.1.3 mrg if (reload_completed
5319 1.1.1.3 mrg && register_operand (operands[4], <MODE>mode)
5320 1.1.1.3 mrg && !rtx_equal_p (operands[0], operands[4]))
5321 1.1.1.3 mrg {
5322 1.1.1.3 mrg emit_insn (gen_vcond_mask_<mode><vpred> (operands[0], operands[2],
5323 1.1.1.3 mrg operands[4], operands[1]));
5324 1.1.1.3 mrg operands[4] = operands[2] = operands[0];
5325 1.1.1.3 mrg }
5326 1.1.1.3 mrg else if (!rtx_equal_p (operands[1], operands[5]))
5327 1.1.1.3 mrg operands[5] = copy_rtx (operands[1]);
5328 1.1.1.3 mrg else
5329 1.1.1.3 mrg FAIL;
5330 1.1.1.3 mrg }
5331 1.1.1.3 mrg [(set_attr "movprfx" "yes")]
5332 1.1.1.3 mrg )
5333 1.1.1.3 mrg
5334 1.1.1.3 mrg (define_insn_and_rewrite "*cond_<optab><mode>_any_const_strict"
5335 1.1.1.3 mrg [(set (match_operand:SVE_FULL_F 0 "register_operand" "=w, w, ?w")
5336 1.1.1.3 mrg (unspec:SVE_FULL_F
5337 1.1.1.3 mrg [(match_operand:<VPRED> 1 "register_operand" "Upl, Upl, Upl")
5338 1.1.1.3 mrg (unspec:SVE_FULL_F
5339 1.1.1.3 mrg [(match_dup 1)
5340 1.1.1.3 mrg (const_int SVE_STRICT_GP)
5341 1.1.1.3 mrg (match_operand:SVE_FULL_F 2 "register_operand" "w, w, w")
5342 1.1.1.3 mrg (match_operand:SVE_FULL_F 3 "<sve_pred_fp_rhs2_immediate>")]
5343 1.1.1.3 mrg SVE_COND_FP_BINARY_I1)
5344 1.1.1.3 mrg (match_operand:SVE_FULL_F 4 "aarch64_simd_reg_or_zero" "Dz, 0, w")]
5345 1.1.1.3 mrg UNSPEC_SEL))]
5346 1.1.1.3 mrg "TARGET_SVE && !rtx_equal_p (operands[2], operands[4])"
5347 1.1.1.3 mrg "@
5348 1.1.1.3 mrg movprfx\t%0.<Vetype>, %1/z, %2.<Vetype>\;<sve_fp_op>\t%0.<Vetype>, %1/m, %0.<Vetype>, #%3
5349 1.1.1.3 mrg movprfx\t%0.<Vetype>, %1/m, %2.<Vetype>\;<sve_fp_op>\t%0.<Vetype>, %1/m, %0.<Vetype>, #%3
5350 1.1.1.3 mrg #"
5351 1.1.1.3 mrg "&& reload_completed
5352 1.1.1.3 mrg && register_operand (operands[4], <MODE>mode)
5353 1.1.1.3 mrg && !rtx_equal_p (operands[0], operands[4])"
5354 1.1.1.3 mrg {
5355 1.1.1.3 mrg emit_insn (gen_vcond_mask_<mode><vpred> (operands[0], operands[2],
5356 1.1.1.3 mrg operands[4], operands[1]));
5357 1.1.1.3 mrg operands[4] = operands[2] = operands[0];
5358 1.1.1.3 mrg }
5359 1.1.1.3 mrg [(set_attr "movprfx" "yes")]
5360 1.1.1.3 mrg )
5361 1.1.1.3 mrg
5362 1.1.1.3 mrg ;; -------------------------------------------------------------------------
5363 1.1.1.3 mrg ;; ---- [FP] Addition
5364 1.1.1.3 mrg ;; -------------------------------------------------------------------------
5365 1.1.1.3 mrg ;; Includes:
5366 1.1.1.3 mrg ;; - FADD
5367 1.1.1.3 mrg ;; - FSUB
5368 1.1.1.3 mrg ;; -------------------------------------------------------------------------
5369 1.1.1.3 mrg
5370 1.1.1.3 mrg ;; Predicated floating-point addition.
5371 1.1.1.3 mrg (define_insn_and_split "@aarch64_pred_<optab><mode>"
5372 1.1.1.3 mrg [(set (match_operand:SVE_FULL_F 0 "register_operand" "=w, w, w, w, ?&w, ?&w, ?&w")
5373 1.1.1.3 mrg (unspec:SVE_FULL_F
5374 1.1.1.3 mrg [(match_operand:<VPRED> 1 "register_operand" "Upl, Upl, Upl, Upl, Upl, Upl, Upl")
5375 1.1.1.3 mrg (match_operand:SI 4 "aarch64_sve_gp_strictness" "i, i, Z, Ui1, i, i, Ui1")
5376 1.1.1.3 mrg (match_operand:SVE_FULL_F 2 "register_operand" "%0, 0, w, 0, w, w, w")
5377 1.1.1.3 mrg (match_operand:SVE_FULL_F 3 "aarch64_sve_float_arith_with_sub_operand" "vsA, vsN, w, w, vsA, vsN, w")]
5378 1.1.1.3 mrg SVE_COND_FP_ADD))]
5379 1.1.1.3 mrg "TARGET_SVE"
5380 1.1.1.3 mrg "@
5381 1.1.1.3 mrg fadd\t%0.<Vetype>, %1/m, %0.<Vetype>, #%3
5382 1.1.1.3 mrg fsub\t%0.<Vetype>, %1/m, %0.<Vetype>, #%N3
5383 1.1.1.3 mrg #
5384 1.1.1.3 mrg fadd\t%0.<Vetype>, %1/m, %0.<Vetype>, %3.<Vetype>
5385 1.1.1.3 mrg movprfx\t%0, %2\;fadd\t%0.<Vetype>, %1/m, %0.<Vetype>, #%3
5386 1.1.1.3 mrg movprfx\t%0, %2\;fsub\t%0.<Vetype>, %1/m, %0.<Vetype>, #%N3
5387 1.1.1.3 mrg movprfx\t%0, %2\;fadd\t%0.<Vetype>, %1/m, %0.<Vetype>, %3.<Vetype>"
5388 1.1.1.3 mrg ; Split the unpredicated form after reload, so that we don't have
5389 1.1.1.3 mrg ; the unnecessary PTRUE.
5390 1.1.1.3 mrg "&& reload_completed
5391 1.1.1.3 mrg && register_operand (operands[3], <MODE>mode)
5392 1.1.1.3 mrg && INTVAL (operands[4]) == SVE_RELAXED_GP"
5393 1.1.1.3 mrg [(set (match_dup 0) (plus:SVE_FULL_F (match_dup 2) (match_dup 3)))]
5394 1.1.1.3 mrg ""
5395 1.1.1.3 mrg [(set_attr "movprfx" "*,*,*,*,yes,yes,yes")]
5396 1.1.1.3 mrg )
5397 1.1.1.3 mrg
5398 1.1.1.3 mrg ;; Predicated floating-point addition of a constant, merging with the
5399 1.1.1.3 mrg ;; first input.
5400 1.1.1.3 mrg (define_insn_and_rewrite "*cond_add<mode>_2_const_relaxed"
5401 1.1.1.3 mrg [(set (match_operand:SVE_FULL_F 0 "register_operand" "=w, w, ?w, ?w")
5402 1.1.1.3 mrg (unspec:SVE_FULL_F
5403 1.1.1.3 mrg [(match_operand:<VPRED> 1 "register_operand" "Upl, Upl, Upl, Upl")
5404 1.1.1.3 mrg (unspec:SVE_FULL_F
5405 1.1.1.3 mrg [(match_operand 4)
5406 1.1.1.3 mrg (const_int SVE_RELAXED_GP)
5407 1.1.1.3 mrg (match_operand:SVE_FULL_F 2 "register_operand" "0, 0, w, w")
5408 1.1.1.3 mrg (match_operand:SVE_FULL_F 3 "aarch64_sve_float_arith_with_sub_immediate" "vsA, vsN, vsA, vsN")]
5409 1.1.1.3 mrg UNSPEC_COND_FADD)
5410 1.1.1.3 mrg (match_dup 2)]
5411 1.1.1.3 mrg UNSPEC_SEL))]
5412 1.1.1.3 mrg "TARGET_SVE"
5413 1.1.1.3 mrg "@
5414 1.1.1.3 mrg fadd\t%0.<Vetype>, %1/m, %0.<Vetype>, #%3
5415 1.1.1.3 mrg fsub\t%0.<Vetype>, %1/m, %0.<Vetype>, #%N3
5416 1.1.1.3 mrg movprfx\t%0, %2\;fadd\t%0.<Vetype>, %1/m, %0.<Vetype>, #%3
5417 1.1.1.3 mrg movprfx\t%0, %2\;fsub\t%0.<Vetype>, %1/m, %0.<Vetype>, #%N3"
5418 1.1.1.3 mrg "&& !rtx_equal_p (operands[1], operands[4])"
5419 1.1.1.3 mrg {
5420 1.1.1.3 mrg operands[4] = copy_rtx (operands[1]);
5421 1.1.1.3 mrg }
5422 1.1.1.3 mrg [(set_attr "movprfx" "*,*,yes,yes")]
5423 1.1.1.3 mrg )
5424 1.1.1.3 mrg
5425 1.1.1.3 mrg (define_insn "*cond_add<mode>_2_const_strict"
5426 1.1.1.3 mrg [(set (match_operand:SVE_FULL_F 0 "register_operand" "=w, w, ?w, ?w")
5427 1.1.1.3 mrg (unspec:SVE_FULL_F
5428 1.1.1.3 mrg [(match_operand:<VPRED> 1 "register_operand" "Upl, Upl, Upl, Upl")
5429 1.1.1.3 mrg (unspec:SVE_FULL_F
5430 1.1.1.3 mrg [(match_dup 1)
5431 1.1.1.3 mrg (const_int SVE_STRICT_GP)
5432 1.1.1.3 mrg (match_operand:SVE_FULL_F 2 "register_operand" "0, 0, w, w")
5433 1.1.1.3 mrg (match_operand:SVE_FULL_F 3 "aarch64_sve_float_arith_with_sub_immediate" "vsA, vsN, vsA, vsN")]
5434 1.1.1.3 mrg UNSPEC_COND_FADD)
5435 1.1.1.3 mrg (match_dup 2)]
5436 1.1.1.3 mrg UNSPEC_SEL))]
5437 1.1.1.3 mrg "TARGET_SVE"
5438 1.1.1.3 mrg "@
5439 1.1.1.3 mrg fadd\t%0.<Vetype>, %1/m, %0.<Vetype>, #%3
5440 1.1.1.3 mrg fsub\t%0.<Vetype>, %1/m, %0.<Vetype>, #%N3
5441 1.1.1.3 mrg movprfx\t%0, %2\;fadd\t%0.<Vetype>, %1/m, %0.<Vetype>, #%3
5442 1.1.1.3 mrg movprfx\t%0, %2\;fsub\t%0.<Vetype>, %1/m, %0.<Vetype>, #%N3"
5443 1.1.1.3 mrg [(set_attr "movprfx" "*,*,yes,yes")]
5444 1.1.1.3 mrg )
5445 1.1.1.3 mrg
5446 1.1.1.3 mrg ;; Predicated floating-point addition of a constant, merging with an
5447 1.1.1.3 mrg ;; independent value.
5448 1.1.1.3 mrg (define_insn_and_rewrite "*cond_add<mode>_any_const_relaxed"
5449 1.1.1.3 mrg [(set (match_operand:SVE_FULL_F 0 "register_operand" "=w, w, w, w, ?w, ?w")
5450 1.1.1.3 mrg (unspec:SVE_FULL_F
5451 1.1.1.3 mrg [(match_operand:<VPRED> 1 "register_operand" "Upl, Upl, Upl, Upl, Upl, Upl")
5452 1.1.1.3 mrg (unspec:SVE_FULL_F
5453 1.1.1.3 mrg [(match_operand 5)
5454 1.1.1.3 mrg (const_int SVE_RELAXED_GP)
5455 1.1.1.3 mrg (match_operand:SVE_FULL_F 2 "register_operand" "w, w, w, w, w, w")
5456 1.1.1.3 mrg (match_operand:SVE_FULL_F 3 "aarch64_sve_float_arith_with_sub_immediate" "vsA, vsN, vsA, vsN, vsA, vsN")]
5457 1.1.1.3 mrg UNSPEC_COND_FADD)
5458 1.1.1.3 mrg (match_operand:SVE_FULL_F 4 "aarch64_simd_reg_or_zero" "Dz, Dz, 0, 0, w, w")]
5459 1.1.1.3 mrg UNSPEC_SEL))]
5460 1.1.1.3 mrg "TARGET_SVE && !rtx_equal_p (operands[2], operands[4])"
5461 1.1.1.3 mrg "@
5462 1.1.1.3 mrg movprfx\t%0.<Vetype>, %1/z, %2.<Vetype>\;fadd\t%0.<Vetype>, %1/m, %0.<Vetype>, #%3
5463 1.1.1.3 mrg movprfx\t%0.<Vetype>, %1/z, %2.<Vetype>\;fsub\t%0.<Vetype>, %1/m, %0.<Vetype>, #%N3
5464 1.1.1.3 mrg movprfx\t%0.<Vetype>, %1/m, %2.<Vetype>\;fadd\t%0.<Vetype>, %1/m, %0.<Vetype>, #%3
5465 1.1.1.3 mrg movprfx\t%0.<Vetype>, %1/m, %2.<Vetype>\;fsub\t%0.<Vetype>, %1/m, %0.<Vetype>, #%N3
5466 1.1.1.3 mrg #
5467 1.1.1.3 mrg #"
5468 1.1.1.3 mrg "&& 1"
5469 1.1.1.3 mrg {
5470 1.1.1.3 mrg if (reload_completed
5471 1.1.1.3 mrg && register_operand (operands[4], <MODE>mode)
5472 1.1.1.3 mrg && !rtx_equal_p (operands[0], operands[4]))
5473 1.1.1.3 mrg {
5474 1.1.1.3 mrg emit_insn (gen_vcond_mask_<mode><vpred> (operands[0], operands[2],
5475 1.1.1.3 mrg operands[4], operands[1]));
5476 1.1.1.3 mrg operands[4] = operands[2] = operands[0];
5477 1.1.1.3 mrg }
5478 1.1.1.3 mrg else if (!rtx_equal_p (operands[1], operands[5]))
5479 1.1.1.3 mrg operands[5] = copy_rtx (operands[1]);
5480 1.1.1.3 mrg else
5481 1.1.1.3 mrg FAIL;
5482 1.1.1.3 mrg }
5483 1.1.1.3 mrg [(set_attr "movprfx" "yes")]
5484 1.1.1.3 mrg )
5485 1.1.1.3 mrg
5486 1.1.1.3 mrg (define_insn_and_rewrite "*cond_add<mode>_any_const_strict"
5487 1.1.1.3 mrg [(set (match_operand:SVE_FULL_F 0 "register_operand" "=w, w, w, w, ?w, ?w")
5488 1.1.1.3 mrg (unspec:SVE_FULL_F
5489 1.1.1.3 mrg [(match_operand:<VPRED> 1 "register_operand" "Upl, Upl, Upl, Upl, Upl, Upl")
5490 1.1.1.3 mrg (unspec:SVE_FULL_F
5491 1.1.1.3 mrg [(match_dup 1)
5492 1.1.1.3 mrg (const_int SVE_STRICT_GP)
5493 1.1.1.3 mrg (match_operand:SVE_FULL_F 2 "register_operand" "w, w, w, w, w, w")
5494 1.1.1.3 mrg (match_operand:SVE_FULL_F 3 "aarch64_sve_float_arith_with_sub_immediate" "vsA, vsN, vsA, vsN, vsA, vsN")]
5495 1.1.1.3 mrg UNSPEC_COND_FADD)
5496 1.1.1.3 mrg (match_operand:SVE_FULL_F 4 "aarch64_simd_reg_or_zero" "Dz, Dz, 0, 0, w, w")]
5497 1.1.1.3 mrg UNSPEC_SEL))]
5498 1.1.1.3 mrg "TARGET_SVE && !rtx_equal_p (operands[2], operands[4])"
5499 1.1.1.3 mrg "@
5500 1.1.1.3 mrg movprfx\t%0.<Vetype>, %1/z, %2.<Vetype>\;fadd\t%0.<Vetype>, %1/m, %0.<Vetype>, #%3
5501 1.1.1.3 mrg movprfx\t%0.<Vetype>, %1/z, %2.<Vetype>\;fsub\t%0.<Vetype>, %1/m, %0.<Vetype>, #%N3
5502 1.1.1.3 mrg movprfx\t%0.<Vetype>, %1/m, %2.<Vetype>\;fadd\t%0.<Vetype>, %1/m, %0.<Vetype>, #%3
5503 1.1.1.3 mrg movprfx\t%0.<Vetype>, %1/m, %2.<Vetype>\;fsub\t%0.<Vetype>, %1/m, %0.<Vetype>, #%N3
5504 1.1.1.3 mrg #
5505 1.1.1.3 mrg #"
5506 1.1.1.3 mrg "&& reload_completed
5507 1.1.1.3 mrg && register_operand (operands[4], <MODE>mode)
5508 1.1.1.3 mrg && !rtx_equal_p (operands[0], operands[4])"
5509 1.1.1.3 mrg {
5510 1.1.1.3 mrg emit_insn (gen_vcond_mask_<mode><vpred> (operands[0], operands[2],
5511 1.1.1.3 mrg operands[4], operands[1]));
5512 1.1.1.3 mrg operands[4] = operands[2] = operands[0];
5513 1.1.1.3 mrg }
5514 1.1.1.3 mrg [(set_attr "movprfx" "yes")]
5515 1.1.1.3 mrg )
5516 1.1.1.3 mrg
5517 1.1.1.3 mrg ;; Register merging forms are handled through SVE_COND_FP_BINARY.
5518 1.1.1.3 mrg
5519 1.1.1.3 mrg ;; -------------------------------------------------------------------------
5520 1.1.1.3 mrg ;; ---- [FP] Complex addition
5521 1.1.1.3 mrg ;; -------------------------------------------------------------------------
5522 1.1.1.3 mrg ;; Includes:
5523 1.1.1.3 mrg ;; - FCADD
5524 1.1.1.3 mrg ;; -------------------------------------------------------------------------
5525 1.1.1.3 mrg
5526 1.1.1.3 mrg ;; Predicated FCADD.
5527 1.1.1.3 mrg (define_insn "@aarch64_pred_<optab><mode>"
5528 1.1.1.3 mrg [(set (match_operand:SVE_FULL_F 0 "register_operand" "=w, ?&w")
5529 1.1.1.3 mrg (unspec:SVE_FULL_F
5530 1.1.1.3 mrg [(match_operand:<VPRED> 1 "register_operand" "Upl, Upl")
5531 1.1.1.3 mrg (match_operand:SI 4 "aarch64_sve_gp_strictness")
5532 1.1.1.3 mrg (match_operand:SVE_FULL_F 2 "register_operand" "0, w")
5533 1.1.1.3 mrg (match_operand:SVE_FULL_F 3 "register_operand" "w, w")]
5534 1.1.1.3 mrg SVE_COND_FCADD))]
5535 1.1.1.3 mrg "TARGET_SVE"
5536 1.1.1.3 mrg "@
5537 1.1.1.3 mrg fcadd\t%0.<Vetype>, %1/m, %0.<Vetype>, %3.<Vetype>, #<rot>
5538 1.1.1.3 mrg movprfx\t%0, %2\;fcadd\t%0.<Vetype>, %1/m, %0.<Vetype>, %3.<Vetype>, #<rot>"
5539 1.1.1.3 mrg [(set_attr "movprfx" "*,yes")]
5540 1.1.1.3 mrg )
5541 1.1.1.3 mrg
5542 1.1.1.3 mrg ;; Predicated FCADD with merging.
5543 1.1.1.3 mrg (define_expand "@cond_<optab><mode>"
5544 1.1.1.3 mrg [(set (match_operand:SVE_FULL_F 0 "register_operand")
5545 1.1.1.3 mrg (unspec:SVE_FULL_F
5546 1.1.1.3 mrg [(match_operand:<VPRED> 1 "register_operand")
5547 1.1.1.3 mrg (unspec:SVE_FULL_F
5548 1.1.1.3 mrg [(match_dup 1)
5549 1.1.1.3 mrg (const_int SVE_STRICT_GP)
5550 1.1.1.3 mrg (match_operand:SVE_FULL_F 2 "register_operand")
5551 1.1.1.3 mrg (match_operand:SVE_FULL_F 3 "register_operand")]
5552 1.1.1.3 mrg SVE_COND_FCADD)
5553 1.1.1.3 mrg (match_operand:SVE_FULL_F 4 "aarch64_simd_reg_or_zero")]
5554 1.1.1.3 mrg UNSPEC_SEL))]
5555 1.1.1.3 mrg "TARGET_SVE"
5556 1.1.1.3 mrg )
5557 1.1.1.3 mrg
5558 1.1.1.5 mrg ;; Predicated FCADD using ptrue for unpredicated optab for auto-vectorizer
5559 1.1.1.5 mrg (define_expand "@cadd<rot><mode>3"
5560 1.1.1.5 mrg [(set (match_operand:SVE_FULL_F 0 "register_operand")
5561 1.1.1.5 mrg (unspec:SVE_FULL_F
5562 1.1.1.5 mrg [(match_dup 3)
5563 1.1.1.5 mrg (const_int SVE_RELAXED_GP)
5564 1.1.1.5 mrg (match_operand:SVE_FULL_F 1 "register_operand")
5565 1.1.1.5 mrg (match_operand:SVE_FULL_F 2 "register_operand")]
5566 1.1.1.5 mrg SVE_COND_FCADD))]
5567 1.1.1.5 mrg "TARGET_SVE"
5568 1.1.1.5 mrg {
5569 1.1.1.5 mrg operands[3] = aarch64_ptrue_reg (<VPRED>mode);
5570 1.1.1.5 mrg })
5571 1.1.1.5 mrg
5572 1.1.1.3 mrg ;; Predicated FCADD, merging with the first input.
5573 1.1.1.3 mrg (define_insn_and_rewrite "*cond_<optab><mode>_2_relaxed"
5574 1.1.1.3 mrg [(set (match_operand:SVE_FULL_F 0 "register_operand" "=w, ?&w")
5575 1.1.1.3 mrg (unspec:SVE_FULL_F
5576 1.1.1.3 mrg [(match_operand:<VPRED> 1 "register_operand" "Upl, Upl")
5577 1.1.1.3 mrg (unspec:SVE_FULL_F
5578 1.1.1.3 mrg [(match_operand 4)
5579 1.1.1.3 mrg (const_int SVE_RELAXED_GP)
5580 1.1.1.3 mrg (match_operand:SVE_FULL_F 2 "register_operand" "0, w")
5581 1.1.1.3 mrg (match_operand:SVE_FULL_F 3 "register_operand" "w, w")]
5582 1.1.1.3 mrg SVE_COND_FCADD)
5583 1.1.1.3 mrg (match_dup 2)]
5584 1.1.1.3 mrg UNSPEC_SEL))]
5585 1.1.1.3 mrg "TARGET_SVE"
5586 1.1.1.3 mrg "@
5587 1.1.1.3 mrg fcadd\t%0.<Vetype>, %1/m, %0.<Vetype>, %3.<Vetype>, #<rot>
5588 1.1.1.3 mrg movprfx\t%0, %2\;fcadd\t%0.<Vetype>, %1/m, %0.<Vetype>, %3.<Vetype>, #<rot>"
5589 1.1.1.3 mrg "&& !rtx_equal_p (operands[1], operands[4])"
5590 1.1.1.3 mrg {
5591 1.1.1.3 mrg operands[4] = copy_rtx (operands[1]);
5592 1.1.1.3 mrg }
5593 1.1.1.3 mrg [(set_attr "movprfx" "*,yes")]
5594 1.1.1.3 mrg )
5595 1.1.1.3 mrg
5596 1.1.1.3 mrg (define_insn "*cond_<optab><mode>_2_strict"
5597 1.1.1.3 mrg [(set (match_operand:SVE_FULL_F 0 "register_operand" "=w, ?&w")
5598 1.1.1.3 mrg (unspec:SVE_FULL_F
5599 1.1.1.3 mrg [(match_operand:<VPRED> 1 "register_operand" "Upl, Upl")
5600 1.1.1.3 mrg (unspec:SVE_FULL_F
5601 1.1.1.3 mrg [(match_dup 1)
5602 1.1.1.3 mrg (const_int SVE_STRICT_GP)
5603 1.1.1.3 mrg (match_operand:SVE_FULL_F 2 "register_operand" "0, w")
5604 1.1.1.3 mrg (match_operand:SVE_FULL_F 3 "register_operand" "w, w")]
5605 1.1.1.3 mrg SVE_COND_FCADD)
5606 1.1.1.3 mrg (match_dup 2)]
5607 1.1.1.3 mrg UNSPEC_SEL))]
5608 1.1.1.3 mrg "TARGET_SVE"
5609 1.1.1.3 mrg "@
5610 1.1.1.3 mrg fcadd\t%0.<Vetype>, %1/m, %0.<Vetype>, %3.<Vetype>, #<rot>
5611 1.1.1.3 mrg movprfx\t%0, %2\;fcadd\t%0.<Vetype>, %1/m, %0.<Vetype>, %3.<Vetype>, #<rot>"
5612 1.1.1.3 mrg [(set_attr "movprfx" "*,yes")]
5613 1.1.1.3 mrg )
5614 1.1.1.3 mrg
5615 1.1.1.3 mrg ;; Predicated FCADD, merging with an independent value.
5616 1.1.1.3 mrg (define_insn_and_rewrite "*cond_<optab><mode>_any_relaxed"
5617 1.1.1.3 mrg [(set (match_operand:SVE_FULL_F 0 "register_operand" "=&w, &w, &w, ?&w")
5618 1.1.1.3 mrg (unspec:SVE_FULL_F
5619 1.1.1.3 mrg [(match_operand:<VPRED> 1 "register_operand" "Upl, Upl, Upl, Upl")
5620 1.1.1.3 mrg (unspec:SVE_FULL_F
5621 1.1.1.3 mrg [(match_operand 5)
5622 1.1.1.3 mrg (const_int SVE_RELAXED_GP)
5623 1.1.1.3 mrg (match_operand:SVE_FULL_F 2 "register_operand" "w, 0, w, w")
5624 1.1.1.3 mrg (match_operand:SVE_FULL_F 3 "register_operand" "w, w, w, w")]
5625 1.1.1.3 mrg SVE_COND_FCADD)
5626 1.1.1.3 mrg (match_operand:SVE_FULL_F 4 "aarch64_simd_reg_or_zero" "Dz, Dz, 0, w")]
5627 1.1.1.3 mrg UNSPEC_SEL))]
5628 1.1.1.3 mrg "TARGET_SVE && !rtx_equal_p (operands[2], operands[4])"
5629 1.1.1.3 mrg "@
5630 1.1.1.3 mrg movprfx\t%0.<Vetype>, %1/z, %2.<Vetype>\;fcadd\t%0.<Vetype>, %1/m, %0.<Vetype>, %3.<Vetype>, #<rot>
5631 1.1.1.3 mrg movprfx\t%0.<Vetype>, %1/z, %0.<Vetype>\;fcadd\t%0.<Vetype>, %1/m, %0.<Vetype>, %3.<Vetype>, #<rot>
5632 1.1.1.3 mrg movprfx\t%0.<Vetype>, %1/m, %2.<Vetype>\;fcadd\t%0.<Vetype>, %1/m, %0.<Vetype>, %3.<Vetype>, #<rot>
5633 1.1.1.3 mrg #"
5634 1.1.1.3 mrg "&& 1"
5635 1.1.1.3 mrg {
5636 1.1.1.3 mrg if (reload_completed
5637 1.1.1.3 mrg && register_operand (operands[4], <MODE>mode)
5638 1.1.1.3 mrg && !rtx_equal_p (operands[0], operands[4]))
5639 1.1.1.3 mrg {
5640 1.1.1.3 mrg emit_insn (gen_vcond_mask_<mode><vpred> (operands[0], operands[2],
5641 1.1.1.3 mrg operands[4], operands[1]));
5642 1.1.1.3 mrg operands[4] = operands[2] = operands[0];
5643 1.1.1.3 mrg }
5644 1.1.1.3 mrg else if (!rtx_equal_p (operands[1], operands[5]))
5645 1.1.1.3 mrg operands[5] = copy_rtx (operands[1]);
5646 1.1.1.3 mrg else
5647 1.1.1.3 mrg FAIL;
5648 1.1.1.3 mrg }
5649 1.1.1.3 mrg [(set_attr "movprfx" "yes")]
5650 1.1.1.3 mrg )
5651 1.1.1.3 mrg
5652 1.1.1.3 mrg (define_insn_and_rewrite "*cond_<optab><mode>_any_strict"
5653 1.1.1.3 mrg [(set (match_operand:SVE_FULL_F 0 "register_operand" "=&w, &w, &w, ?&w")
5654 1.1.1.3 mrg (unspec:SVE_FULL_F
5655 1.1.1.3 mrg [(match_operand:<VPRED> 1 "register_operand" "Upl, Upl, Upl, Upl")
5656 1.1.1.3 mrg (unspec:SVE_FULL_F
5657 1.1.1.3 mrg [(match_dup 1)
5658 1.1.1.3 mrg (const_int SVE_STRICT_GP)
5659 1.1.1.3 mrg (match_operand:SVE_FULL_F 2 "register_operand" "w, 0, w, w")
5660 1.1.1.3 mrg (match_operand:SVE_FULL_F 3 "register_operand" "w, w, w, w")]
5661 1.1.1.3 mrg SVE_COND_FCADD)
5662 1.1.1.3 mrg (match_operand:SVE_FULL_F 4 "aarch64_simd_reg_or_zero" "Dz, Dz, 0, w")]
5663 1.1.1.3 mrg UNSPEC_SEL))]
5664 1.1.1.3 mrg "TARGET_SVE && !rtx_equal_p (operands[2], operands[4])"
5665 1.1.1.3 mrg "@
5666 1.1.1.3 mrg movprfx\t%0.<Vetype>, %1/z, %2.<Vetype>\;fcadd\t%0.<Vetype>, %1/m, %0.<Vetype>, %3.<Vetype>, #<rot>
5667 1.1.1.3 mrg movprfx\t%0.<Vetype>, %1/z, %0.<Vetype>\;fcadd\t%0.<Vetype>, %1/m, %0.<Vetype>, %3.<Vetype>, #<rot>
5668 1.1.1.3 mrg movprfx\t%0.<Vetype>, %1/m, %2.<Vetype>\;fcadd\t%0.<Vetype>, %1/m, %0.<Vetype>, %3.<Vetype>, #<rot>
5669 1.1.1.3 mrg #"
5670 1.1.1.3 mrg "&& reload_completed
5671 1.1.1.3 mrg && register_operand (operands[4], <MODE>mode)
5672 1.1.1.3 mrg && !rtx_equal_p (operands[0], operands[4])"
5673 1.1.1.3 mrg {
5674 1.1.1.3 mrg emit_insn (gen_vcond_mask_<mode><vpred> (operands[0], operands[2],
5675 1.1.1.3 mrg operands[4], operands[1]));
5676 1.1.1.3 mrg operands[4] = operands[2] = operands[0];
5677 1.1.1.3 mrg }
5678 1.1.1.3 mrg [(set_attr "movprfx" "yes")]
5679 1.1.1.3 mrg )
5680 1.1.1.3 mrg
5681 1.1.1.3 mrg ;; -------------------------------------------------------------------------
5682 1.1.1.3 mrg ;; ---- [FP] Subtraction
5683 1.1.1.3 mrg ;; -------------------------------------------------------------------------
5684 1.1.1.3 mrg ;; Includes:
5685 1.1.1.3 mrg ;; - FSUB
5686 1.1.1.3 mrg ;; - FSUBR
5687 1.1.1.3 mrg ;; -------------------------------------------------------------------------
5688 1.1.1.3 mrg
5689 1.1.1.3 mrg ;; Predicated floating-point subtraction.
5690 1.1.1.3 mrg (define_insn_and_split "@aarch64_pred_<optab><mode>"
5691 1.1.1.3 mrg [(set (match_operand:SVE_FULL_F 0 "register_operand" "=w, w, w, w, ?&w, ?&w")
5692 1.1.1.3 mrg (unspec:SVE_FULL_F
5693 1.1.1.3 mrg [(match_operand:<VPRED> 1 "register_operand" "Upl, Upl, Upl, Upl, Upl, Upl")
5694 1.1.1.3 mrg (match_operand:SI 4 "aarch64_sve_gp_strictness" "i, Z, Ui1, Ui1, i, Ui1")
5695 1.1.1.3 mrg (match_operand:SVE_FULL_F 2 "aarch64_sve_float_arith_operand" "vsA, w, 0, w, vsA, w")
5696 1.1.1.3 mrg (match_operand:SVE_FULL_F 3 "register_operand" "0, w, w, 0, w, w")]
5697 1.1.1.3 mrg SVE_COND_FP_SUB))]
5698 1.1.1.3 mrg "TARGET_SVE"
5699 1.1.1.3 mrg "@
5700 1.1.1.3 mrg fsubr\t%0.<Vetype>, %1/m, %0.<Vetype>, #%2
5701 1.1.1.3 mrg #
5702 1.1.1.3 mrg fsub\t%0.<Vetype>, %1/m, %0.<Vetype>, %3.<Vetype>
5703 1.1.1.3 mrg fsubr\t%0.<Vetype>, %1/m, %0.<Vetype>, %2.<Vetype>
5704 1.1.1.3 mrg movprfx\t%0, %3\;fsubr\t%0.<Vetype>, %1/m, %0.<Vetype>, #%2
5705 1.1.1.3 mrg movprfx\t%0, %2\;fsub\t%0.<Vetype>, %1/m, %0.<Vetype>, %3.<Vetype>"
5706 1.1.1.3 mrg ; Split the unpredicated form after reload, so that we don't have
5707 1.1.1.3 mrg ; the unnecessary PTRUE.
5708 1.1.1.3 mrg "&& reload_completed
5709 1.1.1.3 mrg && register_operand (operands[2], <MODE>mode)
5710 1.1.1.3 mrg && INTVAL (operands[4]) == SVE_RELAXED_GP"
5711 1.1.1.3 mrg [(set (match_dup 0) (minus:SVE_FULL_F (match_dup 2) (match_dup 3)))]
5712 1.1.1.3 mrg ""
5713 1.1.1.3 mrg [(set_attr "movprfx" "*,*,*,*,yes,yes")]
5714 1.1.1.3 mrg )
5715 1.1.1.3 mrg
5716 1.1.1.3 mrg ;; Predicated floating-point subtraction from a constant, merging with the
5717 1.1.1.3 mrg ;; second input.
5718 1.1.1.3 mrg (define_insn_and_rewrite "*cond_sub<mode>_3_const_relaxed"
5719 1.1.1.3 mrg [(set (match_operand:SVE_FULL_F 0 "register_operand" "=w, ?w")
5720 1.1.1.3 mrg (unspec:SVE_FULL_F
5721 1.1.1.3 mrg [(match_operand:<VPRED> 1 "register_operand" "Upl, Upl")
5722 1.1.1.3 mrg (unspec:SVE_FULL_F
5723 1.1.1.3 mrg [(match_operand 4)
5724 1.1.1.3 mrg (const_int SVE_RELAXED_GP)
5725 1.1.1.3 mrg (match_operand:SVE_FULL_F 2 "aarch64_sve_float_arith_immediate")
5726 1.1.1.3 mrg (match_operand:SVE_FULL_F 3 "register_operand" "0, w")]
5727 1.1.1.3 mrg UNSPEC_COND_FSUB)
5728 1.1.1.3 mrg (match_dup 3)]
5729 1.1.1.3 mrg UNSPEC_SEL))]
5730 1.1.1.3 mrg "TARGET_SVE"
5731 1.1.1.3 mrg "@
5732 1.1.1.3 mrg fsubr\t%0.<Vetype>, %1/m, %0.<Vetype>, #%2
5733 1.1.1.3 mrg movprfx\t%0, %3\;fsubr\t%0.<Vetype>, %1/m, %0.<Vetype>, #%2"
5734 1.1.1.3 mrg "&& !rtx_equal_p (operands[1], operands[4])"
5735 1.1.1.3 mrg {
5736 1.1.1.3 mrg operands[4] = copy_rtx (operands[1]);
5737 1.1.1.3 mrg }
5738 1.1.1.3 mrg [(set_attr "movprfx" "*,yes")]
5739 1.1.1.3 mrg )
5740 1.1.1.3 mrg
5741 1.1.1.3 mrg (define_insn "*cond_sub<mode>_3_const_strict"
5742 1.1.1.3 mrg [(set (match_operand:SVE_FULL_F 0 "register_operand" "=w, ?w")
5743 1.1.1.3 mrg (unspec:SVE_FULL_F
5744 1.1.1.3 mrg [(match_operand:<VPRED> 1 "register_operand" "Upl, Upl")
5745 1.1.1.3 mrg (unspec:SVE_FULL_F
5746 1.1.1.3 mrg [(match_dup 1)
5747 1.1.1.3 mrg (const_int SVE_STRICT_GP)
5748 1.1.1.3 mrg (match_operand:SVE_FULL_F 2 "aarch64_sve_float_arith_immediate")
5749 1.1.1.3 mrg (match_operand:SVE_FULL_F 3 "register_operand" "0, w")]
5750 1.1.1.3 mrg UNSPEC_COND_FSUB)
5751 1.1.1.3 mrg (match_dup 3)]
5752 1.1.1.3 mrg UNSPEC_SEL))]
5753 1.1.1.3 mrg "TARGET_SVE"
5754 1.1.1.3 mrg "@
5755 1.1.1.3 mrg fsubr\t%0.<Vetype>, %1/m, %0.<Vetype>, #%2
5756 1.1.1.3 mrg movprfx\t%0, %3\;fsubr\t%0.<Vetype>, %1/m, %0.<Vetype>, #%2"
5757 1.1.1.3 mrg [(set_attr "movprfx" "*,yes")]
5758 1.1.1.3 mrg )
5759 1.1.1.3 mrg
5760 1.1.1.3 mrg ;; Predicated floating-point subtraction from a constant, merging with an
5761 1.1.1.3 mrg ;; independent value.
5762 1.1.1.3 mrg (define_insn_and_rewrite "*cond_sub<mode>_const_relaxed"
5763 1.1.1.3 mrg [(set (match_operand:SVE_FULL_F 0 "register_operand" "=w, w, ?w")
5764 1.1.1.3 mrg (unspec:SVE_FULL_F
5765 1.1.1.3 mrg [(match_operand:<VPRED> 1 "register_operand" "Upl, Upl, Upl")
5766 1.1.1.3 mrg (unspec:SVE_FULL_F
5767 1.1.1.3 mrg [(match_operand 5)
5768 1.1.1.3 mrg (const_int SVE_RELAXED_GP)
5769 1.1.1.3 mrg (match_operand:SVE_FULL_F 2 "aarch64_sve_float_arith_immediate")
5770 1.1.1.3 mrg (match_operand:SVE_FULL_F 3 "register_operand" "w, w, w")]
5771 1.1.1.3 mrg UNSPEC_COND_FSUB)
5772 1.1.1.3 mrg (match_operand:SVE_FULL_F 4 "aarch64_simd_reg_or_zero" "Dz, 0, w")]
5773 1.1.1.3 mrg UNSPEC_SEL))]
5774 1.1.1.3 mrg "TARGET_SVE && !rtx_equal_p (operands[3], operands[4])"
5775 1.1.1.3 mrg "@
5776 1.1.1.3 mrg movprfx\t%0.<Vetype>, %1/z, %3.<Vetype>\;fsubr\t%0.<Vetype>, %1/m, %0.<Vetype>, #%2
5777 1.1.1.3 mrg movprfx\t%0.<Vetype>, %1/m, %3.<Vetype>\;fsubr\t%0.<Vetype>, %1/m, %0.<Vetype>, #%2
5778 1.1.1.3 mrg #"
5779 1.1.1.3 mrg "&& 1"
5780 1.1.1.3 mrg {
5781 1.1.1.3 mrg if (reload_completed
5782 1.1.1.3 mrg && register_operand (operands[4], <MODE>mode)
5783 1.1.1.3 mrg && !rtx_equal_p (operands[0], operands[4]))
5784 1.1.1.3 mrg {
5785 1.1.1.3 mrg emit_insn (gen_vcond_mask_<mode><vpred> (operands[0], operands[3],
5786 1.1.1.3 mrg operands[4], operands[1]));
5787 1.1.1.3 mrg operands[4] = operands[3] = operands[0];
5788 1.1.1.3 mrg }
5789 1.1.1.3 mrg else if (!rtx_equal_p (operands[1], operands[5]))
5790 1.1.1.3 mrg operands[5] = copy_rtx (operands[1]);
5791 1.1.1.3 mrg else
5792 1.1.1.3 mrg FAIL;
5793 1.1.1.3 mrg }
5794 1.1.1.3 mrg [(set_attr "movprfx" "yes")]
5795 1.1.1.3 mrg )
5796 1.1.1.3 mrg
5797 1.1.1.3 mrg (define_insn_and_rewrite "*cond_sub<mode>_const_strict"
5798 1.1.1.3 mrg [(set (match_operand:SVE_FULL_F 0 "register_operand" "=w, w, ?w")
5799 1.1.1.3 mrg (unspec:SVE_FULL_F
5800 1.1.1.3 mrg [(match_operand:<VPRED> 1 "register_operand" "Upl, Upl, Upl")
5801 1.1.1.3 mrg (unspec:SVE_FULL_F
5802 1.1.1.3 mrg [(match_dup 1)
5803 1.1.1.3 mrg (const_int SVE_STRICT_GP)
5804 1.1.1.3 mrg (match_operand:SVE_FULL_F 2 "aarch64_sve_float_arith_immediate")
5805 1.1.1.3 mrg (match_operand:SVE_FULL_F 3 "register_operand" "w, w, w")]
5806 1.1.1.3 mrg UNSPEC_COND_FSUB)
5807 1.1.1.3 mrg (match_operand:SVE_FULL_F 4 "aarch64_simd_reg_or_zero" "Dz, 0, w")]
5808 1.1.1.3 mrg UNSPEC_SEL))]
5809 1.1.1.3 mrg "TARGET_SVE && !rtx_equal_p (operands[3], operands[4])"
5810 1.1.1.3 mrg "@
5811 1.1.1.3 mrg movprfx\t%0.<Vetype>, %1/z, %3.<Vetype>\;fsubr\t%0.<Vetype>, %1/m, %0.<Vetype>, #%2
5812 1.1.1.3 mrg movprfx\t%0.<Vetype>, %1/m, %3.<Vetype>\;fsubr\t%0.<Vetype>, %1/m, %0.<Vetype>, #%2
5813 1.1.1.3 mrg #"
5814 1.1.1.3 mrg "&& reload_completed
5815 1.1.1.3 mrg && register_operand (operands[4], <MODE>mode)
5816 1.1.1.3 mrg && !rtx_equal_p (operands[0], operands[4])"
5817 1.1.1.3 mrg {
5818 1.1.1.3 mrg emit_insn (gen_vcond_mask_<mode><vpred> (operands[0], operands[3],
5819 1.1.1.3 mrg operands[4], operands[1]));
5820 1.1.1.3 mrg operands[4] = operands[3] = operands[0];
5821 1.1.1.3 mrg }
5822 1.1.1.3 mrg [(set_attr "movprfx" "yes")]
5823 1.1.1.3 mrg )
5824 1.1.1.3 mrg ;; Register merging forms are handled through SVE_COND_FP_BINARY.
5825 1.1.1.3 mrg
5826 1.1.1.3 mrg ;; -------------------------------------------------------------------------
5827 1.1.1.3 mrg ;; ---- [FP] Absolute difference
5828 1.1.1.3 mrg ;; -------------------------------------------------------------------------
5829 1.1.1.3 mrg ;; Includes:
5830 1.1.1.3 mrg ;; - FABD
5831 1.1.1.3 mrg ;; -------------------------------------------------------------------------
5832 1.1.1.3 mrg
5833 1.1.1.3 mrg ;; Predicated floating-point absolute difference.
5834 1.1.1.3 mrg (define_expand "@aarch64_pred_abd<mode>"
5835 1.1.1.3 mrg [(set (match_operand:SVE_FULL_F 0 "register_operand")
5836 1.1.1.3 mrg (unspec:SVE_FULL_F
5837 1.1.1.3 mrg [(match_operand:<VPRED> 1 "register_operand")
5838 1.1.1.3 mrg (match_operand:SI 4 "aarch64_sve_gp_strictness")
5839 1.1.1.3 mrg (unspec:SVE_FULL_F
5840 1.1.1.3 mrg [(match_dup 1)
5841 1.1.1.3 mrg (match_dup 4)
5842 1.1.1.3 mrg (match_operand:SVE_FULL_F 2 "register_operand")
5843 1.1.1.3 mrg (match_operand:SVE_FULL_F 3 "register_operand")]
5844 1.1.1.3 mrg UNSPEC_COND_FSUB)]
5845 1.1.1.3 mrg UNSPEC_COND_FABS))]
5846 1.1.1.3 mrg "TARGET_SVE"
5847 1.1.1.3 mrg )
5848 1.1.1.3 mrg
5849 1.1.1.3 mrg ;; Predicated floating-point absolute difference.
5850 1.1.1.3 mrg (define_insn_and_rewrite "*aarch64_pred_abd<mode>_relaxed"
5851 1.1.1.3 mrg [(set (match_operand:SVE_FULL_F 0 "register_operand" "=w, ?&w")
5852 1.1.1.3 mrg (unspec:SVE_FULL_F
5853 1.1.1.3 mrg [(match_operand:<VPRED> 1 "register_operand" "Upl, Upl")
5854 1.1.1.3 mrg (match_operand:SI 4 "aarch64_sve_gp_strictness")
5855 1.1.1.3 mrg (unspec:SVE_FULL_F
5856 1.1.1.3 mrg [(match_operand 5)
5857 1.1.1.3 mrg (const_int SVE_RELAXED_GP)
5858 1.1.1.3 mrg (match_operand:SVE_FULL_F 2 "register_operand" "%0, w")
5859 1.1.1.3 mrg (match_operand:SVE_FULL_F 3 "register_operand" "w, w")]
5860 1.1.1.3 mrg UNSPEC_COND_FSUB)]
5861 1.1.1.3 mrg UNSPEC_COND_FABS))]
5862 1.1.1.3 mrg "TARGET_SVE"
5863 1.1.1.3 mrg "@
5864 1.1.1.3 mrg fabd\t%0.<Vetype>, %1/m, %0.<Vetype>, %3.<Vetype>
5865 1.1.1.3 mrg movprfx\t%0, %2\;fabd\t%0.<Vetype>, %1/m, %0.<Vetype>, %3.<Vetype>"
5866 1.1.1.3 mrg "&& !rtx_equal_p (operands[1], operands[5])"
5867 1.1.1.3 mrg {
5868 1.1.1.3 mrg operands[5] = copy_rtx (operands[1]);
5869 1.1.1.3 mrg }
5870 1.1.1.3 mrg [(set_attr "movprfx" "*,yes")]
5871 1.1.1.3 mrg )
5872 1.1.1.3 mrg
5873 1.1.1.3 mrg (define_insn "*aarch64_pred_abd<mode>_strict"
5874 1.1.1.3 mrg [(set (match_operand:SVE_FULL_F 0 "register_operand" "=w, ?&w")
5875 1.1.1.3 mrg (unspec:SVE_FULL_F
5876 1.1.1.3 mrg [(match_operand:<VPRED> 1 "register_operand" "Upl, Upl")
5877 1.1.1.3 mrg (match_operand:SI 4 "aarch64_sve_gp_strictness")
5878 1.1.1.3 mrg (unspec:SVE_FULL_F
5879 1.1.1.3 mrg [(match_dup 1)
5880 1.1.1.3 mrg (const_int SVE_STRICT_GP)
5881 1.1.1.3 mrg (match_operand:SVE_FULL_F 2 "register_operand" "%0, w")
5882 1.1.1.3 mrg (match_operand:SVE_FULL_F 3 "register_operand" "w, w")]
5883 1.1.1.3 mrg UNSPEC_COND_FSUB)]
5884 1.1.1.3 mrg UNSPEC_COND_FABS))]
5885 1.1.1.3 mrg "TARGET_SVE"
5886 1.1.1.3 mrg "@
5887 1.1.1.3 mrg fabd\t%0.<Vetype>, %1/m, %0.<Vetype>, %3.<Vetype>
5888 1.1.1.3 mrg movprfx\t%0, %2\;fabd\t%0.<Vetype>, %1/m, %0.<Vetype>, %3.<Vetype>"
5889 1.1.1.3 mrg [(set_attr "movprfx" "*,yes")]
5890 1.1.1.3 mrg )
5891 1.1.1.3 mrg
5892 1.1.1.3 mrg (define_expand "@aarch64_cond_abd<mode>"
5893 1.1.1.3 mrg [(set (match_operand:SVE_FULL_F 0 "register_operand")
5894 1.1.1.3 mrg (unspec:SVE_FULL_F
5895 1.1.1.3 mrg [(match_operand:<VPRED> 1 "register_operand")
5896 1.1.1.3 mrg (unspec:SVE_FULL_F
5897 1.1.1.3 mrg [(match_dup 1)
5898 1.1.1.3 mrg (const_int SVE_STRICT_GP)
5899 1.1.1.3 mrg (unspec:SVE_FULL_F
5900 1.1.1.3 mrg [(match_dup 1)
5901 1.1.1.3 mrg (const_int SVE_STRICT_GP)
5902 1.1.1.3 mrg (match_operand:SVE_FULL_F 2 "register_operand")
5903 1.1.1.3 mrg (match_operand:SVE_FULL_F 3 "register_operand")]
5904 1.1.1.3 mrg UNSPEC_COND_FSUB)]
5905 1.1.1.3 mrg UNSPEC_COND_FABS)
5906 1.1.1.3 mrg (match_operand:SVE_FULL_F 4 "aarch64_simd_reg_or_zero")]
5907 1.1.1.3 mrg UNSPEC_SEL))]
5908 1.1.1.3 mrg "TARGET_SVE"
5909 1.1.1.3 mrg {
5910 1.1.1.3 mrg if (rtx_equal_p (operands[3], operands[4]))
5911 1.1.1.3 mrg std::swap (operands[2], operands[3]);
5912 1.1.1.3 mrg })
5913 1.1.1.3 mrg
5914 1.1.1.3 mrg ;; Predicated floating-point absolute difference, merging with the first
5915 1.1.1.3 mrg ;; input.
5916 1.1.1.3 mrg (define_insn_and_rewrite "*aarch64_cond_abd<mode>_2_relaxed"
5917 1.1.1.3 mrg [(set (match_operand:SVE_FULL_F 0 "register_operand" "=w, ?&w")
5918 1.1.1.3 mrg (unspec:SVE_FULL_F
5919 1.1.1.3 mrg [(match_operand:<VPRED> 1 "register_operand" "Upl, Upl")
5920 1.1.1.3 mrg (unspec:SVE_FULL_F
5921 1.1.1.3 mrg [(match_operand 4)
5922 1.1.1.3 mrg (const_int SVE_RELAXED_GP)
5923 1.1.1.3 mrg (unspec:SVE_FULL_F
5924 1.1.1.3 mrg [(match_operand 5)
5925 1.1.1.3 mrg (const_int SVE_RELAXED_GP)
5926 1.1.1.3 mrg (match_operand:SVE_FULL_F 2 "register_operand" "0, w")
5927 1.1.1.3 mrg (match_operand:SVE_FULL_F 3 "register_operand" "w, w")]
5928 1.1.1.3 mrg UNSPEC_COND_FSUB)]
5929 1.1.1.3 mrg UNSPEC_COND_FABS)
5930 1.1.1.3 mrg (match_dup 2)]
5931 1.1.1.3 mrg UNSPEC_SEL))]
5932 1.1.1.3 mrg "TARGET_SVE"
5933 1.1.1.3 mrg "@
5934 1.1.1.3 mrg fabd\t%0.<Vetype>, %1/m, %0.<Vetype>, %3.<Vetype>
5935 1.1.1.3 mrg movprfx\t%0, %2\;fabd\t%0.<Vetype>, %1/m, %0.<Vetype>, %3.<Vetype>"
5936 1.1.1.3 mrg "&& (!rtx_equal_p (operands[1], operands[4])
5937 1.1.1.3 mrg || !rtx_equal_p (operands[1], operands[5]))"
5938 1.1.1.3 mrg {
5939 1.1.1.3 mrg operands[4] = copy_rtx (operands[1]);
5940 1.1.1.3 mrg operands[5] = copy_rtx (operands[1]);
5941 1.1.1.3 mrg }
5942 1.1.1.3 mrg [(set_attr "movprfx" "*,yes")]
5943 1.1.1.3 mrg )
5944 1.1.1.3 mrg
5945 1.1.1.3 mrg (define_insn "*aarch64_cond_abd<mode>_2_strict"
5946 1.1.1.3 mrg [(set (match_operand:SVE_FULL_F 0 "register_operand" "=w, ?&w")
5947 1.1.1.3 mrg (unspec:SVE_FULL_F
5948 1.1.1.3 mrg [(match_operand:<VPRED> 1 "register_operand" "Upl, Upl")
5949 1.1.1.3 mrg (unspec:SVE_FULL_F
5950 1.1.1.3 mrg [(match_dup 1)
5951 1.1.1.3 mrg (match_operand:SI 4 "aarch64_sve_gp_strictness")
5952 1.1.1.3 mrg (unspec:SVE_FULL_F
5953 1.1.1.3 mrg [(match_dup 1)
5954 1.1.1.3 mrg (match_operand:SI 5 "aarch64_sve_gp_strictness")
5955 1.1.1.3 mrg (match_operand:SVE_FULL_F 2 "register_operand" "0, w")
5956 1.1.1.3 mrg (match_operand:SVE_FULL_F 3 "register_operand" "w, w")]
5957 1.1.1.3 mrg UNSPEC_COND_FSUB)]
5958 1.1.1.3 mrg UNSPEC_COND_FABS)
5959 1.1.1.3 mrg (match_dup 2)]
5960 1.1.1.3 mrg UNSPEC_SEL))]
5961 1.1.1.3 mrg "TARGET_SVE"
5962 1.1.1.3 mrg "@
5963 1.1.1.3 mrg fabd\t%0.<Vetype>, %1/m, %0.<Vetype>, %3.<Vetype>
5964 1.1.1.3 mrg movprfx\t%0, %2\;fabd\t%0.<Vetype>, %1/m, %0.<Vetype>, %3.<Vetype>"
5965 1.1.1.3 mrg [(set_attr "movprfx" "*,yes")]
5966 1.1.1.3 mrg )
5967 1.1.1.3 mrg
5968 1.1.1.3 mrg ;; Predicated floating-point absolute difference, merging with the second
5969 1.1.1.3 mrg ;; input.
5970 1.1.1.3 mrg (define_insn_and_rewrite "*aarch64_cond_abd<mode>_3_relaxed"
5971 1.1.1.3 mrg [(set (match_operand:SVE_FULL_F 0 "register_operand" "=w, ?&w")
5972 1.1.1.3 mrg (unspec:SVE_FULL_F
5973 1.1.1.3 mrg [(match_operand:<VPRED> 1 "register_operand" "Upl, Upl")
5974 1.1.1.3 mrg (unspec:SVE_FULL_F
5975 1.1.1.3 mrg [(match_operand 4)
5976 1.1.1.3 mrg (const_int SVE_RELAXED_GP)
5977 1.1.1.3 mrg (unspec:SVE_FULL_F
5978 1.1.1.3 mrg [(match_operand 5)
5979 1.1.1.3 mrg (const_int SVE_RELAXED_GP)
5980 1.1.1.3 mrg (match_operand:SVE_FULL_F 2 "register_operand" "w, w")
5981 1.1.1.3 mrg (match_operand:SVE_FULL_F 3 "register_operand" "0, w")]
5982 1.1.1.3 mrg UNSPEC_COND_FSUB)]
5983 1.1.1.3 mrg UNSPEC_COND_FABS)
5984 1.1.1.3 mrg (match_dup 3)]
5985 1.1.1.3 mrg UNSPEC_SEL))]
5986 1.1.1.3 mrg "TARGET_SVE"
5987 1.1.1.3 mrg "@
5988 1.1.1.3 mrg fabd\t%0.<Vetype>, %1/m, %0.<Vetype>, %2.<Vetype>
5989 1.1.1.3 mrg movprfx\t%0, %3\;fabd\t%0.<Vetype>, %1/m, %0.<Vetype>, %2.<Vetype>"
5990 1.1.1.3 mrg "&& (!rtx_equal_p (operands[1], operands[4])
5991 1.1.1.3 mrg || !rtx_equal_p (operands[1], operands[5]))"
5992 1.1.1.3 mrg {
5993 1.1.1.3 mrg operands[4] = copy_rtx (operands[1]);
5994 1.1.1.3 mrg operands[5] = copy_rtx (operands[1]);
5995 1.1.1.3 mrg }
5996 1.1.1.3 mrg [(set_attr "movprfx" "*,yes")]
5997 1.1.1.3 mrg )
5998 1.1.1.3 mrg
5999 1.1.1.3 mrg (define_insn "*aarch64_cond_abd<mode>_3_strict"
6000 1.1.1.3 mrg [(set (match_operand:SVE_FULL_F 0 "register_operand" "=w, ?&w")
6001 1.1.1.3 mrg (unspec:SVE_FULL_F
6002 1.1.1.3 mrg [(match_operand:<VPRED> 1 "register_operand" "Upl, Upl")
6003 1.1.1.3 mrg (unspec:SVE_FULL_F
6004 1.1.1.3 mrg [(match_dup 1)
6005 1.1.1.3 mrg (match_operand:SI 4 "aarch64_sve_gp_strictness")
6006 1.1.1.3 mrg (unspec:SVE_FULL_F
6007 1.1.1.3 mrg [(match_dup 1)
6008 1.1.1.3 mrg (match_operand:SI 5 "aarch64_sve_gp_strictness")
6009 1.1.1.3 mrg (match_operand:SVE_FULL_F 2 "register_operand" "w, w")
6010 1.1.1.3 mrg (match_operand:SVE_FULL_F 3 "register_operand" "0, w")]
6011 1.1.1.3 mrg UNSPEC_COND_FSUB)]
6012 1.1.1.3 mrg UNSPEC_COND_FABS)
6013 1.1.1.3 mrg (match_dup 3)]
6014 1.1.1.3 mrg UNSPEC_SEL))]
6015 1.1.1.3 mrg "TARGET_SVE"
6016 1.1.1.3 mrg "@
6017 1.1.1.3 mrg fabd\t%0.<Vetype>, %1/m, %0.<Vetype>, %2.<Vetype>
6018 1.1.1.3 mrg movprfx\t%0, %3\;fabd\t%0.<Vetype>, %1/m, %0.<Vetype>, %2.<Vetype>"
6019 1.1.1.3 mrg [(set_attr "movprfx" "*,yes")]
6020 1.1.1.3 mrg )
6021 1.1.1.3 mrg
6022 1.1.1.3 mrg ;; Predicated floating-point absolute difference, merging with an
6023 1.1.1.3 mrg ;; independent value.
6024 1.1.1.3 mrg (define_insn_and_rewrite "*aarch64_cond_abd<mode>_any_relaxed"
6025 1.1.1.3 mrg [(set (match_operand:SVE_FULL_F 0 "register_operand" "=&w, &w, &w, &w, ?&w")
6026 1.1.1.3 mrg (unspec:SVE_FULL_F
6027 1.1.1.3 mrg [(match_operand:<VPRED> 1 "register_operand" "Upl, Upl, Upl, Upl, Upl")
6028 1.1.1.3 mrg (unspec:SVE_FULL_F
6029 1.1.1.3 mrg [(match_operand 5)
6030 1.1.1.3 mrg (const_int SVE_RELAXED_GP)
6031 1.1.1.3 mrg (unspec:SVE_FULL_F
6032 1.1.1.3 mrg [(match_operand 6)
6033 1.1.1.3 mrg (const_int SVE_RELAXED_GP)
6034 1.1.1.3 mrg (match_operand:SVE_FULL_F 2 "register_operand" "0, w, w, w, w")
6035 1.1.1.3 mrg (match_operand:SVE_FULL_F 3 "register_operand" "w, 0, w, w, w")]
6036 1.1.1.3 mrg UNSPEC_COND_FSUB)]
6037 1.1.1.3 mrg UNSPEC_COND_FABS)
6038 1.1.1.3 mrg (match_operand:SVE_FULL_F 4 "aarch64_simd_reg_or_zero" "Dz, Dz, Dz, 0, w")]
6039 1.1.1.3 mrg UNSPEC_SEL))]
6040 1.1.1.3 mrg "TARGET_SVE
6041 1.1.1.3 mrg && !rtx_equal_p (operands[2], operands[4])
6042 1.1.1.3 mrg && !rtx_equal_p (operands[3], operands[4])"
6043 1.1.1.3 mrg "@
6044 1.1.1.3 mrg movprfx\t%0.<Vetype>, %1/z, %0.<Vetype>\;fabd\t%0.<Vetype>, %1/m, %0.<Vetype>, %3.<Vetype>
6045 1.1.1.3 mrg movprfx\t%0.<Vetype>, %1/z, %0.<Vetype>\;fabd\t%0.<Vetype>, %1/m, %0.<Vetype>, %2.<Vetype>
6046 1.1.1.3 mrg movprfx\t%0.<Vetype>, %1/z, %2.<Vetype>\;fabd\t%0.<Vetype>, %1/m, %0.<Vetype>, %3.<Vetype>
6047 1.1.1.3 mrg movprfx\t%0.<Vetype>, %1/m, %2.<Vetype>\;fabd\t%0.<Vetype>, %1/m, %0.<Vetype>, %3.<Vetype>
6048 1.1.1.3 mrg #"
6049 1.1.1.3 mrg "&& 1"
6050 1.1.1.3 mrg {
6051 1.1.1.3 mrg if (reload_completed
6052 1.1.1.3 mrg && register_operand (operands[4], <MODE>mode)
6053 1.1.1.3 mrg && !rtx_equal_p (operands[0], operands[4]))
6054 1.1.1.3 mrg {
6055 1.1.1.3 mrg emit_insn (gen_vcond_mask_<mode><vpred> (operands[0], operands[3],
6056 1.1.1.3 mrg operands[4], operands[1]));
6057 1.1.1.3 mrg operands[4] = operands[3] = operands[0];
6058 1.1.1.3 mrg }
6059 1.1.1.3 mrg else if (!rtx_equal_p (operands[1], operands[5])
6060 1.1.1.3 mrg || !rtx_equal_p (operands[1], operands[6]))
6061 1.1.1.3 mrg {
6062 1.1.1.3 mrg operands[5] = copy_rtx (operands[1]);
6063 1.1.1.3 mrg operands[6] = copy_rtx (operands[1]);
6064 1.1.1.3 mrg }
6065 1.1.1.3 mrg else
6066 1.1.1.3 mrg FAIL;
6067 1.1.1.3 mrg }
6068 1.1.1.3 mrg [(set_attr "movprfx" "yes")]
6069 1.1.1.3 mrg )
6070 1.1.1.3 mrg
6071 1.1.1.3 mrg (define_insn_and_rewrite "*aarch64_cond_abd<mode>_any_strict"
6072 1.1.1.3 mrg [(set (match_operand:SVE_FULL_F 0 "register_operand" "=&w, &w, &w, &w, ?&w")
6073 1.1.1.3 mrg (unspec:SVE_FULL_F
6074 1.1.1.3 mrg [(match_operand:<VPRED> 1 "register_operand" "Upl, Upl, Upl, Upl, Upl")
6075 1.1.1.3 mrg (unspec:SVE_FULL_F
6076 1.1.1.3 mrg [(match_dup 1)
6077 1.1.1.3 mrg (match_operand:SI 5 "aarch64_sve_gp_strictness")
6078 1.1.1.3 mrg (unspec:SVE_FULL_F
6079 1.1.1.3 mrg [(match_dup 1)
6080 1.1.1.3 mrg (match_operand:SI 6 "aarch64_sve_gp_strictness")
6081 1.1.1.3 mrg (match_operand:SVE_FULL_F 2 "register_operand" "0, w, w, w, w")
6082 1.1.1.3 mrg (match_operand:SVE_FULL_F 3 "register_operand" "w, 0, w, w, w")]
6083 1.1.1.3 mrg UNSPEC_COND_FSUB)]
6084 1.1.1.3 mrg UNSPEC_COND_FABS)
6085 1.1.1.3 mrg (match_operand:SVE_FULL_F 4 "aarch64_simd_reg_or_zero" "Dz, Dz, Dz, 0, w")]
6086 1.1.1.3 mrg UNSPEC_SEL))]
6087 1.1.1.3 mrg "TARGET_SVE
6088 1.1.1.3 mrg && !rtx_equal_p (operands[2], operands[4])
6089 1.1.1.3 mrg && !rtx_equal_p (operands[3], operands[4])"
6090 1.1.1.3 mrg "@
6091 1.1.1.3 mrg movprfx\t%0.<Vetype>, %1/z, %0.<Vetype>\;fabd\t%0.<Vetype>, %1/m, %0.<Vetype>, %3.<Vetype>
6092 1.1.1.3 mrg movprfx\t%0.<Vetype>, %1/z, %0.<Vetype>\;fabd\t%0.<Vetype>, %1/m, %0.<Vetype>, %2.<Vetype>
6093 1.1.1.3 mrg movprfx\t%0.<Vetype>, %1/z, %2.<Vetype>\;fabd\t%0.<Vetype>, %1/m, %0.<Vetype>, %3.<Vetype>
6094 1.1.1.3 mrg movprfx\t%0.<Vetype>, %1/m, %2.<Vetype>\;fabd\t%0.<Vetype>, %1/m, %0.<Vetype>, %3.<Vetype>
6095 1.1.1.3 mrg #"
6096 1.1.1.3 mrg "&& reload_completed
6097 1.1.1.3 mrg && register_operand (operands[4], <MODE>mode)
6098 1.1.1.3 mrg && !rtx_equal_p (operands[0], operands[4])"
6099 1.1.1.3 mrg {
6100 1.1.1.3 mrg emit_insn (gen_vcond_mask_<mode><vpred> (operands[0], operands[3],
6101 1.1.1.3 mrg operands[4], operands[1]));
6102 1.1.1.3 mrg operands[4] = operands[3] = operands[0];
6103 1.1.1.3 mrg }
6104 1.1.1.3 mrg [(set_attr "movprfx" "yes")]
6105 1.1.1.3 mrg )
6106 1.1.1.3 mrg
6107 1.1.1.3 mrg ;; -------------------------------------------------------------------------
6108 1.1.1.3 mrg ;; ---- [FP] Multiplication
6109 1.1.1.3 mrg ;; -------------------------------------------------------------------------
6110 1.1.1.3 mrg ;; Includes:
6111 1.1.1.3 mrg ;; - FMUL
6112 1.1.1.3 mrg ;; -------------------------------------------------------------------------
6113 1.1.1.3 mrg
6114 1.1.1.3 mrg ;; Predicated floating-point multiplication.
6115 1.1.1.3 mrg (define_insn_and_split "@aarch64_pred_<optab><mode>"
6116 1.1.1.3 mrg [(set (match_operand:SVE_FULL_F 0 "register_operand" "=w, w, w, ?&w, ?&w")
6117 1.1.1.3 mrg (unspec:SVE_FULL_F
6118 1.1.1.3 mrg [(match_operand:<VPRED> 1 "register_operand" "Upl, Upl, Upl, Upl, Upl")
6119 1.1.1.3 mrg (match_operand:SI 4 "aarch64_sve_gp_strictness" "i, Z, Ui1, i, Ui1")
6120 1.1.1.3 mrg (match_operand:SVE_FULL_F 2 "register_operand" "%0, w, 0, w, w")
6121 1.1.1.3 mrg (match_operand:SVE_FULL_F 3 "aarch64_sve_float_mul_operand" "vsM, w, w, vsM, w")]
6122 1.1.1.3 mrg SVE_COND_FP_MUL))]
6123 1.1.1.3 mrg "TARGET_SVE"
6124 1.1.1.3 mrg "@
6125 1.1.1.3 mrg fmul\t%0.<Vetype>, %1/m, %0.<Vetype>, #%3
6126 1.1.1.3 mrg #
6127 1.1.1.3 mrg fmul\t%0.<Vetype>, %1/m, %0.<Vetype>, %3.<Vetype>
6128 1.1.1.3 mrg movprfx\t%0, %2\;fmul\t%0.<Vetype>, %1/m, %0.<Vetype>, #%3
6129 1.1.1.3 mrg movprfx\t%0, %2\;fmul\t%0.<Vetype>, %1/m, %0.<Vetype>, %3.<Vetype>"
6130 1.1.1.3 mrg ; Split the unpredicated form after reload, so that we don't have
6131 1.1.1.3 mrg ; the unnecessary PTRUE.
6132 1.1.1.3 mrg "&& reload_completed
6133 1.1.1.3 mrg && register_operand (operands[3], <MODE>mode)
6134 1.1.1.3 mrg && INTVAL (operands[4]) == SVE_RELAXED_GP"
6135 1.1.1.3 mrg [(set (match_dup 0) (mult:SVE_FULL_F (match_dup 2) (match_dup 3)))]
6136 1.1.1.3 mrg ""
6137 1.1.1.3 mrg [(set_attr "movprfx" "*,*,*,yes,yes")]
6138 1.1.1.3 mrg )
6139 1.1.1.3 mrg
6140 1.1.1.3 mrg ;; Merging forms are handled through SVE_COND_FP_BINARY and
6141 1.1.1.3 mrg ;; SVE_COND_FP_BINARY_I1.
6142 1.1.1.3 mrg
6143 1.1.1.3 mrg ;; Unpredicated multiplication by selected lanes.
6144 1.1.1.3 mrg (define_insn "@aarch64_mul_lane_<mode>"
6145 1.1.1.3 mrg [(set (match_operand:SVE_FULL_F 0 "register_operand" "=w")
6146 1.1.1.3 mrg (mult:SVE_FULL_F
6147 1.1.1.3 mrg (unspec:SVE_FULL_F
6148 1.1.1.3 mrg [(match_operand:SVE_FULL_F 2 "register_operand" "<sve_lane_con>")
6149 1.1.1.3 mrg (match_operand:SI 3 "const_int_operand")]
6150 1.1.1.3 mrg UNSPEC_SVE_LANE_SELECT)
6151 1.1.1.3 mrg (match_operand:SVE_FULL_F 1 "register_operand" "w")))]
6152 1.1.1.3 mrg "TARGET_SVE"
6153 1.1.1.3 mrg "fmul\t%0.<Vetype>, %1.<Vetype>, %2.<Vetype>[%3]"
6154 1.1.1.3 mrg )
6155 1.1.1.3 mrg
6156 1.1.1.3 mrg ;; -------------------------------------------------------------------------
6157 1.1.1.3 mrg ;; ---- [FP] Division
6158 1.1.1.3 mrg ;; -------------------------------------------------------------------------
6159 1.1.1.3 mrg ;; The patterns in this section are synthetic.
6160 1.1.1.3 mrg ;; -------------------------------------------------------------------------
6161 1.1.1.3 mrg
6162 1.1.1.3 mrg (define_expand "div<mode>3"
6163 1.1.1.3 mrg [(set (match_operand:SVE_FULL_F 0 "register_operand")
6164 1.1.1.3 mrg (unspec:SVE_FULL_F
6165 1.1.1.3 mrg [(match_dup 3)
6166 1.1.1.3 mrg (const_int SVE_RELAXED_GP)
6167 1.1.1.3 mrg (match_operand:SVE_FULL_F 1 "nonmemory_operand")
6168 1.1.1.3 mrg (match_operand:SVE_FULL_F 2 "register_operand")]
6169 1.1.1.3 mrg UNSPEC_COND_FDIV))]
6170 1.1.1.3 mrg "TARGET_SVE"
6171 1.1.1.3 mrg {
6172 1.1.1.3 mrg if (aarch64_emit_approx_div (operands[0], operands[1], operands[2]))
6173 1.1.1.3 mrg DONE;
6174 1.1.1.3 mrg
6175 1.1.1.3 mrg operands[1] = force_reg (<MODE>mode, operands[1]);
6176 1.1.1.3 mrg operands[3] = aarch64_ptrue_reg (<VPRED>mode);
6177 1.1.1.3 mrg }
6178 1.1.1.3 mrg )
6179 1.1.1.3 mrg
6180 1.1.1.3 mrg (define_expand "@aarch64_frecpe<mode>"
6181 1.1.1.3 mrg [(set (match_operand:SVE_FULL_F 0 "register_operand")
6182 1.1.1.3 mrg (unspec:SVE_FULL_F
6183 1.1.1.3 mrg [(match_operand:SVE_FULL_F 1 "register_operand")]
6184 1.1.1.3 mrg UNSPEC_FRECPE))]
6185 1.1.1.3 mrg "TARGET_SVE"
6186 1.1.1.3 mrg )
6187 1.1.1.3 mrg
6188 1.1.1.3 mrg (define_expand "@aarch64_frecps<mode>"
6189 1.1.1.3 mrg [(set (match_operand:SVE_FULL_F 0 "register_operand")
6190 1.1.1.3 mrg (unspec:SVE_FULL_F
6191 1.1.1.3 mrg [(match_operand:SVE_FULL_F 1 "register_operand")
6192 1.1.1.3 mrg (match_operand:SVE_FULL_F 2 "register_operand")]
6193 1.1.1.3 mrg UNSPEC_FRECPS))]
6194 1.1.1.3 mrg "TARGET_SVE"
6195 1.1.1.3 mrg )
6196 1.1.1.3 mrg
6197 1.1.1.3 mrg ;; -------------------------------------------------------------------------
6198 1.1.1.3 mrg ;; ---- [FP] Binary logical operations
6199 1.1.1.3 mrg ;; -------------------------------------------------------------------------
6200 1.1.1.3 mrg ;; Includes
6201 1.1.1.3 mrg ;; - AND
6202 1.1.1.3 mrg ;; - EOR
6203 1.1.1.3 mrg ;; - ORR
6204 1.1.1.3 mrg ;; -------------------------------------------------------------------------
6205 1.1.1.3 mrg
6206 1.1.1.3 mrg ;; Binary logical operations on floating-point modes. We avoid subregs
6207 1.1.1.3 mrg ;; by providing this, but we need to use UNSPECs since rtx logical ops
6208 1.1.1.3 mrg ;; aren't defined for floating-point modes.
6209 1.1.1.3 mrg (define_insn "*<optab><mode>3"
6210 1.1.1.3 mrg [(set (match_operand:SVE_FULL_F 0 "register_operand" "=w")
6211 1.1.1.3 mrg (unspec:SVE_FULL_F
6212 1.1.1.3 mrg [(match_operand:SVE_FULL_F 1 "register_operand" "w")
6213 1.1.1.3 mrg (match_operand:SVE_FULL_F 2 "register_operand" "w")]
6214 1.1.1.3 mrg LOGICALF))]
6215 1.1.1.3 mrg "TARGET_SVE"
6216 1.1.1.3 mrg "<logicalf_op>\t%0.d, %1.d, %2.d"
6217 1.1.1.3 mrg )
6218 1.1.1.3 mrg
6219 1.1.1.3 mrg ;; -------------------------------------------------------------------------
6220 1.1.1.3 mrg ;; ---- [FP] Sign copying
6221 1.1.1.3 mrg ;; -------------------------------------------------------------------------
6222 1.1.1.3 mrg ;; The patterns in this section are synthetic.
6223 1.1.1.3 mrg ;; -------------------------------------------------------------------------
6224 1.1.1.3 mrg
6225 1.1.1.3 mrg (define_expand "copysign<mode>3"
6226 1.1.1.3 mrg [(match_operand:SVE_FULL_F 0 "register_operand")
6227 1.1.1.3 mrg (match_operand:SVE_FULL_F 1 "register_operand")
6228 1.1.1.3 mrg (match_operand:SVE_FULL_F 2 "register_operand")]
6229 1.1.1.3 mrg "TARGET_SVE"
6230 1.1.1.3 mrg {
6231 1.1.1.3 mrg rtx sign = gen_reg_rtx (<V_INT_EQUIV>mode);
6232 1.1.1.3 mrg rtx mant = gen_reg_rtx (<V_INT_EQUIV>mode);
6233 1.1.1.3 mrg rtx int_res = gen_reg_rtx (<V_INT_EQUIV>mode);
6234 1.1.1.3 mrg int bits = GET_MODE_UNIT_BITSIZE (<MODE>mode) - 1;
6235 1.1.1.3 mrg
6236 1.1.1.3 mrg rtx arg1 = lowpart_subreg (<V_INT_EQUIV>mode, operands[1], <MODE>mode);
6237 1.1.1.3 mrg rtx arg2 = lowpart_subreg (<V_INT_EQUIV>mode, operands[2], <MODE>mode);
6238 1.1.1.3 mrg
6239 1.1.1.3 mrg emit_insn (gen_and<v_int_equiv>3
6240 1.1.1.3 mrg (sign, arg2,
6241 1.1.1.3 mrg aarch64_simd_gen_const_vector_dup (<V_INT_EQUIV>mode,
6242 1.1.1.3 mrg HOST_WIDE_INT_M1U
6243 1.1.1.3 mrg << bits)));
6244 1.1.1.3 mrg emit_insn (gen_and<v_int_equiv>3
6245 1.1.1.3 mrg (mant, arg1,
6246 1.1.1.3 mrg aarch64_simd_gen_const_vector_dup (<V_INT_EQUIV>mode,
6247 1.1.1.3 mrg ~(HOST_WIDE_INT_M1U
6248 1.1.1.3 mrg << bits))));
6249 1.1.1.3 mrg emit_insn (gen_ior<v_int_equiv>3 (int_res, sign, mant));
6250 1.1.1.3 mrg emit_move_insn (operands[0], gen_lowpart (<MODE>mode, int_res));
6251 1.1.1.3 mrg DONE;
6252 1.1.1.3 mrg }
6253 1.1.1.3 mrg )
6254 1.1.1.3 mrg
6255 1.1.1.3 mrg (define_expand "xorsign<mode>3"
6256 1.1.1.3 mrg [(match_operand:SVE_FULL_F 0 "register_operand")
6257 1.1.1.3 mrg (match_operand:SVE_FULL_F 1 "register_operand")
6258 1.1.1.3 mrg (match_operand:SVE_FULL_F 2 "register_operand")]
6259 1.1.1.3 mrg "TARGET_SVE"
6260 1.1.1.3 mrg {
6261 1.1.1.3 mrg rtx sign = gen_reg_rtx (<V_INT_EQUIV>mode);
6262 1.1.1.3 mrg rtx int_res = gen_reg_rtx (<V_INT_EQUIV>mode);
6263 1.1.1.3 mrg int bits = GET_MODE_UNIT_BITSIZE (<MODE>mode) - 1;
6264 1.1.1.3 mrg
6265 1.1.1.3 mrg rtx arg1 = lowpart_subreg (<V_INT_EQUIV>mode, operands[1], <MODE>mode);
6266 1.1.1.3 mrg rtx arg2 = lowpart_subreg (<V_INT_EQUIV>mode, operands[2], <MODE>mode);
6267 1.1.1.3 mrg
6268 1.1.1.3 mrg emit_insn (gen_and<v_int_equiv>3
6269 1.1.1.3 mrg (sign, arg2,
6270 1.1.1.3 mrg aarch64_simd_gen_const_vector_dup (<V_INT_EQUIV>mode,
6271 1.1.1.3 mrg HOST_WIDE_INT_M1U
6272 1.1.1.3 mrg << bits)));
6273 1.1.1.3 mrg emit_insn (gen_xor<v_int_equiv>3 (int_res, arg1, sign));
6274 1.1.1.3 mrg emit_move_insn (operands[0], gen_lowpart (<MODE>mode, int_res));
6275 1.1.1.3 mrg DONE;
6276 1.1.1.3 mrg }
6277 1.1.1.3 mrg )
6278 1.1.1.3 mrg
6279 1.1.1.3 mrg ;; -------------------------------------------------------------------------
6280 1.1.1.3 mrg ;; ---- [FP] Maximum and minimum
6281 1.1.1.3 mrg ;; -------------------------------------------------------------------------
6282 1.1.1.3 mrg ;; Includes:
6283 1.1.1.3 mrg ;; - FMAX
6284 1.1.1.3 mrg ;; - FMAXNM
6285 1.1.1.3 mrg ;; - FMIN
6286 1.1.1.3 mrg ;; - FMINNM
6287 1.1.1.3 mrg ;; -------------------------------------------------------------------------
6288 1.1.1.3 mrg
6289 1.1.1.3 mrg ;; Unpredicated fmax/fmin (the libm functions). The optabs for the
6290 1.1.1.5 mrg ;; smax/smin rtx codes are handled in the generic section above.
6291 1.1.1.5 mrg (define_expand "<fmaxmin><mode>3"
6292 1.1.1.3 mrg [(set (match_operand:SVE_FULL_F 0 "register_operand")
6293 1.1.1.3 mrg (unspec:SVE_FULL_F
6294 1.1.1.3 mrg [(match_dup 3)
6295 1.1.1.3 mrg (const_int SVE_RELAXED_GP)
6296 1.1.1.3 mrg (match_operand:SVE_FULL_F 1 "register_operand")
6297 1.1.1.3 mrg (match_operand:SVE_FULL_F 2 "aarch64_sve_float_maxmin_operand")]
6298 1.1.1.3 mrg SVE_COND_FP_MAXMIN_PUBLIC))]
6299 1.1.1.3 mrg "TARGET_SVE"
6300 1.1.1.3 mrg {
6301 1.1.1.3 mrg operands[3] = aarch64_ptrue_reg (<VPRED>mode);
6302 1.1.1.3 mrg }
6303 1.1.1.3 mrg )
6304 1.1.1.3 mrg
6305 1.1.1.5 mrg ;; Predicated fmax/fmin (the libm functions). The optabs for the
6306 1.1.1.5 mrg ;; smax/smin rtx codes are handled in the generic section above.
6307 1.1.1.5 mrg (define_expand "cond_<fmaxmin><mode>"
6308 1.1.1.5 mrg [(set (match_operand:SVE_FULL_F 0 "register_operand")
6309 1.1.1.5 mrg (unspec:SVE_FULL_F
6310 1.1.1.5 mrg [(match_operand:<VPRED> 1 "register_operand")
6311 1.1.1.5 mrg (unspec:SVE_FULL_F
6312 1.1.1.5 mrg [(match_dup 1)
6313 1.1.1.5 mrg (const_int SVE_RELAXED_GP)
6314 1.1.1.5 mrg (match_operand:SVE_FULL_F 2 "register_operand")
6315 1.1.1.5 mrg (match_operand:SVE_FULL_F 3 "aarch64_sve_float_maxmin_operand")]
6316 1.1.1.5 mrg SVE_COND_FP_MAXMIN_PUBLIC)
6317 1.1.1.5 mrg (match_operand:SVE_FULL_F 4 "aarch64_simd_reg_or_zero")]
6318 1.1.1.5 mrg UNSPEC_SEL))]
6319 1.1.1.5 mrg "TARGET_SVE"
6320 1.1.1.5 mrg )
6321 1.1.1.5 mrg
6322 1.1.1.3 mrg ;; Predicated floating-point maximum/minimum.
6323 1.1.1.3 mrg (define_insn "@aarch64_pred_<optab><mode>"
6324 1.1.1.3 mrg [(set (match_operand:SVE_FULL_F 0 "register_operand" "=w, w, ?&w, ?&w")
6325 1.1.1.3 mrg (unspec:SVE_FULL_F
6326 1.1.1.3 mrg [(match_operand:<VPRED> 1 "register_operand" "Upl, Upl, Upl, Upl")
6327 1.1.1.3 mrg (match_operand:SI 4 "aarch64_sve_gp_strictness")
6328 1.1.1.3 mrg (match_operand:SVE_FULL_F 2 "register_operand" "%0, 0, w, w")
6329 1.1.1.3 mrg (match_operand:SVE_FULL_F 3 "aarch64_sve_float_maxmin_operand" "vsB, w, vsB, w")]
6330 1.1.1.3 mrg SVE_COND_FP_MAXMIN))]
6331 1.1.1.3 mrg "TARGET_SVE"
6332 1.1.1.3 mrg "@
6333 1.1.1.3 mrg <sve_fp_op>\t%0.<Vetype>, %1/m, %0.<Vetype>, #%3
6334 1.1.1.3 mrg <sve_fp_op>\t%0.<Vetype>, %1/m, %0.<Vetype>, %3.<Vetype>
6335 1.1.1.3 mrg movprfx\t%0, %2\;<sve_fp_op>\t%0.<Vetype>, %1/m, %0.<Vetype>, #%3
6336 1.1.1.3 mrg movprfx\t%0, %2\;<sve_fp_op>\t%0.<Vetype>, %1/m, %0.<Vetype>, %3.<Vetype>"
6337 1.1.1.3 mrg [(set_attr "movprfx" "*,*,yes,yes")]
6338 1.1.1.3 mrg )
6339 1.1.1.3 mrg
6340 1.1.1.3 mrg ;; Merging forms are handled through SVE_COND_FP_BINARY and
6341 1.1.1.3 mrg ;; SVE_COND_FP_BINARY_I1.
6342 1.1.1.3 mrg
6343 1.1.1.3 mrg ;; -------------------------------------------------------------------------
6344 1.1.1.3 mrg ;; ---- [PRED] Binary logical operations
6345 1.1.1.3 mrg ;; -------------------------------------------------------------------------
6346 1.1.1.3 mrg ;; Includes:
6347 1.1.1.3 mrg ;; - AND
6348 1.1.1.3 mrg ;; - ANDS
6349 1.1.1.3 mrg ;; - EOR
6350 1.1.1.3 mrg ;; - EORS
6351 1.1.1.3 mrg ;; - ORR
6352 1.1.1.3 mrg ;; - ORRS
6353 1.1.1.3 mrg ;; -------------------------------------------------------------------------
6354 1.1.1.3 mrg
6355 1.1.1.3 mrg ;; Predicate AND. We can reuse one of the inputs as the GP.
6356 1.1.1.3 mrg ;; Doubling the second operand is the preferred implementation
6357 1.1.1.3 mrg ;; of the MOV alias, so we use that instead of %1/z, %1, %2.
6358 1.1.1.3 mrg (define_insn "and<mode>3"
6359 1.1.1.3 mrg [(set (match_operand:PRED_ALL 0 "register_operand" "=Upa")
6360 1.1.1.3 mrg (and:PRED_ALL (match_operand:PRED_ALL 1 "register_operand" "Upa")
6361 1.1.1.3 mrg (match_operand:PRED_ALL 2 "register_operand" "Upa")))]
6362 1.1.1.3 mrg "TARGET_SVE"
6363 1.1.1.3 mrg "and\t%0.b, %1/z, %2.b, %2.b"
6364 1.1.1.3 mrg )
6365 1.1.1.3 mrg
6366 1.1.1.3 mrg ;; Unpredicated predicate EOR and ORR.
6367 1.1.1.3 mrg (define_expand "<optab><mode>3"
6368 1.1.1.3 mrg [(set (match_operand:PRED_ALL 0 "register_operand")
6369 1.1.1.3 mrg (and:PRED_ALL
6370 1.1.1.3 mrg (LOGICAL_OR:PRED_ALL
6371 1.1.1.3 mrg (match_operand:PRED_ALL 1 "register_operand")
6372 1.1.1.3 mrg (match_operand:PRED_ALL 2 "register_operand"))
6373 1.1.1.3 mrg (match_dup 3)))]
6374 1.1.1.3 mrg "TARGET_SVE"
6375 1.1.1.3 mrg {
6376 1.1.1.3 mrg operands[3] = aarch64_ptrue_reg (<MODE>mode);
6377 1.1.1.3 mrg }
6378 1.1.1.3 mrg )
6379 1.1.1.3 mrg
6380 1.1.1.3 mrg ;; Predicated predicate AND, EOR and ORR.
6381 1.1.1.3 mrg (define_insn "@aarch64_pred_<optab><mode>_z"
6382 1.1.1.3 mrg [(set (match_operand:PRED_ALL 0 "register_operand" "=Upa")
6383 1.1.1.3 mrg (and:PRED_ALL
6384 1.1.1.3 mrg (LOGICAL:PRED_ALL
6385 1.1.1.3 mrg (match_operand:PRED_ALL 2 "register_operand" "Upa")
6386 1.1.1.3 mrg (match_operand:PRED_ALL 3 "register_operand" "Upa"))
6387 1.1.1.3 mrg (match_operand:PRED_ALL 1 "register_operand" "Upa")))]
6388 1.1.1.3 mrg "TARGET_SVE"
6389 1.1.1.3 mrg "<logical>\t%0.b, %1/z, %2.b, %3.b"
6390 1.1.1.3 mrg )
6391 1.1.1.3 mrg
6392 1.1.1.3 mrg ;; Perform a logical operation on operands 2 and 3, using operand 1 as
6393 1.1.1.3 mrg ;; the GP. Store the result in operand 0 and set the flags in the same
6394 1.1.1.3 mrg ;; way as for PTEST.
6395 1.1.1.3 mrg (define_insn "*<optab><mode>3_cc"
6396 1.1.1.3 mrg [(set (reg:CC_NZC CC_REGNUM)
6397 1.1.1.3 mrg (unspec:CC_NZC
6398 1.1.1.3 mrg [(match_operand:VNx16BI 1 "register_operand" "Upa")
6399 1.1.1.3 mrg (match_operand 4)
6400 1.1.1.3 mrg (match_operand:SI 5 "aarch64_sve_ptrue_flag")
6401 1.1.1.3 mrg (and:PRED_ALL
6402 1.1.1.3 mrg (LOGICAL:PRED_ALL
6403 1.1.1.3 mrg (match_operand:PRED_ALL 2 "register_operand" "Upa")
6404 1.1.1.3 mrg (match_operand:PRED_ALL 3 "register_operand" "Upa"))
6405 1.1.1.3 mrg (match_dup 4))]
6406 1.1.1.3 mrg UNSPEC_PTEST))
6407 1.1.1.3 mrg (set (match_operand:PRED_ALL 0 "register_operand" "=Upa")
6408 1.1.1.3 mrg (and:PRED_ALL (LOGICAL:PRED_ALL (match_dup 2) (match_dup 3))
6409 1.1.1.3 mrg (match_dup 4)))]
6410 1.1.1.3 mrg "TARGET_SVE"
6411 1.1.1.3 mrg "<logical>s\t%0.b, %1/z, %2.b, %3.b"
6412 1.1.1.3 mrg )
6413 1.1.1.3 mrg
6414 1.1.1.3 mrg ;; Same with just the flags result.
6415 1.1.1.3 mrg (define_insn "*<optab><mode>3_ptest"
6416 1.1.1.3 mrg [(set (reg:CC_NZC CC_REGNUM)
6417 1.1.1.3 mrg (unspec:CC_NZC
6418 1.1.1.3 mrg [(match_operand:VNx16BI 1 "register_operand" "Upa")
6419 1.1.1.3 mrg (match_operand 4)
6420 1.1.1.3 mrg (match_operand:SI 5 "aarch64_sve_ptrue_flag")
6421 1.1.1.3 mrg (and:PRED_ALL
6422 1.1.1.3 mrg (LOGICAL:PRED_ALL
6423 1.1.1.3 mrg (match_operand:PRED_ALL 2 "register_operand" "Upa")
6424 1.1.1.3 mrg (match_operand:PRED_ALL 3 "register_operand" "Upa"))
6425 1.1.1.3 mrg (match_dup 4))]
6426 1.1.1.3 mrg UNSPEC_PTEST))
6427 1.1.1.3 mrg (clobber (match_scratch:VNx16BI 0 "=Upa"))]
6428 1.1.1.3 mrg "TARGET_SVE"
6429 1.1.1.3 mrg "<logical>s\t%0.b, %1/z, %2.b, %3.b"
6430 1.1.1.3 mrg )
6431 1.1.1.3 mrg
6432 1.1.1.3 mrg ;; -------------------------------------------------------------------------
6433 1.1.1.3 mrg ;; ---- [PRED] Binary logical operations (inverted second input)
6434 1.1.1.3 mrg ;; -------------------------------------------------------------------------
6435 1.1.1.3 mrg ;; Includes:
6436 1.1.1.3 mrg ;; - BIC
6437 1.1.1.3 mrg ;; - ORN
6438 1.1.1.3 mrg ;; -------------------------------------------------------------------------
6439 1.1.1.3 mrg
6440 1.1.1.3 mrg ;; Predicated predicate BIC and ORN.
6441 1.1.1.3 mrg (define_insn "aarch64_pred_<nlogical><mode>_z"
6442 1.1.1.3 mrg [(set (match_operand:PRED_ALL 0 "register_operand" "=Upa")
6443 1.1.1.3 mrg (and:PRED_ALL
6444 1.1.1.3 mrg (NLOGICAL:PRED_ALL
6445 1.1.1.3 mrg (not:PRED_ALL (match_operand:PRED_ALL 3 "register_operand" "Upa"))
6446 1.1.1.3 mrg (match_operand:PRED_ALL 2 "register_operand" "Upa"))
6447 1.1.1.3 mrg (match_operand:PRED_ALL 1 "register_operand" "Upa")))]
6448 1.1.1.3 mrg "TARGET_SVE"
6449 1.1.1.3 mrg "<nlogical>\t%0.b, %1/z, %2.b, %3.b"
6450 1.1.1.3 mrg )
6451 1.1.1.3 mrg
6452 1.1.1.3 mrg ;; Same, but set the flags as a side-effect.
6453 1.1.1.3 mrg (define_insn "*<nlogical><mode>3_cc"
6454 1.1.1.3 mrg [(set (reg:CC_NZC CC_REGNUM)
6455 1.1.1.3 mrg (unspec:CC_NZC
6456 1.1.1.3 mrg [(match_operand:VNx16BI 1 "register_operand" "Upa")
6457 1.1.1.3 mrg (match_operand 4)
6458 1.1.1.3 mrg (match_operand:SI 5 "aarch64_sve_ptrue_flag")
6459 1.1.1.3 mrg (and:PRED_ALL
6460 1.1.1.3 mrg (NLOGICAL:PRED_ALL
6461 1.1.1.3 mrg (not:PRED_ALL
6462 1.1.1.3 mrg (match_operand:PRED_ALL 3 "register_operand" "Upa"))
6463 1.1.1.3 mrg (match_operand:PRED_ALL 2 "register_operand" "Upa"))
6464 1.1.1.3 mrg (match_dup 4))]
6465 1.1.1.3 mrg UNSPEC_PTEST))
6466 1.1.1.3 mrg (set (match_operand:PRED_ALL 0 "register_operand" "=Upa")
6467 1.1.1.3 mrg (and:PRED_ALL (NLOGICAL:PRED_ALL
6468 1.1.1.3 mrg (not:PRED_ALL (match_dup 3))
6469 1.1.1.3 mrg (match_dup 2))
6470 1.1.1.3 mrg (match_dup 4)))]
6471 1.1.1.3 mrg "TARGET_SVE"
6472 1.1.1.3 mrg "<nlogical>s\t%0.b, %1/z, %2.b, %3.b"
6473 1.1.1.3 mrg )
6474 1.1.1.3 mrg
6475 1.1.1.3 mrg ;; Same with just the flags result.
6476 1.1.1.3 mrg (define_insn "*<nlogical><mode>3_ptest"
6477 1.1.1.3 mrg [(set (reg:CC_NZC CC_REGNUM)
6478 1.1.1.3 mrg (unspec:CC_NZC
6479 1.1.1.3 mrg [(match_operand:VNx16BI 1 "register_operand" "Upa")
6480 1.1.1.3 mrg (match_operand 4)
6481 1.1.1.3 mrg (match_operand:SI 5 "aarch64_sve_ptrue_flag")
6482 1.1.1.3 mrg (and:PRED_ALL
6483 1.1.1.3 mrg (NLOGICAL:PRED_ALL
6484 1.1.1.3 mrg (not:PRED_ALL
6485 1.1.1.3 mrg (match_operand:PRED_ALL 3 "register_operand" "Upa"))
6486 1.1.1.3 mrg (match_operand:PRED_ALL 2 "register_operand" "Upa"))
6487 1.1.1.3 mrg (match_dup 4))]
6488 1.1.1.3 mrg UNSPEC_PTEST))
6489 1.1.1.3 mrg (clobber (match_scratch:VNx16BI 0 "=Upa"))]
6490 1.1.1.3 mrg "TARGET_SVE"
6491 1.1.1.3 mrg "<nlogical>s\t%0.b, %1/z, %2.b, %3.b"
6492 1.1.1.3 mrg )
6493 1.1.1.3 mrg
6494 1.1.1.3 mrg ;; -------------------------------------------------------------------------
6495 1.1.1.3 mrg ;; ---- [PRED] Binary logical operations (inverted result)
6496 1.1.1.3 mrg ;; -------------------------------------------------------------------------
6497 1.1.1.3 mrg ;; Includes:
6498 1.1.1.3 mrg ;; - NAND
6499 1.1.1.3 mrg ;; - NOR
6500 1.1.1.3 mrg ;; -------------------------------------------------------------------------
6501 1.1.1.3 mrg
6502 1.1.1.3 mrg ;; Predicated predicate NAND and NOR.
6503 1.1.1.3 mrg (define_insn "aarch64_pred_<logical_nn><mode>_z"
6504 1.1.1.3 mrg [(set (match_operand:PRED_ALL 0 "register_operand" "=Upa")
6505 1.1.1.3 mrg (and:PRED_ALL
6506 1.1.1.3 mrg (NLOGICAL:PRED_ALL
6507 1.1.1.3 mrg (not:PRED_ALL (match_operand:PRED_ALL 2 "register_operand" "Upa"))
6508 1.1.1.3 mrg (not:PRED_ALL (match_operand:PRED_ALL 3 "register_operand" "Upa")))
6509 1.1.1.3 mrg (match_operand:PRED_ALL 1 "register_operand" "Upa")))]
6510 1.1.1.3 mrg "TARGET_SVE"
6511 1.1.1.3 mrg "<logical_nn>\t%0.b, %1/z, %2.b, %3.b"
6512 1.1.1.3 mrg )
6513 1.1.1.3 mrg
6514 1.1.1.3 mrg ;; Same, but set the flags as a side-effect.
6515 1.1.1.3 mrg (define_insn "*<logical_nn><mode>3_cc"
6516 1.1.1.3 mrg [(set (reg:CC_NZC CC_REGNUM)
6517 1.1.1.3 mrg (unspec:CC_NZC
6518 1.1.1.3 mrg [(match_operand:VNx16BI 1 "register_operand" "Upa")
6519 1.1.1.3 mrg (match_operand 4)
6520 1.1.1.3 mrg (match_operand:SI 5 "aarch64_sve_ptrue_flag")
6521 1.1.1.3 mrg (and:PRED_ALL
6522 1.1.1.3 mrg (NLOGICAL:PRED_ALL
6523 1.1.1.3 mrg (not:PRED_ALL
6524 1.1.1.3 mrg (match_operand:PRED_ALL 2 "register_operand" "Upa"))
6525 1.1.1.3 mrg (not:PRED_ALL
6526 1.1.1.3 mrg (match_operand:PRED_ALL 3 "register_operand" "Upa")))
6527 1.1.1.3 mrg (match_dup 4))]
6528 1.1.1.3 mrg UNSPEC_PTEST))
6529 1.1.1.3 mrg (set (match_operand:PRED_ALL 0 "register_operand" "=Upa")
6530 1.1.1.3 mrg (and:PRED_ALL (NLOGICAL:PRED_ALL
6531 1.1.1.3 mrg (not:PRED_ALL (match_dup 2))
6532 1.1.1.3 mrg (not:PRED_ALL (match_dup 3)))
6533 1.1.1.3 mrg (match_dup 4)))]
6534 1.1.1.3 mrg "TARGET_SVE"
6535 1.1.1.3 mrg "<logical_nn>s\t%0.b, %1/z, %2.b, %3.b"
6536 1.1.1.3 mrg )
6537 1.1.1.3 mrg
6538 1.1.1.3 mrg ;; Same with just the flags result.
6539 1.1.1.3 mrg (define_insn "*<logical_nn><mode>3_ptest"
6540 1.1.1.3 mrg [(set (reg:CC_NZC CC_REGNUM)
6541 1.1.1.3 mrg (unspec:CC_NZC
6542 1.1.1.3 mrg [(match_operand:VNx16BI 1 "register_operand" "Upa")
6543 1.1.1.3 mrg (match_operand 4)
6544 1.1.1.3 mrg (match_operand:SI 5 "aarch64_sve_ptrue_flag")
6545 1.1.1.3 mrg (and:PRED_ALL
6546 1.1.1.3 mrg (NLOGICAL:PRED_ALL
6547 1.1.1.3 mrg (not:PRED_ALL
6548 1.1.1.3 mrg (match_operand:PRED_ALL 2 "register_operand" "Upa"))
6549 1.1.1.3 mrg (not:PRED_ALL
6550 1.1.1.3 mrg (match_operand:PRED_ALL 3 "register_operand" "Upa")))
6551 1.1.1.3 mrg (match_dup 4))]
6552 1.1.1.3 mrg UNSPEC_PTEST))
6553 1.1.1.3 mrg (clobber (match_scratch:VNx16BI 0 "=Upa"))]
6554 1.1.1.3 mrg "TARGET_SVE"
6555 1.1.1.3 mrg "<logical_nn>s\t%0.b, %1/z, %2.b, %3.b"
6556 1.1.1.3 mrg )
6557 1.1.1.3 mrg
6558 1.1.1.3 mrg ;; =========================================================================
6559 1.1.1.3 mrg ;; == Ternary arithmetic
6560 1.1.1.3 mrg ;; =========================================================================
6561 1.1.1.3 mrg
6562 1.1.1.3 mrg ;; -------------------------------------------------------------------------
6563 1.1.1.3 mrg ;; ---- [INT] MLA and MAD
6564 1.1.1.3 mrg ;; -------------------------------------------------------------------------
6565 1.1.1.3 mrg ;; Includes:
6566 1.1.1.3 mrg ;; - MAD
6567 1.1.1.3 mrg ;; - MLA
6568 1.1.1.3 mrg ;; -------------------------------------------------------------------------
6569 1.1.1.3 mrg
6570 1.1.1.3 mrg ;; Unpredicated integer addition of product.
6571 1.1.1.3 mrg (define_expand "fma<mode>4"
6572 1.1.1.5 mrg [(set (match_operand:SVE_I 0 "register_operand")
6573 1.1.1.5 mrg (plus:SVE_I
6574 1.1.1.5 mrg (unspec:SVE_I
6575 1.1.1.3 mrg [(match_dup 4)
6576 1.1.1.5 mrg (mult:SVE_I
6577 1.1.1.5 mrg (match_operand:SVE_I 1 "register_operand")
6578 1.1.1.5 mrg (match_operand:SVE_I 2 "nonmemory_operand"))]
6579 1.1.1.3 mrg UNSPEC_PRED_X)
6580 1.1.1.5 mrg (match_operand:SVE_I 3 "register_operand")))]
6581 1.1.1.3 mrg "TARGET_SVE"
6582 1.1.1.3 mrg {
6583 1.1.1.3 mrg if (aarch64_prepare_sve_int_fma (operands, PLUS))
6584 1.1.1.3 mrg DONE;
6585 1.1.1.3 mrg operands[4] = aarch64_ptrue_reg (<VPRED>mode);
6586 1.1.1.3 mrg }
6587 1.1.1.3 mrg )
6588 1.1.1.3 mrg
6589 1.1.1.3 mrg ;; Predicated integer addition of product.
6590 1.1.1.3 mrg (define_insn "@aarch64_pred_fma<mode>"
6591 1.1.1.5 mrg [(set (match_operand:SVE_I 0 "register_operand" "=w, w, ?&w")
6592 1.1.1.5 mrg (plus:SVE_I
6593 1.1.1.5 mrg (unspec:SVE_I
6594 1.1.1.3 mrg [(match_operand:<VPRED> 1 "register_operand" "Upl, Upl, Upl")
6595 1.1.1.5 mrg (mult:SVE_I
6596 1.1.1.5 mrg (match_operand:SVE_I 2 "register_operand" "%0, w, w")
6597 1.1.1.5 mrg (match_operand:SVE_I 3 "register_operand" "w, w, w"))]
6598 1.1.1.3 mrg UNSPEC_PRED_X)
6599 1.1.1.5 mrg (match_operand:SVE_I 4 "register_operand" "w, 0, w")))]
6600 1.1.1.3 mrg "TARGET_SVE"
6601 1.1.1.3 mrg "@
6602 1.1.1.3 mrg mad\t%0.<Vetype>, %1/m, %3.<Vetype>, %4.<Vetype>
6603 1.1.1.3 mrg mla\t%0.<Vetype>, %1/m, %2.<Vetype>, %3.<Vetype>
6604 1.1.1.3 mrg movprfx\t%0, %4\;mla\t%0.<Vetype>, %1/m, %2.<Vetype>, %3.<Vetype>"
6605 1.1.1.3 mrg [(set_attr "movprfx" "*,*,yes")]
6606 1.1.1.3 mrg )
6607 1.1.1.3 mrg
6608 1.1.1.3 mrg ;; Predicated integer addition of product with merging.
6609 1.1.1.3 mrg (define_expand "cond_fma<mode>"
6610 1.1.1.5 mrg [(set (match_operand:SVE_I 0 "register_operand")
6611 1.1.1.5 mrg (unspec:SVE_I
6612 1.1.1.3 mrg [(match_operand:<VPRED> 1 "register_operand")
6613 1.1.1.5 mrg (plus:SVE_I
6614 1.1.1.5 mrg (mult:SVE_I
6615 1.1.1.5 mrg (match_operand:SVE_I 2 "register_operand")
6616 1.1.1.5 mrg (match_operand:SVE_I 3 "general_operand"))
6617 1.1.1.5 mrg (match_operand:SVE_I 4 "register_operand"))
6618 1.1.1.5 mrg (match_operand:SVE_I 5 "aarch64_simd_reg_or_zero")]
6619 1.1.1.3 mrg UNSPEC_SEL))]
6620 1.1 mrg "TARGET_SVE"
6621 1.1 mrg {
6622 1.1.1.3 mrg if (aarch64_prepare_sve_cond_int_fma (operands, PLUS))
6623 1.1.1.3 mrg DONE;
6624 1.1.1.3 mrg /* Swap the multiplication operands if the fallback value is the
6625 1.1.1.3 mrg second of the two. */
6626 1.1.1.3 mrg if (rtx_equal_p (operands[3], operands[5]))
6627 1.1.1.3 mrg std::swap (operands[2], operands[3]);
6628 1.1 mrg }
6629 1.1 mrg )
6630 1.1 mrg
6631 1.1.1.3 mrg ;; Predicated integer addition of product, merging with the first input.
6632 1.1.1.3 mrg (define_insn "*cond_fma<mode>_2"
6633 1.1.1.5 mrg [(set (match_operand:SVE_I 0 "register_operand" "=w, ?&w")
6634 1.1.1.5 mrg (unspec:SVE_I
6635 1.1.1.3 mrg [(match_operand:<VPRED> 1 "register_operand" "Upl, Upl")
6636 1.1.1.5 mrg (plus:SVE_I
6637 1.1.1.5 mrg (mult:SVE_I
6638 1.1.1.5 mrg (match_operand:SVE_I 2 "register_operand" "0, w")
6639 1.1.1.5 mrg (match_operand:SVE_I 3 "register_operand" "w, w"))
6640 1.1.1.5 mrg (match_operand:SVE_I 4 "register_operand" "w, w"))
6641 1.1.1.3 mrg (match_dup 2)]
6642 1.1.1.3 mrg UNSPEC_SEL))]
6643 1.1 mrg "TARGET_SVE"
6644 1.1 mrg "@
6645 1.1.1.3 mrg mad\t%0.<Vetype>, %1/m, %3.<Vetype>, %4.<Vetype>
6646 1.1.1.3 mrg movprfx\t%0, %2\;mad\t%0.<Vetype>, %1/m, %3.<Vetype>, %4.<Vetype>"
6647 1.1.1.3 mrg [(set_attr "movprfx" "*,yes")]
6648 1.1.1.3 mrg )
6649 1.1.1.3 mrg
6650 1.1.1.3 mrg ;; Predicated integer addition of product, merging with the third input.
6651 1.1.1.3 mrg (define_insn "*cond_fma<mode>_4"
6652 1.1.1.5 mrg [(set (match_operand:SVE_I 0 "register_operand" "=w, ?&w")
6653 1.1.1.5 mrg (unspec:SVE_I
6654 1.1.1.3 mrg [(match_operand:<VPRED> 1 "register_operand" "Upl, Upl")
6655 1.1.1.5 mrg (plus:SVE_I
6656 1.1.1.5 mrg (mult:SVE_I
6657 1.1.1.5 mrg (match_operand:SVE_I 2 "register_operand" "w, w")
6658 1.1.1.5 mrg (match_operand:SVE_I 3 "register_operand" "w, w"))
6659 1.1.1.5 mrg (match_operand:SVE_I 4 "register_operand" "0, w"))
6660 1.1.1.3 mrg (match_dup 4)]
6661 1.1.1.3 mrg UNSPEC_SEL))]
6662 1.1.1.3 mrg "TARGET_SVE"
6663 1.1.1.3 mrg "@
6664 1.1.1.3 mrg mla\t%0.<Vetype>, %1/m, %2.<Vetype>, %3.<Vetype>
6665 1.1.1.3 mrg movprfx\t%0, %4\;mla\t%0.<Vetype>, %1/m, %2.<Vetype>, %3.<Vetype>"
6666 1.1.1.3 mrg [(set_attr "movprfx" "*,yes")]
6667 1.1.1.3 mrg )
6668 1.1.1.3 mrg
6669 1.1.1.3 mrg ;; Predicated integer addition of product, merging with an independent value.
6670 1.1.1.3 mrg (define_insn_and_rewrite "*cond_fma<mode>_any"
6671 1.1.1.5 mrg [(set (match_operand:SVE_I 0 "register_operand" "=&w, &w, &w, &w, &w, ?&w")
6672 1.1.1.5 mrg (unspec:SVE_I
6673 1.1.1.3 mrg [(match_operand:<VPRED> 1 "register_operand" "Upl, Upl, Upl, Upl, Upl, Upl")
6674 1.1.1.5 mrg (plus:SVE_I
6675 1.1.1.5 mrg (mult:SVE_I
6676 1.1.1.5 mrg (match_operand:SVE_I 2 "register_operand" "w, w, 0, w, w, w")
6677 1.1.1.5 mrg (match_operand:SVE_I 3 "register_operand" "w, w, w, 0, w, w"))
6678 1.1.1.5 mrg (match_operand:SVE_I 4 "register_operand" "w, 0, w, w, w, w"))
6679 1.1.1.5 mrg (match_operand:SVE_I 5 "aarch64_simd_reg_or_zero" "Dz, Dz, Dz, Dz, 0, w")]
6680 1.1.1.3 mrg UNSPEC_SEL))]
6681 1.1.1.3 mrg "TARGET_SVE
6682 1.1.1.3 mrg && !rtx_equal_p (operands[2], operands[5])
6683 1.1.1.3 mrg && !rtx_equal_p (operands[3], operands[5])
6684 1.1.1.3 mrg && !rtx_equal_p (operands[4], operands[5])"
6685 1.1.1.3 mrg "@
6686 1.1.1.3 mrg movprfx\t%0.<Vetype>, %1/z, %4.<Vetype>\;mla\t%0.<Vetype>, %1/m, %2.<Vetype>, %3.<Vetype>
6687 1.1.1.3 mrg movprfx\t%0.<Vetype>, %1/z, %0.<Vetype>\;mla\t%0.<Vetype>, %1/m, %2.<Vetype>, %3.<Vetype>
6688 1.1.1.3 mrg movprfx\t%0.<Vetype>, %1/z, %0.<Vetype>\;mad\t%0.<Vetype>, %1/m, %3.<Vetype>, %4.<Vetype>
6689 1.1.1.3 mrg movprfx\t%0.<Vetype>, %1/z, %0.<Vetype>\;mad\t%0.<Vetype>, %1/m, %2.<Vetype>, %4.<Vetype>
6690 1.1.1.3 mrg movprfx\t%0.<Vetype>, %1/m, %4.<Vetype>\;mla\t%0.<Vetype>, %1/m, %2.<Vetype>, %3.<Vetype>
6691 1.1.1.3 mrg #"
6692 1.1.1.2 mrg "&& reload_completed
6693 1.1.1.3 mrg && register_operand (operands[5], <MODE>mode)
6694 1.1.1.3 mrg && !rtx_equal_p (operands[0], operands[5])"
6695 1.1.1.3 mrg {
6696 1.1.1.3 mrg emit_insn (gen_vcond_mask_<mode><vpred> (operands[0], operands[4],
6697 1.1.1.3 mrg operands[5], operands[1]));
6698 1.1.1.3 mrg operands[5] = operands[4] = operands[0];
6699 1.1.1.3 mrg }
6700 1.1.1.3 mrg [(set_attr "movprfx" "yes")]
6701 1.1.1.3 mrg )
6702 1.1.1.3 mrg
6703 1.1.1.3 mrg ;; -------------------------------------------------------------------------
6704 1.1.1.3 mrg ;; ---- [INT] MLS and MSB
6705 1.1.1.3 mrg ;; -------------------------------------------------------------------------
6706 1.1.1.3 mrg ;; Includes:
6707 1.1.1.3 mrg ;; - MLS
6708 1.1.1.3 mrg ;; - MSB
6709 1.1.1.3 mrg ;; -------------------------------------------------------------------------
6710 1.1.1.3 mrg
6711 1.1.1.3 mrg ;; Unpredicated integer subtraction of product.
6712 1.1.1.3 mrg (define_expand "fnma<mode>4"
6713 1.1.1.5 mrg [(set (match_operand:SVE_I 0 "register_operand")
6714 1.1.1.5 mrg (minus:SVE_I
6715 1.1.1.5 mrg (match_operand:SVE_I 3 "register_operand")
6716 1.1.1.5 mrg (unspec:SVE_I
6717 1.1.1.3 mrg [(match_dup 4)
6718 1.1.1.5 mrg (mult:SVE_I
6719 1.1.1.5 mrg (match_operand:SVE_I 1 "register_operand")
6720 1.1.1.5 mrg (match_operand:SVE_I 2 "general_operand"))]
6721 1.1.1.3 mrg UNSPEC_PRED_X)))]
6722 1.1.1.3 mrg "TARGET_SVE"
6723 1.1.1.3 mrg {
6724 1.1.1.3 mrg if (aarch64_prepare_sve_int_fma (operands, MINUS))
6725 1.1.1.3 mrg DONE;
6726 1.1.1.3 mrg operands[4] = aarch64_ptrue_reg (<VPRED>mode);
6727 1.1.1.3 mrg }
6728 1.1.1.3 mrg )
6729 1.1.1.3 mrg
6730 1.1.1.3 mrg ;; Predicated integer subtraction of product.
6731 1.1.1.3 mrg (define_insn "@aarch64_pred_fnma<mode>"
6732 1.1.1.5 mrg [(set (match_operand:SVE_I 0 "register_operand" "=w, w, ?&w")
6733 1.1.1.5 mrg (minus:SVE_I
6734 1.1.1.5 mrg (match_operand:SVE_I 4 "register_operand" "w, 0, w")
6735 1.1.1.5 mrg (unspec:SVE_I
6736 1.1.1.3 mrg [(match_operand:<VPRED> 1 "register_operand" "Upl, Upl, Upl")
6737 1.1.1.5 mrg (mult:SVE_I
6738 1.1.1.5 mrg (match_operand:SVE_I 2 "register_operand" "%0, w, w")
6739 1.1.1.5 mrg (match_operand:SVE_I 3 "register_operand" "w, w, w"))]
6740 1.1.1.3 mrg UNSPEC_PRED_X)))]
6741 1.1.1.3 mrg "TARGET_SVE"
6742 1.1.1.3 mrg "@
6743 1.1.1.3 mrg msb\t%0.<Vetype>, %1/m, %3.<Vetype>, %4.<Vetype>
6744 1.1.1.3 mrg mls\t%0.<Vetype>, %1/m, %2.<Vetype>, %3.<Vetype>
6745 1.1.1.3 mrg movprfx\t%0, %4\;mls\t%0.<Vetype>, %1/m, %2.<Vetype>, %3.<Vetype>"
6746 1.1.1.2 mrg [(set_attr "movprfx" "*,*,yes")]
6747 1.1.1.2 mrg )
6748 1.1.1.2 mrg
6749 1.1.1.3 mrg ;; Predicated integer subtraction of product with merging.
6750 1.1.1.3 mrg (define_expand "cond_fnma<mode>"
6751 1.1.1.5 mrg [(set (match_operand:SVE_I 0 "register_operand")
6752 1.1.1.5 mrg (unspec:SVE_I
6753 1.1.1.3 mrg [(match_operand:<VPRED> 1 "register_operand")
6754 1.1.1.5 mrg (minus:SVE_I
6755 1.1.1.5 mrg (match_operand:SVE_I 4 "register_operand")
6756 1.1.1.5 mrg (mult:SVE_I
6757 1.1.1.5 mrg (match_operand:SVE_I 2 "register_operand")
6758 1.1.1.5 mrg (match_operand:SVE_I 3 "general_operand")))
6759 1.1.1.5 mrg (match_operand:SVE_I 5 "aarch64_simd_reg_or_zero")]
6760 1.1.1.3 mrg UNSPEC_SEL))]
6761 1.1.1.3 mrg "TARGET_SVE"
6762 1.1.1.3 mrg {
6763 1.1.1.3 mrg if (aarch64_prepare_sve_cond_int_fma (operands, MINUS))
6764 1.1.1.3 mrg DONE;
6765 1.1.1.3 mrg /* Swap the multiplication operands if the fallback value is the
6766 1.1.1.3 mrg second of the two. */
6767 1.1.1.3 mrg if (rtx_equal_p (operands[3], operands[5]))
6768 1.1.1.3 mrg std::swap (operands[2], operands[3]);
6769 1.1.1.3 mrg }
6770 1.1 mrg )
6771 1.1 mrg
6772 1.1.1.3 mrg ;; Predicated integer subtraction of product, merging with the first input.
6773 1.1.1.3 mrg (define_insn "*cond_fnma<mode>_2"
6774 1.1.1.5 mrg [(set (match_operand:SVE_I 0 "register_operand" "=w, ?&w")
6775 1.1.1.5 mrg (unspec:SVE_I
6776 1.1.1.3 mrg [(match_operand:<VPRED> 1 "register_operand" "Upl, Upl")
6777 1.1.1.5 mrg (minus:SVE_I
6778 1.1.1.5 mrg (match_operand:SVE_I 4 "register_operand" "w, w")
6779 1.1.1.5 mrg (mult:SVE_I
6780 1.1.1.5 mrg (match_operand:SVE_I 2 "register_operand" "0, w")
6781 1.1.1.5 mrg (match_operand:SVE_I 3 "register_operand" "w, w")))
6782 1.1.1.3 mrg (match_dup 2)]
6783 1.1.1.3 mrg UNSPEC_SEL))]
6784 1.1.1.3 mrg "TARGET_SVE"
6785 1.1.1.3 mrg "@
6786 1.1.1.3 mrg msb\t%0.<Vetype>, %1/m, %3.<Vetype>, %4.<Vetype>
6787 1.1.1.3 mrg movprfx\t%0, %2\;msb\t%0.<Vetype>, %1/m, %3.<Vetype>, %4.<Vetype>"
6788 1.1.1.3 mrg [(set_attr "movprfx" "*,yes")]
6789 1.1.1.3 mrg )
6790 1.1.1.3 mrg
6791 1.1.1.3 mrg ;; Predicated integer subtraction of product, merging with the third input.
6792 1.1.1.3 mrg (define_insn "*cond_fnma<mode>_4"
6793 1.1.1.5 mrg [(set (match_operand:SVE_I 0 "register_operand" "=w, ?&w")
6794 1.1.1.5 mrg (unspec:SVE_I
6795 1.1.1.3 mrg [(match_operand:<VPRED> 1 "register_operand" "Upl, Upl")
6796 1.1.1.5 mrg (minus:SVE_I
6797 1.1.1.5 mrg (match_operand:SVE_I 4 "register_operand" "0, w")
6798 1.1.1.5 mrg (mult:SVE_I
6799 1.1.1.5 mrg (match_operand:SVE_I 2 "register_operand" "w, w")
6800 1.1.1.5 mrg (match_operand:SVE_I 3 "register_operand" "w, w")))
6801 1.1.1.3 mrg (match_dup 4)]
6802 1.1.1.3 mrg UNSPEC_SEL))]
6803 1.1 mrg "TARGET_SVE"
6804 1.1.1.3 mrg "@
6805 1.1.1.3 mrg mls\t%0.<Vetype>, %1/m, %2.<Vetype>, %3.<Vetype>
6806 1.1.1.3 mrg movprfx\t%0, %4\;mls\t%0.<Vetype>, %1/m, %2.<Vetype>, %3.<Vetype>"
6807 1.1.1.3 mrg [(set_attr "movprfx" "*,yes")]
6808 1.1.1.3 mrg )
6809 1.1.1.3 mrg
6810 1.1.1.3 mrg ;; Predicated integer subtraction of product, merging with an
6811 1.1.1.3 mrg ;; independent value.
6812 1.1.1.3 mrg (define_insn_and_rewrite "*cond_fnma<mode>_any"
6813 1.1.1.5 mrg [(set (match_operand:SVE_I 0 "register_operand" "=&w, &w, &w, &w, &w, ?&w")
6814 1.1.1.5 mrg (unspec:SVE_I
6815 1.1.1.3 mrg [(match_operand:<VPRED> 1 "register_operand" "Upl, Upl, Upl, Upl, Upl, Upl")
6816 1.1.1.5 mrg (minus:SVE_I
6817 1.1.1.5 mrg (match_operand:SVE_I 4 "register_operand" "w, 0, w, w, w, w")
6818 1.1.1.5 mrg (mult:SVE_I
6819 1.1.1.5 mrg (match_operand:SVE_I 2 "register_operand" "w, w, 0, w, w, w")
6820 1.1.1.5 mrg (match_operand:SVE_I 3 "register_operand" "w, w, w, 0, w, w")))
6821 1.1.1.5 mrg (match_operand:SVE_I 5 "aarch64_simd_reg_or_zero" "Dz, Dz, Dz, Dz, 0, w")]
6822 1.1.1.3 mrg UNSPEC_SEL))]
6823 1.1.1.3 mrg "TARGET_SVE
6824 1.1.1.3 mrg && !rtx_equal_p (operands[2], operands[5])
6825 1.1.1.3 mrg && !rtx_equal_p (operands[3], operands[5])
6826 1.1.1.3 mrg && !rtx_equal_p (operands[4], operands[5])"
6827 1.1.1.3 mrg "@
6828 1.1.1.3 mrg movprfx\t%0.<Vetype>, %1/z, %4.<Vetype>\;mls\t%0.<Vetype>, %1/m, %2.<Vetype>, %3.<Vetype>
6829 1.1.1.3 mrg movprfx\t%0.<Vetype>, %1/z, %0.<Vetype>\;mls\t%0.<Vetype>, %1/m, %2.<Vetype>, %3.<Vetype>
6830 1.1.1.3 mrg movprfx\t%0.<Vetype>, %1/z, %0.<Vetype>\;msb\t%0.<Vetype>, %1/m, %3.<Vetype>, %4.<Vetype>
6831 1.1.1.3 mrg movprfx\t%0.<Vetype>, %1/z, %0.<Vetype>\;msb\t%0.<Vetype>, %1/m, %2.<Vetype>, %4.<Vetype>
6832 1.1.1.3 mrg movprfx\t%0.<Vetype>, %1/m, %4.<Vetype>\;mls\t%0.<Vetype>, %1/m, %2.<Vetype>, %3.<Vetype>
6833 1.1.1.3 mrg #"
6834 1.1.1.3 mrg "&& reload_completed
6835 1.1.1.3 mrg && register_operand (operands[5], <MODE>mode)
6836 1.1.1.3 mrg && !rtx_equal_p (operands[0], operands[5])"
6837 1.1 mrg {
6838 1.1.1.3 mrg emit_insn (gen_vcond_mask_<mode><vpred> (operands[0], operands[4],
6839 1.1.1.3 mrg operands[5], operands[1]));
6840 1.1.1.3 mrg operands[5] = operands[4] = operands[0];
6841 1.1.1.3 mrg }
6842 1.1.1.3 mrg [(set_attr "movprfx" "yes")]
6843 1.1.1.3 mrg )
6844 1.1.1.3 mrg
6845 1.1.1.3 mrg ;; -------------------------------------------------------------------------
6846 1.1.1.3 mrg ;; ---- [INT] Dot product
6847 1.1.1.3 mrg ;; -------------------------------------------------------------------------
6848 1.1.1.3 mrg ;; Includes:
6849 1.1.1.3 mrg ;; - SDOT
6850 1.1.1.3 mrg ;; - SUDOT (I8MM)
6851 1.1.1.3 mrg ;; - UDOT
6852 1.1.1.3 mrg ;; - USDOT (I8MM)
6853 1.1.1.3 mrg ;; -------------------------------------------------------------------------
6854 1.1.1.3 mrg
6855 1.1.1.3 mrg ;; Four-element integer dot-product with accumulation.
6856 1.1.1.3 mrg (define_insn "<sur>dot_prod<vsi2qi>"
6857 1.1.1.3 mrg [(set (match_operand:SVE_FULL_SDI 0 "register_operand" "=w, ?&w")
6858 1.1.1.3 mrg (plus:SVE_FULL_SDI
6859 1.1.1.3 mrg (unspec:SVE_FULL_SDI
6860 1.1.1.3 mrg [(match_operand:<VSI2QI> 1 "register_operand" "w, w")
6861 1.1.1.3 mrg (match_operand:<VSI2QI> 2 "register_operand" "w, w")]
6862 1.1.1.3 mrg DOTPROD)
6863 1.1.1.3 mrg (match_operand:SVE_FULL_SDI 3 "register_operand" "0, w")))]
6864 1.1.1.3 mrg "TARGET_SVE"
6865 1.1.1.3 mrg "@
6866 1.1.1.3 mrg <sur>dot\\t%0.<Vetype>, %1.<Vetype_fourth>, %2.<Vetype_fourth>
6867 1.1.1.3 mrg movprfx\t%0, %3\;<sur>dot\\t%0.<Vetype>, %1.<Vetype_fourth>, %2.<Vetype_fourth>"
6868 1.1.1.3 mrg [(set_attr "movprfx" "*,yes")]
6869 1.1.1.3 mrg )
6870 1.1.1.3 mrg
6871 1.1.1.3 mrg ;; Four-element integer dot-product by selected lanes with accumulation.
6872 1.1.1.3 mrg (define_insn "@aarch64_<sur>dot_prod_lane<vsi2qi>"
6873 1.1.1.3 mrg [(set (match_operand:SVE_FULL_SDI 0 "register_operand" "=w, ?&w")
6874 1.1.1.3 mrg (plus:SVE_FULL_SDI
6875 1.1.1.3 mrg (unspec:SVE_FULL_SDI
6876 1.1.1.3 mrg [(match_operand:<VSI2QI> 1 "register_operand" "w, w")
6877 1.1.1.3 mrg (unspec:<VSI2QI>
6878 1.1.1.3 mrg [(match_operand:<VSI2QI> 2 "register_operand" "<sve_lane_con>, <sve_lane_con>")
6879 1.1.1.3 mrg (match_operand:SI 3 "const_int_operand")]
6880 1.1.1.3 mrg UNSPEC_SVE_LANE_SELECT)]
6881 1.1.1.3 mrg DOTPROD)
6882 1.1.1.3 mrg (match_operand:SVE_FULL_SDI 4 "register_operand" "0, w")))]
6883 1.1.1.3 mrg "TARGET_SVE"
6884 1.1.1.3 mrg "@
6885 1.1.1.3 mrg <sur>dot\\t%0.<Vetype>, %1.<Vetype_fourth>, %2.<Vetype_fourth>[%3]
6886 1.1.1.3 mrg movprfx\t%0, %4\;<sur>dot\\t%0.<Vetype>, %1.<Vetype_fourth>, %2.<Vetype_fourth>[%3]"
6887 1.1.1.3 mrg [(set_attr "movprfx" "*,yes")]
6888 1.1.1.3 mrg )
6889 1.1.1.3 mrg
6890 1.1.1.5 mrg (define_insn "@<sur>dot_prod<vsi2qi>"
6891 1.1.1.3 mrg [(set (match_operand:VNx4SI_ONLY 0 "register_operand" "=w, ?&w")
6892 1.1.1.3 mrg (plus:VNx4SI_ONLY
6893 1.1.1.3 mrg (unspec:VNx4SI_ONLY
6894 1.1.1.3 mrg [(match_operand:<VSI2QI> 1 "register_operand" "w, w")
6895 1.1.1.3 mrg (match_operand:<VSI2QI> 2 "register_operand" "w, w")]
6896 1.1.1.3 mrg DOTPROD_US_ONLY)
6897 1.1.1.3 mrg (match_operand:VNx4SI_ONLY 3 "register_operand" "0, w")))]
6898 1.1.1.3 mrg "TARGET_SVE_I8MM"
6899 1.1.1.3 mrg "@
6900 1.1.1.3 mrg <sur>dot\\t%0.s, %1.b, %2.b
6901 1.1.1.3 mrg movprfx\t%0, %3\;<sur>dot\\t%0.s, %1.b, %2.b"
6902 1.1.1.3 mrg [(set_attr "movprfx" "*,yes")]
6903 1.1.1.3 mrg )
6904 1.1.1.3 mrg
6905 1.1.1.3 mrg (define_insn "@aarch64_<sur>dot_prod_lane<vsi2qi>"
6906 1.1.1.3 mrg [(set (match_operand:VNx4SI_ONLY 0 "register_operand" "=w, ?&w")
6907 1.1.1.3 mrg (plus:VNx4SI_ONLY
6908 1.1.1.3 mrg (unspec:VNx4SI_ONLY
6909 1.1.1.3 mrg [(match_operand:<VSI2QI> 1 "register_operand" "w, w")
6910 1.1.1.3 mrg (unspec:<VSI2QI>
6911 1.1.1.3 mrg [(match_operand:<VSI2QI> 2 "register_operand" "y, y")
6912 1.1.1.3 mrg (match_operand:SI 3 "const_int_operand")]
6913 1.1.1.3 mrg UNSPEC_SVE_LANE_SELECT)]
6914 1.1.1.3 mrg DOTPROD_I8MM)
6915 1.1.1.3 mrg (match_operand:VNx4SI_ONLY 4 "register_operand" "0, w")))]
6916 1.1.1.3 mrg "TARGET_SVE_I8MM"
6917 1.1.1.3 mrg "@
6918 1.1.1.3 mrg <sur>dot\\t%0.s, %1.b, %2.b[%3]
6919 1.1.1.3 mrg movprfx\t%0, %4\;<sur>dot\\t%0.s, %1.b, %2.b[%3]"
6920 1.1.1.3 mrg [(set_attr "movprfx" "*,yes")]
6921 1.1.1.3 mrg )
6922 1.1.1.3 mrg
6923 1.1.1.3 mrg ;; -------------------------------------------------------------------------
6924 1.1.1.3 mrg ;; ---- [INT] Sum of absolute differences
6925 1.1.1.3 mrg ;; -------------------------------------------------------------------------
6926 1.1.1.3 mrg ;; The patterns in this section are synthetic.
6927 1.1.1.3 mrg ;; -------------------------------------------------------------------------
6928 1.1.1.3 mrg
6929 1.1.1.3 mrg ;; Emit a sequence to produce a sum-of-absolute-differences of the inputs in
6930 1.1.1.3 mrg ;; operands 1 and 2. The sequence also has to perform a widening reduction of
6931 1.1.1.3 mrg ;; the difference into a vector and accumulate that into operand 3 before
6932 1.1.1.3 mrg ;; copying that into the result operand 0.
6933 1.1.1.3 mrg ;; Perform that with a sequence of:
6934 1.1.1.3 mrg ;; MOV ones.b, #1
6935 1.1.1.3 mrg ;; [SU]ABD diff.b, p0/m, op1.b, op2.b
6936 1.1.1.3 mrg ;; MOVPRFX op0, op3 // If necessary
6937 1.1.1.3 mrg ;; UDOT op0.s, diff.b, ones.b
6938 1.1.1.3 mrg (define_expand "<sur>sad<vsi2qi>"
6939 1.1.1.3 mrg [(use (match_operand:SVE_FULL_SDI 0 "register_operand"))
6940 1.1.1.3 mrg (unspec:<VSI2QI> [(use (match_operand:<VSI2QI> 1 "register_operand"))
6941 1.1.1.3 mrg (use (match_operand:<VSI2QI> 2 "register_operand"))] ABAL)
6942 1.1.1.3 mrg (use (match_operand:SVE_FULL_SDI 3 "register_operand"))]
6943 1.1.1.3 mrg "TARGET_SVE"
6944 1.1.1.3 mrg {
6945 1.1.1.3 mrg rtx ones = force_reg (<VSI2QI>mode, CONST1_RTX (<VSI2QI>mode));
6946 1.1.1.3 mrg rtx diff = gen_reg_rtx (<VSI2QI>mode);
6947 1.1.1.3 mrg emit_insn (gen_<sur>abd<vsi2qi>_3 (diff, operands[1], operands[2]));
6948 1.1.1.3 mrg emit_insn (gen_udot_prod<vsi2qi> (operands[0], diff, ones, operands[3]));
6949 1.1 mrg DONE;
6950 1.1 mrg }
6951 1.1 mrg )
6952 1.1 mrg
6953 1.1.1.3 mrg ;; -------------------------------------------------------------------------
6954 1.1.1.3 mrg ;; ---- [INT] Matrix multiply-accumulate
6955 1.1.1.3 mrg ;; -------------------------------------------------------------------------
6956 1.1.1.3 mrg ;; Includes:
6957 1.1.1.3 mrg ;; - SMMLA (I8MM)
6958 1.1.1.3 mrg ;; - UMMLA (I8MM)
6959 1.1.1.3 mrg ;; - USMMLA (I8MM)
6960 1.1.1.3 mrg ;; -------------------------------------------------------------------------
6961 1.1.1.3 mrg
6962 1.1.1.3 mrg (define_insn "@aarch64_sve_add_<optab><vsi2qi>"
6963 1.1.1.3 mrg [(set (match_operand:VNx4SI_ONLY 0 "register_operand" "=w, ?&w")
6964 1.1.1.3 mrg (plus:VNx4SI_ONLY
6965 1.1.1.3 mrg (unspec:VNx4SI_ONLY
6966 1.1.1.3 mrg [(match_operand:<VSI2QI> 2 "register_operand" "w, w")
6967 1.1.1.3 mrg (match_operand:<VSI2QI> 3 "register_operand" "w, w")]
6968 1.1.1.3 mrg MATMUL)
6969 1.1.1.3 mrg (match_operand:VNx4SI_ONLY 1 "register_operand" "0, w")))]
6970 1.1.1.3 mrg "TARGET_SVE_I8MM"
6971 1.1.1.3 mrg "@
6972 1.1.1.3 mrg <sur>mmla\\t%0.s, %2.b, %3.b
6973 1.1.1.3 mrg movprfx\t%0, %1\;<sur>mmla\\t%0.s, %2.b, %3.b"
6974 1.1.1.3 mrg [(set_attr "movprfx" "*,yes")]
6975 1.1.1.3 mrg )
6976 1.1.1.3 mrg
6977 1.1.1.3 mrg ;; -------------------------------------------------------------------------
6978 1.1.1.3 mrg ;; ---- [FP] General ternary arithmetic corresponding to unspecs
6979 1.1.1.3 mrg ;; -------------------------------------------------------------------------
6980 1.1.1.3 mrg ;; Includes merging patterns for:
6981 1.1.1.3 mrg ;; - FMAD
6982 1.1.1.3 mrg ;; - FMLA
6983 1.1.1.3 mrg ;; - FMLS
6984 1.1.1.3 mrg ;; - FMSB
6985 1.1.1.3 mrg ;; - FNMAD
6986 1.1.1.3 mrg ;; - FNMLA
6987 1.1.1.3 mrg ;; - FNMLS
6988 1.1.1.3 mrg ;; - FNMSB
6989 1.1.1.3 mrg ;; -------------------------------------------------------------------------
6990 1.1.1.3 mrg
6991 1.1.1.3 mrg ;; Unpredicated floating-point ternary operations.
6992 1.1.1.3 mrg (define_expand "<optab><mode>4"
6993 1.1.1.3 mrg [(set (match_operand:SVE_FULL_F 0 "register_operand")
6994 1.1.1.3 mrg (unspec:SVE_FULL_F
6995 1.1.1.3 mrg [(match_dup 4)
6996 1.1.1.3 mrg (const_int SVE_RELAXED_GP)
6997 1.1.1.3 mrg (match_operand:SVE_FULL_F 1 "register_operand")
6998 1.1.1.3 mrg (match_operand:SVE_FULL_F 2 "register_operand")
6999 1.1.1.3 mrg (match_operand:SVE_FULL_F 3 "register_operand")]
7000 1.1.1.3 mrg SVE_COND_FP_TERNARY))]
7001 1.1 mrg "TARGET_SVE"
7002 1.1.1.3 mrg {
7003 1.1.1.3 mrg operands[4] = aarch64_ptrue_reg (<VPRED>mode);
7004 1.1.1.3 mrg }
7005 1.1 mrg )
7006 1.1 mrg
7007 1.1.1.3 mrg ;; Predicated floating-point ternary operations.
7008 1.1.1.3 mrg (define_insn "@aarch64_pred_<optab><mode>"
7009 1.1.1.3 mrg [(set (match_operand:SVE_FULL_F 0 "register_operand" "=w, w, ?&w")
7010 1.1.1.3 mrg (unspec:SVE_FULL_F
7011 1.1.1.3 mrg [(match_operand:<VPRED> 1 "register_operand" "Upl, Upl, Upl")
7012 1.1.1.3 mrg (match_operand:SI 5 "aarch64_sve_gp_strictness")
7013 1.1.1.3 mrg (match_operand:SVE_FULL_F 2 "register_operand" "%w, 0, w")
7014 1.1.1.3 mrg (match_operand:SVE_FULL_F 3 "register_operand" "w, w, w")
7015 1.1.1.3 mrg (match_operand:SVE_FULL_F 4 "register_operand" "0, w, w")]
7016 1.1.1.3 mrg SVE_COND_FP_TERNARY))]
7017 1.1 mrg "TARGET_SVE"
7018 1.1.1.3 mrg "@
7019 1.1.1.3 mrg <sve_fmla_op>\t%0.<Vetype>, %1/m, %2.<Vetype>, %3.<Vetype>
7020 1.1.1.3 mrg <sve_fmad_op>\t%0.<Vetype>, %1/m, %3.<Vetype>, %4.<Vetype>
7021 1.1.1.3 mrg movprfx\t%0, %4\;<sve_fmla_op>\t%0.<Vetype>, %1/m, %2.<Vetype>, %3.<Vetype>"
7022 1.1.1.3 mrg [(set_attr "movprfx" "*,*,yes")]
7023 1.1.1.3 mrg )
7024 1.1.1.3 mrg
7025 1.1.1.3 mrg ;; Predicated floating-point ternary operations with merging.
7026 1.1.1.3 mrg (define_expand "@cond_<optab><mode>"
7027 1.1.1.3 mrg [(set (match_operand:SVE_FULL_F 0 "register_operand")
7028 1.1.1.3 mrg (unspec:SVE_FULL_F
7029 1.1.1.3 mrg [(match_operand:<VPRED> 1 "register_operand")
7030 1.1.1.3 mrg (unspec:SVE_FULL_F
7031 1.1.1.3 mrg [(match_dup 1)
7032 1.1.1.3 mrg (const_int SVE_STRICT_GP)
7033 1.1.1.3 mrg (match_operand:SVE_FULL_F 2 "register_operand")
7034 1.1.1.3 mrg (match_operand:SVE_FULL_F 3 "register_operand")
7035 1.1.1.3 mrg (match_operand:SVE_FULL_F 4 "register_operand")]
7036 1.1.1.3 mrg SVE_COND_FP_TERNARY)
7037 1.1.1.3 mrg (match_operand:SVE_FULL_F 5 "aarch64_simd_reg_or_zero")]
7038 1.1.1.3 mrg UNSPEC_SEL))]
7039 1.1.1.3 mrg "TARGET_SVE"
7040 1.1.1.3 mrg {
7041 1.1.1.3 mrg /* Swap the multiplication operands if the fallback value is the
7042 1.1.1.3 mrg second of the two. */
7043 1.1.1.3 mrg if (rtx_equal_p (operands[3], operands[5]))
7044 1.1.1.3 mrg std::swap (operands[2], operands[3]);
7045 1.1.1.3 mrg })
7046 1.1.1.3 mrg
7047 1.1.1.3 mrg ;; Predicated floating-point ternary operations, merging with the
7048 1.1.1.3 mrg ;; first input.
7049 1.1.1.3 mrg (define_insn_and_rewrite "*cond_<optab><mode>_2_relaxed"
7050 1.1.1.3 mrg [(set (match_operand:SVE_FULL_F 0 "register_operand" "=w, ?&w")
7051 1.1.1.3 mrg (unspec:SVE_FULL_F
7052 1.1.1.3 mrg [(match_operand:<VPRED> 1 "register_operand" "Upl, Upl")
7053 1.1.1.3 mrg (unspec:SVE_FULL_F
7054 1.1.1.3 mrg [(match_operand 5)
7055 1.1.1.3 mrg (const_int SVE_RELAXED_GP)
7056 1.1.1.3 mrg (match_operand:SVE_FULL_F 2 "register_operand" "0, w")
7057 1.1.1.3 mrg (match_operand:SVE_FULL_F 3 "register_operand" "w, w")
7058 1.1.1.3 mrg (match_operand:SVE_FULL_F 4 "register_operand" "w, w")]
7059 1.1.1.3 mrg SVE_COND_FP_TERNARY)
7060 1.1.1.3 mrg (match_dup 2)]
7061 1.1.1.3 mrg UNSPEC_SEL))]
7062 1.1.1.3 mrg "TARGET_SVE"
7063 1.1.1.3 mrg "@
7064 1.1.1.3 mrg <sve_fmad_op>\t%0.<Vetype>, %1/m, %3.<Vetype>, %4.<Vetype>
7065 1.1.1.3 mrg movprfx\t%0, %2\;<sve_fmad_op>\t%0.<Vetype>, %1/m, %3.<Vetype>, %4.<Vetype>"
7066 1.1.1.3 mrg "&& !rtx_equal_p (operands[1], operands[5])"
7067 1.1 mrg {
7068 1.1.1.3 mrg operands[5] = copy_rtx (operands[1]);
7069 1.1 mrg }
7070 1.1.1.3 mrg [(set_attr "movprfx" "*,yes")]
7071 1.1 mrg )
7072 1.1 mrg
7073 1.1.1.3 mrg (define_insn "*cond_<optab><mode>_2_strict"
7074 1.1.1.3 mrg [(set (match_operand:SVE_FULL_F 0 "register_operand" "=w, ?&w")
7075 1.1.1.3 mrg (unspec:SVE_FULL_F
7076 1.1 mrg [(match_operand:<VPRED> 1 "register_operand" "Upl, Upl")
7077 1.1.1.3 mrg (unspec:SVE_FULL_F
7078 1.1.1.3 mrg [(match_dup 1)
7079 1.1.1.3 mrg (const_int SVE_STRICT_GP)
7080 1.1.1.3 mrg (match_operand:SVE_FULL_F 2 "register_operand" "0, w")
7081 1.1.1.3 mrg (match_operand:SVE_FULL_F 3 "register_operand" "w, w")
7082 1.1.1.3 mrg (match_operand:SVE_FULL_F 4 "register_operand" "w, w")]
7083 1.1.1.3 mrg SVE_COND_FP_TERNARY)
7084 1.1.1.3 mrg (match_dup 2)]
7085 1.1.1.3 mrg UNSPEC_SEL))]
7086 1.1 mrg "TARGET_SVE"
7087 1.1 mrg "@
7088 1.1.1.3 mrg <sve_fmad_op>\t%0.<Vetype>, %1/m, %3.<Vetype>, %4.<Vetype>
7089 1.1.1.3 mrg movprfx\t%0, %2\;<sve_fmad_op>\t%0.<Vetype>, %1/m, %3.<Vetype>, %4.<Vetype>"
7090 1.1.1.3 mrg [(set_attr "movprfx" "*,yes")]
7091 1.1 mrg )
7092 1.1 mrg
7093 1.1.1.3 mrg ;; Predicated floating-point ternary operations, merging with the
7094 1.1.1.3 mrg ;; third input.
7095 1.1.1.3 mrg (define_insn_and_rewrite "*cond_<optab><mode>_4_relaxed"
7096 1.1.1.3 mrg [(set (match_operand:SVE_FULL_F 0 "register_operand" "=w, ?&w")
7097 1.1.1.3 mrg (unspec:SVE_FULL_F
7098 1.1.1.3 mrg [(match_operand:<VPRED> 1 "register_operand" "Upl, Upl")
7099 1.1.1.3 mrg (unspec:SVE_FULL_F
7100 1.1.1.3 mrg [(match_operand 5)
7101 1.1.1.3 mrg (const_int SVE_RELAXED_GP)
7102 1.1.1.3 mrg (match_operand:SVE_FULL_F 2 "register_operand" "w, w")
7103 1.1.1.3 mrg (match_operand:SVE_FULL_F 3 "register_operand" "w, w")
7104 1.1.1.3 mrg (match_operand:SVE_FULL_F 4 "register_operand" "0, w")]
7105 1.1.1.3 mrg SVE_COND_FP_TERNARY)
7106 1.1.1.3 mrg (match_dup 4)]
7107 1.1.1.3 mrg UNSPEC_SEL))]
7108 1.1 mrg "TARGET_SVE"
7109 1.1 mrg "@
7110 1.1.1.3 mrg <sve_fmla_op>\t%0.<Vetype>, %1/m, %2.<Vetype>, %3.<Vetype>
7111 1.1.1.3 mrg movprfx\t%0, %4\;<sve_fmla_op>\t%0.<Vetype>, %1/m, %2.<Vetype>, %3.<Vetype>"
7112 1.1.1.3 mrg "&& !rtx_equal_p (operands[1], operands[5])"
7113 1.1.1.3 mrg {
7114 1.1.1.3 mrg operands[5] = copy_rtx (operands[1]);
7115 1.1.1.3 mrg }
7116 1.1.1.3 mrg [(set_attr "movprfx" "*,yes")]
7117 1.1.1.3 mrg )
7118 1.1.1.3 mrg
7119 1.1.1.3 mrg (define_insn "*cond_<optab><mode>_4_strict"
7120 1.1.1.3 mrg [(set (match_operand:SVE_FULL_F 0 "register_operand" "=w, ?&w")
7121 1.1.1.3 mrg (unspec:SVE_FULL_F
7122 1.1.1.3 mrg [(match_operand:<VPRED> 1 "register_operand" "Upl, Upl")
7123 1.1.1.3 mrg (unspec:SVE_FULL_F
7124 1.1.1.3 mrg [(match_dup 1)
7125 1.1.1.3 mrg (const_int SVE_STRICT_GP)
7126 1.1.1.3 mrg (match_operand:SVE_FULL_F 2 "register_operand" "w, w")
7127 1.1.1.3 mrg (match_operand:SVE_FULL_F 3 "register_operand" "w, w")
7128 1.1.1.3 mrg (match_operand:SVE_FULL_F 4 "register_operand" "0, w")]
7129 1.1.1.3 mrg SVE_COND_FP_TERNARY)
7130 1.1.1.3 mrg (match_dup 4)]
7131 1.1.1.3 mrg UNSPEC_SEL))]
7132 1.1.1.3 mrg "TARGET_SVE"
7133 1.1.1.3 mrg "@
7134 1.1.1.3 mrg <sve_fmla_op>\t%0.<Vetype>, %1/m, %2.<Vetype>, %3.<Vetype>
7135 1.1.1.3 mrg movprfx\t%0, %4\;<sve_fmla_op>\t%0.<Vetype>, %1/m, %2.<Vetype>, %3.<Vetype>"
7136 1.1.1.3 mrg [(set_attr "movprfx" "*,yes")]
7137 1.1.1.3 mrg )
7138 1.1.1.3 mrg
7139 1.1.1.3 mrg ;; Predicated floating-point ternary operations, merging with an
7140 1.1.1.3 mrg ;; independent value.
7141 1.1.1.3 mrg (define_insn_and_rewrite "*cond_<optab><mode>_any_relaxed"
7142 1.1.1.3 mrg [(set (match_operand:SVE_FULL_F 0 "register_operand" "=&w, &w, &w, &w, &w, ?&w")
7143 1.1.1.3 mrg (unspec:SVE_FULL_F
7144 1.1.1.3 mrg [(match_operand:<VPRED> 1 "register_operand" "Upl, Upl, Upl, Upl, Upl, Upl")
7145 1.1.1.3 mrg (unspec:SVE_FULL_F
7146 1.1.1.3 mrg [(match_operand 6)
7147 1.1.1.3 mrg (const_int SVE_RELAXED_GP)
7148 1.1.1.3 mrg (match_operand:SVE_FULL_F 2 "register_operand" "w, w, 0, w, w, w")
7149 1.1.1.3 mrg (match_operand:SVE_FULL_F 3 "register_operand" "w, w, w, 0, w, w")
7150 1.1.1.3 mrg (match_operand:SVE_FULL_F 4 "register_operand" "w, 0, w, w, w, w")]
7151 1.1.1.3 mrg SVE_COND_FP_TERNARY)
7152 1.1.1.3 mrg (match_operand:SVE_FULL_F 5 "aarch64_simd_reg_or_zero" "Dz, Dz, Dz, Dz, 0, w")]
7153 1.1.1.3 mrg UNSPEC_SEL))]
7154 1.1.1.3 mrg "TARGET_SVE
7155 1.1.1.3 mrg && !rtx_equal_p (operands[2], operands[5])
7156 1.1.1.3 mrg && !rtx_equal_p (operands[3], operands[5])
7157 1.1.1.3 mrg && !rtx_equal_p (operands[4], operands[5])"
7158 1.1.1.3 mrg "@
7159 1.1.1.3 mrg movprfx\t%0.<Vetype>, %1/z, %4.<Vetype>\;<sve_fmla_op>\t%0.<Vetype>, %1/m, %2.<Vetype>, %3.<Vetype>
7160 1.1.1.3 mrg movprfx\t%0.<Vetype>, %1/z, %0.<Vetype>\;<sve_fmla_op>\t%0.<Vetype>, %1/m, %2.<Vetype>, %3.<Vetype>
7161 1.1.1.3 mrg movprfx\t%0.<Vetype>, %1/z, %0.<Vetype>\;<sve_fmad_op>\t%0.<Vetype>, %1/m, %3.<Vetype>, %4.<Vetype>
7162 1.1.1.3 mrg movprfx\t%0.<Vetype>, %1/z, %0.<Vetype>\;<sve_fmad_op>\t%0.<Vetype>, %1/m, %2.<Vetype>, %4.<Vetype>
7163 1.1.1.3 mrg movprfx\t%0.<Vetype>, %1/m, %4.<Vetype>\;<sve_fmla_op>\t%0.<Vetype>, %1/m, %2.<Vetype>, %3.<Vetype>
7164 1.1.1.3 mrg #"
7165 1.1.1.3 mrg "&& 1"
7166 1.1.1.3 mrg {
7167 1.1.1.3 mrg if (reload_completed
7168 1.1.1.3 mrg && register_operand (operands[5], <MODE>mode)
7169 1.1.1.3 mrg && !rtx_equal_p (operands[0], operands[5]))
7170 1.1.1.3 mrg {
7171 1.1.1.3 mrg emit_insn (gen_vcond_mask_<mode><vpred> (operands[0], operands[4],
7172 1.1.1.3 mrg operands[5], operands[1]));
7173 1.1.1.3 mrg operands[5] = operands[4] = operands[0];
7174 1.1.1.3 mrg }
7175 1.1.1.3 mrg else if (!rtx_equal_p (operands[1], operands[6]))
7176 1.1.1.3 mrg operands[6] = copy_rtx (operands[1]);
7177 1.1.1.3 mrg else
7178 1.1.1.3 mrg FAIL;
7179 1.1.1.3 mrg }
7180 1.1.1.3 mrg [(set_attr "movprfx" "yes")]
7181 1.1.1.3 mrg )
7182 1.1.1.3 mrg
7183 1.1.1.3 mrg (define_insn_and_rewrite "*cond_<optab><mode>_any_strict"
7184 1.1.1.3 mrg [(set (match_operand:SVE_FULL_F 0 "register_operand" "=&w, &w, &w, &w, &w, ?&w")
7185 1.1.1.3 mrg (unspec:SVE_FULL_F
7186 1.1.1.3 mrg [(match_operand:<VPRED> 1 "register_operand" "Upl, Upl, Upl, Upl, Upl, Upl")
7187 1.1.1.3 mrg (unspec:SVE_FULL_F
7188 1.1.1.3 mrg [(match_dup 1)
7189 1.1.1.3 mrg (const_int SVE_STRICT_GP)
7190 1.1.1.3 mrg (match_operand:SVE_FULL_F 2 "register_operand" "w, w, 0, w, w, w")
7191 1.1.1.3 mrg (match_operand:SVE_FULL_F 3 "register_operand" "w, w, w, 0, w, w")
7192 1.1.1.3 mrg (match_operand:SVE_FULL_F 4 "register_operand" "w, 0, w, w, w, w")]
7193 1.1.1.3 mrg SVE_COND_FP_TERNARY)
7194 1.1.1.3 mrg (match_operand:SVE_FULL_F 5 "aarch64_simd_reg_or_zero" "Dz, Dz, Dz, Dz, 0, w")]
7195 1.1.1.3 mrg UNSPEC_SEL))]
7196 1.1.1.3 mrg "TARGET_SVE
7197 1.1.1.3 mrg && !rtx_equal_p (operands[2], operands[5])
7198 1.1.1.3 mrg && !rtx_equal_p (operands[3], operands[5])
7199 1.1.1.3 mrg && !rtx_equal_p (operands[4], operands[5])"
7200 1.1.1.3 mrg "@
7201 1.1.1.3 mrg movprfx\t%0.<Vetype>, %1/z, %4.<Vetype>\;<sve_fmla_op>\t%0.<Vetype>, %1/m, %2.<Vetype>, %3.<Vetype>
7202 1.1.1.3 mrg movprfx\t%0.<Vetype>, %1/z, %0.<Vetype>\;<sve_fmla_op>\t%0.<Vetype>, %1/m, %2.<Vetype>, %3.<Vetype>
7203 1.1.1.3 mrg movprfx\t%0.<Vetype>, %1/z, %0.<Vetype>\;<sve_fmad_op>\t%0.<Vetype>, %1/m, %3.<Vetype>, %4.<Vetype>
7204 1.1.1.3 mrg movprfx\t%0.<Vetype>, %1/z, %0.<Vetype>\;<sve_fmad_op>\t%0.<Vetype>, %1/m, %2.<Vetype>, %4.<Vetype>
7205 1.1.1.3 mrg movprfx\t%0.<Vetype>, %1/m, %4.<Vetype>\;<sve_fmla_op>\t%0.<Vetype>, %1/m, %2.<Vetype>, %3.<Vetype>
7206 1.1.1.3 mrg #"
7207 1.1.1.3 mrg "&& reload_completed
7208 1.1.1.3 mrg && register_operand (operands[5], <MODE>mode)
7209 1.1.1.3 mrg && !rtx_equal_p (operands[0], operands[5])"
7210 1.1.1.3 mrg {
7211 1.1.1.3 mrg emit_insn (gen_vcond_mask_<mode><vpred> (operands[0], operands[4],
7212 1.1.1.3 mrg operands[5], operands[1]));
7213 1.1.1.3 mrg operands[5] = operands[4] = operands[0];
7214 1.1.1.3 mrg }
7215 1.1.1.3 mrg [(set_attr "movprfx" "yes")]
7216 1.1.1.3 mrg )
7217 1.1.1.3 mrg
7218 1.1.1.3 mrg ;; Unpredicated FMLA and FMLS by selected lanes. It doesn't seem worth using
7219 1.1.1.3 mrg ;; (fma ...) since target-independent code won't understand the indexing.
7220 1.1.1.3 mrg (define_insn "@aarch64_<optab>_lane_<mode>"
7221 1.1.1.3 mrg [(set (match_operand:SVE_FULL_F 0 "register_operand" "=w, ?&w")
7222 1.1.1.3 mrg (unspec:SVE_FULL_F
7223 1.1.1.3 mrg [(match_operand:SVE_FULL_F 1 "register_operand" "w, w")
7224 1.1.1.3 mrg (unspec:SVE_FULL_F
7225 1.1.1.3 mrg [(match_operand:SVE_FULL_F 2 "register_operand" "<sve_lane_con>, <sve_lane_con>")
7226 1.1.1.3 mrg (match_operand:SI 3 "const_int_operand")]
7227 1.1.1.3 mrg UNSPEC_SVE_LANE_SELECT)
7228 1.1.1.3 mrg (match_operand:SVE_FULL_F 4 "register_operand" "0, w")]
7229 1.1.1.3 mrg SVE_FP_TERNARY_LANE))]
7230 1.1.1.3 mrg "TARGET_SVE"
7231 1.1.1.3 mrg "@
7232 1.1.1.3 mrg <sve_fp_op>\t%0.<Vetype>, %1.<Vetype>, %2.<Vetype>[%3]
7233 1.1.1.3 mrg movprfx\t%0, %4\;<sve_fp_op>\t%0.<Vetype>, %1.<Vetype>, %2.<Vetype>[%3]"
7234 1.1.1.3 mrg [(set_attr "movprfx" "*,yes")]
7235 1.1 mrg )
7236 1.1 mrg
7237 1.1.1.3 mrg ;; -------------------------------------------------------------------------
7238 1.1.1.3 mrg ;; ---- [FP] Complex multiply-add
7239 1.1.1.3 mrg ;; -------------------------------------------------------------------------
7240 1.1.1.3 mrg ;; Includes merging patterns for:
7241 1.1.1.3 mrg ;; - FCMLA
7242 1.1.1.3 mrg ;; -------------------------------------------------------------------------
7243 1.1.1.3 mrg
7244 1.1.1.3 mrg ;; Predicated FCMLA.
7245 1.1.1.3 mrg (define_insn "@aarch64_pred_<optab><mode>"
7246 1.1.1.3 mrg [(set (match_operand:SVE_FULL_F 0 "register_operand" "=w, ?&w")
7247 1.1.1.3 mrg (unspec:SVE_FULL_F
7248 1.1.1.3 mrg [(match_operand:<VPRED> 1 "register_operand" "Upl, Upl")
7249 1.1.1.3 mrg (match_operand:SI 5 "aarch64_sve_gp_strictness")
7250 1.1.1.3 mrg (match_operand:SVE_FULL_F 2 "register_operand" "w, w")
7251 1.1.1.3 mrg (match_operand:SVE_FULL_F 3 "register_operand" "w, w")
7252 1.1.1.3 mrg (match_operand:SVE_FULL_F 4 "register_operand" "0, w")]
7253 1.1.1.3 mrg SVE_COND_FCMLA))]
7254 1.1 mrg "TARGET_SVE"
7255 1.1 mrg "@
7256 1.1.1.3 mrg fcmla\t%0.<Vetype>, %1/m, %2.<Vetype>, %3.<Vetype>, #<rot>
7257 1.1.1.3 mrg movprfx\t%0, %4\;fcmla\t%0.<Vetype>, %1/m, %2.<Vetype>, %3.<Vetype>, #<rot>"
7258 1.1.1.3 mrg [(set_attr "movprfx" "*,yes")]
7259 1.1 mrg )
7260 1.1 mrg
7261 1.1.1.5 mrg ;; unpredicated optab pattern for auto-vectorizer
7262 1.1.1.5 mrg ;; The complex mla/mls operations always need to expand to two instructions.
7263 1.1.1.5 mrg ;; The first operation does half the computation and the second does the
7264 1.1.1.5 mrg ;; remainder. Because of this, expand early.
7265 1.1.1.5 mrg (define_expand "cml<fcmac1><conj_op><mode>4"
7266 1.1.1.5 mrg [(set (match_operand:SVE_FULL_F 0 "register_operand")
7267 1.1.1.5 mrg (unspec:SVE_FULL_F
7268 1.1.1.5 mrg [(match_dup 4)
7269 1.1.1.5 mrg (match_dup 5)
7270 1.1.1.5 mrg (match_operand:SVE_FULL_F 1 "register_operand")
7271 1.1.1.5 mrg (match_operand:SVE_FULL_F 2 "register_operand")
7272 1.1.1.5 mrg (match_operand:SVE_FULL_F 3 "register_operand")]
7273 1.1.1.5 mrg FCMLA_OP))]
7274 1.1.1.5 mrg "TARGET_SVE"
7275 1.1.1.5 mrg {
7276 1.1.1.5 mrg operands[4] = aarch64_ptrue_reg (<VPRED>mode);
7277 1.1.1.5 mrg operands[5] = gen_int_mode (SVE_RELAXED_GP, SImode);
7278 1.1.1.5 mrg rtx tmp = gen_reg_rtx (<MODE>mode);
7279 1.1.1.5 mrg emit_insn
7280 1.1.1.5 mrg (gen_aarch64_pred_fcmla<sve_rot1><mode> (tmp, operands[4],
7281 1.1.1.5 mrg operands[2], operands[1],
7282 1.1.1.5 mrg operands[3], operands[5]));
7283 1.1.1.5 mrg emit_insn
7284 1.1.1.5 mrg (gen_aarch64_pred_fcmla<sve_rot2><mode> (operands[0], operands[4],
7285 1.1.1.5 mrg operands[2], operands[1],
7286 1.1.1.5 mrg tmp, operands[5]));
7287 1.1.1.5 mrg DONE;
7288 1.1.1.5 mrg })
7289 1.1.1.5 mrg
7290 1.1.1.5 mrg ;; unpredicated optab pattern for auto-vectorizer
7291 1.1.1.5 mrg ;; The complex mul operations always need to expand to two instructions.
7292 1.1.1.5 mrg ;; The first operation does half the computation and the second does the
7293 1.1.1.5 mrg ;; remainder. Because of this, expand early.
7294 1.1.1.5 mrg (define_expand "cmul<conj_op><mode>3"
7295 1.1.1.5 mrg [(set (match_operand:SVE_FULL_F 0 "register_operand")
7296 1.1.1.5 mrg (unspec:SVE_FULL_F
7297 1.1.1.5 mrg [(match_operand:SVE_FULL_F 1 "register_operand")
7298 1.1.1.5 mrg (match_operand:SVE_FULL_F 2 "register_operand")]
7299 1.1.1.5 mrg FCMUL_OP))]
7300 1.1.1.5 mrg "TARGET_SVE"
7301 1.1.1.5 mrg {
7302 1.1.1.5 mrg rtx pred_reg = aarch64_ptrue_reg (<VPRED>mode);
7303 1.1.1.5 mrg rtx gp_mode = gen_int_mode (SVE_RELAXED_GP, SImode);
7304 1.1.1.5 mrg rtx accum = force_reg (<MODE>mode, CONST0_RTX (<MODE>mode));
7305 1.1.1.5 mrg rtx tmp = gen_reg_rtx (<MODE>mode);
7306 1.1.1.5 mrg emit_insn
7307 1.1.1.5 mrg (gen_aarch64_pred_fcmla<sve_rot1><mode> (tmp, pred_reg,
7308 1.1.1.5 mrg operands[2], operands[1],
7309 1.1.1.5 mrg accum, gp_mode));
7310 1.1.1.5 mrg emit_insn
7311 1.1.1.5 mrg (gen_aarch64_pred_fcmla<sve_rot2><mode> (operands[0], pred_reg,
7312 1.1.1.5 mrg operands[2], operands[1],
7313 1.1.1.5 mrg tmp, gp_mode));
7314 1.1.1.5 mrg DONE;
7315 1.1.1.5 mrg })
7316 1.1.1.5 mrg
7317 1.1.1.3 mrg ;; Predicated FCMLA with merging.
7318 1.1.1.3 mrg (define_expand "@cond_<optab><mode>"
7319 1.1.1.3 mrg [(set (match_operand:SVE_FULL_F 0 "register_operand")
7320 1.1.1.3 mrg (unspec:SVE_FULL_F
7321 1.1.1.3 mrg [(match_operand:<VPRED> 1 "register_operand")
7322 1.1.1.3 mrg (unspec:SVE_FULL_F
7323 1.1.1.3 mrg [(match_dup 1)
7324 1.1.1.3 mrg (const_int SVE_STRICT_GP)
7325 1.1.1.3 mrg (match_operand:SVE_FULL_F 2 "register_operand")
7326 1.1.1.3 mrg (match_operand:SVE_FULL_F 3 "register_operand")
7327 1.1.1.3 mrg (match_operand:SVE_FULL_F 4 "register_operand")]
7328 1.1.1.3 mrg SVE_COND_FCMLA)
7329 1.1.1.3 mrg (match_operand:SVE_FULL_F 5 "aarch64_simd_reg_or_zero")]
7330 1.1.1.3 mrg UNSPEC_SEL))]
7331 1.1.1.2 mrg "TARGET_SVE"
7332 1.1.1.2 mrg )
7333 1.1.1.2 mrg
7334 1.1.1.3 mrg ;; Predicated FCMLA, merging with the third input.
7335 1.1.1.3 mrg (define_insn_and_rewrite "*cond_<optab><mode>_4_relaxed"
7336 1.1.1.3 mrg [(set (match_operand:SVE_FULL_F 0 "register_operand" "=w, ?&w")
7337 1.1.1.3 mrg (unspec:SVE_FULL_F
7338 1.1.1.3 mrg [(match_operand:<VPRED> 1 "register_operand" "Upl, Upl")
7339 1.1.1.3 mrg (unspec:SVE_FULL_F
7340 1.1.1.3 mrg [(match_operand 5)
7341 1.1.1.3 mrg (const_int SVE_RELAXED_GP)
7342 1.1.1.3 mrg (match_operand:SVE_FULL_F 2 "register_operand" "w, w")
7343 1.1.1.3 mrg (match_operand:SVE_FULL_F 3 "register_operand" "w, w")
7344 1.1.1.3 mrg (match_operand:SVE_FULL_F 4 "register_operand" "0, w")]
7345 1.1.1.3 mrg SVE_COND_FCMLA)
7346 1.1.1.3 mrg (match_dup 4)]
7347 1.1.1.3 mrg UNSPEC_SEL))]
7348 1.1.1.2 mrg "TARGET_SVE"
7349 1.1.1.2 mrg "@
7350 1.1.1.3 mrg fcmla\t%0.<Vetype>, %1/m, %2.<Vetype>, %3.<Vetype>, #<rot>
7351 1.1.1.3 mrg movprfx\t%0, %4\;fcmla\t%0.<Vetype>, %1/m, %2.<Vetype>, %3.<Vetype>, #<rot>"
7352 1.1.1.3 mrg "&& !rtx_equal_p (operands[1], operands[5])"
7353 1.1.1.3 mrg {
7354 1.1.1.3 mrg operands[5] = copy_rtx (operands[1]);
7355 1.1.1.3 mrg }
7356 1.1.1.3 mrg [(set_attr "movprfx" "*,yes")]
7357 1.1.1.2 mrg )
7358 1.1.1.2 mrg
7359 1.1.1.3 mrg (define_insn "*cond_<optab><mode>_4_strict"
7360 1.1.1.3 mrg [(set (match_operand:SVE_FULL_F 0 "register_operand" "=w, ?&w")
7361 1.1.1.3 mrg (unspec:SVE_FULL_F
7362 1.1 mrg [(match_operand:<VPRED> 1 "register_operand" "Upl, Upl")
7363 1.1.1.3 mrg (unspec:SVE_FULL_F
7364 1.1.1.3 mrg [(match_dup 1)
7365 1.1.1.3 mrg (const_int SVE_STRICT_GP)
7366 1.1.1.3 mrg (match_operand:SVE_FULL_F 2 "register_operand" "w, w")
7367 1.1.1.3 mrg (match_operand:SVE_FULL_F 3 "register_operand" "w, w")
7368 1.1.1.3 mrg (match_operand:SVE_FULL_F 4 "register_operand" "0, w")]
7369 1.1.1.3 mrg SVE_COND_FCMLA)
7370 1.1.1.3 mrg (match_dup 4)]
7371 1.1.1.3 mrg UNSPEC_SEL))]
7372 1.1 mrg "TARGET_SVE"
7373 1.1 mrg "@
7374 1.1.1.3 mrg fcmla\t%0.<Vetype>, %1/m, %2.<Vetype>, %3.<Vetype>, #<rot>
7375 1.1.1.3 mrg movprfx\t%0, %4\;fcmla\t%0.<Vetype>, %1/m, %2.<Vetype>, %3.<Vetype>, #<rot>"
7376 1.1.1.3 mrg [(set_attr "movprfx" "*,yes")]
7377 1.1 mrg )
7378 1.1 mrg
7379 1.1.1.3 mrg ;; Predicated FCMLA, merging with an independent value.
7380 1.1.1.3 mrg (define_insn_and_rewrite "*cond_<optab><mode>_any_relaxed"
7381 1.1.1.3 mrg [(set (match_operand:SVE_FULL_F 0 "register_operand" "=&w, &w, &w, ?&w")
7382 1.1.1.3 mrg (unspec:SVE_FULL_F
7383 1.1.1.3 mrg [(match_operand:<VPRED> 1 "register_operand" "Upl, Upl, Upl, Upl")
7384 1.1.1.3 mrg (unspec:SVE_FULL_F
7385 1.1.1.3 mrg [(match_operand 6)
7386 1.1.1.3 mrg (const_int SVE_RELAXED_GP)
7387 1.1.1.3 mrg (match_operand:SVE_FULL_F 2 "register_operand" "w, w, w, w")
7388 1.1.1.3 mrg (match_operand:SVE_FULL_F 3 "register_operand" "w, w, w, w")
7389 1.1.1.3 mrg (match_operand:SVE_FULL_F 4 "register_operand" "w, 0, w, w")]
7390 1.1.1.3 mrg SVE_COND_FCMLA)
7391 1.1.1.3 mrg (match_operand:SVE_FULL_F 5 "aarch64_simd_reg_or_zero" "Dz, Dz, 0, w")]
7392 1.1.1.3 mrg UNSPEC_SEL))]
7393 1.1.1.3 mrg "TARGET_SVE && !rtx_equal_p (operands[4], operands[5])"
7394 1.1.1.3 mrg "@
7395 1.1.1.3 mrg movprfx\t%0.<Vetype>, %1/z, %4.<Vetype>\;fcmla\t%0.<Vetype>, %1/m, %2.<Vetype>, %3.<Vetype>, #<rot>
7396 1.1.1.3 mrg movprfx\t%0.<Vetype>, %1/z, %0.<Vetype>\;fcmla\t%0.<Vetype>, %1/m, %2.<Vetype>, %3.<Vetype>, #<rot>
7397 1.1.1.3 mrg movprfx\t%0.<Vetype>, %1/m, %4.<Vetype>\;fcmla\t%0.<Vetype>, %1/m, %2.<Vetype>, %3.<Vetype>, #<rot>
7398 1.1.1.3 mrg #"
7399 1.1.1.3 mrg "&& 1"
7400 1.1.1.3 mrg {
7401 1.1.1.3 mrg if (reload_completed
7402 1.1.1.3 mrg && register_operand (operands[5], <MODE>mode)
7403 1.1.1.3 mrg && !rtx_equal_p (operands[0], operands[5]))
7404 1.1.1.3 mrg {
7405 1.1.1.3 mrg emit_insn (gen_vcond_mask_<mode><vpred> (operands[0], operands[4],
7406 1.1.1.3 mrg operands[5], operands[1]));
7407 1.1.1.3 mrg operands[5] = operands[4] = operands[0];
7408 1.1.1.3 mrg }
7409 1.1.1.3 mrg else if (!rtx_equal_p (operands[1], operands[6]))
7410 1.1.1.3 mrg operands[6] = copy_rtx (operands[1]);
7411 1.1.1.3 mrg else
7412 1.1.1.3 mrg FAIL;
7413 1.1.1.3 mrg }
7414 1.1.1.3 mrg [(set_attr "movprfx" "yes")]
7415 1.1 mrg )
7416 1.1 mrg
7417 1.1.1.3 mrg (define_insn_and_rewrite "*cond_<optab><mode>_any_strict"
7418 1.1.1.3 mrg [(set (match_operand:SVE_FULL_F 0 "register_operand" "=&w, &w, &w, ?&w")
7419 1.1.1.3 mrg (unspec:SVE_FULL_F
7420 1.1.1.3 mrg [(match_operand:<VPRED> 1 "register_operand" "Upl, Upl, Upl, Upl")
7421 1.1.1.3 mrg (unspec:SVE_FULL_F
7422 1.1.1.3 mrg [(match_dup 1)
7423 1.1.1.3 mrg (const_int SVE_STRICT_GP)
7424 1.1.1.3 mrg (match_operand:SVE_FULL_F 2 "register_operand" "w, w, w, w")
7425 1.1.1.3 mrg (match_operand:SVE_FULL_F 3 "register_operand" "w, w, w, w")
7426 1.1.1.3 mrg (match_operand:SVE_FULL_F 4 "register_operand" "w, 0, w, w")]
7427 1.1.1.3 mrg SVE_COND_FCMLA)
7428 1.1.1.3 mrg (match_operand:SVE_FULL_F 5 "aarch64_simd_reg_or_zero" "Dz, Dz, 0, w")]
7429 1.1.1.3 mrg UNSPEC_SEL))]
7430 1.1.1.3 mrg "TARGET_SVE && !rtx_equal_p (operands[4], operands[5])"
7431 1.1.1.3 mrg "@
7432 1.1.1.3 mrg movprfx\t%0.<Vetype>, %1/z, %4.<Vetype>\;fcmla\t%0.<Vetype>, %1/m, %2.<Vetype>, %3.<Vetype>, #<rot>
7433 1.1.1.3 mrg movprfx\t%0.<Vetype>, %1/z, %0.<Vetype>\;fcmla\t%0.<Vetype>, %1/m, %2.<Vetype>, %3.<Vetype>, #<rot>
7434 1.1.1.3 mrg movprfx\t%0.<Vetype>, %1/m, %4.<Vetype>\;fcmla\t%0.<Vetype>, %1/m, %2.<Vetype>, %3.<Vetype>, #<rot>
7435 1.1.1.3 mrg #"
7436 1.1.1.3 mrg "&& reload_completed
7437 1.1.1.3 mrg && register_operand (operands[5], <MODE>mode)
7438 1.1.1.3 mrg && !rtx_equal_p (operands[0], operands[5])"
7439 1.1.1.3 mrg {
7440 1.1.1.3 mrg emit_insn (gen_vcond_mask_<mode><vpred> (operands[0], operands[4],
7441 1.1.1.3 mrg operands[5], operands[1]));
7442 1.1.1.3 mrg operands[5] = operands[4] = operands[0];
7443 1.1.1.3 mrg }
7444 1.1.1.3 mrg [(set_attr "movprfx" "yes")]
7445 1.1.1.2 mrg )
7446 1.1.1.2 mrg
7447 1.1.1.3 mrg ;; Unpredicated FCMLA with indexing.
7448 1.1.1.3 mrg (define_insn "@aarch64_<optab>_lane_<mode>"
7449 1.1.1.3 mrg [(set (match_operand:SVE_FULL_HSF 0 "register_operand" "=w, ?&w")
7450 1.1.1.3 mrg (unspec:SVE_FULL_HSF
7451 1.1.1.3 mrg [(match_operand:SVE_FULL_HSF 1 "register_operand" "w, w")
7452 1.1.1.3 mrg (unspec:SVE_FULL_HSF
7453 1.1.1.3 mrg [(match_operand:SVE_FULL_HSF 2 "register_operand" "<sve_lane_pair_con>, <sve_lane_pair_con>")
7454 1.1.1.3 mrg (match_operand:SI 3 "const_int_operand")]
7455 1.1.1.3 mrg UNSPEC_SVE_LANE_SELECT)
7456 1.1.1.3 mrg (match_operand:SVE_FULL_HSF 4 "register_operand" "0, w")]
7457 1.1.1.3 mrg FCMLA))]
7458 1.1.1.2 mrg "TARGET_SVE"
7459 1.1.1.3 mrg "@
7460 1.1.1.3 mrg fcmla\t%0.<Vetype>, %1.<Vetype>, %2.<Vetype>[%3], #<rot>
7461 1.1.1.3 mrg movprfx\t%0, %4\;fcmla\t%0.<Vetype>, %1.<Vetype>, %2.<Vetype>[%3], #<rot>"
7462 1.1.1.3 mrg [(set_attr "movprfx" "*,yes")]
7463 1.1.1.2 mrg )
7464 1.1.1.2 mrg
7465 1.1.1.3 mrg ;; -------------------------------------------------------------------------
7466 1.1.1.3 mrg ;; ---- [FP] Trigonometric multiply-add
7467 1.1.1.3 mrg ;; -------------------------------------------------------------------------
7468 1.1.1.3 mrg ;; Includes:
7469 1.1.1.3 mrg ;; - FTMAD
7470 1.1.1.3 mrg ;; -------------------------------------------------------------------------
7471 1.1.1.3 mrg
7472 1.1.1.3 mrg (define_insn "@aarch64_sve_tmad<mode>"
7473 1.1.1.3 mrg [(set (match_operand:SVE_FULL_F 0 "register_operand" "=w, ?&w")
7474 1.1.1.3 mrg (unspec:SVE_FULL_F
7475 1.1.1.3 mrg [(match_operand:SVE_FULL_F 1 "register_operand" "0, w")
7476 1.1.1.3 mrg (match_operand:SVE_FULL_F 2 "register_operand" "w, w")
7477 1.1.1.3 mrg (match_operand:DI 3 "const_int_operand")]
7478 1.1.1.3 mrg UNSPEC_FTMAD))]
7479 1.1.1.2 mrg "TARGET_SVE"
7480 1.1.1.2 mrg "@
7481 1.1.1.3 mrg ftmad\t%0.<Vetype>, %0.<Vetype>, %2.<Vetype>, #%3
7482 1.1.1.3 mrg movprfx\t%0, %1\;ftmad\t%0.<Vetype>, %0.<Vetype>, %2.<Vetype>, #%3"
7483 1.1.1.3 mrg [(set_attr "movprfx" "*,yes")]
7484 1.1.1.2 mrg )
7485 1.1.1.2 mrg
7486 1.1.1.3 mrg ;; -------------------------------------------------------------------------
7487 1.1.1.3 mrg ;; ---- [FP] Bfloat16 long ternary arithmetic (SF,BF,BF)
7488 1.1.1.3 mrg ;; -------------------------------------------------------------------------
7489 1.1.1.3 mrg ;; Includes:
7490 1.1.1.3 mrg ;; - BFDOT (BF16)
7491 1.1.1.3 mrg ;; - BFMLALB (BF16)
7492 1.1.1.3 mrg ;; - BFMLALT (BF16)
7493 1.1.1.3 mrg ;; - BFMMLA (BF16)
7494 1.1.1.3 mrg ;; -------------------------------------------------------------------------
7495 1.1.1.3 mrg
7496 1.1.1.3 mrg (define_insn "@aarch64_sve_<sve_fp_op>vnx4sf"
7497 1.1.1.3 mrg [(set (match_operand:VNx4SF 0 "register_operand" "=w, ?&w")
7498 1.1.1.3 mrg (unspec:VNx4SF
7499 1.1.1.3 mrg [(match_operand:VNx4SF 1 "register_operand" "0, w")
7500 1.1.1.3 mrg (match_operand:VNx8BF 2 "register_operand" "w, w")
7501 1.1.1.3 mrg (match_operand:VNx8BF 3 "register_operand" "w, w")]
7502 1.1.1.3 mrg SVE_BFLOAT_TERNARY_LONG))]
7503 1.1.1.3 mrg "TARGET_SVE_BF16"
7504 1.1.1.3 mrg "@
7505 1.1.1.3 mrg <sve_fp_op>\t%0.s, %2.h, %3.h
7506 1.1.1.3 mrg movprfx\t%0, %1\;<sve_fp_op>\t%0.s, %2.h, %3.h"
7507 1.1.1.3 mrg [(set_attr "movprfx" "*,yes")]
7508 1.1.1.2 mrg )
7509 1.1.1.2 mrg
7510 1.1.1.3 mrg ;; The immediate range is enforced before generating the instruction.
7511 1.1.1.3 mrg (define_insn "@aarch64_sve_<sve_fp_op>_lanevnx4sf"
7512 1.1.1.3 mrg [(set (match_operand:VNx4SF 0 "register_operand" "=w, ?&w")
7513 1.1.1.3 mrg (unspec:VNx4SF
7514 1.1.1.3 mrg [(match_operand:VNx4SF 1 "register_operand" "0, w")
7515 1.1.1.3 mrg (match_operand:VNx8BF 2 "register_operand" "w, w")
7516 1.1.1.3 mrg (match_operand:VNx8BF 3 "register_operand" "y, y")
7517 1.1.1.3 mrg (match_operand:SI 4 "const_int_operand")]
7518 1.1.1.3 mrg SVE_BFLOAT_TERNARY_LONG_LANE))]
7519 1.1.1.3 mrg "TARGET_SVE_BF16"
7520 1.1.1.3 mrg "@
7521 1.1.1.3 mrg <sve_fp_op>\t%0.s, %2.h, %3.h[%4]
7522 1.1.1.3 mrg movprfx\t%0, %1\;<sve_fp_op>\t%0.s, %2.h, %3.h[%4]"
7523 1.1.1.3 mrg [(set_attr "movprfx" "*,yes")]
7524 1.1.1.3 mrg )
7525 1.1.1.3 mrg
7526 1.1.1.3 mrg ;; -------------------------------------------------------------------------
7527 1.1.1.3 mrg ;; ---- [FP] Matrix multiply-accumulate
7528 1.1.1.3 mrg ;; -------------------------------------------------------------------------
7529 1.1.1.3 mrg ;; Includes:
7530 1.1.1.3 mrg ;; - FMMLA (F32MM,F64MM)
7531 1.1.1.3 mrg ;; -------------------------------------------------------------------------
7532 1.1.1.3 mrg
7533 1.1.1.3 mrg ;; The mode iterator enforces the target requirements.
7534 1.1.1.3 mrg (define_insn "@aarch64_sve_<sve_fp_op><mode>"
7535 1.1.1.3 mrg [(set (match_operand:SVE_MATMULF 0 "register_operand" "=w, ?&w")
7536 1.1.1.3 mrg (unspec:SVE_MATMULF
7537 1.1.1.3 mrg [(match_operand:SVE_MATMULF 2 "register_operand" "w, w")
7538 1.1.1.3 mrg (match_operand:SVE_MATMULF 3 "register_operand" "w, w")
7539 1.1.1.3 mrg (match_operand:SVE_MATMULF 1 "register_operand" "0, w")]
7540 1.1.1.3 mrg FMMLA))]
7541 1.1.1.2 mrg "TARGET_SVE"
7542 1.1.1.2 mrg "@
7543 1.1.1.3 mrg <sve_fp_op>\\t%0.<Vetype>, %2.<Vetype>, %3.<Vetype>
7544 1.1.1.3 mrg movprfx\t%0, %1\;<sve_fp_op>\\t%0.<Vetype>, %2.<Vetype>, %3.<Vetype>"
7545 1.1.1.3 mrg [(set_attr "movprfx" "*,yes")]
7546 1.1.1.2 mrg )
7547 1.1.1.2 mrg
7548 1.1.1.3 mrg ;; =========================================================================
7549 1.1.1.3 mrg ;; == Comparisons and selects
7550 1.1.1.3 mrg ;; =========================================================================
7551 1.1.1.3 mrg
7552 1.1.1.3 mrg ;; -------------------------------------------------------------------------
7553 1.1.1.3 mrg ;; ---- [INT,FP] Select based on predicates
7554 1.1.1.3 mrg ;; -------------------------------------------------------------------------
7555 1.1.1.3 mrg ;; Includes merging patterns for:
7556 1.1.1.3 mrg ;; - FMOV
7557 1.1.1.3 mrg ;; - MOV
7558 1.1.1.3 mrg ;; - SEL
7559 1.1.1.3 mrg ;; -------------------------------------------------------------------------
7560 1.1.1.3 mrg
7561 1.1 mrg ;; vcond_mask operand order: true, false, mask
7562 1.1 mrg ;; UNSPEC_SEL operand order: mask, true, false (as for VEC_COND_EXPR)
7563 1.1 mrg ;; SEL operand order: mask, true, false
7564 1.1.1.3 mrg (define_expand "@vcond_mask_<mode><vpred>"
7565 1.1.1.5 mrg [(set (match_operand:SVE_ALL 0 "register_operand")
7566 1.1.1.5 mrg (unspec:SVE_ALL
7567 1.1.1.3 mrg [(match_operand:<VPRED> 3 "register_operand")
7568 1.1.1.5 mrg (match_operand:SVE_ALL 1 "aarch64_sve_reg_or_dup_imm")
7569 1.1.1.5 mrg (match_operand:SVE_ALL 2 "aarch64_simd_reg_or_zero")]
7570 1.1 mrg UNSPEC_SEL))]
7571 1.1 mrg "TARGET_SVE"
7572 1.1.1.3 mrg {
7573 1.1.1.3 mrg if (register_operand (operands[1], <MODE>mode))
7574 1.1.1.3 mrg operands[2] = force_reg (<MODE>mode, operands[2]);
7575 1.1.1.3 mrg }
7576 1.1 mrg )
7577 1.1 mrg
7578 1.1.1.3 mrg ;; Selects between:
7579 1.1.1.3 mrg ;; - two registers
7580 1.1.1.3 mrg ;; - a duplicated immediate and a register
7581 1.1.1.3 mrg ;; - a duplicated immediate and zero
7582 1.1.1.5 mrg ;;
7583 1.1.1.5 mrg ;; For unpacked vectors, it doesn't really matter whether SEL uses the
7584 1.1.1.5 mrg ;; the container size or the element size. If SEL used the container size,
7585 1.1.1.5 mrg ;; it would ignore undefined bits of the predicate but would copy the
7586 1.1.1.5 mrg ;; upper (undefined) bits of each container along with the defined bits.
7587 1.1.1.5 mrg ;; If SEL used the element size, it would use undefined bits of the predicate
7588 1.1.1.5 mrg ;; to select between undefined elements in each input vector. Thus the only
7589 1.1.1.5 mrg ;; difference is whether the undefined bits in a container always come from
7590 1.1.1.5 mrg ;; the same input as the defined bits, or whether the choice can vary
7591 1.1.1.5 mrg ;; independently of the defined bits.
7592 1.1.1.5 mrg ;;
7593 1.1.1.5 mrg ;; For the other instructions, using the element size is more natural,
7594 1.1.1.5 mrg ;; so we do that for SEL as well.
7595 1.1.1.3 mrg (define_insn "*vcond_mask_<mode><vpred>"
7596 1.1.1.5 mrg [(set (match_operand:SVE_ALL 0 "register_operand" "=w, w, w, w, ?w, ?&w, ?&w")
7597 1.1.1.5 mrg (unspec:SVE_ALL
7598 1.1.1.3 mrg [(match_operand:<VPRED> 3 "register_operand" "Upa, Upa, Upa, Upa, Upl, Upl, Upl")
7599 1.1.1.5 mrg (match_operand:SVE_ALL 1 "aarch64_sve_reg_or_dup_imm" "w, vss, vss, Ufc, Ufc, vss, Ufc")
7600 1.1.1.5 mrg (match_operand:SVE_ALL 2 "aarch64_simd_reg_or_zero" "w, 0, Dz, 0, Dz, w, w")]
7601 1.1.1.3 mrg UNSPEC_SEL))]
7602 1.1.1.3 mrg "TARGET_SVE
7603 1.1.1.3 mrg && (!register_operand (operands[1], <MODE>mode)
7604 1.1.1.3 mrg || register_operand (operands[2], <MODE>mode))"
7605 1.1.1.3 mrg "@
7606 1.1.1.3 mrg sel\t%0.<Vetype>, %3, %1.<Vetype>, %2.<Vetype>
7607 1.1.1.3 mrg mov\t%0.<Vetype>, %3/m, #%I1
7608 1.1.1.3 mrg mov\t%0.<Vetype>, %3/z, #%I1
7609 1.1.1.3 mrg fmov\t%0.<Vetype>, %3/m, #%1
7610 1.1.1.3 mrg movprfx\t%0.<Vetype>, %3/z, %0.<Vetype>\;fmov\t%0.<Vetype>, %3/m, #%1
7611 1.1.1.3 mrg movprfx\t%0, %2\;mov\t%0.<Vetype>, %3/m, #%I1
7612 1.1.1.3 mrg movprfx\t%0, %2\;fmov\t%0.<Vetype>, %3/m, #%1"
7613 1.1.1.3 mrg [(set_attr "movprfx" "*,*,*,*,yes,yes,yes")]
7614 1.1.1.3 mrg )
7615 1.1.1.3 mrg
7616 1.1.1.3 mrg ;; Optimize selects between a duplicated scalar variable and another vector,
7617 1.1.1.3 mrg ;; the latter of which can be a zero constant or a variable. Treat duplicates
7618 1.1.1.3 mrg ;; of GPRs as being more expensive than duplicates of FPRs, since they
7619 1.1.1.3 mrg ;; involve a cross-file move.
7620 1.1.1.3 mrg (define_insn "@aarch64_sel_dup<mode>"
7621 1.1.1.5 mrg [(set (match_operand:SVE_ALL 0 "register_operand" "=?w, w, ??w, ?&w, ??&w, ?&w")
7622 1.1.1.5 mrg (unspec:SVE_ALL
7623 1.1.1.3 mrg [(match_operand:<VPRED> 3 "register_operand" "Upl, Upl, Upl, Upl, Upl, Upl")
7624 1.1.1.5 mrg (vec_duplicate:SVE_ALL
7625 1.1.1.3 mrg (match_operand:<VEL> 1 "register_operand" "r, w, r, w, r, w"))
7626 1.1.1.5 mrg (match_operand:SVE_ALL 2 "aarch64_simd_reg_or_zero" "0, 0, Dz, Dz, w, w")]
7627 1.1 mrg UNSPEC_SEL))]
7628 1.1 mrg "TARGET_SVE"
7629 1.1.1.3 mrg "@
7630 1.1.1.3 mrg mov\t%0.<Vetype>, %3/m, %<vwcore>1
7631 1.1.1.3 mrg mov\t%0.<Vetype>, %3/m, %<Vetype>1
7632 1.1.1.3 mrg movprfx\t%0.<Vetype>, %3/z, %0.<Vetype>\;mov\t%0.<Vetype>, %3/m, %<vwcore>1
7633 1.1.1.3 mrg movprfx\t%0.<Vetype>, %3/z, %0.<Vetype>\;mov\t%0.<Vetype>, %3/m, %<Vetype>1
7634 1.1.1.3 mrg movprfx\t%0, %2\;mov\t%0.<Vetype>, %3/m, %<vwcore>1
7635 1.1.1.3 mrg movprfx\t%0, %2\;mov\t%0.<Vetype>, %3/m, %<Vetype>1"
7636 1.1.1.3 mrg [(set_attr "movprfx" "*,*,yes,yes,yes,yes")]
7637 1.1 mrg )
7638 1.1 mrg
7639 1.1.1.3 mrg ;; -------------------------------------------------------------------------
7640 1.1.1.3 mrg ;; ---- [INT,FP] Compare and select
7641 1.1.1.3 mrg ;; -------------------------------------------------------------------------
7642 1.1.1.3 mrg ;; The patterns in this section are synthetic.
7643 1.1.1.3 mrg ;; -------------------------------------------------------------------------
7644 1.1.1.3 mrg
7645 1.1 mrg ;; Integer (signed) vcond. Don't enforce an immediate range here, since it
7646 1.1 mrg ;; depends on the comparison; leave it to aarch64_expand_sve_vcond instead.
7647 1.1.1.5 mrg (define_expand "vcond<SVE_ALL:mode><SVE_I:mode>"
7648 1.1.1.5 mrg [(set (match_operand:SVE_ALL 0 "register_operand")
7649 1.1.1.5 mrg (if_then_else:SVE_ALL
7650 1.1 mrg (match_operator 3 "comparison_operator"
7651 1.1.1.5 mrg [(match_operand:SVE_I 4 "register_operand")
7652 1.1.1.5 mrg (match_operand:SVE_I 5 "nonmemory_operand")])
7653 1.1.1.5 mrg (match_operand:SVE_ALL 1 "nonmemory_operand")
7654 1.1.1.5 mrg (match_operand:SVE_ALL 2 "nonmemory_operand")))]
7655 1.1.1.5 mrg "TARGET_SVE && <SVE_ALL:container_bits> == <SVE_I:container_bits>"
7656 1.1 mrg {
7657 1.1.1.5 mrg aarch64_expand_sve_vcond (<SVE_ALL:MODE>mode, <SVE_I:MODE>mode, operands);
7658 1.1 mrg DONE;
7659 1.1 mrg }
7660 1.1 mrg )
7661 1.1 mrg
7662 1.1 mrg ;; Integer vcondu. Don't enforce an immediate range here, since it
7663 1.1 mrg ;; depends on the comparison; leave it to aarch64_expand_sve_vcond instead.
7664 1.1.1.5 mrg (define_expand "vcondu<SVE_ALL:mode><SVE_I:mode>"
7665 1.1.1.5 mrg [(set (match_operand:SVE_ALL 0 "register_operand")
7666 1.1.1.5 mrg (if_then_else:SVE_ALL
7667 1.1 mrg (match_operator 3 "comparison_operator"
7668 1.1.1.5 mrg [(match_operand:SVE_I 4 "register_operand")
7669 1.1.1.5 mrg (match_operand:SVE_I 5 "nonmemory_operand")])
7670 1.1.1.5 mrg (match_operand:SVE_ALL 1 "nonmemory_operand")
7671 1.1.1.5 mrg (match_operand:SVE_ALL 2 "nonmemory_operand")))]
7672 1.1.1.5 mrg "TARGET_SVE && <SVE_ALL:container_bits> == <SVE_I:container_bits>"
7673 1.1 mrg {
7674 1.1.1.5 mrg aarch64_expand_sve_vcond (<SVE_ALL:MODE>mode, <SVE_I:MODE>mode, operands);
7675 1.1 mrg DONE;
7676 1.1 mrg }
7677 1.1 mrg )
7678 1.1 mrg
7679 1.1.1.3 mrg ;; Floating-point vcond. All comparisons except FCMUO allow a zero operand;
7680 1.1.1.3 mrg ;; aarch64_expand_sve_vcond handles the case of an FCMUO with zero.
7681 1.1 mrg (define_expand "vcond<mode><v_fp_equiv>"
7682 1.1.1.3 mrg [(set (match_operand:SVE_FULL_HSD 0 "register_operand")
7683 1.1.1.3 mrg (if_then_else:SVE_FULL_HSD
7684 1.1 mrg (match_operator 3 "comparison_operator"
7685 1.1 mrg [(match_operand:<V_FP_EQUIV> 4 "register_operand")
7686 1.1 mrg (match_operand:<V_FP_EQUIV> 5 "aarch64_simd_reg_or_zero")])
7687 1.1.1.3 mrg (match_operand:SVE_FULL_HSD 1 "nonmemory_operand")
7688 1.1.1.3 mrg (match_operand:SVE_FULL_HSD 2 "nonmemory_operand")))]
7689 1.1 mrg "TARGET_SVE"
7690 1.1 mrg {
7691 1.1 mrg aarch64_expand_sve_vcond (<MODE>mode, <V_FP_EQUIV>mode, operands);
7692 1.1 mrg DONE;
7693 1.1 mrg }
7694 1.1 mrg )
7695 1.1 mrg
7696 1.1.1.3 mrg ;; -------------------------------------------------------------------------
7697 1.1.1.3 mrg ;; ---- [INT] Comparisons
7698 1.1.1.3 mrg ;; -------------------------------------------------------------------------
7699 1.1.1.3 mrg ;; Includes:
7700 1.1.1.3 mrg ;; - CMPEQ
7701 1.1.1.3 mrg ;; - CMPGE
7702 1.1.1.3 mrg ;; - CMPGT
7703 1.1.1.3 mrg ;; - CMPHI
7704 1.1.1.3 mrg ;; - CMPHS
7705 1.1.1.3 mrg ;; - CMPLE
7706 1.1.1.3 mrg ;; - CMPLO
7707 1.1.1.3 mrg ;; - CMPLS
7708 1.1.1.3 mrg ;; - CMPLT
7709 1.1.1.3 mrg ;; - CMPNE
7710 1.1.1.3 mrg ;; -------------------------------------------------------------------------
7711 1.1.1.3 mrg
7712 1.1 mrg ;; Signed integer comparisons. Don't enforce an immediate range here, since
7713 1.1 mrg ;; it depends on the comparison; leave it to aarch64_expand_sve_vec_cmp_int
7714 1.1 mrg ;; instead.
7715 1.1 mrg (define_expand "vec_cmp<mode><vpred>"
7716 1.1 mrg [(parallel
7717 1.1 mrg [(set (match_operand:<VPRED> 0 "register_operand")
7718 1.1 mrg (match_operator:<VPRED> 1 "comparison_operator"
7719 1.1.1.5 mrg [(match_operand:SVE_I 2 "register_operand")
7720 1.1.1.5 mrg (match_operand:SVE_I 3 "nonmemory_operand")]))
7721 1.1.1.3 mrg (clobber (reg:CC_NZC CC_REGNUM))])]
7722 1.1 mrg "TARGET_SVE"
7723 1.1 mrg {
7724 1.1 mrg aarch64_expand_sve_vec_cmp_int (operands[0], GET_CODE (operands[1]),
7725 1.1 mrg operands[2], operands[3]);
7726 1.1 mrg DONE;
7727 1.1 mrg }
7728 1.1 mrg )
7729 1.1 mrg
7730 1.1 mrg ;; Unsigned integer comparisons. Don't enforce an immediate range here, since
7731 1.1 mrg ;; it depends on the comparison; leave it to aarch64_expand_sve_vec_cmp_int
7732 1.1 mrg ;; instead.
7733 1.1 mrg (define_expand "vec_cmpu<mode><vpred>"
7734 1.1 mrg [(parallel
7735 1.1 mrg [(set (match_operand:<VPRED> 0 "register_operand")
7736 1.1 mrg (match_operator:<VPRED> 1 "comparison_operator"
7737 1.1.1.5 mrg [(match_operand:SVE_I 2 "register_operand")
7738 1.1.1.5 mrg (match_operand:SVE_I 3 "nonmemory_operand")]))
7739 1.1.1.3 mrg (clobber (reg:CC_NZC CC_REGNUM))])]
7740 1.1 mrg "TARGET_SVE"
7741 1.1 mrg {
7742 1.1 mrg aarch64_expand_sve_vec_cmp_int (operands[0], GET_CODE (operands[1]),
7743 1.1 mrg operands[2], operands[3]);
7744 1.1 mrg DONE;
7745 1.1 mrg }
7746 1.1 mrg )
7747 1.1 mrg
7748 1.1.1.3 mrg ;; Predicated integer comparisons.
7749 1.1.1.5 mrg ;;
7750 1.1.1.5 mrg ;; For unpacked vectors, only the lowpart element in each input container
7751 1.1.1.5 mrg ;; has a defined value, and only the predicate bits associated with
7752 1.1.1.5 mrg ;; those elements are defined. For example, when comparing two VNx2SIs:
7753 1.1.1.5 mrg ;;
7754 1.1.1.5 mrg ;; - The VNx2SIs can be seem as VNx2DIs in which the low halves of each
7755 1.1.1.5 mrg ;; DI container store an SI element. The upper bits of each DI container
7756 1.1.1.5 mrg ;; are undefined.
7757 1.1.1.5 mrg ;;
7758 1.1.1.5 mrg ;; - Alternatively, the VNx2SIs can be seen as VNx4SIs in which the
7759 1.1.1.5 mrg ;; even elements are defined and the odd elements are undefined.
7760 1.1.1.5 mrg ;;
7761 1.1.1.5 mrg ;; - The associated predicate mode is VNx2BI. This means that only the
7762 1.1.1.5 mrg ;; low bit in each predicate byte is defined (on input and on output).
7763 1.1.1.5 mrg ;;
7764 1.1.1.5 mrg ;; - We use a .s comparison to compare VNx2SIs, under the control of a
7765 1.1.1.5 mrg ;; VNx2BI governing predicate, to produce a VNx2BI result. If we view
7766 1.1.1.5 mrg ;; the .s operation as operating on VNx4SIs then for odd lanes:
7767 1.1.1.5 mrg ;;
7768 1.1.1.5 mrg ;; - the input governing predicate bit is undefined
7769 1.1.1.5 mrg ;; - the SI elements being compared are undefined
7770 1.1.1.5 mrg ;; - the predicate result bit is therefore undefined, but
7771 1.1.1.5 mrg ;; - the predicate result bit is in the undefined part of a VNx2BI,
7772 1.1.1.5 mrg ;; so its value doesn't matter anyway.
7773 1.1.1.3 mrg (define_insn "@aarch64_pred_cmp<cmp_op><mode>"
7774 1.1.1.3 mrg [(set (match_operand:<VPRED> 0 "register_operand" "=Upa, Upa")
7775 1.1.1.3 mrg (unspec:<VPRED>
7776 1.1.1.2 mrg [(match_operand:<VPRED> 1 "register_operand" "Upl, Upl")
7777 1.1.1.3 mrg (match_operand:SI 2 "aarch64_sve_ptrue_flag")
7778 1.1.1.3 mrg (SVE_INT_CMP:<VPRED>
7779 1.1.1.5 mrg (match_operand:SVE_I 3 "register_operand" "w, w")
7780 1.1.1.5 mrg (match_operand:SVE_I 4 "aarch64_sve_cmp_<sve_imm_con>_operand" "<sve_imm_con>, w"))]
7781 1.1.1.3 mrg UNSPEC_PRED_Z))
7782 1.1.1.3 mrg (clobber (reg:CC_NZC CC_REGNUM))]
7783 1.1.1.3 mrg "TARGET_SVE"
7784 1.1.1.3 mrg "@
7785 1.1.1.3 mrg cmp<cmp_op>\t%0.<Vetype>, %1/z, %3.<Vetype>, #%4
7786 1.1.1.3 mrg cmp<cmp_op>\t%0.<Vetype>, %1/z, %3.<Vetype>, %4.<Vetype>"
7787 1.1.1.3 mrg )
7788 1.1.1.3 mrg
7789 1.1.1.3 mrg ;; Predicated integer comparisons in which both the flag and predicate
7790 1.1.1.3 mrg ;; results are interesting.
7791 1.1.1.3 mrg (define_insn_and_rewrite "*cmp<cmp_op><mode>_cc"
7792 1.1.1.3 mrg [(set (reg:CC_NZC CC_REGNUM)
7793 1.1.1.3 mrg (unspec:CC_NZC
7794 1.1.1.3 mrg [(match_operand:VNx16BI 1 "register_operand" "Upl, Upl")
7795 1.1.1.3 mrg (match_operand 4)
7796 1.1.1.3 mrg (match_operand:SI 5 "aarch64_sve_ptrue_flag")
7797 1.1.1.3 mrg (unspec:<VPRED>
7798 1.1.1.3 mrg [(match_operand 6)
7799 1.1.1.3 mrg (match_operand:SI 7 "aarch64_sve_ptrue_flag")
7800 1.1.1.3 mrg (SVE_INT_CMP:<VPRED>
7801 1.1.1.5 mrg (match_operand:SVE_I 2 "register_operand" "w, w")
7802 1.1.1.5 mrg (match_operand:SVE_I 3 "aarch64_sve_cmp_<sve_imm_con>_operand" "<sve_imm_con>, w"))]
7803 1.1.1.3 mrg UNSPEC_PRED_Z)]
7804 1.1.1.3 mrg UNSPEC_PTEST))
7805 1.1.1.3 mrg (set (match_operand:<VPRED> 0 "register_operand" "=Upa, Upa")
7806 1.1.1.3 mrg (unspec:<VPRED>
7807 1.1.1.3 mrg [(match_dup 6)
7808 1.1.1.3 mrg (match_dup 7)
7809 1.1.1.3 mrg (SVE_INT_CMP:<VPRED>
7810 1.1.1.3 mrg (match_dup 2)
7811 1.1.1.3 mrg (match_dup 3))]
7812 1.1.1.3 mrg UNSPEC_PRED_Z))]
7813 1.1.1.3 mrg "TARGET_SVE
7814 1.1.1.3 mrg && aarch64_sve_same_pred_for_ptest_p (&operands[4], &operands[6])"
7815 1.1.1.2 mrg "@
7816 1.1.1.3 mrg cmp<cmp_op>\t%0.<Vetype>, %1/z, %2.<Vetype>, #%3
7817 1.1.1.3 mrg cmp<cmp_op>\t%0.<Vetype>, %1/z, %2.<Vetype>, %3.<Vetype>"
7818 1.1.1.3 mrg "&& !rtx_equal_p (operands[4], operands[6])"
7819 1.1 mrg {
7820 1.1.1.3 mrg operands[6] = copy_rtx (operands[4]);
7821 1.1.1.3 mrg operands[7] = operands[5];
7822 1.1 mrg }
7823 1.1 mrg )
7824 1.1 mrg
7825 1.1.1.3 mrg ;; Predicated integer comparisons in which only the flags result is
7826 1.1.1.3 mrg ;; interesting.
7827 1.1.1.3 mrg (define_insn_and_rewrite "*cmp<cmp_op><mode>_ptest"
7828 1.1.1.3 mrg [(set (reg:CC_NZC CC_REGNUM)
7829 1.1.1.3 mrg (unspec:CC_NZC
7830 1.1.1.3 mrg [(match_operand:VNx16BI 1 "register_operand" "Upl, Upl")
7831 1.1.1.3 mrg (match_operand 4)
7832 1.1.1.3 mrg (match_operand:SI 5 "aarch64_sve_ptrue_flag")
7833 1.1.1.3 mrg (unspec:<VPRED>
7834 1.1.1.3 mrg [(match_operand 6)
7835 1.1.1.3 mrg (match_operand:SI 7 "aarch64_sve_ptrue_flag")
7836 1.1.1.3 mrg (SVE_INT_CMP:<VPRED>
7837 1.1.1.5 mrg (match_operand:SVE_I 2 "register_operand" "w, w")
7838 1.1.1.5 mrg (match_operand:SVE_I 3 "aarch64_sve_cmp_<sve_imm_con>_operand" "<sve_imm_con>, w"))]
7839 1.1.1.3 mrg UNSPEC_PRED_Z)]
7840 1.1.1.3 mrg UNSPEC_PTEST))
7841 1.1.1.3 mrg (clobber (match_scratch:<VPRED> 0 "=Upa, Upa"))]
7842 1.1.1.3 mrg "TARGET_SVE
7843 1.1.1.3 mrg && aarch64_sve_same_pred_for_ptest_p (&operands[4], &operands[6])"
7844 1.1.1.2 mrg "@
7845 1.1.1.3 mrg cmp<cmp_op>\t%0.<Vetype>, %1/z, %2.<Vetype>, #%3
7846 1.1.1.3 mrg cmp<cmp_op>\t%0.<Vetype>, %1/z, %2.<Vetype>, %3.<Vetype>"
7847 1.1.1.3 mrg "&& !rtx_equal_p (operands[4], operands[6])"
7848 1.1 mrg {
7849 1.1.1.3 mrg operands[6] = copy_rtx (operands[4]);
7850 1.1.1.3 mrg operands[7] = operands[5];
7851 1.1 mrg }
7852 1.1 mrg )
7853 1.1 mrg
7854 1.1.1.3 mrg ;; Predicated integer comparisons, formed by combining a PTRUE-predicated
7855 1.1.1.3 mrg ;; comparison with an AND. Split the instruction into its preferred form
7856 1.1.1.3 mrg ;; at the earliest opportunity, in order to get rid of the redundant
7857 1.1.1.3 mrg ;; operand 4.
7858 1.1.1.3 mrg (define_insn_and_split "*cmp<cmp_op><mode>_and"
7859 1.1.1.3 mrg [(set (match_operand:<VPRED> 0 "register_operand" "=Upa, Upa")
7860 1.1.1.3 mrg (and:<VPRED>
7861 1.1.1.3 mrg (unspec:<VPRED>
7862 1.1.1.3 mrg [(match_operand 4)
7863 1.1.1.3 mrg (const_int SVE_KNOWN_PTRUE)
7864 1.1.1.3 mrg (SVE_INT_CMP:<VPRED>
7865 1.1.1.5 mrg (match_operand:SVE_I 2 "register_operand" "w, w")
7866 1.1.1.5 mrg (match_operand:SVE_I 3 "aarch64_sve_cmp_<sve_imm_con>_operand" "<sve_imm_con>, w"))]
7867 1.1.1.3 mrg UNSPEC_PRED_Z)
7868 1.1.1.3 mrg (match_operand:<VPRED> 1 "register_operand" "Upl, Upl")))
7869 1.1.1.3 mrg (clobber (reg:CC_NZC CC_REGNUM))]
7870 1.1 mrg "TARGET_SVE"
7871 1.1.1.3 mrg "#"
7872 1.1.1.3 mrg "&& 1"
7873 1.1.1.3 mrg [(parallel
7874 1.1.1.3 mrg [(set (match_dup 0)
7875 1.1.1.3 mrg (unspec:<VPRED>
7876 1.1.1.3 mrg [(match_dup 1)
7877 1.1.1.3 mrg (const_int SVE_MAYBE_NOT_PTRUE)
7878 1.1.1.3 mrg (SVE_INT_CMP:<VPRED>
7879 1.1.1.3 mrg (match_dup 2)
7880 1.1.1.3 mrg (match_dup 3))]
7881 1.1.1.3 mrg UNSPEC_PRED_Z))
7882 1.1.1.3 mrg (clobber (reg:CC_NZC CC_REGNUM))])]
7883 1.1 mrg )
7884 1.1 mrg
7885 1.1.1.3 mrg ;; Predicated integer wide comparisons.
7886 1.1.1.3 mrg (define_insn "@aarch64_pred_cmp<cmp_op><mode>_wide"
7887 1.1.1.3 mrg [(set (match_operand:<VPRED> 0 "register_operand" "=Upa")
7888 1.1.1.3 mrg (unspec:<VPRED>
7889 1.1.1.3 mrg [(match_operand:VNx16BI 1 "register_operand" "Upl")
7890 1.1.1.3 mrg (match_operand:SI 2 "aarch64_sve_ptrue_flag")
7891 1.1.1.3 mrg (unspec:<VPRED>
7892 1.1.1.3 mrg [(match_operand:SVE_FULL_BHSI 3 "register_operand" "w")
7893 1.1.1.3 mrg (match_operand:VNx2DI 4 "register_operand" "w")]
7894 1.1.1.3 mrg SVE_COND_INT_CMP_WIDE)]
7895 1.1.1.3 mrg UNSPEC_PRED_Z))
7896 1.1.1.3 mrg (clobber (reg:CC_NZC CC_REGNUM))]
7897 1.1.1.2 mrg "TARGET_SVE"
7898 1.1.1.3 mrg "cmp<cmp_op>\t%0.<Vetype>, %1/z, %3.<Vetype>, %4.d"
7899 1.1.1.2 mrg )
7900 1.1.1.2 mrg
7901 1.1.1.3 mrg ;; Predicated integer wide comparisons in which both the flag and
7902 1.1.1.3 mrg ;; predicate results are interesting.
7903 1.1.1.3 mrg (define_insn "*aarch64_pred_cmp<cmp_op><mode>_wide_cc"
7904 1.1.1.3 mrg [(set (reg:CC_NZC CC_REGNUM)
7905 1.1.1.3 mrg (unspec:CC_NZC
7906 1.1.1.3 mrg [(match_operand:VNx16BI 1 "register_operand" "Upl")
7907 1.1.1.3 mrg (match_operand 4)
7908 1.1.1.3 mrg (match_operand:SI 5 "aarch64_sve_ptrue_flag")
7909 1.1.1.3 mrg (unspec:<VPRED>
7910 1.1.1.3 mrg [(match_operand:VNx16BI 6 "register_operand" "Upl")
7911 1.1.1.3 mrg (match_operand:SI 7 "aarch64_sve_ptrue_flag")
7912 1.1.1.3 mrg (unspec:<VPRED>
7913 1.1.1.3 mrg [(match_operand:SVE_FULL_BHSI 2 "register_operand" "w")
7914 1.1.1.3 mrg (match_operand:VNx2DI 3 "register_operand" "w")]
7915 1.1.1.3 mrg SVE_COND_INT_CMP_WIDE)]
7916 1.1.1.3 mrg UNSPEC_PRED_Z)]
7917 1.1.1.3 mrg UNSPEC_PTEST))
7918 1.1.1.3 mrg (set (match_operand:<VPRED> 0 "register_operand" "=Upa")
7919 1.1.1.3 mrg (unspec:<VPRED>
7920 1.1.1.3 mrg [(match_dup 6)
7921 1.1.1.3 mrg (match_dup 7)
7922 1.1.1.3 mrg (unspec:<VPRED>
7923 1.1.1.3 mrg [(match_dup 2)
7924 1.1.1.3 mrg (match_dup 3)]
7925 1.1.1.3 mrg SVE_COND_INT_CMP_WIDE)]
7926 1.1.1.3 mrg UNSPEC_PRED_Z))]
7927 1.1.1.3 mrg "TARGET_SVE
7928 1.1.1.3 mrg && aarch64_sve_same_pred_for_ptest_p (&operands[4], &operands[6])"
7929 1.1.1.3 mrg "cmp<cmp_op>\t%0.<Vetype>, %1/z, %2.<Vetype>, %3.d"
7930 1.1.1.2 mrg )
7931 1.1.1.2 mrg
7932 1.1.1.3 mrg ;; Predicated integer wide comparisons in which only the flags result
7933 1.1.1.3 mrg ;; is interesting.
7934 1.1.1.3 mrg (define_insn "*aarch64_pred_cmp<cmp_op><mode>_wide_ptest"
7935 1.1.1.3 mrg [(set (reg:CC_NZC CC_REGNUM)
7936 1.1.1.3 mrg (unspec:CC_NZC
7937 1.1.1.3 mrg [(match_operand:VNx16BI 1 "register_operand" "Upl")
7938 1.1.1.3 mrg (match_operand 4)
7939 1.1.1.3 mrg (match_operand:SI 5 "aarch64_sve_ptrue_flag")
7940 1.1.1.3 mrg (unspec:<VPRED>
7941 1.1.1.3 mrg [(match_operand:VNx16BI 6 "register_operand" "Upl")
7942 1.1.1.3 mrg (match_operand:SI 7 "aarch64_sve_ptrue_flag")
7943 1.1.1.3 mrg (unspec:<VPRED>
7944 1.1.1.3 mrg [(match_operand:SVE_FULL_BHSI 2 "register_operand" "w")
7945 1.1.1.3 mrg (match_operand:VNx2DI 3 "register_operand" "w")]
7946 1.1.1.3 mrg SVE_COND_INT_CMP_WIDE)]
7947 1.1.1.3 mrg UNSPEC_PRED_Z)]
7948 1.1.1.3 mrg UNSPEC_PTEST))
7949 1.1.1.3 mrg (clobber (match_scratch:<VPRED> 0 "=Upa"))]
7950 1.1.1.3 mrg "TARGET_SVE
7951 1.1.1.3 mrg && aarch64_sve_same_pred_for_ptest_p (&operands[4], &operands[6])"
7952 1.1.1.3 mrg "cmp<cmp_op>\t%0.<Vetype>, %1/z, %2.<Vetype>, %3.d"
7953 1.1.1.2 mrg )
7954 1.1.1.2 mrg
7955 1.1.1.3 mrg ;; -------------------------------------------------------------------------
7956 1.1.1.3 mrg ;; ---- [INT] While tests
7957 1.1.1.3 mrg ;; -------------------------------------------------------------------------
7958 1.1.1.3 mrg ;; Includes:
7959 1.1.1.3 mrg ;; - WHILEGE (SVE2)
7960 1.1.1.3 mrg ;; - WHILEGT (SVE2)
7961 1.1.1.3 mrg ;; - WHILEHI (SVE2)
7962 1.1.1.3 mrg ;; - WHILEHS (SVE2)
7963 1.1.1.3 mrg ;; - WHILELE
7964 1.1.1.3 mrg ;; - WHILELO
7965 1.1.1.3 mrg ;; - WHILELS
7966 1.1.1.3 mrg ;; - WHILELT
7967 1.1.1.3 mrg ;; - WHILERW (SVE2)
7968 1.1.1.3 mrg ;; - WHILEWR (SVE2)
7969 1.1.1.3 mrg ;; -------------------------------------------------------------------------
7970 1.1.1.3 mrg
7971 1.1.1.3 mrg ;; Set element I of the result if (cmp (plus operand1 J) operand2) is
7972 1.1.1.3 mrg ;; true for all J in [0, I].
7973 1.1.1.3 mrg (define_insn "@while_<while_optab_cmp><GPI:mode><PRED_ALL:mode>"
7974 1.1.1.3 mrg [(set (match_operand:PRED_ALL 0 "register_operand" "=Upa")
7975 1.1.1.3 mrg (unspec:PRED_ALL [(match_operand:GPI 1 "aarch64_reg_or_zero" "rZ")
7976 1.1.1.3 mrg (match_operand:GPI 2 "aarch64_reg_or_zero" "rZ")]
7977 1.1.1.3 mrg SVE_WHILE))
7978 1.1.1.3 mrg (clobber (reg:CC_NZC CC_REGNUM))]
7979 1.1.1.2 mrg "TARGET_SVE"
7980 1.1.1.3 mrg "while<cmp_op>\t%0.<PRED_ALL:Vetype>, %<w>1, %<w>2"
7981 1.1.1.2 mrg )
7982 1.1.1.2 mrg
7983 1.1.1.3 mrg ;; The WHILE instructions set the flags in the same way as a PTEST with
7984 1.1.1.3 mrg ;; a PTRUE GP. Handle the case in which both results are useful. The GP
7985 1.1.1.3 mrg ;; operands to the PTEST aren't needed, so we allow them to be anything.
7986 1.1.1.3 mrg (define_insn_and_rewrite "*while_<while_optab_cmp><GPI:mode><PRED_ALL:mode>_cc"
7987 1.1.1.3 mrg [(set (reg:CC_NZC CC_REGNUM)
7988 1.1.1.3 mrg (unspec:CC_NZC
7989 1.1.1.3 mrg [(match_operand 3)
7990 1.1.1.3 mrg (match_operand 4)
7991 1.1.1.3 mrg (const_int SVE_KNOWN_PTRUE)
7992 1.1.1.3 mrg (unspec:PRED_ALL
7993 1.1.1.3 mrg [(match_operand:GPI 1 "aarch64_reg_or_zero" "rZ")
7994 1.1.1.3 mrg (match_operand:GPI 2 "aarch64_reg_or_zero" "rZ")]
7995 1.1.1.3 mrg SVE_WHILE)]
7996 1.1.1.3 mrg UNSPEC_PTEST))
7997 1.1.1.3 mrg (set (match_operand:PRED_ALL 0 "register_operand" "=Upa")
7998 1.1.1.3 mrg (unspec:PRED_ALL [(match_dup 1)
7999 1.1.1.3 mrg (match_dup 2)]
8000 1.1.1.3 mrg SVE_WHILE))]
8001 1.1.1.2 mrg "TARGET_SVE"
8002 1.1.1.3 mrg "while<cmp_op>\t%0.<PRED_ALL:Vetype>, %<w>1, %<w>2"
8003 1.1.1.3 mrg ;; Force the compiler to drop the unused predicate operand, so that we
8004 1.1.1.3 mrg ;; don't have an unnecessary PTRUE.
8005 1.1.1.3 mrg "&& (!CONSTANT_P (operands[3]) || !CONSTANT_P (operands[4]))"
8006 1.1.1.3 mrg {
8007 1.1.1.3 mrg operands[3] = CONSTM1_RTX (VNx16BImode);
8008 1.1.1.3 mrg operands[4] = CONSTM1_RTX (<PRED_ALL:MODE>mode);
8009 1.1.1.3 mrg }
8010 1.1.1.2 mrg )
8011 1.1.1.2 mrg
8012 1.1.1.3 mrg ;; Same, but handle the case in which only the flags result is useful.
8013 1.1.1.3 mrg (define_insn_and_rewrite "@while_<while_optab_cmp><GPI:mode><PRED_ALL:mode>_ptest"
8014 1.1.1.3 mrg [(set (reg:CC_NZC CC_REGNUM)
8015 1.1.1.3 mrg (unspec:CC_NZC
8016 1.1.1.3 mrg [(match_operand 3)
8017 1.1.1.3 mrg (match_operand 4)
8018 1.1.1.3 mrg (const_int SVE_KNOWN_PTRUE)
8019 1.1.1.3 mrg (unspec:PRED_ALL
8020 1.1.1.3 mrg [(match_operand:GPI 1 "aarch64_reg_or_zero" "rZ")
8021 1.1.1.3 mrg (match_operand:GPI 2 "aarch64_reg_or_zero" "rZ")]
8022 1.1.1.3 mrg SVE_WHILE)]
8023 1.1.1.3 mrg UNSPEC_PTEST))
8024 1.1.1.3 mrg (clobber (match_scratch:PRED_ALL 0 "=Upa"))]
8025 1.1.1.2 mrg "TARGET_SVE"
8026 1.1.1.3 mrg "while<cmp_op>\t%0.<PRED_ALL:Vetype>, %<w>1, %<w>2"
8027 1.1.1.3 mrg ;; Force the compiler to drop the unused predicate operand, so that we
8028 1.1.1.3 mrg ;; don't have an unnecessary PTRUE.
8029 1.1.1.3 mrg "&& (!CONSTANT_P (operands[3]) || !CONSTANT_P (operands[4]))"
8030 1.1.1.3 mrg {
8031 1.1.1.3 mrg operands[3] = CONSTM1_RTX (VNx16BImode);
8032 1.1.1.3 mrg operands[4] = CONSTM1_RTX (<PRED_ALL:MODE>mode);
8033 1.1.1.3 mrg }
8034 1.1.1.2 mrg )
8035 1.1.1.2 mrg
8036 1.1.1.3 mrg ;; -------------------------------------------------------------------------
8037 1.1.1.3 mrg ;; ---- [FP] Direct comparisons
8038 1.1.1.3 mrg ;; -------------------------------------------------------------------------
8039 1.1.1.3 mrg ;; Includes:
8040 1.1.1.3 mrg ;; - FCMEQ
8041 1.1.1.3 mrg ;; - FCMGE
8042 1.1.1.3 mrg ;; - FCMGT
8043 1.1.1.3 mrg ;; - FCMLE
8044 1.1.1.3 mrg ;; - FCMLT
8045 1.1.1.3 mrg ;; - FCMNE
8046 1.1.1.3 mrg ;; - FCMUO
8047 1.1.1.3 mrg ;; -------------------------------------------------------------------------
8048 1.1.1.3 mrg
8049 1.1.1.3 mrg ;; Floating-point comparisons. All comparisons except FCMUO allow a zero
8050 1.1.1.3 mrg ;; operand; aarch64_expand_sve_vec_cmp_float handles the case of an FCMUO
8051 1.1.1.3 mrg ;; with zero.
8052 1.1.1.3 mrg (define_expand "vec_cmp<mode><vpred>"
8053 1.1.1.3 mrg [(set (match_operand:<VPRED> 0 "register_operand")
8054 1.1.1.3 mrg (match_operator:<VPRED> 1 "comparison_operator"
8055 1.1.1.3 mrg [(match_operand:SVE_FULL_F 2 "register_operand")
8056 1.1.1.3 mrg (match_operand:SVE_FULL_F 3 "aarch64_simd_reg_or_zero")]))]
8057 1.1.1.2 mrg "TARGET_SVE"
8058 1.1.1.3 mrg {
8059 1.1.1.3 mrg aarch64_expand_sve_vec_cmp_float (operands[0], GET_CODE (operands[1]),
8060 1.1.1.3 mrg operands[2], operands[3], false);
8061 1.1.1.3 mrg DONE;
8062 1.1.1.3 mrg }
8063 1.1.1.2 mrg )
8064 1.1.1.2 mrg
8065 1.1.1.3 mrg ;; Predicated floating-point comparisons.
8066 1.1.1.3 mrg (define_insn "@aarch64_pred_fcm<cmp_op><mode>"
8067 1.1.1.3 mrg [(set (match_operand:<VPRED> 0 "register_operand" "=Upa, Upa")
8068 1.1.1.3 mrg (unspec:<VPRED>
8069 1.1.1.2 mrg [(match_operand:<VPRED> 1 "register_operand" "Upl, Upl")
8070 1.1.1.3 mrg (match_operand:SI 2 "aarch64_sve_ptrue_flag")
8071 1.1.1.3 mrg (match_operand:SVE_FULL_F 3 "register_operand" "w, w")
8072 1.1.1.3 mrg (match_operand:SVE_FULL_F 4 "aarch64_simd_reg_or_zero" "Dz, w")]
8073 1.1.1.3 mrg SVE_COND_FP_CMP_I0))]
8074 1.1.1.2 mrg "TARGET_SVE"
8075 1.1.1.2 mrg "@
8076 1.1.1.3 mrg fcm<cmp_op>\t%0.<Vetype>, %1/z, %3.<Vetype>, #0.0
8077 1.1.1.3 mrg fcm<cmp_op>\t%0.<Vetype>, %1/z, %3.<Vetype>, %4.<Vetype>"
8078 1.1.1.2 mrg )
8079 1.1.1.2 mrg
8080 1.1.1.3 mrg ;; Same for unordered comparisons.
8081 1.1.1.3 mrg (define_insn "@aarch64_pred_fcmuo<mode>"
8082 1.1.1.3 mrg [(set (match_operand:<VPRED> 0 "register_operand" "=Upa")
8083 1.1.1.3 mrg (unspec:<VPRED>
8084 1.1 mrg [(match_operand:<VPRED> 1 "register_operand" "Upl")
8085 1.1.1.3 mrg (match_operand:SI 2 "aarch64_sve_ptrue_flag")
8086 1.1.1.3 mrg (match_operand:SVE_FULL_F 3 "register_operand" "w")
8087 1.1.1.3 mrg (match_operand:SVE_FULL_F 4 "register_operand" "w")]
8088 1.1.1.3 mrg UNSPEC_COND_FCMUO))]
8089 1.1 mrg "TARGET_SVE"
8090 1.1.1.3 mrg "fcmuo\t%0.<Vetype>, %1/z, %3.<Vetype>, %4.<Vetype>"
8091 1.1.1.2 mrg )
8092 1.1.1.2 mrg
8093 1.1.1.3 mrg ;; Floating-point comparisons predicated on a PTRUE, with the results ANDed
8094 1.1.1.3 mrg ;; with another predicate P. This does not have the same trapping behavior
8095 1.1.1.3 mrg ;; as predicating the comparison itself on P, but it's a legitimate fold,
8096 1.1.1.3 mrg ;; since we can drop any potentially-trapping operations whose results
8097 1.1.1.3 mrg ;; are not needed.
8098 1.1.1.3 mrg ;;
8099 1.1.1.3 mrg ;; Split the instruction into its preferred form (below) at the earliest
8100 1.1.1.3 mrg ;; opportunity, in order to get rid of the redundant operand 1.
8101 1.1.1.3 mrg (define_insn_and_split "*fcm<cmp_op><mode>_and_combine"
8102 1.1.1.3 mrg [(set (match_operand:<VPRED> 0 "register_operand" "=Upa, Upa")
8103 1.1.1.3 mrg (and:<VPRED>
8104 1.1.1.3 mrg (unspec:<VPRED>
8105 1.1.1.3 mrg [(match_operand:<VPRED> 1)
8106 1.1.1.3 mrg (const_int SVE_KNOWN_PTRUE)
8107 1.1.1.3 mrg (match_operand:SVE_FULL_F 2 "register_operand" "w, w")
8108 1.1.1.3 mrg (match_operand:SVE_FULL_F 3 "aarch64_simd_reg_or_zero" "Dz, w")]
8109 1.1.1.3 mrg SVE_COND_FP_CMP_I0)
8110 1.1.1.3 mrg (match_operand:<VPRED> 4 "register_operand" "Upl, Upl")))]
8111 1.1.1.2 mrg "TARGET_SVE"
8112 1.1.1.3 mrg "#"
8113 1.1.1.3 mrg "&& 1"
8114 1.1.1.3 mrg [(set (match_dup 0)
8115 1.1.1.3 mrg (unspec:<VPRED>
8116 1.1.1.3 mrg [(match_dup 4)
8117 1.1.1.3 mrg (const_int SVE_MAYBE_NOT_PTRUE)
8118 1.1.1.3 mrg (match_dup 2)
8119 1.1.1.3 mrg (match_dup 3)]
8120 1.1.1.3 mrg SVE_COND_FP_CMP_I0))]
8121 1.1.1.2 mrg )
8122 1.1.1.2 mrg
8123 1.1.1.3 mrg ;; Same for unordered comparisons.
8124 1.1.1.3 mrg (define_insn_and_split "*fcmuo<mode>_and_combine"
8125 1.1.1.3 mrg [(set (match_operand:<VPRED> 0 "register_operand" "=Upa")
8126 1.1.1.3 mrg (and:<VPRED>
8127 1.1.1.3 mrg (unspec:<VPRED>
8128 1.1.1.3 mrg [(match_operand:<VPRED> 1)
8129 1.1.1.3 mrg (const_int SVE_KNOWN_PTRUE)
8130 1.1.1.3 mrg (match_operand:SVE_FULL_F 2 "register_operand" "w")
8131 1.1.1.3 mrg (match_operand:SVE_FULL_F 3 "register_operand" "w")]
8132 1.1.1.3 mrg UNSPEC_COND_FCMUO)
8133 1.1.1.3 mrg (match_operand:<VPRED> 4 "register_operand" "Upl")))]
8134 1.1.1.2 mrg "TARGET_SVE"
8135 1.1.1.2 mrg "#"
8136 1.1.1.3 mrg "&& 1"
8137 1.1.1.3 mrg [(set (match_dup 0)
8138 1.1.1.3 mrg (unspec:<VPRED>
8139 1.1.1.3 mrg [(match_dup 4)
8140 1.1.1.3 mrg (const_int SVE_MAYBE_NOT_PTRUE)
8141 1.1.1.3 mrg (match_dup 2)
8142 1.1.1.3 mrg (match_dup 3)]
8143 1.1.1.3 mrg UNSPEC_COND_FCMUO))]
8144 1.1.1.2 mrg )
8145 1.1.1.2 mrg
8146 1.1.1.5 mrg ;; Similar to *fcm<cmp_op><mode>_and_combine, but for BIC rather than AND.
8147 1.1.1.5 mrg ;; In this case, we still need a separate NOT/BIC operation, but predicating
8148 1.1.1.5 mrg ;; the comparison on the BIC operand removes the need for a PTRUE.
8149 1.1.1.5 mrg (define_insn_and_split "*fcm<cmp_op><mode>_bic_combine"
8150 1.1.1.5 mrg [(set (match_operand:<VPRED> 0 "register_operand" "=Upa")
8151 1.1.1.5 mrg (and:<VPRED>
8152 1.1.1.5 mrg (and:<VPRED>
8153 1.1.1.5 mrg (not:<VPRED>
8154 1.1.1.5 mrg (unspec:<VPRED>
8155 1.1.1.5 mrg [(match_operand:<VPRED> 1)
8156 1.1.1.5 mrg (const_int SVE_KNOWN_PTRUE)
8157 1.1.1.5 mrg (match_operand:SVE_FULL_F 2 "register_operand" "w")
8158 1.1.1.5 mrg (match_operand:SVE_FULL_F 3 "aarch64_simd_reg_or_zero" "wDz")]
8159 1.1.1.5 mrg SVE_COND_FP_CMP_I0))
8160 1.1.1.5 mrg (match_operand:<VPRED> 4 "register_operand" "Upa"))
8161 1.1.1.5 mrg (match_dup:<VPRED> 1)))
8162 1.1.1.5 mrg (clobber (match_scratch:<VPRED> 5 "=&Upl"))]
8163 1.1.1.5 mrg "TARGET_SVE"
8164 1.1.1.5 mrg "#"
8165 1.1.1.5 mrg "&& 1"
8166 1.1.1.5 mrg [(set (match_dup 5)
8167 1.1.1.5 mrg (unspec:<VPRED>
8168 1.1.1.5 mrg [(match_dup 4)
8169 1.1.1.5 mrg (const_int SVE_MAYBE_NOT_PTRUE)
8170 1.1.1.5 mrg (match_dup 2)
8171 1.1.1.5 mrg (match_dup 3)]
8172 1.1.1.5 mrg SVE_COND_FP_CMP_I0))
8173 1.1.1.5 mrg (set (match_dup 0)
8174 1.1.1.5 mrg (and:<VPRED>
8175 1.1.1.5 mrg (not:<VPRED>
8176 1.1.1.5 mrg (match_dup 5))
8177 1.1.1.5 mrg (match_dup 4)))]
8178 1.1.1.5 mrg {
8179 1.1.1.5 mrg if (can_create_pseudo_p ())
8180 1.1.1.5 mrg operands[5] = gen_reg_rtx (<VPRED>mode);
8181 1.1.1.5 mrg }
8182 1.1.1.5 mrg )
8183 1.1.1.5 mrg
8184 1.1.1.5 mrg ;; Make sure that we expand to a nor when the operand 4 of
8185 1.1.1.5 mrg ;; *fcm<cmp_op><mode>_bic_combine is a not.
8186 1.1.1.5 mrg (define_insn_and_split "*fcm<cmp_op><mode>_nor_combine"
8187 1.1.1.5 mrg [(set (match_operand:<VPRED> 0 "register_operand" "=Upa")
8188 1.1.1.5 mrg (and:<VPRED>
8189 1.1.1.5 mrg (and:<VPRED>
8190 1.1.1.5 mrg (not:<VPRED>
8191 1.1.1.5 mrg (unspec:<VPRED>
8192 1.1.1.5 mrg [(match_operand:<VPRED> 1)
8193 1.1.1.5 mrg (const_int SVE_KNOWN_PTRUE)
8194 1.1.1.5 mrg (match_operand:SVE_FULL_F 2 "register_operand" "w")
8195 1.1.1.5 mrg (match_operand:SVE_FULL_F 3 "aarch64_simd_reg_or_zero" "wDz")]
8196 1.1.1.5 mrg SVE_COND_FP_CMP_I0))
8197 1.1.1.5 mrg (not:<VPRED>
8198 1.1.1.5 mrg (match_operand:<VPRED> 4 "register_operand" "Upa")))
8199 1.1.1.5 mrg (match_dup:<VPRED> 1)))
8200 1.1.1.5 mrg (clobber (match_scratch:<VPRED> 5 "=&Upl"))]
8201 1.1.1.5 mrg "TARGET_SVE"
8202 1.1.1.5 mrg "#"
8203 1.1.1.5 mrg "&& 1"
8204 1.1.1.5 mrg [(set (match_dup 5)
8205 1.1.1.5 mrg (unspec:<VPRED>
8206 1.1.1.5 mrg [(match_dup 1)
8207 1.1.1.5 mrg (const_int SVE_KNOWN_PTRUE)
8208 1.1.1.5 mrg (match_dup 2)
8209 1.1.1.5 mrg (match_dup 3)]
8210 1.1.1.5 mrg SVE_COND_FP_CMP_I0))
8211 1.1.1.5 mrg (set (match_dup 0)
8212 1.1.1.5 mrg (and:<VPRED>
8213 1.1.1.5 mrg (and:<VPRED>
8214 1.1.1.5 mrg (not:<VPRED>
8215 1.1.1.5 mrg (match_dup 5))
8216 1.1.1.5 mrg (not:<VPRED>
8217 1.1.1.5 mrg (match_dup 4)))
8218 1.1.1.5 mrg (match_dup 1)))]
8219 1.1.1.5 mrg {
8220 1.1.1.5 mrg if (can_create_pseudo_p ())
8221 1.1.1.5 mrg operands[5] = gen_reg_rtx (<VPRED>mode);
8222 1.1.1.5 mrg }
8223 1.1.1.5 mrg )
8224 1.1.1.5 mrg
8225 1.1.1.5 mrg (define_insn_and_split "*fcmuo<mode>_bic_combine"
8226 1.1.1.5 mrg [(set (match_operand:<VPRED> 0 "register_operand" "=Upa")
8227 1.1.1.5 mrg (and:<VPRED>
8228 1.1.1.5 mrg (and:<VPRED>
8229 1.1.1.5 mrg (not:<VPRED>
8230 1.1.1.5 mrg (unspec:<VPRED>
8231 1.1.1.5 mrg [(match_operand:<VPRED> 1)
8232 1.1.1.5 mrg (const_int SVE_KNOWN_PTRUE)
8233 1.1.1.5 mrg (match_operand:SVE_FULL_F 2 "register_operand" "w")
8234 1.1.1.5 mrg (match_operand:SVE_FULL_F 3 "register_operand" "w")]
8235 1.1.1.5 mrg UNSPEC_COND_FCMUO))
8236 1.1.1.5 mrg (match_operand:<VPRED> 4 "register_operand" "Upa"))
8237 1.1.1.5 mrg (match_dup:<VPRED> 1)))
8238 1.1.1.5 mrg (clobber (match_scratch:<VPRED> 5 "=&Upl"))]
8239 1.1.1.5 mrg "TARGET_SVE"
8240 1.1.1.5 mrg "#"
8241 1.1.1.5 mrg "&& 1"
8242 1.1.1.5 mrg [(set (match_dup 5)
8243 1.1.1.5 mrg (unspec:<VPRED>
8244 1.1.1.5 mrg [(match_dup 4)
8245 1.1.1.5 mrg (const_int SVE_MAYBE_NOT_PTRUE)
8246 1.1.1.5 mrg (match_dup 2)
8247 1.1.1.5 mrg (match_dup 3)]
8248 1.1.1.5 mrg UNSPEC_COND_FCMUO))
8249 1.1.1.5 mrg (set (match_dup 0)
8250 1.1.1.5 mrg (and:<VPRED>
8251 1.1.1.5 mrg (not:<VPRED>
8252 1.1.1.5 mrg (match_dup 5))
8253 1.1.1.5 mrg (match_dup 4)))]
8254 1.1.1.5 mrg {
8255 1.1.1.5 mrg if (can_create_pseudo_p ())
8256 1.1.1.5 mrg operands[5] = gen_reg_rtx (<VPRED>mode);
8257 1.1.1.5 mrg }
8258 1.1.1.5 mrg )
8259 1.1.1.5 mrg
8260 1.1.1.5 mrg ;; Same for unordered comparisons.
8261 1.1.1.5 mrg (define_insn_and_split "*fcmuo<mode>_nor_combine"
8262 1.1.1.5 mrg [(set (match_operand:<VPRED> 0 "register_operand" "=Upa")
8263 1.1.1.5 mrg (and:<VPRED>
8264 1.1.1.5 mrg (and:<VPRED>
8265 1.1.1.5 mrg (not:<VPRED>
8266 1.1.1.5 mrg (unspec:<VPRED>
8267 1.1.1.5 mrg [(match_operand:<VPRED> 1)
8268 1.1.1.5 mrg (const_int SVE_KNOWN_PTRUE)
8269 1.1.1.5 mrg (match_operand:SVE_FULL_F 2 "register_operand" "w")
8270 1.1.1.5 mrg (match_operand:SVE_FULL_F 3 "register_operand" "w")]
8271 1.1.1.5 mrg UNSPEC_COND_FCMUO))
8272 1.1.1.5 mrg (not:<VPRED>
8273 1.1.1.5 mrg (match_operand:<VPRED> 4 "register_operand" "Upa")))
8274 1.1.1.5 mrg (match_dup:<VPRED> 1)))
8275 1.1.1.5 mrg (clobber (match_scratch:<VPRED> 5 "=&Upl"))]
8276 1.1.1.5 mrg "TARGET_SVE"
8277 1.1.1.5 mrg "#"
8278 1.1.1.5 mrg "&& 1"
8279 1.1.1.5 mrg [(set (match_dup 5)
8280 1.1.1.5 mrg (unspec:<VPRED>
8281 1.1.1.5 mrg [(match_dup 1)
8282 1.1.1.5 mrg (const_int SVE_KNOWN_PTRUE)
8283 1.1.1.5 mrg (match_dup 2)
8284 1.1.1.5 mrg (match_dup 3)]
8285 1.1.1.5 mrg UNSPEC_COND_FCMUO))
8286 1.1.1.5 mrg (set (match_dup 0)
8287 1.1.1.5 mrg (and:<VPRED>
8288 1.1.1.5 mrg (and:<VPRED>
8289 1.1.1.5 mrg (not:<VPRED>
8290 1.1.1.5 mrg (match_dup 5))
8291 1.1.1.5 mrg (not:<VPRED>
8292 1.1.1.5 mrg (match_dup 4)))
8293 1.1.1.5 mrg (match_dup 1)))]
8294 1.1.1.5 mrg {
8295 1.1.1.5 mrg if (can_create_pseudo_p ())
8296 1.1.1.5 mrg operands[5] = gen_reg_rtx (<VPRED>mode);
8297 1.1.1.5 mrg }
8298 1.1.1.5 mrg )
8299 1.1.1.5 mrg
8300 1.1.1.3 mrg ;; -------------------------------------------------------------------------
8301 1.1.1.3 mrg ;; ---- [FP] Absolute comparisons
8302 1.1.1.3 mrg ;; -------------------------------------------------------------------------
8303 1.1.1.3 mrg ;; Includes:
8304 1.1.1.3 mrg ;; - FACGE
8305 1.1.1.3 mrg ;; - FACGT
8306 1.1.1.3 mrg ;; - FACLE
8307 1.1.1.3 mrg ;; - FACLT
8308 1.1.1.3 mrg ;; -------------------------------------------------------------------------
8309 1.1.1.3 mrg
8310 1.1.1.3 mrg ;; Predicated floating-point absolute comparisons.
8311 1.1.1.3 mrg (define_expand "@aarch64_pred_fac<cmp_op><mode>"
8312 1.1.1.3 mrg [(set (match_operand:<VPRED> 0 "register_operand")
8313 1.1.1.3 mrg (unspec:<VPRED>
8314 1.1.1.3 mrg [(match_operand:<VPRED> 1 "register_operand")
8315 1.1.1.3 mrg (match_operand:SI 2 "aarch64_sve_ptrue_flag")
8316 1.1.1.3 mrg (unspec:SVE_FULL_F
8317 1.1.1.3 mrg [(match_dup 1)
8318 1.1.1.3 mrg (match_dup 2)
8319 1.1.1.3 mrg (match_operand:SVE_FULL_F 3 "register_operand")]
8320 1.1.1.3 mrg UNSPEC_COND_FABS)
8321 1.1.1.3 mrg (unspec:SVE_FULL_F
8322 1.1.1.3 mrg [(match_dup 1)
8323 1.1.1.3 mrg (match_dup 2)
8324 1.1.1.3 mrg (match_operand:SVE_FULL_F 4 "register_operand")]
8325 1.1.1.3 mrg UNSPEC_COND_FABS)]
8326 1.1.1.3 mrg SVE_COND_FP_ABS_CMP))]
8327 1.1.1.2 mrg "TARGET_SVE"
8328 1.1.1.2 mrg )
8329 1.1.1.2 mrg
8330 1.1.1.3 mrg (define_insn_and_rewrite "*aarch64_pred_fac<cmp_op><mode>_relaxed"
8331 1.1.1.3 mrg [(set (match_operand:<VPRED> 0 "register_operand" "=Upa")
8332 1.1.1.3 mrg (unspec:<VPRED>
8333 1.1.1.3 mrg [(match_operand:<VPRED> 1 "register_operand" "Upl")
8334 1.1.1.3 mrg (match_operand:SI 4 "aarch64_sve_ptrue_flag")
8335 1.1.1.3 mrg (unspec:SVE_FULL_F
8336 1.1.1.3 mrg [(match_operand 5)
8337 1.1.1.3 mrg (const_int SVE_RELAXED_GP)
8338 1.1.1.3 mrg (match_operand:SVE_FULL_F 2 "register_operand" "w")]
8339 1.1.1.3 mrg UNSPEC_COND_FABS)
8340 1.1.1.3 mrg (unspec:SVE_FULL_F
8341 1.1.1.3 mrg [(match_operand 6)
8342 1.1.1.3 mrg (const_int SVE_RELAXED_GP)
8343 1.1.1.3 mrg (match_operand:SVE_FULL_F 3 "register_operand" "w")]
8344 1.1.1.3 mrg UNSPEC_COND_FABS)]
8345 1.1.1.3 mrg SVE_COND_FP_ABS_CMP))]
8346 1.1.1.3 mrg "TARGET_SVE"
8347 1.1.1.3 mrg "fac<cmp_op>\t%0.<Vetype>, %1/z, %2.<Vetype>, %3.<Vetype>"
8348 1.1.1.3 mrg "&& (!rtx_equal_p (operands[1], operands[5])
8349 1.1.1.3 mrg || !rtx_equal_p (operands[1], operands[6]))"
8350 1.1.1.3 mrg {
8351 1.1.1.3 mrg operands[5] = copy_rtx (operands[1]);
8352 1.1.1.3 mrg operands[6] = copy_rtx (operands[1]);
8353 1.1.1.3 mrg }
8354 1.1.1.3 mrg )
8355 1.1.1.3 mrg
8356 1.1.1.3 mrg (define_insn "*aarch64_pred_fac<cmp_op><mode>_strict"
8357 1.1.1.3 mrg [(set (match_operand:<VPRED> 0 "register_operand" "=Upa")
8358 1.1.1.3 mrg (unspec:<VPRED>
8359 1.1.1.3 mrg [(match_operand:<VPRED> 1 "register_operand" "Upl")
8360 1.1.1.3 mrg (match_operand:SI 4 "aarch64_sve_ptrue_flag")
8361 1.1.1.3 mrg (unspec:SVE_FULL_F
8362 1.1.1.3 mrg [(match_dup 1)
8363 1.1.1.3 mrg (match_operand:SI 5 "aarch64_sve_gp_strictness")
8364 1.1.1.3 mrg (match_operand:SVE_FULL_F 2 "register_operand" "w")]
8365 1.1.1.3 mrg UNSPEC_COND_FABS)
8366 1.1.1.3 mrg (unspec:SVE_FULL_F
8367 1.1.1.3 mrg [(match_dup 1)
8368 1.1.1.3 mrg (match_operand:SI 6 "aarch64_sve_gp_strictness")
8369 1.1.1.3 mrg (match_operand:SVE_FULL_F 3 "register_operand" "w")]
8370 1.1.1.3 mrg UNSPEC_COND_FABS)]
8371 1.1.1.3 mrg SVE_COND_FP_ABS_CMP))]
8372 1.1.1.3 mrg "TARGET_SVE"
8373 1.1.1.3 mrg "fac<cmp_op>\t%0.<Vetype>, %1/z, %2.<Vetype>, %3.<Vetype>"
8374 1.1.1.3 mrg )
8375 1.1.1.3 mrg
8376 1.1.1.3 mrg ;; -------------------------------------------------------------------------
8377 1.1.1.3 mrg ;; ---- [PRED] Select
8378 1.1.1.3 mrg ;; -------------------------------------------------------------------------
8379 1.1.1.3 mrg ;; Includes:
8380 1.1.1.3 mrg ;; - SEL
8381 1.1.1.3 mrg ;; -------------------------------------------------------------------------
8382 1.1.1.3 mrg
8383 1.1.1.3 mrg (define_insn "@vcond_mask_<mode><mode>"
8384 1.1.1.3 mrg [(set (match_operand:PRED_ALL 0 "register_operand" "=Upa")
8385 1.1.1.3 mrg (ior:PRED_ALL
8386 1.1.1.3 mrg (and:PRED_ALL
8387 1.1.1.3 mrg (match_operand:PRED_ALL 3 "register_operand" "Upa")
8388 1.1.1.3 mrg (match_operand:PRED_ALL 1 "register_operand" "Upa"))
8389 1.1.1.3 mrg (and:PRED_ALL
8390 1.1.1.3 mrg (not (match_dup 3))
8391 1.1.1.3 mrg (match_operand:PRED_ALL 2 "register_operand" "Upa"))))]
8392 1.1.1.3 mrg "TARGET_SVE"
8393 1.1.1.3 mrg "sel\t%0.b, %3, %1.b, %2.b"
8394 1.1.1.3 mrg )
8395 1.1.1.3 mrg
8396 1.1.1.3 mrg ;; -------------------------------------------------------------------------
8397 1.1.1.3 mrg ;; ---- [PRED] Test bits
8398 1.1.1.3 mrg ;; -------------------------------------------------------------------------
8399 1.1.1.3 mrg ;; Includes:
8400 1.1.1.3 mrg ;; - PTEST
8401 1.1.1.3 mrg ;; -------------------------------------------------------------------------
8402 1.1.1.3 mrg
8403 1.1.1.3 mrg ;; Branch based on predicate equality or inequality.
8404 1.1.1.3 mrg (define_expand "cbranch<mode>4"
8405 1.1.1.3 mrg [(set (pc)
8406 1.1.1.3 mrg (if_then_else
8407 1.1.1.3 mrg (match_operator 0 "aarch64_equality_operator"
8408 1.1.1.3 mrg [(match_operand:PRED_ALL 1 "register_operand")
8409 1.1.1.3 mrg (match_operand:PRED_ALL 2 "aarch64_simd_reg_or_zero")])
8410 1.1.1.3 mrg (label_ref (match_operand 3 ""))
8411 1.1.1.3 mrg (pc)))]
8412 1.1.1.3 mrg ""
8413 1.1.1.3 mrg {
8414 1.1.1.3 mrg rtx ptrue = force_reg (VNx16BImode, aarch64_ptrue_all (<data_bytes>));
8415 1.1.1.3 mrg rtx cast_ptrue = gen_lowpart (<MODE>mode, ptrue);
8416 1.1.1.3 mrg rtx ptrue_flag = gen_int_mode (SVE_KNOWN_PTRUE, SImode);
8417 1.1.1.3 mrg rtx pred;
8418 1.1.1.3 mrg if (operands[2] == CONST0_RTX (<MODE>mode))
8419 1.1.1.3 mrg pred = operands[1];
8420 1.1.1.3 mrg else
8421 1.1.1.3 mrg {
8422 1.1.1.3 mrg pred = gen_reg_rtx (<MODE>mode);
8423 1.1.1.3 mrg emit_insn (gen_aarch64_pred_xor<mode>_z (pred, cast_ptrue, operands[1],
8424 1.1.1.3 mrg operands[2]));
8425 1.1.1.3 mrg }
8426 1.1.1.3 mrg emit_insn (gen_aarch64_ptest<mode> (ptrue, cast_ptrue, ptrue_flag, pred));
8427 1.1.1.3 mrg operands[1] = gen_rtx_REG (CC_NZCmode, CC_REGNUM);
8428 1.1.1.3 mrg operands[2] = const0_rtx;
8429 1.1.1.3 mrg }
8430 1.1 mrg )
8431 1.1 mrg
8432 1.1.1.3 mrg ;; See "Description of UNSPEC_PTEST" above for details.
8433 1.1.1.3 mrg (define_insn "aarch64_ptest<mode>"
8434 1.1.1.3 mrg [(set (reg:CC_NZC CC_REGNUM)
8435 1.1.1.3 mrg (unspec:CC_NZC [(match_operand:VNx16BI 0 "register_operand" "Upa")
8436 1.1.1.3 mrg (match_operand 1)
8437 1.1.1.3 mrg (match_operand:SI 2 "aarch64_sve_ptrue_flag")
8438 1.1.1.3 mrg (match_operand:PRED_ALL 3 "register_operand" "Upa")]
8439 1.1.1.3 mrg UNSPEC_PTEST))]
8440 1.1.1.3 mrg "TARGET_SVE"
8441 1.1.1.3 mrg "ptest\t%0, %3.b"
8442 1.1.1.3 mrg )
8443 1.1.1.3 mrg
8444 1.1.1.3 mrg ;; =========================================================================
8445 1.1.1.3 mrg ;; == Reductions
8446 1.1.1.3 mrg ;; =========================================================================
8447 1.1.1.3 mrg
8448 1.1.1.3 mrg ;; -------------------------------------------------------------------------
8449 1.1.1.3 mrg ;; ---- [INT,FP] Conditional reductions
8450 1.1.1.3 mrg ;; -------------------------------------------------------------------------
8451 1.1.1.3 mrg ;; Includes:
8452 1.1.1.3 mrg ;; - CLASTA
8453 1.1.1.3 mrg ;; - CLASTB
8454 1.1.1.3 mrg ;; -------------------------------------------------------------------------
8455 1.1.1.3 mrg
8456 1.1 mrg ;; Set operand 0 to the last active element in operand 3, or to tied
8457 1.1 mrg ;; operand 1 if no elements are active.
8458 1.1.1.3 mrg (define_insn "@fold_extract_<last_op>_<mode>"
8459 1.1.1.3 mrg [(set (match_operand:<VEL> 0 "register_operand" "=?r, w")
8460 1.1 mrg (unspec:<VEL>
8461 1.1 mrg [(match_operand:<VEL> 1 "register_operand" "0, 0")
8462 1.1 mrg (match_operand:<VPRED> 2 "register_operand" "Upl, Upl")
8463 1.1.1.3 mrg (match_operand:SVE_FULL 3 "register_operand" "w, w")]
8464 1.1.1.3 mrg CLAST))]
8465 1.1.1.3 mrg "TARGET_SVE"
8466 1.1.1.3 mrg "@
8467 1.1.1.3 mrg clast<ab>\t%<vwcore>0, %2, %<vwcore>0, %3.<Vetype>
8468 1.1.1.3 mrg clast<ab>\t%<Vetype>0, %2, %<Vetype>0, %3.<Vetype>"
8469 1.1.1.3 mrg )
8470 1.1.1.3 mrg
8471 1.1.1.3 mrg (define_insn "@aarch64_fold_extract_vector_<last_op>_<mode>"
8472 1.1.1.3 mrg [(set (match_operand:SVE_FULL 0 "register_operand" "=w, ?&w")
8473 1.1.1.3 mrg (unspec:SVE_FULL
8474 1.1.1.3 mrg [(match_operand:SVE_FULL 1 "register_operand" "0, w")
8475 1.1.1.3 mrg (match_operand:<VPRED> 2 "register_operand" "Upl, Upl")
8476 1.1.1.3 mrg (match_operand:SVE_FULL 3 "register_operand" "w, w")]
8477 1.1.1.3 mrg CLAST))]
8478 1.1 mrg "TARGET_SVE"
8479 1.1 mrg "@
8480 1.1.1.3 mrg clast<ab>\t%0.<Vetype>, %2, %0.<Vetype>, %3.<Vetype>
8481 1.1.1.3 mrg movprfx\t%0, %1\;clast<ab>\t%0.<Vetype>, %2, %0.<Vetype>, %3.<Vetype>"
8482 1.1 mrg )
8483 1.1 mrg
8484 1.1.1.3 mrg ;; -------------------------------------------------------------------------
8485 1.1.1.3 mrg ;; ---- [INT] Tree reductions
8486 1.1.1.3 mrg ;; -------------------------------------------------------------------------
8487 1.1.1.3 mrg ;; Includes:
8488 1.1.1.3 mrg ;; - ANDV
8489 1.1.1.3 mrg ;; - EORV
8490 1.1.1.3 mrg ;; - ORV
8491 1.1.1.3 mrg ;; - SADDV
8492 1.1.1.3 mrg ;; - SMAXV
8493 1.1.1.3 mrg ;; - SMINV
8494 1.1.1.3 mrg ;; - UADDV
8495 1.1.1.3 mrg ;; - UMAXV
8496 1.1.1.3 mrg ;; - UMINV
8497 1.1.1.3 mrg ;; -------------------------------------------------------------------------
8498 1.1.1.3 mrg
8499 1.1 mrg ;; Unpredicated integer add reduction.
8500 1.1 mrg (define_expand "reduc_plus_scal_<mode>"
8501 1.1.1.3 mrg [(match_operand:<VEL> 0 "register_operand")
8502 1.1.1.3 mrg (match_operand:SVE_FULL_I 1 "register_operand")]
8503 1.1 mrg "TARGET_SVE"
8504 1.1 mrg {
8505 1.1.1.3 mrg rtx pred = aarch64_ptrue_reg (<VPRED>mode);
8506 1.1.1.3 mrg rtx tmp = <VEL>mode == DImode ? operands[0] : gen_reg_rtx (DImode);
8507 1.1.1.3 mrg emit_insn (gen_aarch64_pred_reduc_uadd_<mode> (tmp, pred, operands[1]));
8508 1.1.1.3 mrg if (tmp != operands[0])
8509 1.1.1.3 mrg emit_move_insn (operands[0], gen_lowpart (<VEL>mode, tmp));
8510 1.1.1.3 mrg DONE;
8511 1.1 mrg }
8512 1.1 mrg )
8513 1.1 mrg
8514 1.1 mrg ;; Predicated integer add reduction. The result is always 64-bits.
8515 1.1.1.3 mrg (define_insn "@aarch64_pred_reduc_<optab>_<mode>"
8516 1.1.1.3 mrg [(set (match_operand:DI 0 "register_operand" "=w")
8517 1.1.1.3 mrg (unspec:DI [(match_operand:<VPRED> 1 "register_operand" "Upl")
8518 1.1.1.3 mrg (match_operand:SVE_FULL_I 2 "register_operand" "w")]
8519 1.1.1.3 mrg SVE_INT_ADDV))]
8520 1.1.1.3 mrg "TARGET_SVE && <max_elem_bits> >= <elem_bits>"
8521 1.1.1.3 mrg "<su>addv\t%d0, %1, %2.<Vetype>"
8522 1.1 mrg )
8523 1.1 mrg
8524 1.1.1.3 mrg ;; Unpredicated integer reductions.
8525 1.1.1.3 mrg (define_expand "reduc_<optab>_scal_<mode>"
8526 1.1 mrg [(set (match_operand:<VEL> 0 "register_operand")
8527 1.1 mrg (unspec:<VEL> [(match_dup 2)
8528 1.1.1.3 mrg (match_operand:SVE_FULL_I 1 "register_operand")]
8529 1.1.1.3 mrg SVE_INT_REDUCTION))]
8530 1.1 mrg "TARGET_SVE"
8531 1.1 mrg {
8532 1.1.1.3 mrg operands[2] = aarch64_ptrue_reg (<VPRED>mode);
8533 1.1 mrg }
8534 1.1 mrg )
8535 1.1 mrg
8536 1.1.1.3 mrg ;; Predicated integer reductions.
8537 1.1.1.3 mrg (define_insn "@aarch64_pred_reduc_<optab>_<mode>"
8538 1.1 mrg [(set (match_operand:<VEL> 0 "register_operand" "=w")
8539 1.1 mrg (unspec:<VEL> [(match_operand:<VPRED> 1 "register_operand" "Upl")
8540 1.1.1.3 mrg (match_operand:SVE_FULL_I 2 "register_operand" "w")]
8541 1.1.1.3 mrg SVE_INT_REDUCTION))]
8542 1.1 mrg "TARGET_SVE"
8543 1.1.1.3 mrg "<sve_int_op>\t%<Vetype>0, %1, %2.<Vetype>"
8544 1.1 mrg )
8545 1.1 mrg
8546 1.1.1.3 mrg ;; -------------------------------------------------------------------------
8547 1.1.1.3 mrg ;; ---- [FP] Tree reductions
8548 1.1.1.3 mrg ;; -------------------------------------------------------------------------
8549 1.1.1.3 mrg ;; Includes:
8550 1.1.1.3 mrg ;; - FADDV
8551 1.1.1.3 mrg ;; - FMAXNMV
8552 1.1.1.3 mrg ;; - FMAXV
8553 1.1.1.3 mrg ;; - FMINNMV
8554 1.1.1.3 mrg ;; - FMINV
8555 1.1.1.3 mrg ;; -------------------------------------------------------------------------
8556 1.1.1.3 mrg
8557 1.1.1.3 mrg ;; Unpredicated floating-point tree reductions.
8558 1.1.1.3 mrg (define_expand "reduc_<optab>_scal_<mode>"
8559 1.1 mrg [(set (match_operand:<VEL> 0 "register_operand")
8560 1.1 mrg (unspec:<VEL> [(match_dup 2)
8561 1.1.1.3 mrg (match_operand:SVE_FULL_F 1 "register_operand")]
8562 1.1.1.3 mrg SVE_FP_REDUCTION))]
8563 1.1 mrg "TARGET_SVE"
8564 1.1 mrg {
8565 1.1.1.3 mrg operands[2] = aarch64_ptrue_reg (<VPRED>mode);
8566 1.1 mrg }
8567 1.1 mrg )
8568 1.1 mrg
8569 1.1.1.5 mrg (define_expand "reduc_<fmaxmin>_scal_<mode>"
8570 1.1.1.5 mrg [(match_operand:<VEL> 0 "register_operand")
8571 1.1.1.5 mrg (unspec:<VEL> [(match_operand:SVE_FULL_F 1 "register_operand")]
8572 1.1.1.5 mrg FMAXMINNMV)]
8573 1.1.1.5 mrg "TARGET_SVE"
8574 1.1.1.5 mrg {
8575 1.1.1.5 mrg emit_insn (gen_reduc_<optab>_scal_<mode> (operands[0], operands[1]));
8576 1.1.1.5 mrg DONE;
8577 1.1.1.5 mrg }
8578 1.1.1.5 mrg )
8579 1.1.1.5 mrg
8580 1.1.1.3 mrg ;; Predicated floating-point tree reductions.
8581 1.1.1.3 mrg (define_insn "@aarch64_pred_reduc_<optab>_<mode>"
8582 1.1 mrg [(set (match_operand:<VEL> 0 "register_operand" "=w")
8583 1.1 mrg (unspec:<VEL> [(match_operand:<VPRED> 1 "register_operand" "Upl")
8584 1.1.1.3 mrg (match_operand:SVE_FULL_F 2 "register_operand" "w")]
8585 1.1.1.3 mrg SVE_FP_REDUCTION))]
8586 1.1 mrg "TARGET_SVE"
8587 1.1.1.3 mrg "<sve_fp_op>\t%<Vetype>0, %1, %2.<Vetype>"
8588 1.1 mrg )
8589 1.1 mrg
8590 1.1.1.3 mrg ;; -------------------------------------------------------------------------
8591 1.1.1.3 mrg ;; ---- [FP] Left-to-right reductions
8592 1.1.1.3 mrg ;; -------------------------------------------------------------------------
8593 1.1.1.3 mrg ;; Includes:
8594 1.1.1.3 mrg ;; - FADDA
8595 1.1.1.3 mrg ;; -------------------------------------------------------------------------
8596 1.1.1.3 mrg
8597 1.1.1.3 mrg ;; Unpredicated in-order FP reductions.
8598 1.1.1.3 mrg (define_expand "fold_left_plus_<mode>"
8599 1.1 mrg [(set (match_operand:<VEL> 0 "register_operand")
8600 1.1.1.3 mrg (unspec:<VEL> [(match_dup 3)
8601 1.1.1.3 mrg (match_operand:<VEL> 1 "register_operand")
8602 1.1.1.3 mrg (match_operand:SVE_FULL_F 2 "register_operand")]
8603 1.1.1.3 mrg UNSPEC_FADDA))]
8604 1.1 mrg "TARGET_SVE"
8605 1.1 mrg {
8606 1.1.1.3 mrg operands[3] = aarch64_ptrue_reg (<VPRED>mode);
8607 1.1 mrg }
8608 1.1 mrg )
8609 1.1 mrg
8610 1.1.1.3 mrg ;; Predicated in-order FP reductions.
8611 1.1.1.3 mrg (define_insn "mask_fold_left_plus_<mode>"
8612 1.1 mrg [(set (match_operand:<VEL> 0 "register_operand" "=w")
8613 1.1.1.3 mrg (unspec:<VEL> [(match_operand:<VPRED> 3 "register_operand" "Upl")
8614 1.1.1.3 mrg (match_operand:<VEL> 1 "register_operand" "0")
8615 1.1.1.3 mrg (match_operand:SVE_FULL_F 2 "register_operand" "w")]
8616 1.1.1.3 mrg UNSPEC_FADDA))]
8617 1.1 mrg "TARGET_SVE"
8618 1.1.1.3 mrg "fadda\t%<Vetype>0, %3, %<Vetype>0, %2.<Vetype>"
8619 1.1 mrg )
8620 1.1 mrg
8621 1.1.1.3 mrg ;; =========================================================================
8622 1.1.1.3 mrg ;; == Permutes
8623 1.1.1.3 mrg ;; =========================================================================
8624 1.1.1.3 mrg
8625 1.1.1.3 mrg ;; -------------------------------------------------------------------------
8626 1.1.1.3 mrg ;; ---- [INT,FP] General permutes
8627 1.1.1.3 mrg ;; -------------------------------------------------------------------------
8628 1.1.1.3 mrg ;; Includes:
8629 1.1.1.3 mrg ;; - TBL
8630 1.1.1.3 mrg ;; -------------------------------------------------------------------------
8631 1.1.1.3 mrg
8632 1.1.1.3 mrg (define_expand "vec_perm<mode>"
8633 1.1.1.3 mrg [(match_operand:SVE_FULL 0 "register_operand")
8634 1.1.1.3 mrg (match_operand:SVE_FULL 1 "register_operand")
8635 1.1.1.3 mrg (match_operand:SVE_FULL 2 "register_operand")
8636 1.1.1.3 mrg (match_operand:<V_INT_EQUIV> 3 "aarch64_sve_vec_perm_operand")]
8637 1.1.1.3 mrg "TARGET_SVE && GET_MODE_NUNITS (<MODE>mode).is_constant ()"
8638 1.1 mrg {
8639 1.1.1.3 mrg aarch64_expand_sve_vec_perm (operands[0], operands[1],
8640 1.1.1.3 mrg operands[2], operands[3]);
8641 1.1.1.3 mrg DONE;
8642 1.1 mrg }
8643 1.1 mrg )
8644 1.1 mrg
8645 1.1.1.3 mrg (define_insn "@aarch64_sve_tbl<mode>"
8646 1.1.1.3 mrg [(set (match_operand:SVE_FULL 0 "register_operand" "=w")
8647 1.1.1.3 mrg (unspec:SVE_FULL
8648 1.1.1.3 mrg [(match_operand:SVE_FULL 1 "register_operand" "w")
8649 1.1.1.3 mrg (match_operand:<V_INT_EQUIV> 2 "register_operand" "w")]
8650 1.1.1.3 mrg UNSPEC_TBL))]
8651 1.1 mrg "TARGET_SVE"
8652 1.1.1.3 mrg "tbl\t%0.<Vetype>, %1.<Vetype>, %2.<Vetype>"
8653 1.1 mrg )
8654 1.1 mrg
8655 1.1.1.3 mrg ;; -------------------------------------------------------------------------
8656 1.1.1.3 mrg ;; ---- [INT,FP] Special-purpose unary permutes
8657 1.1.1.3 mrg ;; -------------------------------------------------------------------------
8658 1.1.1.3 mrg ;; Includes:
8659 1.1.1.3 mrg ;; - COMPACT
8660 1.1.1.3 mrg ;; - DUP
8661 1.1.1.3 mrg ;; - REV
8662 1.1.1.3 mrg ;; -------------------------------------------------------------------------
8663 1.1.1.3 mrg
8664 1.1.1.3 mrg ;; Compact active elements and pad with zeros.
8665 1.1.1.3 mrg (define_insn "@aarch64_sve_compact<mode>"
8666 1.1.1.3 mrg [(set (match_operand:SVE_FULL_SD 0 "register_operand" "=w")
8667 1.1.1.3 mrg (unspec:SVE_FULL_SD
8668 1.1.1.3 mrg [(match_operand:<VPRED> 1 "register_operand" "Upl")
8669 1.1.1.3 mrg (match_operand:SVE_FULL_SD 2 "register_operand" "w")]
8670 1.1.1.3 mrg UNSPEC_SVE_COMPACT))]
8671 1.1.1.3 mrg "TARGET_SVE"
8672 1.1.1.3 mrg "compact\t%0.<Vetype>, %1, %2.<Vetype>"
8673 1.1.1.3 mrg )
8674 1.1.1.3 mrg
8675 1.1.1.3 mrg ;; Duplicate one element of a vector.
8676 1.1.1.3 mrg (define_insn "@aarch64_sve_dup_lane<mode>"
8677 1.1.1.5 mrg [(set (match_operand:SVE_ALL 0 "register_operand" "=w")
8678 1.1.1.5 mrg (vec_duplicate:SVE_ALL
8679 1.1.1.3 mrg (vec_select:<VEL>
8680 1.1.1.5 mrg (match_operand:SVE_ALL 1 "register_operand" "w")
8681 1.1.1.3 mrg (parallel [(match_operand:SI 2 "const_int_operand")]))))]
8682 1.1.1.3 mrg "TARGET_SVE
8683 1.1.1.5 mrg && IN_RANGE (INTVAL (operands[2]) * <container_bits> / 8, 0, 63)"
8684 1.1.1.5 mrg "dup\t%0.<Vctype>, %1.<Vctype>[%2]"
8685 1.1.1.3 mrg )
8686 1.1.1.3 mrg
8687 1.1.1.3 mrg ;; Use DUP.Q to duplicate a 128-bit segment of a register.
8688 1.1.1.3 mrg ;;
8689 1.1.1.3 mrg ;; The vec_select:<V128> sets memory lane number N of the V128 to lane
8690 1.1.1.3 mrg ;; number op2 + N of op1. (We don't need to distinguish between memory
8691 1.1.1.3 mrg ;; and architectural register lane numbering for op1 or op0, since the
8692 1.1.1.3 mrg ;; two numbering schemes are the same for SVE.)
8693 1.1.1.3 mrg ;;
8694 1.1.1.3 mrg ;; The vec_duplicate:SVE_FULL then copies memory lane number N of the
8695 1.1.1.3 mrg ;; V128 (and thus lane number op2 + N of op1) to lane numbers N + I * STEP
8696 1.1.1.3 mrg ;; of op0. We therefore get the correct result for both endiannesses.
8697 1.1.1.3 mrg ;;
8698 1.1.1.3 mrg ;; The wrinkle is that for big-endian V128 registers, memory lane numbering
8699 1.1.1.3 mrg ;; is in the opposite order to architectural register lane numbering.
8700 1.1.1.3 mrg ;; Thus if we were to do this operation via a V128 temporary register,
8701 1.1.1.3 mrg ;; the vec_select and vec_duplicate would both involve a reverse operation
8702 1.1.1.3 mrg ;; for big-endian targets. In this fused pattern the two reverses cancel
8703 1.1.1.3 mrg ;; each other out.
8704 1.1.1.3 mrg (define_insn "@aarch64_sve_dupq_lane<mode>"
8705 1.1.1.3 mrg [(set (match_operand:SVE_FULL 0 "register_operand" "=w")
8706 1.1.1.3 mrg (vec_duplicate:SVE_FULL
8707 1.1.1.3 mrg (vec_select:<V128>
8708 1.1.1.3 mrg (match_operand:SVE_FULL 1 "register_operand" "w")
8709 1.1.1.3 mrg (match_operand 2 "ascending_int_parallel"))))]
8710 1.1.1.3 mrg "TARGET_SVE
8711 1.1.1.3 mrg && (INTVAL (XVECEXP (operands[2], 0, 0))
8712 1.1.1.3 mrg * GET_MODE_SIZE (<VEL>mode)) % 16 == 0
8713 1.1.1.3 mrg && IN_RANGE (INTVAL (XVECEXP (operands[2], 0, 0))
8714 1.1.1.3 mrg * GET_MODE_SIZE (<VEL>mode), 0, 63)"
8715 1.1.1.3 mrg {
8716 1.1.1.3 mrg unsigned int byte = (INTVAL (XVECEXP (operands[2], 0, 0))
8717 1.1.1.3 mrg * GET_MODE_SIZE (<VEL>mode));
8718 1.1.1.3 mrg operands[2] = gen_int_mode (byte / 16, DImode);
8719 1.1.1.3 mrg return "dup\t%0.q, %1.q[%2]";
8720 1.1.1.3 mrg }
8721 1.1.1.3 mrg )
8722 1.1.1.3 mrg
8723 1.1.1.3 mrg ;; Reverse the order of elements within a full vector.
8724 1.1.1.3 mrg (define_insn "@aarch64_sve_rev<mode>"
8725 1.1.1.5 mrg [(set (match_operand:SVE_ALL 0 "register_operand" "=w")
8726 1.1.1.5 mrg (unspec:SVE_ALL
8727 1.1.1.5 mrg [(match_operand:SVE_ALL 1 "register_operand" "w")]
8728 1.1.1.3 mrg UNSPEC_REV))]
8729 1.1 mrg "TARGET_SVE"
8730 1.1.1.5 mrg "rev\t%0.<Vctype>, %1.<Vctype>")
8731 1.1.1.3 mrg
8732 1.1.1.3 mrg ;; -------------------------------------------------------------------------
8733 1.1.1.3 mrg ;; ---- [INT,FP] Special-purpose binary permutes
8734 1.1.1.3 mrg ;; -------------------------------------------------------------------------
8735 1.1.1.3 mrg ;; Includes:
8736 1.1.1.5 mrg ;; - EXT
8737 1.1.1.3 mrg ;; - SPLICE
8738 1.1.1.3 mrg ;; - TRN1
8739 1.1.1.3 mrg ;; - TRN2
8740 1.1.1.3 mrg ;; - UZP1
8741 1.1.1.3 mrg ;; - UZP2
8742 1.1.1.3 mrg ;; - ZIP1
8743 1.1.1.3 mrg ;; - ZIP2
8744 1.1.1.3 mrg ;; -------------------------------------------------------------------------
8745 1.1.1.3 mrg
8746 1.1.1.3 mrg ;; Like EXT, but start at the first active element.
8747 1.1.1.3 mrg (define_insn "@aarch64_sve_splice<mode>"
8748 1.1.1.3 mrg [(set (match_operand:SVE_FULL 0 "register_operand" "=w, ?&w")
8749 1.1.1.3 mrg (unspec:SVE_FULL
8750 1.1.1.3 mrg [(match_operand:<VPRED> 1 "register_operand" "Upl, Upl")
8751 1.1.1.3 mrg (match_operand:SVE_FULL 2 "register_operand" "0, w")
8752 1.1.1.3 mrg (match_operand:SVE_FULL 3 "register_operand" "w, w")]
8753 1.1.1.3 mrg UNSPEC_SVE_SPLICE))]
8754 1.1.1.3 mrg "TARGET_SVE"
8755 1.1.1.3 mrg "@
8756 1.1.1.3 mrg splice\t%0.<Vetype>, %1, %0.<Vetype>, %3.<Vetype>
8757 1.1.1.3 mrg movprfx\t%0, %2\;splice\t%0.<Vetype>, %1, %0.<Vetype>, %3.<Vetype>"
8758 1.1.1.3 mrg [(set_attr "movprfx" "*, yes")]
8759 1.1.1.3 mrg )
8760 1.1.1.3 mrg
8761 1.1.1.3 mrg ;; Permutes that take half the elements from one vector and half the
8762 1.1.1.3 mrg ;; elements from the other.
8763 1.1.1.3 mrg (define_insn "@aarch64_sve_<perm_insn><mode>"
8764 1.1.1.5 mrg [(set (match_operand:SVE_ALL 0 "register_operand" "=w")
8765 1.1.1.5 mrg (unspec:SVE_ALL
8766 1.1.1.5 mrg [(match_operand:SVE_ALL 1 "register_operand" "w")
8767 1.1.1.5 mrg (match_operand:SVE_ALL 2 "register_operand" "w")]
8768 1.1.1.3 mrg PERMUTE))]
8769 1.1.1.3 mrg "TARGET_SVE"
8770 1.1.1.5 mrg "<perm_insn>\t%0.<Vctype>, %1.<Vctype>, %2.<Vctype>"
8771 1.1.1.3 mrg )
8772 1.1.1.3 mrg
8773 1.1.1.3 mrg ;; Apply PERMUTE to 128-bit sequences. The behavior of these patterns
8774 1.1.1.3 mrg ;; doesn't depend on the mode.
8775 1.1.1.3 mrg (define_insn "@aarch64_sve_<optab><mode>"
8776 1.1.1.3 mrg [(set (match_operand:SVE_FULL 0 "register_operand" "=w")
8777 1.1.1.3 mrg (unspec:SVE_FULL
8778 1.1.1.3 mrg [(match_operand:SVE_FULL 1 "register_operand" "w")
8779 1.1.1.3 mrg (match_operand:SVE_FULL 2 "register_operand" "w")]
8780 1.1.1.3 mrg PERMUTEQ))]
8781 1.1.1.3 mrg "TARGET_SVE_F64MM"
8782 1.1.1.3 mrg "<perm_insn>\t%0.q, %1.q, %2.q"
8783 1.1.1.3 mrg )
8784 1.1.1.3 mrg
8785 1.1.1.3 mrg ;; Concatenate two vectors and extract a subvector. Note that the
8786 1.1.1.3 mrg ;; immediate (third) operand is the lane index not the byte index.
8787 1.1.1.3 mrg (define_insn "@aarch64_sve_ext<mode>"
8788 1.1.1.5 mrg [(set (match_operand:SVE_ALL 0 "register_operand" "=w, ?&w")
8789 1.1.1.5 mrg (unspec:SVE_ALL
8790 1.1.1.5 mrg [(match_operand:SVE_ALL 1 "register_operand" "0, w")
8791 1.1.1.5 mrg (match_operand:SVE_ALL 2 "register_operand" "w, w")
8792 1.1.1.3 mrg (match_operand:SI 3 "const_int_operand")]
8793 1.1.1.3 mrg UNSPEC_EXT))]
8794 1.1.1.3 mrg "TARGET_SVE
8795 1.1.1.5 mrg && IN_RANGE (INTVAL (operands[3]) * <container_bits> / 8, 0, 255)"
8796 1.1 mrg {
8797 1.1.1.5 mrg operands[3] = GEN_INT (INTVAL (operands[3]) * <container_bits> / 8);
8798 1.1.1.3 mrg return (which_alternative == 0
8799 1.1.1.3 mrg ? "ext\\t%0.b, %0.b, %2.b, #%3"
8800 1.1.1.3 mrg : "movprfx\t%0, %1\;ext\\t%0.b, %0.b, %2.b, #%3");
8801 1.1 mrg }
8802 1.1.1.3 mrg [(set_attr "movprfx" "*,yes")]
8803 1.1 mrg )
8804 1.1 mrg
8805 1.1.1.3 mrg ;; -------------------------------------------------------------------------
8806 1.1.1.3 mrg ;; ---- [PRED] Special-purpose unary permutes
8807 1.1.1.3 mrg ;; -------------------------------------------------------------------------
8808 1.1.1.3 mrg ;; Includes:
8809 1.1.1.3 mrg ;; - REV
8810 1.1.1.3 mrg ;; -------------------------------------------------------------------------
8811 1.1.1.3 mrg
8812 1.1.1.3 mrg (define_insn "@aarch64_sve_rev<mode>"
8813 1.1.1.3 mrg [(set (match_operand:PRED_ALL 0 "register_operand" "=Upa")
8814 1.1.1.3 mrg (unspec:PRED_ALL [(match_operand:PRED_ALL 1 "register_operand" "Upa")]
8815 1.1.1.3 mrg UNSPEC_REV))]
8816 1.1.1.3 mrg "TARGET_SVE"
8817 1.1.1.3 mrg "rev\t%0.<Vetype>, %1.<Vetype>")
8818 1.1.1.3 mrg
8819 1.1.1.3 mrg ;; -------------------------------------------------------------------------
8820 1.1.1.3 mrg ;; ---- [PRED] Special-purpose binary permutes
8821 1.1.1.3 mrg ;; -------------------------------------------------------------------------
8822 1.1.1.3 mrg ;; Includes:
8823 1.1.1.3 mrg ;; - TRN1
8824 1.1.1.3 mrg ;; - TRN2
8825 1.1.1.3 mrg ;; - UZP1
8826 1.1.1.3 mrg ;; - UZP2
8827 1.1.1.3 mrg ;; - ZIP1
8828 1.1.1.3 mrg ;; - ZIP2
8829 1.1.1.3 mrg ;; -------------------------------------------------------------------------
8830 1.1.1.3 mrg
8831 1.1.1.3 mrg ;; Permutes that take half the elements from one vector and half the
8832 1.1.1.3 mrg ;; elements from the other.
8833 1.1.1.3 mrg (define_insn "@aarch64_sve_<perm_insn><mode>"
8834 1.1.1.3 mrg [(set (match_operand:PRED_ALL 0 "register_operand" "=Upa")
8835 1.1.1.3 mrg (unspec:PRED_ALL [(match_operand:PRED_ALL 1 "register_operand" "Upa")
8836 1.1.1.3 mrg (match_operand:PRED_ALL 2 "register_operand" "Upa")]
8837 1.1.1.3 mrg PERMUTE))]
8838 1.1 mrg "TARGET_SVE"
8839 1.1.1.3 mrg "<perm_insn>\t%0.<Vetype>, %1.<Vetype>, %2.<Vetype>"
8840 1.1 mrg )
8841 1.1 mrg
8842 1.1.1.3 mrg ;; Special purpose permute used by the predicate generation instructions.
8843 1.1.1.3 mrg ;; Unlike the normal permute patterns, these instructions operate on VNx16BI
8844 1.1.1.3 mrg ;; regardless of the element size, so that all input and output bits are
8845 1.1.1.3 mrg ;; well-defined. Operand 3 then indicates the size of the permute.
8846 1.1.1.3 mrg (define_insn "@aarch64_sve_trn1_conv<mode>"
8847 1.1.1.3 mrg [(set (match_operand:VNx16BI 0 "register_operand" "=Upa")
8848 1.1.1.3 mrg (unspec:VNx16BI [(match_operand:VNx16BI 1 "register_operand" "Upa")
8849 1.1.1.3 mrg (match_operand:VNx16BI 2 "register_operand" "Upa")
8850 1.1.1.3 mrg (match_operand:PRED_ALL 3 "aarch64_simd_imm_zero")]
8851 1.1.1.3 mrg UNSPEC_TRN1_CONV))]
8852 1.1.1.3 mrg "TARGET_SVE"
8853 1.1.1.3 mrg "trn1\t%0.<PRED_ALL:Vetype>, %1.<PRED_ALL:Vetype>, %2.<PRED_ALL:Vetype>"
8854 1.1.1.3 mrg )
8855 1.1.1.3 mrg
8856 1.1.1.3 mrg ;; =========================================================================
8857 1.1.1.3 mrg ;; == Conversions
8858 1.1.1.3 mrg ;; =========================================================================
8859 1.1.1.3 mrg
8860 1.1.1.3 mrg ;; -------------------------------------------------------------------------
8861 1.1.1.3 mrg ;; ---- [INT<-INT] Packs
8862 1.1.1.3 mrg ;; -------------------------------------------------------------------------
8863 1.1.1.3 mrg ;; Includes:
8864 1.1.1.3 mrg ;; - UZP1
8865 1.1.1.3 mrg ;; -------------------------------------------------------------------------
8866 1.1.1.3 mrg
8867 1.1.1.3 mrg ;; Integer pack. Use UZP1 on the narrower type, which discards
8868 1.1.1.3 mrg ;; the high part of each wide element.
8869 1.1.1.3 mrg (define_insn "vec_pack_trunc_<Vwide>"
8870 1.1.1.3 mrg [(set (match_operand:SVE_FULL_BHSI 0 "register_operand" "=w")
8871 1.1.1.3 mrg (unspec:SVE_FULL_BHSI
8872 1.1.1.3 mrg [(match_operand:<VWIDE> 1 "register_operand" "w")
8873 1.1.1.3 mrg (match_operand:<VWIDE> 2 "register_operand" "w")]
8874 1.1.1.3 mrg UNSPEC_PACK))]
8875 1.1.1.3 mrg "TARGET_SVE"
8876 1.1.1.3 mrg "uzp1\t%0.<Vetype>, %1.<Vetype>, %2.<Vetype>"
8877 1.1 mrg )
8878 1.1 mrg
8879 1.1.1.3 mrg ;; -------------------------------------------------------------------------
8880 1.1.1.3 mrg ;; ---- [INT<-INT] Unpacks
8881 1.1.1.3 mrg ;; -------------------------------------------------------------------------
8882 1.1.1.3 mrg ;; Includes:
8883 1.1.1.3 mrg ;; - SUNPKHI
8884 1.1.1.3 mrg ;; - SUNPKLO
8885 1.1.1.3 mrg ;; - UUNPKHI
8886 1.1.1.3 mrg ;; - UUNPKLO
8887 1.1.1.3 mrg ;; -------------------------------------------------------------------------
8888 1.1.1.3 mrg
8889 1.1.1.3 mrg ;; Unpack the low or high half of a vector, where "high" refers to
8890 1.1.1.3 mrg ;; the low-numbered lanes for big-endian and the high-numbered lanes
8891 1.1.1.3 mrg ;; for little-endian.
8892 1.1.1.3 mrg (define_expand "vec_unpack<su>_<perm_hilo>_<SVE_FULL_BHSI:mode>"
8893 1.1.1.3 mrg [(match_operand:<VWIDE> 0 "register_operand")
8894 1.1.1.3 mrg (unspec:<VWIDE>
8895 1.1.1.3 mrg [(match_operand:SVE_FULL_BHSI 1 "register_operand")] UNPACK)]
8896 1.1 mrg "TARGET_SVE"
8897 1.1 mrg {
8898 1.1.1.3 mrg emit_insn ((<hi_lanes_optab>
8899 1.1.1.3 mrg ? gen_aarch64_sve_<su>unpkhi_<SVE_FULL_BHSI:mode>
8900 1.1.1.3 mrg : gen_aarch64_sve_<su>unpklo_<SVE_FULL_BHSI:mode>)
8901 1.1.1.3 mrg (operands[0], operands[1]));
8902 1.1.1.3 mrg DONE;
8903 1.1 mrg }
8904 1.1 mrg )
8905 1.1 mrg
8906 1.1.1.3 mrg (define_insn "@aarch64_sve_<su>unpk<perm_hilo>_<SVE_FULL_BHSI:mode>"
8907 1.1.1.3 mrg [(set (match_operand:<VWIDE> 0 "register_operand" "=w")
8908 1.1.1.3 mrg (unspec:<VWIDE>
8909 1.1.1.3 mrg [(match_operand:SVE_FULL_BHSI 1 "register_operand" "w")]
8910 1.1.1.3 mrg UNPACK))]
8911 1.1 mrg "TARGET_SVE"
8912 1.1.1.3 mrg "<su>unpk<perm_hilo>\t%0.<Vewtype>, %1.<Vetype>"
8913 1.1 mrg )
8914 1.1 mrg
8915 1.1.1.3 mrg ;; -------------------------------------------------------------------------
8916 1.1.1.3 mrg ;; ---- [INT<-FP] Conversions
8917 1.1.1.3 mrg ;; -------------------------------------------------------------------------
8918 1.1.1.3 mrg ;; Includes:
8919 1.1.1.3 mrg ;; - FCVTZS
8920 1.1.1.3 mrg ;; - FCVTZU
8921 1.1.1.3 mrg ;; -------------------------------------------------------------------------
8922 1.1.1.3 mrg
8923 1.1.1.3 mrg ;; Unpredicated conversion of floats to integers of the same size (HF to HI,
8924 1.1.1.3 mrg ;; SF to SI or DF to DI).
8925 1.1.1.3 mrg (define_expand "<optab><mode><v_int_equiv>2"
8926 1.1.1.3 mrg [(set (match_operand:<V_INT_EQUIV> 0 "register_operand")
8927 1.1.1.3 mrg (unspec:<V_INT_EQUIV>
8928 1.1.1.3 mrg [(match_dup 2)
8929 1.1.1.3 mrg (const_int SVE_RELAXED_GP)
8930 1.1.1.3 mrg (match_operand:SVE_FULL_F 1 "register_operand")]
8931 1.1.1.3 mrg SVE_COND_FCVTI))]
8932 1.1 mrg "TARGET_SVE"
8933 1.1 mrg {
8934 1.1.1.3 mrg operands[2] = aarch64_ptrue_reg (<VPRED>mode);
8935 1.1 mrg }
8936 1.1 mrg )
8937 1.1 mrg
8938 1.1.1.3 mrg ;; Predicated float-to-integer conversion, either to the same width or wider.
8939 1.1.1.3 mrg (define_insn "@aarch64_sve_<optab>_nontrunc<SVE_FULL_F:mode><SVE_FULL_HSDI:mode>"
8940 1.1.1.3 mrg [(set (match_operand:SVE_FULL_HSDI 0 "register_operand" "=w, ?&w")
8941 1.1.1.3 mrg (unspec:SVE_FULL_HSDI
8942 1.1.1.3 mrg [(match_operand:<SVE_FULL_HSDI:VPRED> 1 "register_operand" "Upl, Upl")
8943 1.1.1.3 mrg (match_operand:SI 3 "aarch64_sve_gp_strictness")
8944 1.1.1.3 mrg (match_operand:SVE_FULL_F 2 "register_operand" "0, w")]
8945 1.1.1.3 mrg SVE_COND_FCVTI))]
8946 1.1.1.3 mrg "TARGET_SVE && <SVE_FULL_HSDI:elem_bits> >= <SVE_FULL_F:elem_bits>"
8947 1.1 mrg "@
8948 1.1.1.3 mrg fcvtz<su>\t%0.<SVE_FULL_HSDI:Vetype>, %1/m, %2.<SVE_FULL_F:Vetype>
8949 1.1.1.3 mrg movprfx\t%0, %2\;fcvtz<su>\t%0.<SVE_FULL_HSDI:Vetype>, %1/m, %2.<SVE_FULL_F:Vetype>"
8950 1.1.1.3 mrg [(set_attr "movprfx" "*,yes")]
8951 1.1 mrg )
8952 1.1 mrg
8953 1.1.1.3 mrg ;; Predicated narrowing float-to-integer conversion.
8954 1.1.1.3 mrg (define_insn "@aarch64_sve_<optab>_trunc<VNx2DF_ONLY:mode><VNx4SI_ONLY:mode>"
8955 1.1.1.3 mrg [(set (match_operand:VNx4SI_ONLY 0 "register_operand" "=w, ?&w")
8956 1.1.1.3 mrg (unspec:VNx4SI_ONLY
8957 1.1.1.3 mrg [(match_operand:VNx2BI 1 "register_operand" "Upl, Upl")
8958 1.1.1.3 mrg (match_operand:SI 3 "aarch64_sve_gp_strictness")
8959 1.1.1.3 mrg (match_operand:VNx2DF_ONLY 2 "register_operand" "0, w")]
8960 1.1.1.3 mrg SVE_COND_FCVTI))]
8961 1.1 mrg "TARGET_SVE"
8962 1.1.1.3 mrg "@
8963 1.1.1.3 mrg fcvtz<su>\t%0.<VNx4SI_ONLY:Vetype>, %1/m, %2.<VNx2DF_ONLY:Vetype>
8964 1.1.1.3 mrg movprfx\t%0, %2\;fcvtz<su>\t%0.<VNx4SI_ONLY:Vetype>, %1/m, %2.<VNx2DF_ONLY:Vetype>"
8965 1.1.1.3 mrg [(set_attr "movprfx" "*,yes")]
8966 1.1 mrg )
8967 1.1 mrg
8968 1.1.1.3 mrg ;; Predicated float-to-integer conversion with merging, either to the same
8969 1.1.1.3 mrg ;; width or wider.
8970 1.1.1.3 mrg (define_expand "@cond_<optab>_nontrunc<SVE_FULL_F:mode><SVE_FULL_HSDI:mode>"
8971 1.1.1.3 mrg [(set (match_operand:SVE_FULL_HSDI 0 "register_operand")
8972 1.1.1.3 mrg (unspec:SVE_FULL_HSDI
8973 1.1.1.3 mrg [(match_operand:<SVE_FULL_HSDI:VPRED> 1 "register_operand")
8974 1.1.1.3 mrg (unspec:SVE_FULL_HSDI
8975 1.1.1.3 mrg [(match_dup 1)
8976 1.1.1.3 mrg (const_int SVE_STRICT_GP)
8977 1.1.1.3 mrg (match_operand:SVE_FULL_F 2 "register_operand")]
8978 1.1.1.3 mrg SVE_COND_FCVTI)
8979 1.1.1.3 mrg (match_operand:SVE_FULL_HSDI 3 "aarch64_simd_reg_or_zero")]
8980 1.1.1.3 mrg UNSPEC_SEL))]
8981 1.1.1.3 mrg "TARGET_SVE && <SVE_FULL_HSDI:elem_bits> >= <SVE_FULL_F:elem_bits>"
8982 1.1.1.3 mrg )
8983 1.1.1.3 mrg
8984 1.1.1.3 mrg ;; The first alternative doesn't need the earlyclobber, but the only case
8985 1.1.1.3 mrg ;; it would help is the uninteresting one in which operands 2 and 3 are
8986 1.1.1.3 mrg ;; the same register (despite having different modes). Making all the
8987 1.1.1.3 mrg ;; alternatives earlyclobber makes things more consistent for the
8988 1.1.1.3 mrg ;; register allocator.
8989 1.1.1.3 mrg (define_insn_and_rewrite "*cond_<optab>_nontrunc<SVE_FULL_F:mode><SVE_FULL_HSDI:mode>_relaxed"
8990 1.1.1.3 mrg [(set (match_operand:SVE_FULL_HSDI 0 "register_operand" "=&w, &w, ?&w")
8991 1.1.1.3 mrg (unspec:SVE_FULL_HSDI
8992 1.1.1.3 mrg [(match_operand:<SVE_FULL_HSDI:VPRED> 1 "register_operand" "Upl, Upl, Upl")
8993 1.1.1.3 mrg (unspec:SVE_FULL_HSDI
8994 1.1.1.3 mrg [(match_operand 4)
8995 1.1.1.3 mrg (const_int SVE_RELAXED_GP)
8996 1.1.1.3 mrg (match_operand:SVE_FULL_F 2 "register_operand" "w, w, w")]
8997 1.1.1.3 mrg SVE_COND_FCVTI)
8998 1.1.1.3 mrg (match_operand:SVE_FULL_HSDI 3 "aarch64_simd_reg_or_zero" "0, Dz, w")]
8999 1.1.1.3 mrg UNSPEC_SEL))]
9000 1.1.1.3 mrg "TARGET_SVE && <SVE_FULL_HSDI:elem_bits> >= <SVE_FULL_F:elem_bits>"
9001 1.1.1.3 mrg "@
9002 1.1.1.3 mrg fcvtz<su>\t%0.<SVE_FULL_HSDI:Vetype>, %1/m, %2.<SVE_FULL_F:Vetype>
9003 1.1.1.3 mrg movprfx\t%0.<SVE_FULL_HSDI:Vetype>, %1/z, %2.<SVE_FULL_HSDI:Vetype>\;fcvtz<su>\t%0.<SVE_FULL_HSDI:Vetype>, %1/m, %2.<SVE_FULL_F:Vetype>
9004 1.1.1.3 mrg movprfx\t%0, %3\;fcvtz<su>\t%0.<SVE_FULL_HSDI:Vetype>, %1/m, %2.<SVE_FULL_F:Vetype>"
9005 1.1.1.3 mrg "&& !rtx_equal_p (operands[1], operands[4])"
9006 1.1.1.3 mrg {
9007 1.1.1.3 mrg operands[4] = copy_rtx (operands[1]);
9008 1.1.1.3 mrg }
9009 1.1.1.3 mrg [(set_attr "movprfx" "*,yes,yes")]
9010 1.1.1.3 mrg )
9011 1.1.1.3 mrg
9012 1.1.1.3 mrg (define_insn "*cond_<optab>_nontrunc<SVE_FULL_F:mode><SVE_FULL_HSDI:mode>_strict"
9013 1.1.1.3 mrg [(set (match_operand:SVE_FULL_HSDI 0 "register_operand" "=&w, &w, ?&w")
9014 1.1.1.3 mrg (unspec:SVE_FULL_HSDI
9015 1.1.1.3 mrg [(match_operand:<SVE_FULL_HSDI:VPRED> 1 "register_operand" "Upl, Upl, Upl")
9016 1.1.1.3 mrg (unspec:SVE_FULL_HSDI
9017 1.1.1.3 mrg [(match_dup 1)
9018 1.1.1.3 mrg (const_int SVE_STRICT_GP)
9019 1.1.1.3 mrg (match_operand:SVE_FULL_F 2 "register_operand" "w, w, w")]
9020 1.1.1.3 mrg SVE_COND_FCVTI)
9021 1.1.1.3 mrg (match_operand:SVE_FULL_HSDI 3 "aarch64_simd_reg_or_zero" "0, Dz, w")]
9022 1.1.1.3 mrg UNSPEC_SEL))]
9023 1.1.1.3 mrg "TARGET_SVE && <SVE_FULL_HSDI:elem_bits> >= <SVE_FULL_F:elem_bits>"
9024 1.1.1.3 mrg "@
9025 1.1.1.3 mrg fcvtz<su>\t%0.<SVE_FULL_HSDI:Vetype>, %1/m, %2.<SVE_FULL_F:Vetype>
9026 1.1.1.3 mrg movprfx\t%0.<SVE_FULL_HSDI:Vetype>, %1/z, %2.<SVE_FULL_HSDI:Vetype>\;fcvtz<su>\t%0.<SVE_FULL_HSDI:Vetype>, %1/m, %2.<SVE_FULL_F:Vetype>
9027 1.1.1.3 mrg movprfx\t%0, %3\;fcvtz<su>\t%0.<SVE_FULL_HSDI:Vetype>, %1/m, %2.<SVE_FULL_F:Vetype>"
9028 1.1.1.3 mrg [(set_attr "movprfx" "*,yes,yes")]
9029 1.1.1.3 mrg )
9030 1.1.1.3 mrg
9031 1.1.1.3 mrg ;; Predicated narrowing float-to-integer conversion with merging.
9032 1.1.1.3 mrg (define_expand "@cond_<optab>_trunc<VNx2DF_ONLY:mode><VNx4SI_ONLY:mode>"
9033 1.1.1.3 mrg [(set (match_operand:VNx4SI_ONLY 0 "register_operand")
9034 1.1.1.3 mrg (unspec:VNx4SI_ONLY
9035 1.1.1.3 mrg [(match_operand:VNx2BI 1 "register_operand")
9036 1.1.1.3 mrg (unspec:VNx4SI_ONLY
9037 1.1.1.3 mrg [(match_dup 1)
9038 1.1.1.3 mrg (const_int SVE_STRICT_GP)
9039 1.1.1.3 mrg (match_operand:VNx2DF_ONLY 2 "register_operand")]
9040 1.1.1.3 mrg SVE_COND_FCVTI)
9041 1.1.1.3 mrg (match_operand:VNx4SI_ONLY 3 "aarch64_simd_reg_or_zero")]
9042 1.1.1.3 mrg UNSPEC_SEL))]
9043 1.1.1.3 mrg "TARGET_SVE"
9044 1.1.1.3 mrg )
9045 1.1.1.3 mrg
9046 1.1.1.3 mrg (define_insn "*cond_<optab>_trunc<VNx2DF_ONLY:mode><VNx4SI_ONLY:mode>"
9047 1.1.1.3 mrg [(set (match_operand:VNx4SI_ONLY 0 "register_operand" "=&w, &w, ?&w")
9048 1.1.1.3 mrg (unspec:VNx4SI_ONLY
9049 1.1.1.3 mrg [(match_operand:VNx2BI 1 "register_operand" "Upl, Upl, Upl")
9050 1.1.1.3 mrg (unspec:VNx4SI_ONLY
9051 1.1.1.3 mrg [(match_dup 1)
9052 1.1.1.3 mrg (match_operand:SI 4 "aarch64_sve_gp_strictness")
9053 1.1.1.3 mrg (match_operand:VNx2DF_ONLY 2 "register_operand" "w, w, w")]
9054 1.1.1.3 mrg SVE_COND_FCVTI)
9055 1.1.1.3 mrg (match_operand:VNx4SI_ONLY 3 "aarch64_simd_reg_or_zero" "0, Dz, w")]
9056 1.1.1.3 mrg UNSPEC_SEL))]
9057 1.1 mrg "TARGET_SVE"
9058 1.1 mrg "@
9059 1.1.1.3 mrg fcvtz<su>\t%0.<VNx4SI_ONLY:Vetype>, %1/m, %2.<VNx2DF_ONLY:Vetype>
9060 1.1.1.3 mrg movprfx\t%0.<VNx2DF_ONLY:Vetype>, %1/z, %2.<VNx2DF_ONLY:Vetype>\;fcvtz<su>\t%0.<VNx4SI_ONLY:Vetype>, %1/m, %2.<VNx2DF_ONLY:Vetype>
9061 1.1.1.3 mrg movprfx\t%0, %3\;fcvtz<su>\t%0.<VNx4SI_ONLY:Vetype>, %1/m, %2.<VNx2DF_ONLY:Vetype>"
9062 1.1.1.3 mrg [(set_attr "movprfx" "*,yes,yes")]
9063 1.1 mrg )
9064 1.1 mrg
9065 1.1.1.3 mrg ;; -------------------------------------------------------------------------
9066 1.1.1.3 mrg ;; ---- [INT<-FP] Packs
9067 1.1.1.3 mrg ;; -------------------------------------------------------------------------
9068 1.1.1.3 mrg ;; The patterns in this section are synthetic.
9069 1.1.1.3 mrg ;; -------------------------------------------------------------------------
9070 1.1.1.2 mrg
9071 1.1.1.3 mrg ;; Convert two vectors of DF to SI and pack the results into a single vector.
9072 1.1.1.3 mrg (define_expand "vec_pack_<su>fix_trunc_vnx2df"
9073 1.1.1.3 mrg [(set (match_dup 4)
9074 1.1.1.3 mrg (unspec:VNx4SI
9075 1.1.1.3 mrg [(match_dup 3)
9076 1.1.1.3 mrg (const_int SVE_RELAXED_GP)
9077 1.1.1.3 mrg (match_operand:VNx2DF 1 "register_operand")]
9078 1.1.1.3 mrg SVE_COND_FCVTI))
9079 1.1.1.3 mrg (set (match_dup 5)
9080 1.1.1.3 mrg (unspec:VNx4SI
9081 1.1.1.3 mrg [(match_dup 3)
9082 1.1.1.3 mrg (const_int SVE_RELAXED_GP)
9083 1.1.1.3 mrg (match_operand:VNx2DF 2 "register_operand")]
9084 1.1.1.3 mrg SVE_COND_FCVTI))
9085 1.1.1.3 mrg (set (match_operand:VNx4SI 0 "register_operand")
9086 1.1.1.3 mrg (unspec:VNx4SI [(match_dup 4) (match_dup 5)] UNSPEC_UZP1))]
9087 1.1 mrg "TARGET_SVE"
9088 1.1 mrg {
9089 1.1.1.3 mrg operands[3] = aarch64_ptrue_reg (VNx2BImode);
9090 1.1.1.3 mrg operands[4] = gen_reg_rtx (VNx4SImode);
9091 1.1.1.3 mrg operands[5] = gen_reg_rtx (VNx4SImode);
9092 1.1 mrg }
9093 1.1 mrg )
9094 1.1 mrg
9095 1.1.1.3 mrg ;; -------------------------------------------------------------------------
9096 1.1.1.3 mrg ;; ---- [INT<-FP] Unpacks
9097 1.1.1.3 mrg ;; -------------------------------------------------------------------------
9098 1.1.1.3 mrg ;; No patterns here yet!
9099 1.1.1.3 mrg ;; -------------------------------------------------------------------------
9100 1.1.1.3 mrg
9101 1.1.1.3 mrg ;; -------------------------------------------------------------------------
9102 1.1.1.3 mrg ;; ---- [FP<-INT] Conversions
9103 1.1.1.3 mrg ;; -------------------------------------------------------------------------
9104 1.1.1.3 mrg ;; Includes:
9105 1.1.1.3 mrg ;; - SCVTF
9106 1.1.1.3 mrg ;; - UCVTF
9107 1.1.1.3 mrg ;; -------------------------------------------------------------------------
9108 1.1 mrg
9109 1.1.1.3 mrg ;; Unpredicated conversion of integers to floats of the same size
9110 1.1.1.3 mrg ;; (HI to HF, SI to SF or DI to DF).
9111 1.1.1.3 mrg (define_expand "<optab><v_int_equiv><mode>2"
9112 1.1.1.3 mrg [(set (match_operand:SVE_FULL_F 0 "register_operand")
9113 1.1.1.3 mrg (unspec:SVE_FULL_F
9114 1.1.1.3 mrg [(match_dup 2)
9115 1.1.1.3 mrg (const_int SVE_RELAXED_GP)
9116 1.1.1.3 mrg (match_operand:<V_INT_EQUIV> 1 "register_operand")]
9117 1.1.1.3 mrg SVE_COND_ICVTF))]
9118 1.1 mrg "TARGET_SVE"
9119 1.1 mrg {
9120 1.1.1.3 mrg operands[2] = aarch64_ptrue_reg (<VPRED>mode);
9121 1.1 mrg }
9122 1.1 mrg )
9123 1.1 mrg
9124 1.1.1.3 mrg ;; Predicated integer-to-float conversion, either to the same width or
9125 1.1.1.3 mrg ;; narrower.
9126 1.1.1.3 mrg (define_insn "@aarch64_sve_<optab>_nonextend<SVE_FULL_HSDI:mode><SVE_FULL_F:mode>"
9127 1.1.1.3 mrg [(set (match_operand:SVE_FULL_F 0 "register_operand" "=w, ?&w")
9128 1.1.1.3 mrg (unspec:SVE_FULL_F
9129 1.1.1.3 mrg [(match_operand:<SVE_FULL_HSDI:VPRED> 1 "register_operand" "Upl, Upl")
9130 1.1.1.3 mrg (match_operand:SI 3 "aarch64_sve_gp_strictness")
9131 1.1.1.3 mrg (match_operand:SVE_FULL_HSDI 2 "register_operand" "0, w")]
9132 1.1.1.3 mrg SVE_COND_ICVTF))]
9133 1.1.1.3 mrg "TARGET_SVE && <SVE_FULL_HSDI:elem_bits> >= <SVE_FULL_F:elem_bits>"
9134 1.1.1.3 mrg "@
9135 1.1.1.3 mrg <su>cvtf\t%0.<SVE_FULL_F:Vetype>, %1/m, %2.<SVE_FULL_HSDI:Vetype>
9136 1.1.1.3 mrg movprfx\t%0, %2\;<su>cvtf\t%0.<SVE_FULL_F:Vetype>, %1/m, %2.<SVE_FULL_HSDI:Vetype>"
9137 1.1.1.3 mrg [(set_attr "movprfx" "*,yes")]
9138 1.1.1.3 mrg )
9139 1.1.1.3 mrg
9140 1.1.1.3 mrg ;; Predicated widening integer-to-float conversion.
9141 1.1.1.3 mrg (define_insn "@aarch64_sve_<optab>_extend<VNx4SI_ONLY:mode><VNx2DF_ONLY:mode>"
9142 1.1.1.3 mrg [(set (match_operand:VNx2DF_ONLY 0 "register_operand" "=w, ?&w")
9143 1.1.1.3 mrg (unspec:VNx2DF_ONLY
9144 1.1.1.3 mrg [(match_operand:VNx2BI 1 "register_operand" "Upl, Upl")
9145 1.1.1.3 mrg (match_operand:SI 3 "aarch64_sve_gp_strictness")
9146 1.1.1.3 mrg (match_operand:VNx4SI_ONLY 2 "register_operand" "0, w")]
9147 1.1.1.3 mrg SVE_COND_ICVTF))]
9148 1.1 mrg "TARGET_SVE"
9149 1.1 mrg "@
9150 1.1.1.3 mrg <su>cvtf\t%0.<VNx2DF_ONLY:Vetype>, %1/m, %2.<VNx4SI_ONLY:Vetype>
9151 1.1.1.3 mrg movprfx\t%0, %2\;<su>cvtf\t%0.<VNx2DF_ONLY:Vetype>, %1/m, %2.<VNx4SI_ONLY:Vetype>"
9152 1.1.1.3 mrg [(set_attr "movprfx" "*,yes")]
9153 1.1 mrg )
9154 1.1 mrg
9155 1.1.1.3 mrg ;; Predicated integer-to-float conversion with merging, either to the same
9156 1.1.1.3 mrg ;; width or narrower.
9157 1.1.1.3 mrg (define_expand "@cond_<optab>_nonextend<SVE_FULL_HSDI:mode><SVE_FULL_F:mode>"
9158 1.1.1.3 mrg [(set (match_operand:SVE_FULL_F 0 "register_operand")
9159 1.1.1.3 mrg (unspec:SVE_FULL_F
9160 1.1.1.3 mrg [(match_operand:<SVE_FULL_HSDI:VPRED> 1 "register_operand")
9161 1.1.1.3 mrg (unspec:SVE_FULL_F
9162 1.1.1.3 mrg [(match_dup 1)
9163 1.1.1.3 mrg (const_int SVE_STRICT_GP)
9164 1.1.1.3 mrg (match_operand:SVE_FULL_HSDI 2 "register_operand")]
9165 1.1.1.3 mrg SVE_COND_ICVTF)
9166 1.1.1.3 mrg (match_operand:SVE_FULL_F 3 "aarch64_simd_reg_or_zero")]
9167 1.1.1.3 mrg UNSPEC_SEL))]
9168 1.1.1.3 mrg "TARGET_SVE && <SVE_FULL_HSDI:elem_bits> >= <SVE_FULL_F:elem_bits>"
9169 1.1.1.3 mrg )
9170 1.1.1.3 mrg
9171 1.1.1.3 mrg ;; The first alternative doesn't need the earlyclobber, but the only case
9172 1.1.1.3 mrg ;; it would help is the uninteresting one in which operands 2 and 3 are
9173 1.1.1.3 mrg ;; the same register (despite having different modes). Making all the
9174 1.1.1.3 mrg ;; alternatives earlyclobber makes things more consistent for the
9175 1.1.1.3 mrg ;; register allocator.
9176 1.1.1.3 mrg (define_insn_and_rewrite "*cond_<optab>_nonextend<SVE_FULL_HSDI:mode><SVE_FULL_F:mode>_relaxed"
9177 1.1.1.3 mrg [(set (match_operand:SVE_FULL_F 0 "register_operand" "=&w, &w, ?&w")
9178 1.1.1.3 mrg (unspec:SVE_FULL_F
9179 1.1.1.3 mrg [(match_operand:<SVE_FULL_HSDI:VPRED> 1 "register_operand" "Upl, Upl, Upl")
9180 1.1.1.3 mrg (unspec:SVE_FULL_F
9181 1.1.1.3 mrg [(match_operand 4)
9182 1.1.1.3 mrg (const_int SVE_RELAXED_GP)
9183 1.1.1.3 mrg (match_operand:SVE_FULL_HSDI 2 "register_operand" "w, w, w")]
9184 1.1.1.3 mrg SVE_COND_ICVTF)
9185 1.1.1.3 mrg (match_operand:SVE_FULL_F 3 "aarch64_simd_reg_or_zero" "0, Dz, w")]
9186 1.1.1.3 mrg UNSPEC_SEL))]
9187 1.1.1.3 mrg "TARGET_SVE && <SVE_FULL_HSDI:elem_bits> >= <SVE_FULL_F:elem_bits>"
9188 1.1.1.3 mrg "@
9189 1.1.1.3 mrg <su>cvtf\t%0.<SVE_FULL_F:Vetype>, %1/m, %2.<SVE_FULL_HSDI:Vetype>
9190 1.1.1.3 mrg movprfx\t%0.<SVE_FULL_HSDI:Vetype>, %1/z, %2.<SVE_FULL_HSDI:Vetype>\;<su>cvtf\t%0.<SVE_FULL_F:Vetype>, %1/m, %2.<SVE_FULL_HSDI:Vetype>
9191 1.1.1.3 mrg movprfx\t%0, %3\;<su>cvtf\t%0.<SVE_FULL_F:Vetype>, %1/m, %2.<SVE_FULL_HSDI:Vetype>"
9192 1.1.1.3 mrg "&& !rtx_equal_p (operands[1], operands[4])"
9193 1.1.1.3 mrg {
9194 1.1.1.3 mrg operands[4] = copy_rtx (operands[1]);
9195 1.1.1.3 mrg }
9196 1.1.1.3 mrg [(set_attr "movprfx" "*,yes,yes")]
9197 1.1.1.3 mrg )
9198 1.1.1.3 mrg
9199 1.1.1.3 mrg (define_insn "*cond_<optab>_nonextend<SVE_FULL_HSDI:mode><SVE_FULL_F:mode>_strict"
9200 1.1.1.3 mrg [(set (match_operand:SVE_FULL_F 0 "register_operand" "=&w, &w, ?&w")
9201 1.1.1.3 mrg (unspec:SVE_FULL_F
9202 1.1.1.3 mrg [(match_operand:<SVE_FULL_HSDI:VPRED> 1 "register_operand" "Upl, Upl, Upl")
9203 1.1.1.3 mrg (unspec:SVE_FULL_F
9204 1.1.1.3 mrg [(match_dup 1)
9205 1.1.1.3 mrg (const_int SVE_STRICT_GP)
9206 1.1.1.3 mrg (match_operand:SVE_FULL_HSDI 2 "register_operand" "w, w, w")]
9207 1.1.1.3 mrg SVE_COND_ICVTF)
9208 1.1.1.3 mrg (match_operand:SVE_FULL_F 3 "aarch64_simd_reg_or_zero" "0, Dz, w")]
9209 1.1.1.3 mrg UNSPEC_SEL))]
9210 1.1.1.3 mrg "TARGET_SVE && <SVE_FULL_HSDI:elem_bits> >= <SVE_FULL_F:elem_bits>"
9211 1.1.1.3 mrg "@
9212 1.1.1.3 mrg <su>cvtf\t%0.<SVE_FULL_F:Vetype>, %1/m, %2.<SVE_FULL_HSDI:Vetype>
9213 1.1.1.3 mrg movprfx\t%0.<SVE_FULL_HSDI:Vetype>, %1/z, %2.<SVE_FULL_HSDI:Vetype>\;<su>cvtf\t%0.<SVE_FULL_F:Vetype>, %1/m, %2.<SVE_FULL_HSDI:Vetype>
9214 1.1.1.3 mrg movprfx\t%0, %3\;<su>cvtf\t%0.<SVE_FULL_F:Vetype>, %1/m, %2.<SVE_FULL_HSDI:Vetype>"
9215 1.1.1.3 mrg [(set_attr "movprfx" "*,yes,yes")]
9216 1.1.1.3 mrg )
9217 1.1.1.3 mrg
9218 1.1.1.3 mrg ;; Predicated widening integer-to-float conversion with merging.
9219 1.1.1.3 mrg (define_expand "@cond_<optab>_extend<VNx4SI_ONLY:mode><VNx2DF_ONLY:mode>"
9220 1.1.1.3 mrg [(set (match_operand:VNx2DF_ONLY 0 "register_operand")
9221 1.1.1.3 mrg (unspec:VNx2DF_ONLY
9222 1.1.1.3 mrg [(match_operand:VNx2BI 1 "register_operand")
9223 1.1.1.3 mrg (unspec:VNx2DF_ONLY
9224 1.1.1.3 mrg [(match_dup 1)
9225 1.1.1.3 mrg (const_int SVE_STRICT_GP)
9226 1.1.1.3 mrg (match_operand:VNx4SI_ONLY 2 "register_operand")]
9227 1.1.1.3 mrg SVE_COND_ICVTF)
9228 1.1.1.3 mrg (match_operand:VNx2DF_ONLY 3 "aarch64_simd_reg_or_zero")]
9229 1.1.1.3 mrg UNSPEC_SEL))]
9230 1.1 mrg "TARGET_SVE"
9231 1.1 mrg )
9232 1.1 mrg
9233 1.1.1.3 mrg (define_insn "*cond_<optab>_extend<VNx4SI_ONLY:mode><VNx2DF_ONLY:mode>"
9234 1.1.1.3 mrg [(set (match_operand:VNx2DF_ONLY 0 "register_operand" "=w, ?&w, ?&w")
9235 1.1.1.3 mrg (unspec:VNx2DF_ONLY
9236 1.1.1.3 mrg [(match_operand:VNx2BI 1 "register_operand" "Upl, Upl, Upl")
9237 1.1.1.3 mrg (unspec:VNx2DF_ONLY
9238 1.1.1.3 mrg [(match_dup 1)
9239 1.1.1.3 mrg (match_operand:SI 4 "aarch64_sve_gp_strictness")
9240 1.1.1.3 mrg (match_operand:VNx4SI_ONLY 2 "register_operand" "w, w, w")]
9241 1.1.1.3 mrg SVE_COND_ICVTF)
9242 1.1.1.3 mrg (match_operand:VNx2DF_ONLY 3 "aarch64_simd_reg_or_zero" "0, Dz, w")]
9243 1.1.1.3 mrg UNSPEC_SEL))]
9244 1.1 mrg "TARGET_SVE"
9245 1.1 mrg "@
9246 1.1.1.3 mrg <su>cvtf\t%0.<VNx2DF_ONLY:Vetype>, %1/m, %2.<VNx4SI_ONLY:Vetype>
9247 1.1.1.3 mrg movprfx\t%0.<VNx2DF_ONLY:Vetype>, %1/z, %2.<VNx2DF_ONLY:Vetype>\;<su>cvtf\t%0.<VNx2DF_ONLY:Vetype>, %1/m, %2.<VNx4SI_ONLY:Vetype>
9248 1.1.1.3 mrg movprfx\t%0, %3\;<su>cvtf\t%0.<VNx2DF_ONLY:Vetype>, %1/m, %2.<VNx4SI_ONLY:Vetype>"
9249 1.1.1.3 mrg [(set_attr "movprfx" "*,yes,yes")]
9250 1.1.1.3 mrg )
9251 1.1.1.3 mrg
9252 1.1.1.3 mrg ;; -------------------------------------------------------------------------
9253 1.1.1.3 mrg ;; ---- [FP<-INT] Packs
9254 1.1.1.3 mrg ;; -------------------------------------------------------------------------
9255 1.1.1.3 mrg ;; No patterns here yet!
9256 1.1.1.3 mrg ;; -------------------------------------------------------------------------
9257 1.1.1.3 mrg
9258 1.1.1.3 mrg ;; -------------------------------------------------------------------------
9259 1.1.1.3 mrg ;; ---- [FP<-INT] Unpacks
9260 1.1.1.3 mrg ;; -------------------------------------------------------------------------
9261 1.1.1.3 mrg ;; The patterns in this section are synthetic.
9262 1.1.1.3 mrg ;; -------------------------------------------------------------------------
9263 1.1 mrg
9264 1.1.1.3 mrg ;; Unpack one half of a VNx4SI to VNx2DF. First unpack from VNx4SI
9265 1.1.1.3 mrg ;; to VNx2DI, reinterpret the VNx2DI as a VNx4SI, then convert the
9266 1.1.1.3 mrg ;; unpacked VNx4SI to VNx2DF.
9267 1.1.1.3 mrg (define_expand "vec_unpack<su_optab>_float_<perm_hilo>_vnx4si"
9268 1.1.1.3 mrg [(match_operand:VNx2DF 0 "register_operand")
9269 1.1.1.3 mrg (FLOATUORS:VNx2DF
9270 1.1.1.3 mrg (unspec:VNx2DI [(match_operand:VNx4SI 1 "register_operand")]
9271 1.1.1.3 mrg UNPACK_UNSIGNED))]
9272 1.1 mrg "TARGET_SVE"
9273 1.1 mrg {
9274 1.1.1.3 mrg /* Use ZIP to do the unpack, since we don't care about the upper halves
9275 1.1.1.3 mrg and since it has the nice property of not needing any subregs.
9276 1.1.1.3 mrg If using UUNPK* turns out to be preferable, we could model it as
9277 1.1.1.3 mrg a ZIP whose first operand is zero. */
9278 1.1.1.3 mrg rtx temp = gen_reg_rtx (VNx4SImode);
9279 1.1.1.3 mrg emit_insn ((<hi_lanes_optab>
9280 1.1.1.3 mrg ? gen_aarch64_sve_zip2vnx4si
9281 1.1.1.3 mrg : gen_aarch64_sve_zip1vnx4si)
9282 1.1.1.3 mrg (temp, operands[1], operands[1]));
9283 1.1.1.3 mrg rtx ptrue = aarch64_ptrue_reg (VNx2BImode);
9284 1.1.1.3 mrg rtx strictness = gen_int_mode (SVE_RELAXED_GP, SImode);
9285 1.1.1.3 mrg emit_insn (gen_aarch64_sve_<FLOATUORS:optab>_extendvnx4sivnx2df
9286 1.1.1.3 mrg (operands[0], ptrue, temp, strictness));
9287 1.1.1.3 mrg DONE;
9288 1.1 mrg }
9289 1.1 mrg )
9290 1.1 mrg
9291 1.1.1.3 mrg ;; -------------------------------------------------------------------------
9292 1.1.1.3 mrg ;; ---- [FP<-FP] Packs
9293 1.1.1.3 mrg ;; -------------------------------------------------------------------------
9294 1.1.1.3 mrg ;; Includes:
9295 1.1.1.3 mrg ;; - FCVT
9296 1.1.1.3 mrg ;; -------------------------------------------------------------------------
9297 1.1 mrg
9298 1.1.1.3 mrg ;; Convert two vectors of DF to SF, or two vectors of SF to HF, and pack
9299 1.1.1.3 mrg ;; the results into a single vector.
9300 1.1.1.3 mrg (define_expand "vec_pack_trunc_<Vwide>"
9301 1.1.1.3 mrg [(set (match_dup 4)
9302 1.1.1.3 mrg (unspec:SVE_FULL_HSF
9303 1.1.1.3 mrg [(match_dup 3)
9304 1.1.1.3 mrg (const_int SVE_RELAXED_GP)
9305 1.1.1.3 mrg (match_operand:<VWIDE> 1 "register_operand")]
9306 1.1.1.3 mrg UNSPEC_COND_FCVT))
9307 1.1.1.3 mrg (set (match_dup 5)
9308 1.1.1.3 mrg (unspec:SVE_FULL_HSF
9309 1.1 mrg [(match_dup 3)
9310 1.1.1.3 mrg (const_int SVE_RELAXED_GP)
9311 1.1.1.3 mrg (match_operand:<VWIDE> 2 "register_operand")]
9312 1.1.1.3 mrg UNSPEC_COND_FCVT))
9313 1.1.1.3 mrg (set (match_operand:SVE_FULL_HSF 0 "register_operand")
9314 1.1.1.3 mrg (unspec:SVE_FULL_HSF [(match_dup 4) (match_dup 5)] UNSPEC_UZP1))]
9315 1.1 mrg "TARGET_SVE"
9316 1.1 mrg {
9317 1.1.1.3 mrg operands[3] = aarch64_ptrue_reg (<VWIDE_PRED>mode);
9318 1.1.1.3 mrg operands[4] = gen_reg_rtx (<MODE>mode);
9319 1.1.1.3 mrg operands[5] = gen_reg_rtx (<MODE>mode);
9320 1.1 mrg }
9321 1.1 mrg )
9322 1.1 mrg
9323 1.1.1.3 mrg ;; Predicated float-to-float truncation.
9324 1.1.1.3 mrg (define_insn "@aarch64_sve_<optab>_trunc<SVE_FULL_SDF:mode><SVE_FULL_HSF:mode>"
9325 1.1.1.3 mrg [(set (match_operand:SVE_FULL_HSF 0 "register_operand" "=w, ?&w")
9326 1.1.1.3 mrg (unspec:SVE_FULL_HSF
9327 1.1.1.3 mrg [(match_operand:<SVE_FULL_SDF:VPRED> 1 "register_operand" "Upl, Upl")
9328 1.1.1.3 mrg (match_operand:SI 3 "aarch64_sve_gp_strictness")
9329 1.1.1.3 mrg (match_operand:SVE_FULL_SDF 2 "register_operand" "0, w")]
9330 1.1.1.3 mrg SVE_COND_FCVT))]
9331 1.1.1.3 mrg "TARGET_SVE && <SVE_FULL_SDF:elem_bits> > <SVE_FULL_HSF:elem_bits>"
9332 1.1 mrg "@
9333 1.1.1.3 mrg fcvt\t%0.<SVE_FULL_HSF:Vetype>, %1/m, %2.<SVE_FULL_SDF:Vetype>
9334 1.1.1.3 mrg movprfx\t%0, %2\;fcvt\t%0.<SVE_FULL_HSF:Vetype>, %1/m, %2.<SVE_FULL_SDF:Vetype>"
9335 1.1.1.3 mrg [(set_attr "movprfx" "*,yes")]
9336 1.1 mrg )
9337 1.1 mrg
9338 1.1.1.3 mrg ;; Predicated float-to-float truncation with merging.
9339 1.1.1.3 mrg (define_expand "@cond_<optab>_trunc<SVE_FULL_SDF:mode><SVE_FULL_HSF:mode>"
9340 1.1.1.3 mrg [(set (match_operand:SVE_FULL_HSF 0 "register_operand")
9341 1.1.1.3 mrg (unspec:SVE_FULL_HSF
9342 1.1.1.3 mrg [(match_operand:<SVE_FULL_SDF:VPRED> 1 "register_operand")
9343 1.1.1.3 mrg (unspec:SVE_FULL_HSF
9344 1.1.1.3 mrg [(match_dup 1)
9345 1.1.1.3 mrg (const_int SVE_STRICT_GP)
9346 1.1.1.3 mrg (match_operand:SVE_FULL_SDF 2 "register_operand")]
9347 1.1.1.3 mrg SVE_COND_FCVT)
9348 1.1.1.3 mrg (match_operand:SVE_FULL_HSF 3 "aarch64_simd_reg_or_zero")]
9349 1.1.1.3 mrg UNSPEC_SEL))]
9350 1.1.1.3 mrg "TARGET_SVE && <SVE_FULL_SDF:elem_bits> > <SVE_FULL_HSF:elem_bits>"
9351 1.1 mrg )
9352 1.1 mrg
9353 1.1.1.3 mrg (define_insn "*cond_<optab>_trunc<SVE_FULL_SDF:mode><SVE_FULL_HSF:mode>"
9354 1.1.1.3 mrg [(set (match_operand:SVE_FULL_HSF 0 "register_operand" "=w, ?&w, ?&w")
9355 1.1.1.3 mrg (unspec:SVE_FULL_HSF
9356 1.1.1.3 mrg [(match_operand:<SVE_FULL_SDF:VPRED> 1 "register_operand" "Upl, Upl, Upl")
9357 1.1.1.3 mrg (unspec:SVE_FULL_HSF
9358 1.1.1.3 mrg [(match_dup 1)
9359 1.1.1.3 mrg (match_operand:SI 4 "aarch64_sve_gp_strictness")
9360 1.1.1.3 mrg (match_operand:SVE_FULL_SDF 2 "register_operand" "w, w, w")]
9361 1.1.1.3 mrg SVE_COND_FCVT)
9362 1.1.1.3 mrg (match_operand:SVE_FULL_HSF 3 "aarch64_simd_reg_or_zero" "0, Dz, w")]
9363 1.1.1.3 mrg UNSPEC_SEL))]
9364 1.1.1.3 mrg "TARGET_SVE && <SVE_FULL_SDF:elem_bits> > <SVE_FULL_HSF:elem_bits>"
9365 1.1.1.3 mrg "@
9366 1.1.1.3 mrg fcvt\t%0.<SVE_FULL_HSF:Vetype>, %1/m, %2.<SVE_FULL_SDF:Vetype>
9367 1.1.1.3 mrg movprfx\t%0.<SVE_FULL_SDF:Vetype>, %1/z, %2.<SVE_FULL_SDF:Vetype>\;fcvt\t%0.<SVE_FULL_HSF:Vetype>, %1/m, %2.<SVE_FULL_SDF:Vetype>
9368 1.1.1.3 mrg movprfx\t%0, %3\;fcvt\t%0.<SVE_FULL_HSF:Vetype>, %1/m, %2.<SVE_FULL_SDF:Vetype>"
9369 1.1.1.3 mrg [(set_attr "movprfx" "*,yes,yes")]
9370 1.1.1.3 mrg )
9371 1.1.1.3 mrg
9372 1.1.1.3 mrg ;; -------------------------------------------------------------------------
9373 1.1.1.3 mrg ;; ---- [FP<-FP] Packs (bfloat16)
9374 1.1.1.3 mrg ;; -------------------------------------------------------------------------
9375 1.1.1.3 mrg ;; Includes:
9376 1.1.1.3 mrg ;; - BFCVT (BF16)
9377 1.1.1.3 mrg ;; - BFCVTNT (BF16)
9378 1.1.1.3 mrg ;; -------------------------------------------------------------------------
9379 1.1.1.3 mrg
9380 1.1.1.3 mrg ;; Predicated BFCVT.
9381 1.1.1.3 mrg (define_insn "@aarch64_sve_<optab>_trunc<VNx4SF_ONLY:mode><VNx8BF_ONLY:mode>"
9382 1.1.1.3 mrg [(set (match_operand:VNx8BF_ONLY 0 "register_operand" "=w, ?&w")
9383 1.1.1.3 mrg (unspec:VNx8BF_ONLY
9384 1.1.1.3 mrg [(match_operand:VNx4BI 1 "register_operand" "Upl, Upl")
9385 1.1.1.3 mrg (match_operand:SI 3 "aarch64_sve_gp_strictness")
9386 1.1.1.3 mrg (match_operand:VNx4SF_ONLY 2 "register_operand" "0, w")]
9387 1.1.1.3 mrg SVE_COND_FCVT))]
9388 1.1.1.3 mrg "TARGET_SVE_BF16"
9389 1.1.1.3 mrg "@
9390 1.1.1.3 mrg bfcvt\t%0.h, %1/m, %2.s
9391 1.1.1.3 mrg movprfx\t%0, %2\;bfcvt\t%0.h, %1/m, %2.s"
9392 1.1.1.3 mrg [(set_attr "movprfx" "*,yes")]
9393 1.1 mrg )
9394 1.1 mrg
9395 1.1.1.3 mrg ;; Predicated BFCVT with merging.
9396 1.1.1.3 mrg (define_expand "@cond_<optab>_trunc<VNx4SF_ONLY:mode><VNx8BF_ONLY:mode>"
9397 1.1.1.3 mrg [(set (match_operand:VNx8BF_ONLY 0 "register_operand")
9398 1.1.1.3 mrg (unspec:VNx8BF_ONLY
9399 1.1.1.3 mrg [(match_operand:VNx4BI 1 "register_operand")
9400 1.1.1.3 mrg (unspec:VNx8BF_ONLY
9401 1.1.1.3 mrg [(match_dup 1)
9402 1.1.1.3 mrg (const_int SVE_STRICT_GP)
9403 1.1.1.3 mrg (match_operand:VNx4SF_ONLY 2 "register_operand")]
9404 1.1.1.3 mrg SVE_COND_FCVT)
9405 1.1.1.3 mrg (match_operand:VNx8BF_ONLY 3 "aarch64_simd_reg_or_zero")]
9406 1.1.1.3 mrg UNSPEC_SEL))]
9407 1.1.1.3 mrg "TARGET_SVE_BF16"
9408 1.1 mrg )
9409 1.1 mrg
9410 1.1.1.3 mrg (define_insn "*cond_<optab>_trunc<VNx4SF_ONLY:mode><VNx8BF_ONLY:mode>"
9411 1.1.1.3 mrg [(set (match_operand:VNx8BF_ONLY 0 "register_operand" "=w, ?&w, ?&w")
9412 1.1.1.3 mrg (unspec:VNx8BF_ONLY
9413 1.1.1.3 mrg [(match_operand:VNx4BI 1 "register_operand" "Upl, Upl, Upl")
9414 1.1.1.3 mrg (unspec:VNx8BF_ONLY
9415 1.1.1.3 mrg [(match_dup 1)
9416 1.1.1.3 mrg (match_operand:SI 4 "aarch64_sve_gp_strictness")
9417 1.1.1.3 mrg (match_operand:VNx4SF_ONLY 2 "register_operand" "w, w, w")]
9418 1.1.1.3 mrg SVE_COND_FCVT)
9419 1.1.1.3 mrg (match_operand:VNx8BF_ONLY 3 "aarch64_simd_reg_or_zero" "0, Dz, w")]
9420 1.1.1.3 mrg UNSPEC_SEL))]
9421 1.1.1.3 mrg "TARGET_SVE_BF16"
9422 1.1.1.3 mrg "@
9423 1.1.1.3 mrg bfcvt\t%0.h, %1/m, %2.s
9424 1.1.1.3 mrg movprfx\t%0.s, %1/z, %2.s\;bfcvt\t%0.h, %1/m, %2.s
9425 1.1.1.3 mrg movprfx\t%0, %3\;bfcvt\t%0.h, %1/m, %2.s"
9426 1.1.1.3 mrg [(set_attr "movprfx" "*,yes,yes")]
9427 1.1 mrg )
9428 1.1 mrg
9429 1.1.1.3 mrg ;; Predicated BFCVTNT. This doesn't give a natural aarch64_pred_*/cond_*
9430 1.1.1.3 mrg ;; pair because the even elements always have to be supplied for active
9431 1.1.1.3 mrg ;; elements, even if the inactive elements don't matter.
9432 1.1.1.3 mrg ;;
9433 1.1.1.3 mrg ;; This instructions does not take MOVPRFX.
9434 1.1.1.3 mrg (define_insn "@aarch64_sve_cvtnt<mode>"
9435 1.1.1.3 mrg [(set (match_operand:VNx8BF_ONLY 0 "register_operand" "=w")
9436 1.1.1.3 mrg (unspec:VNx8BF_ONLY
9437 1.1.1.3 mrg [(match_operand:VNx4BI 2 "register_operand" "Upl")
9438 1.1.1.3 mrg (const_int SVE_STRICT_GP)
9439 1.1.1.3 mrg (match_operand:VNx8BF_ONLY 1 "register_operand" "0")
9440 1.1.1.3 mrg (match_operand:VNx4SF 3 "register_operand" "w")]
9441 1.1.1.3 mrg UNSPEC_COND_FCVTNT))]
9442 1.1.1.3 mrg "TARGET_SVE_BF16"
9443 1.1.1.3 mrg "bfcvtnt\t%0.h, %2/m, %3.s"
9444 1.1.1.3 mrg )
9445 1.1.1.3 mrg
9446 1.1.1.3 mrg ;; -------------------------------------------------------------------------
9447 1.1.1.3 mrg ;; ---- [FP<-FP] Unpacks
9448 1.1.1.3 mrg ;; -------------------------------------------------------------------------
9449 1.1.1.3 mrg ;; Includes:
9450 1.1.1.3 mrg ;; - FCVT
9451 1.1.1.3 mrg ;; -------------------------------------------------------------------------
9452 1.1.1.3 mrg
9453 1.1.1.3 mrg ;; Unpack one half of a VNx4SF to VNx2DF, or one half of a VNx8HF to VNx4SF.
9454 1.1.1.3 mrg ;; First unpack the source without conversion, then float-convert the
9455 1.1.1.3 mrg ;; unpacked source.
9456 1.1.1.3 mrg (define_expand "vec_unpacks_<perm_hilo>_<mode>"
9457 1.1.1.3 mrg [(match_operand:<VWIDE> 0 "register_operand")
9458 1.1.1.3 mrg (unspec:SVE_FULL_HSF
9459 1.1.1.3 mrg [(match_operand:SVE_FULL_HSF 1 "register_operand")]
9460 1.1.1.3 mrg UNPACK_UNSIGNED)]
9461 1.1 mrg "TARGET_SVE"
9462 1.1 mrg {
9463 1.1.1.3 mrg /* Use ZIP to do the unpack, since we don't care about the upper halves
9464 1.1.1.3 mrg and since it has the nice property of not needing any subregs.
9465 1.1.1.3 mrg If using UUNPK* turns out to be preferable, we could model it as
9466 1.1.1.3 mrg a ZIP whose first operand is zero. */
9467 1.1.1.3 mrg rtx temp = gen_reg_rtx (<MODE>mode);
9468 1.1.1.3 mrg emit_insn ((<hi_lanes_optab>
9469 1.1.1.3 mrg ? gen_aarch64_sve_zip2<mode>
9470 1.1.1.3 mrg : gen_aarch64_sve_zip1<mode>)
9471 1.1.1.3 mrg (temp, operands[1], operands[1]));
9472 1.1.1.3 mrg rtx ptrue = aarch64_ptrue_reg (<VWIDE_PRED>mode);
9473 1.1.1.3 mrg rtx strictness = gen_int_mode (SVE_RELAXED_GP, SImode);
9474 1.1.1.3 mrg emit_insn (gen_aarch64_sve_fcvt_nontrunc<mode><Vwide>
9475 1.1.1.3 mrg (operands[0], ptrue, temp, strictness));
9476 1.1.1.3 mrg DONE;
9477 1.1 mrg }
9478 1.1 mrg )
9479 1.1 mrg
9480 1.1.1.3 mrg ;; Predicated float-to-float extension.
9481 1.1.1.3 mrg (define_insn "@aarch64_sve_<optab>_nontrunc<SVE_FULL_HSF:mode><SVE_FULL_SDF:mode>"
9482 1.1.1.3 mrg [(set (match_operand:SVE_FULL_SDF 0 "register_operand" "=w, ?&w")
9483 1.1.1.3 mrg (unspec:SVE_FULL_SDF
9484 1.1.1.3 mrg [(match_operand:<SVE_FULL_SDF:VPRED> 1 "register_operand" "Upl, Upl")
9485 1.1.1.3 mrg (match_operand:SI 3 "aarch64_sve_gp_strictness")
9486 1.1.1.3 mrg (match_operand:SVE_FULL_HSF 2 "register_operand" "0, w")]
9487 1.1.1.3 mrg SVE_COND_FCVT))]
9488 1.1.1.3 mrg "TARGET_SVE && <SVE_FULL_SDF:elem_bits> > <SVE_FULL_HSF:elem_bits>"
9489 1.1.1.3 mrg "@
9490 1.1.1.3 mrg fcvt\t%0.<SVE_FULL_SDF:Vetype>, %1/m, %2.<SVE_FULL_HSF:Vetype>
9491 1.1.1.3 mrg movprfx\t%0, %2\;fcvt\t%0.<SVE_FULL_SDF:Vetype>, %1/m, %2.<SVE_FULL_HSF:Vetype>"
9492 1.1.1.3 mrg [(set_attr "movprfx" "*,yes")]
9493 1.1 mrg )
9494 1.1 mrg
9495 1.1.1.3 mrg ;; Predicated float-to-float extension with merging.
9496 1.1.1.3 mrg (define_expand "@cond_<optab>_nontrunc<SVE_FULL_HSF:mode><SVE_FULL_SDF:mode>"
9497 1.1.1.3 mrg [(set (match_operand:SVE_FULL_SDF 0 "register_operand")
9498 1.1.1.3 mrg (unspec:SVE_FULL_SDF
9499 1.1.1.3 mrg [(match_operand:<SVE_FULL_SDF:VPRED> 1 "register_operand")
9500 1.1.1.3 mrg (unspec:SVE_FULL_SDF
9501 1.1.1.3 mrg [(match_dup 1)
9502 1.1.1.3 mrg (const_int SVE_STRICT_GP)
9503 1.1.1.3 mrg (match_operand:SVE_FULL_HSF 2 "register_operand")]
9504 1.1.1.3 mrg SVE_COND_FCVT)
9505 1.1.1.3 mrg (match_operand:SVE_FULL_SDF 3 "aarch64_simd_reg_or_zero")]
9506 1.1.1.3 mrg UNSPEC_SEL))]
9507 1.1.1.3 mrg "TARGET_SVE && <SVE_FULL_SDF:elem_bits> > <SVE_FULL_HSF:elem_bits>"
9508 1.1 mrg )
9509 1.1 mrg
9510 1.1.1.3 mrg (define_insn "*cond_<optab>_nontrunc<SVE_FULL_HSF:mode><SVE_FULL_SDF:mode>"
9511 1.1.1.3 mrg [(set (match_operand:SVE_FULL_SDF 0 "register_operand" "=w, ?&w, ?&w")
9512 1.1.1.3 mrg (unspec:SVE_FULL_SDF
9513 1.1.1.3 mrg [(match_operand:<SVE_FULL_SDF:VPRED> 1 "register_operand" "Upl, Upl, Upl")
9514 1.1.1.3 mrg (unspec:SVE_FULL_SDF
9515 1.1.1.3 mrg [(match_dup 1)
9516 1.1.1.3 mrg (match_operand:SI 4 "aarch64_sve_gp_strictness")
9517 1.1.1.3 mrg (match_operand:SVE_FULL_HSF 2 "register_operand" "w, w, w")]
9518 1.1.1.3 mrg SVE_COND_FCVT)
9519 1.1.1.3 mrg (match_operand:SVE_FULL_SDF 3 "aarch64_simd_reg_or_zero" "0, Dz, w")]
9520 1.1.1.3 mrg UNSPEC_SEL))]
9521 1.1.1.3 mrg "TARGET_SVE && <SVE_FULL_SDF:elem_bits> > <SVE_FULL_HSF:elem_bits>"
9522 1.1.1.3 mrg "@
9523 1.1.1.3 mrg fcvt\t%0.<SVE_FULL_SDF:Vetype>, %1/m, %2.<SVE_FULL_HSF:Vetype>
9524 1.1.1.3 mrg movprfx\t%0.<SVE_FULL_SDF:Vetype>, %1/z, %2.<SVE_FULL_SDF:Vetype>\;fcvt\t%0.<SVE_FULL_SDF:Vetype>, %1/m, %2.<SVE_FULL_HSF:Vetype>
9525 1.1.1.3 mrg movprfx\t%0, %3\;fcvt\t%0.<SVE_FULL_SDF:Vetype>, %1/m, %2.<SVE_FULL_HSF:Vetype>"
9526 1.1.1.3 mrg [(set_attr "movprfx" "*,yes,yes")]
9527 1.1 mrg )
9528 1.1 mrg
9529 1.1.1.3 mrg ;; -------------------------------------------------------------------------
9530 1.1.1.3 mrg ;; ---- [PRED<-PRED] Packs
9531 1.1.1.3 mrg ;; -------------------------------------------------------------------------
9532 1.1.1.3 mrg ;; Includes:
9533 1.1.1.3 mrg ;; - UZP1
9534 1.1.1.3 mrg ;; -------------------------------------------------------------------------
9535 1.1 mrg
9536 1.1.1.3 mrg ;; Predicate pack. Use UZP1 on the narrower type, which discards
9537 1.1.1.3 mrg ;; the high part of each wide element.
9538 1.1.1.3 mrg (define_insn "vec_pack_trunc_<Vwide>"
9539 1.1.1.3 mrg [(set (match_operand:PRED_BHS 0 "register_operand" "=Upa")
9540 1.1.1.3 mrg (unspec:PRED_BHS
9541 1.1.1.3 mrg [(match_operand:<VWIDE> 1 "register_operand" "Upa")
9542 1.1.1.3 mrg (match_operand:<VWIDE> 2 "register_operand" "Upa")]
9543 1.1.1.3 mrg UNSPEC_PACK))]
9544 1.1 mrg "TARGET_SVE"
9545 1.1.1.3 mrg "uzp1\t%0.<Vetype>, %1.<Vetype>, %2.<Vetype>"
9546 1.1 mrg )
9547 1.1 mrg
9548 1.1.1.3 mrg ;; -------------------------------------------------------------------------
9549 1.1.1.3 mrg ;; ---- [PRED<-PRED] Unpacks
9550 1.1.1.3 mrg ;; -------------------------------------------------------------------------
9551 1.1.1.3 mrg ;; Includes:
9552 1.1.1.3 mrg ;; - PUNPKHI
9553 1.1.1.3 mrg ;; - PUNPKLO
9554 1.1.1.3 mrg ;; -------------------------------------------------------------------------
9555 1.1.1.3 mrg
9556 1.1 mrg ;; Unpack the low or high half of a predicate, where "high" refers to
9557 1.1 mrg ;; the low-numbered lanes for big-endian and the high-numbered lanes
9558 1.1 mrg ;; for little-endian.
9559 1.1 mrg (define_expand "vec_unpack<su>_<perm_hilo>_<mode>"
9560 1.1 mrg [(match_operand:<VWIDE> 0 "register_operand")
9561 1.1 mrg (unspec:<VWIDE> [(match_operand:PRED_BHS 1 "register_operand")]
9562 1.1 mrg UNPACK)]
9563 1.1 mrg "TARGET_SVE"
9564 1.1 mrg {
9565 1.1 mrg emit_insn ((<hi_lanes_optab>
9566 1.1 mrg ? gen_aarch64_sve_punpkhi_<PRED_BHS:mode>
9567 1.1 mrg : gen_aarch64_sve_punpklo_<PRED_BHS:mode>)
9568 1.1 mrg (operands[0], operands[1]));
9569 1.1 mrg DONE;
9570 1.1 mrg }
9571 1.1 mrg )
9572 1.1 mrg
9573 1.1.1.3 mrg (define_insn "@aarch64_sve_punpk<perm_hilo>_<mode>"
9574 1.1 mrg [(set (match_operand:<VWIDE> 0 "register_operand" "=Upa")
9575 1.1 mrg (unspec:<VWIDE> [(match_operand:PRED_BHS 1 "register_operand" "Upa")]
9576 1.1 mrg UNPACK_UNSIGNED))]
9577 1.1 mrg "TARGET_SVE"
9578 1.1 mrg "punpk<perm_hilo>\t%0.h, %1.b"
9579 1.1 mrg )
9580 1.1 mrg
9581 1.1.1.3 mrg ;; =========================================================================
9582 1.1.1.3 mrg ;; == Vector partitioning
9583 1.1.1.3 mrg ;; =========================================================================
9584 1.1.1.3 mrg
9585 1.1.1.3 mrg ;; -------------------------------------------------------------------------
9586 1.1.1.3 mrg ;; ---- [PRED] Unary partitioning
9587 1.1.1.3 mrg ;; -------------------------------------------------------------------------
9588 1.1.1.3 mrg ;; Includes:
9589 1.1.1.3 mrg ;; - BRKA
9590 1.1.1.3 mrg ;; - BRKAS
9591 1.1.1.3 mrg ;; - BRKB
9592 1.1.1.3 mrg ;; - BRKBS
9593 1.1.1.3 mrg ;; -------------------------------------------------------------------------
9594 1.1.1.3 mrg
9595 1.1.1.3 mrg ;; Note that unlike most other instructions that have both merging and
9596 1.1.1.3 mrg ;; zeroing forms, these instructions don't operate elementwise and so
9597 1.1.1.3 mrg ;; don't fit the IFN_COND model.
9598 1.1.1.3 mrg (define_insn "@aarch64_brk<brk_op>"
9599 1.1.1.3 mrg [(set (match_operand:VNx16BI 0 "register_operand" "=Upa, Upa")
9600 1.1.1.3 mrg (unspec:VNx16BI
9601 1.1.1.3 mrg [(match_operand:VNx16BI 1 "register_operand" "Upa, Upa")
9602 1.1.1.3 mrg (match_operand:VNx16BI 2 "register_operand" "Upa, Upa")
9603 1.1.1.3 mrg (match_operand:VNx16BI 3 "aarch64_simd_reg_or_zero" "Dz, 0")]
9604 1.1.1.3 mrg SVE_BRK_UNARY))]
9605 1.1.1.3 mrg "TARGET_SVE"
9606 1.1.1.3 mrg "@
9607 1.1.1.3 mrg brk<brk_op>\t%0.b, %1/z, %2.b
9608 1.1.1.3 mrg brk<brk_op>\t%0.b, %1/m, %2.b"
9609 1.1.1.3 mrg )
9610 1.1.1.3 mrg
9611 1.1.1.3 mrg ;; Same, but also producing a flags result.
9612 1.1.1.3 mrg (define_insn "*aarch64_brk<brk_op>_cc"
9613 1.1.1.3 mrg [(set (reg:CC_NZC CC_REGNUM)
9614 1.1.1.3 mrg (unspec:CC_NZC
9615 1.1.1.4 mrg [(match_operand:VNx16BI 1 "register_operand" "Upa")
9616 1.1.1.3 mrg (match_dup 1)
9617 1.1.1.3 mrg (match_operand:SI 4 "aarch64_sve_ptrue_flag")
9618 1.1.1.3 mrg (unspec:VNx16BI
9619 1.1.1.3 mrg [(match_dup 1)
9620 1.1.1.4 mrg (match_operand:VNx16BI 2 "register_operand" "Upa")
9621 1.1.1.4 mrg (match_operand:VNx16BI 3 "aarch64_simd_imm_zero")]
9622 1.1.1.3 mrg SVE_BRK_UNARY)]
9623 1.1.1.3 mrg UNSPEC_PTEST))
9624 1.1.1.4 mrg (set (match_operand:VNx16BI 0 "register_operand" "=Upa")
9625 1.1.1.3 mrg (unspec:VNx16BI
9626 1.1.1.3 mrg [(match_dup 1)
9627 1.1.1.3 mrg (match_dup 2)
9628 1.1.1.3 mrg (match_dup 3)]
9629 1.1.1.3 mrg SVE_BRK_UNARY))]
9630 1.1.1.3 mrg "TARGET_SVE"
9631 1.1.1.4 mrg "brk<brk_op>s\t%0.b, %1/z, %2.b"
9632 1.1.1.3 mrg )
9633 1.1.1.3 mrg
9634 1.1.1.3 mrg ;; Same, but with only the flags result being interesting.
9635 1.1.1.3 mrg (define_insn "*aarch64_brk<brk_op>_ptest"
9636 1.1.1.3 mrg [(set (reg:CC_NZC CC_REGNUM)
9637 1.1.1.3 mrg (unspec:CC_NZC
9638 1.1.1.4 mrg [(match_operand:VNx16BI 1 "register_operand" "Upa")
9639 1.1.1.3 mrg (match_dup 1)
9640 1.1.1.3 mrg (match_operand:SI 4 "aarch64_sve_ptrue_flag")
9641 1.1.1.3 mrg (unspec:VNx16BI
9642 1.1.1.3 mrg [(match_dup 1)
9643 1.1.1.4 mrg (match_operand:VNx16BI 2 "register_operand" "Upa")
9644 1.1.1.4 mrg (match_operand:VNx16BI 3 "aarch64_simd_imm_zero")]
9645 1.1.1.3 mrg SVE_BRK_UNARY)]
9646 1.1.1.3 mrg UNSPEC_PTEST))
9647 1.1.1.4 mrg (clobber (match_scratch:VNx16BI 0 "=Upa"))]
9648 1.1.1.3 mrg "TARGET_SVE"
9649 1.1.1.4 mrg "brk<brk_op>s\t%0.b, %1/z, %2.b"
9650 1.1.1.3 mrg )
9651 1.1.1.3 mrg
9652 1.1.1.3 mrg ;; -------------------------------------------------------------------------
9653 1.1.1.3 mrg ;; ---- [PRED] Binary partitioning
9654 1.1.1.3 mrg ;; -------------------------------------------------------------------------
9655 1.1.1.3 mrg ;; Includes:
9656 1.1.1.3 mrg ;; - BRKN
9657 1.1.1.3 mrg ;; - BRKNS
9658 1.1.1.3 mrg ;; - BRKPA
9659 1.1.1.3 mrg ;; - BRKPAS
9660 1.1.1.3 mrg ;; - BRKPB
9661 1.1.1.3 mrg ;; - BRKPBS
9662 1.1.1.3 mrg ;; -------------------------------------------------------------------------
9663 1.1.1.3 mrg
9664 1.1.1.3 mrg ;; Binary BRKs (BRKN, BRKPA, BRKPB).
9665 1.1.1.3 mrg (define_insn "@aarch64_brk<brk_op>"
9666 1.1.1.3 mrg [(set (match_operand:VNx16BI 0 "register_operand" "=Upa")
9667 1.1.1.3 mrg (unspec:VNx16BI
9668 1.1.1.3 mrg [(match_operand:VNx16BI 1 "register_operand" "Upa")
9669 1.1.1.3 mrg (match_operand:VNx16BI 2 "register_operand" "Upa")
9670 1.1.1.3 mrg (match_operand:VNx16BI 3 "register_operand" "<brk_reg_con>")]
9671 1.1.1.3 mrg SVE_BRK_BINARY))]
9672 1.1.1.3 mrg "TARGET_SVE"
9673 1.1.1.3 mrg "brk<brk_op>\t%0.b, %1/z, %2.b, %<brk_reg_opno>.b"
9674 1.1.1.3 mrg )
9675 1.1.1.3 mrg
9676 1.1.1.4 mrg ;; BRKN, producing both a predicate and a flags result. Unlike other
9677 1.1.1.4 mrg ;; flag-setting instructions, these flags are always set wrt a ptrue.
9678 1.1.1.4 mrg (define_insn_and_rewrite "*aarch64_brkn_cc"
9679 1.1.1.4 mrg [(set (reg:CC_NZC CC_REGNUM)
9680 1.1.1.4 mrg (unspec:CC_NZC
9681 1.1.1.4 mrg [(match_operand:VNx16BI 4)
9682 1.1.1.4 mrg (match_operand:VNx16BI 5)
9683 1.1.1.4 mrg (const_int SVE_KNOWN_PTRUE)
9684 1.1.1.4 mrg (unspec:VNx16BI
9685 1.1.1.4 mrg [(match_operand:VNx16BI 1 "register_operand" "Upa")
9686 1.1.1.4 mrg (match_operand:VNx16BI 2 "register_operand" "Upa")
9687 1.1.1.4 mrg (match_operand:VNx16BI 3 "register_operand" "0")]
9688 1.1.1.4 mrg UNSPEC_BRKN)]
9689 1.1.1.4 mrg UNSPEC_PTEST))
9690 1.1.1.4 mrg (set (match_operand:VNx16BI 0 "register_operand" "=Upa")
9691 1.1.1.4 mrg (unspec:VNx16BI
9692 1.1.1.4 mrg [(match_dup 1)
9693 1.1.1.4 mrg (match_dup 2)
9694 1.1.1.4 mrg (match_dup 3)]
9695 1.1.1.4 mrg UNSPEC_BRKN))]
9696 1.1.1.4 mrg "TARGET_SVE"
9697 1.1.1.4 mrg "brkns\t%0.b, %1/z, %2.b, %0.b"
9698 1.1.1.4 mrg "&& (operands[4] != CONST0_RTX (VNx16BImode)
9699 1.1.1.4 mrg || operands[5] != CONST0_RTX (VNx16BImode))"
9700 1.1.1.4 mrg {
9701 1.1.1.4 mrg operands[4] = CONST0_RTX (VNx16BImode);
9702 1.1.1.4 mrg operands[5] = CONST0_RTX (VNx16BImode);
9703 1.1.1.4 mrg }
9704 1.1.1.4 mrg )
9705 1.1.1.4 mrg
9706 1.1.1.4 mrg ;; Same, but with only the flags result being interesting.
9707 1.1.1.4 mrg (define_insn_and_rewrite "*aarch64_brkn_ptest"
9708 1.1.1.4 mrg [(set (reg:CC_NZC CC_REGNUM)
9709 1.1.1.4 mrg (unspec:CC_NZC
9710 1.1.1.4 mrg [(match_operand:VNx16BI 4)
9711 1.1.1.4 mrg (match_operand:VNx16BI 5)
9712 1.1.1.4 mrg (const_int SVE_KNOWN_PTRUE)
9713 1.1.1.4 mrg (unspec:VNx16BI
9714 1.1.1.4 mrg [(match_operand:VNx16BI 1 "register_operand" "Upa")
9715 1.1.1.4 mrg (match_operand:VNx16BI 2 "register_operand" "Upa")
9716 1.1.1.4 mrg (match_operand:VNx16BI 3 "register_operand" "0")]
9717 1.1.1.4 mrg UNSPEC_BRKN)]
9718 1.1.1.4 mrg UNSPEC_PTEST))
9719 1.1.1.4 mrg (clobber (match_scratch:VNx16BI 0 "=Upa"))]
9720 1.1.1.4 mrg "TARGET_SVE"
9721 1.1.1.4 mrg "brkns\t%0.b, %1/z, %2.b, %0.b"
9722 1.1.1.4 mrg "&& (operands[4] != CONST0_RTX (VNx16BImode)
9723 1.1.1.4 mrg || operands[5] != CONST0_RTX (VNx16BImode))"
9724 1.1.1.4 mrg {
9725 1.1.1.4 mrg operands[4] = CONST0_RTX (VNx16BImode);
9726 1.1.1.4 mrg operands[5] = CONST0_RTX (VNx16BImode);
9727 1.1.1.4 mrg }
9728 1.1.1.4 mrg )
9729 1.1.1.4 mrg
9730 1.1.1.4 mrg ;; BRKPA and BRKPB, producing both a predicate and a flags result.
9731 1.1.1.3 mrg (define_insn "*aarch64_brk<brk_op>_cc"
9732 1.1.1.3 mrg [(set (reg:CC_NZC CC_REGNUM)
9733 1.1.1.3 mrg (unspec:CC_NZC
9734 1.1.1.3 mrg [(match_operand:VNx16BI 1 "register_operand" "Upa")
9735 1.1.1.3 mrg (match_dup 1)
9736 1.1.1.3 mrg (match_operand:SI 4 "aarch64_sve_ptrue_flag")
9737 1.1.1.3 mrg (unspec:VNx16BI
9738 1.1.1.3 mrg [(match_dup 1)
9739 1.1.1.3 mrg (match_operand:VNx16BI 2 "register_operand" "Upa")
9740 1.1.1.4 mrg (match_operand:VNx16BI 3 "register_operand" "Upa")]
9741 1.1.1.4 mrg SVE_BRKP)]
9742 1.1.1.3 mrg UNSPEC_PTEST))
9743 1.1.1.3 mrg (set (match_operand:VNx16BI 0 "register_operand" "=Upa")
9744 1.1.1.3 mrg (unspec:VNx16BI
9745 1.1.1.3 mrg [(match_dup 1)
9746 1.1.1.3 mrg (match_dup 2)
9747 1.1.1.3 mrg (match_dup 3)]
9748 1.1.1.4 mrg SVE_BRKP))]
9749 1.1.1.3 mrg "TARGET_SVE"
9750 1.1.1.4 mrg "brk<brk_op>s\t%0.b, %1/z, %2.b, %3.b"
9751 1.1.1.3 mrg )
9752 1.1.1.3 mrg
9753 1.1.1.3 mrg ;; Same, but with only the flags result being interesting.
9754 1.1.1.3 mrg (define_insn "*aarch64_brk<brk_op>_ptest"
9755 1.1.1.3 mrg [(set (reg:CC_NZC CC_REGNUM)
9756 1.1.1.3 mrg (unspec:CC_NZC
9757 1.1.1.3 mrg [(match_operand:VNx16BI 1 "register_operand" "Upa")
9758 1.1.1.3 mrg (match_dup 1)
9759 1.1.1.3 mrg (match_operand:SI 4 "aarch64_sve_ptrue_flag")
9760 1.1.1.3 mrg (unspec:VNx16BI
9761 1.1.1.3 mrg [(match_dup 1)
9762 1.1.1.3 mrg (match_operand:VNx16BI 2 "register_operand" "Upa")
9763 1.1.1.4 mrg (match_operand:VNx16BI 3 "register_operand" "Upa")]
9764 1.1.1.4 mrg SVE_BRKP)]
9765 1.1.1.3 mrg UNSPEC_PTEST))
9766 1.1.1.3 mrg (clobber (match_scratch:VNx16BI 0 "=Upa"))]
9767 1.1.1.3 mrg "TARGET_SVE"
9768 1.1.1.4 mrg "brk<brk_op>s\t%0.b, %1/z, %2.b, %3.b"
9769 1.1.1.3 mrg )
9770 1.1.1.3 mrg
9771 1.1.1.3 mrg ;; -------------------------------------------------------------------------
9772 1.1.1.3 mrg ;; ---- [PRED] Scalarization
9773 1.1.1.3 mrg ;; -------------------------------------------------------------------------
9774 1.1.1.3 mrg ;; Includes:
9775 1.1.1.3 mrg ;; - PFIRST
9776 1.1.1.3 mrg ;; - PNEXT
9777 1.1.1.3 mrg ;; -------------------------------------------------------------------------
9778 1.1.1.3 mrg
9779 1.1.1.3 mrg (define_insn "@aarch64_sve_<sve_pred_op><mode>"
9780 1.1.1.3 mrg [(set (match_operand:PRED_ALL 0 "register_operand" "=Upa")
9781 1.1.1.3 mrg (unspec:PRED_ALL
9782 1.1.1.3 mrg [(match_operand:PRED_ALL 1 "register_operand" "Upa")
9783 1.1.1.3 mrg (match_operand:SI 2 "aarch64_sve_ptrue_flag")
9784 1.1.1.3 mrg (match_operand:PRED_ALL 3 "register_operand" "0")]
9785 1.1.1.3 mrg SVE_PITER))
9786 1.1.1.3 mrg (clobber (reg:CC_NZC CC_REGNUM))]
9787 1.1.1.3 mrg "TARGET_SVE && <max_elem_bits> >= <elem_bits>"
9788 1.1.1.3 mrg "<sve_pred_op>\t%0.<Vetype>, %1, %0.<Vetype>"
9789 1.1.1.3 mrg )
9790 1.1.1.3 mrg
9791 1.1.1.3 mrg ;; Same, but also producing a flags result.
9792 1.1.1.3 mrg (define_insn_and_rewrite "*aarch64_sve_<sve_pred_op><mode>_cc"
9793 1.1.1.3 mrg [(set (reg:CC_NZC CC_REGNUM)
9794 1.1.1.3 mrg (unspec:CC_NZC
9795 1.1.1.3 mrg [(match_operand:VNx16BI 1 "register_operand" "Upa")
9796 1.1.1.3 mrg (match_operand 2)
9797 1.1.1.3 mrg (match_operand:SI 3 "aarch64_sve_ptrue_flag")
9798 1.1.1.3 mrg (unspec:PRED_ALL
9799 1.1.1.3 mrg [(match_operand 4)
9800 1.1.1.3 mrg (match_operand:SI 5 "aarch64_sve_ptrue_flag")
9801 1.1.1.3 mrg (match_operand:PRED_ALL 6 "register_operand" "0")]
9802 1.1.1.3 mrg SVE_PITER)]
9803 1.1.1.3 mrg UNSPEC_PTEST))
9804 1.1.1.3 mrg (set (match_operand:PRED_ALL 0 "register_operand" "=Upa")
9805 1.1.1.3 mrg (unspec:PRED_ALL
9806 1.1.1.3 mrg [(match_dup 4)
9807 1.1.1.3 mrg (match_dup 5)
9808 1.1.1.3 mrg (match_dup 6)]
9809 1.1.1.3 mrg SVE_PITER))]
9810 1.1.1.3 mrg "TARGET_SVE
9811 1.1.1.3 mrg && <max_elem_bits> >= <elem_bits>
9812 1.1.1.3 mrg && aarch64_sve_same_pred_for_ptest_p (&operands[2], &operands[4])"
9813 1.1.1.3 mrg "<sve_pred_op>\t%0.<Vetype>, %1, %0.<Vetype>"
9814 1.1.1.3 mrg "&& !rtx_equal_p (operands[2], operands[4])"
9815 1.1.1.3 mrg {
9816 1.1.1.3 mrg operands[4] = operands[2];
9817 1.1.1.3 mrg operands[5] = operands[3];
9818 1.1.1.3 mrg }
9819 1.1.1.3 mrg )
9820 1.1.1.3 mrg
9821 1.1.1.3 mrg ;; Same, but with only the flags result being interesting.
9822 1.1.1.3 mrg (define_insn_and_rewrite "*aarch64_sve_<sve_pred_op><mode>_ptest"
9823 1.1.1.3 mrg [(set (reg:CC_NZC CC_REGNUM)
9824 1.1.1.3 mrg (unspec:CC_NZC
9825 1.1.1.3 mrg [(match_operand:VNx16BI 1 "register_operand" "Upa")
9826 1.1.1.3 mrg (match_operand 2)
9827 1.1.1.3 mrg (match_operand:SI 3 "aarch64_sve_ptrue_flag")
9828 1.1.1.3 mrg (unspec:PRED_ALL
9829 1.1.1.3 mrg [(match_operand 4)
9830 1.1.1.3 mrg (match_operand:SI 5 "aarch64_sve_ptrue_flag")
9831 1.1.1.3 mrg (match_operand:PRED_ALL 6 "register_operand" "0")]
9832 1.1.1.3 mrg SVE_PITER)]
9833 1.1.1.3 mrg UNSPEC_PTEST))
9834 1.1.1.3 mrg (clobber (match_scratch:PRED_ALL 0 "=Upa"))]
9835 1.1.1.3 mrg "TARGET_SVE
9836 1.1.1.3 mrg && <max_elem_bits> >= <elem_bits>
9837 1.1.1.3 mrg && aarch64_sve_same_pred_for_ptest_p (&operands[2], &operands[4])"
9838 1.1.1.3 mrg "<sve_pred_op>\t%0.<Vetype>, %1, %0.<Vetype>"
9839 1.1.1.3 mrg "&& !rtx_equal_p (operands[2], operands[4])"
9840 1.1.1.3 mrg {
9841 1.1.1.3 mrg operands[4] = operands[2];
9842 1.1.1.3 mrg operands[5] = operands[3];
9843 1.1.1.3 mrg }
9844 1.1.1.3 mrg )
9845 1.1.1.3 mrg
9846 1.1.1.3 mrg ;; =========================================================================
9847 1.1.1.3 mrg ;; == Counting elements
9848 1.1.1.3 mrg ;; =========================================================================
9849 1.1.1.3 mrg
9850 1.1.1.3 mrg ;; -------------------------------------------------------------------------
9851 1.1.1.3 mrg ;; ---- [INT] Count elements in a pattern (scalar)
9852 1.1.1.3 mrg ;; -------------------------------------------------------------------------
9853 1.1.1.3 mrg ;; Includes:
9854 1.1.1.3 mrg ;; - CNTB
9855 1.1.1.3 mrg ;; - CNTD
9856 1.1.1.3 mrg ;; - CNTH
9857 1.1.1.3 mrg ;; - CNTW
9858 1.1.1.3 mrg ;; -------------------------------------------------------------------------
9859 1.1.1.3 mrg
9860 1.1.1.3 mrg ;; Count the number of elements in an svpattern. Operand 1 is the pattern,
9861 1.1.1.3 mrg ;; operand 2 is the number of elements that fit in a 128-bit block, and
9862 1.1.1.3 mrg ;; operand 3 is a multiplier in the range [1, 16].
9863 1.1.1.3 mrg ;;
9864 1.1.1.3 mrg ;; Note that this pattern isn't used for SV_ALL (but would work for that too).
9865 1.1.1.3 mrg (define_insn "aarch64_sve_cnt_pat"
9866 1.1.1.3 mrg [(set (match_operand:DI 0 "register_operand" "=r")
9867 1.1.1.3 mrg (zero_extend:DI
9868 1.1.1.3 mrg (unspec:SI [(match_operand:DI 1 "const_int_operand")
9869 1.1.1.3 mrg (match_operand:DI 2 "const_int_operand")
9870 1.1.1.3 mrg (match_operand:DI 3 "const_int_operand")]
9871 1.1.1.3 mrg UNSPEC_SVE_CNT_PAT)))]
9872 1.1 mrg "TARGET_SVE"
9873 1.1 mrg {
9874 1.1.1.3 mrg return aarch64_output_sve_cnt_pat_immediate ("cnt", "%x0", operands + 1);
9875 1.1 mrg }
9876 1.1 mrg )
9877 1.1 mrg
9878 1.1.1.3 mrg ;; -------------------------------------------------------------------------
9879 1.1.1.3 mrg ;; ---- [INT] Increment by the number of elements in a pattern (scalar)
9880 1.1.1.3 mrg ;; -------------------------------------------------------------------------
9881 1.1.1.3 mrg ;; Includes:
9882 1.1.1.3 mrg ;; - INC
9883 1.1.1.3 mrg ;; - SQINC
9884 1.1.1.3 mrg ;; - UQINC
9885 1.1.1.3 mrg ;; -------------------------------------------------------------------------
9886 1.1.1.3 mrg
9887 1.1.1.3 mrg ;; Increment a DImode register by the number of elements in an svpattern.
9888 1.1.1.3 mrg ;; See aarch64_sve_cnt_pat for the counting behavior.
9889 1.1.1.3 mrg (define_insn "@aarch64_sve_<inc_dec><mode>_pat"
9890 1.1.1.3 mrg [(set (match_operand:DI 0 "register_operand" "=r")
9891 1.1.1.3 mrg (ANY_PLUS:DI (zero_extend:DI
9892 1.1.1.3 mrg (unspec:SI [(match_operand:DI 2 "const_int_operand")
9893 1.1.1.3 mrg (match_operand:DI 3 "const_int_operand")
9894 1.1.1.3 mrg (match_operand:DI 4 "const_int_operand")]
9895 1.1.1.3 mrg UNSPEC_SVE_CNT_PAT))
9896 1.1.1.3 mrg (match_operand:DI_ONLY 1 "register_operand" "0")))]
9897 1.1 mrg "TARGET_SVE"
9898 1.1.1.3 mrg {
9899 1.1.1.3 mrg return aarch64_output_sve_cnt_pat_immediate ("<inc_dec>", "%x0",
9900 1.1.1.3 mrg operands + 2);
9901 1.1.1.3 mrg }
9902 1.1 mrg )
9903 1.1 mrg
9904 1.1.1.3 mrg ;; Increment an SImode register by the number of elements in an svpattern
9905 1.1.1.3 mrg ;; using modular arithmetic. See aarch64_sve_cnt_pat for the counting
9906 1.1.1.3 mrg ;; behavior.
9907 1.1.1.3 mrg (define_insn "*aarch64_sve_incsi_pat"
9908 1.1.1.3 mrg [(set (match_operand:SI 0 "register_operand" "=r")
9909 1.1.1.3 mrg (plus:SI (unspec:SI [(match_operand:DI 2 "const_int_operand")
9910 1.1.1.3 mrg (match_operand:DI 3 "const_int_operand")
9911 1.1.1.3 mrg (match_operand:DI 4 "const_int_operand")]
9912 1.1.1.3 mrg UNSPEC_SVE_CNT_PAT)
9913 1.1.1.3 mrg (match_operand:SI 1 "register_operand" "0")))]
9914 1.1 mrg "TARGET_SVE"
9915 1.1 mrg {
9916 1.1.1.3 mrg return aarch64_output_sve_cnt_pat_immediate ("inc", "%x0", operands + 2);
9917 1.1.1.3 mrg }
9918 1.1.1.3 mrg )
9919 1.1.1.3 mrg
9920 1.1.1.3 mrg ;; Increment an SImode register by the number of elements in an svpattern
9921 1.1.1.3 mrg ;; using saturating arithmetic, extending the result to 64 bits.
9922 1.1.1.3 mrg ;;
9923 1.1.1.3 mrg ;; See aarch64_sve_cnt_pat for the counting behavior.
9924 1.1.1.3 mrg (define_insn "@aarch64_sve_<inc_dec><mode>_pat"
9925 1.1.1.3 mrg [(set (match_operand:DI 0 "register_operand" "=r")
9926 1.1.1.3 mrg (<paired_extend>:DI
9927 1.1.1.3 mrg (SAT_PLUS:SI
9928 1.1.1.3 mrg (unspec:SI [(match_operand:DI 2 "const_int_operand")
9929 1.1.1.3 mrg (match_operand:DI 3 "const_int_operand")
9930 1.1.1.3 mrg (match_operand:DI 4 "const_int_operand")]
9931 1.1.1.3 mrg UNSPEC_SVE_CNT_PAT)
9932 1.1.1.3 mrg (match_operand:SI_ONLY 1 "register_operand" "0"))))]
9933 1.1.1.3 mrg "TARGET_SVE"
9934 1.1.1.3 mrg {
9935 1.1.1.3 mrg const char *registers = (<CODE> == SS_PLUS ? "%x0, %w0" : "%w0");
9936 1.1.1.3 mrg return aarch64_output_sve_cnt_pat_immediate ("<inc_dec>", registers,
9937 1.1.1.3 mrg operands + 2);
9938 1.1.1.3 mrg }
9939 1.1.1.3 mrg )
9940 1.1.1.3 mrg
9941 1.1.1.3 mrg ;; -------------------------------------------------------------------------
9942 1.1.1.3 mrg ;; ---- [INT] Increment by the number of elements in a pattern (vector)
9943 1.1.1.3 mrg ;; -------------------------------------------------------------------------
9944 1.1.1.3 mrg ;; Includes:
9945 1.1.1.3 mrg ;; - INC
9946 1.1.1.3 mrg ;; - SQINC
9947 1.1.1.3 mrg ;; - UQINC
9948 1.1.1.3 mrg ;; -------------------------------------------------------------------------
9949 1.1.1.3 mrg
9950 1.1.1.3 mrg ;; Increment a vector of DIs by the number of elements in an svpattern.
9951 1.1.1.3 mrg ;; See aarch64_sve_cnt_pat for the counting behavior.
9952 1.1.1.3 mrg (define_insn "@aarch64_sve_<inc_dec><mode>_pat"
9953 1.1.1.3 mrg [(set (match_operand:VNx2DI 0 "register_operand" "=w, ?&w")
9954 1.1.1.3 mrg (ANY_PLUS:VNx2DI
9955 1.1.1.3 mrg (vec_duplicate:VNx2DI
9956 1.1.1.3 mrg (zero_extend:DI
9957 1.1.1.3 mrg (unspec:SI [(match_operand:DI 2 "const_int_operand")
9958 1.1.1.3 mrg (match_operand:DI 3 "const_int_operand")
9959 1.1.1.3 mrg (match_operand:DI 4 "const_int_operand")]
9960 1.1.1.3 mrg UNSPEC_SVE_CNT_PAT)))
9961 1.1.1.3 mrg (match_operand:VNx2DI_ONLY 1 "register_operand" "0, w")))]
9962 1.1.1.3 mrg "TARGET_SVE"
9963 1.1.1.3 mrg {
9964 1.1.1.3 mrg if (which_alternative == 1)
9965 1.1.1.3 mrg output_asm_insn ("movprfx\t%0, %1", operands);
9966 1.1.1.3 mrg return aarch64_output_sve_cnt_pat_immediate ("<inc_dec>", "%0.<Vetype>",
9967 1.1.1.3 mrg operands + 2);
9968 1.1 mrg }
9969 1.1.1.3 mrg [(set_attr "movprfx" "*,yes")]
9970 1.1 mrg )
9971 1.1 mrg
9972 1.1.1.3 mrg ;; Increment a vector of SIs by the number of elements in an svpattern.
9973 1.1.1.3 mrg ;; See aarch64_sve_cnt_pat for the counting behavior.
9974 1.1.1.3 mrg (define_insn "@aarch64_sve_<inc_dec><mode>_pat"
9975 1.1.1.3 mrg [(set (match_operand:VNx4SI 0 "register_operand" "=w, ?&w")
9976 1.1.1.3 mrg (ANY_PLUS:VNx4SI
9977 1.1.1.3 mrg (vec_duplicate:VNx4SI
9978 1.1.1.3 mrg (unspec:SI [(match_operand:DI 2 "const_int_operand")
9979 1.1.1.3 mrg (match_operand:DI 3 "const_int_operand")
9980 1.1.1.3 mrg (match_operand:DI 4 "const_int_operand")]
9981 1.1.1.3 mrg UNSPEC_SVE_CNT_PAT))
9982 1.1.1.3 mrg (match_operand:VNx4SI_ONLY 1 "register_operand" "0, w")))]
9983 1.1.1.3 mrg "TARGET_SVE"
9984 1.1.1.3 mrg {
9985 1.1.1.3 mrg if (which_alternative == 1)
9986 1.1.1.3 mrg output_asm_insn ("movprfx\t%0, %1", operands);
9987 1.1.1.3 mrg return aarch64_output_sve_cnt_pat_immediate ("<inc_dec>", "%0.<Vetype>",
9988 1.1.1.3 mrg operands + 2);
9989 1.1 mrg }
9990 1.1.1.3 mrg [(set_attr "movprfx" "*,yes")]
9991 1.1 mrg )
9992 1.1 mrg
9993 1.1.1.3 mrg ;; Increment a vector of HIs by the number of elements in an svpattern.
9994 1.1.1.3 mrg ;; See aarch64_sve_cnt_pat for the counting behavior.
9995 1.1.1.3 mrg (define_expand "@aarch64_sve_<inc_dec><mode>_pat"
9996 1.1.1.3 mrg [(set (match_operand:VNx8HI 0 "register_operand")
9997 1.1.1.3 mrg (ANY_PLUS:VNx8HI
9998 1.1.1.3 mrg (vec_duplicate:VNx8HI
9999 1.1.1.3 mrg (truncate:HI
10000 1.1.1.3 mrg (unspec:SI [(match_operand:DI 2 "const_int_operand")
10001 1.1.1.3 mrg (match_operand:DI 3 "const_int_operand")
10002 1.1.1.3 mrg (match_operand:DI 4 "const_int_operand")]
10003 1.1.1.3 mrg UNSPEC_SVE_CNT_PAT)))
10004 1.1.1.3 mrg (match_operand:VNx8HI_ONLY 1 "register_operand")))]
10005 1.1 mrg "TARGET_SVE"
10006 1.1 mrg )
10007 1.1 mrg
10008 1.1.1.3 mrg (define_insn "*aarch64_sve_<inc_dec><mode>_pat"
10009 1.1.1.3 mrg [(set (match_operand:VNx8HI 0 "register_operand" "=w, ?&w")
10010 1.1.1.3 mrg (ANY_PLUS:VNx8HI
10011 1.1.1.3 mrg (vec_duplicate:VNx8HI
10012 1.1.1.3 mrg (match_operator:HI 5 "subreg_lowpart_operator"
10013 1.1.1.3 mrg [(unspec:SI [(match_operand:DI 2 "const_int_operand")
10014 1.1.1.3 mrg (match_operand:DI 3 "const_int_operand")
10015 1.1.1.3 mrg (match_operand:DI 4 "const_int_operand")]
10016 1.1.1.3 mrg UNSPEC_SVE_CNT_PAT)]))
10017 1.1.1.3 mrg (match_operand:VNx8HI_ONLY 1 "register_operand" "0, w")))]
10018 1.1.1.3 mrg "TARGET_SVE"
10019 1.1.1.3 mrg {
10020 1.1.1.3 mrg if (which_alternative == 1)
10021 1.1.1.3 mrg output_asm_insn ("movprfx\t%0, %1", operands);
10022 1.1.1.3 mrg return aarch64_output_sve_cnt_pat_immediate ("<inc_dec>", "%0.<Vetype>",
10023 1.1.1.3 mrg operands + 2);
10024 1.1.1.3 mrg }
10025 1.1.1.3 mrg [(set_attr "movprfx" "*,yes")]
10026 1.1 mrg )
10027 1.1 mrg
10028 1.1.1.3 mrg ;; -------------------------------------------------------------------------
10029 1.1.1.3 mrg ;; ---- [INT] Decrement by the number of elements in a pattern (scalar)
10030 1.1.1.3 mrg ;; -------------------------------------------------------------------------
10031 1.1.1.3 mrg ;; Includes:
10032 1.1.1.3 mrg ;; - DEC
10033 1.1.1.3 mrg ;; - SQDEC
10034 1.1.1.3 mrg ;; - UQDEC
10035 1.1.1.3 mrg ;; -------------------------------------------------------------------------
10036 1.1.1.3 mrg
10037 1.1.1.3 mrg ;; Decrement a DImode register by the number of elements in an svpattern.
10038 1.1.1.3 mrg ;; See aarch64_sve_cnt_pat for the counting behavior.
10039 1.1.1.3 mrg (define_insn "@aarch64_sve_<inc_dec><mode>_pat"
10040 1.1.1.3 mrg [(set (match_operand:DI 0 "register_operand" "=r")
10041 1.1.1.3 mrg (ANY_MINUS:DI (match_operand:DI_ONLY 1 "register_operand" "0")
10042 1.1.1.3 mrg (zero_extend:DI
10043 1.1.1.3 mrg (unspec:SI [(match_operand:DI 2 "const_int_operand")
10044 1.1.1.3 mrg (match_operand:DI 3 "const_int_operand")
10045 1.1.1.3 mrg (match_operand:DI 4 "const_int_operand")]
10046 1.1.1.3 mrg UNSPEC_SVE_CNT_PAT))))]
10047 1.1.1.3 mrg "TARGET_SVE"
10048 1.1.1.3 mrg {
10049 1.1.1.3 mrg return aarch64_output_sve_cnt_pat_immediate ("<inc_dec>", "%x0",
10050 1.1.1.3 mrg operands + 2);
10051 1.1 mrg }
10052 1.1 mrg )
10053 1.1 mrg
10054 1.1.1.3 mrg ;; Decrement an SImode register by the number of elements in an svpattern
10055 1.1.1.3 mrg ;; using modular arithmetic. See aarch64_sve_cnt_pat for the counting
10056 1.1.1.3 mrg ;; behavior.
10057 1.1.1.3 mrg (define_insn "*aarch64_sve_decsi_pat"
10058 1.1.1.3 mrg [(set (match_operand:SI 0 "register_operand" "=r")
10059 1.1.1.3 mrg (minus:SI (match_operand:SI 1 "register_operand" "0")
10060 1.1.1.3 mrg (unspec:SI [(match_operand:DI 2 "const_int_operand")
10061 1.1.1.3 mrg (match_operand:DI 3 "const_int_operand")
10062 1.1.1.3 mrg (match_operand:DI 4 "const_int_operand")]
10063 1.1.1.3 mrg UNSPEC_SVE_CNT_PAT)))]
10064 1.1 mrg "TARGET_SVE"
10065 1.1 mrg {
10066 1.1.1.3 mrg return aarch64_output_sve_cnt_pat_immediate ("dec", "%x0", operands + 2);
10067 1.1 mrg }
10068 1.1 mrg )
10069 1.1 mrg
10070 1.1.1.3 mrg ;; Decrement an SImode register by the number of elements in an svpattern
10071 1.1.1.3 mrg ;; using saturating arithmetic, extending the result to 64 bits.
10072 1.1.1.3 mrg ;;
10073 1.1.1.3 mrg ;; See aarch64_sve_cnt_pat for the counting behavior.
10074 1.1.1.3 mrg (define_insn "@aarch64_sve_<inc_dec><mode>_pat"
10075 1.1.1.3 mrg [(set (match_operand:DI 0 "register_operand" "=r")
10076 1.1.1.3 mrg (<paired_extend>:DI
10077 1.1.1.3 mrg (SAT_MINUS:SI
10078 1.1.1.3 mrg (match_operand:SI_ONLY 1 "register_operand" "0")
10079 1.1.1.3 mrg (unspec:SI [(match_operand:DI 2 "const_int_operand")
10080 1.1.1.3 mrg (match_operand:DI 3 "const_int_operand")
10081 1.1.1.3 mrg (match_operand:DI 4 "const_int_operand")]
10082 1.1.1.3 mrg UNSPEC_SVE_CNT_PAT))))]
10083 1.1.1.3 mrg "TARGET_SVE"
10084 1.1.1.3 mrg {
10085 1.1.1.3 mrg const char *registers = (<CODE> == SS_MINUS ? "%x0, %w0" : "%w0");
10086 1.1.1.3 mrg return aarch64_output_sve_cnt_pat_immediate ("<inc_dec>", registers,
10087 1.1.1.3 mrg operands + 2);
10088 1.1.1.3 mrg }
10089 1.1.1.2 mrg )
10090 1.1.1.2 mrg
10091 1.1.1.3 mrg ;; -------------------------------------------------------------------------
10092 1.1.1.3 mrg ;; ---- [INT] Decrement by the number of elements in a pattern (vector)
10093 1.1.1.3 mrg ;; -------------------------------------------------------------------------
10094 1.1.1.3 mrg ;; Includes:
10095 1.1.1.3 mrg ;; - DEC
10096 1.1.1.3 mrg ;; - SQDEC
10097 1.1.1.3 mrg ;; - UQDEC
10098 1.1.1.3 mrg ;; -------------------------------------------------------------------------
10099 1.1.1.3 mrg
10100 1.1.1.3 mrg ;; Decrement a vector of DIs by the number of elements in an svpattern.
10101 1.1.1.3 mrg ;; See aarch64_sve_cnt_pat for the counting behavior.
10102 1.1.1.3 mrg (define_insn "@aarch64_sve_<inc_dec><mode>_pat"
10103 1.1.1.3 mrg [(set (match_operand:VNx2DI 0 "register_operand" "=w, ?&w")
10104 1.1.1.3 mrg (ANY_MINUS:VNx2DI
10105 1.1.1.3 mrg (match_operand:VNx2DI_ONLY 1 "register_operand" "0, w")
10106 1.1.1.3 mrg (vec_duplicate:VNx2DI
10107 1.1.1.3 mrg (zero_extend:DI
10108 1.1.1.3 mrg (unspec:SI [(match_operand:DI 2 "const_int_operand")
10109 1.1.1.3 mrg (match_operand:DI 3 "const_int_operand")
10110 1.1.1.3 mrg (match_operand:DI 4 "const_int_operand")]
10111 1.1.1.3 mrg UNSPEC_SVE_CNT_PAT)))))]
10112 1.1.1.3 mrg "TARGET_SVE"
10113 1.1.1.3 mrg {
10114 1.1.1.3 mrg if (which_alternative == 1)
10115 1.1.1.3 mrg output_asm_insn ("movprfx\t%0, %1", operands);
10116 1.1.1.3 mrg return aarch64_output_sve_cnt_pat_immediate ("<inc_dec>", "%0.<Vetype>",
10117 1.1.1.3 mrg operands + 2);
10118 1.1.1.3 mrg }
10119 1.1.1.3 mrg [(set_attr "movprfx" "*,yes")]
10120 1.1.1.2 mrg )
10121 1.1.1.2 mrg
10122 1.1.1.3 mrg ;; Decrement a vector of SIs by the number of elements in an svpattern.
10123 1.1.1.3 mrg ;; See aarch64_sve_cnt_pat for the counting behavior.
10124 1.1.1.3 mrg (define_insn "@aarch64_sve_<inc_dec><mode>_pat"
10125 1.1.1.3 mrg [(set (match_operand:VNx4SI 0 "register_operand" "=w, ?&w")
10126 1.1.1.3 mrg (ANY_MINUS:VNx4SI
10127 1.1.1.3 mrg (match_operand:VNx4SI_ONLY 1 "register_operand" "0, w")
10128 1.1.1.3 mrg (vec_duplicate:VNx4SI
10129 1.1.1.3 mrg (unspec:SI [(match_operand:DI 2 "const_int_operand")
10130 1.1.1.3 mrg (match_operand:DI 3 "const_int_operand")
10131 1.1.1.3 mrg (match_operand:DI 4 "const_int_operand")]
10132 1.1.1.3 mrg UNSPEC_SVE_CNT_PAT))))]
10133 1.1.1.3 mrg "TARGET_SVE"
10134 1.1.1.3 mrg {
10135 1.1.1.3 mrg if (which_alternative == 1)
10136 1.1.1.3 mrg output_asm_insn ("movprfx\t%0, %1", operands);
10137 1.1.1.3 mrg return aarch64_output_sve_cnt_pat_immediate ("<inc_dec>", "%0.<Vetype>",
10138 1.1.1.3 mrg operands + 2);
10139 1.1.1.3 mrg }
10140 1.1.1.2 mrg [(set_attr "movprfx" "*,yes")]
10141 1.1.1.2 mrg )
10142 1.1.1.2 mrg
10143 1.1.1.3 mrg ;; Decrement a vector of HIs by the number of elements in an svpattern.
10144 1.1.1.3 mrg ;; See aarch64_sve_cnt_pat for the counting behavior.
10145 1.1.1.3 mrg (define_expand "@aarch64_sve_<inc_dec><mode>_pat"
10146 1.1.1.3 mrg [(set (match_operand:VNx8HI 0 "register_operand")
10147 1.1.1.3 mrg (ANY_MINUS:VNx8HI
10148 1.1.1.3 mrg (match_operand:VNx8HI_ONLY 1 "register_operand")
10149 1.1.1.3 mrg (vec_duplicate:VNx8HI
10150 1.1.1.3 mrg (truncate:HI
10151 1.1.1.3 mrg (unspec:SI [(match_operand:DI 2 "const_int_operand")
10152 1.1.1.3 mrg (match_operand:DI 3 "const_int_operand")
10153 1.1.1.3 mrg (match_operand:DI 4 "const_int_operand")]
10154 1.1.1.3 mrg UNSPEC_SVE_CNT_PAT)))))]
10155 1.1.1.2 mrg "TARGET_SVE"
10156 1.1.1.3 mrg )
10157 1.1.1.3 mrg
10158 1.1.1.3 mrg (define_insn "*aarch64_sve_<inc_dec><mode>_pat"
10159 1.1.1.3 mrg [(set (match_operand:VNx8HI 0 "register_operand" "=w, ?&w")
10160 1.1.1.3 mrg (ANY_MINUS:VNx8HI
10161 1.1.1.3 mrg (match_operand:VNx8HI_ONLY 1 "register_operand" "0, w")
10162 1.1.1.3 mrg (vec_duplicate:VNx8HI
10163 1.1.1.3 mrg (match_operator:HI 5 "subreg_lowpart_operator"
10164 1.1.1.3 mrg [(unspec:SI [(match_operand:DI 2 "const_int_operand")
10165 1.1.1.3 mrg (match_operand:DI 3 "const_int_operand")
10166 1.1.1.3 mrg (match_operand:DI 4 "const_int_operand")]
10167 1.1.1.3 mrg UNSPEC_SVE_CNT_PAT)]))))]
10168 1.1.1.3 mrg "TARGET_SVE"
10169 1.1.1.3 mrg {
10170 1.1.1.3 mrg if (which_alternative == 1)
10171 1.1.1.3 mrg output_asm_insn ("movprfx\t%0, %1", operands);
10172 1.1.1.3 mrg return aarch64_output_sve_cnt_pat_immediate ("<inc_dec>", "%0.<Vetype>",
10173 1.1.1.3 mrg operands + 2);
10174 1.1.1.3 mrg }
10175 1.1.1.2 mrg [(set_attr "movprfx" "*,yes")]
10176 1.1.1.2 mrg )
10177 1.1.1.2 mrg
10178 1.1.1.3 mrg ;; -------------------------------------------------------------------------
10179 1.1.1.3 mrg ;; ---- [INT] Count elements in a predicate (scalar)
10180 1.1.1.3 mrg ;; -------------------------------------------------------------------------
10181 1.1.1.3 mrg ;; Includes:
10182 1.1.1.3 mrg ;; - CNTP
10183 1.1.1.3 mrg ;; -------------------------------------------------------------------------
10184 1.1.1.3 mrg
10185 1.1.1.3 mrg ;; Count the number of set bits in a predicate. Operand 3 is true if
10186 1.1.1.3 mrg ;; operand 1 is known to be all-true.
10187 1.1.1.3 mrg (define_insn "@aarch64_pred_cntp<mode>"
10188 1.1.1.3 mrg [(set (match_operand:DI 0 "register_operand" "=r")
10189 1.1.1.3 mrg (zero_extend:DI
10190 1.1.1.3 mrg (unspec:SI [(match_operand:PRED_ALL 1 "register_operand" "Upl")
10191 1.1.1.3 mrg (match_operand:SI 2 "aarch64_sve_ptrue_flag")
10192 1.1.1.3 mrg (match_operand:PRED_ALL 3 "register_operand" "Upa")]
10193 1.1.1.3 mrg UNSPEC_CNTP)))]
10194 1.1.1.3 mrg "TARGET_SVE"
10195 1.1.1.3 mrg "cntp\t%x0, %1, %3.<Vetype>")
10196 1.1.1.3 mrg
10197 1.1.1.3 mrg ;; -------------------------------------------------------------------------
10198 1.1.1.3 mrg ;; ---- [INT] Increment by the number of elements in a predicate (scalar)
10199 1.1.1.3 mrg ;; -------------------------------------------------------------------------
10200 1.1.1.3 mrg ;; Includes:
10201 1.1.1.3 mrg ;; - INCP
10202 1.1.1.3 mrg ;; - SQINCP
10203 1.1.1.3 mrg ;; - UQINCP
10204 1.1.1.3 mrg ;; -------------------------------------------------------------------------
10205 1.1.1.3 mrg
10206 1.1.1.3 mrg ;; Increment a DImode register by the number of set bits in a predicate.
10207 1.1.1.3 mrg ;; See aarch64_sve_cntp for a description of the operands.
10208 1.1.1.3 mrg (define_expand "@aarch64_sve_<inc_dec><DI_ONLY:mode><PRED_ALL:mode>_cntp"
10209 1.1.1.3 mrg [(set (match_operand:DI 0 "register_operand")
10210 1.1.1.3 mrg (ANY_PLUS:DI
10211 1.1.1.3 mrg (zero_extend:DI
10212 1.1.1.3 mrg (unspec:SI [(match_dup 3)
10213 1.1.1.3 mrg (const_int SVE_KNOWN_PTRUE)
10214 1.1.1.3 mrg (match_operand:PRED_ALL 2 "register_operand")]
10215 1.1.1.3 mrg UNSPEC_CNTP))
10216 1.1.1.3 mrg (match_operand:DI_ONLY 1 "register_operand")))]
10217 1.1.1.3 mrg "TARGET_SVE"
10218 1.1.1.3 mrg {
10219 1.1.1.3 mrg operands[3] = CONSTM1_RTX (<PRED_ALL:MODE>mode);
10220 1.1.1.3 mrg }
10221 1.1.1.3 mrg )
10222 1.1.1.3 mrg
10223 1.1.1.3 mrg (define_insn_and_rewrite "*aarch64_sve_<inc_dec><DI_ONLY:mode><PRED_ALL:mode>_cntp"
10224 1.1.1.3 mrg [(set (match_operand:DI 0 "register_operand" "=r")
10225 1.1.1.3 mrg (ANY_PLUS:DI
10226 1.1.1.3 mrg (zero_extend:DI
10227 1.1.1.3 mrg (unspec:SI [(match_operand 3)
10228 1.1.1.3 mrg (const_int SVE_KNOWN_PTRUE)
10229 1.1.1.3 mrg (match_operand:PRED_ALL 2 "register_operand" "Upa")]
10230 1.1.1.3 mrg UNSPEC_CNTP))
10231 1.1.1.3 mrg (match_operand:DI_ONLY 1 "register_operand" "0")))]
10232 1.1.1.3 mrg "TARGET_SVE"
10233 1.1.1.3 mrg "<inc_dec>p\t%x0, %2.<PRED_ALL:Vetype>"
10234 1.1.1.3 mrg "&& !CONSTANT_P (operands[3])"
10235 1.1.1.3 mrg {
10236 1.1.1.3 mrg operands[3] = CONSTM1_RTX (<PRED_ALL:MODE>mode);
10237 1.1.1.3 mrg }
10238 1.1.1.3 mrg )
10239 1.1.1.3 mrg
10240 1.1.1.3 mrg ;; Increment an SImode register by the number of set bits in a predicate
10241 1.1.1.3 mrg ;; using modular arithmetic. See aarch64_sve_cntp for a description of
10242 1.1.1.3 mrg ;; the operands.
10243 1.1.1.3 mrg (define_insn_and_rewrite "*aarch64_incsi<mode>_cntp"
10244 1.1.1.3 mrg [(set (match_operand:SI 0 "register_operand" "=r")
10245 1.1.1.3 mrg (plus:SI
10246 1.1.1.3 mrg (unspec:SI [(match_operand 3)
10247 1.1.1.3 mrg (const_int SVE_KNOWN_PTRUE)
10248 1.1.1.3 mrg (match_operand:PRED_ALL 2 "register_operand" "Upa")]
10249 1.1.1.3 mrg UNSPEC_CNTP)
10250 1.1.1.3 mrg (match_operand:SI 1 "register_operand" "0")))]
10251 1.1.1.3 mrg "TARGET_SVE"
10252 1.1.1.3 mrg "incp\t%x0, %2.<Vetype>"
10253 1.1.1.3 mrg "&& !CONSTANT_P (operands[3])"
10254 1.1.1.3 mrg {
10255 1.1.1.3 mrg operands[3] = CONSTM1_RTX (<MODE>mode);
10256 1.1.1.3 mrg }
10257 1.1.1.2 mrg )
10258 1.1.1.2 mrg
10259 1.1.1.3 mrg ;; Increment an SImode register by the number of set bits in a predicate
10260 1.1.1.3 mrg ;; using saturating arithmetic, extending the result to 64 bits.
10261 1.1.1.3 mrg ;;
10262 1.1.1.3 mrg ;; See aarch64_sve_cntp for a description of the operands.
10263 1.1.1.3 mrg (define_expand "@aarch64_sve_<inc_dec><SI_ONLY:mode><PRED_ALL:mode>_cntp"
10264 1.1.1.3 mrg [(set (match_operand:DI 0 "register_operand")
10265 1.1.1.3 mrg (<paired_extend>:DI
10266 1.1.1.3 mrg (SAT_PLUS:SI
10267 1.1.1.3 mrg (unspec:SI [(match_dup 3)
10268 1.1.1.3 mrg (const_int SVE_KNOWN_PTRUE)
10269 1.1.1.3 mrg (match_operand:PRED_ALL 2 "register_operand")]
10270 1.1.1.3 mrg UNSPEC_CNTP)
10271 1.1.1.3 mrg (match_operand:SI_ONLY 1 "register_operand"))))]
10272 1.1.1.3 mrg "TARGET_SVE"
10273 1.1.1.3 mrg {
10274 1.1.1.3 mrg operands[3] = CONSTM1_RTX (<PRED_ALL:MODE>mode);
10275 1.1.1.3 mrg }
10276 1.1.1.3 mrg )
10277 1.1.1.3 mrg
10278 1.1.1.3 mrg (define_insn_and_rewrite "*aarch64_sve_<inc_dec><SI_ONLY:mode><PRED_ALL:mode>_cntp"
10279 1.1.1.3 mrg [(set (match_operand:DI 0 "register_operand" "=r")
10280 1.1.1.3 mrg (<paired_extend>:DI
10281 1.1.1.3 mrg (SAT_PLUS:SI
10282 1.1.1.3 mrg (unspec:SI [(match_operand 3)
10283 1.1.1.3 mrg (const_int SVE_KNOWN_PTRUE)
10284 1.1.1.3 mrg (match_operand:PRED_ALL 2 "register_operand" "Upa")]
10285 1.1.1.3 mrg UNSPEC_CNTP)
10286 1.1.1.3 mrg (match_operand:SI_ONLY 1 "register_operand" "0"))))]
10287 1.1 mrg "TARGET_SVE"
10288 1.1.1.3 mrg {
10289 1.1.1.3 mrg if (<CODE> == SS_PLUS)
10290 1.1.1.3 mrg return "<inc_dec>p\t%x0, %2.<PRED_ALL:Vetype>, %w0";
10291 1.1.1.3 mrg else
10292 1.1.1.3 mrg return "<inc_dec>p\t%w0, %2.<PRED_ALL:Vetype>";
10293 1.1.1.3 mrg }
10294 1.1.1.3 mrg "&& !CONSTANT_P (operands[3])"
10295 1.1.1.3 mrg {
10296 1.1.1.3 mrg operands[3] = CONSTM1_RTX (<PRED_ALL:MODE>mode);
10297 1.1.1.3 mrg }
10298 1.1.1.2 mrg )
10299 1.1.1.2 mrg
10300 1.1.1.3 mrg ;; -------------------------------------------------------------------------
10301 1.1.1.3 mrg ;; ---- [INT] Increment by the number of elements in a predicate (vector)
10302 1.1.1.3 mrg ;; -------------------------------------------------------------------------
10303 1.1.1.3 mrg ;; Includes:
10304 1.1.1.3 mrg ;; - INCP
10305 1.1.1.3 mrg ;; - SQINCP
10306 1.1.1.3 mrg ;; - UQINCP
10307 1.1.1.3 mrg ;; -------------------------------------------------------------------------
10308 1.1.1.3 mrg
10309 1.1.1.3 mrg ;; Increment a vector of DIs by the number of set bits in a predicate.
10310 1.1.1.3 mrg ;; See aarch64_sve_cntp for a description of the operands.
10311 1.1.1.3 mrg (define_expand "@aarch64_sve_<inc_dec><mode>_cntp"
10312 1.1.1.3 mrg [(set (match_operand:VNx2DI 0 "register_operand")
10313 1.1.1.3 mrg (ANY_PLUS:VNx2DI
10314 1.1.1.3 mrg (vec_duplicate:VNx2DI
10315 1.1.1.3 mrg (zero_extend:DI
10316 1.1.1.3 mrg (unspec:SI
10317 1.1.1.3 mrg [(match_dup 3)
10318 1.1.1.3 mrg (const_int SVE_KNOWN_PTRUE)
10319 1.1.1.3 mrg (match_operand:<VPRED> 2 "register_operand")]
10320 1.1.1.3 mrg UNSPEC_CNTP)))
10321 1.1.1.3 mrg (match_operand:VNx2DI_ONLY 1 "register_operand")))]
10322 1.1.1.2 mrg "TARGET_SVE"
10323 1.1.1.3 mrg {
10324 1.1.1.3 mrg operands[3] = CONSTM1_RTX (<VPRED>mode);
10325 1.1.1.3 mrg }
10326 1.1.1.3 mrg )
10327 1.1.1.2 mrg
10328 1.1.1.3 mrg (define_insn_and_rewrite "*aarch64_sve_<inc_dec><mode>_cntp"
10329 1.1.1.3 mrg [(set (match_operand:VNx2DI 0 "register_operand" "=w, ?&w")
10330 1.1.1.3 mrg (ANY_PLUS:VNx2DI
10331 1.1.1.3 mrg (vec_duplicate:VNx2DI
10332 1.1.1.3 mrg (zero_extend:DI
10333 1.1.1.3 mrg (unspec:SI
10334 1.1.1.3 mrg [(match_operand 3)
10335 1.1.1.3 mrg (const_int SVE_KNOWN_PTRUE)
10336 1.1.1.3 mrg (match_operand:<VPRED> 2 "register_operand" "Upa, Upa")]
10337 1.1.1.3 mrg UNSPEC_CNTP)))
10338 1.1.1.3 mrg (match_operand:VNx2DI_ONLY 1 "register_operand" "0, w")))]
10339 1.1.1.2 mrg "TARGET_SVE"
10340 1.1.1.2 mrg "@
10341 1.1.1.3 mrg <inc_dec>p\t%0.d, %2
10342 1.1.1.3 mrg movprfx\t%0, %1\;<inc_dec>p\t%0.d, %2"
10343 1.1.1.3 mrg "&& !CONSTANT_P (operands[3])"
10344 1.1.1.3 mrg {
10345 1.1.1.3 mrg operands[3] = CONSTM1_RTX (<VPRED>mode);
10346 1.1.1.3 mrg }
10347 1.1.1.2 mrg [(set_attr "movprfx" "*,yes")]
10348 1.1.1.2 mrg )
10349 1.1.1.2 mrg
10350 1.1.1.3 mrg ;; Increment a vector of SIs by the number of set bits in a predicate.
10351 1.1.1.3 mrg ;; See aarch64_sve_cntp for a description of the operands.
10352 1.1.1.3 mrg (define_expand "@aarch64_sve_<inc_dec><mode>_cntp"
10353 1.1.1.3 mrg [(set (match_operand:VNx4SI 0 "register_operand")
10354 1.1.1.3 mrg (ANY_PLUS:VNx4SI
10355 1.1.1.3 mrg (vec_duplicate:VNx4SI
10356 1.1.1.3 mrg (unspec:SI
10357 1.1.1.3 mrg [(match_dup 3)
10358 1.1.1.3 mrg (const_int SVE_KNOWN_PTRUE)
10359 1.1.1.3 mrg (match_operand:<VPRED> 2 "register_operand")]
10360 1.1.1.3 mrg UNSPEC_CNTP))
10361 1.1.1.3 mrg (match_operand:VNx4SI_ONLY 1 "register_operand")))]
10362 1.1.1.3 mrg "TARGET_SVE"
10363 1.1.1.3 mrg {
10364 1.1.1.3 mrg operands[3] = CONSTM1_RTX (<VPRED>mode);
10365 1.1.1.3 mrg }
10366 1.1.1.3 mrg )
10367 1.1.1.3 mrg
10368 1.1.1.3 mrg (define_insn_and_rewrite "*aarch64_sve_<inc_dec><mode>_cntp"
10369 1.1.1.3 mrg [(set (match_operand:VNx4SI 0 "register_operand" "=w, ?&w")
10370 1.1.1.3 mrg (ANY_PLUS:VNx4SI
10371 1.1.1.3 mrg (vec_duplicate:VNx4SI
10372 1.1.1.3 mrg (unspec:SI
10373 1.1.1.3 mrg [(match_operand 3)
10374 1.1.1.3 mrg (const_int SVE_KNOWN_PTRUE)
10375 1.1.1.3 mrg (match_operand:<VPRED> 2 "register_operand" "Upa, Upa")]
10376 1.1.1.3 mrg UNSPEC_CNTP))
10377 1.1.1.3 mrg (match_operand:VNx4SI_ONLY 1 "register_operand" "0, w")))]
10378 1.1.1.3 mrg "TARGET_SVE"
10379 1.1.1.3 mrg "@
10380 1.1.1.3 mrg <inc_dec>p\t%0.s, %2
10381 1.1.1.3 mrg movprfx\t%0, %1\;<inc_dec>p\t%0.s, %2"
10382 1.1.1.3 mrg "&& !CONSTANT_P (operands[3])"
10383 1.1.1.3 mrg {
10384 1.1.1.3 mrg operands[3] = CONSTM1_RTX (<VPRED>mode);
10385 1.1.1.3 mrg }
10386 1.1.1.2 mrg [(set_attr "movprfx" "*,yes")]
10387 1.1.1.2 mrg )
10388 1.1.1.2 mrg
10389 1.1.1.3 mrg ;; Increment a vector of HIs by the number of set bits in a predicate.
10390 1.1.1.3 mrg ;; See aarch64_sve_cntp for a description of the operands.
10391 1.1.1.3 mrg (define_expand "@aarch64_sve_<inc_dec><mode>_cntp"
10392 1.1.1.3 mrg [(set (match_operand:VNx8HI 0 "register_operand")
10393 1.1.1.3 mrg (ANY_PLUS:VNx8HI
10394 1.1.1.3 mrg (vec_duplicate:VNx8HI
10395 1.1.1.3 mrg (truncate:HI
10396 1.1.1.3 mrg (unspec:SI
10397 1.1.1.3 mrg [(match_dup 3)
10398 1.1.1.3 mrg (const_int SVE_KNOWN_PTRUE)
10399 1.1.1.3 mrg (match_operand:<VPRED> 2 "register_operand")]
10400 1.1.1.3 mrg UNSPEC_CNTP)))
10401 1.1.1.3 mrg (match_operand:VNx8HI_ONLY 1 "register_operand")))]
10402 1.1.1.3 mrg "TARGET_SVE"
10403 1.1.1.3 mrg {
10404 1.1.1.3 mrg operands[3] = CONSTM1_RTX (<VPRED>mode);
10405 1.1.1.3 mrg }
10406 1.1 mrg )
10407 1.1 mrg
10408 1.1.1.3 mrg (define_insn_and_rewrite "*aarch64_sve_<inc_dec><mode>_cntp"
10409 1.1.1.3 mrg [(set (match_operand:VNx8HI 0 "register_operand" "=w, ?&w")
10410 1.1.1.3 mrg (ANY_PLUS:VNx8HI
10411 1.1.1.3 mrg (vec_duplicate:VNx8HI
10412 1.1.1.3 mrg (match_operator:HI 3 "subreg_lowpart_operator"
10413 1.1.1.3 mrg [(unspec:SI
10414 1.1.1.3 mrg [(match_operand 4)
10415 1.1.1.3 mrg (const_int SVE_KNOWN_PTRUE)
10416 1.1.1.3 mrg (match_operand:<VPRED> 2 "register_operand" "Upa, Upa")]
10417 1.1.1.3 mrg UNSPEC_CNTP)]))
10418 1.1.1.3 mrg (match_operand:VNx8HI_ONLY 1 "register_operand" "0, w")))]
10419 1.1.1.3 mrg "TARGET_SVE"
10420 1.1.1.3 mrg "@
10421 1.1.1.3 mrg <inc_dec>p\t%0.h, %2
10422 1.1.1.3 mrg movprfx\t%0, %1\;<inc_dec>p\t%0.h, %2"
10423 1.1.1.3 mrg "&& !CONSTANT_P (operands[4])"
10424 1.1.1.3 mrg {
10425 1.1.1.3 mrg operands[4] = CONSTM1_RTX (<VPRED>mode);
10426 1.1.1.3 mrg }
10427 1.1.1.3 mrg [(set_attr "movprfx" "*,yes")]
10428 1.1 mrg )
10429 1.1.1.2 mrg
10430 1.1.1.3 mrg ;; -------------------------------------------------------------------------
10431 1.1.1.3 mrg ;; ---- [INT] Decrement by the number of elements in a predicate (scalar)
10432 1.1.1.3 mrg ;; -------------------------------------------------------------------------
10433 1.1.1.3 mrg ;; Includes:
10434 1.1.1.3 mrg ;; - DECP
10435 1.1.1.3 mrg ;; - SQDECP
10436 1.1.1.3 mrg ;; - UQDECP
10437 1.1.1.3 mrg ;; -------------------------------------------------------------------------
10438 1.1.1.3 mrg
10439 1.1.1.3 mrg ;; Decrement a DImode register by the number of set bits in a predicate.
10440 1.1.1.3 mrg ;; See aarch64_sve_cntp for a description of the operands.
10441 1.1.1.3 mrg (define_expand "@aarch64_sve_<inc_dec><DI_ONLY:mode><PRED_ALL:mode>_cntp"
10442 1.1.1.3 mrg [(set (match_operand:DI 0 "register_operand")
10443 1.1.1.3 mrg (ANY_MINUS:DI
10444 1.1.1.3 mrg (match_operand:DI_ONLY 1 "register_operand")
10445 1.1.1.3 mrg (zero_extend:DI
10446 1.1.1.3 mrg (unspec:SI [(match_dup 3)
10447 1.1.1.3 mrg (const_int SVE_KNOWN_PTRUE)
10448 1.1.1.3 mrg (match_operand:PRED_ALL 2 "register_operand")]
10449 1.1.1.3 mrg UNSPEC_CNTP))))]
10450 1.1.1.3 mrg "TARGET_SVE"
10451 1.1.1.3 mrg {
10452 1.1.1.3 mrg operands[3] = CONSTM1_RTX (<PRED_ALL:MODE>mode);
10453 1.1.1.3 mrg }
10454 1.1.1.3 mrg )
10455 1.1.1.3 mrg
10456 1.1.1.3 mrg (define_insn_and_rewrite "*aarch64_sve_<inc_dec><DI_ONLY:mode><PRED_ALL:mode>_cntp"
10457 1.1.1.3 mrg [(set (match_operand:DI 0 "register_operand" "=r")
10458 1.1.1.3 mrg (ANY_MINUS:DI
10459 1.1.1.3 mrg (match_operand:DI_ONLY 1 "register_operand" "0")
10460 1.1.1.3 mrg (zero_extend:DI
10461 1.1.1.3 mrg (unspec:SI [(match_operand 3)
10462 1.1.1.3 mrg (const_int SVE_KNOWN_PTRUE)
10463 1.1.1.3 mrg (match_operand:PRED_ALL 2 "register_operand" "Upa")]
10464 1.1.1.3 mrg UNSPEC_CNTP))))]
10465 1.1.1.3 mrg "TARGET_SVE"
10466 1.1.1.3 mrg "<inc_dec>p\t%x0, %2.<PRED_ALL:Vetype>"
10467 1.1.1.3 mrg "&& !CONSTANT_P (operands[3])"
10468 1.1.1.3 mrg {
10469 1.1.1.3 mrg operands[3] = CONSTM1_RTX (<PRED_ALL:MODE>mode);
10470 1.1.1.3 mrg }
10471 1.1.1.3 mrg )
10472 1.1.1.3 mrg
10473 1.1.1.3 mrg ;; Decrement an SImode register by the number of set bits in a predicate
10474 1.1.1.3 mrg ;; using modular arithmetic. See aarch64_sve_cntp for a description of the
10475 1.1.1.3 mrg ;; operands.
10476 1.1.1.3 mrg (define_insn_and_rewrite "*aarch64_decsi<mode>_cntp"
10477 1.1.1.3 mrg [(set (match_operand:SI 0 "register_operand" "=r")
10478 1.1.1.3 mrg (minus:SI
10479 1.1.1.3 mrg (match_operand:SI 1 "register_operand" "0")
10480 1.1.1.3 mrg (unspec:SI [(match_operand 3)
10481 1.1.1.3 mrg (const_int SVE_KNOWN_PTRUE)
10482 1.1.1.3 mrg (match_operand:PRED_ALL 2 "register_operand" "Upa")]
10483 1.1.1.3 mrg UNSPEC_CNTP)))]
10484 1.1.1.3 mrg "TARGET_SVE"
10485 1.1.1.3 mrg "decp\t%x0, %2.<Vetype>"
10486 1.1.1.3 mrg "&& !CONSTANT_P (operands[3])"
10487 1.1.1.3 mrg {
10488 1.1.1.3 mrg operands[3] = CONSTM1_RTX (<MODE>mode);
10489 1.1.1.3 mrg }
10490 1.1.1.3 mrg )
10491 1.1.1.3 mrg
10492 1.1.1.3 mrg ;; Decrement an SImode register by the number of set bits in a predicate
10493 1.1.1.3 mrg ;; using saturating arithmetic, extending the result to 64 bits.
10494 1.1.1.3 mrg ;;
10495 1.1.1.3 mrg ;; See aarch64_sve_cntp for a description of the operands.
10496 1.1.1.3 mrg (define_expand "@aarch64_sve_<inc_dec><SI_ONLY:mode><PRED_ALL:mode>_cntp"
10497 1.1.1.3 mrg [(set (match_operand:DI 0 "register_operand")
10498 1.1.1.3 mrg (<paired_extend>:DI
10499 1.1.1.3 mrg (SAT_MINUS:SI
10500 1.1.1.3 mrg (match_operand:SI_ONLY 1 "register_operand")
10501 1.1.1.3 mrg (unspec:SI [(match_dup 3)
10502 1.1.1.3 mrg (const_int SVE_KNOWN_PTRUE)
10503 1.1.1.3 mrg (match_operand:PRED_ALL 2 "register_operand")]
10504 1.1.1.3 mrg UNSPEC_CNTP))))]
10505 1.1.1.3 mrg "TARGET_SVE"
10506 1.1.1.3 mrg {
10507 1.1.1.3 mrg operands[3] = CONSTM1_RTX (<PRED_ALL:MODE>mode);
10508 1.1.1.3 mrg }
10509 1.1.1.3 mrg )
10510 1.1.1.3 mrg
10511 1.1.1.3 mrg (define_insn_and_rewrite "*aarch64_sve_<inc_dec><SI_ONLY:mode><PRED_ALL:mode>_cntp"
10512 1.1.1.3 mrg [(set (match_operand:DI 0 "register_operand" "=r")
10513 1.1.1.3 mrg (<paired_extend>:DI
10514 1.1.1.3 mrg (SAT_MINUS:SI
10515 1.1.1.3 mrg (match_operand:SI_ONLY 1 "register_operand" "0")
10516 1.1.1.3 mrg (unspec:SI [(match_operand 3)
10517 1.1.1.3 mrg (const_int SVE_KNOWN_PTRUE)
10518 1.1.1.3 mrg (match_operand:PRED_ALL 2 "register_operand" "Upa")]
10519 1.1.1.3 mrg UNSPEC_CNTP))))]
10520 1.1.1.2 mrg "TARGET_SVE"
10521 1.1.1.2 mrg {
10522 1.1.1.3 mrg if (<CODE> == SS_MINUS)
10523 1.1.1.3 mrg return "<inc_dec>p\t%x0, %2.<PRED_ALL:Vetype>, %w0";
10524 1.1.1.3 mrg else
10525 1.1.1.3 mrg return "<inc_dec>p\t%w0, %2.<PRED_ALL:Vetype>";
10526 1.1.1.3 mrg }
10527 1.1.1.3 mrg "&& !CONSTANT_P (operands[3])"
10528 1.1.1.3 mrg {
10529 1.1.1.3 mrg operands[3] = CONSTM1_RTX (<PRED_ALL:MODE>mode);
10530 1.1.1.3 mrg }
10531 1.1.1.3 mrg )
10532 1.1.1.2 mrg
10533 1.1.1.3 mrg ;; -------------------------------------------------------------------------
10534 1.1.1.3 mrg ;; ---- [INT] Decrement by the number of elements in a predicate (vector)
10535 1.1.1.3 mrg ;; -------------------------------------------------------------------------
10536 1.1.1.3 mrg ;; Includes:
10537 1.1.1.3 mrg ;; - DECP
10538 1.1.1.3 mrg ;; - SQDECP
10539 1.1.1.3 mrg ;; - UQDECP
10540 1.1.1.3 mrg ;; -------------------------------------------------------------------------
10541 1.1.1.2 mrg
10542 1.1.1.3 mrg ;; Decrement a vector of DIs by the number of set bits in a predicate.
10543 1.1.1.3 mrg ;; See aarch64_sve_cntp for a description of the operands.
10544 1.1.1.3 mrg (define_expand "@aarch64_sve_<inc_dec><mode>_cntp"
10545 1.1.1.3 mrg [(set (match_operand:VNx2DI 0 "register_operand")
10546 1.1.1.3 mrg (ANY_MINUS:VNx2DI
10547 1.1.1.3 mrg (match_operand:VNx2DI_ONLY 1 "register_operand")
10548 1.1.1.3 mrg (vec_duplicate:VNx2DI
10549 1.1.1.3 mrg (zero_extend:DI
10550 1.1.1.3 mrg (unspec:SI
10551 1.1.1.3 mrg [(match_dup 3)
10552 1.1.1.3 mrg (const_int SVE_KNOWN_PTRUE)
10553 1.1.1.3 mrg (match_operand:<VPRED> 2 "register_operand")]
10554 1.1.1.3 mrg UNSPEC_CNTP)))))]
10555 1.1.1.3 mrg "TARGET_SVE"
10556 1.1.1.3 mrg {
10557 1.1.1.3 mrg operands[3] = CONSTM1_RTX (<VPRED>mode);
10558 1.1.1.2 mrg }
10559 1.1.1.2 mrg )
10560 1.1.1.2 mrg
10561 1.1.1.3 mrg (define_insn_and_rewrite "*aarch64_sve_<inc_dec><mode>_cntp"
10562 1.1.1.3 mrg [(set (match_operand:VNx2DI 0 "register_operand" "=w, ?&w")
10563 1.1.1.3 mrg (ANY_MINUS:VNx2DI
10564 1.1.1.3 mrg (match_operand:VNx2DI_ONLY 1 "register_operand" "0, w")
10565 1.1.1.3 mrg (vec_duplicate:VNx2DI
10566 1.1.1.3 mrg (zero_extend:DI
10567 1.1.1.3 mrg (unspec:SI
10568 1.1.1.3 mrg [(match_operand 3)
10569 1.1.1.3 mrg (const_int SVE_KNOWN_PTRUE)
10570 1.1.1.3 mrg (match_operand:<VPRED> 2 "register_operand" "Upa, Upa")]
10571 1.1.1.3 mrg UNSPEC_CNTP)))))]
10572 1.1.1.2 mrg "TARGET_SVE"
10573 1.1.1.3 mrg "@
10574 1.1.1.3 mrg <inc_dec>p\t%0.d, %2
10575 1.1.1.3 mrg movprfx\t%0, %1\;<inc_dec>p\t%0.d, %2"
10576 1.1.1.3 mrg "&& !CONSTANT_P (operands[3])"
10577 1.1.1.2 mrg {
10578 1.1.1.3 mrg operands[3] = CONSTM1_RTX (<VPRED>mode);
10579 1.1.1.3 mrg }
10580 1.1.1.3 mrg [(set_attr "movprfx" "*,yes")]
10581 1.1.1.3 mrg )
10582 1.1.1.2 mrg
10583 1.1.1.3 mrg ;; Decrement a vector of SIs by the number of set bits in a predicate.
10584 1.1.1.3 mrg ;; See aarch64_sve_cntp for a description of the operands.
10585 1.1.1.3 mrg (define_expand "@aarch64_sve_<inc_dec><mode>_cntp"
10586 1.1.1.3 mrg [(set (match_operand:VNx4SI 0 "register_operand")
10587 1.1.1.3 mrg (ANY_MINUS:VNx4SI
10588 1.1.1.3 mrg (match_operand:VNx4SI_ONLY 1 "register_operand")
10589 1.1.1.3 mrg (vec_duplicate:VNx4SI
10590 1.1.1.3 mrg (unspec:SI
10591 1.1.1.3 mrg [(match_dup 3)
10592 1.1.1.3 mrg (const_int SVE_KNOWN_PTRUE)
10593 1.1.1.3 mrg (match_operand:<VPRED> 2 "register_operand")]
10594 1.1.1.3 mrg UNSPEC_CNTP))))]
10595 1.1.1.3 mrg "TARGET_SVE"
10596 1.1.1.3 mrg {
10597 1.1.1.3 mrg operands[3] = CONSTM1_RTX (<VPRED>mode);
10598 1.1.1.3 mrg }
10599 1.1.1.3 mrg )
10600 1.1.1.2 mrg
10601 1.1.1.3 mrg (define_insn_and_rewrite "*aarch64_sve_<inc_dec><mode>_cntp"
10602 1.1.1.3 mrg [(set (match_operand:VNx4SI 0 "register_operand" "=w, ?&w")
10603 1.1.1.3 mrg (ANY_MINUS:VNx4SI
10604 1.1.1.3 mrg (match_operand:VNx4SI_ONLY 1 "register_operand" "0, w")
10605 1.1.1.3 mrg (vec_duplicate:VNx4SI
10606 1.1.1.3 mrg (unspec:SI
10607 1.1.1.3 mrg [(match_operand 3)
10608 1.1.1.3 mrg (const_int SVE_KNOWN_PTRUE)
10609 1.1.1.3 mrg (match_operand:<VPRED> 2 "register_operand" "Upa, Upa")]
10610 1.1.1.3 mrg UNSPEC_CNTP))))]
10611 1.1.1.3 mrg "TARGET_SVE"
10612 1.1.1.3 mrg "@
10613 1.1.1.3 mrg <inc_dec>p\t%0.s, %2
10614 1.1.1.3 mrg movprfx\t%0, %1\;<inc_dec>p\t%0.s, %2"
10615 1.1.1.3 mrg "&& !CONSTANT_P (operands[3])"
10616 1.1.1.3 mrg {
10617 1.1.1.3 mrg operands[3] = CONSTM1_RTX (<VPRED>mode);
10618 1.1.1.3 mrg }
10619 1.1.1.3 mrg [(set_attr "movprfx" "*,yes")]
10620 1.1.1.3 mrg )
10621 1.1.1.3 mrg
10622 1.1.1.3 mrg ;; Decrement a vector of HIs by the number of set bits in a predicate.
10623 1.1.1.3 mrg ;; See aarch64_sve_cntp for a description of the operands.
10624 1.1.1.3 mrg (define_expand "@aarch64_sve_<inc_dec><mode>_cntp"
10625 1.1.1.3 mrg [(set (match_operand:VNx8HI 0 "register_operand")
10626 1.1.1.3 mrg (ANY_MINUS:VNx8HI
10627 1.1.1.3 mrg (match_operand:VNx8HI_ONLY 1 "register_operand")
10628 1.1.1.3 mrg (vec_duplicate:VNx8HI
10629 1.1.1.3 mrg (truncate:HI
10630 1.1.1.3 mrg (unspec:SI
10631 1.1.1.3 mrg [(match_dup 3)
10632 1.1.1.3 mrg (const_int SVE_KNOWN_PTRUE)
10633 1.1.1.3 mrg (match_operand:<VPRED> 2 "register_operand")]
10634 1.1.1.3 mrg UNSPEC_CNTP)))))]
10635 1.1.1.3 mrg "TARGET_SVE"
10636 1.1.1.3 mrg {
10637 1.1.1.3 mrg operands[3] = CONSTM1_RTX (<VPRED>mode);
10638 1.1.1.3 mrg }
10639 1.1.1.3 mrg )
10640 1.1.1.3 mrg
10641 1.1.1.3 mrg (define_insn_and_rewrite "*aarch64_sve_<inc_dec><mode>_cntp"
10642 1.1.1.3 mrg [(set (match_operand:VNx8HI 0 "register_operand" "=w, ?&w")
10643 1.1.1.3 mrg (ANY_MINUS:VNx8HI
10644 1.1.1.3 mrg (match_operand:VNx8HI_ONLY 1 "register_operand" "0, w")
10645 1.1.1.3 mrg (vec_duplicate:VNx8HI
10646 1.1.1.3 mrg (match_operator:HI 3 "subreg_lowpart_operator"
10647 1.1.1.3 mrg [(unspec:SI
10648 1.1.1.3 mrg [(match_operand 4)
10649 1.1.1.3 mrg (const_int SVE_KNOWN_PTRUE)
10650 1.1.1.3 mrg (match_operand:<VPRED> 2 "register_operand" "Upa, Upa")]
10651 1.1.1.3 mrg UNSPEC_CNTP)]))))]
10652 1.1.1.3 mrg "TARGET_SVE"
10653 1.1.1.3 mrg "@
10654 1.1.1.3 mrg <inc_dec>p\t%0.h, %2
10655 1.1.1.3 mrg movprfx\t%0, %1\;<inc_dec>p\t%0.h, %2"
10656 1.1.1.3 mrg "&& !CONSTANT_P (operands[4])"
10657 1.1.1.3 mrg {
10658 1.1.1.3 mrg operands[4] = CONSTM1_RTX (<VPRED>mode);
10659 1.1.1.2 mrg }
10660 1.1.1.3 mrg [(set_attr "movprfx" "*,yes")]
10661 1.1.1.2 mrg )
10662