]> 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-2024 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 (vec_select:SI
444 (match_operand:V4SI 1 "register_operand" "v")
445 (parallel [(match_operand:QI 3 "const_mask_operand" "C")])))
446 (match_operand:SI 2 "address_operand" "ZQ")))
447 (vec_select:<non_vec>
448 (match_operand:V_HW_4 0 "register_operand" "v")
449 (parallel [(match_dup 3)])))]
450 "TARGET_VX && TARGET_64BIT && UINTVAL (operands[3]) < 4"
451 "vscef\t%v0,%O2(%v1,%R2),%3"
452 [(set_attr "op_type" "VRV")])
453
454 ; A 31 bit target address is generated from 64 bit elements
455 ; vsceg
456 (define_insn "vec_scatter_element<V_HW_2:mode>_SI"
457 [(set (mem:<non_vec>
458 (plus:SI (subreg:SI
459 (vec_select:<non_vec_int>
460 (match_operand:<TOINTVEC> 1 "register_operand" "v")
461 (parallel [(match_operand:QI 3 "const_mask_operand" "C")])) 4)
462 (match_operand:SI 2 "address_operand" "ZQ")))
463 (vec_select:<non_vec>
464 (match_operand:V_HW_2 0 "register_operand" "v")
465 (parallel [(match_dup 3)])))]
466 "TARGET_VX && !TARGET_64BIT && UINTVAL (operands[3]) < GET_MODE_NUNITS (<V_HW_2:MODE>mode)"
467 "vsce<V_HW_2:bhfgq>\t%v0,%O2(%v1,%R2),%3"
468 [(set_attr "op_type" "VRV")])
469
470 ; Element size and target address size is the same
471 ; vscef, vsceg
472 (define_insn "vec_scatter_element<mode>_<non_vec_int>"
473 [(set (mem:<non_vec>
474 (plus:<non_vec_int>
475 (vec_select:<non_vec_int>
476 (match_operand:<TOINTVEC> 1 "register_operand" "v")
477 (parallel [(match_operand:QI 3 "const_mask_operand" "C")]))
478 (match_operand:DI 2 "address_operand" "ZQ")))
479 (vec_select:<non_vec>
480 (match_operand:V_HW_32_64 0 "register_operand" "v")
481 (parallel [(match_dup 3)])))]
482 "TARGET_VX && UINTVAL (operands[3]) < GET_MODE_NUNITS (<V_HW_32_64:MODE>mode)"
483 "vsce<bhfgq>\t%v0,%O2(%v1,%R2),%3"
484 [(set_attr "op_type" "VRV")])
485
486 ; Depending on the address size we have to expand a different pattern.
487 ; This however cannot be represented in s390-builtins.def so we do the
488 ; multiplexing here in the expander.
489 (define_expand "vec_scatter_element<V_HW_32_64:mode>"
490 [(match_operand:V_HW_32_64 0 "register_operand" "")
491 (match_operand:<TOINTVEC> 1 "register_operand" "")
492 (match_operand 2 "address_operand" "")
493 (match_operand:QI 3 "const_mask_operand" "")]
494 "TARGET_VX"
495 {
496 if (TARGET_64BIT)
497 {
498 PUT_MODE (operands[2], DImode);
499 emit_insn (
500 gen_vec_scatter_element<V_HW_32_64:mode>_DI (operands[0], operands[1],
501 operands[2], operands[3]));
502 }
503 else
504 {
505 PUT_MODE (operands[2], SImode);
506 emit_insn (
507 gen_vec_scatter_element<V_HW_32_64:mode>_SI (operands[0], operands[1],
508 operands[2], operands[3]));
509 }
510 DONE;
511 })
512
513
514 ; Vector select
515
516 ; for all b in bits op0[b] = op3[b] == 0 ? op2[b] : op1[b]
517 ; implemented as: op0 = (op1 & op3) | (op2 & ~op3)
518
519 ; Used to expand the vec_sel builtin. Operands op1 and op2 already got
520 ; swapped in s390-c.cc when we get here.
521
522 (define_insn "vsel<mode>"
523 [(set (match_operand:V_HW_FT 0 "register_operand" "=v")
524 (ior:V_HW_FT
525 (and:V_HW_FT (match_operand:V_HW_FT 1 "register_operand" "v")
526 (match_operand:V_HW_FT 3 "register_operand" "v"))
527 (and:V_HW_FT (not:V_HW_FT (match_dup 3))
528 (match_operand:V_HW_FT 2 "register_operand" "v"))))]
529 "TARGET_VX"
530 "vsel\t%v0,%1,%2,%3"
531 [(set_attr "op_type" "VRR")])
532
533 (define_insn "*vsel<mode>_swapped"
534 [(set (match_operand:V_HW_FT 0 "register_operand" "=v")
535 (ior:V_HW_FT
536 (and:V_HW_FT (not:V_HW_FT (match_operand:V_HW_FT 3 "register_operand" "v"))
537 (match_operand:V_HW_FT 1 "register_operand" "v"))
538 (and:V_HW_FT (match_dup 3)
539 (match_operand:V_HW_FT 2 "register_operand" "v"))))]
540 "TARGET_VX"
541 "vsel\t%v0,%2,%1,%3"
542 [(set_attr "op_type" "VRR")])
543
544
545 ; Vector sign extend to doubleword
546
547 ; Sign extend of right most vector element to respective double-word
548 ; vsegb, vsegh, vsegf
549 (define_insn "vec_extend<mode>"
550 [(set (match_operand:VI_HW_QHS 0 "register_operand" "=v")
551 (unspec:VI_HW_QHS [(match_operand:VI_HW_QHS 1 "register_operand" "v")]
552 UNSPEC_VEC_EXTEND))]
553 "TARGET_VX"
554 "vseg<bhfgq>\t%v0,%1"
555 [(set_attr "op_type" "VRR")])
556
557
558 ; Vector store with length
559
560 ; Store bytes in OP1 from OP0 with the highest indexed byte to be
561 ; stored from OP0 given by OP2
562 (define_insn "vstl<mode>"
563 [(set (match_operand:BLK 2 "memory_operand" "=Q")
564 (unspec:BLK [(match_operand:V 0 "register_operand" "v")
565 (match_operand:SI 1 "register_operand" "d")]
566 UNSPEC_VEC_STORE_LEN))]
567 "TARGET_VX"
568 "vstl\t%v0,%1,%2"
569 [(set_attr "op_type" "VRS")])
570
571 ; Vector store rightmost with length
572
573 (define_expand "vstrlrv16qi"
574 [(set (match_operand:BLK 2 "memory_operand" "")
575 (unspec:BLK [(match_operand:V16QI 0 "register_operand" "")
576 (match_operand:SI 1 "nonmemory_operand" "")]
577 UNSPEC_VEC_STORE_LEN_R))]
578 "TARGET_VXE"
579 {
580 /* vstrlr sets all length values beyond 15 to 15. Emulate the same
581 behavior for immediate length operands. vstrl would trigger a
582 SIGILL for too large immediate operands. */
583 if (CONST_INT_P (operands[1])
584 && (UINTVAL (operands[1]) & 0xffffffff) > 15)
585 operands[1] = GEN_INT (15);
586 })
587
588 (define_insn "*vstrlrv16qi"
589 [(set (match_operand:BLK 2 "memory_operand" "=Q, R, Q")
590 (unspec:BLK [(match_operand:V16QI 0 "register_operand" "v, v, v")
591 (match_operand:SI 1 "nonmemory_operand" "d,j>f,jb4")]
592 UNSPEC_VEC_STORE_LEN_R))]
593 "TARGET_VXE"
594 "@
595 vstrlr\t%v0,%1,%2
596 vst\t%v0,%2%A2
597 vstrl\t%v0,%2,%1"
598 [(set_attr "op_type" "VRS,VRX,VSI")])
599
600
601
602 ; vector bit permute
603
604 (define_insn "vbpermv16qi"
605 [(set (match_operand:V2DI 0 "register_operand" "=v")
606 (unspec:V2DI [(match_operand:V16QI 1 "register_operand" "v")
607 (match_operand:V16QI 2 "register_operand" "v")]
608 UNSPEC_VEC_VBPERM))]
609 "TARGET_VXE"
610 "vbperm\t%v0,%v1,%v2"
611 [(set_attr "op_type" "VRR")])
612
613 ; Vector unpack high
614
615 ; vuphb, vuphh, vuphf
616 (define_insn "vec_unpackh<mode>"
617 [(set (match_operand:<vec_double> 0 "register_operand" "=v")
618 (unspec:<vec_double> [(match_operand:VI_HW_QHS 1 "register_operand" "v")]
619 UNSPEC_VEC_UNPACKH))]
620 "TARGET_VX"
621 "vuph<bhfgq>\t%v0,%v1"
622 [(set_attr "op_type" "VRR")])
623
624 ; vuplhb, vuplhh, vuplhf
625 (define_insn "vec_unpackh_l<mode>"
626 [(set (match_operand:<vec_double> 0 "register_operand" "=v")
627 (unspec:<vec_double> [(match_operand:VI_HW_QHS 1 "register_operand" "v")]
628 UNSPEC_VEC_UNPACKH_L))]
629 "TARGET_VX"
630 "vuplh<bhfgq>\t%v0,%v1"
631 [(set_attr "op_type" "VRR")])
632
633
634 ; Vector unpack low
635
636 ; vuplb, vuplhw, vuplf
637 (define_insn "vec_unpackl<mode>"
638 [(set (match_operand:<vec_double> 0 "register_operand" "=v")
639 (unspec:<vec_double> [(match_operand:VI_HW_QHS 1 "register_operand" "v")]
640 UNSPEC_VEC_UNPACKL))]
641 "TARGET_VX"
642 "vupl<bhfgq><w>\t%v0,%v1"
643 [(set_attr "op_type" "VRR")])
644
645 ; vupllb, vupllh, vupllf
646 (define_insn "vec_unpackl_l<mode>"
647 [(set (match_operand:<vec_double> 0 "register_operand" "=v")
648 (unspec:<vec_double> [(match_operand:VI_HW_QHS 1 "register_operand" "v")]
649 UNSPEC_VEC_UNPACKL_L))]
650 "TARGET_VX"
651 "vupll<bhfgq>\t%v0,%v1"
652 [(set_attr "op_type" "VRR")])
653
654
655 ; Vector add
656
657 ; Vector add compute carry
658
659 ; vaccb, vacch, vaccf, vaccg, vaccq
660 (define_insn "vacc<bhfgq>_<mode>"
661 [(set (match_operand:VIT_HW 0 "register_operand" "=v")
662 (unspec:VIT_HW [(match_operand:VIT_HW 1 "register_operand" "v")
663 (match_operand:VIT_HW 2 "register_operand" "v")]
664 UNSPEC_VEC_ADDC))]
665 "TARGET_VX"
666 "vacc<bhfgq>\t%v0,%v1,%v2"
667 [(set_attr "op_type" "VRR")])
668
669 ; Vector add with carry
670
671 (define_insn "vacq"
672 [(set (match_operand:TI 0 "register_operand" "=v")
673 (unspec:TI [(match_operand:TI 1 "register_operand" "v")
674 (match_operand:TI 2 "register_operand" "v")
675 (match_operand:TI 3 "register_operand" "v")]
676 UNSPEC_VEC_ADDE_U128))]
677 "TARGET_VX"
678 "vacq\t%v0,%v1,%v2,%v3"
679 [(set_attr "op_type" "VRR")])
680
681
682 ; Vector add with carry compute carry
683
684 (define_insn "vacccq"
685 [(set (match_operand:TI 0 "register_operand" "=v")
686 (unspec:TI [(match_operand:TI 1 "register_operand" "v")
687 (match_operand:TI 2 "register_operand" "v")
688 (match_operand:TI 3 "register_operand" "v")]
689 UNSPEC_VEC_ADDEC_U128))]
690 "TARGET_VX"
691 "vacccq\t%v0,%v1,%v2,%v3"
692 [(set_attr "op_type" "VRR")])
693
694
695 ; Vector and
696
697 ; Vector and with complement
698
699 ; vnc
700 (define_insn "vec_andc<mode>3"
701 [(set (match_operand:VT_HW 0 "register_operand" "=v")
702 (and:VT_HW (not:VT_HW (match_operand:VT_HW 2 "register_operand" "v"))
703 (match_operand:VT_HW 1 "register_operand" "v")))]
704 "TARGET_VX"
705 "vnc\t%v0,%v1,%v2"
706 [(set_attr "op_type" "VRR")])
707
708
709 ; Vector average
710
711 ; vavgb, vavgh, vavgf, vavgg
712 (define_insn "vec_avg<mode>"
713 [(set (match_operand:VI_HW 0 "register_operand" "=v")
714 (unspec:VI_HW [(match_operand:VI_HW 1 "register_operand" "v")
715 (match_operand:VI_HW 2 "register_operand" "v")]
716 UNSPEC_VEC_AVG))]
717 "TARGET_VX"
718 "vavg<bhfgq>\t%v0,%v1,%v2"
719 [(set_attr "op_type" "VRR")])
720
721 ; Vector average logical
722
723 ; vavglb, vavglh, vavglf, vavglg
724 (define_insn "vec_avgu<mode>"
725 [(set (match_operand:VI_HW 0 "register_operand" "=v")
726 (unspec:VI_HW [(match_operand:VI_HW 1 "register_operand" "v")
727 (match_operand:VI_HW 2 "register_operand" "v")]
728 UNSPEC_VEC_AVGU))]
729 "TARGET_VX"
730 "vavgl<bhfgq>\t%v0,%v1,%v2"
731 [(set_attr "op_type" "VRR")])
732
733
734 ; Vector checksum
735
736 (define_insn "vec_checksum"
737 [(set (match_operand:V4SI 0 "register_operand" "=v")
738 (unspec:V4SI [(match_operand:V4SI 1 "register_operand" "v")
739 (match_operand:V4SI 2 "register_operand" "v")]
740 UNSPEC_VEC_CHECKSUM))]
741 "TARGET_VX"
742 "vcksm\t%v0,%v1,%v2"
743 [(set_attr "op_type" "VRR")])
744
745 ;;
746 ;; Vector compare
747 ;;
748
749 ; vec_all/any int compares
750
751 (define_expand "vec_all_<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 true);
762 DONE;
763 })
764
765 (define_expand "vec_any_<intcmpcc:code><VI_HW:mode>"
766 [(match_operand:SI 0 "register_operand" "")
767 (intcmpcc (match_operand:VI_HW 1 "register_operand" "")
768 (match_operand:VI_HW 2 "register_operand" ""))]
769 "TARGET_VX"
770 {
771 s390_expand_vec_compare_cc (operands[0],
772 <intcmpcc:CODE>,
773 operands[1],
774 operands[2],
775 false);
776 DONE;
777 })
778
779 ; vec_all/any fp compares
780
781 (define_expand "vec_all_<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 true);
792 DONE;
793 })
794
795 (define_expand "vec_any_<fpcmpcc:code><mode>"
796 [(match_operand:SI 0 "register_operand" "")
797 (fpcmpcc (match_operand:VECF_HW 1 "register_operand" "")
798 (match_operand:VECF_HW 2 "register_operand" ""))]
799 "TARGET_VX"
800 {
801 s390_expand_vec_compare_cc (operands[0],
802 <fpcmpcc:CODE>,
803 operands[1],
804 operands[2],
805 false);
806 DONE;
807 })
808
809
810 ; Compare without generating CC
811
812 (define_expand "vec_cmp<intcmp:code><VI_HW:mode>"
813 [(set (match_operand:VI_HW 0 "register_operand" "=v")
814 (intcmp:VI_HW (match_operand:VI_HW 1 "register_operand" "v")
815 (match_operand:VI_HW 2 "register_operand" "v")))]
816 "TARGET_VX"
817 {
818 s390_expand_vec_compare (operands[0], <intcmp:CODE>, operands[1], operands[2]);
819 DONE;
820 })
821
822 (define_expand "vec_cmp<fpcmp:code><mode>"
823 [(set (match_operand:<TOINTVEC> 0 "register_operand" "=v")
824 (fpcmp:<TOINTVEC> (match_operand:VF_HW 1 "register_operand" "v")
825 (match_operand:VF_HW 2 "register_operand" "v")))]
826 "TARGET_VX"
827 {
828 s390_expand_vec_compare (operands[0], <fpcmp:CODE>, operands[1], operands[2]);
829 DONE;
830 })
831
832
833 ; Vector count leading zeros
834
835 ; vec_cntlz -> clz
836 ; vec_cnttz -> ctz
837
838 ; Vector xor
839
840 ; vec_xor -> xor
841
842 ; Vector Galois field multiply sum
843
844 ; vgfmb, vgfmh, vgfmf
845 (define_insn "vec_gfmsum<mode>"
846 [(set (match_operand:VI_HW_QHS 0 "register_operand" "=v")
847 (unspec:VI_HW_QHS [(match_operand:VI_HW_QHS 1 "register_operand" "v")
848 (match_operand:VI_HW_QHS 2 "register_operand" "v")]
849 UNSPEC_VEC_GFMSUM))]
850 "TARGET_VX"
851 "vgfm<bhfgq>\t%v0,%v1,%v2"
852 [(set_attr "op_type" "VRR")])
853
854 (define_insn "vec_gfmsum_128"
855 [(set (match_operand:V16QI 0 "register_operand" "=v")
856 (unspec:V16QI [(match_operand:V2DI 1 "register_operand" "v")
857 (match_operand:V2DI 2 "register_operand" "v")]
858 UNSPEC_VEC_GFMSUM_128))]
859 "TARGET_VX"
860 "vgfmg\t%v0,%v1,%v2"
861 [(set_attr "op_type" "VRR")])
862
863 ; vgfmab, vgfmah, vgfmaf
864 (define_insn "vec_gfmsum_accum<mode>"
865 [(set (match_operand:<vec_double> 0 "register_operand" "=v")
866 (unspec:<vec_double> [(match_operand:VI_HW_QHS 1 "register_operand" "v")
867 (match_operand:VI_HW_QHS 2 "register_operand" "v")
868 (match_operand:<vec_double> 3 "register_operand" "v")]
869 UNSPEC_VEC_GFMSUM_ACCUM))]
870 "TARGET_VX"
871 "vgfma<bhfgq>\t%v0,%v1,%v2,%v3"
872 [(set_attr "op_type" "VRR")])
873
874 (define_insn "vec_gfmsum_accum_128"
875 [(set (match_operand:V16QI 0 "register_operand" "=v")
876 (unspec:V16QI [(match_operand:V2DI 1 "register_operand" "v")
877 (match_operand:V2DI 2 "register_operand" "v")
878 (match_operand:V16QI 3 "register_operand" "v")]
879 UNSPEC_VEC_GFMSUM_ACCUM_128))]
880 "TARGET_VX"
881 "vgfmag\t%v0,%v1,%v2,%v3"
882 [(set_attr "op_type" "VRR")])
883
884
885 ; FIXME: vec_neg ?
886
887 ; Vector load positive: vec_abs -> abs
888 ; Vector maximum vec_max -> smax, logical vec_max -> umax
889 ; Vector maximum vec_min -> smin, logical vec_min -> umin
890
891
892 ; Vector multiply and add high
893
894 ; vec_mladd -> vec_vmal
895 ; vmalb, vmalh, vmalf, vmalg
896 (define_insn "vec_vmal<mode>"
897 [(set (match_operand:VI_HW_QHS 0 "register_operand" "=v")
898 (unspec:VI_HW_QHS [(match_operand:VI_HW_QHS 1 "register_operand" "v")
899 (match_operand:VI_HW_QHS 2 "register_operand" "v")
900 (match_operand:VI_HW_QHS 3 "register_operand" "v")]
901 UNSPEC_VEC_VMAL))]
902 "TARGET_VX"
903 "vmal<bhfgq><w>\t%v0,%v1,%v2,%v3"
904 [(set_attr "op_type" "VRR")])
905
906 ; vec_mhadd -> vec_vmah/vec_vmalh
907
908 ; vmahb; vmahh, vmahf, vmahg
909 (define_insn "vec_vmah<mode>"
910 [(set (match_operand:VI_HW_QHS 0 "register_operand" "=v")
911 (unspec:VI_HW_QHS [(match_operand:VI_HW_QHS 1 "register_operand" "v")
912 (match_operand:VI_HW_QHS 2 "register_operand" "v")
913 (match_operand:VI_HW_QHS 3 "register_operand" "v")]
914 UNSPEC_VEC_VMAH))]
915 "TARGET_VX"
916 "vmah<bhfgq>\t%v0,%v1,%v2,%v3"
917 [(set_attr "op_type" "VRR")])
918
919 ; vmalhb; vmalhh, vmalhf, vmalhg
920 (define_insn "vec_vmalh<mode>"
921 [(set (match_operand:VI_HW_QHS 0 "register_operand" "=v")
922 (unspec:VI_HW_QHS [(match_operand:VI_HW_QHS 1 "register_operand" "v")
923 (match_operand:VI_HW_QHS 2 "register_operand" "v")
924 (match_operand:VI_HW_QHS 3 "register_operand" "v")]
925 UNSPEC_VEC_VMALH))]
926 "TARGET_VX"
927 "vmalh<bhfgq>\t%v0,%v1,%v2,%v3"
928 [(set_attr "op_type" "VRR")])
929
930 ; vec_meadd -> vec_vmae/vec_vmale
931
932 ; vmaeb; vmaeh, vmaef, vmaeg
933 (define_insn "vec_vmae<mode>"
934 [(set (match_operand:<vec_double> 0 "register_operand" "=v")
935 (unspec:<vec_double> [(match_operand:VI_HW_QHS 1 "register_operand" "v")
936 (match_operand:VI_HW_QHS 2 "register_operand" "v")
937 (match_operand:<vec_double> 3 "register_operand" "v")]
938 UNSPEC_VEC_VMAE))]
939 "TARGET_VX"
940 "vmae<bhfgq>\t%v0,%v1,%v2,%v3"
941 [(set_attr "op_type" "VRR")])
942
943 ; vmaleb; vmaleh, vmalef, vmaleg
944 (define_insn "vec_vmale<mode>"
945 [(set (match_operand:<vec_double> 0 "register_operand" "=v")
946 (unspec:<vec_double> [(match_operand:VI_HW_QHS 1 "register_operand" "v")
947 (match_operand:VI_HW_QHS 2 "register_operand" "v")
948 (match_operand:<vec_double> 3 "register_operand" "v")]
949 UNSPEC_VEC_VMALE))]
950 "TARGET_VX"
951 "vmale<bhfgq>\t%v0,%v1,%v2,%v3"
952 [(set_attr "op_type" "VRR")])
953
954 ; vec_moadd -> vec_vmao/vec_vmalo
955
956 ; vmaob; vmaoh, vmaof, vmaog
957 (define_insn "vec_vmao<mode>"
958 [(set (match_operand:<vec_double> 0 "register_operand" "=v")
959 (unspec:<vec_double> [(match_operand:VI_HW_QHS 1 "register_operand" "v")
960 (match_operand:VI_HW_QHS 2 "register_operand" "v")
961 (match_operand:<vec_double> 3 "register_operand" "v")]
962 UNSPEC_VEC_VMAO))]
963 "TARGET_VX"
964 "vmao<bhfgq>\t%v0,%v1,%v2,%v3"
965 [(set_attr "op_type" "VRR")])
966
967 ; vmalob; vmaloh, vmalof, vmalog
968 (define_insn "vec_vmalo<mode>"
969 [(set (match_operand:<vec_double> 0 "register_operand" "=v")
970 (unspec:<vec_double> [(match_operand:VI_HW_QHS 1 "register_operand" "v")
971 (match_operand:VI_HW_QHS 2 "register_operand" "v")
972 (match_operand:<vec_double> 3 "register_operand" "v")]
973 UNSPEC_VEC_VMALO))]
974 "TARGET_VX"
975 "vmalo<bhfgq>\t%v0,%v1,%v2,%v3"
976 [(set_attr "op_type" "VRR")])
977
978
979 ; Vector multiply high
980
981 ; vec_mulh -> vec_smulh/vec_umulh
982
983 ; vmhb, vmhh, vmhf
984 (define_insn "vec_smulh<mode>"
985 [(set (match_operand:VI_HW_QHS 0 "register_operand" "=v")
986 (unspec:VI_HW_QHS [(match_operand:VI_HW_QHS 1 "register_operand" "v")
987 (match_operand:VI_HW_QHS 2 "register_operand" "v")]
988 UNSPEC_VEC_SMULT_HI))]
989 "TARGET_VX"
990 "vmh<bhfgq>\t%v0,%v1,%v2"
991 [(set_attr "op_type" "VRR")])
992
993 ; vmlhb, vmlhh, vmlhf
994 (define_insn "vec_umulh<mode>"
995 [(set (match_operand:VI_HW_QHS 0 "register_operand" "=v")
996 (unspec:VI_HW_QHS [(match_operand:VI_HW_QHS 1 "register_operand" "v")
997 (match_operand:VI_HW_QHS 2 "register_operand" "v")]
998 UNSPEC_VEC_UMULT_HI))]
999 "TARGET_VX"
1000 "vmlh<bhfgq>\t%v0,%v1,%v2"
1001 [(set_attr "op_type" "VRR")])
1002
1003
1004 ; Vector multiply low
1005
1006 ; vec_mule -> vec_widen_umult_even/vec_widen_smult_even
1007 ; vec_mulo -> vec_widen_umult_odd/vec_widen_smult_odd
1008
1009
1010 ; Vector nor
1011
1012 (define_insn "vec_nor<mode>3"
1013 [(set (match_operand:VT_HW 0 "register_operand" "=v")
1014 (not:VT_HW
1015 (ior:VT_HW (match_operand:VT_HW 1 "register_operand" "v")
1016 (match_operand:VT_HW 2 "register_operand" "v"))))]
1017 "TARGET_VX"
1018 "vno\t%v0,%v1,%v2"
1019 [(set_attr "op_type" "VRR")])
1020
1021
1022 ; Vector or
1023
1024 ; Vector population count vec_popcnt -> popcount
1025 ; Vector element rotate left logical vec_rl -> vrotl, vec_rli -> rot
1026
1027 ; Vector element rotate and insert under mask
1028
1029 ; verimb, verimh, verimf, verimg
1030 (define_insn "verim<mode>"
1031 [(set (match_operand:VI_HW 0 "register_operand" "=v")
1032 (unspec:VI_HW [(match_operand:VI_HW 1 "register_operand" "0")
1033 (match_operand:VI_HW 2 "register_operand" "v")
1034 (match_operand:VI_HW 3 "register_operand" "v")
1035 (match_operand:QI 4 "const_int_operand" "C")]
1036 UNSPEC_VEC_RL_MASK))]
1037 "TARGET_VX"
1038 "verim<bhfgq>\t%v0,%v2,%v3,%b4"
1039 [(set_attr "op_type" "VRI")])
1040
1041
1042 ; Vector shift left
1043
1044 (define_insn "vec_sll<VI_HW:mode><VI_HW_QHS:mode>"
1045 [(set (match_operand:VI_HW 0 "register_operand" "=v")
1046 (unspec:VI_HW [(match_operand:VI_HW 1 "register_operand" "v")
1047 (match_operand:VI_HW_QHS 2 "register_operand" "v")]
1048 UNSPEC_VEC_SLL))]
1049 "TARGET_VX"
1050 "vsl\t%v0,%v1,%v2"
1051 [(set_attr "op_type" "VRR")])
1052
1053
1054 ; Vector shift left by byte
1055
1056 ; Pattern definition in vector.md, see vec_vslb
1057 (define_expand "vec_slb<mode>"
1058 [(set (match_operand:V_HW 0 "register_operand" "")
1059 (unspec:V_HW [(match_operand:V_HW 1 "register_operand" "")
1060 (match_operand:<TOINTVEC> 2 "register_operand" "")]
1061 UNSPEC_VEC_SLB))]
1062 "TARGET_VX"
1063 {
1064 PUT_MODE (operands[2], V16QImode);
1065 })
1066
1067 ; Vector shift left double by byte
1068
1069 (define_insn "vec_sld<mode>"
1070 [(set (match_operand:V_HW 0 "register_operand" "=v")
1071 (unspec:V_HW [(match_operand:V_HW 1 "register_operand" "v")
1072 (match_operand:V_HW 2 "register_operand" "v")
1073 (match_operand:QI 3 "const_int_operand" "C")]
1074 UNSPEC_VEC_SLDBYTE))]
1075 "TARGET_VX"
1076 "vsldb\t%v0,%v1,%v2,%b3"
1077 [(set_attr "op_type" "VRI")])
1078
1079 (define_expand "vec_sldw<mode>"
1080 [(set (match_operand:V_HW 0 "register_operand" "")
1081 (unspec:V_HW [(match_operand:V_HW 1 "register_operand" "")
1082 (match_operand:V_HW 2 "register_operand" "")
1083 (match_operand:QI 3 "const_int_operand" "")]
1084 UNSPEC_VEC_SLDBYTE))]
1085 "TARGET_VX"
1086 {
1087 operands[3] = GEN_INT (INTVAL (operands[3]) << 2);
1088 })
1089
1090 ; Vector shift left double by bit
1091
1092 (define_insn "vec_sldb<mode>"
1093 [(set (match_operand:V_HW 0 "register_operand" "=v")
1094 (unspec:V_HW [(match_operand:V_HW 1 "register_operand" "v")
1095 (match_operand:V_HW 2 "register_operand" "v")
1096 (match_operand:QI 3 "const_int_operand" "C")]
1097 UNSPEC_VEC_SLDBIT))]
1098 "TARGET_VXE2"
1099 "vsld\t%v0,%v1,%v2,%b3"
1100 [(set_attr "op_type" "VRI")])
1101
1102 ; Vector shift right double by bit
1103
1104 (define_insn "vec_srdb<mode>"
1105 [(set (match_operand:V_HW 0 "register_operand" "=v")
1106 (unspec:V_HW [(match_operand:V_HW 1 "register_operand" "v")
1107 (match_operand:V_HW 2 "register_operand" "v")
1108 (match_operand:QI 3 "const_int_operand" "C")]
1109 UNSPEC_VEC_SRDBIT))]
1110 "TARGET_VXE2"
1111 "vsrd\t%v0,%v1,%v2,%b3"
1112 [(set_attr "op_type" "VRI")])
1113
1114 ; Vector shift right arithmetic
1115
1116 (define_insn "vec_sral<VI_HW:mode><VI_HW_QHS:mode>"
1117 [(set (match_operand:VI_HW 0 "register_operand" "=v")
1118 (unspec:VI_HW [(match_operand:VI_HW 1 "register_operand" "v")
1119 (match_operand:VI_HW_QHS 2 "register_operand" "v")]
1120 UNSPEC_VEC_SRAL))]
1121 "TARGET_VX"
1122 "vsra\t%v0,%v1,%v2"
1123 [(set_attr "op_type" "VRR")])
1124
1125
1126 ; Vector shift right arithmetic by byte
1127
1128 (define_insn "vec_srab<mode>"
1129 [(set (match_operand:V_HW 0 "register_operand" "=v")
1130 (unspec:V_HW [(match_operand:V_HW 1 "register_operand" "v")
1131 (match_operand:<TOINTVEC> 2 "register_operand" "v")]
1132 UNSPEC_VEC_SRAB))]
1133 "TARGET_VX"
1134 "vsrab\t%v0,%v1,%v2"
1135 [(set_attr "op_type" "VRR")])
1136
1137
1138 ; Vector shift right logical
1139
1140 (define_insn "vec_srl<VI_HW:mode><VI_HW_QHS:mode>"
1141 [(set (match_operand:VI_HW 0 "register_operand" "=v")
1142 (unspec:VI_HW [(match_operand:VI_HW 1 "register_operand" "v")
1143 (match_operand:VI_HW_QHS 2 "register_operand" "v")]
1144 UNSPEC_VEC_SRL))]
1145 "TARGET_VX"
1146 "vsrl\t%v0,%v1,%v2"
1147 [(set_attr "op_type" "VRR")])
1148
1149
1150 ; Vector shift right logical by byte
1151
1152 ; Pattern definition in vector.md, see vec_vsrb
1153 (define_expand "vec_srb<mode>"
1154 [(set (match_operand:V_HW 0 "register_operand" "")
1155 (unspec:V_HW [(match_operand:V_HW 1 "register_operand" "")
1156 (match_operand:<TOINTVEC> 2 "register_operand" "")]
1157 UNSPEC_VEC_SRLB))]
1158 "TARGET_VX"
1159 {
1160 PUT_MODE (operands[2], V16QImode);
1161 })
1162
1163 ; Vector subtract
1164
1165 ; Vector subtract compute borrow indication
1166
1167 ; vscbib, vscbih, vscbif, vscbig, vscbiq
1168 (define_insn "vscbi<bhfgq>_<mode>"
1169 [(set (match_operand:VIT_HW 0 "register_operand" "=v")
1170 (unspec:VIT_HW [(match_operand:VIT_HW 1 "register_operand" "v")
1171 (match_operand:VIT_HW 2 "register_operand" "v")]
1172 UNSPEC_VEC_SUBC))]
1173 "TARGET_VX"
1174 "vscbi<bhfgq>\t%v0,%v1,%v2"
1175 [(set_attr "op_type" "VRR")])
1176
1177 ; Vector subtract with borrow indication
1178
1179 (define_insn "vsbiq"
1180 [(set (match_operand:TI 0 "register_operand" "=v")
1181 (unspec:TI [(match_operand:TI 1 "register_operand" "v")
1182 (match_operand:TI 2 "register_operand" "v")
1183 (match_operand:TI 3 "register_operand" "v")]
1184 UNSPEC_VEC_SUBE_U128))]
1185 "TARGET_VX"
1186 "vsbiq\t%v0,%v1,%v2,%v3"
1187 [(set_attr "op_type" "VRR")])
1188
1189
1190 ; Vector subtract with borrow compute and borrow indication
1191
1192 (define_insn "vsbcbiq"
1193 [(set (match_operand:TI 0 "register_operand" "=v")
1194 (unspec:TI [(match_operand:TI 1 "register_operand" "v")
1195 (match_operand:TI 2 "register_operand" "v")
1196 (match_operand:TI 3 "register_operand" "v")]
1197 UNSPEC_VEC_SUBEC_U128))]
1198 "TARGET_VX"
1199 "vsbcbiq\t%v0,%v1,%v2,%v3"
1200 [(set_attr "op_type" "VRR")])
1201
1202
1203 ; Vector sum across
1204
1205 ; Sum across DImode parts of the 1st operand and add the rightmost
1206 ; element of 2nd operand
1207 ; vsumgh, vsumgf
1208 (define_expand "vec_sum2<mode>"
1209 [(set (match_operand:V2DI 0 "register_operand" "")
1210 (unspec:V2DI [(match_operand:VI_HW_HS 1 "register_operand" "")
1211 (match_operand:VI_HW_HS 2 "register_operand" "")]
1212 UNSPEC_VEC_VSUMG))]
1213 "TARGET_VX")
1214
1215 ; vsumqh, vsumqf
1216 (define_insn "vec_sum_u128<mode>"
1217 [(set (match_operand:V2DI 0 "register_operand" "=v")
1218 (unspec:V2DI [(match_operand:VI_HW_SD 1 "register_operand" "v")
1219 (match_operand:VI_HW_SD 2 "register_operand" "v")]
1220 UNSPEC_VEC_VSUMQ))]
1221 "TARGET_VX"
1222 "vsumq<bhfgq>\t%v0,%v1,%v2"
1223 [(set_attr "op_type" "VRR")])
1224
1225 ; vsumb, vsumh
1226 (define_expand "vec_sum4<mode>"
1227 [(set (match_operand:V4SI 0 "register_operand" "")
1228 (unspec:V4SI [(match_operand:VI_HW_QH 1 "register_operand" "")
1229 (match_operand:VI_HW_QH 2 "register_operand" "")]
1230 UNSPEC_VEC_VSUM))]
1231 "TARGET_VX")
1232
1233
1234 ; Vector test under mask
1235
1236 (define_expand "vec_test_mask_int<mode>"
1237 [(set (reg:CCRAW CC_REGNUM)
1238 (unspec:CCRAW [(match_operand:V_HW 1 "register_operand" "")
1239 (match_operand:<TOINTVEC> 2 "register_operand" "")]
1240 UNSPEC_VEC_TEST_MASK))
1241 (set (match_operand:SI 0 "register_operand" "")
1242 (unspec:SI [(reg:CCRAW CC_REGNUM)] UNSPEC_CC_TO_INT))]
1243 "TARGET_VX")
1244
1245 (define_insn "*vec_test_mask<mode>"
1246 [(set (reg:CCRAW CC_REGNUM)
1247 (unspec:CCRAW [(match_operand:V_HW 0 "register_operand" "v")
1248 (match_operand:<TOINTVEC> 1 "register_operand" "v")]
1249 UNSPEC_VEC_TEST_MASK))]
1250 "TARGET_VX"
1251 "vtm\t%v0,%v1"
1252 [(set_attr "op_type" "VRR")])
1253
1254
1255 ; Vector multiply sum logical
1256
1257 (define_insn "vec_msumv2di"
1258 [(set (match_operand:V16QI 0 "register_operand" "=v")
1259 (unspec:V16QI [(match_operand:V2DI 1 "register_operand" "v")
1260 (match_operand:V2DI 2 "register_operand" "v")
1261 (match_operand:V16QI 3 "register_operand" "v")
1262 (match_operand:QI 4 "const_mask_operand" "C")]
1263 UNSPEC_VEC_MSUM))]
1264 "TARGET_VXE"
1265 "vmslg\t%v0,%v1,%v2,%v3,%4"
1266 [(set_attr "op_type" "VRR")])
1267
1268 (define_insn "vmslg"
1269 [(set (match_operand:TI 0 "register_operand" "=v")
1270 (unspec:TI [(match_operand:V2DI 1 "register_operand" "v")
1271 (match_operand:V2DI 2 "register_operand" "v")
1272 (match_operand:TI 3 "register_operand" "v")
1273 (match_operand:QI 4 "const_mask_operand" "C")]
1274 UNSPEC_VEC_MSUM))]
1275 "TARGET_VXE"
1276 "vmslg\t%v0,%v1,%v2,%v3,%4"
1277 [(set_attr "op_type" "VRR")])
1278
1279
1280 ; Vector find any element equal
1281
1282 ; vfaeb, vfaeh, vfaef
1283 ; vfaezb, vfaezh, vfaezf
1284 (define_insn "vfae<mode>"
1285 [(set (match_operand:VI_HW_QHS 0 "register_operand" "=v")
1286 (unspec:VI_HW_QHS [(match_operand:VI_HW_QHS 1 "register_operand" "v")
1287 (match_operand:VI_HW_QHS 2 "register_operand" "v")
1288 (match_operand:QI 3 "const_mask_operand" "C")]
1289 UNSPEC_VEC_VFAE))]
1290 "TARGET_VX"
1291 {
1292 unsigned HOST_WIDE_INT flags = UINTVAL (operands[3]);
1293
1294 if (flags & VSTRING_FLAG_ZS)
1295 {
1296 flags &= ~VSTRING_FLAG_ZS;
1297 operands[3] = GEN_INT (flags);
1298 return "vfaez<bhfgq>\t%v0,%v1,%v2,%b3";
1299 }
1300 return "vfae<bhfgq>\t%v0,%v1,%v2,%b3";
1301 }
1302 [(set_attr "op_type" "VRR")])
1303
1304 ; vfaebs, vfaehs, vfaefs
1305 ; vfaezbs, vfaezhs, vfaezfs
1306 (define_insn "*vfaes<mode>"
1307 [(set (match_operand:VI_HW_QHS 0 "register_operand" "=v")
1308 (unspec:VI_HW_QHS [(match_operand:VI_HW_QHS 1 "register_operand" "v")
1309 (match_operand:VI_HW_QHS 2 "register_operand" "v")
1310 (match_operand:QI 3 "const_mask_operand" "C")]
1311 UNSPEC_VEC_VFAE))
1312 (set (reg:CCRAW CC_REGNUM)
1313 (unspec:CCRAW [(match_dup 1)
1314 (match_dup 2)
1315 (match_dup 3)]
1316 UNSPEC_VEC_VFAECC))]
1317 "TARGET_VX"
1318 {
1319 unsigned HOST_WIDE_INT flags = UINTVAL (operands[3]);
1320
1321 if (flags & VSTRING_FLAG_ZS)
1322 {
1323 flags &= ~VSTRING_FLAG_ZS;
1324 operands[3] = GEN_INT (flags);
1325 return "vfaez<bhfgq>s\t%v0,%v1,%v2,%b3";
1326 }
1327 return "vfae<bhfgq>s\t%v0,%v1,%v2,%b3";
1328 }
1329 [(set_attr "op_type" "VRR")])
1330
1331 (define_expand "vfaez<mode>"
1332 [(set (match_operand:VI_HW_QHS 0 "register_operand" "=v")
1333 (unspec:VI_HW_QHS [(match_operand:VI_HW_QHS 1 "register_operand" "")
1334 (match_operand:VI_HW_QHS 2 "register_operand" "")
1335 (match_operand:QI 3 "const_mask_operand" "")]
1336 UNSPEC_VEC_VFAE))]
1337 "TARGET_VX"
1338 {
1339 operands[3] = GEN_INT (INTVAL (operands[3]) | VSTRING_FLAG_ZS);
1340 })
1341
1342 (define_expand "vfaes<mode>"
1343 [(parallel
1344 [(set (match_operand:VI_HW_QHS 0 "register_operand" "")
1345 (unspec:VI_HW_QHS [(match_operand:VI_HW_QHS 1 "register_operand" "")
1346 (match_operand:VI_HW_QHS 2 "register_operand" "")
1347 (match_operand:QI 3 "const_mask_operand" "")]
1348 UNSPEC_VEC_VFAE))
1349 (set (reg:CCRAW CC_REGNUM)
1350 (unspec:CCRAW [(match_dup 1)
1351 (match_dup 2)
1352 (match_dup 3)]
1353 UNSPEC_VEC_VFAECC))])
1354 (set (match_operand:SI 4 "memory_operand" "")
1355 (unspec:SI [(reg:CCRAW CC_REGNUM)] UNSPEC_CC_TO_INT))]
1356 "TARGET_VX"
1357 {
1358 operands[3] = GEN_INT (INTVAL (operands[3]) | VSTRING_FLAG_CS);
1359 })
1360
1361 (define_expand "vfaezs<mode>"
1362 [(parallel
1363 [(set (match_operand:VI_HW_QHS 0 "register_operand" "")
1364 (unspec:VI_HW_QHS [(match_operand:VI_HW_QHS 1 "register_operand" "")
1365 (match_operand:VI_HW_QHS 2 "register_operand" "")
1366 (match_operand:SI 3 "const_mask_operand" "")]
1367 UNSPEC_VEC_VFAE))
1368 (set (reg:CCRAW CC_REGNUM)
1369 (unspec:CCRAW [(match_dup 1)
1370 (match_dup 2)
1371 (match_dup 3)]
1372 UNSPEC_VEC_VFAECC))])
1373 (set (match_operand:SI 4 "memory_operand" "")
1374 (unspec:SI [(reg:CCRAW CC_REGNUM)] UNSPEC_CC_TO_INT))]
1375 "TARGET_VX"
1376 {
1377 operands[3] = GEN_INT (INTVAL (operands[3]) | VSTRING_FLAG_CS | VSTRING_FLAG_ZS);
1378 })
1379
1380
1381 ; Vector find element equal
1382
1383 ; vfeeb, vfeeh, vfeef
1384 (define_insn "vfee<mode>"
1385 [(set (match_operand:VI_HW_QHS 0 "register_operand" "=v")
1386 (unspec:VI_HW_QHS [(match_operand:VI_HW_QHS 1 "register_operand" "v")
1387 (match_operand:VI_HW_QHS 2 "register_operand" "v")
1388 (const_int 0)]
1389 UNSPEC_VEC_VFEE))]
1390 "TARGET_VX"
1391 "vfee<bhfgq>\t%v0,%v1,%v2,0"
1392 [(set_attr "op_type" "VRR")])
1393
1394 ; vfeezb, vfeezh, vfeezf
1395 (define_insn "vfeez<mode>"
1396 [(set (match_operand:VI_HW_QHS 0 "register_operand" "=v")
1397 (unspec:VI_HW_QHS [(match_operand:VI_HW_QHS 1 "register_operand" "v")
1398 (match_operand:VI_HW_QHS 2 "register_operand" "v")
1399 (const_int VSTRING_FLAG_ZS)]
1400 UNSPEC_VEC_VFEE))]
1401 "TARGET_VX"
1402 "vfeez<bhfgq>s\t%v0,%v1,%v2,2"
1403 [(set_attr "op_type" "VRR")])
1404
1405 (define_expand "vfees<mode>"
1406 [(parallel
1407 [(set (match_operand:VI_HW_QHS 0 "register_operand" "")
1408 (unspec:VI_HW_QHS [(match_operand:VI_HW_QHS 1 "register_operand" "")
1409 (match_operand:VI_HW_QHS 2 "register_operand" "")
1410 (const_int VSTRING_FLAG_CS)]
1411 UNSPEC_VEC_VFEE))
1412 (set (reg:CCRAW CC_REGNUM)
1413 (unspec:CCRAW [(match_dup 1)
1414 (match_dup 2)
1415 (const_int VSTRING_FLAG_CS)]
1416 UNSPEC_VEC_VFEECC))])
1417 (set (match_operand:SI 3 "memory_operand" "")
1418 (unspec:SI [(reg:CCRAW CC_REGNUM)] UNSPEC_CC_TO_INT))]
1419 "TARGET_VX")
1420
1421 (define_expand "vfeezs<mode>"
1422 [(parallel
1423 [(set (match_operand:VI_HW_QHS 0 "register_operand" "")
1424 (unspec:VI_HW_QHS [(match_operand:VI_HW_QHS 1 "register_operand" "")
1425 (match_operand:VI_HW_QHS 2 "register_operand" "")
1426 (match_dup 4)]
1427 UNSPEC_VEC_VFEE))
1428 (set (reg:CCRAW CC_REGNUM)
1429 (unspec:CCRAW [(match_dup 1)
1430 (match_dup 2)
1431 (match_dup 4)]
1432 UNSPEC_VEC_VFEECC))])
1433 (set (match_operand:SI 3 "memory_operand" "")
1434 (unspec:SI [(reg:CCRAW CC_REGNUM)] UNSPEC_CC_TO_INT))]
1435 "TARGET_VX"
1436 {
1437 operands[4] = GEN_INT (VSTRING_FLAG_ZS | VSTRING_FLAG_CS);
1438 })
1439
1440 ; Vector find element not equal
1441
1442 ; vfeneb, vfeneh, vfenef
1443 (define_insn "vfene<mode>"
1444 [(set (match_operand:VI_HW_QHS 0 "register_operand" "=v")
1445 (unspec:VI_HW_QHS [(match_operand:VI_HW_QHS 1 "register_operand" "v")
1446 (match_operand:VI_HW_QHS 2 "register_operand" "v")
1447 (const_int 0)]
1448 UNSPEC_VEC_VFENE))]
1449 "TARGET_VX"
1450 "vfene<bhfgq>\t%v0,%v1,%v2,0"
1451 [(set_attr "op_type" "VRR")])
1452
1453 ; vec_vfenes can be found in vector.md since it is used for strlen
1454
1455 ; vfenezb, vfenezh, vfenezf
1456 (define_insn "vfenez<mode>"
1457 [(set (match_operand:VI_HW_QHS 0 "register_operand" "=v")
1458 (unspec:VI_HW_QHS [(match_operand:VI_HW_QHS 1 "register_operand" "v")
1459 (match_operand:VI_HW_QHS 2 "register_operand" "v")
1460 (const_int VSTRING_FLAG_ZS)]
1461 UNSPEC_VEC_VFENE))]
1462 "TARGET_VX"
1463 "vfenez<bhfgq>\t%v0,%v1,%v2"
1464 [(set_attr "op_type" "VRR")])
1465
1466 (define_expand "vfenes<mode>"
1467 [(parallel
1468 [(set (match_operand:VI_HW_QHS 0 "register_operand" "")
1469 (unspec:VI_HW_QHS [(match_operand:VI_HW_QHS 1 "register_operand" "")
1470 (match_operand:VI_HW_QHS 2 "register_operand" "")
1471 (const_int VSTRING_FLAG_CS)]
1472 UNSPEC_VEC_VFENE))
1473 (set (reg:CCRAW CC_REGNUM)
1474 (unspec:CCRAW [(match_dup 1)
1475 (match_dup 2)
1476 (const_int VSTRING_FLAG_CS)]
1477 UNSPEC_VEC_VFENECC))])
1478 (set (match_operand:SI 3 "memory_operand" "")
1479 (unspec:SI [(reg:CCRAW CC_REGNUM)] UNSPEC_CC_TO_INT))]
1480 "TARGET_VX")
1481
1482 (define_expand "vfenezs<mode>"
1483 [(parallel
1484 [(set (match_operand:VI_HW_QHS 0 "register_operand" "")
1485 (unspec:VI_HW_QHS [(match_operand:VI_HW_QHS 1 "register_operand" "")
1486 (match_operand:VI_HW_QHS 2 "register_operand" "")
1487 (match_dup 4)]
1488 UNSPEC_VEC_VFENE))
1489 (set (reg:CCRAW CC_REGNUM)
1490 (unspec:CCRAW [(match_dup 1)
1491 (match_dup 2)
1492 (match_dup 4)]
1493 UNSPEC_VEC_VFENECC))])
1494 (set (match_operand:SI 3 "memory_operand" "")
1495 (unspec:SI [(reg:CCRAW CC_REGNUM)] UNSPEC_CC_TO_INT))]
1496 "TARGET_VX"
1497 {
1498 operands[4] = GEN_INT (VSTRING_FLAG_ZS | VSTRING_FLAG_CS);
1499 })
1500
1501 ; Vector isolate string
1502
1503 ; vistrb, vistrh, vistrf
1504 (define_insn "vistr<mode>"
1505 [(set (match_operand:VI_HW_QHS 0 "register_operand" "=v")
1506 (unspec:VI_HW_QHS [(match_operand:VI_HW_QHS 1 "register_operand" "v")]
1507 UNSPEC_VEC_VISTR))]
1508 "TARGET_VX"
1509 "vistr<bhfgq>\t%v0,%v1"
1510 [(set_attr "op_type" "VRR")])
1511
1512 ; vistrbs, vistrhs, vistrfs
1513 (define_insn "*vistrs<mode>"
1514 [(set (match_operand:VI_HW_QHS 0 "register_operand" "=v")
1515 (unspec:VI_HW_QHS [(match_operand:VI_HW_QHS 1 "register_operand" "v")]
1516 UNSPEC_VEC_VISTR))
1517 (set (reg:CCRAW CC_REGNUM)
1518 (unspec:CCRAW [(match_dup 1)] UNSPEC_VEC_VISTRCC))]
1519 "TARGET_VX"
1520 "vistr<bhfgq>s\t%v0,%v1"
1521 [(set_attr "op_type" "VRR")])
1522
1523 (define_expand "vistrs<mode>"
1524 [(parallel
1525 [(set (match_operand:VI_HW_QHS 0 "register_operand" "")
1526 (unspec:VI_HW_QHS [(match_operand:VI_HW_QHS 1 "register_operand" "")]
1527 UNSPEC_VEC_VISTR))
1528 (set (reg:CCRAW CC_REGNUM)
1529 (unspec:CCRAW [(match_dup 1)]
1530 UNSPEC_VEC_VISTRCC))])
1531 (set (match_operand:SI 2 "memory_operand" "")
1532 (unspec:SI [(reg:CCRAW CC_REGNUM)] UNSPEC_CC_TO_INT))]
1533 "TARGET_VX")
1534
1535
1536 ; Vector compare range
1537
1538 ; vstrcb, vstrch, vstrcf
1539 ; vstrczb, vstrczh, vstrczf
1540 (define_insn "vstrc<mode>"
1541 [(set (match_operand:VI_HW_QHS 0 "register_operand" "=v")
1542 (unspec:VI_HW_QHS [(match_operand:VI_HW_QHS 1 "register_operand" "v")
1543 (match_operand:VI_HW_QHS 2 "register_operand" "v")
1544 (match_operand:VI_HW_QHS 3 "register_operand" "v")
1545 (match_operand:QI 4 "const_mask_operand" "C")]
1546 UNSPEC_VEC_VSTRC))]
1547 "TARGET_VX"
1548 {
1549 unsigned HOST_WIDE_INT flags = UINTVAL (operands[4]);
1550
1551 if (flags & VSTRING_FLAG_ZS)
1552 {
1553 flags &= ~VSTRING_FLAG_ZS;
1554 operands[4] = GEN_INT (flags);
1555 return "vstrcz<bhfgq>\t%v0,%v1,%v2,%v3,%b4";
1556 }
1557 return "vstrc<bhfgq>\t%v0,%v1,%v2,%v3,%b4";
1558 }
1559 [(set_attr "op_type" "VRR")])
1560
1561 ; vstrcbs, vstrchs, vstrcfs
1562 ; vstrczbs, vstrczhs, vstrczfs
1563 (define_insn "*vstrcs<mode>"
1564 [(set (match_operand:VI_HW_QHS 0 "register_operand" "=v")
1565 (unspec:VI_HW_QHS [(match_operand:VI_HW_QHS 1 "register_operand" "v")
1566 (match_operand:VI_HW_QHS 2 "register_operand" "v")
1567 (match_operand:VI_HW_QHS 3 "register_operand" "v")
1568 (match_operand:QI 4 "const_mask_operand" "C")]
1569 UNSPEC_VEC_VSTRC))
1570 (set (reg:CCRAW CC_REGNUM)
1571 (unspec:CCRAW [(match_dup 1)
1572 (match_dup 2)
1573 (match_dup 3)
1574 (match_dup 4)]
1575 UNSPEC_VEC_VSTRCCC))]
1576 "TARGET_VX"
1577 {
1578 unsigned HOST_WIDE_INT flags = UINTVAL (operands[4]);
1579
1580 if (flags & VSTRING_FLAG_ZS)
1581 {
1582 flags &= ~VSTRING_FLAG_ZS;
1583 operands[4] = GEN_INT (flags);
1584 return "vstrcz<bhfgq>s\t%v0,%v1,%v2,%v3,%b4";
1585 }
1586 return "vstrc<bhfgq>s\t%v0,%v1,%v2,%v3,%b4";
1587 }
1588 [(set_attr "op_type" "VRR")])
1589
1590 (define_expand "vstrcz<mode>"
1591 [(set (match_operand:VI_HW_QHS 0 "register_operand" "")
1592 (unspec:VI_HW_QHS [(match_operand:VI_HW_QHS 1 "register_operand" "")
1593 (match_operand:VI_HW_QHS 2 "register_operand" "")
1594 (match_operand:VI_HW_QHS 3 "register_operand" "")
1595 (match_operand:QI 4 "const_mask_operand" "")]
1596 UNSPEC_VEC_VSTRC))]
1597 "TARGET_VX"
1598 {
1599 operands[4] = GEN_INT (INTVAL (operands[4]) | VSTRING_FLAG_ZS);
1600 })
1601
1602 (define_expand "vstrcs<mode>"
1603 [(parallel
1604 [(set (match_operand:VI_HW_QHS 0 "register_operand" "")
1605 (unspec:VI_HW_QHS [(match_operand:VI_HW_QHS 1 "register_operand" "")
1606 (match_operand:VI_HW_QHS 2 "register_operand" "")
1607 (match_operand:VI_HW_QHS 3 "register_operand" "")
1608 (match_operand:QI 4 "const_mask_operand" "")]
1609 UNSPEC_VEC_VSTRC))
1610 (set (reg:CCRAW CC_REGNUM)
1611 (unspec:CCRAW [(match_dup 1)
1612 (match_dup 2)
1613 (match_dup 3)
1614 (match_dup 4)]
1615 UNSPEC_VEC_VSTRCCC))])
1616 (set (match_operand:SI 5 "memory_operand" "")
1617 (unspec:SI [(reg:CCRAW CC_REGNUM)] UNSPEC_CC_TO_INT))]
1618 "TARGET_VX"
1619 {
1620 operands[4] = GEN_INT (INTVAL (operands[4]) | VSTRING_FLAG_CS);
1621 })
1622
1623 (define_expand "vstrczs<mode>"
1624 [(parallel
1625 [(set (match_operand:VI_HW_QHS 0 "register_operand" "")
1626 (unspec:VI_HW_QHS [(match_operand:VI_HW_QHS 1 "register_operand" "")
1627 (match_operand:VI_HW_QHS 2 "register_operand" "")
1628 (match_operand:VI_HW_QHS 3 "register_operand" "")
1629 (match_operand:QI 4 "const_mask_operand" "")]
1630 UNSPEC_VEC_VSTRC))
1631 (set (reg:CCRAW CC_REGNUM)
1632 (unspec:CCRAW [(match_dup 1)
1633 (match_dup 2)
1634 (match_dup 3)
1635 (match_dup 4)]
1636 UNSPEC_VEC_VSTRCCC))])
1637 (set (match_operand:SI 5 "memory_operand" "")
1638 (unspec:SI [(reg:CCRAW CC_REGNUM)] UNSPEC_CC_TO_INT))]
1639 "TARGET_VX"
1640 {
1641 operands[4] = GEN_INT (INTVAL (operands[4]) | VSTRING_FLAG_CS | VSTRING_FLAG_ZS);
1642 })
1643
1644 ; Vector string search
1645
1646 (define_expand "vstrs<mode>"
1647 [(parallel
1648 [(set (match_operand:V16QI 0 "register_operand" "")
1649 (unspec:V16QI [(match_operand:VI_HW_QHS 1 "register_operand" "")
1650 (match_operand:VI_HW_QHS 2 "register_operand" "")
1651 (match_operand:V16QI 3 "register_operand" "")
1652 (const_int 0)]
1653 UNSPEC_VEC_VSTRS))
1654 (set (reg:CCRAW CC_REGNUM)
1655 (unspec:CCRAW [(match_dup 1)
1656 (match_dup 2)
1657 (match_dup 3)
1658 (const_int 0)]
1659 UNSPEC_VEC_VSTRSCC))])
1660 (set (match_operand:SI 4 "memory_operand" "")
1661 (unspec:SI [(reg:CCRAW CC_REGNUM)] UNSPEC_CC_TO_INT))]
1662 "TARGET_VXE2")
1663
1664 (define_expand "vstrsz<mode>"
1665 [(parallel
1666 [(set (match_operand:V16QI 0 "register_operand" "")
1667 (unspec:V16QI [(match_operand:VI_HW_QHS 1 "register_operand" "")
1668 (match_operand:VI_HW_QHS 2 "register_operand" "")
1669 (match_operand:V16QI 3 "register_operand" "")
1670 (const_int VSTRING_FLAG_ZS)]
1671 UNSPEC_VEC_VSTRS))
1672 (set (reg:CCRAW CC_REGNUM)
1673 (unspec:CCRAW [(match_dup 1)
1674 (match_dup 2)
1675 (match_dup 3)
1676 (const_int VSTRING_FLAG_ZS)]
1677 UNSPEC_VEC_VSTRSCC))])
1678 (set (match_operand:SI 4 "memory_operand" "")
1679 (unspec:SI [(reg:CCRAW CC_REGNUM)] UNSPEC_CC_TO_INT))]
1680 "TARGET_VXE2")
1681
1682 ; vstrsb, vstrsh, vstrsf
1683 ; vstrszb, vstrszh, vstrszf
1684 (define_insn "vec_vstrs<mode>"
1685 [(set (match_operand:V16QI 0 "register_operand" "=v")
1686 (unspec:V16QI [(match_operand:VI_HW_QHS 1 "register_operand" "v")
1687 (match_operand:VI_HW_QHS 2 "register_operand" "v")
1688 (match_operand:V16QI 3 "register_operand" "v")
1689 (match_operand:QI 4 "const_mask_operand" "C")]
1690 UNSPEC_VEC_VSTRS))
1691 (set (reg:CCRAW CC_REGNUM)
1692 (unspec:CCRAW [(match_dup 1)
1693 (match_dup 2)
1694 (match_dup 3)
1695 (match_dup 4)]
1696 UNSPEC_VEC_VSTRSCC))]
1697 "TARGET_VXE2"
1698 {
1699 unsigned HOST_WIDE_INT flags = UINTVAL (operands[4]);
1700
1701 gcc_assert (!(flags & ~VSTRING_FLAG_ZS));
1702
1703 if (flags == VSTRING_FLAG_ZS)
1704 return "vstrsz<bhfgq>\t%v0,%v1,%v2,%v3";
1705 return "vstrs<bhfgq>\t%v0,%v1,%v2,%v3";
1706 }
1707 [(set_attr "op_type" "VRR")])
1708
1709
1710 ; Vector convert int<->float
1711
1712 (define_insn "vcdgb"
1713 [(set (match_operand:V2DF 0 "register_operand" "=v")
1714 (unspec:V2DF [(match_operand:V2DI 1 "register_operand" "v")
1715 (match_operand:QI 2 "const_mask_operand" "C") ; inexact suppression
1716 (match_operand:QI 3 "const_mask_operand" "C")] ; rounding mode
1717 UNSPEC_VEC_VCDGB))]
1718 "TARGET_VX && UINTVAL (operands[3]) != 2 && UINTVAL (operands[3]) <= 7"
1719 "vcdgb\t%v0,%v1,%b2,%b3"
1720 [(set_attr "op_type" "VRR")])
1721
1722
1723 ; The result needs to be multiplied with 2**-op2
1724 (define_expand "vec_ctd_s64"
1725 [(set (match_operand:V2DF 0 "register_operand" "")
1726 (unspec:V2DF [(match_operand:V2DI 1 "register_operand" "")
1727 (const_int VEC_NOINEXACT)
1728 (const_int VEC_RND_CURRENT)]
1729 UNSPEC_VEC_VCDGB))
1730 (use (match_operand:QI 2 "const_int_operand" ""))
1731 (set (match_dup 0) (mult:V2DF (match_dup 0) (match_dup 3)))]
1732 "TARGET_VX"
1733 {
1734 REAL_VALUE_TYPE f;
1735 rtx c;
1736
1737 real_2expN (&f, -INTVAL (operands[2]), DFmode);
1738 c = const_double_from_real_value (f, DFmode);
1739
1740 operands[3] = gen_const_vec_duplicate (V2DFmode, c);
1741 operands[3] = force_reg (V2DFmode, operands[3]);
1742 })
1743
1744 (define_insn "vcdlgb"
1745 [(set (match_operand:V2DF 0 "register_operand" "=v")
1746 (unspec:V2DF [(match_operand:V2DI 1 "register_operand" "v")
1747 (match_operand:QI 2 "const_mask_operand" "C") ; inexact suppression
1748 (match_operand:QI 3 "const_mask_operand" "C")] ; rounding mode
1749 UNSPEC_VEC_VCDLGB))]
1750 "TARGET_VX && UINTVAL (operands[3]) != 2 && UINTVAL (operands[3]) <= 7"
1751 "vcdlgb\t%v0,%v1,%b2,%b3"
1752 [(set_attr "op_type" "VRR")])
1753
1754 ; The result needs to be multiplied with 2**-op2
1755 (define_expand "vec_ctd_u64"
1756 [(set (match_operand:V2DF 0 "register_operand" "")
1757 (unspec:V2DF [(match_operand:V2DI 1 "register_operand" "")
1758 (const_int VEC_NOINEXACT)
1759 (const_int VEC_RND_CURRENT)]
1760 UNSPEC_VEC_VCDLGB))
1761 (use (match_operand:QI 2 "const_int_operand" ""))
1762 (set (match_dup 0) (mult:V2DF (match_dup 0) (match_dup 3)))]
1763 "TARGET_VX"
1764 {
1765 REAL_VALUE_TYPE f;
1766 rtx c;
1767
1768 real_2expN (&f, -INTVAL (operands[2]), DFmode);
1769 c = const_double_from_real_value (f, DFmode);
1770
1771 operands[3] = gen_const_vec_duplicate (V2DFmode, c);
1772 operands[3] = force_reg (V2DFmode, operands[3]);
1773 })
1774
1775 (define_insn "vcgdb"
1776 [(set (match_operand:V2DI 0 "register_operand" "=v")
1777 (unspec:V2DI [(match_operand:V2DF 1 "register_operand" "v")
1778 (match_operand:QI 2 "const_mask_operand" "C")
1779 (match_operand:QI 3 "const_mask_operand" "C")]
1780 UNSPEC_VEC_VCGDB))]
1781 "TARGET_VX && UINTVAL (operands[3]) != 2 && UINTVAL (operands[3]) <= 7"
1782 "vcgdb\t%v0,%v1,%b2,%b3"
1783 [(set_attr "op_type" "VRR")])
1784
1785 ; The input needs to be multiplied with 2**op2
1786 (define_expand "vec_ctsl"
1787 [(use (match_operand:QI 2 "const_int_operand" ""))
1788 (set (match_dup 4) (mult:V2DF (match_operand:V2DF 1 "register_operand" "")
1789 (match_dup 3)))
1790 (set (match_operand:V2DI 0 "register_operand" "")
1791 (unspec:V2DI [(match_dup 4)
1792 (const_int VEC_NOINEXACT)
1793 (const_int VEC_RND_CURRENT)]
1794 UNSPEC_VEC_VCGDB))]
1795 "TARGET_VX"
1796 {
1797 REAL_VALUE_TYPE f;
1798 rtx c;
1799
1800 real_2expN (&f, INTVAL (operands[2]), DFmode);
1801 c = const_double_from_real_value (f, DFmode);
1802
1803 operands[3] = gen_const_vec_duplicate (V2DFmode, c);
1804 operands[3] = force_reg (V2DFmode, operands[3]);
1805 operands[4] = gen_reg_rtx (V2DFmode);
1806 })
1807
1808 (define_insn "vclgdb"
1809 [(set (match_operand:V2DI 0 "register_operand" "=v")
1810 (unspec:V2DI [(match_operand:V2DF 1 "register_operand" "v")
1811 (match_operand:QI 2 "const_mask_operand" "C")
1812 (match_operand:QI 3 "const_mask_operand" "C")]
1813 UNSPEC_VEC_VCLGDB))]
1814 "TARGET_VX && UINTVAL (operands[3]) != 2 && UINTVAL (operands[3]) <= 7"
1815 "vclgdb\t%v0,%v1,%b2,%b3"
1816 [(set_attr "op_type" "VRR")])
1817
1818 ; The input needs to be multiplied with 2**op2
1819 (define_expand "vec_ctul"
1820 [(use (match_operand:QI 2 "const_int_operand" ""))
1821 (set (match_dup 4) (mult:V2DF (match_operand:V2DF 1 "register_operand" "")
1822 (match_dup 3)))
1823 (set (match_operand:V2DI 0 "register_operand" "")
1824 (unspec:V2DI [(match_dup 4)
1825 (const_int VEC_NOINEXACT)
1826 (const_int VEC_RND_CURRENT)]
1827 UNSPEC_VEC_VCLGDB))]
1828 "TARGET_VX"
1829 {
1830 REAL_VALUE_TYPE f;
1831 rtx c;
1832
1833 real_2expN (&f, INTVAL (operands[2]), DFmode);
1834 c = const_double_from_real_value (f, DFmode);
1835
1836 operands[3] = gen_const_vec_duplicate (V2DFmode, c);
1837 operands[3] = force_reg (V2DFmode, operands[3]);
1838 operands[4] = gen_reg_rtx (V2DFmode);
1839 })
1840
1841 ; Vector load fp integer - IEEE inexact exception is suppressed
1842 ; vfisb, vfidb, wfisb, wfidb, wfixb
1843 (define_insn "vec_fpint<mode>"
1844 [(set (match_operand:VFT 0 "register_operand" "=v")
1845 (unspec:VFT [(match_operand:VFT 1 "register_operand" "v")
1846 (match_operand:QI 2 "const_mask_operand" "C") ; inexact suppression control
1847 (match_operand:QI 3 "const_mask_operand" "C")] ; rounding mode
1848 UNSPEC_VEC_VFI))]
1849 "TARGET_VX"
1850 "<vw>fi<sdx>b\t%v0,%v1,%b2,%b3"
1851 [(set_attr "op_type" "VRR")])
1852
1853
1854 ; Vector load lengthened - V4SF -> V2DF
1855
1856 (define_insn "vflls"
1857 [(set (match_operand:V2DF 0 "register_operand" "=v")
1858 (unspec:V2DF [(match_operand:V4SF 1 "register_operand" "v")]
1859 UNSPEC_VEC_VFLL))]
1860 "TARGET_VX"
1861 "vldeb\t%v0,%v1"
1862 [(set_attr "op_type" "VRR")])
1863
1864 (define_expand "vec_ld2f"
1865 [; Initialize a vector to all zeroes. FIXME: This should not be
1866 ; necessary since all elements of the vector will be set anyway.
1867 ; This is just to make it explicit to the data flow framework.
1868 (set (match_dup 2) (match_dup 3))
1869 (set (match_dup 2) (unspec:V4SF [(match_operand:SF 1 "memory_operand" "")
1870 (const_int 0)
1871 (match_dup 2)]
1872 UNSPEC_VEC_SET))
1873 (set (match_dup 2) (unspec:V4SF [(match_dup 4)
1874 (const_int 2)
1875 (match_dup 2)]
1876 UNSPEC_VEC_SET))
1877 (set (match_operand:V2DF 0 "register_operand" "")
1878 (unspec:V2DF [(match_dup 2)] UNSPEC_VEC_VFLL))]
1879 "TARGET_VX"
1880 {
1881 operands[2] = gen_reg_rtx (V4SFmode);
1882 operands[3] = CONST0_RTX (V4SFmode);
1883 operands[4] = adjust_address (operands[1], SFmode, 4);
1884 })
1885
1886
1887 ; Vector load rounded - V2DF -> V4SF
1888
1889 (define_insn "vflrd"
1890 [(set (match_operand:V4SF 0 "register_operand" "=v")
1891 (unspec:V4SF [(match_operand:V2DF 1 "register_operand" "v")
1892 (match_operand:QI 2 "const_mask_operand" "C")
1893 (match_operand:QI 3 "const_mask_operand" "C")]
1894 UNSPEC_VEC_VFLR))]
1895 "TARGET_VX"
1896 "vledb\t%v0,%v1,%b2,%b3"
1897 [(set_attr "op_type" "VRR")])
1898
1899 (define_expand "vec_st2f"
1900 [(set (match_dup 2)
1901 (unspec:V4SF [(match_operand:V2DF 0 "register_operand" "")
1902 (const_int VEC_INEXACT)
1903 (const_int VEC_RND_CURRENT)]
1904 UNSPEC_VEC_VFLR))
1905 (set (match_operand:SF 1 "memory_operand" "")
1906 (vec_select:SF (match_dup 2)
1907 (parallel [(const_int 0)])))
1908 (set (match_dup 3)
1909 (vec_select:SF (match_dup 2)
1910 (parallel [(const_int 2)])))]
1911 "TARGET_VX"
1912 {
1913 operands[2] = gen_reg_rtx (V4SFmode);
1914 operands[3] = adjust_address (operands[1], SFmode, 4);
1915 })
1916
1917
1918 ; Vector square root fp vec_sqrt -> sqrt rtx standard name
1919
1920 ;; Vector FP test data class immediate
1921
1922 ; vec_all_nan, vec_all_numeric, vec_any_nan, vec_any_numeric
1923 ; These ignore the vector result and only want CC stored to an int
1924 ; pointer.
1925
1926 ; vftcisb, vftcidb, wftcixb
1927 (define_insn "*vftci<mode>_cconly"
1928 [(set (reg:CCRAW CC_REGNUM)
1929 (unspec:CCRAW [(match_operand:VF_HW 1 "register_operand" "v")
1930 (match_operand:HI 2 "const_int_operand" "J")]
1931 UNSPEC_VEC_VFTCICC))
1932 (clobber (match_scratch:<TOINTVEC> 0 "=v"))]
1933 "TARGET_VX && CONST_OK_FOR_CONSTRAINT_P (INTVAL (operands[2]), 'J', \"J\")"
1934 "<vw>ftci<sdx>b\t%v0,%v1,%x2"
1935 [(set_attr "op_type" "VRR")])
1936
1937 (define_expand "vftci<mode>_intcconly"
1938 [(parallel
1939 [(set (reg:CCRAW CC_REGNUM)
1940 (unspec:CCRAW [(match_operand:VF_HW 0 "register_operand")
1941 (match_operand:HI 1 "const_int_operand")]
1942 UNSPEC_VEC_VFTCICC))
1943 (clobber (scratch:<TOINTVEC>))])
1944 (set (match_operand:SI 2 "register_operand" "")
1945 (unspec:SI [(reg:CCRAW CC_REGNUM)] UNSPEC_CC_TO_INT))]
1946 "TARGET_VX && CONST_OK_FOR_CONSTRAINT_P (INTVAL (operands[1]), 'J', \"J\")")
1947
1948 ; vec_fp_test_data_class wants the result vector and the CC stored to
1949 ; an int pointer.
1950
1951 ; vftcisb, vftcidb, wftcixb
1952 (define_insn "vftci<mode>"
1953 [(set (match_operand:VF_HW 0 "register_operand" "=v")
1954 (unspec:VF_HW [(match_operand:VF_HW 1 "register_operand" "v")
1955 (match_operand:HI 2 "const_int_operand" "J")]
1956 UNSPEC_VEC_VFTCI))
1957 (set (reg:CCRAW CC_REGNUM)
1958 (unspec:CCRAW [(match_dup 1) (match_dup 2)] UNSPEC_VEC_VFTCICC))]
1959 "TARGET_VX && CONST_OK_FOR_CONSTRAINT_P (INTVAL (operands[2]), 'J', \"J\")"
1960 "<vw>ftci<sdx>b\t%v0,%v1,%x2"
1961 [(set_attr "op_type" "VRR")])
1962
1963 (define_expand "vftci<mode>_intcc"
1964 [(parallel
1965 [(set (match_operand:VF_HW 0 "register_operand")
1966 (unspec:VF_HW [(match_operand:VF_HW 1 "register_operand")
1967 (match_operand:HI 2 "const_int_operand")]
1968 UNSPEC_VEC_VFTCI))
1969 (set (reg:CCRAW CC_REGNUM)
1970 (unspec:CCRAW [(match_dup 1) (match_dup 2)] UNSPEC_VEC_VFTCICC))])
1971 (set (match_operand:SI 3 "nonimmediate_operand")
1972 (unspec:SI [(reg:CCRAW CC_REGNUM)] UNSPEC_CC_TO_INT))]
1973 "TARGET_VX && CONST_OK_FOR_CONSTRAINT_P (INTVAL (operands[2]), 'J', \"J\")")
1974
1975 ;;
1976 ;; Integer compares
1977 ;;
1978
1979 ; All comparisons which produce a CC need fully populated (VI_HW)
1980 ; vector arguments. Otherwise the any/all CCs would be just bogus.
1981
1982 (define_insn "*vec_cmp<VICMP:insn_cmp><VI_HW:mode>_cconly"
1983 [(set (reg:VICMP CC_REGNUM)
1984 (compare:VICMP (match_operand:VI_HW 0 "register_operand" "v")
1985 (match_operand:VI_HW 1 "register_operand" "v")))
1986 (clobber (match_scratch:VI_HW 2 "=v"))]
1987 "TARGET_VX"
1988 "vc<VICMP:insn_cmp><VI_HW:bhfgq>s\t%v2,%v0,%v1"
1989 [(set_attr "op_type" "VRR")])
1990
1991 ; FIXME: The following 2x3 definitions should be merged into 2 with
1992 ; VICMP like above but I could not find a way to set the comparison
1993 ; operator (eq) depending on the mode CCVEQ (mode_iterator). Or the
1994 ; other way around - setting the mode depending on the code
1995 ; (code_iterator).
1996 (define_expand "vec_cmpeq<VI_HW:mode>_cc"
1997 [(parallel
1998 [(set (reg:CCVEQ CC_REGNUM)
1999 (compare:CCVEQ (match_operand:VI_HW 1 "register_operand" "v")
2000 (match_operand:VI_HW 2 "register_operand" "v")))
2001 (set (match_operand:VI_HW 0 "register_operand" "=v")
2002 (eq:VI_HW (match_dup 1) (match_dup 2)))])
2003 (set (match_operand:SI 3 "memory_operand" "")
2004 (unspec:SI [(reg:CCVEQ CC_REGNUM)] UNSPEC_CC_TO_INT))]
2005 "TARGET_VX")
2006
2007 (define_expand "vec_cmph<VI_HW:mode>_cc"
2008 [(parallel
2009 [(set (reg:CCVIH CC_REGNUM)
2010 (compare:CCVIH (match_operand:VI_HW 1 "register_operand" "v")
2011 (match_operand:VI_HW 2 "register_operand" "v")))
2012 (set (match_operand:VI_HW 0 "register_operand" "=v")
2013 (gt:VI_HW (match_dup 1) (match_dup 2)))])
2014 (set (match_operand:SI 3 "memory_operand" "")
2015 (unspec:SI [(reg:CCVIH CC_REGNUM)] UNSPEC_CC_TO_INT))]
2016 "TARGET_VX")
2017
2018 (define_expand "vec_cmphl<VI_HW:mode>_cc"
2019 [(parallel
2020 [(set (reg:CCVIHU CC_REGNUM)
2021 (compare:CCVIHU (match_operand:VI_HW 1 "register_operand" "v")
2022 (match_operand:VI_HW 2 "register_operand" "v")))
2023 (set (match_operand:VI_HW 0 "register_operand" "=v")
2024 (gtu:VI_HW (match_dup 1) (match_dup 2)))])
2025 (set (match_operand:SI 3 "memory_operand" "")
2026 (unspec:SI [(reg:CCVIHU CC_REGNUM)] UNSPEC_CC_TO_INT))]
2027 "TARGET_VX")
2028
2029
2030 (define_insn "*vec_cmpeq<VI_HW:mode>_cc"
2031 [(set (reg:CCVEQ CC_REGNUM)
2032 (compare:CCVEQ (match_operand:VI_HW 0 "register_operand" "v")
2033 (match_operand:VI_HW 1 "register_operand" "v")))
2034 (set (match_operand:VI_HW 2 "register_operand" "=v")
2035 (eq:VI_HW (match_dup 0) (match_dup 1)))]
2036 "TARGET_VX"
2037 "vceq<VI_HW:bhfgq>s\t%v2,%v0,%v1"
2038 [(set_attr "op_type" "VRR")])
2039
2040 (define_insn "*vec_cmph<VI_HW:mode>_cc"
2041 [(set (reg:CCVIH CC_REGNUM)
2042 (compare:CCVIH (match_operand:VI_HW 0 "register_operand" "v")
2043 (match_operand:VI_HW 1 "register_operand" "v")))
2044 (set (match_operand:VI_HW 2 "register_operand" "=v")
2045 (gt:VI_HW (match_dup 0) (match_dup 1)))]
2046 "TARGET_VX"
2047 "vch<VI_HW:bhfgq>s\t%v2,%v0,%v1"
2048 [(set_attr "op_type" "VRR")])
2049
2050 (define_insn "*vec_cmphl<VI_HW:mode>_cc"
2051 [(set (reg:CCVIHU CC_REGNUM)
2052 (compare:CCVIHU (match_operand:VI_HW 0 "register_operand" "v")
2053 (match_operand:VI_HW 1 "register_operand" "v")))
2054 (set (match_operand:VI_HW 2 "register_operand" "=v")
2055 (gtu:VI_HW (match_dup 0) (match_dup 1)))]
2056 "TARGET_VX"
2057 "vchl<VI_HW:bhfgq>s\t%v2,%v0,%v1"
2058 [(set_attr "op_type" "VRR")])
2059
2060 ;;
2061 ;; Floating point compares
2062 ;;
2063
2064 ; vfcesbs, vfcedbs, wfcexbs, vfchsbs, vfchdbs, wfchxbs, vfchesbs, vfchedbs, wfchexbs
2065 (define_insn "*vec_cmp<insn_cmp><VF_HW:mode>_cconly"
2066 [(set (reg:VFCMP CC_REGNUM)
2067 (compare:VFCMP (match_operand:VF_HW 0 "register_operand" "v")
2068 (match_operand:VF_HW 1 "register_operand" "v")))
2069 (clobber (match_scratch:<TOINTVEC> 2 "=v"))]
2070 "TARGET_VX"
2071 "<vw>fc<asm_fcmp><sdx>bs\t%v2,%v0,%v1"
2072 [(set_attr "op_type" "VRR")])
2073
2074 ; FIXME: Merge the following 2x3 patterns with VFCMP
2075 (define_expand "vec_cmpeq<mode>_cc"
2076 [(parallel
2077 [(set (reg:CCVEQ CC_REGNUM)
2078 (compare:CCVEQ (match_operand:VF_HW 1 "register_operand" "v")
2079 (match_operand:VF_HW 2 "register_operand" "v")))
2080 (set (match_operand:<TOINTVEC> 0 "register_operand" "=v")
2081 (eq:<TOINTVEC> (match_dup 1) (match_dup 2)))])
2082 (set (match_operand:SI 3 "memory_operand" "")
2083 (unspec:SI [(reg:CCVEQ CC_REGNUM)] UNSPEC_CC_TO_INT))]
2084 "TARGET_VX")
2085
2086 (define_expand "vec_cmph<mode>_cc"
2087 [(parallel
2088 [(set (reg:CCVFH CC_REGNUM)
2089 (compare:CCVFH (match_operand:VF_HW 1 "register_operand" "v")
2090 (match_operand:VF_HW 2 "register_operand" "v")))
2091 (set (match_operand:<TOINTVEC> 0 "register_operand" "=v")
2092 (gt:<TOINTVEC> (match_dup 1) (match_dup 2)))])
2093 (set (match_operand:SI 3 "memory_operand" "")
2094 (unspec:SI [(reg:CCVIH CC_REGNUM)] UNSPEC_CC_TO_INT))]
2095 "TARGET_VX")
2096
2097 (define_expand "vec_cmphe<mode>_cc"
2098 [(parallel
2099 [(set (reg:CCVFHE CC_REGNUM)
2100 (compare:CCVFHE (match_operand:VF_HW 1 "register_operand" "v")
2101 (match_operand:VF_HW 2 "register_operand" "v")))
2102 (set (match_operand:<TOINTVEC> 0 "register_operand" "=v")
2103 (ge:<TOINTVEC> (match_dup 1) (match_dup 2)))])
2104 (set (match_operand:SI 3 "memory_operand" "")
2105 (unspec:SI [(reg:CCVFHE CC_REGNUM)] UNSPEC_CC_TO_INT))]
2106 "TARGET_VX")
2107
2108 ; These 3 cannot be merged as the insn defintion above since it also
2109 ; requires to rewrite the RTL equality operator that the same time as
2110 ; the CC mode.
2111
2112 ; vfcesbs, vfcedbs, wfcexbs
2113 (define_insn "*vec_cmpeq<mode>_cc"
2114 [(set (reg:CCVEQ CC_REGNUM)
2115 (compare:CCVEQ (match_operand:VF_HW 0 "register_operand" "v")
2116 (match_operand:VF_HW 1 "register_operand" "v")))
2117 (set (match_operand:<TOINTVEC> 2 "register_operand" "=v")
2118 (eq:<TOINTVEC> (match_dup 0) (match_dup 1)))]
2119 "TARGET_VX"
2120 "<vw>fce<sdx>bs\t%v2,%v0,%v1"
2121 [(set_attr "op_type" "VRR")])
2122
2123 ; vfchsbs, vfchdbs, wfchxbs
2124 (define_insn "*vec_cmph<mode>_cc"
2125 [(set (reg:CCVFH CC_REGNUM)
2126 (compare:CCVFH (match_operand:VF_HW 0 "register_operand" "v")
2127 (match_operand:VF_HW 1 "register_operand" "v")))
2128 (set (match_operand:<TOINTVEC> 2 "register_operand" "=v")
2129 (gt:<TOINTVEC> (match_dup 0) (match_dup 1)))]
2130 "TARGET_VX"
2131 "<vw>fch<sdx>bs\t%v2,%v0,%v1"
2132 [(set_attr "op_type" "VRR")])
2133
2134 ; vfchesbs, vfchedbs, wfchexbs
2135 (define_insn "*vec_cmphe<mode>_cc"
2136 [(set (reg:CCVFHE CC_REGNUM)
2137 (compare:CCVFHE (match_operand:VF_HW 0 "register_operand" "v")
2138 (match_operand:VF_HW 1 "register_operand" "v")))
2139 (set (match_operand:<TOINTVEC> 2 "register_operand" "=v")
2140 (ge:<TOINTVEC> (match_dup 0) (match_dup 1)))]
2141 "TARGET_VX"
2142 "<vw>fche<sdx>bs\t%v2,%v0,%v1"
2143 [(set_attr "op_type" "VRR")])
2144
2145
2146 (define_insn "vfmin<mode>"
2147 [(set (match_operand:VF_HW 0 "register_operand" "=v")
2148 (unspec:VF_HW [(match_operand:VF_HW 1 "register_operand" "v")
2149 (match_operand:VF_HW 2 "register_operand" "v")
2150 (match_operand:QI 3 "const_mask_operand" "C")]
2151 UNSPEC_VEC_VFMIN))]
2152 "TARGET_VXE"
2153 "<vw>fmin<sdx>b\t%v0,%v1,%v2,%b3"
2154 [(set_attr "op_type" "VRR")])
2155
2156 (define_insn "vfmax<mode>"
2157 [(set (match_operand:VF_HW 0 "register_operand" "=v")
2158 (unspec:VF_HW [(match_operand:VF_HW 1 "register_operand" "v")
2159 (match_operand:VF_HW 2 "register_operand" "v")
2160 (match_operand:QI 3 "const_mask_operand" "C")]
2161 UNSPEC_VEC_VFMAX))]
2162 "TARGET_VXE"
2163 "<vw>fmax<sdx>b\t%v0,%v1,%v2,%b3"
2164 [(set_attr "op_type" "VRR")])
2165
2166 ; vec_insert (__builtin_bswap32 (*a), b, 1) set-element-bswap-2.c
2167 ; b[1] = __builtin_bswap32 (*a) set-element-bswap-3.c
2168 ; vlebrh, vlebrf, vlebrg
2169 (define_insn "*vec_set_bswap_elem<mode>"
2170 [(set (match_operand:V_HW_HSD 0 "register_operand" "=v")
2171 (unspec:V_HW_HSD [(bswap:<non_vec> (match_operand:<non_vec> 1 "memory_operand" "R"))
2172 (match_operand:SI 2 "const_int_operand" "C")
2173 (match_operand:V_HW_HSD 3 "register_operand" "0")]
2174 UNSPEC_VEC_SET))]
2175 "TARGET_VXE2 && UINTVAL (operands[2]) < GET_MODE_NUNITS (<V_HW_HSD:MODE>mode)"
2176 "vlebr<bhfgq>\t%v0,%1,%2"
2177 [(set_attr "op_type" "VRX")])
2178
2179 ; vec_revb (vec_insert (*a, vec_revb (b), 1)) set-element-bswap-1.c
2180 ; vlebrh, vlebrf, vlebrg
2181 (define_insn "*vec_set_bswap_vec<mode>"
2182 [(set (match_operand:V_HW_HSD 0 "register_operand" "=v")
2183 (bswap:V_HW_HSD
2184 (unspec:V_HW_HSD [(match_operand:<non_vec> 1 "memory_operand" "R")
2185 (match_operand:SI 2 "const_int_operand" "C")
2186 (bswap:V_HW_HSD (match_operand:V_HW_HSD 3 "register_operand" "0"))]
2187 UNSPEC_VEC_SET)))
2188 (use (match_operand:V16QI 4 "permute_pattern_operand" "X"))]
2189 "TARGET_VXE2 && UINTVAL (operands[2]) < GET_MODE_NUNITS (<V_HW_HSD:MODE>mode)"
2190 "vlebr<bhfgq>\t%v0,%1,%2"
2191 [(set_attr "op_type" "VRX")])
2192
2193 ; *a = vec_extract (vec_revb (b), 1); get-element-bswap-3.c
2194 ; *a = vec_revb (b)[1]; get-element-bswap-4.c
2195 ; vstebrh, vstebrf, vstebrg
2196 (define_insn "*vec_extract_bswap_vec<mode>"
2197 [(set (match_operand:<non_vec> 0 "memory_operand" "=R")
2198 (vec_select:<non_vec>
2199 (bswap:V_HW_HSD (match_operand:V_HW_HSD 1 "register_operand" "v"))
2200 (parallel [(match_operand:SI 2 "const_int_operand" "C")])))]
2201 "TARGET_VXE2 && UINTVAL (operands[2]) < GET_MODE_NUNITS (<V_HW_HSD:MODE>mode)"
2202 "vstebr<bhfgq>\t%v1,%0,%2"
2203 [(set_attr "op_type" "VRX")])
2204
2205 ; *a = __builtin_bswap32 (vec_extract (b, 1)); get-element-bswap-1.c
2206 ; *a = __builtin_bswap32 (b[1]); get-element-bswap-2.c
2207 ; vstebrh, vstebrf, vstebrg
2208 (define_insn "*vec_extract_bswap_elem<mode>"
2209 [(set (match_operand:<non_vec> 0 "memory_operand" "=R")
2210 (bswap:<non_vec>
2211 (vec_select:<non_vec>
2212 (match_operand:V_HW_HSD 1 "register_operand" "v")
2213 (parallel [(match_operand:SI 2 "const_int_operand" "C")]))))]
2214 "TARGET_VXE2 && UINTVAL (operands[2]) < GET_MODE_NUNITS (<V_HW_HSD:MODE>mode)"
2215 "vstebr<bhfgq>\t%v1,%0,%2"
2216 [(set_attr "op_type" "VRX")])
2217
2218
2219 ;;
2220 ;; NNPA Facility
2221 ;;
2222
2223 (define_insn "vclfnhs_v8hi"
2224 [(set (match_operand:V4SF 0 "register_operand" "=v")
2225 (unspec:V4SF [(vec_select:V4HI
2226 (match_operand:V8HI 1 "register_operand" "v")
2227 (parallel [(const_int 0) (const_int 1) (const_int 2) (const_int 3)]))
2228 (match_operand:QI 2 "const_mask_operand" "C")]
2229 UNSPEC_NNPA_VCLFNHS_V8HI))]
2230 "TARGET_NNPA"
2231 "vclfnh\t%v0,%v1,2,%2"
2232 [(set_attr "op_type" "VRR")])
2233
2234 (define_insn "vclfnls_v8hi"
2235 [(set (match_operand:V4SF 0 "register_operand" "=v")
2236 (unspec:V4SF [(vec_select:V4HI
2237 (match_operand:V8HI 1 "register_operand" "v")
2238 (parallel [(const_int 4) (const_int 5) (const_int 6) (const_int 7)]))
2239 (match_operand:QI 2 "const_mask_operand" "C")]
2240 UNSPEC_NNPA_VCLFNLS_V8HI))]
2241 "TARGET_NNPA"
2242 "vclfnl\t%v0,%v1,2,%2"
2243 [(set_attr "op_type" "VRR")])
2244
2245 (define_insn "vcrnfs_v8hi"
2246 [(set (match_operand:V8HI 0 "register_operand" "=v")
2247 (unspec:V8HI [(match_operand:V4SF 1 "register_operand" "v")
2248 (match_operand:V4SF 2 "register_operand" "v")
2249 (match_operand:QI 3 "const_mask_operand" "C")]
2250 UNSPEC_NNPA_VCRNFS_V8HI))]
2251 "TARGET_NNPA"
2252 "vcrnf\t%v0,%v1,%v2,%3,2"
2253 [(set_attr "op_type" "VRR")])
2254
2255 (define_insn "vcfn_v8hi"
2256 [(set (match_operand:V8HI 0 "register_operand" "=v")
2257 (unspec:V8HI [(match_operand:V8HI 1 "register_operand" "v")
2258 (match_operand:QI 2 "const_mask_operand" "C")]
2259 UNSPEC_NNPA_VCFN_V8HI))]
2260 "TARGET_NNPA"
2261 "vcfn\t%v0,%v1,1,%2"
2262 [(set_attr "op_type" "VRR")])
2263
2264 (define_insn "vcnf_v8hi"
2265 [(set (match_operand:V8HI 0 "register_operand" "=v")
2266 (unspec:V8HI [(match_operand:V8HI 1 "register_operand" "v")
2267 (match_operand:QI 2 "const_mask_operand" "C")]
2268 UNSPEC_NNPA_VCNF_V8HI))]
2269 "TARGET_NNPA"
2270 "vcnf\t%v0,%v1,%2,1"
2271 [(set_attr "op_type" "VRR")])