]> git.ipfire.org Git - thirdparty/gcc.git/blame - gcc/config/rs6000/altivec.md
decl.c, [...]: Remove redundant enum from machine_mode.
[thirdparty/gcc.git] / gcc / config / rs6000 / altivec.md
CommitLineData
10ed84db 1;; AltiVec patterns.
23a5b65a 2;; Copyright (C) 2002-2014 Free Software Foundation, Inc.
10ed84db
AH
3;; Contributed by Aldy Hernandez (aldy@quesejoda.com)
4
5de601cf 5;; This file is part of GCC.
10ed84db 6
5de601cf
NC
7;; GCC is free software; you can redistribute it and/or modify it
8;; under the terms of the GNU General Public License as published
2f83c7d6 9;; by the Free Software Foundation; either version 3, or (at your
5de601cf 10;; option) any later version.
10ed84db 11
5de601cf
NC
12;; GCC is distributed in the hope that it will be useful, but WITHOUT
13;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
14;; or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
15;; License for more details.
10ed84db
AH
16
17;; You should have received a copy of the GNU General Public License
2f83c7d6
NC
18;; along with GCC; see the file COPYING3. If not see
19;; <http://www.gnu.org/licenses/>.
10ed84db 20
f3c33d9d
MM
21(define_c_enum "unspec"
22 [UNSPEC_VCMPBFP
23 UNSPEC_VMSUMU
24 UNSPEC_VMSUMM
25 UNSPEC_VMSUMSHM
26 UNSPEC_VMSUMUHS
27 UNSPEC_VMSUMSHS
28 UNSPEC_VMHADDSHS
29 UNSPEC_VMHRADDSHS
30 UNSPEC_VMLADDUHM
31 UNSPEC_VADDCUW
32 UNSPEC_VADDU
33 UNSPEC_VADDS
34 UNSPEC_VAVGU
35 UNSPEC_VAVGS
36 UNSPEC_VMULEUB
37 UNSPEC_VMULESB
38 UNSPEC_VMULEUH
39 UNSPEC_VMULESH
40 UNSPEC_VMULOUB
41 UNSPEC_VMULOSB
42 UNSPEC_VMULOUH
43 UNSPEC_VMULOSH
f3c33d9d 44 UNSPEC_VPKPX
a5965b52
MM
45 UNSPEC_VPACK_SIGN_SIGN_SAT
46 UNSPEC_VPACK_SIGN_UNS_SAT
47 UNSPEC_VPACK_UNS_UNS_SAT
48 UNSPEC_VPACK_UNS_UNS_MOD
52a93551 49 UNSPEC_VPACK_UNS_UNS_MOD_DIRECT
f3c33d9d
MM
50 UNSPEC_VSLV4SI
51 UNSPEC_VSLO
52 UNSPEC_VSR
53 UNSPEC_VSRO
54 UNSPEC_VSUBCUW
55 UNSPEC_VSUBU
56 UNSPEC_VSUBS
57 UNSPEC_VSUM4UBS
58 UNSPEC_VSUM4S
59 UNSPEC_VSUM2SWS
60 UNSPEC_VSUMSWS
61 UNSPEC_VPERM
62 UNSPEC_VPERM_UNS
63 UNSPEC_VRFIN
64 UNSPEC_VCFUX
65 UNSPEC_VCFSX
66 UNSPEC_VCTUXS
67 UNSPEC_VCTSXS
68 UNSPEC_VLOGEFP
69 UNSPEC_VEXPTEFP
fbd86cc6 70 UNSPEC_VSLDOI
a5965b52
MM
71 UNSPEC_VUNPACK_HI_SIGN
72 UNSPEC_VUNPACK_LO_SIGN
52a93551
BS
73 UNSPEC_VUNPACK_HI_SIGN_DIRECT
74 UNSPEC_VUNPACK_LO_SIGN_DIRECT
f3c33d9d 75 UNSPEC_VUPKHPX
f3c33d9d 76 UNSPEC_VUPKLPX
f3c33d9d
MM
77 UNSPEC_DST
78 UNSPEC_DSTT
79 UNSPEC_DSTST
80 UNSPEC_DSTSTT
81 UNSPEC_LVSL
82 UNSPEC_LVSR
83 UNSPEC_LVE
84 UNSPEC_STVX
85 UNSPEC_STVXL
86 UNSPEC_STVE
87 UNSPEC_SET_VSCR
88 UNSPEC_GET_VRSAVE
89 UNSPEC_LVX
90 UNSPEC_REDUC_PLUS
91 UNSPEC_VECSH
92 UNSPEC_EXTEVEN_V4SI
93 UNSPEC_EXTEVEN_V8HI
94 UNSPEC_EXTEVEN_V16QI
95 UNSPEC_EXTEVEN_V4SF
96 UNSPEC_EXTODD_V4SI
97 UNSPEC_EXTODD_V8HI
98 UNSPEC_EXTODD_V16QI
99 UNSPEC_EXTODD_V4SF
100 UNSPEC_INTERHI_V4SI
101 UNSPEC_INTERHI_V8HI
102 UNSPEC_INTERHI_V16QI
103 UNSPEC_INTERLO_V4SI
104 UNSPEC_INTERLO_V8HI
105 UNSPEC_INTERLO_V16QI
106 UNSPEC_LVLX
107 UNSPEC_LVLXL
108 UNSPEC_LVRX
109 UNSPEC_LVRXL
110 UNSPEC_STVLX
111 UNSPEC_STVLXL
112 UNSPEC_STVRX
113 UNSPEC_STVRXL
114 UNSPEC_VMULWHUB
115 UNSPEC_VMULWLUB
116 UNSPEC_VMULWHSB
117 UNSPEC_VMULWLSB
118 UNSPEC_VMULWHUH
119 UNSPEC_VMULWLUH
120 UNSPEC_VMULWHSH
121 UNSPEC_VMULWLSH
122 UNSPEC_VUPKHUB
123 UNSPEC_VUPKHUH
124 UNSPEC_VUPKLUB
125 UNSPEC_VUPKLUH
126 UNSPEC_VPERMSI
127 UNSPEC_VPERMHI
128 UNSPEC_INTERHI
129 UNSPEC_INTERLO
130 UNSPEC_VUPKHS_V4SF
131 UNSPEC_VUPKLS_V4SF
132 UNSPEC_VUPKHU_V4SF
133 UNSPEC_VUPKLU_V4SF
0bd62dca 134 UNSPEC_VGBBD
68d3bacf
BS
135 UNSPEC_VMRGH_DIRECT
136 UNSPEC_VMRGL_DIRECT
137 UNSPEC_VSPLT_DIRECT
b80afde9 138 UNSPEC_VSUMSWS_DIRECT
a16a872d
MM
139 UNSPEC_VADDCUQ
140 UNSPEC_VADDEUQM
141 UNSPEC_VADDECUQ
142 UNSPEC_VSUBCUQ
143 UNSPEC_VSUBEUQM
144 UNSPEC_VSUBECUQ
117f16fb 145 UNSPEC_VBPERMQ
06b39289
MM
146 UNSPEC_BCDADD
147 UNSPEC_BCDSUB
148 UNSPEC_BCD_OVERFLOW
98b44b0e 149])
d744e06e 150
f3c33d9d
MM
151(define_c_enum "unspecv"
152 [UNSPECV_SET_VRSAVE
153 UNSPECV_MTVSCR
154 UNSPECV_MFVSCR
155 UNSPECV_DSSALL
156 UNSPECV_DSS
3aca4bff
DE
157 ])
158
81466555 159;; Vec int modes
3abcb3a7 160(define_mode_iterator VI [V4SI V8HI V16QI])
a5965b52
MM
161;; Like VI, but add ISA 2.07 integer vector ops
162(define_mode_iterator VI2 [V4SI V8HI V16QI V2DI])
aba5fb01 163;; Short vec in modes
3abcb3a7 164(define_mode_iterator VIshort [V8HI V16QI])
81466555 165;; Vec float modes
3abcb3a7
HPN
166(define_mode_iterator VF [V4SF])
167;; Vec modes, pity mode iterators are not composable
168(define_mode_iterator V [V4SI V8HI V16QI V4SF])
a72c65c7
MM
169;; Vec modes for move/logical/permute ops, include vector types for move not
170;; otherwise handled by altivec (v2df, v2di, ti)
a16a872d 171(define_mode_iterator VM [V4SI V8HI V16QI V4SF V2DF V2DI V1TI TI])
10ed84db 172
a72c65c7 173;; Like VM, except don't do TImode
a16a872d 174(define_mode_iterator VM2 [V4SI V8HI V16QI V4SF V2DF V2DI V1TI])
10ed84db 175
a5965b52
MM
176(define_mode_attr VI_char [(V2DI "d") (V4SI "w") (V8HI "h") (V16QI "b")])
177(define_mode_attr VI_scalar [(V2DI "DI") (V4SI "SI") (V8HI "HI") (V16QI "QI")])
178(define_mode_attr VI_unit [(V16QI "VECTOR_UNIT_ALTIVEC_P (V16QImode)")
179 (V8HI "VECTOR_UNIT_ALTIVEC_P (V8HImode)")
180 (V4SI "VECTOR_UNIT_ALTIVEC_P (V4SImode)")
a16a872d
MM
181 (V2DI "VECTOR_UNIT_P8_VECTOR_P (V2DImode)")
182 (V1TI "VECTOR_UNIT_ALTIVEC_P (V1TImode)")])
a5965b52
MM
183
184;; Vector pack/unpack
185(define_mode_iterator VP [V2DI V4SI V8HI])
186(define_mode_attr VP_small [(V2DI "V4SI") (V4SI "V8HI") (V8HI "V16QI")])
187(define_mode_attr VP_small_lc [(V2DI "v4si") (V4SI "v8hi") (V8HI "v16qi")])
188(define_mode_attr VU_char [(V2DI "w") (V4SI "h") (V8HI "b")])
10ed84db
AH
189
190;; Vector move instructions.
a72c65c7 191(define_insn "*altivec_mov<mode>"
d0a54439
AM
192 [(set (match_operand:VM2 0 "nonimmediate_operand" "=Z,v,v,*Y,*r,*r,v,v")
193 (match_operand:VM2 1 "input_operand" "v,Z,v,r,Y,r,j,W"))]
a72c65c7 194 "VECTOR_MEM_ALTIVEC_P (<MODE>mode)
81466555
NS
195 && (register_operand (operands[0], <MODE>mode)
196 || register_operand (operands[1], <MODE>mode))"
d744e06e
AH
197{
198 switch (which_alternative)
199 {
81466555
NS
200 case 0: return "stvx %1,%y0";
201 case 1: return "lvx %0,%y1";
202 case 2: return "vor %0,%1,%1";
203 case 3: return "#";
204 case 4: return "#";
205 case 5: return "#";
a72c65c7
MM
206 case 6: return "vxor %0,%0,%0";
207 case 7: return output_vec_const_move (operands);
992d08b1 208 default: gcc_unreachable ();
d744e06e 209 }
81466555 210}
a72c65c7
MM
211 [(set_attr "type" "vecstore,vecload,vecsimple,store,load,*,vecsimple,*")])
212
213;; Unlike other altivec moves, allow the GPRs, since a normal use of TImode
214;; is for unions. However for plain data movement, slightly favor the vector
215;; loads
216(define_insn "*altivec_movti"
d0a54439
AM
217 [(set (match_operand:TI 0 "nonimmediate_operand" "=Z,v,v,?Y,?r,?r,v,v")
218 (match_operand:TI 1 "input_operand" "v,Z,v,r,Y,r,j,W"))]
a72c65c7
MM
219 "VECTOR_MEM_ALTIVEC_P (TImode)
220 && (register_operand (operands[0], TImode)
221 || register_operand (operands[1], TImode))"
81466555 222{
a72c65c7
MM
223 switch (which_alternative)
224 {
225 case 0: return "stvx %1,%y0";
226 case 1: return "lvx %0,%y1";
227 case 2: return "vor %0,%1,%1";
228 case 3: return "#";
229 case 4: return "#";
230 case 5: return "#";
231 case 6: return "vxor %0,%0,%0";
232 case 7: return output_vec_const_move (operands);
233 default: gcc_unreachable ();
234 }
235}
236 [(set_attr "type" "vecstore,vecload,vecsimple,store,load,*,vecsimple,*")])
10ed84db 237
29e6733c
MM
238;; Load up a vector with the most significant bit set by loading up -1 and
239;; doing a shift left
240(define_split
241 [(set (match_operand:VM 0 "altivec_register_operand" "")
242 (match_operand:VM 1 "easy_vector_constant_msb" ""))]
3ff79f99 243 "VECTOR_UNIT_ALTIVEC_OR_VSX_P (<MODE>mode) && reload_completed"
29e6733c
MM
244 [(const_int 0)]
245{
246 rtx dest = operands[0];
ef4bddc2 247 machine_mode mode = GET_MODE (operands[0]);
29e6733c
MM
248 rtvec v;
249 int i, num_elements;
250
251 if (mode == V4SFmode)
252 {
253 mode = V4SImode;
254 dest = gen_lowpart (V4SImode, dest);
255 }
256
257 num_elements = GET_MODE_NUNITS (mode);
258 v = rtvec_alloc (num_elements);
259 for (i = 0; i < num_elements; i++)
260 RTVEC_ELT (v, i) = constm1_rtx;
261
262 emit_insn (gen_vec_initv4si (dest, gen_rtx_PARALLEL (mode, v)));
263 emit_insn (gen_rtx_SET (VOIDmode, dest, gen_rtx_ASHIFT (mode, dest, dest)));
264 DONE;
265})
266
66180ff3 267(define_split
a72c65c7
MM
268 [(set (match_operand:VM 0 "altivec_register_operand" "")
269 (match_operand:VM 1 "easy_vector_constant_add_self" ""))]
3ff79f99 270 "VECTOR_UNIT_ALTIVEC_OR_VSX_P (<MODE>mode) && reload_completed"
66180ff3 271 [(set (match_dup 0) (match_dup 3))
847535b6 272 (set (match_dup 0) (match_dup 4))]
66180ff3
PB
273{
274 rtx dup = gen_easy_altivec_constant (operands[1]);
275 rtx const_vec;
ef4bddc2 276 machine_mode op_mode = <MODE>mode;
66180ff3
PB
277
278 /* Divide the operand of the resulting VEC_DUPLICATE, and use
279 simplify_rtx to make a CONST_VECTOR. */
280 XEXP (dup, 0) = simplify_const_binary_operation (ASHIFTRT, QImode,
281 XEXP (dup, 0), const1_rtx);
282 const_vec = simplify_rtx (dup);
283
847535b6
JJ
284 if (op_mode == V4SFmode)
285 {
286 op_mode = V4SImode;
287 operands[0] = gen_lowpart (op_mode, operands[0]);
288 }
289 if (GET_MODE (const_vec) == op_mode)
66180ff3
PB
290 operands[3] = const_vec;
291 else
847535b6
JJ
292 operands[3] = gen_lowpart (op_mode, const_vec);
293 operands[4] = gen_rtx_PLUS (op_mode, operands[0], operands[0]);
66180ff3
PB
294})
295
10ed84db
AH
296(define_insn "get_vrsave_internal"
297 [(set (match_operand:SI 0 "register_operand" "=r")
3aca4bff 298 (unspec:SI [(reg:SI 109)] UNSPEC_GET_VRSAVE))]
10ed84db 299 "TARGET_ALTIVEC"
10ed84db
AH
300{
301 if (TARGET_MACHO)
81466555 302 return "mfspr %0,256";
10ed84db 303 else
81466555
NS
304 return "mfvrsave %0";
305}
310b9b1d 306 [(set_attr "type" "*")])
10ed84db
AH
307
308(define_insn "*set_vrsave_internal"
309 [(match_parallel 0 "vrsave_operation"
310 [(set (reg:SI 109)
311 (unspec_volatile:SI [(match_operand:SI 1 "register_operand" "r")
3aca4bff 312 (reg:SI 109)] UNSPECV_SET_VRSAVE))])]
10ed84db 313 "TARGET_ALTIVEC"
10ed84db
AH
314{
315 if (TARGET_MACHO)
81466555 316 return "mtspr 256,%1";
10ed84db 317 else
81466555
NS
318 return "mtvrsave %1";
319}
310b9b1d 320 [(set_attr "type" "*")])
10ed84db 321
d62294f5
FJ
322(define_insn "*save_world"
323 [(match_parallel 0 "save_world_operation"
a5ad2017
DE
324 [(clobber (reg:SI 65))
325 (use (match_operand:SI 1 "call_operand" "s"))])]
d62294f5 326 "TARGET_MACHO && (DEFAULT_ABI == ABI_DARWIN) && TARGET_32BIT"
a5ad2017 327 "bl %z1"
d62294f5
FJ
328 [(set_attr "type" "branch")
329 (set_attr "length" "4")])
330
331(define_insn "*restore_world"
332 [(match_parallel 0 "restore_world_operation"
333 [(return)
e65a3857 334 (use (reg:SI 65))
a5ad2017
DE
335 (use (match_operand:SI 1 "call_operand" "s"))
336 (clobber (match_operand:SI 2 "gpc_reg_operand" "=r"))])]
d62294f5 337 "TARGET_MACHO && (DEFAULT_ABI == ABI_DARWIN) && TARGET_32BIT"
a5ad2017 338 "b %z1")
d62294f5 339
b427dd7a
AM
340;; The save_vregs and restore_vregs patterns don't use memory_operand
341;; because (plus (reg) (const_int)) is not a valid vector address.
342;; This way is more compact than describing exactly what happens in
343;; the out-of-line functions, ie. loading the constant into r11/r12
344;; then using indexed addressing, and requires less editing of rtl
345;; to describe the operation to dwarf2out_frame_debug_expr.
346(define_insn "*save_vregs_<mode>_r11"
347 [(match_parallel 0 "any_parallel_operand"
348 [(clobber (reg:P 65))
349 (use (match_operand:P 1 "symbol_ref_operand" "s"))
350 (clobber (reg:P 11))
351 (use (reg:P 0))
352 (set (mem:V4SI (plus:P (match_operand:P 2 "gpc_reg_operand" "b")
353 (match_operand:P 3 "short_cint_operand" "I")))
354 (match_operand:V4SI 4 "gpc_reg_operand" "v"))])]
355 ""
356 "bl %1"
357 [(set_attr "type" "branch")
358 (set_attr "length" "4")])
359
360(define_insn "*save_vregs_<mode>_r12"
361 [(match_parallel 0 "any_parallel_operand"
362 [(clobber (reg:P 65))
363 (use (match_operand:P 1 "symbol_ref_operand" "s"))
364 (clobber (reg:P 12))
365 (use (reg:P 0))
366 (set (mem:V4SI (plus:P (match_operand:P 2 "gpc_reg_operand" "b")
367 (match_operand:P 3 "short_cint_operand" "I")))
368 (match_operand:V4SI 4 "gpc_reg_operand" "v"))])]
369 ""
370 "bl %1"
371 [(set_attr "type" "branch")
372 (set_attr "length" "4")])
373
374(define_insn "*restore_vregs_<mode>_r11"
375 [(match_parallel 0 "any_parallel_operand"
376 [(clobber (reg:P 65))
377 (use (match_operand:P 1 "symbol_ref_operand" "s"))
378 (clobber (reg:P 11))
379 (use (reg:P 0))
380 (set (match_operand:V4SI 2 "gpc_reg_operand" "=v")
381 (mem:V4SI (plus:P (match_operand:P 3 "gpc_reg_operand" "b")
382 (match_operand:P 4 "short_cint_operand" "I"))))])]
383 ""
384 "bl %1"
385 [(set_attr "type" "branch")
386 (set_attr "length" "4")])
387
388(define_insn "*restore_vregs_<mode>_r12"
389 [(match_parallel 0 "any_parallel_operand"
390 [(clobber (reg:P 65))
391 (use (match_operand:P 1 "symbol_ref_operand" "s"))
392 (clobber (reg:P 12))
393 (use (reg:P 0))
394 (set (match_operand:V4SI 2 "gpc_reg_operand" "=v")
395 (mem:V4SI (plus:P (match_operand:P 3 "gpc_reg_operand" "b")
396 (match_operand:P 4 "short_cint_operand" "I"))))])]
397 ""
398 "bl %1"
399 [(set_attr "type" "branch")
400 (set_attr "length" "4")])
401
10ed84db
AH
402;; Simple binary operations.
403
f96bc213
NS
404;; add
405(define_insn "add<mode>3"
a5965b52
MM
406 [(set (match_operand:VI2 0 "register_operand" "=v")
407 (plus:VI2 (match_operand:VI2 1 "register_operand" "v")
408 (match_operand:VI2 2 "register_operand" "v")))]
409 "<VI_unit>"
f96bc213 410 "vaddu<VI_char>m %0,%1,%2"
10ed84db
AH
411 [(set_attr "type" "vecsimple")])
412
a72c65c7 413(define_insn "*altivec_addv4sf3"
10ed84db
AH
414 [(set (match_operand:V4SF 0 "register_operand" "=v")
415 (plus:V4SF (match_operand:V4SF 1 "register_operand" "v")
5aebfdad 416 (match_operand:V4SF 2 "register_operand" "v")))]
a72c65c7 417 "VECTOR_UNIT_ALTIVEC_P (V4SFmode)"
10ed84db
AH
418 "vaddfp %0,%1,%2"
419 [(set_attr "type" "vecfloat")])
420
421(define_insn "altivec_vaddcuw"
422 [(set (match_operand:V4SI 0 "register_operand" "=v")
423 (unspec:V4SI [(match_operand:V4SI 1 "register_operand" "v")
3aca4bff
DE
424 (match_operand:V4SI 2 "register_operand" "v")]
425 UNSPEC_VADDCUW))]
a5965b52 426 "VECTOR_UNIT_ALTIVEC_P (V4SImode)"
10ed84db
AH
427 "vaddcuw %0,%1,%2"
428 [(set_attr "type" "vecsimple")])
429
aba5fb01
NS
430(define_insn "altivec_vaddu<VI_char>s"
431 [(set (match_operand:VI 0 "register_operand" "=v")
432 (unspec:VI [(match_operand:VI 1 "register_operand" "v")
a5965b52 433 (match_operand:VI 2 "register_operand" "v")]
3aca4bff 434 UNSPEC_VADDU))
27ffac37 435 (set (reg:SI 110) (unspec:SI [(const_int 0)] UNSPEC_SET_VSCR))]
a5965b52 436 "<VI_unit>"
aba5fb01 437 "vaddu<VI_char>s %0,%1,%2"
10ed84db
AH
438 [(set_attr "type" "vecsimple")])
439
aba5fb01
NS
440(define_insn "altivec_vadds<VI_char>s"
441 [(set (match_operand:VI 0 "register_operand" "=v")
442 (unspec:VI [(match_operand:VI 1 "register_operand" "v")
3aca4bff
DE
443 (match_operand:VI 2 "register_operand" "v")]
444 UNSPEC_VADDS))
27ffac37 445 (set (reg:SI 110) (unspec:SI [(const_int 0)] UNSPEC_SET_VSCR))]
a5965b52 446 "VECTOR_UNIT_ALTIVEC_P (<MODE>mode)"
aba5fb01 447 "vadds<VI_char>s %0,%1,%2"
10ed84db
AH
448 [(set_attr "type" "vecsimple")])
449
f96bc213
NS
450;; sub
451(define_insn "sub<mode>3"
a5965b52
MM
452 [(set (match_operand:VI2 0 "register_operand" "=v")
453 (minus:VI2 (match_operand:VI2 1 "register_operand" "v")
454 (match_operand:VI2 2 "register_operand" "v")))]
455 "<VI_unit>"
f96bc213
NS
456 "vsubu<VI_char>m %0,%1,%2"
457 [(set_attr "type" "vecsimple")])
458
a72c65c7 459(define_insn "*altivec_subv4sf3"
f96bc213
NS
460 [(set (match_operand:V4SF 0 "register_operand" "=v")
461 (minus:V4SF (match_operand:V4SF 1 "register_operand" "v")
462 (match_operand:V4SF 2 "register_operand" "v")))]
a72c65c7 463 "VECTOR_UNIT_ALTIVEC_P (V4SFmode)"
f96bc213
NS
464 "vsubfp %0,%1,%2"
465 [(set_attr "type" "vecfloat")])
466
467(define_insn "altivec_vsubcuw"
468 [(set (match_operand:V4SI 0 "register_operand" "=v")
469 (unspec:V4SI [(match_operand:V4SI 1 "register_operand" "v")
3aca4bff
DE
470 (match_operand:V4SI 2 "register_operand" "v")]
471 UNSPEC_VSUBCUW))]
a5965b52 472 "VECTOR_UNIT_ALTIVEC_P (V4SImode)"
f96bc213
NS
473 "vsubcuw %0,%1,%2"
474 [(set_attr "type" "vecsimple")])
475
aba5fb01
NS
476(define_insn "altivec_vsubu<VI_char>s"
477 [(set (match_operand:VI 0 "register_operand" "=v")
478 (unspec:VI [(match_operand:VI 1 "register_operand" "v")
3aca4bff
DE
479 (match_operand:VI 2 "register_operand" "v")]
480 UNSPEC_VSUBU))
27ffac37 481 (set (reg:SI 110) (unspec:SI [(const_int 0)] UNSPEC_SET_VSCR))]
a5965b52 482 "VECTOR_UNIT_ALTIVEC_P (<MODE>mode)"
aba5fb01 483 "vsubu<VI_char>s %0,%1,%2"
10ed84db
AH
484 [(set_attr "type" "vecsimple")])
485
aba5fb01
NS
486(define_insn "altivec_vsubs<VI_char>s"
487 [(set (match_operand:VI 0 "register_operand" "=v")
488 (unspec:VI [(match_operand:VI 1 "register_operand" "v")
3aca4bff
DE
489 (match_operand:VI 2 "register_operand" "v")]
490 UNSPEC_VSUBS))
27ffac37 491 (set (reg:SI 110) (unspec:SI [(const_int 0)] UNSPEC_SET_VSCR))]
a5965b52 492 "VECTOR_UNIT_ALTIVEC_P (<MODE>mode)"
aba5fb01 493 "vsubs<VI_char>s %0,%1,%2"
10ed84db
AH
494 [(set_attr "type" "vecsimple")])
495
f96bc213 496;;
aba5fb01
NS
497(define_insn "altivec_vavgu<VI_char>"
498 [(set (match_operand:VI 0 "register_operand" "=v")
499 (unspec:VI [(match_operand:VI 1 "register_operand" "v")
3aca4bff
DE
500 (match_operand:VI 2 "register_operand" "v")]
501 UNSPEC_VAVGU))]
10ed84db 502 "TARGET_ALTIVEC"
aba5fb01 503 "vavgu<VI_char> %0,%1,%2"
10ed84db
AH
504 [(set_attr "type" "vecsimple")])
505
aba5fb01
NS
506(define_insn "altivec_vavgs<VI_char>"
507 [(set (match_operand:VI 0 "register_operand" "=v")
508 (unspec:VI [(match_operand:VI 1 "register_operand" "v")
3aca4bff
DE
509 (match_operand:VI 2 "register_operand" "v")]
510 UNSPEC_VAVGS))]
a5965b52 511 "VECTOR_UNIT_ALTIVEC_P (<MODE>mode)"
aba5fb01 512 "vavgs<VI_char> %0,%1,%2"
10ed84db
AH
513 [(set_attr "type" "vecsimple")])
514
515(define_insn "altivec_vcmpbfp"
516 [(set (match_operand:V4SI 0 "register_operand" "=v")
517 (unspec:V4SI [(match_operand:V4SF 1 "register_operand" "v")
21213b4c
DP
518 (match_operand:V4SF 2 "register_operand" "v")]
519 UNSPEC_VCMPBFP))]
a5965b52 520 "VECTOR_UNIT_ALTIVEC_P (V4SImode)"
10ed84db
AH
521 "vcmpbfp %0,%1,%2"
522 [(set_attr "type" "veccmp")])
523
a72c65c7 524(define_insn "*altivec_eq<mode>"
a5965b52
MM
525 [(set (match_operand:VI2 0 "altivec_register_operand" "=v")
526 (eq:VI2 (match_operand:VI2 1 "altivec_register_operand" "v")
527 (match_operand:VI2 2 "altivec_register_operand" "v")))]
528 "<VI_unit>"
a72c65c7
MM
529 "vcmpequ<VI_char> %0,%1,%2"
530 [(set_attr "type" "veccmp")])
10ed84db 531
a72c65c7 532(define_insn "*altivec_gt<mode>"
a5965b52
MM
533 [(set (match_operand:VI2 0 "altivec_register_operand" "=v")
534 (gt:VI2 (match_operand:VI2 1 "altivec_register_operand" "v")
535 (match_operand:VI2 2 "altivec_register_operand" "v")))]
536 "<VI_unit>"
a72c65c7
MM
537 "vcmpgts<VI_char> %0,%1,%2"
538 [(set_attr "type" "veccmp")])
10ed84db 539
a72c65c7 540(define_insn "*altivec_gtu<mode>"
a5965b52
MM
541 [(set (match_operand:VI2 0 "altivec_register_operand" "=v")
542 (gtu:VI2 (match_operand:VI2 1 "altivec_register_operand" "v")
543 (match_operand:VI2 2 "altivec_register_operand" "v")))]
544 "<VI_unit>"
a72c65c7
MM
545 "vcmpgtu<VI_char> %0,%1,%2"
546 [(set_attr "type" "veccmp")])
10ed84db 547
a72c65c7
MM
548(define_insn "*altivec_eqv4sf"
549 [(set (match_operand:V4SF 0 "altivec_register_operand" "=v")
550 (eq:V4SF (match_operand:V4SF 1 "altivec_register_operand" "v")
551 (match_operand:V4SF 2 "altivec_register_operand" "v")))]
552 "VECTOR_UNIT_ALTIVEC_P (V4SFmode)"
10ed84db
AH
553 "vcmpeqfp %0,%1,%2"
554 [(set_attr "type" "veccmp")])
555
a72c65c7
MM
556(define_insn "*altivec_gtv4sf"
557 [(set (match_operand:V4SF 0 "altivec_register_operand" "=v")
558 (gt:V4SF (match_operand:V4SF 1 "altivec_register_operand" "v")
559 (match_operand:V4SF 2 "altivec_register_operand" "v")))]
560 "VECTOR_UNIT_ALTIVEC_P (V4SFmode)"
561 "vcmpgtfp %0,%1,%2"
10ed84db
AH
562 [(set_attr "type" "veccmp")])
563
a72c65c7
MM
564(define_insn "*altivec_gev4sf"
565 [(set (match_operand:V4SF 0 "altivec_register_operand" "=v")
566 (ge:V4SF (match_operand:V4SF 1 "altivec_register_operand" "v")
567 (match_operand:V4SF 2 "altivec_register_operand" "v")))]
568 "VECTOR_UNIT_ALTIVEC_P (V4SFmode)"
569 "vcmpgefp %0,%1,%2"
570 [(set_attr "type" "veccmp")])
10ed84db 571
a72c65c7
MM
572(define_insn "*altivec_vsel<mode>"
573 [(set (match_operand:VM 0 "altivec_register_operand" "=v")
574 (if_then_else:VM
575 (ne:CC (match_operand:VM 1 "altivec_register_operand" "v")
70db9095 576 (match_operand:VM 4 "zero_constant" ""))
a72c65c7
MM
577 (match_operand:VM 2 "altivec_register_operand" "v")
578 (match_operand:VM 3 "altivec_register_operand" "v")))]
579 "VECTOR_MEM_ALTIVEC_P (<MODE>mode)"
580 "vsel %0,%3,%2,%1"
581 [(set_attr "type" "vecperm")])
10ed84db 582
a72c65c7
MM
583(define_insn "*altivec_vsel<mode>_uns"
584 [(set (match_operand:VM 0 "altivec_register_operand" "=v")
585 (if_then_else:VM
586 (ne:CCUNS (match_operand:VM 1 "altivec_register_operand" "v")
70db9095 587 (match_operand:VM 4 "zero_constant" ""))
a72c65c7
MM
588 (match_operand:VM 2 "altivec_register_operand" "v")
589 (match_operand:VM 3 "altivec_register_operand" "v")))]
590 "VECTOR_MEM_ALTIVEC_P (<MODE>mode)"
591 "vsel %0,%3,%2,%1"
592 [(set_attr "type" "vecperm")])
10ed84db 593
d6613781 594;; Fused multiply add.
1b1562a5 595
d6613781 596(define_insn "*altivec_fmav4sf4"
1b1562a5
MM
597 [(set (match_operand:V4SF 0 "register_operand" "=v")
598 (fma:V4SF (match_operand:V4SF 1 "register_operand" "v")
599 (match_operand:V4SF 2 "register_operand" "v")
600 (match_operand:V4SF 3 "register_operand" "v")))]
a72c65c7 601 "VECTOR_UNIT_ALTIVEC_P (V4SFmode)"
10ed84db
AH
602 "vmaddfp %0,%1,%2,%3"
603 [(set_attr "type" "vecfloat")])
604
a67ed43f 605;; We do multiply as a fused multiply-add with an add of a -0.0 vector.
10ed84db 606
a72c65c7 607(define_expand "altivec_mulv4sf3"
d6613781
RH
608 [(set (match_operand:V4SF 0 "register_operand" "")
609 (fma:V4SF (match_operand:V4SF 1 "register_operand" "")
610 (match_operand:V4SF 2 "register_operand" "")
611 (match_dup 3)))]
1b1562a5 612 "VECTOR_UNIT_ALTIVEC_P (V4SFmode)"
a67ed43f
AH
613{
614 rtx neg0;
615
616 /* Generate [-0.0, -0.0, -0.0, -0.0]. */
8cf0db2b
UW
617 neg0 = gen_reg_rtx (V4SImode);
618 emit_insn (gen_altivec_vspltisw (neg0, constm1_rtx));
71d46ca5 619 emit_insn (gen_vashlv4si3 (neg0, neg0, neg0));
a67ed43f 620
d6613781
RH
621 operands[3] = gen_lowpart (V4SFmode, neg0);
622})
10ed84db 623
a7b376ee 624;; 32-bit integer multiplication
a45f6936
DP
625;; A_high = Operand_0 & 0xFFFF0000 >> 16
626;; A_low = Operand_0 & 0xFFFF
627;; B_high = Operand_1 & 0xFFFF0000 >> 16
628;; B_low = Operand_1 & 0xFFFF
629;; result = A_low * B_low + (A_high * B_low + B_high * A_low) << 16
630
631;; (define_insn "mulv4si3"
632;; [(set (match_operand:V4SI 0 "register_operand" "=v")
633;; (mult:V4SI (match_operand:V4SI 1 "register_operand" "v")
634;; (match_operand:V4SI 2 "register_operand" "v")))]
635(define_expand "mulv4si3"
636 [(use (match_operand:V4SI 0 "register_operand" ""))
637 (use (match_operand:V4SI 1 "register_operand" ""))
638 (use (match_operand:V4SI 2 "register_operand" ""))]
639 "TARGET_ALTIVEC"
640 "
641 {
642 rtx zero;
643 rtx swap;
644 rtx small_swap;
645 rtx sixteen;
646 rtx one;
647 rtx two;
648 rtx low_product;
649 rtx high_product;
650
651 zero = gen_reg_rtx (V4SImode);
652 emit_insn (gen_altivec_vspltisw (zero, const0_rtx));
653
654 sixteen = gen_reg_rtx (V4SImode);
655 emit_insn (gen_altivec_vspltisw (sixteen, gen_rtx_CONST_INT (V4SImode, -16)));
656
657 swap = gen_reg_rtx (V4SImode);
a72c65c7 658 emit_insn (gen_vrotlv4si3 (swap, operands[2], sixteen));
a45f6936
DP
659
660 one = gen_reg_rtx (V8HImode);
661 convert_move (one, operands[1], 0);
662
663 two = gen_reg_rtx (V8HImode);
664 convert_move (two, operands[2], 0);
665
666 small_swap = gen_reg_rtx (V8HImode);
667 convert_move (small_swap, swap, 0);
668
669 low_product = gen_reg_rtx (V4SImode);
2b9d0476 670 emit_insn (gen_altivec_vmulouh (low_product, one, two));
a45f6936
DP
671
672 high_product = gen_reg_rtx (V4SImode);
673 emit_insn (gen_altivec_vmsumuhm (high_product, one, small_swap, zero));
674
71d46ca5 675 emit_insn (gen_vashlv4si3 (high_product, high_product, sixteen));
a45f6936
DP
676
677 emit_insn (gen_addv4si3 (operands[0], high_product, low_product));
678
679 DONE;
680 }")
681
cc54af20
DN
682(define_expand "mulv8hi3"
683 [(use (match_operand:V8HI 0 "register_operand" ""))
684 (use (match_operand:V8HI 1 "register_operand" ""))
685 (use (match_operand:V8HI 2 "register_operand" ""))]
686 "TARGET_ALTIVEC"
687 "
688{
689 rtx odd = gen_reg_rtx (V4SImode);
690 rtx even = gen_reg_rtx (V4SImode);
691 rtx high = gen_reg_rtx (V4SImode);
692 rtx low = gen_reg_rtx (V4SImode);
693
24d2e5eb 694 if (BYTES_BIG_ENDIAN)
2b9d0476 695 {
d13dfec8
BS
696 emit_insn (gen_altivec_vmulesh (even, operands[1], operands[2]));
697 emit_insn (gen_altivec_vmulosh (odd, operands[1], operands[2]));
68d3bacf
BS
698 emit_insn (gen_altivec_vmrghw_direct (high, even, odd));
699 emit_insn (gen_altivec_vmrglw_direct (low, even, odd));
52a93551 700 emit_insn (gen_altivec_vpkuwum_direct (operands[0], high, low));
2b9d0476 701 }
24d2e5eb 702 else
2b9d0476 703 {
d13dfec8
BS
704 emit_insn (gen_altivec_vmulosh (even, operands[1], operands[2]));
705 emit_insn (gen_altivec_vmulesh (odd, operands[1], operands[2]));
68d3bacf
BS
706 emit_insn (gen_altivec_vmrghw_direct (high, odd, even));
707 emit_insn (gen_altivec_vmrglw_direct (low, odd, even));
52a93551 708 emit_insn (gen_altivec_vpkuwum_direct (operands[0], low, high));
2b9d0476 709 }
cc54af20
DN
710
711 DONE;
712}")
a45f6936 713
10ed84db 714;; Fused multiply subtract
d6613781 715(define_insn "*altivec_vnmsubfp"
1b1562a5
MM
716 [(set (match_operand:V4SF 0 "register_operand" "=v")
717 (neg:V4SF
718 (fma:V4SF (match_operand:V4SF 1 "register_operand" "v")
719 (match_operand:V4SF 2 "register_operand" "v")
720 (neg:V4SF
721 (match_operand:V4SF 3 "register_operand" "v")))))]
92902797 722 "VECTOR_UNIT_ALTIVEC_P (V4SFmode)"
1b1562a5
MM
723 "vnmsubfp %0,%1,%2,%3"
724 [(set_attr "type" "vecfloat")])
92902797 725
aba5fb01 726(define_insn "altivec_vmsumu<VI_char>m"
10ed84db 727 [(set (match_operand:V4SI 0 "register_operand" "=v")
aba5fb01
NS
728 (unspec:V4SI [(match_operand:VIshort 1 "register_operand" "v")
729 (match_operand:VIshort 2 "register_operand" "v")
3aca4bff
DE
730 (match_operand:V4SI 3 "register_operand" "v")]
731 UNSPEC_VMSUMU))]
10ed84db 732 "TARGET_ALTIVEC"
aba5fb01 733 "vmsumu<VI_char>m %0,%1,%2,%3"
10ed84db
AH
734 [(set_attr "type" "veccomplex")])
735
aba5fb01 736(define_insn "altivec_vmsumm<VI_char>m"
10ed84db 737 [(set (match_operand:V4SI 0 "register_operand" "=v")
aba5fb01
NS
738 (unspec:V4SI [(match_operand:VIshort 1 "register_operand" "v")
739 (match_operand:VIshort 2 "register_operand" "v")
3aca4bff
DE
740 (match_operand:V4SI 3 "register_operand" "v")]
741 UNSPEC_VMSUMM))]
10ed84db 742 "TARGET_ALTIVEC"
aba5fb01 743 "vmsumm<VI_char>m %0,%1,%2,%3"
10ed84db
AH
744 [(set_attr "type" "veccomplex")])
745
746(define_insn "altivec_vmsumshm"
747 [(set (match_operand:V4SI 0 "register_operand" "=v")
748 (unspec:V4SI [(match_operand:V8HI 1 "register_operand" "v")
749 (match_operand:V8HI 2 "register_operand" "v")
3aca4bff
DE
750 (match_operand:V4SI 3 "register_operand" "v")]
751 UNSPEC_VMSUMSHM))]
10ed84db 752 "TARGET_ALTIVEC"
98c9a8e8 753 "vmsumshm %0,%1,%2,%3"
10ed84db
AH
754 [(set_attr "type" "veccomplex")])
755
756(define_insn "altivec_vmsumuhs"
757 [(set (match_operand:V4SI 0 "register_operand" "=v")
758 (unspec:V4SI [(match_operand:V8HI 1 "register_operand" "v")
759 (match_operand:V8HI 2 "register_operand" "v")
3aca4bff
DE
760 (match_operand:V4SI 3 "register_operand" "v")]
761 UNSPEC_VMSUMUHS))
27ffac37 762 (set (reg:SI 110) (unspec:SI [(const_int 0)] UNSPEC_SET_VSCR))]
10ed84db 763 "TARGET_ALTIVEC"
98c9a8e8 764 "vmsumuhs %0,%1,%2,%3"
10ed84db
AH
765 [(set_attr "type" "veccomplex")])
766
767(define_insn "altivec_vmsumshs"
768 [(set (match_operand:V4SI 0 "register_operand" "=v")
769 (unspec:V4SI [(match_operand:V8HI 1 "register_operand" "v")
770 (match_operand:V8HI 2 "register_operand" "v")
3aca4bff
DE
771 (match_operand:V4SI 3 "register_operand" "v")]
772 UNSPEC_VMSUMSHS))
27ffac37 773 (set (reg:SI 110) (unspec:SI [(const_int 0)] UNSPEC_SET_VSCR))]
10ed84db 774 "TARGET_ALTIVEC"
98c9a8e8 775 "vmsumshs %0,%1,%2,%3"
10ed84db
AH
776 [(set_attr "type" "veccomplex")])
777
f96bc213 778;; max
10ed84db 779
f96bc213 780(define_insn "umax<mode>3"
a5965b52
MM
781 [(set (match_operand:VI2 0 "register_operand" "=v")
782 (umax:VI2 (match_operand:VI2 1 "register_operand" "v")
783 (match_operand:VI2 2 "register_operand" "v")))]
784 "<VI_unit>"
f96bc213 785 "vmaxu<VI_char> %0,%1,%2"
10ed84db
AH
786 [(set_attr "type" "vecsimple")])
787
f96bc213 788(define_insn "smax<mode>3"
a5965b52
MM
789 [(set (match_operand:VI2 0 "register_operand" "=v")
790 (smax:VI2 (match_operand:VI2 1 "register_operand" "v")
791 (match_operand:VI2 2 "register_operand" "v")))]
792 "<VI_unit>"
f96bc213 793 "vmaxs<VI_char> %0,%1,%2"
10ed84db
AH
794 [(set_attr "type" "vecsimple")])
795
a72c65c7 796(define_insn "*altivec_smaxv4sf3"
f96bc213
NS
797 [(set (match_operand:V4SF 0 "register_operand" "=v")
798 (smax:V4SF (match_operand:V4SF 1 "register_operand" "v")
799 (match_operand:V4SF 2 "register_operand" "v")))]
a72c65c7 800 "VECTOR_UNIT_ALTIVEC_P (V4SFmode)"
f96bc213
NS
801 "vmaxfp %0,%1,%2"
802 [(set_attr "type" "veccmp")])
10ed84db 803
f96bc213 804(define_insn "umin<mode>3"
a5965b52
MM
805 [(set (match_operand:VI2 0 "register_operand" "=v")
806 (umin:VI2 (match_operand:VI2 1 "register_operand" "v")
807 (match_operand:VI2 2 "register_operand" "v")))]
808 "<VI_unit>"
f96bc213 809 "vminu<VI_char> %0,%1,%2"
10ed84db
AH
810 [(set_attr "type" "vecsimple")])
811
f96bc213 812(define_insn "smin<mode>3"
a5965b52
MM
813 [(set (match_operand:VI2 0 "register_operand" "=v")
814 (smin:VI2 (match_operand:VI2 1 "register_operand" "v")
815 (match_operand:VI2 2 "register_operand" "v")))]
816 "<VI_unit>"
f96bc213 817 "vmins<VI_char> %0,%1,%2"
10ed84db
AH
818 [(set_attr "type" "vecsimple")])
819
a72c65c7 820(define_insn "*altivec_sminv4sf3"
10ed84db 821 [(set (match_operand:V4SF 0 "register_operand" "=v")
f96bc213 822 (smin:V4SF (match_operand:V4SF 1 "register_operand" "v")
10ed84db 823 (match_operand:V4SF 2 "register_operand" "v")))]
a72c65c7 824 "VECTOR_UNIT_ALTIVEC_P (V4SFmode)"
f96bc213 825 "vminfp %0,%1,%2"
10ed84db
AH
826 [(set_attr "type" "veccmp")])
827
828(define_insn "altivec_vmhaddshs"
829 [(set (match_operand:V8HI 0 "register_operand" "=v")
830 (unspec:V8HI [(match_operand:V8HI 1 "register_operand" "v")
831 (match_operand:V8HI 2 "register_operand" "v")
3aca4bff
DE
832 (match_operand:V8HI 3 "register_operand" "v")]
833 UNSPEC_VMHADDSHS))
27ffac37 834 (set (reg:SI 110) (unspec:SI [(const_int 0)] UNSPEC_SET_VSCR))]
10ed84db 835 "TARGET_ALTIVEC"
98c9a8e8 836 "vmhaddshs %0,%1,%2,%3"
10ed84db 837 [(set_attr "type" "veccomplex")])
3aca4bff 838
10ed84db
AH
839(define_insn "altivec_vmhraddshs"
840 [(set (match_operand:V8HI 0 "register_operand" "=v")
841 (unspec:V8HI [(match_operand:V8HI 1 "register_operand" "v")
842 (match_operand:V8HI 2 "register_operand" "v")
3aca4bff
DE
843 (match_operand:V8HI 3 "register_operand" "v")]
844 UNSPEC_VMHRADDSHS))
27ffac37 845 (set (reg:SI 110) (unspec:SI [(const_int 0)] UNSPEC_SET_VSCR))]
10ed84db 846 "TARGET_ALTIVEC"
98c9a8e8 847 "vmhraddshs %0,%1,%2,%3"
10ed84db 848 [(set_attr "type" "veccomplex")])
3aca4bff 849
10ed84db
AH
850(define_insn "altivec_vmladduhm"
851 [(set (match_operand:V8HI 0 "register_operand" "=v")
852 (unspec:V8HI [(match_operand:V8HI 1 "register_operand" "v")
853 (match_operand:V8HI 2 "register_operand" "v")
3aca4bff
DE
854 (match_operand:V8HI 3 "register_operand" "v")]
855 UNSPEC_VMLADDUHM))]
10ed84db 856 "TARGET_ALTIVEC"
98c9a8e8 857 "vmladduhm %0,%1,%2,%3"
10ed84db
AH
858 [(set_attr "type" "veccomplex")])
859
68d3bacf
BS
860(define_expand "altivec_vmrghb"
861 [(use (match_operand:V16QI 0 "register_operand" ""))
862 (use (match_operand:V16QI 1 "register_operand" ""))
863 (use (match_operand:V16QI 2 "register_operand" ""))]
864 "TARGET_ALTIVEC"
865{
866 rtvec v;
867 rtx x;
868
869 /* Special handling for LE with -maltivec=be. */
870 if (!BYTES_BIG_ENDIAN && VECTOR_ELT_ORDER_BIG)
871 {
872 v = gen_rtvec (16, GEN_INT (8), GEN_INT (24), GEN_INT (9), GEN_INT (25),
873 GEN_INT (10), GEN_INT (26), GEN_INT (11), GEN_INT (27),
874 GEN_INT (12), GEN_INT (28), GEN_INT (13), GEN_INT (29),
875 GEN_INT (14), GEN_INT (30), GEN_INT (15), GEN_INT (31));
876 x = gen_rtx_VEC_CONCAT (V32QImode, operands[2], operands[1]);
877 }
878 else
879 {
880 v = gen_rtvec (16, GEN_INT (0), GEN_INT (16), GEN_INT (1), GEN_INT (17),
881 GEN_INT (2), GEN_INT (18), GEN_INT (3), GEN_INT (19),
882 GEN_INT (4), GEN_INT (20), GEN_INT (5), GEN_INT (21),
883 GEN_INT (6), GEN_INT (22), GEN_INT (7), GEN_INT (23));
884 x = gen_rtx_VEC_CONCAT (V32QImode, operands[1], operands[2]);
885 }
886
887 x = gen_rtx_VEC_SELECT (V16QImode, x, gen_rtx_PARALLEL (VOIDmode, v));
888 emit_insn (gen_rtx_SET (VOIDmode, operands[0], x));
c3e96073 889 DONE;
68d3bacf
BS
890})
891
892(define_insn "*altivec_vmrghb_internal"
10ed84db 893 [(set (match_operand:V16QI 0 "register_operand" "=v")
68d3bacf 894 (vec_select:V16QI
5aebfdad
RH
895 (vec_concat:V32QI
896 (match_operand:V16QI 1 "register_operand" "v")
897 (match_operand:V16QI 2 "register_operand" "v"))
898 (parallel [(const_int 0) (const_int 16)
899 (const_int 1) (const_int 17)
900 (const_int 2) (const_int 18)
901 (const_int 3) (const_int 19)
902 (const_int 4) (const_int 20)
903 (const_int 5) (const_int 21)
904 (const_int 6) (const_int 22)
905 (const_int 7) (const_int 23)])))]
10ed84db 906 "TARGET_ALTIVEC"
68d3bacf
BS
907{
908 if (BYTES_BIG_ENDIAN)
909 return "vmrghb %0,%1,%2";
910 else
911 return "vmrglb %0,%2,%1";
912}
913 [(set_attr "type" "vecperm")])
914
915(define_insn "altivec_vmrghb_direct"
916 [(set (match_operand:V16QI 0 "register_operand" "=v")
917 (unspec:V16QI [(match_operand:V16QI 1 "register_operand" "v")
918 (match_operand:V16QI 2 "register_operand" "v")]
919 UNSPEC_VMRGH_DIRECT))]
920 "TARGET_ALTIVEC"
10ed84db
AH
921 "vmrghb %0,%1,%2"
922 [(set_attr "type" "vecperm")])
923
68d3bacf
BS
924(define_expand "altivec_vmrghh"
925 [(use (match_operand:V8HI 0 "register_operand" ""))
926 (use (match_operand:V8HI 1 "register_operand" ""))
927 (use (match_operand:V8HI 2 "register_operand" ""))]
928 "TARGET_ALTIVEC"
929{
930 rtvec v;
931 rtx x;
932
933 /* Special handling for LE with -maltivec=be. */
934 if (!BYTES_BIG_ENDIAN && VECTOR_ELT_ORDER_BIG)
935 {
936 v = gen_rtvec (8, GEN_INT (4), GEN_INT (12), GEN_INT (5), GEN_INT (13),
937 GEN_INT (6), GEN_INT (14), GEN_INT (7), GEN_INT (15));
938 x = gen_rtx_VEC_CONCAT (V16HImode, operands[2], operands[1]);
939 }
940 else
941 {
942 v = gen_rtvec (8, GEN_INT (0), GEN_INT (8), GEN_INT (1), GEN_INT (9),
943 GEN_INT (2), GEN_INT (10), GEN_INT (3), GEN_INT (11));
944 x = gen_rtx_VEC_CONCAT (V16HImode, operands[1], operands[2]);
945 }
946
947 x = gen_rtx_VEC_SELECT (V8HImode, x, gen_rtx_PARALLEL (VOIDmode, v));
948 emit_insn (gen_rtx_SET (VOIDmode, operands[0], x));
c3e96073 949 DONE;
68d3bacf
BS
950})
951
952(define_insn "*altivec_vmrghh_internal"
10ed84db 953 [(set (match_operand:V8HI 0 "register_operand" "=v")
68d3bacf 954 (vec_select:V8HI
5aebfdad
RH
955 (vec_concat:V16HI
956 (match_operand:V8HI 1 "register_operand" "v")
957 (match_operand:V8HI 2 "register_operand" "v"))
958 (parallel [(const_int 0) (const_int 8)
959 (const_int 1) (const_int 9)
960 (const_int 2) (const_int 10)
961 (const_int 3) (const_int 11)])))]
10ed84db 962 "TARGET_ALTIVEC"
68d3bacf
BS
963{
964 if (BYTES_BIG_ENDIAN)
965 return "vmrghh %0,%1,%2";
966 else
967 return "vmrglh %0,%2,%1";
968}
969 [(set_attr "type" "vecperm")])
970
971(define_insn "altivec_vmrghh_direct"
972 [(set (match_operand:V8HI 0 "register_operand" "=v")
973 (unspec:V8HI [(match_operand:V8HI 1 "register_operand" "v")
974 (match_operand:V8HI 2 "register_operand" "v")]
975 UNSPEC_VMRGH_DIRECT))]
976 "TARGET_ALTIVEC"
10ed84db
AH
977 "vmrghh %0,%1,%2"
978 [(set_attr "type" "vecperm")])
979
68d3bacf
BS
980(define_expand "altivec_vmrghw"
981 [(use (match_operand:V4SI 0 "register_operand" ""))
982 (use (match_operand:V4SI 1 "register_operand" ""))
983 (use (match_operand:V4SI 2 "register_operand" ""))]
984 "VECTOR_MEM_ALTIVEC_P (V4SImode)"
985{
986 rtvec v;
987 rtx x;
988
989 /* Special handling for LE with -maltivec=be. */
990 if (!BYTES_BIG_ENDIAN && VECTOR_ELT_ORDER_BIG)
991 {
992 v = gen_rtvec (4, GEN_INT (2), GEN_INT (6), GEN_INT (3), GEN_INT (7));
993 x = gen_rtx_VEC_CONCAT (V8SImode, operands[2], operands[1]);
994 }
995 else
996 {
997 v = gen_rtvec (4, GEN_INT (0), GEN_INT (4), GEN_INT (1), GEN_INT (5));
998 x = gen_rtx_VEC_CONCAT (V8SImode, operands[1], operands[2]);
999 }
1000
1001 x = gen_rtx_VEC_SELECT (V4SImode, x, gen_rtx_PARALLEL (VOIDmode, v));
1002 emit_insn (gen_rtx_SET (VOIDmode, operands[0], x));
c3e96073 1003 DONE;
68d3bacf
BS
1004})
1005
1006(define_insn "*altivec_vmrghw_internal"
10ed84db 1007 [(set (match_operand:V4SI 0 "register_operand" "=v")
5aebfdad
RH
1008 (vec_select:V4SI
1009 (vec_concat:V8SI
1010 (match_operand:V4SI 1 "register_operand" "v")
1011 (match_operand:V4SI 2 "register_operand" "v"))
1012 (parallel [(const_int 0) (const_int 4)
1013 (const_int 1) (const_int 5)])))]
a72c65c7 1014 "VECTOR_MEM_ALTIVEC_P (V4SImode)"
68d3bacf
BS
1015{
1016 if (BYTES_BIG_ENDIAN)
1017 return "vmrghw %0,%1,%2";
1018 else
1019 return "vmrglw %0,%2,%1";
1020}
1021 [(set_attr "type" "vecperm")])
1022
1023(define_insn "altivec_vmrghw_direct"
1024 [(set (match_operand:V4SI 0 "register_operand" "=v")
1025 (unspec:V4SI [(match_operand:V4SI 1 "register_operand" "v")
1026 (match_operand:V4SI 2 "register_operand" "v")]
1027 UNSPEC_VMRGH_DIRECT))]
1028 "TARGET_ALTIVEC"
10ed84db
AH
1029 "vmrghw %0,%1,%2"
1030 [(set_attr "type" "vecperm")])
1031
a72c65c7 1032(define_insn "*altivec_vmrghsf"
98b44b0e 1033 [(set (match_operand:V4SF 0 "register_operand" "=v")
5aebfdad
RH
1034 (vec_select:V4SF
1035 (vec_concat:V8SF
1036 (match_operand:V4SF 1 "register_operand" "v")
1037 (match_operand:V4SF 2 "register_operand" "v"))
1038 (parallel [(const_int 0) (const_int 4)
1039 (const_int 1) (const_int 5)])))]
a72c65c7 1040 "VECTOR_MEM_ALTIVEC_P (V4SFmode)"
68d3bacf
BS
1041{
1042 if (BYTES_BIG_ENDIAN)
1043 return "vmrghw %0,%1,%2";
1044 else
1045 return "vmrglw %0,%2,%1";
1046}
98b44b0e
IR
1047 [(set_attr "type" "vecperm")])
1048
68d3bacf
BS
1049(define_expand "altivec_vmrglb"
1050 [(use (match_operand:V16QI 0 "register_operand" ""))
1051 (use (match_operand:V16QI 1 "register_operand" ""))
1052 (use (match_operand:V16QI 2 "register_operand" ""))]
1053 "TARGET_ALTIVEC"
1054{
1055 rtvec v;
1056 rtx x;
1057
1058 /* Special handling for LE with -maltivec=be. */
1059 if (!BYTES_BIG_ENDIAN && VECTOR_ELT_ORDER_BIG)
1060 {
1061 v = gen_rtvec (16, GEN_INT (0), GEN_INT (16), GEN_INT (1), GEN_INT (17),
1062 GEN_INT (2), GEN_INT (18), GEN_INT (3), GEN_INT (19),
1063 GEN_INT (4), GEN_INT (20), GEN_INT (5), GEN_INT (21),
1064 GEN_INT (6), GEN_INT (22), GEN_INT (7), GEN_INT (23));
1065 x = gen_rtx_VEC_CONCAT (V32QImode, operands[2], operands[1]);
1066 }
1067 else
1068 {
1069 v = gen_rtvec (16, GEN_INT (8), GEN_INT (24), GEN_INT (9), GEN_INT (25),
1070 GEN_INT (10), GEN_INT (26), GEN_INT (11), GEN_INT (27),
1071 GEN_INT (12), GEN_INT (28), GEN_INT (13), GEN_INT (29),
1072 GEN_INT (14), GEN_INT (30), GEN_INT (15), GEN_INT (31));
1073 x = gen_rtx_VEC_CONCAT (V32QImode, operands[1], operands[2]);
1074 }
1075
1076 x = gen_rtx_VEC_SELECT (V16QImode, x, gen_rtx_PARALLEL (VOIDmode, v));
1077 emit_insn (gen_rtx_SET (VOIDmode, operands[0], x));
c3e96073 1078 DONE;
68d3bacf
BS
1079})
1080
1081(define_insn "*altivec_vmrglb_internal"
10ed84db 1082 [(set (match_operand:V16QI 0 "register_operand" "=v")
5aebfdad
RH
1083 (vec_select:V16QI
1084 (vec_concat:V32QI
1085 (match_operand:V16QI 1 "register_operand" "v")
1086 (match_operand:V16QI 2 "register_operand" "v"))
1087 (parallel [(const_int 8) (const_int 24)
1088 (const_int 9) (const_int 25)
1089 (const_int 10) (const_int 26)
1090 (const_int 11) (const_int 27)
1091 (const_int 12) (const_int 28)
1092 (const_int 13) (const_int 29)
1093 (const_int 14) (const_int 30)
1094 (const_int 15) (const_int 31)])))]
10ed84db 1095 "TARGET_ALTIVEC"
68d3bacf
BS
1096{
1097 if (BYTES_BIG_ENDIAN)
1098 return "vmrglb %0,%1,%2";
1099 else
1100 return "vmrghb %0,%2,%1";
1101}
1102 [(set_attr "type" "vecperm")])
1103
1104(define_insn "altivec_vmrglb_direct"
1105 [(set (match_operand:V16QI 0 "register_operand" "=v")
1106 (unspec:V16QI [(match_operand:V16QI 1 "register_operand" "v")
1107 (match_operand:V16QI 2 "register_operand" "v")]
1108 UNSPEC_VMRGL_DIRECT))]
1109 "TARGET_ALTIVEC"
10ed84db
AH
1110 "vmrglb %0,%1,%2"
1111 [(set_attr "type" "vecperm")])
1112
68d3bacf
BS
1113(define_expand "altivec_vmrglh"
1114 [(use (match_operand:V8HI 0 "register_operand" ""))
1115 (use (match_operand:V8HI 1 "register_operand" ""))
1116 (use (match_operand:V8HI 2 "register_operand" ""))]
1117 "TARGET_ALTIVEC"
1118{
1119 rtvec v;
1120 rtx x;
1121
1122 /* Special handling for LE with -maltivec=be. */
1123 if (!BYTES_BIG_ENDIAN && VECTOR_ELT_ORDER_BIG)
1124 {
1125 v = gen_rtvec (8, GEN_INT (0), GEN_INT (8), GEN_INT (1), GEN_INT (9),
1126 GEN_INT (2), GEN_INT (10), GEN_INT (3), GEN_INT (11));
1127 x = gen_rtx_VEC_CONCAT (V16HImode, operands[2], operands[1]);
1128 }
1129 else
1130 {
1131 v = gen_rtvec (8, GEN_INT (4), GEN_INT (12), GEN_INT (5), GEN_INT (13),
1132 GEN_INT (6), GEN_INT (14), GEN_INT (7), GEN_INT (15));
1133 x = gen_rtx_VEC_CONCAT (V16HImode, operands[1], operands[2]);
1134 }
1135
1136 x = gen_rtx_VEC_SELECT (V8HImode, x, gen_rtx_PARALLEL (VOIDmode, v));
1137 emit_insn (gen_rtx_SET (VOIDmode, operands[0], x));
c3e96073 1138 DONE;
68d3bacf
BS
1139})
1140
1141(define_insn "*altivec_vmrglh_internal"
10ed84db 1142 [(set (match_operand:V8HI 0 "register_operand" "=v")
5aebfdad
RH
1143 (vec_select:V8HI
1144 (vec_concat:V16HI
1145 (match_operand:V8HI 1 "register_operand" "v")
1146 (match_operand:V8HI 2 "register_operand" "v"))
1147 (parallel [(const_int 4) (const_int 12)
1148 (const_int 5) (const_int 13)
1149 (const_int 6) (const_int 14)
1150 (const_int 7) (const_int 15)])))]
10ed84db 1151 "TARGET_ALTIVEC"
68d3bacf
BS
1152{
1153 if (BYTES_BIG_ENDIAN)
1154 return "vmrglh %0,%1,%2";
1155 else
1156 return "vmrghh %0,%2,%1";
1157}
1158 [(set_attr "type" "vecperm")])
1159
1160(define_insn "altivec_vmrglh_direct"
1161 [(set (match_operand:V8HI 0 "register_operand" "=v")
1162 (unspec:V8HI [(match_operand:V8HI 1 "register_operand" "v")
1163 (match_operand:V8HI 2 "register_operand" "v")]
1164 UNSPEC_VMRGL_DIRECT))]
1165 "TARGET_ALTIVEC"
10ed84db
AH
1166 "vmrglh %0,%1,%2"
1167 [(set_attr "type" "vecperm")])
1168
68d3bacf
BS
1169(define_expand "altivec_vmrglw"
1170 [(use (match_operand:V4SI 0 "register_operand" ""))
1171 (use (match_operand:V4SI 1 "register_operand" ""))
1172 (use (match_operand:V4SI 2 "register_operand" ""))]
1173 "VECTOR_MEM_ALTIVEC_P (V4SImode)"
1174{
1175 rtvec v;
1176 rtx x;
1177
1178 /* Special handling for LE with -maltivec=be. */
1179 if (!BYTES_BIG_ENDIAN && VECTOR_ELT_ORDER_BIG)
1180 {
1181 v = gen_rtvec (4, GEN_INT (0), GEN_INT (4), GEN_INT (1), GEN_INT (5));
1182 x = gen_rtx_VEC_CONCAT (V8SImode, operands[2], operands[1]);
1183 }
1184 else
1185 {
1186 v = gen_rtvec (4, GEN_INT (2), GEN_INT (6), GEN_INT (3), GEN_INT (7));
1187 x = gen_rtx_VEC_CONCAT (V8SImode, operands[1], operands[2]);
1188 }
1189
1190 x = gen_rtx_VEC_SELECT (V4SImode, x, gen_rtx_PARALLEL (VOIDmode, v));
1191 emit_insn (gen_rtx_SET (VOIDmode, operands[0], x));
c3e96073 1192 DONE;
68d3bacf
BS
1193})
1194
1195(define_insn "*altivec_vmrglw_internal"
10ed84db 1196 [(set (match_operand:V4SI 0 "register_operand" "=v")
5aebfdad
RH
1197 (vec_select:V4SI
1198 (vec_concat:V8SI
1199 (match_operand:V4SI 1 "register_operand" "v")
1200 (match_operand:V4SI 2 "register_operand" "v"))
1201 (parallel [(const_int 2) (const_int 6)
1202 (const_int 3) (const_int 7)])))]
a72c65c7 1203 "VECTOR_MEM_ALTIVEC_P (V4SImode)"
68d3bacf
BS
1204{
1205 if (BYTES_BIG_ENDIAN)
1206 return "vmrglw %0,%1,%2";
1207 else
1208 return "vmrghw %0,%2,%1";
1209}
1210 [(set_attr "type" "vecperm")])
1211
1212(define_insn "altivec_vmrglw_direct"
1213 [(set (match_operand:V4SI 0 "register_operand" "=v")
1214 (unspec:V4SI [(match_operand:V4SI 1 "register_operand" "v")
1215 (match_operand:V4SI 2 "register_operand" "v")]
1216 UNSPEC_VMRGL_DIRECT))]
1217 "TARGET_ALTIVEC"
10ed84db
AH
1218 "vmrglw %0,%1,%2"
1219 [(set_attr "type" "vecperm")])
1220
a72c65c7 1221(define_insn "*altivec_vmrglsf"
98b44b0e 1222 [(set (match_operand:V4SF 0 "register_operand" "=v")
5aebfdad
RH
1223 (vec_select:V4SF
1224 (vec_concat:V8SF
1225 (match_operand:V4SF 1 "register_operand" "v")
1226 (match_operand:V4SF 2 "register_operand" "v"))
1227 (parallel [(const_int 2) (const_int 6)
1228 (const_int 3) (const_int 7)])))]
a72c65c7 1229 "VECTOR_MEM_ALTIVEC_P (V4SFmode)"
68d3bacf
BS
1230{
1231 if (BYTES_BIG_ENDIAN)
1232 return "vmrglw %0,%1,%2";
1233 else
1234 return "vmrghw %0,%2,%1";
1235}
98b44b0e
IR
1236 [(set_attr "type" "vecperm")])
1237
0bd62dca
MM
1238;; Power8 vector merge even/odd
1239(define_insn "p8_vmrgew"
1240 [(set (match_operand:V4SI 0 "register_operand" "=v")
1241 (vec_select:V4SI
1242 (vec_concat:V8SI
1243 (match_operand:V4SI 1 "register_operand" "v")
1244 (match_operand:V4SI 2 "register_operand" "v"))
1245 (parallel [(const_int 0) (const_int 4)
1246 (const_int 2) (const_int 6)])))]
1247 "TARGET_P8_VECTOR"
d737743f
BS
1248{
1249 if (BYTES_BIG_ENDIAN)
1250 return "vmrgew %0,%1,%2";
1251 else
1252 return "vmrgow %0,%2,%1";
1253}
0bd62dca
MM
1254 [(set_attr "type" "vecperm")])
1255
1256(define_insn "p8_vmrgow"
1257 [(set (match_operand:V4SI 0 "register_operand" "=v")
1258 (vec_select:V4SI
1259 (vec_concat:V8SI
1260 (match_operand:V4SI 1 "register_operand" "v")
1261 (match_operand:V4SI 2 "register_operand" "v"))
1262 (parallel [(const_int 1) (const_int 5)
1263 (const_int 3) (const_int 7)])))]
1264 "TARGET_P8_VECTOR"
d737743f
BS
1265{
1266 if (BYTES_BIG_ENDIAN)
1267 return "vmrgow %0,%1,%2";
1268 else
1269 return "vmrgew %0,%2,%1";
1270}
0bd62dca
MM
1271 [(set_attr "type" "vecperm")])
1272
1a5d2261
BS
1273(define_expand "vec_widen_umult_even_v16qi"
1274 [(use (match_operand:V8HI 0 "register_operand" ""))
1275 (use (match_operand:V16QI 1 "register_operand" ""))
1276 (use (match_operand:V16QI 2 "register_operand" ""))]
1277 "TARGET_ALTIVEC"
1278{
d13dfec8 1279 if (VECTOR_ELT_ORDER_BIG)
1a5d2261
BS
1280 emit_insn (gen_altivec_vmuleub (operands[0], operands[1], operands[2]));
1281 else
1282 emit_insn (gen_altivec_vmuloub (operands[0], operands[1], operands[2]));
1283 DONE;
1284})
1285
1286(define_expand "vec_widen_smult_even_v16qi"
1287 [(use (match_operand:V8HI 0 "register_operand" ""))
1288 (use (match_operand:V16QI 1 "register_operand" ""))
1289 (use (match_operand:V16QI 2 "register_operand" ""))]
1290 "TARGET_ALTIVEC"
1291{
d13dfec8 1292 if (VECTOR_ELT_ORDER_BIG)
1a5d2261
BS
1293 emit_insn (gen_altivec_vmulesb (operands[0], operands[1], operands[2]));
1294 else
1295 emit_insn (gen_altivec_vmulosb (operands[0], operands[1], operands[2]));
1296 DONE;
1297})
1298
1299(define_expand "vec_widen_umult_even_v8hi"
1300 [(use (match_operand:V4SI 0 "register_operand" ""))
1301 (use (match_operand:V8HI 1 "register_operand" ""))
1302 (use (match_operand:V8HI 2 "register_operand" ""))]
1303 "TARGET_ALTIVEC"
1304{
d13dfec8 1305 if (VECTOR_ELT_ORDER_BIG)
1a5d2261
BS
1306 emit_insn (gen_altivec_vmuleuh (operands[0], operands[1], operands[2]));
1307 else
1308 emit_insn (gen_altivec_vmulouh (operands[0], operands[1], operands[2]));
1309 DONE;
1310})
1311
1312(define_expand "vec_widen_smult_even_v8hi"
1313 [(use (match_operand:V4SI 0 "register_operand" ""))
1314 (use (match_operand:V8HI 1 "register_operand" ""))
1315 (use (match_operand:V8HI 2 "register_operand" ""))]
1316 "TARGET_ALTIVEC"
1317{
d13dfec8 1318 if (VECTOR_ELT_ORDER_BIG)
1a5d2261
BS
1319 emit_insn (gen_altivec_vmulesh (operands[0], operands[1], operands[2]));
1320 else
1321 emit_insn (gen_altivec_vmulosh (operands[0], operands[1], operands[2]));
1322 DONE;
1323})
1324
1325(define_expand "vec_widen_umult_odd_v16qi"
1326 [(use (match_operand:V8HI 0 "register_operand" ""))
1327 (use (match_operand:V16QI 1 "register_operand" ""))
1328 (use (match_operand:V16QI 2 "register_operand" ""))]
1329 "TARGET_ALTIVEC"
1330{
d13dfec8 1331 if (VECTOR_ELT_ORDER_BIG)
1a5d2261
BS
1332 emit_insn (gen_altivec_vmuloub (operands[0], operands[1], operands[2]));
1333 else
1334 emit_insn (gen_altivec_vmuleub (operands[0], operands[1], operands[2]));
1335 DONE;
1336})
1337
1338(define_expand "vec_widen_smult_odd_v16qi"
1339 [(use (match_operand:V8HI 0 "register_operand" ""))
1340 (use (match_operand:V16QI 1 "register_operand" ""))
1341 (use (match_operand:V16QI 2 "register_operand" ""))]
1342 "TARGET_ALTIVEC"
1343{
d13dfec8 1344 if (VECTOR_ELT_ORDER_BIG)
1a5d2261
BS
1345 emit_insn (gen_altivec_vmulosb (operands[0], operands[1], operands[2]));
1346 else
1347 emit_insn (gen_altivec_vmulesb (operands[0], operands[1], operands[2]));
1348 DONE;
1349})
1350
1351(define_expand "vec_widen_umult_odd_v8hi"
1352 [(use (match_operand:V4SI 0 "register_operand" ""))
1353 (use (match_operand:V8HI 1 "register_operand" ""))
1354 (use (match_operand:V8HI 2 "register_operand" ""))]
1355 "TARGET_ALTIVEC"
1356{
d13dfec8 1357 if (VECTOR_ELT_ORDER_BIG)
1a5d2261
BS
1358 emit_insn (gen_altivec_vmulouh (operands[0], operands[1], operands[2]));
1359 else
1360 emit_insn (gen_altivec_vmuleuh (operands[0], operands[1], operands[2]));
1361 DONE;
1362})
1363
1364(define_expand "vec_widen_smult_odd_v8hi"
1365 [(use (match_operand:V4SI 0 "register_operand" ""))
1366 (use (match_operand:V8HI 1 "register_operand" ""))
1367 (use (match_operand:V8HI 2 "register_operand" ""))]
1368 "TARGET_ALTIVEC"
1369{
d13dfec8 1370 if (VECTOR_ELT_ORDER_BIG)
1a5d2261
BS
1371 emit_insn (gen_altivec_vmulosh (operands[0], operands[1], operands[2]));
1372 else
1373 emit_insn (gen_altivec_vmulesh (operands[0], operands[1], operands[2]));
1374 DONE;
1375})
1376
1377(define_insn "altivec_vmuleub"
10ed84db
AH
1378 [(set (match_operand:V8HI 0 "register_operand" "=v")
1379 (unspec:V8HI [(match_operand:V16QI 1 "register_operand" "v")
3aca4bff
DE
1380 (match_operand:V16QI 2 "register_operand" "v")]
1381 UNSPEC_VMULEUB))]
10ed84db
AH
1382 "TARGET_ALTIVEC"
1383 "vmuleub %0,%1,%2"
1384 [(set_attr "type" "veccomplex")])
1385
1a5d2261 1386(define_insn "altivec_vmuloub"
10ed84db
AH
1387 [(set (match_operand:V8HI 0 "register_operand" "=v")
1388 (unspec:V8HI [(match_operand:V16QI 1 "register_operand" "v")
3aca4bff 1389 (match_operand:V16QI 2 "register_operand" "v")]
1a5d2261 1390 UNSPEC_VMULOUB))]
10ed84db 1391 "TARGET_ALTIVEC"
1a5d2261 1392 "vmuloub %0,%1,%2"
10ed84db
AH
1393 [(set_attr "type" "veccomplex")])
1394
1a5d2261 1395(define_insn "altivec_vmulesb"
10ed84db
AH
1396 [(set (match_operand:V8HI 0 "register_operand" "=v")
1397 (unspec:V8HI [(match_operand:V16QI 1 "register_operand" "v")
3aca4bff 1398 (match_operand:V16QI 2 "register_operand" "v")]
1a5d2261 1399 UNSPEC_VMULESB))]
10ed84db 1400 "TARGET_ALTIVEC"
1a5d2261 1401 "vmulesb %0,%1,%2"
10ed84db
AH
1402 [(set_attr "type" "veccomplex")])
1403
1a5d2261 1404(define_insn "altivec_vmulosb"
10ed84db
AH
1405 [(set (match_operand:V8HI 0 "register_operand" "=v")
1406 (unspec:V8HI [(match_operand:V16QI 1 "register_operand" "v")
3aca4bff
DE
1407 (match_operand:V16QI 2 "register_operand" "v")]
1408 UNSPEC_VMULOSB))]
10ed84db
AH
1409 "TARGET_ALTIVEC"
1410 "vmulosb %0,%1,%2"
1411 [(set_attr "type" "veccomplex")])
1412
1a5d2261
BS
1413(define_insn "altivec_vmuleuh"
1414 [(set (match_operand:V4SI 0 "register_operand" "=v")
1415 (unspec:V4SI [(match_operand:V8HI 1 "register_operand" "v")
1416 (match_operand:V8HI 2 "register_operand" "v")]
1417 UNSPEC_VMULEUH))]
1418 "TARGET_ALTIVEC"
1419 "vmuleuh %0,%1,%2"
1420 [(set_attr "type" "veccomplex")])
1421
1422(define_insn "altivec_vmulouh"
10ed84db
AH
1423 [(set (match_operand:V4SI 0 "register_operand" "=v")
1424 (unspec:V4SI [(match_operand:V8HI 1 "register_operand" "v")
3aca4bff
DE
1425 (match_operand:V8HI 2 "register_operand" "v")]
1426 UNSPEC_VMULOUH))]
10ed84db
AH
1427 "TARGET_ALTIVEC"
1428 "vmulouh %0,%1,%2"
1429 [(set_attr "type" "veccomplex")])
1430
1a5d2261
BS
1431(define_insn "altivec_vmulesh"
1432 [(set (match_operand:V4SI 0 "register_operand" "=v")
1433 (unspec:V4SI [(match_operand:V8HI 1 "register_operand" "v")
1434 (match_operand:V8HI 2 "register_operand" "v")]
1435 UNSPEC_VMULESH))]
1436 "TARGET_ALTIVEC"
1437 "vmulesh %0,%1,%2"
1438 [(set_attr "type" "veccomplex")])
1439
1440(define_insn "altivec_vmulosh"
10ed84db
AH
1441 [(set (match_operand:V4SI 0 "register_operand" "=v")
1442 (unspec:V4SI [(match_operand:V8HI 1 "register_operand" "v")
3aca4bff
DE
1443 (match_operand:V8HI 2 "register_operand" "v")]
1444 UNSPEC_VMULOSH))]
10ed84db
AH
1445 "TARGET_ALTIVEC"
1446 "vmulosh %0,%1,%2"
1447 [(set_attr "type" "veccomplex")])
1448
f96bc213 1449
dd7a40e1 1450;; Vector pack/unpack
10ed84db
AH
1451(define_insn "altivec_vpkpx"
1452 [(set (match_operand:V8HI 0 "register_operand" "=v")
1453 (unspec:V8HI [(match_operand:V4SI 1 "register_operand" "v")
3aca4bff
DE
1454 (match_operand:V4SI 2 "register_operand" "v")]
1455 UNSPEC_VPKPX))]
10ed84db 1456 "TARGET_ALTIVEC"
a4ad093b
BS
1457 "*
1458 {
52a93551 1459 if (VECTOR_ELT_ORDER_BIG)
a4ad093b
BS
1460 return \"vpkpx %0,%1,%2\";
1461 else
1462 return \"vpkpx %0,%2,%1\";
1463 }"
10ed84db
AH
1464 [(set_attr "type" "vecperm")])
1465
a5965b52
MM
1466(define_insn "altivec_vpks<VI_char>ss"
1467 [(set (match_operand:<VP_small> 0 "register_operand" "=v")
1468 (unspec:<VP_small> [(match_operand:VP 1 "register_operand" "v")
1469 (match_operand:VP 2 "register_operand" "v")]
1470 UNSPEC_VPACK_SIGN_SIGN_SAT))]
1471 "<VI_unit>"
a4ad093b
BS
1472 "*
1473 {
52a93551 1474 if (VECTOR_ELT_ORDER_BIG)
a4ad093b
BS
1475 return \"vpks<VI_char>ss %0,%1,%2\";
1476 else
1477 return \"vpks<VI_char>ss %0,%2,%1\";
1478 }"
10ed84db
AH
1479 [(set_attr "type" "vecperm")])
1480
a5965b52
MM
1481(define_insn "altivec_vpks<VI_char>us"
1482 [(set (match_operand:<VP_small> 0 "register_operand" "=v")
1483 (unspec:<VP_small> [(match_operand:VP 1 "register_operand" "v")
1484 (match_operand:VP 2 "register_operand" "v")]
1485 UNSPEC_VPACK_SIGN_UNS_SAT))]
1486 "<VI_unit>"
a4ad093b
BS
1487 "*
1488 {
52a93551 1489 if (VECTOR_ELT_ORDER_BIG)
a4ad093b
BS
1490 return \"vpks<VI_char>us %0,%1,%2\";
1491 else
1492 return \"vpks<VI_char>us %0,%2,%1\";
1493 }"
10ed84db
AH
1494 [(set_attr "type" "vecperm")])
1495
a5965b52
MM
1496(define_insn "altivec_vpku<VI_char>us"
1497 [(set (match_operand:<VP_small> 0 "register_operand" "=v")
1498 (unspec:<VP_small> [(match_operand:VP 1 "register_operand" "v")
1499 (match_operand:VP 2 "register_operand" "v")]
1500 UNSPEC_VPACK_UNS_UNS_SAT))]
1501 "<VI_unit>"
a4ad093b
BS
1502 "*
1503 {
52a93551 1504 if (VECTOR_ELT_ORDER_BIG)
a4ad093b
BS
1505 return \"vpku<VI_char>us %0,%1,%2\";
1506 else
1507 return \"vpku<VI_char>us %0,%2,%1\";
1508 }"
10ed84db
AH
1509 [(set_attr "type" "vecperm")])
1510
a5965b52
MM
1511(define_insn "altivec_vpku<VI_char>um"
1512 [(set (match_operand:<VP_small> 0 "register_operand" "=v")
1513 (unspec:<VP_small> [(match_operand:VP 1 "register_operand" "v")
1514 (match_operand:VP 2 "register_operand" "v")]
1515 UNSPEC_VPACK_UNS_UNS_MOD))]
1516 "<VI_unit>"
a4ad093b 1517 "*
52a93551
BS
1518 {
1519 if (VECTOR_ELT_ORDER_BIG)
1520 return \"vpku<VI_char>um %0,%1,%2\";
1521 else
1522 return \"vpku<VI_char>um %0,%2,%1\";
1523 }"
1524 [(set_attr "type" "vecperm")])
1525
1526(define_insn "altivec_vpku<VI_char>um_direct"
1527 [(set (match_operand:<VP_small> 0 "register_operand" "=v")
1528 (unspec:<VP_small> [(match_operand:VP 1 "register_operand" "v")
1529 (match_operand:VP 2 "register_operand" "v")]
1530 UNSPEC_VPACK_UNS_UNS_MOD_DIRECT))]
1531 "<VI_unit>"
1532 "*
a4ad093b
BS
1533 {
1534 if (BYTES_BIG_ENDIAN)
1535 return \"vpku<VI_char>um %0,%1,%2\";
1536 else
1537 return \"vpku<VI_char>um %0,%2,%1\";
1538 }"
10ed84db
AH
1539 [(set_attr "type" "vecperm")])
1540
a72c65c7 1541(define_insn "*altivec_vrl<VI_char>"
a5965b52
MM
1542 [(set (match_operand:VI2 0 "register_operand" "=v")
1543 (rotate:VI2 (match_operand:VI2 1 "register_operand" "v")
1544 (match_operand:VI2 2 "register_operand" "v")))]
1545 "<VI_unit>"
aba5fb01 1546 "vrl<VI_char> %0,%1,%2"
10ed84db
AH
1547 [(set_attr "type" "vecsimple")])
1548
10ed84db
AH
1549(define_insn "altivec_vsl"
1550 [(set (match_operand:V4SI 0 "register_operand" "=v")
1551 (unspec:V4SI [(match_operand:V4SI 1 "register_operand" "v")
3aca4bff
DE
1552 (match_operand:V4SI 2 "register_operand" "v")]
1553 UNSPEC_VSLV4SI))]
10ed84db
AH
1554 "TARGET_ALTIVEC"
1555 "vsl %0,%1,%2"
1556 [(set_attr "type" "vecperm")])
1557
1558(define_insn "altivec_vslo"
1559 [(set (match_operand:V4SI 0 "register_operand" "=v")
1560 (unspec:V4SI [(match_operand:V4SI 1 "register_operand" "v")
3aca4bff
DE
1561 (match_operand:V4SI 2 "register_operand" "v")]
1562 UNSPEC_VSLO))]
10ed84db
AH
1563 "TARGET_ALTIVEC"
1564 "vslo %0,%1,%2"
1565 [(set_attr "type" "vecperm")])
1566
a72c65c7 1567(define_insn "*altivec_vsl<VI_char>"
a5965b52
MM
1568 [(set (match_operand:VI2 0 "register_operand" "=v")
1569 (ashift:VI2 (match_operand:VI2 1 "register_operand" "v")
1570 (match_operand:VI2 2 "register_operand" "v")))]
1571 "<VI_unit>"
e83a75a7
IR
1572 "vsl<VI_char> %0,%1,%2"
1573 [(set_attr "type" "vecsimple")])
1574
a72c65c7 1575(define_insn "*altivec_vsr<VI_char>"
a5965b52
MM
1576 [(set (match_operand:VI2 0 "register_operand" "=v")
1577 (lshiftrt:VI2 (match_operand:VI2 1 "register_operand" "v")
1578 (match_operand:VI2 2 "register_operand" "v")))]
1579 "<VI_unit>"
aba5fb01 1580 "vsr<VI_char> %0,%1,%2"
10ed84db
AH
1581 [(set_attr "type" "vecsimple")])
1582
a72c65c7 1583(define_insn "*altivec_vsra<VI_char>"
a5965b52
MM
1584 [(set (match_operand:VI2 0 "register_operand" "=v")
1585 (ashiftrt:VI2 (match_operand:VI2 1 "register_operand" "v")
1586 (match_operand:VI2 2 "register_operand" "v")))]
1587 "<VI_unit>"
aba5fb01 1588 "vsra<VI_char> %0,%1,%2"
10ed84db
AH
1589 [(set_attr "type" "vecsimple")])
1590
1591(define_insn "altivec_vsr"
1592 [(set (match_operand:V4SI 0 "register_operand" "=v")
1593 (unspec:V4SI [(match_operand:V4SI 1 "register_operand" "v")
3aca4bff
DE
1594 (match_operand:V4SI 2 "register_operand" "v")]
1595 UNSPEC_VSR))]
10ed84db
AH
1596 "TARGET_ALTIVEC"
1597 "vsr %0,%1,%2"
1598 [(set_attr "type" "vecperm")])
1599
1600(define_insn "altivec_vsro"
1601 [(set (match_operand:V4SI 0 "register_operand" "=v")
1602 (unspec:V4SI [(match_operand:V4SI 1 "register_operand" "v")
3aca4bff
DE
1603 (match_operand:V4SI 2 "register_operand" "v")]
1604 UNSPEC_VSRO))]
10ed84db
AH
1605 "TARGET_ALTIVEC"
1606 "vsro %0,%1,%2"
1607 [(set_attr "type" "vecperm")])
1608
10ed84db
AH
1609(define_insn "altivec_vsum4ubs"
1610 [(set (match_operand:V4SI 0 "register_operand" "=v")
1611 (unspec:V4SI [(match_operand:V16QI 1 "register_operand" "v")
3aca4bff
DE
1612 (match_operand:V4SI 2 "register_operand" "v")]
1613 UNSPEC_VSUM4UBS))
27ffac37 1614 (set (reg:SI 110) (unspec:SI [(const_int 0)] UNSPEC_SET_VSCR))]
10ed84db
AH
1615 "TARGET_ALTIVEC"
1616 "vsum4ubs %0,%1,%2"
1617 [(set_attr "type" "veccomplex")])
1618
aba5fb01 1619(define_insn "altivec_vsum4s<VI_char>s"
10ed84db 1620 [(set (match_operand:V4SI 0 "register_operand" "=v")
aba5fb01 1621 (unspec:V4SI [(match_operand:VIshort 1 "register_operand" "v")
3aca4bff
DE
1622 (match_operand:V4SI 2 "register_operand" "v")]
1623 UNSPEC_VSUM4S))
27ffac37 1624 (set (reg:SI 110) (unspec:SI [(const_int 0)] UNSPEC_SET_VSCR))]
10ed84db 1625 "TARGET_ALTIVEC"
aba5fb01 1626 "vsum4s<VI_char>s %0,%1,%2"
10ed84db
AH
1627 [(set_attr "type" "veccomplex")])
1628
7b1cd427
BS
1629;; FIXME: For the following two patterns, the scratch should only be
1630;; allocated for !VECTOR_ELT_ORDER_BIG, and the instructions should
1631;; be emitted separately.
10ed84db
AH
1632(define_insn "altivec_vsum2sws"
1633 [(set (match_operand:V4SI 0 "register_operand" "=v")
1634 (unspec:V4SI [(match_operand:V4SI 1 "register_operand" "v")
3aca4bff
DE
1635 (match_operand:V4SI 2 "register_operand" "v")]
1636 UNSPEC_VSUM2SWS))
7b1cd427
BS
1637 (set (reg:SI 110) (unspec:SI [(const_int 0)] UNSPEC_SET_VSCR))
1638 (clobber (match_scratch:V4SI 3 "=v"))]
10ed84db 1639 "TARGET_ALTIVEC"
7b1cd427
BS
1640{
1641 if (VECTOR_ELT_ORDER_BIG)
1642 return "vsum2sws %0,%1,%2";
1643 else
1644 return "vsldoi %3,%2,%2,12\n\tvsum2sws %3,%1,%3\n\tvsldoi %0,%3,%3,4";
1645}
1646 [(set_attr "type" "veccomplex")
1647 (set (attr "length")
1648 (if_then_else
1649 (match_test "VECTOR_ELT_ORDER_BIG")
1650 (const_string "4")
1651 (const_string "12")))])
10ed84db
AH
1652
1653(define_insn "altivec_vsumsws"
1654 [(set (match_operand:V4SI 0 "register_operand" "=v")
1655 (unspec:V4SI [(match_operand:V4SI 1 "register_operand" "v")
3aca4bff
DE
1656 (match_operand:V4SI 2 "register_operand" "v")]
1657 UNSPEC_VSUMSWS))
b80afde9
BS
1658 (set (reg:SI 110) (unspec:SI [(const_int 0)] UNSPEC_SET_VSCR))
1659 (clobber (match_scratch:V4SI 3 "=v"))]
1660 "TARGET_ALTIVEC"
1661{
7b1cd427 1662 if (VECTOR_ELT_ORDER_BIG)
b80afde9
BS
1663 return "vsumsws %0,%1,%2";
1664 else
b90ab1ba 1665 return "vspltw %3,%2,0\n\tvsumsws %3,%1,%3\n\tvsldoi %0,%3,%3,12";
b80afde9
BS
1666}
1667 [(set_attr "type" "veccomplex")
1668 (set (attr "length")
1669 (if_then_else
7b1cd427 1670 (match_test "(VECTOR_ELT_ORDER_BIG)")
b80afde9
BS
1671 (const_string "4")
1672 (const_string "12")))])
1673
1674(define_insn "altivec_vsumsws_direct"
1675 [(set (match_operand:V4SI 0 "register_operand" "=v")
1676 (unspec:V4SI [(match_operand:V4SI 1 "register_operand" "v")
1677 (match_operand:V4SI 2 "register_operand" "v")]
1678 UNSPEC_VSUMSWS_DIRECT))
27ffac37 1679 (set (reg:SI 110) (unspec:SI [(const_int 0)] UNSPEC_SET_VSCR))]
10ed84db
AH
1680 "TARGET_ALTIVEC"
1681 "vsumsws %0,%1,%2"
1682 [(set_attr "type" "veccomplex")])
1683
bf53d4b8 1684(define_expand "altivec_vspltb"
c3e96073
BS
1685 [(use (match_operand:V16QI 0 "register_operand" ""))
1686 (use (match_operand:V16QI 1 "register_operand" ""))
1687 (use (match_operand:QI 2 "u5bit_cint_operand" ""))]
bf53d4b8
BS
1688 "TARGET_ALTIVEC"
1689{
1690 rtvec v;
1691 rtx x;
1692
1693 /* Special handling for LE with -maltivec=be. We have to reflect
1694 the actual selected index for the splat in the RTL. */
1695 if (!BYTES_BIG_ENDIAN && VECTOR_ELT_ORDER_BIG)
1696 operands[2] = GEN_INT (15 - INTVAL (operands[2]));
1697
1698 v = gen_rtvec (1, operands[2]);
1699 x = gen_rtx_VEC_SELECT (QImode, operands[1], gen_rtx_PARALLEL (VOIDmode, v));
1700 x = gen_rtx_VEC_DUPLICATE (V16QImode, x);
1701 emit_insn (gen_rtx_SET (VOIDmode, operands[0], x));
1702 DONE;
1703})
1704
1705(define_insn "*altivec_vspltb_internal"
10ed84db 1706 [(set (match_operand:V16QI 0 "register_operand" "=v")
e5f9d916
AH
1707 (vec_duplicate:V16QI
1708 (vec_select:QI (match_operand:V16QI 1 "register_operand" "v")
1709 (parallel
afca671b 1710 [(match_operand:QI 2 "u5bit_cint_operand" "")]))))]
10ed84db 1711 "TARGET_ALTIVEC"
bf53d4b8
BS
1712{
1713 /* For true LE, this adjusts the selected index. For LE with
1714 -maltivec=be, this reverses what was done in the define_expand
1715 because the instruction already has big-endian bias. */
1716 if (!BYTES_BIG_ENDIAN)
1717 operands[2] = GEN_INT (15 - INTVAL (operands[2]));
1718
1719 return "vspltb %0,%1,%2";
1720}
1721 [(set_attr "type" "vecperm")])
1722
1723(define_insn "altivec_vspltb_direct"
1724 [(set (match_operand:V16QI 0 "register_operand" "=v")
1725 (unspec:V16QI [(match_operand:V16QI 1 "register_operand" "v")
1726 (match_operand:QI 2 "u5bit_cint_operand" "i")]
1727 UNSPEC_VSPLT_DIRECT))]
1728 "TARGET_ALTIVEC"
10ed84db
AH
1729 "vspltb %0,%1,%2"
1730 [(set_attr "type" "vecperm")])
1731
bf53d4b8 1732(define_expand "altivec_vsplth"
c3e96073
BS
1733 [(use (match_operand:V8HI 0 "register_operand" ""))
1734 (use (match_operand:V8HI 1 "register_operand" ""))
1735 (use (match_operand:QI 2 "u5bit_cint_operand" ""))]
bf53d4b8
BS
1736 "TARGET_ALTIVEC"
1737{
1738 rtvec v;
1739 rtx x;
1740
1741 /* Special handling for LE with -maltivec=be. We have to reflect
1742 the actual selected index for the splat in the RTL. */
1743 if (!BYTES_BIG_ENDIAN && VECTOR_ELT_ORDER_BIG)
1744 operands[2] = GEN_INT (7 - INTVAL (operands[2]));
1745
1746 v = gen_rtvec (1, operands[2]);
1747 x = gen_rtx_VEC_SELECT (HImode, operands[1], gen_rtx_PARALLEL (VOIDmode, v));
1748 x = gen_rtx_VEC_DUPLICATE (V8HImode, x);
1749 emit_insn (gen_rtx_SET (VOIDmode, operands[0], x));
1750 DONE;
1751})
1752
1753(define_insn "*altivec_vsplth_internal"
10ed84db 1754 [(set (match_operand:V8HI 0 "register_operand" "=v")
e5f9d916
AH
1755 (vec_duplicate:V8HI
1756 (vec_select:HI (match_operand:V8HI 1 "register_operand" "v")
1757 (parallel
afca671b 1758 [(match_operand:QI 2 "u5bit_cint_operand" "")]))))]
10ed84db 1759 "TARGET_ALTIVEC"
bf53d4b8
BS
1760{
1761 /* For true LE, this adjusts the selected index. For LE with
1762 -maltivec=be, this reverses what was done in the define_expand
1763 because the instruction already has big-endian bias. */
1764 if (!BYTES_BIG_ENDIAN)
1765 operands[2] = GEN_INT (7 - INTVAL (operands[2]));
1766
1767 return "vsplth %0,%1,%2";
1768}
1769 [(set_attr "type" "vecperm")])
1770
1771(define_insn "altivec_vsplth_direct"
1772 [(set (match_operand:V8HI 0 "register_operand" "=v")
1773 (unspec:V8HI [(match_operand:V8HI 1 "register_operand" "v")
1774 (match_operand:QI 2 "u5bit_cint_operand" "i")]
1775 UNSPEC_VSPLT_DIRECT))]
1776 "TARGET_ALTIVEC"
10ed84db
AH
1777 "vsplth %0,%1,%2"
1778 [(set_attr "type" "vecperm")])
1779
bf53d4b8 1780(define_expand "altivec_vspltw"
c3e96073
BS
1781 [(use (match_operand:V4SI 0 "register_operand" ""))
1782 (use (match_operand:V4SI 1 "register_operand" ""))
1783 (use (match_operand:QI 2 "u5bit_cint_operand" ""))]
bf53d4b8
BS
1784 "TARGET_ALTIVEC"
1785{
1786 rtvec v;
1787 rtx x;
1788
1789 /* Special handling for LE with -maltivec=be. We have to reflect
1790 the actual selected index for the splat in the RTL. */
1791 if (!BYTES_BIG_ENDIAN && VECTOR_ELT_ORDER_BIG)
1792 operands[2] = GEN_INT (3 - INTVAL (operands[2]));
1793
1794 v = gen_rtvec (1, operands[2]);
1795 x = gen_rtx_VEC_SELECT (SImode, operands[1], gen_rtx_PARALLEL (VOIDmode, v));
1796 x = gen_rtx_VEC_DUPLICATE (V4SImode, x);
1797 emit_insn (gen_rtx_SET (VOIDmode, operands[0], x));
1798 DONE;
1799})
1800
1801(define_insn "*altivec_vspltw_internal"
10ed84db 1802 [(set (match_operand:V4SI 0 "register_operand" "=v")
e5f9d916
AH
1803 (vec_duplicate:V4SI
1804 (vec_select:SI (match_operand:V4SI 1 "register_operand" "v")
1805 (parallel
afca671b 1806 [(match_operand:QI 2 "u5bit_cint_operand" "i")]))))]
10ed84db 1807 "TARGET_ALTIVEC"
bf53d4b8
BS
1808{
1809 /* For true LE, this adjusts the selected index. For LE with
1810 -maltivec=be, this reverses what was done in the define_expand
1811 because the instruction already has big-endian bias. */
1812 if (!BYTES_BIG_ENDIAN)
1813 operands[2] = GEN_INT (3 - INTVAL (operands[2]));
1814
1815 return "vspltw %0,%1,%2";
1816}
1817 [(set_attr "type" "vecperm")])
1818
1819(define_insn "altivec_vspltw_direct"
1820 [(set (match_operand:V4SI 0 "register_operand" "=v")
1821 (unspec:V4SI [(match_operand:V4SI 1 "register_operand" "v")
1822 (match_operand:QI 2 "u5bit_cint_operand" "i")]
1823 UNSPEC_VSPLT_DIRECT))]
1824 "TARGET_ALTIVEC"
10ed84db
AH
1825 "vspltw %0,%1,%2"
1826 [(set_attr "type" "vecperm")])
1827
bf53d4b8 1828(define_expand "altivec_vspltsf"
c3e96073
BS
1829 [(use (match_operand:V4SF 0 "register_operand" ""))
1830 (use (match_operand:V4SF 1 "register_operand" ""))
1831 (use (match_operand:QI 2 "u5bit_cint_operand" ""))]
bf53d4b8
BS
1832 "TARGET_ALTIVEC"
1833{
1834 rtvec v;
1835 rtx x;
1836
1837 /* Special handling for LE with -maltivec=be. We have to reflect
1838 the actual selected index for the splat in the RTL. */
1839 if (!BYTES_BIG_ENDIAN && VECTOR_ELT_ORDER_BIG)
1840 operands[2] = GEN_INT (3 - INTVAL (operands[2]));
1841
1842 v = gen_rtvec (1, operands[2]);
1843 x = gen_rtx_VEC_SELECT (SFmode, operands[1], gen_rtx_PARALLEL (VOIDmode, v));
1844 x = gen_rtx_VEC_DUPLICATE (V4SFmode, x);
1845 emit_insn (gen_rtx_SET (VOIDmode, operands[0], x));
1846 DONE;
1847})
1848
1849(define_insn "*altivec_vspltsf_internal"
3aca4bff
DE
1850 [(set (match_operand:V4SF 0 "register_operand" "=v")
1851 (vec_duplicate:V4SF
1852 (vec_select:SF (match_operand:V4SF 1 "register_operand" "v")
1853 (parallel
1854 [(match_operand:QI 2 "u5bit_cint_operand" "i")]))))]
a72c65c7 1855 "VECTOR_UNIT_ALTIVEC_P (V4SFmode)"
bf53d4b8
BS
1856{
1857 /* For true LE, this adjusts the selected index. For LE with
1858 -maltivec=be, this reverses what was done in the define_expand
1859 because the instruction already has big-endian bias. */
1860 if (!BYTES_BIG_ENDIAN)
1861 operands[2] = GEN_INT (3 - INTVAL (operands[2]));
1862
1863 return "vspltw %0,%1,%2";
1864}
3aca4bff
DE
1865 [(set_attr "type" "vecperm")])
1866
27ffac37
PB
1867(define_insn "altivec_vspltis<VI_char>"
1868 [(set (match_operand:VI 0 "register_operand" "=v")
1869 (vec_duplicate:VI
afca671b 1870 (match_operand:QI 1 "s5bit_cint_operand" "i")))]
10ed84db 1871 "TARGET_ALTIVEC"
27ffac37 1872 "vspltis<VI_char> %0,%1"
310b9b1d 1873 [(set_attr "type" "vecperm")])
10ed84db 1874
29e6733c 1875(define_insn "*altivec_vrfiz"
10ed84db 1876 [(set (match_operand:V4SF 0 "register_operand" "=v")
5aebfdad 1877 (fix:V4SF (match_operand:V4SF 1 "register_operand" "v")))]
a72c65c7 1878 "VECTOR_UNIT_ALTIVEC_P (V4SFmode)"
98c9a8e8 1879 "vrfiz %0,%1"
10ed84db
AH
1880 [(set_attr "type" "vecfloat")])
1881
60331d00
BS
1882(define_expand "altivec_vperm_<mode>"
1883 [(set (match_operand:VM 0 "register_operand" "=v")
1884 (unspec:VM [(match_operand:VM 1 "register_operand" "v")
1885 (match_operand:VM 2 "register_operand" "v")
1886 (match_operand:V16QI 3 "register_operand" "v")]
1887 UNSPEC_VPERM))]
1888 "TARGET_ALTIVEC"
1889{
1890 if (!VECTOR_ELT_ORDER_BIG)
1891 {
1892 altivec_expand_vec_perm_le (operands);
1893 DONE;
1894 }
1895})
1896
1897(define_insn "*altivec_vperm_<mode>_internal"
a72c65c7
MM
1898 [(set (match_operand:VM 0 "register_operand" "=v")
1899 (unspec:VM [(match_operand:VM 1 "register_operand" "v")
1900 (match_operand:VM 2 "register_operand" "v")
1901 (match_operand:V16QI 3 "register_operand" "v")]
1902 UNSPEC_VPERM))]
1903 "TARGET_ALTIVEC"
1904 "vperm %0,%1,%2,%3"
1905 [(set_attr "type" "vecperm")])
1906
60331d00
BS
1907(define_expand "altivec_vperm_<mode>_uns"
1908 [(set (match_operand:VM 0 "register_operand" "=v")
1909 (unspec:VM [(match_operand:VM 1 "register_operand" "v")
1910 (match_operand:VM 2 "register_operand" "v")
1911 (match_operand:V16QI 3 "register_operand" "v")]
1912 UNSPEC_VPERM_UNS))]
1913 "TARGET_ALTIVEC"
1914{
1915 if (!VECTOR_ELT_ORDER_BIG)
1916 {
1917 altivec_expand_vec_perm_le (operands);
1918 DONE;
1919 }
1920})
1921
1922(define_insn "*altivec_vperm_<mode>_uns_internal"
a72c65c7
MM
1923 [(set (match_operand:VM 0 "register_operand" "=v")
1924 (unspec:VM [(match_operand:VM 1 "register_operand" "v")
1925 (match_operand:VM 2 "register_operand" "v")
1926 (match_operand:V16QI 3 "register_operand" "v")]
1927 UNSPEC_VPERM_UNS))]
10ed84db
AH
1928 "TARGET_ALTIVEC"
1929 "vperm %0,%1,%2,%3"
1930 [(set_attr "type" "vecperm")])
1931
cba86444
RH
1932(define_expand "vec_permv16qi"
1933 [(set (match_operand:V16QI 0 "register_operand" "")
1934 (unspec:V16QI [(match_operand:V16QI 1 "register_operand" "")
1935 (match_operand:V16QI 2 "register_operand" "")
1936 (match_operand:V16QI 3 "register_operand" "")]
1937 UNSPEC_VPERM))]
1938 "TARGET_ALTIVEC"
f200869a
BS
1939{
1940 if (!BYTES_BIG_ENDIAN) {
1941 altivec_expand_vec_perm_le (operands);
1942 DONE;
1943 }
1944})
cba86444 1945
5aebfdad
RH
1946(define_expand "vec_perm_constv16qi"
1947 [(match_operand:V16QI 0 "register_operand" "")
1948 (match_operand:V16QI 1 "register_operand" "")
1949 (match_operand:V16QI 2 "register_operand" "")
1950 (match_operand:V16QI 3 "" "")]
1951 "TARGET_ALTIVEC"
1952{
1953 if (altivec_expand_vec_perm_const (operands))
1954 DONE;
1955 else
1956 FAIL;
1957})
1958
29e6733c 1959(define_insn "altivec_vrfip" ; ceil
10ed84db 1960 [(set (match_operand:V4SF 0 "register_operand" "=v")
3aca4bff 1961 (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "v")]
29e6733c 1962 UNSPEC_FRIP))]
10ed84db 1963 "TARGET_ALTIVEC"
98c9a8e8 1964 "vrfip %0,%1"
10ed84db
AH
1965 [(set_attr "type" "vecfloat")])
1966
1967(define_insn "altivec_vrfin"
1968 [(set (match_operand:V4SF 0 "register_operand" "=v")
3aca4bff
DE
1969 (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "v")]
1970 UNSPEC_VRFIN))]
10ed84db 1971 "TARGET_ALTIVEC"
98c9a8e8 1972 "vrfin %0,%1"
10ed84db
AH
1973 [(set_attr "type" "vecfloat")])
1974
29e6733c 1975(define_insn "*altivec_vrfim" ; floor
10ed84db 1976 [(set (match_operand:V4SF 0 "register_operand" "=v")
3aca4bff 1977 (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "v")]
29e6733c 1978 UNSPEC_FRIM))]
10ed84db 1979 "TARGET_ALTIVEC"
98c9a8e8 1980 "vrfim %0,%1"
10ed84db
AH
1981 [(set_attr "type" "vecfloat")])
1982
1983(define_insn "altivec_vcfux"
1984 [(set (match_operand:V4SF 0 "register_operand" "=v")
1985 (unspec:V4SF [(match_operand:V4SI 1 "register_operand" "v")
3aca4bff
DE
1986 (match_operand:QI 2 "immediate_operand" "i")]
1987 UNSPEC_VCFUX))]
10ed84db 1988 "TARGET_ALTIVEC"
98c9a8e8 1989 "vcfux %0,%1,%2"
10ed84db
AH
1990 [(set_attr "type" "vecfloat")])
1991
1992(define_insn "altivec_vcfsx"
1993 [(set (match_operand:V4SF 0 "register_operand" "=v")
1994 (unspec:V4SF [(match_operand:V4SI 1 "register_operand" "v")
3aca4bff
DE
1995 (match_operand:QI 2 "immediate_operand" "i")]
1996 UNSPEC_VCFSX))]
10ed84db 1997 "TARGET_ALTIVEC"
98c9a8e8 1998 "vcfsx %0,%1,%2"
10ed84db
AH
1999 [(set_attr "type" "vecfloat")])
2000
2001(define_insn "altivec_vctuxs"
2002 [(set (match_operand:V4SI 0 "register_operand" "=v")
2003 (unspec:V4SI [(match_operand:V4SF 1 "register_operand" "v")
3aca4bff
DE
2004 (match_operand:QI 2 "immediate_operand" "i")]
2005 UNSPEC_VCTUXS))
27ffac37 2006 (set (reg:SI 110) (unspec:SI [(const_int 0)] UNSPEC_SET_VSCR))]
10ed84db 2007 "TARGET_ALTIVEC"
98c9a8e8 2008 "vctuxs %0,%1,%2"
10ed84db
AH
2009 [(set_attr "type" "vecfloat")])
2010
2011(define_insn "altivec_vctsxs"
2012 [(set (match_operand:V4SI 0 "register_operand" "=v")
2013 (unspec:V4SI [(match_operand:V4SF 1 "register_operand" "v")
3aca4bff
DE
2014 (match_operand:QI 2 "immediate_operand" "i")]
2015 UNSPEC_VCTSXS))
27ffac37 2016 (set (reg:SI 110) (unspec:SI [(const_int 0)] UNSPEC_SET_VSCR))]
10ed84db 2017 "TARGET_ALTIVEC"
98c9a8e8 2018 "vctsxs %0,%1,%2"
10ed84db
AH
2019 [(set_attr "type" "vecfloat")])
2020
2021(define_insn "altivec_vlogefp"
2022 [(set (match_operand:V4SF 0 "register_operand" "=v")
3aca4bff
DE
2023 (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "v")]
2024 UNSPEC_VLOGEFP))]
10ed84db 2025 "TARGET_ALTIVEC"
98c9a8e8 2026 "vlogefp %0,%1"
10ed84db
AH
2027 [(set_attr "type" "vecfloat")])
2028
2029(define_insn "altivec_vexptefp"
2030 [(set (match_operand:V4SF 0 "register_operand" "=v")
3aca4bff
DE
2031 (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "v")]
2032 UNSPEC_VEXPTEFP))]
10ed84db 2033 "TARGET_ALTIVEC"
98c9a8e8 2034 "vexptefp %0,%1"
10ed84db
AH
2035 [(set_attr "type" "vecfloat")])
2036
92902797 2037(define_insn "*altivec_vrsqrtefp"
10ed84db 2038 [(set (match_operand:V4SF 0 "register_operand" "=v")
3aca4bff 2039 (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "v")]
92902797
MM
2040 UNSPEC_RSQRT))]
2041 "VECTOR_UNIT_ALTIVEC_P (V4SFmode)"
98c9a8e8 2042 "vrsqrtefp %0,%1"
10ed84db
AH
2043 [(set_attr "type" "vecfloat")])
2044
2045(define_insn "altivec_vrefp"
2046 [(set (match_operand:V4SF 0 "register_operand" "=v")
3aca4bff 2047 (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "v")]
92902797
MM
2048 UNSPEC_FRES))]
2049 "VECTOR_UNIT_ALTIVEC_P (V4SFmode)"
98c9a8e8 2050 "vrefp %0,%1"
10ed84db
AH
2051 [(set_attr "type" "vecfloat")])
2052
29e6733c
MM
2053(define_expand "altivec_copysign_v4sf3"
2054 [(use (match_operand:V4SF 0 "register_operand" ""))
2055 (use (match_operand:V4SF 1 "register_operand" ""))
2056 (use (match_operand:V4SF 2 "register_operand" ""))]
2057 "VECTOR_UNIT_ALTIVEC_P (V4SFmode)"
2058 "
2059{
2060 rtx mask = gen_reg_rtx (V4SImode);
2061 rtvec v = rtvec_alloc (4);
2062 unsigned HOST_WIDE_INT mask_val = ((unsigned HOST_WIDE_INT)1) << 31;
2063
2064 RTVEC_ELT (v, 0) = GEN_INT (mask_val);
2065 RTVEC_ELT (v, 1) = GEN_INT (mask_val);
2066 RTVEC_ELT (v, 2) = GEN_INT (mask_val);
2067 RTVEC_ELT (v, 3) = GEN_INT (mask_val);
2068
2069 emit_insn (gen_vec_initv4si (mask, gen_rtx_PARALLEL (V4SImode, v)));
2070 emit_insn (gen_vector_select_v4sf (operands[0], operands[1], operands[2],
2071 gen_lowpart (V4SFmode, mask)));
2072 DONE;
2073}")
2074
3aca4bff 2075(define_insn "altivec_vsldoi_<mode>"
a72c65c7
MM
2076 [(set (match_operand:VM 0 "register_operand" "=v")
2077 (unspec:VM [(match_operand:VM 1 "register_operand" "v")
2078 (match_operand:VM 2 "register_operand" "v")
2079 (match_operand:QI 3 "immediate_operand" "i")]
fbd86cc6 2080 UNSPEC_VSLDOI))]
10ed84db 2081 "TARGET_ALTIVEC"
98c9a8e8 2082 "vsldoi %0,%1,%2,%3"
10ed84db
AH
2083 [(set_attr "type" "vecperm")])
2084
a5965b52
MM
2085(define_insn "altivec_vupkhs<VU_char>"
2086 [(set (match_operand:VP 0 "register_operand" "=v")
2087 (unspec:VP [(match_operand:<VP_small> 1 "register_operand" "v")]
2088 UNSPEC_VUNPACK_HI_SIGN))]
2089 "<VI_unit>"
52a93551
BS
2090{
2091 if (VECTOR_ELT_ORDER_BIG)
2092 return "vupkhs<VU_char> %0,%1";
2093 else
2094 return "vupkls<VU_char> %0,%1";
2095}
2096 [(set_attr "type" "vecperm")])
2097
2098(define_insn "*altivec_vupkhs<VU_char>_direct"
2099 [(set (match_operand:VP 0 "register_operand" "=v")
2100 (unspec:VP [(match_operand:<VP_small> 1 "register_operand" "v")]
2101 UNSPEC_VUNPACK_HI_SIGN_DIRECT))]
2102 "<VI_unit>"
a5965b52
MM
2103 "vupkhs<VU_char> %0,%1"
2104 [(set_attr "type" "vecperm")])
2105
2106(define_insn "altivec_vupkls<VU_char>"
2107 [(set (match_operand:VP 0 "register_operand" "=v")
2108 (unspec:VP [(match_operand:<VP_small> 1 "register_operand" "v")]
2109 UNSPEC_VUNPACK_LO_SIGN))]
2110 "<VI_unit>"
52a93551
BS
2111{
2112 if (VECTOR_ELT_ORDER_BIG)
2113 return "vupkls<VU_char> %0,%1";
2114 else
2115 return "vupkhs<VU_char> %0,%1";
2116}
2117 [(set_attr "type" "vecperm")])
2118
2119(define_insn "*altivec_vupkls<VU_char>_direct"
2120 [(set (match_operand:VP 0 "register_operand" "=v")
2121 (unspec:VP [(match_operand:<VP_small> 1 "register_operand" "v")]
2122 UNSPEC_VUNPACK_LO_SIGN_DIRECT))]
2123 "<VI_unit>"
a5965b52 2124 "vupkls<VU_char> %0,%1"
10ed84db
AH
2125 [(set_attr "type" "vecperm")])
2126
2127(define_insn "altivec_vupkhpx"
2128 [(set (match_operand:V4SI 0 "register_operand" "=v")
5aebfdad 2129 (unspec:V4SI [(match_operand:V8HI 1 "register_operand" "v")]
3aca4bff 2130 UNSPEC_VUPKHPX))]
10ed84db 2131 "TARGET_ALTIVEC"
52a93551
BS
2132{
2133 if (VECTOR_ELT_ORDER_BIG)
2134 return "vupkhpx %0,%1";
2135 else
2136 return "vupklpx %0,%1";
2137}
10ed84db
AH
2138 [(set_attr "type" "vecperm")])
2139
10ed84db
AH
2140(define_insn "altivec_vupklpx"
2141 [(set (match_operand:V4SI 0 "register_operand" "=v")
5aebfdad 2142 (unspec:V4SI [(match_operand:V8HI 1 "register_operand" "v")]
3aca4bff 2143 UNSPEC_VUPKLPX))]
10ed84db 2144 "TARGET_ALTIVEC"
52a93551
BS
2145{
2146 if (VECTOR_ELT_ORDER_BIG)
2147 return "vupklpx %0,%1";
2148 else
2149 return "vupkhpx %0,%1";
2150}
10ed84db
AH
2151 [(set_attr "type" "vecperm")])
2152
a72c65c7
MM
2153;; Compare vectors producing a vector result and a predicate, setting CR6 to
2154;; indicate a combined status
2155(define_insn "*altivec_vcmpequ<VI_char>_p"
2156 [(set (reg:CC 74)
a5965b52
MM
2157 (unspec:CC [(eq:CC (match_operand:VI2 1 "register_operand" "v")
2158 (match_operand:VI2 2 "register_operand" "v"))]
a72c65c7 2159 UNSPEC_PREDICATE))
a5965b52
MM
2160 (set (match_operand:VI2 0 "register_operand" "=v")
2161 (eq:VI2 (match_dup 1)
2162 (match_dup 2)))]
2163 "<VI_unit>"
a72c65c7
MM
2164 "vcmpequ<VI_char>. %0,%1,%2"
2165 [(set_attr "type" "veccmp")])
10ed84db 2166
a72c65c7
MM
2167(define_insn "*altivec_vcmpgts<VI_char>_p"
2168 [(set (reg:CC 74)
a5965b52
MM
2169 (unspec:CC [(gt:CC (match_operand:VI2 1 "register_operand" "v")
2170 (match_operand:VI2 2 "register_operand" "v"))]
a72c65c7 2171 UNSPEC_PREDICATE))
a5965b52
MM
2172 (set (match_operand:VI2 0 "register_operand" "=v")
2173 (gt:VI2 (match_dup 1)
2174 (match_dup 2)))]
2175 "<VI_unit>"
a72c65c7
MM
2176 "vcmpgts<VI_char>. %0,%1,%2"
2177 [(set_attr "type" "veccmp")])
10ed84db 2178
a72c65c7
MM
2179(define_insn "*altivec_vcmpgtu<VI_char>_p"
2180 [(set (reg:CC 74)
a5965b52
MM
2181 (unspec:CC [(gtu:CC (match_operand:VI2 1 "register_operand" "v")
2182 (match_operand:VI2 2 "register_operand" "v"))]
a72c65c7 2183 UNSPEC_PREDICATE))
a5965b52
MM
2184 (set (match_operand:VI2 0 "register_operand" "=v")
2185 (gtu:VI2 (match_dup 1)
2186 (match_dup 2)))]
2187 "<VI_unit>"
a72c65c7
MM
2188 "vcmpgtu<VI_char>. %0,%1,%2"
2189 [(set_attr "type" "veccmp")])
10ed84db 2190
a72c65c7
MM
2191(define_insn "*altivec_vcmpeqfp_p"
2192 [(set (reg:CC 74)
2193 (unspec:CC [(eq:CC (match_operand:V4SF 1 "register_operand" "v")
2194 (match_operand:V4SF 2 "register_operand" "v"))]
2195 UNSPEC_PREDICATE))
2196 (set (match_operand:V4SF 0 "register_operand" "=v")
2197 (eq:V4SF (match_dup 1)
2198 (match_dup 2)))]
2199 "VECTOR_UNIT_ALTIVEC_P (V4SFmode)"
2200 "vcmpeqfp. %0,%1,%2"
2201 [(set_attr "type" "veccmp")])
10ed84db 2202
a72c65c7
MM
2203(define_insn "*altivec_vcmpgtfp_p"
2204 [(set (reg:CC 74)
2205 (unspec:CC [(gt:CC (match_operand:V4SF 1 "register_operand" "v")
2206 (match_operand:V4SF 2 "register_operand" "v"))]
2207 UNSPEC_PREDICATE))
2208 (set (match_operand:V4SF 0 "register_operand" "=v")
2209 (gt:V4SF (match_dup 1)
2210 (match_dup 2)))]
2211 "VECTOR_UNIT_ALTIVEC_P (V4SFmode)"
2212 "vcmpgtfp. %0,%1,%2"
2213 [(set_attr "type" "veccmp")])
10ed84db 2214
a72c65c7
MM
2215(define_insn "*altivec_vcmpgefp_p"
2216 [(set (reg:CC 74)
2217 (unspec:CC [(ge:CC (match_operand:V4SF 1 "register_operand" "v")
2218 (match_operand:V4SF 2 "register_operand" "v"))]
2219 UNSPEC_PREDICATE))
2220 (set (match_operand:V4SF 0 "register_operand" "=v")
2221 (ge:V4SF (match_dup 1)
2222 (match_dup 2)))]
2223 "VECTOR_UNIT_ALTIVEC_P (V4SFmode)"
2224 "vcmpgefp. %0,%1,%2"
2225 [(set_attr "type" "veccmp")])
10ed84db 2226
a72c65c7 2227(define_insn "altivec_vcmpbfp_p"
10ed84db 2228 [(set (reg:CC 74)
a72c65c7
MM
2229 (unspec:CC [(match_operand:V4SF 1 "register_operand" "v")
2230 (match_operand:V4SF 2 "register_operand" "v")]
2231 UNSPEC_VCMPBFP))
2232 (set (match_operand:V4SF 0 "register_operand" "=v")
2233 (unspec:V4SF [(match_dup 1)
2234 (match_dup 2)]
2235 UNSPEC_VCMPBFP))]
2236 "VECTOR_UNIT_ALTIVEC_OR_VSX_P (V4SFmode)"
2237 "vcmpbfp. %0,%1,%2"
2238 [(set_attr "type" "veccmp")])
10ed84db
AH
2239
2240(define_insn "altivec_mtvscr"
2241 [(set (reg:SI 110)
2242 (unspec_volatile:SI
3aca4bff 2243 [(match_operand:V4SI 0 "register_operand" "v")] UNSPECV_MTVSCR))]
10ed84db
AH
2244 "TARGET_ALTIVEC"
2245 "mtvscr %0"
2246 [(set_attr "type" "vecsimple")])
2247
2248(define_insn "altivec_mfvscr"
2249 [(set (match_operand:V8HI 0 "register_operand" "=v")
3aca4bff 2250 (unspec_volatile:V8HI [(reg:SI 110)] UNSPECV_MFVSCR))]
10ed84db
AH
2251 "TARGET_ALTIVEC"
2252 "mfvscr %0"
2253 [(set_attr "type" "vecsimple")])
2254
2255(define_insn "altivec_dssall"
3aca4bff 2256 [(unspec_volatile [(const_int 0)] UNSPECV_DSSALL)]
10ed84db
AH
2257 "TARGET_ALTIVEC"
2258 "dssall"
2259 [(set_attr "type" "vecsimple")])
2260
2261(define_insn "altivec_dss"
3aca4bff
DE
2262 [(unspec_volatile [(match_operand:QI 0 "immediate_operand" "i")]
2263 UNSPECV_DSS)]
10ed84db
AH
2264 "TARGET_ALTIVEC"
2265 "dss %0"
2266 [(set_attr "type" "vecsimple")])
2267
2268(define_insn "altivec_dst"
666158b9 2269 [(unspec [(match_operand 0 "register_operand" "b")
10ed84db 2270 (match_operand:SI 1 "register_operand" "r")
3aca4bff 2271 (match_operand:QI 2 "immediate_operand" "i")] UNSPEC_DST)]
666158b9
GK
2272 "TARGET_ALTIVEC && GET_MODE (operands[0]) == Pmode"
2273 "dst %0,%1,%2"
10ed84db
AH
2274 [(set_attr "type" "vecsimple")])
2275
2276(define_insn "altivec_dstt"
666158b9 2277 [(unspec [(match_operand 0 "register_operand" "b")
10ed84db 2278 (match_operand:SI 1 "register_operand" "r")
3aca4bff 2279 (match_operand:QI 2 "immediate_operand" "i")] UNSPEC_DSTT)]
666158b9
GK
2280 "TARGET_ALTIVEC && GET_MODE (operands[0]) == Pmode"
2281 "dstt %0,%1,%2"
10ed84db
AH
2282 [(set_attr "type" "vecsimple")])
2283
2284(define_insn "altivec_dstst"
666158b9 2285 [(unspec [(match_operand 0 "register_operand" "b")
10ed84db 2286 (match_operand:SI 1 "register_operand" "r")
3aca4bff 2287 (match_operand:QI 2 "immediate_operand" "i")] UNSPEC_DSTST)]
666158b9
GK
2288 "TARGET_ALTIVEC && GET_MODE (operands[0]) == Pmode"
2289 "dstst %0,%1,%2"
10ed84db
AH
2290 [(set_attr "type" "vecsimple")])
2291
2292(define_insn "altivec_dststt"
666158b9 2293 [(unspec [(match_operand 0 "register_operand" "b")
10ed84db 2294 (match_operand:SI 1 "register_operand" "r")
3aca4bff 2295 (match_operand:QI 2 "immediate_operand" "i")] UNSPEC_DSTSTT)]
666158b9
GK
2296 "TARGET_ALTIVEC && GET_MODE (operands[0]) == Pmode"
2297 "dststt %0,%1,%2"
10ed84db
AH
2298 [(set_attr "type" "vecsimple")])
2299
0b4718c9
BS
2300(define_expand "altivec_lvsl"
2301 [(use (match_operand:V16QI 0 "register_operand" ""))
2302 (use (match_operand:V16QI 1 "memory_operand" ""))]
2303 "TARGET_ALTIVEC"
2304{
2305 if (VECTOR_ELT_ORDER_BIG)
2306 emit_insn (gen_altivec_lvsl_direct (operands[0], operands[1]));
2307 else
2308 {
2309 int i;
2310 rtx mask, perm[16], constv, vperm;
2311 mask = gen_reg_rtx (V16QImode);
2312 emit_insn (gen_altivec_lvsl_direct (mask, operands[1]));
2313 for (i = 0; i < 16; ++i)
2314 perm[i] = GEN_INT (i);
2315 constv = gen_rtx_CONST_VECTOR (V16QImode, gen_rtvec_v (16, perm));
2316 constv = force_reg (V16QImode, constv);
2317 vperm = gen_rtx_UNSPEC (V16QImode, gen_rtvec (3, mask, mask, constv),
2318 UNSPEC_VPERM);
2319 emit_insn (gen_rtx_SET (VOIDmode, operands[0], vperm));
2320 }
2321 DONE;
2322})
2323
2324(define_insn "altivec_lvsl_direct"
10ed84db 2325 [(set (match_operand:V16QI 0 "register_operand" "=v")
1ba24090
SB
2326 (unspec:V16QI [(match_operand:V16QI 1 "memory_operand" "Z")]
2327 UNSPEC_LVSL))]
10ed84db 2328 "TARGET_ALTIVEC"
b4a62fa0 2329 "lvsl %0,%y1"
10ed84db
AH
2330 [(set_attr "type" "vecload")])
2331
0b4718c9
BS
2332(define_expand "altivec_lvsr"
2333 [(use (match_operand:V16QI 0 "register_operand" ""))
2334 (use (match_operand:V16QI 1 "memory_operand" ""))]
2335 "TARGET_ALTIVEC"
2336{
2337 if (VECTOR_ELT_ORDER_BIG)
2338 emit_insn (gen_altivec_lvsr_direct (operands[0], operands[1]));
2339 else
2340 {
2341 int i;
2342 rtx mask, perm[16], constv, vperm;
2343 mask = gen_reg_rtx (V16QImode);
2344 emit_insn (gen_altivec_lvsr_direct (mask, operands[1]));
2345 for (i = 0; i < 16; ++i)
2346 perm[i] = GEN_INT (i);
2347 constv = gen_rtx_CONST_VECTOR (V16QImode, gen_rtvec_v (16, perm));
2348 constv = force_reg (V16QImode, constv);
2349 vperm = gen_rtx_UNSPEC (V16QImode, gen_rtvec (3, mask, mask, constv),
2350 UNSPEC_VPERM);
2351 emit_insn (gen_rtx_SET (VOIDmode, operands[0], vperm));
2352 }
2353 DONE;
2354})
2355
2356(define_insn "altivec_lvsr_direct"
10ed84db 2357 [(set (match_operand:V16QI 0 "register_operand" "=v")
1ba24090
SB
2358 (unspec:V16QI [(match_operand:V16QI 1 "memory_operand" "Z")]
2359 UNSPEC_LVSR))]
10ed84db 2360 "TARGET_ALTIVEC"
b4a62fa0 2361 "lvsr %0,%y1"
10ed84db
AH
2362 [(set_attr "type" "vecload")])
2363
7ccf35ed 2364(define_expand "build_vector_mask_for_load"
dec1f3aa
DE
2365 [(set (match_operand:V16QI 0 "register_operand" "")
2366 (unspec:V16QI [(match_operand 1 "memory_operand" "")] UNSPEC_LVSR))]
7ccf35ed
DN
2367 "TARGET_ALTIVEC"
2368 "
2369{
2370 rtx addr;
2371 rtx temp;
2372
992d08b1 2373 gcc_assert (GET_CODE (operands[1]) == MEM);
7ccf35ed
DN
2374
2375 addr = XEXP (operands[1], 0);
2376 temp = gen_reg_rtx (GET_MODE (addr));
2377 emit_insn (gen_rtx_SET (VOIDmode, temp,
2378 gen_rtx_NEG (GET_MODE (addr), addr)));
2379 emit_insn (gen_altivec_lvsr (operands[0],
8308679f 2380 replace_equiv_address (operands[1], temp)));
7ccf35ed
DN
2381 DONE;
2382}")
2383
10ed84db
AH
2384;; Parallel some of the LVE* and STV*'s with unspecs because some have
2385;; identical rtl but different instructions-- and gcc gets confused.
2386
a6eecdc1
BS
2387(define_expand "altivec_lve<VI_char>x"
2388 [(parallel
2389 [(set (match_operand:VI 0 "register_operand" "=v")
2390 (match_operand:VI 1 "memory_operand" "Z"))
2391 (unspec [(const_int 0)] UNSPEC_LVE)])]
2392 "TARGET_ALTIVEC"
2393{
2394 if (!BYTES_BIG_ENDIAN && VECTOR_ELT_ORDER_BIG)
2395 {
2396 altivec_expand_lvx_be (operands[0], operands[1], <MODE>mode, UNSPEC_LVE);
2397 DONE;
2398 }
2399})
2400
2401(define_insn "*altivec_lve<VI_char>x_internal"
10ed84db 2402 [(parallel
aba5fb01 2403 [(set (match_operand:VI 0 "register_operand" "=v")
7a4eca66 2404 (match_operand:VI 1 "memory_operand" "Z"))
3aca4bff 2405 (unspec [(const_int 0)] UNSPEC_LVE)])]
10ed84db 2406 "TARGET_ALTIVEC"
aba5fb01 2407 "lve<VI_char>x %0,%y1"
10ed84db
AH
2408 [(set_attr "type" "vecload")])
2409
3aca4bff
DE
2410(define_insn "*altivec_lvesfx"
2411 [(parallel
2412 [(set (match_operand:V4SF 0 "register_operand" "=v")
7a4eca66 2413 (match_operand:V4SF 1 "memory_operand" "Z"))
3aca4bff
DE
2414 (unspec [(const_int 0)] UNSPEC_LVE)])]
2415 "TARGET_ALTIVEC"
2416 "lvewx %0,%y1"
2417 [(set_attr "type" "vecload")])
2418
4b3a6bcb 2419(define_expand "altivec_lvxl_<mode>"
10ed84db 2420 [(parallel
4b3a6bcb
WS
2421 [(set (match_operand:VM2 0 "register_operand" "=v")
2422 (match_operand:VM2 1 "memory_operand" "Z"))
2423 (unspec [(const_int 0)] UNSPEC_SET_VSCR)])]
2424 "TARGET_ALTIVEC"
2425{
2426 if (!BYTES_BIG_ENDIAN && VECTOR_ELT_ORDER_BIG)
2427 {
2428 altivec_expand_lvx_be (operands[0], operands[1], <MODE>mode, UNSPEC_SET_VSCR);
2429 DONE;
2430 }
2431})
2432
2433(define_insn "*altivec_lvxl_<mode>_internal"
2434 [(parallel
2435 [(set (match_operand:VM2 0 "register_operand" "=v")
2436 (match_operand:VM2 1 "memory_operand" "Z"))
27ffac37 2437 (unspec [(const_int 0)] UNSPEC_SET_VSCR)])]
10ed84db 2438 "TARGET_ALTIVEC"
4b3a6bcb 2439 "lvx %0,%y1"
10ed84db
AH
2440 [(set_attr "type" "vecload")])
2441
4b3a6bcb
WS
2442(define_expand "altivec_lvx_<mode>"
2443 [(parallel
2444 [(set (match_operand:VM2 0 "register_operand" "=v")
2445 (match_operand:VM2 1 "memory_operand" "Z"))
2446 (unspec [(const_int 0)] UNSPEC_LVX)])]
2447 "TARGET_ALTIVEC"
2448{
2449 if (!BYTES_BIG_ENDIAN && VECTOR_ELT_ORDER_BIG)
2450 {
2451 altivec_expand_lvx_be (operands[0], operands[1], <MODE>mode, UNSPEC_LVX);
2452 DONE;
2453 }
2454})
2455
2456(define_insn "*altivec_lvx_<mode>_internal"
c9485473
MM
2457 [(parallel
2458 [(set (match_operand:VM2 0 "register_operand" "=v")
2459 (match_operand:VM2 1 "memory_operand" "Z"))
2460 (unspec [(const_int 0)] UNSPEC_LVX)])]
10ed84db 2461 "TARGET_ALTIVEC"
b4a62fa0 2462 "lvx %0,%y1"
10ed84db
AH
2463 [(set_attr "type" "vecload")])
2464
4b3a6bcb
WS
2465(define_expand "altivec_stvx_<mode>"
2466 [(parallel
2467 [(set (match_operand:VM2 0 "memory_operand" "=Z")
2468 (match_operand:VM2 1 "register_operand" "v"))
2469 (unspec [(const_int 0)] UNSPEC_STVX)])]
2470 "TARGET_ALTIVEC"
2471{
2472 if (!BYTES_BIG_ENDIAN && VECTOR_ELT_ORDER_BIG)
2473 {
2474 altivec_expand_stvx_be (operands[0], operands[1], <MODE>mode, UNSPEC_STVX);
2475 DONE;
2476 }
2477})
2478
2479(define_insn "*altivec_stvx_<mode>_internal"
10ed84db 2480 [(parallel
c9485473
MM
2481 [(set (match_operand:VM2 0 "memory_operand" "=Z")
2482 (match_operand:VM2 1 "register_operand" "v"))
3aca4bff 2483 (unspec [(const_int 0)] UNSPEC_STVX)])]
10ed84db 2484 "TARGET_ALTIVEC"
b4a62fa0 2485 "stvx %1,%y0"
10ed84db
AH
2486 [(set_attr "type" "vecstore")])
2487
4b3a6bcb
WS
2488(define_expand "altivec_stvxl_<mode>"
2489 [(parallel
2490 [(set (match_operand:VM2 0 "memory_operand" "=Z")
2491 (match_operand:VM2 1 "register_operand" "v"))
2492 (unspec [(const_int 0)] UNSPEC_STVXL)])]
2493 "TARGET_ALTIVEC"
2494{
2495 if (!BYTES_BIG_ENDIAN && VECTOR_ELT_ORDER_BIG)
2496 {
2497 altivec_expand_stvx_be (operands[0], operands[1], <MODE>mode, UNSPEC_STVXL);
2498 DONE;
2499 }
2500})
2501
2502(define_insn "*altivec_stvxl_<mode>_internal"
10ed84db 2503 [(parallel
4b3a6bcb
WS
2504 [(set (match_operand:VM2 0 "memory_operand" "=Z")
2505 (match_operand:VM2 1 "register_operand" "v"))
3aca4bff 2506 (unspec [(const_int 0)] UNSPEC_STVXL)])]
10ed84db 2507 "TARGET_ALTIVEC"
b4a62fa0 2508 "stvxl %1,%y0"
10ed84db
AH
2509 [(set_attr "type" "vecstore")])
2510
a6eecdc1
BS
2511(define_expand "altivec_stve<VI_char>x"
2512 [(set (match_operand:<VI_scalar> 0 "memory_operand" "=Z")
2513 (unspec:<VI_scalar> [(match_operand:VI 1 "register_operand" "v")] UNSPEC_STVE))]
2514 "TARGET_ALTIVEC"
2515{
2516 if (!BYTES_BIG_ENDIAN && VECTOR_ELT_ORDER_BIG)
2517 {
2518 altivec_expand_stvex_be (operands[0], operands[1], <MODE>mode, UNSPEC_STVE);
2519 DONE;
2520 }
2521})
2522
2523(define_insn "*altivec_stve<VI_char>x_internal"
99eeedc4
JJ
2524 [(set (match_operand:<VI_scalar> 0 "memory_operand" "=Z")
2525 (unspec:<VI_scalar> [(match_operand:VI 1 "register_operand" "v")] UNSPEC_STVE))]
10ed84db 2526 "TARGET_ALTIVEC"
aba5fb01 2527 "stve<VI_char>x %1,%y0"
10ed84db
AH
2528 [(set_attr "type" "vecstore")])
2529
3aca4bff 2530(define_insn "*altivec_stvesfx"
99eeedc4
JJ
2531 [(set (match_operand:SF 0 "memory_operand" "=Z")
2532 (unspec:SF [(match_operand:V4SF 1 "register_operand" "v")] UNSPEC_STVE))]
3aca4bff
DE
2533 "TARGET_ALTIVEC"
2534 "stvewx %1,%y0"
2535 [(set_attr "type" "vecstore")])
2536
27ffac37 2537;; Generate
a5965b52 2538;; xxlxor/vxor SCRATCH0,SCRATCH0,SCRATCH0
27ffac37
PB
2539;; vsubu?m SCRATCH2,SCRATCH1,%1
2540;; vmaxs? %0,%1,SCRATCH2"
2541(define_expand "abs<mode>2"
a5965b52
MM
2542 [(set (match_dup 2) (match_dup 3))
2543 (set (match_dup 4)
2544 (minus:VI2 (match_dup 2)
2545 (match_operand:VI2 1 "register_operand" "v")))
2546 (set (match_operand:VI2 0 "register_operand" "=v")
2547 (smax:VI2 (match_dup 1) (match_dup 4)))]
2548 "<VI_unit>"
27ffac37 2549{
a5965b52
MM
2550 int i, n_elt = GET_MODE_NUNITS (<MODE>mode);
2551 rtvec v = rtvec_alloc (n_elt);
2552
2553 /* Create an all 0 constant. */
2554 for (i = 0; i < n_elt; ++i)
2555 RTVEC_ELT (v, i) = const0_rtx;
2556
2557 operands[2] = gen_reg_rtx (<MODE>mode);
2558 operands[3] = gen_rtx_CONST_VECTOR (<MODE>mode, v);
2559 operands[4] = gen_reg_rtx (<MODE>mode);
27ffac37 2560})
10ed84db 2561
27ffac37
PB
2562;; Generate
2563;; vspltisw SCRATCH1,-1
2564;; vslw SCRATCH2,SCRATCH1,SCRATCH1
2565;; vandc %0,%1,SCRATCH2
a72c65c7 2566(define_expand "altivec_absv4sf2"
27ffac37 2567 [(set (match_dup 2)
8cf0db2b 2568 (vec_duplicate:V4SI (const_int -1)))
27ffac37 2569 (set (match_dup 3)
e83a75a7 2570 (ashift:V4SI (match_dup 2) (match_dup 2)))
27ffac37 2571 (set (match_operand:V4SF 0 "register_operand" "=v")
8cf0db2b 2572 (and:V4SF (not:V4SF (subreg:V4SF (match_dup 3) 0))
27ffac37 2573 (match_operand:V4SF 1 "register_operand" "v")))]
10ed84db 2574 "TARGET_ALTIVEC"
27ffac37 2575{
8cf0db2b
UW
2576 operands[2] = gen_reg_rtx (V4SImode);
2577 operands[3] = gen_reg_rtx (V4SImode);
27ffac37 2578})
10ed84db 2579
27ffac37
PB
2580;; Generate
2581;; vspltis? SCRATCH0,0
2582;; vsubs?s SCRATCH2,SCRATCH1,%1
2583;; vmaxs? %0,%1,SCRATCH2"
2584(define_expand "altivec_abss_<mode>"
2585 [(set (match_dup 2) (vec_duplicate:VI (const_int 0)))
2586 (parallel [(set (match_dup 3)
2587 (unspec:VI [(match_dup 2)
2588 (match_operand:VI 1 "register_operand" "v")]
3aca4bff 2589 UNSPEC_VSUBS))
27ffac37
PB
2590 (set (reg:SI 110) (unspec:SI [(const_int 0)] UNSPEC_SET_VSCR))])
2591 (set (match_operand:VI 0 "register_operand" "=v")
2592 (smax:VI (match_dup 1) (match_dup 3)))]
10ed84db 2593 "TARGET_ALTIVEC"
27ffac37
PB
2594{
2595 operands[2] = gen_reg_rtx (GET_MODE (operands[0]));
2596 operands[3] = gen_reg_rtx (GET_MODE (operands[0]));
2597})
7ccf35ed 2598
a6b46ba2
DN
2599(define_expand "reduc_splus_<mode>"
2600 [(set (match_operand:VIshort 0 "register_operand" "=v")
3aca4bff
DE
2601 (unspec:VIshort [(match_operand:VIshort 1 "register_operand" "v")]
2602 UNSPEC_REDUC_PLUS))]
61d3cdbb 2603 "TARGET_ALTIVEC"
1ba24090 2604{
a6b46ba2 2605 rtx vzero = gen_reg_rtx (V4SImode);
61d3cdbb 2606 rtx vtmp1 = gen_reg_rtx (V4SImode);
1ba24090 2607 rtx dest = gen_lowpart (V4SImode, operands[0]);
61d3cdbb 2608
a6b46ba2
DN
2609 emit_insn (gen_altivec_vspltisw (vzero, const0_rtx));
2610 emit_insn (gen_altivec_vsum4s<VI_char>s (vtmp1, operands[1], vzero));
b80afde9 2611 emit_insn (gen_altivec_vsumsws_direct (dest, vtmp1, vzero));
61d3cdbb 2612 DONE;
1ba24090 2613})
61d3cdbb 2614
a6b46ba2
DN
2615(define_expand "reduc_uplus_v16qi"
2616 [(set (match_operand:V16QI 0 "register_operand" "=v")
3aca4bff
DE
2617 (unspec:V16QI [(match_operand:V16QI 1 "register_operand" "v")]
2618 UNSPEC_REDUC_PLUS))]
61d3cdbb 2619 "TARGET_ALTIVEC"
61d3cdbb 2620{
a6b46ba2 2621 rtx vzero = gen_reg_rtx (V4SImode);
61d3cdbb 2622 rtx vtmp1 = gen_reg_rtx (V4SImode);
1ba24090 2623 rtx dest = gen_lowpart (V4SImode, operands[0]);
61d3cdbb 2624
a6b46ba2
DN
2625 emit_insn (gen_altivec_vspltisw (vzero, const0_rtx));
2626 emit_insn (gen_altivec_vsum4ubs (vtmp1, operands[1], vzero));
b90ab1ba 2627 emit_insn (gen_altivec_vsumsws_direct (dest, vtmp1, vzero));
61d3cdbb 2628 DONE;
1ba24090 2629})
61d3cdbb 2630
70a39602
IR
2631(define_expand "neg<mode>2"
2632 [(use (match_operand:VI 0 "register_operand" ""))
2633 (use (match_operand:VI 1 "register_operand" ""))]
2634 "TARGET_ALTIVEC"
2635 "
2636{
2637 rtx vzero;
2638
2639 vzero = gen_reg_rtx (GET_MODE (operands[0]));
2640 emit_insn (gen_altivec_vspltis<VI_char> (vzero, const0_rtx));
2641 emit_insn (gen_sub<mode>3 (operands[0], vzero, operands[1]));
2642
2643 DONE;
2644}")
2645
20f06221
DN
2646(define_expand "udot_prod<mode>"
2647 [(set (match_operand:V4SI 0 "register_operand" "=v")
2648 (plus:V4SI (match_operand:V4SI 3 "register_operand" "v")
2649 (unspec:V4SI [(match_operand:VIshort 1 "register_operand" "v")
2650 (match_operand:VIshort 2 "register_operand" "v")]
2651 UNSPEC_VMSUMU)))]
2652 "TARGET_ALTIVEC"
2653 "
2654{
2655 emit_insn (gen_altivec_vmsumu<VI_char>m (operands[0], operands[1], operands[2], operands[3]));
2656 DONE;
2657}")
2658
2659(define_expand "sdot_prodv8hi"
2660 [(set (match_operand:V4SI 0 "register_operand" "=v")
2661 (plus:V4SI (match_operand:V4SI 3 "register_operand" "v")
2662 (unspec:V4SI [(match_operand:V8HI 1 "register_operand" "v")
2663 (match_operand:V8HI 2 "register_operand" "v")]
2664 UNSPEC_VMSUMSHM)))]
2665 "TARGET_ALTIVEC"
2666 "
2667{
2668 emit_insn (gen_altivec_vmsumshm (operands[0], operands[1], operands[2], operands[3]));
2669 DONE;
2670}")
2671
2672(define_expand "widen_usum<mode>3"
2673 [(set (match_operand:V4SI 0 "register_operand" "=v")
2674 (plus:V4SI (match_operand:V4SI 2 "register_operand" "v")
2675 (unspec:V4SI [(match_operand:VIshort 1 "register_operand" "v")]
2676 UNSPEC_VMSUMU)))]
2677 "TARGET_ALTIVEC"
2678 "
2679{
2680 rtx vones = gen_reg_rtx (GET_MODE (operands[1]));
2681
2682 emit_insn (gen_altivec_vspltis<VI_char> (vones, const1_rtx));
2683 emit_insn (gen_altivec_vmsumu<VI_char>m (operands[0], operands[1], vones, operands[2]));
2684 DONE;
2685}")
2686
2687(define_expand "widen_ssumv16qi3"
2688 [(set (match_operand:V4SI 0 "register_operand" "=v")
2689 (plus:V4SI (match_operand:V4SI 2 "register_operand" "v")
2690 (unspec:V4SI [(match_operand:V16QI 1 "register_operand" "v")]
2691 UNSPEC_VMSUMM)))]
2692 "TARGET_ALTIVEC"
2693 "
2694{
2695 rtx vones = gen_reg_rtx (V16QImode);
2696
2697 emit_insn (gen_altivec_vspltisb (vones, const1_rtx));
2698 emit_insn (gen_altivec_vmsummbm (operands[0], operands[1], vones, operands[2]));
2699 DONE;
2700}")
2701
2702(define_expand "widen_ssumv8hi3"
2703 [(set (match_operand:V4SI 0 "register_operand" "=v")
2704 (plus:V4SI (match_operand:V4SI 2 "register_operand" "v")
2705 (unspec:V4SI [(match_operand:V8HI 1 "register_operand" "v")]
2706 UNSPEC_VMSUMSHM)))]
2707 "TARGET_ALTIVEC"
2708 "
2709{
2710 rtx vones = gen_reg_rtx (V8HImode);
2711
2712 emit_insn (gen_altivec_vspltish (vones, const1_rtx));
2713 emit_insn (gen_altivec_vmsumshm (operands[0], operands[1], vones, operands[2]));
2714 DONE;
2715}")
2716
a5965b52
MM
2717(define_expand "vec_unpacks_hi_<VP_small_lc>"
2718 [(set (match_operand:VP 0 "register_operand" "=v")
2719 (unspec:VP [(match_operand:<VP_small> 1 "register_operand" "v")]
d85f364c 2720 UNSPEC_VUNPACK_HI_SIGN_DIRECT))]
a5965b52
MM
2721 "<VI_unit>"
2722 "")
89d67cca 2723
a5965b52
MM
2724(define_expand "vec_unpacks_lo_<VP_small_lc>"
2725 [(set (match_operand:VP 0 "register_operand" "=v")
2726 (unspec:VP [(match_operand:<VP_small> 1 "register_operand" "v")]
d85f364c 2727 UNSPEC_VUNPACK_LO_SIGN_DIRECT))]
a5965b52
MM
2728 "<VI_unit>"
2729 "")
89d67cca
DN
2730
2731(define_insn "vperm_v8hiv4si"
2732 [(set (match_operand:V4SI 0 "register_operand" "=v")
2733 (unspec:V4SI [(match_operand:V8HI 1 "register_operand" "v")
2734 (match_operand:V4SI 2 "register_operand" "v")
2735 (match_operand:V16QI 3 "register_operand" "v")]
2736 UNSPEC_VPERMSI))]
2737 "TARGET_ALTIVEC"
2738 "vperm %0,%1,%2,%3"
2739 [(set_attr "type" "vecperm")])
2740
2741(define_insn "vperm_v16qiv8hi"
2742 [(set (match_operand:V8HI 0 "register_operand" "=v")
2743 (unspec:V8HI [(match_operand:V16QI 1 "register_operand" "v")
2744 (match_operand:V8HI 2 "register_operand" "v")
2745 (match_operand:V16QI 3 "register_operand" "v")]
2746 UNSPEC_VPERMHI))]
2747 "TARGET_ALTIVEC"
2748 "vperm %0,%1,%2,%3"
2749 [(set_attr "type" "vecperm")])
2750
2751
2752(define_expand "vec_unpacku_hi_v16qi"
2753 [(set (match_operand:V8HI 0 "register_operand" "=v")
2754 (unspec:V8HI [(match_operand:V16QI 1 "register_operand" "v")]
2755 UNSPEC_VUPKHUB))]
2756 "TARGET_ALTIVEC"
2757 "
2758{
2759 rtx vzero = gen_reg_rtx (V8HImode);
2760 rtx mask = gen_reg_rtx (V16QImode);
2761 rtvec v = rtvec_alloc (16);
dd346f1f 2762 bool be = BYTES_BIG_ENDIAN;
89d67cca
DN
2763
2764 emit_insn (gen_altivec_vspltish (vzero, const0_rtx));
2765
dd346f1f
BS
2766 RTVEC_ELT (v, 0) = gen_rtx_CONST_INT (QImode, be ? 16 : 7);
2767 RTVEC_ELT (v, 1) = gen_rtx_CONST_INT (QImode, be ? 0 : 16);
2768 RTVEC_ELT (v, 2) = gen_rtx_CONST_INT (QImode, be ? 16 : 6);
2769 RTVEC_ELT (v, 3) = gen_rtx_CONST_INT (QImode, be ? 1 : 16);
2770 RTVEC_ELT (v, 4) = gen_rtx_CONST_INT (QImode, be ? 16 : 5);
2771 RTVEC_ELT (v, 5) = gen_rtx_CONST_INT (QImode, be ? 2 : 16);
2772 RTVEC_ELT (v, 6) = gen_rtx_CONST_INT (QImode, be ? 16 : 4);
2773 RTVEC_ELT (v, 7) = gen_rtx_CONST_INT (QImode, be ? 3 : 16);
2774 RTVEC_ELT (v, 8) = gen_rtx_CONST_INT (QImode, be ? 16 : 3);
2775 RTVEC_ELT (v, 9) = gen_rtx_CONST_INT (QImode, be ? 4 : 16);
2776 RTVEC_ELT (v, 10) = gen_rtx_CONST_INT (QImode, be ? 16 : 2);
2777 RTVEC_ELT (v, 11) = gen_rtx_CONST_INT (QImode, be ? 5 : 16);
2778 RTVEC_ELT (v, 12) = gen_rtx_CONST_INT (QImode, be ? 16 : 1);
2779 RTVEC_ELT (v, 13) = gen_rtx_CONST_INT (QImode, be ? 6 : 16);
2780 RTVEC_ELT (v, 14) = gen_rtx_CONST_INT (QImode, be ? 16 : 0);
2781 RTVEC_ELT (v, 15) = gen_rtx_CONST_INT (QImode, be ? 7 : 16);
89d67cca
DN
2782
2783 emit_insn (gen_vec_initv16qi (mask, gen_rtx_PARALLEL (V16QImode, v)));
2784 emit_insn (gen_vperm_v16qiv8hi (operands[0], operands[1], vzero, mask));
2785 DONE;
2786}")
2787
2788(define_expand "vec_unpacku_hi_v8hi"
2789 [(set (match_operand:V4SI 0 "register_operand" "=v")
2790 (unspec:V4SI [(match_operand:V8HI 1 "register_operand" "v")]
2791 UNSPEC_VUPKHUH))]
2792 "TARGET_ALTIVEC"
2793 "
2794{
2795 rtx vzero = gen_reg_rtx (V4SImode);
2796 rtx mask = gen_reg_rtx (V16QImode);
2797 rtvec v = rtvec_alloc (16);
dd346f1f 2798 bool be = BYTES_BIG_ENDIAN;
89d67cca
DN
2799
2800 emit_insn (gen_altivec_vspltisw (vzero, const0_rtx));
2801
dd346f1f
BS
2802 RTVEC_ELT (v, 0) = gen_rtx_CONST_INT (QImode, be ? 16 : 7);
2803 RTVEC_ELT (v, 1) = gen_rtx_CONST_INT (QImode, be ? 17 : 6);
2804 RTVEC_ELT (v, 2) = gen_rtx_CONST_INT (QImode, be ? 0 : 17);
2805 RTVEC_ELT (v, 3) = gen_rtx_CONST_INT (QImode, be ? 1 : 16);
2806 RTVEC_ELT (v, 4) = gen_rtx_CONST_INT (QImode, be ? 16 : 5);
2807 RTVEC_ELT (v, 5) = gen_rtx_CONST_INT (QImode, be ? 17 : 4);
2808 RTVEC_ELT (v, 6) = gen_rtx_CONST_INT (QImode, be ? 2 : 17);
2809 RTVEC_ELT (v, 7) = gen_rtx_CONST_INT (QImode, be ? 3 : 16);
2810 RTVEC_ELT (v, 8) = gen_rtx_CONST_INT (QImode, be ? 16 : 3);
2811 RTVEC_ELT (v, 9) = gen_rtx_CONST_INT (QImode, be ? 17 : 2);
2812 RTVEC_ELT (v, 10) = gen_rtx_CONST_INT (QImode, be ? 4 : 17);
2813 RTVEC_ELT (v, 11) = gen_rtx_CONST_INT (QImode, be ? 5 : 16);
2814 RTVEC_ELT (v, 12) = gen_rtx_CONST_INT (QImode, be ? 16 : 1);
2815 RTVEC_ELT (v, 13) = gen_rtx_CONST_INT (QImode, be ? 17 : 0);
2816 RTVEC_ELT (v, 14) = gen_rtx_CONST_INT (QImode, be ? 6 : 17);
2817 RTVEC_ELT (v, 15) = gen_rtx_CONST_INT (QImode, be ? 7 : 16);
89d67cca
DN
2818
2819 emit_insn (gen_vec_initv16qi (mask, gen_rtx_PARALLEL (V16QImode, v)));
2820 emit_insn (gen_vperm_v8hiv4si (operands[0], operands[1], vzero, mask));
2821 DONE;
2822}")
2823
2824(define_expand "vec_unpacku_lo_v16qi"
2825 [(set (match_operand:V8HI 0 "register_operand" "=v")
2826 (unspec:V8HI [(match_operand:V16QI 1 "register_operand" "v")]
2827 UNSPEC_VUPKLUB))]
2828 "TARGET_ALTIVEC"
2829 "
2830{
2831 rtx vzero = gen_reg_rtx (V8HImode);
2832 rtx mask = gen_reg_rtx (V16QImode);
2833 rtvec v = rtvec_alloc (16);
dd346f1f 2834 bool be = BYTES_BIG_ENDIAN;
89d67cca
DN
2835
2836 emit_insn (gen_altivec_vspltish (vzero, const0_rtx));
2837
dd346f1f
BS
2838 RTVEC_ELT (v, 0) = gen_rtx_CONST_INT (QImode, be ? 16 : 15);
2839 RTVEC_ELT (v, 1) = gen_rtx_CONST_INT (QImode, be ? 8 : 16);
2840 RTVEC_ELT (v, 2) = gen_rtx_CONST_INT (QImode, be ? 16 : 14);
2841 RTVEC_ELT (v, 3) = gen_rtx_CONST_INT (QImode, be ? 9 : 16);
2842 RTVEC_ELT (v, 4) = gen_rtx_CONST_INT (QImode, be ? 16 : 13);
2843 RTVEC_ELT (v, 5) = gen_rtx_CONST_INT (QImode, be ? 10 : 16);
2844 RTVEC_ELT (v, 6) = gen_rtx_CONST_INT (QImode, be ? 16 : 12);
2845 RTVEC_ELT (v, 7) = gen_rtx_CONST_INT (QImode, be ? 11 : 16);
2846 RTVEC_ELT (v, 8) = gen_rtx_CONST_INT (QImode, be ? 16 : 11);
2847 RTVEC_ELT (v, 9) = gen_rtx_CONST_INT (QImode, be ? 12 : 16);
2848 RTVEC_ELT (v, 10) = gen_rtx_CONST_INT (QImode, be ? 16 : 10);
2849 RTVEC_ELT (v, 11) = gen_rtx_CONST_INT (QImode, be ? 13 : 16);
2850 RTVEC_ELT (v, 12) = gen_rtx_CONST_INT (QImode, be ? 16 : 9);
2851 RTVEC_ELT (v, 13) = gen_rtx_CONST_INT (QImode, be ? 14 : 16);
2852 RTVEC_ELT (v, 14) = gen_rtx_CONST_INT (QImode, be ? 16 : 8);
2853 RTVEC_ELT (v, 15) = gen_rtx_CONST_INT (QImode, be ? 15 : 16);
89d67cca
DN
2854
2855 emit_insn (gen_vec_initv16qi (mask, gen_rtx_PARALLEL (V16QImode, v)));
2856 emit_insn (gen_vperm_v16qiv8hi (operands[0], operands[1], vzero, mask));
2857 DONE;
2858}")
2859
2860(define_expand "vec_unpacku_lo_v8hi"
2861 [(set (match_operand:V4SI 0 "register_operand" "=v")
2862 (unspec:V4SI [(match_operand:V8HI 1 "register_operand" "v")]
2863 UNSPEC_VUPKLUH))]
2864 "TARGET_ALTIVEC"
2865 "
2866{
2867 rtx vzero = gen_reg_rtx (V4SImode);
2868 rtx mask = gen_reg_rtx (V16QImode);
2869 rtvec v = rtvec_alloc (16);
dd346f1f 2870 bool be = BYTES_BIG_ENDIAN;
89d67cca
DN
2871
2872 emit_insn (gen_altivec_vspltisw (vzero, const0_rtx));
2873
dd346f1f
BS
2874 RTVEC_ELT (v, 0) = gen_rtx_CONST_INT (QImode, be ? 16 : 15);
2875 RTVEC_ELT (v, 1) = gen_rtx_CONST_INT (QImode, be ? 17 : 14);
2876 RTVEC_ELT (v, 2) = gen_rtx_CONST_INT (QImode, be ? 8 : 17);
2877 RTVEC_ELT (v, 3) = gen_rtx_CONST_INT (QImode, be ? 9 : 16);
2878 RTVEC_ELT (v, 4) = gen_rtx_CONST_INT (QImode, be ? 16 : 13);
2879 RTVEC_ELT (v, 5) = gen_rtx_CONST_INT (QImode, be ? 17 : 12);
2880 RTVEC_ELT (v, 6) = gen_rtx_CONST_INT (QImode, be ? 10 : 17);
2881 RTVEC_ELT (v, 7) = gen_rtx_CONST_INT (QImode, be ? 11 : 16);
2882 RTVEC_ELT (v, 8) = gen_rtx_CONST_INT (QImode, be ? 16 : 11);
2883 RTVEC_ELT (v, 9) = gen_rtx_CONST_INT (QImode, be ? 17 : 10);
2884 RTVEC_ELT (v, 10) = gen_rtx_CONST_INT (QImode, be ? 12 : 17);
2885 RTVEC_ELT (v, 11) = gen_rtx_CONST_INT (QImode, be ? 13 : 16);
2886 RTVEC_ELT (v, 12) = gen_rtx_CONST_INT (QImode, be ? 16 : 9);
2887 RTVEC_ELT (v, 13) = gen_rtx_CONST_INT (QImode, be ? 17 : 8);
2888 RTVEC_ELT (v, 14) = gen_rtx_CONST_INT (QImode, be ? 14 : 17);
2889 RTVEC_ELT (v, 15) = gen_rtx_CONST_INT (QImode, be ? 15 : 16);
89d67cca
DN
2890
2891 emit_insn (gen_vec_initv16qi (mask, gen_rtx_PARALLEL (V16QImode, v)));
2892 emit_insn (gen_vperm_v8hiv4si (operands[0], operands[1], vzero, mask));
2893 DONE;
2894}")
2895
2896(define_expand "vec_widen_umult_hi_v16qi"
2897 [(set (match_operand:V8HI 0 "register_operand" "=v")
2898 (unspec:V8HI [(match_operand:V16QI 1 "register_operand" "v")
2899 (match_operand:V16QI 2 "register_operand" "v")]
2900 UNSPEC_VMULWHUB))]
2901 "TARGET_ALTIVEC"
2902 "
2903{
2904 rtx ve = gen_reg_rtx (V8HImode);
2905 rtx vo = gen_reg_rtx (V8HImode);
2906
578acbf0 2907 if (BYTES_BIG_ENDIAN)
d13dfec8
BS
2908 {
2909 emit_insn (gen_altivec_vmuleub (ve, operands[1], operands[2]));
2910 emit_insn (gen_altivec_vmuloub (vo, operands[1], operands[2]));
68d3bacf 2911 emit_insn (gen_altivec_vmrghh_direct (operands[0], ve, vo));
d13dfec8 2912 }
578acbf0 2913 else
d13dfec8
BS
2914 {
2915 emit_insn (gen_altivec_vmuloub (ve, operands[1], operands[2]));
2916 emit_insn (gen_altivec_vmuleub (vo, operands[1], operands[2]));
68d3bacf 2917 emit_insn (gen_altivec_vmrghh_direct (operands[0], vo, ve));
d13dfec8 2918 }
89d67cca
DN
2919 DONE;
2920}")
2921
2922(define_expand "vec_widen_umult_lo_v16qi"
2923 [(set (match_operand:V8HI 0 "register_operand" "=v")
2924 (unspec:V8HI [(match_operand:V16QI 1 "register_operand" "v")
2925 (match_operand:V16QI 2 "register_operand" "v")]
2926 UNSPEC_VMULWLUB))]
2927 "TARGET_ALTIVEC"
2928 "
2929{
2930 rtx ve = gen_reg_rtx (V8HImode);
2931 rtx vo = gen_reg_rtx (V8HImode);
2932
578acbf0 2933 if (BYTES_BIG_ENDIAN)
d13dfec8
BS
2934 {
2935 emit_insn (gen_altivec_vmuleub (ve, operands[1], operands[2]));
2936 emit_insn (gen_altivec_vmuloub (vo, operands[1], operands[2]));
68d3bacf 2937 emit_insn (gen_altivec_vmrglh_direct (operands[0], ve, vo));
d13dfec8 2938 }
578acbf0 2939 else
d13dfec8
BS
2940 {
2941 emit_insn (gen_altivec_vmuloub (ve, operands[1], operands[2]));
2942 emit_insn (gen_altivec_vmuleub (vo, operands[1], operands[2]));
68d3bacf 2943 emit_insn (gen_altivec_vmrglh_direct (operands[0], vo, ve));
d13dfec8 2944 }
89d67cca
DN
2945 DONE;
2946}")
2947
2948(define_expand "vec_widen_smult_hi_v16qi"
2949 [(set (match_operand:V8HI 0 "register_operand" "=v")
2950 (unspec:V8HI [(match_operand:V16QI 1 "register_operand" "v")
2951 (match_operand:V16QI 2 "register_operand" "v")]
2952 UNSPEC_VMULWHSB))]
2953 "TARGET_ALTIVEC"
2954 "
2955{
2956 rtx ve = gen_reg_rtx (V8HImode);
2957 rtx vo = gen_reg_rtx (V8HImode);
2958
578acbf0 2959 if (BYTES_BIG_ENDIAN)
d13dfec8
BS
2960 {
2961 emit_insn (gen_altivec_vmulesb (ve, operands[1], operands[2]));
2962 emit_insn (gen_altivec_vmulosb (vo, operands[1], operands[2]));
68d3bacf 2963 emit_insn (gen_altivec_vmrghh_direct (operands[0], ve, vo));
d13dfec8 2964 }
578acbf0 2965 else
d13dfec8
BS
2966 {
2967 emit_insn (gen_altivec_vmulosb (ve, operands[1], operands[2]));
2968 emit_insn (gen_altivec_vmulesb (vo, operands[1], operands[2]));
68d3bacf 2969 emit_insn (gen_altivec_vmrghh_direct (operands[0], vo, ve));
d13dfec8 2970 }
89d67cca
DN
2971 DONE;
2972}")
2973
2974(define_expand "vec_widen_smult_lo_v16qi"
2975 [(set (match_operand:V8HI 0 "register_operand" "=v")
2976 (unspec:V8HI [(match_operand:V16QI 1 "register_operand" "v")
2977 (match_operand:V16QI 2 "register_operand" "v")]
2978 UNSPEC_VMULWLSB))]
2979 "TARGET_ALTIVEC"
2980 "
2981{
2982 rtx ve = gen_reg_rtx (V8HImode);
2983 rtx vo = gen_reg_rtx (V8HImode);
2984
578acbf0 2985 if (BYTES_BIG_ENDIAN)
d13dfec8
BS
2986 {
2987 emit_insn (gen_altivec_vmulesb (ve, operands[1], operands[2]));
2988 emit_insn (gen_altivec_vmulosb (vo, operands[1], operands[2]));
68d3bacf 2989 emit_insn (gen_altivec_vmrglh_direct (operands[0], ve, vo));
d13dfec8 2990 }
578acbf0 2991 else
d13dfec8
BS
2992 {
2993 emit_insn (gen_altivec_vmulosb (ve, operands[1], operands[2]));
2994 emit_insn (gen_altivec_vmulesb (vo, operands[1], operands[2]));
68d3bacf 2995 emit_insn (gen_altivec_vmrglh_direct (operands[0], vo, ve));
d13dfec8 2996 }
89d67cca
DN
2997 DONE;
2998}")
2999
3000(define_expand "vec_widen_umult_hi_v8hi"
3001 [(set (match_operand:V4SI 0 "register_operand" "=v")
3002 (unspec:V4SI [(match_operand:V8HI 1 "register_operand" "v")
3003 (match_operand:V8HI 2 "register_operand" "v")]
3004 UNSPEC_VMULWHUH))]
3005 "TARGET_ALTIVEC"
3006 "
3007{
3008 rtx ve = gen_reg_rtx (V4SImode);
3009 rtx vo = gen_reg_rtx (V4SImode);
3010
578acbf0 3011 if (BYTES_BIG_ENDIAN)
d13dfec8
BS
3012 {
3013 emit_insn (gen_altivec_vmuleuh (ve, operands[1], operands[2]));
3014 emit_insn (gen_altivec_vmulouh (vo, operands[1], operands[2]));
68d3bacf 3015 emit_insn (gen_altivec_vmrghw_direct (operands[0], ve, vo));
d13dfec8 3016 }
578acbf0 3017 else
d13dfec8
BS
3018 {
3019 emit_insn (gen_altivec_vmulouh (ve, operands[1], operands[2]));
3020 emit_insn (gen_altivec_vmuleuh (vo, operands[1], operands[2]));
68d3bacf 3021 emit_insn (gen_altivec_vmrghw_direct (operands[0], vo, ve));
d13dfec8 3022 }
89d67cca
DN
3023 DONE;
3024}")
3025
3026(define_expand "vec_widen_umult_lo_v8hi"
3027 [(set (match_operand:V4SI 0 "register_operand" "=v")
3028 (unspec:V4SI [(match_operand:V8HI 1 "register_operand" "v")
3029 (match_operand:V8HI 2 "register_operand" "v")]
3030 UNSPEC_VMULWLUH))]
3031 "TARGET_ALTIVEC"
3032 "
3033{
3034 rtx ve = gen_reg_rtx (V4SImode);
3035 rtx vo = gen_reg_rtx (V4SImode);
3036
578acbf0 3037 if (BYTES_BIG_ENDIAN)
d13dfec8
BS
3038 {
3039 emit_insn (gen_altivec_vmuleuh (ve, operands[1], operands[2]));
3040 emit_insn (gen_altivec_vmulouh (vo, operands[1], operands[2]));
68d3bacf 3041 emit_insn (gen_altivec_vmrglw_direct (operands[0], ve, vo));
d13dfec8 3042 }
578acbf0 3043 else
d13dfec8
BS
3044 {
3045 emit_insn (gen_altivec_vmulouh (ve, operands[1], operands[2]));
3046 emit_insn (gen_altivec_vmuleuh (vo, operands[1], operands[2]));
68d3bacf 3047 emit_insn (gen_altivec_vmrglw_direct (operands[0], vo, ve));
d13dfec8 3048 }
89d67cca
DN
3049 DONE;
3050}")
3051
3052(define_expand "vec_widen_smult_hi_v8hi"
3053 [(set (match_operand:V4SI 0 "register_operand" "=v")
3054 (unspec:V4SI [(match_operand:V8HI 1 "register_operand" "v")
3055 (match_operand:V8HI 2 "register_operand" "v")]
3056 UNSPEC_VMULWHSH))]
3057 "TARGET_ALTIVEC"
3058 "
3059{
3060 rtx ve = gen_reg_rtx (V4SImode);
3061 rtx vo = gen_reg_rtx (V4SImode);
3062
578acbf0 3063 if (BYTES_BIG_ENDIAN)
d13dfec8
BS
3064 {
3065 emit_insn (gen_altivec_vmulesh (ve, operands[1], operands[2]));
3066 emit_insn (gen_altivec_vmulosh (vo, operands[1], operands[2]));
68d3bacf 3067 emit_insn (gen_altivec_vmrghw_direct (operands[0], ve, vo));
d13dfec8 3068 }
578acbf0 3069 else
d13dfec8
BS
3070 {
3071 emit_insn (gen_altivec_vmulosh (ve, operands[1], operands[2]));
3072 emit_insn (gen_altivec_vmulesh (vo, operands[1], operands[2]));
68d3bacf 3073 emit_insn (gen_altivec_vmrghw_direct (operands[0], vo, ve));
d13dfec8 3074 }
89d67cca
DN
3075 DONE;
3076}")
3077
3078(define_expand "vec_widen_smult_lo_v8hi"
3079 [(set (match_operand:V4SI 0 "register_operand" "=v")
3080 (unspec:V4SI [(match_operand:V8HI 1 "register_operand" "v")
3081 (match_operand:V8HI 2 "register_operand" "v")]
3082 UNSPEC_VMULWLSH))]
3083 "TARGET_ALTIVEC"
3084 "
3085{
3086 rtx ve = gen_reg_rtx (V4SImode);
3087 rtx vo = gen_reg_rtx (V4SImode);
3088
578acbf0 3089 if (BYTES_BIG_ENDIAN)
d13dfec8
BS
3090 {
3091 emit_insn (gen_altivec_vmulesh (ve, operands[1], operands[2]));
3092 emit_insn (gen_altivec_vmulosh (vo, operands[1], operands[2]));
68d3bacf 3093 emit_insn (gen_altivec_vmrglw_direct (operands[0], ve, vo));
d13dfec8 3094 }
578acbf0 3095 else
d13dfec8
BS
3096 {
3097 emit_insn (gen_altivec_vmulosh (ve, operands[1], operands[2]));
3098 emit_insn (gen_altivec_vmulesh (vo, operands[1], operands[2]));
68d3bacf 3099 emit_insn (gen_altivec_vmrglw_direct (operands[0], vo, ve));
d13dfec8 3100 }
89d67cca
DN
3101 DONE;
3102}")
3103
a5965b52
MM
3104(define_expand "vec_pack_trunc_<mode>"
3105 [(set (match_operand:<VP_small> 0 "register_operand" "=v")
3106 (unspec:<VP_small> [(match_operand:VP 1 "register_operand" "v")
3107 (match_operand:VP 2 "register_operand" "v")]
3108 UNSPEC_VPACK_UNS_UNS_MOD))]
3109 "<VI_unit>"
3110 "")
89d67cca 3111
a72c65c7 3112(define_expand "altivec_negv4sf2"
70a39602
IR
3113 [(use (match_operand:V4SF 0 "register_operand" ""))
3114 (use (match_operand:V4SF 1 "register_operand" ""))]
3115 "TARGET_ALTIVEC"
3116 "
3117{
3118 rtx neg0;
3119
3120 /* Generate [-0.0, -0.0, -0.0, -0.0]. */
8cf0db2b
UW
3121 neg0 = gen_reg_rtx (V4SImode);
3122 emit_insn (gen_altivec_vspltisw (neg0, constm1_rtx));
71d46ca5 3123 emit_insn (gen_vashlv4si3 (neg0, neg0, neg0));
70a39602
IR
3124
3125 /* XOR */
8cf0db2b
UW
3126 emit_insn (gen_xorv4sf3 (operands[0],
3127 gen_lowpart (V4SFmode, neg0), operands[1]));
70a39602
IR
3128
3129 DONE;
3130}")
98b44b0e 3131
0b61703c
AP
3132;; Vector SIMD PEM v2.06c defines LVLX, LVLXL, LVRX, LVRXL,
3133;; STVLX, STVLXL, STVVRX, STVRXL are available only on Cell.
3134(define_insn "altivec_lvlx"
3135 [(set (match_operand:V16QI 0 "register_operand" "=v")
1ba24090 3136 (unspec:V16QI [(match_operand:BLK 1 "memory_operand" "Z")]
0b61703c
AP
3137 UNSPEC_LVLX))]
3138 "TARGET_ALTIVEC && rs6000_cpu == PROCESSOR_CELL"
3139 "lvlx %0,%y1"
3140 [(set_attr "type" "vecload")])
3141
3142(define_insn "altivec_lvlxl"
3143 [(set (match_operand:V16QI 0 "register_operand" "=v")
1ba24090 3144 (unspec:V16QI [(match_operand:BLK 1 "memory_operand" "Z")]
0b61703c
AP
3145 UNSPEC_LVLXL))]
3146 "TARGET_ALTIVEC && rs6000_cpu == PROCESSOR_CELL"
3147 "lvlxl %0,%y1"
3148 [(set_attr "type" "vecload")])
3149
3150(define_insn "altivec_lvrx"
3151 [(set (match_operand:V16QI 0 "register_operand" "=v")
1ba24090 3152 (unspec:V16QI [(match_operand:BLK 1 "memory_operand" "Z")]
0b61703c
AP
3153 UNSPEC_LVRX))]
3154 "TARGET_ALTIVEC && rs6000_cpu == PROCESSOR_CELL"
3155 "lvrx %0,%y1"
3156 [(set_attr "type" "vecload")])
3157
3158(define_insn "altivec_lvrxl"
3159 [(set (match_operand:V16QI 0 "register_operand" "=v")
1ba24090 3160 (unspec:V16QI [(match_operand:BLK 1 "memory_operand" "Z")]
0b61703c
AP
3161 UNSPEC_LVRXL))]
3162 "TARGET_ALTIVEC && rs6000_cpu == PROCESSOR_CELL"
3163 "lvrxl %0,%y1"
3164 [(set_attr "type" "vecload")])
3165
3166(define_insn "altivec_stvlx"
3167 [(parallel
fbc932e7
EW
3168 [(set (match_operand:V16QI 0 "memory_operand" "=Z")
3169 (match_operand:V16QI 1 "register_operand" "v"))
0b61703c
AP
3170 (unspec [(const_int 0)] UNSPEC_STVLX)])]
3171 "TARGET_ALTIVEC && rs6000_cpu == PROCESSOR_CELL"
3172 "stvlx %1,%y0"
3173 [(set_attr "type" "vecstore")])
3174
3175(define_insn "altivec_stvlxl"
3176 [(parallel
fbc932e7
EW
3177 [(set (match_operand:V16QI 0 "memory_operand" "=Z")
3178 (match_operand:V16QI 1 "register_operand" "v"))
0b61703c
AP
3179 (unspec [(const_int 0)] UNSPEC_STVLXL)])]
3180 "TARGET_ALTIVEC && rs6000_cpu == PROCESSOR_CELL"
3181 "stvlxl %1,%y0"
3182 [(set_attr "type" "vecstore")])
3183
3184(define_insn "altivec_stvrx"
3185 [(parallel
fbc932e7
EW
3186 [(set (match_operand:V16QI 0 "memory_operand" "=Z")
3187 (match_operand:V16QI 1 "register_operand" "v"))
0b61703c
AP
3188 (unspec [(const_int 0)] UNSPEC_STVRX)])]
3189 "TARGET_ALTIVEC && rs6000_cpu == PROCESSOR_CELL"
3190 "stvrx %1,%y0"
3191 [(set_attr "type" "vecstore")])
3192
3193(define_insn "altivec_stvrxl"
3194 [(parallel
fbc932e7
EW
3195 [(set (match_operand:V16QI 0 "memory_operand" "=Z")
3196 (match_operand:V16QI 1 "register_operand" "v"))
0b61703c
AP
3197 (unspec [(const_int 0)] UNSPEC_STVRXL)])]
3198 "TARGET_ALTIVEC && rs6000_cpu == PROCESSOR_CELL"
3199 "stvrxl %1,%y0"
3200 [(set_attr "type" "vecstore")])
3201
4643b716
DN
3202(define_expand "vec_unpacks_float_hi_v8hi"
3203 [(set (match_operand:V4SF 0 "register_operand" "")
3204 (unspec:V4SF [(match_operand:V8HI 1 "register_operand" "")]
3205 UNSPEC_VUPKHS_V4SF))]
3206 "TARGET_ALTIVEC"
3207 "
3208{
3209 rtx tmp = gen_reg_rtx (V4SImode);
3210
3211 emit_insn (gen_vec_unpacks_hi_v8hi (tmp, operands[1]));
3212 emit_insn (gen_altivec_vcfsx (operands[0], tmp, const0_rtx));
3213 DONE;
3214}")
3215
3216(define_expand "vec_unpacks_float_lo_v8hi"
3217 [(set (match_operand:V4SF 0 "register_operand" "")
3218 (unspec:V4SF [(match_operand:V8HI 1 "register_operand" "")]
3219 UNSPEC_VUPKLS_V4SF))]
3220 "TARGET_ALTIVEC"
3221 "
3222{
3223 rtx tmp = gen_reg_rtx (V4SImode);
3224
3225 emit_insn (gen_vec_unpacks_lo_v8hi (tmp, operands[1]));
3226 emit_insn (gen_altivec_vcfsx (operands[0], tmp, const0_rtx));
3227 DONE;
3228}")
3229
3230(define_expand "vec_unpacku_float_hi_v8hi"
3231 [(set (match_operand:V4SF 0 "register_operand" "")
3232 (unspec:V4SF [(match_operand:V8HI 1 "register_operand" "")]
3233 UNSPEC_VUPKHU_V4SF))]
3234 "TARGET_ALTIVEC"
3235 "
3236{
3237 rtx tmp = gen_reg_rtx (V4SImode);
3238
3239 emit_insn (gen_vec_unpacku_hi_v8hi (tmp, operands[1]));
3240 emit_insn (gen_altivec_vcfux (operands[0], tmp, const0_rtx));
3241 DONE;
3242}")
3243
3244(define_expand "vec_unpacku_float_lo_v8hi"
3245 [(set (match_operand:V4SF 0 "register_operand" "")
3246 (unspec:V4SF [(match_operand:V8HI 1 "register_operand" "")]
3247 UNSPEC_VUPKLU_V4SF))]
3248 "TARGET_ALTIVEC"
3249 "
3250{
3251 rtx tmp = gen_reg_rtx (V4SImode);
3252
3253 emit_insn (gen_vec_unpacku_lo_v8hi (tmp, operands[1]));
3254 emit_insn (gen_altivec_vcfux (operands[0], tmp, const0_rtx));
3255 DONE;
3256}")
0bd62dca
MM
3257
3258\f
3259;; Power8 vector instructions encoded as Altivec instructions
3260
3261;; Vector count leading zeros
3262(define_insn "*p8v_clz<mode>2"
3263 [(set (match_operand:VI2 0 "register_operand" "=v")
3264 (clz:VI2 (match_operand:VI2 1 "register_operand" "v")))]
3265 "TARGET_P8_VECTOR"
3266 "vclz<wd> %0,%1"
3267 [(set_attr "length" "4")
3268 (set_attr "type" "vecsimple")])
3269
3270;; Vector population count
3271(define_insn "*p8v_popcount<mode>2"
3272 [(set (match_operand:VI2 0 "register_operand" "=v")
3273 (popcount:VI2 (match_operand:VI2 1 "register_operand" "v")))]
3274 "TARGET_P8_VECTOR"
3275 "vpopcnt<wd> %0,%1"
3276 [(set_attr "length" "4")
3277 (set_attr "type" "vecsimple")])
3278
3279;; Vector Gather Bits by Bytes by Doubleword
3280(define_insn "p8v_vgbbd"
3281 [(set (match_operand:V16QI 0 "register_operand" "=v")
3282 (unspec:V16QI [(match_operand:V16QI 1 "register_operand" "v")]
3283 UNSPEC_VGBBD))]
3284 "TARGET_P8_VECTOR"
3285 "vgbbd %0,%1"
3286 [(set_attr "length" "4")
3287 (set_attr "type" "vecsimple")])
a16a872d
MM
3288
3289\f
3290;; 128-bit binary integer arithmetic
3291;; We have a special container type (V1TImode) to allow operations using the
3292;; ISA 2.07 128-bit binary support to target the VMX/altivec registers without
3293;; having to worry about the register allocator deciding GPRs are better.
3294
3295(define_insn "altivec_vadduqm"
3296 [(set (match_operand:V1TI 0 "register_operand" "=v")
3297 (plus:V1TI (match_operand:V1TI 1 "register_operand" "v")
3298 (match_operand:V1TI 2 "register_operand" "v")))]
3299 "TARGET_VADDUQM"
3300 "vadduqm %0,%1,%2"
3301 [(set_attr "length" "4")
3302 (set_attr "type" "vecsimple")])
3303
3304(define_insn "altivec_vaddcuq"
3305 [(set (match_operand:V1TI 0 "register_operand" "=v")
3306 (unspec:V1TI [(match_operand:V1TI 1 "register_operand" "v")
3307 (match_operand:V1TI 2 "register_operand" "v")]
3308 UNSPEC_VADDCUQ))]
3309 "TARGET_VADDUQM"
3310 "vaddcuq %0,%1,%2"
3311 [(set_attr "length" "4")
3312 (set_attr "type" "vecsimple")])
3313
3314(define_insn "altivec_vsubuqm"
3315 [(set (match_operand:V1TI 0 "register_operand" "=v")
3316 (minus:V1TI (match_operand:V1TI 1 "register_operand" "v")
3317 (match_operand:V1TI 2 "register_operand" "v")))]
3318 "TARGET_VADDUQM"
3319 "vsubuqm %0,%1,%2"
3320 [(set_attr "length" "4")
3321 (set_attr "type" "vecsimple")])
3322
3323(define_insn "altivec_vsubcuq"
3324 [(set (match_operand:V1TI 0 "register_operand" "=v")
3325 (unspec:V1TI [(match_operand:V1TI 1 "register_operand" "v")
3326 (match_operand:V1TI 2 "register_operand" "v")]
3327 UNSPEC_VSUBCUQ))]
3328 "TARGET_VADDUQM"
3329 "vsubcuq %0,%1,%2"
3330 [(set_attr "length" "4")
3331 (set_attr "type" "vecsimple")])
3332
3333(define_insn "altivec_vaddeuqm"
3334 [(set (match_operand:V1TI 0 "register_operand" "=v")
3335 (unspec:V1TI [(match_operand:V1TI 1 "register_operand" "v")
3336 (match_operand:V1TI 2 "register_operand" "v")
3337 (match_operand:V1TI 3 "register_operand" "v")]
3338 UNSPEC_VADDEUQM))]
3339 "TARGET_VADDUQM"
3340 "vaddeuqm %0,%1,%2,%3"
3341 [(set_attr "length" "4")
3342 (set_attr "type" "vecsimple")])
3343
3344(define_insn "altivec_vaddecuq"
3345 [(set (match_operand:V1TI 0 "register_operand" "=v")
3346 (unspec:V1TI [(match_operand:V1TI 1 "register_operand" "v")
3347 (match_operand:V1TI 2 "register_operand" "v")
3348 (match_operand:V1TI 3 "register_operand" "v")]
3349 UNSPEC_VADDECUQ))]
3350 "TARGET_VADDUQM"
3351 "vaddecuq %0,%1,%2,%3"
3352 [(set_attr "length" "4")
3353 (set_attr "type" "vecsimple")])
3354
3355(define_insn "altivec_vsubeuqm"
3356 [(set (match_operand:V1TI 0 "register_operand" "=v")
3357 (unspec:V1TI [(match_operand:V1TI 1 "register_operand" "v")
3358 (match_operand:V1TI 2 "register_operand" "v")
3359 (match_operand:V1TI 3 "register_operand" "v")]
3360 UNSPEC_VSUBEUQM))]
3361 "TARGET_VADDUQM"
3362 "vsubeuqm %0,%1,%2,%3"
3363 [(set_attr "length" "4")
3364 (set_attr "type" "vecsimple")])
3365
3366(define_insn "altivec_vsubecuq"
3367 [(set (match_operand:V1TI 0 "register_operand" "=v")
3368 (unspec:V1TI [(match_operand:V1TI 1 "register_operand" "v")
3369 (match_operand:V1TI 2 "register_operand" "v")
3370 (match_operand:V1TI 3 "register_operand" "v")]
3371 UNSPEC_VSUBECUQ))]
3372 "TARGET_VADDUQM"
3373 "vsubecuq %0,%1,%2,%3"
3374 [(set_attr "length" "4")
3375 (set_attr "type" "vecsimple")])
3376
117f16fb
MM
3377;; We use V2DI as the output type to simplify converting the permute
3378;; bits into an integer
3379(define_insn "altivec_vbpermq"
3380 [(set (match_operand:V2DI 0 "register_operand" "=v")
3381 (unspec:V2DI [(match_operand:V16QI 1 "register_operand" "v")
3382 (match_operand:V16QI 2 "register_operand" "v")]
3383 UNSPEC_VBPERMQ))]
3384 "TARGET_P8_VECTOR"
3385 "vbpermq %0,%1,%2"
3386 [(set_attr "length" "4")
3387 (set_attr "type" "vecsimple")])
06b39289
MM
3388
3389;; Decimal Integer operations
3390(define_int_iterator UNSPEC_BCD_ADD_SUB [UNSPEC_BCDADD UNSPEC_BCDSUB])
3391
3392(define_int_attr bcd_add_sub [(UNSPEC_BCDADD "add")
3393 (UNSPEC_BCDSUB "sub")])
3394
3395(define_code_iterator BCD_TEST [eq lt gt unordered])
3396
3397(define_insn "bcd<bcd_add_sub>"
3398 [(set (match_operand:V1TI 0 "register_operand" "")
3399 (unspec:V1TI [(match_operand:V1TI 1 "register_operand" "")
3400 (match_operand:V1TI 2 "register_operand" "")
3401 (match_operand:QI 3 "const_0_to_1_operand" "")]
3402 UNSPEC_BCD_ADD_SUB))
3403 (clobber (reg:CCFP 74))]
3404 "TARGET_P8_VECTOR"
3405 "bcd<bcd_add_sub>. %0,%1,%2,%3"
3406 [(set_attr "length" "4")
3407 (set_attr "type" "vecsimple")])
3408
3409;; Use a floating point type (V2DFmode) for the compare to set CR6 so that we
3410;; can use the unordered test for BCD nans and add/subtracts that overflow. An
3411;; UNORDERED test on an integer type (like V1TImode) is not defined. The type
3412;; probably should be one that can go in the VMX (Altivec) registers, so we
3413;; can't use DDmode or DFmode.
3414(define_insn "*bcd<bcd_add_sub>_test"
3415 [(set (reg:CCFP 74)
3416 (compare:CCFP
3417 (unspec:V2DF [(match_operand:V1TI 1 "register_operand" "v")
3418 (match_operand:V1TI 2 "register_operand" "v")
3419 (match_operand:QI 3 "const_0_to_1_operand" "i")]
3420 UNSPEC_BCD_ADD_SUB)
3421 (match_operand:V2DF 4 "zero_constant" "j")))
3422 (clobber (match_scratch:V1TI 0 "=v"))]
3423 "TARGET_P8_VECTOR"
3424 "bcd<bcd_add_sub>. %0,%1,%2,%3"
3425 [(set_attr "length" "4")
3426 (set_attr "type" "vecsimple")])
3427
3428(define_insn "*bcd<bcd_add_sub>_test2"
3429 [(set (match_operand:V1TI 0 "register_operand" "=v")
3430 (unspec:V1TI [(match_operand:V1TI 1 "register_operand" "v")
3431 (match_operand:V1TI 2 "register_operand" "v")
3432 (match_operand:QI 3 "const_0_to_1_operand" "i")]
3433 UNSPEC_BCD_ADD_SUB))
3434 (set (reg:CCFP 74)
3435 (compare:CCFP
3436 (unspec:V2DF [(match_dup 1)
3437 (match_dup 2)
3438 (match_dup 3)]
3439 UNSPEC_BCD_ADD_SUB)
3440 (match_operand:V2DF 4 "zero_constant" "j")))]
3441 "TARGET_P8_VECTOR"
3442 "bcd<bcd_add_sub>. %0,%1,%2,%3"
3443 [(set_attr "length" "4")
3444 (set_attr "type" "vecsimple")])
3445
3446(define_expand "bcd<bcd_add_sub>_<code>"
3447 [(parallel [(set (reg:CCFP 74)
3448 (compare:CCFP
3449 (unspec:V2DF [(match_operand:V1TI 1 "register_operand" "")
3450 (match_operand:V1TI 2 "register_operand" "")
3451 (match_operand:QI 3 "const_0_to_1_operand" "")]
3452 UNSPEC_BCD_ADD_SUB)
3453 (match_dup 4)))
3454 (clobber (match_scratch:V1TI 5 ""))])
3455 (set (match_operand:SI 0 "register_operand" "")
3456 (BCD_TEST:SI (reg:CCFP 74)
3457 (const_int 0)))]
3458 "TARGET_P8_VECTOR"
3459{
3460 operands[4] = CONST0_RTX (V2DFmode);
3461})
3462
3463;; Peephole2 pattern to combine a bcdadd/bcdsub that calculates the value and
3464;; the bcdadd/bcdsub that tests the value. The combiner won't work since
3465;; CR6 is a hard coded register. Unfortunately, all of the Altivec predicate
3466;; support is hard coded to use the fixed register CR6 instead of creating
3467;; a register class for CR6.
3468
3469(define_peephole2
3470 [(parallel [(set (match_operand:V1TI 0 "register_operand" "")
3471 (unspec:V1TI [(match_operand:V1TI 1 "register_operand" "")
3472 (match_operand:V1TI 2 "register_operand" "")
3473 (match_operand:QI 3 "const_0_to_1_operand" "")]
3474 UNSPEC_BCD_ADD_SUB))
3475 (clobber (reg:CCFP 74))])
3476 (parallel [(set (reg:CCFP 74)
3477 (compare:CCFP
3478 (unspec:V2DF [(match_dup 1)
3479 (match_dup 2)
3480 (match_dup 3)]
3481 UNSPEC_BCD_ADD_SUB)
3482 (match_operand:V2DF 4 "zero_constant" "")))
3483 (clobber (match_operand:V1TI 5 "register_operand" ""))])]
3484 "TARGET_P8_VECTOR"
3485 [(parallel [(set (match_dup 0)
3486 (unspec:V1TI [(match_dup 1)
3487 (match_dup 2)
3488 (match_dup 3)]
3489 UNSPEC_BCD_ADD_SUB))
3490 (set (reg:CCFP 74)
3491 (compare:CCFP
3492 (unspec:V2DF [(match_dup 1)
3493 (match_dup 2)
3494 (match_dup 3)]
3495 UNSPEC_BCD_ADD_SUB)
3496 (match_dup 4)))])])