]> git.ipfire.org Git - thirdparty/gcc.git/blame - gcc/config/rs6000/vector.md
Update copyright years.
[thirdparty/gcc.git] / gcc / config / rs6000 / vector.md
CommitLineData
29e6733c
MM
1;; Expander definitions for vector support between altivec & vsx. No
2;; instructions are in this file, this file provides the generic vector
3;; expander, and the actual vector instructions will be in altivec.md and
4;; vsx.md
a72c65c7 5
a5544970 6;; Copyright (C) 2009-2019 Free Software Foundation, Inc.
a72c65c7
MM
7;; Contributed by Michael Meissner <meissner@linux.vnet.ibm.com>
8
9;; This file is part of GCC.
10
11;; GCC is free software; you can redistribute it and/or modify it
12;; under the terms of the GNU General Public License as published
13;; by the Free Software Foundation; either version 3, or (at your
14;; option) any later version.
15
16;; GCC is distributed in the hope that it will be useful, but WITHOUT
17;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
18;; or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
19;; License for more details.
20
21;; You should have received a copy of the GNU General Public License
22;; along with GCC; see the file COPYING3. If not see
23;; <http://www.gnu.org/licenses/>.
24
25
26;; Vector int modes
a5965b52 27(define_mode_iterator VEC_I [V16QI V8HI V4SI V2DI])
a72c65c7 28
4bfc9db7
MM
29;; Vector int modes for parity
30(define_mode_iterator VEC_IP [V8HI
31 V4SI
32 V2DI
33 V1TI
4a89b7e7 34 TI])
4bfc9db7 35
a72c65c7 36;; Vector float modes
29e6733c 37(define_mode_iterator VEC_F [V4SF V2DF])
a72c65c7
MM
38
39;; Vector arithmetic modes
a5965b52 40(define_mode_iterator VEC_A [V16QI V8HI V4SI V2DI V4SF V2DF])
a72c65c7
MM
41
42;; Vector modes that need alginment via permutes
43(define_mode_iterator VEC_K [V16QI V8HI V4SI V4SF])
44
45;; Vector logical modes
c477a667 46(define_mode_iterator VEC_L [V16QI V8HI V4SI V2DI V4SF V2DF V1TI TI KF TF])
a72c65c7 47
c477a667
MM
48;; Vector modes for moves. Don't do TImode or TFmode here, since their
49;; moves are handled elsewhere.
50(define_mode_iterator VEC_M [V16QI V8HI V4SI V2DI V4SF V2DF V1TI KF])
a72c65c7 51
29e6733c 52;; Vector modes for types that don't need a realignment under VSX
c477a667 53(define_mode_iterator VEC_N [V4SI V4SF V2DI V2DF V1TI KF TF])
29e6733c 54
a72c65c7 55;; Vector comparison modes
a5965b52 56(define_mode_iterator VEC_C [V16QI V8HI V4SI V2DI V4SF V2DF])
a72c65c7
MM
57
58;; Vector init/extract modes
59(define_mode_iterator VEC_E [V16QI V8HI V4SI V2DI V4SF V2DF])
60
2fcd8e02
MM
61;; Vector modes for 64-bit base types
62(define_mode_iterator VEC_64 [V2DI V2DF])
63
902cb7b1
KN
64;; Vector integer modes
65(define_mode_iterator VI [V4SI V8HI V16QI])
66
a72c65c7
MM
67;; Base type from vector mode
68(define_mode_attr VEC_base [(V16QI "QI")
69 (V8HI "HI")
70 (V4SI "SI")
71 (V2DI "DI")
72 (V4SF "SF")
73 (V2DF "DF")
a16a872d 74 (V1TI "TI")
a72c65c7
MM
75 (TI "TI")])
76
ff03930a
JJ
77;; As above, but in lower case
78(define_mode_attr VEC_base_l [(V16QI "qi")
79 (V8HI "hi")
80 (V4SI "si")
81 (V2DI "di")
82 (V4SF "sf")
83 (V2DF "df")
84 (V1TI "ti")
85 (TI "ti")])
86
a72c65c7
MM
87;; Same size integer type for floating point data
88(define_mode_attr VEC_int [(V4SF "v4si")
89 (V2DF "v2di")])
90
91(define_mode_attr VEC_INT [(V4SF "V4SI")
92 (V2DF "V2DI")])
93
94;; constants for unspec
df10b6d4 95(define_c_enum "unspec" [UNSPEC_PREDICATE
902cb7b1
KN
96 UNSPEC_REDUC
97 UNSPEC_NEZ_P])
df10b6d4
MM
98
99;; Vector reduction code iterators
100(define_code_iterator VEC_reduc [plus smin smax])
101
5e8edf67 102(define_code_attr VEC_reduc_name [(plus "plus")
df10b6d4
MM
103 (smin "smin")
104 (smax "smax")])
105
106(define_code_attr VEC_reduc_rtx [(plus "add")
107 (smin "smin")
108 (smax "smax")])
a72c65c7
MM
109
110\f
0cf68694
BS
111;; Vector move instructions. Little-endian VSX loads and stores require
112;; special handling to circumvent "element endianness."
a72c65c7 113(define_expand "mov<mode>"
ad18eed2
SB
114 [(set (match_operand:VEC_M 0 "nonimmediate_operand")
115 (match_operand:VEC_M 1 "any_operand"))]
29e6733c 116 "VECTOR_MEM_ALTIVEC_OR_VSX_P (<MODE>mode)"
a72c65c7
MM
117{
118 if (can_create_pseudo_p ())
119 {
c477a667
MM
120 if (CONSTANT_P (operands[1]))
121 {
122 if (FLOAT128_VECTOR_P (<MODE>mode))
123 {
124 if (!easy_fp_constant (operands[1], <MODE>mode))
125 operands[1] = force_const_mem (<MODE>mode, operands[1]);
126 }
127 else if (!easy_vector_constant (operands[1], <MODE>mode))
128 operands[1] = force_const_mem (<MODE>mode, operands[1]);
129 }
130
131 if (!vlogical_operand (operands[0], <MODE>mode)
132 && !vlogical_operand (operands[1], <MODE>mode))
a72c65c7
MM
133 operands[1] = force_reg (<MODE>mode, operands[1]);
134 }
75a741e8
PB
135 /* When generating load/store instructions to/from VSX registers on
136 pre-power9 hardware in little endian mode, we need to emit register
137 permute instructions to byte swap the contents, since the VSX load/store
138 instructions do not include a byte swap as part of their operation.
139 Altivec loads and stores have no such problem, so we skip them below. */
0cf68694
BS
140 if (!BYTES_BIG_ENDIAN
141 && VECTOR_MEM_VSX_P (<MODE>mode)
5d57fdc1 142 && !TARGET_P9_VECTOR
2d04cc30 143 && !gpr_or_gpr_p (operands[0], operands[1])
75a741e8
PB
144 && ((memory_operand (operands[0], <MODE>mode)
145 && !altivec_indexed_or_indirect_operand(operands[0], <MODE>mode))
146 ^ (memory_operand (operands[1], <MODE>mode)
147 && !altivec_indexed_or_indirect_operand(operands[1], <MODE>mode))))
0cf68694
BS
148 {
149 rs6000_emit_le_vsx_move (operands[0], operands[1], <MODE>mode);
150 DONE;
151 }
a72c65c7
MM
152})
153
29e6733c
MM
154;; Generic vector floating point load/store instructions. These will match
155;; insns defined in vsx.md or altivec.md depending on the switches.
a72c65c7 156(define_expand "vector_load_<mode>"
ad18eed2
SB
157 [(set (match_operand:VEC_M 0 "vfloat_operand")
158 (match_operand:VEC_M 1 "memory_operand"))]
29e6733c 159 "VECTOR_MEM_ALTIVEC_OR_VSX_P (<MODE>mode)"
a72c65c7
MM
160 "")
161
162(define_expand "vector_store_<mode>"
ad18eed2
SB
163 [(set (match_operand:VEC_M 0 "memory_operand")
164 (match_operand:VEC_M 1 "vfloat_operand"))]
29e6733c 165 "VECTOR_MEM_ALTIVEC_OR_VSX_P (<MODE>mode)"
a72c65c7
MM
166 "")
167
168;; Splits if a GPR register was chosen for the move
169(define_split
ad18eed2
SB
170 [(set (match_operand:VEC_L 0 "nonimmediate_operand")
171 (match_operand:VEC_L 1 "input_operand"))]
29e6733c 172 "VECTOR_MEM_ALTIVEC_OR_VSX_P (<MODE>mode)
a72c65c7 173 && reload_completed
19be72ab
MM
174 && gpr_or_gpr_p (operands[0], operands[1])
175 && !direct_move_p (operands[0], operands[1])
176 && !quad_load_store_p (operands[0], operands[1])"
a72c65c7
MM
177 [(pc)]
178{
179 rs6000_split_multireg_move (operands[0], operands[1]);
180 DONE;
181})
182
a72c65c7
MM
183\f
184;; Generic floating point vector arithmetic support
185(define_expand "add<mode>3"
ad18eed2
SB
186 [(set (match_operand:VEC_F 0 "vfloat_operand")
187 (plus:VEC_F (match_operand:VEC_F 1 "vfloat_operand")
188 (match_operand:VEC_F 2 "vfloat_operand")))]
29e6733c 189 "VECTOR_UNIT_ALTIVEC_OR_VSX_P (<MODE>mode)"
a72c65c7
MM
190 "")
191
192(define_expand "sub<mode>3"
ad18eed2
SB
193 [(set (match_operand:VEC_F 0 "vfloat_operand")
194 (minus:VEC_F (match_operand:VEC_F 1 "vfloat_operand")
195 (match_operand:VEC_F 2 "vfloat_operand")))]
29e6733c 196 "VECTOR_UNIT_ALTIVEC_OR_VSX_P (<MODE>mode)"
a72c65c7
MM
197 "")
198
199(define_expand "mul<mode>3"
ad18eed2
SB
200 [(set (match_operand:VEC_F 0 "vfloat_operand")
201 (mult:VEC_F (match_operand:VEC_F 1 "vfloat_operand")
202 (match_operand:VEC_F 2 "vfloat_operand")))]
c6d5ff83 203 "VECTOR_UNIT_ALTIVEC_OR_VSX_P (<MODE>mode)"
a72c65c7 204{
29e6733c
MM
205 if (<MODE>mode == V4SFmode && VECTOR_UNIT_ALTIVEC_P (<MODE>mode))
206 {
207 emit_insn (gen_altivec_mulv4sf3 (operands[0], operands[1], operands[2]));
208 DONE;
209 }
d6613781 210})
a72c65c7 211
29e6733c 212(define_expand "div<mode>3"
ad18eed2
SB
213 [(set (match_operand:VEC_F 0 "vfloat_operand")
214 (div:VEC_F (match_operand:VEC_F 1 "vfloat_operand")
215 (match_operand:VEC_F 2 "vfloat_operand")))]
29e6733c 216 "VECTOR_UNIT_VSX_P (<MODE>mode)"
b7fa8414
SB
217{
218 if (RS6000_RECIP_AUTO_RE_P (<MODE>mode)
219 && can_create_pseudo_p () && flag_finite_math_only
220 && !flag_trapping_math && flag_reciprocal_math)
221 {
222 rs6000_emit_swdiv (operands[0], operands[1], operands[2], true);
223 DONE;
224 }
225})
29e6733c 226
a72c65c7 227(define_expand "neg<mode>2"
ad18eed2
SB
228 [(set (match_operand:VEC_F 0 "vfloat_operand")
229 (neg:VEC_F (match_operand:VEC_F 1 "vfloat_operand")))]
29e6733c 230 "VECTOR_UNIT_ALTIVEC_OR_VSX_P (<MODE>mode)"
a72c65c7 231{
29e6733c
MM
232 if (<MODE>mode == V4SFmode && VECTOR_UNIT_ALTIVEC_P (<MODE>mode))
233 {
234 emit_insn (gen_altivec_negv4sf2 (operands[0], operands[1]));
235 DONE;
236 }
6c332313 237})
a72c65c7
MM
238
239(define_expand "abs<mode>2"
ad18eed2
SB
240 [(set (match_operand:VEC_F 0 "vfloat_operand")
241 (abs:VEC_F (match_operand:VEC_F 1 "vfloat_operand")))]
29e6733c 242 "VECTOR_UNIT_ALTIVEC_OR_VSX_P (<MODE>mode)"
a72c65c7 243{
29e6733c
MM
244 if (<MODE>mode == V4SFmode && VECTOR_UNIT_ALTIVEC_P (<MODE>mode))
245 {
246 emit_insn (gen_altivec_absv4sf2 (operands[0], operands[1]));
247 DONE;
248 }
6c332313 249})
a72c65c7
MM
250
251(define_expand "smin<mode>3"
ad18eed2
SB
252 [(set (match_operand:VEC_F 0 "register_operand")
253 (smin:VEC_F (match_operand:VEC_F 1 "register_operand")
254 (match_operand:VEC_F 2 "register_operand")))]
29e6733c 255 "VECTOR_UNIT_ALTIVEC_OR_VSX_P (<MODE>mode)"
a72c65c7
MM
256 "")
257
258(define_expand "smax<mode>3"
ad18eed2
SB
259 [(set (match_operand:VEC_F 0 "register_operand")
260 (smax:VEC_F (match_operand:VEC_F 1 "register_operand")
261 (match_operand:VEC_F 2 "register_operand")))]
29e6733c 262 "VECTOR_UNIT_ALTIVEC_OR_VSX_P (<MODE>mode)"
a72c65c7
MM
263 "")
264
265
29e6733c 266(define_expand "sqrt<mode>2"
ad18eed2
SB
267 [(set (match_operand:VEC_F 0 "vfloat_operand")
268 (sqrt:VEC_F (match_operand:VEC_F 1 "vfloat_operand")))]
29e6733c 269 "VECTOR_UNIT_VSX_P (<MODE>mode)"
11c7bfe6
DE
270{
271 if (<MODE>mode == V4SFmode
272 && !optimize_function_for_size_p (cfun)
273 && flag_finite_math_only && !flag_trapping_math
274 && flag_unsafe_math_optimizations)
275 {
276 rs6000_emit_swsqrt (operands[0], operands[1], 0);
277 DONE;
278 }
279})
29e6733c 280
92902797 281(define_expand "rsqrte<mode>2"
ad18eed2
SB
282 [(set (match_operand:VEC_F 0 "vfloat_operand")
283 (unspec:VEC_F [(match_operand:VEC_F 1 "vfloat_operand")]
92902797
MM
284 UNSPEC_RSQRT))]
285 "VECTOR_UNIT_ALTIVEC_OR_VSX_P (<MODE>mode)"
286 "")
287
288(define_expand "re<mode>2"
ad18eed2
SB
289 [(set (match_operand:VEC_F 0 "vfloat_operand")
290 (unspec:VEC_F [(match_operand:VEC_F 1 "vfloat_operand")]
92902797
MM
291 UNSPEC_FRES))]
292 "VECTOR_UNIT_ALTIVEC_OR_VSX_P (<MODE>mode)"
293 "")
294
a72c65c7 295(define_expand "ftrunc<mode>2"
ad18eed2
SB
296 [(set (match_operand:VEC_F 0 "vfloat_operand")
297 (fix:VEC_F (match_operand:VEC_F 1 "vfloat_operand")))]
29e6733c
MM
298 "VECTOR_UNIT_ALTIVEC_OR_VSX_P (<MODE>mode)"
299 "")
300
301(define_expand "vector_ceil<mode>2"
ad18eed2
SB
302 [(set (match_operand:VEC_F 0 "vfloat_operand")
303 (unspec:VEC_F [(match_operand:VEC_F 1 "vfloat_operand")]
29e6733c
MM
304 UNSPEC_FRIP))]
305 "VECTOR_UNIT_ALTIVEC_OR_VSX_P (<MODE>mode)"
306 "")
307
308(define_expand "vector_floor<mode>2"
ad18eed2
SB
309 [(set (match_operand:VEC_F 0 "vfloat_operand")
310 (unspec:VEC_F [(match_operand:VEC_F 1 "vfloat_operand")]
29e6733c
MM
311 UNSPEC_FRIM))]
312 "VECTOR_UNIT_ALTIVEC_OR_VSX_P (<MODE>mode)"
a72c65c7
MM
313 "")
314
29e6733c 315(define_expand "vector_btrunc<mode>2"
ad18eed2
SB
316 [(set (match_operand:VEC_F 0 "vfloat_operand")
317 (fix:VEC_F (match_operand:VEC_F 1 "vfloat_operand")))]
29e6733c
MM
318 "VECTOR_UNIT_ALTIVEC_OR_VSX_P (<MODE>mode)"
319 "")
320
321(define_expand "vector_copysign<mode>3"
ad18eed2
SB
322 [(set (match_operand:VEC_F 0 "vfloat_operand")
323 (unspec:VEC_F [(match_operand:VEC_F 1 "vfloat_operand")
324 (match_operand:VEC_F 2 "vfloat_operand")] UNSPEC_COPYSIGN))]
29e6733c 325 "VECTOR_UNIT_ALTIVEC_OR_VSX_P (<MODE>mode)"
29e6733c
MM
326{
327 if (<MODE>mode == V4SFmode && VECTOR_UNIT_ALTIVEC_P (<MODE>mode))
328 {
329 emit_insn (gen_altivec_copysign_v4sf3 (operands[0], operands[1],
330 operands[2]));
331 DONE;
332 }
6c332313 333})
29e6733c 334
a72c65c7
MM
335\f
336;; Vector comparisons
e9e1d143 337(define_expand "vcond<mode><mode>"
ad18eed2 338 [(set (match_operand:VEC_F 0 "vfloat_operand")
a72c65c7
MM
339 (if_then_else:VEC_F
340 (match_operator 3 "comparison_operator"
ad18eed2
SB
341 [(match_operand:VEC_F 4 "vfloat_operand")
342 (match_operand:VEC_F 5 "vfloat_operand")])
343 (match_operand:VEC_F 1 "vfloat_operand")
344 (match_operand:VEC_F 2 "vfloat_operand")))]
29e6733c 345 "VECTOR_UNIT_ALTIVEC_OR_VSX_P (<MODE>mode)"
a72c65c7
MM
346{
347 if (rs6000_emit_vector_cond_expr (operands[0], operands[1], operands[2],
348 operands[3], operands[4], operands[5]))
349 DONE;
350 else
351 FAIL;
6c332313 352})
a72c65c7 353
e9e1d143 354(define_expand "vcond<mode><mode>"
391675ac 355 [(set (match_operand:VEC_I 0 "vint_operand")
a72c65c7
MM
356 (if_then_else:VEC_I
357 (match_operator 3 "comparison_operator"
391675ac
MM
358 [(match_operand:VEC_I 4 "vint_operand")
359 (match_operand:VEC_I 5 "vint_operand")])
360 (match_operand:VEC_I 1 "vector_int_reg_or_same_bit")
361 (match_operand:VEC_I 2 "vector_int_reg_or_same_bit")))]
c6d5ff83 362 "VECTOR_UNIT_ALTIVEC_OR_VSX_P (<MODE>mode)"
a72c65c7
MM
363{
364 if (rs6000_emit_vector_cond_expr (operands[0], operands[1], operands[2],
365 operands[3], operands[4], operands[5]))
366 DONE;
367 else
368 FAIL;
6c332313 369})
a72c65c7 370
69d3d957 371(define_expand "vcondv4sfv4si"
ad18eed2 372 [(set (match_operand:V4SF 0 "vfloat_operand")
69d3d957
JJ
373 (if_then_else:V4SF
374 (match_operator 3 "comparison_operator"
ad18eed2
SB
375 [(match_operand:V4SI 4 "vint_operand")
376 (match_operand:V4SI 5 "vint_operand")])
377 (match_operand:V4SF 1 "vfloat_operand")
378 (match_operand:V4SF 2 "vfloat_operand")))]
69d3d957
JJ
379 "VECTOR_UNIT_ALTIVEC_OR_VSX_P (V4SFmode)
380 && VECTOR_UNIT_ALTIVEC_P (V4SImode)"
69d3d957
JJ
381{
382 if (rs6000_emit_vector_cond_expr (operands[0], operands[1], operands[2],
383 operands[3], operands[4], operands[5]))
384 DONE;
385 else
386 FAIL;
6c332313 387})
69d3d957
JJ
388
389(define_expand "vcondv4siv4sf"
ad18eed2 390 [(set (match_operand:V4SI 0 "vint_operand")
69d3d957
JJ
391 (if_then_else:V4SI
392 (match_operator 3 "comparison_operator"
ad18eed2
SB
393 [(match_operand:V4SF 4 "vfloat_operand")
394 (match_operand:V4SF 5 "vfloat_operand")])
395 (match_operand:V4SI 1 "vint_operand")
396 (match_operand:V4SI 2 "vint_operand")))]
69d3d957
JJ
397 "VECTOR_UNIT_ALTIVEC_OR_VSX_P (V4SFmode)
398 && VECTOR_UNIT_ALTIVEC_P (V4SImode)"
69d3d957
JJ
399{
400 if (rs6000_emit_vector_cond_expr (operands[0], operands[1], operands[2],
401 operands[3], operands[4], operands[5]))
402 DONE;
403 else
404 FAIL;
6c332313 405})
69d3d957 406
95e5bea0
BS
407(define_expand "vcondv2dfv2di"
408 [(set (match_operand:V2DF 0 "vfloat_operand")
409 (if_then_else:V2DF
410 (match_operator 3 "comparison_operator"
411 [(match_operand:V2DI 4 "vint_operand")
412 (match_operand:V2DI 5 "vint_operand")])
413 (match_operand:V2DF 1 "vfloat_operand")
414 (match_operand:V2DF 2 "vfloat_operand")))]
415 "VECTOR_UNIT_ALTIVEC_OR_VSX_P (V2DFmode)
416 && VECTOR_UNIT_ALTIVEC_OR_VSX_P (V2DImode)"
417{
418 if (rs6000_emit_vector_cond_expr (operands[0], operands[1], operands[2],
419 operands[3], operands[4], operands[5]))
420 DONE;
421 else
422 FAIL;
423})
424
425(define_expand "vcondv2div2df"
426 [(set (match_operand:V2DI 0 "vint_operand")
427 (if_then_else:V2DI
428 (match_operator 3 "comparison_operator"
429 [(match_operand:V2DF 4 "vfloat_operand")
430 (match_operand:V2DF 5 "vfloat_operand")])
431 (match_operand:V2DI 1 "vint_operand")
432 (match_operand:V2DI 2 "vint_operand")))]
433 "VECTOR_UNIT_ALTIVEC_OR_VSX_P (V2DFmode)
434 && VECTOR_UNIT_ALTIVEC_OR_VSX_P (V2DImode)"
435{
436 if (rs6000_emit_vector_cond_expr (operands[0], operands[1], operands[2],
437 operands[3], operands[4], operands[5]))
438 DONE;
439 else
440 FAIL;
441})
442
e9e1d143 443(define_expand "vcondu<mode><mode>"
391675ac 444 [(set (match_operand:VEC_I 0 "vint_operand")
a72c65c7
MM
445 (if_then_else:VEC_I
446 (match_operator 3 "comparison_operator"
391675ac
MM
447 [(match_operand:VEC_I 4 "vint_operand")
448 (match_operand:VEC_I 5 "vint_operand")])
449 (match_operand:VEC_I 1 "vector_int_reg_or_same_bit")
450 (match_operand:VEC_I 2 "vector_int_reg_or_same_bit")))]
c6d5ff83 451 "VECTOR_UNIT_ALTIVEC_OR_VSX_P (<MODE>mode)"
a72c65c7
MM
452{
453 if (rs6000_emit_vector_cond_expr (operands[0], operands[1], operands[2],
454 operands[3], operands[4], operands[5]))
455 DONE;
456 else
457 FAIL;
6c332313 458})
a72c65c7 459
69d3d957 460(define_expand "vconduv4sfv4si"
ad18eed2 461 [(set (match_operand:V4SF 0 "vfloat_operand")
69d3d957
JJ
462 (if_then_else:V4SF
463 (match_operator 3 "comparison_operator"
ad18eed2
SB
464 [(match_operand:V4SI 4 "vint_operand")
465 (match_operand:V4SI 5 "vint_operand")])
466 (match_operand:V4SF 1 "vfloat_operand")
467 (match_operand:V4SF 2 "vfloat_operand")))]
69d3d957
JJ
468 "VECTOR_UNIT_ALTIVEC_OR_VSX_P (V4SFmode)
469 && VECTOR_UNIT_ALTIVEC_P (V4SImode)"
69d3d957
JJ
470{
471 if (rs6000_emit_vector_cond_expr (operands[0], operands[1], operands[2],
472 operands[3], operands[4], operands[5]))
473 DONE;
474 else
475 FAIL;
6c332313 476})
69d3d957 477
95e5bea0
BS
478(define_expand "vconduv2dfv2di"
479 [(set (match_operand:V2DF 0 "vfloat_operand")
480 (if_then_else:V2DF
481 (match_operator 3 "comparison_operator"
482 [(match_operand:V2DI 4 "vint_operand")
483 (match_operand:V2DI 5 "vint_operand")])
484 (match_operand:V2DF 1 "vfloat_operand")
485 (match_operand:V2DF 2 "vfloat_operand")))]
486 "VECTOR_UNIT_ALTIVEC_OR_VSX_P (V2DFmode)
487 && VECTOR_UNIT_ALTIVEC_OR_VSX_P (V2DImode)"
488{
489 if (rs6000_emit_vector_cond_expr (operands[0], operands[1], operands[2],
490 operands[3], operands[4], operands[5]))
491 DONE;
492 else
493 FAIL;
494})
495
a72c65c7 496(define_expand "vector_eq<mode>"
ad18eed2
SB
497 [(set (match_operand:VEC_C 0 "vlogical_operand")
498 (eq:VEC_C (match_operand:VEC_C 1 "vlogical_operand")
499 (match_operand:VEC_C 2 "vlogical_operand")))]
29e6733c 500 "VECTOR_UNIT_ALTIVEC_OR_VSX_P (<MODE>mode)"
a72c65c7
MM
501 "")
502
503(define_expand "vector_gt<mode>"
ad18eed2
SB
504 [(set (match_operand:VEC_C 0 "vlogical_operand")
505 (gt:VEC_C (match_operand:VEC_C 1 "vlogical_operand")
506 (match_operand:VEC_C 2 "vlogical_operand")))]
29e6733c 507 "VECTOR_UNIT_ALTIVEC_OR_VSX_P (<MODE>mode)"
a72c65c7
MM
508 "")
509
510(define_expand "vector_ge<mode>"
ad18eed2
SB
511 [(set (match_operand:VEC_F 0 "vlogical_operand")
512 (ge:VEC_F (match_operand:VEC_F 1 "vlogical_operand")
513 (match_operand:VEC_F 2 "vlogical_operand")))]
29e6733c 514 "VECTOR_UNIT_ALTIVEC_OR_VSX_P (<MODE>mode)"
a72c65c7
MM
515 "")
516
a05d02b2
BS
517; >= for integer vectors: swap operands and apply not-greater-than
518(define_expand "vector_nlt<mode>"
ad18eed2
SB
519 [(set (match_operand:VEC_I 3 "vlogical_operand")
520 (gt:VEC_I (match_operand:VEC_I 2 "vlogical_operand")
521 (match_operand:VEC_I 1 "vlogical_operand")))
522 (set (match_operand:VEC_I 0 "vlogical_operand")
a05d02b2
BS
523 (not:VEC_I (match_dup 3)))]
524 "VECTOR_UNIT_ALTIVEC_OR_VSX_P (<MODE>mode)"
a05d02b2
BS
525{
526 operands[3] = gen_reg_rtx_and_attrs (operands[0]);
6c332313 527})
a05d02b2 528
a72c65c7 529(define_expand "vector_gtu<mode>"
ad18eed2
SB
530 [(set (match_operand:VEC_I 0 "vint_operand")
531 (gtu:VEC_I (match_operand:VEC_I 1 "vint_operand")
532 (match_operand:VEC_I 2 "vint_operand")))]
c6d5ff83 533 "VECTOR_UNIT_ALTIVEC_OR_VSX_P (<MODE>mode)"
a72c65c7
MM
534 "")
535
a05d02b2
BS
536; >= for integer vectors: swap operands and apply not-greater-than
537(define_expand "vector_nltu<mode>"
ad18eed2
SB
538 [(set (match_operand:VEC_I 3 "vlogical_operand")
539 (gtu:VEC_I (match_operand:VEC_I 2 "vlogical_operand")
540 (match_operand:VEC_I 1 "vlogical_operand")))
541 (set (match_operand:VEC_I 0 "vlogical_operand")
a05d02b2
BS
542 (not:VEC_I (match_dup 3)))]
543 "VECTOR_UNIT_ALTIVEC_OR_VSX_P (<MODE>mode)"
a05d02b2
BS
544{
545 operands[3] = gen_reg_rtx_and_attrs (operands[0]);
6c332313 546})
a05d02b2 547
a72c65c7 548(define_expand "vector_geu<mode>"
ad18eed2
SB
549 [(set (match_operand:VEC_I 0 "vint_operand")
550 (geu:VEC_I (match_operand:VEC_I 1 "vint_operand")
551 (match_operand:VEC_I 2 "vint_operand")))]
c6d5ff83 552 "VECTOR_UNIT_ALTIVEC_OR_VSX_P (<MODE>mode)"
a72c65c7
MM
553 "")
554
a05d02b2
BS
555; <= for integer vectors: apply not-greater-than
556(define_expand "vector_ngt<mode>"
ad18eed2
SB
557 [(set (match_operand:VEC_I 3 "vlogical_operand")
558 (gt:VEC_I (match_operand:VEC_I 1 "vlogical_operand")
559 (match_operand:VEC_I 2 "vlogical_operand")))
560 (set (match_operand:VEC_I 0 "vlogical_operand")
a05d02b2
BS
561 (not:VEC_I (match_dup 3)))]
562 "VECTOR_UNIT_ALTIVEC_OR_VSX_P (<MODE>mode)"
a05d02b2
BS
563{
564 operands[3] = gen_reg_rtx_and_attrs (operands[0]);
6c332313 565})
a05d02b2
BS
566
567(define_expand "vector_ngtu<mode>"
ad18eed2
SB
568 [(set (match_operand:VEC_I 3 "vlogical_operand")
569 (gtu:VEC_I (match_operand:VEC_I 1 "vlogical_operand")
570 (match_operand:VEC_I 2 "vlogical_operand")))
571 (set (match_operand:VEC_I 0 "vlogical_operand")
a05d02b2
BS
572 (not:VEC_I (match_dup 3)))]
573 "VECTOR_UNIT_ALTIVEC_OR_VSX_P (<MODE>mode)"
a05d02b2
BS
574{
575 operands[3] = gen_reg_rtx_and_attrs (operands[0]);
6c332313 576})
a05d02b2 577
46402cbe 578(define_insn_and_split "*vector_uneq<mode>"
ad18eed2
SB
579 [(set (match_operand:VEC_F 0 "vfloat_operand")
580 (uneq:VEC_F (match_operand:VEC_F 1 "vfloat_operand")
581 (match_operand:VEC_F 2 "vfloat_operand")))]
46402cbe
MM
582 "VECTOR_UNIT_ALTIVEC_OR_VSX_P (<MODE>mode)"
583 "#"
584 ""
585 [(set (match_dup 3)
586 (gt:VEC_F (match_dup 1)
587 (match_dup 2)))
588 (set (match_dup 4)
589 (gt:VEC_F (match_dup 2)
590 (match_dup 1)))
591 (set (match_dup 0)
ba0ece39
SB
592 (and:VEC_F (not:VEC_F (match_dup 3))
593 (not:VEC_F (match_dup 4))))]
46402cbe
MM
594{
595 operands[3] = gen_reg_rtx (<MODE>mode);
596 operands[4] = gen_reg_rtx (<MODE>mode);
ba0ece39 597})
46402cbe
MM
598
599(define_insn_and_split "*vector_ltgt<mode>"
ad18eed2
SB
600 [(set (match_operand:VEC_F 0 "vfloat_operand")
601 (ltgt:VEC_F (match_operand:VEC_F 1 "vfloat_operand")
602 (match_operand:VEC_F 2 "vfloat_operand")))]
46402cbe
MM
603 "VECTOR_UNIT_ALTIVEC_OR_VSX_P (<MODE>mode)"
604 "#"
605 ""
606 [(set (match_dup 3)
607 (gt:VEC_F (match_dup 1)
608 (match_dup 2)))
609 (set (match_dup 4)
610 (gt:VEC_F (match_dup 2)
611 (match_dup 1)))
612 (set (match_dup 0)
613 (ior:VEC_F (match_dup 3)
614 (match_dup 4)))]
46402cbe
MM
615{
616 operands[3] = gen_reg_rtx (<MODE>mode);
617 operands[4] = gen_reg_rtx (<MODE>mode);
6c332313 618})
46402cbe
MM
619
620(define_insn_and_split "*vector_ordered<mode>"
ad18eed2
SB
621 [(set (match_operand:VEC_F 0 "vfloat_operand")
622 (ordered:VEC_F (match_operand:VEC_F 1 "vfloat_operand")
623 (match_operand:VEC_F 2 "vfloat_operand")))]
46402cbe
MM
624 "VECTOR_UNIT_ALTIVEC_OR_VSX_P (<MODE>mode)"
625 "#"
626 ""
627 [(set (match_dup 3)
628 (ge:VEC_F (match_dup 1)
629 (match_dup 2)))
630 (set (match_dup 4)
631 (ge:VEC_F (match_dup 2)
632 (match_dup 1)))
633 (set (match_dup 0)
634 (ior:VEC_F (match_dup 3)
635 (match_dup 4)))]
46402cbe
MM
636{
637 operands[3] = gen_reg_rtx (<MODE>mode);
638 operands[4] = gen_reg_rtx (<MODE>mode);
6c332313 639})
46402cbe
MM
640
641(define_insn_and_split "*vector_unordered<mode>"
ad18eed2
SB
642 [(set (match_operand:VEC_F 0 "vfloat_operand")
643 (unordered:VEC_F (match_operand:VEC_F 1 "vfloat_operand")
644 (match_operand:VEC_F 2 "vfloat_operand")))]
46402cbe
MM
645 "VECTOR_UNIT_ALTIVEC_OR_VSX_P (<MODE>mode)"
646 "#"
647 ""
648 [(set (match_dup 3)
649 (ge:VEC_F (match_dup 1)
650 (match_dup 2)))
651 (set (match_dup 4)
652 (ge:VEC_F (match_dup 2)
653 (match_dup 1)))
654 (set (match_dup 0)
68908a06
BS
655 (and:VEC_F (not:VEC_F (match_dup 3))
656 (not:VEC_F (match_dup 4))))]
46402cbe
MM
657{
658 operands[3] = gen_reg_rtx (<MODE>mode);
659 operands[4] = gen_reg_rtx (<MODE>mode);
6c332313 660})
46402cbe 661
a72c65c7
MM
662;; Note the arguments for __builtin_altivec_vsel are op2, op1, mask
663;; which is in the reverse order that we want
664(define_expand "vector_select_<mode>"
ad18eed2 665 [(set (match_operand:VEC_L 0 "vlogical_operand")
a72c65c7 666 (if_then_else:VEC_L
ad18eed2 667 (ne:CC (match_operand:VEC_L 3 "vlogical_operand")
70db9095 668 (match_dup 4))
ad18eed2
SB
669 (match_operand:VEC_L 2 "vlogical_operand")
670 (match_operand:VEC_L 1 "vlogical_operand")))]
29e6733c 671 "VECTOR_UNIT_ALTIVEC_OR_VSX_P (<MODE>mode)"
70db9095 672 "operands[4] = CONST0_RTX (<MODE>mode);")
a72c65c7
MM
673
674(define_expand "vector_select_<mode>_uns"
ad18eed2 675 [(set (match_operand:VEC_L 0 "vlogical_operand")
a72c65c7 676 (if_then_else:VEC_L
ad18eed2 677 (ne:CCUNS (match_operand:VEC_L 3 "vlogical_operand")
70db9095 678 (match_dup 4))
ad18eed2
SB
679 (match_operand:VEC_L 2 "vlogical_operand")
680 (match_operand:VEC_L 1 "vlogical_operand")))]
29e6733c 681 "VECTOR_UNIT_ALTIVEC_OR_VSX_P (<MODE>mode)"
70db9095 682 "operands[4] = CONST0_RTX (<MODE>mode);")
a72c65c7
MM
683
684;; Expansions that compare vectors producing a vector result and a predicate,
685;; setting CR6 to indicate a combined status
686(define_expand "vector_eq_<mode>_p"
687 [(parallel
b65261f6 688 [(set (reg:CC CR6_REGNO)
ad18eed2
SB
689 (unspec:CC [(eq:CC (match_operand:VEC_A 1 "vlogical_operand")
690 (match_operand:VEC_A 2 "vlogical_operand"))]
a72c65c7 691 UNSPEC_PREDICATE))
ad18eed2 692 (set (match_operand:VEC_A 0 "vlogical_operand")
a72c65c7
MM
693 (eq:VEC_A (match_dup 1)
694 (match_dup 2)))])]
29e6733c 695 "VECTOR_UNIT_ALTIVEC_OR_VSX_P (<MODE>mode)"
a72c65c7
MM
696 "")
697
902cb7b1 698;; This expansion handles the V16QI, V8HI, and V4SI modes in the
50181506 699;; implementation of the vec_all_ne built-in functions on Power9.
902cb7b1
KN
700(define_expand "vector_ne_<mode>_p"
701 [(parallel
702 [(set (reg:CC CR6_REGNO)
703 (unspec:CC [(ne:CC (match_operand:VI 1 "vlogical_operand")
704 (match_operand:VI 2 "vlogical_operand"))]
705 UNSPEC_PREDICATE))
d36a53d6 706 (set (match_dup 3)
902cb7b1 707 (ne:VI (match_dup 1)
50181506
KN
708 (match_dup 2)))])
709 (set (match_operand:SI 0 "register_operand" "=r")
710 (lt:SI (reg:CC CR6_REGNO)
711 (const_int 0)))]
902cb7b1 712 "TARGET_P9_VECTOR"
50181506 713{
d36a53d6 714 operands[3] = gen_reg_rtx (<MODE>mode);
50181506
KN
715})
716
717;; This expansion handles the V16QI, V8HI, and V4SI modes in the
718;; implementation of the vec_any_eq built-in functions on Power9.
719(define_expand "vector_ae_<mode>_p"
720 [(parallel
721 [(set (reg:CC CR6_REGNO)
722 (unspec:CC [(ne:CC (match_operand:VI 1 "vlogical_operand")
723 (match_operand:VI 2 "vlogical_operand"))]
724 UNSPEC_PREDICATE))
d36a53d6 725 (set (match_dup 3)
50181506
KN
726 (ne:VI (match_dup 1)
727 (match_dup 2)))])
728 (set (match_operand:SI 0 "register_operand" "=r")
729 (lt:SI (reg:CC CR6_REGNO)
730 (const_int 0)))
731 (set (match_dup 0)
732 (xor:SI (match_dup 0)
733 (const_int 1)))]
734 "TARGET_P9_VECTOR"
735{
d36a53d6 736 operands[3] = gen_reg_rtx (<MODE>mode);
50181506 737})
902cb7b1
KN
738
739;; This expansion handles the V16QI, V8HI, and V4SI modes in the
740;; implementation of the vec_all_nez and vec_any_eqz built-in
741;; functions on Power9.
742(define_expand "vector_nez_<mode>_p"
743 [(parallel
744 [(set (reg:CC CR6_REGNO)
745 (unspec:CC [(unspec:VI
746 [(match_operand:VI 1 "vlogical_operand")
747 (match_operand:VI 2 "vlogical_operand")]
748 UNSPEC_NEZ_P)]
749 UNSPEC_PREDICATE))
750 (set (match_operand:VI 0 "vlogical_operand")
751 (unspec:VI [(match_dup 1)
752 (match_dup 2)]
753 UNSPEC_NEZ_P))])]
754 "TARGET_P9_VECTOR"
755 "")
756
50181506
KN
757;; This expansion handles the V2DI mode in the implementation of the
758;; vec_all_ne built-in function on Power9.
902cb7b1 759;;
50181506
KN
760;; Since the Power9 "xvcmpne<mode>." instruction does not support DImode,
761;; this expands into the same rtl that would be used for the Power8
762;; architecture.
902cb7b1
KN
763(define_expand "vector_ne_v2di_p"
764 [(parallel
765 [(set (reg:CC CR6_REGNO)
50181506
KN
766 (unspec:CC [(eq:CC (match_operand:V2DI 1 "vlogical_operand")
767 (match_operand:V2DI 2 "vlogical_operand"))]
768 UNSPEC_PREDICATE))
d36a53d6 769 (set (match_dup 3)
50181506
KN
770 (eq:V2DI (match_dup 1)
771 (match_dup 2)))])
772 (set (match_operand:SI 0 "register_operand" "=r")
773 (eq:SI (reg:CC CR6_REGNO)
774 (const_int 0)))]
902cb7b1 775 "TARGET_P9_VECTOR"
50181506 776{
d36a53d6 777 operands[3] = gen_reg_rtx (V2DImode);
50181506
KN
778})
779
780;; This expansion handles the V2DI mode in the implementation of the
781;; vec_any_eq built-in function on Power9.
782;;
783;; Since the Power9 "xvcmpne<mode>." instruction does not support DImode,
784;; this expands into the same rtl that would be used for the Power8
785;; architecture.
786(define_expand "vector_ae_v2di_p"
787 [(parallel
788 [(set (reg:CC CR6_REGNO)
789 (unspec:CC [(eq:CC (match_operand:V2DI 1 "vlogical_operand")
790 (match_operand:V2DI 2 "vlogical_operand"))]
791 UNSPEC_PREDICATE))
d36a53d6 792 (set (match_dup 3)
50181506
KN
793 (eq:V2DI (match_dup 1)
794 (match_dup 2)))])
795 (set (match_operand:SI 0 "register_operand" "=r")
b0ba96c2 796 (eq:SI (reg:CC CR6_REGNO)
50181506
KN
797 (const_int 0)))
798 (set (match_dup 0)
799 (xor:SI (match_dup 0)
800 (const_int 1)))]
801 "TARGET_P9_VECTOR"
802{
d36a53d6 803 operands[3] = gen_reg_rtx (V2DImode);
50181506 804})
902cb7b1
KN
805
806;; This expansion handles the V4SF and V2DF modes in the Power9
50181506
KN
807;; implementation of the vec_all_ne built-in functions. Note that the
808;; expansions for this pattern with these modes makes no use of power9-
809;; specific instructions since there are no new power9 instructions
810;; for vector compare not equal with floating point arguments.
902cb7b1
KN
811(define_expand "vector_ne_<mode>_p"
812 [(parallel
813 [(set (reg:CC CR6_REGNO)
50181506 814 (unspec:CC [(eq:CC (match_operand:VEC_F 1 "vlogical_operand")
902cb7b1 815 (match_operand:VEC_F 2 "vlogical_operand"))]
50181506 816 UNSPEC_PREDICATE))
d36a53d6 817 (set (match_dup 3)
50181506
KN
818 (eq:VEC_F (match_dup 1)
819 (match_dup 2)))])
820 (set (match_operand:SI 0 "register_operand" "=r")
821 (eq:SI (reg:CC CR6_REGNO)
822 (const_int 0)))]
902cb7b1 823 "TARGET_P9_VECTOR"
50181506 824{
d36a53d6 825 operands[3] = gen_reg_rtx (<MODE>mode);
50181506
KN
826})
827
828;; This expansion handles the V4SF and V2DF modes in the Power9
829;; implementation of the vec_any_eq built-in functions. Note that the
830;; expansions for this pattern with these modes makes no use of power9-
831;; specific instructions since there are no new power9 instructions
832;; for vector compare not equal with floating point arguments.
833(define_expand "vector_ae_<mode>_p"
834 [(parallel
835 [(set (reg:CC CR6_REGNO)
836 (unspec:CC [(eq:CC (match_operand:VEC_F 1 "vlogical_operand")
837 (match_operand:VEC_F 2 "vlogical_operand"))]
838 UNSPEC_PREDICATE))
d36a53d6 839 (set (match_dup 3)
50181506
KN
840 (eq:VEC_F (match_dup 1)
841 (match_dup 2)))])
842 (set (match_operand:SI 0 "register_operand" "=r")
b0ba96c2 843 (eq:SI (reg:CC CR6_REGNO)
50181506
KN
844 (const_int 0)))
845 (set (match_dup 0)
846 (xor:SI (match_dup 0)
847 (const_int 1)))]
848 "TARGET_P9_VECTOR"
849{
d36a53d6 850 operands[3] = gen_reg_rtx (<MODE>mode);
50181506 851})
902cb7b1 852
a72c65c7
MM
853(define_expand "vector_gt_<mode>_p"
854 [(parallel
b65261f6 855 [(set (reg:CC CR6_REGNO)
ad18eed2
SB
856 (unspec:CC [(gt:CC (match_operand:VEC_A 1 "vlogical_operand")
857 (match_operand:VEC_A 2 "vlogical_operand"))]
a72c65c7 858 UNSPEC_PREDICATE))
ad18eed2 859 (set (match_operand:VEC_A 0 "vlogical_operand")
a72c65c7
MM
860 (gt:VEC_A (match_dup 1)
861 (match_dup 2)))])]
29e6733c 862 "VECTOR_UNIT_ALTIVEC_OR_VSX_P (<MODE>mode)"
a72c65c7
MM
863 "")
864
865(define_expand "vector_ge_<mode>_p"
866 [(parallel
b65261f6 867 [(set (reg:CC CR6_REGNO)
ad18eed2
SB
868 (unspec:CC [(ge:CC (match_operand:VEC_F 1 "vfloat_operand")
869 (match_operand:VEC_F 2 "vfloat_operand"))]
a72c65c7 870 UNSPEC_PREDICATE))
ad18eed2 871 (set (match_operand:VEC_F 0 "vfloat_operand")
a72c65c7
MM
872 (ge:VEC_F (match_dup 1)
873 (match_dup 2)))])]
29e6733c 874 "VECTOR_UNIT_ALTIVEC_OR_VSX_P (<MODE>mode)"
a72c65c7
MM
875 "")
876
877(define_expand "vector_gtu_<mode>_p"
878 [(parallel
b65261f6 879 [(set (reg:CC CR6_REGNO)
ad18eed2
SB
880 (unspec:CC [(gtu:CC (match_operand:VEC_I 1 "vint_operand")
881 (match_operand:VEC_I 2 "vint_operand"))]
a72c65c7 882 UNSPEC_PREDICATE))
ad18eed2 883 (set (match_operand:VEC_I 0 "vlogical_operand")
a72c65c7
MM
884 (gtu:VEC_I (match_dup 1)
885 (match_dup 2)))])]
29e6733c 886 "VECTOR_UNIT_ALTIVEC_OR_VSX_P (<MODE>mode)"
a72c65c7
MM
887 "")
888
29e6733c 889;; AltiVec/VSX predicates.
a72c65c7 890
902cb7b1
KN
891;; This expansion is triggered during expansion of predicate built-in
892;; functions (built-ins defined with the RS6000_BUILTIN_P macro) by the
893;; altivec_expand_predicate_builtin() function when the value of the
894;; integer constant first argument equals zero (aka __CR6_EQ in altivec.h).
a72c65c7
MM
895(define_expand "cr6_test_for_zero"
896 [(set (match_operand:SI 0 "register_operand" "=r")
b65261f6 897 (eq:SI (reg:CC CR6_REGNO)
a72c65c7 898 (const_int 0)))]
29e6733c 899 "TARGET_ALTIVEC || TARGET_VSX"
2fcd8e02 900 "")
a72c65c7 901
902cb7b1
KN
902;; This expansion is triggered during expansion of predicate built-in
903;; functions (built-ins defined with the RS6000_BUILTIN_P macro) by the
904;; altivec_expand_predicate_builtin() function when the value of the
905;; integer constant first argument equals one (aka __CR6_EQ_REV in altivec.h).
a72c65c7
MM
906(define_expand "cr6_test_for_zero_reverse"
907 [(set (match_operand:SI 0 "register_operand" "=r")
b65261f6 908 (eq:SI (reg:CC CR6_REGNO)
a72c65c7 909 (const_int 0)))
e4fb6f09
SB
910 (set (match_dup 0)
911 (xor:SI (match_dup 0)
912 (const_int 1)))]
29e6733c 913 "TARGET_ALTIVEC || TARGET_VSX"
a72c65c7
MM
914 "")
915
902cb7b1
KN
916;; This expansion is triggered during expansion of predicate built-in
917;; functions (built-ins defined with the RS6000_BUILTIN_P macro) by the
918;; altivec_expand_predicate_builtin() function when the value of the
919;; integer constant first argument equals two (aka __CR6_LT in altivec.h).
a72c65c7
MM
920(define_expand "cr6_test_for_lt"
921 [(set (match_operand:SI 0 "register_operand" "=r")
b65261f6 922 (lt:SI (reg:CC CR6_REGNO)
a72c65c7 923 (const_int 0)))]
29e6733c 924 "TARGET_ALTIVEC || TARGET_VSX"
a72c65c7
MM
925 "")
926
902cb7b1
KN
927;; This expansion is triggered during expansion of predicate built-in
928;; functions (built-ins defined with the RS6000_BUILTIN_P macro) by the
929;; altivec_expand_predicate_builtin() function when the value of the
930;; integer constant first argument equals three
931;; (aka __CR6_LT_REV in altivec.h).
a72c65c7
MM
932(define_expand "cr6_test_for_lt_reverse"
933 [(set (match_operand:SI 0 "register_operand" "=r")
b65261f6 934 (lt:SI (reg:CC CR6_REGNO)
a72c65c7 935 (const_int 0)))
e4fb6f09
SB
936 (set (match_dup 0)
937 (xor:SI (match_dup 0)
938 (const_int 1)))]
29e6733c 939 "TARGET_ALTIVEC || TARGET_VSX"
a72c65c7
MM
940 "")
941
942\f
0bd62dca
MM
943;; Vector count leading zeros
944(define_expand "clz<mode>2"
ad18eed2
SB
945 [(set (match_operand:VEC_I 0 "register_operand")
946 (clz:VEC_I (match_operand:VEC_I 1 "register_operand")))]
0bd62dca
MM
947 "TARGET_P8_VECTOR")
948
4bfc9db7
MM
949;; Vector count trailing zeros
950(define_expand "ctz<mode>2"
ad18eed2
SB
951 [(set (match_operand:VEC_I 0 "register_operand")
952 (ctz:VEC_I (match_operand:VEC_I 1 "register_operand")))]
4bfc9db7
MM
953 "TARGET_P9_VECTOR")
954
0bd62dca
MM
955;; Vector population count
956(define_expand "popcount<mode>2"
ad18eed2
SB
957 [(set (match_operand:VEC_I 0 "register_operand")
958 (popcount:VEC_I (match_operand:VEC_I 1 "register_operand")))]
0bd62dca
MM
959 "TARGET_P8_VECTOR")
960
4bfc9db7
MM
961;; Vector parity
962(define_expand "parity<mode>2"
ad18eed2
SB
963 [(set (match_operand:VEC_IP 0 "register_operand")
964 (parity:VEC_IP (match_operand:VEC_IP 1 "register_operand")))]
4bfc9db7
MM
965 "TARGET_P9_VECTOR")
966
0bd62dca 967\f
a72c65c7
MM
968;; Same size conversions
969(define_expand "float<VEC_int><mode>2"
ad18eed2
SB
970 [(set (match_operand:VEC_F 0 "vfloat_operand")
971 (float:VEC_F (match_operand:<VEC_INT> 1 "vint_operand")))]
29e6733c 972 "VECTOR_UNIT_ALTIVEC_OR_VSX_P (<MODE>mode)"
a72c65c7 973{
29e6733c
MM
974 if (<MODE>mode == V4SFmode && VECTOR_UNIT_ALTIVEC_P (<MODE>mode))
975 {
976 emit_insn (gen_altivec_vcfsx (operands[0], operands[1], const0_rtx));
977 DONE;
978 }
6c332313 979})
a72c65c7 980
7fa14a01 981(define_expand "floatuns<VEC_int><mode>2"
ad18eed2
SB
982 [(set (match_operand:VEC_F 0 "vfloat_operand")
983 (unsigned_float:VEC_F (match_operand:<VEC_INT> 1 "vint_operand")))]
29e6733c 984 "VECTOR_UNIT_ALTIVEC_OR_VSX_P (<MODE>mode)"
a72c65c7 985{
29e6733c
MM
986 if (<MODE>mode == V4SFmode && VECTOR_UNIT_ALTIVEC_P (<MODE>mode))
987 {
988 emit_insn (gen_altivec_vcfux (operands[0], operands[1], const0_rtx));
989 DONE;
990 }
6c332313 991})
a72c65c7
MM
992
993(define_expand "fix_trunc<mode><VEC_int>2"
ad18eed2
SB
994 [(set (match_operand:<VEC_INT> 0 "vint_operand")
995 (fix:<VEC_INT> (match_operand:VEC_F 1 "vfloat_operand")))]
29e6733c 996 "VECTOR_UNIT_ALTIVEC_OR_VSX_P (<MODE>mode)"
a72c65c7 997{
29e6733c
MM
998 if (<MODE>mode == V4SFmode && VECTOR_UNIT_ALTIVEC_P (<MODE>mode))
999 {
1000 emit_insn (gen_altivec_vctsxs (operands[0], operands[1], const0_rtx));
1001 DONE;
1002 }
6c332313 1003})
a72c65c7
MM
1004
1005(define_expand "fixuns_trunc<mode><VEC_int>2"
ad18eed2
SB
1006 [(set (match_operand:<VEC_INT> 0 "vint_operand")
1007 (unsigned_fix:<VEC_INT> (match_operand:VEC_F 1 "vfloat_operand")))]
29e6733c 1008 "VECTOR_UNIT_ALTIVEC_OR_VSX_P (<MODE>mode)"
a72c65c7 1009{
29e6733c
MM
1010 if (<MODE>mode == V4SFmode && VECTOR_UNIT_ALTIVEC_P (<MODE>mode))
1011 {
1012 emit_insn (gen_altivec_vctuxs (operands[0], operands[1], const0_rtx));
1013 DONE;
1014 }
6c332313 1015})
a72c65c7
MM
1016
1017\f
1018;; Vector initialization, set, extract
ff03930a 1019(define_expand "vec_init<mode><VEC_base_l>"
ad18eed2
SB
1020 [(match_operand:VEC_E 0 "vlogical_operand")
1021 (match_operand:VEC_E 1 "")]
29e6733c 1022 "VECTOR_MEM_ALTIVEC_OR_VSX_P (<MODE>mode)"
a72c65c7
MM
1023{
1024 rs6000_expand_vector_init (operands[0], operands[1]);
1025 DONE;
1026})
1027
1028(define_expand "vec_set<mode>"
ad18eed2
SB
1029 [(match_operand:VEC_E 0 "vlogical_operand")
1030 (match_operand:<VEC_base> 1 "register_operand")
1031 (match_operand 2 "const_int_operand")]
29e6733c 1032 "VECTOR_MEM_ALTIVEC_OR_VSX_P (<MODE>mode)"
a72c65c7
MM
1033{
1034 rs6000_expand_vector_set (operands[0], operands[1], INTVAL (operands[2]));
1035 DONE;
1036})
1037
ff03930a 1038(define_expand "vec_extract<mode><VEC_base_l>"
ad18eed2
SB
1039 [(match_operand:<VEC_base> 0 "register_operand")
1040 (match_operand:VEC_E 1 "vlogical_operand")
1041 (match_operand 2 "const_int_operand")]
29e6733c 1042 "VECTOR_MEM_ALTIVEC_OR_VSX_P (<MODE>mode)"
a72c65c7 1043{
98060bbe 1044 rs6000_expand_vector_extract (operands[0], operands[1], operands[2]);
a72c65c7
MM
1045 DONE;
1046})
29e6733c
MM
1047\f
1048;; Convert double word types to single word types
1049(define_expand "vec_pack_trunc_v2df"
ad18eed2
SB
1050 [(match_operand:V4SF 0 "vfloat_operand")
1051 (match_operand:V2DF 1 "vfloat_operand")
1052 (match_operand:V2DF 2 "vfloat_operand")]
29e6733c
MM
1053 "VECTOR_UNIT_VSX_P (V2DFmode) && TARGET_ALTIVEC"
1054{
1055 rtx r1 = gen_reg_rtx (V4SFmode);
1056 rtx r2 = gen_reg_rtx (V4SFmode);
1057
1058 emit_insn (gen_vsx_xvcvdpsp (r1, operands[1]));
1059 emit_insn (gen_vsx_xvcvdpsp (r2, operands[2]));
5b3f0a54 1060 rs6000_expand_extract_even (operands[0], r1, r2);
29e6733c
MM
1061 DONE;
1062})
1063
1064(define_expand "vec_pack_sfix_trunc_v2df"
ad18eed2
SB
1065 [(match_operand:V4SI 0 "vint_operand")
1066 (match_operand:V2DF 1 "vfloat_operand")
1067 (match_operand:V2DF 2 "vfloat_operand")]
29e6733c
MM
1068 "VECTOR_UNIT_VSX_P (V2DFmode) && TARGET_ALTIVEC"
1069{
1070 rtx r1 = gen_reg_rtx (V4SImode);
1071 rtx r2 = gen_reg_rtx (V4SImode);
1072
1073 emit_insn (gen_vsx_xvcvdpsxws (r1, operands[1]));
1074 emit_insn (gen_vsx_xvcvdpsxws (r2, operands[2]));
5b3f0a54 1075 rs6000_expand_extract_even (operands[0], r1, r2);
29e6733c
MM
1076 DONE;
1077})
1078
1079(define_expand "vec_pack_ufix_trunc_v2df"
ad18eed2
SB
1080 [(match_operand:V4SI 0 "vint_operand")
1081 (match_operand:V2DF 1 "vfloat_operand")
1082 (match_operand:V2DF 2 "vfloat_operand")]
29e6733c
MM
1083 "VECTOR_UNIT_VSX_P (V2DFmode) && TARGET_ALTIVEC"
1084{
1085 rtx r1 = gen_reg_rtx (V4SImode);
1086 rtx r2 = gen_reg_rtx (V4SImode);
1087
1088 emit_insn (gen_vsx_xvcvdpuxws (r1, operands[1]));
1089 emit_insn (gen_vsx_xvcvdpuxws (r2, operands[2]));
5b3f0a54 1090 rs6000_expand_extract_even (operands[0], r1, r2);
29e6733c
MM
1091 DONE;
1092})
1093
1094;; Convert single word types to double word
1095(define_expand "vec_unpacks_hi_v4sf"
ad18eed2
SB
1096 [(match_operand:V2DF 0 "vfloat_operand")
1097 (match_operand:V4SF 1 "vfloat_operand")]
29e6733c
MM
1098 "VECTOR_UNIT_VSX_P (V2DFmode) && VECTOR_UNIT_ALTIVEC_OR_VSX_P (V4SFmode)"
1099{
1100 rtx reg = gen_reg_rtx (V4SFmode);
1101
90d3bd51 1102 rs6000_expand_interleave (reg, operands[1], operands[1], BYTES_BIG_ENDIAN);
29e6733c
MM
1103 emit_insn (gen_vsx_xvcvspdp (operands[0], reg));
1104 DONE;
1105})
1106
1107(define_expand "vec_unpacks_lo_v4sf"
ad18eed2
SB
1108 [(match_operand:V2DF 0 "vfloat_operand")
1109 (match_operand:V4SF 1 "vfloat_operand")]
29e6733c
MM
1110 "VECTOR_UNIT_VSX_P (V2DFmode) && VECTOR_UNIT_ALTIVEC_OR_VSX_P (V4SFmode)"
1111{
1112 rtx reg = gen_reg_rtx (V4SFmode);
1113
90d3bd51 1114 rs6000_expand_interleave (reg, operands[1], operands[1], !BYTES_BIG_ENDIAN);
29e6733c
MM
1115 emit_insn (gen_vsx_xvcvspdp (operands[0], reg));
1116 DONE;
1117})
1118
1119(define_expand "vec_unpacks_float_hi_v4si"
ad18eed2
SB
1120 [(match_operand:V2DF 0 "vfloat_operand")
1121 (match_operand:V4SI 1 "vint_operand")]
29e6733c
MM
1122 "VECTOR_UNIT_VSX_P (V2DFmode) && VECTOR_UNIT_ALTIVEC_OR_VSX_P (V4SImode)"
1123{
1124 rtx reg = gen_reg_rtx (V4SImode);
1125
90d3bd51 1126 rs6000_expand_interleave (reg, operands[1], operands[1], BYTES_BIG_ENDIAN);
29e6733c
MM
1127 emit_insn (gen_vsx_xvcvsxwdp (operands[0], reg));
1128 DONE;
1129})
1130
1131(define_expand "vec_unpacks_float_lo_v4si"
ad18eed2
SB
1132 [(match_operand:V2DF 0 "vfloat_operand")
1133 (match_operand:V4SI 1 "vint_operand")]
29e6733c
MM
1134 "VECTOR_UNIT_VSX_P (V2DFmode) && VECTOR_UNIT_ALTIVEC_OR_VSX_P (V4SImode)"
1135{
1136 rtx reg = gen_reg_rtx (V4SImode);
1137
90d3bd51 1138 rs6000_expand_interleave (reg, operands[1], operands[1], !BYTES_BIG_ENDIAN);
29e6733c
MM
1139 emit_insn (gen_vsx_xvcvsxwdp (operands[0], reg));
1140 DONE;
1141})
1142
1143(define_expand "vec_unpacku_float_hi_v4si"
ad18eed2
SB
1144 [(match_operand:V2DF 0 "vfloat_operand")
1145 (match_operand:V4SI 1 "vint_operand")]
29e6733c
MM
1146 "VECTOR_UNIT_VSX_P (V2DFmode) && VECTOR_UNIT_ALTIVEC_OR_VSX_P (V4SImode)"
1147{
1148 rtx reg = gen_reg_rtx (V4SImode);
1149
90d3bd51 1150 rs6000_expand_interleave (reg, operands[1], operands[1], BYTES_BIG_ENDIAN);
29e6733c
MM
1151 emit_insn (gen_vsx_xvcvuxwdp (operands[0], reg));
1152 DONE;
1153})
1154
1155(define_expand "vec_unpacku_float_lo_v4si"
ad18eed2
SB
1156 [(match_operand:V2DF 0 "vfloat_operand")
1157 (match_operand:V4SI 1 "vint_operand")]
29e6733c
MM
1158 "VECTOR_UNIT_VSX_P (V2DFmode) && VECTOR_UNIT_ALTIVEC_OR_VSX_P (V4SImode)"
1159{
1160 rtx reg = gen_reg_rtx (V4SImode);
1161
90d3bd51 1162 rs6000_expand_interleave (reg, operands[1], operands[1], !BYTES_BIG_ENDIAN);
29e6733c
MM
1163 emit_insn (gen_vsx_xvcvuxwdp (operands[0], reg));
1164 DONE;
1165})
1166
a72c65c7
MM
1167\f
1168;; Align vector loads with a permute.
1169(define_expand "vec_realign_load_<mode>"
ad18eed2
SB
1170 [(match_operand:VEC_K 0 "vlogical_operand")
1171 (match_operand:VEC_K 1 "vlogical_operand")
1172 (match_operand:VEC_K 2 "vlogical_operand")
1173 (match_operand:V16QI 3 "vlogical_operand")]
29e6733c 1174 "VECTOR_MEM_ALTIVEC_OR_VSX_P (<MODE>mode)"
a72c65c7 1175{
493f4c9e
BS
1176 if (BYTES_BIG_ENDIAN)
1177 emit_insn (gen_altivec_vperm_<mode> (operands[0], operands[1],
1178 operands[2], operands[3]));
1179 else
f200869a 1180 {
e19eea71
BS
1181 /* We have changed lvsr to lvsl, so to complete the transformation
1182 of vperm for LE, we must swap the inputs. */
f200869a
BS
1183 rtx unspec = gen_rtx_UNSPEC (<MODE>mode,
1184 gen_rtvec (3, operands[2],
1185 operands[1], operands[3]),
1186 UNSPEC_VPERM);
1187 emit_move_insn (operands[0], unspec);
1188 }
a72c65c7
MM
1189 DONE;
1190})
1191
29e6733c
MM
1192;; Under VSX, vectors of 4/8 byte alignments do not need to be aligned
1193;; since the load already handles it.
1194(define_expand "movmisalign<mode>"
ad18eed2
SB
1195 [(set (match_operand:VEC_N 0 "nonimmediate_operand")
1196 (match_operand:VEC_N 1 "any_operand"))]
29e6733c
MM
1197 "VECTOR_MEM_VSX_P (<MODE>mode) && TARGET_ALLOW_MOVMISALIGN"
1198 "")
1199
a72c65c7
MM
1200;; Vector shift right in bits. Currently supported ony for shift
1201;; amounts that can be expressed as byte shifts (divisible by 8).
1202;; General shift amounts can be supported using vsro + vsr. We're
1203;; not expecting to see these yet (the vectorizer currently
ba067536 1204;; generates only shifts by a whole number of vector elements).
2b6fb4aa
PH
1205;; Note that the vec_shr operation is actually defined as
1206;; 'shift toward element 0' so is a shr for LE and shl for BE.
a72c65c7 1207(define_expand "vec_shr_<mode>"
ad18eed2
SB
1208 [(match_operand:VEC_L 0 "vlogical_operand")
1209 (match_operand:VEC_L 1 "vlogical_operand")
1210 (match_operand:QI 2 "reg_or_short_operand")]
a72c65c7 1211 "TARGET_ALTIVEC"
a72c65c7
MM
1212{
1213 rtx bitshift = operands[2];
1214 rtx shift;
1215 rtx insn;
2b6fb4aa 1216 rtx zero_reg, op1, op2;
a72c65c7
MM
1217 HOST_WIDE_INT bitshift_val;
1218 HOST_WIDE_INT byteshift_val;
2fcd8e02 1219
a72c65c7
MM
1220 if (! CONSTANT_P (bitshift))
1221 FAIL;
1222 bitshift_val = INTVAL (bitshift);
1223 if (bitshift_val & 0x7)
1224 FAIL;
ba067536 1225 byteshift_val = (bitshift_val >> 3);
2b6fb4aa
PH
1226 zero_reg = gen_reg_rtx (<MODE>mode);
1227 emit_move_insn (zero_reg, CONST0_RTX (<MODE>mode));
ba067536 1228 if (!BYTES_BIG_ENDIAN)
2b6fb4aa
PH
1229 {
1230 byteshift_val = 16 - byteshift_val;
1231 op1 = zero_reg;
1232 op2 = operands[1];
1233 }
1234 else
1235 {
1236 op1 = operands[1];
1237 op2 = zero_reg;
1238 }
1239
29e6733c
MM
1240 if (TARGET_VSX && (byteshift_val & 0x3) == 0)
1241 {
1242 shift = gen_rtx_CONST_INT (QImode, byteshift_val >> 2);
2b6fb4aa 1243 insn = gen_vsx_xxsldwi_<mode> (operands[0], op1, op2, shift);
29e6733c
MM
1244 }
1245 else
1246 {
1247 shift = gen_rtx_CONST_INT (QImode, byteshift_val);
2b6fb4aa 1248 insn = gen_altivec_vsldoi_<mode> (operands[0], op1, op2, shift);
29e6733c 1249 }
a72c65c7
MM
1250
1251 emit_insn (insn);
1252 DONE;
6c332313 1253})
a72c65c7
MM
1254
1255;; Expanders for rotate each element in a vector
1256(define_expand "vrotl<mode>3"
ad18eed2
SB
1257 [(set (match_operand:VEC_I 0 "vint_operand")
1258 (rotate:VEC_I (match_operand:VEC_I 1 "vint_operand")
1259 (match_operand:VEC_I 2 "vint_operand")))]
a5965b52 1260 "VECTOR_UNIT_ALTIVEC_OR_VSX_P (<MODE>mode)"
a72c65c7
MM
1261 "")
1262
1263;; Expanders for arithmetic shift left on each vector element
1264(define_expand "vashl<mode>3"
ad18eed2
SB
1265 [(set (match_operand:VEC_I 0 "vint_operand")
1266 (ashift:VEC_I (match_operand:VEC_I 1 "vint_operand")
1267 (match_operand:VEC_I 2 "vint_operand")))]
a5965b52 1268 "VECTOR_UNIT_ALTIVEC_OR_VSX_P (<MODE>mode)"
a72c65c7
MM
1269 "")
1270
1271;; Expanders for logical shift right on each vector element
1272(define_expand "vlshr<mode>3"
ad18eed2
SB
1273 [(set (match_operand:VEC_I 0 "vint_operand")
1274 (lshiftrt:VEC_I (match_operand:VEC_I 1 "vint_operand")
1275 (match_operand:VEC_I 2 "vint_operand")))]
a5965b52 1276 "VECTOR_UNIT_ALTIVEC_OR_VSX_P (<MODE>mode)"
a72c65c7
MM
1277 "")
1278
1279;; Expanders for arithmetic shift right on each vector element
1280(define_expand "vashr<mode>3"
ad18eed2
SB
1281 [(set (match_operand:VEC_I 0 "vint_operand")
1282 (ashiftrt:VEC_I (match_operand:VEC_I 1 "vint_operand")
1283 (match_operand:VEC_I 2 "vint_operand")))]
a5965b52 1284 "VECTOR_UNIT_ALTIVEC_OR_VSX_P (<MODE>mode)"
a72c65c7 1285 "")
ab8d2734 1286\f
df10b6d4 1287;; Vector reduction expanders for VSX
5e8edf67 1288; The (VEC_reduc:...
df10b6d4 1289; (op1)
5e8edf67 1290; (unspec:... [(const_int 0)] UNSPEC_REDUC))
df10b6d4
MM
1291;
1292; is to allow us to use a code iterator, but not completely list all of the
1293; vector rotates, etc. to prevent canonicalization
1294
5e8edf67
AL
1295
1296(define_expand "reduc_<VEC_reduc:VEC_reduc_name>_scal_<VEC_F:mode>"
ad18eed2
SB
1297 [(match_operand:<VEC_base> 0 "register_operand")
1298 (VEC_reduc:VEC_F (match_operand:VEC_F 1 "vfloat_operand")
5e8edf67
AL
1299 (unspec:VEC_F [(const_int 0)] UNSPEC_REDUC))]
1300 "VECTOR_UNIT_VSX_P (<VEC_F:MODE>mode)"
1301 {
1302 rtx vec = gen_reg_rtx (<VEC_F:MODE>mode);
1303 rtx elt = BYTES_BIG_ENDIAN
1304 ? gen_int_mode (GET_MODE_NUNITS (<VEC_F:MODE>mode) - 1, QImode)
1305 : const0_rtx;
1306 emit_insn (gen_vsx_reduc_<VEC_reduc:VEC_reduc_name>_<VEC_F:mode> (vec,
1307 operand1));
1308 emit_insn (gen_vsx_extract_<VEC_F:mode> (operand0, vec, elt));
1309 DONE;
1310 })