OSDN Git Service

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