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