]> CyberLeo.Net >> Repos - FreeBSD/releng/10.0.git/blob - contrib/gcc/config/rs6000/altivec.md
- Copy stable/10 (r259064) to releng/10.0 as part of the
[FreeBSD/releng/10.0.git] / contrib / gcc / config / rs6000 / altivec.md
1 ;; AltiVec patterns.
2 ;; Copyright (C) 2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc.
3 ;; Contributed by Aldy Hernandez (aldy@quesejoda.com)
4
5 ;; This file is part of GCC.
6
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 2, or (at your
10 ;; option) any later version.
11
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.
16
17 ;; You should have received a copy of the GNU General Public License
18 ;; along with GCC; see the file COPYING.  If not, write to the
19 ;; Free Software Foundation, 51 Franklin Street, Fifth Floor, Boston,
20 ;; MA 02110-1301, USA.
21
22 (define_constants
23   [(UNSPEC_VCMPBFP       50)
24    (UNSPEC_VCMPEQUB      51)
25    (UNSPEC_VCMPEQUH      52)
26    (UNSPEC_VCMPEQUW      53)
27    (UNSPEC_VCMPEQFP      54)
28    (UNSPEC_VCMPGEFP      55)
29    (UNSPEC_VCMPGTUB      56)
30    (UNSPEC_VCMPGTSB      57)
31    (UNSPEC_VCMPGTUH      58)
32    (UNSPEC_VCMPGTSH      59)
33    (UNSPEC_VCMPGTUW      60)
34    (UNSPEC_VCMPGTSW      61)
35    (UNSPEC_VCMPGTFP      62)
36    (UNSPEC_VMSUMU        65)
37    (UNSPEC_VMSUMM        66)
38    (UNSPEC_VMSUMSHM      68)
39    (UNSPEC_VMSUMUHS      69)
40    (UNSPEC_VMSUMSHS      70)
41    (UNSPEC_VMHADDSHS     71)
42    (UNSPEC_VMHRADDSHS    72)
43    (UNSPEC_VMLADDUHM     73)
44    (UNSPEC_VADDCUW       75)
45    (UNSPEC_VADDU         76)
46    (UNSPEC_VADDS         77)
47    (UNSPEC_VAVGU         80)
48    (UNSPEC_VAVGS         81)
49    (UNSPEC_VMULEUB       83)
50    (UNSPEC_VMULESB       84)
51    (UNSPEC_VMULEUH       85)
52    (UNSPEC_VMULESH       86)
53    (UNSPEC_VMULOUB       87)
54    (UNSPEC_VMULOSB       88)
55    (UNSPEC_VMULOUH       89)
56    (UNSPEC_VMULOSH       90)
57    (UNSPEC_VPKUHUM       93)
58    (UNSPEC_VPKUWUM       94)
59    (UNSPEC_VPKPX         95)
60    (UNSPEC_VPKSHSS       97)
61    (UNSPEC_VPKSWSS       99)
62    (UNSPEC_VPKUHUS      100)
63    (UNSPEC_VPKSHUS      101)
64    (UNSPEC_VPKUWUS      102)
65    (UNSPEC_VPKSWUS      103)
66    (UNSPEC_VRL          104)
67    (UNSPEC_VSL          107)
68    (UNSPEC_VSLV4SI      110)
69    (UNSPEC_VSLO         111)
70    (UNSPEC_VSR          118)
71    (UNSPEC_VSRO         119)
72    (UNSPEC_VSUBCUW      124)
73    (UNSPEC_VSUBU        125)
74    (UNSPEC_VSUBS        126)
75    (UNSPEC_VSUM4UBS     131)
76    (UNSPEC_VSUM4S       132)
77    (UNSPEC_VSUM2SWS     134)
78    (UNSPEC_VSUMSWS      135)
79    (UNSPEC_VPERM        144)
80    (UNSPEC_VRFIP        148)
81    (UNSPEC_VRFIN        149)
82    (UNSPEC_VRFIM        150)
83    (UNSPEC_VCFUX        151)
84    (UNSPEC_VCFSX        152)
85    (UNSPEC_VCTUXS       153)
86    (UNSPEC_VCTSXS       154)
87    (UNSPEC_VLOGEFP      155)
88    (UNSPEC_VEXPTEFP     156)
89    (UNSPEC_VRSQRTEFP    157)
90    (UNSPEC_VREFP        158)
91    (UNSPEC_VSEL4SI      159)
92    (UNSPEC_VSEL4SF      160)
93    (UNSPEC_VSEL8HI      161)
94    (UNSPEC_VSEL16QI     162)
95    (UNSPEC_VLSDOI       163)
96    (UNSPEC_VUPKHSB      167)
97    (UNSPEC_VUPKHPX      168)
98    (UNSPEC_VUPKHSH      169)
99    (UNSPEC_VUPKLSB      170)
100    (UNSPEC_VUPKLPX      171)
101    (UNSPEC_VUPKLSH      172)
102    (UNSPEC_PREDICATE    173)
103    (UNSPEC_DST          190)
104    (UNSPEC_DSTT         191)
105    (UNSPEC_DSTST        192)
106    (UNSPEC_DSTSTT       193)
107    (UNSPEC_LVSL         194)
108    (UNSPEC_LVSR         195)
109    (UNSPEC_LVE          196)
110    (UNSPEC_STVX         201)
111    (UNSPEC_STVXL        202)
112    (UNSPEC_STVE         203)
113    (UNSPEC_SET_VSCR     213)
114    (UNSPEC_GET_VRSAVE   214)
115    (UNSPEC_REALIGN_LOAD 215)
116    (UNSPEC_REDUC_PLUS   217)
117    (UNSPEC_VECSH        219)
118    (UNSPEC_VCOND_V4SI   301)
119    (UNSPEC_VCOND_V4SF   302)
120    (UNSPEC_VCOND_V8HI   303)
121    (UNSPEC_VCOND_V16QI  304)
122    (UNSPEC_VCONDU_V4SI  305)
123    (UNSPEC_VCONDU_V8HI  306)
124    (UNSPEC_VCONDU_V16QI 307)
125    ])
126
127 (define_constants
128   [(UNSPECV_SET_VRSAVE   30)
129    (UNSPECV_MTVSCR      186)
130    (UNSPECV_MFVSCR      187)
131    (UNSPECV_DSSALL      188)
132    (UNSPECV_DSS         189)
133   ])
134
135 ;; Vec int modes
136 (define_mode_macro VI [V4SI V8HI V16QI])
137 ;; Short vec in modes
138 (define_mode_macro VIshort [V8HI V16QI])
139 ;; Vec float modes
140 (define_mode_macro VF [V4SF])
141 ;; Vec modes, pity mode macros are not composable
142 (define_mode_macro V [V4SI V8HI V16QI V4SF])
143
144 (define_mode_attr VI_char [(V4SI "w") (V8HI "h") (V16QI "b")])
145
146 ;; Generic LVX load instruction.
147 (define_insn "altivec_lvx_<mode>"
148   [(set (match_operand:V 0 "altivec_register_operand" "=v")
149         (match_operand:V 1 "memory_operand" "Z"))]
150   "TARGET_ALTIVEC"
151   "lvx %0,%y1"
152   [(set_attr "type" "vecload")])
153
154 ;; Generic STVX store instruction.
155 (define_insn "altivec_stvx_<mode>"
156   [(set (match_operand:V 0 "memory_operand" "=Z")
157         (match_operand:V 1 "altivec_register_operand" "v"))]
158   "TARGET_ALTIVEC"
159   "stvx %1,%y0"
160   [(set_attr "type" "vecstore")])
161
162 ;; Vector move instructions.
163 (define_expand "mov<mode>"
164   [(set (match_operand:V 0 "nonimmediate_operand" "")
165         (match_operand:V 1 "any_operand" ""))]
166   "TARGET_ALTIVEC"
167 {
168   rs6000_emit_move (operands[0], operands[1], <MODE>mode);
169   DONE;
170 })
171
172 (define_insn "*mov<mode>_internal"
173   [(set (match_operand:V 0 "nonimmediate_operand" "=Z,v,v,o,r,r,v")
174         (match_operand:V 1 "input_operand" "v,Z,v,r,o,r,W"))]
175   "TARGET_ALTIVEC 
176    && (register_operand (operands[0], <MODE>mode) 
177        || register_operand (operands[1], <MODE>mode))"
178 {
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 output_vec_const_move (operands);
188     default: gcc_unreachable ();
189     }
190 }
191   [(set_attr "type" "vecstore,vecload,vecsimple,store,load,*,*")])
192
193 (define_split
194   [(set (match_operand:V4SI 0 "nonimmediate_operand" "")
195         (match_operand:V4SI 1 "input_operand" ""))]
196   "TARGET_ALTIVEC && reload_completed
197    && gpr_or_gpr_p (operands[0], operands[1])"
198   [(pc)]
199 {
200   rs6000_split_multireg_move (operands[0], operands[1]); DONE;
201 })
202
203 (define_split
204   [(set (match_operand:V8HI 0 "nonimmediate_operand" "")
205         (match_operand:V8HI 1 "input_operand" ""))]
206   "TARGET_ALTIVEC && reload_completed
207    && gpr_or_gpr_p (operands[0], operands[1])"
208   [(pc)]
209 { rs6000_split_multireg_move (operands[0], operands[1]); DONE; })
210
211 (define_split
212   [(set (match_operand:V16QI 0 "nonimmediate_operand" "")
213         (match_operand:V16QI 1 "input_operand" ""))]
214   "TARGET_ALTIVEC && reload_completed
215    && gpr_or_gpr_p (operands[0], operands[1])"
216   [(pc)]
217 { rs6000_split_multireg_move (operands[0], operands[1]); DONE; })
218
219 (define_split
220   [(set (match_operand:V4SF 0 "nonimmediate_operand" "")
221         (match_operand:V4SF 1 "input_operand" ""))]
222   "TARGET_ALTIVEC && reload_completed
223    && gpr_or_gpr_p (operands[0], operands[1])"
224   [(pc)]
225 {
226   rs6000_split_multireg_move (operands[0], operands[1]); DONE;
227 })
228
229 (define_split
230   [(set (match_operand:VI 0 "altivec_register_operand" "")
231         (match_operand:VI 1 "easy_vector_constant_add_self" ""))]
232   "TARGET_ALTIVEC && reload_completed"
233   [(set (match_dup 0) (match_dup 3))
234    (set (match_dup 0) (plus:VI (match_dup 0)
235                                (match_dup 0)))]
236 {
237   rtx dup = gen_easy_altivec_constant (operands[1]);
238   rtx const_vec;
239
240   /* Divide the operand of the resulting VEC_DUPLICATE, and use
241      simplify_rtx to make a CONST_VECTOR.  */
242   XEXP (dup, 0) = simplify_const_binary_operation (ASHIFTRT, QImode,
243                                                    XEXP (dup, 0), const1_rtx);
244   const_vec = simplify_rtx (dup);
245
246   if (GET_MODE (const_vec) == <MODE>mode)
247     operands[3] = const_vec;
248   else
249     operands[3] = gen_lowpart (<MODE>mode, const_vec);
250 })
251
252 (define_insn "get_vrsave_internal"
253   [(set (match_operand:SI 0 "register_operand" "=r")
254         (unspec:SI [(reg:SI 109)] UNSPEC_GET_VRSAVE))]
255   "TARGET_ALTIVEC"
256 {
257   if (TARGET_MACHO)
258      return "mfspr %0,256";
259   else
260      return "mfvrsave %0";
261 }
262   [(set_attr "type" "*")])
263
264 (define_insn "*set_vrsave_internal"
265   [(match_parallel 0 "vrsave_operation"
266      [(set (reg:SI 109)
267            (unspec_volatile:SI [(match_operand:SI 1 "register_operand" "r")
268                                 (reg:SI 109)] UNSPECV_SET_VRSAVE))])]
269   "TARGET_ALTIVEC"
270 {
271   if (TARGET_MACHO)
272     return "mtspr 256,%1";
273   else
274     return "mtvrsave %1";
275 }
276   [(set_attr "type" "*")])
277
278 (define_insn "*save_world"
279  [(match_parallel 0 "save_world_operation"
280                   [(clobber (match_operand:SI 1 "register_operand" "=l"))
281                    (use (match_operand:SI 2 "call_operand" "s"))])]
282  "TARGET_MACHO && (DEFAULT_ABI == ABI_DARWIN) && TARGET_32BIT"         
283  "bl %z2"
284   [(set_attr "type" "branch")
285    (set_attr "length" "4")])
286
287 (define_insn "*restore_world"
288  [(match_parallel 0 "restore_world_operation"
289                   [(return)
290                    (use (match_operand:SI 1 "register_operand" "l"))
291                    (use (match_operand:SI 2 "call_operand" "s"))
292                    (clobber (match_operand:SI 3 "gpc_reg_operand" "=r"))])]
293  "TARGET_MACHO && (DEFAULT_ABI == ABI_DARWIN) && TARGET_32BIT"
294  "b %z2")
295
296 ;; Simple binary operations.
297
298 ;; add
299 (define_insn "add<mode>3"
300   [(set (match_operand:VI 0 "register_operand" "=v")
301         (plus:VI (match_operand:VI 1 "register_operand" "v")
302                  (match_operand:VI 2 "register_operand" "v")))]
303   "TARGET_ALTIVEC"
304   "vaddu<VI_char>m %0,%1,%2"
305   [(set_attr "type" "vecsimple")])
306
307 (define_insn "addv4sf3"
308   [(set (match_operand:V4SF 0 "register_operand" "=v")
309         (plus:V4SF (match_operand:V4SF 1 "register_operand" "v")
310                    (match_operand:V4SF 2 "register_operand" "v")))]
311   "TARGET_ALTIVEC"
312   "vaddfp %0,%1,%2"
313   [(set_attr "type" "vecfloat")])
314
315 (define_insn "altivec_vaddcuw"
316   [(set (match_operand:V4SI 0 "register_operand" "=v")
317         (unspec:V4SI [(match_operand:V4SI 1 "register_operand" "v")
318                       (match_operand:V4SI 2 "register_operand" "v")]
319                      UNSPEC_VADDCUW))]
320   "TARGET_ALTIVEC"
321   "vaddcuw %0,%1,%2"
322   [(set_attr "type" "vecsimple")])
323
324 (define_insn "altivec_vaddu<VI_char>s"
325   [(set (match_operand:VI 0 "register_operand" "=v")
326         (unspec:VI [(match_operand:VI 1 "register_operand" "v")
327                     (match_operand:VI 2 "register_operand" "v")]
328                    UNSPEC_VADDU))
329    (set (reg:SI 110) (unspec:SI [(const_int 0)] UNSPEC_SET_VSCR))]
330   "TARGET_ALTIVEC"
331   "vaddu<VI_char>s %0,%1,%2"
332   [(set_attr "type" "vecsimple")])
333
334 (define_insn "altivec_vadds<VI_char>s"
335   [(set (match_operand:VI 0 "register_operand" "=v")
336         (unspec:VI [(match_operand:VI 1 "register_operand" "v")
337                     (match_operand:VI 2 "register_operand" "v")]
338                    UNSPEC_VADDS))
339    (set (reg:SI 110) (unspec:SI [(const_int 0)] UNSPEC_SET_VSCR))]
340   "TARGET_ALTIVEC"
341   "vadds<VI_char>s %0,%1,%2"
342   [(set_attr "type" "vecsimple")])
343
344 ;; sub
345 (define_insn "sub<mode>3"
346   [(set (match_operand:VI 0 "register_operand" "=v")
347         (minus:VI (match_operand:VI 1 "register_operand" "v")
348                   (match_operand:VI 2 "register_operand" "v")))]
349   "TARGET_ALTIVEC"
350   "vsubu<VI_char>m %0,%1,%2"
351   [(set_attr "type" "vecsimple")])
352
353 (define_insn "subv4sf3"
354   [(set (match_operand:V4SF 0 "register_operand" "=v")
355         (minus:V4SF (match_operand:V4SF 1 "register_operand" "v")
356                     (match_operand:V4SF 2 "register_operand" "v")))]
357   "TARGET_ALTIVEC"
358   "vsubfp %0,%1,%2"
359   [(set_attr "type" "vecfloat")])
360
361 (define_insn "altivec_vsubcuw"
362   [(set (match_operand:V4SI 0 "register_operand" "=v")
363         (unspec:V4SI [(match_operand:V4SI 1 "register_operand" "v")
364                       (match_operand:V4SI 2 "register_operand" "v")]
365                      UNSPEC_VSUBCUW))]
366   "TARGET_ALTIVEC"
367   "vsubcuw %0,%1,%2"
368   [(set_attr "type" "vecsimple")])
369
370 (define_insn "altivec_vsubu<VI_char>s"
371   [(set (match_operand:VI 0 "register_operand" "=v")
372         (unspec:VI [(match_operand:VI 1 "register_operand" "v")
373                     (match_operand:VI 2 "register_operand" "v")]
374                    UNSPEC_VSUBU))
375    (set (reg:SI 110) (unspec:SI [(const_int 0)] UNSPEC_SET_VSCR))]
376   "TARGET_ALTIVEC"
377   "vsubu<VI_char>s %0,%1,%2"
378   [(set_attr "type" "vecsimple")])
379
380 (define_insn "altivec_vsubs<VI_char>s"
381   [(set (match_operand:VI 0 "register_operand" "=v")
382         (unspec:VI [(match_operand:VI 1 "register_operand" "v")
383                     (match_operand:VI 2 "register_operand" "v")]
384                    UNSPEC_VSUBS))
385    (set (reg:SI 110) (unspec:SI [(const_int 0)] UNSPEC_SET_VSCR))]
386   "TARGET_ALTIVEC"
387   "vsubs<VI_char>s %0,%1,%2"
388   [(set_attr "type" "vecsimple")])
389
390 ;;
391 (define_insn "altivec_vavgu<VI_char>"
392   [(set (match_operand:VI 0 "register_operand" "=v")
393         (unspec:VI [(match_operand:VI 1 "register_operand" "v")
394                     (match_operand:VI 2 "register_operand" "v")]
395                    UNSPEC_VAVGU))]
396   "TARGET_ALTIVEC"
397   "vavgu<VI_char> %0,%1,%2"
398   [(set_attr "type" "vecsimple")])
399
400 (define_insn "altivec_vavgs<VI_char>"
401   [(set (match_operand:VI 0 "register_operand" "=v")
402         (unspec:VI [(match_operand:VI 1 "register_operand" "v")
403                     (match_operand:VI 2 "register_operand" "v")]
404                    UNSPEC_VAVGS))]
405   "TARGET_ALTIVEC"
406   "vavgs<VI_char> %0,%1,%2"
407   [(set_attr "type" "vecsimple")])
408
409 (define_insn "altivec_vcmpbfp"
410   [(set (match_operand:V4SI 0 "register_operand" "=v")
411         (unspec:V4SI [(match_operand:V4SF 1 "register_operand" "v")
412                       (match_operand:V4SF 2 "register_operand" "v")] 
413                       UNSPEC_VCMPBFP))]
414   "TARGET_ALTIVEC"
415   "vcmpbfp %0,%1,%2"
416   [(set_attr "type" "veccmp")])
417
418 (define_insn "altivec_vcmpequb"
419   [(set (match_operand:V16QI 0 "register_operand" "=v")
420         (unspec:V16QI [(match_operand:V16QI 1 "register_operand" "v")
421                        (match_operand:V16QI 2 "register_operand" "v")] 
422                        UNSPEC_VCMPEQUB))]
423   "TARGET_ALTIVEC"
424   "vcmpequb %0,%1,%2"
425   [(set_attr "type" "vecsimple")])
426
427 (define_insn "altivec_vcmpequh"
428   [(set (match_operand:V8HI 0 "register_operand" "=v")
429         (unspec:V8HI [(match_operand:V8HI 1 "register_operand" "v")
430                       (match_operand:V8HI 2 "register_operand" "v")] 
431                       UNSPEC_VCMPEQUH))]
432   "TARGET_ALTIVEC"
433   "vcmpequh %0,%1,%2"
434   [(set_attr "type" "vecsimple")])
435
436 (define_insn "altivec_vcmpequw"
437   [(set (match_operand:V4SI 0 "register_operand" "=v")
438         (unspec:V4SI [(match_operand:V4SI 1 "register_operand" "v")
439                       (match_operand:V4SI 2 "register_operand" "v")] 
440                       UNSPEC_VCMPEQUW))]
441   "TARGET_ALTIVEC"
442   "vcmpequw %0,%1,%2"
443   [(set_attr "type" "vecsimple")])
444
445 (define_insn "altivec_vcmpeqfp"
446   [(set (match_operand:V4SI 0 "register_operand" "=v")
447         (unspec:V4SI [(match_operand:V4SF 1 "register_operand" "v")
448                       (match_operand:V4SF 2 "register_operand" "v")] 
449                       UNSPEC_VCMPEQFP))]
450   "TARGET_ALTIVEC"
451   "vcmpeqfp %0,%1,%2"
452   [(set_attr "type" "veccmp")])
453
454 (define_insn "altivec_vcmpgefp"
455   [(set (match_operand:V4SI 0 "register_operand" "=v")
456         (unspec:V4SI [(match_operand:V4SF 1 "register_operand" "v")
457                       (match_operand:V4SF 2 "register_operand" "v")] 
458                      UNSPEC_VCMPGEFP))]
459   "TARGET_ALTIVEC"
460   "vcmpgefp %0,%1,%2"
461   [(set_attr "type" "veccmp")])
462
463 (define_insn "altivec_vcmpgtub"
464   [(set (match_operand:V16QI 0 "register_operand" "=v")
465         (unspec:V16QI [(match_operand:V16QI 1 "register_operand" "v")
466                        (match_operand:V16QI 2 "register_operand" "v")] 
467                       UNSPEC_VCMPGTUB))]
468   "TARGET_ALTIVEC"
469   "vcmpgtub %0,%1,%2"
470   [(set_attr "type" "vecsimple")])
471
472 (define_insn "altivec_vcmpgtsb"
473   [(set (match_operand:V16QI 0 "register_operand" "=v")
474         (unspec:V16QI [(match_operand:V16QI 1 "register_operand" "v")
475                        (match_operand:V16QI 2 "register_operand" "v")] 
476                       UNSPEC_VCMPGTSB))]
477   "TARGET_ALTIVEC"
478   "vcmpgtsb %0,%1,%2"
479   [(set_attr "type" "vecsimple")])
480
481 (define_insn "altivec_vcmpgtuh"
482   [(set (match_operand:V8HI 0 "register_operand" "=v")
483         (unspec:V8HI [(match_operand:V8HI 1 "register_operand" "v")
484                       (match_operand:V8HI 2 "register_operand" "v")] 
485                      UNSPEC_VCMPGTUH))]
486   "TARGET_ALTIVEC"
487   "vcmpgtuh %0,%1,%2"
488   [(set_attr "type" "vecsimple")])
489
490 (define_insn "altivec_vcmpgtsh"
491   [(set (match_operand:V8HI 0 "register_operand" "=v")
492         (unspec:V8HI [(match_operand:V8HI 1 "register_operand" "v")
493                       (match_operand:V8HI 2 "register_operand" "v")] 
494                      UNSPEC_VCMPGTSH))]
495   "TARGET_ALTIVEC"
496   "vcmpgtsh %0,%1,%2"
497   [(set_attr "type" "vecsimple")])
498
499 (define_insn "altivec_vcmpgtuw"
500   [(set (match_operand:V4SI 0 "register_operand" "=v")
501         (unspec:V4SI [(match_operand:V4SI 1 "register_operand" "v")
502                       (match_operand:V4SI 2 "register_operand" "v")] 
503                      UNSPEC_VCMPGTUW))]
504   "TARGET_ALTIVEC"
505   "vcmpgtuw %0,%1,%2"
506   [(set_attr "type" "vecsimple")])
507
508 (define_insn "altivec_vcmpgtsw"
509   [(set (match_operand:V4SI 0 "register_operand" "=v")
510         (unspec:V4SI [(match_operand:V4SI 1 "register_operand" "v")
511                       (match_operand:V4SI 2 "register_operand" "v")] 
512                      UNSPEC_VCMPGTSW))]
513   "TARGET_ALTIVEC"
514   "vcmpgtsw %0,%1,%2"
515   [(set_attr "type" "vecsimple")])
516
517 (define_insn "altivec_vcmpgtfp"
518   [(set (match_operand:V4SI 0 "register_operand" "=v")
519         (unspec:V4SI [(match_operand:V4SF 1 "register_operand" "v")
520                       (match_operand:V4SF 2 "register_operand" "v")] 
521                      UNSPEC_VCMPGTFP))]
522   "TARGET_ALTIVEC"
523   "vcmpgtfp %0,%1,%2"
524   [(set_attr "type" "veccmp")])
525
526 ;; Fused multiply add
527 (define_insn "altivec_vmaddfp"
528   [(set (match_operand:V4SF 0 "register_operand" "=v")
529         (plus:V4SF (mult:V4SF (match_operand:V4SF 1 "register_operand" "v")
530                               (match_operand:V4SF 2 "register_operand" "v"))
531                    (match_operand:V4SF 3 "register_operand" "v")))]
532   "TARGET_ALTIVEC"
533   "vmaddfp %0,%1,%2,%3"
534   [(set_attr "type" "vecfloat")])
535
536 ;; We do multiply as a fused multiply-add with an add of a -0.0 vector.
537
538 (define_expand "mulv4sf3"
539   [(use (match_operand:V4SF 0 "register_operand" ""))
540    (use (match_operand:V4SF 1 "register_operand" ""))
541    (use (match_operand:V4SF 2 "register_operand" ""))]
542   "TARGET_ALTIVEC && TARGET_FUSED_MADD"
543   "
544 {
545   rtx neg0;
546
547   /* Generate [-0.0, -0.0, -0.0, -0.0].  */
548   neg0 = gen_reg_rtx (V4SImode);
549   emit_insn (gen_altivec_vspltisw (neg0, constm1_rtx));
550   emit_insn (gen_altivec_vslw (neg0, neg0, neg0));
551
552   /* Use the multiply-add.  */
553   emit_insn (gen_altivec_vmaddfp (operands[0], operands[1], operands[2],
554                                   gen_lowpart (V4SFmode, neg0)));
555   DONE;
556 }")
557
558 ;; 32 bit integer multiplication
559 ;; A_high = Operand_0 & 0xFFFF0000 >> 16
560 ;; A_low = Operand_0 & 0xFFFF
561 ;; B_high = Operand_1 & 0xFFFF0000 >> 16
562 ;; B_low = Operand_1 & 0xFFFF
563 ;; result = A_low * B_low + (A_high * B_low + B_high * A_low) << 16
564
565 ;; (define_insn "mulv4si3"
566 ;;   [(set (match_operand:V4SI 0 "register_operand" "=v")
567 ;;         (mult:V4SI (match_operand:V4SI 1 "register_operand" "v")
568 ;;                    (match_operand:V4SI 2 "register_operand" "v")))]
569 (define_expand "mulv4si3"
570   [(use (match_operand:V4SI 0 "register_operand" ""))
571    (use (match_operand:V4SI 1 "register_operand" ""))
572    (use (match_operand:V4SI 2 "register_operand" ""))]
573    "TARGET_ALTIVEC"
574    "
575  {
576    rtx zero;
577    rtx swap;
578    rtx small_swap;
579    rtx sixteen;
580    rtx one;
581    rtx two;
582    rtx low_product;
583    rtx high_product;
584        
585    zero = gen_reg_rtx (V4SImode);
586    emit_insn (gen_altivec_vspltisw (zero, const0_rtx));
587  
588    sixteen = gen_reg_rtx (V4SImode);   
589    emit_insn (gen_altivec_vspltisw (sixteen,  gen_rtx_CONST_INT (V4SImode, -16)));
590  
591    swap = gen_reg_rtx (V4SImode);
592    emit_insn (gen_altivec_vrlw (swap, operands[2], sixteen));
593  
594    one = gen_reg_rtx (V8HImode);
595    convert_move (one, operands[1], 0);
596  
597    two = gen_reg_rtx (V8HImode);
598    convert_move (two, operands[2], 0);
599  
600    small_swap = gen_reg_rtx (V8HImode);
601    convert_move (small_swap, swap, 0);
602  
603    low_product = gen_reg_rtx (V4SImode);
604    emit_insn (gen_altivec_vmulouh (low_product, one, two));
605  
606    high_product = gen_reg_rtx (V4SImode);
607    emit_insn (gen_altivec_vmsumuhm (high_product, one, small_swap, zero));
608  
609    emit_insn (gen_altivec_vslw (high_product, high_product, sixteen));
610  
611    emit_insn (gen_addv4si3 (operands[0], high_product, low_product));
612    
613    DONE;
614  }")
615  
616
617 ;; Fused multiply subtract 
618 (define_insn "altivec_vnmsubfp"
619   [(set (match_operand:V4SF 0 "register_operand" "=v")
620         (neg:V4SF (minus:V4SF (mult:V4SF (match_operand:V4SF 1 "register_operand" "v")
621                                (match_operand:V4SF 2 "register_operand" "v"))
622                     (match_operand:V4SF 3 "register_operand" "v"))))]
623   "TARGET_ALTIVEC"
624   "vnmsubfp %0,%1,%2,%3"
625   [(set_attr "type" "vecfloat")])
626
627 (define_insn "altivec_vmsumu<VI_char>m"
628   [(set (match_operand:V4SI 0 "register_operand" "=v")
629         (unspec:V4SI [(match_operand:VIshort 1 "register_operand" "v")
630                       (match_operand:VIshort 2 "register_operand" "v")
631                       (match_operand:V4SI 3 "register_operand" "v")]
632                      UNSPEC_VMSUMU))]
633   "TARGET_ALTIVEC"
634   "vmsumu<VI_char>m %0,%1,%2,%3"
635   [(set_attr "type" "veccomplex")])
636
637 (define_insn "altivec_vmsumm<VI_char>m"
638   [(set (match_operand:V4SI 0 "register_operand" "=v")
639         (unspec:V4SI [(match_operand:VIshort 1 "register_operand" "v")
640                       (match_operand:VIshort 2 "register_operand" "v")
641                       (match_operand:V4SI 3 "register_operand" "v")]
642                      UNSPEC_VMSUMM))]
643   "TARGET_ALTIVEC"
644   "vmsumm<VI_char>m %0,%1,%2,%3"
645   [(set_attr "type" "veccomplex")])
646
647 (define_insn "altivec_vmsumshm"
648   [(set (match_operand:V4SI 0 "register_operand" "=v")
649         (unspec:V4SI [(match_operand:V8HI 1 "register_operand" "v")
650                       (match_operand:V8HI 2 "register_operand" "v")
651                       (match_operand:V4SI 3 "register_operand" "v")]
652                      UNSPEC_VMSUMSHM))]
653   "TARGET_ALTIVEC"
654   "vmsumshm %0,%1,%2,%3"
655   [(set_attr "type" "veccomplex")])
656
657 (define_insn "altivec_vmsumuhs"
658   [(set (match_operand:V4SI 0 "register_operand" "=v")
659         (unspec:V4SI [(match_operand:V8HI 1 "register_operand" "v")
660                       (match_operand:V8HI 2 "register_operand" "v")
661                       (match_operand:V4SI 3 "register_operand" "v")]
662                      UNSPEC_VMSUMUHS))
663    (set (reg:SI 110) (unspec:SI [(const_int 0)] UNSPEC_SET_VSCR))]
664   "TARGET_ALTIVEC"
665   "vmsumuhs %0,%1,%2,%3"
666   [(set_attr "type" "veccomplex")])
667
668 (define_insn "altivec_vmsumshs"
669   [(set (match_operand:V4SI 0 "register_operand" "=v")
670         (unspec:V4SI [(match_operand:V8HI 1 "register_operand" "v")
671                       (match_operand:V8HI 2 "register_operand" "v")
672                       (match_operand:V4SI 3 "register_operand" "v")]
673                      UNSPEC_VMSUMSHS))
674    (set (reg:SI 110) (unspec:SI [(const_int 0)] UNSPEC_SET_VSCR))]
675   "TARGET_ALTIVEC"
676   "vmsumshs %0,%1,%2,%3"
677   [(set_attr "type" "veccomplex")])
678
679 ;; max
680
681 (define_insn "umax<mode>3"
682   [(set (match_operand:VI 0 "register_operand" "=v")
683         (umax:VI (match_operand:VI 1 "register_operand" "v")
684                  (match_operand:VI 2 "register_operand" "v")))]
685   "TARGET_ALTIVEC"
686   "vmaxu<VI_char> %0,%1,%2"
687   [(set_attr "type" "vecsimple")])
688
689 (define_insn "smax<mode>3"
690   [(set (match_operand:VI 0 "register_operand" "=v")
691         (smax:VI (match_operand:VI 1 "register_operand" "v")
692                  (match_operand:VI 2 "register_operand" "v")))]
693   "TARGET_ALTIVEC"
694   "vmaxs<VI_char> %0,%1,%2"
695   [(set_attr "type" "vecsimple")])
696
697 (define_insn "smaxv4sf3"
698   [(set (match_operand:V4SF 0 "register_operand" "=v")
699         (smax:V4SF (match_operand:V4SF 1 "register_operand" "v")
700                    (match_operand:V4SF 2 "register_operand" "v")))]
701   "TARGET_ALTIVEC"
702   "vmaxfp %0,%1,%2"
703   [(set_attr "type" "veccmp")])
704
705 (define_insn "umin<mode>3"
706   [(set (match_operand:VI 0 "register_operand" "=v")
707         (umin:VI (match_operand:VI 1 "register_operand" "v")
708                  (match_operand:VI 2 "register_operand" "v")))]
709   "TARGET_ALTIVEC"
710   "vminu<VI_char> %0,%1,%2"
711   [(set_attr "type" "vecsimple")])
712
713 (define_insn "smin<mode>3"
714   [(set (match_operand:VI 0 "register_operand" "=v")
715         (smin:VI (match_operand:VI 1 "register_operand" "v")
716                  (match_operand:VI 2 "register_operand" "v")))]
717   "TARGET_ALTIVEC"
718   "vmins<VI_char> %0,%1,%2"
719   [(set_attr "type" "vecsimple")])
720
721 (define_insn "sminv4sf3"
722   [(set (match_operand:V4SF 0 "register_operand" "=v")
723         (smin:V4SF (match_operand:V4SF 1 "register_operand" "v")
724                    (match_operand:V4SF 2 "register_operand" "v")))]
725   "TARGET_ALTIVEC"
726   "vminfp %0,%1,%2"
727   [(set_attr "type" "veccmp")])
728
729 (define_insn "altivec_vmhaddshs"
730   [(set (match_operand:V8HI 0 "register_operand" "=v")
731         (unspec:V8HI [(match_operand:V8HI 1 "register_operand" "v")
732                       (match_operand:V8HI 2 "register_operand" "v")
733                       (match_operand:V8HI 3 "register_operand" "v")]
734                      UNSPEC_VMHADDSHS))
735    (set (reg:SI 110) (unspec:SI [(const_int 0)] UNSPEC_SET_VSCR))]
736   "TARGET_ALTIVEC"
737   "vmhaddshs %0,%1,%2,%3"
738   [(set_attr "type" "veccomplex")])
739
740 (define_insn "altivec_vmhraddshs"
741   [(set (match_operand:V8HI 0 "register_operand" "=v")
742         (unspec:V8HI [(match_operand:V8HI 1 "register_operand" "v")
743                       (match_operand:V8HI 2 "register_operand" "v")
744                       (match_operand:V8HI 3 "register_operand" "v")]
745                      UNSPEC_VMHRADDSHS))
746    (set (reg:SI 110) (unspec:SI [(const_int 0)] UNSPEC_SET_VSCR))]
747   "TARGET_ALTIVEC"
748   "vmhraddshs %0,%1,%2,%3"
749   [(set_attr "type" "veccomplex")])
750
751 (define_insn "altivec_vmladduhm"
752   [(set (match_operand:V8HI 0 "register_operand" "=v")
753         (unspec:V8HI [(match_operand:V8HI 1 "register_operand" "v")
754                       (match_operand:V8HI 2 "register_operand" "v")
755                       (match_operand:V8HI 3 "register_operand" "v")]
756                      UNSPEC_VMLADDUHM))]
757   "TARGET_ALTIVEC"
758   "vmladduhm %0,%1,%2,%3"
759   [(set_attr "type" "veccomplex")])
760
761 (define_insn "altivec_vmrghb"
762   [(set (match_operand:V16QI 0 "register_operand" "=v")
763         (vec_merge:V16QI (vec_select:V16QI (match_operand:V16QI 1 "register_operand" "v")
764                                            (parallel [(const_int 0)
765                                                       (const_int 8)
766                                                       (const_int 1)
767                                                       (const_int 9)
768                                                       (const_int 2)
769                                                       (const_int 10)
770                                                       (const_int 3)
771                                                       (const_int 11)
772                                                       (const_int 4)
773                                                       (const_int 12)
774                                                       (const_int 5)
775                                                       (const_int 13)
776                                                       (const_int 6)
777                                                       (const_int 14)
778                                                       (const_int 7)
779                                                       (const_int 15)]))
780                         (vec_select:V16QI (match_operand:V16QI 2 "register_operand" "v")
781                                            (parallel [(const_int 8)
782                                                       (const_int 0)
783                                                       (const_int 9)
784                                                       (const_int 1)
785                                                       (const_int 10)
786                                                       (const_int 2)
787                                                       (const_int 11)
788                                                       (const_int 3)
789                                                       (const_int 12)
790                                                       (const_int 4)
791                                                       (const_int 13)
792                                                       (const_int 5)
793                                                       (const_int 14)
794                                                       (const_int 6)
795                                                       (const_int 15)
796                                                       (const_int 7)]))
797                       (const_int 21845)))]
798   "TARGET_ALTIVEC"
799   "vmrghb %0,%1,%2"
800   [(set_attr "type" "vecperm")])
801
802 (define_insn "altivec_vmrghh"
803   [(set (match_operand:V8HI 0 "register_operand" "=v")
804         (vec_merge:V8HI (vec_select:V8HI (match_operand:V8HI 1 "register_operand" "v")
805                                            (parallel [(const_int 0)
806                                                       (const_int 4)
807                                                       (const_int 1)
808                                                       (const_int 5)
809                                                       (const_int 2)
810                                                       (const_int 6)
811                                                       (const_int 3)
812                                                       (const_int 7)]))
813                         (vec_select:V8HI (match_operand:V8HI 2 "register_operand" "v")
814                                            (parallel [(const_int 4)
815                                                       (const_int 0)
816                                                       (const_int 5)
817                                                       (const_int 1)
818                                                       (const_int 6)
819                                                       (const_int 2)
820                                                       (const_int 7)
821                                                       (const_int 3)]))
822                       (const_int 85)))]
823   "TARGET_ALTIVEC"
824   "vmrghh %0,%1,%2"
825   [(set_attr "type" "vecperm")])
826
827 (define_insn "altivec_vmrghw"
828   [(set (match_operand:V4SI 0 "register_operand" "=v")
829         (vec_merge:V4SI (vec_select:V4SI (match_operand:V4SI 1 "register_operand" "v")
830                                          (parallel [(const_int 0)
831                                                     (const_int 2)
832                                                     (const_int 1)
833                                                     (const_int 3)]))
834                         (vec_select:V4SI (match_operand:V4SI 2 "register_operand" "v")
835                                          (parallel [(const_int 2)
836                                                     (const_int 0)
837                                                     (const_int 3)
838                                                     (const_int 1)]))
839                       (const_int 5)))]
840   "TARGET_ALTIVEC"
841   "vmrghw %0,%1,%2"
842   [(set_attr "type" "vecperm")])
843
844 (define_insn "altivec_vmrglb"
845   [(set (match_operand:V16QI 0 "register_operand" "=v")
846         (vec_merge:V16QI (vec_select:V16QI (match_operand:V16QI 1 "register_operand" "v")
847                                            (parallel [(const_int 8)
848                                                       (const_int 0)
849                                                       (const_int 9)
850                                                       (const_int 1)
851                                                       (const_int 10)
852                                                       (const_int 2)
853                                                       (const_int 11)
854                                                       (const_int 3)
855                                                       (const_int 12)
856                                                       (const_int 4)
857                                                       (const_int 13)
858                                                       (const_int 5)
859                                                       (const_int 14)
860                                                       (const_int 6)
861                                                       (const_int 15)
862                                                       (const_int 7)]))
863                       (vec_select:V16QI (match_operand:V16QI 2 "register_operand" "v")
864                                            (parallel [(const_int 0)
865                                                       (const_int 8)
866                                                       (const_int 1)
867                                                       (const_int 9)
868                                                       (const_int 2)
869                                                       (const_int 10)
870                                                       (const_int 3)
871                                                       (const_int 11)
872                                                       (const_int 4)
873                                                       (const_int 12)
874                                                       (const_int 5)
875                                                       (const_int 13)
876                                                       (const_int 6)
877                                                       (const_int 14)
878                                                       (const_int 7)
879                                                       (const_int 15)]))
880                       (const_int 21845)))]
881   "TARGET_ALTIVEC"
882   "vmrglb %0,%1,%2"
883   [(set_attr "type" "vecperm")])
884
885 (define_insn "altivec_vmrglh"
886   [(set (match_operand:V8HI 0 "register_operand" "=v")
887         (vec_merge:V8HI (vec_select:V8HI (match_operand:V8HI 1 "register_operand" "v")
888                                            (parallel [(const_int 4)
889                                                       (const_int 0)
890                                                       (const_int 5)
891                                                       (const_int 1)
892                                                       (const_int 6)
893                                                       (const_int 2)
894                                                       (const_int 7)
895                                                       (const_int 3)]))
896                         (vec_select:V8HI (match_operand:V8HI 2 "register_operand" "v")
897                                            (parallel [(const_int 0)
898                                                       (const_int 4)
899                                                       (const_int 1)
900                                                       (const_int 5)
901                                                       (const_int 2)
902                                                       (const_int 6)
903                                                       (const_int 3)
904                                                       (const_int 7)]))
905                       (const_int 85)))]
906   "TARGET_ALTIVEC"
907   "vmrglh %0,%1,%2"
908   [(set_attr "type" "vecperm")])
909
910 (define_insn "altivec_vmrglw"
911   [(set (match_operand:V4SI 0 "register_operand" "=v")
912         (vec_merge:V4SI (vec_select:V4SI (match_operand:V4SI 1 "register_operand" "v")
913                                          (parallel [(const_int 2)
914                                                     (const_int 0)
915                                                     (const_int 3)
916                                                     (const_int 1)]))
917                         (vec_select:V4SI (match_operand:V4SI 2 "register_operand" "v")
918                                          (parallel [(const_int 0)
919                                                     (const_int 2)
920                                                     (const_int 1)
921                                                     (const_int 3)]))
922                       (const_int 5)))]
923   "TARGET_ALTIVEC"
924   "vmrglw %0,%1,%2"
925   [(set_attr "type" "vecperm")])
926
927 (define_insn "altivec_vmuleub"
928   [(set (match_operand:V8HI 0 "register_operand" "=v")
929         (unspec:V8HI [(match_operand:V16QI 1 "register_operand" "v")
930                       (match_operand:V16QI 2 "register_operand" "v")]
931                      UNSPEC_VMULEUB))]
932   "TARGET_ALTIVEC"
933   "vmuleub %0,%1,%2"
934   [(set_attr "type" "veccomplex")])
935
936 (define_insn "altivec_vmulesb"
937   [(set (match_operand:V8HI 0 "register_operand" "=v")
938         (unspec:V8HI [(match_operand:V16QI 1 "register_operand" "v")
939                       (match_operand:V16QI 2 "register_operand" "v")]
940                      UNSPEC_VMULESB))]
941   "TARGET_ALTIVEC"
942   "vmulesb %0,%1,%2"
943   [(set_attr "type" "veccomplex")])
944
945 (define_insn "altivec_vmuleuh"
946   [(set (match_operand:V4SI 0 "register_operand" "=v")
947         (unspec:V4SI [(match_operand:V8HI 1 "register_operand" "v")
948                       (match_operand:V8HI 2 "register_operand" "v")]
949                      UNSPEC_VMULEUH))]
950   "TARGET_ALTIVEC"
951   "vmuleuh %0,%1,%2"
952   [(set_attr "type" "veccomplex")])
953
954 (define_insn "altivec_vmulesh"
955   [(set (match_operand:V4SI 0 "register_operand" "=v")
956         (unspec:V4SI [(match_operand:V8HI 1 "register_operand" "v")
957                       (match_operand:V8HI 2 "register_operand" "v")]
958                      UNSPEC_VMULESH))]
959   "TARGET_ALTIVEC"
960   "vmulesh %0,%1,%2"
961   [(set_attr "type" "veccomplex")])
962
963 (define_insn "altivec_vmuloub"
964   [(set (match_operand:V8HI 0 "register_operand" "=v")
965         (unspec:V8HI [(match_operand:V16QI 1 "register_operand" "v")
966                       (match_operand:V16QI 2 "register_operand" "v")]
967                      UNSPEC_VMULOUB))]
968   "TARGET_ALTIVEC"
969   "vmuloub %0,%1,%2"
970   [(set_attr "type" "veccomplex")])
971
972 (define_insn "altivec_vmulosb"
973   [(set (match_operand:V8HI 0 "register_operand" "=v")
974         (unspec:V8HI [(match_operand:V16QI 1 "register_operand" "v")
975                       (match_operand:V16QI 2 "register_operand" "v")]
976                      UNSPEC_VMULOSB))]
977   "TARGET_ALTIVEC"
978   "vmulosb %0,%1,%2"
979   [(set_attr "type" "veccomplex")])
980
981 (define_insn "altivec_vmulouh"
982   [(set (match_operand:V4SI 0 "register_operand" "=v")
983         (unspec:V4SI [(match_operand:V8HI 1 "register_operand" "v")
984                       (match_operand:V8HI 2 "register_operand" "v")]
985                      UNSPEC_VMULOUH))]
986   "TARGET_ALTIVEC"
987   "vmulouh %0,%1,%2"
988   [(set_attr "type" "veccomplex")])
989
990 (define_insn "altivec_vmulosh"
991   [(set (match_operand:V4SI 0 "register_operand" "=v")
992         (unspec:V4SI [(match_operand:V8HI 1 "register_operand" "v")
993                       (match_operand:V8HI 2 "register_operand" "v")]
994                      UNSPEC_VMULOSH))]
995   "TARGET_ALTIVEC"
996   "vmulosh %0,%1,%2"
997   [(set_attr "type" "veccomplex")])
998
999
1000 ;; logical ops
1001
1002 (define_insn "and<mode>3"
1003   [(set (match_operand:VI 0 "register_operand" "=v")
1004         (and:VI (match_operand:VI 1 "register_operand" "v")
1005                 (match_operand:VI 2 "register_operand" "v")))]
1006   "TARGET_ALTIVEC"
1007   "vand %0,%1,%2"
1008   [(set_attr "type" "vecsimple")])
1009
1010 (define_insn "ior<mode>3"
1011   [(set (match_operand:VI 0 "register_operand" "=v")
1012         (ior:VI (match_operand:VI 1 "register_operand" "v")
1013                 (match_operand:VI 2 "register_operand" "v")))]
1014   "TARGET_ALTIVEC"
1015   "vor %0,%1,%2"
1016   [(set_attr "type" "vecsimple")])
1017
1018 (define_insn "xor<mode>3"
1019   [(set (match_operand:VI 0 "register_operand" "=v")
1020         (xor:VI (match_operand:VI 1 "register_operand" "v")
1021                 (match_operand:VI 2 "register_operand" "v")))]
1022   "TARGET_ALTIVEC"
1023   "vxor %0,%1,%2"
1024   [(set_attr "type" "vecsimple")])
1025
1026 (define_insn "xorv4sf3"
1027   [(set (match_operand:V4SF 0 "register_operand" "=v")
1028         (xor:V4SF (match_operand:V4SF 1 "register_operand" "v")
1029                   (match_operand:V4SF 2 "register_operand" "v")))]
1030   "TARGET_ALTIVEC"
1031   "vxor %0,%1,%2" 
1032   [(set_attr "type" "vecsimple")])
1033
1034 (define_insn "one_cmpl<mode>2"
1035   [(set (match_operand:VI 0 "register_operand" "=v")
1036         (not:VI (match_operand:VI 1 "register_operand" "v")))]
1037   "TARGET_ALTIVEC"
1038   "vnor %0,%1,%1"
1039   [(set_attr "type" "vecsimple")])
1040   
1041 (define_insn "altivec_nor<mode>3"
1042   [(set (match_operand:VI 0 "register_operand" "=v")
1043         (not:VI (ior:VI (match_operand:VI 1 "register_operand" "v")
1044                         (match_operand:VI 2 "register_operand" "v"))))]
1045   "TARGET_ALTIVEC"
1046   "vnor %0,%1,%2"
1047   [(set_attr "type" "vecsimple")])
1048
1049 (define_insn "andc<mode>3"
1050   [(set (match_operand:VI 0 "register_operand" "=v")
1051         (and:VI (not:VI (match_operand:VI 2 "register_operand" "v"))
1052                 (match_operand:VI 1 "register_operand" "v")))]
1053   "TARGET_ALTIVEC"
1054   "vandc %0,%1,%2"
1055   [(set_attr "type" "vecsimple")])
1056
1057 (define_insn "*andc3_v4sf"
1058   [(set (match_operand:V4SF 0 "register_operand" "=v")
1059         (and:V4SF (not:V4SF (match_operand:V4SF 2 "register_operand" "v"))
1060                   (match_operand:V4SF 1 "register_operand" "v")))]
1061   "TARGET_ALTIVEC"
1062   "vandc %0,%1,%2"
1063   [(set_attr "type" "vecsimple")])
1064
1065 (define_insn "altivec_vpkuhum"
1066   [(set (match_operand:V16QI 0 "register_operand" "=v")
1067         (unspec:V16QI [(match_operand:V8HI 1 "register_operand" "v")
1068                        (match_operand:V8HI 2 "register_operand" "v")]
1069                       UNSPEC_VPKUHUM))]
1070   "TARGET_ALTIVEC"
1071   "vpkuhum %0,%1,%2"
1072   [(set_attr "type" "vecperm")])
1073
1074 (define_insn "altivec_vpkuwum"
1075   [(set (match_operand:V8HI 0 "register_operand" "=v")
1076         (unspec:V8HI [(match_operand:V4SI 1 "register_operand" "v")
1077                       (match_operand:V4SI 2 "register_operand" "v")]
1078                      UNSPEC_VPKUWUM))]
1079   "TARGET_ALTIVEC"
1080   "vpkuwum %0,%1,%2"
1081   [(set_attr "type" "vecperm")])
1082
1083 (define_insn "altivec_vpkpx"
1084   [(set (match_operand:V8HI 0 "register_operand" "=v")
1085         (unspec:V8HI [(match_operand:V4SI 1 "register_operand" "v")
1086                       (match_operand:V4SI 2 "register_operand" "v")]
1087                      UNSPEC_VPKPX))]
1088   "TARGET_ALTIVEC"
1089   "vpkpx %0,%1,%2"
1090   [(set_attr "type" "vecperm")])
1091
1092 (define_insn "altivec_vpkshss"
1093   [(set (match_operand:V16QI 0 "register_operand" "=v")
1094         (unspec:V16QI [(match_operand:V8HI 1 "register_operand" "v")
1095                        (match_operand:V8HI 2 "register_operand" "v")]
1096                       UNSPEC_VPKSHSS))
1097    (set (reg:SI 110) (unspec:SI [(const_int 0)] UNSPEC_SET_VSCR))]
1098   "TARGET_ALTIVEC"
1099   "vpkshss %0,%1,%2"
1100   [(set_attr "type" "vecperm")])
1101
1102 (define_insn "altivec_vpkswss"
1103   [(set (match_operand:V8HI 0 "register_operand" "=v")
1104         (unspec:V8HI [(match_operand:V4SI 1 "register_operand" "v")
1105                       (match_operand:V4SI 2 "register_operand" "v")]
1106                      UNSPEC_VPKSWSS))
1107    (set (reg:SI 110) (unspec:SI [(const_int 0)] UNSPEC_SET_VSCR))]
1108   "TARGET_ALTIVEC"
1109   "vpkswss %0,%1,%2"
1110   [(set_attr "type" "vecperm")])
1111
1112 (define_insn "altivec_vpkuhus"
1113   [(set (match_operand:V16QI 0 "register_operand" "=v")
1114         (unspec:V16QI [(match_operand:V8HI 1 "register_operand" "v")
1115                        (match_operand:V8HI 2 "register_operand" "v")]
1116                       UNSPEC_VPKUHUS))
1117    (set (reg:SI 110) (unspec:SI [(const_int 0)] UNSPEC_SET_VSCR))]
1118   "TARGET_ALTIVEC"
1119   "vpkuhus %0,%1,%2"
1120   [(set_attr "type" "vecperm")])
1121
1122 (define_insn "altivec_vpkshus"
1123   [(set (match_operand:V16QI 0 "register_operand" "=v")
1124         (unspec:V16QI [(match_operand:V8HI 1 "register_operand" "v")
1125                        (match_operand:V8HI 2 "register_operand" "v")]
1126                       UNSPEC_VPKSHUS))
1127    (set (reg:SI 110) (unspec:SI [(const_int 0)] UNSPEC_SET_VSCR))]
1128   "TARGET_ALTIVEC"
1129   "vpkshus %0,%1,%2"
1130   [(set_attr "type" "vecperm")])
1131
1132 (define_insn "altivec_vpkuwus"
1133   [(set (match_operand:V8HI 0 "register_operand" "=v")
1134         (unspec:V8HI [(match_operand:V4SI 1 "register_operand" "v")
1135                       (match_operand:V4SI 2 "register_operand" "v")]
1136                      UNSPEC_VPKUWUS))
1137    (set (reg:SI 110) (unspec:SI [(const_int 0)] UNSPEC_SET_VSCR))]
1138   "TARGET_ALTIVEC"
1139   "vpkuwus %0,%1,%2"
1140   [(set_attr "type" "vecperm")])
1141
1142 (define_insn "altivec_vpkswus"
1143   [(set (match_operand:V8HI 0 "register_operand" "=v")
1144         (unspec:V8HI [(match_operand:V4SI 1 "register_operand" "v")
1145                       (match_operand:V4SI 2 "register_operand" "v")]
1146                      UNSPEC_VPKSWUS))
1147    (set (reg:SI 110) (unspec:SI [(const_int 0)] UNSPEC_SET_VSCR))]
1148   "TARGET_ALTIVEC"
1149   "vpkswus %0,%1,%2"
1150   [(set_attr "type" "vecperm")])
1151
1152 (define_insn "altivec_vrl<VI_char>"
1153   [(set (match_operand:VI 0 "register_operand" "=v")
1154         (unspec:VI [(match_operand:VI 1 "register_operand" "v")
1155                     (match_operand:VI 2 "register_operand" "v")]
1156                    UNSPEC_VRL))]
1157   "TARGET_ALTIVEC"
1158   "vrl<VI_char> %0,%1,%2"
1159   [(set_attr "type" "vecsimple")])
1160
1161 (define_insn "altivec_vsl<VI_char>"
1162   [(set (match_operand:VI 0 "register_operand" "=v")
1163         (unspec:VI [(match_operand:VI 1 "register_operand" "v")
1164                     (match_operand:VI 2 "register_operand" "v")]
1165                    UNSPEC_VSL))]
1166   "TARGET_ALTIVEC"
1167   "vsl<VI_char> %0,%1,%2"
1168   [(set_attr "type" "vecsimple")])
1169
1170 (define_insn "altivec_vsl"
1171   [(set (match_operand:V4SI 0 "register_operand" "=v")
1172         (unspec:V4SI [(match_operand:V4SI 1 "register_operand" "v")
1173                       (match_operand:V4SI 2 "register_operand" "v")]
1174                      UNSPEC_VSLV4SI))]
1175   "TARGET_ALTIVEC"
1176   "vsl %0,%1,%2"
1177   [(set_attr "type" "vecperm")])
1178
1179 (define_insn "altivec_vslo"
1180   [(set (match_operand:V4SI 0 "register_operand" "=v")
1181         (unspec:V4SI [(match_operand:V4SI 1 "register_operand" "v")
1182                       (match_operand:V4SI 2 "register_operand" "v")]
1183                      UNSPEC_VSLO))]
1184   "TARGET_ALTIVEC"
1185   "vslo %0,%1,%2"
1186   [(set_attr "type" "vecperm")])
1187
1188 (define_insn "lshr<mode>3"
1189   [(set (match_operand:VI 0 "register_operand" "=v")
1190         (lshiftrt:VI (match_operand:VI 1 "register_operand" "v")
1191                     (match_operand:VI 2 "register_operand" "v") ))]
1192   "TARGET_ALTIVEC"
1193   "vsr<VI_char> %0,%1,%2"
1194   [(set_attr "type" "vecsimple")])
1195
1196 (define_insn "ashr<mode>3"
1197   [(set (match_operand:VI 0 "register_operand" "=v")
1198         (ashiftrt:VI (match_operand:VI 1 "register_operand" "v")
1199                     (match_operand:VI 2 "register_operand" "v") ))]
1200   "TARGET_ALTIVEC"
1201   "vsra<VI_char> %0,%1,%2"
1202   [(set_attr "type" "vecsimple")])
1203
1204 (define_insn "altivec_vsr"
1205   [(set (match_operand:V4SI 0 "register_operand" "=v")
1206         (unspec:V4SI [(match_operand:V4SI 1 "register_operand" "v")
1207                       (match_operand:V4SI 2 "register_operand" "v")]
1208                      UNSPEC_VSR))]
1209   "TARGET_ALTIVEC"
1210   "vsr %0,%1,%2"
1211   [(set_attr "type" "vecperm")])
1212
1213 (define_insn "altivec_vsro"
1214   [(set (match_operand:V4SI 0 "register_operand" "=v")
1215         (unspec:V4SI [(match_operand:V4SI 1 "register_operand" "v")
1216                       (match_operand:V4SI 2 "register_operand" "v")]
1217                      UNSPEC_VSRO))]
1218   "TARGET_ALTIVEC"
1219   "vsro %0,%1,%2"
1220   [(set_attr "type" "vecperm")])
1221
1222 (define_insn "altivec_vsum4ubs"
1223   [(set (match_operand:V4SI 0 "register_operand" "=v")
1224         (unspec:V4SI [(match_operand:V16QI 1 "register_operand" "v")
1225                       (match_operand:V4SI 2 "register_operand" "v")]
1226                      UNSPEC_VSUM4UBS))
1227    (set (reg:SI 110) (unspec:SI [(const_int 0)] UNSPEC_SET_VSCR))]
1228   "TARGET_ALTIVEC"
1229   "vsum4ubs %0,%1,%2"
1230   [(set_attr "type" "veccomplex")])
1231
1232 (define_insn "altivec_vsum4s<VI_char>s"
1233   [(set (match_operand:V4SI 0 "register_operand" "=v")
1234         (unspec:V4SI [(match_operand:VIshort 1 "register_operand" "v")
1235                       (match_operand:V4SI 2 "register_operand" "v")]
1236                      UNSPEC_VSUM4S))
1237    (set (reg:SI 110) (unspec:SI [(const_int 0)] UNSPEC_SET_VSCR))]
1238   "TARGET_ALTIVEC"
1239   "vsum4s<VI_char>s %0,%1,%2"
1240   [(set_attr "type" "veccomplex")])
1241
1242 (define_insn "altivec_vsum2sws"
1243   [(set (match_operand:V4SI 0 "register_operand" "=v")
1244         (unspec:V4SI [(match_operand:V4SI 1 "register_operand" "v")
1245                       (match_operand:V4SI 2 "register_operand" "v")]
1246                      UNSPEC_VSUM2SWS))
1247    (set (reg:SI 110) (unspec:SI [(const_int 0)] UNSPEC_SET_VSCR))]
1248   "TARGET_ALTIVEC"
1249   "vsum2sws %0,%1,%2"
1250   [(set_attr "type" "veccomplex")])
1251
1252 (define_insn "altivec_vsumsws"
1253   [(set (match_operand:V4SI 0 "register_operand" "=v")
1254         (unspec:V4SI [(match_operand:V4SI 1 "register_operand" "v")
1255                       (match_operand:V4SI 2 "register_operand" "v")]
1256                      UNSPEC_VSUMSWS))
1257    (set (reg:SI 110) (unspec:SI [(const_int 0)] UNSPEC_SET_VSCR))]
1258   "TARGET_ALTIVEC"
1259   "vsumsws %0,%1,%2"
1260   [(set_attr "type" "veccomplex")])
1261
1262 (define_insn "altivec_vspltb"
1263   [(set (match_operand:V16QI 0 "register_operand" "=v")
1264         (vec_duplicate:V16QI
1265          (vec_select:QI (match_operand:V16QI 1 "register_operand" "v")
1266                         (parallel
1267                          [(match_operand:QI 2 "u5bit_cint_operand" "")]))))]
1268   "TARGET_ALTIVEC"
1269   "vspltb %0,%1,%2"
1270   [(set_attr "type" "vecperm")])
1271
1272 (define_insn "altivec_vsplth"
1273   [(set (match_operand:V8HI 0 "register_operand" "=v")
1274         (vec_duplicate:V8HI
1275          (vec_select:HI (match_operand:V8HI 1 "register_operand" "v")
1276                         (parallel
1277                          [(match_operand:QI 2 "u5bit_cint_operand" "")]))))]
1278   "TARGET_ALTIVEC"
1279   "vsplth %0,%1,%2"
1280   [(set_attr "type" "vecperm")])
1281
1282 (define_insn "altivec_vspltw"
1283   [(set (match_operand:V4SI 0 "register_operand" "=v")
1284         (vec_duplicate:V4SI
1285          (vec_select:SI (match_operand:V4SI 1 "register_operand" "v")
1286                         (parallel
1287                          [(match_operand:QI 2 "u5bit_cint_operand" "i")]))))]
1288   "TARGET_ALTIVEC"
1289   "vspltw %0,%1,%2"
1290   [(set_attr "type" "vecperm")])
1291
1292 (define_insn "*altivec_vspltsf"
1293   [(set (match_operand:V4SF 0 "register_operand" "=v")
1294         (vec_duplicate:V4SF
1295          (vec_select:SF (match_operand:V4SF 1 "register_operand" "v")
1296                         (parallel
1297                          [(match_operand:QI 2 "u5bit_cint_operand" "i")]))))]
1298   "TARGET_ALTIVEC"
1299   "vspltw %0,%1,%2"
1300   [(set_attr "type" "vecperm")])
1301
1302 (define_insn "altivec_vspltis<VI_char>"
1303   [(set (match_operand:VI 0 "register_operand" "=v")
1304         (vec_duplicate:VI
1305          (match_operand:QI 1 "s5bit_cint_operand" "i")))]
1306   "TARGET_ALTIVEC"
1307   "vspltis<VI_char> %0,%1"
1308   [(set_attr "type" "vecperm")])
1309
1310 (define_insn "ftruncv4sf2"
1311   [(set (match_operand:V4SF 0 "register_operand" "=v")
1312         (fix:V4SF (match_operand:V4SF 1 "register_operand" "v")))]
1313   "TARGET_ALTIVEC"
1314   "vrfiz %0,%1"
1315   [(set_attr "type" "vecfloat")])
1316
1317 (define_insn "altivec_vperm_<mode>"
1318   [(set (match_operand:V 0 "register_operand" "=v")
1319         (unspec:V [(match_operand:V 1 "register_operand" "v")
1320                    (match_operand:V 2 "register_operand" "v")
1321                    (match_operand:V16QI 3 "register_operand" "v")]
1322                   UNSPEC_VPERM))]
1323   "TARGET_ALTIVEC"
1324   "vperm %0,%1,%2,%3"
1325   [(set_attr "type" "vecperm")])
1326
1327 (define_insn "altivec_vrfip"
1328   [(set (match_operand:V4SF 0 "register_operand" "=v")
1329         (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "v")]
1330                      UNSPEC_VRFIP))]
1331   "TARGET_ALTIVEC"
1332   "vrfip %0,%1"
1333   [(set_attr "type" "vecfloat")])
1334
1335 (define_insn "altivec_vrfin"
1336   [(set (match_operand:V4SF 0 "register_operand" "=v")
1337         (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "v")]
1338                      UNSPEC_VRFIN))]
1339   "TARGET_ALTIVEC"
1340   "vrfin %0,%1"
1341   [(set_attr "type" "vecfloat")])
1342
1343 (define_insn "altivec_vrfim"
1344   [(set (match_operand:V4SF 0 "register_operand" "=v")
1345         (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "v")]
1346                      UNSPEC_VRFIM))]
1347   "TARGET_ALTIVEC"
1348   "vrfim %0,%1"
1349   [(set_attr "type" "vecfloat")])
1350
1351 (define_insn "altivec_vcfux"
1352   [(set (match_operand:V4SF 0 "register_operand" "=v")
1353         (unspec:V4SF [(match_operand:V4SI 1 "register_operand" "v")
1354                       (match_operand:QI 2 "immediate_operand" "i")]
1355                      UNSPEC_VCFUX))]
1356   "TARGET_ALTIVEC"
1357   "vcfux %0,%1,%2"
1358   [(set_attr "type" "vecfloat")])
1359
1360 (define_insn "altivec_vcfsx"
1361   [(set (match_operand:V4SF 0 "register_operand" "=v")
1362         (unspec:V4SF [(match_operand:V4SI 1 "register_operand" "v")
1363                       (match_operand:QI 2 "immediate_operand" "i")]
1364                      UNSPEC_VCFSX))]
1365   "TARGET_ALTIVEC"
1366   "vcfsx %0,%1,%2"
1367   [(set_attr "type" "vecfloat")])
1368
1369 (define_insn "altivec_vctuxs"
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_VCTUXS))
1374    (set (reg:SI 110) (unspec:SI [(const_int 0)] UNSPEC_SET_VSCR))]
1375   "TARGET_ALTIVEC"
1376   "vctuxs %0,%1,%2"
1377   [(set_attr "type" "vecfloat")])
1378
1379 (define_insn "altivec_vctsxs"
1380   [(set (match_operand:V4SI 0 "register_operand" "=v")
1381         (unspec:V4SI [(match_operand:V4SF 1 "register_operand" "v")
1382                       (match_operand:QI 2 "immediate_operand" "i")]
1383                      UNSPEC_VCTSXS))
1384    (set (reg:SI 110) (unspec:SI [(const_int 0)] UNSPEC_SET_VSCR))]
1385   "TARGET_ALTIVEC"
1386   "vctsxs %0,%1,%2"
1387   [(set_attr "type" "vecfloat")])
1388
1389 (define_insn "altivec_vlogefp"
1390   [(set (match_operand:V4SF 0 "register_operand" "=v")
1391         (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "v")]
1392                      UNSPEC_VLOGEFP))]
1393   "TARGET_ALTIVEC"
1394   "vlogefp %0,%1"
1395   [(set_attr "type" "vecfloat")])
1396
1397 (define_insn "altivec_vexptefp"
1398   [(set (match_operand:V4SF 0 "register_operand" "=v")
1399         (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "v")]
1400                      UNSPEC_VEXPTEFP))]
1401   "TARGET_ALTIVEC"
1402   "vexptefp %0,%1"
1403   [(set_attr "type" "vecfloat")])
1404
1405 (define_insn "altivec_vrsqrtefp"
1406   [(set (match_operand:V4SF 0 "register_operand" "=v")
1407         (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "v")]
1408                      UNSPEC_VRSQRTEFP))]
1409   "TARGET_ALTIVEC"
1410   "vrsqrtefp %0,%1"
1411   [(set_attr "type" "vecfloat")])
1412
1413 (define_insn "altivec_vrefp"
1414   [(set (match_operand:V4SF 0 "register_operand" "=v")
1415         (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "v")]
1416                      UNSPEC_VREFP))]
1417   "TARGET_ALTIVEC"
1418   "vrefp %0,%1"
1419   [(set_attr "type" "vecfloat")])
1420
1421 (define_expand "vcondv4si"
1422         [(set (match_operand:V4SI 0 "register_operand" "=v")
1423               (unspec:V4SI [(match_operand:V4SI 1 "register_operand" "v")
1424                (match_operand:V4SI 2 "register_operand" "v")
1425                (match_operand:V4SI 3 "comparison_operator" "")
1426                (match_operand:V4SI 4 "register_operand" "v")
1427                (match_operand:V4SI 5 "register_operand" "v")
1428                ] UNSPEC_VCOND_V4SI))]
1429         "TARGET_ALTIVEC"
1430         "
1431 {
1432         if (rs6000_emit_vector_cond_expr (operands[0], operands[1], operands[2],
1433                                           operands[3], operands[4], operands[5]))
1434         DONE;
1435         else
1436         FAIL;
1437 }
1438         ")
1439
1440 (define_expand "vconduv4si"
1441         [(set (match_operand:V4SI 0 "register_operand" "=v")
1442               (unspec:V4SI [(match_operand:V4SI 1 "register_operand" "v")
1443                (match_operand:V4SI 2 "register_operand" "v")
1444                (match_operand:V4SI 3 "comparison_operator" "")
1445                (match_operand:V4SI 4 "register_operand" "v")
1446                (match_operand:V4SI 5 "register_operand" "v")
1447                ] UNSPEC_VCONDU_V4SI))]
1448         "TARGET_ALTIVEC"
1449         "
1450 {
1451         if (rs6000_emit_vector_cond_expr (operands[0], operands[1], operands[2],
1452                                           operands[3], operands[4], operands[5]))
1453         DONE;
1454         else
1455         FAIL;
1456 }
1457         ")
1458
1459 (define_expand "vcondv4sf"
1460         [(set (match_operand:V4SF 0 "register_operand" "=v")
1461               (unspec:V4SF [(match_operand:V4SI 1 "register_operand" "v")
1462                (match_operand:V4SF 2 "register_operand" "v")
1463                (match_operand:V4SF 3 "comparison_operator" "")
1464                (match_operand:V4SF 4 "register_operand" "v")
1465                (match_operand:V4SF 5 "register_operand" "v")
1466                ] UNSPEC_VCOND_V4SF))]
1467         "TARGET_ALTIVEC"
1468         "
1469 {
1470         if (rs6000_emit_vector_cond_expr (operands[0], operands[1], operands[2],
1471                                           operands[3], operands[4], operands[5]))
1472         DONE;
1473         else
1474         FAIL;
1475 }
1476         ")
1477
1478 (define_expand "vcondv8hi"
1479         [(set (match_operand:V4SF 0 "register_operand" "=v")
1480               (unspec:V8HI [(match_operand:V4SI 1 "register_operand" "v")
1481                (match_operand:V8HI 2 "register_operand" "v")
1482                (match_operand:V8HI 3 "comparison_operator" "")
1483                (match_operand:V8HI 4 "register_operand" "v")
1484                (match_operand:V8HI 5 "register_operand" "v")
1485                ] UNSPEC_VCOND_V8HI))]
1486         "TARGET_ALTIVEC"
1487         "
1488 {
1489         if (rs6000_emit_vector_cond_expr (operands[0], operands[1], operands[2],
1490                                           operands[3], operands[4], operands[5]))
1491         DONE;
1492         else
1493         FAIL;
1494 }
1495         ")
1496
1497 (define_expand "vconduv8hi"
1498         [(set (match_operand:V4SF 0 "register_operand" "=v")
1499               (unspec:V8HI [(match_operand:V4SI 1 "register_operand" "v")
1500                (match_operand:V8HI 2 "register_operand" "v")
1501                (match_operand:V8HI 3 "comparison_operator" "")
1502                (match_operand:V8HI 4 "register_operand" "v")
1503                (match_operand:V8HI 5 "register_operand" "v")
1504                ] UNSPEC_VCONDU_V8HI))]
1505         "TARGET_ALTIVEC"
1506         "
1507 {
1508         if (rs6000_emit_vector_cond_expr (operands[0], operands[1], operands[2],
1509                                           operands[3], operands[4], operands[5]))
1510         DONE;
1511         else
1512         FAIL;
1513 }
1514         ")
1515
1516 (define_expand "vcondv16qi"
1517         [(set (match_operand:V4SF 0 "register_operand" "=v")
1518               (unspec:V16QI [(match_operand:V4SI 1 "register_operand" "v")
1519                (match_operand:V16QI 2 "register_operand" "v")
1520                (match_operand:V16QI 3 "comparison_operator" "")
1521                (match_operand:V16QI 4 "register_operand" "v")
1522                (match_operand:V16QI 5 "register_operand" "v")
1523                ] UNSPEC_VCOND_V16QI))]
1524         "TARGET_ALTIVEC"
1525         "
1526 {
1527         if (rs6000_emit_vector_cond_expr (operands[0], operands[1], operands[2],
1528                                           operands[3], operands[4], operands[5]))
1529         DONE;
1530         else
1531         FAIL;
1532 }
1533         ")
1534
1535 (define_expand "vconduv16qi"
1536         [(set (match_operand:V4SF 0 "register_operand" "=v")
1537               (unspec:V16QI [(match_operand:V4SI 1 "register_operand" "v")
1538                (match_operand:V16QI 2 "register_operand" "v")
1539                (match_operand:V16QI 3 "comparison_operator" "")
1540                (match_operand:V16QI 4 "register_operand" "v")
1541                (match_operand:V16QI 5 "register_operand" "v")
1542                ] UNSPEC_VCONDU_V16QI))]
1543         "TARGET_ALTIVEC"
1544         "
1545 {
1546         if (rs6000_emit_vector_cond_expr (operands[0], operands[1], operands[2],
1547                                           operands[3], operands[4], operands[5]))
1548         DONE;
1549         else
1550         FAIL;
1551 }
1552         ")
1553
1554
1555 (define_insn "altivec_vsel_v4si"
1556   [(set (match_operand:V4SI 0 "register_operand" "=v")
1557         (unspec:V4SI [(match_operand:V4SI 1 "register_operand" "v")
1558                       (match_operand:V4SI 2 "register_operand" "v")
1559                       (match_operand:V4SI 3 "register_operand" "v")] 
1560                      UNSPEC_VSEL4SI))]
1561   "TARGET_ALTIVEC"
1562   "vsel %0,%1,%2,%3"
1563   [(set_attr "type" "vecperm")])
1564
1565 (define_insn "altivec_vsel_v4sf"
1566   [(set (match_operand:V4SF 0 "register_operand" "=v")
1567         (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "v")
1568                       (match_operand:V4SF 2 "register_operand" "v")
1569                       (match_operand:V4SI 3 "register_operand" "v")] 
1570                       UNSPEC_VSEL4SF))]
1571   "TARGET_ALTIVEC"
1572   "vsel %0,%1,%2,%3"
1573   [(set_attr "type" "vecperm")])
1574
1575 (define_insn "altivec_vsel_v8hi"
1576   [(set (match_operand:V8HI 0 "register_operand" "=v")
1577         (unspec:V8HI [(match_operand:V8HI 1 "register_operand" "v")
1578                       (match_operand:V8HI 2 "register_operand" "v")
1579                       (match_operand:V8HI 3 "register_operand" "v")] 
1580                      UNSPEC_VSEL8HI))]
1581   "TARGET_ALTIVEC"
1582   "vsel %0,%1,%2,%3"
1583   [(set_attr "type" "vecperm")])
1584
1585 (define_insn "altivec_vsel_v16qi"
1586   [(set (match_operand:V16QI 0 "register_operand" "=v")
1587         (unspec:V16QI [(match_operand:V16QI 1 "register_operand" "v")
1588                        (match_operand:V16QI 2 "register_operand" "v")
1589                        (match_operand:V16QI 3 "register_operand" "v")] 
1590                       UNSPEC_VSEL16QI))]
1591   "TARGET_ALTIVEC"
1592   "vsel %0,%1,%2,%3"
1593   [(set_attr "type" "vecperm")])
1594
1595 (define_insn "altivec_vsldoi_<mode>"
1596   [(set (match_operand:V 0 "register_operand" "=v")
1597         (unspec:V [(match_operand:V 1 "register_operand" "v")
1598                    (match_operand:V 2 "register_operand" "v")
1599                    (match_operand:QI 3 "immediate_operand" "i")]
1600                   UNSPEC_VLSDOI))]
1601   "TARGET_ALTIVEC"
1602   "vsldoi %0,%1,%2,%3"
1603   [(set_attr "type" "vecperm")])
1604
1605 (define_insn "altivec_vupkhsb"
1606   [(set (match_operand:V8HI 0 "register_operand" "=v")
1607         (unspec:V8HI [(match_operand:V16QI 1 "register_operand" "v")]
1608                      UNSPEC_VUPKHSB))]
1609   "TARGET_ALTIVEC"
1610   "vupkhsb %0,%1"
1611   [(set_attr "type" "vecperm")])
1612
1613 (define_insn "altivec_vupkhpx"
1614   [(set (match_operand:V4SI 0 "register_operand" "=v")
1615         (unspec:V4SI [(match_operand:V8HI 1 "register_operand" "v")]
1616                      UNSPEC_VUPKHPX))]
1617   "TARGET_ALTIVEC"
1618   "vupkhpx %0,%1"
1619   [(set_attr "type" "vecperm")])
1620
1621 (define_insn "altivec_vupkhsh"
1622   [(set (match_operand:V4SI 0 "register_operand" "=v")
1623         (unspec:V4SI [(match_operand:V8HI 1 "register_operand" "v")]
1624                      UNSPEC_VUPKHSH))]
1625   "TARGET_ALTIVEC"
1626   "vupkhsh %0,%1"
1627   [(set_attr "type" "vecperm")])
1628
1629 (define_insn "altivec_vupklsb"
1630   [(set (match_operand:V8HI 0 "register_operand" "=v")
1631         (unspec:V8HI [(match_operand:V16QI 1 "register_operand" "v")]
1632                      UNSPEC_VUPKLSB))]
1633   "TARGET_ALTIVEC"
1634   "vupklsb %0,%1"
1635   [(set_attr "type" "vecperm")])
1636
1637 (define_insn "altivec_vupklpx"
1638   [(set (match_operand:V4SI 0 "register_operand" "=v")
1639         (unspec:V4SI [(match_operand:V8HI 1 "register_operand" "v")]
1640                      UNSPEC_VUPKLPX))]
1641   "TARGET_ALTIVEC"
1642   "vupklpx %0,%1"
1643   [(set_attr "type" "vecperm")])
1644
1645 (define_insn "altivec_vupklsh"
1646   [(set (match_operand:V4SI 0 "register_operand" "=v")
1647         (unspec:V4SI [(match_operand:V8HI 1 "register_operand" "v")]
1648                      UNSPEC_VUPKLSH))]
1649   "TARGET_ALTIVEC"
1650   "vupklsh %0,%1"
1651   [(set_attr "type" "vecperm")])
1652
1653 ;; AltiVec predicates.
1654
1655 (define_expand "cr6_test_for_zero"
1656   [(set (match_operand:SI 0 "register_operand" "=r")
1657         (eq:SI (reg:CC 74)
1658                (const_int 0)))]
1659   "TARGET_ALTIVEC"
1660   "")   
1661
1662 (define_expand "cr6_test_for_zero_reverse"
1663   [(set (match_operand:SI 0 "register_operand" "=r")
1664         (eq:SI (reg:CC 74)
1665                (const_int 0)))
1666    (set (match_dup 0) (minus:SI (const_int 1) (match_dup 0)))]
1667   "TARGET_ALTIVEC"
1668   "")
1669
1670 (define_expand "cr6_test_for_lt"
1671   [(set (match_operand:SI 0 "register_operand" "=r")
1672         (lt:SI (reg:CC 74)
1673                (const_int 0)))]
1674   "TARGET_ALTIVEC"
1675   "")
1676
1677 (define_expand "cr6_test_for_lt_reverse"
1678   [(set (match_operand:SI 0 "register_operand" "=r")
1679         (lt:SI (reg:CC 74)
1680                (const_int 0)))
1681    (set (match_dup 0) (minus:SI (const_int 1) (match_dup 0)))]
1682   "TARGET_ALTIVEC"
1683   "")
1684
1685 ;; We can get away with generating the opcode on the fly (%3 below)
1686 ;; because all the predicates have the same scheduling parameters.
1687
1688 (define_insn "altivec_predicate_<mode>"
1689   [(set (reg:CC 74)
1690         (unspec:CC [(match_operand:V 1 "register_operand" "v")
1691                     (match_operand:V 2 "register_operand" "v")
1692                     (match_operand 3 "any_operand" "")] UNSPEC_PREDICATE))
1693    (clobber (match_scratch:V 0 "=v"))]
1694   "TARGET_ALTIVEC"
1695   "%3 %0,%1,%2"
1696 [(set_attr "type" "veccmp")])
1697
1698 (define_insn "altivec_mtvscr"
1699   [(set (reg:SI 110)
1700         (unspec_volatile:SI
1701          [(match_operand:V4SI 0 "register_operand" "v")] UNSPECV_MTVSCR))]
1702   "TARGET_ALTIVEC"
1703   "mtvscr %0"
1704   [(set_attr "type" "vecsimple")])
1705
1706 (define_insn "altivec_mfvscr"
1707   [(set (match_operand:V8HI 0 "register_operand" "=v")
1708         (unspec_volatile:V8HI [(reg:SI 110)] UNSPECV_MFVSCR))]
1709   "TARGET_ALTIVEC"
1710   "mfvscr %0"
1711   [(set_attr "type" "vecsimple")])
1712
1713 (define_insn "altivec_dssall"
1714   [(unspec_volatile [(const_int 0)] UNSPECV_DSSALL)]
1715   "TARGET_ALTIVEC"
1716   "dssall"
1717   [(set_attr "type" "vecsimple")])
1718
1719 (define_insn "altivec_dss"
1720   [(unspec_volatile [(match_operand:QI 0 "immediate_operand" "i")]
1721                     UNSPECV_DSS)]
1722   "TARGET_ALTIVEC"
1723   "dss %0"
1724   [(set_attr "type" "vecsimple")])
1725
1726 (define_insn "altivec_dst"
1727   [(unspec [(match_operand 0 "register_operand" "b")
1728             (match_operand:SI 1 "register_operand" "r")
1729             (match_operand:QI 2 "immediate_operand" "i")] UNSPEC_DST)]
1730   "TARGET_ALTIVEC && GET_MODE (operands[0]) == Pmode"
1731   "dst %0,%1,%2"
1732   [(set_attr "type" "vecsimple")])
1733
1734 (define_insn "altivec_dstt"
1735   [(unspec [(match_operand 0 "register_operand" "b")
1736             (match_operand:SI 1 "register_operand" "r")
1737             (match_operand:QI 2 "immediate_operand" "i")] UNSPEC_DSTT)]
1738   "TARGET_ALTIVEC && GET_MODE (operands[0]) == Pmode"
1739   "dstt %0,%1,%2"
1740   [(set_attr "type" "vecsimple")])
1741
1742 (define_insn "altivec_dstst"
1743   [(unspec [(match_operand 0 "register_operand" "b")
1744             (match_operand:SI 1 "register_operand" "r")
1745             (match_operand:QI 2 "immediate_operand" "i")] UNSPEC_DSTST)]
1746   "TARGET_ALTIVEC && GET_MODE (operands[0]) == Pmode"
1747   "dstst %0,%1,%2"
1748   [(set_attr "type" "vecsimple")])
1749
1750 (define_insn "altivec_dststt"
1751   [(unspec [(match_operand 0 "register_operand" "b")
1752             (match_operand:SI 1 "register_operand" "r")
1753             (match_operand:QI 2 "immediate_operand" "i")] UNSPEC_DSTSTT)]
1754   "TARGET_ALTIVEC && GET_MODE (operands[0]) == Pmode"
1755   "dststt %0,%1,%2"
1756   [(set_attr "type" "vecsimple")])
1757
1758 (define_insn "altivec_lvsl"
1759   [(set (match_operand:V16QI 0 "register_operand" "=v")
1760         (unspec:V16QI [(match_operand 1 "memory_operand" "Z")] UNSPEC_LVSL))]
1761   "TARGET_ALTIVEC"
1762   "lvsl %0,%y1"
1763   [(set_attr "type" "vecload")])
1764
1765 (define_insn "altivec_lvsr"
1766   [(set (match_operand:V16QI 0 "register_operand" "=v")
1767         (unspec:V16QI [(match_operand 1 "memory_operand" "Z")] UNSPEC_LVSR))]
1768   "TARGET_ALTIVEC"
1769   "lvsr %0,%y1"
1770   [(set_attr "type" "vecload")])
1771
1772 (define_expand "build_vector_mask_for_load"
1773   [(set (match_operand:V16QI 0 "register_operand" "")
1774         (unspec:V16QI [(match_operand 1 "memory_operand" "")] UNSPEC_LVSR))]
1775   "TARGET_ALTIVEC"
1776   "
1777
1778   rtx addr;
1779   rtx temp;
1780
1781   gcc_assert (GET_CODE (operands[1]) == MEM);
1782
1783   addr = XEXP (operands[1], 0);
1784   temp = gen_reg_rtx (GET_MODE (addr));
1785   emit_insn (gen_rtx_SET (VOIDmode, temp, 
1786                           gen_rtx_NEG (GET_MODE (addr), addr)));
1787   emit_insn (gen_altivec_lvsr (operands[0], 
1788                                replace_equiv_address (operands[1], temp)));
1789   DONE;
1790 }")
1791
1792 ;; Parallel some of the LVE* and STV*'s with unspecs because some have
1793 ;; identical rtl but different instructions-- and gcc gets confused.
1794
1795 (define_insn "altivec_lve<VI_char>x"
1796   [(parallel
1797     [(set (match_operand:VI 0 "register_operand" "=v")
1798           (match_operand:VI 1 "memory_operand" "Z"))
1799      (unspec [(const_int 0)] UNSPEC_LVE)])]
1800   "TARGET_ALTIVEC"
1801   "lve<VI_char>x %0,%y1"
1802   [(set_attr "type" "vecload")])
1803
1804 (define_insn "*altivec_lvesfx"
1805   [(parallel
1806     [(set (match_operand:V4SF 0 "register_operand" "=v")
1807           (match_operand:V4SF 1 "memory_operand" "Z"))
1808      (unspec [(const_int 0)] UNSPEC_LVE)])]
1809   "TARGET_ALTIVEC"
1810   "lvewx %0,%y1"
1811   [(set_attr "type" "vecload")])
1812
1813 (define_insn "altivec_lvxl"
1814   [(parallel
1815     [(set (match_operand:V4SI 0 "register_operand" "=v")
1816           (match_operand:V4SI 1 "memory_operand" "Z"))
1817      (unspec [(const_int 0)] UNSPEC_SET_VSCR)])]
1818   "TARGET_ALTIVEC"
1819   "lvxl %0,%y1"
1820   [(set_attr "type" "vecload")])
1821
1822 (define_insn "altivec_lvx"
1823   [(set (match_operand:V4SI 0 "register_operand" "=v")
1824         (match_operand:V4SI 1 "memory_operand" "Z"))]
1825   "TARGET_ALTIVEC"
1826   "lvx %0,%y1"
1827   [(set_attr "type" "vecload")])
1828
1829 (define_insn "altivec_stvx"
1830   [(parallel
1831     [(set (match_operand:V4SI 0 "memory_operand" "=Z")
1832           (match_operand:V4SI 1 "register_operand" "v"))
1833      (unspec [(const_int 0)] UNSPEC_STVX)])]
1834   "TARGET_ALTIVEC"
1835   "stvx %1,%y0"
1836   [(set_attr "type" "vecstore")])
1837
1838 (define_insn "altivec_stvxl"
1839   [(parallel
1840     [(set (match_operand:V4SI 0 "memory_operand" "=Z")
1841           (match_operand:V4SI 1 "register_operand" "v"))
1842      (unspec [(const_int 0)] UNSPEC_STVXL)])]
1843   "TARGET_ALTIVEC"
1844   "stvxl %1,%y0"
1845   [(set_attr "type" "vecstore")])
1846
1847 (define_insn "altivec_stve<VI_char>x"
1848   [(parallel
1849     [(set (match_operand:VI 0 "memory_operand" "=Z")
1850           (match_operand:VI 1 "register_operand" "v"))
1851      (unspec [(const_int 0)] UNSPEC_STVE)])]
1852   "TARGET_ALTIVEC"
1853   "stve<VI_char>x %1,%y0"
1854   [(set_attr "type" "vecstore")])
1855
1856 (define_insn "*altivec_stvesfx"
1857   [(parallel
1858     [(set (match_operand:V4SF 0 "memory_operand" "=Z")
1859           (match_operand:V4SF 1 "register_operand" "v"))
1860      (unspec [(const_int 0)] UNSPEC_STVE)])]
1861   "TARGET_ALTIVEC"
1862   "stvewx %1,%y0"
1863   [(set_attr "type" "vecstore")])
1864
1865 (define_expand "vec_init<mode>"
1866   [(match_operand:V 0 "register_operand" "")
1867    (match_operand 1 "" "")]
1868   "TARGET_ALTIVEC"
1869 {
1870   rs6000_expand_vector_init (operands[0], operands[1]);
1871   DONE;
1872 })
1873
1874 (define_expand "vec_setv4si"
1875   [(match_operand:V4SI 0 "register_operand" "")
1876    (match_operand:SI 1 "register_operand" "")
1877    (match_operand 2 "const_int_operand" "")]
1878   "TARGET_ALTIVEC"
1879 {
1880   rs6000_expand_vector_set (operands[0], operands[1], INTVAL (operands[2]));
1881   DONE;
1882 })
1883
1884 (define_expand "vec_setv8hi"
1885   [(match_operand:V8HI 0 "register_operand" "")
1886    (match_operand:HI 1 "register_operand" "")
1887    (match_operand 2 "const_int_operand" "")]
1888   "TARGET_ALTIVEC"
1889 {
1890   rs6000_expand_vector_set (operands[0], operands[1], INTVAL (operands[2]));
1891   DONE;
1892 })
1893
1894 (define_expand "vec_setv16qi"
1895   [(match_operand:V16QI 0 "register_operand" "")
1896    (match_operand:QI 1 "register_operand" "")
1897    (match_operand 2 "const_int_operand" "")]
1898   "TARGET_ALTIVEC"
1899 {
1900   rs6000_expand_vector_set (operands[0], operands[1], INTVAL (operands[2]));
1901   DONE;
1902 })
1903
1904 (define_expand "vec_setv4sf"
1905   [(match_operand:V4SF 0 "register_operand" "")
1906    (match_operand:SF 1 "register_operand" "")
1907    (match_operand 2 "const_int_operand" "")]
1908   "TARGET_ALTIVEC"
1909 {
1910   rs6000_expand_vector_set (operands[0], operands[1], INTVAL (operands[2]));
1911   DONE;
1912 })
1913
1914 (define_expand "vec_extractv4si"
1915   [(match_operand:SI 0 "register_operand" "")
1916    (match_operand:V4SI 1 "register_operand" "")
1917    (match_operand 2 "const_int_operand" "")]
1918   "TARGET_ALTIVEC"
1919 {
1920   rs6000_expand_vector_extract (operands[0], operands[1], INTVAL (operands[2]));
1921   DONE;
1922 })
1923
1924 (define_expand "vec_extractv8hi"
1925   [(match_operand:HI 0 "register_operand" "")
1926    (match_operand:V8HI 1 "register_operand" "")
1927    (match_operand 2 "const_int_operand" "")]
1928   "TARGET_ALTIVEC"
1929 {
1930   rs6000_expand_vector_extract (operands[0], operands[1], INTVAL (operands[2]));
1931   DONE;
1932 })
1933
1934 (define_expand "vec_extractv16qi"
1935   [(match_operand:QI 0 "register_operand" "")
1936    (match_operand:V16QI 1 "register_operand" "")
1937    (match_operand 2 "const_int_operand" "")]
1938   "TARGET_ALTIVEC"
1939 {
1940   rs6000_expand_vector_extract (operands[0], operands[1], INTVAL (operands[2]));
1941   DONE;
1942 })
1943
1944 (define_expand "vec_extractv4sf"
1945   [(match_operand:SF 0 "register_operand" "")
1946    (match_operand:V4SF 1 "register_operand" "")
1947    (match_operand 2 "const_int_operand" "")]
1948   "TARGET_ALTIVEC"
1949 {
1950   rs6000_expand_vector_extract (operands[0], operands[1], INTVAL (operands[2]));
1951   DONE;
1952 })
1953
1954 ;; Generate
1955 ;;    vspltis? SCRATCH0,0
1956 ;;    vsubu?m SCRATCH2,SCRATCH1,%1
1957 ;;    vmaxs? %0,%1,SCRATCH2"
1958 (define_expand "abs<mode>2"
1959   [(set (match_dup 2) (vec_duplicate:VI (const_int 0)))
1960    (set (match_dup 3)
1961         (minus:VI (match_dup 2)
1962                   (match_operand:VI 1 "register_operand" "v")))
1963    (set (match_operand:VI 0 "register_operand" "=v")
1964         (smax:VI (match_dup 1) (match_dup 3)))]
1965   "TARGET_ALTIVEC"
1966 {
1967   operands[2] = gen_reg_rtx (GET_MODE (operands[0]));
1968   operands[3] = gen_reg_rtx (GET_MODE (operands[0]));
1969 })
1970
1971 ;; Generate
1972 ;;    vspltisw SCRATCH1,-1
1973 ;;    vslw SCRATCH2,SCRATCH1,SCRATCH1
1974 ;;    vandc %0,%1,SCRATCH2
1975 (define_expand "absv4sf2"
1976   [(set (match_dup 2)
1977         (vec_duplicate:V4SI (const_int -1)))
1978    (set (match_dup 3)
1979         (unspec:V4SI [(match_dup 2) (match_dup 2)] UNSPEC_VSL))
1980    (set (match_operand:V4SF 0 "register_operand" "=v")
1981         (and:V4SF (not:V4SF (subreg:V4SF (match_dup 3) 0))
1982                   (match_operand:V4SF 1 "register_operand" "v")))]
1983   "TARGET_ALTIVEC"
1984 {
1985   operands[2] = gen_reg_rtx (V4SImode);
1986   operands[3] = gen_reg_rtx (V4SImode);
1987 })
1988
1989 ;; Generate
1990 ;;    vspltis? SCRATCH0,0
1991 ;;    vsubs?s SCRATCH2,SCRATCH1,%1
1992 ;;    vmaxs? %0,%1,SCRATCH2"
1993 (define_expand "altivec_abss_<mode>"
1994   [(set (match_dup 2) (vec_duplicate:VI (const_int 0)))
1995    (parallel [(set (match_dup 3)
1996                    (unspec:VI [(match_dup 2)
1997                                (match_operand:VI 1 "register_operand" "v")]
1998                               UNSPEC_VSUBS))
1999               (set (reg:SI 110) (unspec:SI [(const_int 0)] UNSPEC_SET_VSCR))])
2000    (set (match_operand:VI 0 "register_operand" "=v")
2001         (smax:VI (match_dup 1) (match_dup 3)))]
2002   "TARGET_ALTIVEC"
2003 {
2004   operands[2] = gen_reg_rtx (GET_MODE (operands[0]));
2005   operands[3] = gen_reg_rtx (GET_MODE (operands[0]));
2006 })
2007
2008 ;; Vector shift left in bits. Currently supported ony for shift
2009 ;; amounts that can be expressed as byte shifts (divisible by 8).
2010 ;; General shift amounts can be supported using vslo + vsl. We're
2011 ;; not expecting to see these yet (the vectorizer currently
2012 ;; generates only shifts divisible by byte_size).
2013 (define_expand "vec_shl_<mode>"
2014   [(set (match_operand:V 0 "register_operand" "=v")
2015         (unspec:V [(match_operand:V 1 "register_operand" "v")
2016                    (match_operand:QI 2 "reg_or_short_operand" "")]
2017                   UNSPEC_VECSH))]
2018   "TARGET_ALTIVEC"
2019   "
2020 {
2021   rtx bitshift = operands[2];
2022   rtx byteshift = gen_reg_rtx (QImode);
2023   HOST_WIDE_INT bitshift_val;
2024   HOST_WIDE_INT byteshift_val;
2025
2026   if (! CONSTANT_P (bitshift))
2027     FAIL;
2028   bitshift_val = INTVAL (bitshift);
2029   if (bitshift_val & 0x7)
2030     FAIL;
2031   byteshift_val = bitshift_val >> 3;
2032   byteshift = gen_rtx_CONST_INT (QImode, byteshift_val);
2033   emit_insn (gen_altivec_vsldoi_<mode> (operands[0], operands[1], operands[1],
2034                                         byteshift));
2035   DONE;
2036 }")
2037
2038 ;; Vector shift left in bits. Currently supported ony for shift
2039 ;; amounts that can be expressed as byte shifts (divisible by 8).
2040 ;; General shift amounts can be supported using vsro + vsr. We're
2041 ;; not expecting to see these yet (the vectorizer currently
2042 ;; generates only shifts divisible by byte_size).
2043 (define_expand "vec_shr_<mode>"
2044   [(set (match_operand:V 0 "register_operand" "=v")
2045         (unspec:V [(match_operand:V 1 "register_operand" "v")
2046                    (match_operand:QI 2 "reg_or_short_operand" "")]
2047                   UNSPEC_VECSH))]
2048   "TARGET_ALTIVEC"
2049   "
2050 {
2051   rtx bitshift = operands[2];
2052   rtx byteshift = gen_reg_rtx (QImode);
2053   HOST_WIDE_INT bitshift_val;
2054   HOST_WIDE_INT byteshift_val;
2055  
2056   if (! CONSTANT_P (bitshift))
2057     FAIL;
2058   bitshift_val = INTVAL (bitshift);
2059   if (bitshift_val & 0x7)
2060     FAIL;
2061   byteshift_val = 16 - (bitshift_val >> 3);
2062   byteshift = gen_rtx_CONST_INT (QImode, byteshift_val);
2063   emit_insn (gen_altivec_vsldoi_<mode> (operands[0], operands[1], operands[1],
2064                                         byteshift));
2065   DONE;
2066 }")
2067
2068 (define_insn "altivec_vsumsws_nomode"
2069   [(set (match_operand 0 "register_operand" "=v")
2070         (unspec:V4SI [(match_operand:V4SI 1 "register_operand" "v")
2071                       (match_operand:V4SI 2 "register_operand" "v")]
2072                      UNSPEC_VSUMSWS))
2073    (set (reg:SI 110) (unspec:SI [(const_int 0)] UNSPEC_SET_VSCR))]
2074   "TARGET_ALTIVEC"
2075   "vsumsws %0,%1,%2"
2076   [(set_attr "type" "veccomplex")])
2077
2078 (define_expand "reduc_splus_<mode>"
2079   [(set (match_operand:VIshort 0 "register_operand" "=v")
2080         (unspec:VIshort [(match_operand:VIshort 1 "register_operand" "v")]
2081                         UNSPEC_REDUC_PLUS))]
2082   "TARGET_ALTIVEC"
2083   "
2084
2085   rtx vzero = gen_reg_rtx (V4SImode);
2086   rtx vtmp1 = gen_reg_rtx (V4SImode);
2087
2088   emit_insn (gen_altivec_vspltisw (vzero, const0_rtx));
2089   emit_insn (gen_altivec_vsum4s<VI_char>s (vtmp1, operands[1], vzero));
2090   emit_insn (gen_altivec_vsumsws_nomode (operands[0], vtmp1, vzero));
2091   DONE;
2092 }")
2093
2094 (define_expand "reduc_uplus_v16qi"
2095   [(set (match_operand:V16QI 0 "register_operand" "=v")
2096         (unspec:V16QI [(match_operand:V16QI 1 "register_operand" "v")]
2097                       UNSPEC_REDUC_PLUS))]
2098   "TARGET_ALTIVEC"
2099   "
2100 {
2101   rtx vzero = gen_reg_rtx (V4SImode);
2102   rtx vtmp1 = gen_reg_rtx (V4SImode);
2103
2104   emit_insn (gen_altivec_vspltisw (vzero, const0_rtx));
2105   emit_insn (gen_altivec_vsum4ubs (vtmp1, operands[1], vzero));
2106   emit_insn (gen_altivec_vsumsws_nomode (operands[0], vtmp1, vzero));
2107   DONE;
2108 }")
2109
2110 (define_insn "vec_realign_load_<mode>"
2111   [(set (match_operand:V 0 "register_operand" "=v")
2112         (unspec:V [(match_operand:V 1 "register_operand" "v")
2113                    (match_operand:V 2 "register_operand" "v")
2114                    (match_operand:V16QI 3 "register_operand" "v")]
2115                   UNSPEC_REALIGN_LOAD))]
2116   "TARGET_ALTIVEC"
2117   "vperm %0,%1,%2,%3"
2118   [(set_attr "type" "vecperm")])
2119
2120 (define_expand "neg<mode>2"
2121   [(use (match_operand:VI 0 "register_operand" ""))
2122    (use (match_operand:VI 1 "register_operand" ""))]
2123   "TARGET_ALTIVEC"
2124   "
2125 {
2126   rtx vzero;
2127
2128   vzero = gen_reg_rtx (GET_MODE (operands[0]));
2129   emit_insn (gen_altivec_vspltis<VI_char> (vzero, const0_rtx));
2130   emit_insn (gen_sub<mode>3 (operands[0], vzero, operands[1])); 
2131   
2132   DONE;
2133 }")
2134
2135 (define_expand "udot_prod<mode>"
2136   [(set (match_operand:V4SI 0 "register_operand" "=v")
2137         (plus:V4SI (match_operand:V4SI 3 "register_operand" "v")
2138                    (unspec:V4SI [(match_operand:VIshort 1 "register_operand" "v")  
2139                                  (match_operand:VIshort 2 "register_operand" "v")] 
2140                                 UNSPEC_VMSUMU)))]
2141   "TARGET_ALTIVEC"
2142   "
2143 {  
2144   emit_insn (gen_altivec_vmsumu<VI_char>m (operands[0], operands[1], operands[2], operands[3]));
2145   DONE;
2146 }")
2147    
2148 (define_expand "sdot_prodv8hi"
2149   [(set (match_operand:V4SI 0 "register_operand" "=v")
2150         (plus:V4SI (match_operand:V4SI 3 "register_operand" "v")
2151                    (unspec:V4SI [(match_operand:V8HI 1 "register_operand" "v")
2152                                  (match_operand:V8HI 2 "register_operand" "v")]
2153                                 UNSPEC_VMSUMSHM)))]
2154   "TARGET_ALTIVEC"
2155   "
2156 {
2157   emit_insn (gen_altivec_vmsumshm (operands[0], operands[1], operands[2], operands[3]));
2158   DONE;
2159 }")
2160
2161 (define_expand "widen_usum<mode>3"
2162   [(set (match_operand:V4SI 0 "register_operand" "=v")
2163         (plus:V4SI (match_operand:V4SI 2 "register_operand" "v")
2164                    (unspec:V4SI [(match_operand:VIshort 1 "register_operand" "v")]
2165                                 UNSPEC_VMSUMU)))]
2166   "TARGET_ALTIVEC"
2167   "
2168 {
2169   rtx vones = gen_reg_rtx (GET_MODE (operands[1]));
2170
2171   emit_insn (gen_altivec_vspltis<VI_char> (vones, const1_rtx));
2172   emit_insn (gen_altivec_vmsumu<VI_char>m (operands[0], operands[1], vones, operands[2]));
2173   DONE;
2174 }")
2175
2176 (define_expand "widen_ssumv16qi3"
2177   [(set (match_operand:V4SI 0 "register_operand" "=v")
2178         (plus:V4SI (match_operand:V4SI 2 "register_operand" "v")
2179                    (unspec:V4SI [(match_operand:V16QI 1 "register_operand" "v")]
2180                                 UNSPEC_VMSUMM)))]
2181   "TARGET_ALTIVEC"
2182   "
2183 {
2184   rtx vones = gen_reg_rtx (V16QImode);
2185
2186   emit_insn (gen_altivec_vspltisb (vones, const1_rtx));
2187   emit_insn (gen_altivec_vmsummbm (operands[0], operands[1], vones, operands[2]));
2188   DONE;
2189 }")
2190
2191 (define_expand "widen_ssumv8hi3"
2192   [(set (match_operand:V4SI 0 "register_operand" "=v")
2193         (plus:V4SI (match_operand:V4SI 2 "register_operand" "v")
2194                    (unspec:V4SI [(match_operand:V8HI 1 "register_operand" "v")]
2195                                 UNSPEC_VMSUMSHM)))]
2196   "TARGET_ALTIVEC"
2197   "
2198 {
2199   rtx vones = gen_reg_rtx (V8HImode);
2200
2201   emit_insn (gen_altivec_vspltish (vones, const1_rtx));
2202   emit_insn (gen_altivec_vmsumshm (operands[0], operands[1], vones, operands[2]));
2203   DONE;
2204 }")
2205
2206 (define_expand "negv4sf2"
2207   [(use (match_operand:V4SF 0 "register_operand" ""))
2208    (use (match_operand:V4SF 1 "register_operand" ""))]
2209   "TARGET_ALTIVEC"
2210   "
2211 {
2212   rtx neg0;
2213
2214   /* Generate [-0.0, -0.0, -0.0, -0.0].  */
2215   neg0 = gen_reg_rtx (V4SImode);
2216   emit_insn (gen_altivec_vspltisw (neg0, constm1_rtx));
2217   emit_insn (gen_altivec_vslw (neg0, neg0, neg0));
2218
2219   /* XOR */
2220   emit_insn (gen_xorv4sf3 (operands[0],
2221                            gen_lowpart (V4SFmode, neg0), operands[1])); 
2222     
2223   DONE;
2224 }")