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