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