* config/rs6000/rs6000.c (rs6000_option_override_internal): Do not
[official-gcc.git] / gcc / config / rs6000 / altivec.md
blob8c168c85daf9373d6139e3f7b200b988ce07f7d2
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 ;; The save_vregs and restore_vregs patterns don't use memory_operand
317 ;; because (plus (reg) (const_int)) is not a valid vector address.
318 ;; This way is more compact than describing exactly what happens in
319 ;; the out-of-line functions, ie. loading the constant into r11/r12
320 ;; then using indexed addressing, and requires less editing of rtl
321 ;; to describe the operation to dwarf2out_frame_debug_expr.
322 (define_insn "*save_vregs_<mode>_r11"
323   [(match_parallel 0 "any_parallel_operand"
324      [(clobber (reg:P 65))
325       (use (match_operand:P 1 "symbol_ref_operand" "s"))
326       (clobber (reg:P 11))
327       (use (reg:P 0))
328       (set (mem:V4SI (plus:P (match_operand:P 2 "gpc_reg_operand" "b")
329                              (match_operand:P 3 "short_cint_operand" "I")))
330            (match_operand:V4SI 4 "gpc_reg_operand" "v"))])]
331   ""
332   "bl %1"
333   [(set_attr "type" "branch")
334    (set_attr "length" "4")])
336 (define_insn "*save_vregs_<mode>_r12"
337   [(match_parallel 0 "any_parallel_operand"
338      [(clobber (reg:P 65))
339       (use (match_operand:P 1 "symbol_ref_operand" "s"))
340       (clobber (reg:P 12))
341       (use (reg:P 0))
342       (set (mem:V4SI (plus:P (match_operand:P 2 "gpc_reg_operand" "b")
343                              (match_operand:P 3 "short_cint_operand" "I")))
344            (match_operand:V4SI 4 "gpc_reg_operand" "v"))])]
345   ""
346   "bl %1"
347   [(set_attr "type" "branch")
348    (set_attr "length" "4")])
350 (define_insn "*restore_vregs_<mode>_r11"
351   [(match_parallel 0 "any_parallel_operand"
352      [(clobber (reg:P 65))
353       (use (match_operand:P 1 "symbol_ref_operand" "s"))
354       (clobber (reg:P 11))
355       (use (reg:P 0))
356       (set (match_operand:V4SI 2 "gpc_reg_operand" "=v")
357            (mem:V4SI (plus:P (match_operand:P 3 "gpc_reg_operand" "b")
358                              (match_operand:P 4 "short_cint_operand" "I"))))])]
359   ""
360   "bl %1"
361   [(set_attr "type" "branch")
362    (set_attr "length" "4")])
364 (define_insn "*restore_vregs_<mode>_r12"
365   [(match_parallel 0 "any_parallel_operand"
366      [(clobber (reg:P 65))
367       (use (match_operand:P 1 "symbol_ref_operand" "s"))
368       (clobber (reg:P 12))
369       (use (reg:P 0))
370       (set (match_operand:V4SI 2 "gpc_reg_operand" "=v")
371            (mem:V4SI (plus:P (match_operand:P 3 "gpc_reg_operand" "b")
372                              (match_operand:P 4 "short_cint_operand" "I"))))])]
373   ""
374   "bl %1"
375   [(set_attr "type" "branch")
376    (set_attr "length" "4")])
378 ;; Simple binary operations.
380 ;; add
381 (define_insn "add<mode>3"
382   [(set (match_operand:VI 0 "register_operand" "=v")
383         (plus:VI (match_operand:VI 1 "register_operand" "v")
384                  (match_operand:VI 2 "register_operand" "v")))]
385   "TARGET_ALTIVEC"
386   "vaddu<VI_char>m %0,%1,%2"
387   [(set_attr "type" "vecsimple")])
389 (define_insn "*altivec_addv4sf3"
390   [(set (match_operand:V4SF 0 "register_operand" "=v")
391         (plus:V4SF (match_operand:V4SF 1 "register_operand" "v")
392                    (match_operand:V4SF 2 "register_operand" "v")))]
393   "VECTOR_UNIT_ALTIVEC_P (V4SFmode)"
394   "vaddfp %0,%1,%2"
395   [(set_attr "type" "vecfloat")])
397 (define_insn "altivec_vaddcuw"
398   [(set (match_operand:V4SI 0 "register_operand" "=v")
399         (unspec:V4SI [(match_operand:V4SI 1 "register_operand" "v")
400                       (match_operand:V4SI 2 "register_operand" "v")]
401                      UNSPEC_VADDCUW))]
402   "TARGET_ALTIVEC"
403   "vaddcuw %0,%1,%2"
404   [(set_attr "type" "vecsimple")])
406 (define_insn "altivec_vaddu<VI_char>s"
407   [(set (match_operand:VI 0 "register_operand" "=v")
408         (unspec:VI [(match_operand:VI 1 "register_operand" "v")
409                     (match_operand:VI 2 "register_operand" "v")]
410                    UNSPEC_VADDU))
411    (set (reg:SI 110) (unspec:SI [(const_int 0)] UNSPEC_SET_VSCR))]
412   "TARGET_ALTIVEC"
413   "vaddu<VI_char>s %0,%1,%2"
414   [(set_attr "type" "vecsimple")])
416 (define_insn "altivec_vadds<VI_char>s"
417   [(set (match_operand:VI 0 "register_operand" "=v")
418         (unspec:VI [(match_operand:VI 1 "register_operand" "v")
419                     (match_operand:VI 2 "register_operand" "v")]
420                    UNSPEC_VADDS))
421    (set (reg:SI 110) (unspec:SI [(const_int 0)] UNSPEC_SET_VSCR))]
422   "TARGET_ALTIVEC"
423   "vadds<VI_char>s %0,%1,%2"
424   [(set_attr "type" "vecsimple")])
426 ;; sub
427 (define_insn "sub<mode>3"
428   [(set (match_operand:VI 0 "register_operand" "=v")
429         (minus:VI (match_operand:VI 1 "register_operand" "v")
430                   (match_operand:VI 2 "register_operand" "v")))]
431   "TARGET_ALTIVEC"
432   "vsubu<VI_char>m %0,%1,%2"
433   [(set_attr "type" "vecsimple")])
435 (define_insn "*altivec_subv4sf3"
436   [(set (match_operand:V4SF 0 "register_operand" "=v")
437         (minus:V4SF (match_operand:V4SF 1 "register_operand" "v")
438                     (match_operand:V4SF 2 "register_operand" "v")))]
439   "VECTOR_UNIT_ALTIVEC_P (V4SFmode)"
440   "vsubfp %0,%1,%2"
441   [(set_attr "type" "vecfloat")])
443 (define_insn "altivec_vsubcuw"
444   [(set (match_operand:V4SI 0 "register_operand" "=v")
445         (unspec:V4SI [(match_operand:V4SI 1 "register_operand" "v")
446                       (match_operand:V4SI 2 "register_operand" "v")]
447                      UNSPEC_VSUBCUW))]
448   "TARGET_ALTIVEC"
449   "vsubcuw %0,%1,%2"
450   [(set_attr "type" "vecsimple")])
452 (define_insn "altivec_vsubu<VI_char>s"
453   [(set (match_operand:VI 0 "register_operand" "=v")
454         (unspec:VI [(match_operand:VI 1 "register_operand" "v")
455                     (match_operand:VI 2 "register_operand" "v")]
456                    UNSPEC_VSUBU))
457    (set (reg:SI 110) (unspec:SI [(const_int 0)] UNSPEC_SET_VSCR))]
458   "TARGET_ALTIVEC"
459   "vsubu<VI_char>s %0,%1,%2"
460   [(set_attr "type" "vecsimple")])
462 (define_insn "altivec_vsubs<VI_char>s"
463   [(set (match_operand:VI 0 "register_operand" "=v")
464         (unspec:VI [(match_operand:VI 1 "register_operand" "v")
465                     (match_operand:VI 2 "register_operand" "v")]
466                    UNSPEC_VSUBS))
467    (set (reg:SI 110) (unspec:SI [(const_int 0)] UNSPEC_SET_VSCR))]
468   "TARGET_ALTIVEC"
469   "vsubs<VI_char>s %0,%1,%2"
470   [(set_attr "type" "vecsimple")])
473 (define_insn "altivec_vavgu<VI_char>"
474   [(set (match_operand:VI 0 "register_operand" "=v")
475         (unspec:VI [(match_operand:VI 1 "register_operand" "v")
476                     (match_operand:VI 2 "register_operand" "v")]
477                    UNSPEC_VAVGU))]
478   "TARGET_ALTIVEC"
479   "vavgu<VI_char> %0,%1,%2"
480   [(set_attr "type" "vecsimple")])
482 (define_insn "altivec_vavgs<VI_char>"
483   [(set (match_operand:VI 0 "register_operand" "=v")
484         (unspec:VI [(match_operand:VI 1 "register_operand" "v")
485                     (match_operand:VI 2 "register_operand" "v")]
486                    UNSPEC_VAVGS))]
487   "TARGET_ALTIVEC"
488   "vavgs<VI_char> %0,%1,%2"
489   [(set_attr "type" "vecsimple")])
491 (define_insn "altivec_vcmpbfp"
492   [(set (match_operand:V4SI 0 "register_operand" "=v")
493         (unspec:V4SI [(match_operand:V4SF 1 "register_operand" "v")
494                       (match_operand:V4SF 2 "register_operand" "v")] 
495                       UNSPEC_VCMPBFP))]
496   "TARGET_ALTIVEC"
497   "vcmpbfp %0,%1,%2"
498   [(set_attr "type" "veccmp")])
500 (define_insn "*altivec_eq<mode>"
501   [(set (match_operand:VI 0 "altivec_register_operand" "=v")
502         (eq:VI (match_operand:VI 1 "altivec_register_operand" "v")
503                (match_operand:VI 2 "altivec_register_operand" "v")))]
504   "TARGET_ALTIVEC"
505   "vcmpequ<VI_char> %0,%1,%2"
506   [(set_attr "type" "veccmp")])
508 (define_insn "*altivec_gt<mode>"
509   [(set (match_operand:VI 0 "altivec_register_operand" "=v")
510         (gt:VI (match_operand:VI 1 "altivec_register_operand" "v")
511                (match_operand:VI 2 "altivec_register_operand" "v")))]
512   "TARGET_ALTIVEC"
513   "vcmpgts<VI_char> %0,%1,%2"
514   [(set_attr "type" "veccmp")])
516 (define_insn "*altivec_gtu<mode>"
517   [(set (match_operand:VI 0 "altivec_register_operand" "=v")
518         (gtu:VI (match_operand:VI 1 "altivec_register_operand" "v")
519                 (match_operand:VI 2 "altivec_register_operand" "v")))]
520   "TARGET_ALTIVEC"
521   "vcmpgtu<VI_char> %0,%1,%2"
522   [(set_attr "type" "veccmp")])
524 (define_insn "*altivec_eqv4sf"
525   [(set (match_operand:V4SF 0 "altivec_register_operand" "=v")
526         (eq:V4SF (match_operand:V4SF 1 "altivec_register_operand" "v")
527                  (match_operand:V4SF 2 "altivec_register_operand" "v")))]
528   "VECTOR_UNIT_ALTIVEC_P (V4SFmode)"
529   "vcmpeqfp %0,%1,%2"
530   [(set_attr "type" "veccmp")])
532 (define_insn "*altivec_gtv4sf"
533   [(set (match_operand:V4SF 0 "altivec_register_operand" "=v")
534         (gt:V4SF (match_operand:V4SF 1 "altivec_register_operand" "v")
535                  (match_operand:V4SF 2 "altivec_register_operand" "v")))]
536   "VECTOR_UNIT_ALTIVEC_P (V4SFmode)"
537   "vcmpgtfp %0,%1,%2"
538   [(set_attr "type" "veccmp")])
540 (define_insn "*altivec_gev4sf"
541   [(set (match_operand:V4SF 0 "altivec_register_operand" "=v")
542         (ge:V4SF (match_operand:V4SF 1 "altivec_register_operand" "v")
543                  (match_operand:V4SF 2 "altivec_register_operand" "v")))]
544   "VECTOR_UNIT_ALTIVEC_P (V4SFmode)"
545   "vcmpgefp %0,%1,%2"
546   [(set_attr "type" "veccmp")])
548 (define_insn "*altivec_vsel<mode>"
549   [(set (match_operand:VM 0 "altivec_register_operand" "=v")
550         (if_then_else:VM
551          (ne:CC (match_operand:VM 1 "altivec_register_operand" "v")
552                 (match_operand:VM 4 "zero_constant" ""))
553          (match_operand:VM 2 "altivec_register_operand" "v")
554          (match_operand:VM 3 "altivec_register_operand" "v")))]
555   "VECTOR_MEM_ALTIVEC_P (<MODE>mode)"
556   "vsel %0,%3,%2,%1"
557   [(set_attr "type" "vecperm")])
559 (define_insn "*altivec_vsel<mode>_uns"
560   [(set (match_operand:VM 0 "altivec_register_operand" "=v")
561         (if_then_else:VM
562          (ne:CCUNS (match_operand:VM 1 "altivec_register_operand" "v")
563                    (match_operand:VM 4 "zero_constant" ""))
564          (match_operand:VM 2 "altivec_register_operand" "v")
565          (match_operand:VM 3 "altivec_register_operand" "v")))]
566   "VECTOR_MEM_ALTIVEC_P (<MODE>mode)"
567   "vsel %0,%3,%2,%1"
568   [(set_attr "type" "vecperm")])
570 ;; Fused multiply add.
572 (define_insn "*altivec_fmav4sf4"
573   [(set (match_operand:V4SF 0 "register_operand" "=v")
574         (fma:V4SF (match_operand:V4SF 1 "register_operand" "v")
575                   (match_operand:V4SF 2 "register_operand" "v")
576                   (match_operand:V4SF 3 "register_operand" "v")))]
577   "VECTOR_UNIT_ALTIVEC_P (V4SFmode)"
578   "vmaddfp %0,%1,%2,%3"
579   [(set_attr "type" "vecfloat")])
581 ;; We do multiply as a fused multiply-add with an add of a -0.0 vector.
583 (define_expand "altivec_mulv4sf3"
584   [(set (match_operand:V4SF 0 "register_operand" "")
585         (fma:V4SF (match_operand:V4SF 1 "register_operand" "")
586                   (match_operand:V4SF 2 "register_operand" "")
587                   (match_dup 3)))]
588   "VECTOR_UNIT_ALTIVEC_P (V4SFmode)"
590   rtx neg0;
592   /* Generate [-0.0, -0.0, -0.0, -0.0].  */
593   neg0 = gen_reg_rtx (V4SImode);
594   emit_insn (gen_altivec_vspltisw (neg0, constm1_rtx));
595   emit_insn (gen_vashlv4si3 (neg0, neg0, neg0));
597   operands[3] = gen_lowpart (V4SFmode, neg0);
600 ;; 32-bit integer multiplication
601 ;; A_high = Operand_0 & 0xFFFF0000 >> 16
602 ;; A_low = Operand_0 & 0xFFFF
603 ;; B_high = Operand_1 & 0xFFFF0000 >> 16
604 ;; B_low = Operand_1 & 0xFFFF
605 ;; result = A_low * B_low + (A_high * B_low + B_high * A_low) << 16
607 ;; (define_insn "mulv4si3"
608 ;;   [(set (match_operand:V4SI 0 "register_operand" "=v")
609 ;;         (mult:V4SI (match_operand:V4SI 1 "register_operand" "v")
610 ;;                    (match_operand:V4SI 2 "register_operand" "v")))]
611 (define_expand "mulv4si3"
612   [(use (match_operand:V4SI 0 "register_operand" ""))
613    (use (match_operand:V4SI 1 "register_operand" ""))
614    (use (match_operand:V4SI 2 "register_operand" ""))]
615    "TARGET_ALTIVEC"
616    "
618    rtx zero;
619    rtx swap;
620    rtx small_swap;
621    rtx sixteen;
622    rtx one;
623    rtx two;
624    rtx low_product;
625    rtx high_product;
626        
627    zero = gen_reg_rtx (V4SImode);
628    emit_insn (gen_altivec_vspltisw (zero, const0_rtx));
630    sixteen = gen_reg_rtx (V4SImode);   
631    emit_insn (gen_altivec_vspltisw (sixteen,  gen_rtx_CONST_INT (V4SImode, -16)));
633    swap = gen_reg_rtx (V4SImode);
634    emit_insn (gen_vrotlv4si3 (swap, operands[2], sixteen));
636    one = gen_reg_rtx (V8HImode);
637    convert_move (one, operands[1], 0);
639    two = gen_reg_rtx (V8HImode);
640    convert_move (two, operands[2], 0);
642    small_swap = gen_reg_rtx (V8HImode);
643    convert_move (small_swap, swap, 0);
645    low_product = gen_reg_rtx (V4SImode);
646    emit_insn (gen_vec_widen_umult_odd_v8hi (low_product, one, two));
648    high_product = gen_reg_rtx (V4SImode);
649    emit_insn (gen_altivec_vmsumuhm (high_product, one, small_swap, zero));
651    emit_insn (gen_vashlv4si3 (high_product, high_product, sixteen));
653    emit_insn (gen_addv4si3 (operands[0], high_product, low_product));
654    
655    DONE;
656  }")
658 (define_expand "mulv8hi3"
659   [(use (match_operand:V8HI 0 "register_operand" ""))
660    (use (match_operand:V8HI 1 "register_operand" ""))
661    (use (match_operand:V8HI 2 "register_operand" ""))]
662    "TARGET_ALTIVEC"
663    "
665    rtx odd = gen_reg_rtx (V4SImode);
666    rtx even = gen_reg_rtx (V4SImode);
667    rtx high = gen_reg_rtx (V4SImode);
668    rtx low = gen_reg_rtx (V4SImode);
670    emit_insn (gen_vec_widen_smult_even_v8hi (even, operands[1], operands[2]));
671    emit_insn (gen_vec_widen_smult_odd_v8hi (odd, operands[1], operands[2]));
673    emit_insn (gen_altivec_vmrghw (high, even, odd));
674    emit_insn (gen_altivec_vmrglw (low, even, odd));
676    emit_insn (gen_altivec_vpkuwum (operands[0], high, low));
678    DONE;
681 ;; Fused multiply subtract 
682 (define_insn "*altivec_vnmsubfp"
683   [(set (match_operand:V4SF 0 "register_operand" "=v")
684         (neg:V4SF
685          (fma:V4SF (match_operand:V4SF 1 "register_operand" "v")
686                    (match_operand:V4SF 2 "register_operand" "v")
687                    (neg:V4SF
688                     (match_operand:V4SF 3 "register_operand" "v")))))]
689   "VECTOR_UNIT_ALTIVEC_P (V4SFmode)"
690   "vnmsubfp %0,%1,%2,%3"
691   [(set_attr "type" "vecfloat")])
693 (define_insn "altivec_vmsumu<VI_char>m"
694   [(set (match_operand:V4SI 0 "register_operand" "=v")
695         (unspec:V4SI [(match_operand:VIshort 1 "register_operand" "v")
696                       (match_operand:VIshort 2 "register_operand" "v")
697                       (match_operand:V4SI 3 "register_operand" "v")]
698                      UNSPEC_VMSUMU))]
699   "TARGET_ALTIVEC"
700   "vmsumu<VI_char>m %0,%1,%2,%3"
701   [(set_attr "type" "veccomplex")])
703 (define_insn "altivec_vmsumm<VI_char>m"
704   [(set (match_operand:V4SI 0 "register_operand" "=v")
705         (unspec:V4SI [(match_operand:VIshort 1 "register_operand" "v")
706                       (match_operand:VIshort 2 "register_operand" "v")
707                       (match_operand:V4SI 3 "register_operand" "v")]
708                      UNSPEC_VMSUMM))]
709   "TARGET_ALTIVEC"
710   "vmsumm<VI_char>m %0,%1,%2,%3"
711   [(set_attr "type" "veccomplex")])
713 (define_insn "altivec_vmsumshm"
714   [(set (match_operand:V4SI 0 "register_operand" "=v")
715         (unspec:V4SI [(match_operand:V8HI 1 "register_operand" "v")
716                       (match_operand:V8HI 2 "register_operand" "v")
717                       (match_operand:V4SI 3 "register_operand" "v")]
718                      UNSPEC_VMSUMSHM))]
719   "TARGET_ALTIVEC"
720   "vmsumshm %0,%1,%2,%3"
721   [(set_attr "type" "veccomplex")])
723 (define_insn "altivec_vmsumuhs"
724   [(set (match_operand:V4SI 0 "register_operand" "=v")
725         (unspec:V4SI [(match_operand:V8HI 1 "register_operand" "v")
726                       (match_operand:V8HI 2 "register_operand" "v")
727                       (match_operand:V4SI 3 "register_operand" "v")]
728                      UNSPEC_VMSUMUHS))
729    (set (reg:SI 110) (unspec:SI [(const_int 0)] UNSPEC_SET_VSCR))]
730   "TARGET_ALTIVEC"
731   "vmsumuhs %0,%1,%2,%3"
732   [(set_attr "type" "veccomplex")])
734 (define_insn "altivec_vmsumshs"
735   [(set (match_operand:V4SI 0 "register_operand" "=v")
736         (unspec:V4SI [(match_operand:V8HI 1 "register_operand" "v")
737                       (match_operand:V8HI 2 "register_operand" "v")
738                       (match_operand:V4SI 3 "register_operand" "v")]
739                      UNSPEC_VMSUMSHS))
740    (set (reg:SI 110) (unspec:SI [(const_int 0)] UNSPEC_SET_VSCR))]
741   "TARGET_ALTIVEC"
742   "vmsumshs %0,%1,%2,%3"
743   [(set_attr "type" "veccomplex")])
745 ;; max
747 (define_insn "umax<mode>3"
748   [(set (match_operand:VI 0 "register_operand" "=v")
749         (umax:VI (match_operand:VI 1 "register_operand" "v")
750                  (match_operand:VI 2 "register_operand" "v")))]
751   "TARGET_ALTIVEC"
752   "vmaxu<VI_char> %0,%1,%2"
753   [(set_attr "type" "vecsimple")])
755 (define_insn "smax<mode>3"
756   [(set (match_operand:VI 0 "register_operand" "=v")
757         (smax:VI (match_operand:VI 1 "register_operand" "v")
758                  (match_operand:VI 2 "register_operand" "v")))]
759   "TARGET_ALTIVEC"
760   "vmaxs<VI_char> %0,%1,%2"
761   [(set_attr "type" "vecsimple")])
763 (define_insn "*altivec_smaxv4sf3"
764   [(set (match_operand:V4SF 0 "register_operand" "=v")
765         (smax:V4SF (match_operand:V4SF 1 "register_operand" "v")
766                    (match_operand:V4SF 2 "register_operand" "v")))]
767   "VECTOR_UNIT_ALTIVEC_P (V4SFmode)"
768   "vmaxfp %0,%1,%2"
769   [(set_attr "type" "veccmp")])
771 (define_insn "umin<mode>3"
772   [(set (match_operand:VI 0 "register_operand" "=v")
773         (umin:VI (match_operand:VI 1 "register_operand" "v")
774                  (match_operand:VI 2 "register_operand" "v")))]
775   "TARGET_ALTIVEC"
776   "vminu<VI_char> %0,%1,%2"
777   [(set_attr "type" "vecsimple")])
779 (define_insn "smin<mode>3"
780   [(set (match_operand:VI 0 "register_operand" "=v")
781         (smin:VI (match_operand:VI 1 "register_operand" "v")
782                  (match_operand:VI 2 "register_operand" "v")))]
783   "TARGET_ALTIVEC"
784   "vmins<VI_char> %0,%1,%2"
785   [(set_attr "type" "vecsimple")])
787 (define_insn "*altivec_sminv4sf3"
788   [(set (match_operand:V4SF 0 "register_operand" "=v")
789         (smin:V4SF (match_operand:V4SF 1 "register_operand" "v")
790                    (match_operand:V4SF 2 "register_operand" "v")))]
791   "VECTOR_UNIT_ALTIVEC_P (V4SFmode)"
792   "vminfp %0,%1,%2"
793   [(set_attr "type" "veccmp")])
795 (define_insn "altivec_vmhaddshs"
796   [(set (match_operand:V8HI 0 "register_operand" "=v")
797         (unspec:V8HI [(match_operand:V8HI 1 "register_operand" "v")
798                       (match_operand:V8HI 2 "register_operand" "v")
799                       (match_operand:V8HI 3 "register_operand" "v")]
800                      UNSPEC_VMHADDSHS))
801    (set (reg:SI 110) (unspec:SI [(const_int 0)] UNSPEC_SET_VSCR))]
802   "TARGET_ALTIVEC"
803   "vmhaddshs %0,%1,%2,%3"
804   [(set_attr "type" "veccomplex")])
806 (define_insn "altivec_vmhraddshs"
807   [(set (match_operand:V8HI 0 "register_operand" "=v")
808         (unspec:V8HI [(match_operand:V8HI 1 "register_operand" "v")
809                       (match_operand:V8HI 2 "register_operand" "v")
810                       (match_operand:V8HI 3 "register_operand" "v")]
811                      UNSPEC_VMHRADDSHS))
812    (set (reg:SI 110) (unspec:SI [(const_int 0)] UNSPEC_SET_VSCR))]
813   "TARGET_ALTIVEC"
814   "vmhraddshs %0,%1,%2,%3"
815   [(set_attr "type" "veccomplex")])
817 (define_insn "altivec_vmladduhm"
818   [(set (match_operand:V8HI 0 "register_operand" "=v")
819         (unspec:V8HI [(match_operand:V8HI 1 "register_operand" "v")
820                       (match_operand:V8HI 2 "register_operand" "v")
821                       (match_operand:V8HI 3 "register_operand" "v")]
822                      UNSPEC_VMLADDUHM))]
823   "TARGET_ALTIVEC"
824   "vmladduhm %0,%1,%2,%3"
825   [(set_attr "type" "veccomplex")])
827 (define_insn "altivec_vmrghb"
828   [(set (match_operand:V16QI 0 "register_operand" "=v")
829         (vec_select:V16QI
830           (vec_concat:V32QI
831             (match_operand:V16QI 1 "register_operand" "v")
832             (match_operand:V16QI 2 "register_operand" "v"))
833           (parallel [(const_int 0) (const_int 16)
834                      (const_int 1) (const_int 17)
835                      (const_int 2) (const_int 18)
836                      (const_int 3) (const_int 19)
837                      (const_int 4) (const_int 20)
838                      (const_int 5) (const_int 21)
839                      (const_int 6) (const_int 22)
840                      (const_int 7) (const_int 23)])))]
841   "TARGET_ALTIVEC"
842   "vmrghb %0,%1,%2"
843   [(set_attr "type" "vecperm")])
845 (define_insn "altivec_vmrghh"
846   [(set (match_operand:V8HI 0 "register_operand" "=v")
847         (vec_select:V8HI
848           (vec_concat:V16HI
849             (match_operand:V8HI 1 "register_operand" "v")
850             (match_operand:V8HI 2 "register_operand" "v"))
851           (parallel [(const_int 0) (const_int 8)
852                      (const_int 1) (const_int 9)
853                      (const_int 2) (const_int 10)
854                      (const_int 3) (const_int 11)])))]
855   "TARGET_ALTIVEC"
856   "vmrghh %0,%1,%2"
857   [(set_attr "type" "vecperm")])
859 (define_insn "altivec_vmrghw"
860   [(set (match_operand:V4SI 0 "register_operand" "=v")
861         (vec_select:V4SI
862           (vec_concat:V8SI
863             (match_operand:V4SI 1 "register_operand" "v")
864             (match_operand:V4SI 2 "register_operand" "v"))
865           (parallel [(const_int 0) (const_int 4)
866                      (const_int 1) (const_int 5)])))]
867   "VECTOR_MEM_ALTIVEC_P (V4SImode)"
868   "vmrghw %0,%1,%2"
869   [(set_attr "type" "vecperm")])
871 (define_insn "*altivec_vmrghsf"
872   [(set (match_operand:V4SF 0 "register_operand" "=v")
873         (vec_select:V4SF
874           (vec_concat:V8SF
875             (match_operand:V4SF 1 "register_operand" "v")
876             (match_operand:V4SF 2 "register_operand" "v"))
877           (parallel [(const_int 0) (const_int 4)
878                      (const_int 1) (const_int 5)])))]
879   "VECTOR_MEM_ALTIVEC_P (V4SFmode)"
880   "vmrghw %0,%1,%2"
881   [(set_attr "type" "vecperm")])
883 (define_insn "altivec_vmrglb"
884   [(set (match_operand:V16QI 0 "register_operand" "=v")
885         (vec_select:V16QI
886           (vec_concat:V32QI
887             (match_operand:V16QI 1 "register_operand" "v")
888             (match_operand:V16QI 2 "register_operand" "v"))
889           (parallel [(const_int  8) (const_int 24)
890                      (const_int  9) (const_int 25)
891                      (const_int 10) (const_int 26)
892                      (const_int 11) (const_int 27)
893                      (const_int 12) (const_int 28)
894                      (const_int 13) (const_int 29)
895                      (const_int 14) (const_int 30)
896                      (const_int 15) (const_int 31)])))]
897   "TARGET_ALTIVEC"
898   "vmrglb %0,%1,%2"
899   [(set_attr "type" "vecperm")])
901 (define_insn "altivec_vmrglh"
902   [(set (match_operand:V8HI 0 "register_operand" "=v")
903         (vec_select:V8HI
904           (vec_concat:V16HI
905             (match_operand:V8HI 1 "register_operand" "v")
906             (match_operand:V8HI 2 "register_operand" "v"))
907           (parallel [(const_int 4) (const_int 12)
908                      (const_int 5) (const_int 13)
909                      (const_int 6) (const_int 14)
910                      (const_int 7) (const_int 15)])))]
911   "TARGET_ALTIVEC"
912   "vmrglh %0,%1,%2"
913   [(set_attr "type" "vecperm")])
915 (define_insn "altivec_vmrglw"
916   [(set (match_operand:V4SI 0 "register_operand" "=v")
917         (vec_select:V4SI
918           (vec_concat:V8SI
919             (match_operand:V4SI 1 "register_operand" "v")
920             (match_operand:V4SI 2 "register_operand" "v"))
921           (parallel [(const_int 2) (const_int 6)
922                      (const_int 3) (const_int 7)])))]
923   "VECTOR_MEM_ALTIVEC_P (V4SImode)"
924   "vmrglw %0,%1,%2"
925   [(set_attr "type" "vecperm")])
927 (define_insn "*altivec_vmrglsf"
928   [(set (match_operand:V4SF 0 "register_operand" "=v")
929         (vec_select:V4SF
930          (vec_concat:V8SF
931            (match_operand:V4SF 1 "register_operand" "v")
932            (match_operand:V4SF 2 "register_operand" "v"))
933          (parallel [(const_int 2) (const_int 6)
934                     (const_int 3) (const_int 7)])))]
935   "VECTOR_MEM_ALTIVEC_P (V4SFmode)"
936   "vmrglw %0,%1,%2"
937   [(set_attr "type" "vecperm")])
939 (define_insn "vec_widen_umult_even_v16qi"
940   [(set (match_operand:V8HI 0 "register_operand" "=v")
941         (unspec:V8HI [(match_operand:V16QI 1 "register_operand" "v")
942                       (match_operand:V16QI 2 "register_operand" "v")]
943                      UNSPEC_VMULEUB))]
944   "TARGET_ALTIVEC"
945   "vmuleub %0,%1,%2"
946   [(set_attr "type" "veccomplex")])
948 (define_insn "vec_widen_smult_even_v16qi"
949   [(set (match_operand:V8HI 0 "register_operand" "=v")
950         (unspec:V8HI [(match_operand:V16QI 1 "register_operand" "v")
951                       (match_operand:V16QI 2 "register_operand" "v")]
952                      UNSPEC_VMULESB))]
953   "TARGET_ALTIVEC"
954   "vmulesb %0,%1,%2"
955   [(set_attr "type" "veccomplex")])
957 (define_insn "vec_widen_umult_even_v8hi"
958   [(set (match_operand:V4SI 0 "register_operand" "=v")
959         (unspec:V4SI [(match_operand:V8HI 1 "register_operand" "v")
960                       (match_operand:V8HI 2 "register_operand" "v")]
961                      UNSPEC_VMULEUH))]
962   "TARGET_ALTIVEC"
963   "vmuleuh %0,%1,%2"
964   [(set_attr "type" "veccomplex")])
966 (define_insn "vec_widen_smult_even_v8hi"
967   [(set (match_operand:V4SI 0 "register_operand" "=v")
968         (unspec:V4SI [(match_operand:V8HI 1 "register_operand" "v")
969                       (match_operand:V8HI 2 "register_operand" "v")]
970                      UNSPEC_VMULESH))]
971   "TARGET_ALTIVEC"
972   "vmulesh %0,%1,%2"
973   [(set_attr "type" "veccomplex")])
975 (define_insn "vec_widen_umult_odd_v16qi"
976   [(set (match_operand:V8HI 0 "register_operand" "=v")
977         (unspec:V8HI [(match_operand:V16QI 1 "register_operand" "v")
978                       (match_operand:V16QI 2 "register_operand" "v")]
979                      UNSPEC_VMULOUB))]
980   "TARGET_ALTIVEC"
981   "vmuloub %0,%1,%2"
982   [(set_attr "type" "veccomplex")])
984 (define_insn "vec_widen_smult_odd_v16qi"
985   [(set (match_operand:V8HI 0 "register_operand" "=v")
986         (unspec:V8HI [(match_operand:V16QI 1 "register_operand" "v")
987                       (match_operand:V16QI 2 "register_operand" "v")]
988                      UNSPEC_VMULOSB))]
989   "TARGET_ALTIVEC"
990   "vmulosb %0,%1,%2"
991   [(set_attr "type" "veccomplex")])
993 (define_insn "vec_widen_umult_odd_v8hi"
994   [(set (match_operand:V4SI 0 "register_operand" "=v")
995         (unspec:V4SI [(match_operand:V8HI 1 "register_operand" "v")
996                       (match_operand:V8HI 2 "register_operand" "v")]
997                      UNSPEC_VMULOUH))]
998   "TARGET_ALTIVEC"
999   "vmulouh %0,%1,%2"
1000   [(set_attr "type" "veccomplex")])
1002 (define_insn "vec_widen_smult_odd_v8hi"
1003   [(set (match_operand:V4SI 0 "register_operand" "=v")
1004         (unspec:V4SI [(match_operand:V8HI 1 "register_operand" "v")
1005                       (match_operand:V8HI 2 "register_operand" "v")]
1006                      UNSPEC_VMULOSH))]
1007   "TARGET_ALTIVEC"
1008   "vmulosh %0,%1,%2"
1009   [(set_attr "type" "veccomplex")])
1012 ;; logical ops.  Have the logical ops follow the memory ops in
1013 ;; terms of whether to prefer VSX or Altivec
1015 (define_insn "*altivec_and<mode>3"
1016   [(set (match_operand:VM 0 "register_operand" "=v")
1017         (and:VM (match_operand:VM 1 "register_operand" "v")
1018                 (match_operand:VM 2 "register_operand" "v")))]
1019   "VECTOR_MEM_ALTIVEC_P (<MODE>mode)"
1020   "vand %0,%1,%2"
1021   [(set_attr "type" "vecsimple")])
1023 (define_insn "*altivec_ior<mode>3"
1024   [(set (match_operand:VM 0 "register_operand" "=v")
1025         (ior:VM (match_operand:VM 1 "register_operand" "v")
1026                 (match_operand:VM 2 "register_operand" "v")))]
1027   "VECTOR_MEM_ALTIVEC_P (<MODE>mode)"
1028   "vor %0,%1,%2"
1029   [(set_attr "type" "vecsimple")])
1031 (define_insn "*altivec_xor<mode>3"
1032   [(set (match_operand:VM 0 "register_operand" "=v")
1033         (xor:VM (match_operand:VM 1 "register_operand" "v")
1034                 (match_operand:VM 2 "register_operand" "v")))]
1035   "VECTOR_MEM_ALTIVEC_P (<MODE>mode)"
1036   "vxor %0,%1,%2"
1037   [(set_attr "type" "vecsimple")])
1039 (define_insn "*altivec_one_cmpl<mode>2"
1040   [(set (match_operand:VM 0 "register_operand" "=v")
1041         (not:VM (match_operand:VM 1 "register_operand" "v")))]
1042   "VECTOR_MEM_ALTIVEC_P (<MODE>mode)"
1043   "vnor %0,%1,%1"
1044   [(set_attr "type" "vecsimple")])
1045   
1046 (define_insn "*altivec_nor<mode>3"
1047   [(set (match_operand:VM 0 "register_operand" "=v")
1048         (not:VM (ior:VM (match_operand:VM 1 "register_operand" "v")
1049                         (match_operand:VM 2 "register_operand" "v"))))]
1050   "VECTOR_MEM_ALTIVEC_P (<MODE>mode)"
1051   "vnor %0,%1,%2"
1052   [(set_attr "type" "vecsimple")])
1054 (define_insn "*altivec_andc<mode>3"
1055   [(set (match_operand:VM 0 "register_operand" "=v")
1056         (and:VM (not:VM (match_operand:VM 2 "register_operand" "v"))
1057                 (match_operand:VM 1 "register_operand" "v")))]
1058   "VECTOR_MEM_ALTIVEC_P (<MODE>mode)"
1059   "vandc %0,%1,%2"
1060   [(set_attr "type" "vecsimple")])
1062 (define_insn "altivec_vpkuhum"
1063   [(set (match_operand:V16QI 0 "register_operand" "=v")
1064         (unspec:V16QI [(match_operand:V8HI 1 "register_operand" "v")
1065                        (match_operand:V8HI 2 "register_operand" "v")]
1066                       UNSPEC_VPKUHUM))]
1067   "TARGET_ALTIVEC"
1068   "vpkuhum %0,%1,%2"
1069   [(set_attr "type" "vecperm")])
1071 (define_insn "altivec_vpkuwum"
1072   [(set (match_operand:V8HI 0 "register_operand" "=v")
1073         (unspec:V8HI [(match_operand:V4SI 1 "register_operand" "v")
1074                       (match_operand:V4SI 2 "register_operand" "v")]
1075                      UNSPEC_VPKUWUM))]
1076   "TARGET_ALTIVEC"
1077   "vpkuwum %0,%1,%2"
1078   [(set_attr "type" "vecperm")])
1080 (define_insn "altivec_vpkpx"
1081   [(set (match_operand:V8HI 0 "register_operand" "=v")
1082         (unspec:V8HI [(match_operand:V4SI 1 "register_operand" "v")
1083                       (match_operand:V4SI 2 "register_operand" "v")]
1084                      UNSPEC_VPKPX))]
1085   "TARGET_ALTIVEC"
1086   "vpkpx %0,%1,%2"
1087   [(set_attr "type" "vecperm")])
1089 (define_insn "altivec_vpkshss"
1090   [(set (match_operand:V16QI 0 "register_operand" "=v")
1091         (unspec:V16QI [(match_operand:V8HI 1 "register_operand" "v")
1092                        (match_operand:V8HI 2 "register_operand" "v")]
1093                       UNSPEC_VPKSHSS))
1094    (set (reg:SI 110) (unspec:SI [(const_int 0)] UNSPEC_SET_VSCR))]
1095   "TARGET_ALTIVEC"
1096   "vpkshss %0,%1,%2"
1097   [(set_attr "type" "vecperm")])
1099 (define_insn "altivec_vpkswss"
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_VPKSWSS))
1104    (set (reg:SI 110) (unspec:SI [(const_int 0)] UNSPEC_SET_VSCR))]
1105   "TARGET_ALTIVEC"
1106   "vpkswss %0,%1,%2"
1107   [(set_attr "type" "vecperm")])
1109 (define_insn "altivec_vpkuhus"
1110   [(set (match_operand:V16QI 0 "register_operand" "=v")
1111         (unspec:V16QI [(match_operand:V8HI 1 "register_operand" "v")
1112                        (match_operand:V8HI 2 "register_operand" "v")]
1113                       UNSPEC_VPKUHUS))
1114    (set (reg:SI 110) (unspec:SI [(const_int 0)] UNSPEC_SET_VSCR))]
1115   "TARGET_ALTIVEC"
1116   "vpkuhus %0,%1,%2"
1117   [(set_attr "type" "vecperm")])
1119 (define_insn "altivec_vpkshus"
1120   [(set (match_operand:V16QI 0 "register_operand" "=v")
1121         (unspec:V16QI [(match_operand:V8HI 1 "register_operand" "v")
1122                        (match_operand:V8HI 2 "register_operand" "v")]
1123                       UNSPEC_VPKSHUS))
1124    (set (reg:SI 110) (unspec:SI [(const_int 0)] UNSPEC_SET_VSCR))]
1125   "TARGET_ALTIVEC"
1126   "vpkshus %0,%1,%2"
1127   [(set_attr "type" "vecperm")])
1129 (define_insn "altivec_vpkuwus"
1130   [(set (match_operand:V8HI 0 "register_operand" "=v")
1131         (unspec:V8HI [(match_operand:V4SI 1 "register_operand" "v")
1132                       (match_operand:V4SI 2 "register_operand" "v")]
1133                      UNSPEC_VPKUWUS))
1134    (set (reg:SI 110) (unspec:SI [(const_int 0)] UNSPEC_SET_VSCR))]
1135   "TARGET_ALTIVEC"
1136   "vpkuwus %0,%1,%2"
1137   [(set_attr "type" "vecperm")])
1139 (define_insn "altivec_vpkswus"
1140   [(set (match_operand:V8HI 0 "register_operand" "=v")
1141         (unspec:V8HI [(match_operand:V4SI 1 "register_operand" "v")
1142                       (match_operand:V4SI 2 "register_operand" "v")]
1143                      UNSPEC_VPKSWUS))
1144    (set (reg:SI 110) (unspec:SI [(const_int 0)] UNSPEC_SET_VSCR))]
1145   "TARGET_ALTIVEC"
1146   "vpkswus %0,%1,%2"
1147   [(set_attr "type" "vecperm")])
1149 (define_insn "*altivec_vrl<VI_char>"
1150   [(set (match_operand:VI 0 "register_operand" "=v")
1151         (rotate:VI (match_operand:VI 1 "register_operand" "v")
1152                    (match_operand:VI 2 "register_operand" "v")))]
1153   "TARGET_ALTIVEC"
1154   "vrl<VI_char> %0,%1,%2"
1155   [(set_attr "type" "vecsimple")])
1157 (define_insn "altivec_vsl"
1158   [(set (match_operand:V4SI 0 "register_operand" "=v")
1159         (unspec:V4SI [(match_operand:V4SI 1 "register_operand" "v")
1160                       (match_operand:V4SI 2 "register_operand" "v")]
1161                      UNSPEC_VSLV4SI))]
1162   "TARGET_ALTIVEC"
1163   "vsl %0,%1,%2"
1164   [(set_attr "type" "vecperm")])
1166 (define_insn "altivec_vslo"
1167   [(set (match_operand:V4SI 0 "register_operand" "=v")
1168         (unspec:V4SI [(match_operand:V4SI 1 "register_operand" "v")
1169                       (match_operand:V4SI 2 "register_operand" "v")]
1170                      UNSPEC_VSLO))]
1171   "TARGET_ALTIVEC"
1172   "vslo %0,%1,%2"
1173   [(set_attr "type" "vecperm")])
1175 (define_insn "*altivec_vsl<VI_char>"
1176   [(set (match_operand:VI 0 "register_operand" "=v")
1177         (ashift:VI (match_operand:VI 1 "register_operand" "v")
1178                    (match_operand:VI 2 "register_operand" "v")))]
1179   "TARGET_ALTIVEC"
1180   "vsl<VI_char> %0,%1,%2"
1181   [(set_attr "type" "vecsimple")])
1183 (define_insn "*altivec_vsr<VI_char>"
1184   [(set (match_operand:VI 0 "register_operand" "=v")
1185         (lshiftrt:VI (match_operand:VI 1 "register_operand" "v")
1186                      (match_operand:VI 2 "register_operand" "v")))]
1187   "TARGET_ALTIVEC"
1188   "vsr<VI_char> %0,%1,%2"
1189   [(set_attr "type" "vecsimple")])
1191 (define_insn "*altivec_vsra<VI_char>"
1192   [(set (match_operand:VI 0 "register_operand" "=v")
1193         (ashiftrt:VI (match_operand:VI 1 "register_operand" "v")
1194                      (match_operand:VI 2 "register_operand" "v")))]
1195   "TARGET_ALTIVEC"
1196   "vsra<VI_char> %0,%1,%2"
1197   [(set_attr "type" "vecsimple")])
1199 (define_insn "altivec_vsr"
1200   [(set (match_operand:V4SI 0 "register_operand" "=v")
1201         (unspec:V4SI [(match_operand:V4SI 1 "register_operand" "v")
1202                       (match_operand:V4SI 2 "register_operand" "v")]
1203                      UNSPEC_VSR))]
1204   "TARGET_ALTIVEC"
1205   "vsr %0,%1,%2"
1206   [(set_attr "type" "vecperm")])
1208 (define_insn "altivec_vsro"
1209   [(set (match_operand:V4SI 0 "register_operand" "=v")
1210         (unspec:V4SI [(match_operand:V4SI 1 "register_operand" "v")
1211                       (match_operand:V4SI 2 "register_operand" "v")]
1212                      UNSPEC_VSRO))]
1213   "TARGET_ALTIVEC"
1214   "vsro %0,%1,%2"
1215   [(set_attr "type" "vecperm")])
1217 (define_insn "altivec_vsum4ubs"
1218   [(set (match_operand:V4SI 0 "register_operand" "=v")
1219         (unspec:V4SI [(match_operand:V16QI 1 "register_operand" "v")
1220                       (match_operand:V4SI 2 "register_operand" "v")]
1221                      UNSPEC_VSUM4UBS))
1222    (set (reg:SI 110) (unspec:SI [(const_int 0)] UNSPEC_SET_VSCR))]
1223   "TARGET_ALTIVEC"
1224   "vsum4ubs %0,%1,%2"
1225   [(set_attr "type" "veccomplex")])
1227 (define_insn "altivec_vsum4s<VI_char>s"
1228   [(set (match_operand:V4SI 0 "register_operand" "=v")
1229         (unspec:V4SI [(match_operand:VIshort 1 "register_operand" "v")
1230                       (match_operand:V4SI 2 "register_operand" "v")]
1231                      UNSPEC_VSUM4S))
1232    (set (reg:SI 110) (unspec:SI [(const_int 0)] UNSPEC_SET_VSCR))]
1233   "TARGET_ALTIVEC"
1234   "vsum4s<VI_char>s %0,%1,%2"
1235   [(set_attr "type" "veccomplex")])
1237 (define_insn "altivec_vsum2sws"
1238   [(set (match_operand:V4SI 0 "register_operand" "=v")
1239         (unspec:V4SI [(match_operand:V4SI 1 "register_operand" "v")
1240                       (match_operand:V4SI 2 "register_operand" "v")]
1241                      UNSPEC_VSUM2SWS))
1242    (set (reg:SI 110) (unspec:SI [(const_int 0)] UNSPEC_SET_VSCR))]
1243   "TARGET_ALTIVEC"
1244   "vsum2sws %0,%1,%2"
1245   [(set_attr "type" "veccomplex")])
1247 (define_insn "altivec_vsumsws"
1248   [(set (match_operand:V4SI 0 "register_operand" "=v")
1249         (unspec:V4SI [(match_operand:V4SI 1 "register_operand" "v")
1250                       (match_operand:V4SI 2 "register_operand" "v")]
1251                      UNSPEC_VSUMSWS))
1252    (set (reg:SI 110) (unspec:SI [(const_int 0)] UNSPEC_SET_VSCR))]
1253   "TARGET_ALTIVEC"
1254   "vsumsws %0,%1,%2"
1255   [(set_attr "type" "veccomplex")])
1257 (define_insn "altivec_vspltb"
1258   [(set (match_operand:V16QI 0 "register_operand" "=v")
1259         (vec_duplicate:V16QI
1260          (vec_select:QI (match_operand:V16QI 1 "register_operand" "v")
1261                         (parallel
1262                          [(match_operand:QI 2 "u5bit_cint_operand" "")]))))]
1263   "TARGET_ALTIVEC"
1264   "vspltb %0,%1,%2"
1265   [(set_attr "type" "vecperm")])
1267 (define_insn "altivec_vsplth"
1268   [(set (match_operand:V8HI 0 "register_operand" "=v")
1269         (vec_duplicate:V8HI
1270          (vec_select:HI (match_operand:V8HI 1 "register_operand" "v")
1271                         (parallel
1272                          [(match_operand:QI 2 "u5bit_cint_operand" "")]))))]
1273   "TARGET_ALTIVEC"
1274   "vsplth %0,%1,%2"
1275   [(set_attr "type" "vecperm")])
1277 (define_insn "altivec_vspltw"
1278   [(set (match_operand:V4SI 0 "register_operand" "=v")
1279         (vec_duplicate:V4SI
1280          (vec_select:SI (match_operand:V4SI 1 "register_operand" "v")
1281                         (parallel
1282                          [(match_operand:QI 2 "u5bit_cint_operand" "i")]))))]
1283   "TARGET_ALTIVEC"
1284   "vspltw %0,%1,%2"
1285   [(set_attr "type" "vecperm")])
1287 (define_insn "altivec_vspltsf"
1288   [(set (match_operand:V4SF 0 "register_operand" "=v")
1289         (vec_duplicate:V4SF
1290          (vec_select:SF (match_operand:V4SF 1 "register_operand" "v")
1291                         (parallel
1292                          [(match_operand:QI 2 "u5bit_cint_operand" "i")]))))]
1293   "VECTOR_UNIT_ALTIVEC_P (V4SFmode)"
1294   "vspltw %0,%1,%2"
1295   [(set_attr "type" "vecperm")])
1297 (define_insn "altivec_vspltis<VI_char>"
1298   [(set (match_operand:VI 0 "register_operand" "=v")
1299         (vec_duplicate:VI
1300          (match_operand:QI 1 "s5bit_cint_operand" "i")))]
1301   "TARGET_ALTIVEC"
1302   "vspltis<VI_char> %0,%1"
1303   [(set_attr "type" "vecperm")])
1305 (define_insn "*altivec_vrfiz"
1306   [(set (match_operand:V4SF 0 "register_operand" "=v")
1307         (fix:V4SF (match_operand:V4SF 1 "register_operand" "v")))]
1308   "VECTOR_UNIT_ALTIVEC_P (V4SFmode)"
1309   "vrfiz %0,%1"
1310   [(set_attr "type" "vecfloat")])
1312 (define_insn "altivec_vperm_<mode>"
1313   [(set (match_operand:VM 0 "register_operand" "=v")
1314         (unspec:VM [(match_operand:VM 1 "register_operand" "v")
1315                     (match_operand:VM 2 "register_operand" "v")
1316                     (match_operand:V16QI 3 "register_operand" "v")]
1317                    UNSPEC_VPERM))]
1318   "TARGET_ALTIVEC"
1319   "vperm %0,%1,%2,%3"
1320   [(set_attr "type" "vecperm")])
1322 (define_insn "altivec_vperm_<mode>_uns"
1323   [(set (match_operand:VM 0 "register_operand" "=v")
1324         (unspec:VM [(match_operand:VM 1 "register_operand" "v")
1325                     (match_operand:VM 2 "register_operand" "v")
1326                     (match_operand:V16QI 3 "register_operand" "v")]
1327                    UNSPEC_VPERM_UNS))]
1328   "TARGET_ALTIVEC"
1329   "vperm %0,%1,%2,%3"
1330   [(set_attr "type" "vecperm")])
1332 (define_expand "vec_permv16qi"
1333   [(set (match_operand:V16QI 0 "register_operand" "")
1334         (unspec:V16QI [(match_operand:V16QI 1 "register_operand" "")
1335                        (match_operand:V16QI 2 "register_operand" "")
1336                        (match_operand:V16QI 3 "register_operand" "")]
1337                       UNSPEC_VPERM))]
1338   "TARGET_ALTIVEC"
1339   "")
1341 (define_expand "vec_perm_constv16qi"
1342   [(match_operand:V16QI 0 "register_operand" "")
1343    (match_operand:V16QI 1 "register_operand" "")
1344    (match_operand:V16QI 2 "register_operand" "")
1345    (match_operand:V16QI 3 "" "")]
1346   "TARGET_ALTIVEC"
1348   if (altivec_expand_vec_perm_const (operands))
1349     DONE;
1350   else
1351     FAIL;
1354 (define_insn "altivec_vrfip"            ; ceil
1355   [(set (match_operand:V4SF 0 "register_operand" "=v")
1356         (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "v")]
1357                      UNSPEC_FRIP))]
1358   "TARGET_ALTIVEC"
1359   "vrfip %0,%1"
1360   [(set_attr "type" "vecfloat")])
1362 (define_insn "altivec_vrfin"
1363   [(set (match_operand:V4SF 0 "register_operand" "=v")
1364         (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "v")]
1365                      UNSPEC_VRFIN))]
1366   "TARGET_ALTIVEC"
1367   "vrfin %0,%1"
1368   [(set_attr "type" "vecfloat")])
1370 (define_insn "*altivec_vrfim"           ; floor
1371   [(set (match_operand:V4SF 0 "register_operand" "=v")
1372         (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "v")]
1373                      UNSPEC_FRIM))]
1374   "TARGET_ALTIVEC"
1375   "vrfim %0,%1"
1376   [(set_attr "type" "vecfloat")])
1378 (define_insn "altivec_vcfux"
1379   [(set (match_operand:V4SF 0 "register_operand" "=v")
1380         (unspec:V4SF [(match_operand:V4SI 1 "register_operand" "v")
1381                       (match_operand:QI 2 "immediate_operand" "i")]
1382                      UNSPEC_VCFUX))]
1383   "TARGET_ALTIVEC"
1384   "vcfux %0,%1,%2"
1385   [(set_attr "type" "vecfloat")])
1387 (define_insn "altivec_vcfsx"
1388   [(set (match_operand:V4SF 0 "register_operand" "=v")
1389         (unspec:V4SF [(match_operand:V4SI 1 "register_operand" "v")
1390                       (match_operand:QI 2 "immediate_operand" "i")]
1391                      UNSPEC_VCFSX))]
1392   "TARGET_ALTIVEC"
1393   "vcfsx %0,%1,%2"
1394   [(set_attr "type" "vecfloat")])
1396 (define_insn "altivec_vctuxs"
1397   [(set (match_operand:V4SI 0 "register_operand" "=v")
1398         (unspec:V4SI [(match_operand:V4SF 1 "register_operand" "v")
1399                       (match_operand:QI 2 "immediate_operand" "i")]
1400                      UNSPEC_VCTUXS))
1401    (set (reg:SI 110) (unspec:SI [(const_int 0)] UNSPEC_SET_VSCR))]
1402   "TARGET_ALTIVEC"
1403   "vctuxs %0,%1,%2"
1404   [(set_attr "type" "vecfloat")])
1406 (define_insn "altivec_vctsxs"
1407   [(set (match_operand:V4SI 0 "register_operand" "=v")
1408         (unspec:V4SI [(match_operand:V4SF 1 "register_operand" "v")
1409                       (match_operand:QI 2 "immediate_operand" "i")]
1410                      UNSPEC_VCTSXS))
1411    (set (reg:SI 110) (unspec:SI [(const_int 0)] UNSPEC_SET_VSCR))]
1412   "TARGET_ALTIVEC"
1413   "vctsxs %0,%1,%2"
1414   [(set_attr "type" "vecfloat")])
1416 (define_insn "altivec_vlogefp"
1417   [(set (match_operand:V4SF 0 "register_operand" "=v")
1418         (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "v")]
1419                      UNSPEC_VLOGEFP))]
1420   "TARGET_ALTIVEC"
1421   "vlogefp %0,%1"
1422   [(set_attr "type" "vecfloat")])
1424 (define_insn "altivec_vexptefp"
1425   [(set (match_operand:V4SF 0 "register_operand" "=v")
1426         (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "v")]
1427                      UNSPEC_VEXPTEFP))]
1428   "TARGET_ALTIVEC"
1429   "vexptefp %0,%1"
1430   [(set_attr "type" "vecfloat")])
1432 (define_insn "*altivec_vrsqrtefp"
1433   [(set (match_operand:V4SF 0 "register_operand" "=v")
1434         (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "v")]
1435                      UNSPEC_RSQRT))]
1436   "VECTOR_UNIT_ALTIVEC_P (V4SFmode)"
1437   "vrsqrtefp %0,%1"
1438   [(set_attr "type" "vecfloat")])
1440 (define_insn "altivec_vrefp"
1441   [(set (match_operand:V4SF 0 "register_operand" "=v")
1442         (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "v")]
1443                      UNSPEC_FRES))]
1444   "VECTOR_UNIT_ALTIVEC_P (V4SFmode)"
1445   "vrefp %0,%1"
1446   [(set_attr "type" "vecfloat")])
1448 (define_expand "altivec_copysign_v4sf3"
1449   [(use (match_operand:V4SF 0 "register_operand" ""))
1450    (use (match_operand:V4SF 1 "register_operand" ""))
1451    (use (match_operand:V4SF 2 "register_operand" ""))]
1452   "VECTOR_UNIT_ALTIVEC_P (V4SFmode)"
1453   "
1455   rtx mask = gen_reg_rtx (V4SImode);
1456   rtvec v = rtvec_alloc (4);
1457   unsigned HOST_WIDE_INT mask_val = ((unsigned HOST_WIDE_INT)1) << 31;
1459   RTVEC_ELT (v, 0) = GEN_INT (mask_val);
1460   RTVEC_ELT (v, 1) = GEN_INT (mask_val);
1461   RTVEC_ELT (v, 2) = GEN_INT (mask_val);
1462   RTVEC_ELT (v, 3) = GEN_INT (mask_val);
1464   emit_insn (gen_vec_initv4si (mask, gen_rtx_PARALLEL (V4SImode, v)));
1465   emit_insn (gen_vector_select_v4sf (operands[0], operands[1], operands[2],
1466                                      gen_lowpart (V4SFmode, mask)));
1467   DONE;
1470 (define_insn "altivec_vsldoi_<mode>"
1471   [(set (match_operand:VM 0 "register_operand" "=v")
1472         (unspec:VM [(match_operand:VM 1 "register_operand" "v")
1473                     (match_operand:VM 2 "register_operand" "v")
1474                     (match_operand:QI 3 "immediate_operand" "i")]
1475                   UNSPEC_VLSDOI))]
1476   "TARGET_ALTIVEC"
1477   "vsldoi %0,%1,%2,%3"
1478   [(set_attr "type" "vecperm")])
1480 (define_insn "altivec_vupkhsb"
1481   [(set (match_operand:V8HI 0 "register_operand" "=v")
1482         (unspec:V8HI [(match_operand:V16QI 1 "register_operand" "v")]
1483                      UNSPEC_VUPKHSB))]
1484   "TARGET_ALTIVEC"
1485   "vupkhsb %0,%1"
1486   [(set_attr "type" "vecperm")])
1488 (define_insn "altivec_vupkhpx"
1489   [(set (match_operand:V4SI 0 "register_operand" "=v")
1490         (unspec:V4SI [(match_operand:V8HI 1 "register_operand" "v")]
1491                      UNSPEC_VUPKHPX))]
1492   "TARGET_ALTIVEC"
1493   "vupkhpx %0,%1"
1494   [(set_attr "type" "vecperm")])
1496 (define_insn "altivec_vupkhsh"
1497   [(set (match_operand:V4SI 0 "register_operand" "=v")
1498         (unspec:V4SI [(match_operand:V8HI 1 "register_operand" "v")]
1499                      UNSPEC_VUPKHSH))]
1500   "TARGET_ALTIVEC"
1501   "vupkhsh %0,%1"
1502   [(set_attr "type" "vecperm")])
1504 (define_insn "altivec_vupklsb"
1505   [(set (match_operand:V8HI 0 "register_operand" "=v")
1506         (unspec:V8HI [(match_operand:V16QI 1 "register_operand" "v")]
1507                      UNSPEC_VUPKLSB))]
1508   "TARGET_ALTIVEC"
1509   "vupklsb %0,%1"
1510   [(set_attr "type" "vecperm")])
1512 (define_insn "altivec_vupklpx"
1513   [(set (match_operand:V4SI 0 "register_operand" "=v")
1514         (unspec:V4SI [(match_operand:V8HI 1 "register_operand" "v")]
1515                      UNSPEC_VUPKLPX))]
1516   "TARGET_ALTIVEC"
1517   "vupklpx %0,%1"
1518   [(set_attr "type" "vecperm")])
1520 (define_insn "altivec_vupklsh"
1521   [(set (match_operand:V4SI 0 "register_operand" "=v")
1522         (unspec:V4SI [(match_operand:V8HI 1 "register_operand" "v")]
1523                      UNSPEC_VUPKLSH))]
1524   "TARGET_ALTIVEC"
1525   "vupklsh %0,%1"
1526   [(set_attr "type" "vecperm")])
1528 ;; Compare vectors producing a vector result and a predicate, setting CR6 to
1529 ;; indicate a combined status
1530 (define_insn "*altivec_vcmpequ<VI_char>_p"
1531   [(set (reg:CC 74)
1532         (unspec:CC [(eq:CC (match_operand:VI 1 "register_operand" "v")
1533                            (match_operand:VI 2 "register_operand" "v"))]
1534                    UNSPEC_PREDICATE))
1535    (set (match_operand:VI 0 "register_operand" "=v")
1536         (eq:VI (match_dup 1)
1537                (match_dup 2)))]
1538   "VECTOR_UNIT_ALTIVEC_P (<MODE>mode)"
1539   "vcmpequ<VI_char>. %0,%1,%2"
1540   [(set_attr "type" "veccmp")])
1542 (define_insn "*altivec_vcmpgts<VI_char>_p"
1543   [(set (reg:CC 74)
1544         (unspec:CC [(gt:CC (match_operand:VI 1 "register_operand" "v")
1545                            (match_operand:VI 2 "register_operand" "v"))]
1546                    UNSPEC_PREDICATE))
1547    (set (match_operand:VI 0 "register_operand" "=v")
1548         (gt:VI (match_dup 1)
1549                (match_dup 2)))]
1550   "VECTOR_UNIT_ALTIVEC_P (<MODE>mode)"
1551   "vcmpgts<VI_char>. %0,%1,%2"
1552   [(set_attr "type" "veccmp")])
1554 (define_insn "*altivec_vcmpgtu<VI_char>_p"
1555   [(set (reg:CC 74)
1556         (unspec:CC [(gtu:CC (match_operand:VI 1 "register_operand" "v")
1557                             (match_operand:VI 2 "register_operand" "v"))]
1558                    UNSPEC_PREDICATE))
1559    (set (match_operand:VI 0 "register_operand" "=v")
1560         (gtu:VI (match_dup 1)
1561                 (match_dup 2)))]
1562   "VECTOR_UNIT_ALTIVEC_P (<MODE>mode)"
1563   "vcmpgtu<VI_char>. %0,%1,%2"
1564   [(set_attr "type" "veccmp")])
1566 (define_insn "*altivec_vcmpeqfp_p"
1567   [(set (reg:CC 74)
1568         (unspec:CC [(eq:CC (match_operand:V4SF 1 "register_operand" "v")
1569                            (match_operand:V4SF 2 "register_operand" "v"))]
1570                    UNSPEC_PREDICATE))
1571    (set (match_operand:V4SF 0 "register_operand" "=v")
1572         (eq:V4SF (match_dup 1)
1573                  (match_dup 2)))]
1574   "VECTOR_UNIT_ALTIVEC_P (V4SFmode)"
1575   "vcmpeqfp. %0,%1,%2"
1576   [(set_attr "type" "veccmp")])
1578 (define_insn "*altivec_vcmpgtfp_p"
1579   [(set (reg:CC 74)
1580         (unspec:CC [(gt:CC (match_operand:V4SF 1 "register_operand" "v")
1581                            (match_operand:V4SF 2 "register_operand" "v"))]
1582                    UNSPEC_PREDICATE))
1583    (set (match_operand:V4SF 0 "register_operand" "=v")
1584         (gt:V4SF (match_dup 1)
1585                  (match_dup 2)))]
1586   "VECTOR_UNIT_ALTIVEC_P (V4SFmode)"
1587   "vcmpgtfp. %0,%1,%2"
1588   [(set_attr "type" "veccmp")])
1590 (define_insn "*altivec_vcmpgefp_p"
1591   [(set (reg:CC 74)
1592         (unspec:CC [(ge:CC (match_operand:V4SF 1 "register_operand" "v")
1593                            (match_operand:V4SF 2 "register_operand" "v"))]
1594                    UNSPEC_PREDICATE))
1595    (set (match_operand:V4SF 0 "register_operand" "=v")
1596         (ge:V4SF (match_dup 1)
1597                  (match_dup 2)))]
1598   "VECTOR_UNIT_ALTIVEC_P (V4SFmode)"
1599   "vcmpgefp. %0,%1,%2"
1600   [(set_attr "type" "veccmp")])
1602 (define_insn "altivec_vcmpbfp_p"
1603   [(set (reg:CC 74)
1604         (unspec:CC [(match_operand:V4SF 1 "register_operand" "v")
1605                     (match_operand:V4SF 2 "register_operand" "v")]
1606                    UNSPEC_VCMPBFP))
1607    (set (match_operand:V4SF 0 "register_operand" "=v")
1608         (unspec:V4SF [(match_dup 1)
1609                       (match_dup 2)] 
1610                       UNSPEC_VCMPBFP))]
1611   "VECTOR_UNIT_ALTIVEC_OR_VSX_P (V4SFmode)"
1612   "vcmpbfp. %0,%1,%2"
1613   [(set_attr "type" "veccmp")])
1615 (define_insn "altivec_mtvscr"
1616   [(set (reg:SI 110)
1617         (unspec_volatile:SI
1618          [(match_operand:V4SI 0 "register_operand" "v")] UNSPECV_MTVSCR))]
1619   "TARGET_ALTIVEC"
1620   "mtvscr %0"
1621   [(set_attr "type" "vecsimple")])
1623 (define_insn "altivec_mfvscr"
1624   [(set (match_operand:V8HI 0 "register_operand" "=v")
1625         (unspec_volatile:V8HI [(reg:SI 110)] UNSPECV_MFVSCR))]
1626   "TARGET_ALTIVEC"
1627   "mfvscr %0"
1628   [(set_attr "type" "vecsimple")])
1630 (define_insn "altivec_dssall"
1631   [(unspec_volatile [(const_int 0)] UNSPECV_DSSALL)]
1632   "TARGET_ALTIVEC"
1633   "dssall"
1634   [(set_attr "type" "vecsimple")])
1636 (define_insn "altivec_dss"
1637   [(unspec_volatile [(match_operand:QI 0 "immediate_operand" "i")]
1638                     UNSPECV_DSS)]
1639   "TARGET_ALTIVEC"
1640   "dss %0"
1641   [(set_attr "type" "vecsimple")])
1643 (define_insn "altivec_dst"
1644   [(unspec [(match_operand 0 "register_operand" "b")
1645             (match_operand:SI 1 "register_operand" "r")
1646             (match_operand:QI 2 "immediate_operand" "i")] UNSPEC_DST)]
1647   "TARGET_ALTIVEC && GET_MODE (operands[0]) == Pmode"
1648   "dst %0,%1,%2"
1649   [(set_attr "type" "vecsimple")])
1651 (define_insn "altivec_dstt"
1652   [(unspec [(match_operand 0 "register_operand" "b")
1653             (match_operand:SI 1 "register_operand" "r")
1654             (match_operand:QI 2 "immediate_operand" "i")] UNSPEC_DSTT)]
1655   "TARGET_ALTIVEC && GET_MODE (operands[0]) == Pmode"
1656   "dstt %0,%1,%2"
1657   [(set_attr "type" "vecsimple")])
1659 (define_insn "altivec_dstst"
1660   [(unspec [(match_operand 0 "register_operand" "b")
1661             (match_operand:SI 1 "register_operand" "r")
1662             (match_operand:QI 2 "immediate_operand" "i")] UNSPEC_DSTST)]
1663   "TARGET_ALTIVEC && GET_MODE (operands[0]) == Pmode"
1664   "dstst %0,%1,%2"
1665   [(set_attr "type" "vecsimple")])
1667 (define_insn "altivec_dststt"
1668   [(unspec [(match_operand 0 "register_operand" "b")
1669             (match_operand:SI 1 "register_operand" "r")
1670             (match_operand:QI 2 "immediate_operand" "i")] UNSPEC_DSTSTT)]
1671   "TARGET_ALTIVEC && GET_MODE (operands[0]) == Pmode"
1672   "dststt %0,%1,%2"
1673   [(set_attr "type" "vecsimple")])
1675 (define_insn "altivec_lvsl"
1676   [(set (match_operand:V16QI 0 "register_operand" "=v")
1677         (unspec:V16QI [(match_operand 1 "memory_operand" "Z")] UNSPEC_LVSL))]
1678   "TARGET_ALTIVEC"
1679   "lvsl %0,%y1"
1680   [(set_attr "type" "vecload")])
1682 (define_insn "altivec_lvsr"
1683   [(set (match_operand:V16QI 0 "register_operand" "=v")
1684         (unspec:V16QI [(match_operand 1 "memory_operand" "Z")] UNSPEC_LVSR))]
1685   "TARGET_ALTIVEC"
1686   "lvsr %0,%y1"
1687   [(set_attr "type" "vecload")])
1689 (define_expand "build_vector_mask_for_load"
1690   [(set (match_operand:V16QI 0 "register_operand" "")
1691         (unspec:V16QI [(match_operand 1 "memory_operand" "")] UNSPEC_LVSR))]
1692   "TARGET_ALTIVEC"
1693   "
1695   rtx addr;
1696   rtx temp;
1698   gcc_assert (GET_CODE (operands[1]) == MEM);
1700   addr = XEXP (operands[1], 0);
1701   temp = gen_reg_rtx (GET_MODE (addr));
1702   emit_insn (gen_rtx_SET (VOIDmode, temp, 
1703                           gen_rtx_NEG (GET_MODE (addr), addr)));
1704   emit_insn (gen_altivec_lvsr (operands[0], 
1705                                replace_equiv_address (operands[1], temp)));
1706   DONE;
1709 ;; Parallel some of the LVE* and STV*'s with unspecs because some have
1710 ;; identical rtl but different instructions-- and gcc gets confused.
1712 (define_insn "altivec_lve<VI_char>x"
1713   [(parallel
1714     [(set (match_operand:VI 0 "register_operand" "=v")
1715           (match_operand:VI 1 "memory_operand" "Z"))
1716      (unspec [(const_int 0)] UNSPEC_LVE)])]
1717   "TARGET_ALTIVEC"
1718   "lve<VI_char>x %0,%y1"
1719   [(set_attr "type" "vecload")])
1721 (define_insn "*altivec_lvesfx"
1722   [(parallel
1723     [(set (match_operand:V4SF 0 "register_operand" "=v")
1724           (match_operand:V4SF 1 "memory_operand" "Z"))
1725      (unspec [(const_int 0)] UNSPEC_LVE)])]
1726   "TARGET_ALTIVEC"
1727   "lvewx %0,%y1"
1728   [(set_attr "type" "vecload")])
1730 (define_insn "altivec_lvxl"
1731   [(parallel
1732     [(set (match_operand:V4SI 0 "register_operand" "=v")
1733           (match_operand:V4SI 1 "memory_operand" "Z"))
1734      (unspec [(const_int 0)] UNSPEC_SET_VSCR)])]
1735   "TARGET_ALTIVEC"
1736   "lvxl %0,%y1"
1737   [(set_attr "type" "vecload")])
1739 (define_insn "altivec_lvx_<mode>"
1740   [(parallel
1741     [(set (match_operand:VM2 0 "register_operand" "=v")
1742           (match_operand:VM2 1 "memory_operand" "Z"))
1743      (unspec [(const_int 0)] UNSPEC_LVX)])]
1744   "TARGET_ALTIVEC"
1745   "lvx %0,%y1"
1746   [(set_attr "type" "vecload")])
1748 (define_insn "altivec_stvx_<mode>"
1749   [(parallel
1750     [(set (match_operand:VM2 0 "memory_operand" "=Z")
1751           (match_operand:VM2 1 "register_operand" "v"))
1752      (unspec [(const_int 0)] UNSPEC_STVX)])]
1753   "TARGET_ALTIVEC"
1754   "stvx %1,%y0"
1755   [(set_attr "type" "vecstore")])
1757 (define_insn "altivec_stvxl"
1758   [(parallel
1759     [(set (match_operand:V4SI 0 "memory_operand" "=Z")
1760           (match_operand:V4SI 1 "register_operand" "v"))
1761      (unspec [(const_int 0)] UNSPEC_STVXL)])]
1762   "TARGET_ALTIVEC"
1763   "stvxl %1,%y0"
1764   [(set_attr "type" "vecstore")])
1766 (define_insn "altivec_stve<VI_char>x"
1767   [(set (match_operand:<VI_scalar> 0 "memory_operand" "=Z")
1768         (unspec:<VI_scalar> [(match_operand:VI 1 "register_operand" "v")] UNSPEC_STVE))]
1769   "TARGET_ALTIVEC"
1770   "stve<VI_char>x %1,%y0"
1771   [(set_attr "type" "vecstore")])
1773 (define_insn "*altivec_stvesfx"
1774   [(set (match_operand:SF 0 "memory_operand" "=Z")
1775         (unspec:SF [(match_operand:V4SF 1 "register_operand" "v")] UNSPEC_STVE))]
1776   "TARGET_ALTIVEC"
1777   "stvewx %1,%y0"
1778   [(set_attr "type" "vecstore")])
1780 ;; Generate
1781 ;;    vspltis? SCRATCH0,0
1782 ;;    vsubu?m SCRATCH2,SCRATCH1,%1
1783 ;;    vmaxs? %0,%1,SCRATCH2"
1784 (define_expand "abs<mode>2"
1785   [(set (match_dup 2) (vec_duplicate:VI (const_int 0)))
1786    (set (match_dup 3)
1787         (minus:VI (match_dup 2)
1788                   (match_operand:VI 1 "register_operand" "v")))
1789    (set (match_operand:VI 0 "register_operand" "=v")
1790         (smax:VI (match_dup 1) (match_dup 3)))]
1791   "TARGET_ALTIVEC"
1793   operands[2] = gen_reg_rtx (GET_MODE (operands[0]));
1794   operands[3] = gen_reg_rtx (GET_MODE (operands[0]));
1797 ;; Generate
1798 ;;    vspltisw SCRATCH1,-1
1799 ;;    vslw SCRATCH2,SCRATCH1,SCRATCH1
1800 ;;    vandc %0,%1,SCRATCH2
1801 (define_expand "altivec_absv4sf2"
1802   [(set (match_dup 2)
1803         (vec_duplicate:V4SI (const_int -1)))
1804    (set (match_dup 3)
1805         (ashift:V4SI (match_dup 2) (match_dup 2)))
1806    (set (match_operand:V4SF 0 "register_operand" "=v")
1807         (and:V4SF (not:V4SF (subreg:V4SF (match_dup 3) 0))
1808                   (match_operand:V4SF 1 "register_operand" "v")))]
1809   "TARGET_ALTIVEC"
1811   operands[2] = gen_reg_rtx (V4SImode);
1812   operands[3] = gen_reg_rtx (V4SImode);
1815 ;; Generate
1816 ;;    vspltis? SCRATCH0,0
1817 ;;    vsubs?s SCRATCH2,SCRATCH1,%1
1818 ;;    vmaxs? %0,%1,SCRATCH2"
1819 (define_expand "altivec_abss_<mode>"
1820   [(set (match_dup 2) (vec_duplicate:VI (const_int 0)))
1821    (parallel [(set (match_dup 3)
1822                    (unspec:VI [(match_dup 2)
1823                                (match_operand:VI 1 "register_operand" "v")]
1824                               UNSPEC_VSUBS))
1825               (set (reg:SI 110) (unspec:SI [(const_int 0)] UNSPEC_SET_VSCR))])
1826    (set (match_operand:VI 0 "register_operand" "=v")
1827         (smax:VI (match_dup 1) (match_dup 3)))]
1828   "TARGET_ALTIVEC"
1830   operands[2] = gen_reg_rtx (GET_MODE (operands[0]));
1831   operands[3] = gen_reg_rtx (GET_MODE (operands[0]));
1834 (define_insn "altivec_vsumsws_nomode"
1835   [(set (match_operand 0 "register_operand" "=v")
1836         (unspec:V4SI [(match_operand:V4SI 1 "register_operand" "v")
1837                       (match_operand:V4SI 2 "register_operand" "v")]
1838                      UNSPEC_VSUMSWS))
1839    (set (reg:SI 110) (unspec:SI [(const_int 0)] UNSPEC_SET_VSCR))]
1840   "TARGET_ALTIVEC"
1841   "vsumsws %0,%1,%2"
1842   [(set_attr "type" "veccomplex")])
1844 (define_expand "reduc_splus_<mode>"
1845   [(set (match_operand:VIshort 0 "register_operand" "=v")
1846         (unspec:VIshort [(match_operand:VIshort 1 "register_operand" "v")]
1847                         UNSPEC_REDUC_PLUS))]
1848   "TARGET_ALTIVEC"
1849   "
1851   rtx vzero = gen_reg_rtx (V4SImode);
1852   rtx vtmp1 = gen_reg_rtx (V4SImode);
1854   emit_insn (gen_altivec_vspltisw (vzero, const0_rtx));
1855   emit_insn (gen_altivec_vsum4s<VI_char>s (vtmp1, operands[1], vzero));
1856   emit_insn (gen_altivec_vsumsws_nomode (operands[0], vtmp1, vzero));
1857   DONE;
1860 (define_expand "reduc_uplus_v16qi"
1861   [(set (match_operand:V16QI 0 "register_operand" "=v")
1862         (unspec:V16QI [(match_operand:V16QI 1 "register_operand" "v")]
1863                       UNSPEC_REDUC_PLUS))]
1864   "TARGET_ALTIVEC"
1865   "
1867   rtx vzero = gen_reg_rtx (V4SImode);
1868   rtx vtmp1 = gen_reg_rtx (V4SImode);
1870   emit_insn (gen_altivec_vspltisw (vzero, const0_rtx));
1871   emit_insn (gen_altivec_vsum4ubs (vtmp1, operands[1], vzero));
1872   emit_insn (gen_altivec_vsumsws_nomode (operands[0], vtmp1, vzero));
1873   DONE;
1876 (define_expand "neg<mode>2"
1877   [(use (match_operand:VI 0 "register_operand" ""))
1878    (use (match_operand:VI 1 "register_operand" ""))]
1879   "TARGET_ALTIVEC"
1880   "
1882   rtx vzero;
1884   vzero = gen_reg_rtx (GET_MODE (operands[0]));
1885   emit_insn (gen_altivec_vspltis<VI_char> (vzero, const0_rtx));
1886   emit_insn (gen_sub<mode>3 (operands[0], vzero, operands[1])); 
1887   
1888   DONE;
1891 (define_expand "udot_prod<mode>"
1892   [(set (match_operand:V4SI 0 "register_operand" "=v")
1893         (plus:V4SI (match_operand:V4SI 3 "register_operand" "v")
1894                    (unspec:V4SI [(match_operand:VIshort 1 "register_operand" "v")  
1895                                  (match_operand:VIshort 2 "register_operand" "v")] 
1896                                 UNSPEC_VMSUMU)))]
1897   "TARGET_ALTIVEC"
1898   "
1899 {  
1900   emit_insn (gen_altivec_vmsumu<VI_char>m (operands[0], operands[1], operands[2], operands[3]));
1901   DONE;
1903    
1904 (define_expand "sdot_prodv8hi"
1905   [(set (match_operand:V4SI 0 "register_operand" "=v")
1906         (plus:V4SI (match_operand:V4SI 3 "register_operand" "v")
1907                    (unspec:V4SI [(match_operand:V8HI 1 "register_operand" "v")
1908                                  (match_operand:V8HI 2 "register_operand" "v")]
1909                                 UNSPEC_VMSUMSHM)))]
1910   "TARGET_ALTIVEC"
1911   "
1913   emit_insn (gen_altivec_vmsumshm (operands[0], operands[1], operands[2], operands[3]));
1914   DONE;
1917 (define_expand "widen_usum<mode>3"
1918   [(set (match_operand:V4SI 0 "register_operand" "=v")
1919         (plus:V4SI (match_operand:V4SI 2 "register_operand" "v")
1920                    (unspec:V4SI [(match_operand:VIshort 1 "register_operand" "v")]
1921                                 UNSPEC_VMSUMU)))]
1922   "TARGET_ALTIVEC"
1923   "
1925   rtx vones = gen_reg_rtx (GET_MODE (operands[1]));
1927   emit_insn (gen_altivec_vspltis<VI_char> (vones, const1_rtx));
1928   emit_insn (gen_altivec_vmsumu<VI_char>m (operands[0], operands[1], vones, operands[2]));
1929   DONE;
1932 (define_expand "widen_ssumv16qi3"
1933   [(set (match_operand:V4SI 0 "register_operand" "=v")
1934         (plus:V4SI (match_operand:V4SI 2 "register_operand" "v")
1935                    (unspec:V4SI [(match_operand:V16QI 1 "register_operand" "v")]
1936                                 UNSPEC_VMSUMM)))]
1937   "TARGET_ALTIVEC"
1938   "
1940   rtx vones = gen_reg_rtx (V16QImode);
1942   emit_insn (gen_altivec_vspltisb (vones, const1_rtx));
1943   emit_insn (gen_altivec_vmsummbm (operands[0], operands[1], vones, operands[2]));
1944   DONE;
1947 (define_expand "widen_ssumv8hi3"
1948   [(set (match_operand:V4SI 0 "register_operand" "=v")
1949         (plus:V4SI (match_operand:V4SI 2 "register_operand" "v")
1950                    (unspec:V4SI [(match_operand:V8HI 1 "register_operand" "v")]
1951                                 UNSPEC_VMSUMSHM)))]
1952   "TARGET_ALTIVEC"
1953   "
1955   rtx vones = gen_reg_rtx (V8HImode);
1957   emit_insn (gen_altivec_vspltish (vones, const1_rtx));
1958   emit_insn (gen_altivec_vmsumshm (operands[0], operands[1], vones, operands[2]));
1959   DONE;
1962 (define_expand "vec_unpacks_hi_v16qi"
1963   [(set (match_operand:V8HI 0 "register_operand" "=v")
1964         (unspec:V8HI [(match_operand:V16QI 1 "register_operand" "v")]
1965                      UNSPEC_VUPKHSB))]
1966   "TARGET_ALTIVEC"
1967   "
1969   emit_insn (gen_altivec_vupkhsb (operands[0], operands[1]));
1970   DONE;
1973 (define_expand "vec_unpacks_hi_v8hi"
1974   [(set (match_operand:V4SI 0 "register_operand" "=v")
1975         (unspec:V4SI [(match_operand:V8HI 1 "register_operand" "v")]
1976                      UNSPEC_VUPKHSH))]
1977   "TARGET_ALTIVEC"
1978   "
1980   emit_insn (gen_altivec_vupkhsh (operands[0], operands[1]));
1981   DONE;
1984 (define_expand "vec_unpacks_lo_v16qi"
1985   [(set (match_operand:V8HI 0 "register_operand" "=v")
1986         (unspec:V8HI [(match_operand:V16QI 1 "register_operand" "v")]
1987                      UNSPEC_VUPKLSB))]
1988   "TARGET_ALTIVEC"
1989   "
1991   emit_insn (gen_altivec_vupklsb (operands[0], operands[1]));
1992   DONE;
1995 (define_expand "vec_unpacks_lo_v8hi"
1996   [(set (match_operand:V4SI 0 "register_operand" "=v")
1997         (unspec:V4SI [(match_operand:V8HI 1 "register_operand" "v")]
1998                      UNSPEC_VUPKLSH))]
1999   "TARGET_ALTIVEC"
2000   "
2002   emit_insn (gen_altivec_vupklsh (operands[0], operands[1]));
2003   DONE;
2006 (define_insn "vperm_v8hiv4si"
2007   [(set (match_operand:V4SI 0 "register_operand" "=v")
2008         (unspec:V4SI [(match_operand:V8HI 1 "register_operand" "v")
2009                    (match_operand:V4SI 2 "register_operand" "v")
2010                    (match_operand:V16QI 3 "register_operand" "v")]
2011                   UNSPEC_VPERMSI))]
2012   "TARGET_ALTIVEC"
2013   "vperm %0,%1,%2,%3"
2014   [(set_attr "type" "vecperm")])
2016 (define_insn "vperm_v16qiv8hi"
2017   [(set (match_operand:V8HI 0 "register_operand" "=v")
2018         (unspec:V8HI [(match_operand:V16QI 1 "register_operand" "v")
2019                    (match_operand:V8HI 2 "register_operand" "v")
2020                    (match_operand:V16QI 3 "register_operand" "v")]
2021                   UNSPEC_VPERMHI))]
2022   "TARGET_ALTIVEC"
2023   "vperm %0,%1,%2,%3"
2024   [(set_attr "type" "vecperm")])
2027 (define_expand "vec_unpacku_hi_v16qi"
2028   [(set (match_operand:V8HI 0 "register_operand" "=v")
2029         (unspec:V8HI [(match_operand:V16QI 1 "register_operand" "v")]
2030                      UNSPEC_VUPKHUB))]
2031   "TARGET_ALTIVEC"      
2032   "
2033 {  
2034   rtx vzero = gen_reg_rtx (V8HImode);
2035   rtx mask = gen_reg_rtx (V16QImode);
2036   rtvec v = rtvec_alloc (16);
2037    
2038   emit_insn (gen_altivec_vspltish (vzero, const0_rtx));
2039    
2040   RTVEC_ELT (v, 0) = gen_rtx_CONST_INT (QImode, 16);
2041   RTVEC_ELT (v, 1) = gen_rtx_CONST_INT (QImode, 0);
2042   RTVEC_ELT (v, 2) = gen_rtx_CONST_INT (QImode, 16);
2043   RTVEC_ELT (v, 3) = gen_rtx_CONST_INT (QImode, 1);
2044   RTVEC_ELT (v, 4) = gen_rtx_CONST_INT (QImode, 16);
2045   RTVEC_ELT (v, 5) = gen_rtx_CONST_INT (QImode, 2);
2046   RTVEC_ELT (v, 6) = gen_rtx_CONST_INT (QImode, 16);
2047   RTVEC_ELT (v, 7) = gen_rtx_CONST_INT (QImode, 3);
2048   RTVEC_ELT (v, 8) = gen_rtx_CONST_INT (QImode, 16);
2049   RTVEC_ELT (v, 9) = gen_rtx_CONST_INT (QImode, 4);
2050   RTVEC_ELT (v, 10) = gen_rtx_CONST_INT (QImode, 16);
2051   RTVEC_ELT (v, 11) = gen_rtx_CONST_INT (QImode, 5);
2052   RTVEC_ELT (v, 12) = gen_rtx_CONST_INT (QImode, 16);
2053   RTVEC_ELT (v, 13) = gen_rtx_CONST_INT (QImode, 6);
2054   RTVEC_ELT (v, 14) = gen_rtx_CONST_INT (QImode, 16);
2055   RTVEC_ELT (v, 15) = gen_rtx_CONST_INT (QImode, 7);
2057   emit_insn (gen_vec_initv16qi (mask, gen_rtx_PARALLEL (V16QImode, v)));
2058   emit_insn (gen_vperm_v16qiv8hi (operands[0], operands[1], vzero, mask));
2059   DONE;
2062 (define_expand "vec_unpacku_hi_v8hi"
2063   [(set (match_operand:V4SI 0 "register_operand" "=v")
2064         (unspec:V4SI [(match_operand:V8HI 1 "register_operand" "v")]
2065                      UNSPEC_VUPKHUH))]
2066   "TARGET_ALTIVEC"
2067   "
2069   rtx vzero = gen_reg_rtx (V4SImode);
2070   rtx mask = gen_reg_rtx (V16QImode);
2071   rtvec v = rtvec_alloc (16);
2073   emit_insn (gen_altivec_vspltisw (vzero, const0_rtx));
2075   RTVEC_ELT (v, 0) = gen_rtx_CONST_INT (QImode, 16);
2076   RTVEC_ELT (v, 1) = gen_rtx_CONST_INT (QImode, 17);
2077   RTVEC_ELT (v, 2) = gen_rtx_CONST_INT (QImode, 0);
2078   RTVEC_ELT (v, 3) = gen_rtx_CONST_INT (QImode, 1);
2079   RTVEC_ELT (v, 4) = gen_rtx_CONST_INT (QImode, 16);
2080   RTVEC_ELT (v, 5) = gen_rtx_CONST_INT (QImode, 17);
2081   RTVEC_ELT (v, 6) = gen_rtx_CONST_INT (QImode, 2);
2082   RTVEC_ELT (v, 7) = gen_rtx_CONST_INT (QImode, 3);
2083   RTVEC_ELT (v, 8) = gen_rtx_CONST_INT (QImode, 16);
2084   RTVEC_ELT (v, 9) = gen_rtx_CONST_INT (QImode, 17);
2085   RTVEC_ELT (v, 10) = gen_rtx_CONST_INT (QImode, 4);
2086   RTVEC_ELT (v, 11) = gen_rtx_CONST_INT (QImode, 5);
2087   RTVEC_ELT (v, 12) = gen_rtx_CONST_INT (QImode, 16);
2088   RTVEC_ELT (v, 13) = gen_rtx_CONST_INT (QImode, 17);
2089   RTVEC_ELT (v, 14) = gen_rtx_CONST_INT (QImode, 6);
2090   RTVEC_ELT (v, 15) = gen_rtx_CONST_INT (QImode, 7);
2092   emit_insn (gen_vec_initv16qi (mask, gen_rtx_PARALLEL (V16QImode, v)));
2093   emit_insn (gen_vperm_v8hiv4si (operands[0], operands[1], vzero, mask));
2094   DONE;
2097 (define_expand "vec_unpacku_lo_v16qi"
2098   [(set (match_operand:V8HI 0 "register_operand" "=v")
2099         (unspec:V8HI [(match_operand:V16QI 1 "register_operand" "v")]
2100                      UNSPEC_VUPKLUB))]
2101   "TARGET_ALTIVEC"
2102   "
2104   rtx vzero = gen_reg_rtx (V8HImode);
2105   rtx mask = gen_reg_rtx (V16QImode);
2106   rtvec v = rtvec_alloc (16);
2108   emit_insn (gen_altivec_vspltish (vzero, const0_rtx));
2110   RTVEC_ELT (v, 0) = gen_rtx_CONST_INT (QImode, 16);
2111   RTVEC_ELT (v, 1) = gen_rtx_CONST_INT (QImode, 8);
2112   RTVEC_ELT (v, 2) = gen_rtx_CONST_INT (QImode, 16);
2113   RTVEC_ELT (v, 3) = gen_rtx_CONST_INT (QImode, 9);
2114   RTVEC_ELT (v, 4) = gen_rtx_CONST_INT (QImode, 16);
2115   RTVEC_ELT (v, 5) = gen_rtx_CONST_INT (QImode, 10);
2116   RTVEC_ELT (v, 6) = gen_rtx_CONST_INT (QImode, 16);
2117   RTVEC_ELT (v, 7) = gen_rtx_CONST_INT (QImode, 11);
2118   RTVEC_ELT (v, 8) = gen_rtx_CONST_INT (QImode, 16);
2119   RTVEC_ELT (v, 9) = gen_rtx_CONST_INT (QImode, 12);
2120   RTVEC_ELT (v, 10) = gen_rtx_CONST_INT (QImode, 16);
2121   RTVEC_ELT (v, 11) = gen_rtx_CONST_INT (QImode, 13);
2122   RTVEC_ELT (v, 12) = gen_rtx_CONST_INT (QImode, 16);
2123   RTVEC_ELT (v, 13) = gen_rtx_CONST_INT (QImode, 14);
2124   RTVEC_ELT (v, 14) = gen_rtx_CONST_INT (QImode, 16);
2125   RTVEC_ELT (v, 15) = gen_rtx_CONST_INT (QImode, 15);
2127   emit_insn (gen_vec_initv16qi (mask, gen_rtx_PARALLEL (V16QImode, v)));
2128   emit_insn (gen_vperm_v16qiv8hi (operands[0], operands[1], vzero, mask));
2129   DONE;
2132 (define_expand "vec_unpacku_lo_v8hi"
2133   [(set (match_operand:V4SI 0 "register_operand" "=v")
2134         (unspec:V4SI [(match_operand:V8HI 1 "register_operand" "v")]
2135                      UNSPEC_VUPKLUH))]
2136   "TARGET_ALTIVEC"
2137   "
2139   rtx vzero = gen_reg_rtx (V4SImode);
2140   rtx mask = gen_reg_rtx (V16QImode);
2141   rtvec v = rtvec_alloc (16);
2143   emit_insn (gen_altivec_vspltisw (vzero, const0_rtx));
2145   RTVEC_ELT (v, 0) = gen_rtx_CONST_INT (QImode, 16);
2146   RTVEC_ELT (v, 1) = gen_rtx_CONST_INT (QImode, 17);
2147   RTVEC_ELT (v, 2) = gen_rtx_CONST_INT (QImode, 8);
2148   RTVEC_ELT (v, 3) = gen_rtx_CONST_INT (QImode, 9);
2149   RTVEC_ELT (v, 4) = gen_rtx_CONST_INT (QImode, 16);
2150   RTVEC_ELT (v, 5) = gen_rtx_CONST_INT (QImode, 17);
2151   RTVEC_ELT (v, 6) = gen_rtx_CONST_INT (QImode, 10);
2152   RTVEC_ELT (v, 7) = gen_rtx_CONST_INT (QImode, 11);
2153   RTVEC_ELT (v, 8) = gen_rtx_CONST_INT (QImode, 16);
2154   RTVEC_ELT (v, 9) = gen_rtx_CONST_INT (QImode, 17);
2155   RTVEC_ELT (v, 10) = gen_rtx_CONST_INT (QImode, 12);
2156   RTVEC_ELT (v, 11) = gen_rtx_CONST_INT (QImode, 13);
2157   RTVEC_ELT (v, 12) = gen_rtx_CONST_INT (QImode, 16);
2158   RTVEC_ELT (v, 13) = gen_rtx_CONST_INT (QImode, 17);
2159   RTVEC_ELT (v, 14) = gen_rtx_CONST_INT (QImode, 14);
2160   RTVEC_ELT (v, 15) = gen_rtx_CONST_INT (QImode, 15);
2162   emit_insn (gen_vec_initv16qi (mask, gen_rtx_PARALLEL (V16QImode, v)));
2163   emit_insn (gen_vperm_v8hiv4si (operands[0], operands[1], vzero, mask));
2164   DONE;
2167 (define_expand "vec_widen_umult_hi_v16qi"
2168   [(set (match_operand:V8HI 0 "register_operand" "=v")
2169         (unspec:V8HI [(match_operand:V16QI 1 "register_operand" "v")
2170                       (match_operand:V16QI 2 "register_operand" "v")]
2171                      UNSPEC_VMULWHUB))]
2172   "TARGET_ALTIVEC"
2173   "
2175   rtx ve = gen_reg_rtx (V8HImode);
2176   rtx vo = gen_reg_rtx (V8HImode);
2177   
2178   emit_insn (gen_vec_widen_umult_even_v16qi (ve, operands[1], operands[2]));
2179   emit_insn (gen_vec_widen_umult_odd_v16qi (vo, operands[1], operands[2]));
2180   emit_insn (gen_altivec_vmrghh (operands[0], ve, vo));
2181   DONE;
2184 (define_expand "vec_widen_umult_lo_v16qi"
2185   [(set (match_operand:V8HI 0 "register_operand" "=v")
2186         (unspec:V8HI [(match_operand:V16QI 1 "register_operand" "v")
2187                       (match_operand:V16QI 2 "register_operand" "v")]
2188                      UNSPEC_VMULWLUB))]
2189   "TARGET_ALTIVEC"
2190   "
2192   rtx ve = gen_reg_rtx (V8HImode);
2193   rtx vo = gen_reg_rtx (V8HImode);
2194   
2195   emit_insn (gen_vec_widen_umult_even_v16qi (ve, operands[1], operands[2]));
2196   emit_insn (gen_vec_widen_umult_odd_v16qi (vo, operands[1], operands[2]));
2197   emit_insn (gen_altivec_vmrglh (operands[0], ve, vo));
2198   DONE;
2201 (define_expand "vec_widen_smult_hi_v16qi"
2202   [(set (match_operand:V8HI 0 "register_operand" "=v")
2203         (unspec:V8HI [(match_operand:V16QI 1 "register_operand" "v")
2204                       (match_operand:V16QI 2 "register_operand" "v")]
2205                      UNSPEC_VMULWHSB))]
2206   "TARGET_ALTIVEC"
2207   "
2209   rtx ve = gen_reg_rtx (V8HImode);
2210   rtx vo = gen_reg_rtx (V8HImode);
2211   
2212   emit_insn (gen_vec_widen_smult_even_v16qi (ve, operands[1], operands[2]));
2213   emit_insn (gen_vec_widen_smult_odd_v16qi (vo, operands[1], operands[2]));
2214   emit_insn (gen_altivec_vmrghh (operands[0], ve, vo));
2215   DONE;
2218 (define_expand "vec_widen_smult_lo_v16qi"
2219   [(set (match_operand:V8HI 0 "register_operand" "=v")
2220         (unspec:V8HI [(match_operand:V16QI 1 "register_operand" "v")
2221                       (match_operand:V16QI 2 "register_operand" "v")]
2222                      UNSPEC_VMULWLSB))]
2223   "TARGET_ALTIVEC"
2224   "
2226   rtx ve = gen_reg_rtx (V8HImode);
2227   rtx vo = gen_reg_rtx (V8HImode);
2228   
2229   emit_insn (gen_vec_widen_smult_even_v16qi (ve, operands[1], operands[2]));
2230   emit_insn (gen_vec_widen_smult_odd_v16qi (vo, operands[1], operands[2]));
2231   emit_insn (gen_altivec_vmrglh (operands[0], ve, vo));
2232   DONE;
2235 (define_expand "vec_widen_umult_hi_v8hi"
2236   [(set (match_operand:V4SI 0 "register_operand" "=v")
2237         (unspec:V4SI [(match_operand:V8HI 1 "register_operand" "v")
2238                       (match_operand:V8HI 2 "register_operand" "v")]
2239                      UNSPEC_VMULWHUH))]
2240   "TARGET_ALTIVEC"
2241   "
2243   rtx ve = gen_reg_rtx (V4SImode);
2244   rtx vo = gen_reg_rtx (V4SImode);
2245   
2246   emit_insn (gen_vec_widen_umult_even_v8hi (ve, operands[1], operands[2]));
2247   emit_insn (gen_vec_widen_umult_odd_v8hi (vo, operands[1], operands[2]));
2248   emit_insn (gen_altivec_vmrghw (operands[0], ve, vo));
2249   DONE;
2252 (define_expand "vec_widen_umult_lo_v8hi"
2253   [(set (match_operand:V4SI 0 "register_operand" "=v")
2254         (unspec:V4SI [(match_operand:V8HI 1 "register_operand" "v")
2255                       (match_operand:V8HI 2 "register_operand" "v")]
2256                      UNSPEC_VMULWLUH))]
2257   "TARGET_ALTIVEC"
2258   "
2260   rtx ve = gen_reg_rtx (V4SImode);
2261   rtx vo = gen_reg_rtx (V4SImode);
2262   
2263   emit_insn (gen_vec_widen_umult_even_v8hi (ve, operands[1], operands[2]));
2264   emit_insn (gen_vec_widen_umult_odd_v8hi (vo, operands[1], operands[2]));
2265   emit_insn (gen_altivec_vmrglw (operands[0], ve, vo));
2266   DONE;
2269 (define_expand "vec_widen_smult_hi_v8hi"
2270   [(set (match_operand:V4SI 0 "register_operand" "=v")
2271         (unspec:V4SI [(match_operand:V8HI 1 "register_operand" "v")
2272                       (match_operand:V8HI 2 "register_operand" "v")]
2273                      UNSPEC_VMULWHSH))]
2274   "TARGET_ALTIVEC"
2275   "
2277   rtx ve = gen_reg_rtx (V4SImode);
2278   rtx vo = gen_reg_rtx (V4SImode);
2279   
2280   emit_insn (gen_vec_widen_smult_even_v8hi (ve, operands[1], operands[2]));
2281   emit_insn (gen_vec_widen_smult_odd_v8hi (vo, operands[1], operands[2]));
2282   emit_insn (gen_altivec_vmrghw (operands[0], ve, vo));
2283   DONE;
2286 (define_expand "vec_widen_smult_lo_v8hi"
2287   [(set (match_operand:V4SI 0 "register_operand" "=v")
2288         (unspec:V4SI [(match_operand:V8HI 1 "register_operand" "v")
2289                       (match_operand:V8HI 2 "register_operand" "v")]
2290                      UNSPEC_VMULWLSH))]
2291   "TARGET_ALTIVEC"
2292   "
2294   rtx ve = gen_reg_rtx (V4SImode);
2295   rtx vo = gen_reg_rtx (V4SImode);
2296   
2297   emit_insn (gen_vec_widen_smult_even_v8hi (ve, operands[1], operands[2]));
2298   emit_insn (gen_vec_widen_smult_odd_v8hi (vo, operands[1], operands[2]));
2299   emit_insn (gen_altivec_vmrglw (operands[0], ve, vo));
2300   DONE;
2303 (define_expand "vec_pack_trunc_v8hi"
2304   [(set (match_operand:V16QI 0 "register_operand" "=v")
2305         (unspec:V16QI [(match_operand:V8HI 1 "register_operand" "v")
2306                        (match_operand:V8HI 2 "register_operand" "v")]
2307                       UNSPEC_VPKUHUM))]
2308   "TARGET_ALTIVEC"
2309   "
2311   emit_insn (gen_altivec_vpkuhum (operands[0], operands[1], operands[2]));
2312   DONE;
2314                                                                                 
2315 (define_expand "vec_pack_trunc_v4si"
2316   [(set (match_operand:V8HI 0 "register_operand" "=v")
2317         (unspec:V8HI [(match_operand:V4SI 1 "register_operand" "v")
2318                       (match_operand:V4SI 2 "register_operand" "v")]
2319                      UNSPEC_VPKUWUM))]
2320   "TARGET_ALTIVEC"
2321   "
2323   emit_insn (gen_altivec_vpkuwum (operands[0], operands[1], operands[2]));
2324   DONE;
2327 (define_expand "altivec_negv4sf2"
2328   [(use (match_operand:V4SF 0 "register_operand" ""))
2329    (use (match_operand:V4SF 1 "register_operand" ""))]
2330   "TARGET_ALTIVEC"
2331   "
2333   rtx neg0;
2335   /* Generate [-0.0, -0.0, -0.0, -0.0].  */
2336   neg0 = gen_reg_rtx (V4SImode);
2337   emit_insn (gen_altivec_vspltisw (neg0, constm1_rtx));
2338   emit_insn (gen_vashlv4si3 (neg0, neg0, neg0));
2340   /* XOR */
2341   emit_insn (gen_xorv4sf3 (operands[0],
2342                            gen_lowpart (V4SFmode, neg0), operands[1])); 
2343     
2344   DONE;
2347 ;; Vector SIMD PEM v2.06c defines LVLX, LVLXL, LVRX, LVRXL,
2348 ;; STVLX, STVLXL, STVVRX, STVRXL are available only on Cell.
2349 (define_insn "altivec_lvlx"
2350   [(set (match_operand:V16QI 0 "register_operand" "=v")
2351         (unspec:V16QI [(match_operand 1 "memory_operand" "Z")] 
2352                       UNSPEC_LVLX))]
2353   "TARGET_ALTIVEC && rs6000_cpu == PROCESSOR_CELL"
2354   "lvlx %0,%y1"
2355   [(set_attr "type" "vecload")])
2357 (define_insn "altivec_lvlxl"
2358   [(set (match_operand:V16QI 0 "register_operand" "=v")
2359         (unspec:V16QI [(match_operand 1 "memory_operand" "Z")] 
2360                       UNSPEC_LVLXL))]
2361   "TARGET_ALTIVEC && rs6000_cpu == PROCESSOR_CELL"
2362   "lvlxl %0,%y1"
2363   [(set_attr "type" "vecload")])
2365 (define_insn "altivec_lvrx"
2366   [(set (match_operand:V16QI 0 "register_operand" "=v")
2367         (unspec:V16QI [(match_operand 1 "memory_operand" "Z")] 
2368                       UNSPEC_LVRX))]
2369   "TARGET_ALTIVEC && rs6000_cpu == PROCESSOR_CELL"
2370   "lvrx %0,%y1"
2371   [(set_attr "type" "vecload")])
2373 (define_insn "altivec_lvrxl"
2374   [(set (match_operand:V16QI 0 "register_operand" "=v")
2375         (unspec:V16QI [(match_operand 1 "memory_operand" "Z")] 
2376                       UNSPEC_LVRXL))]
2377   "TARGET_ALTIVEC && rs6000_cpu == PROCESSOR_CELL"
2378   "lvrxl %0,%y1"
2379   [(set_attr "type" "vecload")])
2381 (define_insn "altivec_stvlx"
2382   [(parallel
2383     [(set (match_operand:V16QI 0 "memory_operand" "=Z")
2384           (match_operand:V16QI 1 "register_operand" "v"))
2385      (unspec [(const_int 0)] UNSPEC_STVLX)])]
2386   "TARGET_ALTIVEC && rs6000_cpu == PROCESSOR_CELL"
2387   "stvlx %1,%y0"
2388   [(set_attr "type" "vecstore")])
2390 (define_insn "altivec_stvlxl"
2391   [(parallel
2392     [(set (match_operand:V16QI 0 "memory_operand" "=Z")
2393           (match_operand:V16QI 1 "register_operand" "v"))
2394      (unspec [(const_int 0)] UNSPEC_STVLXL)])]
2395   "TARGET_ALTIVEC && rs6000_cpu == PROCESSOR_CELL"
2396   "stvlxl %1,%y0"
2397   [(set_attr "type" "vecstore")])
2399 (define_insn "altivec_stvrx"
2400   [(parallel
2401     [(set (match_operand:V16QI 0 "memory_operand" "=Z")
2402           (match_operand:V16QI 1 "register_operand" "v"))
2403      (unspec [(const_int 0)] UNSPEC_STVRX)])]
2404   "TARGET_ALTIVEC && rs6000_cpu == PROCESSOR_CELL"
2405   "stvrx %1,%y0"
2406   [(set_attr "type" "vecstore")])
2408 (define_insn "altivec_stvrxl"
2409   [(parallel
2410     [(set (match_operand:V16QI 0 "memory_operand" "=Z")
2411           (match_operand:V16QI 1 "register_operand" "v"))
2412      (unspec [(const_int 0)] UNSPEC_STVRXL)])]
2413   "TARGET_ALTIVEC && rs6000_cpu == PROCESSOR_CELL"
2414   "stvrxl %1,%y0"
2415   [(set_attr "type" "vecstore")])
2417 (define_expand "vec_unpacks_float_hi_v8hi"
2418  [(set (match_operand:V4SF 0 "register_operand" "")
2419         (unspec:V4SF [(match_operand:V8HI 1 "register_operand" "")]
2420                      UNSPEC_VUPKHS_V4SF))]
2421   "TARGET_ALTIVEC"
2422   "
2424   rtx tmp = gen_reg_rtx (V4SImode);
2426   emit_insn (gen_vec_unpacks_hi_v8hi (tmp, operands[1]));
2427   emit_insn (gen_altivec_vcfsx (operands[0], tmp, const0_rtx));
2428   DONE;
2431 (define_expand "vec_unpacks_float_lo_v8hi"
2432  [(set (match_operand:V4SF 0 "register_operand" "")
2433         (unspec:V4SF [(match_operand:V8HI 1 "register_operand" "")]
2434                      UNSPEC_VUPKLS_V4SF))]
2435   "TARGET_ALTIVEC"
2436   "
2438   rtx tmp = gen_reg_rtx (V4SImode);
2440   emit_insn (gen_vec_unpacks_lo_v8hi (tmp, operands[1]));
2441   emit_insn (gen_altivec_vcfsx (operands[0], tmp, const0_rtx));
2442   DONE;
2445 (define_expand "vec_unpacku_float_hi_v8hi"
2446  [(set (match_operand:V4SF 0 "register_operand" "")
2447         (unspec:V4SF [(match_operand:V8HI 1 "register_operand" "")]
2448                      UNSPEC_VUPKHU_V4SF))]
2449   "TARGET_ALTIVEC"
2450   "
2452   rtx tmp = gen_reg_rtx (V4SImode);
2454   emit_insn (gen_vec_unpacku_hi_v8hi (tmp, operands[1]));
2455   emit_insn (gen_altivec_vcfux (operands[0], tmp, const0_rtx));
2456   DONE;
2459 (define_expand "vec_unpacku_float_lo_v8hi"
2460  [(set (match_operand:V4SF 0 "register_operand" "")
2461         (unspec:V4SF [(match_operand:V8HI 1 "register_operand" "")]
2462                      UNSPEC_VUPKLU_V4SF))]
2463   "TARGET_ALTIVEC"
2464   "
2466   rtx tmp = gen_reg_rtx (V4SImode);
2468   emit_insn (gen_vec_unpacku_lo_v8hi (tmp, operands[1]));
2469   emit_insn (gen_altivec_vcfux (operands[0], tmp, const0_rtx));
2470   DONE;