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}")
2225