* config/rs6000/rs6000.h (ASM_OUTPUT_DEF_FROM_DECLS): Only emit
[official-gcc.git] / gcc / config / rs6000 / altivec.md
blob47a3a6894e15ef17e2775bc889b1ff74ddeace48
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_vec_widen_umult_odd_v8hi (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    emit_insn (gen_altivec_vmrghw (high, even, odd));
680    emit_insn (gen_altivec_vmrglw (low, even, odd));
682    emit_insn (gen_altivec_vpkuwum (operands[0], high, low));
684    DONE;
687 ;; Fused multiply subtract 
688 (define_insn "*altivec_vnmsubfp"
689   [(set (match_operand:V4SF 0 "register_operand" "=v")
690         (neg:V4SF
691          (fma:V4SF (match_operand:V4SF 1 "register_operand" "v")
692                    (match_operand:V4SF 2 "register_operand" "v")
693                    (neg:V4SF
694                     (match_operand:V4SF 3 "register_operand" "v")))))]
695   "VECTOR_UNIT_ALTIVEC_P (V4SFmode)"
696   "vnmsubfp %0,%1,%2,%3"
697   [(set_attr "type" "vecfloat")])
699 (define_insn "altivec_vmsumu<VI_char>m"
700   [(set (match_operand:V4SI 0 "register_operand" "=v")
701         (unspec:V4SI [(match_operand:VIshort 1 "register_operand" "v")
702                       (match_operand:VIshort 2 "register_operand" "v")
703                       (match_operand:V4SI 3 "register_operand" "v")]
704                      UNSPEC_VMSUMU))]
705   "TARGET_ALTIVEC"
706   "vmsumu<VI_char>m %0,%1,%2,%3"
707   [(set_attr "type" "veccomplex")])
709 (define_insn "altivec_vmsumm<VI_char>m"
710   [(set (match_operand:V4SI 0 "register_operand" "=v")
711         (unspec:V4SI [(match_operand:VIshort 1 "register_operand" "v")
712                       (match_operand:VIshort 2 "register_operand" "v")
713                       (match_operand:V4SI 3 "register_operand" "v")]
714                      UNSPEC_VMSUMM))]
715   "TARGET_ALTIVEC"
716   "vmsumm<VI_char>m %0,%1,%2,%3"
717   [(set_attr "type" "veccomplex")])
719 (define_insn "altivec_vmsumshm"
720   [(set (match_operand:V4SI 0 "register_operand" "=v")
721         (unspec:V4SI [(match_operand:V8HI 1 "register_operand" "v")
722                       (match_operand:V8HI 2 "register_operand" "v")
723                       (match_operand:V4SI 3 "register_operand" "v")]
724                      UNSPEC_VMSUMSHM))]
725   "TARGET_ALTIVEC"
726   "vmsumshm %0,%1,%2,%3"
727   [(set_attr "type" "veccomplex")])
729 (define_insn "altivec_vmsumuhs"
730   [(set (match_operand:V4SI 0 "register_operand" "=v")
731         (unspec:V4SI [(match_operand:V8HI 1 "register_operand" "v")
732                       (match_operand:V8HI 2 "register_operand" "v")
733                       (match_operand:V4SI 3 "register_operand" "v")]
734                      UNSPEC_VMSUMUHS))
735    (set (reg:SI 110) (unspec:SI [(const_int 0)] UNSPEC_SET_VSCR))]
736   "TARGET_ALTIVEC"
737   "vmsumuhs %0,%1,%2,%3"
738   [(set_attr "type" "veccomplex")])
740 (define_insn "altivec_vmsumshs"
741   [(set (match_operand:V4SI 0 "register_operand" "=v")
742         (unspec:V4SI [(match_operand:V8HI 1 "register_operand" "v")
743                       (match_operand:V8HI 2 "register_operand" "v")
744                       (match_operand:V4SI 3 "register_operand" "v")]
745                      UNSPEC_VMSUMSHS))
746    (set (reg:SI 110) (unspec:SI [(const_int 0)] UNSPEC_SET_VSCR))]
747   "TARGET_ALTIVEC"
748   "vmsumshs %0,%1,%2,%3"
749   [(set_attr "type" "veccomplex")])
751 ;; max
753 (define_insn "umax<mode>3"
754   [(set (match_operand:VI2 0 "register_operand" "=v")
755         (umax:VI2 (match_operand:VI2 1 "register_operand" "v")
756                   (match_operand:VI2 2 "register_operand" "v")))]
757   "<VI_unit>"
758   "vmaxu<VI_char> %0,%1,%2"
759   [(set_attr "type" "vecsimple")])
761 (define_insn "smax<mode>3"
762   [(set (match_operand:VI2 0 "register_operand" "=v")
763         (smax:VI2 (match_operand:VI2 1 "register_operand" "v")
764                   (match_operand:VI2 2 "register_operand" "v")))]
765   "<VI_unit>"
766   "vmaxs<VI_char> %0,%1,%2"
767   [(set_attr "type" "vecsimple")])
769 (define_insn "*altivec_smaxv4sf3"
770   [(set (match_operand:V4SF 0 "register_operand" "=v")
771         (smax:V4SF (match_operand:V4SF 1 "register_operand" "v")
772                    (match_operand:V4SF 2 "register_operand" "v")))]
773   "VECTOR_UNIT_ALTIVEC_P (V4SFmode)"
774   "vmaxfp %0,%1,%2"
775   [(set_attr "type" "veccmp")])
777 (define_insn "umin<mode>3"
778   [(set (match_operand:VI2 0 "register_operand" "=v")
779         (umin:VI2 (match_operand:VI2 1 "register_operand" "v")
780                   (match_operand:VI2 2 "register_operand" "v")))]
781   "<VI_unit>"
782   "vminu<VI_char> %0,%1,%2"
783   [(set_attr "type" "vecsimple")])
785 (define_insn "smin<mode>3"
786   [(set (match_operand:VI2 0 "register_operand" "=v")
787         (smin:VI2 (match_operand:VI2 1 "register_operand" "v")
788                   (match_operand:VI2 2 "register_operand" "v")))]
789   "<VI_unit>"
790   "vmins<VI_char> %0,%1,%2"
791   [(set_attr "type" "vecsimple")])
793 (define_insn "*altivec_sminv4sf3"
794   [(set (match_operand:V4SF 0 "register_operand" "=v")
795         (smin:V4SF (match_operand:V4SF 1 "register_operand" "v")
796                    (match_operand:V4SF 2 "register_operand" "v")))]
797   "VECTOR_UNIT_ALTIVEC_P (V4SFmode)"
798   "vminfp %0,%1,%2"
799   [(set_attr "type" "veccmp")])
801 (define_insn "altivec_vmhaddshs"
802   [(set (match_operand:V8HI 0 "register_operand" "=v")
803         (unspec:V8HI [(match_operand:V8HI 1 "register_operand" "v")
804                       (match_operand:V8HI 2 "register_operand" "v")
805                       (match_operand:V8HI 3 "register_operand" "v")]
806                      UNSPEC_VMHADDSHS))
807    (set (reg:SI 110) (unspec:SI [(const_int 0)] UNSPEC_SET_VSCR))]
808   "TARGET_ALTIVEC"
809   "vmhaddshs %0,%1,%2,%3"
810   [(set_attr "type" "veccomplex")])
812 (define_insn "altivec_vmhraddshs"
813   [(set (match_operand:V8HI 0 "register_operand" "=v")
814         (unspec:V8HI [(match_operand:V8HI 1 "register_operand" "v")
815                       (match_operand:V8HI 2 "register_operand" "v")
816                       (match_operand:V8HI 3 "register_operand" "v")]
817                      UNSPEC_VMHRADDSHS))
818    (set (reg:SI 110) (unspec:SI [(const_int 0)] UNSPEC_SET_VSCR))]
819   "TARGET_ALTIVEC"
820   "vmhraddshs %0,%1,%2,%3"
821   [(set_attr "type" "veccomplex")])
823 (define_insn "altivec_vmladduhm"
824   [(set (match_operand:V8HI 0 "register_operand" "=v")
825         (unspec:V8HI [(match_operand:V8HI 1 "register_operand" "v")
826                       (match_operand:V8HI 2 "register_operand" "v")
827                       (match_operand:V8HI 3 "register_operand" "v")]
828                      UNSPEC_VMLADDUHM))]
829   "TARGET_ALTIVEC"
830   "vmladduhm %0,%1,%2,%3"
831   [(set_attr "type" "veccomplex")])
833 (define_insn "altivec_vmrghb"
834   [(set (match_operand:V16QI 0 "register_operand" "=v")
835         (vec_select:V16QI
836           (vec_concat:V32QI
837             (match_operand:V16QI 1 "register_operand" "v")
838             (match_operand:V16QI 2 "register_operand" "v"))
839           (parallel [(const_int 0) (const_int 16)
840                      (const_int 1) (const_int 17)
841                      (const_int 2) (const_int 18)
842                      (const_int 3) (const_int 19)
843                      (const_int 4) (const_int 20)
844                      (const_int 5) (const_int 21)
845                      (const_int 6) (const_int 22)
846                      (const_int 7) (const_int 23)])))]
847   "TARGET_ALTIVEC"
848   "vmrghb %0,%1,%2"
849   [(set_attr "type" "vecperm")])
851 (define_insn "altivec_vmrghh"
852   [(set (match_operand:V8HI 0 "register_operand" "=v")
853         (vec_select:V8HI
854           (vec_concat:V16HI
855             (match_operand:V8HI 1 "register_operand" "v")
856             (match_operand:V8HI 2 "register_operand" "v"))
857           (parallel [(const_int 0) (const_int 8)
858                      (const_int 1) (const_int 9)
859                      (const_int 2) (const_int 10)
860                      (const_int 3) (const_int 11)])))]
861   "TARGET_ALTIVEC"
862   "vmrghh %0,%1,%2"
863   [(set_attr "type" "vecperm")])
865 (define_insn "altivec_vmrghw"
866   [(set (match_operand:V4SI 0 "register_operand" "=v")
867         (vec_select:V4SI
868           (vec_concat:V8SI
869             (match_operand:V4SI 1 "register_operand" "v")
870             (match_operand:V4SI 2 "register_operand" "v"))
871           (parallel [(const_int 0) (const_int 4)
872                      (const_int 1) (const_int 5)])))]
873   "VECTOR_MEM_ALTIVEC_P (V4SImode)"
874   "vmrghw %0,%1,%2"
875   [(set_attr "type" "vecperm")])
877 (define_insn "*altivec_vmrghsf"
878   [(set (match_operand:V4SF 0 "register_operand" "=v")
879         (vec_select:V4SF
880           (vec_concat:V8SF
881             (match_operand:V4SF 1 "register_operand" "v")
882             (match_operand:V4SF 2 "register_operand" "v"))
883           (parallel [(const_int 0) (const_int 4)
884                      (const_int 1) (const_int 5)])))]
885   "VECTOR_MEM_ALTIVEC_P (V4SFmode)"
886   "vmrghw %0,%1,%2"
887   [(set_attr "type" "vecperm")])
889 (define_insn "altivec_vmrglb"
890   [(set (match_operand:V16QI 0 "register_operand" "=v")
891         (vec_select:V16QI
892           (vec_concat:V32QI
893             (match_operand:V16QI 1 "register_operand" "v")
894             (match_operand:V16QI 2 "register_operand" "v"))
895           (parallel [(const_int  8) (const_int 24)
896                      (const_int  9) (const_int 25)
897                      (const_int 10) (const_int 26)
898                      (const_int 11) (const_int 27)
899                      (const_int 12) (const_int 28)
900                      (const_int 13) (const_int 29)
901                      (const_int 14) (const_int 30)
902                      (const_int 15) (const_int 31)])))]
903   "TARGET_ALTIVEC"
904   "vmrglb %0,%1,%2"
905   [(set_attr "type" "vecperm")])
907 (define_insn "altivec_vmrglh"
908   [(set (match_operand:V8HI 0 "register_operand" "=v")
909         (vec_select:V8HI
910           (vec_concat:V16HI
911             (match_operand:V8HI 1 "register_operand" "v")
912             (match_operand:V8HI 2 "register_operand" "v"))
913           (parallel [(const_int 4) (const_int 12)
914                      (const_int 5) (const_int 13)
915                      (const_int 6) (const_int 14)
916                      (const_int 7) (const_int 15)])))]
917   "TARGET_ALTIVEC"
918   "vmrglh %0,%1,%2"
919   [(set_attr "type" "vecperm")])
921 (define_insn "altivec_vmrglw"
922   [(set (match_operand:V4SI 0 "register_operand" "=v")
923         (vec_select:V4SI
924           (vec_concat:V8SI
925             (match_operand:V4SI 1 "register_operand" "v")
926             (match_operand:V4SI 2 "register_operand" "v"))
927           (parallel [(const_int 2) (const_int 6)
928                      (const_int 3) (const_int 7)])))]
929   "VECTOR_MEM_ALTIVEC_P (V4SImode)"
930   "vmrglw %0,%1,%2"
931   [(set_attr "type" "vecperm")])
933 (define_insn "*altivec_vmrglsf"
934   [(set (match_operand:V4SF 0 "register_operand" "=v")
935         (vec_select:V4SF
936          (vec_concat:V8SF
937            (match_operand:V4SF 1 "register_operand" "v")
938            (match_operand:V4SF 2 "register_operand" "v"))
939          (parallel [(const_int 2) (const_int 6)
940                     (const_int 3) (const_int 7)])))]
941   "VECTOR_MEM_ALTIVEC_P (V4SFmode)"
942   "vmrglw %0,%1,%2"
943   [(set_attr "type" "vecperm")])
945 ;; Power8 vector merge even/odd
946 (define_insn "p8_vmrgew"
947   [(set (match_operand:V4SI 0 "register_operand" "=v")
948         (vec_select:V4SI
949           (vec_concat:V8SI
950             (match_operand:V4SI 1 "register_operand" "v")
951             (match_operand:V4SI 2 "register_operand" "v"))
952           (parallel [(const_int 0) (const_int 4)
953                      (const_int 2) (const_int 6)])))]
954   "TARGET_P8_VECTOR"
955   "vmrgew %0,%1,%2"
956   [(set_attr "type" "vecperm")])
958 (define_insn "p8_vmrgow"
959   [(set (match_operand:V4SI 0 "register_operand" "=v")
960         (vec_select:V4SI
961           (vec_concat:V8SI
962             (match_operand:V4SI 1 "register_operand" "v")
963             (match_operand:V4SI 2 "register_operand" "v"))
964           (parallel [(const_int 1) (const_int 5)
965                      (const_int 3) (const_int 7)])))]
966   "TARGET_P8_VECTOR"
967   "vmrgow %0,%1,%2"
968   [(set_attr "type" "vecperm")])
970 (define_insn "vec_widen_umult_even_v16qi"
971   [(set (match_operand:V8HI 0 "register_operand" "=v")
972         (unspec:V8HI [(match_operand:V16QI 1 "register_operand" "v")
973                       (match_operand:V16QI 2 "register_operand" "v")]
974                      UNSPEC_VMULEUB))]
975   "TARGET_ALTIVEC"
976   "vmuleub %0,%1,%2"
977   [(set_attr "type" "veccomplex")])
979 (define_insn "vec_widen_smult_even_v16qi"
980   [(set (match_operand:V8HI 0 "register_operand" "=v")
981         (unspec:V8HI [(match_operand:V16QI 1 "register_operand" "v")
982                       (match_operand:V16QI 2 "register_operand" "v")]
983                      UNSPEC_VMULESB))]
984   "TARGET_ALTIVEC"
985   "vmulesb %0,%1,%2"
986   [(set_attr "type" "veccomplex")])
988 (define_insn "vec_widen_umult_even_v8hi"
989   [(set (match_operand:V4SI 0 "register_operand" "=v")
990         (unspec:V4SI [(match_operand:V8HI 1 "register_operand" "v")
991                       (match_operand:V8HI 2 "register_operand" "v")]
992                      UNSPEC_VMULEUH))]
993   "TARGET_ALTIVEC"
994   "vmuleuh %0,%1,%2"
995   [(set_attr "type" "veccomplex")])
997 (define_insn "vec_widen_smult_even_v8hi"
998   [(set (match_operand:V4SI 0 "register_operand" "=v")
999         (unspec:V4SI [(match_operand:V8HI 1 "register_operand" "v")
1000                       (match_operand:V8HI 2 "register_operand" "v")]
1001                      UNSPEC_VMULESH))]
1002   "TARGET_ALTIVEC"
1003   "vmulesh %0,%1,%2"
1004   [(set_attr "type" "veccomplex")])
1006 (define_insn "vec_widen_umult_odd_v16qi"
1007   [(set (match_operand:V8HI 0 "register_operand" "=v")
1008         (unspec:V8HI [(match_operand:V16QI 1 "register_operand" "v")
1009                       (match_operand:V16QI 2 "register_operand" "v")]
1010                      UNSPEC_VMULOUB))]
1011   "TARGET_ALTIVEC"
1012   "vmuloub %0,%1,%2"
1013   [(set_attr "type" "veccomplex")])
1015 (define_insn "vec_widen_smult_odd_v16qi"
1016   [(set (match_operand:V8HI 0 "register_operand" "=v")
1017         (unspec:V8HI [(match_operand:V16QI 1 "register_operand" "v")
1018                       (match_operand:V16QI 2 "register_operand" "v")]
1019                      UNSPEC_VMULOSB))]
1020   "TARGET_ALTIVEC"
1021   "vmulosb %0,%1,%2"
1022   [(set_attr "type" "veccomplex")])
1024 (define_insn "vec_widen_umult_odd_v8hi"
1025   [(set (match_operand:V4SI 0 "register_operand" "=v")
1026         (unspec:V4SI [(match_operand:V8HI 1 "register_operand" "v")
1027                       (match_operand:V8HI 2 "register_operand" "v")]
1028                      UNSPEC_VMULOUH))]
1029   "TARGET_ALTIVEC"
1030   "vmulouh %0,%1,%2"
1031   [(set_attr "type" "veccomplex")])
1033 (define_insn "vec_widen_smult_odd_v8hi"
1034   [(set (match_operand:V4SI 0 "register_operand" "=v")
1035         (unspec:V4SI [(match_operand:V8HI 1 "register_operand" "v")
1036                       (match_operand:V8HI 2 "register_operand" "v")]
1037                      UNSPEC_VMULOSH))]
1038   "TARGET_ALTIVEC"
1039   "vmulosh %0,%1,%2"
1040   [(set_attr "type" "veccomplex")])
1043 ;; Vector pack/unpack
1044 (define_insn "altivec_vpkpx"
1045   [(set (match_operand:V8HI 0 "register_operand" "=v")
1046         (unspec:V8HI [(match_operand:V4SI 1 "register_operand" "v")
1047                       (match_operand:V4SI 2 "register_operand" "v")]
1048                      UNSPEC_VPKPX))]
1049   "TARGET_ALTIVEC"
1050   "*
1051   {
1052     if (BYTES_BIG_ENDIAN)
1053       return \"vpkpx %0,%1,%2\";
1054     else
1055       return \"vpkpx %0,%2,%1\";
1056   }"
1057   [(set_attr "type" "vecperm")])
1059 (define_insn "altivec_vpks<VI_char>ss"
1060   [(set (match_operand:<VP_small> 0 "register_operand" "=v")
1061         (unspec:<VP_small> [(match_operand:VP 1 "register_operand" "v")
1062                             (match_operand:VP 2 "register_operand" "v")]
1063                            UNSPEC_VPACK_SIGN_SIGN_SAT))]
1064   "<VI_unit>"
1065   "*
1066   {
1067     if (BYTES_BIG_ENDIAN)
1068       return \"vpks<VI_char>ss %0,%1,%2\";
1069     else
1070       return \"vpks<VI_char>ss %0,%2,%1\";
1071   }"
1072   [(set_attr "type" "vecperm")])
1074 (define_insn "altivec_vpks<VI_char>us"
1075   [(set (match_operand:<VP_small> 0 "register_operand" "=v")
1076         (unspec:<VP_small> [(match_operand:VP 1 "register_operand" "v")
1077                             (match_operand:VP 2 "register_operand" "v")]
1078                            UNSPEC_VPACK_SIGN_UNS_SAT))]
1079   "<VI_unit>"
1080   "*
1081   {
1082     if (BYTES_BIG_ENDIAN)
1083       return \"vpks<VI_char>us %0,%1,%2\";
1084     else
1085       return \"vpks<VI_char>us %0,%2,%1\";
1086   }"
1087   [(set_attr "type" "vecperm")])
1089 (define_insn "altivec_vpku<VI_char>us"
1090   [(set (match_operand:<VP_small> 0 "register_operand" "=v")
1091         (unspec:<VP_small> [(match_operand:VP 1 "register_operand" "v")
1092                             (match_operand:VP 2 "register_operand" "v")]
1093                            UNSPEC_VPACK_UNS_UNS_SAT))]
1094   "<VI_unit>"
1095   "*
1096   {
1097     if (BYTES_BIG_ENDIAN)
1098       return \"vpku<VI_char>us %0,%1,%2\";
1099     else
1100       return \"vpku<VI_char>us %0,%2,%1\";
1101   }"
1102   [(set_attr "type" "vecperm")])
1104 (define_insn "altivec_vpku<VI_char>um"
1105   [(set (match_operand:<VP_small> 0 "register_operand" "=v")
1106         (unspec:<VP_small> [(match_operand:VP 1 "register_operand" "v")
1107                             (match_operand:VP 2 "register_operand" "v")]
1108                            UNSPEC_VPACK_UNS_UNS_MOD))]
1109   "<VI_unit>"
1110   "*
1111   {
1112     if (BYTES_BIG_ENDIAN)
1113       return \"vpku<VI_char>um %0,%1,%2\";
1114     else
1115       return \"vpku<VI_char>um %0,%2,%1\";
1116   }"
1117   [(set_attr "type" "vecperm")])
1119 (define_insn "*altivec_vrl<VI_char>"
1120   [(set (match_operand:VI2 0 "register_operand" "=v")
1121         (rotate:VI2 (match_operand:VI2 1 "register_operand" "v")
1122                     (match_operand:VI2 2 "register_operand" "v")))]
1123   "<VI_unit>"
1124   "vrl<VI_char> %0,%1,%2"
1125   [(set_attr "type" "vecsimple")])
1127 (define_insn "altivec_vsl"
1128   [(set (match_operand:V4SI 0 "register_operand" "=v")
1129         (unspec:V4SI [(match_operand:V4SI 1 "register_operand" "v")
1130                       (match_operand:V4SI 2 "register_operand" "v")]
1131                      UNSPEC_VSLV4SI))]
1132   "TARGET_ALTIVEC"
1133   "vsl %0,%1,%2"
1134   [(set_attr "type" "vecperm")])
1136 (define_insn "altivec_vslo"
1137   [(set (match_operand:V4SI 0 "register_operand" "=v")
1138         (unspec:V4SI [(match_operand:V4SI 1 "register_operand" "v")
1139                       (match_operand:V4SI 2 "register_operand" "v")]
1140                      UNSPEC_VSLO))]
1141   "TARGET_ALTIVEC"
1142   "vslo %0,%1,%2"
1143   [(set_attr "type" "vecperm")])
1145 (define_insn "*altivec_vsl<VI_char>"
1146   [(set (match_operand:VI2 0 "register_operand" "=v")
1147         (ashift:VI2 (match_operand:VI2 1 "register_operand" "v")
1148                     (match_operand:VI2 2 "register_operand" "v")))]
1149   "<VI_unit>"
1150   "vsl<VI_char> %0,%1,%2"
1151   [(set_attr "type" "vecsimple")])
1153 (define_insn "*altivec_vsr<VI_char>"
1154   [(set (match_operand:VI2 0 "register_operand" "=v")
1155         (lshiftrt:VI2 (match_operand:VI2 1 "register_operand" "v")
1156                       (match_operand:VI2 2 "register_operand" "v")))]
1157   "<VI_unit>"
1158   "vsr<VI_char> %0,%1,%2"
1159   [(set_attr "type" "vecsimple")])
1161 (define_insn "*altivec_vsra<VI_char>"
1162   [(set (match_operand:VI2 0 "register_operand" "=v")
1163         (ashiftrt:VI2 (match_operand:VI2 1 "register_operand" "v")
1164                       (match_operand:VI2 2 "register_operand" "v")))]
1165   "<VI_unit>"
1166   "vsra<VI_char> %0,%1,%2"
1167   [(set_attr "type" "vecsimple")])
1169 (define_insn "altivec_vsr"
1170   [(set (match_operand:V4SI 0 "register_operand" "=v")
1171         (unspec:V4SI [(match_operand:V4SI 1 "register_operand" "v")
1172                       (match_operand:V4SI 2 "register_operand" "v")]
1173                      UNSPEC_VSR))]
1174   "TARGET_ALTIVEC"
1175   "vsr %0,%1,%2"
1176   [(set_attr "type" "vecperm")])
1178 (define_insn "altivec_vsro"
1179   [(set (match_operand:V4SI 0 "register_operand" "=v")
1180         (unspec:V4SI [(match_operand:V4SI 1 "register_operand" "v")
1181                       (match_operand:V4SI 2 "register_operand" "v")]
1182                      UNSPEC_VSRO))]
1183   "TARGET_ALTIVEC"
1184   "vsro %0,%1,%2"
1185   [(set_attr "type" "vecperm")])
1187 (define_insn "altivec_vsum4ubs"
1188   [(set (match_operand:V4SI 0 "register_operand" "=v")
1189         (unspec:V4SI [(match_operand:V16QI 1 "register_operand" "v")
1190                       (match_operand:V4SI 2 "register_operand" "v")]
1191                      UNSPEC_VSUM4UBS))
1192    (set (reg:SI 110) (unspec:SI [(const_int 0)] UNSPEC_SET_VSCR))]
1193   "TARGET_ALTIVEC"
1194   "vsum4ubs %0,%1,%2"
1195   [(set_attr "type" "veccomplex")])
1197 (define_insn "altivec_vsum4s<VI_char>s"
1198   [(set (match_operand:V4SI 0 "register_operand" "=v")
1199         (unspec:V4SI [(match_operand:VIshort 1 "register_operand" "v")
1200                       (match_operand:V4SI 2 "register_operand" "v")]
1201                      UNSPEC_VSUM4S))
1202    (set (reg:SI 110) (unspec:SI [(const_int 0)] UNSPEC_SET_VSCR))]
1203   "TARGET_ALTIVEC"
1204   "vsum4s<VI_char>s %0,%1,%2"
1205   [(set_attr "type" "veccomplex")])
1207 (define_insn "altivec_vsum2sws"
1208   [(set (match_operand:V4SI 0 "register_operand" "=v")
1209         (unspec:V4SI [(match_operand:V4SI 1 "register_operand" "v")
1210                       (match_operand:V4SI 2 "register_operand" "v")]
1211                      UNSPEC_VSUM2SWS))
1212    (set (reg:SI 110) (unspec:SI [(const_int 0)] UNSPEC_SET_VSCR))]
1213   "TARGET_ALTIVEC"
1214   "vsum2sws %0,%1,%2"
1215   [(set_attr "type" "veccomplex")])
1217 (define_insn "altivec_vsumsws"
1218   [(set (match_operand:V4SI 0 "register_operand" "=v")
1219         (unspec:V4SI [(match_operand:V4SI 1 "register_operand" "v")
1220                       (match_operand:V4SI 2 "register_operand" "v")]
1221                      UNSPEC_VSUMSWS))
1222    (set (reg:SI 110) (unspec:SI [(const_int 0)] UNSPEC_SET_VSCR))]
1223   "TARGET_ALTIVEC"
1224   "vsumsws %0,%1,%2"
1225   [(set_attr "type" "veccomplex")])
1227 (define_insn "altivec_vspltb"
1228   [(set (match_operand:V16QI 0 "register_operand" "=v")
1229         (vec_duplicate:V16QI
1230          (vec_select:QI (match_operand:V16QI 1 "register_operand" "v")
1231                         (parallel
1232                          [(match_operand:QI 2 "u5bit_cint_operand" "")]))))]
1233   "TARGET_ALTIVEC"
1234   "vspltb %0,%1,%2"
1235   [(set_attr "type" "vecperm")])
1237 (define_insn "altivec_vsplth"
1238   [(set (match_operand:V8HI 0 "register_operand" "=v")
1239         (vec_duplicate:V8HI
1240          (vec_select:HI (match_operand:V8HI 1 "register_operand" "v")
1241                         (parallel
1242                          [(match_operand:QI 2 "u5bit_cint_operand" "")]))))]
1243   "TARGET_ALTIVEC"
1244   "vsplth %0,%1,%2"
1245   [(set_attr "type" "vecperm")])
1247 (define_insn "altivec_vspltw"
1248   [(set (match_operand:V4SI 0 "register_operand" "=v")
1249         (vec_duplicate:V4SI
1250          (vec_select:SI (match_operand:V4SI 1 "register_operand" "v")
1251                         (parallel
1252                          [(match_operand:QI 2 "u5bit_cint_operand" "i")]))))]
1253   "TARGET_ALTIVEC"
1254   "vspltw %0,%1,%2"
1255   [(set_attr "type" "vecperm")])
1257 (define_insn "altivec_vspltsf"
1258   [(set (match_operand:V4SF 0 "register_operand" "=v")
1259         (vec_duplicate:V4SF
1260          (vec_select:SF (match_operand:V4SF 1 "register_operand" "v")
1261                         (parallel
1262                          [(match_operand:QI 2 "u5bit_cint_operand" "i")]))))]
1263   "VECTOR_UNIT_ALTIVEC_P (V4SFmode)"
1264   "vspltw %0,%1,%2"
1265   [(set_attr "type" "vecperm")])
1267 (define_insn "altivec_vspltis<VI_char>"
1268   [(set (match_operand:VI 0 "register_operand" "=v")
1269         (vec_duplicate:VI
1270          (match_operand:QI 1 "s5bit_cint_operand" "i")))]
1271   "TARGET_ALTIVEC"
1272   "vspltis<VI_char> %0,%1"
1273   [(set_attr "type" "vecperm")])
1275 (define_insn "*altivec_vrfiz"
1276   [(set (match_operand:V4SF 0 "register_operand" "=v")
1277         (fix:V4SF (match_operand:V4SF 1 "register_operand" "v")))]
1278   "VECTOR_UNIT_ALTIVEC_P (V4SFmode)"
1279   "vrfiz %0,%1"
1280   [(set_attr "type" "vecfloat")])
1282 (define_insn "altivec_vperm_<mode>"
1283   [(set (match_operand:VM 0 "register_operand" "=v")
1284         (unspec:VM [(match_operand:VM 1 "register_operand" "v")
1285                     (match_operand:VM 2 "register_operand" "v")
1286                     (match_operand:V16QI 3 "register_operand" "v")]
1287                    UNSPEC_VPERM))]
1288   "TARGET_ALTIVEC"
1289   "vperm %0,%1,%2,%3"
1290   [(set_attr "type" "vecperm")])
1292 (define_insn "altivec_vperm_<mode>_uns"
1293   [(set (match_operand:VM 0 "register_operand" "=v")
1294         (unspec:VM [(match_operand:VM 1 "register_operand" "v")
1295                     (match_operand:VM 2 "register_operand" "v")
1296                     (match_operand:V16QI 3 "register_operand" "v")]
1297                    UNSPEC_VPERM_UNS))]
1298   "TARGET_ALTIVEC"
1299   "vperm %0,%1,%2,%3"
1300   [(set_attr "type" "vecperm")])
1302 (define_expand "vec_permv16qi"
1303   [(set (match_operand:V16QI 0 "register_operand" "")
1304         (unspec:V16QI [(match_operand:V16QI 1 "register_operand" "")
1305                        (match_operand:V16QI 2 "register_operand" "")
1306                        (match_operand:V16QI 3 "register_operand" "")]
1307                       UNSPEC_VPERM))]
1308   "TARGET_ALTIVEC"
1309   "")
1311 (define_expand "vec_perm_constv16qi"
1312   [(match_operand:V16QI 0 "register_operand" "")
1313    (match_operand:V16QI 1 "register_operand" "")
1314    (match_operand:V16QI 2 "register_operand" "")
1315    (match_operand:V16QI 3 "" "")]
1316   "TARGET_ALTIVEC"
1318   if (altivec_expand_vec_perm_const (operands))
1319     DONE;
1320   else
1321     FAIL;
1324 (define_insn "altivec_vrfip"            ; ceil
1325   [(set (match_operand:V4SF 0 "register_operand" "=v")
1326         (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "v")]
1327                      UNSPEC_FRIP))]
1328   "TARGET_ALTIVEC"
1329   "vrfip %0,%1"
1330   [(set_attr "type" "vecfloat")])
1332 (define_insn "altivec_vrfin"
1333   [(set (match_operand:V4SF 0 "register_operand" "=v")
1334         (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "v")]
1335                      UNSPEC_VRFIN))]
1336   "TARGET_ALTIVEC"
1337   "vrfin %0,%1"
1338   [(set_attr "type" "vecfloat")])
1340 (define_insn "*altivec_vrfim"           ; floor
1341   [(set (match_operand:V4SF 0 "register_operand" "=v")
1342         (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "v")]
1343                      UNSPEC_FRIM))]
1344   "TARGET_ALTIVEC"
1345   "vrfim %0,%1"
1346   [(set_attr "type" "vecfloat")])
1348 (define_insn "altivec_vcfux"
1349   [(set (match_operand:V4SF 0 "register_operand" "=v")
1350         (unspec:V4SF [(match_operand:V4SI 1 "register_operand" "v")
1351                       (match_operand:QI 2 "immediate_operand" "i")]
1352                      UNSPEC_VCFUX))]
1353   "TARGET_ALTIVEC"
1354   "vcfux %0,%1,%2"
1355   [(set_attr "type" "vecfloat")])
1357 (define_insn "altivec_vcfsx"
1358   [(set (match_operand:V4SF 0 "register_operand" "=v")
1359         (unspec:V4SF [(match_operand:V4SI 1 "register_operand" "v")
1360                       (match_operand:QI 2 "immediate_operand" "i")]
1361                      UNSPEC_VCFSX))]
1362   "TARGET_ALTIVEC"
1363   "vcfsx %0,%1,%2"
1364   [(set_attr "type" "vecfloat")])
1366 (define_insn "altivec_vctuxs"
1367   [(set (match_operand:V4SI 0 "register_operand" "=v")
1368         (unspec:V4SI [(match_operand:V4SF 1 "register_operand" "v")
1369                       (match_operand:QI 2 "immediate_operand" "i")]
1370                      UNSPEC_VCTUXS))
1371    (set (reg:SI 110) (unspec:SI [(const_int 0)] UNSPEC_SET_VSCR))]
1372   "TARGET_ALTIVEC"
1373   "vctuxs %0,%1,%2"
1374   [(set_attr "type" "vecfloat")])
1376 (define_insn "altivec_vctsxs"
1377   [(set (match_operand:V4SI 0 "register_operand" "=v")
1378         (unspec:V4SI [(match_operand:V4SF 1 "register_operand" "v")
1379                       (match_operand:QI 2 "immediate_operand" "i")]
1380                      UNSPEC_VCTSXS))
1381    (set (reg:SI 110) (unspec:SI [(const_int 0)] UNSPEC_SET_VSCR))]
1382   "TARGET_ALTIVEC"
1383   "vctsxs %0,%1,%2"
1384   [(set_attr "type" "vecfloat")])
1386 (define_insn "altivec_vlogefp"
1387   [(set (match_operand:V4SF 0 "register_operand" "=v")
1388         (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "v")]
1389                      UNSPEC_VLOGEFP))]
1390   "TARGET_ALTIVEC"
1391   "vlogefp %0,%1"
1392   [(set_attr "type" "vecfloat")])
1394 (define_insn "altivec_vexptefp"
1395   [(set (match_operand:V4SF 0 "register_operand" "=v")
1396         (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "v")]
1397                      UNSPEC_VEXPTEFP))]
1398   "TARGET_ALTIVEC"
1399   "vexptefp %0,%1"
1400   [(set_attr "type" "vecfloat")])
1402 (define_insn "*altivec_vrsqrtefp"
1403   [(set (match_operand:V4SF 0 "register_operand" "=v")
1404         (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "v")]
1405                      UNSPEC_RSQRT))]
1406   "VECTOR_UNIT_ALTIVEC_P (V4SFmode)"
1407   "vrsqrtefp %0,%1"
1408   [(set_attr "type" "vecfloat")])
1410 (define_insn "altivec_vrefp"
1411   [(set (match_operand:V4SF 0 "register_operand" "=v")
1412         (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "v")]
1413                      UNSPEC_FRES))]
1414   "VECTOR_UNIT_ALTIVEC_P (V4SFmode)"
1415   "vrefp %0,%1"
1416   [(set_attr "type" "vecfloat")])
1418 (define_expand "altivec_copysign_v4sf3"
1419   [(use (match_operand:V4SF 0 "register_operand" ""))
1420    (use (match_operand:V4SF 1 "register_operand" ""))
1421    (use (match_operand:V4SF 2 "register_operand" ""))]
1422   "VECTOR_UNIT_ALTIVEC_P (V4SFmode)"
1423   "
1425   rtx mask = gen_reg_rtx (V4SImode);
1426   rtvec v = rtvec_alloc (4);
1427   unsigned HOST_WIDE_INT mask_val = ((unsigned HOST_WIDE_INT)1) << 31;
1429   RTVEC_ELT (v, 0) = GEN_INT (mask_val);
1430   RTVEC_ELT (v, 1) = GEN_INT (mask_val);
1431   RTVEC_ELT (v, 2) = GEN_INT (mask_val);
1432   RTVEC_ELT (v, 3) = GEN_INT (mask_val);
1434   emit_insn (gen_vec_initv4si (mask, gen_rtx_PARALLEL (V4SImode, v)));
1435   emit_insn (gen_vector_select_v4sf (operands[0], operands[1], operands[2],
1436                                      gen_lowpart (V4SFmode, mask)));
1437   DONE;
1440 (define_insn "altivec_vsldoi_<mode>"
1441   [(set (match_operand:VM 0 "register_operand" "=v")
1442         (unspec:VM [(match_operand:VM 1 "register_operand" "v")
1443                     (match_operand:VM 2 "register_operand" "v")
1444                     (match_operand:QI 3 "immediate_operand" "i")]
1445                   UNSPEC_VLSDOI))]
1446   "TARGET_ALTIVEC"
1447   "vsldoi %0,%1,%2,%3"
1448   [(set_attr "type" "vecperm")])
1450 (define_insn "altivec_vupkhs<VU_char>"
1451   [(set (match_operand:VP 0 "register_operand" "=v")
1452         (unspec:VP [(match_operand:<VP_small> 1 "register_operand" "v")]
1453                      UNSPEC_VUNPACK_HI_SIGN))]
1454   "<VI_unit>"
1455   "vupkhs<VU_char> %0,%1"
1456   [(set_attr "type" "vecperm")])
1458 (define_insn "altivec_vupkls<VU_char>"
1459   [(set (match_operand:VP 0 "register_operand" "=v")
1460         (unspec:VP [(match_operand:<VP_small> 1 "register_operand" "v")]
1461                      UNSPEC_VUNPACK_LO_SIGN))]
1462   "<VI_unit>"
1463   "vupkls<VU_char> %0,%1"
1464   [(set_attr "type" "vecperm")])
1466 (define_insn "altivec_vupkhpx"
1467   [(set (match_operand:V4SI 0 "register_operand" "=v")
1468         (unspec:V4SI [(match_operand:V8HI 1 "register_operand" "v")]
1469                      UNSPEC_VUPKHPX))]
1470   "TARGET_ALTIVEC"
1471   "vupkhpx %0,%1"
1472   [(set_attr "type" "vecperm")])
1474 (define_insn "altivec_vupklpx"
1475   [(set (match_operand:V4SI 0 "register_operand" "=v")
1476         (unspec:V4SI [(match_operand:V8HI 1 "register_operand" "v")]
1477                      UNSPEC_VUPKLPX))]
1478   "TARGET_ALTIVEC"
1479   "vupklpx %0,%1"
1480   [(set_attr "type" "vecperm")])
1482 ;; Compare vectors producing a vector result and a predicate, setting CR6 to
1483 ;; indicate a combined status
1484 (define_insn "*altivec_vcmpequ<VI_char>_p"
1485   [(set (reg:CC 74)
1486         (unspec:CC [(eq:CC (match_operand:VI2 1 "register_operand" "v")
1487                            (match_operand:VI2 2 "register_operand" "v"))]
1488                    UNSPEC_PREDICATE))
1489    (set (match_operand:VI2 0 "register_operand" "=v")
1490         (eq:VI2 (match_dup 1)
1491                 (match_dup 2)))]
1492   "<VI_unit>"
1493   "vcmpequ<VI_char>. %0,%1,%2"
1494   [(set_attr "type" "veccmp")])
1496 (define_insn "*altivec_vcmpgts<VI_char>_p"
1497   [(set (reg:CC 74)
1498         (unspec:CC [(gt:CC (match_operand:VI2 1 "register_operand" "v")
1499                            (match_operand:VI2 2 "register_operand" "v"))]
1500                    UNSPEC_PREDICATE))
1501    (set (match_operand:VI2 0 "register_operand" "=v")
1502         (gt:VI2 (match_dup 1)
1503                 (match_dup 2)))]
1504   "<VI_unit>"
1505   "vcmpgts<VI_char>. %0,%1,%2"
1506   [(set_attr "type" "veccmp")])
1508 (define_insn "*altivec_vcmpgtu<VI_char>_p"
1509   [(set (reg:CC 74)
1510         (unspec:CC [(gtu:CC (match_operand:VI2 1 "register_operand" "v")
1511                             (match_operand:VI2 2 "register_operand" "v"))]
1512                    UNSPEC_PREDICATE))
1513    (set (match_operand:VI2 0 "register_operand" "=v")
1514         (gtu:VI2 (match_dup 1)
1515                  (match_dup 2)))]
1516   "<VI_unit>"
1517   "vcmpgtu<VI_char>. %0,%1,%2"
1518   [(set_attr "type" "veccmp")])
1520 (define_insn "*altivec_vcmpeqfp_p"
1521   [(set (reg:CC 74)
1522         (unspec:CC [(eq:CC (match_operand:V4SF 1 "register_operand" "v")
1523                            (match_operand:V4SF 2 "register_operand" "v"))]
1524                    UNSPEC_PREDICATE))
1525    (set (match_operand:V4SF 0 "register_operand" "=v")
1526         (eq:V4SF (match_dup 1)
1527                  (match_dup 2)))]
1528   "VECTOR_UNIT_ALTIVEC_P (V4SFmode)"
1529   "vcmpeqfp. %0,%1,%2"
1530   [(set_attr "type" "veccmp")])
1532 (define_insn "*altivec_vcmpgtfp_p"
1533   [(set (reg:CC 74)
1534         (unspec:CC [(gt:CC (match_operand:V4SF 1 "register_operand" "v")
1535                            (match_operand:V4SF 2 "register_operand" "v"))]
1536                    UNSPEC_PREDICATE))
1537    (set (match_operand:V4SF 0 "register_operand" "=v")
1538         (gt:V4SF (match_dup 1)
1539                  (match_dup 2)))]
1540   "VECTOR_UNIT_ALTIVEC_P (V4SFmode)"
1541   "vcmpgtfp. %0,%1,%2"
1542   [(set_attr "type" "veccmp")])
1544 (define_insn "*altivec_vcmpgefp_p"
1545   [(set (reg:CC 74)
1546         (unspec:CC [(ge:CC (match_operand:V4SF 1 "register_operand" "v")
1547                            (match_operand:V4SF 2 "register_operand" "v"))]
1548                    UNSPEC_PREDICATE))
1549    (set (match_operand:V4SF 0 "register_operand" "=v")
1550         (ge:V4SF (match_dup 1)
1551                  (match_dup 2)))]
1552   "VECTOR_UNIT_ALTIVEC_P (V4SFmode)"
1553   "vcmpgefp. %0,%1,%2"
1554   [(set_attr "type" "veccmp")])
1556 (define_insn "altivec_vcmpbfp_p"
1557   [(set (reg:CC 74)
1558         (unspec:CC [(match_operand:V4SF 1 "register_operand" "v")
1559                     (match_operand:V4SF 2 "register_operand" "v")]
1560                    UNSPEC_VCMPBFP))
1561    (set (match_operand:V4SF 0 "register_operand" "=v")
1562         (unspec:V4SF [(match_dup 1)
1563                       (match_dup 2)] 
1564                       UNSPEC_VCMPBFP))]
1565   "VECTOR_UNIT_ALTIVEC_OR_VSX_P (V4SFmode)"
1566   "vcmpbfp. %0,%1,%2"
1567   [(set_attr "type" "veccmp")])
1569 (define_insn "altivec_mtvscr"
1570   [(set (reg:SI 110)
1571         (unspec_volatile:SI
1572          [(match_operand:V4SI 0 "register_operand" "v")] UNSPECV_MTVSCR))]
1573   "TARGET_ALTIVEC"
1574   "mtvscr %0"
1575   [(set_attr "type" "vecsimple")])
1577 (define_insn "altivec_mfvscr"
1578   [(set (match_operand:V8HI 0 "register_operand" "=v")
1579         (unspec_volatile:V8HI [(reg:SI 110)] UNSPECV_MFVSCR))]
1580   "TARGET_ALTIVEC"
1581   "mfvscr %0"
1582   [(set_attr "type" "vecsimple")])
1584 (define_insn "altivec_dssall"
1585   [(unspec_volatile [(const_int 0)] UNSPECV_DSSALL)]
1586   "TARGET_ALTIVEC"
1587   "dssall"
1588   [(set_attr "type" "vecsimple")])
1590 (define_insn "altivec_dss"
1591   [(unspec_volatile [(match_operand:QI 0 "immediate_operand" "i")]
1592                     UNSPECV_DSS)]
1593   "TARGET_ALTIVEC"
1594   "dss %0"
1595   [(set_attr "type" "vecsimple")])
1597 (define_insn "altivec_dst"
1598   [(unspec [(match_operand 0 "register_operand" "b")
1599             (match_operand:SI 1 "register_operand" "r")
1600             (match_operand:QI 2 "immediate_operand" "i")] UNSPEC_DST)]
1601   "TARGET_ALTIVEC && GET_MODE (operands[0]) == Pmode"
1602   "dst %0,%1,%2"
1603   [(set_attr "type" "vecsimple")])
1605 (define_insn "altivec_dstt"
1606   [(unspec [(match_operand 0 "register_operand" "b")
1607             (match_operand:SI 1 "register_operand" "r")
1608             (match_operand:QI 2 "immediate_operand" "i")] UNSPEC_DSTT)]
1609   "TARGET_ALTIVEC && GET_MODE (operands[0]) == Pmode"
1610   "dstt %0,%1,%2"
1611   [(set_attr "type" "vecsimple")])
1613 (define_insn "altivec_dstst"
1614   [(unspec [(match_operand 0 "register_operand" "b")
1615             (match_operand:SI 1 "register_operand" "r")
1616             (match_operand:QI 2 "immediate_operand" "i")] UNSPEC_DSTST)]
1617   "TARGET_ALTIVEC && GET_MODE (operands[0]) == Pmode"
1618   "dstst %0,%1,%2"
1619   [(set_attr "type" "vecsimple")])
1621 (define_insn "altivec_dststt"
1622   [(unspec [(match_operand 0 "register_operand" "b")
1623             (match_operand:SI 1 "register_operand" "r")
1624             (match_operand:QI 2 "immediate_operand" "i")] UNSPEC_DSTSTT)]
1625   "TARGET_ALTIVEC && GET_MODE (operands[0]) == Pmode"
1626   "dststt %0,%1,%2"
1627   [(set_attr "type" "vecsimple")])
1629 (define_insn "altivec_lvsl"
1630   [(set (match_operand:V16QI 0 "register_operand" "=v")
1631         (unspec:V16QI [(match_operand:V16QI 1 "memory_operand" "Z")]
1632                       UNSPEC_LVSL))]
1633   "TARGET_ALTIVEC"
1634   "lvsl %0,%y1"
1635   [(set_attr "type" "vecload")])
1637 (define_insn "altivec_lvsr"
1638   [(set (match_operand:V16QI 0 "register_operand" "=v")
1639         (unspec:V16QI [(match_operand:V16QI 1 "memory_operand" "Z")]
1640                       UNSPEC_LVSR))]
1641   "TARGET_ALTIVEC"
1642   "lvsr %0,%y1"
1643   [(set_attr "type" "vecload")])
1645 (define_expand "build_vector_mask_for_load"
1646   [(set (match_operand:V16QI 0 "register_operand" "")
1647         (unspec:V16QI [(match_operand 1 "memory_operand" "")] UNSPEC_LVSR))]
1648   "TARGET_ALTIVEC"
1649   "
1651   rtx addr;
1652   rtx temp;
1654   gcc_assert (GET_CODE (operands[1]) == MEM);
1656   addr = XEXP (operands[1], 0);
1657   temp = gen_reg_rtx (GET_MODE (addr));
1658   emit_insn (gen_rtx_SET (VOIDmode, temp, 
1659                           gen_rtx_NEG (GET_MODE (addr), addr)));
1660   emit_insn (gen_altivec_lvsr (operands[0], 
1661                                replace_equiv_address (operands[1], temp)));
1662   DONE;
1665 ;; Parallel some of the LVE* and STV*'s with unspecs because some have
1666 ;; identical rtl but different instructions-- and gcc gets confused.
1668 (define_insn "altivec_lve<VI_char>x"
1669   [(parallel
1670     [(set (match_operand:VI 0 "register_operand" "=v")
1671           (match_operand:VI 1 "memory_operand" "Z"))
1672      (unspec [(const_int 0)] UNSPEC_LVE)])]
1673   "TARGET_ALTIVEC"
1674   "lve<VI_char>x %0,%y1"
1675   [(set_attr "type" "vecload")])
1677 (define_insn "*altivec_lvesfx"
1678   [(parallel
1679     [(set (match_operand:V4SF 0 "register_operand" "=v")
1680           (match_operand:V4SF 1 "memory_operand" "Z"))
1681      (unspec [(const_int 0)] UNSPEC_LVE)])]
1682   "TARGET_ALTIVEC"
1683   "lvewx %0,%y1"
1684   [(set_attr "type" "vecload")])
1686 (define_insn "altivec_lvxl"
1687   [(parallel
1688     [(set (match_operand:V4SI 0 "register_operand" "=v")
1689           (match_operand:V4SI 1 "memory_operand" "Z"))
1690      (unspec [(const_int 0)] UNSPEC_SET_VSCR)])]
1691   "TARGET_ALTIVEC"
1692   "lvxl %0,%y1"
1693   [(set_attr "type" "vecload")])
1695 (define_insn "altivec_lvx_<mode>"
1696   [(parallel
1697     [(set (match_operand:VM2 0 "register_operand" "=v")
1698           (match_operand:VM2 1 "memory_operand" "Z"))
1699      (unspec [(const_int 0)] UNSPEC_LVX)])]
1700   "TARGET_ALTIVEC"
1701   "lvx %0,%y1"
1702   [(set_attr "type" "vecload")])
1704 (define_insn "altivec_stvx_<mode>"
1705   [(parallel
1706     [(set (match_operand:VM2 0 "memory_operand" "=Z")
1707           (match_operand:VM2 1 "register_operand" "v"))
1708      (unspec [(const_int 0)] UNSPEC_STVX)])]
1709   "TARGET_ALTIVEC"
1710   "stvx %1,%y0"
1711   [(set_attr "type" "vecstore")])
1713 (define_insn "altivec_stvxl"
1714   [(parallel
1715     [(set (match_operand:V4SI 0 "memory_operand" "=Z")
1716           (match_operand:V4SI 1 "register_operand" "v"))
1717      (unspec [(const_int 0)] UNSPEC_STVXL)])]
1718   "TARGET_ALTIVEC"
1719   "stvxl %1,%y0"
1720   [(set_attr "type" "vecstore")])
1722 (define_insn "altivec_stve<VI_char>x"
1723   [(set (match_operand:<VI_scalar> 0 "memory_operand" "=Z")
1724         (unspec:<VI_scalar> [(match_operand:VI 1 "register_operand" "v")] UNSPEC_STVE))]
1725   "TARGET_ALTIVEC"
1726   "stve<VI_char>x %1,%y0"
1727   [(set_attr "type" "vecstore")])
1729 (define_insn "*altivec_stvesfx"
1730   [(set (match_operand:SF 0 "memory_operand" "=Z")
1731         (unspec:SF [(match_operand:V4SF 1 "register_operand" "v")] UNSPEC_STVE))]
1732   "TARGET_ALTIVEC"
1733   "stvewx %1,%y0"
1734   [(set_attr "type" "vecstore")])
1736 ;; Generate
1737 ;;    xxlxor/vxor SCRATCH0,SCRATCH0,SCRATCH0
1738 ;;    vsubu?m SCRATCH2,SCRATCH1,%1
1739 ;;    vmaxs? %0,%1,SCRATCH2"
1740 (define_expand "abs<mode>2"
1741   [(set (match_dup 2) (match_dup 3))
1742    (set (match_dup 4)
1743         (minus:VI2 (match_dup 2)
1744                    (match_operand:VI2 1 "register_operand" "v")))
1745    (set (match_operand:VI2 0 "register_operand" "=v")
1746         (smax:VI2 (match_dup 1) (match_dup 4)))]
1747   "<VI_unit>"
1749   int i, n_elt = GET_MODE_NUNITS (<MODE>mode);
1750   rtvec v = rtvec_alloc (n_elt);
1752   /* Create an all 0 constant.  */
1753   for (i = 0; i < n_elt; ++i)
1754     RTVEC_ELT (v, i) = const0_rtx;
1756   operands[2] = gen_reg_rtx (<MODE>mode);
1757   operands[3] = gen_rtx_CONST_VECTOR (<MODE>mode, v);
1758   operands[4] = gen_reg_rtx (<MODE>mode);
1761 ;; Generate
1762 ;;    vspltisw SCRATCH1,-1
1763 ;;    vslw SCRATCH2,SCRATCH1,SCRATCH1
1764 ;;    vandc %0,%1,SCRATCH2
1765 (define_expand "altivec_absv4sf2"
1766   [(set (match_dup 2)
1767         (vec_duplicate:V4SI (const_int -1)))
1768    (set (match_dup 3)
1769         (ashift:V4SI (match_dup 2) (match_dup 2)))
1770    (set (match_operand:V4SF 0 "register_operand" "=v")
1771         (and:V4SF (not:V4SF (subreg:V4SF (match_dup 3) 0))
1772                   (match_operand:V4SF 1 "register_operand" "v")))]
1773   "TARGET_ALTIVEC"
1775   operands[2] = gen_reg_rtx (V4SImode);
1776   operands[3] = gen_reg_rtx (V4SImode);
1779 ;; Generate
1780 ;;    vspltis? SCRATCH0,0
1781 ;;    vsubs?s SCRATCH2,SCRATCH1,%1
1782 ;;    vmaxs? %0,%1,SCRATCH2"
1783 (define_expand "altivec_abss_<mode>"
1784   [(set (match_dup 2) (vec_duplicate:VI (const_int 0)))
1785    (parallel [(set (match_dup 3)
1786                    (unspec:VI [(match_dup 2)
1787                                (match_operand:VI 1 "register_operand" "v")]
1788                               UNSPEC_VSUBS))
1789               (set (reg:SI 110) (unspec:SI [(const_int 0)] UNSPEC_SET_VSCR))])
1790    (set (match_operand:VI 0 "register_operand" "=v")
1791         (smax:VI (match_dup 1) (match_dup 3)))]
1792   "TARGET_ALTIVEC"
1794   operands[2] = gen_reg_rtx (GET_MODE (operands[0]));
1795   operands[3] = gen_reg_rtx (GET_MODE (operands[0]));
1798 (define_expand "reduc_splus_<mode>"
1799   [(set (match_operand:VIshort 0 "register_operand" "=v")
1800         (unspec:VIshort [(match_operand:VIshort 1 "register_operand" "v")]
1801                         UNSPEC_REDUC_PLUS))]
1802   "TARGET_ALTIVEC"
1804   rtx vzero = gen_reg_rtx (V4SImode);
1805   rtx vtmp1 = gen_reg_rtx (V4SImode);
1806   rtx dest = gen_lowpart (V4SImode, operands[0]);
1808   emit_insn (gen_altivec_vspltisw (vzero, const0_rtx));
1809   emit_insn (gen_altivec_vsum4s<VI_char>s (vtmp1, operands[1], vzero));
1810   emit_insn (gen_altivec_vsumsws (dest, vtmp1, vzero));
1811   DONE;
1814 (define_expand "reduc_uplus_v16qi"
1815   [(set (match_operand:V16QI 0 "register_operand" "=v")
1816         (unspec:V16QI [(match_operand:V16QI 1 "register_operand" "v")]
1817                       UNSPEC_REDUC_PLUS))]
1818   "TARGET_ALTIVEC"
1820   rtx vzero = gen_reg_rtx (V4SImode);
1821   rtx vtmp1 = gen_reg_rtx (V4SImode);
1822   rtx dest = gen_lowpart (V4SImode, operands[0]);
1824   emit_insn (gen_altivec_vspltisw (vzero, const0_rtx));
1825   emit_insn (gen_altivec_vsum4ubs (vtmp1, operands[1], vzero));
1826   emit_insn (gen_altivec_vsumsws (dest, vtmp1, vzero));
1827   DONE;
1830 (define_expand "neg<mode>2"
1831   [(use (match_operand:VI 0 "register_operand" ""))
1832    (use (match_operand:VI 1 "register_operand" ""))]
1833   "TARGET_ALTIVEC"
1834   "
1836   rtx vzero;
1838   vzero = gen_reg_rtx (GET_MODE (operands[0]));
1839   emit_insn (gen_altivec_vspltis<VI_char> (vzero, const0_rtx));
1840   emit_insn (gen_sub<mode>3 (operands[0], vzero, operands[1])); 
1841   
1842   DONE;
1845 (define_expand "udot_prod<mode>"
1846   [(set (match_operand:V4SI 0 "register_operand" "=v")
1847         (plus:V4SI (match_operand:V4SI 3 "register_operand" "v")
1848                    (unspec:V4SI [(match_operand:VIshort 1 "register_operand" "v")  
1849                                  (match_operand:VIshort 2 "register_operand" "v")] 
1850                                 UNSPEC_VMSUMU)))]
1851   "TARGET_ALTIVEC"
1852   "
1853 {  
1854   emit_insn (gen_altivec_vmsumu<VI_char>m (operands[0], operands[1], operands[2], operands[3]));
1855   DONE;
1857    
1858 (define_expand "sdot_prodv8hi"
1859   [(set (match_operand:V4SI 0 "register_operand" "=v")
1860         (plus:V4SI (match_operand:V4SI 3 "register_operand" "v")
1861                    (unspec:V4SI [(match_operand:V8HI 1 "register_operand" "v")
1862                                  (match_operand:V8HI 2 "register_operand" "v")]
1863                                 UNSPEC_VMSUMSHM)))]
1864   "TARGET_ALTIVEC"
1865   "
1867   emit_insn (gen_altivec_vmsumshm (operands[0], operands[1], operands[2], operands[3]));
1868   DONE;
1871 (define_expand "widen_usum<mode>3"
1872   [(set (match_operand:V4SI 0 "register_operand" "=v")
1873         (plus:V4SI (match_operand:V4SI 2 "register_operand" "v")
1874                    (unspec:V4SI [(match_operand:VIshort 1 "register_operand" "v")]
1875                                 UNSPEC_VMSUMU)))]
1876   "TARGET_ALTIVEC"
1877   "
1879   rtx vones = gen_reg_rtx (GET_MODE (operands[1]));
1881   emit_insn (gen_altivec_vspltis<VI_char> (vones, const1_rtx));
1882   emit_insn (gen_altivec_vmsumu<VI_char>m (operands[0], operands[1], vones, operands[2]));
1883   DONE;
1886 (define_expand "widen_ssumv16qi3"
1887   [(set (match_operand:V4SI 0 "register_operand" "=v")
1888         (plus:V4SI (match_operand:V4SI 2 "register_operand" "v")
1889                    (unspec:V4SI [(match_operand:V16QI 1 "register_operand" "v")]
1890                                 UNSPEC_VMSUMM)))]
1891   "TARGET_ALTIVEC"
1892   "
1894   rtx vones = gen_reg_rtx (V16QImode);
1896   emit_insn (gen_altivec_vspltisb (vones, const1_rtx));
1897   emit_insn (gen_altivec_vmsummbm (operands[0], operands[1], vones, operands[2]));
1898   DONE;
1901 (define_expand "widen_ssumv8hi3"
1902   [(set (match_operand:V4SI 0 "register_operand" "=v")
1903         (plus:V4SI (match_operand:V4SI 2 "register_operand" "v")
1904                    (unspec:V4SI [(match_operand:V8HI 1 "register_operand" "v")]
1905                                 UNSPEC_VMSUMSHM)))]
1906   "TARGET_ALTIVEC"
1907   "
1909   rtx vones = gen_reg_rtx (V8HImode);
1911   emit_insn (gen_altivec_vspltish (vones, const1_rtx));
1912   emit_insn (gen_altivec_vmsumshm (operands[0], operands[1], vones, operands[2]));
1913   DONE;
1916 (define_expand "vec_unpacks_hi_<VP_small_lc>"
1917   [(set (match_operand:VP 0 "register_operand" "=v")
1918         (unspec:VP [(match_operand:<VP_small> 1 "register_operand" "v")]
1919                    UNSPEC_VUNPACK_HI_SIGN))]
1920   "<VI_unit>"
1921   "")
1923 (define_expand "vec_unpacks_lo_<VP_small_lc>"
1924   [(set (match_operand:VP 0 "register_operand" "=v")
1925         (unspec:VP [(match_operand:<VP_small> 1 "register_operand" "v")]
1926                    UNSPEC_VUNPACK_LO_SIGN))]
1927   "<VI_unit>"
1928   "")
1930 (define_insn "vperm_v8hiv4si"
1931   [(set (match_operand:V4SI 0 "register_operand" "=v")
1932         (unspec:V4SI [(match_operand:V8HI 1 "register_operand" "v")
1933                    (match_operand:V4SI 2 "register_operand" "v")
1934                    (match_operand:V16QI 3 "register_operand" "v")]
1935                   UNSPEC_VPERMSI))]
1936   "TARGET_ALTIVEC"
1937   "vperm %0,%1,%2,%3"
1938   [(set_attr "type" "vecperm")])
1940 (define_insn "vperm_v16qiv8hi"
1941   [(set (match_operand:V8HI 0 "register_operand" "=v")
1942         (unspec:V8HI [(match_operand:V16QI 1 "register_operand" "v")
1943                    (match_operand:V8HI 2 "register_operand" "v")
1944                    (match_operand:V16QI 3 "register_operand" "v")]
1945                   UNSPEC_VPERMHI))]
1946   "TARGET_ALTIVEC"
1947   "vperm %0,%1,%2,%3"
1948   [(set_attr "type" "vecperm")])
1951 (define_expand "vec_unpacku_hi_v16qi"
1952   [(set (match_operand:V8HI 0 "register_operand" "=v")
1953         (unspec:V8HI [(match_operand:V16QI 1 "register_operand" "v")]
1954                      UNSPEC_VUPKHUB))]
1955   "TARGET_ALTIVEC"      
1956   "
1957 {  
1958   rtx vzero = gen_reg_rtx (V8HImode);
1959   rtx mask = gen_reg_rtx (V16QImode);
1960   rtvec v = rtvec_alloc (16);
1961    
1962   emit_insn (gen_altivec_vspltish (vzero, const0_rtx));
1963    
1964   RTVEC_ELT (v, 0) = gen_rtx_CONST_INT (QImode, 16);
1965   RTVEC_ELT (v, 1) = gen_rtx_CONST_INT (QImode, 0);
1966   RTVEC_ELT (v, 2) = gen_rtx_CONST_INT (QImode, 16);
1967   RTVEC_ELT (v, 3) = gen_rtx_CONST_INT (QImode, 1);
1968   RTVEC_ELT (v, 4) = gen_rtx_CONST_INT (QImode, 16);
1969   RTVEC_ELT (v, 5) = gen_rtx_CONST_INT (QImode, 2);
1970   RTVEC_ELT (v, 6) = gen_rtx_CONST_INT (QImode, 16);
1971   RTVEC_ELT (v, 7) = gen_rtx_CONST_INT (QImode, 3);
1972   RTVEC_ELT (v, 8) = gen_rtx_CONST_INT (QImode, 16);
1973   RTVEC_ELT (v, 9) = gen_rtx_CONST_INT (QImode, 4);
1974   RTVEC_ELT (v, 10) = gen_rtx_CONST_INT (QImode, 16);
1975   RTVEC_ELT (v, 11) = gen_rtx_CONST_INT (QImode, 5);
1976   RTVEC_ELT (v, 12) = gen_rtx_CONST_INT (QImode, 16);
1977   RTVEC_ELT (v, 13) = gen_rtx_CONST_INT (QImode, 6);
1978   RTVEC_ELT (v, 14) = gen_rtx_CONST_INT (QImode, 16);
1979   RTVEC_ELT (v, 15) = gen_rtx_CONST_INT (QImode, 7);
1981   emit_insn (gen_vec_initv16qi (mask, gen_rtx_PARALLEL (V16QImode, v)));
1982   emit_insn (gen_vperm_v16qiv8hi (operands[0], operands[1], vzero, mask));
1983   DONE;
1986 (define_expand "vec_unpacku_hi_v8hi"
1987   [(set (match_operand:V4SI 0 "register_operand" "=v")
1988         (unspec:V4SI [(match_operand:V8HI 1 "register_operand" "v")]
1989                      UNSPEC_VUPKHUH))]
1990   "TARGET_ALTIVEC"
1991   "
1993   rtx vzero = gen_reg_rtx (V4SImode);
1994   rtx mask = gen_reg_rtx (V16QImode);
1995   rtvec v = rtvec_alloc (16);
1997   emit_insn (gen_altivec_vspltisw (vzero, const0_rtx));
1999   RTVEC_ELT (v, 0) = gen_rtx_CONST_INT (QImode, 16);
2000   RTVEC_ELT (v, 1) = gen_rtx_CONST_INT (QImode, 17);
2001   RTVEC_ELT (v, 2) = gen_rtx_CONST_INT (QImode, 0);
2002   RTVEC_ELT (v, 3) = gen_rtx_CONST_INT (QImode, 1);
2003   RTVEC_ELT (v, 4) = gen_rtx_CONST_INT (QImode, 16);
2004   RTVEC_ELT (v, 5) = gen_rtx_CONST_INT (QImode, 17);
2005   RTVEC_ELT (v, 6) = gen_rtx_CONST_INT (QImode, 2);
2006   RTVEC_ELT (v, 7) = gen_rtx_CONST_INT (QImode, 3);
2007   RTVEC_ELT (v, 8) = gen_rtx_CONST_INT (QImode, 16);
2008   RTVEC_ELT (v, 9) = gen_rtx_CONST_INT (QImode, 17);
2009   RTVEC_ELT (v, 10) = gen_rtx_CONST_INT (QImode, 4);
2010   RTVEC_ELT (v, 11) = gen_rtx_CONST_INT (QImode, 5);
2011   RTVEC_ELT (v, 12) = gen_rtx_CONST_INT (QImode, 16);
2012   RTVEC_ELT (v, 13) = gen_rtx_CONST_INT (QImode, 17);
2013   RTVEC_ELT (v, 14) = gen_rtx_CONST_INT (QImode, 6);
2014   RTVEC_ELT (v, 15) = gen_rtx_CONST_INT (QImode, 7);
2016   emit_insn (gen_vec_initv16qi (mask, gen_rtx_PARALLEL (V16QImode, v)));
2017   emit_insn (gen_vperm_v8hiv4si (operands[0], operands[1], vzero, mask));
2018   DONE;
2021 (define_expand "vec_unpacku_lo_v16qi"
2022   [(set (match_operand:V8HI 0 "register_operand" "=v")
2023         (unspec:V8HI [(match_operand:V16QI 1 "register_operand" "v")]
2024                      UNSPEC_VUPKLUB))]
2025   "TARGET_ALTIVEC"
2026   "
2028   rtx vzero = gen_reg_rtx (V8HImode);
2029   rtx mask = gen_reg_rtx (V16QImode);
2030   rtvec v = rtvec_alloc (16);
2032   emit_insn (gen_altivec_vspltish (vzero, const0_rtx));
2034   RTVEC_ELT (v, 0) = gen_rtx_CONST_INT (QImode, 16);
2035   RTVEC_ELT (v, 1) = gen_rtx_CONST_INT (QImode, 8);
2036   RTVEC_ELT (v, 2) = gen_rtx_CONST_INT (QImode, 16);
2037   RTVEC_ELT (v, 3) = gen_rtx_CONST_INT (QImode, 9);
2038   RTVEC_ELT (v, 4) = gen_rtx_CONST_INT (QImode, 16);
2039   RTVEC_ELT (v, 5) = gen_rtx_CONST_INT (QImode, 10);
2040   RTVEC_ELT (v, 6) = gen_rtx_CONST_INT (QImode, 16);
2041   RTVEC_ELT (v, 7) = gen_rtx_CONST_INT (QImode, 11);
2042   RTVEC_ELT (v, 8) = gen_rtx_CONST_INT (QImode, 16);
2043   RTVEC_ELT (v, 9) = gen_rtx_CONST_INT (QImode, 12);
2044   RTVEC_ELT (v, 10) = gen_rtx_CONST_INT (QImode, 16);
2045   RTVEC_ELT (v, 11) = gen_rtx_CONST_INT (QImode, 13);
2046   RTVEC_ELT (v, 12) = gen_rtx_CONST_INT (QImode, 16);
2047   RTVEC_ELT (v, 13) = gen_rtx_CONST_INT (QImode, 14);
2048   RTVEC_ELT (v, 14) = gen_rtx_CONST_INT (QImode, 16);
2049   RTVEC_ELT (v, 15) = gen_rtx_CONST_INT (QImode, 15);
2051   emit_insn (gen_vec_initv16qi (mask, gen_rtx_PARALLEL (V16QImode, v)));
2052   emit_insn (gen_vperm_v16qiv8hi (operands[0], operands[1], vzero, mask));
2053   DONE;
2056 (define_expand "vec_unpacku_lo_v8hi"
2057   [(set (match_operand:V4SI 0 "register_operand" "=v")
2058         (unspec:V4SI [(match_operand:V8HI 1 "register_operand" "v")]
2059                      UNSPEC_VUPKLUH))]
2060   "TARGET_ALTIVEC"
2061   "
2063   rtx vzero = gen_reg_rtx (V4SImode);
2064   rtx mask = gen_reg_rtx (V16QImode);
2065   rtvec v = rtvec_alloc (16);
2067   emit_insn (gen_altivec_vspltisw (vzero, const0_rtx));
2069   RTVEC_ELT (v, 0) = gen_rtx_CONST_INT (QImode, 16);
2070   RTVEC_ELT (v, 1) = gen_rtx_CONST_INT (QImode, 17);
2071   RTVEC_ELT (v, 2) = gen_rtx_CONST_INT (QImode, 8);
2072   RTVEC_ELT (v, 3) = gen_rtx_CONST_INT (QImode, 9);
2073   RTVEC_ELT (v, 4) = gen_rtx_CONST_INT (QImode, 16);
2074   RTVEC_ELT (v, 5) = gen_rtx_CONST_INT (QImode, 17);
2075   RTVEC_ELT (v, 6) = gen_rtx_CONST_INT (QImode, 10);
2076   RTVEC_ELT (v, 7) = gen_rtx_CONST_INT (QImode, 11);
2077   RTVEC_ELT (v, 8) = gen_rtx_CONST_INT (QImode, 16);
2078   RTVEC_ELT (v, 9) = gen_rtx_CONST_INT (QImode, 17);
2079   RTVEC_ELT (v, 10) = gen_rtx_CONST_INT (QImode, 12);
2080   RTVEC_ELT (v, 11) = gen_rtx_CONST_INT (QImode, 13);
2081   RTVEC_ELT (v, 12) = gen_rtx_CONST_INT (QImode, 16);
2082   RTVEC_ELT (v, 13) = gen_rtx_CONST_INT (QImode, 17);
2083   RTVEC_ELT (v, 14) = gen_rtx_CONST_INT (QImode, 14);
2084   RTVEC_ELT (v, 15) = gen_rtx_CONST_INT (QImode, 15);
2086   emit_insn (gen_vec_initv16qi (mask, gen_rtx_PARALLEL (V16QImode, v)));
2087   emit_insn (gen_vperm_v8hiv4si (operands[0], operands[1], vzero, mask));
2088   DONE;
2091 (define_expand "vec_widen_umult_hi_v16qi"
2092   [(set (match_operand:V8HI 0 "register_operand" "=v")
2093         (unspec:V8HI [(match_operand:V16QI 1 "register_operand" "v")
2094                       (match_operand:V16QI 2 "register_operand" "v")]
2095                      UNSPEC_VMULWHUB))]
2096   "TARGET_ALTIVEC"
2097   "
2099   rtx ve = gen_reg_rtx (V8HImode);
2100   rtx vo = gen_reg_rtx (V8HImode);
2101   
2102   emit_insn (gen_vec_widen_umult_even_v16qi (ve, operands[1], operands[2]));
2103   emit_insn (gen_vec_widen_umult_odd_v16qi (vo, operands[1], operands[2]));
2104   emit_insn (gen_altivec_vmrghh (operands[0], ve, vo));
2105   DONE;
2108 (define_expand "vec_widen_umult_lo_v16qi"
2109   [(set (match_operand:V8HI 0 "register_operand" "=v")
2110         (unspec:V8HI [(match_operand:V16QI 1 "register_operand" "v")
2111                       (match_operand:V16QI 2 "register_operand" "v")]
2112                      UNSPEC_VMULWLUB))]
2113   "TARGET_ALTIVEC"
2114   "
2116   rtx ve = gen_reg_rtx (V8HImode);
2117   rtx vo = gen_reg_rtx (V8HImode);
2118   
2119   emit_insn (gen_vec_widen_umult_even_v16qi (ve, operands[1], operands[2]));
2120   emit_insn (gen_vec_widen_umult_odd_v16qi (vo, operands[1], operands[2]));
2121   emit_insn (gen_altivec_vmrglh (operands[0], ve, vo));
2122   DONE;
2125 (define_expand "vec_widen_smult_hi_v16qi"
2126   [(set (match_operand:V8HI 0 "register_operand" "=v")
2127         (unspec:V8HI [(match_operand:V16QI 1 "register_operand" "v")
2128                       (match_operand:V16QI 2 "register_operand" "v")]
2129                      UNSPEC_VMULWHSB))]
2130   "TARGET_ALTIVEC"
2131   "
2133   rtx ve = gen_reg_rtx (V8HImode);
2134   rtx vo = gen_reg_rtx (V8HImode);
2135   
2136   emit_insn (gen_vec_widen_smult_even_v16qi (ve, operands[1], operands[2]));
2137   emit_insn (gen_vec_widen_smult_odd_v16qi (vo, operands[1], operands[2]));
2138   emit_insn (gen_altivec_vmrghh (operands[0], ve, vo));
2139   DONE;
2142 (define_expand "vec_widen_smult_lo_v16qi"
2143   [(set (match_operand:V8HI 0 "register_operand" "=v")
2144         (unspec:V8HI [(match_operand:V16QI 1 "register_operand" "v")
2145                       (match_operand:V16QI 2 "register_operand" "v")]
2146                      UNSPEC_VMULWLSB))]
2147   "TARGET_ALTIVEC"
2148   "
2150   rtx ve = gen_reg_rtx (V8HImode);
2151   rtx vo = gen_reg_rtx (V8HImode);
2152   
2153   emit_insn (gen_vec_widen_smult_even_v16qi (ve, operands[1], operands[2]));
2154   emit_insn (gen_vec_widen_smult_odd_v16qi (vo, operands[1], operands[2]));
2155   emit_insn (gen_altivec_vmrglh (operands[0], ve, vo));
2156   DONE;
2159 (define_expand "vec_widen_umult_hi_v8hi"
2160   [(set (match_operand:V4SI 0 "register_operand" "=v")
2161         (unspec:V4SI [(match_operand:V8HI 1 "register_operand" "v")
2162                       (match_operand:V8HI 2 "register_operand" "v")]
2163                      UNSPEC_VMULWHUH))]
2164   "TARGET_ALTIVEC"
2165   "
2167   rtx ve = gen_reg_rtx (V4SImode);
2168   rtx vo = gen_reg_rtx (V4SImode);
2169   
2170   emit_insn (gen_vec_widen_umult_even_v8hi (ve, operands[1], operands[2]));
2171   emit_insn (gen_vec_widen_umult_odd_v8hi (vo, operands[1], operands[2]));
2172   emit_insn (gen_altivec_vmrghw (operands[0], ve, vo));
2173   DONE;
2176 (define_expand "vec_widen_umult_lo_v8hi"
2177   [(set (match_operand:V4SI 0 "register_operand" "=v")
2178         (unspec:V4SI [(match_operand:V8HI 1 "register_operand" "v")
2179                       (match_operand:V8HI 2 "register_operand" "v")]
2180                      UNSPEC_VMULWLUH))]
2181   "TARGET_ALTIVEC"
2182   "
2184   rtx ve = gen_reg_rtx (V4SImode);
2185   rtx vo = gen_reg_rtx (V4SImode);
2186   
2187   emit_insn (gen_vec_widen_umult_even_v8hi (ve, operands[1], operands[2]));
2188   emit_insn (gen_vec_widen_umult_odd_v8hi (vo, operands[1], operands[2]));
2189   emit_insn (gen_altivec_vmrglw (operands[0], ve, vo));
2190   DONE;
2193 (define_expand "vec_widen_smult_hi_v8hi"
2194   [(set (match_operand:V4SI 0 "register_operand" "=v")
2195         (unspec:V4SI [(match_operand:V8HI 1 "register_operand" "v")
2196                       (match_operand:V8HI 2 "register_operand" "v")]
2197                      UNSPEC_VMULWHSH))]
2198   "TARGET_ALTIVEC"
2199   "
2201   rtx ve = gen_reg_rtx (V4SImode);
2202   rtx vo = gen_reg_rtx (V4SImode);
2203   
2204   emit_insn (gen_vec_widen_smult_even_v8hi (ve, operands[1], operands[2]));
2205   emit_insn (gen_vec_widen_smult_odd_v8hi (vo, operands[1], operands[2]));
2206   emit_insn (gen_altivec_vmrghw (operands[0], ve, vo));
2207   DONE;
2210 (define_expand "vec_widen_smult_lo_v8hi"
2211   [(set (match_operand:V4SI 0 "register_operand" "=v")
2212         (unspec:V4SI [(match_operand:V8HI 1 "register_operand" "v")
2213                       (match_operand:V8HI 2 "register_operand" "v")]
2214                      UNSPEC_VMULWLSH))]
2215   "TARGET_ALTIVEC"
2216   "
2218   rtx ve = gen_reg_rtx (V4SImode);
2219   rtx vo = gen_reg_rtx (V4SImode);
2220   
2221   emit_insn (gen_vec_widen_smult_even_v8hi (ve, operands[1], operands[2]));
2222   emit_insn (gen_vec_widen_smult_odd_v8hi (vo, operands[1], operands[2]));
2223   emit_insn (gen_altivec_vmrglw (operands[0], ve, vo));
2224   DONE;
2227 (define_expand "vec_pack_trunc_<mode>"
2228   [(set (match_operand:<VP_small> 0 "register_operand" "=v")
2229         (unspec:<VP_small> [(match_operand:VP 1 "register_operand" "v")
2230                             (match_operand:VP 2 "register_operand" "v")]
2231                       UNSPEC_VPACK_UNS_UNS_MOD))]
2232   "<VI_unit>"
2233   "")
2235 (define_expand "altivec_negv4sf2"
2236   [(use (match_operand:V4SF 0 "register_operand" ""))
2237    (use (match_operand:V4SF 1 "register_operand" ""))]
2238   "TARGET_ALTIVEC"
2239   "
2241   rtx neg0;
2243   /* Generate [-0.0, -0.0, -0.0, -0.0].  */
2244   neg0 = gen_reg_rtx (V4SImode);
2245   emit_insn (gen_altivec_vspltisw (neg0, constm1_rtx));
2246   emit_insn (gen_vashlv4si3 (neg0, neg0, neg0));
2248   /* XOR */
2249   emit_insn (gen_xorv4sf3 (operands[0],
2250                            gen_lowpart (V4SFmode, neg0), operands[1])); 
2251     
2252   DONE;
2255 ;; Vector SIMD PEM v2.06c defines LVLX, LVLXL, LVRX, LVRXL,
2256 ;; STVLX, STVLXL, STVVRX, STVRXL are available only on Cell.
2257 (define_insn "altivec_lvlx"
2258   [(set (match_operand:V16QI 0 "register_operand" "=v")
2259         (unspec:V16QI [(match_operand:BLK 1 "memory_operand" "Z")]
2260                       UNSPEC_LVLX))]
2261   "TARGET_ALTIVEC && rs6000_cpu == PROCESSOR_CELL"
2262   "lvlx %0,%y1"
2263   [(set_attr "type" "vecload")])
2265 (define_insn "altivec_lvlxl"
2266   [(set (match_operand:V16QI 0 "register_operand" "=v")
2267         (unspec:V16QI [(match_operand:BLK 1 "memory_operand" "Z")]
2268                       UNSPEC_LVLXL))]
2269   "TARGET_ALTIVEC && rs6000_cpu == PROCESSOR_CELL"
2270   "lvlxl %0,%y1"
2271   [(set_attr "type" "vecload")])
2273 (define_insn "altivec_lvrx"
2274   [(set (match_operand:V16QI 0 "register_operand" "=v")
2275         (unspec:V16QI [(match_operand:BLK 1 "memory_operand" "Z")]
2276                       UNSPEC_LVRX))]
2277   "TARGET_ALTIVEC && rs6000_cpu == PROCESSOR_CELL"
2278   "lvrx %0,%y1"
2279   [(set_attr "type" "vecload")])
2281 (define_insn "altivec_lvrxl"
2282   [(set (match_operand:V16QI 0 "register_operand" "=v")
2283         (unspec:V16QI [(match_operand:BLK 1 "memory_operand" "Z")]
2284                       UNSPEC_LVRXL))]
2285   "TARGET_ALTIVEC && rs6000_cpu == PROCESSOR_CELL"
2286   "lvrxl %0,%y1"
2287   [(set_attr "type" "vecload")])
2289 (define_insn "altivec_stvlx"
2290   [(parallel
2291     [(set (match_operand:V16QI 0 "memory_operand" "=Z")
2292           (match_operand:V16QI 1 "register_operand" "v"))
2293      (unspec [(const_int 0)] UNSPEC_STVLX)])]
2294   "TARGET_ALTIVEC && rs6000_cpu == PROCESSOR_CELL"
2295   "stvlx %1,%y0"
2296   [(set_attr "type" "vecstore")])
2298 (define_insn "altivec_stvlxl"
2299   [(parallel
2300     [(set (match_operand:V16QI 0 "memory_operand" "=Z")
2301           (match_operand:V16QI 1 "register_operand" "v"))
2302      (unspec [(const_int 0)] UNSPEC_STVLXL)])]
2303   "TARGET_ALTIVEC && rs6000_cpu == PROCESSOR_CELL"
2304   "stvlxl %1,%y0"
2305   [(set_attr "type" "vecstore")])
2307 (define_insn "altivec_stvrx"
2308   [(parallel
2309     [(set (match_operand:V16QI 0 "memory_operand" "=Z")
2310           (match_operand:V16QI 1 "register_operand" "v"))
2311      (unspec [(const_int 0)] UNSPEC_STVRX)])]
2312   "TARGET_ALTIVEC && rs6000_cpu == PROCESSOR_CELL"
2313   "stvrx %1,%y0"
2314   [(set_attr "type" "vecstore")])
2316 (define_insn "altivec_stvrxl"
2317   [(parallel
2318     [(set (match_operand:V16QI 0 "memory_operand" "=Z")
2319           (match_operand:V16QI 1 "register_operand" "v"))
2320      (unspec [(const_int 0)] UNSPEC_STVRXL)])]
2321   "TARGET_ALTIVEC && rs6000_cpu == PROCESSOR_CELL"
2322   "stvrxl %1,%y0"
2323   [(set_attr "type" "vecstore")])
2325 (define_expand "vec_unpacks_float_hi_v8hi"
2326  [(set (match_operand:V4SF 0 "register_operand" "")
2327         (unspec:V4SF [(match_operand:V8HI 1 "register_operand" "")]
2328                      UNSPEC_VUPKHS_V4SF))]
2329   "TARGET_ALTIVEC"
2330   "
2332   rtx tmp = gen_reg_rtx (V4SImode);
2334   emit_insn (gen_vec_unpacks_hi_v8hi (tmp, operands[1]));
2335   emit_insn (gen_altivec_vcfsx (operands[0], tmp, const0_rtx));
2336   DONE;
2339 (define_expand "vec_unpacks_float_lo_v8hi"
2340  [(set (match_operand:V4SF 0 "register_operand" "")
2341         (unspec:V4SF [(match_operand:V8HI 1 "register_operand" "")]
2342                      UNSPEC_VUPKLS_V4SF))]
2343   "TARGET_ALTIVEC"
2344   "
2346   rtx tmp = gen_reg_rtx (V4SImode);
2348   emit_insn (gen_vec_unpacks_lo_v8hi (tmp, operands[1]));
2349   emit_insn (gen_altivec_vcfsx (operands[0], tmp, const0_rtx));
2350   DONE;
2353 (define_expand "vec_unpacku_float_hi_v8hi"
2354  [(set (match_operand:V4SF 0 "register_operand" "")
2355         (unspec:V4SF [(match_operand:V8HI 1 "register_operand" "")]
2356                      UNSPEC_VUPKHU_V4SF))]
2357   "TARGET_ALTIVEC"
2358   "
2360   rtx tmp = gen_reg_rtx (V4SImode);
2362   emit_insn (gen_vec_unpacku_hi_v8hi (tmp, operands[1]));
2363   emit_insn (gen_altivec_vcfux (operands[0], tmp, const0_rtx));
2364   DONE;
2367 (define_expand "vec_unpacku_float_lo_v8hi"
2368  [(set (match_operand:V4SF 0 "register_operand" "")
2369         (unspec:V4SF [(match_operand:V8HI 1 "register_operand" "")]
2370                      UNSPEC_VUPKLU_V4SF))]
2371   "TARGET_ALTIVEC"
2372   "
2374   rtx tmp = gen_reg_rtx (V4SImode);
2376   emit_insn (gen_vec_unpacku_lo_v8hi (tmp, operands[1]));
2377   emit_insn (gen_altivec_vcfux (operands[0], tmp, const0_rtx));
2378   DONE;
2382 ;; Power8 vector instructions encoded as Altivec instructions
2384 ;; Vector count leading zeros
2385 (define_insn "*p8v_clz<mode>2"
2386   [(set (match_operand:VI2 0 "register_operand" "=v")
2387         (clz:VI2 (match_operand:VI2 1 "register_operand" "v")))]
2388   "TARGET_P8_VECTOR"
2389   "vclz<wd> %0,%1"
2390   [(set_attr "length" "4")
2391    (set_attr "type" "vecsimple")])
2393 ;; Vector population count
2394 (define_insn "*p8v_popcount<mode>2"
2395   [(set (match_operand:VI2 0 "register_operand" "=v")
2396         (popcount:VI2 (match_operand:VI2 1 "register_operand" "v")))]
2397   "TARGET_P8_VECTOR"
2398   "vpopcnt<wd> %0,%1"
2399   [(set_attr "length" "4")
2400    (set_attr "type" "vecsimple")])
2402 ;; Vector Gather Bits by Bytes by Doubleword
2403 (define_insn "p8v_vgbbd"
2404   [(set (match_operand:V16QI 0 "register_operand" "=v")
2405         (unspec:V16QI [(match_operand:V16QI 1 "register_operand" "v")]
2406                       UNSPEC_VGBBD))]
2407   "TARGET_P8_VECTOR"
2408   "vgbbd %0,%1"
2409   [(set_attr "length" "4")
2410    (set_attr "type" "vecsimple")])