]> git.ipfire.org Git - thirdparty/gcc.git/blob - gcc/config/s390/vx-builtins.md
Update copyright years.
[thirdparty/gcc.git] / gcc / config / s390 / vx-builtins.md
1 ;;- Instruction patterns for the System z vector facility builtins.
2 ;; Copyright (C) 2015-2022 Free Software Foundation, Inc.
3 ;; Contributed by Andreas Krebbel (Andreas.Krebbel@de.ibm.com)
4
5 ;; This file is part of GCC.
6
7 ;; GCC is free software; you can redistribute it and/or modify it under
8 ;; the terms of the GNU General Public License as published by the Free
9 ;; Software Foundation; either version 3, or (at your option) any later
10 ;; version.
11
12 ;; GCC is distributed in the hope that it will be useful, but WITHOUT ANY
13 ;; WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 ;; FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
15 ;; for more details.
16
17 ;; You should have received a copy of the GNU General Public License
18 ;; along with GCC; see the file COPYING3. If not see
19 ;; <http://www.gnu.org/licenses/>.
20
21 ; The patterns in this file are enabled with -mzvector
22
23 (define_mode_iterator V_HW_32_64 [V4SI V2DI V2DF (V4SF "TARGET_VXE")])
24 (define_mode_iterator VI_HW_SD [V4SI V2DI])
25
26 ; Full size vector modes with more than one element which are directly supported in vector registers by the hardware.
27 (define_mode_iterator VEC_HW [V16QI V8HI V4SI V2DI V2DF (V4SF "TARGET_VXE")])
28 (define_mode_iterator VECF_HW [(V4SF "TARGET_VXE") V2DF])
29
30 ; The element type of the vector with floating point modes translated
31 ; to int modes of the same size.
32 (define_mode_attr non_vec_int[(V1QI "QI") (V2QI "QI") (V4QI "QI") (V8QI "QI") (V16QI "QI")
33 (V1HI "HI") (V2HI "HI") (V4HI "HI") (V8HI "HI")
34 (V1SI "SI") (V2SI "SI") (V4SI "SI")
35 (V1DI "DI") (V2DI "DI")
36 (V1SF "SI") (V2SF "SI") (V4SF "SI")
37 (V1DF "DI") (V2DF "DI")])
38
39 ; Condition code modes generated by int comparisons
40 (define_mode_iterator VICMP [CCVEQ CCVIH CCVIHU])
41
42 ; Comparisons supported by the vec_cmp* builtins
43 (define_code_iterator intcmp [eq gt gtu ge geu lt ltu le leu])
44 (define_code_iterator fpcmp [eq gt ge lt le])
45
46 ; Comparisons supported by the vec_all/any* builtins
47 (define_code_iterator intcmpcc [eq ne gt ge lt le gtu geu ltu leu])
48 (define_code_iterator fpcmpcc [eq ne gt ge unle unlt lt le])
49
50 ; Flags for vector string instructions (vfae all 4, vfee only ZS and CS, vstrc all 4)
51 (define_constants
52 [(VSTRING_FLAG_IN 8) ; invert result
53 (VSTRING_FLAG_RT 4) ; result type
54 (VSTRING_FLAG_ZS 2) ; zero search
55 (VSTRING_FLAG_CS 1)]) ; condition code set
56
57 ; Rounding modes as being used for e.g. VFI
58 (define_constants
59 [(VEC_RND_CURRENT 0)
60 (VEC_RND_NEAREST_AWAY_FROM_ZERO 1)
61 (VEC_RND_SHORT_PREC 3)
62 (VEC_RND_NEAREST_TO_EVEN 4)
63 (VEC_RND_TO_ZERO 5)
64 (VEC_RND_TO_INF 6)
65 (VEC_RND_TO_MINF 7)])
66
67 ; Inexact suppression facility flag as being used for e.g. VFI
68 (define_constants
69 [(VEC_INEXACT 0)
70 (VEC_NOINEXACT 4)])
71
72
73 ; Vector gather element
74
75 ; vgef, vgeg
76 (define_insn "vec_gather_element<mode>"
77 [(set (match_operand:V_HW_32_64 0 "register_operand" "=v")
78 (unspec:V_HW_32_64 [(match_operand:V_HW_32_64 1 "register_operand" "0")
79 (match_operand:<TOINTVEC> 2 "register_operand" "v")
80 (match_operand:BLK 3 "memory_operand" "R")
81 (match_operand:QI 4 "const_mask_operand" "C")]
82 UNSPEC_VEC_GATHER))]
83 "TARGET_VX && UINTVAL (operands[4]) < GET_MODE_NUNITS (<V_HW_32_64:MODE>mode)"
84 "vge<bhfgq>\t%0,%O3(%v2,%R3),%b4"
85 [(set_attr "op_type" "VRV")])
86
87 (define_expand "vec_genmask<mode>"
88 [(match_operand:VI_HW 0 "register_operand" "=v")
89 (match_operand:QI 1 "const_int_operand" "C")
90 (match_operand:QI 2 "const_int_operand" "C")]
91 "TARGET_VX"
92 {
93 int bitlen = GET_MODE_UNIT_BITSIZE (<VI_HW:MODE>mode);
94 /* To bit little endian style. */
95 int end = bitlen - 1 - INTVAL (operands[1]);
96 int start = bitlen - 1 - INTVAL (operands[2]);
97 int i;
98 unsigned HOST_WIDE_INT mask;
99 bool swapped_p = false;
100
101 if (start > end)
102 {
103 i = start - 1; start = end + 1; end = i;
104 swapped_p = true;
105 }
106 if (end == 63)
107 mask = HOST_WIDE_INT_M1U;
108 else
109 mask = (HOST_WIDE_INT_1U << (end + 1)) - 1;
110
111 mask &= ~((HOST_WIDE_INT_1U << start) - 1);
112
113 if (swapped_p)
114 mask = ~mask;
115
116 rtx mask_rtx = gen_int_mode (mask, GET_MODE_INNER (<VI_HW:MODE>mode));
117
118 emit_insn (gen_rtx_SET (operands[0],
119 gen_const_vec_duplicate (<VI_HW:MODE>mode,
120 mask_rtx)));
121 DONE;
122 })
123
124 (define_expand "vec_genbytemaskv16qi"
125 [(match_operand:V16QI 0 "register_operand" "")
126 (match_operand:HI 1 "const_int_operand" "")]
127 "TARGET_VX"
128 {
129 int i;
130 unsigned mask = 0x8000;
131 rtx const_vec[16];
132 unsigned HOST_WIDE_INT byte_mask = UINTVAL (operands[1]);
133
134 for (i = 0; i < 16; i++)
135 {
136 if (mask & byte_mask)
137 const_vec[i] = constm1_rtx;
138 else
139 const_vec[i] = const0_rtx;
140 mask = mask >> 1;
141 }
142 emit_insn (gen_rtx_SET (operands[0],
143 gen_rtx_CONST_VECTOR (V16QImode,
144 gen_rtvec_v (16, const_vec))));
145 DONE;
146 })
147
148 (define_expand "vec_splats<mode>"
149 [(set (match_operand:VEC_HW 0 "register_operand" "")
150 (vec_duplicate:VEC_HW (match_operand:<non_vec> 1 "general_operand" "")))]
151 "TARGET_VX")
152
153 (define_expand "vec_insert<mode>"
154 [(set (match_operand:VEC_HW 0 "register_operand" "")
155 (unspec:VEC_HW [(match_operand:<non_vec> 2 "register_operand" "")
156 (match_operand:SI 3 "nonmemory_operand" "")
157 (match_operand:VEC_HW 1 "register_operand" "")]
158 UNSPEC_VEC_SET))]
159 "TARGET_VX"
160 "")
161
162 ; This is vec_set + modulo arithmetic on the element selector (op 2)
163 (define_expand "vec_promote<mode>"
164 [(set (match_operand:VEC_HW 0 "register_operand" "")
165 (unspec:VEC_HW [(match_operand:<non_vec> 1 "register_operand" "")
166 (match_operand:SI 2 "nonmemory_operand" "")
167 (match_dup 0)]
168 UNSPEC_VEC_SET))]
169 "TARGET_VX"
170 "")
171
172 ; vec_extract is also an RTL standard name -> vector.md
173
174 ; vllezb, vllezh, vllezf, vllezg
175 (define_insn "vec_insert_and_zero<mode>"
176 [(set (match_operand:VEC_HW 0 "register_operand" "=v")
177 (unspec:VEC_HW [(match_operand:<non_vec> 1 "memory_operand" "R")]
178 UNSPEC_VEC_INSERT_AND_ZERO))]
179 "TARGET_VX"
180 "vllez<bhfgq>\t%v0,%1"
181 [(set_attr "op_type" "VRX")])
182
183 ; vec_revb (vec_insert_and_zero(x)) bswap-and-replicate-1.c
184 ; vllebrzh, vllebrzf, vllebrzg
185 (define_insn "*vec_insert_and_zero_bswap<mode>"
186 [(set (match_operand:V_HW_HSD 0 "register_operand" "=v")
187 (bswap:V_HW_HSD (unspec:V_HW_HSD
188 [(match_operand:<non_vec> 1 "memory_operand" "R")]
189 UNSPEC_VEC_INSERT_AND_ZERO)))
190 (use (match_operand:V16QI 2 "permute_pattern_operand" "X"))]
191 "TARGET_VXE2"
192 "vllebrz<bhfgq>\t%v0,%1"
193 [(set_attr "op_type" "VRX")])
194
195
196 (define_insn "vlbb"
197 [(set (match_operand:V16QI 0 "register_operand" "=v")
198 (unspec:V16QI [(match_operand:BLK 1 "memory_operand" "R")
199 (match_operand:QI 2 "const_mask_operand" "C")]
200 UNSPEC_VEC_LOAD_BNDRY))]
201 "TARGET_VX && UINTVAL (operands[2]) < 7"
202 "vlbb\t%v0,%1,%2"
203 [(set_attr "op_type" "VRX")])
204
205 ; Vector load rightmost with length
206
207 (define_expand "vlrlrv16qi"
208 [(set (match_operand:V16QI 0 "register_operand" "")
209 (unspec:V16QI [(match_operand:BLK 2 "memory_operand" "")
210 (match_operand:SI 1 "nonmemory_operand" "")]
211 UNSPEC_VEC_LOAD_LEN_R))]
212 "TARGET_VXE"
213 {
214 /* vlrlr sets all length values beyond 15 to 15. Emulate the same
215 behavior for immediate length operands. vlrl would trigger a
216 SIGILL for too large immediate operands. */
217 if (CONST_INT_P (operands[1])
218 && (UINTVAL (operands[1]) & 0xffffffff) > 15)
219 operands[1] = GEN_INT (15);
220 })
221
222 (define_insn "*vlrlrv16qi"
223 [(set (match_operand:V16QI 0 "register_operand" "=v, v, v")
224 (unspec:V16QI [(match_operand:BLK 2 "memory_operand" "Q, R, Q")
225 (match_operand:SI 1 "nonmemory_operand" "d,j>f,jb4")]
226 UNSPEC_VEC_LOAD_LEN_R))]
227 "TARGET_VXE"
228 "@
229 vlrlr\t%v0,%1,%2
230 vl\t%v0,%2%A2
231 vlrl\t%v0,%2,%1"
232 [(set_attr "op_type" "VRS,VRX,VSI")])
233
234
235 ; vmrhb, vmrhh, vmrhf, vmrhg
236 (define_expand "vec_mergeh<mode>"
237 [(match_operand:V_128_NOSINGLE 0 "register_operand" "")
238 (match_operand:V_128_NOSINGLE 1 "register_operand" "")
239 (match_operand:V_128_NOSINGLE 2 "register_operand" "")]
240 "TARGET_VX"
241 {
242 s390_expand_merge (operands[0], operands[1], operands[2], true);
243 DONE;
244 })
245
246 ; vmrlb, vmrlh, vmrlf, vmrlg
247 (define_expand "vec_mergel<mode>"
248 [(match_operand:V_128_NOSINGLE 0 "register_operand" "")
249 (match_operand:V_128_NOSINGLE 1 "register_operand" "")
250 (match_operand:V_128_NOSINGLE 2 "register_operand" "")]
251 "TARGET_VX"
252 {
253 s390_expand_merge (operands[0], operands[1], operands[2], false);
254 DONE;
255 })
256
257
258 ; Vector pack
259
260 ; vpkh, vpkf, vpkg
261 (define_insn "vec_pack<mode>"
262 [(set (match_operand:<vec_half> 0 "register_operand" "=v")
263 (unspec:<vec_half> [(match_operand:VI_HW_HSD 1 "register_operand" "v")
264 (match_operand:VI_HW_HSD 2 "register_operand" "v")]
265 UNSPEC_VEC_PACK))]
266 "TARGET_VX"
267 "vpk<bhfgq>\t%v0,%v1,%v2"
268 [(set_attr "op_type" "VRR")])
269
270
271 ; Vector pack saturate
272
273 ; vpksh, vpksf, vpksg
274 (define_insn "vec_packs<mode>"
275 [(set (match_operand:<vec_half> 0 "register_operand" "=v")
276 (unspec:<vec_half> [(match_operand:VI_HW_HSD 1 "register_operand" "v")
277 (match_operand:VI_HW_HSD 2 "register_operand" "v")]
278 UNSPEC_VEC_PACK_SATURATE))]
279 "TARGET_VX"
280 "vpks<bhfgq>\t%v0,%v1,%v2"
281 [(set_attr "op_type" "VRR")])
282
283
284 ; This is vec_packs_cc + loading cc into a caller specified memory location.
285 (define_expand "vec_packs_cc<mode>"
286 [(parallel
287 [(set (reg:CCRAW CC_REGNUM)
288 (unspec:CCRAW [(match_operand:VI_HW_HSD 1 "register_operand" "")
289 (match_operand:VI_HW_HSD 2 "register_operand" "")]
290 UNSPEC_VEC_PACK_SATURATE_GENCC))
291 (set (match_operand:<vec_half> 0 "register_operand" "")
292 (unspec:<vec_half> [(match_dup 1) (match_dup 2)]
293 UNSPEC_VEC_PACK_SATURATE_CC))])
294 (set (match_dup 4)
295 (unspec:SI [(reg:CCRAW CC_REGNUM)] UNSPEC_CC_TO_INT))
296 (set (match_operand:SI 3 "memory_operand" "")
297 (match_dup 4))]
298 "TARGET_VX"
299 {
300 operands[4] = gen_reg_rtx (SImode);
301 })
302
303 ; vpksh, vpksf, vpksg
304 (define_insn "*vec_packs_cc<mode>"
305 [(set (reg:CCRAW CC_REGNUM)
306 (unspec:CCRAW [(match_operand:VI_HW_HSD 1 "register_operand" "v")
307 (match_operand:VI_HW_HSD 2 "register_operand" "v")]
308 UNSPEC_VEC_PACK_SATURATE_GENCC))
309 (set (match_operand:<vec_half> 0 "register_operand" "=v")
310 (unspec:<vec_half> [(match_dup 1) (match_dup 2)]
311 UNSPEC_VEC_PACK_SATURATE_CC))]
312 "TARGET_VX"
313 "vpks<bhfgq>s\t%v0,%v1,%v2"
314 [(set_attr "op_type" "VRR")])
315
316
317 ; Vector pack logical saturate
318
319 ; vpklsh, vpklsf, vpklsg
320 (define_insn "vec_packsu<mode>"
321 [(set (match_operand:<vec_half> 0 "register_operand" "=v")
322 (unspec:<vec_half> [(match_operand:VI_HW_HSD 1 "register_operand" "v")
323 (match_operand:VI_HW_HSD 2 "register_operand" "v")]
324 UNSPEC_VEC_PACK_UNSIGNED_SATURATE))]
325 "TARGET_VX"
326 "vpkls<bhfgq>\t%v0,%v1,%v2"
327 [(set_attr "op_type" "VRR")])
328
329 ; Emulate saturate unsigned pack on signed operands.
330 ; Zero out negative elements and continue with the unsigned saturating pack.
331 (define_expand "vec_packsu_u<mode>"
332 [(set (match_operand:<vec_half> 0 "register_operand" "=v")
333 (unspec:<vec_half> [(match_operand:VI_HW_HSD 1 "register_operand" "v")
334 (match_operand:VI_HW_HSD 2 "register_operand" "v")]
335 UNSPEC_VEC_PACK_UNSIGNED_SATURATE))]
336 "TARGET_VX"
337 {
338 rtx null_vec = CONST0_RTX(<MODE>mode);
339 machine_mode half_mode;
340 switch (<MODE>mode)
341 {
342 case E_V8HImode: half_mode = V16QImode; break;
343 case E_V4SImode: half_mode = V8HImode; break;
344 case E_V2DImode: half_mode = V4SImode; break;
345 default: gcc_unreachable ();
346 }
347 s390_expand_vcond (operands[1], operands[1], null_vec,
348 GE, operands[1], null_vec);
349 s390_expand_vcond (operands[2], operands[2], null_vec,
350 GE, operands[2], null_vec);
351 emit_insn (gen_rtx_SET (operands[0],
352 gen_rtx_UNSPEC (half_mode,
353 gen_rtvec (2, operands[1], operands[2]),
354 UNSPEC_VEC_PACK_UNSIGNED_SATURATE)));
355 DONE;
356 })
357
358 ; This is vec_packsu_cc + loading cc into a caller specified memory location.
359 ; FIXME: The reg to target mem copy should be issued by reload?!
360 (define_expand "vec_packsu_cc<mode>"
361 [(parallel
362 [(set (reg:CCRAW CC_REGNUM)
363 (unspec:CCRAW [(match_operand:VI_HW_HSD 1 "register_operand" "")
364 (match_operand:VI_HW_HSD 2 "register_operand" "")]
365 UNSPEC_VEC_PACK_UNSIGNED_SATURATE_GENCC))
366 (set (match_operand:<vec_half> 0 "register_operand" "")
367 (unspec:<vec_half> [(match_dup 1) (match_dup 2)]
368 UNSPEC_VEC_PACK_UNSIGNED_SATURATE_CC))])
369 (set (match_dup 4)
370 (unspec:SI [(reg:CCRAW CC_REGNUM)] UNSPEC_CC_TO_INT))
371 (set (match_operand:SI 3 "memory_operand" "")
372 (match_dup 4))]
373 "TARGET_VX"
374 {
375 operands[4] = gen_reg_rtx (SImode);
376 })
377
378 ; vpklsh, vpklsf, vpklsg
379 (define_insn "*vec_packsu_cc<mode>"
380 [(set (reg:CCRAW CC_REGNUM)
381 (unspec:CCRAW [(match_operand:VI_HW_HSD 1 "register_operand" "v")
382 (match_operand:VI_HW_HSD 2 "register_operand" "v")]
383 UNSPEC_VEC_PACK_UNSIGNED_SATURATE_GENCC))
384 (set (match_operand:<vec_half> 0 "register_operand" "=v")
385 (unspec:<vec_half> [(match_dup 1) (match_dup 2)]
386 UNSPEC_VEC_PACK_UNSIGNED_SATURATE_CC))]
387 "TARGET_VX"
388 "vpkls<bhfgq>s\t%v0,%v1,%v2"
389 [(set_attr "op_type" "VRR")])
390
391
392 ; Vector permute
393
394 ; vec_perm is also RTL standard name, but we can only use it for V16QI
395
396 (define_insn "vec_zperm<mode>"
397 [(set (match_operand:V_HW_HSD 0 "register_operand" "=v")
398 (unspec:V_HW_HSD [(match_operand:V_HW_HSD 1 "register_operand" "v")
399 (match_operand:V_HW_HSD 2 "register_operand" "v")
400 (match_operand:V16QI 3 "register_operand" "v")]
401 UNSPEC_VEC_PERM))]
402 "TARGET_VX"
403 "vperm\t%v0,%v1,%v2,%v3"
404 [(set_attr "op_type" "VRR")])
405
406 ; Incoming op3 is in vec_permi format and will we turned into a
407 ; permute vector consisting of op3 and op4.
408 (define_expand "vec_permi<mode>"
409 [(set (match_operand:V_HW_2 0 "register_operand" "")
410 (vec_select:V_HW_2
411 (vec_concat:<vec_2x_nelts>
412 (match_operand:V_HW_2 1 "register_operand" "")
413 (match_operand:V_HW_2 2 "register_operand" ""))
414 (parallel [(match_operand:QI 3 "const_mask_operand" "") (match_dup 4)])))]
415 "TARGET_VX"
416 {
417 HOST_WIDE_INT val = INTVAL (operands[3]);
418 operands[3] = GEN_INT ((val & 2) >> 1);
419 operands[4] = GEN_INT ((val & 1) + 2);
420 })
421
422
423 ; Vector replicate
424
425
426 ; Replicate from vector element
427 (define_expand "vec_splat<mode>"
428 [(set (match_operand:V_HW 0 "register_operand" "")
429 (vec_duplicate:V_HW (vec_select:<non_vec>
430 (match_operand:V_HW 1 "register_operand" "")
431 (parallel
432 [(match_operand:QI 2 "const_mask_operand" "")]))))]
433 "TARGET_VX")
434
435 ; Vector scatter element
436
437 ; vscef, vsceg
438
439 ; A 64 bit target address generated from 32 bit elements
440 (define_insn "vec_scatter_element<V_HW_4:mode>_DI"
441 [(set (mem:<non_vec>
442 (plus:DI (zero_extend:DI
443 (unspec:SI [(match_operand:V4SI 1 "register_operand" "v")
444 (match_operand:QI 3 "const_mask_operand" "C")]
445 UNSPEC_VEC_EXTRACT))
446 (match_operand:SI 2 "address_operand" "ZQ")))
447 (unspec:<non_vec> [(match_operand:V_HW_4 0 "register_operand" "v")
448 (match_dup 3)] UNSPEC_VEC_EXTRACT))]
449 "TARGET_VX && TARGET_64BIT && UINTVAL (operands[3]) < 4"
450 "vscef\t%v0,%O2(%v1,%R2),%3"
451 [(set_attr "op_type" "VRV")])
452
453 ; A 31 bit target address is generated from 64 bit elements
454 ; vsceg
455 (define_insn "vec_scatter_element<V_HW_2:mode>_SI"
456 [(set (mem:<non_vec>
457 (plus:SI (subreg:SI
458 (unspec:<non_vec_int> [(match_operand:V_HW_2 1 "register_operand" "v")
459 (match_operand:QI 3 "const_mask_operand" "C")]
460 UNSPEC_VEC_EXTRACT) 4)
461 (match_operand:SI 2 "address_operand" "ZQ")))
462 (unspec:<non_vec> [(match_operand:V_HW_2 0 "register_operand" "v")
463 (match_dup 3)] UNSPEC_VEC_EXTRACT))]
464 "TARGET_VX && !TARGET_64BIT && UINTVAL (operands[3]) < GET_MODE_NUNITS (<V_HW_2:MODE>mode)"
465 "vsce<V_HW_2:bhfgq>\t%v0,%O2(%v1,%R2),%3"
466 [(set_attr "op_type" "VRV")])
467
468 ; Element size and target address size is the same
469 ; vscef, vsceg
470 (define_insn "vec_scatter_element<mode>_<non_vec_int>"
471 [(set (mem:<non_vec>
472 (plus:<non_vec_int> (unspec:<non_vec_int>
473 [(match_operand:<TOINTVEC> 1 "register_operand" "v")
474 (match_operand:QI 3 "const_mask_operand" "C")]
475 UNSPEC_VEC_EXTRACT)
476 (match_operand:DI 2 "address_operand" "ZQ")))
477 (unspec:<non_vec> [(match_operand:V_HW_32_64 0 "register_operand" "v")
478 (match_dup 3)] UNSPEC_VEC_EXTRACT))]
479 "TARGET_VX && UINTVAL (operands[3]) < GET_MODE_NUNITS (<V_HW_32_64:MODE>mode)"
480 "vsce<bhfgq>\t%v0,%O2(%v1,%R2),%3"
481 [(set_attr "op_type" "VRV")])
482
483 ; Depending on the address size we have to expand a different pattern.
484 ; This however cannot be represented in s390-builtins.def so we do the
485 ; multiplexing here in the expander.
486 (define_expand "vec_scatter_element<V_HW_32_64:mode>"
487 [(match_operand:V_HW_32_64 0 "register_operand" "")
488 (match_operand:<TOINTVEC> 1 "register_operand" "")
489 (match_operand 2 "address_operand" "")
490 (match_operand:QI 3 "const_mask_operand" "")]
491 "TARGET_VX"
492 {
493 if (TARGET_64BIT)
494 {
495 PUT_MODE (operands[2], DImode);
496 emit_insn (
497 gen_vec_scatter_element<V_HW_32_64:mode>_DI (operands[0], operands[1],
498 operands[2], operands[3]));
499 }
500 else
501 {
502 PUT_MODE (operands[2], SImode);
503 emit_insn (
504 gen_vec_scatter_element<V_HW_32_64:mode>_SI (operands[0], operands[1],
505 operands[2], operands[3]));
506 }
507 DONE;
508 })
509
510
511 ; Vector select
512
513 ; for all b in bits op0[b] = op3[b] == 0 ? op2[b] : op1[b]
514 ; implemented as: op0 = (op1 & op3) | (op2 & ~op3)
515
516 ; Used to expand the vec_sel builtin. Operands op1 and op2 already got
517 ; swapped in s390-c.c when we get here.
518
519 (define_insn "vsel<mode>"
520 [(set (match_operand:V_HW 0 "register_operand" "=v")
521 (ior:V_HW
522 (and:V_HW (match_operand:V_HW 1 "register_operand" "v")
523 (match_operand:V_HW 3 "register_operand" "v"))
524 (and:V_HW (not:V_HW (match_dup 3))
525 (match_operand:V_HW 2 "register_operand" "v"))))]
526 "TARGET_VX"
527 "vsel\t%v0,%1,%2,%3"
528 [(set_attr "op_type" "VRR")])
529
530
531 ; Vector sign extend to doubleword
532
533 ; Sign extend of right most vector element to respective double-word
534 ; vsegb, vsegh, vsegf
535 (define_insn "vec_extend<mode>"
536 [(set (match_operand:VI_HW_QHS 0 "register_operand" "=v")
537 (unspec:VI_HW_QHS [(match_operand:VI_HW_QHS 1 "register_operand" "v")]
538 UNSPEC_VEC_EXTEND))]
539 "TARGET_VX"
540 "vseg<bhfgq>\t%v0,%1"
541 [(set_attr "op_type" "VRR")])
542
543
544 ; Vector store with length
545
546 ; Store bytes in OP1 from OP0 with the highest indexed byte to be
547 ; stored from OP0 given by OP2
548 (define_insn "vstl<mode>"
549 [(set (match_operand:BLK 2 "memory_operand" "=Q")
550 (unspec:BLK [(match_operand:V 0 "register_operand" "v")
551 (match_operand:SI 1 "register_operand" "d")]
552 UNSPEC_VEC_STORE_LEN))]
553 "TARGET_VX"
554 "vstl\t%v0,%1,%2"
555 [(set_attr "op_type" "VRS")])
556
557 ; Vector store rightmost with length
558
559 (define_expand "vstrlrv16qi"
560 [(set (match_operand:BLK 2 "memory_operand" "")
561 (unspec:BLK [(match_operand:V16QI 0 "register_operand" "")
562 (match_operand:SI 1 "nonmemory_operand" "")]
563 UNSPEC_VEC_STORE_LEN_R))]
564 "TARGET_VXE"
565 {
566 /* vstrlr sets all length values beyond 15 to 15. Emulate the same
567 behavior for immediate length operands. vstrl would trigger a
568 SIGILL for too large immediate operands. */
569 if (CONST_INT_P (operands[1])
570 && (UINTVAL (operands[1]) & 0xffffffff) > 15)
571 operands[1] = GEN_INT (15);
572 })
573
574 (define_insn "*vstrlrv16qi"
575 [(set (match_operand:BLK 2 "memory_operand" "=Q, R, Q")
576 (unspec:BLK [(match_operand:V16QI 0 "register_operand" "v, v, v")
577 (match_operand:SI 1 "nonmemory_operand" "d,j>f,jb4")]
578 UNSPEC_VEC_STORE_LEN_R))]
579 "TARGET_VXE"
580 "@
581 vstrlr\t%v0,%1,%2
582 vst\t%v0,%2%A2
583 vstrl\t%v0,%2,%1"
584 [(set_attr "op_type" "VRS,VRX,VSI")])
585
586
587
588 ; vector bit permute
589
590 (define_insn "vbpermv16qi"
591 [(set (match_operand:V2DI 0 "register_operand" "=v")
592 (unspec:V2DI [(match_operand:V16QI 1 "register_operand" "v")
593 (match_operand:V16QI 2 "register_operand" "v")]
594 UNSPEC_VEC_VBPERM))]
595 "TARGET_VXE"
596 "vbperm\t%v0,%v1,%v2"
597 [(set_attr "op_type" "VRR")])
598
599 ; Vector unpack high
600
601 ; vuphb, vuphh, vuphf
602 (define_insn "vec_unpackh<mode>"
603 [(set (match_operand:<vec_double> 0 "register_operand" "=v")
604 (unspec:<vec_double> [(match_operand:VI_HW_QHS 1 "register_operand" "v")]
605 UNSPEC_VEC_UNPACKH))]
606 "TARGET_VX"
607 "vuph<bhfgq>\t%v0,%v1"
608 [(set_attr "op_type" "VRR")])
609
610 ; vuplhb, vuplhh, vuplhf
611 (define_insn "vec_unpackh_l<mode>"
612 [(set (match_operand:<vec_double> 0 "register_operand" "=v")
613 (unspec:<vec_double> [(match_operand:VI_HW_QHS 1 "register_operand" "v")]
614 UNSPEC_VEC_UNPACKH_L))]
615 "TARGET_VX"
616 "vuplh<bhfgq>\t%v0,%v1"
617 [(set_attr "op_type" "VRR")])
618
619
620 ; Vector unpack low
621
622 ; vuplb, vuplhw, vuplf
623 (define_insn "vec_unpackl<mode>"
624 [(set (match_operand:<vec_double> 0 "register_operand" "=v")
625 (unspec:<vec_double> [(match_operand:VI_HW_QHS 1 "register_operand" "v")]
626 UNSPEC_VEC_UNPACKL))]
627 "TARGET_VX"
628 "vupl<bhfgq><w>\t%v0,%v1"
629 [(set_attr "op_type" "VRR")])
630
631 ; vupllb, vupllh, vupllf
632 (define_insn "vec_unpackl_l<mode>"
633 [(set (match_operand:<vec_double> 0 "register_operand" "=v")
634 (unspec:<vec_double> [(match_operand:VI_HW_QHS 1 "register_operand" "v")]
635 UNSPEC_VEC_UNPACKL_L))]
636 "TARGET_VX"
637 "vupll<bhfgq>\t%v0,%v1"
638 [(set_attr "op_type" "VRR")])
639
640
641 ; Vector add
642
643 ; Vector add compute carry
644
645 ; vaccb, vacch, vaccf, vaccg, vaccq
646 (define_insn "vacc<bhfgq>_<mode>"
647 [(set (match_operand:VIT_HW 0 "register_operand" "=v")
648 (unspec:VIT_HW [(match_operand:VIT_HW 1 "register_operand" "v")
649 (match_operand:VIT_HW 2 "register_operand" "v")]
650 UNSPEC_VEC_ADDC))]
651 "TARGET_VX"
652 "vacc<bhfgq>\t%v0,%v1,%v2"
653 [(set_attr "op_type" "VRR")])
654
655 ; Vector add with carry
656
657 (define_insn "vacq"
658 [(set (match_operand:TI 0 "register_operand" "=v")
659 (unspec:TI [(match_operand:TI 1 "register_operand" "v")
660 (match_operand:TI 2 "register_operand" "v")
661 (match_operand:TI 3 "register_operand" "v")]
662 UNSPEC_VEC_ADDE_U128))]
663 "TARGET_VX"
664 "vacq\t%v0,%v1,%v2,%v3"
665 [(set_attr "op_type" "VRR")])
666
667
668 ; Vector add with carry compute carry
669
670 (define_insn "vacccq"
671 [(set (match_operand:TI 0 "register_operand" "=v")
672 (unspec:TI [(match_operand:TI 1 "register_operand" "v")
673 (match_operand:TI 2 "register_operand" "v")
674 (match_operand:TI 3 "register_operand" "v")]
675 UNSPEC_VEC_ADDEC_U128))]
676 "TARGET_VX"
677 "vacccq\t%v0,%v1,%v2,%v3"
678 [(set_attr "op_type" "VRR")])
679
680
681 ; Vector and
682
683 ; Vector and with complement
684
685 ; vnc
686 (define_insn "vec_andc<mode>3"
687 [(set (match_operand:VT_HW 0 "register_operand" "=v")
688 (and:VT_HW (not:VT_HW (match_operand:VT_HW 2 "register_operand" "v"))
689 (match_operand:VT_HW 1 "register_operand" "v")))]
690 "TARGET_VX"
691 "vnc\t%v0,%v1,%v2"
692 [(set_attr "op_type" "VRR")])
693
694
695 ; Vector average
696
697 ; vavgb, vavgh, vavgf, vavgg
698 (define_insn "vec_avg<mode>"
699 [(set (match_operand:VI_HW 0 "register_operand" "=v")
700 (unspec:VI_HW [(match_operand:VI_HW 1 "register_operand" "v")
701 (match_operand:VI_HW 2 "register_operand" "v")]
702 UNSPEC_VEC_AVG))]
703 "TARGET_VX"
704 "vavg<bhfgq>\t%v0,%v1,%v2"
705 [(set_attr "op_type" "VRR")])
706
707 ; Vector average logical
708
709 ; vavglb, vavglh, vavglf, vavglg
710 (define_insn "vec_avgu<mode>"
711 [(set (match_operand:VI_HW 0 "register_operand" "=v")
712 (unspec:VI_HW [(match_operand:VI_HW 1 "register_operand" "v")
713 (match_operand:VI_HW 2 "register_operand" "v")]
714 UNSPEC_VEC_AVGU))]
715 "TARGET_VX"
716 "vavgl<bhfgq>\t%v0,%v1,%v2"
717 [(set_attr "op_type" "VRR")])
718
719
720 ; Vector checksum
721
722 (define_insn "vec_checksum"
723 [(set (match_operand:V4SI 0 "register_operand" "=v")
724 (unspec:V4SI [(match_operand:V4SI 1 "register_operand" "v")
725 (match_operand:V4SI 2 "register_operand" "v")]
726 UNSPEC_VEC_CHECKSUM))]
727 "TARGET_VX"
728 "vcksm\t%v0,%v1,%v2"
729 [(set_attr "op_type" "VRR")])
730
731 ;;
732 ;; Vector compare
733 ;;
734
735 ; vec_all/any int compares
736
737 (define_expand "vec_all_<intcmpcc:code><VI_HW:mode>"
738 [(match_operand:SI 0 "register_operand" "")
739 (intcmpcc (match_operand:VI_HW 1 "register_operand" "")
740 (match_operand:VI_HW 2 "register_operand" ""))]
741 "TARGET_VX"
742 {
743 s390_expand_vec_compare_cc (operands[0],
744 <intcmpcc:CODE>,
745 operands[1],
746 operands[2],
747 true);
748 DONE;
749 })
750
751 (define_expand "vec_any_<intcmpcc:code><VI_HW:mode>"
752 [(match_operand:SI 0 "register_operand" "")
753 (intcmpcc (match_operand:VI_HW 1 "register_operand" "")
754 (match_operand:VI_HW 2 "register_operand" ""))]
755 "TARGET_VX"
756 {
757 s390_expand_vec_compare_cc (operands[0],
758 <intcmpcc:CODE>,
759 operands[1],
760 operands[2],
761 false);
762 DONE;
763 })
764
765 ; vec_all/any fp compares
766
767 (define_expand "vec_all_<fpcmpcc:code><mode>"
768 [(match_operand:SI 0 "register_operand" "")
769 (fpcmpcc (match_operand:VECF_HW 1 "register_operand" "")
770 (match_operand:VECF_HW 2 "register_operand" ""))]
771 "TARGET_VX"
772 {
773 s390_expand_vec_compare_cc (operands[0],
774 <fpcmpcc:CODE>,
775 operands[1],
776 operands[2],
777 true);
778 DONE;
779 })
780
781 (define_expand "vec_any_<fpcmpcc:code><mode>"
782 [(match_operand:SI 0 "register_operand" "")
783 (fpcmpcc (match_operand:VECF_HW 1 "register_operand" "")
784 (match_operand:VECF_HW 2 "register_operand" ""))]
785 "TARGET_VX"
786 {
787 s390_expand_vec_compare_cc (operands[0],
788 <fpcmpcc:CODE>,
789 operands[1],
790 operands[2],
791 false);
792 DONE;
793 })
794
795
796 ; Compare without generating CC
797
798 (define_expand "vec_cmp<intcmp:code><VI_HW:mode>"
799 [(set (match_operand:VI_HW 0 "register_operand" "=v")
800 (intcmp:VI_HW (match_operand:VI_HW 1 "register_operand" "v")
801 (match_operand:VI_HW 2 "register_operand" "v")))]
802 "TARGET_VX"
803 {
804 s390_expand_vec_compare (operands[0], <intcmp:CODE>, operands[1], operands[2]);
805 DONE;
806 })
807
808 (define_expand "vec_cmp<fpcmp:code><mode>"
809 [(set (match_operand:<TOINTVEC> 0 "register_operand" "=v")
810 (fpcmp:<TOINTVEC> (match_operand:VF_HW 1 "register_operand" "v")
811 (match_operand:VF_HW 2 "register_operand" "v")))]
812 "TARGET_VX"
813 {
814 s390_expand_vec_compare (operands[0], <fpcmp:CODE>, operands[1], operands[2]);
815 DONE;
816 })
817
818
819 ; Vector count leading zeros
820
821 ; vec_cntlz -> clz
822 ; vec_cnttz -> ctz
823
824 ; Vector xor
825
826 ; vec_xor -> xor
827
828 ; Vector Galois field multiply sum
829
830 ; vgfmb, vgfmh, vgfmf
831 (define_insn "vec_gfmsum<mode>"
832 [(set (match_operand:VI_HW_QHS 0 "register_operand" "=v")
833 (unspec:VI_HW_QHS [(match_operand:VI_HW_QHS 1 "register_operand" "v")
834 (match_operand:VI_HW_QHS 2 "register_operand" "v")]
835 UNSPEC_VEC_GFMSUM))]
836 "TARGET_VX"
837 "vgfm<bhfgq>\t%v0,%v1,%v2"
838 [(set_attr "op_type" "VRR")])
839
840 (define_insn "vec_gfmsum_128"
841 [(set (match_operand:V16QI 0 "register_operand" "=v")
842 (unspec:V16QI [(match_operand:V2DI 1 "register_operand" "v")
843 (match_operand:V2DI 2 "register_operand" "v")]
844 UNSPEC_VEC_GFMSUM_128))]
845 "TARGET_VX"
846 "vgfmg\t%v0,%v1,%v2"
847 [(set_attr "op_type" "VRR")])
848
849 ; vgfmab, vgfmah, vgfmaf
850 (define_insn "vec_gfmsum_accum<mode>"
851 [(set (match_operand:<vec_double> 0 "register_operand" "=v")
852 (unspec:<vec_double> [(match_operand:VI_HW_QHS 1 "register_operand" "v")
853 (match_operand:VI_HW_QHS 2 "register_operand" "v")
854 (match_operand:<vec_double> 3 "register_operand" "v")]
855 UNSPEC_VEC_GFMSUM_ACCUM))]
856 "TARGET_VX"
857 "vgfma<bhfgq>\t%v0,%v1,%v2,%v3"
858 [(set_attr "op_type" "VRR")])
859
860 (define_insn "vec_gfmsum_accum_128"
861 [(set (match_operand:V16QI 0 "register_operand" "=v")
862 (unspec:V16QI [(match_operand:V2DI 1 "register_operand" "v")
863 (match_operand:V2DI 2 "register_operand" "v")
864 (match_operand:V16QI 3 "register_operand" "v")]
865 UNSPEC_VEC_GFMSUM_ACCUM_128))]
866 "TARGET_VX"
867 "vgfmag\t%v0,%v1,%v2,%v3"
868 [(set_attr "op_type" "VRR")])
869
870
871 ; FIXME: vec_neg ?
872
873 ; Vector load positive: vec_abs -> abs
874 ; Vector maximum vec_max -> smax, logical vec_max -> umax
875 ; Vector maximum vec_min -> smin, logical vec_min -> umin
876
877
878 ; Vector multiply and add high
879
880 ; vec_mladd -> vec_vmal
881 ; vmalb, vmalh, vmalf, vmalg
882 (define_insn "vec_vmal<mode>"
883 [(set (match_operand:VI_HW_QHS 0 "register_operand" "=v")
884 (unspec:VI_HW_QHS [(match_operand:VI_HW_QHS 1 "register_operand" "v")
885 (match_operand:VI_HW_QHS 2 "register_operand" "v")
886 (match_operand:VI_HW_QHS 3 "register_operand" "v")]
887 UNSPEC_VEC_VMAL))]
888 "TARGET_VX"
889 "vmal<bhfgq><w>\t%v0,%v1,%v2,%v3"
890 [(set_attr "op_type" "VRR")])
891
892 ; vec_mhadd -> vec_vmah/vec_vmalh
893
894 ; vmahb; vmahh, vmahf, vmahg
895 (define_insn "vec_vmah<mode>"
896 [(set (match_operand:VI_HW_QHS 0 "register_operand" "=v")
897 (unspec:VI_HW_QHS [(match_operand:VI_HW_QHS 1 "register_operand" "v")
898 (match_operand:VI_HW_QHS 2 "register_operand" "v")
899 (match_operand:VI_HW_QHS 3 "register_operand" "v")]
900 UNSPEC_VEC_VMAH))]
901 "TARGET_VX"
902 "vmah<bhfgq>\t%v0,%v1,%v2,%v3"
903 [(set_attr "op_type" "VRR")])
904
905 ; vmalhb; vmalhh, vmalhf, vmalhg
906 (define_insn "vec_vmalh<mode>"
907 [(set (match_operand:VI_HW_QHS 0 "register_operand" "=v")
908 (unspec:VI_HW_QHS [(match_operand:VI_HW_QHS 1 "register_operand" "v")
909 (match_operand:VI_HW_QHS 2 "register_operand" "v")
910 (match_operand:VI_HW_QHS 3 "register_operand" "v")]
911 UNSPEC_VEC_VMALH))]
912 "TARGET_VX"
913 "vmalh<bhfgq>\t%v0,%v1,%v2,%v3"
914 [(set_attr "op_type" "VRR")])
915
916 ; vec_meadd -> vec_vmae/vec_vmale
917
918 ; vmaeb; vmaeh, vmaef, vmaeg
919 (define_insn "vec_vmae<mode>"
920 [(set (match_operand:<vec_double> 0 "register_operand" "=v")
921 (unspec:<vec_double> [(match_operand:VI_HW_QHS 1 "register_operand" "v")
922 (match_operand:VI_HW_QHS 2 "register_operand" "v")
923 (match_operand:<vec_double> 3 "register_operand" "v")]
924 UNSPEC_VEC_VMAE))]
925 "TARGET_VX"
926 "vmae<bhfgq>\t%v0,%v1,%v2,%v3"
927 [(set_attr "op_type" "VRR")])
928
929 ; vmaleb; vmaleh, vmalef, vmaleg
930 (define_insn "vec_vmale<mode>"
931 [(set (match_operand:<vec_double> 0 "register_operand" "=v")
932 (unspec:<vec_double> [(match_operand:VI_HW_QHS 1 "register_operand" "v")
933 (match_operand:VI_HW_QHS 2 "register_operand" "v")
934 (match_operand:<vec_double> 3 "register_operand" "v")]
935 UNSPEC_VEC_VMALE))]
936 "TARGET_VX"
937 "vmale<bhfgq>\t%v0,%v1,%v2,%v3"
938 [(set_attr "op_type" "VRR")])
939
940 ; vec_moadd -> vec_vmao/vec_vmalo
941
942 ; vmaob; vmaoh, vmaof, vmaog
943 (define_insn "vec_vmao<mode>"
944 [(set (match_operand:<vec_double> 0 "register_operand" "=v")
945 (unspec:<vec_double> [(match_operand:VI_HW_QHS 1 "register_operand" "v")
946 (match_operand:VI_HW_QHS 2 "register_operand" "v")
947 (match_operand:<vec_double> 3 "register_operand" "v")]
948 UNSPEC_VEC_VMAO))]
949 "TARGET_VX"
950 "vmao<bhfgq>\t%v0,%v1,%v2,%v3"
951 [(set_attr "op_type" "VRR")])
952
953 ; vmalob; vmaloh, vmalof, vmalog
954 (define_insn "vec_vmalo<mode>"
955 [(set (match_operand:<vec_double> 0 "register_operand" "=v")
956 (unspec:<vec_double> [(match_operand:VI_HW_QHS 1 "register_operand" "v")
957 (match_operand:VI_HW_QHS 2 "register_operand" "v")
958 (match_operand:<vec_double> 3 "register_operand" "v")]
959 UNSPEC_VEC_VMALO))]
960 "TARGET_VX"
961 "vmalo<bhfgq>\t%v0,%v1,%v2,%v3"
962 [(set_attr "op_type" "VRR")])
963
964
965 ; Vector multiply high
966
967 ; vec_mulh -> vec_smulh/vec_umulh
968
969 ; vmhb, vmhh, vmhf
970 (define_insn "vec_smulh<mode>"
971 [(set (match_operand:VI_HW_QHS 0 "register_operand" "=v")
972 (unspec:VI_HW_QHS [(match_operand:VI_HW_QHS 1 "register_operand" "v")
973 (match_operand:VI_HW_QHS 2 "register_operand" "v")]
974 UNSPEC_VEC_SMULT_HI))]
975 "TARGET_VX"
976 "vmh<bhfgq>\t%v0,%v1,%v2"
977 [(set_attr "op_type" "VRR")])
978
979 ; vmlhb, vmlhh, vmlhf
980 (define_insn "vec_umulh<mode>"
981 [(set (match_operand:VI_HW_QHS 0 "register_operand" "=v")
982 (unspec:VI_HW_QHS [(match_operand:VI_HW_QHS 1 "register_operand" "v")
983 (match_operand:VI_HW_QHS 2 "register_operand" "v")]
984 UNSPEC_VEC_UMULT_HI))]
985 "TARGET_VX"
986 "vmlh<bhfgq>\t%v0,%v1,%v2"
987 [(set_attr "op_type" "VRR")])
988
989
990 ; Vector multiply low
991
992 ; vec_mule -> vec_widen_umult_even/vec_widen_smult_even
993 ; vec_mulo -> vec_widen_umult_odd/vec_widen_smult_odd
994
995
996 ; Vector nor
997
998 (define_insn "vec_nor<mode>3"
999 [(set (match_operand:VT_HW 0 "register_operand" "=v")
1000 (not:VT_HW
1001 (ior:VT_HW (match_operand:VT_HW 1 "register_operand" "v")
1002 (match_operand:VT_HW 2 "register_operand" "v"))))]
1003 "TARGET_VX"
1004 "vno\t%v0,%v1,%v2"
1005 [(set_attr "op_type" "VRR")])
1006
1007
1008 ; Vector or
1009
1010 ; Vector population count vec_popcnt -> popcount
1011 ; Vector element rotate left logical vec_rl -> vrotl, vec_rli -> rot
1012
1013 ; Vector element rotate and insert under mask
1014
1015 ; verimb, verimh, verimf, verimg
1016 (define_insn "verim<mode>"
1017 [(set (match_operand:VI_HW 0 "register_operand" "=v")
1018 (unspec:VI_HW [(match_operand:VI_HW 1 "register_operand" "0")
1019 (match_operand:VI_HW 2 "register_operand" "v")
1020 (match_operand:VI_HW 3 "register_operand" "v")
1021 (match_operand:QI 4 "const_int_operand" "C")]
1022 UNSPEC_VEC_RL_MASK))]
1023 "TARGET_VX"
1024 "verim<bhfgq>\t%v0,%v2,%v3,%b4"
1025 [(set_attr "op_type" "VRI")])
1026
1027
1028 ; Vector shift left
1029
1030 (define_insn "vec_sll<VI_HW:mode><VI_HW_QHS:mode>"
1031 [(set (match_operand:VI_HW 0 "register_operand" "=v")
1032 (unspec:VI_HW [(match_operand:VI_HW 1 "register_operand" "v")
1033 (match_operand:VI_HW_QHS 2 "register_operand" "v")]
1034 UNSPEC_VEC_SLL))]
1035 "TARGET_VX"
1036 "vsl\t%v0,%v1,%v2"
1037 [(set_attr "op_type" "VRR")])
1038
1039
1040 ; Vector shift left by byte
1041
1042 ; Pattern definition in vector.md, see vec_vslb
1043 (define_expand "vec_slb<mode>"
1044 [(set (match_operand:V_HW 0 "register_operand" "")
1045 (unspec:V_HW [(match_operand:V_HW 1 "register_operand" "")
1046 (match_operand:<TOINTVEC> 2 "register_operand" "")]
1047 UNSPEC_VEC_SLB))]
1048 "TARGET_VX"
1049 {
1050 PUT_MODE (operands[2], V16QImode);
1051 })
1052
1053 ; Vector shift left double by byte
1054
1055 (define_insn "vec_sld<mode>"
1056 [(set (match_operand:V_HW 0 "register_operand" "=v")
1057 (unspec:V_HW [(match_operand:V_HW 1 "register_operand" "v")
1058 (match_operand:V_HW 2 "register_operand" "v")
1059 (match_operand:QI 3 "const_int_operand" "C")]
1060 UNSPEC_VEC_SLDBYTE))]
1061 "TARGET_VX"
1062 "vsldb\t%v0,%v1,%v2,%b3"
1063 [(set_attr "op_type" "VRI")])
1064
1065 (define_expand "vec_sldw<mode>"
1066 [(set (match_operand:V_HW 0 "register_operand" "")
1067 (unspec:V_HW [(match_operand:V_HW 1 "register_operand" "")
1068 (match_operand:V_HW 2 "register_operand" "")
1069 (match_operand:QI 3 "const_int_operand" "")]
1070 UNSPEC_VEC_SLDBYTE))]
1071 "TARGET_VX"
1072 {
1073 operands[3] = GEN_INT (INTVAL (operands[3]) << 2);
1074 })
1075
1076 ; Vector shift left double by bit
1077
1078 (define_insn "vec_sldb<mode>"
1079 [(set (match_operand:V_HW 0 "register_operand" "=v")
1080 (unspec:V_HW [(match_operand:V_HW 1 "register_operand" "v")
1081 (match_operand:V_HW 2 "register_operand" "v")
1082 (match_operand:QI 3 "const_int_operand" "C")]
1083 UNSPEC_VEC_SLDBIT))]
1084 "TARGET_VXE2"
1085 "vsld\t%v0,%v1,%v2,%b3"
1086 [(set_attr "op_type" "VRI")])
1087
1088 ; Vector shift right double by bit
1089
1090 (define_insn "vec_srdb<mode>"
1091 [(set (match_operand:V_HW 0 "register_operand" "=v")
1092 (unspec:V_HW [(match_operand:V_HW 1 "register_operand" "v")
1093 (match_operand:V_HW 2 "register_operand" "v")
1094 (match_operand:QI 3 "const_int_operand" "C")]
1095 UNSPEC_VEC_SRDBIT))]
1096 "TARGET_VXE2"
1097 "vsrd\t%v0,%v1,%v2,%b3"
1098 [(set_attr "op_type" "VRI")])
1099
1100 ; Vector shift right arithmetic
1101
1102 (define_insn "vec_sral<VI_HW:mode><VI_HW_QHS:mode>"
1103 [(set (match_operand:VI_HW 0 "register_operand" "=v")
1104 (unspec:VI_HW [(match_operand:VI_HW 1 "register_operand" "v")
1105 (match_operand:VI_HW_QHS 2 "register_operand" "v")]
1106 UNSPEC_VEC_SRAL))]
1107 "TARGET_VX"
1108 "vsra\t%v0,%v1,%v2"
1109 [(set_attr "op_type" "VRR")])
1110
1111
1112 ; Vector shift right arithmetic by byte
1113
1114 (define_insn "vec_srab<mode>"
1115 [(set (match_operand:V_HW 0 "register_operand" "=v")
1116 (unspec:V_HW [(match_operand:V_HW 1 "register_operand" "v")
1117 (match_operand:<TOINTVEC> 2 "register_operand" "v")]
1118 UNSPEC_VEC_SRAB))]
1119 "TARGET_VX"
1120 "vsrab\t%v0,%v1,%v2"
1121 [(set_attr "op_type" "VRR")])
1122
1123
1124 ; Vector shift right logical
1125
1126 (define_insn "vec_srl<VI_HW:mode><VI_HW_QHS:mode>"
1127 [(set (match_operand:VI_HW 0 "register_operand" "=v")
1128 (unspec:VI_HW [(match_operand:VI_HW 1 "register_operand" "v")
1129 (match_operand:VI_HW_QHS 2 "register_operand" "v")]
1130 UNSPEC_VEC_SRL))]
1131 "TARGET_VX"
1132 "vsrl\t%v0,%v1,%v2"
1133 [(set_attr "op_type" "VRR")])
1134
1135
1136 ; Vector shift right logical by byte
1137
1138 ; Pattern definition in vector.md, see vec_vsrb
1139 (define_expand "vec_srb<mode>"
1140 [(set (match_operand:V_HW 0 "register_operand" "")
1141 (unspec:V_HW [(match_operand:V_HW 1 "register_operand" "")
1142 (match_operand:<TOINTVEC> 2 "register_operand" "")]
1143 UNSPEC_VEC_SRLB))]
1144 "TARGET_VX"
1145 {
1146 PUT_MODE (operands[2], V16QImode);
1147 })
1148
1149 ; Vector subtract
1150
1151 ; Vector subtract compute borrow indication
1152
1153 ; vscbib, vscbih, vscbif, vscbig, vscbiq
1154 (define_insn "vscbi<bhfgq>_<mode>"
1155 [(set (match_operand:VIT_HW 0 "register_operand" "=v")
1156 (unspec:VIT_HW [(match_operand:VIT_HW 1 "register_operand" "v")
1157 (match_operand:VIT_HW 2 "register_operand" "v")]
1158 UNSPEC_VEC_SUBC))]
1159 "TARGET_VX"
1160 "vscbi<bhfgq>\t%v0,%v1,%v2"
1161 [(set_attr "op_type" "VRR")])
1162
1163 ; Vector subtract with borrow indication
1164
1165 (define_insn "vsbiq"
1166 [(set (match_operand:TI 0 "register_operand" "=v")
1167 (unspec:TI [(match_operand:TI 1 "register_operand" "v")
1168 (match_operand:TI 2 "register_operand" "v")
1169 (match_operand:TI 3 "register_operand" "v")]
1170 UNSPEC_VEC_SUBE_U128))]
1171 "TARGET_VX"
1172 "vsbiq\t%v0,%v1,%v2,%v3"
1173 [(set_attr "op_type" "VRR")])
1174
1175
1176 ; Vector subtract with borrow compute and borrow indication
1177
1178 (define_insn "vsbcbiq"
1179 [(set (match_operand:TI 0 "register_operand" "=v")
1180 (unspec:TI [(match_operand:TI 1 "register_operand" "v")
1181 (match_operand:TI 2 "register_operand" "v")
1182 (match_operand:TI 3 "register_operand" "v")]
1183 UNSPEC_VEC_SUBEC_U128))]
1184 "TARGET_VX"
1185 "vsbcbiq\t%v0,%v1,%v2,%v3"
1186 [(set_attr "op_type" "VRR")])
1187
1188
1189 ; Vector sum across
1190
1191 ; Sum across DImode parts of the 1st operand and add the rightmost
1192 ; element of 2nd operand
1193 ; vsumgh, vsumgf
1194 (define_expand "vec_sum2<mode>"
1195 [(set (match_operand:V2DI 0 "register_operand" "")
1196 (unspec:V2DI [(match_operand:VI_HW_HS 1 "register_operand" "")
1197 (match_operand:VI_HW_HS 2 "register_operand" "")]
1198 UNSPEC_VEC_VSUMG))]
1199 "TARGET_VX")
1200
1201 ; vsumqh, vsumqf
1202 (define_insn "vec_sum_u128<mode>"
1203 [(set (match_operand:V2DI 0 "register_operand" "=v")
1204 (unspec:V2DI [(match_operand:VI_HW_SD 1 "register_operand" "v")
1205 (match_operand:VI_HW_SD 2 "register_operand" "v")]
1206 UNSPEC_VEC_VSUMQ))]
1207 "TARGET_VX"
1208 "vsumq<bhfgq>\t%v0,%v1,%v2"
1209 [(set_attr "op_type" "VRR")])
1210
1211 ; vsumb, vsumh
1212 (define_expand "vec_sum4<mode>"
1213 [(set (match_operand:V4SI 0 "register_operand" "")
1214 (unspec:V4SI [(match_operand:VI_HW_QH 1 "register_operand" "")
1215 (match_operand:VI_HW_QH 2 "register_operand" "")]
1216 UNSPEC_VEC_VSUM))]
1217 "TARGET_VX")
1218
1219
1220 ; Vector test under mask
1221
1222 (define_expand "vec_test_mask_int<mode>"
1223 [(set (reg:CCRAW CC_REGNUM)
1224 (unspec:CCRAW [(match_operand:V_HW 1 "register_operand" "")
1225 (match_operand:<TOINTVEC> 2 "register_operand" "")]
1226 UNSPEC_VEC_TEST_MASK))
1227 (set (match_operand:SI 0 "register_operand" "")
1228 (unspec:SI [(reg:CCRAW CC_REGNUM)] UNSPEC_CC_TO_INT))]
1229 "TARGET_VX")
1230
1231 (define_insn "*vec_test_mask<mode>"
1232 [(set (reg:CCRAW CC_REGNUM)
1233 (unspec:CCRAW [(match_operand:V_HW 0 "register_operand" "v")
1234 (match_operand:<TOINTVEC> 1 "register_operand" "v")]
1235 UNSPEC_VEC_TEST_MASK))]
1236 "TARGET_VX"
1237 "vtm\t%v0,%v1"
1238 [(set_attr "op_type" "VRR")])
1239
1240
1241 ; Vector multiply sum logical
1242
1243 (define_insn "vec_msumv2di"
1244 [(set (match_operand:V16QI 0 "register_operand" "=v")
1245 (unspec:V16QI [(match_operand:V2DI 1 "register_operand" "v")
1246 (match_operand:V2DI 2 "register_operand" "v")
1247 (match_operand:V16QI 3 "register_operand" "v")
1248 (match_operand:QI 4 "const_mask_operand" "C")]
1249 UNSPEC_VEC_MSUM))]
1250 "TARGET_VXE"
1251 "vmslg\t%v0,%v1,%v2,%v3,%4"
1252 [(set_attr "op_type" "VRR")])
1253
1254 (define_insn "vmslg"
1255 [(set (match_operand:TI 0 "register_operand" "=v")
1256 (unspec:TI [(match_operand:V2DI 1 "register_operand" "v")
1257 (match_operand:V2DI 2 "register_operand" "v")
1258 (match_operand:TI 3 "register_operand" "v")
1259 (match_operand:QI 4 "const_mask_operand" "C")]
1260 UNSPEC_VEC_MSUM))]
1261 "TARGET_VXE"
1262 "vmslg\t%v0,%v1,%v2,%v3,%4"
1263 [(set_attr "op_type" "VRR")])
1264
1265
1266 ; Vector find any element equal
1267
1268 ; vfaeb, vfaeh, vfaef
1269 ; vfaezb, vfaezh, vfaezf
1270 (define_insn "vfae<mode>"
1271 [(set (match_operand:VI_HW_QHS 0 "register_operand" "=v")
1272 (unspec:VI_HW_QHS [(match_operand:VI_HW_QHS 1 "register_operand" "v")
1273 (match_operand:VI_HW_QHS 2 "register_operand" "v")
1274 (match_operand:QI 3 "const_mask_operand" "C")]
1275 UNSPEC_VEC_VFAE))]
1276 "TARGET_VX"
1277 {
1278 unsigned HOST_WIDE_INT flags = UINTVAL (operands[3]);
1279
1280 if (flags & VSTRING_FLAG_ZS)
1281 {
1282 flags &= ~VSTRING_FLAG_ZS;
1283 operands[3] = GEN_INT (flags);
1284 return "vfaez<bhfgq>\t%v0,%v1,%v2,%b3";
1285 }
1286 return "vfae<bhfgq>\t%v0,%v1,%v2,%b3";
1287 }
1288 [(set_attr "op_type" "VRR")])
1289
1290 ; vfaebs, vfaehs, vfaefs
1291 ; vfaezbs, vfaezhs, vfaezfs
1292 (define_insn "*vfaes<mode>"
1293 [(set (match_operand:VI_HW_QHS 0 "register_operand" "=v")
1294 (unspec:VI_HW_QHS [(match_operand:VI_HW_QHS 1 "register_operand" "v")
1295 (match_operand:VI_HW_QHS 2 "register_operand" "v")
1296 (match_operand:QI 3 "const_mask_operand" "C")]
1297 UNSPEC_VEC_VFAE))
1298 (set (reg:CCRAW CC_REGNUM)
1299 (unspec:CCRAW [(match_dup 1)
1300 (match_dup 2)
1301 (match_dup 3)]
1302 UNSPEC_VEC_VFAECC))]
1303 "TARGET_VX"
1304 {
1305 unsigned HOST_WIDE_INT flags = UINTVAL (operands[3]);
1306
1307 if (flags & VSTRING_FLAG_ZS)
1308 {
1309 flags &= ~VSTRING_FLAG_ZS;
1310 operands[3] = GEN_INT (flags);
1311 return "vfaez<bhfgq>s\t%v0,%v1,%v2,%b3";
1312 }
1313 return "vfae<bhfgq>s\t%v0,%v1,%v2,%b3";
1314 }
1315 [(set_attr "op_type" "VRR")])
1316
1317 (define_expand "vfaez<mode>"
1318 [(set (match_operand:VI_HW_QHS 0 "register_operand" "=v")
1319 (unspec:VI_HW_QHS [(match_operand:VI_HW_QHS 1 "register_operand" "")
1320 (match_operand:VI_HW_QHS 2 "register_operand" "")
1321 (match_operand:QI 3 "const_mask_operand" "")]
1322 UNSPEC_VEC_VFAE))]
1323 "TARGET_VX"
1324 {
1325 operands[3] = GEN_INT (INTVAL (operands[3]) | VSTRING_FLAG_ZS);
1326 })
1327
1328 (define_expand "vfaes<mode>"
1329 [(parallel
1330 [(set (match_operand:VI_HW_QHS 0 "register_operand" "")
1331 (unspec:VI_HW_QHS [(match_operand:VI_HW_QHS 1 "register_operand" "")
1332 (match_operand:VI_HW_QHS 2 "register_operand" "")
1333 (match_operand:QI 3 "const_mask_operand" "")]
1334 UNSPEC_VEC_VFAE))
1335 (set (reg:CCRAW CC_REGNUM)
1336 (unspec:CCRAW [(match_dup 1)
1337 (match_dup 2)
1338 (match_dup 3)]
1339 UNSPEC_VEC_VFAECC))])
1340 (set (match_operand:SI 4 "memory_operand" "")
1341 (unspec:SI [(reg:CCRAW CC_REGNUM)] UNSPEC_CC_TO_INT))]
1342 "TARGET_VX"
1343 {
1344 operands[3] = GEN_INT (INTVAL (operands[3]) | VSTRING_FLAG_CS);
1345 })
1346
1347 (define_expand "vfaezs<mode>"
1348 [(parallel
1349 [(set (match_operand:VI_HW_QHS 0 "register_operand" "")
1350 (unspec:VI_HW_QHS [(match_operand:VI_HW_QHS 1 "register_operand" "")
1351 (match_operand:VI_HW_QHS 2 "register_operand" "")
1352 (match_operand:SI 3 "const_mask_operand" "")]
1353 UNSPEC_VEC_VFAE))
1354 (set (reg:CCRAW CC_REGNUM)
1355 (unspec:CCRAW [(match_dup 1)
1356 (match_dup 2)
1357 (match_dup 3)]
1358 UNSPEC_VEC_VFAECC))])
1359 (set (match_operand:SI 4 "memory_operand" "")
1360 (unspec:SI [(reg:CCRAW CC_REGNUM)] UNSPEC_CC_TO_INT))]
1361 "TARGET_VX"
1362 {
1363 operands[3] = GEN_INT (INTVAL (operands[3]) | VSTRING_FLAG_CS | VSTRING_FLAG_ZS);
1364 })
1365
1366
1367 ; Vector find element equal
1368
1369 ; vfeeb, vfeeh, vfeef
1370 (define_insn "vfee<mode>"
1371 [(set (match_operand:VI_HW_QHS 0 "register_operand" "=v")
1372 (unspec:VI_HW_QHS [(match_operand:VI_HW_QHS 1 "register_operand" "v")
1373 (match_operand:VI_HW_QHS 2 "register_operand" "v")
1374 (const_int 0)]
1375 UNSPEC_VEC_VFEE))]
1376 "TARGET_VX"
1377 "vfee<bhfgq>\t%v0,%v1,%v2,0"
1378 [(set_attr "op_type" "VRR")])
1379
1380 ; vfeezb, vfeezh, vfeezf
1381 (define_insn "vfeez<mode>"
1382 [(set (match_operand:VI_HW_QHS 0 "register_operand" "=v")
1383 (unspec:VI_HW_QHS [(match_operand:VI_HW_QHS 1 "register_operand" "v")
1384 (match_operand:VI_HW_QHS 2 "register_operand" "v")
1385 (const_int VSTRING_FLAG_ZS)]
1386 UNSPEC_VEC_VFEE))]
1387 "TARGET_VX"
1388 "vfeez<bhfgq>s\t%v0,%v1,%v2,2"
1389 [(set_attr "op_type" "VRR")])
1390
1391 (define_expand "vfees<mode>"
1392 [(parallel
1393 [(set (match_operand:VI_HW_QHS 0 "register_operand" "")
1394 (unspec:VI_HW_QHS [(match_operand:VI_HW_QHS 1 "register_operand" "")
1395 (match_operand:VI_HW_QHS 2 "register_operand" "")
1396 (const_int VSTRING_FLAG_CS)]
1397 UNSPEC_VEC_VFEE))
1398 (set (reg:CCRAW CC_REGNUM)
1399 (unspec:CCRAW [(match_dup 1)
1400 (match_dup 2)
1401 (const_int VSTRING_FLAG_CS)]
1402 UNSPEC_VEC_VFEECC))])
1403 (set (match_operand:SI 3 "memory_operand" "")
1404 (unspec:SI [(reg:CCRAW CC_REGNUM)] UNSPEC_CC_TO_INT))]
1405 "TARGET_VX")
1406
1407 (define_expand "vfeezs<mode>"
1408 [(parallel
1409 [(set (match_operand:VI_HW_QHS 0 "register_operand" "")
1410 (unspec:VI_HW_QHS [(match_operand:VI_HW_QHS 1 "register_operand" "")
1411 (match_operand:VI_HW_QHS 2 "register_operand" "")
1412 (match_dup 4)]
1413 UNSPEC_VEC_VFEE))
1414 (set (reg:CCRAW CC_REGNUM)
1415 (unspec:CCRAW [(match_dup 1)
1416 (match_dup 2)
1417 (match_dup 4)]
1418 UNSPEC_VEC_VFEECC))])
1419 (set (match_operand:SI 3 "memory_operand" "")
1420 (unspec:SI [(reg:CCRAW CC_REGNUM)] UNSPEC_CC_TO_INT))]
1421 "TARGET_VX"
1422 {
1423 operands[4] = GEN_INT (VSTRING_FLAG_ZS | VSTRING_FLAG_CS);
1424 })
1425
1426 ; Vector find element not equal
1427
1428 ; vfeneb, vfeneh, vfenef
1429 (define_insn "vfene<mode>"
1430 [(set (match_operand:VI_HW_QHS 0 "register_operand" "=v")
1431 (unspec:VI_HW_QHS [(match_operand:VI_HW_QHS 1 "register_operand" "v")
1432 (match_operand:VI_HW_QHS 2 "register_operand" "v")
1433 (const_int 0)]
1434 UNSPEC_VEC_VFENE))]
1435 "TARGET_VX"
1436 "vfene<bhfgq>\t%v0,%v1,%v2,0"
1437 [(set_attr "op_type" "VRR")])
1438
1439 ; vec_vfenes can be found in vector.md since it is used for strlen
1440
1441 ; vfenezb, vfenezh, vfenezf
1442 (define_insn "vfenez<mode>"
1443 [(set (match_operand:VI_HW_QHS 0 "register_operand" "=v")
1444 (unspec:VI_HW_QHS [(match_operand:VI_HW_QHS 1 "register_operand" "v")
1445 (match_operand:VI_HW_QHS 2 "register_operand" "v")
1446 (const_int VSTRING_FLAG_ZS)]
1447 UNSPEC_VEC_VFENE))]
1448 "TARGET_VX"
1449 "vfenez<bhfgq>\t%v0,%v1,%v2"
1450 [(set_attr "op_type" "VRR")])
1451
1452 (define_expand "vfenes<mode>"
1453 [(parallel
1454 [(set (match_operand:VI_HW_QHS 0 "register_operand" "")
1455 (unspec:VI_HW_QHS [(match_operand:VI_HW_QHS 1 "register_operand" "")
1456 (match_operand:VI_HW_QHS 2 "register_operand" "")
1457 (const_int VSTRING_FLAG_CS)]
1458 UNSPEC_VEC_VFENE))
1459 (set (reg:CCRAW CC_REGNUM)
1460 (unspec:CCRAW [(match_dup 1)
1461 (match_dup 2)
1462 (const_int VSTRING_FLAG_CS)]
1463 UNSPEC_VEC_VFENECC))])
1464 (set (match_operand:SI 3 "memory_operand" "")
1465 (unspec:SI [(reg:CCRAW CC_REGNUM)] UNSPEC_CC_TO_INT))]
1466 "TARGET_VX")
1467
1468 (define_expand "vfenezs<mode>"
1469 [(parallel
1470 [(set (match_operand:VI_HW_QHS 0 "register_operand" "")
1471 (unspec:VI_HW_QHS [(match_operand:VI_HW_QHS 1 "register_operand" "")
1472 (match_operand:VI_HW_QHS 2 "register_operand" "")
1473 (match_dup 4)]
1474 UNSPEC_VEC_VFENE))
1475 (set (reg:CCRAW CC_REGNUM)
1476 (unspec:CCRAW [(match_dup 1)
1477 (match_dup 2)
1478 (match_dup 4)]
1479 UNSPEC_VEC_VFENECC))])
1480 (set (match_operand:SI 3 "memory_operand" "")
1481 (unspec:SI [(reg:CCRAW CC_REGNUM)] UNSPEC_CC_TO_INT))]
1482 "TARGET_VX"
1483 {
1484 operands[4] = GEN_INT (VSTRING_FLAG_ZS | VSTRING_FLAG_CS);
1485 })
1486
1487 ; Vector isolate string
1488
1489 ; vistrb, vistrh, vistrf
1490 (define_insn "vistr<mode>"
1491 [(set (match_operand:VI_HW_QHS 0 "register_operand" "=v")
1492 (unspec:VI_HW_QHS [(match_operand:VI_HW_QHS 1 "register_operand" "v")]
1493 UNSPEC_VEC_VISTR))]
1494 "TARGET_VX"
1495 "vistr<bhfgq>\t%v0,%v1"
1496 [(set_attr "op_type" "VRR")])
1497
1498 ; vistrbs, vistrhs, vistrfs
1499 (define_insn "*vistrs<mode>"
1500 [(set (match_operand:VI_HW_QHS 0 "register_operand" "=v")
1501 (unspec:VI_HW_QHS [(match_operand:VI_HW_QHS 1 "register_operand" "v")]
1502 UNSPEC_VEC_VISTR))
1503 (set (reg:CCRAW CC_REGNUM)
1504 (unspec:CCRAW [(match_dup 1)] UNSPEC_VEC_VISTRCC))]
1505 "TARGET_VX"
1506 "vistr<bhfgq>s\t%v0,%v1"
1507 [(set_attr "op_type" "VRR")])
1508
1509 (define_expand "vistrs<mode>"
1510 [(parallel
1511 [(set (match_operand:VI_HW_QHS 0 "register_operand" "")
1512 (unspec:VI_HW_QHS [(match_operand:VI_HW_QHS 1 "register_operand" "")]
1513 UNSPEC_VEC_VISTR))
1514 (set (reg:CCRAW CC_REGNUM)
1515 (unspec:CCRAW [(match_dup 1)]
1516 UNSPEC_VEC_VISTRCC))])
1517 (set (match_operand:SI 2 "memory_operand" "")
1518 (unspec:SI [(reg:CCRAW CC_REGNUM)] UNSPEC_CC_TO_INT))]
1519 "TARGET_VX")
1520
1521
1522 ; Vector compare range
1523
1524 ; vstrcb, vstrch, vstrcf
1525 ; vstrczb, vstrczh, vstrczf
1526 (define_insn "vstrc<mode>"
1527 [(set (match_operand:VI_HW_QHS 0 "register_operand" "=v")
1528 (unspec:VI_HW_QHS [(match_operand:VI_HW_QHS 1 "register_operand" "v")
1529 (match_operand:VI_HW_QHS 2 "register_operand" "v")
1530 (match_operand:VI_HW_QHS 3 "register_operand" "v")
1531 (match_operand:QI 4 "const_mask_operand" "C")]
1532 UNSPEC_VEC_VSTRC))]
1533 "TARGET_VX"
1534 {
1535 unsigned HOST_WIDE_INT flags = UINTVAL (operands[4]);
1536
1537 if (flags & VSTRING_FLAG_ZS)
1538 {
1539 flags &= ~VSTRING_FLAG_ZS;
1540 operands[4] = GEN_INT (flags);
1541 return "vstrcz<bhfgq>\t%v0,%v1,%v2,%v3,%b4";
1542 }
1543 return "vstrc<bhfgq>\t%v0,%v1,%v2,%v3,%b4";
1544 }
1545 [(set_attr "op_type" "VRR")])
1546
1547 ; vstrcbs, vstrchs, vstrcfs
1548 ; vstrczbs, vstrczhs, vstrczfs
1549 (define_insn "*vstrcs<mode>"
1550 [(set (match_operand:VI_HW_QHS 0 "register_operand" "=v")
1551 (unspec:VI_HW_QHS [(match_operand:VI_HW_QHS 1 "register_operand" "v")
1552 (match_operand:VI_HW_QHS 2 "register_operand" "v")
1553 (match_operand:VI_HW_QHS 3 "register_operand" "v")
1554 (match_operand:QI 4 "const_mask_operand" "C")]
1555 UNSPEC_VEC_VSTRC))
1556 (set (reg:CCRAW CC_REGNUM)
1557 (unspec:CCRAW [(match_dup 1)
1558 (match_dup 2)
1559 (match_dup 3)
1560 (match_dup 4)]
1561 UNSPEC_VEC_VSTRCCC))]
1562 "TARGET_VX"
1563 {
1564 unsigned HOST_WIDE_INT flags = UINTVAL (operands[4]);
1565
1566 if (flags & VSTRING_FLAG_ZS)
1567 {
1568 flags &= ~VSTRING_FLAG_ZS;
1569 operands[4] = GEN_INT (flags);
1570 return "vstrcz<bhfgq>s\t%v0,%v1,%v2,%v3,%b4";
1571 }
1572 return "vstrc<bhfgq>s\t%v0,%v1,%v2,%v3,%b4";
1573 }
1574 [(set_attr "op_type" "VRR")])
1575
1576 (define_expand "vstrcz<mode>"
1577 [(set (match_operand:VI_HW_QHS 0 "register_operand" "")
1578 (unspec:VI_HW_QHS [(match_operand:VI_HW_QHS 1 "register_operand" "")
1579 (match_operand:VI_HW_QHS 2 "register_operand" "")
1580 (match_operand:VI_HW_QHS 3 "register_operand" "")
1581 (match_operand:QI 4 "const_mask_operand" "")]
1582 UNSPEC_VEC_VSTRC))]
1583 "TARGET_VX"
1584 {
1585 operands[4] = GEN_INT (INTVAL (operands[4]) | VSTRING_FLAG_ZS);
1586 })
1587
1588 (define_expand "vstrcs<mode>"
1589 [(parallel
1590 [(set (match_operand:VI_HW_QHS 0 "register_operand" "")
1591 (unspec:VI_HW_QHS [(match_operand:VI_HW_QHS 1 "register_operand" "")
1592 (match_operand:VI_HW_QHS 2 "register_operand" "")
1593 (match_operand:VI_HW_QHS 3 "register_operand" "")
1594 (match_operand:QI 4 "const_mask_operand" "")]
1595 UNSPEC_VEC_VSTRC))
1596 (set (reg:CCRAW CC_REGNUM)
1597 (unspec:CCRAW [(match_dup 1)
1598 (match_dup 2)
1599 (match_dup 3)
1600 (match_dup 4)]
1601 UNSPEC_VEC_VSTRCCC))])
1602 (set (match_operand:SI 5 "memory_operand" "")
1603 (unspec:SI [(reg:CCRAW CC_REGNUM)] UNSPEC_CC_TO_INT))]
1604 "TARGET_VX"
1605 {
1606 operands[4] = GEN_INT (INTVAL (operands[4]) | VSTRING_FLAG_CS);
1607 })
1608
1609 (define_expand "vstrczs<mode>"
1610 [(parallel
1611 [(set (match_operand:VI_HW_QHS 0 "register_operand" "")
1612 (unspec:VI_HW_QHS [(match_operand:VI_HW_QHS 1 "register_operand" "")
1613 (match_operand:VI_HW_QHS 2 "register_operand" "")
1614 (match_operand:VI_HW_QHS 3 "register_operand" "")
1615 (match_operand:QI 4 "const_mask_operand" "")]
1616 UNSPEC_VEC_VSTRC))
1617 (set (reg:CCRAW CC_REGNUM)
1618 (unspec:CCRAW [(match_dup 1)
1619 (match_dup 2)
1620 (match_dup 3)
1621 (match_dup 4)]
1622 UNSPEC_VEC_VSTRCCC))])
1623 (set (match_operand:SI 5 "memory_operand" "")
1624 (unspec:SI [(reg:CCRAW CC_REGNUM)] UNSPEC_CC_TO_INT))]
1625 "TARGET_VX"
1626 {
1627 operands[4] = GEN_INT (INTVAL (operands[4]) | VSTRING_FLAG_CS | VSTRING_FLAG_ZS);
1628 })
1629
1630 ; Vector string search
1631
1632 (define_expand "vstrs<mode>"
1633 [(parallel
1634 [(set (match_operand:V16QI 0 "register_operand" "")
1635 (unspec:V16QI [(match_operand:VI_HW_QHS 1 "register_operand" "")
1636 (match_operand:VI_HW_QHS 2 "register_operand" "")
1637 (match_operand:V16QI 3 "register_operand" "")
1638 (const_int 0)]
1639 UNSPEC_VEC_VSTRS))
1640 (set (reg:CCRAW CC_REGNUM)
1641 (unspec:CCRAW [(match_dup 1)
1642 (match_dup 2)
1643 (match_dup 3)
1644 (const_int 0)]
1645 UNSPEC_VEC_VSTRSCC))])
1646 (set (match_operand:SI 4 "memory_operand" "")
1647 (unspec:SI [(reg:CCRAW CC_REGNUM)] UNSPEC_CC_TO_INT))]
1648 "TARGET_VXE2")
1649
1650 (define_expand "vstrsz<mode>"
1651 [(parallel
1652 [(set (match_operand:V16QI 0 "register_operand" "")
1653 (unspec:V16QI [(match_operand:VI_HW_QHS 1 "register_operand" "")
1654 (match_operand:VI_HW_QHS 2 "register_operand" "")
1655 (match_operand:V16QI 3 "register_operand" "")
1656 (const_int VSTRING_FLAG_ZS)]
1657 UNSPEC_VEC_VSTRS))
1658 (set (reg:CCRAW CC_REGNUM)
1659 (unspec:CCRAW [(match_dup 1)
1660 (match_dup 2)
1661 (match_dup 3)
1662 (const_int VSTRING_FLAG_ZS)]
1663 UNSPEC_VEC_VSTRSCC))])
1664 (set (match_operand:SI 4 "memory_operand" "")
1665 (unspec:SI [(reg:CCRAW CC_REGNUM)] UNSPEC_CC_TO_INT))]
1666 "TARGET_VXE2")
1667
1668 ; vstrsb, vstrsh, vstrsf
1669 ; vstrszb, vstrszh, vstrszf
1670 (define_insn "vec_vstrs<mode>"
1671 [(set (match_operand:V16QI 0 "register_operand" "=v")
1672 (unspec:V16QI [(match_operand:VI_HW_QHS 1 "register_operand" "v")
1673 (match_operand:VI_HW_QHS 2 "register_operand" "v")
1674 (match_operand:V16QI 3 "register_operand" "v")
1675 (match_operand:QI 4 "const_mask_operand" "C")]
1676 UNSPEC_VEC_VSTRS))
1677 (set (reg:CCRAW CC_REGNUM)
1678 (unspec:CCRAW [(match_dup 1)
1679 (match_dup 2)
1680 (match_dup 3)
1681 (match_dup 4)]
1682 UNSPEC_VEC_VSTRSCC))]
1683 "TARGET_VXE2"
1684 {
1685 unsigned HOST_WIDE_INT flags = UINTVAL (operands[4]);
1686
1687 gcc_assert (!(flags & ~VSTRING_FLAG_ZS));
1688
1689 if (flags == VSTRING_FLAG_ZS)
1690 return "vstrsz<bhfgq>\t%v0,%v1,%v2,%v3";
1691 return "vstrs<bhfgq>\t%v0,%v1,%v2,%v3";
1692 }
1693 [(set_attr "op_type" "VRR")])
1694
1695
1696 ; Vector convert int<->float
1697
1698 (define_insn "vcdgb"
1699 [(set (match_operand:V2DF 0 "register_operand" "=v")
1700 (unspec:V2DF [(match_operand:V2DI 1 "register_operand" "v")
1701 (match_operand:QI 2 "const_mask_operand" "C") ; inexact suppression
1702 (match_operand:QI 3 "const_mask_operand" "C")] ; rounding mode
1703 UNSPEC_VEC_VCDGB))]
1704 "TARGET_VX && UINTVAL (operands[3]) != 2 && UINTVAL (operands[3]) <= 7"
1705 "vcdgb\t%v0,%v1,%b2,%b3"
1706 [(set_attr "op_type" "VRR")])
1707
1708
1709 ; The result needs to be multiplied with 2**-op2
1710 (define_expand "vec_ctd_s64"
1711 [(set (match_operand:V2DF 0 "register_operand" "")
1712 (unspec:V2DF [(match_operand:V2DI 1 "register_operand" "")
1713 (const_int VEC_NOINEXACT)
1714 (const_int VEC_RND_CURRENT)]
1715 UNSPEC_VEC_VCDGB))
1716 (use (match_operand:QI 2 "const_int_operand" ""))
1717 (set (match_dup 0) (mult:V2DF (match_dup 0) (match_dup 3)))]
1718 "TARGET_VX"
1719 {
1720 REAL_VALUE_TYPE f;
1721 rtx c;
1722
1723 real_2expN (&f, -INTVAL (operands[2]), DFmode);
1724 c = const_double_from_real_value (f, DFmode);
1725
1726 operands[3] = gen_const_vec_duplicate (V2DFmode, c);
1727 operands[3] = force_reg (V2DFmode, operands[3]);
1728 })
1729
1730 (define_insn "vcdlgb"
1731 [(set (match_operand:V2DF 0 "register_operand" "=v")
1732 (unspec:V2DF [(match_operand:V2DI 1 "register_operand" "v")
1733 (match_operand:QI 2 "const_mask_operand" "C") ; inexact suppression
1734 (match_operand:QI 3 "const_mask_operand" "C")] ; rounding mode
1735 UNSPEC_VEC_VCDLGB))]
1736 "TARGET_VX && UINTVAL (operands[3]) != 2 && UINTVAL (operands[3]) <= 7"
1737 "vcdlgb\t%v0,%v1,%b2,%b3"
1738 [(set_attr "op_type" "VRR")])
1739
1740 ; The result needs to be multiplied with 2**-op2
1741 (define_expand "vec_ctd_u64"
1742 [(set (match_operand:V2DF 0 "register_operand" "")
1743 (unspec:V2DF [(match_operand:V2DI 1 "register_operand" "")
1744 (const_int VEC_NOINEXACT)
1745 (const_int VEC_RND_CURRENT)]
1746 UNSPEC_VEC_VCDLGB))
1747 (use (match_operand:QI 2 "const_int_operand" ""))
1748 (set (match_dup 0) (mult:V2DF (match_dup 0) (match_dup 3)))]
1749 "TARGET_VX"
1750 {
1751 REAL_VALUE_TYPE f;
1752 rtx c;
1753
1754 real_2expN (&f, -INTVAL (operands[2]), DFmode);
1755 c = const_double_from_real_value (f, DFmode);
1756
1757 operands[3] = gen_const_vec_duplicate (V2DFmode, c);
1758 operands[3] = force_reg (V2DFmode, operands[3]);
1759 })
1760
1761 (define_insn "vcgdb"
1762 [(set (match_operand:V2DI 0 "register_operand" "=v")
1763 (unspec:V2DI [(match_operand:V2DF 1 "register_operand" "v")
1764 (match_operand:QI 2 "const_mask_operand" "C")
1765 (match_operand:QI 3 "const_mask_operand" "C")]
1766 UNSPEC_VEC_VCGDB))]
1767 "TARGET_VX && UINTVAL (operands[3]) != 2 && UINTVAL (operands[3]) <= 7"
1768 "vcgdb\t%v0,%v1,%b2,%b3"
1769 [(set_attr "op_type" "VRR")])
1770
1771 ; The input needs to be multiplied with 2**op2
1772 (define_expand "vec_ctsl"
1773 [(use (match_operand:QI 2 "const_int_operand" ""))
1774 (set (match_dup 4) (mult:V2DF (match_operand:V2DF 1 "register_operand" "")
1775 (match_dup 3)))
1776 (set (match_operand:V2DI 0 "register_operand" "")
1777 (unspec:V2DI [(match_dup 4)
1778 (const_int VEC_NOINEXACT)
1779 (const_int VEC_RND_CURRENT)]
1780 UNSPEC_VEC_VCGDB))]
1781 "TARGET_VX"
1782 {
1783 REAL_VALUE_TYPE f;
1784 rtx c;
1785
1786 real_2expN (&f, INTVAL (operands[2]), DFmode);
1787 c = const_double_from_real_value (f, DFmode);
1788
1789 operands[3] = gen_const_vec_duplicate (V2DFmode, c);
1790 operands[3] = force_reg (V2DFmode, operands[3]);
1791 operands[4] = gen_reg_rtx (V2DFmode);
1792 })
1793
1794 (define_insn "vclgdb"
1795 [(set (match_operand:V2DI 0 "register_operand" "=v")
1796 (unspec:V2DI [(match_operand:V2DF 1 "register_operand" "v")
1797 (match_operand:QI 2 "const_mask_operand" "C")
1798 (match_operand:QI 3 "const_mask_operand" "C")]
1799 UNSPEC_VEC_VCLGDB))]
1800 "TARGET_VX && UINTVAL (operands[3]) != 2 && UINTVAL (operands[3]) <= 7"
1801 "vclgdb\t%v0,%v1,%b2,%b3"
1802 [(set_attr "op_type" "VRR")])
1803
1804 ; The input needs to be multiplied with 2**op2
1805 (define_expand "vec_ctul"
1806 [(use (match_operand:QI 2 "const_int_operand" ""))
1807 (set (match_dup 4) (mult:V2DF (match_operand:V2DF 1 "register_operand" "")
1808 (match_dup 3)))
1809 (set (match_operand:V2DI 0 "register_operand" "")
1810 (unspec:V2DI [(match_dup 4)
1811 (const_int VEC_NOINEXACT)
1812 (const_int VEC_RND_CURRENT)]
1813 UNSPEC_VEC_VCLGDB))]
1814 "TARGET_VX"
1815 {
1816 REAL_VALUE_TYPE f;
1817 rtx c;
1818
1819 real_2expN (&f, INTVAL (operands[2]), DFmode);
1820 c = const_double_from_real_value (f, DFmode);
1821
1822 operands[3] = gen_const_vec_duplicate (V2DFmode, c);
1823 operands[3] = force_reg (V2DFmode, operands[3]);
1824 operands[4] = gen_reg_rtx (V2DFmode);
1825 })
1826
1827 ; Vector load fp integer - IEEE inexact exception is suppressed
1828 ; vfisb, vfidb, wfisb, wfidb, wfixb
1829 (define_insn "vec_fpint<mode>"
1830 [(set (match_operand:VFT 0 "register_operand" "=v")
1831 (unspec:VFT [(match_operand:VFT 1 "register_operand" "v")
1832 (match_operand:QI 2 "const_mask_operand" "C") ; inexact suppression control
1833 (match_operand:QI 3 "const_mask_operand" "C")] ; rounding mode
1834 UNSPEC_VEC_VFI))]
1835 "TARGET_VX"
1836 "<vw>fi<sdx>b\t%v0,%v1,%b2,%b3"
1837 [(set_attr "op_type" "VRR")])
1838
1839
1840 ; Vector load lengthened - V4SF -> V2DF
1841
1842 (define_insn "vflls"
1843 [(set (match_operand:V2DF 0 "register_operand" "=v")
1844 (unspec:V2DF [(match_operand:V4SF 1 "register_operand" "v")]
1845 UNSPEC_VEC_VFLL))]
1846 "TARGET_VX"
1847 "vldeb\t%v0,%v1"
1848 [(set_attr "op_type" "VRR")])
1849
1850 (define_expand "vec_ld2f"
1851 [; Initialize a vector to all zeroes. FIXME: This should not be
1852 ; necessary since all elements of the vector will be set anyway.
1853 ; This is just to make it explicit to the data flow framework.
1854 (set (match_dup 2) (match_dup 3))
1855 (set (match_dup 2) (unspec:V4SF [(match_operand:SF 1 "memory_operand" "")
1856 (const_int 0)
1857 (match_dup 2)]
1858 UNSPEC_VEC_SET))
1859 (set (match_dup 2) (unspec:V4SF [(match_dup 4)
1860 (const_int 2)
1861 (match_dup 2)]
1862 UNSPEC_VEC_SET))
1863 (set (match_operand:V2DF 0 "register_operand" "")
1864 (unspec:V2DF [(match_dup 2)] UNSPEC_VEC_VFLL))]
1865 "TARGET_VX"
1866 {
1867 operands[2] = gen_reg_rtx (V4SFmode);
1868 operands[3] = CONST0_RTX (V4SFmode);
1869 operands[4] = adjust_address (operands[1], SFmode, 4);
1870 })
1871
1872
1873 ; Vector load rounded - V2DF -> V4SF
1874
1875 (define_insn "vflrd"
1876 [(set (match_operand:V4SF 0 "register_operand" "=v")
1877 (unspec:V4SF [(match_operand:V2DF 1 "register_operand" "v")
1878 (match_operand:QI 2 "const_mask_operand" "C")
1879 (match_operand:QI 3 "const_mask_operand" "C")]
1880 UNSPEC_VEC_VFLR))]
1881 "TARGET_VX"
1882 "vledb\t%v0,%v1,%b2,%b3"
1883 [(set_attr "op_type" "VRR")])
1884
1885 (define_expand "vec_st2f"
1886 [(set (match_dup 2)
1887 (unspec:V4SF [(match_operand:V2DF 0 "register_operand" "")
1888 (const_int VEC_INEXACT)
1889 (const_int VEC_RND_CURRENT)]
1890 UNSPEC_VEC_VFLR))
1891 (set (match_operand:SF 1 "memory_operand" "")
1892 (unspec:SF [(match_dup 2) (const_int 0)] UNSPEC_VEC_EXTRACT))
1893 (set (match_dup 3)
1894 (unspec:SF [(match_dup 2) (const_int 2)] UNSPEC_VEC_EXTRACT))]
1895 "TARGET_VX"
1896 {
1897 operands[2] = gen_reg_rtx (V4SFmode);
1898 operands[3] = adjust_address (operands[1], SFmode, 4);
1899 })
1900
1901
1902 ; Vector square root fp vec_sqrt -> sqrt rtx standard name
1903
1904 ;; Vector FP test data class immediate
1905
1906 ; vec_all_nan, vec_all_numeric, vec_any_nan, vec_any_numeric
1907 ; These ignore the vector result and only want CC stored to an int
1908 ; pointer.
1909
1910 ; vftcisb, vftcidb, wftcixb
1911 (define_insn "*vftci<mode>_cconly"
1912 [(set (reg:CCRAW CC_REGNUM)
1913 (unspec:CCRAW [(match_operand:VF_HW 1 "register_operand" "v")
1914 (match_operand:HI 2 "const_int_operand" "J")]
1915 UNSPEC_VEC_VFTCICC))
1916 (clobber (match_scratch:<TOINTVEC> 0 "=v"))]
1917 "TARGET_VX && CONST_OK_FOR_CONSTRAINT_P (INTVAL (operands[2]), 'J', \"J\")"
1918 "<vw>ftci<sdx>b\t%v0,%v1,%x2"
1919 [(set_attr "op_type" "VRR")])
1920
1921 (define_expand "vftci<mode>_intcconly"
1922 [(parallel
1923 [(set (reg:CCRAW CC_REGNUM)
1924 (unspec:CCRAW [(match_operand:VF_HW 0 "register_operand")
1925 (match_operand:HI 1 "const_int_operand")]
1926 UNSPEC_VEC_VFTCICC))
1927 (clobber (scratch:<TOINTVEC>))])
1928 (set (match_operand:SI 2 "register_operand" "")
1929 (unspec:SI [(reg:CCRAW CC_REGNUM)] UNSPEC_CC_TO_INT))]
1930 "TARGET_VX && CONST_OK_FOR_CONSTRAINT_P (INTVAL (operands[1]), 'J', \"J\")")
1931
1932 ; vec_fp_test_data_class wants the result vector and the CC stored to
1933 ; an int pointer.
1934
1935 ; vftcisb, vftcidb, wftcixb
1936 (define_insn "vftci<mode>"
1937 [(set (match_operand:VF_HW 0 "register_operand" "=v")
1938 (unspec:VF_HW [(match_operand:VF_HW 1 "register_operand" "v")
1939 (match_operand:HI 2 "const_int_operand" "J")]
1940 UNSPEC_VEC_VFTCI))
1941 (set (reg:CCRAW CC_REGNUM)
1942 (unspec:CCRAW [(match_dup 1) (match_dup 2)] UNSPEC_VEC_VFTCICC))]
1943 "TARGET_VX && CONST_OK_FOR_CONSTRAINT_P (INTVAL (operands[2]), 'J', \"J\")"
1944 "<vw>ftci<sdx>b\t%v0,%v1,%x2"
1945 [(set_attr "op_type" "VRR")])
1946
1947 (define_expand "vftci<mode>_intcc"
1948 [(parallel
1949 [(set (match_operand:VF_HW 0 "register_operand")
1950 (unspec:VF_HW [(match_operand:VF_HW 1 "register_operand")
1951 (match_operand:HI 2 "const_int_operand")]
1952 UNSPEC_VEC_VFTCI))
1953 (set (reg:CCRAW CC_REGNUM)
1954 (unspec:CCRAW [(match_dup 1) (match_dup 2)] UNSPEC_VEC_VFTCICC))])
1955 (set (match_operand:SI 3 "nonimmediate_operand")
1956 (unspec:SI [(reg:CCRAW CC_REGNUM)] UNSPEC_CC_TO_INT))]
1957 "TARGET_VX && CONST_OK_FOR_CONSTRAINT_P (INTVAL (operands[2]), 'J', \"J\")")
1958
1959 ;;
1960 ;; Integer compares
1961 ;;
1962
1963 ; All comparisons which produce a CC need fully populated (VI_HW)
1964 ; vector arguments. Otherwise the any/all CCs would be just bogus.
1965
1966 (define_insn "*vec_cmp<VICMP:insn_cmp><VI_HW:mode>_cconly"
1967 [(set (reg:VICMP CC_REGNUM)
1968 (compare:VICMP (match_operand:VI_HW 0 "register_operand" "v")
1969 (match_operand:VI_HW 1 "register_operand" "v")))
1970 (clobber (match_scratch:VI_HW 2 "=v"))]
1971 "TARGET_VX"
1972 "vc<VICMP:insn_cmp><VI_HW:bhfgq>s\t%v2,%v0,%v1"
1973 [(set_attr "op_type" "VRR")])
1974
1975 ; FIXME: The following 2x3 definitions should be merged into 2 with
1976 ; VICMP like above but I could not find a way to set the comparison
1977 ; operator (eq) depending on the mode CCVEQ (mode_iterator). Or the
1978 ; other way around - setting the mode depending on the code
1979 ; (code_iterator).
1980 (define_expand "vec_cmpeq<VI_HW:mode>_cc"
1981 [(parallel
1982 [(set (reg:CCVEQ CC_REGNUM)
1983 (compare:CCVEQ (match_operand:VI_HW 1 "register_operand" "v")
1984 (match_operand:VI_HW 2 "register_operand" "v")))
1985 (set (match_operand:VI_HW 0 "register_operand" "=v")
1986 (eq:VI_HW (match_dup 1) (match_dup 2)))])
1987 (set (match_operand:SI 3 "memory_operand" "")
1988 (unspec:SI [(reg:CCVEQ CC_REGNUM)] UNSPEC_CC_TO_INT))]
1989 "TARGET_VX")
1990
1991 (define_expand "vec_cmph<VI_HW:mode>_cc"
1992 [(parallel
1993 [(set (reg:CCVIH CC_REGNUM)
1994 (compare:CCVIH (match_operand:VI_HW 1 "register_operand" "v")
1995 (match_operand:VI_HW 2 "register_operand" "v")))
1996 (set (match_operand:VI_HW 0 "register_operand" "=v")
1997 (gt:VI_HW (match_dup 1) (match_dup 2)))])
1998 (set (match_operand:SI 3 "memory_operand" "")
1999 (unspec:SI [(reg:CCVIH CC_REGNUM)] UNSPEC_CC_TO_INT))]
2000 "TARGET_VX")
2001
2002 (define_expand "vec_cmphl<VI_HW:mode>_cc"
2003 [(parallel
2004 [(set (reg:CCVIHU CC_REGNUM)
2005 (compare:CCVIHU (match_operand:VI_HW 1 "register_operand" "v")
2006 (match_operand:VI_HW 2 "register_operand" "v")))
2007 (set (match_operand:VI_HW 0 "register_operand" "=v")
2008 (gtu:VI_HW (match_dup 1) (match_dup 2)))])
2009 (set (match_operand:SI 3 "memory_operand" "")
2010 (unspec:SI [(reg:CCVIHU CC_REGNUM)] UNSPEC_CC_TO_INT))]
2011 "TARGET_VX")
2012
2013
2014 (define_insn "*vec_cmpeq<VI_HW:mode>_cc"
2015 [(set (reg:CCVEQ CC_REGNUM)
2016 (compare:CCVEQ (match_operand:VI_HW 0 "register_operand" "v")
2017 (match_operand:VI_HW 1 "register_operand" "v")))
2018 (set (match_operand:VI_HW 2 "register_operand" "=v")
2019 (eq:VI_HW (match_dup 0) (match_dup 1)))]
2020 "TARGET_VX"
2021 "vceq<VI_HW:bhfgq>s\t%v2,%v0,%v1"
2022 [(set_attr "op_type" "VRR")])
2023
2024 (define_insn "*vec_cmph<VI_HW:mode>_cc"
2025 [(set (reg:CCVIH CC_REGNUM)
2026 (compare:CCVIH (match_operand:VI_HW 0 "register_operand" "v")
2027 (match_operand:VI_HW 1 "register_operand" "v")))
2028 (set (match_operand:VI_HW 2 "register_operand" "=v")
2029 (gt:VI_HW (match_dup 0) (match_dup 1)))]
2030 "TARGET_VX"
2031 "vch<VI_HW:bhfgq>s\t%v2,%v0,%v1"
2032 [(set_attr "op_type" "VRR")])
2033
2034 (define_insn "*vec_cmphl<VI_HW:mode>_cc"
2035 [(set (reg:CCVIHU CC_REGNUM)
2036 (compare:CCVIHU (match_operand:VI_HW 0 "register_operand" "v")
2037 (match_operand:VI_HW 1 "register_operand" "v")))
2038 (set (match_operand:VI_HW 2 "register_operand" "=v")
2039 (gtu:VI_HW (match_dup 0) (match_dup 1)))]
2040 "TARGET_VX"
2041 "vchl<VI_HW:bhfgq>s\t%v2,%v0,%v1"
2042 [(set_attr "op_type" "VRR")])
2043
2044 ;;
2045 ;; Floating point compares
2046 ;;
2047
2048 ; vfcesbs, vfcedbs, wfcexbs, vfchsbs, vfchdbs, wfchxbs, vfchesbs, vfchedbs, wfchexbs
2049 (define_insn "*vec_cmp<insn_cmp><VF_HW:mode>_cconly"
2050 [(set (reg:VFCMP CC_REGNUM)
2051 (compare:VFCMP (match_operand:VF_HW 0 "register_operand" "v")
2052 (match_operand:VF_HW 1 "register_operand" "v")))
2053 (clobber (match_scratch:<TOINTVEC> 2 "=v"))]
2054 "TARGET_VX"
2055 "<vw>fc<asm_fcmp><sdx>bs\t%v2,%v0,%v1"
2056 [(set_attr "op_type" "VRR")])
2057
2058 ; FIXME: Merge the following 2x3 patterns with VFCMP
2059 (define_expand "vec_cmpeq<mode>_cc"
2060 [(parallel
2061 [(set (reg:CCVEQ CC_REGNUM)
2062 (compare:CCVEQ (match_operand:VF_HW 1 "register_operand" "v")
2063 (match_operand:VF_HW 2 "register_operand" "v")))
2064 (set (match_operand:<TOINTVEC> 0 "register_operand" "=v")
2065 (eq:<TOINTVEC> (match_dup 1) (match_dup 2)))])
2066 (set (match_operand:SI 3 "memory_operand" "")
2067 (unspec:SI [(reg:CCVEQ CC_REGNUM)] UNSPEC_CC_TO_INT))]
2068 "TARGET_VX")
2069
2070 (define_expand "vec_cmph<mode>_cc"
2071 [(parallel
2072 [(set (reg:CCVFH CC_REGNUM)
2073 (compare:CCVFH (match_operand:VF_HW 1 "register_operand" "v")
2074 (match_operand:VF_HW 2 "register_operand" "v")))
2075 (set (match_operand:<TOINTVEC> 0 "register_operand" "=v")
2076 (gt:<TOINTVEC> (match_dup 1) (match_dup 2)))])
2077 (set (match_operand:SI 3 "memory_operand" "")
2078 (unspec:SI [(reg:CCVIH CC_REGNUM)] UNSPEC_CC_TO_INT))]
2079 "TARGET_VX")
2080
2081 (define_expand "vec_cmphe<mode>_cc"
2082 [(parallel
2083 [(set (reg:CCVFHE CC_REGNUM)
2084 (compare:CCVFHE (match_operand:VF_HW 1 "register_operand" "v")
2085 (match_operand:VF_HW 2 "register_operand" "v")))
2086 (set (match_operand:<TOINTVEC> 0 "register_operand" "=v")
2087 (ge:<TOINTVEC> (match_dup 1) (match_dup 2)))])
2088 (set (match_operand:SI 3 "memory_operand" "")
2089 (unspec:SI [(reg:CCVFHE CC_REGNUM)] UNSPEC_CC_TO_INT))]
2090 "TARGET_VX")
2091
2092 ; These 3 cannot be merged as the insn defintion above since it also
2093 ; requires to rewrite the RTL equality operator that the same time as
2094 ; the CC mode.
2095
2096 ; vfcesbs, vfcedbs, wfcexbs
2097 (define_insn "*vec_cmpeq<mode>_cc"
2098 [(set (reg:CCVEQ CC_REGNUM)
2099 (compare:CCVEQ (match_operand:VF_HW 0 "register_operand" "v")
2100 (match_operand:VF_HW 1 "register_operand" "v")))
2101 (set (match_operand:<TOINTVEC> 2 "register_operand" "=v")
2102 (eq:<TOINTVEC> (match_dup 0) (match_dup 1)))]
2103 "TARGET_VX"
2104 "<vw>fce<sdx>bs\t%v2,%v0,%v1"
2105 [(set_attr "op_type" "VRR")])
2106
2107 ; vfchsbs, vfchdbs, wfchxbs
2108 (define_insn "*vec_cmph<mode>_cc"
2109 [(set (reg:CCVFH CC_REGNUM)
2110 (compare:CCVFH (match_operand:VF_HW 0 "register_operand" "v")
2111 (match_operand:VF_HW 1 "register_operand" "v")))
2112 (set (match_operand:<TOINTVEC> 2 "register_operand" "=v")
2113 (gt:<TOINTVEC> (match_dup 0) (match_dup 1)))]
2114 "TARGET_VX"
2115 "<vw>fch<sdx>bs\t%v2,%v0,%v1"
2116 [(set_attr "op_type" "VRR")])
2117
2118 ; vfchesbs, vfchedbs, wfchexbs
2119 (define_insn "*vec_cmphe<mode>_cc"
2120 [(set (reg:CCVFHE CC_REGNUM)
2121 (compare:CCVFHE (match_operand:VF_HW 0 "register_operand" "v")
2122 (match_operand:VF_HW 1 "register_operand" "v")))
2123 (set (match_operand:<TOINTVEC> 2 "register_operand" "=v")
2124 (ge:<TOINTVEC> (match_dup 0) (match_dup 1)))]
2125 "TARGET_VX"
2126 "<vw>fche<sdx>bs\t%v2,%v0,%v1"
2127 [(set_attr "op_type" "VRR")])
2128
2129
2130 (define_insn "vfmin<mode>"
2131 [(set (match_operand:VF_HW 0 "register_operand" "=v")
2132 (unspec:VF_HW [(match_operand:VF_HW 1 "register_operand" "v")
2133 (match_operand:VF_HW 2 "register_operand" "v")
2134 (match_operand:QI 3 "const_mask_operand" "C")]
2135 UNSPEC_VEC_VFMIN))]
2136 "TARGET_VXE"
2137 "<vw>fmin<sdx>b\t%v0,%v1,%v2,%b3"
2138 [(set_attr "op_type" "VRR")])
2139
2140 (define_insn "vfmax<mode>"
2141 [(set (match_operand:VF_HW 0 "register_operand" "=v")
2142 (unspec:VF_HW [(match_operand:VF_HW 1 "register_operand" "v")
2143 (match_operand:VF_HW 2 "register_operand" "v")
2144 (match_operand:QI 3 "const_mask_operand" "C")]
2145 UNSPEC_VEC_VFMAX))]
2146 "TARGET_VXE"
2147 "<vw>fmax<sdx>b\t%v0,%v1,%v2,%b3"
2148 [(set_attr "op_type" "VRR")])
2149
2150 ; The element reversal builtins introduced with z15 have been made
2151 ; available also for older CPUs down to z13.
2152 (define_expand "eltswap<mode>"
2153 [(set (match_operand:VEC_HW 0 "nonimmediate_operand" "")
2154 (unspec:VEC_HW [(match_operand:VEC_HW 1 "nonimmediate_operand" "")]
2155 UNSPEC_VEC_ELTSWAP))]
2156 "TARGET_VX")
2157
2158 ; The byte element reversal is implemented as 128 bit byte swap.
2159 ; Alternatively this could be emitted as bswap:V1TI but the required
2160 ; subregs appear to confuse combine.
2161 (define_insn "*eltswapv16qi"
2162 [(set (match_operand:V16QI 0 "nonimmediate_operand" "=v,v,R")
2163 (unspec:V16QI [(match_operand:V16QI 1 "nonimmediate_operand" "v,R,v")]
2164 UNSPEC_VEC_ELTSWAP))]
2165 "TARGET_VXE2"
2166 "@
2167 #
2168 vlbrq\t%v0,%v1
2169 vstbrq\t%v1,%v0"
2170 [(set_attr "op_type" "*,VRX,VRX")])
2171
2172 ; vlerh, vlerf, vlerg, vsterh, vsterf, vsterg
2173 (define_insn "*eltswap<mode>"
2174 [(set (match_operand:V_HW_HSD 0 "nonimmediate_operand" "=v,v,R")
2175 (unspec:V_HW_HSD [(match_operand:V_HW_HSD 1 "nonimmediate_operand" "v,R,v")]
2176 UNSPEC_VEC_ELTSWAP))]
2177 "TARGET_VXE2"
2178 "@
2179 #
2180 vler<bhfgq>\t%v0,%v1
2181 vster<bhfgq>\t%v1,%v0"
2182 [(set_attr "op_type" "*,VRX,VRX")])
2183
2184 ; z15 has instructions for doing element reversal from mem to reg
2185 ; or the other way around. For reg to reg or on pre z15 machines
2186 ; we have to emulate it with vector permute.
2187 (define_insn_and_split "*eltswap<mode>_emu"
2188 [(set (match_operand:VEC_HW 0 "nonimmediate_operand" "=vR")
2189 (unspec:VEC_HW [(match_operand:VEC_HW 1 "nonimmediate_operand" "vR")]
2190 UNSPEC_VEC_ELTSWAP))]
2191 "TARGET_VX && can_create_pseudo_p ()"
2192 "#"
2193 "&& ((!memory_operand (operands[0], <MODE>mode)
2194 && !memory_operand (operands[1], <MODE>mode))
2195 || !TARGET_VXE2)"
2196 [(set (match_dup 3)
2197 (unspec:V16QI [(match_dup 4)
2198 (match_dup 4)
2199 (match_dup 2)]
2200 UNSPEC_VEC_PERM))
2201 (set (match_dup 0) (subreg:VEC_HW (match_dup 3) 0))]
2202 {
2203 static char p[4][16] =
2204 { { 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0 }, /* Q */
2205 { 14, 15, 12, 13, 10, 11, 8, 9, 6, 7, 4, 5, 2, 3, 0, 1 }, /* H */
2206 { 12, 13, 14, 15, 8, 9, 10, 11, 4, 5, 6, 7, 0, 1, 2, 3 }, /* S */
2207 { 8, 9, 10, 11, 12, 13, 14, 15, 0, 1, 2, 3, 4, 5, 6, 7 } }; /* D */
2208 char *perm;
2209 rtx perm_rtx[16], constv;
2210
2211 switch (GET_MODE_SIZE (GET_MODE_INNER (<MODE>mode)))
2212 {
2213 case 1: perm = p[0]; break;
2214 case 2: perm = p[1]; break;
2215 case 4: perm = p[2]; break;
2216 case 8: perm = p[3]; break;
2217 default: gcc_unreachable ();
2218 }
2219
2220 for (int i = 0; i < 16; i++)
2221 perm_rtx[i] = GEN_INT (perm[i]);
2222
2223 operands[1] = force_reg (<MODE>mode, operands[1]);
2224 operands[2] = gen_reg_rtx (V16QImode);
2225 operands[3] = gen_reg_rtx (V16QImode);
2226 operands[4] = simplify_gen_subreg (V16QImode, operands[1], <MODE>mode, 0);
2227 constv = force_const_mem (V16QImode, gen_rtx_CONST_VECTOR (V16QImode, gen_rtvec_v (16, perm_rtx)));
2228 emit_move_insn (operands[2], constv);
2229 })
2230
2231 ; vec_insert (__builtin_bswap32 (*a), b, 1) set-element-bswap-2.c
2232 ; b[1] = __builtin_bswap32 (*a) set-element-bswap-3.c
2233 ; vlebrh, vlebrf, vlebrg
2234 (define_insn "*vec_set_bswap_elem<mode>"
2235 [(set (match_operand:V_HW_HSD 0 "register_operand" "=v")
2236 (unspec:V_HW_HSD [(bswap:<non_vec> (match_operand:<non_vec> 1 "memory_operand" "R"))
2237 (match_operand:SI 2 "const_int_operand" "C")
2238 (match_operand:V_HW_HSD 3 "register_operand" "0")]
2239 UNSPEC_VEC_SET))]
2240 "TARGET_VXE2 && UINTVAL (operands[2]) < GET_MODE_NUNITS (<V_HW_HSD:MODE>mode)"
2241 "vlebr<bhfgq>\t%v0,%1,%2"
2242 [(set_attr "op_type" "VRX")])
2243
2244 ; vec_revb (vec_insert (*a, vec_revb (b), 1)) set-element-bswap-1.c
2245 ; vlebrh, vlebrf, vlebrg
2246 (define_insn "*vec_set_bswap_vec<mode>"
2247 [(set (match_operand:V_HW_HSD 0 "register_operand" "=v")
2248 (bswap:V_HW_HSD
2249 (unspec:V_HW_HSD [(match_operand:<non_vec> 1 "memory_operand" "R")
2250 (match_operand:SI 2 "const_int_operand" "C")
2251 (bswap:V_HW_HSD (match_operand:V_HW_HSD 3 "register_operand" "0"))]
2252 UNSPEC_VEC_SET)))
2253 (use (match_operand:V16QI 4 "permute_pattern_operand" "X"))]
2254 "TARGET_VXE2 && UINTVAL (operands[2]) < GET_MODE_NUNITS (<V_HW_HSD:MODE>mode)"
2255 "vlebr<bhfgq>\t%v0,%1,%2"
2256 [(set_attr "op_type" "VRX")])
2257
2258 ; *a = vec_extract (vec_revb (b), 1); get-element-bswap-3.c
2259 ; *a = vec_revb (b)[1]; get-element-bswap-4.c
2260 ; vstebrh, vstebrf, vstebrg
2261 (define_insn "*vec_extract_bswap_vec<mode>"
2262 [(set (match_operand:<non_vec> 0 "memory_operand" "=R")
2263 (unspec:<non_vec> [(bswap:V_HW_HSD (match_operand:V_HW_HSD 1 "register_operand" "v"))
2264 (match_operand:SI 2 "const_int_operand" "C")]
2265 UNSPEC_VEC_EXTRACT))]
2266 "TARGET_VXE2 && UINTVAL (operands[2]) < GET_MODE_NUNITS (<V_HW_HSD:MODE>mode)"
2267 "vstebr<bhfgq>\t%v1,%0,%2"
2268 [(set_attr "op_type" "VRX")])
2269
2270 ; *a = __builtin_bswap32 (vec_extract (b, 1)); get-element-bswap-1.c
2271 ; *a = __builtin_bswap32 (b[1]); get-element-bswap-2.c
2272 ; vstebrh, vstebrf, vstebrg
2273 (define_insn "*vec_extract_bswap_elem<mode>"
2274 [(set (match_operand:<non_vec> 0 "memory_operand" "=R")
2275 (bswap:<non_vec>
2276 (unspec:<non_vec> [(match_operand:V_HW_HSD 1 "register_operand" "v")
2277 (match_operand:SI 2 "const_int_operand" "C")]
2278 UNSPEC_VEC_EXTRACT)))]
2279 "TARGET_VXE2 && UINTVAL (operands[2]) < GET_MODE_NUNITS (<V_HW_HSD:MODE>mode)"
2280 "vstebr<bhfgq>\t%v1,%0,%2"
2281 [(set_attr "op_type" "VRX")])
2282
2283
2284 ;;
2285 ;; NNPA Facility
2286 ;;
2287
2288 (define_insn "vclfnhs_v8hi"
2289 [(set (match_operand:V4SF 0 "register_operand" "=v")
2290 (unspec:V4SF [(vec_select:V4HI
2291 (match_operand:V8HI 1 "register_operand" "v")
2292 (parallel [(const_int 0) (const_int 1) (const_int 2) (const_int 3)]))
2293 (match_operand:QI 2 "const_mask_operand" "C")]
2294 UNSPEC_NNPA_VCLFNHS_V8HI))]
2295 "TARGET_NNPA"
2296 "vclfnh\t%v0,%v1,2,%2"
2297 [(set_attr "op_type" "VRR")])
2298
2299 (define_insn "vclfnls_v8hi"
2300 [(set (match_operand:V4SF 0 "register_operand" "=v")
2301 (unspec:V4SF [(vec_select:V4HI
2302 (match_operand:V8HI 1 "register_operand" "v")
2303 (parallel [(const_int 4) (const_int 5) (const_int 6) (const_int 7)]))
2304 (match_operand:QI 2 "const_mask_operand" "C")]
2305 UNSPEC_NNPA_VCLFNLS_V8HI))]
2306 "TARGET_NNPA"
2307 "vclfnl\t%v0,%v1,2,%2"
2308 [(set_attr "op_type" "VRR")])
2309
2310 (define_insn "vcrnfs_v8hi"
2311 [(set (match_operand:V8HI 0 "register_operand" "=v")
2312 (unspec:V8HI [(match_operand:V4SF 1 "register_operand" "v")
2313 (match_operand:V4SF 2 "register_operand" "v")
2314 (match_operand:QI 3 "const_mask_operand" "C")]
2315 UNSPEC_NNPA_VCRNFS_V8HI))]
2316 "TARGET_NNPA"
2317 "vcrnf\t%v0,%v1,%v2,%3,2"
2318 [(set_attr "op_type" "VRR")])
2319
2320 (define_insn "vcfn_v8hi"
2321 [(set (match_operand:V8HI 0 "register_operand" "=v")
2322 (unspec:V8HI [(match_operand:V8HI 1 "register_operand" "v")
2323 (match_operand:QI 2 "const_mask_operand" "C")]
2324 UNSPEC_NNPA_VCFN_V8HI))]
2325 "TARGET_NNPA"
2326 "vcfn\t%v0,%v1,1,%2"
2327 [(set_attr "op_type" "VRR")])
2328
2329 (define_insn "vcnf_v8hi"
2330 [(set (match_operand:V8HI 0 "register_operand" "=v")
2331 (unspec:V8HI [(match_operand:V8HI 1 "register_operand" "v")
2332 (match_operand:QI 2 "const_mask_operand" "C")]
2333 UNSPEC_NNPA_VCNF_V8HI))]
2334 "TARGET_NNPA"
2335 "vcnf\t%v0,%v1,%2,1"
2336 [(set_attr "op_type" "VRR")])