altivec.md (vec_unpacku_hi_v16qi): Adjust for little endian.
[gcc.git] / gcc / config / rs6000 / altivec.md
1 ;; AltiVec patterns.
2 ;; Copyright (C) 2002-2013 Free Software Foundation, Inc.
3 ;; Contributed by Aldy Hernandez (aldy@quesejoda.com)
4
5 ;; This file is part of GCC.
6
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
9 ;; by the Free Software Foundation; either version 3, or (at your
10 ;; option) any later version.
11
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.
16
17 ;; You should have received a copy of the GNU General Public License
18 ;; along with GCC; see the file COPYING3. If not see
19 ;; <http://www.gnu.org/licenses/>.
20
21 (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
44 UNSPEC_VPKPX
45 UNSPEC_VPACK_SIGN_SIGN_SAT
46 UNSPEC_VPACK_SIGN_UNS_SAT
47 UNSPEC_VPACK_UNS_UNS_SAT
48 UNSPEC_VPACK_UNS_UNS_MOD
49 UNSPEC_VSLV4SI
50 UNSPEC_VSLO
51 UNSPEC_VSR
52 UNSPEC_VSRO
53 UNSPEC_VSUBCUW
54 UNSPEC_VSUBU
55 UNSPEC_VSUBS
56 UNSPEC_VSUM4UBS
57 UNSPEC_VSUM4S
58 UNSPEC_VSUM2SWS
59 UNSPEC_VSUMSWS
60 UNSPEC_VPERM
61 UNSPEC_VPERM_UNS
62 UNSPEC_VPERM_X
63 UNSPEC_VPERM_UNS_X
64 UNSPEC_VRFIN
65 UNSPEC_VCFUX
66 UNSPEC_VCFSX
67 UNSPEC_VCTUXS
68 UNSPEC_VCTSXS
69 UNSPEC_VLOGEFP
70 UNSPEC_VEXPTEFP
71 UNSPEC_VLSDOI
72 UNSPEC_VUNPACK_HI_SIGN
73 UNSPEC_VUNPACK_LO_SIGN
74 UNSPEC_VUPKHPX
75 UNSPEC_VUPKLPX
76 UNSPEC_DST
77 UNSPEC_DSTT
78 UNSPEC_DSTST
79 UNSPEC_DSTSTT
80 UNSPEC_LVSL
81 UNSPEC_LVSR
82 UNSPEC_LVE
83 UNSPEC_STVX
84 UNSPEC_STVXL
85 UNSPEC_STVE
86 UNSPEC_SET_VSCR
87 UNSPEC_GET_VRSAVE
88 UNSPEC_LVX
89 UNSPEC_REDUC_PLUS
90 UNSPEC_VECSH
91 UNSPEC_EXTEVEN_V4SI
92 UNSPEC_EXTEVEN_V8HI
93 UNSPEC_EXTEVEN_V16QI
94 UNSPEC_EXTEVEN_V4SF
95 UNSPEC_EXTODD_V4SI
96 UNSPEC_EXTODD_V8HI
97 UNSPEC_EXTODD_V16QI
98 UNSPEC_EXTODD_V4SF
99 UNSPEC_INTERHI_V4SI
100 UNSPEC_INTERHI_V8HI
101 UNSPEC_INTERHI_V16QI
102 UNSPEC_INTERLO_V4SI
103 UNSPEC_INTERLO_V8HI
104 UNSPEC_INTERLO_V16QI
105 UNSPEC_LVLX
106 UNSPEC_LVLXL
107 UNSPEC_LVRX
108 UNSPEC_LVRXL
109 UNSPEC_STVLX
110 UNSPEC_STVLXL
111 UNSPEC_STVRX
112 UNSPEC_STVRXL
113 UNSPEC_VMULWHUB
114 UNSPEC_VMULWLUB
115 UNSPEC_VMULWHSB
116 UNSPEC_VMULWLSB
117 UNSPEC_VMULWHUH
118 UNSPEC_VMULWLUH
119 UNSPEC_VMULWHSH
120 UNSPEC_VMULWLSH
121 UNSPEC_VUPKHUB
122 UNSPEC_VUPKHUH
123 UNSPEC_VUPKLUB
124 UNSPEC_VUPKLUH
125 UNSPEC_VPERMSI
126 UNSPEC_VPERMHI
127 UNSPEC_INTERHI
128 UNSPEC_INTERLO
129 UNSPEC_VUPKHS_V4SF
130 UNSPEC_VUPKLS_V4SF
131 UNSPEC_VUPKHU_V4SF
132 UNSPEC_VUPKLU_V4SF
133 UNSPEC_VGBBD
134 ])
135
136 (define_c_enum "unspecv"
137 [UNSPECV_SET_VRSAVE
138 UNSPECV_MTVSCR
139 UNSPECV_MFVSCR
140 UNSPECV_DSSALL
141 UNSPECV_DSS
142 ])
143
144 ;; Vec int modes
145 (define_mode_iterator VI [V4SI V8HI V16QI])
146 ;; Like VI, but add ISA 2.07 integer vector ops
147 (define_mode_iterator VI2 [V4SI V8HI V16QI V2DI])
148 ;; Short vec in modes
149 (define_mode_iterator VIshort [V8HI V16QI])
150 ;; Vec float modes
151 (define_mode_iterator VF [V4SF])
152 ;; Vec modes, pity mode iterators are not composable
153 (define_mode_iterator V [V4SI V8HI V16QI V4SF])
154 ;; Vec modes for move/logical/permute ops, include vector types for move not
155 ;; otherwise handled by altivec (v2df, v2di, ti)
156 (define_mode_iterator VM [V4SI V8HI V16QI V4SF V2DF V2DI TI])
157
158 ;; Like VM, except don't do TImode
159 (define_mode_iterator VM2 [V4SI V8HI V16QI V4SF V2DF V2DI])
160
161 (define_mode_attr VI_char [(V2DI "d") (V4SI "w") (V8HI "h") (V16QI "b")])
162 (define_mode_attr VI_scalar [(V2DI "DI") (V4SI "SI") (V8HI "HI") (V16QI "QI")])
163 (define_mode_attr VI_unit [(V16QI "VECTOR_UNIT_ALTIVEC_P (V16QImode)")
164 (V8HI "VECTOR_UNIT_ALTIVEC_P (V8HImode)")
165 (V4SI "VECTOR_UNIT_ALTIVEC_P (V4SImode)")
166 (V2DI "VECTOR_UNIT_P8_VECTOR_P (V2DImode)")])
167
168 ;; Vector pack/unpack
169 (define_mode_iterator VP [V2DI V4SI V8HI])
170 (define_mode_attr VP_small [(V2DI "V4SI") (V4SI "V8HI") (V8HI "V16QI")])
171 (define_mode_attr VP_small_lc [(V2DI "v4si") (V4SI "v8hi") (V8HI "v16qi")])
172 (define_mode_attr VU_char [(V2DI "w") (V4SI "h") (V8HI "b")])
173
174 ;; Vector move instructions.
175 (define_insn "*altivec_mov<mode>"
176 [(set (match_operand:VM2 0 "nonimmediate_operand" "=Z,v,v,*Y,*r,*r,v,v")
177 (match_operand:VM2 1 "input_operand" "v,Z,v,r,Y,r,j,W"))]
178 "VECTOR_MEM_ALTIVEC_P (<MODE>mode)
179 && (register_operand (operands[0], <MODE>mode)
180 || register_operand (operands[1], <MODE>mode))"
181 {
182 switch (which_alternative)
183 {
184 case 0: return "stvx %1,%y0";
185 case 1: return "lvx %0,%y1";
186 case 2: return "vor %0,%1,%1";
187 case 3: return "#";
188 case 4: return "#";
189 case 5: return "#";
190 case 6: return "vxor %0,%0,%0";
191 case 7: return output_vec_const_move (operands);
192 default: gcc_unreachable ();
193 }
194 }
195 [(set_attr "type" "vecstore,vecload,vecsimple,store,load,*,vecsimple,*")])
196
197 ;; Unlike other altivec moves, allow the GPRs, since a normal use of TImode
198 ;; is for unions. However for plain data movement, slightly favor the vector
199 ;; loads
200 (define_insn "*altivec_movti"
201 [(set (match_operand:TI 0 "nonimmediate_operand" "=Z,v,v,?Y,?r,?r,v,v")
202 (match_operand:TI 1 "input_operand" "v,Z,v,r,Y,r,j,W"))]
203 "VECTOR_MEM_ALTIVEC_P (TImode)
204 && (register_operand (operands[0], TImode)
205 || register_operand (operands[1], TImode))"
206 {
207 switch (which_alternative)
208 {
209 case 0: return "stvx %1,%y0";
210 case 1: return "lvx %0,%y1";
211 case 2: return "vor %0,%1,%1";
212 case 3: return "#";
213 case 4: return "#";
214 case 5: return "#";
215 case 6: return "vxor %0,%0,%0";
216 case 7: return output_vec_const_move (operands);
217 default: gcc_unreachable ();
218 }
219 }
220 [(set_attr "type" "vecstore,vecload,vecsimple,store,load,*,vecsimple,*")])
221
222 ;; Load up a vector with the most significant bit set by loading up -1 and
223 ;; doing a shift left
224 (define_split
225 [(set (match_operand:VM 0 "altivec_register_operand" "")
226 (match_operand:VM 1 "easy_vector_constant_msb" ""))]
227 "VECTOR_UNIT_ALTIVEC_OR_VSX_P (<MODE>mode) && reload_completed"
228 [(const_int 0)]
229 {
230 rtx dest = operands[0];
231 enum machine_mode mode = GET_MODE (operands[0]);
232 rtvec v;
233 int i, num_elements;
234
235 if (mode == V4SFmode)
236 {
237 mode = V4SImode;
238 dest = gen_lowpart (V4SImode, dest);
239 }
240
241 num_elements = GET_MODE_NUNITS (mode);
242 v = rtvec_alloc (num_elements);
243 for (i = 0; i < num_elements; i++)
244 RTVEC_ELT (v, i) = constm1_rtx;
245
246 emit_insn (gen_vec_initv4si (dest, gen_rtx_PARALLEL (mode, v)));
247 emit_insn (gen_rtx_SET (VOIDmode, dest, gen_rtx_ASHIFT (mode, dest, dest)));
248 DONE;
249 })
250
251 (define_split
252 [(set (match_operand:VM 0 "altivec_register_operand" "")
253 (match_operand:VM 1 "easy_vector_constant_add_self" ""))]
254 "VECTOR_UNIT_ALTIVEC_OR_VSX_P (<MODE>mode) && reload_completed"
255 [(set (match_dup 0) (match_dup 3))
256 (set (match_dup 0) (match_dup 4))]
257 {
258 rtx dup = gen_easy_altivec_constant (operands[1]);
259 rtx const_vec;
260 enum machine_mode op_mode = <MODE>mode;
261
262 /* Divide the operand of the resulting VEC_DUPLICATE, and use
263 simplify_rtx to make a CONST_VECTOR. */
264 XEXP (dup, 0) = simplify_const_binary_operation (ASHIFTRT, QImode,
265 XEXP (dup, 0), const1_rtx);
266 const_vec = simplify_rtx (dup);
267
268 if (op_mode == V4SFmode)
269 {
270 op_mode = V4SImode;
271 operands[0] = gen_lowpart (op_mode, operands[0]);
272 }
273 if (GET_MODE (const_vec) == op_mode)
274 operands[3] = const_vec;
275 else
276 operands[3] = gen_lowpart (op_mode, const_vec);
277 operands[4] = gen_rtx_PLUS (op_mode, operands[0], operands[0]);
278 })
279
280 (define_insn "get_vrsave_internal"
281 [(set (match_operand:SI 0 "register_operand" "=r")
282 (unspec:SI [(reg:SI 109)] UNSPEC_GET_VRSAVE))]
283 "TARGET_ALTIVEC"
284 {
285 if (TARGET_MACHO)
286 return "mfspr %0,256";
287 else
288 return "mfvrsave %0";
289 }
290 [(set_attr "type" "*")])
291
292 (define_insn "*set_vrsave_internal"
293 [(match_parallel 0 "vrsave_operation"
294 [(set (reg:SI 109)
295 (unspec_volatile:SI [(match_operand:SI 1 "register_operand" "r")
296 (reg:SI 109)] UNSPECV_SET_VRSAVE))])]
297 "TARGET_ALTIVEC"
298 {
299 if (TARGET_MACHO)
300 return "mtspr 256,%1";
301 else
302 return "mtvrsave %1";
303 }
304 [(set_attr "type" "*")])
305
306 (define_insn "*save_world"
307 [(match_parallel 0 "save_world_operation"
308 [(clobber (reg:SI 65))
309 (use (match_operand:SI 1 "call_operand" "s"))])]
310 "TARGET_MACHO && (DEFAULT_ABI == ABI_DARWIN) && TARGET_32BIT"
311 "bl %z1"
312 [(set_attr "type" "branch")
313 (set_attr "length" "4")])
314
315 (define_insn "*restore_world"
316 [(match_parallel 0 "restore_world_operation"
317 [(return)
318 (use (reg:SI 65))
319 (use (match_operand:SI 1 "call_operand" "s"))
320 (clobber (match_operand:SI 2 "gpc_reg_operand" "=r"))])]
321 "TARGET_MACHO && (DEFAULT_ABI == ABI_DARWIN) && TARGET_32BIT"
322 "b %z1")
323
324 ;; The save_vregs and restore_vregs patterns don't use memory_operand
325 ;; because (plus (reg) (const_int)) is not a valid vector address.
326 ;; This way is more compact than describing exactly what happens in
327 ;; the out-of-line functions, ie. loading the constant into r11/r12
328 ;; then using indexed addressing, and requires less editing of rtl
329 ;; to describe the operation to dwarf2out_frame_debug_expr.
330 (define_insn "*save_vregs_<mode>_r11"
331 [(match_parallel 0 "any_parallel_operand"
332 [(clobber (reg:P 65))
333 (use (match_operand:P 1 "symbol_ref_operand" "s"))
334 (clobber (reg:P 11))
335 (use (reg:P 0))
336 (set (mem:V4SI (plus:P (match_operand:P 2 "gpc_reg_operand" "b")
337 (match_operand:P 3 "short_cint_operand" "I")))
338 (match_operand:V4SI 4 "gpc_reg_operand" "v"))])]
339 ""
340 "bl %1"
341 [(set_attr "type" "branch")
342 (set_attr "length" "4")])
343
344 (define_insn "*save_vregs_<mode>_r12"
345 [(match_parallel 0 "any_parallel_operand"
346 [(clobber (reg:P 65))
347 (use (match_operand:P 1 "symbol_ref_operand" "s"))
348 (clobber (reg:P 12))
349 (use (reg:P 0))
350 (set (mem:V4SI (plus:P (match_operand:P 2 "gpc_reg_operand" "b")
351 (match_operand:P 3 "short_cint_operand" "I")))
352 (match_operand:V4SI 4 "gpc_reg_operand" "v"))])]
353 ""
354 "bl %1"
355 [(set_attr "type" "branch")
356 (set_attr "length" "4")])
357
358 (define_insn "*restore_vregs_<mode>_r11"
359 [(match_parallel 0 "any_parallel_operand"
360 [(clobber (reg:P 65))
361 (use (match_operand:P 1 "symbol_ref_operand" "s"))
362 (clobber (reg:P 11))
363 (use (reg:P 0))
364 (set (match_operand:V4SI 2 "gpc_reg_operand" "=v")
365 (mem:V4SI (plus:P (match_operand:P 3 "gpc_reg_operand" "b")
366 (match_operand:P 4 "short_cint_operand" "I"))))])]
367 ""
368 "bl %1"
369 [(set_attr "type" "branch")
370 (set_attr "length" "4")])
371
372 (define_insn "*restore_vregs_<mode>_r12"
373 [(match_parallel 0 "any_parallel_operand"
374 [(clobber (reg:P 65))
375 (use (match_operand:P 1 "symbol_ref_operand" "s"))
376 (clobber (reg:P 12))
377 (use (reg:P 0))
378 (set (match_operand:V4SI 2 "gpc_reg_operand" "=v")
379 (mem:V4SI (plus:P (match_operand:P 3 "gpc_reg_operand" "b")
380 (match_operand:P 4 "short_cint_operand" "I"))))])]
381 ""
382 "bl %1"
383 [(set_attr "type" "branch")
384 (set_attr "length" "4")])
385
386 ;; Simple binary operations.
387
388 ;; add
389 (define_insn "add<mode>3"
390 [(set (match_operand:VI2 0 "register_operand" "=v")
391 (plus:VI2 (match_operand:VI2 1 "register_operand" "v")
392 (match_operand:VI2 2 "register_operand" "v")))]
393 "<VI_unit>"
394 "vaddu<VI_char>m %0,%1,%2"
395 [(set_attr "type" "vecsimple")])
396
397 (define_insn "*altivec_addv4sf3"
398 [(set (match_operand:V4SF 0 "register_operand" "=v")
399 (plus:V4SF (match_operand:V4SF 1 "register_operand" "v")
400 (match_operand:V4SF 2 "register_operand" "v")))]
401 "VECTOR_UNIT_ALTIVEC_P (V4SFmode)"
402 "vaddfp %0,%1,%2"
403 [(set_attr "type" "vecfloat")])
404
405 (define_insn "altivec_vaddcuw"
406 [(set (match_operand:V4SI 0 "register_operand" "=v")
407 (unspec:V4SI [(match_operand:V4SI 1 "register_operand" "v")
408 (match_operand:V4SI 2 "register_operand" "v")]
409 UNSPEC_VADDCUW))]
410 "VECTOR_UNIT_ALTIVEC_P (V4SImode)"
411 "vaddcuw %0,%1,%2"
412 [(set_attr "type" "vecsimple")])
413
414 (define_insn "altivec_vaddu<VI_char>s"
415 [(set (match_operand:VI 0 "register_operand" "=v")
416 (unspec:VI [(match_operand:VI 1 "register_operand" "v")
417 (match_operand:VI 2 "register_operand" "v")]
418 UNSPEC_VADDU))
419 (set (reg:SI 110) (unspec:SI [(const_int 0)] UNSPEC_SET_VSCR))]
420 "<VI_unit>"
421 "vaddu<VI_char>s %0,%1,%2"
422 [(set_attr "type" "vecsimple")])
423
424 (define_insn "altivec_vadds<VI_char>s"
425 [(set (match_operand:VI 0 "register_operand" "=v")
426 (unspec:VI [(match_operand:VI 1 "register_operand" "v")
427 (match_operand:VI 2 "register_operand" "v")]
428 UNSPEC_VADDS))
429 (set (reg:SI 110) (unspec:SI [(const_int 0)] UNSPEC_SET_VSCR))]
430 "VECTOR_UNIT_ALTIVEC_P (<MODE>mode)"
431 "vadds<VI_char>s %0,%1,%2"
432 [(set_attr "type" "vecsimple")])
433
434 ;; sub
435 (define_insn "sub<mode>3"
436 [(set (match_operand:VI2 0 "register_operand" "=v")
437 (minus:VI2 (match_operand:VI2 1 "register_operand" "v")
438 (match_operand:VI2 2 "register_operand" "v")))]
439 "<VI_unit>"
440 "vsubu<VI_char>m %0,%1,%2"
441 [(set_attr "type" "vecsimple")])
442
443 (define_insn "*altivec_subv4sf3"
444 [(set (match_operand:V4SF 0 "register_operand" "=v")
445 (minus:V4SF (match_operand:V4SF 1 "register_operand" "v")
446 (match_operand:V4SF 2 "register_operand" "v")))]
447 "VECTOR_UNIT_ALTIVEC_P (V4SFmode)"
448 "vsubfp %0,%1,%2"
449 [(set_attr "type" "vecfloat")])
450
451 (define_insn "altivec_vsubcuw"
452 [(set (match_operand:V4SI 0 "register_operand" "=v")
453 (unspec:V4SI [(match_operand:V4SI 1 "register_operand" "v")
454 (match_operand:V4SI 2 "register_operand" "v")]
455 UNSPEC_VSUBCUW))]
456 "VECTOR_UNIT_ALTIVEC_P (V4SImode)"
457 "vsubcuw %0,%1,%2"
458 [(set_attr "type" "vecsimple")])
459
460 (define_insn "altivec_vsubu<VI_char>s"
461 [(set (match_operand:VI 0 "register_operand" "=v")
462 (unspec:VI [(match_operand:VI 1 "register_operand" "v")
463 (match_operand:VI 2 "register_operand" "v")]
464 UNSPEC_VSUBU))
465 (set (reg:SI 110) (unspec:SI [(const_int 0)] UNSPEC_SET_VSCR))]
466 "VECTOR_UNIT_ALTIVEC_P (<MODE>mode)"
467 "vsubu<VI_char>s %0,%1,%2"
468 [(set_attr "type" "vecsimple")])
469
470 (define_insn "altivec_vsubs<VI_char>s"
471 [(set (match_operand:VI 0 "register_operand" "=v")
472 (unspec:VI [(match_operand:VI 1 "register_operand" "v")
473 (match_operand:VI 2 "register_operand" "v")]
474 UNSPEC_VSUBS))
475 (set (reg:SI 110) (unspec:SI [(const_int 0)] UNSPEC_SET_VSCR))]
476 "VECTOR_UNIT_ALTIVEC_P (<MODE>mode)"
477 "vsubs<VI_char>s %0,%1,%2"
478 [(set_attr "type" "vecsimple")])
479
480 ;;
481 (define_insn "altivec_vavgu<VI_char>"
482 [(set (match_operand:VI 0 "register_operand" "=v")
483 (unspec:VI [(match_operand:VI 1 "register_operand" "v")
484 (match_operand:VI 2 "register_operand" "v")]
485 UNSPEC_VAVGU))]
486 "TARGET_ALTIVEC"
487 "vavgu<VI_char> %0,%1,%2"
488 [(set_attr "type" "vecsimple")])
489
490 (define_insn "altivec_vavgs<VI_char>"
491 [(set (match_operand:VI 0 "register_operand" "=v")
492 (unspec:VI [(match_operand:VI 1 "register_operand" "v")
493 (match_operand:VI 2 "register_operand" "v")]
494 UNSPEC_VAVGS))]
495 "VECTOR_UNIT_ALTIVEC_P (<MODE>mode)"
496 "vavgs<VI_char> %0,%1,%2"
497 [(set_attr "type" "vecsimple")])
498
499 (define_insn "altivec_vcmpbfp"
500 [(set (match_operand:V4SI 0 "register_operand" "=v")
501 (unspec:V4SI [(match_operand:V4SF 1 "register_operand" "v")
502 (match_operand:V4SF 2 "register_operand" "v")]
503 UNSPEC_VCMPBFP))]
504 "VECTOR_UNIT_ALTIVEC_P (V4SImode)"
505 "vcmpbfp %0,%1,%2"
506 [(set_attr "type" "veccmp")])
507
508 (define_insn "*altivec_eq<mode>"
509 [(set (match_operand:VI2 0 "altivec_register_operand" "=v")
510 (eq:VI2 (match_operand:VI2 1 "altivec_register_operand" "v")
511 (match_operand:VI2 2 "altivec_register_operand" "v")))]
512 "<VI_unit>"
513 "vcmpequ<VI_char> %0,%1,%2"
514 [(set_attr "type" "veccmp")])
515
516 (define_insn "*altivec_gt<mode>"
517 [(set (match_operand:VI2 0 "altivec_register_operand" "=v")
518 (gt:VI2 (match_operand:VI2 1 "altivec_register_operand" "v")
519 (match_operand:VI2 2 "altivec_register_operand" "v")))]
520 "<VI_unit>"
521 "vcmpgts<VI_char> %0,%1,%2"
522 [(set_attr "type" "veccmp")])
523
524 (define_insn "*altivec_gtu<mode>"
525 [(set (match_operand:VI2 0 "altivec_register_operand" "=v")
526 (gtu:VI2 (match_operand:VI2 1 "altivec_register_operand" "v")
527 (match_operand:VI2 2 "altivec_register_operand" "v")))]
528 "<VI_unit>"
529 "vcmpgtu<VI_char> %0,%1,%2"
530 [(set_attr "type" "veccmp")])
531
532 (define_insn "*altivec_eqv4sf"
533 [(set (match_operand:V4SF 0 "altivec_register_operand" "=v")
534 (eq:V4SF (match_operand:V4SF 1 "altivec_register_operand" "v")
535 (match_operand:V4SF 2 "altivec_register_operand" "v")))]
536 "VECTOR_UNIT_ALTIVEC_P (V4SFmode)"
537 "vcmpeqfp %0,%1,%2"
538 [(set_attr "type" "veccmp")])
539
540 (define_insn "*altivec_gtv4sf"
541 [(set (match_operand:V4SF 0 "altivec_register_operand" "=v")
542 (gt:V4SF (match_operand:V4SF 1 "altivec_register_operand" "v")
543 (match_operand:V4SF 2 "altivec_register_operand" "v")))]
544 "VECTOR_UNIT_ALTIVEC_P (V4SFmode)"
545 "vcmpgtfp %0,%1,%2"
546 [(set_attr "type" "veccmp")])
547
548 (define_insn "*altivec_gev4sf"
549 [(set (match_operand:V4SF 0 "altivec_register_operand" "=v")
550 (ge:V4SF (match_operand:V4SF 1 "altivec_register_operand" "v")
551 (match_operand:V4SF 2 "altivec_register_operand" "v")))]
552 "VECTOR_UNIT_ALTIVEC_P (V4SFmode)"
553 "vcmpgefp %0,%1,%2"
554 [(set_attr "type" "veccmp")])
555
556 (define_insn "*altivec_vsel<mode>"
557 [(set (match_operand:VM 0 "altivec_register_operand" "=v")
558 (if_then_else:VM
559 (ne:CC (match_operand:VM 1 "altivec_register_operand" "v")
560 (match_operand:VM 4 "zero_constant" ""))
561 (match_operand:VM 2 "altivec_register_operand" "v")
562 (match_operand:VM 3 "altivec_register_operand" "v")))]
563 "VECTOR_MEM_ALTIVEC_P (<MODE>mode)"
564 "vsel %0,%3,%2,%1"
565 [(set_attr "type" "vecperm")])
566
567 (define_insn "*altivec_vsel<mode>_uns"
568 [(set (match_operand:VM 0 "altivec_register_operand" "=v")
569 (if_then_else:VM
570 (ne:CCUNS (match_operand:VM 1 "altivec_register_operand" "v")
571 (match_operand:VM 4 "zero_constant" ""))
572 (match_operand:VM 2 "altivec_register_operand" "v")
573 (match_operand:VM 3 "altivec_register_operand" "v")))]
574 "VECTOR_MEM_ALTIVEC_P (<MODE>mode)"
575 "vsel %0,%3,%2,%1"
576 [(set_attr "type" "vecperm")])
577
578 ;; Fused multiply add.
579
580 (define_insn "*altivec_fmav4sf4"
581 [(set (match_operand:V4SF 0 "register_operand" "=v")
582 (fma:V4SF (match_operand:V4SF 1 "register_operand" "v")
583 (match_operand:V4SF 2 "register_operand" "v")
584 (match_operand:V4SF 3 "register_operand" "v")))]
585 "VECTOR_UNIT_ALTIVEC_P (V4SFmode)"
586 "vmaddfp %0,%1,%2,%3"
587 [(set_attr "type" "vecfloat")])
588
589 ;; We do multiply as a fused multiply-add with an add of a -0.0 vector.
590
591 (define_expand "altivec_mulv4sf3"
592 [(set (match_operand:V4SF 0 "register_operand" "")
593 (fma:V4SF (match_operand:V4SF 1 "register_operand" "")
594 (match_operand:V4SF 2 "register_operand" "")
595 (match_dup 3)))]
596 "VECTOR_UNIT_ALTIVEC_P (V4SFmode)"
597 {
598 rtx neg0;
599
600 /* Generate [-0.0, -0.0, -0.0, -0.0]. */
601 neg0 = gen_reg_rtx (V4SImode);
602 emit_insn (gen_altivec_vspltisw (neg0, constm1_rtx));
603 emit_insn (gen_vashlv4si3 (neg0, neg0, neg0));
604
605 operands[3] = gen_lowpart (V4SFmode, neg0);
606 })
607
608 ;; 32-bit integer multiplication
609 ;; A_high = Operand_0 & 0xFFFF0000 >> 16
610 ;; A_low = Operand_0 & 0xFFFF
611 ;; B_high = Operand_1 & 0xFFFF0000 >> 16
612 ;; B_low = Operand_1 & 0xFFFF
613 ;; result = A_low * B_low + (A_high * B_low + B_high * A_low) << 16
614
615 ;; (define_insn "mulv4si3"
616 ;; [(set (match_operand:V4SI 0 "register_operand" "=v")
617 ;; (mult:V4SI (match_operand:V4SI 1 "register_operand" "v")
618 ;; (match_operand:V4SI 2 "register_operand" "v")))]
619 (define_expand "mulv4si3"
620 [(use (match_operand:V4SI 0 "register_operand" ""))
621 (use (match_operand:V4SI 1 "register_operand" ""))
622 (use (match_operand:V4SI 2 "register_operand" ""))]
623 "TARGET_ALTIVEC"
624 "
625 {
626 rtx zero;
627 rtx swap;
628 rtx small_swap;
629 rtx sixteen;
630 rtx one;
631 rtx two;
632 rtx low_product;
633 rtx high_product;
634
635 zero = gen_reg_rtx (V4SImode);
636 emit_insn (gen_altivec_vspltisw (zero, const0_rtx));
637
638 sixteen = gen_reg_rtx (V4SImode);
639 emit_insn (gen_altivec_vspltisw (sixteen, gen_rtx_CONST_INT (V4SImode, -16)));
640
641 swap = gen_reg_rtx (V4SImode);
642 emit_insn (gen_vrotlv4si3 (swap, operands[2], sixteen));
643
644 one = gen_reg_rtx (V8HImode);
645 convert_move (one, operands[1], 0);
646
647 two = gen_reg_rtx (V8HImode);
648 convert_move (two, operands[2], 0);
649
650 small_swap = gen_reg_rtx (V8HImode);
651 convert_move (small_swap, swap, 0);
652
653 low_product = gen_reg_rtx (V4SImode);
654 emit_insn (gen_vec_widen_umult_odd_v8hi (low_product, one, two));
655
656 high_product = gen_reg_rtx (V4SImode);
657 emit_insn (gen_altivec_vmsumuhm (high_product, one, small_swap, zero));
658
659 emit_insn (gen_vashlv4si3 (high_product, high_product, sixteen));
660
661 emit_insn (gen_addv4si3 (operands[0], high_product, low_product));
662
663 DONE;
664 }")
665
666 (define_expand "mulv8hi3"
667 [(use (match_operand:V8HI 0 "register_operand" ""))
668 (use (match_operand:V8HI 1 "register_operand" ""))
669 (use (match_operand:V8HI 2 "register_operand" ""))]
670 "TARGET_ALTIVEC"
671 "
672 {
673 rtx odd = gen_reg_rtx (V4SImode);
674 rtx even = gen_reg_rtx (V4SImode);
675 rtx high = gen_reg_rtx (V4SImode);
676 rtx low = gen_reg_rtx (V4SImode);
677
678 emit_insn (gen_vec_widen_smult_even_v8hi (even, operands[1], operands[2]));
679 emit_insn (gen_vec_widen_smult_odd_v8hi (odd, operands[1], operands[2]));
680
681 emit_insn (gen_altivec_vmrghw (high, even, odd));
682 emit_insn (gen_altivec_vmrglw (low, even, odd));
683
684 emit_insn (gen_altivec_vpkuwum (operands[0], high, low));
685
686 DONE;
687 }")
688
689 ;; Fused multiply subtract
690 (define_insn "*altivec_vnmsubfp"
691 [(set (match_operand:V4SF 0 "register_operand" "=v")
692 (neg:V4SF
693 (fma:V4SF (match_operand:V4SF 1 "register_operand" "v")
694 (match_operand:V4SF 2 "register_operand" "v")
695 (neg:V4SF
696 (match_operand:V4SF 3 "register_operand" "v")))))]
697 "VECTOR_UNIT_ALTIVEC_P (V4SFmode)"
698 "vnmsubfp %0,%1,%2,%3"
699 [(set_attr "type" "vecfloat")])
700
701 (define_insn "altivec_vmsumu<VI_char>m"
702 [(set (match_operand:V4SI 0 "register_operand" "=v")
703 (unspec:V4SI [(match_operand:VIshort 1 "register_operand" "v")
704 (match_operand:VIshort 2 "register_operand" "v")
705 (match_operand:V4SI 3 "register_operand" "v")]
706 UNSPEC_VMSUMU))]
707 "TARGET_ALTIVEC"
708 "vmsumu<VI_char>m %0,%1,%2,%3"
709 [(set_attr "type" "veccomplex")])
710
711 (define_insn "altivec_vmsumm<VI_char>m"
712 [(set (match_operand:V4SI 0 "register_operand" "=v")
713 (unspec:V4SI [(match_operand:VIshort 1 "register_operand" "v")
714 (match_operand:VIshort 2 "register_operand" "v")
715 (match_operand:V4SI 3 "register_operand" "v")]
716 UNSPEC_VMSUMM))]
717 "TARGET_ALTIVEC"
718 "vmsumm<VI_char>m %0,%1,%2,%3"
719 [(set_attr "type" "veccomplex")])
720
721 (define_insn "altivec_vmsumshm"
722 [(set (match_operand:V4SI 0 "register_operand" "=v")
723 (unspec:V4SI [(match_operand:V8HI 1 "register_operand" "v")
724 (match_operand:V8HI 2 "register_operand" "v")
725 (match_operand:V4SI 3 "register_operand" "v")]
726 UNSPEC_VMSUMSHM))]
727 "TARGET_ALTIVEC"
728 "vmsumshm %0,%1,%2,%3"
729 [(set_attr "type" "veccomplex")])
730
731 (define_insn "altivec_vmsumuhs"
732 [(set (match_operand:V4SI 0 "register_operand" "=v")
733 (unspec:V4SI [(match_operand:V8HI 1 "register_operand" "v")
734 (match_operand:V8HI 2 "register_operand" "v")
735 (match_operand:V4SI 3 "register_operand" "v")]
736 UNSPEC_VMSUMUHS))
737 (set (reg:SI 110) (unspec:SI [(const_int 0)] UNSPEC_SET_VSCR))]
738 "TARGET_ALTIVEC"
739 "vmsumuhs %0,%1,%2,%3"
740 [(set_attr "type" "veccomplex")])
741
742 (define_insn "altivec_vmsumshs"
743 [(set (match_operand:V4SI 0 "register_operand" "=v")
744 (unspec:V4SI [(match_operand:V8HI 1 "register_operand" "v")
745 (match_operand:V8HI 2 "register_operand" "v")
746 (match_operand:V4SI 3 "register_operand" "v")]
747 UNSPEC_VMSUMSHS))
748 (set (reg:SI 110) (unspec:SI [(const_int 0)] UNSPEC_SET_VSCR))]
749 "TARGET_ALTIVEC"
750 "vmsumshs %0,%1,%2,%3"
751 [(set_attr "type" "veccomplex")])
752
753 ;; max
754
755 (define_insn "umax<mode>3"
756 [(set (match_operand:VI2 0 "register_operand" "=v")
757 (umax:VI2 (match_operand:VI2 1 "register_operand" "v")
758 (match_operand:VI2 2 "register_operand" "v")))]
759 "<VI_unit>"
760 "vmaxu<VI_char> %0,%1,%2"
761 [(set_attr "type" "vecsimple")])
762
763 (define_insn "smax<mode>3"
764 [(set (match_operand:VI2 0 "register_operand" "=v")
765 (smax:VI2 (match_operand:VI2 1 "register_operand" "v")
766 (match_operand:VI2 2 "register_operand" "v")))]
767 "<VI_unit>"
768 "vmaxs<VI_char> %0,%1,%2"
769 [(set_attr "type" "vecsimple")])
770
771 (define_insn "*altivec_smaxv4sf3"
772 [(set (match_operand:V4SF 0 "register_operand" "=v")
773 (smax:V4SF (match_operand:V4SF 1 "register_operand" "v")
774 (match_operand:V4SF 2 "register_operand" "v")))]
775 "VECTOR_UNIT_ALTIVEC_P (V4SFmode)"
776 "vmaxfp %0,%1,%2"
777 [(set_attr "type" "veccmp")])
778
779 (define_insn "umin<mode>3"
780 [(set (match_operand:VI2 0 "register_operand" "=v")
781 (umin:VI2 (match_operand:VI2 1 "register_operand" "v")
782 (match_operand:VI2 2 "register_operand" "v")))]
783 "<VI_unit>"
784 "vminu<VI_char> %0,%1,%2"
785 [(set_attr "type" "vecsimple")])
786
787 (define_insn "smin<mode>3"
788 [(set (match_operand:VI2 0 "register_operand" "=v")
789 (smin:VI2 (match_operand:VI2 1 "register_operand" "v")
790 (match_operand:VI2 2 "register_operand" "v")))]
791 "<VI_unit>"
792 "vmins<VI_char> %0,%1,%2"
793 [(set_attr "type" "vecsimple")])
794
795 (define_insn "*altivec_sminv4sf3"
796 [(set (match_operand:V4SF 0 "register_operand" "=v")
797 (smin:V4SF (match_operand:V4SF 1 "register_operand" "v")
798 (match_operand:V4SF 2 "register_operand" "v")))]
799 "VECTOR_UNIT_ALTIVEC_P (V4SFmode)"
800 "vminfp %0,%1,%2"
801 [(set_attr "type" "veccmp")])
802
803 (define_insn "altivec_vmhaddshs"
804 [(set (match_operand:V8HI 0 "register_operand" "=v")
805 (unspec:V8HI [(match_operand:V8HI 1 "register_operand" "v")
806 (match_operand:V8HI 2 "register_operand" "v")
807 (match_operand:V8HI 3 "register_operand" "v")]
808 UNSPEC_VMHADDSHS))
809 (set (reg:SI 110) (unspec:SI [(const_int 0)] UNSPEC_SET_VSCR))]
810 "TARGET_ALTIVEC"
811 "vmhaddshs %0,%1,%2,%3"
812 [(set_attr "type" "veccomplex")])
813
814 (define_insn "altivec_vmhraddshs"
815 [(set (match_operand:V8HI 0 "register_operand" "=v")
816 (unspec:V8HI [(match_operand:V8HI 1 "register_operand" "v")
817 (match_operand:V8HI 2 "register_operand" "v")
818 (match_operand:V8HI 3 "register_operand" "v")]
819 UNSPEC_VMHRADDSHS))
820 (set (reg:SI 110) (unspec:SI [(const_int 0)] UNSPEC_SET_VSCR))]
821 "TARGET_ALTIVEC"
822 "vmhraddshs %0,%1,%2,%3"
823 [(set_attr "type" "veccomplex")])
824
825 (define_insn "altivec_vmladduhm"
826 [(set (match_operand:V8HI 0 "register_operand" "=v")
827 (unspec:V8HI [(match_operand:V8HI 1 "register_operand" "v")
828 (match_operand:V8HI 2 "register_operand" "v")
829 (match_operand:V8HI 3 "register_operand" "v")]
830 UNSPEC_VMLADDUHM))]
831 "TARGET_ALTIVEC"
832 "vmladduhm %0,%1,%2,%3"
833 [(set_attr "type" "veccomplex")])
834
835 (define_insn "altivec_vmrghb"
836 [(set (match_operand:V16QI 0 "register_operand" "=v")
837 (vec_select:V16QI
838 (vec_concat:V32QI
839 (match_operand:V16QI 1 "register_operand" "v")
840 (match_operand:V16QI 2 "register_operand" "v"))
841 (parallel [(const_int 0) (const_int 16)
842 (const_int 1) (const_int 17)
843 (const_int 2) (const_int 18)
844 (const_int 3) (const_int 19)
845 (const_int 4) (const_int 20)
846 (const_int 5) (const_int 21)
847 (const_int 6) (const_int 22)
848 (const_int 7) (const_int 23)])))]
849 "TARGET_ALTIVEC"
850 "vmrghb %0,%1,%2"
851 [(set_attr "type" "vecperm")])
852
853 (define_insn "altivec_vmrghh"
854 [(set (match_operand:V8HI 0 "register_operand" "=v")
855 (vec_select:V8HI
856 (vec_concat:V16HI
857 (match_operand:V8HI 1 "register_operand" "v")
858 (match_operand:V8HI 2 "register_operand" "v"))
859 (parallel [(const_int 0) (const_int 8)
860 (const_int 1) (const_int 9)
861 (const_int 2) (const_int 10)
862 (const_int 3) (const_int 11)])))]
863 "TARGET_ALTIVEC"
864 "vmrghh %0,%1,%2"
865 [(set_attr "type" "vecperm")])
866
867 (define_insn "altivec_vmrghw"
868 [(set (match_operand:V4SI 0 "register_operand" "=v")
869 (vec_select:V4SI
870 (vec_concat:V8SI
871 (match_operand:V4SI 1 "register_operand" "v")
872 (match_operand:V4SI 2 "register_operand" "v"))
873 (parallel [(const_int 0) (const_int 4)
874 (const_int 1) (const_int 5)])))]
875 "VECTOR_MEM_ALTIVEC_P (V4SImode)"
876 "vmrghw %0,%1,%2"
877 [(set_attr "type" "vecperm")])
878
879 (define_insn "*altivec_vmrghsf"
880 [(set (match_operand:V4SF 0 "register_operand" "=v")
881 (vec_select:V4SF
882 (vec_concat:V8SF
883 (match_operand:V4SF 1 "register_operand" "v")
884 (match_operand:V4SF 2 "register_operand" "v"))
885 (parallel [(const_int 0) (const_int 4)
886 (const_int 1) (const_int 5)])))]
887 "VECTOR_MEM_ALTIVEC_P (V4SFmode)"
888 "vmrghw %0,%1,%2"
889 [(set_attr "type" "vecperm")])
890
891 (define_insn "altivec_vmrglb"
892 [(set (match_operand:V16QI 0 "register_operand" "=v")
893 (vec_select:V16QI
894 (vec_concat:V32QI
895 (match_operand:V16QI 1 "register_operand" "v")
896 (match_operand:V16QI 2 "register_operand" "v"))
897 (parallel [(const_int 8) (const_int 24)
898 (const_int 9) (const_int 25)
899 (const_int 10) (const_int 26)
900 (const_int 11) (const_int 27)
901 (const_int 12) (const_int 28)
902 (const_int 13) (const_int 29)
903 (const_int 14) (const_int 30)
904 (const_int 15) (const_int 31)])))]
905 "TARGET_ALTIVEC"
906 "vmrglb %0,%1,%2"
907 [(set_attr "type" "vecperm")])
908
909 (define_insn "altivec_vmrglh"
910 [(set (match_operand:V8HI 0 "register_operand" "=v")
911 (vec_select:V8HI
912 (vec_concat:V16HI
913 (match_operand:V8HI 1 "register_operand" "v")
914 (match_operand:V8HI 2 "register_operand" "v"))
915 (parallel [(const_int 4) (const_int 12)
916 (const_int 5) (const_int 13)
917 (const_int 6) (const_int 14)
918 (const_int 7) (const_int 15)])))]
919 "TARGET_ALTIVEC"
920 "vmrglh %0,%1,%2"
921 [(set_attr "type" "vecperm")])
922
923 (define_insn "altivec_vmrglw"
924 [(set (match_operand:V4SI 0 "register_operand" "=v")
925 (vec_select:V4SI
926 (vec_concat:V8SI
927 (match_operand:V4SI 1 "register_operand" "v")
928 (match_operand:V4SI 2 "register_operand" "v"))
929 (parallel [(const_int 2) (const_int 6)
930 (const_int 3) (const_int 7)])))]
931 "VECTOR_MEM_ALTIVEC_P (V4SImode)"
932 "vmrglw %0,%1,%2"
933 [(set_attr "type" "vecperm")])
934
935 (define_insn "*altivec_vmrglsf"
936 [(set (match_operand:V4SF 0 "register_operand" "=v")
937 (vec_select:V4SF
938 (vec_concat:V8SF
939 (match_operand:V4SF 1 "register_operand" "v")
940 (match_operand:V4SF 2 "register_operand" "v"))
941 (parallel [(const_int 2) (const_int 6)
942 (const_int 3) (const_int 7)])))]
943 "VECTOR_MEM_ALTIVEC_P (V4SFmode)"
944 "vmrglw %0,%1,%2"
945 [(set_attr "type" "vecperm")])
946
947 ;; Power8 vector merge even/odd
948 (define_insn "p8_vmrgew"
949 [(set (match_operand:V4SI 0 "register_operand" "=v")
950 (vec_select:V4SI
951 (vec_concat:V8SI
952 (match_operand:V4SI 1 "register_operand" "v")
953 (match_operand:V4SI 2 "register_operand" "v"))
954 (parallel [(const_int 0) (const_int 4)
955 (const_int 2) (const_int 6)])))]
956 "TARGET_P8_VECTOR"
957 "vmrgew %0,%1,%2"
958 [(set_attr "type" "vecperm")])
959
960 (define_insn "p8_vmrgow"
961 [(set (match_operand:V4SI 0 "register_operand" "=v")
962 (vec_select:V4SI
963 (vec_concat:V8SI
964 (match_operand:V4SI 1 "register_operand" "v")
965 (match_operand:V4SI 2 "register_operand" "v"))
966 (parallel [(const_int 1) (const_int 5)
967 (const_int 3) (const_int 7)])))]
968 "TARGET_P8_VECTOR"
969 "vmrgow %0,%1,%2"
970 [(set_attr "type" "vecperm")])
971
972 (define_insn "vec_widen_umult_even_v16qi"
973 [(set (match_operand:V8HI 0 "register_operand" "=v")
974 (unspec:V8HI [(match_operand:V16QI 1 "register_operand" "v")
975 (match_operand:V16QI 2 "register_operand" "v")]
976 UNSPEC_VMULEUB))]
977 "TARGET_ALTIVEC"
978 "vmuleub %0,%1,%2"
979 [(set_attr "type" "veccomplex")])
980
981 (define_insn "vec_widen_smult_even_v16qi"
982 [(set (match_operand:V8HI 0 "register_operand" "=v")
983 (unspec:V8HI [(match_operand:V16QI 1 "register_operand" "v")
984 (match_operand:V16QI 2 "register_operand" "v")]
985 UNSPEC_VMULESB))]
986 "TARGET_ALTIVEC"
987 "vmulesb %0,%1,%2"
988 [(set_attr "type" "veccomplex")])
989
990 (define_insn "vec_widen_umult_even_v8hi"
991 [(set (match_operand:V4SI 0 "register_operand" "=v")
992 (unspec:V4SI [(match_operand:V8HI 1 "register_operand" "v")
993 (match_operand:V8HI 2 "register_operand" "v")]
994 UNSPEC_VMULEUH))]
995 "TARGET_ALTIVEC"
996 "vmuleuh %0,%1,%2"
997 [(set_attr "type" "veccomplex")])
998
999 (define_insn "vec_widen_smult_even_v8hi"
1000 [(set (match_operand:V4SI 0 "register_operand" "=v")
1001 (unspec:V4SI [(match_operand:V8HI 1 "register_operand" "v")
1002 (match_operand:V8HI 2 "register_operand" "v")]
1003 UNSPEC_VMULESH))]
1004 "TARGET_ALTIVEC"
1005 "vmulesh %0,%1,%2"
1006 [(set_attr "type" "veccomplex")])
1007
1008 (define_insn "vec_widen_umult_odd_v16qi"
1009 [(set (match_operand:V8HI 0 "register_operand" "=v")
1010 (unspec:V8HI [(match_operand:V16QI 1 "register_operand" "v")
1011 (match_operand:V16QI 2 "register_operand" "v")]
1012 UNSPEC_VMULOUB))]
1013 "TARGET_ALTIVEC"
1014 "vmuloub %0,%1,%2"
1015 [(set_attr "type" "veccomplex")])
1016
1017 (define_insn "vec_widen_smult_odd_v16qi"
1018 [(set (match_operand:V8HI 0 "register_operand" "=v")
1019 (unspec:V8HI [(match_operand:V16QI 1 "register_operand" "v")
1020 (match_operand:V16QI 2 "register_operand" "v")]
1021 UNSPEC_VMULOSB))]
1022 "TARGET_ALTIVEC"
1023 "vmulosb %0,%1,%2"
1024 [(set_attr "type" "veccomplex")])
1025
1026 (define_insn "vec_widen_umult_odd_v8hi"
1027 [(set (match_operand:V4SI 0 "register_operand" "=v")
1028 (unspec:V4SI [(match_operand:V8HI 1 "register_operand" "v")
1029 (match_operand:V8HI 2 "register_operand" "v")]
1030 UNSPEC_VMULOUH))]
1031 "TARGET_ALTIVEC"
1032 "vmulouh %0,%1,%2"
1033 [(set_attr "type" "veccomplex")])
1034
1035 (define_insn "vec_widen_smult_odd_v8hi"
1036 [(set (match_operand:V4SI 0 "register_operand" "=v")
1037 (unspec:V4SI [(match_operand:V8HI 1 "register_operand" "v")
1038 (match_operand:V8HI 2 "register_operand" "v")]
1039 UNSPEC_VMULOSH))]
1040 "TARGET_ALTIVEC"
1041 "vmulosh %0,%1,%2"
1042 [(set_attr "type" "veccomplex")])
1043
1044
1045 ;; Vector pack/unpack
1046 (define_insn "altivec_vpkpx"
1047 [(set (match_operand:V8HI 0 "register_operand" "=v")
1048 (unspec:V8HI [(match_operand:V4SI 1 "register_operand" "v")
1049 (match_operand:V4SI 2 "register_operand" "v")]
1050 UNSPEC_VPKPX))]
1051 "TARGET_ALTIVEC"
1052 "*
1053 {
1054 if (BYTES_BIG_ENDIAN)
1055 return \"vpkpx %0,%1,%2\";
1056 else
1057 return \"vpkpx %0,%2,%1\";
1058 }"
1059 [(set_attr "type" "vecperm")])
1060
1061 (define_insn "altivec_vpks<VI_char>ss"
1062 [(set (match_operand:<VP_small> 0 "register_operand" "=v")
1063 (unspec:<VP_small> [(match_operand:VP 1 "register_operand" "v")
1064 (match_operand:VP 2 "register_operand" "v")]
1065 UNSPEC_VPACK_SIGN_SIGN_SAT))]
1066 "<VI_unit>"
1067 "*
1068 {
1069 if (BYTES_BIG_ENDIAN)
1070 return \"vpks<VI_char>ss %0,%1,%2\";
1071 else
1072 return \"vpks<VI_char>ss %0,%2,%1\";
1073 }"
1074 [(set_attr "type" "vecperm")])
1075
1076 (define_insn "altivec_vpks<VI_char>us"
1077 [(set (match_operand:<VP_small> 0 "register_operand" "=v")
1078 (unspec:<VP_small> [(match_operand:VP 1 "register_operand" "v")
1079 (match_operand:VP 2 "register_operand" "v")]
1080 UNSPEC_VPACK_SIGN_UNS_SAT))]
1081 "<VI_unit>"
1082 "*
1083 {
1084 if (BYTES_BIG_ENDIAN)
1085 return \"vpks<VI_char>us %0,%1,%2\";
1086 else
1087 return \"vpks<VI_char>us %0,%2,%1\";
1088 }"
1089 [(set_attr "type" "vecperm")])
1090
1091 (define_insn "altivec_vpku<VI_char>us"
1092 [(set (match_operand:<VP_small> 0 "register_operand" "=v")
1093 (unspec:<VP_small> [(match_operand:VP 1 "register_operand" "v")
1094 (match_operand:VP 2 "register_operand" "v")]
1095 UNSPEC_VPACK_UNS_UNS_SAT))]
1096 "<VI_unit>"
1097 "*
1098 {
1099 if (BYTES_BIG_ENDIAN)
1100 return \"vpku<VI_char>us %0,%1,%2\";
1101 else
1102 return \"vpku<VI_char>us %0,%2,%1\";
1103 }"
1104 [(set_attr "type" "vecperm")])
1105
1106 (define_insn "altivec_vpku<VI_char>um"
1107 [(set (match_operand:<VP_small> 0 "register_operand" "=v")
1108 (unspec:<VP_small> [(match_operand:VP 1 "register_operand" "v")
1109 (match_operand:VP 2 "register_operand" "v")]
1110 UNSPEC_VPACK_UNS_UNS_MOD))]
1111 "<VI_unit>"
1112 "*
1113 {
1114 if (BYTES_BIG_ENDIAN)
1115 return \"vpku<VI_char>um %0,%1,%2\";
1116 else
1117 return \"vpku<VI_char>um %0,%2,%1\";
1118 }"
1119 [(set_attr "type" "vecperm")])
1120
1121 (define_insn "*altivec_vrl<VI_char>"
1122 [(set (match_operand:VI2 0 "register_operand" "=v")
1123 (rotate:VI2 (match_operand:VI2 1 "register_operand" "v")
1124 (match_operand:VI2 2 "register_operand" "v")))]
1125 "<VI_unit>"
1126 "vrl<VI_char> %0,%1,%2"
1127 [(set_attr "type" "vecsimple")])
1128
1129 (define_insn "altivec_vsl"
1130 [(set (match_operand:V4SI 0 "register_operand" "=v")
1131 (unspec:V4SI [(match_operand:V4SI 1 "register_operand" "v")
1132 (match_operand:V4SI 2 "register_operand" "v")]
1133 UNSPEC_VSLV4SI))]
1134 "TARGET_ALTIVEC"
1135 "vsl %0,%1,%2"
1136 [(set_attr "type" "vecperm")])
1137
1138 (define_insn "altivec_vslo"
1139 [(set (match_operand:V4SI 0 "register_operand" "=v")
1140 (unspec:V4SI [(match_operand:V4SI 1 "register_operand" "v")
1141 (match_operand:V4SI 2 "register_operand" "v")]
1142 UNSPEC_VSLO))]
1143 "TARGET_ALTIVEC"
1144 "vslo %0,%1,%2"
1145 [(set_attr "type" "vecperm")])
1146
1147 (define_insn "*altivec_vsl<VI_char>"
1148 [(set (match_operand:VI2 0 "register_operand" "=v")
1149 (ashift:VI2 (match_operand:VI2 1 "register_operand" "v")
1150 (match_operand:VI2 2 "register_operand" "v")))]
1151 "<VI_unit>"
1152 "vsl<VI_char> %0,%1,%2"
1153 [(set_attr "type" "vecsimple")])
1154
1155 (define_insn "*altivec_vsr<VI_char>"
1156 [(set (match_operand:VI2 0 "register_operand" "=v")
1157 (lshiftrt:VI2 (match_operand:VI2 1 "register_operand" "v")
1158 (match_operand:VI2 2 "register_operand" "v")))]
1159 "<VI_unit>"
1160 "vsr<VI_char> %0,%1,%2"
1161 [(set_attr "type" "vecsimple")])
1162
1163 (define_insn "*altivec_vsra<VI_char>"
1164 [(set (match_operand:VI2 0 "register_operand" "=v")
1165 (ashiftrt:VI2 (match_operand:VI2 1 "register_operand" "v")
1166 (match_operand:VI2 2 "register_operand" "v")))]
1167 "<VI_unit>"
1168 "vsra<VI_char> %0,%1,%2"
1169 [(set_attr "type" "vecsimple")])
1170
1171 (define_insn "altivec_vsr"
1172 [(set (match_operand:V4SI 0 "register_operand" "=v")
1173 (unspec:V4SI [(match_operand:V4SI 1 "register_operand" "v")
1174 (match_operand:V4SI 2 "register_operand" "v")]
1175 UNSPEC_VSR))]
1176 "TARGET_ALTIVEC"
1177 "vsr %0,%1,%2"
1178 [(set_attr "type" "vecperm")])
1179
1180 (define_insn "altivec_vsro"
1181 [(set (match_operand:V4SI 0 "register_operand" "=v")
1182 (unspec:V4SI [(match_operand:V4SI 1 "register_operand" "v")
1183 (match_operand:V4SI 2 "register_operand" "v")]
1184 UNSPEC_VSRO))]
1185 "TARGET_ALTIVEC"
1186 "vsro %0,%1,%2"
1187 [(set_attr "type" "vecperm")])
1188
1189 (define_insn "altivec_vsum4ubs"
1190 [(set (match_operand:V4SI 0 "register_operand" "=v")
1191 (unspec:V4SI [(match_operand:V16QI 1 "register_operand" "v")
1192 (match_operand:V4SI 2 "register_operand" "v")]
1193 UNSPEC_VSUM4UBS))
1194 (set (reg:SI 110) (unspec:SI [(const_int 0)] UNSPEC_SET_VSCR))]
1195 "TARGET_ALTIVEC"
1196 "vsum4ubs %0,%1,%2"
1197 [(set_attr "type" "veccomplex")])
1198
1199 (define_insn "altivec_vsum4s<VI_char>s"
1200 [(set (match_operand:V4SI 0 "register_operand" "=v")
1201 (unspec:V4SI [(match_operand:VIshort 1 "register_operand" "v")
1202 (match_operand:V4SI 2 "register_operand" "v")]
1203 UNSPEC_VSUM4S))
1204 (set (reg:SI 110) (unspec:SI [(const_int 0)] UNSPEC_SET_VSCR))]
1205 "TARGET_ALTIVEC"
1206 "vsum4s<VI_char>s %0,%1,%2"
1207 [(set_attr "type" "veccomplex")])
1208
1209 (define_insn "altivec_vsum2sws"
1210 [(set (match_operand:V4SI 0 "register_operand" "=v")
1211 (unspec:V4SI [(match_operand:V4SI 1 "register_operand" "v")
1212 (match_operand:V4SI 2 "register_operand" "v")]
1213 UNSPEC_VSUM2SWS))
1214 (set (reg:SI 110) (unspec:SI [(const_int 0)] UNSPEC_SET_VSCR))]
1215 "TARGET_ALTIVEC"
1216 "vsum2sws %0,%1,%2"
1217 [(set_attr "type" "veccomplex")])
1218
1219 (define_insn "altivec_vsumsws"
1220 [(set (match_operand:V4SI 0 "register_operand" "=v")
1221 (unspec:V4SI [(match_operand:V4SI 1 "register_operand" "v")
1222 (match_operand:V4SI 2 "register_operand" "v")]
1223 UNSPEC_VSUMSWS))
1224 (set (reg:SI 110) (unspec:SI [(const_int 0)] UNSPEC_SET_VSCR))]
1225 "TARGET_ALTIVEC"
1226 "vsumsws %0,%1,%2"
1227 [(set_attr "type" "veccomplex")])
1228
1229 (define_insn "altivec_vspltb"
1230 [(set (match_operand:V16QI 0 "register_operand" "=v")
1231 (vec_duplicate:V16QI
1232 (vec_select:QI (match_operand:V16QI 1 "register_operand" "v")
1233 (parallel
1234 [(match_operand:QI 2 "u5bit_cint_operand" "")]))))]
1235 "TARGET_ALTIVEC"
1236 "vspltb %0,%1,%2"
1237 [(set_attr "type" "vecperm")])
1238
1239 (define_insn "altivec_vsplth"
1240 [(set (match_operand:V8HI 0 "register_operand" "=v")
1241 (vec_duplicate:V8HI
1242 (vec_select:HI (match_operand:V8HI 1 "register_operand" "v")
1243 (parallel
1244 [(match_operand:QI 2 "u5bit_cint_operand" "")]))))]
1245 "TARGET_ALTIVEC"
1246 "vsplth %0,%1,%2"
1247 [(set_attr "type" "vecperm")])
1248
1249 (define_insn "altivec_vspltw"
1250 [(set (match_operand:V4SI 0 "register_operand" "=v")
1251 (vec_duplicate:V4SI
1252 (vec_select:SI (match_operand:V4SI 1 "register_operand" "v")
1253 (parallel
1254 [(match_operand:QI 2 "u5bit_cint_operand" "i")]))))]
1255 "TARGET_ALTIVEC"
1256 "vspltw %0,%1,%2"
1257 [(set_attr "type" "vecperm")])
1258
1259 (define_insn "altivec_vspltsf"
1260 [(set (match_operand:V4SF 0 "register_operand" "=v")
1261 (vec_duplicate:V4SF
1262 (vec_select:SF (match_operand:V4SF 1 "register_operand" "v")
1263 (parallel
1264 [(match_operand:QI 2 "u5bit_cint_operand" "i")]))))]
1265 "VECTOR_UNIT_ALTIVEC_P (V4SFmode)"
1266 "vspltw %0,%1,%2"
1267 [(set_attr "type" "vecperm")])
1268
1269 (define_insn "altivec_vspltis<VI_char>"
1270 [(set (match_operand:VI 0 "register_operand" "=v")
1271 (vec_duplicate:VI
1272 (match_operand:QI 1 "s5bit_cint_operand" "i")))]
1273 "TARGET_ALTIVEC"
1274 "vspltis<VI_char> %0,%1"
1275 [(set_attr "type" "vecperm")])
1276
1277 (define_insn "*altivec_vrfiz"
1278 [(set (match_operand:V4SF 0 "register_operand" "=v")
1279 (fix:V4SF (match_operand:V4SF 1 "register_operand" "v")))]
1280 "VECTOR_UNIT_ALTIVEC_P (V4SFmode)"
1281 "vrfiz %0,%1"
1282 [(set_attr "type" "vecfloat")])
1283
1284 (define_insn_and_split "altivec_vperm_<mode>"
1285 [(set (match_operand:VM 0 "register_operand" "=v")
1286 (unspec:VM [(match_operand:VM 1 "register_operand" "v")
1287 (match_operand:VM 2 "register_operand" "v")
1288 (match_operand:V16QI 3 "register_operand" "v")]
1289 UNSPEC_VPERM_X))]
1290 "TARGET_ALTIVEC"
1291 "#"
1292 "!reload_in_progress && !reload_completed"
1293 [(set (match_dup 0) (match_dup 4))]
1294 {
1295 if (BYTES_BIG_ENDIAN)
1296 operands[4] = gen_rtx_UNSPEC (<MODE>mode,
1297 gen_rtvec (3, operands[1],
1298 operands[2], operands[3]),
1299 UNSPEC_VPERM);
1300 else
1301 {
1302 /* We want to subtract from 31, but we can't vspltisb 31 since
1303 it's out of range. -1 works as well because only the low-order
1304 five bits of the permute control vector elements are used. */
1305 rtx splat = gen_rtx_VEC_DUPLICATE (V16QImode,
1306 gen_rtx_CONST_INT (QImode, -1));
1307 rtx tmp = gen_reg_rtx (V16QImode);
1308 emit_move_insn (tmp, splat);
1309 rtx sel = gen_rtx_MINUS (V16QImode, tmp, operands[3]);
1310 emit_move_insn (tmp, sel);
1311 operands[4] = gen_rtx_UNSPEC (<MODE>mode,
1312 gen_rtvec (3, operands[2],
1313 operands[1], tmp),
1314 UNSPEC_VPERM);
1315 }
1316 }
1317 [(set_attr "type" "vecperm")])
1318
1319 (define_insn "*altivec_vperm_<mode>_internal"
1320 [(set (match_operand:VM 0 "register_operand" "=v")
1321 (unspec:VM [(match_operand:VM 1 "register_operand" "v")
1322 (match_operand:VM 2 "register_operand" "v")
1323 (match_operand:V16QI 3 "register_operand" "+v")]
1324 UNSPEC_VPERM))]
1325 "TARGET_ALTIVEC"
1326 "vperm %0,%1,%2,%3"
1327 [(set_attr "type" "vecperm")])
1328
1329 (define_insn_and_split "altivec_vperm_<mode>_uns"
1330 [(set (match_operand:VM 0 "register_operand" "=v")
1331 (unspec:VM [(match_operand:VM 1 "register_operand" "v")
1332 (match_operand:VM 2 "register_operand" "v")
1333 (match_operand:V16QI 3 "register_operand" "v")]
1334 UNSPEC_VPERM_UNS_X))]
1335 "TARGET_ALTIVEC"
1336 "#"
1337 "!reload_in_progress && !reload_completed"
1338 [(set (match_dup 0) (match_dup 4))]
1339 {
1340 if (BYTES_BIG_ENDIAN)
1341 operands[4] = gen_rtx_UNSPEC (<MODE>mode,
1342 gen_rtvec (3, operands[1],
1343 operands[2], operands[3]),
1344 UNSPEC_VPERM_UNS);
1345 else
1346 {
1347 /* We want to subtract from 31, but we can't vspltisb 31 since
1348 it's out of range. -1 works as well because only the low-order
1349 five bits of the permute control vector elements are used. */
1350 rtx splat = gen_rtx_VEC_DUPLICATE (V16QImode,
1351 gen_rtx_CONST_INT (QImode, -1));
1352 rtx tmp = gen_reg_rtx (V16QImode);
1353 emit_move_insn (tmp, splat);
1354 rtx sel = gen_rtx_MINUS (V16QImode, tmp, operands[3]);
1355 emit_move_insn (tmp, sel);
1356 operands[4] = gen_rtx_UNSPEC (<MODE>mode,
1357 gen_rtvec (3, operands[2],
1358 operands[1], tmp),
1359 UNSPEC_VPERM_UNS);
1360 }
1361 }
1362 [(set_attr "type" "vecperm")])
1363
1364 (define_insn "*altivec_vperm_<mode>_uns_internal"
1365 [(set (match_operand:VM 0 "register_operand" "=v")
1366 (unspec:VM [(match_operand:VM 1 "register_operand" "v")
1367 (match_operand:VM 2 "register_operand" "v")
1368 (match_operand:V16QI 3 "register_operand" "+v")]
1369 UNSPEC_VPERM_UNS))]
1370 "TARGET_ALTIVEC"
1371 "vperm %0,%1,%2,%3"
1372 [(set_attr "type" "vecperm")])
1373
1374 (define_expand "vec_permv16qi"
1375 [(set (match_operand:V16QI 0 "register_operand" "")
1376 (unspec:V16QI [(match_operand:V16QI 1 "register_operand" "")
1377 (match_operand:V16QI 2 "register_operand" "")
1378 (match_operand:V16QI 3 "register_operand" "")]
1379 UNSPEC_VPERM))]
1380 "TARGET_ALTIVEC"
1381 {
1382 if (!BYTES_BIG_ENDIAN) {
1383 altivec_expand_vec_perm_le (operands);
1384 DONE;
1385 }
1386 })
1387
1388 (define_expand "vec_perm_constv16qi"
1389 [(match_operand:V16QI 0 "register_operand" "")
1390 (match_operand:V16QI 1 "register_operand" "")
1391 (match_operand:V16QI 2 "register_operand" "")
1392 (match_operand:V16QI 3 "" "")]
1393 "TARGET_ALTIVEC"
1394 {
1395 if (altivec_expand_vec_perm_const (operands))
1396 DONE;
1397 else
1398 FAIL;
1399 })
1400
1401 (define_insn "altivec_vrfip" ; ceil
1402 [(set (match_operand:V4SF 0 "register_operand" "=v")
1403 (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "v")]
1404 UNSPEC_FRIP))]
1405 "TARGET_ALTIVEC"
1406 "vrfip %0,%1"
1407 [(set_attr "type" "vecfloat")])
1408
1409 (define_insn "altivec_vrfin"
1410 [(set (match_operand:V4SF 0 "register_operand" "=v")
1411 (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "v")]
1412 UNSPEC_VRFIN))]
1413 "TARGET_ALTIVEC"
1414 "vrfin %0,%1"
1415 [(set_attr "type" "vecfloat")])
1416
1417 (define_insn "*altivec_vrfim" ; floor
1418 [(set (match_operand:V4SF 0 "register_operand" "=v")
1419 (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "v")]
1420 UNSPEC_FRIM))]
1421 "TARGET_ALTIVEC"
1422 "vrfim %0,%1"
1423 [(set_attr "type" "vecfloat")])
1424
1425 (define_insn "altivec_vcfux"
1426 [(set (match_operand:V4SF 0 "register_operand" "=v")
1427 (unspec:V4SF [(match_operand:V4SI 1 "register_operand" "v")
1428 (match_operand:QI 2 "immediate_operand" "i")]
1429 UNSPEC_VCFUX))]
1430 "TARGET_ALTIVEC"
1431 "vcfux %0,%1,%2"
1432 [(set_attr "type" "vecfloat")])
1433
1434 (define_insn "altivec_vcfsx"
1435 [(set (match_operand:V4SF 0 "register_operand" "=v")
1436 (unspec:V4SF [(match_operand:V4SI 1 "register_operand" "v")
1437 (match_operand:QI 2 "immediate_operand" "i")]
1438 UNSPEC_VCFSX))]
1439 "TARGET_ALTIVEC"
1440 "vcfsx %0,%1,%2"
1441 [(set_attr "type" "vecfloat")])
1442
1443 (define_insn "altivec_vctuxs"
1444 [(set (match_operand:V4SI 0 "register_operand" "=v")
1445 (unspec:V4SI [(match_operand:V4SF 1 "register_operand" "v")
1446 (match_operand:QI 2 "immediate_operand" "i")]
1447 UNSPEC_VCTUXS))
1448 (set (reg:SI 110) (unspec:SI [(const_int 0)] UNSPEC_SET_VSCR))]
1449 "TARGET_ALTIVEC"
1450 "vctuxs %0,%1,%2"
1451 [(set_attr "type" "vecfloat")])
1452
1453 (define_insn "altivec_vctsxs"
1454 [(set (match_operand:V4SI 0 "register_operand" "=v")
1455 (unspec:V4SI [(match_operand:V4SF 1 "register_operand" "v")
1456 (match_operand:QI 2 "immediate_operand" "i")]
1457 UNSPEC_VCTSXS))
1458 (set (reg:SI 110) (unspec:SI [(const_int 0)] UNSPEC_SET_VSCR))]
1459 "TARGET_ALTIVEC"
1460 "vctsxs %0,%1,%2"
1461 [(set_attr "type" "vecfloat")])
1462
1463 (define_insn "altivec_vlogefp"
1464 [(set (match_operand:V4SF 0 "register_operand" "=v")
1465 (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "v")]
1466 UNSPEC_VLOGEFP))]
1467 "TARGET_ALTIVEC"
1468 "vlogefp %0,%1"
1469 [(set_attr "type" "vecfloat")])
1470
1471 (define_insn "altivec_vexptefp"
1472 [(set (match_operand:V4SF 0 "register_operand" "=v")
1473 (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "v")]
1474 UNSPEC_VEXPTEFP))]
1475 "TARGET_ALTIVEC"
1476 "vexptefp %0,%1"
1477 [(set_attr "type" "vecfloat")])
1478
1479 (define_insn "*altivec_vrsqrtefp"
1480 [(set (match_operand:V4SF 0 "register_operand" "=v")
1481 (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "v")]
1482 UNSPEC_RSQRT))]
1483 "VECTOR_UNIT_ALTIVEC_P (V4SFmode)"
1484 "vrsqrtefp %0,%1"
1485 [(set_attr "type" "vecfloat")])
1486
1487 (define_insn "altivec_vrefp"
1488 [(set (match_operand:V4SF 0 "register_operand" "=v")
1489 (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "v")]
1490 UNSPEC_FRES))]
1491 "VECTOR_UNIT_ALTIVEC_P (V4SFmode)"
1492 "vrefp %0,%1"
1493 [(set_attr "type" "vecfloat")])
1494
1495 (define_expand "altivec_copysign_v4sf3"
1496 [(use (match_operand:V4SF 0 "register_operand" ""))
1497 (use (match_operand:V4SF 1 "register_operand" ""))
1498 (use (match_operand:V4SF 2 "register_operand" ""))]
1499 "VECTOR_UNIT_ALTIVEC_P (V4SFmode)"
1500 "
1501 {
1502 rtx mask = gen_reg_rtx (V4SImode);
1503 rtvec v = rtvec_alloc (4);
1504 unsigned HOST_WIDE_INT mask_val = ((unsigned HOST_WIDE_INT)1) << 31;
1505
1506 RTVEC_ELT (v, 0) = GEN_INT (mask_val);
1507 RTVEC_ELT (v, 1) = GEN_INT (mask_val);
1508 RTVEC_ELT (v, 2) = GEN_INT (mask_val);
1509 RTVEC_ELT (v, 3) = GEN_INT (mask_val);
1510
1511 emit_insn (gen_vec_initv4si (mask, gen_rtx_PARALLEL (V4SImode, v)));
1512 emit_insn (gen_vector_select_v4sf (operands[0], operands[1], operands[2],
1513 gen_lowpart (V4SFmode, mask)));
1514 DONE;
1515 }")
1516
1517 (define_insn "altivec_vsldoi_<mode>"
1518 [(set (match_operand:VM 0 "register_operand" "=v")
1519 (unspec:VM [(match_operand:VM 1 "register_operand" "v")
1520 (match_operand:VM 2 "register_operand" "v")
1521 (match_operand:QI 3 "immediate_operand" "i")]
1522 UNSPEC_VLSDOI))]
1523 "TARGET_ALTIVEC"
1524 "vsldoi %0,%1,%2,%3"
1525 [(set_attr "type" "vecperm")])
1526
1527 (define_insn "altivec_vupkhs<VU_char>"
1528 [(set (match_operand:VP 0 "register_operand" "=v")
1529 (unspec:VP [(match_operand:<VP_small> 1 "register_operand" "v")]
1530 UNSPEC_VUNPACK_HI_SIGN))]
1531 "<VI_unit>"
1532 "vupkhs<VU_char> %0,%1"
1533 [(set_attr "type" "vecperm")])
1534
1535 (define_insn "altivec_vupkls<VU_char>"
1536 [(set (match_operand:VP 0 "register_operand" "=v")
1537 (unspec:VP [(match_operand:<VP_small> 1 "register_operand" "v")]
1538 UNSPEC_VUNPACK_LO_SIGN))]
1539 "<VI_unit>"
1540 "vupkls<VU_char> %0,%1"
1541 [(set_attr "type" "vecperm")])
1542
1543 (define_insn "altivec_vupkhpx"
1544 [(set (match_operand:V4SI 0 "register_operand" "=v")
1545 (unspec:V4SI [(match_operand:V8HI 1 "register_operand" "v")]
1546 UNSPEC_VUPKHPX))]
1547 "TARGET_ALTIVEC"
1548 "vupkhpx %0,%1"
1549 [(set_attr "type" "vecperm")])
1550
1551 (define_insn "altivec_vupklpx"
1552 [(set (match_operand:V4SI 0 "register_operand" "=v")
1553 (unspec:V4SI [(match_operand:V8HI 1 "register_operand" "v")]
1554 UNSPEC_VUPKLPX))]
1555 "TARGET_ALTIVEC"
1556 "vupklpx %0,%1"
1557 [(set_attr "type" "vecperm")])
1558
1559 ;; Compare vectors producing a vector result and a predicate, setting CR6 to
1560 ;; indicate a combined status
1561 (define_insn "*altivec_vcmpequ<VI_char>_p"
1562 [(set (reg:CC 74)
1563 (unspec:CC [(eq:CC (match_operand:VI2 1 "register_operand" "v")
1564 (match_operand:VI2 2 "register_operand" "v"))]
1565 UNSPEC_PREDICATE))
1566 (set (match_operand:VI2 0 "register_operand" "=v")
1567 (eq:VI2 (match_dup 1)
1568 (match_dup 2)))]
1569 "<VI_unit>"
1570 "vcmpequ<VI_char>. %0,%1,%2"
1571 [(set_attr "type" "veccmp")])
1572
1573 (define_insn "*altivec_vcmpgts<VI_char>_p"
1574 [(set (reg:CC 74)
1575 (unspec:CC [(gt:CC (match_operand:VI2 1 "register_operand" "v")
1576 (match_operand:VI2 2 "register_operand" "v"))]
1577 UNSPEC_PREDICATE))
1578 (set (match_operand:VI2 0 "register_operand" "=v")
1579 (gt:VI2 (match_dup 1)
1580 (match_dup 2)))]
1581 "<VI_unit>"
1582 "vcmpgts<VI_char>. %0,%1,%2"
1583 [(set_attr "type" "veccmp")])
1584
1585 (define_insn "*altivec_vcmpgtu<VI_char>_p"
1586 [(set (reg:CC 74)
1587 (unspec:CC [(gtu:CC (match_operand:VI2 1 "register_operand" "v")
1588 (match_operand:VI2 2 "register_operand" "v"))]
1589 UNSPEC_PREDICATE))
1590 (set (match_operand:VI2 0 "register_operand" "=v")
1591 (gtu:VI2 (match_dup 1)
1592 (match_dup 2)))]
1593 "<VI_unit>"
1594 "vcmpgtu<VI_char>. %0,%1,%2"
1595 [(set_attr "type" "veccmp")])
1596
1597 (define_insn "*altivec_vcmpeqfp_p"
1598 [(set (reg:CC 74)
1599 (unspec:CC [(eq:CC (match_operand:V4SF 1 "register_operand" "v")
1600 (match_operand:V4SF 2 "register_operand" "v"))]
1601 UNSPEC_PREDICATE))
1602 (set (match_operand:V4SF 0 "register_operand" "=v")
1603 (eq:V4SF (match_dup 1)
1604 (match_dup 2)))]
1605 "VECTOR_UNIT_ALTIVEC_P (V4SFmode)"
1606 "vcmpeqfp. %0,%1,%2"
1607 [(set_attr "type" "veccmp")])
1608
1609 (define_insn "*altivec_vcmpgtfp_p"
1610 [(set (reg:CC 74)
1611 (unspec:CC [(gt:CC (match_operand:V4SF 1 "register_operand" "v")
1612 (match_operand:V4SF 2 "register_operand" "v"))]
1613 UNSPEC_PREDICATE))
1614 (set (match_operand:V4SF 0 "register_operand" "=v")
1615 (gt:V4SF (match_dup 1)
1616 (match_dup 2)))]
1617 "VECTOR_UNIT_ALTIVEC_P (V4SFmode)"
1618 "vcmpgtfp. %0,%1,%2"
1619 [(set_attr "type" "veccmp")])
1620
1621 (define_insn "*altivec_vcmpgefp_p"
1622 [(set (reg:CC 74)
1623 (unspec:CC [(ge:CC (match_operand:V4SF 1 "register_operand" "v")
1624 (match_operand:V4SF 2 "register_operand" "v"))]
1625 UNSPEC_PREDICATE))
1626 (set (match_operand:V4SF 0 "register_operand" "=v")
1627 (ge:V4SF (match_dup 1)
1628 (match_dup 2)))]
1629 "VECTOR_UNIT_ALTIVEC_P (V4SFmode)"
1630 "vcmpgefp. %0,%1,%2"
1631 [(set_attr "type" "veccmp")])
1632
1633 (define_insn "altivec_vcmpbfp_p"
1634 [(set (reg:CC 74)
1635 (unspec:CC [(match_operand:V4SF 1 "register_operand" "v")
1636 (match_operand:V4SF 2 "register_operand" "v")]
1637 UNSPEC_VCMPBFP))
1638 (set (match_operand:V4SF 0 "register_operand" "=v")
1639 (unspec:V4SF [(match_dup 1)
1640 (match_dup 2)]
1641 UNSPEC_VCMPBFP))]
1642 "VECTOR_UNIT_ALTIVEC_OR_VSX_P (V4SFmode)"
1643 "vcmpbfp. %0,%1,%2"
1644 [(set_attr "type" "veccmp")])
1645
1646 (define_insn "altivec_mtvscr"
1647 [(set (reg:SI 110)
1648 (unspec_volatile:SI
1649 [(match_operand:V4SI 0 "register_operand" "v")] UNSPECV_MTVSCR))]
1650 "TARGET_ALTIVEC"
1651 "mtvscr %0"
1652 [(set_attr "type" "vecsimple")])
1653
1654 (define_insn "altivec_mfvscr"
1655 [(set (match_operand:V8HI 0 "register_operand" "=v")
1656 (unspec_volatile:V8HI [(reg:SI 110)] UNSPECV_MFVSCR))]
1657 "TARGET_ALTIVEC"
1658 "mfvscr %0"
1659 [(set_attr "type" "vecsimple")])
1660
1661 (define_insn "altivec_dssall"
1662 [(unspec_volatile [(const_int 0)] UNSPECV_DSSALL)]
1663 "TARGET_ALTIVEC"
1664 "dssall"
1665 [(set_attr "type" "vecsimple")])
1666
1667 (define_insn "altivec_dss"
1668 [(unspec_volatile [(match_operand:QI 0 "immediate_operand" "i")]
1669 UNSPECV_DSS)]
1670 "TARGET_ALTIVEC"
1671 "dss %0"
1672 [(set_attr "type" "vecsimple")])
1673
1674 (define_insn "altivec_dst"
1675 [(unspec [(match_operand 0 "register_operand" "b")
1676 (match_operand:SI 1 "register_operand" "r")
1677 (match_operand:QI 2 "immediate_operand" "i")] UNSPEC_DST)]
1678 "TARGET_ALTIVEC && GET_MODE (operands[0]) == Pmode"
1679 "dst %0,%1,%2"
1680 [(set_attr "type" "vecsimple")])
1681
1682 (define_insn "altivec_dstt"
1683 [(unspec [(match_operand 0 "register_operand" "b")
1684 (match_operand:SI 1 "register_operand" "r")
1685 (match_operand:QI 2 "immediate_operand" "i")] UNSPEC_DSTT)]
1686 "TARGET_ALTIVEC && GET_MODE (operands[0]) == Pmode"
1687 "dstt %0,%1,%2"
1688 [(set_attr "type" "vecsimple")])
1689
1690 (define_insn "altivec_dstst"
1691 [(unspec [(match_operand 0 "register_operand" "b")
1692 (match_operand:SI 1 "register_operand" "r")
1693 (match_operand:QI 2 "immediate_operand" "i")] UNSPEC_DSTST)]
1694 "TARGET_ALTIVEC && GET_MODE (operands[0]) == Pmode"
1695 "dstst %0,%1,%2"
1696 [(set_attr "type" "vecsimple")])
1697
1698 (define_insn "altivec_dststt"
1699 [(unspec [(match_operand 0 "register_operand" "b")
1700 (match_operand:SI 1 "register_operand" "r")
1701 (match_operand:QI 2 "immediate_operand" "i")] UNSPEC_DSTSTT)]
1702 "TARGET_ALTIVEC && GET_MODE (operands[0]) == Pmode"
1703 "dststt %0,%1,%2"
1704 [(set_attr "type" "vecsimple")])
1705
1706 (define_insn "altivec_lvsl"
1707 [(set (match_operand:V16QI 0 "register_operand" "=v")
1708 (unspec:V16QI [(match_operand:V16QI 1 "memory_operand" "Z")]
1709 UNSPEC_LVSL))]
1710 "TARGET_ALTIVEC"
1711 "lvsl %0,%y1"
1712 [(set_attr "type" "vecload")])
1713
1714 (define_insn "altivec_lvsr"
1715 [(set (match_operand:V16QI 0 "register_operand" "=v")
1716 (unspec:V16QI [(match_operand:V16QI 1 "memory_operand" "Z")]
1717 UNSPEC_LVSR))]
1718 "TARGET_ALTIVEC"
1719 "lvsr %0,%y1"
1720 [(set_attr "type" "vecload")])
1721
1722 (define_expand "build_vector_mask_for_load"
1723 [(set (match_operand:V16QI 0 "register_operand" "")
1724 (unspec:V16QI [(match_operand 1 "memory_operand" "")] UNSPEC_LVSR))]
1725 "TARGET_ALTIVEC"
1726 "
1727 {
1728 rtx addr;
1729 rtx temp;
1730
1731 gcc_assert (GET_CODE (operands[1]) == MEM);
1732
1733 addr = XEXP (operands[1], 0);
1734 temp = gen_reg_rtx (GET_MODE (addr));
1735 emit_insn (gen_rtx_SET (VOIDmode, temp,
1736 gen_rtx_NEG (GET_MODE (addr), addr)));
1737 emit_insn (gen_altivec_lvsr (operands[0],
1738 replace_equiv_address (operands[1], temp)));
1739 DONE;
1740 }")
1741
1742 ;; Parallel some of the LVE* and STV*'s with unspecs because some have
1743 ;; identical rtl but different instructions-- and gcc gets confused.
1744
1745 (define_insn "altivec_lve<VI_char>x"
1746 [(parallel
1747 [(set (match_operand:VI 0 "register_operand" "=v")
1748 (match_operand:VI 1 "memory_operand" "Z"))
1749 (unspec [(const_int 0)] UNSPEC_LVE)])]
1750 "TARGET_ALTIVEC"
1751 "lve<VI_char>x %0,%y1"
1752 [(set_attr "type" "vecload")])
1753
1754 (define_insn "*altivec_lvesfx"
1755 [(parallel
1756 [(set (match_operand:V4SF 0 "register_operand" "=v")
1757 (match_operand:V4SF 1 "memory_operand" "Z"))
1758 (unspec [(const_int 0)] UNSPEC_LVE)])]
1759 "TARGET_ALTIVEC"
1760 "lvewx %0,%y1"
1761 [(set_attr "type" "vecload")])
1762
1763 (define_insn "altivec_lvxl"
1764 [(parallel
1765 [(set (match_operand:V4SI 0 "register_operand" "=v")
1766 (match_operand:V4SI 1 "memory_operand" "Z"))
1767 (unspec [(const_int 0)] UNSPEC_SET_VSCR)])]
1768 "TARGET_ALTIVEC"
1769 "lvxl %0,%y1"
1770 [(set_attr "type" "vecload")])
1771
1772 (define_insn "altivec_lvx_<mode>"
1773 [(parallel
1774 [(set (match_operand:VM2 0 "register_operand" "=v")
1775 (match_operand:VM2 1 "memory_operand" "Z"))
1776 (unspec [(const_int 0)] UNSPEC_LVX)])]
1777 "TARGET_ALTIVEC"
1778 "lvx %0,%y1"
1779 [(set_attr "type" "vecload")])
1780
1781 (define_insn "altivec_stvx_<mode>"
1782 [(parallel
1783 [(set (match_operand:VM2 0 "memory_operand" "=Z")
1784 (match_operand:VM2 1 "register_operand" "v"))
1785 (unspec [(const_int 0)] UNSPEC_STVX)])]
1786 "TARGET_ALTIVEC"
1787 "stvx %1,%y0"
1788 [(set_attr "type" "vecstore")])
1789
1790 (define_insn "altivec_stvxl"
1791 [(parallel
1792 [(set (match_operand:V4SI 0 "memory_operand" "=Z")
1793 (match_operand:V4SI 1 "register_operand" "v"))
1794 (unspec [(const_int 0)] UNSPEC_STVXL)])]
1795 "TARGET_ALTIVEC"
1796 "stvxl %1,%y0"
1797 [(set_attr "type" "vecstore")])
1798
1799 (define_insn "altivec_stve<VI_char>x"
1800 [(set (match_operand:<VI_scalar> 0 "memory_operand" "=Z")
1801 (unspec:<VI_scalar> [(match_operand:VI 1 "register_operand" "v")] UNSPEC_STVE))]
1802 "TARGET_ALTIVEC"
1803 "stve<VI_char>x %1,%y0"
1804 [(set_attr "type" "vecstore")])
1805
1806 (define_insn "*altivec_stvesfx"
1807 [(set (match_operand:SF 0 "memory_operand" "=Z")
1808 (unspec:SF [(match_operand:V4SF 1 "register_operand" "v")] UNSPEC_STVE))]
1809 "TARGET_ALTIVEC"
1810 "stvewx %1,%y0"
1811 [(set_attr "type" "vecstore")])
1812
1813 ;; Generate
1814 ;; xxlxor/vxor SCRATCH0,SCRATCH0,SCRATCH0
1815 ;; vsubu?m SCRATCH2,SCRATCH1,%1
1816 ;; vmaxs? %0,%1,SCRATCH2"
1817 (define_expand "abs<mode>2"
1818 [(set (match_dup 2) (match_dup 3))
1819 (set (match_dup 4)
1820 (minus:VI2 (match_dup 2)
1821 (match_operand:VI2 1 "register_operand" "v")))
1822 (set (match_operand:VI2 0 "register_operand" "=v")
1823 (smax:VI2 (match_dup 1) (match_dup 4)))]
1824 "<VI_unit>"
1825 {
1826 int i, n_elt = GET_MODE_NUNITS (<MODE>mode);
1827 rtvec v = rtvec_alloc (n_elt);
1828
1829 /* Create an all 0 constant. */
1830 for (i = 0; i < n_elt; ++i)
1831 RTVEC_ELT (v, i) = const0_rtx;
1832
1833 operands[2] = gen_reg_rtx (<MODE>mode);
1834 operands[3] = gen_rtx_CONST_VECTOR (<MODE>mode, v);
1835 operands[4] = gen_reg_rtx (<MODE>mode);
1836 })
1837
1838 ;; Generate
1839 ;; vspltisw SCRATCH1,-1
1840 ;; vslw SCRATCH2,SCRATCH1,SCRATCH1
1841 ;; vandc %0,%1,SCRATCH2
1842 (define_expand "altivec_absv4sf2"
1843 [(set (match_dup 2)
1844 (vec_duplicate:V4SI (const_int -1)))
1845 (set (match_dup 3)
1846 (ashift:V4SI (match_dup 2) (match_dup 2)))
1847 (set (match_operand:V4SF 0 "register_operand" "=v")
1848 (and:V4SF (not:V4SF (subreg:V4SF (match_dup 3) 0))
1849 (match_operand:V4SF 1 "register_operand" "v")))]
1850 "TARGET_ALTIVEC"
1851 {
1852 operands[2] = gen_reg_rtx (V4SImode);
1853 operands[3] = gen_reg_rtx (V4SImode);
1854 })
1855
1856 ;; Generate
1857 ;; vspltis? SCRATCH0,0
1858 ;; vsubs?s SCRATCH2,SCRATCH1,%1
1859 ;; vmaxs? %0,%1,SCRATCH2"
1860 (define_expand "altivec_abss_<mode>"
1861 [(set (match_dup 2) (vec_duplicate:VI (const_int 0)))
1862 (parallel [(set (match_dup 3)
1863 (unspec:VI [(match_dup 2)
1864 (match_operand:VI 1 "register_operand" "v")]
1865 UNSPEC_VSUBS))
1866 (set (reg:SI 110) (unspec:SI [(const_int 0)] UNSPEC_SET_VSCR))])
1867 (set (match_operand:VI 0 "register_operand" "=v")
1868 (smax:VI (match_dup 1) (match_dup 3)))]
1869 "TARGET_ALTIVEC"
1870 {
1871 operands[2] = gen_reg_rtx (GET_MODE (operands[0]));
1872 operands[3] = gen_reg_rtx (GET_MODE (operands[0]));
1873 })
1874
1875 (define_expand "reduc_splus_<mode>"
1876 [(set (match_operand:VIshort 0 "register_operand" "=v")
1877 (unspec:VIshort [(match_operand:VIshort 1 "register_operand" "v")]
1878 UNSPEC_REDUC_PLUS))]
1879 "TARGET_ALTIVEC"
1880 {
1881 rtx vzero = gen_reg_rtx (V4SImode);
1882 rtx vtmp1 = gen_reg_rtx (V4SImode);
1883 rtx dest = gen_lowpart (V4SImode, operands[0]);
1884
1885 emit_insn (gen_altivec_vspltisw (vzero, const0_rtx));
1886 emit_insn (gen_altivec_vsum4s<VI_char>s (vtmp1, operands[1], vzero));
1887 emit_insn (gen_altivec_vsumsws (dest, vtmp1, vzero));
1888 DONE;
1889 })
1890
1891 (define_expand "reduc_uplus_v16qi"
1892 [(set (match_operand:V16QI 0 "register_operand" "=v")
1893 (unspec:V16QI [(match_operand:V16QI 1 "register_operand" "v")]
1894 UNSPEC_REDUC_PLUS))]
1895 "TARGET_ALTIVEC"
1896 {
1897 rtx vzero = gen_reg_rtx (V4SImode);
1898 rtx vtmp1 = gen_reg_rtx (V4SImode);
1899 rtx dest = gen_lowpart (V4SImode, operands[0]);
1900
1901 emit_insn (gen_altivec_vspltisw (vzero, const0_rtx));
1902 emit_insn (gen_altivec_vsum4ubs (vtmp1, operands[1], vzero));
1903 emit_insn (gen_altivec_vsumsws (dest, vtmp1, vzero));
1904 DONE;
1905 })
1906
1907 (define_expand "neg<mode>2"
1908 [(use (match_operand:VI 0 "register_operand" ""))
1909 (use (match_operand:VI 1 "register_operand" ""))]
1910 "TARGET_ALTIVEC"
1911 "
1912 {
1913 rtx vzero;
1914
1915 vzero = gen_reg_rtx (GET_MODE (operands[0]));
1916 emit_insn (gen_altivec_vspltis<VI_char> (vzero, const0_rtx));
1917 emit_insn (gen_sub<mode>3 (operands[0], vzero, operands[1]));
1918
1919 DONE;
1920 }")
1921
1922 (define_expand "udot_prod<mode>"
1923 [(set (match_operand:V4SI 0 "register_operand" "=v")
1924 (plus:V4SI (match_operand:V4SI 3 "register_operand" "v")
1925 (unspec:V4SI [(match_operand:VIshort 1 "register_operand" "v")
1926 (match_operand:VIshort 2 "register_operand" "v")]
1927 UNSPEC_VMSUMU)))]
1928 "TARGET_ALTIVEC"
1929 "
1930 {
1931 emit_insn (gen_altivec_vmsumu<VI_char>m (operands[0], operands[1], operands[2], operands[3]));
1932 DONE;
1933 }")
1934
1935 (define_expand "sdot_prodv8hi"
1936 [(set (match_operand:V4SI 0 "register_operand" "=v")
1937 (plus:V4SI (match_operand:V4SI 3 "register_operand" "v")
1938 (unspec:V4SI [(match_operand:V8HI 1 "register_operand" "v")
1939 (match_operand:V8HI 2 "register_operand" "v")]
1940 UNSPEC_VMSUMSHM)))]
1941 "TARGET_ALTIVEC"
1942 "
1943 {
1944 emit_insn (gen_altivec_vmsumshm (operands[0], operands[1], operands[2], operands[3]));
1945 DONE;
1946 }")
1947
1948 (define_expand "widen_usum<mode>3"
1949 [(set (match_operand:V4SI 0 "register_operand" "=v")
1950 (plus:V4SI (match_operand:V4SI 2 "register_operand" "v")
1951 (unspec:V4SI [(match_operand:VIshort 1 "register_operand" "v")]
1952 UNSPEC_VMSUMU)))]
1953 "TARGET_ALTIVEC"
1954 "
1955 {
1956 rtx vones = gen_reg_rtx (GET_MODE (operands[1]));
1957
1958 emit_insn (gen_altivec_vspltis<VI_char> (vones, const1_rtx));
1959 emit_insn (gen_altivec_vmsumu<VI_char>m (operands[0], operands[1], vones, operands[2]));
1960 DONE;
1961 }")
1962
1963 (define_expand "widen_ssumv16qi3"
1964 [(set (match_operand:V4SI 0 "register_operand" "=v")
1965 (plus:V4SI (match_operand:V4SI 2 "register_operand" "v")
1966 (unspec:V4SI [(match_operand:V16QI 1 "register_operand" "v")]
1967 UNSPEC_VMSUMM)))]
1968 "TARGET_ALTIVEC"
1969 "
1970 {
1971 rtx vones = gen_reg_rtx (V16QImode);
1972
1973 emit_insn (gen_altivec_vspltisb (vones, const1_rtx));
1974 emit_insn (gen_altivec_vmsummbm (operands[0], operands[1], vones, operands[2]));
1975 DONE;
1976 }")
1977
1978 (define_expand "widen_ssumv8hi3"
1979 [(set (match_operand:V4SI 0 "register_operand" "=v")
1980 (plus:V4SI (match_operand:V4SI 2 "register_operand" "v")
1981 (unspec:V4SI [(match_operand:V8HI 1 "register_operand" "v")]
1982 UNSPEC_VMSUMSHM)))]
1983 "TARGET_ALTIVEC"
1984 "
1985 {
1986 rtx vones = gen_reg_rtx (V8HImode);
1987
1988 emit_insn (gen_altivec_vspltish (vones, const1_rtx));
1989 emit_insn (gen_altivec_vmsumshm (operands[0], operands[1], vones, operands[2]));
1990 DONE;
1991 }")
1992
1993 (define_expand "vec_unpacks_hi_<VP_small_lc>"
1994 [(set (match_operand:VP 0 "register_operand" "=v")
1995 (unspec:VP [(match_operand:<VP_small> 1 "register_operand" "v")]
1996 UNSPEC_VUNPACK_HI_SIGN))]
1997 "<VI_unit>"
1998 "")
1999
2000 (define_expand "vec_unpacks_lo_<VP_small_lc>"
2001 [(set (match_operand:VP 0 "register_operand" "=v")
2002 (unspec:VP [(match_operand:<VP_small> 1 "register_operand" "v")]
2003 UNSPEC_VUNPACK_LO_SIGN))]
2004 "<VI_unit>"
2005 "")
2006
2007 (define_insn "vperm_v8hiv4si"
2008 [(set (match_operand:V4SI 0 "register_operand" "=v")
2009 (unspec:V4SI [(match_operand:V8HI 1 "register_operand" "v")
2010 (match_operand:V4SI 2 "register_operand" "v")
2011 (match_operand:V16QI 3 "register_operand" "v")]
2012 UNSPEC_VPERMSI))]
2013 "TARGET_ALTIVEC"
2014 "vperm %0,%1,%2,%3"
2015 [(set_attr "type" "vecperm")])
2016
2017 (define_insn "vperm_v16qiv8hi"
2018 [(set (match_operand:V8HI 0 "register_operand" "=v")
2019 (unspec:V8HI [(match_operand:V16QI 1 "register_operand" "v")
2020 (match_operand:V8HI 2 "register_operand" "v")
2021 (match_operand:V16QI 3 "register_operand" "v")]
2022 UNSPEC_VPERMHI))]
2023 "TARGET_ALTIVEC"
2024 "vperm %0,%1,%2,%3"
2025 [(set_attr "type" "vecperm")])
2026
2027
2028 (define_expand "vec_unpacku_hi_v16qi"
2029 [(set (match_operand:V8HI 0 "register_operand" "=v")
2030 (unspec:V8HI [(match_operand:V16QI 1 "register_operand" "v")]
2031 UNSPEC_VUPKHUB))]
2032 "TARGET_ALTIVEC"
2033 "
2034 {
2035 rtx vzero = gen_reg_rtx (V8HImode);
2036 rtx mask = gen_reg_rtx (V16QImode);
2037 rtvec v = rtvec_alloc (16);
2038 bool be = BYTES_BIG_ENDIAN;
2039
2040 emit_insn (gen_altivec_vspltish (vzero, const0_rtx));
2041
2042 RTVEC_ELT (v, 0) = gen_rtx_CONST_INT (QImode, be ? 16 : 7);
2043 RTVEC_ELT (v, 1) = gen_rtx_CONST_INT (QImode, be ? 0 : 16);
2044 RTVEC_ELT (v, 2) = gen_rtx_CONST_INT (QImode, be ? 16 : 6);
2045 RTVEC_ELT (v, 3) = gen_rtx_CONST_INT (QImode, be ? 1 : 16);
2046 RTVEC_ELT (v, 4) = gen_rtx_CONST_INT (QImode, be ? 16 : 5);
2047 RTVEC_ELT (v, 5) = gen_rtx_CONST_INT (QImode, be ? 2 : 16);
2048 RTVEC_ELT (v, 6) = gen_rtx_CONST_INT (QImode, be ? 16 : 4);
2049 RTVEC_ELT (v, 7) = gen_rtx_CONST_INT (QImode, be ? 3 : 16);
2050 RTVEC_ELT (v, 8) = gen_rtx_CONST_INT (QImode, be ? 16 : 3);
2051 RTVEC_ELT (v, 9) = gen_rtx_CONST_INT (QImode, be ? 4 : 16);
2052 RTVEC_ELT (v, 10) = gen_rtx_CONST_INT (QImode, be ? 16 : 2);
2053 RTVEC_ELT (v, 11) = gen_rtx_CONST_INT (QImode, be ? 5 : 16);
2054 RTVEC_ELT (v, 12) = gen_rtx_CONST_INT (QImode, be ? 16 : 1);
2055 RTVEC_ELT (v, 13) = gen_rtx_CONST_INT (QImode, be ? 6 : 16);
2056 RTVEC_ELT (v, 14) = gen_rtx_CONST_INT (QImode, be ? 16 : 0);
2057 RTVEC_ELT (v, 15) = gen_rtx_CONST_INT (QImode, be ? 7 : 16);
2058
2059 emit_insn (gen_vec_initv16qi (mask, gen_rtx_PARALLEL (V16QImode, v)));
2060 emit_insn (gen_vperm_v16qiv8hi (operands[0], operands[1], vzero, mask));
2061 DONE;
2062 }")
2063
2064 (define_expand "vec_unpacku_hi_v8hi"
2065 [(set (match_operand:V4SI 0 "register_operand" "=v")
2066 (unspec:V4SI [(match_operand:V8HI 1 "register_operand" "v")]
2067 UNSPEC_VUPKHUH))]
2068 "TARGET_ALTIVEC"
2069 "
2070 {
2071 rtx vzero = gen_reg_rtx (V4SImode);
2072 rtx mask = gen_reg_rtx (V16QImode);
2073 rtvec v = rtvec_alloc (16);
2074 bool be = BYTES_BIG_ENDIAN;
2075
2076 emit_insn (gen_altivec_vspltisw (vzero, const0_rtx));
2077
2078 RTVEC_ELT (v, 0) = gen_rtx_CONST_INT (QImode, be ? 16 : 7);
2079 RTVEC_ELT (v, 1) = gen_rtx_CONST_INT (QImode, be ? 17 : 6);
2080 RTVEC_ELT (v, 2) = gen_rtx_CONST_INT (QImode, be ? 0 : 17);
2081 RTVEC_ELT (v, 3) = gen_rtx_CONST_INT (QImode, be ? 1 : 16);
2082 RTVEC_ELT (v, 4) = gen_rtx_CONST_INT (QImode, be ? 16 : 5);
2083 RTVEC_ELT (v, 5) = gen_rtx_CONST_INT (QImode, be ? 17 : 4);
2084 RTVEC_ELT (v, 6) = gen_rtx_CONST_INT (QImode, be ? 2 : 17);
2085 RTVEC_ELT (v, 7) = gen_rtx_CONST_INT (QImode, be ? 3 : 16);
2086 RTVEC_ELT (v, 8) = gen_rtx_CONST_INT (QImode, be ? 16 : 3);
2087 RTVEC_ELT (v, 9) = gen_rtx_CONST_INT (QImode, be ? 17 : 2);
2088 RTVEC_ELT (v, 10) = gen_rtx_CONST_INT (QImode, be ? 4 : 17);
2089 RTVEC_ELT (v, 11) = gen_rtx_CONST_INT (QImode, be ? 5 : 16);
2090 RTVEC_ELT (v, 12) = gen_rtx_CONST_INT (QImode, be ? 16 : 1);
2091 RTVEC_ELT (v, 13) = gen_rtx_CONST_INT (QImode, be ? 17 : 0);
2092 RTVEC_ELT (v, 14) = gen_rtx_CONST_INT (QImode, be ? 6 : 17);
2093 RTVEC_ELT (v, 15) = gen_rtx_CONST_INT (QImode, be ? 7 : 16);
2094
2095 emit_insn (gen_vec_initv16qi (mask, gen_rtx_PARALLEL (V16QImode, v)));
2096 emit_insn (gen_vperm_v8hiv4si (operands[0], operands[1], vzero, mask));
2097 DONE;
2098 }")
2099
2100 (define_expand "vec_unpacku_lo_v16qi"
2101 [(set (match_operand:V8HI 0 "register_operand" "=v")
2102 (unspec:V8HI [(match_operand:V16QI 1 "register_operand" "v")]
2103 UNSPEC_VUPKLUB))]
2104 "TARGET_ALTIVEC"
2105 "
2106 {
2107 rtx vzero = gen_reg_rtx (V8HImode);
2108 rtx mask = gen_reg_rtx (V16QImode);
2109 rtvec v = rtvec_alloc (16);
2110 bool be = BYTES_BIG_ENDIAN;
2111
2112 emit_insn (gen_altivec_vspltish (vzero, const0_rtx));
2113
2114 RTVEC_ELT (v, 0) = gen_rtx_CONST_INT (QImode, be ? 16 : 15);
2115 RTVEC_ELT (v, 1) = gen_rtx_CONST_INT (QImode, be ? 8 : 16);
2116 RTVEC_ELT (v, 2) = gen_rtx_CONST_INT (QImode, be ? 16 : 14);
2117 RTVEC_ELT (v, 3) = gen_rtx_CONST_INT (QImode, be ? 9 : 16);
2118 RTVEC_ELT (v, 4) = gen_rtx_CONST_INT (QImode, be ? 16 : 13);
2119 RTVEC_ELT (v, 5) = gen_rtx_CONST_INT (QImode, be ? 10 : 16);
2120 RTVEC_ELT (v, 6) = gen_rtx_CONST_INT (QImode, be ? 16 : 12);
2121 RTVEC_ELT (v, 7) = gen_rtx_CONST_INT (QImode, be ? 11 : 16);
2122 RTVEC_ELT (v, 8) = gen_rtx_CONST_INT (QImode, be ? 16 : 11);
2123 RTVEC_ELT (v, 9) = gen_rtx_CONST_INT (QImode, be ? 12 : 16);
2124 RTVEC_ELT (v, 10) = gen_rtx_CONST_INT (QImode, be ? 16 : 10);
2125 RTVEC_ELT (v, 11) = gen_rtx_CONST_INT (QImode, be ? 13 : 16);
2126 RTVEC_ELT (v, 12) = gen_rtx_CONST_INT (QImode, be ? 16 : 9);
2127 RTVEC_ELT (v, 13) = gen_rtx_CONST_INT (QImode, be ? 14 : 16);
2128 RTVEC_ELT (v, 14) = gen_rtx_CONST_INT (QImode, be ? 16 : 8);
2129 RTVEC_ELT (v, 15) = gen_rtx_CONST_INT (QImode, be ? 15 : 16);
2130
2131 emit_insn (gen_vec_initv16qi (mask, gen_rtx_PARALLEL (V16QImode, v)));
2132 emit_insn (gen_vperm_v16qiv8hi (operands[0], operands[1], vzero, mask));
2133 DONE;
2134 }")
2135
2136 (define_expand "vec_unpacku_lo_v8hi"
2137 [(set (match_operand:V4SI 0 "register_operand" "=v")
2138 (unspec:V4SI [(match_operand:V8HI 1 "register_operand" "v")]
2139 UNSPEC_VUPKLUH))]
2140 "TARGET_ALTIVEC"
2141 "
2142 {
2143 rtx vzero = gen_reg_rtx (V4SImode);
2144 rtx mask = gen_reg_rtx (V16QImode);
2145 rtvec v = rtvec_alloc (16);
2146 bool be = BYTES_BIG_ENDIAN;
2147
2148 emit_insn (gen_altivec_vspltisw (vzero, const0_rtx));
2149
2150 RTVEC_ELT (v, 0) = gen_rtx_CONST_INT (QImode, be ? 16 : 15);
2151 RTVEC_ELT (v, 1) = gen_rtx_CONST_INT (QImode, be ? 17 : 14);
2152 RTVEC_ELT (v, 2) = gen_rtx_CONST_INT (QImode, be ? 8 : 17);
2153 RTVEC_ELT (v, 3) = gen_rtx_CONST_INT (QImode, be ? 9 : 16);
2154 RTVEC_ELT (v, 4) = gen_rtx_CONST_INT (QImode, be ? 16 : 13);
2155 RTVEC_ELT (v, 5) = gen_rtx_CONST_INT (QImode, be ? 17 : 12);
2156 RTVEC_ELT (v, 6) = gen_rtx_CONST_INT (QImode, be ? 10 : 17);
2157 RTVEC_ELT (v, 7) = gen_rtx_CONST_INT (QImode, be ? 11 : 16);
2158 RTVEC_ELT (v, 8) = gen_rtx_CONST_INT (QImode, be ? 16 : 11);
2159 RTVEC_ELT (v, 9) = gen_rtx_CONST_INT (QImode, be ? 17 : 10);
2160 RTVEC_ELT (v, 10) = gen_rtx_CONST_INT (QImode, be ? 12 : 17);
2161 RTVEC_ELT (v, 11) = gen_rtx_CONST_INT (QImode, be ? 13 : 16);
2162 RTVEC_ELT (v, 12) = gen_rtx_CONST_INT (QImode, be ? 16 : 9);
2163 RTVEC_ELT (v, 13) = gen_rtx_CONST_INT (QImode, be ? 17 : 8);
2164 RTVEC_ELT (v, 14) = gen_rtx_CONST_INT (QImode, be ? 14 : 17);
2165 RTVEC_ELT (v, 15) = gen_rtx_CONST_INT (QImode, be ? 15 : 16);
2166
2167 emit_insn (gen_vec_initv16qi (mask, gen_rtx_PARALLEL (V16QImode, v)));
2168 emit_insn (gen_vperm_v8hiv4si (operands[0], operands[1], vzero, mask));
2169 DONE;
2170 }")
2171
2172 (define_expand "vec_widen_umult_hi_v16qi"
2173 [(set (match_operand:V8HI 0 "register_operand" "=v")
2174 (unspec:V8HI [(match_operand:V16QI 1 "register_operand" "v")
2175 (match_operand:V16QI 2 "register_operand" "v")]
2176 UNSPEC_VMULWHUB))]
2177 "TARGET_ALTIVEC"
2178 "
2179 {
2180 rtx ve = gen_reg_rtx (V8HImode);
2181 rtx vo = gen_reg_rtx (V8HImode);
2182
2183 emit_insn (gen_vec_widen_umult_even_v16qi (ve, operands[1], operands[2]));
2184 emit_insn (gen_vec_widen_umult_odd_v16qi (vo, operands[1], operands[2]));
2185 emit_insn (gen_altivec_vmrghh (operands[0], ve, vo));
2186 DONE;
2187 }")
2188
2189 (define_expand "vec_widen_umult_lo_v16qi"
2190 [(set (match_operand:V8HI 0 "register_operand" "=v")
2191 (unspec:V8HI [(match_operand:V16QI 1 "register_operand" "v")
2192 (match_operand:V16QI 2 "register_operand" "v")]
2193 UNSPEC_VMULWLUB))]
2194 "TARGET_ALTIVEC"
2195 "
2196 {
2197 rtx ve = gen_reg_rtx (V8HImode);
2198 rtx vo = gen_reg_rtx (V8HImode);
2199
2200 emit_insn (gen_vec_widen_umult_even_v16qi (ve, operands[1], operands[2]));
2201 emit_insn (gen_vec_widen_umult_odd_v16qi (vo, operands[1], operands[2]));
2202 emit_insn (gen_altivec_vmrglh (operands[0], ve, vo));
2203 DONE;
2204 }")
2205
2206 (define_expand "vec_widen_smult_hi_v16qi"
2207 [(set (match_operand:V8HI 0 "register_operand" "=v")
2208 (unspec:V8HI [(match_operand:V16QI 1 "register_operand" "v")
2209 (match_operand:V16QI 2 "register_operand" "v")]
2210 UNSPEC_VMULWHSB))]
2211 "TARGET_ALTIVEC"
2212 "
2213 {
2214 rtx ve = gen_reg_rtx (V8HImode);
2215 rtx vo = gen_reg_rtx (V8HImode);
2216
2217 emit_insn (gen_vec_widen_smult_even_v16qi (ve, operands[1], operands[2]));
2218 emit_insn (gen_vec_widen_smult_odd_v16qi (vo, operands[1], operands[2]));
2219 emit_insn (gen_altivec_vmrghh (operands[0], ve, vo));
2220 DONE;
2221 }")
2222
2223 (define_expand "vec_widen_smult_lo_v16qi"
2224 [(set (match_operand:V8HI 0 "register_operand" "=v")
2225 (unspec:V8HI [(match_operand:V16QI 1 "register_operand" "v")
2226 (match_operand:V16QI 2 "register_operand" "v")]
2227 UNSPEC_VMULWLSB))]
2228 "TARGET_ALTIVEC"
2229 "
2230 {
2231 rtx ve = gen_reg_rtx (V8HImode);
2232 rtx vo = gen_reg_rtx (V8HImode);
2233
2234 emit_insn (gen_vec_widen_smult_even_v16qi (ve, operands[1], operands[2]));
2235 emit_insn (gen_vec_widen_smult_odd_v16qi (vo, operands[1], operands[2]));
2236 emit_insn (gen_altivec_vmrglh (operands[0], ve, vo));
2237 DONE;
2238 }")
2239
2240 (define_expand "vec_widen_umult_hi_v8hi"
2241 [(set (match_operand:V4SI 0 "register_operand" "=v")
2242 (unspec:V4SI [(match_operand:V8HI 1 "register_operand" "v")
2243 (match_operand:V8HI 2 "register_operand" "v")]
2244 UNSPEC_VMULWHUH))]
2245 "TARGET_ALTIVEC"
2246 "
2247 {
2248 rtx ve = gen_reg_rtx (V4SImode);
2249 rtx vo = gen_reg_rtx (V4SImode);
2250
2251 emit_insn (gen_vec_widen_umult_even_v8hi (ve, operands[1], operands[2]));
2252 emit_insn (gen_vec_widen_umult_odd_v8hi (vo, operands[1], operands[2]));
2253 emit_insn (gen_altivec_vmrghw (operands[0], ve, vo));
2254 DONE;
2255 }")
2256
2257 (define_expand "vec_widen_umult_lo_v8hi"
2258 [(set (match_operand:V4SI 0 "register_operand" "=v")
2259 (unspec:V4SI [(match_operand:V8HI 1 "register_operand" "v")
2260 (match_operand:V8HI 2 "register_operand" "v")]
2261 UNSPEC_VMULWLUH))]
2262 "TARGET_ALTIVEC"
2263 "
2264 {
2265 rtx ve = gen_reg_rtx (V4SImode);
2266 rtx vo = gen_reg_rtx (V4SImode);
2267
2268 emit_insn (gen_vec_widen_umult_even_v8hi (ve, operands[1], operands[2]));
2269 emit_insn (gen_vec_widen_umult_odd_v8hi (vo, operands[1], operands[2]));
2270 emit_insn (gen_altivec_vmrglw (operands[0], ve, vo));
2271 DONE;
2272 }")
2273
2274 (define_expand "vec_widen_smult_hi_v8hi"
2275 [(set (match_operand:V4SI 0 "register_operand" "=v")
2276 (unspec:V4SI [(match_operand:V8HI 1 "register_operand" "v")
2277 (match_operand:V8HI 2 "register_operand" "v")]
2278 UNSPEC_VMULWHSH))]
2279 "TARGET_ALTIVEC"
2280 "
2281 {
2282 rtx ve = gen_reg_rtx (V4SImode);
2283 rtx vo = gen_reg_rtx (V4SImode);
2284
2285 emit_insn (gen_vec_widen_smult_even_v8hi (ve, operands[1], operands[2]));
2286 emit_insn (gen_vec_widen_smult_odd_v8hi (vo, operands[1], operands[2]));
2287 emit_insn (gen_altivec_vmrghw (operands[0], ve, vo));
2288 DONE;
2289 }")
2290
2291 (define_expand "vec_widen_smult_lo_v8hi"
2292 [(set (match_operand:V4SI 0 "register_operand" "=v")
2293 (unspec:V4SI [(match_operand:V8HI 1 "register_operand" "v")
2294 (match_operand:V8HI 2 "register_operand" "v")]
2295 UNSPEC_VMULWLSH))]
2296 "TARGET_ALTIVEC"
2297 "
2298 {
2299 rtx ve = gen_reg_rtx (V4SImode);
2300 rtx vo = gen_reg_rtx (V4SImode);
2301
2302 emit_insn (gen_vec_widen_smult_even_v8hi (ve, operands[1], operands[2]));
2303 emit_insn (gen_vec_widen_smult_odd_v8hi (vo, operands[1], operands[2]));
2304 emit_insn (gen_altivec_vmrglw (operands[0], ve, vo));
2305 DONE;
2306 }")
2307
2308 (define_expand "vec_pack_trunc_<mode>"
2309 [(set (match_operand:<VP_small> 0 "register_operand" "=v")
2310 (unspec:<VP_small> [(match_operand:VP 1 "register_operand" "v")
2311 (match_operand:VP 2 "register_operand" "v")]
2312 UNSPEC_VPACK_UNS_UNS_MOD))]
2313 "<VI_unit>"
2314 "")
2315
2316 (define_expand "altivec_negv4sf2"
2317 [(use (match_operand:V4SF 0 "register_operand" ""))
2318 (use (match_operand:V4SF 1 "register_operand" ""))]
2319 "TARGET_ALTIVEC"
2320 "
2321 {
2322 rtx neg0;
2323
2324 /* Generate [-0.0, -0.0, -0.0, -0.0]. */
2325 neg0 = gen_reg_rtx (V4SImode);
2326 emit_insn (gen_altivec_vspltisw (neg0, constm1_rtx));
2327 emit_insn (gen_vashlv4si3 (neg0, neg0, neg0));
2328
2329 /* XOR */
2330 emit_insn (gen_xorv4sf3 (operands[0],
2331 gen_lowpart (V4SFmode, neg0), operands[1]));
2332
2333 DONE;
2334 }")
2335
2336 ;; Vector SIMD PEM v2.06c defines LVLX, LVLXL, LVRX, LVRXL,
2337 ;; STVLX, STVLXL, STVVRX, STVRXL are available only on Cell.
2338 (define_insn "altivec_lvlx"
2339 [(set (match_operand:V16QI 0 "register_operand" "=v")
2340 (unspec:V16QI [(match_operand:BLK 1 "memory_operand" "Z")]
2341 UNSPEC_LVLX))]
2342 "TARGET_ALTIVEC && rs6000_cpu == PROCESSOR_CELL"
2343 "lvlx %0,%y1"
2344 [(set_attr "type" "vecload")])
2345
2346 (define_insn "altivec_lvlxl"
2347 [(set (match_operand:V16QI 0 "register_operand" "=v")
2348 (unspec:V16QI [(match_operand:BLK 1 "memory_operand" "Z")]
2349 UNSPEC_LVLXL))]
2350 "TARGET_ALTIVEC && rs6000_cpu == PROCESSOR_CELL"
2351 "lvlxl %0,%y1"
2352 [(set_attr "type" "vecload")])
2353
2354 (define_insn "altivec_lvrx"
2355 [(set (match_operand:V16QI 0 "register_operand" "=v")
2356 (unspec:V16QI [(match_operand:BLK 1 "memory_operand" "Z")]
2357 UNSPEC_LVRX))]
2358 "TARGET_ALTIVEC && rs6000_cpu == PROCESSOR_CELL"
2359 "lvrx %0,%y1"
2360 [(set_attr "type" "vecload")])
2361
2362 (define_insn "altivec_lvrxl"
2363 [(set (match_operand:V16QI 0 "register_operand" "=v")
2364 (unspec:V16QI [(match_operand:BLK 1 "memory_operand" "Z")]
2365 UNSPEC_LVRXL))]
2366 "TARGET_ALTIVEC && rs6000_cpu == PROCESSOR_CELL"
2367 "lvrxl %0,%y1"
2368 [(set_attr "type" "vecload")])
2369
2370 (define_insn "altivec_stvlx"
2371 [(parallel
2372 [(set (match_operand:V16QI 0 "memory_operand" "=Z")
2373 (match_operand:V16QI 1 "register_operand" "v"))
2374 (unspec [(const_int 0)] UNSPEC_STVLX)])]
2375 "TARGET_ALTIVEC && rs6000_cpu == PROCESSOR_CELL"
2376 "stvlx %1,%y0"
2377 [(set_attr "type" "vecstore")])
2378
2379 (define_insn "altivec_stvlxl"
2380 [(parallel
2381 [(set (match_operand:V16QI 0 "memory_operand" "=Z")
2382 (match_operand:V16QI 1 "register_operand" "v"))
2383 (unspec [(const_int 0)] UNSPEC_STVLXL)])]
2384 "TARGET_ALTIVEC && rs6000_cpu == PROCESSOR_CELL"
2385 "stvlxl %1,%y0"
2386 [(set_attr "type" "vecstore")])
2387
2388 (define_insn "altivec_stvrx"
2389 [(parallel
2390 [(set (match_operand:V16QI 0 "memory_operand" "=Z")
2391 (match_operand:V16QI 1 "register_operand" "v"))
2392 (unspec [(const_int 0)] UNSPEC_STVRX)])]
2393 "TARGET_ALTIVEC && rs6000_cpu == PROCESSOR_CELL"
2394 "stvrx %1,%y0"
2395 [(set_attr "type" "vecstore")])
2396
2397 (define_insn "altivec_stvrxl"
2398 [(parallel
2399 [(set (match_operand:V16QI 0 "memory_operand" "=Z")
2400 (match_operand:V16QI 1 "register_operand" "v"))
2401 (unspec [(const_int 0)] UNSPEC_STVRXL)])]
2402 "TARGET_ALTIVEC && rs6000_cpu == PROCESSOR_CELL"
2403 "stvrxl %1,%y0"
2404 [(set_attr "type" "vecstore")])
2405
2406 (define_expand "vec_unpacks_float_hi_v8hi"
2407 [(set (match_operand:V4SF 0 "register_operand" "")
2408 (unspec:V4SF [(match_operand:V8HI 1 "register_operand" "")]
2409 UNSPEC_VUPKHS_V4SF))]
2410 "TARGET_ALTIVEC"
2411 "
2412 {
2413 rtx tmp = gen_reg_rtx (V4SImode);
2414
2415 emit_insn (gen_vec_unpacks_hi_v8hi (tmp, operands[1]));
2416 emit_insn (gen_altivec_vcfsx (operands[0], tmp, const0_rtx));
2417 DONE;
2418 }")
2419
2420 (define_expand "vec_unpacks_float_lo_v8hi"
2421 [(set (match_operand:V4SF 0 "register_operand" "")
2422 (unspec:V4SF [(match_operand:V8HI 1 "register_operand" "")]
2423 UNSPEC_VUPKLS_V4SF))]
2424 "TARGET_ALTIVEC"
2425 "
2426 {
2427 rtx tmp = gen_reg_rtx (V4SImode);
2428
2429 emit_insn (gen_vec_unpacks_lo_v8hi (tmp, operands[1]));
2430 emit_insn (gen_altivec_vcfsx (operands[0], tmp, const0_rtx));
2431 DONE;
2432 }")
2433
2434 (define_expand "vec_unpacku_float_hi_v8hi"
2435 [(set (match_operand:V4SF 0 "register_operand" "")
2436 (unspec:V4SF [(match_operand:V8HI 1 "register_operand" "")]
2437 UNSPEC_VUPKHU_V4SF))]
2438 "TARGET_ALTIVEC"
2439 "
2440 {
2441 rtx tmp = gen_reg_rtx (V4SImode);
2442
2443 emit_insn (gen_vec_unpacku_hi_v8hi (tmp, operands[1]));
2444 emit_insn (gen_altivec_vcfux (operands[0], tmp, const0_rtx));
2445 DONE;
2446 }")
2447
2448 (define_expand "vec_unpacku_float_lo_v8hi"
2449 [(set (match_operand:V4SF 0 "register_operand" "")
2450 (unspec:V4SF [(match_operand:V8HI 1 "register_operand" "")]
2451 UNSPEC_VUPKLU_V4SF))]
2452 "TARGET_ALTIVEC"
2453 "
2454 {
2455 rtx tmp = gen_reg_rtx (V4SImode);
2456
2457 emit_insn (gen_vec_unpacku_lo_v8hi (tmp, operands[1]));
2458 emit_insn (gen_altivec_vcfux (operands[0], tmp, const0_rtx));
2459 DONE;
2460 }")
2461
2462 \f
2463 ;; Power8 vector instructions encoded as Altivec instructions
2464
2465 ;; Vector count leading zeros
2466 (define_insn "*p8v_clz<mode>2"
2467 [(set (match_operand:VI2 0 "register_operand" "=v")
2468 (clz:VI2 (match_operand:VI2 1 "register_operand" "v")))]
2469 "TARGET_P8_VECTOR"
2470 "vclz<wd> %0,%1"
2471 [(set_attr "length" "4")
2472 (set_attr "type" "vecsimple")])
2473
2474 ;; Vector population count
2475 (define_insn "*p8v_popcount<mode>2"
2476 [(set (match_operand:VI2 0 "register_operand" "=v")
2477 (popcount:VI2 (match_operand:VI2 1 "register_operand" "v")))]
2478 "TARGET_P8_VECTOR"
2479 "vpopcnt<wd> %0,%1"
2480 [(set_attr "length" "4")
2481 (set_attr "type" "vecsimple")])
2482
2483 ;; Vector Gather Bits by Bytes by Doubleword
2484 (define_insn "p8v_vgbbd"
2485 [(set (match_operand:V16QI 0 "register_operand" "=v")
2486 (unspec:V16QI [(match_operand:V16QI 1 "register_operand" "v")]
2487 UNSPEC_VGBBD))]
2488 "TARGET_P8_VECTOR"
2489 "vgbbd %0,%1"
2490 [(set_attr "length" "4")
2491 (set_attr "type" "vecsimple")])