Make UNSPEC/UNSPECV constants use the enum; Fix 48192; Add test case for 48053
[official-gcc.git] / gcc / config / rs6000 / altivec.md
blobd507b86973f43bd788d267cace35326fbeef4762
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)
6 ;; This file is part of GCC.
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.
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.
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/>.
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
140 (define_c_enum "unspecv"
141   [UNSPECV_SET_VRSAVE
142    UNSPECV_MTVSCR
143    UNSPECV_MFVSCR
144    UNSPECV_DSSALL
145    UNSPECV_DSS
146   ])
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])
160 ;; Like VM, except don't do TImode
161 (define_mode_iterator VM2 [V4SI V8HI V16QI V4SF V2DF V2DI])
163 (define_mode_attr VI_char [(V4SI "w") (V8HI "h") (V16QI "b")])
164 (define_mode_attr VI_scalar [(V4SI "SI") (V8HI "HI") (V16QI "QI")])
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))"
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     }
187   [(set_attr "type" "vecstore,vecload,vecsimple,store,load,*,vecsimple,*")])
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))"
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     }
212   [(set_attr "type" "vecstore,vecload,vecsimple,store,load,*,vecsimple,*")])
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)]
222   rtx dest = operands[0];
223   enum machine_mode mode = GET_MODE (operands[0]);
224   rtvec v;
225   int i, num_elements;
227   if (mode == V4SFmode)
228     {
229       mode = V4SImode;
230       dest = gen_lowpart (V4SImode, dest);
231     }
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;
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;
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))]
250   rtx dup = gen_easy_altivec_constant (operands[1]);
251   rtx const_vec;
252   enum machine_mode op_mode = <MODE>mode;
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);
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]);
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"
277   if (TARGET_MACHO)
278      return "mfspr %0,256";
279   else
280      return "mfvrsave %0";
282   [(set_attr "type" "*")])
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"
291   if (TARGET_MACHO)
292     return "mtspr 256,%1";
293   else
294     return "mtvrsave %1";
296   [(set_attr "type" "*")])
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")])
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")
316 ;; Simple binary operations.
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")])
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")])
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")])
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")])
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")])
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")])
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")])
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")])
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")])
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")])
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")])
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")])
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")])
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")])
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")])
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")])
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")])
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")])
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")])
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                 (const_int 0))
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")])
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                    (const_int 0))
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")])
508 ;; Fused multiply add.
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")])
519 ;; We do multiply as a fused multiply-add with an add of a -0.0 vector.
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)"
528   rtx neg0;
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));
535   operands[3] = gen_lowpart (V4SFmode, neg0);
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
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    "
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));
568    sixteen = gen_reg_rtx (V4SImode);   
569    emit_insn (gen_altivec_vspltisw (sixteen,  gen_rtx_CONST_INT (V4SImode, -16)));
571    swap = gen_reg_rtx (V4SImode);
572    emit_insn (gen_vrotlv4si3 (swap, operands[2], sixteen));
574    one = gen_reg_rtx (V8HImode);
575    convert_move (one, operands[1], 0);
577    two = gen_reg_rtx (V8HImode);
578    convert_move (two, operands[2], 0);
580    small_swap = gen_reg_rtx (V8HImode);
581    convert_move (small_swap, swap, 0);
583    low_product = gen_reg_rtx (V4SImode);
584    emit_insn (gen_altivec_vmulouh (low_product, one, two));
586    high_product = gen_reg_rtx (V4SImode);
587    emit_insn (gen_altivec_vmsumuhm (high_product, one, small_swap, zero));
589    emit_insn (gen_vashlv4si3 (high_product, high_product, sixteen));
591    emit_insn (gen_addv4si3 (operands[0], high_product, low_product));
592    
593    DONE;
594  }")
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    "
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);
608    emit_insn (gen_altivec_vmulesh (even, operands[1], operands[2]));
609    emit_insn (gen_altivec_vmulosh (odd, operands[1], operands[2]));
611    emit_insn (gen_altivec_vmrghw (high, even, odd));
612    emit_insn (gen_altivec_vmrglw (low, even, odd));
614    emit_insn (gen_altivec_vpkuwum (operands[0], high, low));
616    DONE;
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")])
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")])
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")])
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")])
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")])
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")])
683 ;; max
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")])
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")])
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")])
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")])
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")])
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")])
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")])
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")])
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")])
765 (define_insn "altivec_vmrghb"
766   [(set (match_operand:V16QI 0 "register_operand" "=v")
767         (vec_merge:V16QI (vec_select:V16QI (match_operand:V16QI 1 "register_operand" "v")
768                                            (parallel [(const_int 0)
769                                                       (const_int 8)
770                                                       (const_int 1)
771                                                       (const_int 9)
772                                                       (const_int 2)
773                                                       (const_int 10)
774                                                       (const_int 3)
775                                                       (const_int 11)
776                                                       (const_int 4)
777                                                       (const_int 12)
778                                                       (const_int 5)
779                                                       (const_int 13)
780                                                       (const_int 6)
781                                                       (const_int 14)
782                                                       (const_int 7)
783                                                       (const_int 15)]))
784                         (vec_select:V16QI (match_operand:V16QI 2 "register_operand" "v")
785                                            (parallel [(const_int 8)
786                                                       (const_int 0)
787                                                       (const_int 9)
788                                                       (const_int 1)
789                                                       (const_int 10)
790                                                       (const_int 2)
791                                                       (const_int 11)
792                                                       (const_int 3)
793                                                       (const_int 12)
794                                                       (const_int 4)
795                                                       (const_int 13)
796                                                       (const_int 5)
797                                                       (const_int 14)
798                                                       (const_int 6)
799                                                       (const_int 15)
800                                                       (const_int 7)]))
801                       (const_int 21845)))]
802   "TARGET_ALTIVEC"
803   "vmrghb %0,%1,%2"
804   [(set_attr "type" "vecperm")])
806 (define_insn "altivec_vmrghh"
807   [(set (match_operand:V8HI 0 "register_operand" "=v")
808         (vec_merge:V8HI (vec_select:V8HI (match_operand:V8HI 1 "register_operand" "v")
809                                            (parallel [(const_int 0)
810                                                       (const_int 4)
811                                                       (const_int 1)
812                                                       (const_int 5)
813                                                       (const_int 2)
814                                                       (const_int 6)
815                                                       (const_int 3)
816                                                       (const_int 7)]))
817                         (vec_select:V8HI (match_operand:V8HI 2 "register_operand" "v")
818                                            (parallel [(const_int 4)
819                                                       (const_int 0)
820                                                       (const_int 5)
821                                                       (const_int 1)
822                                                       (const_int 6)
823                                                       (const_int 2)
824                                                       (const_int 7)
825                                                       (const_int 3)]))
826                       (const_int 85)))]
827   "TARGET_ALTIVEC"
828   "vmrghh %0,%1,%2"
829   [(set_attr "type" "vecperm")])
831 (define_insn "altivec_vmrghw"
832   [(set (match_operand:V4SI 0 "register_operand" "=v")
833         (vec_merge:V4SI (vec_select:V4SI (match_operand:V4SI 1 "register_operand" "v")
834                                          (parallel [(const_int 0)
835                                                     (const_int 2)
836                                                     (const_int 1)
837                                                     (const_int 3)]))
838                         (vec_select:V4SI (match_operand:V4SI 2 "register_operand" "v")
839                                          (parallel [(const_int 2)
840                                                     (const_int 0)
841                                                     (const_int 3)
842                                                     (const_int 1)]))
843                       (const_int 5)))]
844   "VECTOR_MEM_ALTIVEC_P (V4SImode)"
845   "vmrghw %0,%1,%2"
846   [(set_attr "type" "vecperm")])
848 (define_insn "*altivec_vmrghsf"
849   [(set (match_operand:V4SF 0 "register_operand" "=v")
850         (vec_merge:V4SF (vec_select:V4SF (match_operand:V4SF 1 "register_operand" "v")
851                                          (parallel [(const_int 0)
852                                                     (const_int 2)
853                                                     (const_int 1)
854                                                     (const_int 3)]))
855                         (vec_select:V4SF (match_operand:V4SF 2 "register_operand" "v")
856                                          (parallel [(const_int 2)
857                                                     (const_int 0)
858                                                     (const_int 3)
859                                                     (const_int 1)]))
860                       (const_int 5)))]
861   "VECTOR_MEM_ALTIVEC_P (V4SFmode)"
862   "vmrghw %0,%1,%2"
863   [(set_attr "type" "vecperm")])
865 (define_insn "altivec_vmrglb"
866   [(set (match_operand:V16QI 0 "register_operand" "=v")
867         (vec_merge:V16QI (vec_select:V16QI (match_operand:V16QI 1 "register_operand" "v")
868                                            (parallel [(const_int 8)
869                                                       (const_int 0)
870                                                       (const_int 9)
871                                                       (const_int 1)
872                                                       (const_int 10)
873                                                       (const_int 2)
874                                                       (const_int 11)
875                                                       (const_int 3)
876                                                       (const_int 12)
877                                                       (const_int 4)
878                                                       (const_int 13)
879                                                       (const_int 5)
880                                                       (const_int 14)
881                                                       (const_int 6)
882                                                       (const_int 15)
883                                                       (const_int 7)]))
884                       (vec_select:V16QI (match_operand:V16QI 2 "register_operand" "v")
885                                            (parallel [(const_int 0)
886                                                       (const_int 8)
887                                                       (const_int 1)
888                                                       (const_int 9)
889                                                       (const_int 2)
890                                                       (const_int 10)
891                                                       (const_int 3)
892                                                       (const_int 11)
893                                                       (const_int 4)
894                                                       (const_int 12)
895                                                       (const_int 5)
896                                                       (const_int 13)
897                                                       (const_int 6)
898                                                       (const_int 14)
899                                                       (const_int 7)
900                                                       (const_int 15)]))
901                       (const_int 21845)))]
902   "TARGET_ALTIVEC"
903   "vmrglb %0,%1,%2"
904   [(set_attr "type" "vecperm")])
906 (define_insn "altivec_vmrglh"
907   [(set (match_operand:V8HI 0 "register_operand" "=v")
908         (vec_merge:V8HI (vec_select:V8HI (match_operand:V8HI 1 "register_operand" "v")
909                                            (parallel [(const_int 4)
910                                                       (const_int 0)
911                                                       (const_int 5)
912                                                       (const_int 1)
913                                                       (const_int 6)
914                                                       (const_int 2)
915                                                       (const_int 7)
916                                                       (const_int 3)]))
917                         (vec_select:V8HI (match_operand:V8HI 2 "register_operand" "v")
918                                            (parallel [(const_int 0)
919                                                       (const_int 4)
920                                                       (const_int 1)
921                                                       (const_int 5)
922                                                       (const_int 2)
923                                                       (const_int 6)
924                                                       (const_int 3)
925                                                       (const_int 7)]))
926                       (const_int 85)))]
927   "TARGET_ALTIVEC"
928   "vmrglh %0,%1,%2"
929   [(set_attr "type" "vecperm")])
931 (define_insn "altivec_vmrglw"
932   [(set (match_operand:V4SI 0 "register_operand" "=v")
933         (vec_merge:V4SI
934          (vec_select:V4SI (match_operand:V4SI 1 "register_operand" "v")
935                           (parallel [(const_int 2)
936                                      (const_int 0)
937                                      (const_int 3)
938                                      (const_int 1)]))
939          (vec_select:V4SI (match_operand:V4SI 2 "register_operand" "v")
940                           (parallel [(const_int 0)
941                                      (const_int 2)
942                                      (const_int 1)
943                                      (const_int 3)]))
944          (const_int 5)))]
945   "VECTOR_MEM_ALTIVEC_P (V4SImode)"
946   "vmrglw %0,%1,%2"
947   [(set_attr "type" "vecperm")])
949 (define_insn "*altivec_vmrglsf"
950   [(set (match_operand:V4SF 0 "register_operand" "=v")
951         (vec_merge:V4SF
952          (vec_select:V4SF (match_operand:V4SF 1 "register_operand" "v")
953                           (parallel [(const_int 2)
954                                      (const_int 0)
955                                      (const_int 3)
956                                      (const_int 1)]))
957          (vec_select:V4SF (match_operand:V4SF 2 "register_operand" "v")
958                           (parallel [(const_int 0)
959                                      (const_int 2)
960                                      (const_int 1)
961                                      (const_int 3)]))
962          (const_int 5)))]
963   "VECTOR_MEM_ALTIVEC_P (V4SFmode)"
964   "vmrglw %0,%1,%2"
965   [(set_attr "type" "vecperm")])
967 (define_insn "altivec_vmuleub"
968   [(set (match_operand:V8HI 0 "register_operand" "=v")
969         (unspec:V8HI [(match_operand:V16QI 1 "register_operand" "v")
970                       (match_operand:V16QI 2 "register_operand" "v")]
971                      UNSPEC_VMULEUB))]
972   "TARGET_ALTIVEC"
973   "vmuleub %0,%1,%2"
974   [(set_attr "type" "veccomplex")])
976 (define_insn "altivec_vmulesb"
977   [(set (match_operand:V8HI 0 "register_operand" "=v")
978         (unspec:V8HI [(match_operand:V16QI 1 "register_operand" "v")
979                       (match_operand:V16QI 2 "register_operand" "v")]
980                      UNSPEC_VMULESB))]
981   "TARGET_ALTIVEC"
982   "vmulesb %0,%1,%2"
983   [(set_attr "type" "veccomplex")])
985 (define_insn "altivec_vmuleuh"
986   [(set (match_operand:V4SI 0 "register_operand" "=v")
987         (unspec:V4SI [(match_operand:V8HI 1 "register_operand" "v")
988                       (match_operand:V8HI 2 "register_operand" "v")]
989                      UNSPEC_VMULEUH))]
990   "TARGET_ALTIVEC"
991   "vmuleuh %0,%1,%2"
992   [(set_attr "type" "veccomplex")])
994 (define_insn "altivec_vmulesh"
995   [(set (match_operand:V4SI 0 "register_operand" "=v")
996         (unspec:V4SI [(match_operand:V8HI 1 "register_operand" "v")
997                       (match_operand:V8HI 2 "register_operand" "v")]
998                      UNSPEC_VMULESH))]
999   "TARGET_ALTIVEC"
1000   "vmulesh %0,%1,%2"
1001   [(set_attr "type" "veccomplex")])
1003 (define_insn "altivec_vmuloub"
1004   [(set (match_operand:V8HI 0 "register_operand" "=v")
1005         (unspec:V8HI [(match_operand:V16QI 1 "register_operand" "v")
1006                       (match_operand:V16QI 2 "register_operand" "v")]
1007                      UNSPEC_VMULOUB))]
1008   "TARGET_ALTIVEC"
1009   "vmuloub %0,%1,%2"
1010   [(set_attr "type" "veccomplex")])
1012 (define_insn "altivec_vmulosb"
1013   [(set (match_operand:V8HI 0 "register_operand" "=v")
1014         (unspec:V8HI [(match_operand:V16QI 1 "register_operand" "v")
1015                       (match_operand:V16QI 2 "register_operand" "v")]
1016                      UNSPEC_VMULOSB))]
1017   "TARGET_ALTIVEC"
1018   "vmulosb %0,%1,%2"
1019   [(set_attr "type" "veccomplex")])
1021 (define_insn "altivec_vmulouh"
1022   [(set (match_operand:V4SI 0 "register_operand" "=v")
1023         (unspec:V4SI [(match_operand:V8HI 1 "register_operand" "v")
1024                       (match_operand:V8HI 2 "register_operand" "v")]
1025                      UNSPEC_VMULOUH))]
1026   "TARGET_ALTIVEC"
1027   "vmulouh %0,%1,%2"
1028   [(set_attr "type" "veccomplex")])
1030 (define_insn "altivec_vmulosh"
1031   [(set (match_operand:V4SI 0 "register_operand" "=v")
1032         (unspec:V4SI [(match_operand:V8HI 1 "register_operand" "v")
1033                       (match_operand:V8HI 2 "register_operand" "v")]
1034                      UNSPEC_VMULOSH))]
1035   "TARGET_ALTIVEC"
1036   "vmulosh %0,%1,%2"
1037   [(set_attr "type" "veccomplex")])
1040 ;; logical ops.  Have the logical ops follow the memory ops in
1041 ;; terms of whether to prefer VSX or Altivec
1043 (define_insn "*altivec_and<mode>3"
1044   [(set (match_operand:VM 0 "register_operand" "=v")
1045         (and:VM (match_operand:VM 1 "register_operand" "v")
1046                 (match_operand:VM 2 "register_operand" "v")))]
1047   "VECTOR_MEM_ALTIVEC_P (<MODE>mode)"
1048   "vand %0,%1,%2"
1049   [(set_attr "type" "vecsimple")])
1051 (define_insn "*altivec_ior<mode>3"
1052   [(set (match_operand:VM 0 "register_operand" "=v")
1053         (ior:VM (match_operand:VM 1 "register_operand" "v")
1054                 (match_operand:VM 2 "register_operand" "v")))]
1055   "VECTOR_MEM_ALTIVEC_P (<MODE>mode)"
1056   "vor %0,%1,%2"
1057   [(set_attr "type" "vecsimple")])
1059 (define_insn "*altivec_xor<mode>3"
1060   [(set (match_operand:VM 0 "register_operand" "=v")
1061         (xor:VM (match_operand:VM 1 "register_operand" "v")
1062                 (match_operand:VM 2 "register_operand" "v")))]
1063   "VECTOR_MEM_ALTIVEC_P (<MODE>mode)"
1064   "vxor %0,%1,%2"
1065   [(set_attr "type" "vecsimple")])
1067 (define_insn "*altivec_one_cmpl<mode>2"
1068   [(set (match_operand:VM 0 "register_operand" "=v")
1069         (not:VM (match_operand:VM 1 "register_operand" "v")))]
1070   "VECTOR_MEM_ALTIVEC_P (<MODE>mode)"
1071   "vnor %0,%1,%1"
1072   [(set_attr "type" "vecsimple")])
1073   
1074 (define_insn "*altivec_nor<mode>3"
1075   [(set (match_operand:VM 0 "register_operand" "=v")
1076         (not:VM (ior:VM (match_operand:VM 1 "register_operand" "v")
1077                         (match_operand:VM 2 "register_operand" "v"))))]
1078   "VECTOR_MEM_ALTIVEC_P (<MODE>mode)"
1079   "vnor %0,%1,%2"
1080   [(set_attr "type" "vecsimple")])
1082 (define_insn "*altivec_andc<mode>3"
1083   [(set (match_operand:VM 0 "register_operand" "=v")
1084         (and:VM (not:VM (match_operand:VM 2 "register_operand" "v"))
1085                 (match_operand:VM 1 "register_operand" "v")))]
1086   "VECTOR_MEM_ALTIVEC_P (<MODE>mode)"
1087   "vandc %0,%1,%2"
1088   [(set_attr "type" "vecsimple")])
1090 (define_insn "altivec_vpkuhum"
1091   [(set (match_operand:V16QI 0 "register_operand" "=v")
1092         (unspec:V16QI [(match_operand:V8HI 1 "register_operand" "v")
1093                        (match_operand:V8HI 2 "register_operand" "v")]
1094                       UNSPEC_VPKUHUM))]
1095   "TARGET_ALTIVEC"
1096   "vpkuhum %0,%1,%2"
1097   [(set_attr "type" "vecperm")])
1099 (define_insn "altivec_vpkuwum"
1100   [(set (match_operand:V8HI 0 "register_operand" "=v")
1101         (unspec:V8HI [(match_operand:V4SI 1 "register_operand" "v")
1102                       (match_operand:V4SI 2 "register_operand" "v")]
1103                      UNSPEC_VPKUWUM))]
1104   "TARGET_ALTIVEC"
1105   "vpkuwum %0,%1,%2"
1106   [(set_attr "type" "vecperm")])
1108 (define_insn "altivec_vpkpx"
1109   [(set (match_operand:V8HI 0 "register_operand" "=v")
1110         (unspec:V8HI [(match_operand:V4SI 1 "register_operand" "v")
1111                       (match_operand:V4SI 2 "register_operand" "v")]
1112                      UNSPEC_VPKPX))]
1113   "TARGET_ALTIVEC"
1114   "vpkpx %0,%1,%2"
1115   [(set_attr "type" "vecperm")])
1117 (define_insn "altivec_vpkshss"
1118   [(set (match_operand:V16QI 0 "register_operand" "=v")
1119         (unspec:V16QI [(match_operand:V8HI 1 "register_operand" "v")
1120                        (match_operand:V8HI 2 "register_operand" "v")]
1121                       UNSPEC_VPKSHSS))
1122    (set (reg:SI 110) (unspec:SI [(const_int 0)] UNSPEC_SET_VSCR))]
1123   "TARGET_ALTIVEC"
1124   "vpkshss %0,%1,%2"
1125   [(set_attr "type" "vecperm")])
1127 (define_insn "altivec_vpkswss"
1128   [(set (match_operand:V8HI 0 "register_operand" "=v")
1129         (unspec:V8HI [(match_operand:V4SI 1 "register_operand" "v")
1130                       (match_operand:V4SI 2 "register_operand" "v")]
1131                      UNSPEC_VPKSWSS))
1132    (set (reg:SI 110) (unspec:SI [(const_int 0)] UNSPEC_SET_VSCR))]
1133   "TARGET_ALTIVEC"
1134   "vpkswss %0,%1,%2"
1135   [(set_attr "type" "vecperm")])
1137 (define_insn "altivec_vpkuhus"
1138   [(set (match_operand:V16QI 0 "register_operand" "=v")
1139         (unspec:V16QI [(match_operand:V8HI 1 "register_operand" "v")
1140                        (match_operand:V8HI 2 "register_operand" "v")]
1141                       UNSPEC_VPKUHUS))
1142    (set (reg:SI 110) (unspec:SI [(const_int 0)] UNSPEC_SET_VSCR))]
1143   "TARGET_ALTIVEC"
1144   "vpkuhus %0,%1,%2"
1145   [(set_attr "type" "vecperm")])
1147 (define_insn "altivec_vpkshus"
1148   [(set (match_operand:V16QI 0 "register_operand" "=v")
1149         (unspec:V16QI [(match_operand:V8HI 1 "register_operand" "v")
1150                        (match_operand:V8HI 2 "register_operand" "v")]
1151                       UNSPEC_VPKSHUS))
1152    (set (reg:SI 110) (unspec:SI [(const_int 0)] UNSPEC_SET_VSCR))]
1153   "TARGET_ALTIVEC"
1154   "vpkshus %0,%1,%2"
1155   [(set_attr "type" "vecperm")])
1157 (define_insn "altivec_vpkuwus"
1158   [(set (match_operand:V8HI 0 "register_operand" "=v")
1159         (unspec:V8HI [(match_operand:V4SI 1 "register_operand" "v")
1160                       (match_operand:V4SI 2 "register_operand" "v")]
1161                      UNSPEC_VPKUWUS))
1162    (set (reg:SI 110) (unspec:SI [(const_int 0)] UNSPEC_SET_VSCR))]
1163   "TARGET_ALTIVEC"
1164   "vpkuwus %0,%1,%2"
1165   [(set_attr "type" "vecperm")])
1167 (define_insn "altivec_vpkswus"
1168   [(set (match_operand:V8HI 0 "register_operand" "=v")
1169         (unspec:V8HI [(match_operand:V4SI 1 "register_operand" "v")
1170                       (match_operand:V4SI 2 "register_operand" "v")]
1171                      UNSPEC_VPKSWUS))
1172    (set (reg:SI 110) (unspec:SI [(const_int 0)] UNSPEC_SET_VSCR))]
1173   "TARGET_ALTIVEC"
1174   "vpkswus %0,%1,%2"
1175   [(set_attr "type" "vecperm")])
1177 (define_insn "*altivec_vrl<VI_char>"
1178   [(set (match_operand:VI 0 "register_operand" "=v")
1179         (rotate:VI (match_operand:VI 1 "register_operand" "v")
1180                    (match_operand:VI 2 "register_operand" "v")))]
1181   "TARGET_ALTIVEC"
1182   "vrl<VI_char> %0,%1,%2"
1183   [(set_attr "type" "vecsimple")])
1185 (define_insn "altivec_vsl"
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_VSLV4SI))]
1190   "TARGET_ALTIVEC"
1191   "vsl %0,%1,%2"
1192   [(set_attr "type" "vecperm")])
1194 (define_insn "altivec_vslo"
1195   [(set (match_operand:V4SI 0 "register_operand" "=v")
1196         (unspec:V4SI [(match_operand:V4SI 1 "register_operand" "v")
1197                       (match_operand:V4SI 2 "register_operand" "v")]
1198                      UNSPEC_VSLO))]
1199   "TARGET_ALTIVEC"
1200   "vslo %0,%1,%2"
1201   [(set_attr "type" "vecperm")])
1203 (define_insn "*altivec_vsl<VI_char>"
1204   [(set (match_operand:VI 0 "register_operand" "=v")
1205         (ashift:VI (match_operand:VI 1 "register_operand" "v")
1206                    (match_operand:VI 2 "register_operand" "v")))]
1207   "TARGET_ALTIVEC"
1208   "vsl<VI_char> %0,%1,%2"
1209   [(set_attr "type" "vecsimple")])
1211 (define_insn "*altivec_vsr<VI_char>"
1212   [(set (match_operand:VI 0 "register_operand" "=v")
1213         (lshiftrt:VI (match_operand:VI 1 "register_operand" "v")
1214                      (match_operand:VI 2 "register_operand" "v")))]
1215   "TARGET_ALTIVEC"
1216   "vsr<VI_char> %0,%1,%2"
1217   [(set_attr "type" "vecsimple")])
1219 (define_insn "*altivec_vsra<VI_char>"
1220   [(set (match_operand:VI 0 "register_operand" "=v")
1221         (ashiftrt:VI (match_operand:VI 1 "register_operand" "v")
1222                      (match_operand:VI 2 "register_operand" "v")))]
1223   "TARGET_ALTIVEC"
1224   "vsra<VI_char> %0,%1,%2"
1225   [(set_attr "type" "vecsimple")])
1227 (define_insn "altivec_vsr"
1228   [(set (match_operand:V4SI 0 "register_operand" "=v")
1229         (unspec:V4SI [(match_operand:V4SI 1 "register_operand" "v")
1230                       (match_operand:V4SI 2 "register_operand" "v")]
1231                      UNSPEC_VSR))]
1232   "TARGET_ALTIVEC"
1233   "vsr %0,%1,%2"
1234   [(set_attr "type" "vecperm")])
1236 (define_insn "altivec_vsro"
1237   [(set (match_operand:V4SI 0 "register_operand" "=v")
1238         (unspec:V4SI [(match_operand:V4SI 1 "register_operand" "v")
1239                       (match_operand:V4SI 2 "register_operand" "v")]
1240                      UNSPEC_VSRO))]
1241   "TARGET_ALTIVEC"
1242   "vsro %0,%1,%2"
1243   [(set_attr "type" "vecperm")])
1245 (define_insn "altivec_vsum4ubs"
1246   [(set (match_operand:V4SI 0 "register_operand" "=v")
1247         (unspec:V4SI [(match_operand:V16QI 1 "register_operand" "v")
1248                       (match_operand:V4SI 2 "register_operand" "v")]
1249                      UNSPEC_VSUM4UBS))
1250    (set (reg:SI 110) (unspec:SI [(const_int 0)] UNSPEC_SET_VSCR))]
1251   "TARGET_ALTIVEC"
1252   "vsum4ubs %0,%1,%2"
1253   [(set_attr "type" "veccomplex")])
1255 (define_insn "altivec_vsum4s<VI_char>s"
1256   [(set (match_operand:V4SI 0 "register_operand" "=v")
1257         (unspec:V4SI [(match_operand:VIshort 1 "register_operand" "v")
1258                       (match_operand:V4SI 2 "register_operand" "v")]
1259                      UNSPEC_VSUM4S))
1260    (set (reg:SI 110) (unspec:SI [(const_int 0)] UNSPEC_SET_VSCR))]
1261   "TARGET_ALTIVEC"
1262   "vsum4s<VI_char>s %0,%1,%2"
1263   [(set_attr "type" "veccomplex")])
1265 (define_insn "altivec_vsum2sws"
1266   [(set (match_operand:V4SI 0 "register_operand" "=v")
1267         (unspec:V4SI [(match_operand:V4SI 1 "register_operand" "v")
1268                       (match_operand:V4SI 2 "register_operand" "v")]
1269                      UNSPEC_VSUM2SWS))
1270    (set (reg:SI 110) (unspec:SI [(const_int 0)] UNSPEC_SET_VSCR))]
1271   "TARGET_ALTIVEC"
1272   "vsum2sws %0,%1,%2"
1273   [(set_attr "type" "veccomplex")])
1275 (define_insn "altivec_vsumsws"
1276   [(set (match_operand:V4SI 0 "register_operand" "=v")
1277         (unspec:V4SI [(match_operand:V4SI 1 "register_operand" "v")
1278                       (match_operand:V4SI 2 "register_operand" "v")]
1279                      UNSPEC_VSUMSWS))
1280    (set (reg:SI 110) (unspec:SI [(const_int 0)] UNSPEC_SET_VSCR))]
1281   "TARGET_ALTIVEC"
1282   "vsumsws %0,%1,%2"
1283   [(set_attr "type" "veccomplex")])
1285 (define_insn "altivec_vspltb"
1286   [(set (match_operand:V16QI 0 "register_operand" "=v")
1287         (vec_duplicate:V16QI
1288          (vec_select:QI (match_operand:V16QI 1 "register_operand" "v")
1289                         (parallel
1290                          [(match_operand:QI 2 "u5bit_cint_operand" "")]))))]
1291   "TARGET_ALTIVEC"
1292   "vspltb %0,%1,%2"
1293   [(set_attr "type" "vecperm")])
1295 (define_insn "altivec_vsplth"
1296   [(set (match_operand:V8HI 0 "register_operand" "=v")
1297         (vec_duplicate:V8HI
1298          (vec_select:HI (match_operand:V8HI 1 "register_operand" "v")
1299                         (parallel
1300                          [(match_operand:QI 2 "u5bit_cint_operand" "")]))))]
1301   "TARGET_ALTIVEC"
1302   "vsplth %0,%1,%2"
1303   [(set_attr "type" "vecperm")])
1305 (define_insn "altivec_vspltw"
1306   [(set (match_operand:V4SI 0 "register_operand" "=v")
1307         (vec_duplicate:V4SI
1308          (vec_select:SI (match_operand:V4SI 1 "register_operand" "v")
1309                         (parallel
1310                          [(match_operand:QI 2 "u5bit_cint_operand" "i")]))))]
1311   "TARGET_ALTIVEC"
1312   "vspltw %0,%1,%2"
1313   [(set_attr "type" "vecperm")])
1315 (define_insn "altivec_vspltsf"
1316   [(set (match_operand:V4SF 0 "register_operand" "=v")
1317         (vec_duplicate:V4SF
1318          (vec_select:SF (match_operand:V4SF 1 "register_operand" "v")
1319                         (parallel
1320                          [(match_operand:QI 2 "u5bit_cint_operand" "i")]))))]
1321   "VECTOR_UNIT_ALTIVEC_P (V4SFmode)"
1322   "vspltw %0,%1,%2"
1323   [(set_attr "type" "vecperm")])
1325 (define_insn "altivec_vspltis<VI_char>"
1326   [(set (match_operand:VI 0 "register_operand" "=v")
1327         (vec_duplicate:VI
1328          (match_operand:QI 1 "s5bit_cint_operand" "i")))]
1329   "TARGET_ALTIVEC"
1330   "vspltis<VI_char> %0,%1"
1331   [(set_attr "type" "vecperm")])
1333 (define_insn "*altivec_vrfiz"
1334   [(set (match_operand:V4SF 0 "register_operand" "=v")
1335         (fix:V4SF (match_operand:V4SF 1 "register_operand" "v")))]
1336   "VECTOR_UNIT_ALTIVEC_P (V4SFmode)"
1337   "vrfiz %0,%1"
1338   [(set_attr "type" "vecfloat")])
1340 (define_insn "altivec_vperm_<mode>"
1341   [(set (match_operand:VM 0 "register_operand" "=v")
1342         (unspec:VM [(match_operand:VM 1 "register_operand" "v")
1343                     (match_operand:VM 2 "register_operand" "v")
1344                     (match_operand:V16QI 3 "register_operand" "v")]
1345                    UNSPEC_VPERM))]
1346   "TARGET_ALTIVEC"
1347   "vperm %0,%1,%2,%3"
1348   [(set_attr "type" "vecperm")])
1350 (define_insn "altivec_vperm_<mode>_uns"
1351   [(set (match_operand:VM 0 "register_operand" "=v")
1352         (unspec:VM [(match_operand:VM 1 "register_operand" "v")
1353                     (match_operand:VM 2 "register_operand" "v")
1354                     (match_operand:V16QI 3 "register_operand" "v")]
1355                    UNSPEC_VPERM_UNS))]
1356   "TARGET_ALTIVEC"
1357   "vperm %0,%1,%2,%3"
1358   [(set_attr "type" "vecperm")])
1360 (define_insn "altivec_vrfip"            ; ceil
1361   [(set (match_operand:V4SF 0 "register_operand" "=v")
1362         (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "v")]
1363                      UNSPEC_FRIP))]
1364   "TARGET_ALTIVEC"
1365   "vrfip %0,%1"
1366   [(set_attr "type" "vecfloat")])
1368 (define_insn "altivec_vrfin"
1369   [(set (match_operand:V4SF 0 "register_operand" "=v")
1370         (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "v")]
1371                      UNSPEC_VRFIN))]
1372   "TARGET_ALTIVEC"
1373   "vrfin %0,%1"
1374   [(set_attr "type" "vecfloat")])
1376 (define_insn "*altivec_vrfim"           ; floor
1377   [(set (match_operand:V4SF 0 "register_operand" "=v")
1378         (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "v")]
1379                      UNSPEC_FRIM))]
1380   "TARGET_ALTIVEC"
1381   "vrfim %0,%1"
1382   [(set_attr "type" "vecfloat")])
1384 (define_insn "altivec_vcfux"
1385   [(set (match_operand:V4SF 0 "register_operand" "=v")
1386         (unspec:V4SF [(match_operand:V4SI 1 "register_operand" "v")
1387                       (match_operand:QI 2 "immediate_operand" "i")]
1388                      UNSPEC_VCFUX))]
1389   "TARGET_ALTIVEC"
1390   "vcfux %0,%1,%2"
1391   [(set_attr "type" "vecfloat")])
1393 (define_insn "altivec_vcfsx"
1394   [(set (match_operand:V4SF 0 "register_operand" "=v")
1395         (unspec:V4SF [(match_operand:V4SI 1 "register_operand" "v")
1396                       (match_operand:QI 2 "immediate_operand" "i")]
1397                      UNSPEC_VCFSX))]
1398   "TARGET_ALTIVEC"
1399   "vcfsx %0,%1,%2"
1400   [(set_attr "type" "vecfloat")])
1402 (define_insn "altivec_vctuxs"
1403   [(set (match_operand:V4SI 0 "register_operand" "=v")
1404         (unspec:V4SI [(match_operand:V4SF 1 "register_operand" "v")
1405                       (match_operand:QI 2 "immediate_operand" "i")]
1406                      UNSPEC_VCTUXS))
1407    (set (reg:SI 110) (unspec:SI [(const_int 0)] UNSPEC_SET_VSCR))]
1408   "TARGET_ALTIVEC"
1409   "vctuxs %0,%1,%2"
1410   [(set_attr "type" "vecfloat")])
1412 (define_insn "altivec_vctsxs"
1413   [(set (match_operand:V4SI 0 "register_operand" "=v")
1414         (unspec:V4SI [(match_operand:V4SF 1 "register_operand" "v")
1415                       (match_operand:QI 2 "immediate_operand" "i")]
1416                      UNSPEC_VCTSXS))
1417    (set (reg:SI 110) (unspec:SI [(const_int 0)] UNSPEC_SET_VSCR))]
1418   "TARGET_ALTIVEC"
1419   "vctsxs %0,%1,%2"
1420   [(set_attr "type" "vecfloat")])
1422 (define_insn "altivec_vlogefp"
1423   [(set (match_operand:V4SF 0 "register_operand" "=v")
1424         (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "v")]
1425                      UNSPEC_VLOGEFP))]
1426   "TARGET_ALTIVEC"
1427   "vlogefp %0,%1"
1428   [(set_attr "type" "vecfloat")])
1430 (define_insn "altivec_vexptefp"
1431   [(set (match_operand:V4SF 0 "register_operand" "=v")
1432         (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "v")]
1433                      UNSPEC_VEXPTEFP))]
1434   "TARGET_ALTIVEC"
1435   "vexptefp %0,%1"
1436   [(set_attr "type" "vecfloat")])
1438 (define_insn "*altivec_vrsqrtefp"
1439   [(set (match_operand:V4SF 0 "register_operand" "=v")
1440         (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "v")]
1441                      UNSPEC_RSQRT))]
1442   "VECTOR_UNIT_ALTIVEC_P (V4SFmode)"
1443   "vrsqrtefp %0,%1"
1444   [(set_attr "type" "vecfloat")])
1446 (define_insn "altivec_vrefp"
1447   [(set (match_operand:V4SF 0 "register_operand" "=v")
1448         (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "v")]
1449                      UNSPEC_FRES))]
1450   "VECTOR_UNIT_ALTIVEC_P (V4SFmode)"
1451   "vrefp %0,%1"
1452   [(set_attr "type" "vecfloat")])
1454 (define_expand "altivec_copysign_v4sf3"
1455   [(use (match_operand:V4SF 0 "register_operand" ""))
1456    (use (match_operand:V4SF 1 "register_operand" ""))
1457    (use (match_operand:V4SF 2 "register_operand" ""))]
1458   "VECTOR_UNIT_ALTIVEC_P (V4SFmode)"
1459   "
1461   rtx mask = gen_reg_rtx (V4SImode);
1462   rtvec v = rtvec_alloc (4);
1463   unsigned HOST_WIDE_INT mask_val = ((unsigned HOST_WIDE_INT)1) << 31;
1465   RTVEC_ELT (v, 0) = GEN_INT (mask_val);
1466   RTVEC_ELT (v, 1) = GEN_INT (mask_val);
1467   RTVEC_ELT (v, 2) = GEN_INT (mask_val);
1468   RTVEC_ELT (v, 3) = GEN_INT (mask_val);
1470   emit_insn (gen_vec_initv4si (mask, gen_rtx_PARALLEL (V4SImode, v)));
1471   emit_insn (gen_vector_select_v4sf (operands[0], operands[1], operands[2],
1472                                      gen_lowpart (V4SFmode, mask)));
1473   DONE;
1476 (define_insn "altivec_vsldoi_<mode>"
1477   [(set (match_operand:VM 0 "register_operand" "=v")
1478         (unspec:VM [(match_operand:VM 1 "register_operand" "v")
1479                     (match_operand:VM 2 "register_operand" "v")
1480                     (match_operand:QI 3 "immediate_operand" "i")]
1481                   UNSPEC_VLSDOI))]
1482   "TARGET_ALTIVEC"
1483   "vsldoi %0,%1,%2,%3"
1484   [(set_attr "type" "vecperm")])
1486 (define_insn "altivec_vupkhsb"
1487   [(set (match_operand:V8HI 0 "register_operand" "=v")
1488         (unspec:V8HI [(match_operand:V16QI 1 "register_operand" "v")]
1489                      UNSPEC_VUPKHSB))]
1490   "TARGET_ALTIVEC"
1491   "vupkhsb %0,%1"
1492   [(set_attr "type" "vecperm")])
1494 (define_insn "altivec_vupkhpx"
1495   [(set (match_operand:V4SI 0 "register_operand" "=v")
1496         (unspec:V4SI [(match_operand:V8HI 1 "register_operand" "v")]
1497                      UNSPEC_VUPKHPX))]
1498   "TARGET_ALTIVEC"
1499   "vupkhpx %0,%1"
1500   [(set_attr "type" "vecperm")])
1502 (define_insn "altivec_vupkhsh"
1503   [(set (match_operand:V4SI 0 "register_operand" "=v")
1504         (unspec:V4SI [(match_operand:V8HI 1 "register_operand" "v")]
1505                      UNSPEC_VUPKHSH))]
1506   "TARGET_ALTIVEC"
1507   "vupkhsh %0,%1"
1508   [(set_attr "type" "vecperm")])
1510 (define_insn "altivec_vupklsb"
1511   [(set (match_operand:V8HI 0 "register_operand" "=v")
1512         (unspec:V8HI [(match_operand:V16QI 1 "register_operand" "v")]
1513                      UNSPEC_VUPKLSB))]
1514   "TARGET_ALTIVEC"
1515   "vupklsb %0,%1"
1516   [(set_attr "type" "vecperm")])
1518 (define_insn "altivec_vupklpx"
1519   [(set (match_operand:V4SI 0 "register_operand" "=v")
1520         (unspec:V4SI [(match_operand:V8HI 1 "register_operand" "v")]
1521                      UNSPEC_VUPKLPX))]
1522   "TARGET_ALTIVEC"
1523   "vupklpx %0,%1"
1524   [(set_attr "type" "vecperm")])
1526 (define_insn "altivec_vupklsh"
1527   [(set (match_operand:V4SI 0 "register_operand" "=v")
1528         (unspec:V4SI [(match_operand:V8HI 1 "register_operand" "v")]
1529                      UNSPEC_VUPKLSH))]
1530   "TARGET_ALTIVEC"
1531   "vupklsh %0,%1"
1532   [(set_attr "type" "vecperm")])
1534 ;; Compare vectors producing a vector result and a predicate, setting CR6 to
1535 ;; indicate a combined status
1536 (define_insn "*altivec_vcmpequ<VI_char>_p"
1537   [(set (reg:CC 74)
1538         (unspec:CC [(eq:CC (match_operand:VI 1 "register_operand" "v")
1539                            (match_operand:VI 2 "register_operand" "v"))]
1540                    UNSPEC_PREDICATE))
1541    (set (match_operand:VI 0 "register_operand" "=v")
1542         (eq:VI (match_dup 1)
1543                (match_dup 2)))]
1544   "VECTOR_UNIT_ALTIVEC_P (<MODE>mode)"
1545   "vcmpequ<VI_char>. %0,%1,%2"
1546   [(set_attr "type" "veccmp")])
1548 (define_insn "*altivec_vcmpgts<VI_char>_p"
1549   [(set (reg:CC 74)
1550         (unspec:CC [(gt:CC (match_operand:VI 1 "register_operand" "v")
1551                            (match_operand:VI 2 "register_operand" "v"))]
1552                    UNSPEC_PREDICATE))
1553    (set (match_operand:VI 0 "register_operand" "=v")
1554         (gt:VI (match_dup 1)
1555                (match_dup 2)))]
1556   "VECTOR_UNIT_ALTIVEC_P (<MODE>mode)"
1557   "vcmpgts<VI_char>. %0,%1,%2"
1558   [(set_attr "type" "veccmp")])
1560 (define_insn "*altivec_vcmpgtu<VI_char>_p"
1561   [(set (reg:CC 74)
1562         (unspec:CC [(gtu:CC (match_operand:VI 1 "register_operand" "v")
1563                             (match_operand:VI 2 "register_operand" "v"))]
1564                    UNSPEC_PREDICATE))
1565    (set (match_operand:VI 0 "register_operand" "=v")
1566         (gtu:VI (match_dup 1)
1567                 (match_dup 2)))]
1568   "VECTOR_UNIT_ALTIVEC_P (<MODE>mode)"
1569   "vcmpgtu<VI_char>. %0,%1,%2"
1570   [(set_attr "type" "veccmp")])
1572 (define_insn "*altivec_vcmpeqfp_p"
1573   [(set (reg:CC 74)
1574         (unspec:CC [(eq:CC (match_operand:V4SF 1 "register_operand" "v")
1575                            (match_operand:V4SF 2 "register_operand" "v"))]
1576                    UNSPEC_PREDICATE))
1577    (set (match_operand:V4SF 0 "register_operand" "=v")
1578         (eq:V4SF (match_dup 1)
1579                  (match_dup 2)))]
1580   "VECTOR_UNIT_ALTIVEC_P (V4SFmode)"
1581   "vcmpeqfp. %0,%1,%2"
1582   [(set_attr "type" "veccmp")])
1584 (define_insn "*altivec_vcmpgtfp_p"
1585   [(set (reg:CC 74)
1586         (unspec:CC [(gt:CC (match_operand:V4SF 1 "register_operand" "v")
1587                            (match_operand:V4SF 2 "register_operand" "v"))]
1588                    UNSPEC_PREDICATE))
1589    (set (match_operand:V4SF 0 "register_operand" "=v")
1590         (gt:V4SF (match_dup 1)
1591                  (match_dup 2)))]
1592   "VECTOR_UNIT_ALTIVEC_P (V4SFmode)"
1593   "vcmpgtfp. %0,%1,%2"
1594   [(set_attr "type" "veccmp")])
1596 (define_insn "*altivec_vcmpgefp_p"
1597   [(set (reg:CC 74)
1598         (unspec:CC [(ge:CC (match_operand:V4SF 1 "register_operand" "v")
1599                            (match_operand:V4SF 2 "register_operand" "v"))]
1600                    UNSPEC_PREDICATE))
1601    (set (match_operand:V4SF 0 "register_operand" "=v")
1602         (ge:V4SF (match_dup 1)
1603                  (match_dup 2)))]
1604   "VECTOR_UNIT_ALTIVEC_P (V4SFmode)"
1605   "vcmpgefp. %0,%1,%2"
1606   [(set_attr "type" "veccmp")])
1608 (define_insn "altivec_vcmpbfp_p"
1609   [(set (reg:CC 74)
1610         (unspec:CC [(match_operand:V4SF 1 "register_operand" "v")
1611                     (match_operand:V4SF 2 "register_operand" "v")]
1612                    UNSPEC_VCMPBFP))
1613    (set (match_operand:V4SF 0 "register_operand" "=v")
1614         (unspec:V4SF [(match_dup 1)
1615                       (match_dup 2)] 
1616                       UNSPEC_VCMPBFP))]
1617   "VECTOR_UNIT_ALTIVEC_OR_VSX_P (V4SFmode)"
1618   "vcmpbfp. %0,%1,%2"
1619   [(set_attr "type" "veccmp")])
1621 (define_insn "altivec_mtvscr"
1622   [(set (reg:SI 110)
1623         (unspec_volatile:SI
1624          [(match_operand:V4SI 0 "register_operand" "v")] UNSPECV_MTVSCR))]
1625   "TARGET_ALTIVEC"
1626   "mtvscr %0"
1627   [(set_attr "type" "vecsimple")])
1629 (define_insn "altivec_mfvscr"
1630   [(set (match_operand:V8HI 0 "register_operand" "=v")
1631         (unspec_volatile:V8HI [(reg:SI 110)] UNSPECV_MFVSCR))]
1632   "TARGET_ALTIVEC"
1633   "mfvscr %0"
1634   [(set_attr "type" "vecsimple")])
1636 (define_insn "altivec_dssall"
1637   [(unspec_volatile [(const_int 0)] UNSPECV_DSSALL)]
1638   "TARGET_ALTIVEC"
1639   "dssall"
1640   [(set_attr "type" "vecsimple")])
1642 (define_insn "altivec_dss"
1643   [(unspec_volatile [(match_operand:QI 0 "immediate_operand" "i")]
1644                     UNSPECV_DSS)]
1645   "TARGET_ALTIVEC"
1646   "dss %0"
1647   [(set_attr "type" "vecsimple")])
1649 (define_insn "altivec_dst"
1650   [(unspec [(match_operand 0 "register_operand" "b")
1651             (match_operand:SI 1 "register_operand" "r")
1652             (match_operand:QI 2 "immediate_operand" "i")] UNSPEC_DST)]
1653   "TARGET_ALTIVEC && GET_MODE (operands[0]) == Pmode"
1654   "dst %0,%1,%2"
1655   [(set_attr "type" "vecsimple")])
1657 (define_insn "altivec_dstt"
1658   [(unspec [(match_operand 0 "register_operand" "b")
1659             (match_operand:SI 1 "register_operand" "r")
1660             (match_operand:QI 2 "immediate_operand" "i")] UNSPEC_DSTT)]
1661   "TARGET_ALTIVEC && GET_MODE (operands[0]) == Pmode"
1662   "dstt %0,%1,%2"
1663   [(set_attr "type" "vecsimple")])
1665 (define_insn "altivec_dstst"
1666   [(unspec [(match_operand 0 "register_operand" "b")
1667             (match_operand:SI 1 "register_operand" "r")
1668             (match_operand:QI 2 "immediate_operand" "i")] UNSPEC_DSTST)]
1669   "TARGET_ALTIVEC && GET_MODE (operands[0]) == Pmode"
1670   "dstst %0,%1,%2"
1671   [(set_attr "type" "vecsimple")])
1673 (define_insn "altivec_dststt"
1674   [(unspec [(match_operand 0 "register_operand" "b")
1675             (match_operand:SI 1 "register_operand" "r")
1676             (match_operand:QI 2 "immediate_operand" "i")] UNSPEC_DSTSTT)]
1677   "TARGET_ALTIVEC && GET_MODE (operands[0]) == Pmode"
1678   "dststt %0,%1,%2"
1679   [(set_attr "type" "vecsimple")])
1681 (define_insn "altivec_lvsl"
1682   [(set (match_operand:V16QI 0 "register_operand" "=v")
1683         (unspec:V16QI [(match_operand 1 "memory_operand" "Z")] UNSPEC_LVSL))]
1684   "TARGET_ALTIVEC"
1685   "lvsl %0,%y1"
1686   [(set_attr "type" "vecload")])
1688 (define_insn "altivec_lvsr"
1689   [(set (match_operand:V16QI 0 "register_operand" "=v")
1690         (unspec:V16QI [(match_operand 1 "memory_operand" "Z")] UNSPEC_LVSR))]
1691   "TARGET_ALTIVEC"
1692   "lvsr %0,%y1"
1693   [(set_attr "type" "vecload")])
1695 (define_expand "build_vector_mask_for_load"
1696   [(set (match_operand:V16QI 0 "register_operand" "")
1697         (unspec:V16QI [(match_operand 1 "memory_operand" "")] UNSPEC_LVSR))]
1698   "TARGET_ALTIVEC"
1699   "
1701   rtx addr;
1702   rtx temp;
1704   gcc_assert (GET_CODE (operands[1]) == MEM);
1706   addr = XEXP (operands[1], 0);
1707   temp = gen_reg_rtx (GET_MODE (addr));
1708   emit_insn (gen_rtx_SET (VOIDmode, temp, 
1709                           gen_rtx_NEG (GET_MODE (addr), addr)));
1710   emit_insn (gen_altivec_lvsr (operands[0], 
1711                                replace_equiv_address (operands[1], temp)));
1712   DONE;
1715 ;; Parallel some of the LVE* and STV*'s with unspecs because some have
1716 ;; identical rtl but different instructions-- and gcc gets confused.
1718 (define_insn "altivec_lve<VI_char>x"
1719   [(parallel
1720     [(set (match_operand:VI 0 "register_operand" "=v")
1721           (match_operand:VI 1 "memory_operand" "Z"))
1722      (unspec [(const_int 0)] UNSPEC_LVE)])]
1723   "TARGET_ALTIVEC"
1724   "lve<VI_char>x %0,%y1"
1725   [(set_attr "type" "vecload")])
1727 (define_insn "*altivec_lvesfx"
1728   [(parallel
1729     [(set (match_operand:V4SF 0 "register_operand" "=v")
1730           (match_operand:V4SF 1 "memory_operand" "Z"))
1731      (unspec [(const_int 0)] UNSPEC_LVE)])]
1732   "TARGET_ALTIVEC"
1733   "lvewx %0,%y1"
1734   [(set_attr "type" "vecload")])
1736 (define_insn "altivec_lvxl"
1737   [(parallel
1738     [(set (match_operand:V4SI 0 "register_operand" "=v")
1739           (match_operand:V4SI 1 "memory_operand" "Z"))
1740      (unspec [(const_int 0)] UNSPEC_SET_VSCR)])]
1741   "TARGET_ALTIVEC"
1742   "lvxl %0,%y1"
1743   [(set_attr "type" "vecload")])
1745 (define_insn "altivec_lvx_<mode>"
1746   [(parallel
1747     [(set (match_operand:VM2 0 "register_operand" "=v")
1748           (match_operand:VM2 1 "memory_operand" "Z"))
1749      (unspec [(const_int 0)] UNSPEC_LVX)])]
1750   "TARGET_ALTIVEC"
1751   "lvx %0,%y1"
1752   [(set_attr "type" "vecload")])
1754 (define_insn "altivec_stvx_<mode>"
1755   [(parallel
1756     [(set (match_operand:VM2 0 "memory_operand" "=Z")
1757           (match_operand:VM2 1 "register_operand" "v"))
1758      (unspec [(const_int 0)] UNSPEC_STVX)])]
1759   "TARGET_ALTIVEC"
1760   "stvx %1,%y0"
1761   [(set_attr "type" "vecstore")])
1763 (define_insn "altivec_stvxl"
1764   [(parallel
1765     [(set (match_operand:V4SI 0 "memory_operand" "=Z")
1766           (match_operand:V4SI 1 "register_operand" "v"))
1767      (unspec [(const_int 0)] UNSPEC_STVXL)])]
1768   "TARGET_ALTIVEC"
1769   "stvxl %1,%y0"
1770   [(set_attr "type" "vecstore")])
1772 (define_insn "altivec_stve<VI_char>x"
1773   [(set (match_operand:<VI_scalar> 0 "memory_operand" "=Z")
1774         (unspec:<VI_scalar> [(match_operand:VI 1 "register_operand" "v")] UNSPEC_STVE))]
1775   "TARGET_ALTIVEC"
1776   "stve<VI_char>x %1,%y0"
1777   [(set_attr "type" "vecstore")])
1779 (define_insn "*altivec_stvesfx"
1780   [(set (match_operand:SF 0 "memory_operand" "=Z")
1781         (unspec:SF [(match_operand:V4SF 1 "register_operand" "v")] UNSPEC_STVE))]
1782   "TARGET_ALTIVEC"
1783   "stvewx %1,%y0"
1784   [(set_attr "type" "vecstore")])
1786 ;; Generate
1787 ;;    vspltis? SCRATCH0,0
1788 ;;    vsubu?m SCRATCH2,SCRATCH1,%1
1789 ;;    vmaxs? %0,%1,SCRATCH2"
1790 (define_expand "abs<mode>2"
1791   [(set (match_dup 2) (vec_duplicate:VI (const_int 0)))
1792    (set (match_dup 3)
1793         (minus:VI (match_dup 2)
1794                   (match_operand:VI 1 "register_operand" "v")))
1795    (set (match_operand:VI 0 "register_operand" "=v")
1796         (smax:VI (match_dup 1) (match_dup 3)))]
1797   "TARGET_ALTIVEC"
1799   operands[2] = gen_reg_rtx (GET_MODE (operands[0]));
1800   operands[3] = gen_reg_rtx (GET_MODE (operands[0]));
1803 ;; Generate
1804 ;;    vspltisw SCRATCH1,-1
1805 ;;    vslw SCRATCH2,SCRATCH1,SCRATCH1
1806 ;;    vandc %0,%1,SCRATCH2
1807 (define_expand "altivec_absv4sf2"
1808   [(set (match_dup 2)
1809         (vec_duplicate:V4SI (const_int -1)))
1810    (set (match_dup 3)
1811         (ashift:V4SI (match_dup 2) (match_dup 2)))
1812    (set (match_operand:V4SF 0 "register_operand" "=v")
1813         (and:V4SF (not:V4SF (subreg:V4SF (match_dup 3) 0))
1814                   (match_operand:V4SF 1 "register_operand" "v")))]
1815   "TARGET_ALTIVEC"
1817   operands[2] = gen_reg_rtx (V4SImode);
1818   operands[3] = gen_reg_rtx (V4SImode);
1821 ;; Generate
1822 ;;    vspltis? SCRATCH0,0
1823 ;;    vsubs?s SCRATCH2,SCRATCH1,%1
1824 ;;    vmaxs? %0,%1,SCRATCH2"
1825 (define_expand "altivec_abss_<mode>"
1826   [(set (match_dup 2) (vec_duplicate:VI (const_int 0)))
1827    (parallel [(set (match_dup 3)
1828                    (unspec:VI [(match_dup 2)
1829                                (match_operand:VI 1 "register_operand" "v")]
1830                               UNSPEC_VSUBS))
1831               (set (reg:SI 110) (unspec:SI [(const_int 0)] UNSPEC_SET_VSCR))])
1832    (set (match_operand:VI 0 "register_operand" "=v")
1833         (smax:VI (match_dup 1) (match_dup 3)))]
1834   "TARGET_ALTIVEC"
1836   operands[2] = gen_reg_rtx (GET_MODE (operands[0]));
1837   operands[3] = gen_reg_rtx (GET_MODE (operands[0]));
1840 (define_insn "altivec_vsumsws_nomode"
1841   [(set (match_operand 0 "register_operand" "=v")
1842         (unspec:V4SI [(match_operand:V4SI 1 "register_operand" "v")
1843                       (match_operand:V4SI 2 "register_operand" "v")]
1844                      UNSPEC_VSUMSWS))
1845    (set (reg:SI 110) (unspec:SI [(const_int 0)] UNSPEC_SET_VSCR))]
1846   "TARGET_ALTIVEC"
1847   "vsumsws %0,%1,%2"
1848   [(set_attr "type" "veccomplex")])
1850 (define_expand "reduc_splus_<mode>"
1851   [(set (match_operand:VIshort 0 "register_operand" "=v")
1852         (unspec:VIshort [(match_operand:VIshort 1 "register_operand" "v")]
1853                         UNSPEC_REDUC_PLUS))]
1854   "TARGET_ALTIVEC"
1855   "
1857   rtx vzero = gen_reg_rtx (V4SImode);
1858   rtx vtmp1 = gen_reg_rtx (V4SImode);
1860   emit_insn (gen_altivec_vspltisw (vzero, const0_rtx));
1861   emit_insn (gen_altivec_vsum4s<VI_char>s (vtmp1, operands[1], vzero));
1862   emit_insn (gen_altivec_vsumsws_nomode (operands[0], vtmp1, vzero));
1863   DONE;
1866 (define_expand "reduc_uplus_v16qi"
1867   [(set (match_operand:V16QI 0 "register_operand" "=v")
1868         (unspec:V16QI [(match_operand:V16QI 1 "register_operand" "v")]
1869                       UNSPEC_REDUC_PLUS))]
1870   "TARGET_ALTIVEC"
1871   "
1873   rtx vzero = gen_reg_rtx (V4SImode);
1874   rtx vtmp1 = gen_reg_rtx (V4SImode);
1876   emit_insn (gen_altivec_vspltisw (vzero, const0_rtx));
1877   emit_insn (gen_altivec_vsum4ubs (vtmp1, operands[1], vzero));
1878   emit_insn (gen_altivec_vsumsws_nomode (operands[0], vtmp1, vzero));
1879   DONE;
1882 (define_expand "neg<mode>2"
1883   [(use (match_operand:VI 0 "register_operand" ""))
1884    (use (match_operand:VI 1 "register_operand" ""))]
1885   "TARGET_ALTIVEC"
1886   "
1888   rtx vzero;
1890   vzero = gen_reg_rtx (GET_MODE (operands[0]));
1891   emit_insn (gen_altivec_vspltis<VI_char> (vzero, const0_rtx));
1892   emit_insn (gen_sub<mode>3 (operands[0], vzero, operands[1])); 
1893   
1894   DONE;
1897 (define_expand "udot_prod<mode>"
1898   [(set (match_operand:V4SI 0 "register_operand" "=v")
1899         (plus:V4SI (match_operand:V4SI 3 "register_operand" "v")
1900                    (unspec:V4SI [(match_operand:VIshort 1 "register_operand" "v")  
1901                                  (match_operand:VIshort 2 "register_operand" "v")] 
1902                                 UNSPEC_VMSUMU)))]
1903   "TARGET_ALTIVEC"
1904   "
1905 {  
1906   emit_insn (gen_altivec_vmsumu<VI_char>m (operands[0], operands[1], operands[2], operands[3]));
1907   DONE;
1909    
1910 (define_expand "sdot_prodv8hi"
1911   [(set (match_operand:V4SI 0 "register_operand" "=v")
1912         (plus:V4SI (match_operand:V4SI 3 "register_operand" "v")
1913                    (unspec:V4SI [(match_operand:V8HI 1 "register_operand" "v")
1914                                  (match_operand:V8HI 2 "register_operand" "v")]
1915                                 UNSPEC_VMSUMSHM)))]
1916   "TARGET_ALTIVEC"
1917   "
1919   emit_insn (gen_altivec_vmsumshm (operands[0], operands[1], operands[2], operands[3]));
1920   DONE;
1923 (define_expand "widen_usum<mode>3"
1924   [(set (match_operand:V4SI 0 "register_operand" "=v")
1925         (plus:V4SI (match_operand:V4SI 2 "register_operand" "v")
1926                    (unspec:V4SI [(match_operand:VIshort 1 "register_operand" "v")]
1927                                 UNSPEC_VMSUMU)))]
1928   "TARGET_ALTIVEC"
1929   "
1931   rtx vones = gen_reg_rtx (GET_MODE (operands[1]));
1933   emit_insn (gen_altivec_vspltis<VI_char> (vones, const1_rtx));
1934   emit_insn (gen_altivec_vmsumu<VI_char>m (operands[0], operands[1], vones, operands[2]));
1935   DONE;
1938 (define_expand "widen_ssumv16qi3"
1939   [(set (match_operand:V4SI 0 "register_operand" "=v")
1940         (plus:V4SI (match_operand:V4SI 2 "register_operand" "v")
1941                    (unspec:V4SI [(match_operand:V16QI 1 "register_operand" "v")]
1942                                 UNSPEC_VMSUMM)))]
1943   "TARGET_ALTIVEC"
1944   "
1946   rtx vones = gen_reg_rtx (V16QImode);
1948   emit_insn (gen_altivec_vspltisb (vones, const1_rtx));
1949   emit_insn (gen_altivec_vmsummbm (operands[0], operands[1], vones, operands[2]));
1950   DONE;
1953 (define_expand "widen_ssumv8hi3"
1954   [(set (match_operand:V4SI 0 "register_operand" "=v")
1955         (plus:V4SI (match_operand:V4SI 2 "register_operand" "v")
1956                    (unspec:V4SI [(match_operand:V8HI 1 "register_operand" "v")]
1957                                 UNSPEC_VMSUMSHM)))]
1958   "TARGET_ALTIVEC"
1959   "
1961   rtx vones = gen_reg_rtx (V8HImode);
1963   emit_insn (gen_altivec_vspltish (vones, const1_rtx));
1964   emit_insn (gen_altivec_vmsumshm (operands[0], operands[1], vones, operands[2]));
1965   DONE;
1968 (define_expand "vec_unpacks_hi_v16qi"
1969   [(set (match_operand:V8HI 0 "register_operand" "=v")
1970         (unspec:V8HI [(match_operand:V16QI 1 "register_operand" "v")]
1971                      UNSPEC_VUPKHSB))]
1972   "TARGET_ALTIVEC"
1973   "
1975   emit_insn (gen_altivec_vupkhsb (operands[0], operands[1]));
1976   DONE;
1979 (define_expand "vec_unpacks_hi_v8hi"
1980   [(set (match_operand:V4SI 0 "register_operand" "=v")
1981         (unspec:V4SI [(match_operand:V8HI 1 "register_operand" "v")]
1982                      UNSPEC_VUPKHSH))]
1983   "TARGET_ALTIVEC"
1984   "
1986   emit_insn (gen_altivec_vupkhsh (operands[0], operands[1]));
1987   DONE;
1990 (define_expand "vec_unpacks_lo_v16qi"
1991   [(set (match_operand:V8HI 0 "register_operand" "=v")
1992         (unspec:V8HI [(match_operand:V16QI 1 "register_operand" "v")]
1993                      UNSPEC_VUPKLSB))]
1994   "TARGET_ALTIVEC"
1995   "
1997   emit_insn (gen_altivec_vupklsb (operands[0], operands[1]));
1998   DONE;
2001 (define_expand "vec_unpacks_lo_v8hi"
2002   [(set (match_operand:V4SI 0 "register_operand" "=v")
2003         (unspec:V4SI [(match_operand:V8HI 1 "register_operand" "v")]
2004                      UNSPEC_VUPKLSH))]
2005   "TARGET_ALTIVEC"
2006   "
2008   emit_insn (gen_altivec_vupklsh (operands[0], operands[1]));
2009   DONE;
2012 (define_insn "vperm_v8hiv4si"
2013   [(set (match_operand:V4SI 0 "register_operand" "=v")
2014         (unspec:V4SI [(match_operand:V8HI 1 "register_operand" "v")
2015                    (match_operand:V4SI 2 "register_operand" "v")
2016                    (match_operand:V16QI 3 "register_operand" "v")]
2017                   UNSPEC_VPERMSI))]
2018   "TARGET_ALTIVEC"
2019   "vperm %0,%1,%2,%3"
2020   [(set_attr "type" "vecperm")])
2022 (define_insn "vperm_v16qiv8hi"
2023   [(set (match_operand:V8HI 0 "register_operand" "=v")
2024         (unspec:V8HI [(match_operand:V16QI 1 "register_operand" "v")
2025                    (match_operand:V8HI 2 "register_operand" "v")
2026                    (match_operand:V16QI 3 "register_operand" "v")]
2027                   UNSPEC_VPERMHI))]
2028   "TARGET_ALTIVEC"
2029   "vperm %0,%1,%2,%3"
2030   [(set_attr "type" "vecperm")])
2033 (define_expand "vec_unpacku_hi_v16qi"
2034   [(set (match_operand:V8HI 0 "register_operand" "=v")
2035         (unspec:V8HI [(match_operand:V16QI 1 "register_operand" "v")]
2036                      UNSPEC_VUPKHUB))]
2037   "TARGET_ALTIVEC"      
2038   "
2039 {  
2040   rtx vzero = gen_reg_rtx (V8HImode);
2041   rtx mask = gen_reg_rtx (V16QImode);
2042   rtvec v = rtvec_alloc (16);
2043    
2044   emit_insn (gen_altivec_vspltish (vzero, const0_rtx));
2045    
2046   RTVEC_ELT (v, 0) = gen_rtx_CONST_INT (QImode, 16);
2047   RTVEC_ELT (v, 1) = gen_rtx_CONST_INT (QImode, 0);
2048   RTVEC_ELT (v, 2) = gen_rtx_CONST_INT (QImode, 16);
2049   RTVEC_ELT (v, 3) = gen_rtx_CONST_INT (QImode, 1);
2050   RTVEC_ELT (v, 4) = gen_rtx_CONST_INT (QImode, 16);
2051   RTVEC_ELT (v, 5) = gen_rtx_CONST_INT (QImode, 2);
2052   RTVEC_ELT (v, 6) = gen_rtx_CONST_INT (QImode, 16);
2053   RTVEC_ELT (v, 7) = gen_rtx_CONST_INT (QImode, 3);
2054   RTVEC_ELT (v, 8) = gen_rtx_CONST_INT (QImode, 16);
2055   RTVEC_ELT (v, 9) = gen_rtx_CONST_INT (QImode, 4);
2056   RTVEC_ELT (v, 10) = gen_rtx_CONST_INT (QImode, 16);
2057   RTVEC_ELT (v, 11) = gen_rtx_CONST_INT (QImode, 5);
2058   RTVEC_ELT (v, 12) = gen_rtx_CONST_INT (QImode, 16);
2059   RTVEC_ELT (v, 13) = gen_rtx_CONST_INT (QImode, 6);
2060   RTVEC_ELT (v, 14) = gen_rtx_CONST_INT (QImode, 16);
2061   RTVEC_ELT (v, 15) = gen_rtx_CONST_INT (QImode, 7);
2063   emit_insn (gen_vec_initv16qi (mask, gen_rtx_PARALLEL (V16QImode, v)));
2064   emit_insn (gen_vperm_v16qiv8hi (operands[0], operands[1], vzero, mask));
2065   DONE;
2068 (define_expand "vec_unpacku_hi_v8hi"
2069   [(set (match_operand:V4SI 0 "register_operand" "=v")
2070         (unspec:V4SI [(match_operand:V8HI 1 "register_operand" "v")]
2071                      UNSPEC_VUPKHUH))]
2072   "TARGET_ALTIVEC"
2073   "
2075   rtx vzero = gen_reg_rtx (V4SImode);
2076   rtx mask = gen_reg_rtx (V16QImode);
2077   rtvec v = rtvec_alloc (16);
2079   emit_insn (gen_altivec_vspltisw (vzero, const0_rtx));
2081   RTVEC_ELT (v, 0) = gen_rtx_CONST_INT (QImode, 16);
2082   RTVEC_ELT (v, 1) = gen_rtx_CONST_INT (QImode, 17);
2083   RTVEC_ELT (v, 2) = gen_rtx_CONST_INT (QImode, 0);
2084   RTVEC_ELT (v, 3) = gen_rtx_CONST_INT (QImode, 1);
2085   RTVEC_ELT (v, 4) = gen_rtx_CONST_INT (QImode, 16);
2086   RTVEC_ELT (v, 5) = gen_rtx_CONST_INT (QImode, 17);
2087   RTVEC_ELT (v, 6) = gen_rtx_CONST_INT (QImode, 2);
2088   RTVEC_ELT (v, 7) = gen_rtx_CONST_INT (QImode, 3);
2089   RTVEC_ELT (v, 8) = gen_rtx_CONST_INT (QImode, 16);
2090   RTVEC_ELT (v, 9) = gen_rtx_CONST_INT (QImode, 17);
2091   RTVEC_ELT (v, 10) = gen_rtx_CONST_INT (QImode, 4);
2092   RTVEC_ELT (v, 11) = gen_rtx_CONST_INT (QImode, 5);
2093   RTVEC_ELT (v, 12) = gen_rtx_CONST_INT (QImode, 16);
2094   RTVEC_ELT (v, 13) = gen_rtx_CONST_INT (QImode, 17);
2095   RTVEC_ELT (v, 14) = gen_rtx_CONST_INT (QImode, 6);
2096   RTVEC_ELT (v, 15) = gen_rtx_CONST_INT (QImode, 7);
2098   emit_insn (gen_vec_initv16qi (mask, gen_rtx_PARALLEL (V16QImode, v)));
2099   emit_insn (gen_vperm_v8hiv4si (operands[0], operands[1], vzero, mask));
2100   DONE;
2103 (define_expand "vec_unpacku_lo_v16qi"
2104   [(set (match_operand:V8HI 0 "register_operand" "=v")
2105         (unspec:V8HI [(match_operand:V16QI 1 "register_operand" "v")]
2106                      UNSPEC_VUPKLUB))]
2107   "TARGET_ALTIVEC"
2108   "
2110   rtx vzero = gen_reg_rtx (V8HImode);
2111   rtx mask = gen_reg_rtx (V16QImode);
2112   rtvec v = rtvec_alloc (16);
2114   emit_insn (gen_altivec_vspltish (vzero, const0_rtx));
2116   RTVEC_ELT (v, 0) = gen_rtx_CONST_INT (QImode, 16);
2117   RTVEC_ELT (v, 1) = gen_rtx_CONST_INT (QImode, 8);
2118   RTVEC_ELT (v, 2) = gen_rtx_CONST_INT (QImode, 16);
2119   RTVEC_ELT (v, 3) = gen_rtx_CONST_INT (QImode, 9);
2120   RTVEC_ELT (v, 4) = gen_rtx_CONST_INT (QImode, 16);
2121   RTVEC_ELT (v, 5) = gen_rtx_CONST_INT (QImode, 10);
2122   RTVEC_ELT (v, 6) = gen_rtx_CONST_INT (QImode, 16);
2123   RTVEC_ELT (v, 7) = gen_rtx_CONST_INT (QImode, 11);
2124   RTVEC_ELT (v, 8) = gen_rtx_CONST_INT (QImode, 16);
2125   RTVEC_ELT (v, 9) = gen_rtx_CONST_INT (QImode, 12);
2126   RTVEC_ELT (v, 10) = gen_rtx_CONST_INT (QImode, 16);
2127   RTVEC_ELT (v, 11) = gen_rtx_CONST_INT (QImode, 13);
2128   RTVEC_ELT (v, 12) = gen_rtx_CONST_INT (QImode, 16);
2129   RTVEC_ELT (v, 13) = gen_rtx_CONST_INT (QImode, 14);
2130   RTVEC_ELT (v, 14) = gen_rtx_CONST_INT (QImode, 16);
2131   RTVEC_ELT (v, 15) = gen_rtx_CONST_INT (QImode, 15);
2133   emit_insn (gen_vec_initv16qi (mask, gen_rtx_PARALLEL (V16QImode, v)));
2134   emit_insn (gen_vperm_v16qiv8hi (operands[0], operands[1], vzero, mask));
2135   DONE;
2138 (define_expand "vec_unpacku_lo_v8hi"
2139   [(set (match_operand:V4SI 0 "register_operand" "=v")
2140         (unspec:V4SI [(match_operand:V8HI 1 "register_operand" "v")]
2141                      UNSPEC_VUPKLUH))]
2142   "TARGET_ALTIVEC"
2143   "
2145   rtx vzero = gen_reg_rtx (V4SImode);
2146   rtx mask = gen_reg_rtx (V16QImode);
2147   rtvec v = rtvec_alloc (16);
2149   emit_insn (gen_altivec_vspltisw (vzero, const0_rtx));
2151   RTVEC_ELT (v, 0) = gen_rtx_CONST_INT (QImode, 16);
2152   RTVEC_ELT (v, 1) = gen_rtx_CONST_INT (QImode, 17);
2153   RTVEC_ELT (v, 2) = gen_rtx_CONST_INT (QImode, 8);
2154   RTVEC_ELT (v, 3) = gen_rtx_CONST_INT (QImode, 9);
2155   RTVEC_ELT (v, 4) = gen_rtx_CONST_INT (QImode, 16);
2156   RTVEC_ELT (v, 5) = gen_rtx_CONST_INT (QImode, 17);
2157   RTVEC_ELT (v, 6) = gen_rtx_CONST_INT (QImode, 10);
2158   RTVEC_ELT (v, 7) = gen_rtx_CONST_INT (QImode, 11);
2159   RTVEC_ELT (v, 8) = gen_rtx_CONST_INT (QImode, 16);
2160   RTVEC_ELT (v, 9) = gen_rtx_CONST_INT (QImode, 17);
2161   RTVEC_ELT (v, 10) = gen_rtx_CONST_INT (QImode, 12);
2162   RTVEC_ELT (v, 11) = gen_rtx_CONST_INT (QImode, 13);
2163   RTVEC_ELT (v, 12) = gen_rtx_CONST_INT (QImode, 16);
2164   RTVEC_ELT (v, 13) = gen_rtx_CONST_INT (QImode, 17);
2165   RTVEC_ELT (v, 14) = gen_rtx_CONST_INT (QImode, 14);
2166   RTVEC_ELT (v, 15) = gen_rtx_CONST_INT (QImode, 15);
2168   emit_insn (gen_vec_initv16qi (mask, gen_rtx_PARALLEL (V16QImode, v)));
2169   emit_insn (gen_vperm_v8hiv4si (operands[0], operands[1], vzero, mask));
2170   DONE;
2173 (define_expand "vec_widen_umult_hi_v16qi"
2174   [(set (match_operand:V8HI 0 "register_operand" "=v")
2175         (unspec:V8HI [(match_operand:V16QI 1 "register_operand" "v")
2176                       (match_operand:V16QI 2 "register_operand" "v")]
2177                      UNSPEC_VMULWHUB))]
2178   "TARGET_ALTIVEC"
2179   "
2181   rtx ve = gen_reg_rtx (V8HImode);
2182   rtx vo = gen_reg_rtx (V8HImode);
2183   
2184   emit_insn (gen_altivec_vmuleub (ve, operands[1], operands[2]));
2185   emit_insn (gen_altivec_vmuloub (vo, operands[1], operands[2]));
2186   emit_insn (gen_altivec_vmrghh (operands[0], ve, vo));
2187   DONE;
2190 (define_expand "vec_widen_umult_lo_v16qi"
2191   [(set (match_operand:V8HI 0 "register_operand" "=v")
2192         (unspec:V8HI [(match_operand:V16QI 1 "register_operand" "v")
2193                       (match_operand:V16QI 2 "register_operand" "v")]
2194                      UNSPEC_VMULWLUB))]
2195   "TARGET_ALTIVEC"
2196   "
2198   rtx ve = gen_reg_rtx (V8HImode);
2199   rtx vo = gen_reg_rtx (V8HImode);
2200   
2201   emit_insn (gen_altivec_vmuleub (ve, operands[1], operands[2]));
2202   emit_insn (gen_altivec_vmuloub (vo, operands[1], operands[2]));
2203   emit_insn (gen_altivec_vmrglh (operands[0], ve, vo));
2204   DONE;
2207 (define_expand "vec_widen_smult_hi_v16qi"
2208   [(set (match_operand:V8HI 0 "register_operand" "=v")
2209         (unspec:V8HI [(match_operand:V16QI 1 "register_operand" "v")
2210                       (match_operand:V16QI 2 "register_operand" "v")]
2211                      UNSPEC_VMULWHSB))]
2212   "TARGET_ALTIVEC"
2213   "
2215   rtx ve = gen_reg_rtx (V8HImode);
2216   rtx vo = gen_reg_rtx (V8HImode);
2217   
2218   emit_insn (gen_altivec_vmulesb (ve, operands[1], operands[2]));
2219   emit_insn (gen_altivec_vmulosb (vo, operands[1], operands[2]));
2220   emit_insn (gen_altivec_vmrghh (operands[0], ve, vo));
2221   DONE;
2224 (define_expand "vec_widen_smult_lo_v16qi"
2225   [(set (match_operand:V8HI 0 "register_operand" "=v")
2226         (unspec:V8HI [(match_operand:V16QI 1 "register_operand" "v")
2227                       (match_operand:V16QI 2 "register_operand" "v")]
2228                      UNSPEC_VMULWLSB))]
2229   "TARGET_ALTIVEC"
2230   "
2232   rtx ve = gen_reg_rtx (V8HImode);
2233   rtx vo = gen_reg_rtx (V8HImode);
2234   
2235   emit_insn (gen_altivec_vmulesb (ve, operands[1], operands[2]));
2236   emit_insn (gen_altivec_vmulosb (vo, operands[1], operands[2]));
2237   emit_insn (gen_altivec_vmrglh (operands[0], ve, vo));
2238   DONE;
2241 (define_expand "vec_widen_umult_hi_v8hi"
2242   [(set (match_operand:V4SI 0 "register_operand" "=v")
2243         (unspec:V4SI [(match_operand:V8HI 1 "register_operand" "v")
2244                       (match_operand:V8HI 2 "register_operand" "v")]
2245                      UNSPEC_VMULWHUH))]
2246   "TARGET_ALTIVEC"
2247   "
2249   rtx ve = gen_reg_rtx (V4SImode);
2250   rtx vo = gen_reg_rtx (V4SImode);
2251   
2252   emit_insn (gen_altivec_vmuleuh (ve, operands[1], operands[2]));
2253   emit_insn (gen_altivec_vmulouh (vo, operands[1], operands[2]));
2254   emit_insn (gen_altivec_vmrghw (operands[0], ve, vo));
2255   DONE;
2258 (define_expand "vec_widen_umult_lo_v8hi"
2259   [(set (match_operand:V4SI 0 "register_operand" "=v")
2260         (unspec:V4SI [(match_operand:V8HI 1 "register_operand" "v")
2261                       (match_operand:V8HI 2 "register_operand" "v")]
2262                      UNSPEC_VMULWLUH))]
2263   "TARGET_ALTIVEC"
2264   "
2266   rtx ve = gen_reg_rtx (V4SImode);
2267   rtx vo = gen_reg_rtx (V4SImode);
2268   
2269   emit_insn (gen_altivec_vmuleuh (ve, operands[1], operands[2]));
2270   emit_insn (gen_altivec_vmulouh (vo, operands[1], operands[2]));
2271   emit_insn (gen_altivec_vmrglw (operands[0], ve, vo));
2272   DONE;
2275 (define_expand "vec_widen_smult_hi_v8hi"
2276   [(set (match_operand:V4SI 0 "register_operand" "=v")
2277         (unspec:V4SI [(match_operand:V8HI 1 "register_operand" "v")
2278                       (match_operand:V8HI 2 "register_operand" "v")]
2279                      UNSPEC_VMULWHSH))]
2280   "TARGET_ALTIVEC"
2281   "
2283   rtx ve = gen_reg_rtx (V4SImode);
2284   rtx vo = gen_reg_rtx (V4SImode);
2285   
2286   emit_insn (gen_altivec_vmulesh (ve, operands[1], operands[2]));
2287   emit_insn (gen_altivec_vmulosh (vo, operands[1], operands[2]));
2288   emit_insn (gen_altivec_vmrghw (operands[0], ve, vo));
2289   DONE;
2292 (define_expand "vec_widen_smult_lo_v8hi"
2293   [(set (match_operand:V4SI 0 "register_operand" "=v")
2294         (unspec:V4SI [(match_operand:V8HI 1 "register_operand" "v")
2295                       (match_operand:V8HI 2 "register_operand" "v")]
2296                      UNSPEC_VMULWLSH))]
2297   "TARGET_ALTIVEC"
2298   "
2300   rtx ve = gen_reg_rtx (V4SImode);
2301   rtx vo = gen_reg_rtx (V4SImode);
2302   
2303   emit_insn (gen_altivec_vmulesh (ve, operands[1], operands[2]));
2304   emit_insn (gen_altivec_vmulosh (vo, operands[1], operands[2]));
2305   emit_insn (gen_altivec_vmrglw (operands[0], ve, vo));
2306   DONE;
2309 (define_expand "vec_pack_trunc_v8hi"
2310   [(set (match_operand:V16QI 0 "register_operand" "=v")
2311         (unspec:V16QI [(match_operand:V8HI 1 "register_operand" "v")
2312                        (match_operand:V8HI 2 "register_operand" "v")]
2313                       UNSPEC_VPKUHUM))]
2314   "TARGET_ALTIVEC"
2315   "
2317   emit_insn (gen_altivec_vpkuhum (operands[0], operands[1], operands[2]));
2318   DONE;
2320                                                                                 
2321 (define_expand "vec_pack_trunc_v4si"
2322   [(set (match_operand:V8HI 0 "register_operand" "=v")
2323         (unspec:V8HI [(match_operand:V4SI 1 "register_operand" "v")
2324                       (match_operand:V4SI 2 "register_operand" "v")]
2325                      UNSPEC_VPKUWUM))]
2326   "TARGET_ALTIVEC"
2327   "
2329   emit_insn (gen_altivec_vpkuwum (operands[0], operands[1], operands[2]));
2330   DONE;
2333 (define_expand "altivec_negv4sf2"
2334   [(use (match_operand:V4SF 0 "register_operand" ""))
2335    (use (match_operand:V4SF 1 "register_operand" ""))]
2336   "TARGET_ALTIVEC"
2337   "
2339   rtx neg0;
2341   /* Generate [-0.0, -0.0, -0.0, -0.0].  */
2342   neg0 = gen_reg_rtx (V4SImode);
2343   emit_insn (gen_altivec_vspltisw (neg0, constm1_rtx));
2344   emit_insn (gen_vashlv4si3 (neg0, neg0, neg0));
2346   /* XOR */
2347   emit_insn (gen_xorv4sf3 (operands[0],
2348                            gen_lowpart (V4SFmode, neg0), operands[1])); 
2349     
2350   DONE;
2353 ;; Vector SIMD PEM v2.06c defines LVLX, LVLXL, LVRX, LVRXL,
2354 ;; STVLX, STVLXL, STVVRX, STVRXL are available only on Cell.
2355 (define_insn "altivec_lvlx"
2356   [(set (match_operand:V16QI 0 "register_operand" "=v")
2357         (unspec:V16QI [(match_operand 1 "memory_operand" "Z")] 
2358                       UNSPEC_LVLX))]
2359   "TARGET_ALTIVEC && rs6000_cpu == PROCESSOR_CELL"
2360   "lvlx %0,%y1"
2361   [(set_attr "type" "vecload")])
2363 (define_insn "altivec_lvlxl"
2364   [(set (match_operand:V16QI 0 "register_operand" "=v")
2365         (unspec:V16QI [(match_operand 1 "memory_operand" "Z")] 
2366                       UNSPEC_LVLXL))]
2367   "TARGET_ALTIVEC && rs6000_cpu == PROCESSOR_CELL"
2368   "lvlxl %0,%y1"
2369   [(set_attr "type" "vecload")])
2371 (define_insn "altivec_lvrx"
2372   [(set (match_operand:V16QI 0 "register_operand" "=v")
2373         (unspec:V16QI [(match_operand 1 "memory_operand" "Z")] 
2374                       UNSPEC_LVRX))]
2375   "TARGET_ALTIVEC && rs6000_cpu == PROCESSOR_CELL"
2376   "lvrx %0,%y1"
2377   [(set_attr "type" "vecload")])
2379 (define_insn "altivec_lvrxl"
2380   [(set (match_operand:V16QI 0 "register_operand" "=v")
2381         (unspec:V16QI [(match_operand 1 "memory_operand" "Z")] 
2382                       UNSPEC_LVRXL))]
2383   "TARGET_ALTIVEC && rs6000_cpu == PROCESSOR_CELL"
2384   "lvrxl %0,%y1"
2385   [(set_attr "type" "vecload")])
2387 (define_insn "altivec_stvlx"
2388   [(parallel
2389     [(set (match_operand:V4SI 0 "memory_operand" "=Z")
2390           (match_operand:V4SI 1 "register_operand" "v"))
2391      (unspec [(const_int 0)] UNSPEC_STVLX)])]
2392   "TARGET_ALTIVEC && rs6000_cpu == PROCESSOR_CELL"
2393   "stvlx %1,%y0"
2394   [(set_attr "type" "vecstore")])
2396 (define_insn "altivec_stvlxl"
2397   [(parallel
2398     [(set (match_operand:V4SI 0 "memory_operand" "=Z")
2399           (match_operand:V4SI 1 "register_operand" "v"))
2400      (unspec [(const_int 0)] UNSPEC_STVLXL)])]
2401   "TARGET_ALTIVEC && rs6000_cpu == PROCESSOR_CELL"
2402   "stvlxl %1,%y0"
2403   [(set_attr "type" "vecstore")])
2405 (define_insn "altivec_stvrx"
2406   [(parallel
2407     [(set (match_operand:V4SI 0 "memory_operand" "=Z")
2408           (match_operand:V4SI 1 "register_operand" "v"))
2409      (unspec [(const_int 0)] UNSPEC_STVRX)])]
2410   "TARGET_ALTIVEC && rs6000_cpu == PROCESSOR_CELL"
2411   "stvrx %1,%y0"
2412   [(set_attr "type" "vecstore")])
2414 (define_insn "altivec_stvrxl"
2415   [(parallel
2416     [(set (match_operand:V4SI 0 "memory_operand" "=Z")
2417           (match_operand:V4SI 1 "register_operand" "v"))
2418      (unspec [(const_int 0)] UNSPEC_STVRXL)])]
2419   "TARGET_ALTIVEC && rs6000_cpu == PROCESSOR_CELL"
2420   "stvrxl %1,%y0"
2421   [(set_attr "type" "vecstore")])
2423 (define_expand "vec_extract_evenv4si"
2424  [(set (match_operand:V4SI 0 "register_operand" "")
2425         (unspec:V8HI [(match_operand:V4SI 1 "register_operand" "")
2426                       (match_operand:V4SI 2 "register_operand" "")]
2427                       UNSPEC_EXTEVEN_V4SI))]
2428   "TARGET_ALTIVEC"
2429   "
2431   rtx mask = gen_reg_rtx (V16QImode);
2432   rtvec v = rtvec_alloc (16);
2434   RTVEC_ELT (v, 0) = gen_rtx_CONST_INT (QImode, 0);
2435   RTVEC_ELT (v, 1) = gen_rtx_CONST_INT (QImode, 1);
2436   RTVEC_ELT (v, 2) = gen_rtx_CONST_INT (QImode, 2);
2437   RTVEC_ELT (v, 3) = gen_rtx_CONST_INT (QImode, 3);
2438   RTVEC_ELT (v, 4) = gen_rtx_CONST_INT (QImode, 8);
2439   RTVEC_ELT (v, 5) = gen_rtx_CONST_INT (QImode, 9);
2440   RTVEC_ELT (v, 6) = gen_rtx_CONST_INT (QImode, 10);
2441   RTVEC_ELT (v, 7) = gen_rtx_CONST_INT (QImode, 11);
2442   RTVEC_ELT (v, 8) = gen_rtx_CONST_INT (QImode, 16);
2443   RTVEC_ELT (v, 9) = gen_rtx_CONST_INT (QImode, 17);
2444   RTVEC_ELT (v, 10) = gen_rtx_CONST_INT (QImode, 18);
2445   RTVEC_ELT (v, 11) = gen_rtx_CONST_INT (QImode, 19);
2446   RTVEC_ELT (v, 12) = gen_rtx_CONST_INT (QImode, 24);
2447   RTVEC_ELT (v, 13) = gen_rtx_CONST_INT (QImode, 25);
2448   RTVEC_ELT (v, 14) = gen_rtx_CONST_INT (QImode, 26);
2449   RTVEC_ELT (v, 15) = gen_rtx_CONST_INT (QImode, 27);
2450   emit_insn (gen_vec_initv16qi (mask, gen_rtx_PARALLEL (V16QImode, v)));
2451   emit_insn (gen_altivec_vperm_v4si (operands[0], operands[1], operands[2], mask));
2452   
2453   DONE;
2456 (define_expand "vec_extract_evenv4sf"
2457  [(set (match_operand:V4SF 0 "register_operand" "")
2458         (unspec:V8HI [(match_operand:V4SF 1 "register_operand" "")
2459                       (match_operand:V4SF 2 "register_operand" "")]
2460                       UNSPEC_EXTEVEN_V4SF))]
2461   "TARGET_ALTIVEC"
2462   "
2464   rtx mask = gen_reg_rtx (V16QImode);
2465   rtvec v = rtvec_alloc (16);
2466   
2467   RTVEC_ELT (v, 0) = gen_rtx_CONST_INT (QImode, 0);
2468   RTVEC_ELT (v, 1) = gen_rtx_CONST_INT (QImode, 1);
2469   RTVEC_ELT (v, 2) = gen_rtx_CONST_INT (QImode, 2);
2470   RTVEC_ELT (v, 3) = gen_rtx_CONST_INT (QImode, 3);
2471   RTVEC_ELT (v, 4) = gen_rtx_CONST_INT (QImode, 8);
2472   RTVEC_ELT (v, 5) = gen_rtx_CONST_INT (QImode, 9);
2473   RTVEC_ELT (v, 6) = gen_rtx_CONST_INT (QImode, 10);
2474   RTVEC_ELT (v, 7) = gen_rtx_CONST_INT (QImode, 11);
2475   RTVEC_ELT (v, 8) = gen_rtx_CONST_INT (QImode, 16);
2476   RTVEC_ELT (v, 9) = gen_rtx_CONST_INT (QImode, 17);
2477   RTVEC_ELT (v, 10) = gen_rtx_CONST_INT (QImode, 18);
2478   RTVEC_ELT (v, 11) = gen_rtx_CONST_INT (QImode, 19);
2479   RTVEC_ELT (v, 12) = gen_rtx_CONST_INT (QImode, 24);
2480   RTVEC_ELT (v, 13) = gen_rtx_CONST_INT (QImode, 25);
2481   RTVEC_ELT (v, 14) = gen_rtx_CONST_INT (QImode, 26);
2482   RTVEC_ELT (v, 15) = gen_rtx_CONST_INT (QImode, 27);
2483   emit_insn (gen_vec_initv16qi (mask, gen_rtx_PARALLEL (V16QImode, v)));
2484   emit_insn (gen_altivec_vperm_v4sf (operands[0], operands[1], operands[2], mask));
2485   
2486   DONE;
2489 (define_expand "vec_extract_evenv8hi"
2490  [(set (match_operand:V4SI 0 "register_operand" "")
2491         (unspec:V8HI [(match_operand:V8HI 1 "register_operand" "")
2492                       (match_operand:V8HI 2 "register_operand" "")]
2493                       UNSPEC_EXTEVEN_V8HI))]
2494   "TARGET_ALTIVEC"
2495   "
2497   rtx mask = gen_reg_rtx (V16QImode);
2498   rtvec v = rtvec_alloc (16);
2499   
2500   RTVEC_ELT (v, 0) = gen_rtx_CONST_INT (QImode, 0);
2501   RTVEC_ELT (v, 1) = gen_rtx_CONST_INT (QImode, 1);
2502   RTVEC_ELT (v, 2) = gen_rtx_CONST_INT (QImode, 4);
2503   RTVEC_ELT (v, 3) = gen_rtx_CONST_INT (QImode, 5);
2504   RTVEC_ELT (v, 4) = gen_rtx_CONST_INT (QImode, 8);
2505   RTVEC_ELT (v, 5) = gen_rtx_CONST_INT (QImode, 9);
2506   RTVEC_ELT (v, 6) = gen_rtx_CONST_INT (QImode, 12);
2507   RTVEC_ELT (v, 7) = gen_rtx_CONST_INT (QImode, 13);
2508   RTVEC_ELT (v, 8) = gen_rtx_CONST_INT (QImode, 16);
2509   RTVEC_ELT (v, 9) = gen_rtx_CONST_INT (QImode, 17);
2510   RTVEC_ELT (v, 10) = gen_rtx_CONST_INT (QImode, 20);
2511   RTVEC_ELT (v, 11) = gen_rtx_CONST_INT (QImode, 21);
2512   RTVEC_ELT (v, 12) = gen_rtx_CONST_INT (QImode, 24);
2513   RTVEC_ELT (v, 13) = gen_rtx_CONST_INT (QImode, 25);
2514   RTVEC_ELT (v, 14) = gen_rtx_CONST_INT (QImode, 28);
2515   RTVEC_ELT (v, 15) = gen_rtx_CONST_INT (QImode, 29);
2516   emit_insn (gen_vec_initv16qi (mask, gen_rtx_PARALLEL (V16QImode, v)));
2517   emit_insn (gen_altivec_vperm_v8hi (operands[0], operands[1], operands[2], mask));
2518   
2519   DONE;
2522 (define_expand "vec_extract_evenv16qi"
2523  [(set (match_operand:V4SI 0 "register_operand" "")
2524         (unspec:V8HI [(match_operand:V16QI 1 "register_operand" "")
2525                       (match_operand:V16QI 2 "register_operand" "")]
2526                       UNSPEC_EXTEVEN_V16QI))]
2527   "TARGET_ALTIVEC"
2528   "
2530   rtx mask = gen_reg_rtx (V16QImode);
2531   rtvec v = rtvec_alloc (16);
2532   
2533   RTVEC_ELT (v, 0) = gen_rtx_CONST_INT (QImode, 0);
2534   RTVEC_ELT (v, 1) = gen_rtx_CONST_INT (QImode, 2);
2535   RTVEC_ELT (v, 2) = gen_rtx_CONST_INT (QImode, 4);
2536   RTVEC_ELT (v, 3) = gen_rtx_CONST_INT (QImode, 6);
2537   RTVEC_ELT (v, 4) = gen_rtx_CONST_INT (QImode, 8);
2538   RTVEC_ELT (v, 5) = gen_rtx_CONST_INT (QImode, 10);
2539   RTVEC_ELT (v, 6) = gen_rtx_CONST_INT (QImode, 12);
2540   RTVEC_ELT (v, 7) = gen_rtx_CONST_INT (QImode, 14);
2541   RTVEC_ELT (v, 8) = gen_rtx_CONST_INT (QImode, 16);
2542   RTVEC_ELT (v, 9) = gen_rtx_CONST_INT (QImode, 18);
2543   RTVEC_ELT (v, 10) = gen_rtx_CONST_INT (QImode, 20);
2544   RTVEC_ELT (v, 11) = gen_rtx_CONST_INT (QImode, 22);
2545   RTVEC_ELT (v, 12) = gen_rtx_CONST_INT (QImode, 24);
2546   RTVEC_ELT (v, 13) = gen_rtx_CONST_INT (QImode, 26);
2547   RTVEC_ELT (v, 14) = gen_rtx_CONST_INT (QImode, 28);
2548   RTVEC_ELT (v, 15) = gen_rtx_CONST_INT (QImode, 30);
2549   emit_insn (gen_vec_initv16qi (mask, gen_rtx_PARALLEL (V16QImode, v)));
2550   emit_insn (gen_altivec_vperm_v16qi (operands[0], operands[1], operands[2], mask));
2551   
2552   DONE;
2555 (define_expand "vec_extract_oddv4si"
2556  [(set (match_operand:V4SI 0 "register_operand" "")
2557         (unspec:V8HI [(match_operand:V4SI 1 "register_operand" "")
2558                       (match_operand:V4SI 2 "register_operand" "")]
2559                       UNSPEC_EXTODD_V4SI))]
2560   "TARGET_ALTIVEC"
2561   "
2563   rtx mask = gen_reg_rtx (V16QImode);
2564   rtvec v = rtvec_alloc (16);
2566   RTVEC_ELT (v, 0) = gen_rtx_CONST_INT (QImode, 4);
2567   RTVEC_ELT (v, 1) = gen_rtx_CONST_INT (QImode, 5);
2568   RTVEC_ELT (v, 2) = gen_rtx_CONST_INT (QImode, 6);
2569   RTVEC_ELT (v, 3) = gen_rtx_CONST_INT (QImode, 7);
2570   RTVEC_ELT (v, 4) = gen_rtx_CONST_INT (QImode, 12);
2571   RTVEC_ELT (v, 5) = gen_rtx_CONST_INT (QImode, 13);
2572   RTVEC_ELT (v, 6) = gen_rtx_CONST_INT (QImode, 14);
2573   RTVEC_ELT (v, 7) = gen_rtx_CONST_INT (QImode, 15);
2574   RTVEC_ELT (v, 8) = gen_rtx_CONST_INT (QImode, 20);
2575   RTVEC_ELT (v, 9) = gen_rtx_CONST_INT (QImode, 21);
2576   RTVEC_ELT (v, 10) = gen_rtx_CONST_INT (QImode, 22);
2577   RTVEC_ELT (v, 11) = gen_rtx_CONST_INT (QImode, 23);
2578   RTVEC_ELT (v, 12) = gen_rtx_CONST_INT (QImode, 28);
2579   RTVEC_ELT (v, 13) = gen_rtx_CONST_INT (QImode, 29);
2580   RTVEC_ELT (v, 14) = gen_rtx_CONST_INT (QImode, 30);
2581   RTVEC_ELT (v, 15) = gen_rtx_CONST_INT (QImode, 31);
2582   emit_insn (gen_vec_initv16qi (mask, gen_rtx_PARALLEL (V16QImode, v)));
2583   emit_insn (gen_altivec_vperm_v4si (operands[0], operands[1], operands[2], mask));
2584   
2585   DONE;
2588 (define_expand "vec_extract_oddv4sf"
2589  [(set (match_operand:V4SF 0 "register_operand" "")
2590         (unspec:V8HI [(match_operand:V4SF 1 "register_operand" "")
2591                       (match_operand:V4SF 2 "register_operand" "")]
2592                       UNSPEC_EXTODD_V4SF))]
2593   "TARGET_ALTIVEC"
2594   "
2596   rtx mask = gen_reg_rtx (V16QImode);
2597   rtvec v = rtvec_alloc (16);
2599   RTVEC_ELT (v, 0) = gen_rtx_CONST_INT (QImode, 4);
2600   RTVEC_ELT (v, 1) = gen_rtx_CONST_INT (QImode, 5);
2601   RTVEC_ELT (v, 2) = gen_rtx_CONST_INT (QImode, 6);
2602   RTVEC_ELT (v, 3) = gen_rtx_CONST_INT (QImode, 7);
2603   RTVEC_ELT (v, 4) = gen_rtx_CONST_INT (QImode, 12);
2604   RTVEC_ELT (v, 5) = gen_rtx_CONST_INT (QImode, 13);
2605   RTVEC_ELT (v, 6) = gen_rtx_CONST_INT (QImode, 14);
2606   RTVEC_ELT (v, 7) = gen_rtx_CONST_INT (QImode, 15);
2607   RTVEC_ELT (v, 8) = gen_rtx_CONST_INT (QImode, 20);
2608   RTVEC_ELT (v, 9) = gen_rtx_CONST_INT (QImode, 21);
2609   RTVEC_ELT (v, 10) = gen_rtx_CONST_INT (QImode, 22);
2610   RTVEC_ELT (v, 11) = gen_rtx_CONST_INT (QImode, 23);
2611   RTVEC_ELT (v, 12) = gen_rtx_CONST_INT (QImode, 28);
2612   RTVEC_ELT (v, 13) = gen_rtx_CONST_INT (QImode, 29);
2613   RTVEC_ELT (v, 14) = gen_rtx_CONST_INT (QImode, 30);
2614   RTVEC_ELT (v, 15) = gen_rtx_CONST_INT (QImode, 31);
2615   emit_insn (gen_vec_initv16qi (mask, gen_rtx_PARALLEL (V16QImode, v)));
2616   emit_insn (gen_altivec_vperm_v4sf (operands[0], operands[1], operands[2], mask));
2618   DONE;
2621 (define_insn "vpkuhum_nomode"
2622   [(set (match_operand:V16QI 0 "register_operand" "=v")
2623         (unspec:V16QI [(match_operand 1 "register_operand" "v")
2624                        (match_operand 2 "register_operand" "v")]
2625                       UNSPEC_VPKUHUM))] 
2626   "TARGET_ALTIVEC"
2627   "vpkuhum %0,%1,%2"
2628   [(set_attr "type" "vecperm")])
2630 (define_insn "vpkuwum_nomode"
2631   [(set (match_operand:V8HI 0 "register_operand" "=v")
2632         (unspec:V8HI [(match_operand 1 "register_operand" "v")
2633                       (match_operand 2 "register_operand" "v")]
2634                      UNSPEC_VPKUWUM))]
2635   "TARGET_ALTIVEC"
2636   "vpkuwum %0,%1,%2"
2637   [(set_attr "type" "vecperm")])
2639 (define_expand "vec_extract_oddv8hi"
2640  [(set (match_operand:V8HI 0 "register_operand" "")
2641         (unspec:V8HI [(match_operand:V8HI 1 "register_operand" "")
2642                       (match_operand:V8HI 2 "register_operand" "")]
2643                       UNSPEC_EXTODD_V8HI))]
2644   "TARGET_ALTIVEC"
2645   "
2647   emit_insn (gen_vpkuwum_nomode (operands[0], operands[1], operands[2]));
2648   DONE;
2651 (define_expand "vec_extract_oddv16qi"
2652  [(set (match_operand:V16QI 0 "register_operand" "")
2653         (unspec:V16QI [(match_operand:V16QI 1 "register_operand" "")
2654                       (match_operand:V16QI 2 "register_operand" "")]
2655                       UNSPEC_EXTODD_V16QI))]
2656   "TARGET_ALTIVEC"
2657   "
2659   emit_insn (gen_vpkuhum_nomode (operands[0], operands[1], operands[2]));
2660   DONE;
2663 (define_expand "vec_interleave_high<mode>"
2664  [(set (match_operand:VI 0 "register_operand" "")
2665         (unspec:VI [(match_operand:VI 1 "register_operand" "")
2666                     (match_operand:VI 2 "register_operand" "")]
2667                      UNSPEC_INTERHI))]
2668   "TARGET_ALTIVEC"
2669   "
2671   emit_insn (gen_altivec_vmrgh<VI_char> (operands[0], operands[1], operands[2]));
2672   DONE;
2675 (define_expand "vec_interleave_low<mode>"
2676  [(set (match_operand:VI 0 "register_operand" "")
2677         (unspec:VI [(match_operand:VI 1 "register_operand" "")
2678                     (match_operand:VI 2 "register_operand" "")]
2679                      UNSPEC_INTERLO))]
2680   "TARGET_ALTIVEC"
2681   "
2683   emit_insn (gen_altivec_vmrgl<VI_char> (operands[0], operands[1], operands[2]));
2684   DONE;
2687 (define_expand "vec_unpacks_float_hi_v8hi"
2688  [(set (match_operand:V4SF 0 "register_operand" "")
2689         (unspec:V4SF [(match_operand:V8HI 1 "register_operand" "")]
2690                      UNSPEC_VUPKHS_V4SF))]
2691   "TARGET_ALTIVEC"
2692   "
2694   rtx tmp = gen_reg_rtx (V4SImode);
2696   emit_insn (gen_vec_unpacks_hi_v8hi (tmp, operands[1]));
2697   emit_insn (gen_altivec_vcfsx (operands[0], tmp, const0_rtx));
2698   DONE;
2701 (define_expand "vec_unpacks_float_lo_v8hi"
2702  [(set (match_operand:V4SF 0 "register_operand" "")
2703         (unspec:V4SF [(match_operand:V8HI 1 "register_operand" "")]
2704                      UNSPEC_VUPKLS_V4SF))]
2705   "TARGET_ALTIVEC"
2706   "
2708   rtx tmp = gen_reg_rtx (V4SImode);
2710   emit_insn (gen_vec_unpacks_lo_v8hi (tmp, operands[1]));
2711   emit_insn (gen_altivec_vcfsx (operands[0], tmp, const0_rtx));
2712   DONE;
2715 (define_expand "vec_unpacku_float_hi_v8hi"
2716  [(set (match_operand:V4SF 0 "register_operand" "")
2717         (unspec:V4SF [(match_operand:V8HI 1 "register_operand" "")]
2718                      UNSPEC_VUPKHU_V4SF))]
2719   "TARGET_ALTIVEC"
2720   "
2722   rtx tmp = gen_reg_rtx (V4SImode);
2724   emit_insn (gen_vec_unpacku_hi_v8hi (tmp, operands[1]));
2725   emit_insn (gen_altivec_vcfux (operands[0], tmp, const0_rtx));
2726   DONE;
2729 (define_expand "vec_unpacku_float_lo_v8hi"
2730  [(set (match_operand:V4SF 0 "register_operand" "")
2731         (unspec:V4SF [(match_operand:V8HI 1 "register_operand" "")]
2732                      UNSPEC_VUPKLU_V4SF))]
2733   "TARGET_ALTIVEC"
2734   "
2736   rtx tmp = gen_reg_rtx (V4SImode);
2738   emit_insn (gen_vec_unpacku_lo_v8hi (tmp, operands[1]));
2739   emit_insn (gen_altivec_vcfux (operands[0], tmp, const0_rtx));
2740   DONE;