Merged trunk at revision 161680 into branch.
[official-gcc.git] / gcc / config / rs6000 / altivec.md
blob7bf3c660312bbe24c32fa92262193430a504f807
1 ;; AltiVec patterns.
2 ;; Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009
3 ;; Free Software Foundation, Inc.
4 ;; Contributed by Aldy Hernandez (aldy@quesejoda.com)
6 ;; This file is part of GCC.
8 ;; GCC is free software; you can redistribute it and/or modify it
9 ;; under the terms of the GNU General Public License as published
10 ;; by the Free Software Foundation; either version 3, or (at your
11 ;; option) any later version.
13 ;; GCC is distributed in the hope that it will be useful, but WITHOUT
14 ;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
15 ;; or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
16 ;; License for more details.
18 ;; You should have received a copy of the GNU General Public License
19 ;; along with GCC; see the file COPYING3.  If not see
20 ;; <http://www.gnu.org/licenses/>.
22 (define_constants
23    ;; 51-62 deleted
24   [(UNSPEC_VCMPBFP       64)
25    (UNSPEC_VMSUMU        65)
26    (UNSPEC_VMSUMM        66)
27    (UNSPEC_VMSUMSHM      68)
28    (UNSPEC_VMSUMUHS      69)
29    (UNSPEC_VMSUMSHS      70)
30    (UNSPEC_VMHADDSHS     71)
31    (UNSPEC_VMHRADDSHS    72)
32    (UNSPEC_VMLADDUHM     73)
33    (UNSPEC_VADDCUW       75)
34    (UNSPEC_VADDU         76)
35    (UNSPEC_VADDS         77)
36    (UNSPEC_VAVGU         80)
37    (UNSPEC_VAVGS         81)
38    (UNSPEC_VMULEUB       83)
39    (UNSPEC_VMULESB       84)
40    (UNSPEC_VMULEUH       85)
41    (UNSPEC_VMULESH       86)
42    (UNSPEC_VMULOUB       87)
43    (UNSPEC_VMULOSB       88)
44    (UNSPEC_VMULOUH       89)
45    (UNSPEC_VMULOSH       90)
46    (UNSPEC_VPKUHUM       93)
47    (UNSPEC_VPKUWUM       94)
48    (UNSPEC_VPKPX         95)
49    (UNSPEC_VPKSHSS       97)
50    (UNSPEC_VPKSWSS       99)
51    (UNSPEC_VPKUHUS      100)
52    (UNSPEC_VPKSHUS      101)
53    (UNSPEC_VPKUWUS      102)
54    (UNSPEC_VPKSWUS      103)
55    ;; 104 deleted
56    (UNSPEC_VSLV4SI      110)
57    (UNSPEC_VSLO         111)
58    (UNSPEC_VSR          118)
59    (UNSPEC_VSRO         119)
60    (UNSPEC_VSUBCUW      124)
61    (UNSPEC_VSUBU        125)
62    (UNSPEC_VSUBS        126)
63    (UNSPEC_VSUM4UBS     131)
64    (UNSPEC_VSUM4S       132)
65    (UNSPEC_VSUM2SWS     134)
66    (UNSPEC_VSUMSWS      135)
67    (UNSPEC_VPERM        144)
68    (UNSPEC_VPERM_UNS    145)
69    ;; 148 deleted
70    (UNSPEC_VRFIN        149)
71    ;; 150 deleted
72    (UNSPEC_VCFUX        151)
73    (UNSPEC_VCFSX        152)
74    (UNSPEC_VCTUXS       153)
75    (UNSPEC_VCTSXS       154)
76    (UNSPEC_VLOGEFP      155)
77    (UNSPEC_VEXPTEFP     156)
78    ;; 157-162 deleted
79    (UNSPEC_VLSDOI       163)
80    (UNSPEC_VUPKHSB      167)
81    (UNSPEC_VUPKHPX      168)
82    (UNSPEC_VUPKHSH      169)
83    (UNSPEC_VUPKLSB      170)
84    (UNSPEC_VUPKLPX      171)
85    (UNSPEC_VUPKLSH      172)
86    ;; 173 deleted
87    (UNSPEC_DST          190)
88    (UNSPEC_DSTT         191)
89    (UNSPEC_DSTST        192)
90    (UNSPEC_DSTSTT       193)
91    (UNSPEC_LVSL         194)
92    (UNSPEC_LVSR         195)
93    (UNSPEC_LVE          196)
94    (UNSPEC_STVX         201)
95    (UNSPEC_STVXL        202)
96    (UNSPEC_STVE         203)
97    (UNSPEC_SET_VSCR     213)
98    (UNSPEC_GET_VRSAVE   214)
99    ;; 215 deleted
100    (UNSPEC_REDUC_PLUS   217)
101    (UNSPEC_VECSH        219)
102    (UNSPEC_EXTEVEN_V4SI 220)
103    (UNSPEC_EXTEVEN_V8HI 221)
104    (UNSPEC_EXTEVEN_V16QI 222)
105    (UNSPEC_EXTEVEN_V4SF 223)
106    (UNSPEC_EXTODD_V4SI  224)
107    (UNSPEC_EXTODD_V8HI  225)
108    (UNSPEC_EXTODD_V16QI 226)
109    (UNSPEC_EXTODD_V4SF  227)
110    (UNSPEC_INTERHI_V4SI 228)
111    (UNSPEC_INTERHI_V8HI 229)
112    (UNSPEC_INTERHI_V16QI 230)
113    ;; delete 231
114    (UNSPEC_INTERLO_V4SI 232)
115    (UNSPEC_INTERLO_V8HI 233)
116    (UNSPEC_INTERLO_V16QI 234)
117    ;; delete 235
118    (UNSPEC_LVLX         236)
119    (UNSPEC_LVLXL        237)
120    (UNSPEC_LVRX         238)
121    (UNSPEC_LVRXL        239)
122    (UNSPEC_STVLX        240)
123    (UNSPEC_STVLXL       241)
124    (UNSPEC_STVRX        242)
125    (UNSPEC_STVRXL       243)
126    (UNSPEC_VMULWHUB     308)
127    (UNSPEC_VMULWLUB     309)
128    (UNSPEC_VMULWHSB     310)
129    (UNSPEC_VMULWLSB     311)
130    (UNSPEC_VMULWHUH     312)
131    (UNSPEC_VMULWLUH     313)
132    (UNSPEC_VMULWHSH     314)
133    (UNSPEC_VMULWLSH     315)
134    (UNSPEC_VUPKHUB      316)
135    (UNSPEC_VUPKHUH      317)
136    (UNSPEC_VUPKLUB      318)
137    (UNSPEC_VUPKLUH      319)
138    (UNSPEC_VPERMSI      320)
139    (UNSPEC_VPERMHI      321)
140    (UNSPEC_INTERHI      322)
141    (UNSPEC_INTERLO      323)
142    (UNSPEC_VUPKHS_V4SF  324)
143    (UNSPEC_VUPKLS_V4SF  325)
144    (UNSPEC_VUPKHU_V4SF  326)
145    (UNSPEC_VUPKLU_V4SF  327)
146    (UNSPEC_VNMSUBFP     328)
149 (define_constants
150   [(UNSPECV_SET_VRSAVE   30)
151    (UNSPECV_MTVSCR      186)
152    (UNSPECV_MFVSCR      187)
153    (UNSPECV_DSSALL      188)
154    (UNSPECV_DSS         189)
155   ])
157 ;; Vec int modes
158 (define_mode_iterator VI [V4SI V8HI V16QI])
159 ;; Short vec in modes
160 (define_mode_iterator VIshort [V8HI V16QI])
161 ;; Vec float modes
162 (define_mode_iterator VF [V4SF])
163 ;; Vec modes, pity mode iterators are not composable
164 (define_mode_iterator V [V4SI V8HI V16QI V4SF])
165 ;; Vec modes for move/logical/permute ops, include vector types for move not
166 ;; otherwise handled by altivec (v2df, v2di, ti)
167 (define_mode_iterator VM [V4SI V8HI V16QI V4SF V2DF V2DI TI])
169 ;; Like VM, except don't do TImode
170 (define_mode_iterator VM2 [V4SI V8HI V16QI V4SF V2DF V2DI])
172 (define_mode_attr VI_char [(V4SI "w") (V8HI "h") (V16QI "b")])
174 ;; Vector move instructions.
175 (define_insn "*altivec_mov<mode>"
176   [(set (match_operand:VM2 0 "nonimmediate_operand" "=Z,v,v,*o,*r,*r,v,v")
177         (match_operand:VM2 1 "input_operand" "v,Z,v,r,o,r,j,W"))]
178   "VECTOR_MEM_ALTIVEC_P (<MODE>mode)
179    && (register_operand (operands[0], <MODE>mode) 
180        || register_operand (operands[1], <MODE>mode))"
182   switch (which_alternative)
183     {
184     case 0: return "stvx %1,%y0";
185     case 1: return "lvx %0,%y1";
186     case 2: return "vor %0,%1,%1";
187     case 3: return "#";
188     case 4: return "#";
189     case 5: return "#";
190     case 6: return "vxor %0,%0,%0";
191     case 7: return output_vec_const_move (operands);
192     default: gcc_unreachable ();
193     }
195   [(set_attr "type" "vecstore,vecload,vecsimple,store,load,*,vecsimple,*")])
197 ;; Unlike other altivec moves, allow the GPRs, since a normal use of TImode
198 ;; is for unions.  However for plain data movement, slightly favor the vector
199 ;; loads
200 (define_insn "*altivec_movti"
201   [(set (match_operand:TI 0 "nonimmediate_operand" "=Z,v,v,?o,?r,?r,v,v")
202         (match_operand:TI 1 "input_operand" "v,Z,v,r,o,r,j,W"))]
203   "VECTOR_MEM_ALTIVEC_P (TImode)
204    && (register_operand (operands[0], TImode) 
205        || register_operand (operands[1], TImode))"
207   switch (which_alternative)
208     {
209     case 0: return "stvx %1,%y0";
210     case 1: return "lvx %0,%y1";
211     case 2: return "vor %0,%1,%1";
212     case 3: return "#";
213     case 4: return "#";
214     case 5: return "#";
215     case 6: return "vxor %0,%0,%0";
216     case 7: return output_vec_const_move (operands);
217     default: gcc_unreachable ();
218     }
220   [(set_attr "type" "vecstore,vecload,vecsimple,store,load,*,vecsimple,*")])
222 ;; Load up a vector with the most significant bit set by loading up -1 and
223 ;; doing a shift left
224 (define_split
225   [(set (match_operand:VM 0 "altivec_register_operand" "")
226         (match_operand:VM 1 "easy_vector_constant_msb" ""))]
227   "VECTOR_UNIT_ALTIVEC_P (<MODE>mode) && reload_completed"
228   [(const_int 0)]
230   rtx dest = operands[0];
231   enum machine_mode mode = GET_MODE (operands[0]);
232   rtvec v;
233   int i, num_elements;
235   if (mode == V4SFmode)
236     {
237       mode = V4SImode;
238       dest = gen_lowpart (V4SImode, dest);
239     }
241   num_elements = GET_MODE_NUNITS (mode);
242   v = rtvec_alloc (num_elements);
243   for (i = 0; i < num_elements; i++)
244     RTVEC_ELT (v, i) = constm1_rtx;
246   emit_insn (gen_vec_initv4si (dest, gen_rtx_PARALLEL (mode, v)));
247   emit_insn (gen_rtx_SET (VOIDmode, dest, gen_rtx_ASHIFT (mode, dest, dest)));
248   DONE;
251 (define_split
252   [(set (match_operand:VM 0 "altivec_register_operand" "")
253         (match_operand:VM 1 "easy_vector_constant_add_self" ""))]
254   "VECTOR_UNIT_ALTIVEC_P (<MODE>mode) && reload_completed"
255   [(set (match_dup 0) (match_dup 3))
256    (set (match_dup 0) (match_dup 4))]
258   rtx dup = gen_easy_altivec_constant (operands[1]);
259   rtx const_vec;
260   enum machine_mode op_mode = <MODE>mode;
262   /* Divide the operand of the resulting VEC_DUPLICATE, and use
263      simplify_rtx to make a CONST_VECTOR.  */
264   XEXP (dup, 0) = simplify_const_binary_operation (ASHIFTRT, QImode,
265                                                    XEXP (dup, 0), const1_rtx);
266   const_vec = simplify_rtx (dup);
268   if (op_mode == V4SFmode)
269     {
270       op_mode = V4SImode;
271       operands[0] = gen_lowpart (op_mode, operands[0]);
272     }
273   if (GET_MODE (const_vec) == op_mode)
274     operands[3] = const_vec;
275   else
276     operands[3] = gen_lowpart (op_mode, const_vec);
277   operands[4] = gen_rtx_PLUS (op_mode, operands[0], operands[0]);
280 (define_insn "get_vrsave_internal"
281   [(set (match_operand:SI 0 "register_operand" "=r")
282         (unspec:SI [(reg:SI 109)] UNSPEC_GET_VRSAVE))]
283   "TARGET_ALTIVEC"
285   if (TARGET_MACHO)
286      return "mfspr %0,256";
287   else
288      return "mfvrsave %0";
290   [(set_attr "type" "*")])
292 (define_insn "*set_vrsave_internal"
293   [(match_parallel 0 "vrsave_operation"
294      [(set (reg:SI 109)
295            (unspec_volatile:SI [(match_operand:SI 1 "register_operand" "r")
296                                 (reg:SI 109)] UNSPECV_SET_VRSAVE))])]
297   "TARGET_ALTIVEC"
299   if (TARGET_MACHO)
300     return "mtspr 256,%1";
301   else
302     return "mtvrsave %1";
304   [(set_attr "type" "*")])
306 (define_insn "*save_world"
307  [(match_parallel 0 "save_world_operation"
308                   [(clobber (reg:SI 65))
309                    (use (match_operand:SI 1 "call_operand" "s"))])]
310  "TARGET_MACHO && (DEFAULT_ABI == ABI_DARWIN) && TARGET_32BIT"         
311  "bl %z1"
312   [(set_attr "type" "branch")
313    (set_attr "length" "4")])
315 (define_insn "*restore_world"
316  [(match_parallel 0 "restore_world_operation"
317                   [(return)
318                    (use (reg:SI 65))
319                    (use (match_operand:SI 1 "call_operand" "s"))
320                    (clobber (match_operand:SI 2 "gpc_reg_operand" "=r"))])]
321  "TARGET_MACHO && (DEFAULT_ABI == ABI_DARWIN) && TARGET_32BIT"
322  "b %z1")
324 ;; Simple binary operations.
326 ;; add
327 (define_insn "add<mode>3"
328   [(set (match_operand:VI 0 "register_operand" "=v")
329         (plus:VI (match_operand:VI 1 "register_operand" "v")
330                  (match_operand:VI 2 "register_operand" "v")))]
331   "TARGET_ALTIVEC"
332   "vaddu<VI_char>m %0,%1,%2"
333   [(set_attr "type" "vecsimple")])
335 (define_insn "*altivec_addv4sf3"
336   [(set (match_operand:V4SF 0 "register_operand" "=v")
337         (plus:V4SF (match_operand:V4SF 1 "register_operand" "v")
338                    (match_operand:V4SF 2 "register_operand" "v")))]
339   "VECTOR_UNIT_ALTIVEC_P (V4SFmode)"
340   "vaddfp %0,%1,%2"
341   [(set_attr "type" "vecfloat")])
343 (define_insn "altivec_vaddcuw"
344   [(set (match_operand:V4SI 0 "register_operand" "=v")
345         (unspec:V4SI [(match_operand:V4SI 1 "register_operand" "v")
346                       (match_operand:V4SI 2 "register_operand" "v")]
347                      UNSPEC_VADDCUW))]
348   "TARGET_ALTIVEC"
349   "vaddcuw %0,%1,%2"
350   [(set_attr "type" "vecsimple")])
352 (define_insn "altivec_vaddu<VI_char>s"
353   [(set (match_operand:VI 0 "register_operand" "=v")
354         (unspec:VI [(match_operand:VI 1 "register_operand" "v")
355                     (match_operand:VI 2 "register_operand" "v")]
356                    UNSPEC_VADDU))
357    (set (reg:SI 110) (unspec:SI [(const_int 0)] UNSPEC_SET_VSCR))]
358   "TARGET_ALTIVEC"
359   "vaddu<VI_char>s %0,%1,%2"
360   [(set_attr "type" "vecsimple")])
362 (define_insn "altivec_vadds<VI_char>s"
363   [(set (match_operand:VI 0 "register_operand" "=v")
364         (unspec:VI [(match_operand:VI 1 "register_operand" "v")
365                     (match_operand:VI 2 "register_operand" "v")]
366                    UNSPEC_VADDS))
367    (set (reg:SI 110) (unspec:SI [(const_int 0)] UNSPEC_SET_VSCR))]
368   "TARGET_ALTIVEC"
369   "vadds<VI_char>s %0,%1,%2"
370   [(set_attr "type" "vecsimple")])
372 ;; sub
373 (define_insn "sub<mode>3"
374   [(set (match_operand:VI 0 "register_operand" "=v")
375         (minus:VI (match_operand:VI 1 "register_operand" "v")
376                   (match_operand:VI 2 "register_operand" "v")))]
377   "TARGET_ALTIVEC"
378   "vsubu<VI_char>m %0,%1,%2"
379   [(set_attr "type" "vecsimple")])
381 (define_insn "*altivec_subv4sf3"
382   [(set (match_operand:V4SF 0 "register_operand" "=v")
383         (minus:V4SF (match_operand:V4SF 1 "register_operand" "v")
384                     (match_operand:V4SF 2 "register_operand" "v")))]
385   "VECTOR_UNIT_ALTIVEC_P (V4SFmode)"
386   "vsubfp %0,%1,%2"
387   [(set_attr "type" "vecfloat")])
389 (define_insn "altivec_vsubcuw"
390   [(set (match_operand:V4SI 0 "register_operand" "=v")
391         (unspec:V4SI [(match_operand:V4SI 1 "register_operand" "v")
392                       (match_operand:V4SI 2 "register_operand" "v")]
393                      UNSPEC_VSUBCUW))]
394   "TARGET_ALTIVEC"
395   "vsubcuw %0,%1,%2"
396   [(set_attr "type" "vecsimple")])
398 (define_insn "altivec_vsubu<VI_char>s"
399   [(set (match_operand:VI 0 "register_operand" "=v")
400         (unspec:VI [(match_operand:VI 1 "register_operand" "v")
401                     (match_operand:VI 2 "register_operand" "v")]
402                    UNSPEC_VSUBU))
403    (set (reg:SI 110) (unspec:SI [(const_int 0)] UNSPEC_SET_VSCR))]
404   "TARGET_ALTIVEC"
405   "vsubu<VI_char>s %0,%1,%2"
406   [(set_attr "type" "vecsimple")])
408 (define_insn "altivec_vsubs<VI_char>s"
409   [(set (match_operand:VI 0 "register_operand" "=v")
410         (unspec:VI [(match_operand:VI 1 "register_operand" "v")
411                     (match_operand:VI 2 "register_operand" "v")]
412                    UNSPEC_VSUBS))
413    (set (reg:SI 110) (unspec:SI [(const_int 0)] UNSPEC_SET_VSCR))]
414   "TARGET_ALTIVEC"
415   "vsubs<VI_char>s %0,%1,%2"
416   [(set_attr "type" "vecsimple")])
419 (define_insn "altivec_vavgu<VI_char>"
420   [(set (match_operand:VI 0 "register_operand" "=v")
421         (unspec:VI [(match_operand:VI 1 "register_operand" "v")
422                     (match_operand:VI 2 "register_operand" "v")]
423                    UNSPEC_VAVGU))]
424   "TARGET_ALTIVEC"
425   "vavgu<VI_char> %0,%1,%2"
426   [(set_attr "type" "vecsimple")])
428 (define_insn "altivec_vavgs<VI_char>"
429   [(set (match_operand:VI 0 "register_operand" "=v")
430         (unspec:VI [(match_operand:VI 1 "register_operand" "v")
431                     (match_operand:VI 2 "register_operand" "v")]
432                    UNSPEC_VAVGS))]
433   "TARGET_ALTIVEC"
434   "vavgs<VI_char> %0,%1,%2"
435   [(set_attr "type" "vecsimple")])
437 (define_insn "altivec_vcmpbfp"
438   [(set (match_operand:V4SI 0 "register_operand" "=v")
439         (unspec:V4SI [(match_operand:V4SF 1 "register_operand" "v")
440                       (match_operand:V4SF 2 "register_operand" "v")] 
441                       UNSPEC_VCMPBFP))]
442   "TARGET_ALTIVEC"
443   "vcmpbfp %0,%1,%2"
444   [(set_attr "type" "veccmp")])
446 (define_insn "*altivec_eq<mode>"
447   [(set (match_operand:VI 0 "altivec_register_operand" "=v")
448         (eq:VI (match_operand:VI 1 "altivec_register_operand" "v")
449                (match_operand:VI 2 "altivec_register_operand" "v")))]
450   "TARGET_ALTIVEC"
451   "vcmpequ<VI_char> %0,%1,%2"
452   [(set_attr "type" "veccmp")])
454 (define_insn "*altivec_gt<mode>"
455   [(set (match_operand:VI 0 "altivec_register_operand" "=v")
456         (gt:VI (match_operand:VI 1 "altivec_register_operand" "v")
457                (match_operand:VI 2 "altivec_register_operand" "v")))]
458   "TARGET_ALTIVEC"
459   "vcmpgts<VI_char> %0,%1,%2"
460   [(set_attr "type" "veccmp")])
462 (define_insn "*altivec_gtu<mode>"
463   [(set (match_operand:VI 0 "altivec_register_operand" "=v")
464         (gtu:VI (match_operand:VI 1 "altivec_register_operand" "v")
465                 (match_operand:VI 2 "altivec_register_operand" "v")))]
466   "TARGET_ALTIVEC"
467   "vcmpgtu<VI_char> %0,%1,%2"
468   [(set_attr "type" "veccmp")])
470 (define_insn "*altivec_eqv4sf"
471   [(set (match_operand:V4SF 0 "altivec_register_operand" "=v")
472         (eq:V4SF (match_operand:V4SF 1 "altivec_register_operand" "v")
473                  (match_operand:V4SF 2 "altivec_register_operand" "v")))]
474   "VECTOR_UNIT_ALTIVEC_P (V4SFmode)"
475   "vcmpeqfp %0,%1,%2"
476   [(set_attr "type" "veccmp")])
478 (define_insn "*altivec_gtv4sf"
479   [(set (match_operand:V4SF 0 "altivec_register_operand" "=v")
480         (gt:V4SF (match_operand:V4SF 1 "altivec_register_operand" "v")
481                  (match_operand:V4SF 2 "altivec_register_operand" "v")))]
482   "VECTOR_UNIT_ALTIVEC_P (V4SFmode)"
483   "vcmpgtfp %0,%1,%2"
484   [(set_attr "type" "veccmp")])
486 (define_insn "*altivec_gev4sf"
487   [(set (match_operand:V4SF 0 "altivec_register_operand" "=v")
488         (ge:V4SF (match_operand:V4SF 1 "altivec_register_operand" "v")
489                  (match_operand:V4SF 2 "altivec_register_operand" "v")))]
490   "VECTOR_UNIT_ALTIVEC_P (V4SFmode)"
491   "vcmpgefp %0,%1,%2"
492   [(set_attr "type" "veccmp")])
494 (define_insn "*altivec_vsel<mode>"
495   [(set (match_operand:VM 0 "altivec_register_operand" "=v")
496         (if_then_else:VM
497          (ne:CC (match_operand:VM 1 "altivec_register_operand" "v")
498                 (const_int 0))
499          (match_operand:VM 2 "altivec_register_operand" "v")
500          (match_operand:VM 3 "altivec_register_operand" "v")))]
501   "VECTOR_MEM_ALTIVEC_P (<MODE>mode)"
502   "vsel %0,%3,%2,%1"
503   [(set_attr "type" "vecperm")])
505 (define_insn "*altivec_vsel<mode>_uns"
506   [(set (match_operand:VM 0 "altivec_register_operand" "=v")
507         (if_then_else:VM
508          (ne:CCUNS (match_operand:VM 1 "altivec_register_operand" "v")
509                    (const_int 0))
510          (match_operand:VM 2 "altivec_register_operand" "v")
511          (match_operand:VM 3 "altivec_register_operand" "v")))]
512   "VECTOR_MEM_ALTIVEC_P (<MODE>mode)"
513   "vsel %0,%3,%2,%1"
514   [(set_attr "type" "vecperm")])
516 ;; Fused multiply add
517 (define_insn "altivec_vmaddfp"
518   [(set (match_operand:V4SF 0 "register_operand" "=v")
519         (plus:V4SF (mult:V4SF (match_operand:V4SF 1 "register_operand" "v")
520                               (match_operand:V4SF 2 "register_operand" "v"))
521                    (match_operand:V4SF 3 "register_operand" "v")))]
522   "VECTOR_UNIT_ALTIVEC_P (V4SFmode)"
523   "vmaddfp %0,%1,%2,%3"
524   [(set_attr "type" "vecfloat")])
526 ;; We do multiply as a fused multiply-add with an add of a -0.0 vector.
528 (define_expand "altivec_mulv4sf3"
529   [(use (match_operand:V4SF 0 "register_operand" ""))
530    (use (match_operand:V4SF 1 "register_operand" ""))
531    (use (match_operand:V4SF 2 "register_operand" ""))]
532   "VECTOR_UNIT_ALTIVEC_P (V4SFmode) && TARGET_FUSED_MADD"
533   "
535   rtx neg0;
537   /* Generate [-0.0, -0.0, -0.0, -0.0].  */
538   neg0 = gen_reg_rtx (V4SImode);
539   emit_insn (gen_altivec_vspltisw (neg0, constm1_rtx));
540   emit_insn (gen_vashlv4si3 (neg0, neg0, neg0));
542   /* Use the multiply-add.  */
543   emit_insn (gen_altivec_vmaddfp (operands[0], operands[1], operands[2],
544                                   gen_lowpart (V4SFmode, neg0)));
545   DONE;
548 ;; 32-bit integer multiplication
549 ;; A_high = Operand_0 & 0xFFFF0000 >> 16
550 ;; A_low = Operand_0 & 0xFFFF
551 ;; B_high = Operand_1 & 0xFFFF0000 >> 16
552 ;; B_low = Operand_1 & 0xFFFF
553 ;; result = A_low * B_low + (A_high * B_low + B_high * A_low) << 16
555 ;; (define_insn "mulv4si3"
556 ;;   [(set (match_operand:V4SI 0 "register_operand" "=v")
557 ;;         (mult:V4SI (match_operand:V4SI 1 "register_operand" "v")
558 ;;                    (match_operand:V4SI 2 "register_operand" "v")))]
559 (define_expand "mulv4si3"
560   [(use (match_operand:V4SI 0 "register_operand" ""))
561    (use (match_operand:V4SI 1 "register_operand" ""))
562    (use (match_operand:V4SI 2 "register_operand" ""))]
563    "TARGET_ALTIVEC"
564    "
566    rtx zero;
567    rtx swap;
568    rtx small_swap;
569    rtx sixteen;
570    rtx one;
571    rtx two;
572    rtx low_product;
573    rtx high_product;
574        
575    zero = gen_reg_rtx (V4SImode);
576    emit_insn (gen_altivec_vspltisw (zero, const0_rtx));
578    sixteen = gen_reg_rtx (V4SImode);   
579    emit_insn (gen_altivec_vspltisw (sixteen,  gen_rtx_CONST_INT (V4SImode, -16)));
581    swap = gen_reg_rtx (V4SImode);
582    emit_insn (gen_vrotlv4si3 (swap, operands[2], sixteen));
584    one = gen_reg_rtx (V8HImode);
585    convert_move (one, operands[1], 0);
587    two = gen_reg_rtx (V8HImode);
588    convert_move (two, operands[2], 0);
590    small_swap = gen_reg_rtx (V8HImode);
591    convert_move (small_swap, swap, 0);
593    low_product = gen_reg_rtx (V4SImode);
594    emit_insn (gen_altivec_vmulouh (low_product, one, two));
596    high_product = gen_reg_rtx (V4SImode);
597    emit_insn (gen_altivec_vmsumuhm (high_product, one, small_swap, zero));
599    emit_insn (gen_vashlv4si3 (high_product, high_product, sixteen));
601    emit_insn (gen_addv4si3 (operands[0], high_product, low_product));
602    
603    DONE;
604  }")
606 (define_expand "mulv8hi3"
607   [(use (match_operand:V8HI 0 "register_operand" ""))
608    (use (match_operand:V8HI 1 "register_operand" ""))
609    (use (match_operand:V8HI 2 "register_operand" ""))]
610    "TARGET_ALTIVEC"
611    "
613    rtx odd = gen_reg_rtx (V4SImode);
614    rtx even = gen_reg_rtx (V4SImode);
615    rtx high = gen_reg_rtx (V4SImode);
616    rtx low = gen_reg_rtx (V4SImode);
618    emit_insn (gen_altivec_vmulesh (even, operands[1], operands[2]));
619    emit_insn (gen_altivec_vmulosh (odd, operands[1], operands[2]));
621    emit_insn (gen_altivec_vmrghw (high, even, odd));
622    emit_insn (gen_altivec_vmrglw (low, even, odd));
624    emit_insn (gen_altivec_vpkuwum (operands[0], high, low));
626    DONE;
629 ;; Fused multiply subtract 
630 (define_expand "altivec_vnmsubfp"
631   [(match_operand:V4SF 0 "register_operand" "")
632    (match_operand:V4SF 1 "register_operand" "")
633    (match_operand:V4SF 2 "register_operand" "")
634    (match_operand:V4SF 3 "register_operand" "")]
635   "VECTOR_UNIT_ALTIVEC_P (V4SFmode)"
637   if (TARGET_FUSED_MADD && HONOR_SIGNED_ZEROS (SFmode))
638     {
639        emit_insn (gen_altivec_vnmsubfp_1 (operands[0], operands[1],
640                                           operands[2], operands[3]));
641        DONE;
642     }
643   else if (TARGET_FUSED_MADD && !HONOR_SIGNED_ZEROS (DFmode))
644     {
645        emit_insn (gen_altivec_vnmsubfp_2 (operands[0], operands[1],
646                                           operands[2], operands[3]));
647        DONE;
648     }
649   else
650     {
651        emit_insn (gen_altivec_vnmsubfp_3 (operands[0], operands[1],
652                                           operands[2], operands[3]));
653        DONE;
654     }
657 (define_insn "altivec_vnmsubfp_1"
658   [(set (match_operand:V4SF 0 "register_operand" "=v")
659         (neg:V4SF
660          (minus:V4SF
661           (mult:V4SF
662            (match_operand:V4SF 1 "register_operand" "v")
663            (match_operand:V4SF 2 "register_operand" "v"))
664           (match_operand:V4SF 3 "register_operand" "v"))))]
665   "VECTOR_UNIT_ALTIVEC_P (V4SFmode) && TARGET_FUSED_MADD
666    && HONOR_SIGNED_ZEROS (SFmode)"
667   "vnmsubfp %0,%1,%2,%3"
668   [(set_attr "type" "vecfloat")])
670 (define_insn "altivec_vnmsubfp_2"
671   [(set (match_operand:V4SF 0 "register_operand" "=v")
672         (minus:V4SF
673          (match_operand:V4SF 3 "register_operand" "v")
674          (mult:V4SF
675           (match_operand:V4SF 1 "register_operand" "v")
676           (match_operand:V4SF 2 "register_operand" "v"))))]
677   "VECTOR_UNIT_ALTIVEC_P (V4SFmode) && TARGET_FUSED_MADD
678    && !HONOR_SIGNED_ZEROS (SFmode)"
679   "vnmsubfp %0,%1,%2,%3"
680   [(set_attr "type" "vecfloat")])
682 (define_insn "altivec_vnmsubfp_3"
683   [(set (match_operand:V4SF 0 "register_operand" "=v")
684         (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "v")
685                        (match_operand:V4SF 2 "register_operand" "v")
686                        (match_operand:V4SF 3 "register_operand" "v")]
687                       UNSPEC_VNMSUBFP))]
688   "VECTOR_UNIT_ALTIVEC_P (V4SFmode)"
689   "vnmsubfp %0,%1,%2,%3"
690   [(set_attr "type" "vecfloat")])
692 (define_insn "altivec_vmsumu<VI_char>m"
693   [(set (match_operand:V4SI 0 "register_operand" "=v")
694         (unspec:V4SI [(match_operand:VIshort 1 "register_operand" "v")
695                       (match_operand:VIshort 2 "register_operand" "v")
696                       (match_operand:V4SI 3 "register_operand" "v")]
697                      UNSPEC_VMSUMU))]
698   "TARGET_ALTIVEC"
699   "vmsumu<VI_char>m %0,%1,%2,%3"
700   [(set_attr "type" "veccomplex")])
702 (define_insn "altivec_vmsumm<VI_char>m"
703   [(set (match_operand:V4SI 0 "register_operand" "=v")
704         (unspec:V4SI [(match_operand:VIshort 1 "register_operand" "v")
705                       (match_operand:VIshort 2 "register_operand" "v")
706                       (match_operand:V4SI 3 "register_operand" "v")]
707                      UNSPEC_VMSUMM))]
708   "TARGET_ALTIVEC"
709   "vmsumm<VI_char>m %0,%1,%2,%3"
710   [(set_attr "type" "veccomplex")])
712 (define_insn "altivec_vmsumshm"
713   [(set (match_operand:V4SI 0 "register_operand" "=v")
714         (unspec:V4SI [(match_operand:V8HI 1 "register_operand" "v")
715                       (match_operand:V8HI 2 "register_operand" "v")
716                       (match_operand:V4SI 3 "register_operand" "v")]
717                      UNSPEC_VMSUMSHM))]
718   "TARGET_ALTIVEC"
719   "vmsumshm %0,%1,%2,%3"
720   [(set_attr "type" "veccomplex")])
722 (define_insn "altivec_vmsumuhs"
723   [(set (match_operand:V4SI 0 "register_operand" "=v")
724         (unspec:V4SI [(match_operand:V8HI 1 "register_operand" "v")
725                       (match_operand:V8HI 2 "register_operand" "v")
726                       (match_operand:V4SI 3 "register_operand" "v")]
727                      UNSPEC_VMSUMUHS))
728    (set (reg:SI 110) (unspec:SI [(const_int 0)] UNSPEC_SET_VSCR))]
729   "TARGET_ALTIVEC"
730   "vmsumuhs %0,%1,%2,%3"
731   [(set_attr "type" "veccomplex")])
733 (define_insn "altivec_vmsumshs"
734   [(set (match_operand:V4SI 0 "register_operand" "=v")
735         (unspec:V4SI [(match_operand:V8HI 1 "register_operand" "v")
736                       (match_operand:V8HI 2 "register_operand" "v")
737                       (match_operand:V4SI 3 "register_operand" "v")]
738                      UNSPEC_VMSUMSHS))
739    (set (reg:SI 110) (unspec:SI [(const_int 0)] UNSPEC_SET_VSCR))]
740   "TARGET_ALTIVEC"
741   "vmsumshs %0,%1,%2,%3"
742   [(set_attr "type" "veccomplex")])
744 ;; max
746 (define_insn "umax<mode>3"
747   [(set (match_operand:VI 0 "register_operand" "=v")
748         (umax:VI (match_operand:VI 1 "register_operand" "v")
749                  (match_operand:VI 2 "register_operand" "v")))]
750   "TARGET_ALTIVEC"
751   "vmaxu<VI_char> %0,%1,%2"
752   [(set_attr "type" "vecsimple")])
754 (define_insn "smax<mode>3"
755   [(set (match_operand:VI 0 "register_operand" "=v")
756         (smax:VI (match_operand:VI 1 "register_operand" "v")
757                  (match_operand:VI 2 "register_operand" "v")))]
758   "TARGET_ALTIVEC"
759   "vmaxs<VI_char> %0,%1,%2"
760   [(set_attr "type" "vecsimple")])
762 (define_insn "*altivec_smaxv4sf3"
763   [(set (match_operand:V4SF 0 "register_operand" "=v")
764         (smax:V4SF (match_operand:V4SF 1 "register_operand" "v")
765                    (match_operand:V4SF 2 "register_operand" "v")))]
766   "VECTOR_UNIT_ALTIVEC_P (V4SFmode)"
767   "vmaxfp %0,%1,%2"
768   [(set_attr "type" "veccmp")])
770 (define_insn "umin<mode>3"
771   [(set (match_operand:VI 0 "register_operand" "=v")
772         (umin:VI (match_operand:VI 1 "register_operand" "v")
773                  (match_operand:VI 2 "register_operand" "v")))]
774   "TARGET_ALTIVEC"
775   "vminu<VI_char> %0,%1,%2"
776   [(set_attr "type" "vecsimple")])
778 (define_insn "smin<mode>3"
779   [(set (match_operand:VI 0 "register_operand" "=v")
780         (smin:VI (match_operand:VI 1 "register_operand" "v")
781                  (match_operand:VI 2 "register_operand" "v")))]
782   "TARGET_ALTIVEC"
783   "vmins<VI_char> %0,%1,%2"
784   [(set_attr "type" "vecsimple")])
786 (define_insn "*altivec_sminv4sf3"
787   [(set (match_operand:V4SF 0 "register_operand" "=v")
788         (smin:V4SF (match_operand:V4SF 1 "register_operand" "v")
789                    (match_operand:V4SF 2 "register_operand" "v")))]
790   "VECTOR_UNIT_ALTIVEC_P (V4SFmode)"
791   "vminfp %0,%1,%2"
792   [(set_attr "type" "veccmp")])
794 (define_insn "altivec_vmhaddshs"
795   [(set (match_operand:V8HI 0 "register_operand" "=v")
796         (unspec:V8HI [(match_operand:V8HI 1 "register_operand" "v")
797                       (match_operand:V8HI 2 "register_operand" "v")
798                       (match_operand:V8HI 3 "register_operand" "v")]
799                      UNSPEC_VMHADDSHS))
800    (set (reg:SI 110) (unspec:SI [(const_int 0)] UNSPEC_SET_VSCR))]
801   "TARGET_ALTIVEC"
802   "vmhaddshs %0,%1,%2,%3"
803   [(set_attr "type" "veccomplex")])
805 (define_insn "altivec_vmhraddshs"
806   [(set (match_operand:V8HI 0 "register_operand" "=v")
807         (unspec:V8HI [(match_operand:V8HI 1 "register_operand" "v")
808                       (match_operand:V8HI 2 "register_operand" "v")
809                       (match_operand:V8HI 3 "register_operand" "v")]
810                      UNSPEC_VMHRADDSHS))
811    (set (reg:SI 110) (unspec:SI [(const_int 0)] UNSPEC_SET_VSCR))]
812   "TARGET_ALTIVEC"
813   "vmhraddshs %0,%1,%2,%3"
814   [(set_attr "type" "veccomplex")])
816 (define_insn "altivec_vmladduhm"
817   [(set (match_operand:V8HI 0 "register_operand" "=v")
818         (unspec:V8HI [(match_operand:V8HI 1 "register_operand" "v")
819                       (match_operand:V8HI 2 "register_operand" "v")
820                       (match_operand:V8HI 3 "register_operand" "v")]
821                      UNSPEC_VMLADDUHM))]
822   "TARGET_ALTIVEC"
823   "vmladduhm %0,%1,%2,%3"
824   [(set_attr "type" "veccomplex")])
826 (define_insn "altivec_vmrghb"
827   [(set (match_operand:V16QI 0 "register_operand" "=v")
828         (vec_merge:V16QI (vec_select:V16QI (match_operand:V16QI 1 "register_operand" "v")
829                                            (parallel [(const_int 0)
830                                                       (const_int 8)
831                                                       (const_int 1)
832                                                       (const_int 9)
833                                                       (const_int 2)
834                                                       (const_int 10)
835                                                       (const_int 3)
836                                                       (const_int 11)
837                                                       (const_int 4)
838                                                       (const_int 12)
839                                                       (const_int 5)
840                                                       (const_int 13)
841                                                       (const_int 6)
842                                                       (const_int 14)
843                                                       (const_int 7)
844                                                       (const_int 15)]))
845                         (vec_select:V16QI (match_operand:V16QI 2 "register_operand" "v")
846                                            (parallel [(const_int 8)
847                                                       (const_int 0)
848                                                       (const_int 9)
849                                                       (const_int 1)
850                                                       (const_int 10)
851                                                       (const_int 2)
852                                                       (const_int 11)
853                                                       (const_int 3)
854                                                       (const_int 12)
855                                                       (const_int 4)
856                                                       (const_int 13)
857                                                       (const_int 5)
858                                                       (const_int 14)
859                                                       (const_int 6)
860                                                       (const_int 15)
861                                                       (const_int 7)]))
862                       (const_int 21845)))]
863   "TARGET_ALTIVEC"
864   "vmrghb %0,%1,%2"
865   [(set_attr "type" "vecperm")])
867 (define_insn "altivec_vmrghh"
868   [(set (match_operand:V8HI 0 "register_operand" "=v")
869         (vec_merge:V8HI (vec_select:V8HI (match_operand:V8HI 1 "register_operand" "v")
870                                            (parallel [(const_int 0)
871                                                       (const_int 4)
872                                                       (const_int 1)
873                                                       (const_int 5)
874                                                       (const_int 2)
875                                                       (const_int 6)
876                                                       (const_int 3)
877                                                       (const_int 7)]))
878                         (vec_select:V8HI (match_operand:V8HI 2 "register_operand" "v")
879                                            (parallel [(const_int 4)
880                                                       (const_int 0)
881                                                       (const_int 5)
882                                                       (const_int 1)
883                                                       (const_int 6)
884                                                       (const_int 2)
885                                                       (const_int 7)
886                                                       (const_int 3)]))
887                       (const_int 85)))]
888   "TARGET_ALTIVEC"
889   "vmrghh %0,%1,%2"
890   [(set_attr "type" "vecperm")])
892 (define_insn "altivec_vmrghw"
893   [(set (match_operand:V4SI 0 "register_operand" "=v")
894         (vec_merge:V4SI (vec_select:V4SI (match_operand:V4SI 1 "register_operand" "v")
895                                          (parallel [(const_int 0)
896                                                     (const_int 2)
897                                                     (const_int 1)
898                                                     (const_int 3)]))
899                         (vec_select:V4SI (match_operand:V4SI 2 "register_operand" "v")
900                                          (parallel [(const_int 2)
901                                                     (const_int 0)
902                                                     (const_int 3)
903                                                     (const_int 1)]))
904                       (const_int 5)))]
905   "VECTOR_MEM_ALTIVEC_P (V4SImode)"
906   "vmrghw %0,%1,%2"
907   [(set_attr "type" "vecperm")])
909 (define_insn "*altivec_vmrghsf"
910   [(set (match_operand:V4SF 0 "register_operand" "=v")
911         (vec_merge:V4SF (vec_select:V4SF (match_operand:V4SF 1 "register_operand" "v")
912                                          (parallel [(const_int 0)
913                                                     (const_int 2)
914                                                     (const_int 1)
915                                                     (const_int 3)]))
916                         (vec_select:V4SF (match_operand:V4SF 2 "register_operand" "v")
917                                          (parallel [(const_int 2)
918                                                     (const_int 0)
919                                                     (const_int 3)
920                                                     (const_int 1)]))
921                       (const_int 5)))]
922   "VECTOR_MEM_ALTIVEC_P (V4SFmode)"
923   "vmrghw %0,%1,%2"
924   [(set_attr "type" "vecperm")])
926 (define_insn "altivec_vmrglb"
927   [(set (match_operand:V16QI 0 "register_operand" "=v")
928         (vec_merge:V16QI (vec_select:V16QI (match_operand:V16QI 1 "register_operand" "v")
929                                            (parallel [(const_int 8)
930                                                       (const_int 0)
931                                                       (const_int 9)
932                                                       (const_int 1)
933                                                       (const_int 10)
934                                                       (const_int 2)
935                                                       (const_int 11)
936                                                       (const_int 3)
937                                                       (const_int 12)
938                                                       (const_int 4)
939                                                       (const_int 13)
940                                                       (const_int 5)
941                                                       (const_int 14)
942                                                       (const_int 6)
943                                                       (const_int 15)
944                                                       (const_int 7)]))
945                       (vec_select:V16QI (match_operand:V16QI 2 "register_operand" "v")
946                                            (parallel [(const_int 0)
947                                                       (const_int 8)
948                                                       (const_int 1)
949                                                       (const_int 9)
950                                                       (const_int 2)
951                                                       (const_int 10)
952                                                       (const_int 3)
953                                                       (const_int 11)
954                                                       (const_int 4)
955                                                       (const_int 12)
956                                                       (const_int 5)
957                                                       (const_int 13)
958                                                       (const_int 6)
959                                                       (const_int 14)
960                                                       (const_int 7)
961                                                       (const_int 15)]))
962                       (const_int 21845)))]
963   "TARGET_ALTIVEC"
964   "vmrglb %0,%1,%2"
965   [(set_attr "type" "vecperm")])
967 (define_insn "altivec_vmrglh"
968   [(set (match_operand:V8HI 0 "register_operand" "=v")
969         (vec_merge:V8HI (vec_select:V8HI (match_operand:V8HI 1 "register_operand" "v")
970                                            (parallel [(const_int 4)
971                                                       (const_int 0)
972                                                       (const_int 5)
973                                                       (const_int 1)
974                                                       (const_int 6)
975                                                       (const_int 2)
976                                                       (const_int 7)
977                                                       (const_int 3)]))
978                         (vec_select:V8HI (match_operand:V8HI 2 "register_operand" "v")
979                                            (parallel [(const_int 0)
980                                                       (const_int 4)
981                                                       (const_int 1)
982                                                       (const_int 5)
983                                                       (const_int 2)
984                                                       (const_int 6)
985                                                       (const_int 3)
986                                                       (const_int 7)]))
987                       (const_int 85)))]
988   "TARGET_ALTIVEC"
989   "vmrglh %0,%1,%2"
990   [(set_attr "type" "vecperm")])
992 (define_insn "altivec_vmrglw"
993   [(set (match_operand:V4SI 0 "register_operand" "=v")
994         (vec_merge:V4SI
995          (vec_select:V4SI (match_operand:V4SI 1 "register_operand" "v")
996                           (parallel [(const_int 2)
997                                      (const_int 0)
998                                      (const_int 3)
999                                      (const_int 1)]))
1000          (vec_select:V4SI (match_operand:V4SI 2 "register_operand" "v")
1001                           (parallel [(const_int 0)
1002                                      (const_int 2)
1003                                      (const_int 1)
1004                                      (const_int 3)]))
1005          (const_int 5)))]
1006   "VECTOR_MEM_ALTIVEC_P (V4SImode)"
1007   "vmrglw %0,%1,%2"
1008   [(set_attr "type" "vecperm")])
1010 (define_insn "*altivec_vmrglsf"
1011   [(set (match_operand:V4SF 0 "register_operand" "=v")
1012         (vec_merge:V4SF
1013          (vec_select:V4SF (match_operand:V4SF 1 "register_operand" "v")
1014                           (parallel [(const_int 2)
1015                                      (const_int 0)
1016                                      (const_int 3)
1017                                      (const_int 1)]))
1018          (vec_select:V4SF (match_operand:V4SF 2 "register_operand" "v")
1019                           (parallel [(const_int 0)
1020                                      (const_int 2)
1021                                      (const_int 1)
1022                                      (const_int 3)]))
1023          (const_int 5)))]
1024   "VECTOR_MEM_ALTIVEC_P (V4SFmode)"
1025   "vmrglw %0,%1,%2"
1026   [(set_attr "type" "vecperm")])
1028 (define_insn "altivec_vmuleub"
1029   [(set (match_operand:V8HI 0 "register_operand" "=v")
1030         (unspec:V8HI [(match_operand:V16QI 1 "register_operand" "v")
1031                       (match_operand:V16QI 2 "register_operand" "v")]
1032                      UNSPEC_VMULEUB))]
1033   "TARGET_ALTIVEC"
1034   "vmuleub %0,%1,%2"
1035   [(set_attr "type" "veccomplex")])
1037 (define_insn "altivec_vmulesb"
1038   [(set (match_operand:V8HI 0 "register_operand" "=v")
1039         (unspec:V8HI [(match_operand:V16QI 1 "register_operand" "v")
1040                       (match_operand:V16QI 2 "register_operand" "v")]
1041                      UNSPEC_VMULESB))]
1042   "TARGET_ALTIVEC"
1043   "vmulesb %0,%1,%2"
1044   [(set_attr "type" "veccomplex")])
1046 (define_insn "altivec_vmuleuh"
1047   [(set (match_operand:V4SI 0 "register_operand" "=v")
1048         (unspec:V4SI [(match_operand:V8HI 1 "register_operand" "v")
1049                       (match_operand:V8HI 2 "register_operand" "v")]
1050                      UNSPEC_VMULEUH))]
1051   "TARGET_ALTIVEC"
1052   "vmuleuh %0,%1,%2"
1053   [(set_attr "type" "veccomplex")])
1055 (define_insn "altivec_vmulesh"
1056   [(set (match_operand:V4SI 0 "register_operand" "=v")
1057         (unspec:V4SI [(match_operand:V8HI 1 "register_operand" "v")
1058                       (match_operand:V8HI 2 "register_operand" "v")]
1059                      UNSPEC_VMULESH))]
1060   "TARGET_ALTIVEC"
1061   "vmulesh %0,%1,%2"
1062   [(set_attr "type" "veccomplex")])
1064 (define_insn "altivec_vmuloub"
1065   [(set (match_operand:V8HI 0 "register_operand" "=v")
1066         (unspec:V8HI [(match_operand:V16QI 1 "register_operand" "v")
1067                       (match_operand:V16QI 2 "register_operand" "v")]
1068                      UNSPEC_VMULOUB))]
1069   "TARGET_ALTIVEC"
1070   "vmuloub %0,%1,%2"
1071   [(set_attr "type" "veccomplex")])
1073 (define_insn "altivec_vmulosb"
1074   [(set (match_operand:V8HI 0 "register_operand" "=v")
1075         (unspec:V8HI [(match_operand:V16QI 1 "register_operand" "v")
1076                       (match_operand:V16QI 2 "register_operand" "v")]
1077                      UNSPEC_VMULOSB))]
1078   "TARGET_ALTIVEC"
1079   "vmulosb %0,%1,%2"
1080   [(set_attr "type" "veccomplex")])
1082 (define_insn "altivec_vmulouh"
1083   [(set (match_operand:V4SI 0 "register_operand" "=v")
1084         (unspec:V4SI [(match_operand:V8HI 1 "register_operand" "v")
1085                       (match_operand:V8HI 2 "register_operand" "v")]
1086                      UNSPEC_VMULOUH))]
1087   "TARGET_ALTIVEC"
1088   "vmulouh %0,%1,%2"
1089   [(set_attr "type" "veccomplex")])
1091 (define_insn "altivec_vmulosh"
1092   [(set (match_operand:V4SI 0 "register_operand" "=v")
1093         (unspec:V4SI [(match_operand:V8HI 1 "register_operand" "v")
1094                       (match_operand:V8HI 2 "register_operand" "v")]
1095                      UNSPEC_VMULOSH))]
1096   "TARGET_ALTIVEC"
1097   "vmulosh %0,%1,%2"
1098   [(set_attr "type" "veccomplex")])
1101 ;; logical ops.  Have the logical ops follow the memory ops in
1102 ;; terms of whether to prefer VSX or Altivec
1104 (define_insn "*altivec_and<mode>3"
1105   [(set (match_operand:VM 0 "register_operand" "=v")
1106         (and:VM (match_operand:VM 1 "register_operand" "v")
1107                 (match_operand:VM 2 "register_operand" "v")))]
1108   "VECTOR_MEM_ALTIVEC_P (<MODE>mode)"
1109   "vand %0,%1,%2"
1110   [(set_attr "type" "vecsimple")])
1112 (define_insn "*altivec_ior<mode>3"
1113   [(set (match_operand:VM 0 "register_operand" "=v")
1114         (ior:VM (match_operand:VM 1 "register_operand" "v")
1115                 (match_operand:VM 2 "register_operand" "v")))]
1116   "VECTOR_MEM_ALTIVEC_P (<MODE>mode)"
1117   "vor %0,%1,%2"
1118   [(set_attr "type" "vecsimple")])
1120 (define_insn "*altivec_xor<mode>3"
1121   [(set (match_operand:VM 0 "register_operand" "=v")
1122         (xor:VM (match_operand:VM 1 "register_operand" "v")
1123                 (match_operand:VM 2 "register_operand" "v")))]
1124   "VECTOR_MEM_ALTIVEC_P (<MODE>mode)"
1125   "vxor %0,%1,%2"
1126   [(set_attr "type" "vecsimple")])
1128 (define_insn "*altivec_one_cmpl<mode>2"
1129   [(set (match_operand:VM 0 "register_operand" "=v")
1130         (not:VM (match_operand:VM 1 "register_operand" "v")))]
1131   "VECTOR_MEM_ALTIVEC_P (<MODE>mode)"
1132   "vnor %0,%1,%1"
1133   [(set_attr "type" "vecsimple")])
1134   
1135 (define_insn "*altivec_nor<mode>3"
1136   [(set (match_operand:VM 0 "register_operand" "=v")
1137         (not:VM (ior:VM (match_operand:VM 1 "register_operand" "v")
1138                         (match_operand:VM 2 "register_operand" "v"))))]
1139   "VECTOR_MEM_ALTIVEC_P (<MODE>mode)"
1140   "vnor %0,%1,%2"
1141   [(set_attr "type" "vecsimple")])
1143 (define_insn "*altivec_andc<mode>3"
1144   [(set (match_operand:VM 0 "register_operand" "=v")
1145         (and:VM (not:VM (match_operand:VM 2 "register_operand" "v"))
1146                 (match_operand:VM 1 "register_operand" "v")))]
1147   "VECTOR_MEM_ALTIVEC_P (<MODE>mode)"
1148   "vandc %0,%1,%2"
1149   [(set_attr "type" "vecsimple")])
1151 (define_insn "altivec_vpkuhum"
1152   [(set (match_operand:V16QI 0 "register_operand" "=v")
1153         (unspec:V16QI [(match_operand:V8HI 1 "register_operand" "v")
1154                        (match_operand:V8HI 2 "register_operand" "v")]
1155                       UNSPEC_VPKUHUM))]
1156   "TARGET_ALTIVEC"
1157   "vpkuhum %0,%1,%2"
1158   [(set_attr "type" "vecperm")])
1160 (define_insn "altivec_vpkuwum"
1161   [(set (match_operand:V8HI 0 "register_operand" "=v")
1162         (unspec:V8HI [(match_operand:V4SI 1 "register_operand" "v")
1163                       (match_operand:V4SI 2 "register_operand" "v")]
1164                      UNSPEC_VPKUWUM))]
1165   "TARGET_ALTIVEC"
1166   "vpkuwum %0,%1,%2"
1167   [(set_attr "type" "vecperm")])
1169 (define_insn "altivec_vpkpx"
1170   [(set (match_operand:V8HI 0 "register_operand" "=v")
1171         (unspec:V8HI [(match_operand:V4SI 1 "register_operand" "v")
1172                       (match_operand:V4SI 2 "register_operand" "v")]
1173                      UNSPEC_VPKPX))]
1174   "TARGET_ALTIVEC"
1175   "vpkpx %0,%1,%2"
1176   [(set_attr "type" "vecperm")])
1178 (define_insn "altivec_vpkshss"
1179   [(set (match_operand:V16QI 0 "register_operand" "=v")
1180         (unspec:V16QI [(match_operand:V8HI 1 "register_operand" "v")
1181                        (match_operand:V8HI 2 "register_operand" "v")]
1182                       UNSPEC_VPKSHSS))
1183    (set (reg:SI 110) (unspec:SI [(const_int 0)] UNSPEC_SET_VSCR))]
1184   "TARGET_ALTIVEC"
1185   "vpkshss %0,%1,%2"
1186   [(set_attr "type" "vecperm")])
1188 (define_insn "altivec_vpkswss"
1189   [(set (match_operand:V8HI 0 "register_operand" "=v")
1190         (unspec:V8HI [(match_operand:V4SI 1 "register_operand" "v")
1191                       (match_operand:V4SI 2 "register_operand" "v")]
1192                      UNSPEC_VPKSWSS))
1193    (set (reg:SI 110) (unspec:SI [(const_int 0)] UNSPEC_SET_VSCR))]
1194   "TARGET_ALTIVEC"
1195   "vpkswss %0,%1,%2"
1196   [(set_attr "type" "vecperm")])
1198 (define_insn "altivec_vpkuhus"
1199   [(set (match_operand:V16QI 0 "register_operand" "=v")
1200         (unspec:V16QI [(match_operand:V8HI 1 "register_operand" "v")
1201                        (match_operand:V8HI 2 "register_operand" "v")]
1202                       UNSPEC_VPKUHUS))
1203    (set (reg:SI 110) (unspec:SI [(const_int 0)] UNSPEC_SET_VSCR))]
1204   "TARGET_ALTIVEC"
1205   "vpkuhus %0,%1,%2"
1206   [(set_attr "type" "vecperm")])
1208 (define_insn "altivec_vpkshus"
1209   [(set (match_operand:V16QI 0 "register_operand" "=v")
1210         (unspec:V16QI [(match_operand:V8HI 1 "register_operand" "v")
1211                        (match_operand:V8HI 2 "register_operand" "v")]
1212                       UNSPEC_VPKSHUS))
1213    (set (reg:SI 110) (unspec:SI [(const_int 0)] UNSPEC_SET_VSCR))]
1214   "TARGET_ALTIVEC"
1215   "vpkshus %0,%1,%2"
1216   [(set_attr "type" "vecperm")])
1218 (define_insn "altivec_vpkuwus"
1219   [(set (match_operand:V8HI 0 "register_operand" "=v")
1220         (unspec:V8HI [(match_operand:V4SI 1 "register_operand" "v")
1221                       (match_operand:V4SI 2 "register_operand" "v")]
1222                      UNSPEC_VPKUWUS))
1223    (set (reg:SI 110) (unspec:SI [(const_int 0)] UNSPEC_SET_VSCR))]
1224   "TARGET_ALTIVEC"
1225   "vpkuwus %0,%1,%2"
1226   [(set_attr "type" "vecperm")])
1228 (define_insn "altivec_vpkswus"
1229   [(set (match_operand:V8HI 0 "register_operand" "=v")
1230         (unspec:V8HI [(match_operand:V4SI 1 "register_operand" "v")
1231                       (match_operand:V4SI 2 "register_operand" "v")]
1232                      UNSPEC_VPKSWUS))
1233    (set (reg:SI 110) (unspec:SI [(const_int 0)] UNSPEC_SET_VSCR))]
1234   "TARGET_ALTIVEC"
1235   "vpkswus %0,%1,%2"
1236   [(set_attr "type" "vecperm")])
1238 (define_insn "*altivec_vrl<VI_char>"
1239   [(set (match_operand:VI 0 "register_operand" "=v")
1240         (rotate:VI (match_operand:VI 1 "register_operand" "v")
1241                    (match_operand:VI 2 "register_operand" "v")))]
1242   "TARGET_ALTIVEC"
1243   "vrl<VI_char> %0,%1,%2"
1244   [(set_attr "type" "vecsimple")])
1246 (define_insn "altivec_vsl"
1247   [(set (match_operand:V4SI 0 "register_operand" "=v")
1248         (unspec:V4SI [(match_operand:V4SI 1 "register_operand" "v")
1249                       (match_operand:V4SI 2 "register_operand" "v")]
1250                      UNSPEC_VSLV4SI))]
1251   "TARGET_ALTIVEC"
1252   "vsl %0,%1,%2"
1253   [(set_attr "type" "vecperm")])
1255 (define_insn "altivec_vslo"
1256   [(set (match_operand:V4SI 0 "register_operand" "=v")
1257         (unspec:V4SI [(match_operand:V4SI 1 "register_operand" "v")
1258                       (match_operand:V4SI 2 "register_operand" "v")]
1259                      UNSPEC_VSLO))]
1260   "TARGET_ALTIVEC"
1261   "vslo %0,%1,%2"
1262   [(set_attr "type" "vecperm")])
1264 (define_insn "*altivec_vsl<VI_char>"
1265   [(set (match_operand:VI 0 "register_operand" "=v")
1266         (ashift:VI (match_operand:VI 1 "register_operand" "v")
1267                    (match_operand:VI 2 "register_operand" "v")))]
1268   "TARGET_ALTIVEC"
1269   "vsl<VI_char> %0,%1,%2"
1270   [(set_attr "type" "vecsimple")])
1272 (define_insn "*altivec_vsr<VI_char>"
1273   [(set (match_operand:VI 0 "register_operand" "=v")
1274         (lshiftrt:VI (match_operand:VI 1 "register_operand" "v")
1275                      (match_operand:VI 2 "register_operand" "v")))]
1276   "TARGET_ALTIVEC"
1277   "vsr<VI_char> %0,%1,%2"
1278   [(set_attr "type" "vecsimple")])
1280 (define_insn "*altivec_vsra<VI_char>"
1281   [(set (match_operand:VI 0 "register_operand" "=v")
1282         (ashiftrt:VI (match_operand:VI 1 "register_operand" "v")
1283                      (match_operand:VI 2 "register_operand" "v")))]
1284   "TARGET_ALTIVEC"
1285   "vsra<VI_char> %0,%1,%2"
1286   [(set_attr "type" "vecsimple")])
1288 (define_insn "altivec_vsr"
1289   [(set (match_operand:V4SI 0 "register_operand" "=v")
1290         (unspec:V4SI [(match_operand:V4SI 1 "register_operand" "v")
1291                       (match_operand:V4SI 2 "register_operand" "v")]
1292                      UNSPEC_VSR))]
1293   "TARGET_ALTIVEC"
1294   "vsr %0,%1,%2"
1295   [(set_attr "type" "vecperm")])
1297 (define_insn "altivec_vsro"
1298   [(set (match_operand:V4SI 0 "register_operand" "=v")
1299         (unspec:V4SI [(match_operand:V4SI 1 "register_operand" "v")
1300                       (match_operand:V4SI 2 "register_operand" "v")]
1301                      UNSPEC_VSRO))]
1302   "TARGET_ALTIVEC"
1303   "vsro %0,%1,%2"
1304   [(set_attr "type" "vecperm")])
1306 (define_insn "altivec_vsum4ubs"
1307   [(set (match_operand:V4SI 0 "register_operand" "=v")
1308         (unspec:V4SI [(match_operand:V16QI 1 "register_operand" "v")
1309                       (match_operand:V4SI 2 "register_operand" "v")]
1310                      UNSPEC_VSUM4UBS))
1311    (set (reg:SI 110) (unspec:SI [(const_int 0)] UNSPEC_SET_VSCR))]
1312   "TARGET_ALTIVEC"
1313   "vsum4ubs %0,%1,%2"
1314   [(set_attr "type" "veccomplex")])
1316 (define_insn "altivec_vsum4s<VI_char>s"
1317   [(set (match_operand:V4SI 0 "register_operand" "=v")
1318         (unspec:V4SI [(match_operand:VIshort 1 "register_operand" "v")
1319                       (match_operand:V4SI 2 "register_operand" "v")]
1320                      UNSPEC_VSUM4S))
1321    (set (reg:SI 110) (unspec:SI [(const_int 0)] UNSPEC_SET_VSCR))]
1322   "TARGET_ALTIVEC"
1323   "vsum4s<VI_char>s %0,%1,%2"
1324   [(set_attr "type" "veccomplex")])
1326 (define_insn "altivec_vsum2sws"
1327   [(set (match_operand:V4SI 0 "register_operand" "=v")
1328         (unspec:V4SI [(match_operand:V4SI 1 "register_operand" "v")
1329                       (match_operand:V4SI 2 "register_operand" "v")]
1330                      UNSPEC_VSUM2SWS))
1331    (set (reg:SI 110) (unspec:SI [(const_int 0)] UNSPEC_SET_VSCR))]
1332   "TARGET_ALTIVEC"
1333   "vsum2sws %0,%1,%2"
1334   [(set_attr "type" "veccomplex")])
1336 (define_insn "altivec_vsumsws"
1337   [(set (match_operand:V4SI 0 "register_operand" "=v")
1338         (unspec:V4SI [(match_operand:V4SI 1 "register_operand" "v")
1339                       (match_operand:V4SI 2 "register_operand" "v")]
1340                      UNSPEC_VSUMSWS))
1341    (set (reg:SI 110) (unspec:SI [(const_int 0)] UNSPEC_SET_VSCR))]
1342   "TARGET_ALTIVEC"
1343   "vsumsws %0,%1,%2"
1344   [(set_attr "type" "veccomplex")])
1346 (define_insn "altivec_vspltb"
1347   [(set (match_operand:V16QI 0 "register_operand" "=v")
1348         (vec_duplicate:V16QI
1349          (vec_select:QI (match_operand:V16QI 1 "register_operand" "v")
1350                         (parallel
1351                          [(match_operand:QI 2 "u5bit_cint_operand" "")]))))]
1352   "TARGET_ALTIVEC"
1353   "vspltb %0,%1,%2"
1354   [(set_attr "type" "vecperm")])
1356 (define_insn "altivec_vsplth"
1357   [(set (match_operand:V8HI 0 "register_operand" "=v")
1358         (vec_duplicate:V8HI
1359          (vec_select:HI (match_operand:V8HI 1 "register_operand" "v")
1360                         (parallel
1361                          [(match_operand:QI 2 "u5bit_cint_operand" "")]))))]
1362   "TARGET_ALTIVEC"
1363   "vsplth %0,%1,%2"
1364   [(set_attr "type" "vecperm")])
1366 (define_insn "altivec_vspltw"
1367   [(set (match_operand:V4SI 0 "register_operand" "=v")
1368         (vec_duplicate:V4SI
1369          (vec_select:SI (match_operand:V4SI 1 "register_operand" "v")
1370                         (parallel
1371                          [(match_operand:QI 2 "u5bit_cint_operand" "i")]))))]
1372   "TARGET_ALTIVEC"
1373   "vspltw %0,%1,%2"
1374   [(set_attr "type" "vecperm")])
1376 (define_insn "altivec_vspltsf"
1377   [(set (match_operand:V4SF 0 "register_operand" "=v")
1378         (vec_duplicate:V4SF
1379          (vec_select:SF (match_operand:V4SF 1 "register_operand" "v")
1380                         (parallel
1381                          [(match_operand:QI 2 "u5bit_cint_operand" "i")]))))]
1382   "VECTOR_UNIT_ALTIVEC_P (V4SFmode)"
1383   "vspltw %0,%1,%2"
1384   [(set_attr "type" "vecperm")])
1386 (define_insn "altivec_vspltis<VI_char>"
1387   [(set (match_operand:VI 0 "register_operand" "=v")
1388         (vec_duplicate:VI
1389          (match_operand:QI 1 "s5bit_cint_operand" "i")))]
1390   "TARGET_ALTIVEC"
1391   "vspltis<VI_char> %0,%1"
1392   [(set_attr "type" "vecperm")])
1394 (define_insn "*altivec_vrfiz"
1395   [(set (match_operand:V4SF 0 "register_operand" "=v")
1396         (fix:V4SF (match_operand:V4SF 1 "register_operand" "v")))]
1397   "VECTOR_UNIT_ALTIVEC_P (V4SFmode)"
1398   "vrfiz %0,%1"
1399   [(set_attr "type" "vecfloat")])
1401 (define_insn "altivec_vperm_<mode>"
1402   [(set (match_operand:VM 0 "register_operand" "=v")
1403         (unspec:VM [(match_operand:VM 1 "register_operand" "v")
1404                     (match_operand:VM 2 "register_operand" "v")
1405                     (match_operand:V16QI 3 "register_operand" "v")]
1406                    UNSPEC_VPERM))]
1407   "TARGET_ALTIVEC"
1408   "vperm %0,%1,%2,%3"
1409   [(set_attr "type" "vecperm")])
1411 (define_insn "altivec_vperm_<mode>_uns"
1412   [(set (match_operand:VM 0 "register_operand" "=v")
1413         (unspec:VM [(match_operand:VM 1 "register_operand" "v")
1414                     (match_operand:VM 2 "register_operand" "v")
1415                     (match_operand:V16QI 3 "register_operand" "v")]
1416                    UNSPEC_VPERM_UNS))]
1417   "TARGET_ALTIVEC"
1418   "vperm %0,%1,%2,%3"
1419   [(set_attr "type" "vecperm")])
1421 (define_insn "altivec_vrfip"            ; ceil
1422   [(set (match_operand:V4SF 0 "register_operand" "=v")
1423         (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "v")]
1424                      UNSPEC_FRIP))]
1425   "TARGET_ALTIVEC"
1426   "vrfip %0,%1"
1427   [(set_attr "type" "vecfloat")])
1429 (define_insn "altivec_vrfin"
1430   [(set (match_operand:V4SF 0 "register_operand" "=v")
1431         (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "v")]
1432                      UNSPEC_VRFIN))]
1433   "TARGET_ALTIVEC"
1434   "vrfin %0,%1"
1435   [(set_attr "type" "vecfloat")])
1437 (define_insn "*altivec_vrfim"           ; floor
1438   [(set (match_operand:V4SF 0 "register_operand" "=v")
1439         (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "v")]
1440                      UNSPEC_FRIM))]
1441   "TARGET_ALTIVEC"
1442   "vrfim %0,%1"
1443   [(set_attr "type" "vecfloat")])
1445 (define_insn "altivec_vcfux"
1446   [(set (match_operand:V4SF 0 "register_operand" "=v")
1447         (unspec:V4SF [(match_operand:V4SI 1 "register_operand" "v")
1448                       (match_operand:QI 2 "immediate_operand" "i")]
1449                      UNSPEC_VCFUX))]
1450   "TARGET_ALTIVEC"
1451   "vcfux %0,%1,%2"
1452   [(set_attr "type" "vecfloat")])
1454 (define_insn "altivec_vcfsx"
1455   [(set (match_operand:V4SF 0 "register_operand" "=v")
1456         (unspec:V4SF [(match_operand:V4SI 1 "register_operand" "v")
1457                       (match_operand:QI 2 "immediate_operand" "i")]
1458                      UNSPEC_VCFSX))]
1459   "TARGET_ALTIVEC"
1460   "vcfsx %0,%1,%2"
1461   [(set_attr "type" "vecfloat")])
1463 (define_insn "altivec_vctuxs"
1464   [(set (match_operand:V4SI 0 "register_operand" "=v")
1465         (unspec:V4SI [(match_operand:V4SF 1 "register_operand" "v")
1466                       (match_operand:QI 2 "immediate_operand" "i")]
1467                      UNSPEC_VCTUXS))
1468    (set (reg:SI 110) (unspec:SI [(const_int 0)] UNSPEC_SET_VSCR))]
1469   "TARGET_ALTIVEC"
1470   "vctuxs %0,%1,%2"
1471   [(set_attr "type" "vecfloat")])
1473 (define_insn "altivec_vctsxs"
1474   [(set (match_operand:V4SI 0 "register_operand" "=v")
1475         (unspec:V4SI [(match_operand:V4SF 1 "register_operand" "v")
1476                       (match_operand:QI 2 "immediate_operand" "i")]
1477                      UNSPEC_VCTSXS))
1478    (set (reg:SI 110) (unspec:SI [(const_int 0)] UNSPEC_SET_VSCR))]
1479   "TARGET_ALTIVEC"
1480   "vctsxs %0,%1,%2"
1481   [(set_attr "type" "vecfloat")])
1483 (define_insn "altivec_vlogefp"
1484   [(set (match_operand:V4SF 0 "register_operand" "=v")
1485         (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "v")]
1486                      UNSPEC_VLOGEFP))]
1487   "TARGET_ALTIVEC"
1488   "vlogefp %0,%1"
1489   [(set_attr "type" "vecfloat")])
1491 (define_insn "altivec_vexptefp"
1492   [(set (match_operand:V4SF 0 "register_operand" "=v")
1493         (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "v")]
1494                      UNSPEC_VEXPTEFP))]
1495   "TARGET_ALTIVEC"
1496   "vexptefp %0,%1"
1497   [(set_attr "type" "vecfloat")])
1499 (define_insn "*altivec_vrsqrtefp"
1500   [(set (match_operand:V4SF 0 "register_operand" "=v")
1501         (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "v")]
1502                      UNSPEC_RSQRT))]
1503   "VECTOR_UNIT_ALTIVEC_P (V4SFmode)"
1504   "vrsqrtefp %0,%1"
1505   [(set_attr "type" "vecfloat")])
1507 (define_insn "altivec_vrefp"
1508   [(set (match_operand:V4SF 0 "register_operand" "=v")
1509         (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "v")]
1510                      UNSPEC_FRES))]
1511   "VECTOR_UNIT_ALTIVEC_P (V4SFmode)"
1512   "vrefp %0,%1"
1513   [(set_attr "type" "vecfloat")])
1515 (define_expand "altivec_copysign_v4sf3"
1516   [(use (match_operand:V4SF 0 "register_operand" ""))
1517    (use (match_operand:V4SF 1 "register_operand" ""))
1518    (use (match_operand:V4SF 2 "register_operand" ""))]
1519   "VECTOR_UNIT_ALTIVEC_P (V4SFmode)"
1520   "
1522   rtx mask = gen_reg_rtx (V4SImode);
1523   rtvec v = rtvec_alloc (4);
1524   unsigned HOST_WIDE_INT mask_val = ((unsigned HOST_WIDE_INT)1) << 31;
1526   RTVEC_ELT (v, 0) = GEN_INT (mask_val);
1527   RTVEC_ELT (v, 1) = GEN_INT (mask_val);
1528   RTVEC_ELT (v, 2) = GEN_INT (mask_val);
1529   RTVEC_ELT (v, 3) = GEN_INT (mask_val);
1531   emit_insn (gen_vec_initv4si (mask, gen_rtx_PARALLEL (V4SImode, v)));
1532   emit_insn (gen_vector_select_v4sf (operands[0], operands[1], operands[2],
1533                                      gen_lowpart (V4SFmode, mask)));
1534   DONE;
1537 (define_insn "altivec_vsldoi_<mode>"
1538   [(set (match_operand:VM 0 "register_operand" "=v")
1539         (unspec:VM [(match_operand:VM 1 "register_operand" "v")
1540                     (match_operand:VM 2 "register_operand" "v")
1541                     (match_operand:QI 3 "immediate_operand" "i")]
1542                   UNSPEC_VLSDOI))]
1543   "TARGET_ALTIVEC"
1544   "vsldoi %0,%1,%2,%3"
1545   [(set_attr "type" "vecperm")])
1547 (define_insn "altivec_vupkhsb"
1548   [(set (match_operand:V8HI 0 "register_operand" "=v")
1549         (unspec:V8HI [(match_operand:V16QI 1 "register_operand" "v")]
1550                      UNSPEC_VUPKHSB))]
1551   "TARGET_ALTIVEC"
1552   "vupkhsb %0,%1"
1553   [(set_attr "type" "vecperm")])
1555 (define_insn "altivec_vupkhpx"
1556   [(set (match_operand:V4SI 0 "register_operand" "=v")
1557         (unspec:V4SI [(match_operand:V8HI 1 "register_operand" "v")]
1558                      UNSPEC_VUPKHPX))]
1559   "TARGET_ALTIVEC"
1560   "vupkhpx %0,%1"
1561   [(set_attr "type" "vecperm")])
1563 (define_insn "altivec_vupkhsh"
1564   [(set (match_operand:V4SI 0 "register_operand" "=v")
1565         (unspec:V4SI [(match_operand:V8HI 1 "register_operand" "v")]
1566                      UNSPEC_VUPKHSH))]
1567   "TARGET_ALTIVEC"
1568   "vupkhsh %0,%1"
1569   [(set_attr "type" "vecperm")])
1571 (define_insn "altivec_vupklsb"
1572   [(set (match_operand:V8HI 0 "register_operand" "=v")
1573         (unspec:V8HI [(match_operand:V16QI 1 "register_operand" "v")]
1574                      UNSPEC_VUPKLSB))]
1575   "TARGET_ALTIVEC"
1576   "vupklsb %0,%1"
1577   [(set_attr "type" "vecperm")])
1579 (define_insn "altivec_vupklpx"
1580   [(set (match_operand:V4SI 0 "register_operand" "=v")
1581         (unspec:V4SI [(match_operand:V8HI 1 "register_operand" "v")]
1582                      UNSPEC_VUPKLPX))]
1583   "TARGET_ALTIVEC"
1584   "vupklpx %0,%1"
1585   [(set_attr "type" "vecperm")])
1587 (define_insn "altivec_vupklsh"
1588   [(set (match_operand:V4SI 0 "register_operand" "=v")
1589         (unspec:V4SI [(match_operand:V8HI 1 "register_operand" "v")]
1590                      UNSPEC_VUPKLSH))]
1591   "TARGET_ALTIVEC"
1592   "vupklsh %0,%1"
1593   [(set_attr "type" "vecperm")])
1595 ;; Compare vectors producing a vector result and a predicate, setting CR6 to
1596 ;; indicate a combined status
1597 (define_insn "*altivec_vcmpequ<VI_char>_p"
1598   [(set (reg:CC 74)
1599         (unspec:CC [(eq:CC (match_operand:VI 1 "register_operand" "v")
1600                            (match_operand:VI 2 "register_operand" "v"))]
1601                    UNSPEC_PREDICATE))
1602    (set (match_operand:VI 0 "register_operand" "=v")
1603         (eq:VI (match_dup 1)
1604                (match_dup 2)))]
1605   "VECTOR_UNIT_ALTIVEC_P (<MODE>mode)"
1606   "vcmpequ<VI_char>. %0,%1,%2"
1607   [(set_attr "type" "veccmp")])
1609 (define_insn "*altivec_vcmpgts<VI_char>_p"
1610   [(set (reg:CC 74)
1611         (unspec:CC [(gt:CC (match_operand:VI 1 "register_operand" "v")
1612                            (match_operand:VI 2 "register_operand" "v"))]
1613                    UNSPEC_PREDICATE))
1614    (set (match_operand:VI 0 "register_operand" "=v")
1615         (gt:VI (match_dup 1)
1616                (match_dup 2)))]
1617   "VECTOR_UNIT_ALTIVEC_P (<MODE>mode)"
1618   "vcmpgts<VI_char>. %0,%1,%2"
1619   [(set_attr "type" "veccmp")])
1621 (define_insn "*altivec_vcmpgtu<VI_char>_p"
1622   [(set (reg:CC 74)
1623         (unspec:CC [(gtu:CC (match_operand:VI 1 "register_operand" "v")
1624                             (match_operand:VI 2 "register_operand" "v"))]
1625                    UNSPEC_PREDICATE))
1626    (set (match_operand:VI 0 "register_operand" "=v")
1627         (gtu:VI (match_dup 1)
1628                 (match_dup 2)))]
1629   "VECTOR_UNIT_ALTIVEC_P (<MODE>mode)"
1630   "vcmpgtu<VI_char>. %0,%1,%2"
1631   [(set_attr "type" "veccmp")])
1633 (define_insn "*altivec_vcmpeqfp_p"
1634   [(set (reg:CC 74)
1635         (unspec:CC [(eq:CC (match_operand:V4SF 1 "register_operand" "v")
1636                            (match_operand:V4SF 2 "register_operand" "v"))]
1637                    UNSPEC_PREDICATE))
1638    (set (match_operand:V4SF 0 "register_operand" "=v")
1639         (eq:V4SF (match_dup 1)
1640                  (match_dup 2)))]
1641   "VECTOR_UNIT_ALTIVEC_P (V4SFmode)"
1642   "vcmpeqfp. %0,%1,%2"
1643   [(set_attr "type" "veccmp")])
1645 (define_insn "*altivec_vcmpgtfp_p"
1646   [(set (reg:CC 74)
1647         (unspec:CC [(gt:CC (match_operand:V4SF 1 "register_operand" "v")
1648                            (match_operand:V4SF 2 "register_operand" "v"))]
1649                    UNSPEC_PREDICATE))
1650    (set (match_operand:V4SF 0 "register_operand" "=v")
1651         (gt:V4SF (match_dup 1)
1652                  (match_dup 2)))]
1653   "VECTOR_UNIT_ALTIVEC_P (V4SFmode)"
1654   "vcmpgtfp. %0,%1,%2"
1655   [(set_attr "type" "veccmp")])
1657 (define_insn "*altivec_vcmpgefp_p"
1658   [(set (reg:CC 74)
1659         (unspec:CC [(ge:CC (match_operand:V4SF 1 "register_operand" "v")
1660                            (match_operand:V4SF 2 "register_operand" "v"))]
1661                    UNSPEC_PREDICATE))
1662    (set (match_operand:V4SF 0 "register_operand" "=v")
1663         (ge:V4SF (match_dup 1)
1664                  (match_dup 2)))]
1665   "VECTOR_UNIT_ALTIVEC_P (V4SFmode)"
1666   "vcmpgefp. %0,%1,%2"
1667   [(set_attr "type" "veccmp")])
1669 (define_insn "altivec_vcmpbfp_p"
1670   [(set (reg:CC 74)
1671         (unspec:CC [(match_operand:V4SF 1 "register_operand" "v")
1672                     (match_operand:V4SF 2 "register_operand" "v")]
1673                    UNSPEC_VCMPBFP))
1674    (set (match_operand:V4SF 0 "register_operand" "=v")
1675         (unspec:V4SF [(match_dup 1)
1676                       (match_dup 2)] 
1677                       UNSPEC_VCMPBFP))]
1678   "VECTOR_UNIT_ALTIVEC_OR_VSX_P (V4SFmode)"
1679   "vcmpbfp. %0,%1,%2"
1680   [(set_attr "type" "veccmp")])
1682 (define_insn "altivec_mtvscr"
1683   [(set (reg:SI 110)
1684         (unspec_volatile:SI
1685          [(match_operand:V4SI 0 "register_operand" "v")] UNSPECV_MTVSCR))]
1686   "TARGET_ALTIVEC"
1687   "mtvscr %0"
1688   [(set_attr "type" "vecsimple")])
1690 (define_insn "altivec_mfvscr"
1691   [(set (match_operand:V8HI 0 "register_operand" "=v")
1692         (unspec_volatile:V8HI [(reg:SI 110)] UNSPECV_MFVSCR))]
1693   "TARGET_ALTIVEC"
1694   "mfvscr %0"
1695   [(set_attr "type" "vecsimple")])
1697 (define_insn "altivec_dssall"
1698   [(unspec_volatile [(const_int 0)] UNSPECV_DSSALL)]
1699   "TARGET_ALTIVEC"
1700   "dssall"
1701   [(set_attr "type" "vecsimple")])
1703 (define_insn "altivec_dss"
1704   [(unspec_volatile [(match_operand:QI 0 "immediate_operand" "i")]
1705                     UNSPECV_DSS)]
1706   "TARGET_ALTIVEC"
1707   "dss %0"
1708   [(set_attr "type" "vecsimple")])
1710 (define_insn "altivec_dst"
1711   [(unspec [(match_operand 0 "register_operand" "b")
1712             (match_operand:SI 1 "register_operand" "r")
1713             (match_operand:QI 2 "immediate_operand" "i")] UNSPEC_DST)]
1714   "TARGET_ALTIVEC && GET_MODE (operands[0]) == Pmode"
1715   "dst %0,%1,%2"
1716   [(set_attr "type" "vecsimple")])
1718 (define_insn "altivec_dstt"
1719   [(unspec [(match_operand 0 "register_operand" "b")
1720             (match_operand:SI 1 "register_operand" "r")
1721             (match_operand:QI 2 "immediate_operand" "i")] UNSPEC_DSTT)]
1722   "TARGET_ALTIVEC && GET_MODE (operands[0]) == Pmode"
1723   "dstt %0,%1,%2"
1724   [(set_attr "type" "vecsimple")])
1726 (define_insn "altivec_dstst"
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_DSTST)]
1730   "TARGET_ALTIVEC && GET_MODE (operands[0]) == Pmode"
1731   "dstst %0,%1,%2"
1732   [(set_attr "type" "vecsimple")])
1734 (define_insn "altivec_dststt"
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_DSTSTT)]
1738   "TARGET_ALTIVEC && GET_MODE (operands[0]) == Pmode"
1739   "dststt %0,%1,%2"
1740   [(set_attr "type" "vecsimple")])
1742 (define_insn "altivec_lvsl"
1743   [(set (match_operand:V16QI 0 "register_operand" "=v")
1744         (unspec:V16QI [(match_operand 1 "memory_operand" "Z")] UNSPEC_LVSL))]
1745   "TARGET_ALTIVEC"
1746   "lvsl %0,%y1"
1747   [(set_attr "type" "vecload")])
1749 (define_insn "altivec_lvsr"
1750   [(set (match_operand:V16QI 0 "register_operand" "=v")
1751         (unspec:V16QI [(match_operand 1 "memory_operand" "Z")] UNSPEC_LVSR))]
1752   "TARGET_ALTIVEC"
1753   "lvsr %0,%y1"
1754   [(set_attr "type" "vecload")])
1756 (define_expand "build_vector_mask_for_load"
1757   [(set (match_operand:V16QI 0 "register_operand" "")
1758         (unspec:V16QI [(match_operand 1 "memory_operand" "")] UNSPEC_LVSR))]
1759   "TARGET_ALTIVEC"
1760   "
1762   rtx addr;
1763   rtx temp;
1765   gcc_assert (GET_CODE (operands[1]) == MEM);
1767   addr = XEXP (operands[1], 0);
1768   temp = gen_reg_rtx (GET_MODE (addr));
1769   emit_insn (gen_rtx_SET (VOIDmode, temp, 
1770                           gen_rtx_NEG (GET_MODE (addr), addr)));
1771   emit_insn (gen_altivec_lvsr (operands[0], 
1772                                replace_equiv_address (operands[1], temp)));
1773   DONE;
1776 ;; Parallel some of the LVE* and STV*'s with unspecs because some have
1777 ;; identical rtl but different instructions-- and gcc gets confused.
1779 (define_insn "altivec_lve<VI_char>x"
1780   [(parallel
1781     [(set (match_operand:VI 0 "register_operand" "=v")
1782           (match_operand:VI 1 "memory_operand" "Z"))
1783      (unspec [(const_int 0)] UNSPEC_LVE)])]
1784   "TARGET_ALTIVEC"
1785   "lve<VI_char>x %0,%y1"
1786   [(set_attr "type" "vecload")])
1788 (define_insn "*altivec_lvesfx"
1789   [(parallel
1790     [(set (match_operand:V4SF 0 "register_operand" "=v")
1791           (match_operand:V4SF 1 "memory_operand" "Z"))
1792      (unspec [(const_int 0)] UNSPEC_LVE)])]
1793   "TARGET_ALTIVEC"
1794   "lvewx %0,%y1"
1795   [(set_attr "type" "vecload")])
1797 (define_insn "altivec_lvxl"
1798   [(parallel
1799     [(set (match_operand:V4SI 0 "register_operand" "=v")
1800           (match_operand:V4SI 1 "memory_operand" "Z"))
1801      (unspec [(const_int 0)] UNSPEC_SET_VSCR)])]
1802   "TARGET_ALTIVEC"
1803   "lvxl %0,%y1"
1804   [(set_attr "type" "vecload")])
1806 (define_insn "altivec_lvx"
1807   [(set (match_operand:V4SI 0 "register_operand" "=v")
1808         (match_operand:V4SI 1 "memory_operand" "Z"))]
1809   "TARGET_ALTIVEC"
1810   "lvx %0,%y1"
1811   [(set_attr "type" "vecload")])
1813 (define_insn "altivec_stvx"
1814   [(parallel
1815     [(set (match_operand:V4SI 0 "memory_operand" "=Z")
1816           (match_operand:V4SI 1 "register_operand" "v"))
1817      (unspec [(const_int 0)] UNSPEC_STVX)])]
1818   "TARGET_ALTIVEC"
1819   "stvx %1,%y0"
1820   [(set_attr "type" "vecstore")])
1822 (define_insn "altivec_stvxl"
1823   [(parallel
1824     [(set (match_operand:V4SI 0 "memory_operand" "=Z")
1825           (match_operand:V4SI 1 "register_operand" "v"))
1826      (unspec [(const_int 0)] UNSPEC_STVXL)])]
1827   "TARGET_ALTIVEC"
1828   "stvxl %1,%y0"
1829   [(set_attr "type" "vecstore")])
1831 (define_insn "altivec_stve<VI_char>x"
1832   [(parallel
1833     [(set (match_operand:VI 0 "memory_operand" "=Z")
1834           (match_operand:VI 1 "register_operand" "v"))
1835      (unspec [(const_int 0)] UNSPEC_STVE)])]
1836   "TARGET_ALTIVEC"
1837   "stve<VI_char>x %1,%y0"
1838   [(set_attr "type" "vecstore")])
1840 (define_insn "*altivec_stvesfx"
1841   [(parallel
1842     [(set (match_operand:V4SF 0 "memory_operand" "=Z")
1843           (match_operand:V4SF 1 "register_operand" "v"))
1844      (unspec [(const_int 0)] UNSPEC_STVE)])]
1845   "TARGET_ALTIVEC"
1846   "stvewx %1,%y0"
1847   [(set_attr "type" "vecstore")])
1849 ;; Generate
1850 ;;    vspltis? SCRATCH0,0
1851 ;;    vsubu?m SCRATCH2,SCRATCH1,%1
1852 ;;    vmaxs? %0,%1,SCRATCH2"
1853 (define_expand "abs<mode>2"
1854   [(set (match_dup 2) (vec_duplicate:VI (const_int 0)))
1855    (set (match_dup 3)
1856         (minus:VI (match_dup 2)
1857                   (match_operand:VI 1 "register_operand" "v")))
1858    (set (match_operand:VI 0 "register_operand" "=v")
1859         (smax:VI (match_dup 1) (match_dup 3)))]
1860   "TARGET_ALTIVEC"
1862   operands[2] = gen_reg_rtx (GET_MODE (operands[0]));
1863   operands[3] = gen_reg_rtx (GET_MODE (operands[0]));
1866 ;; Generate
1867 ;;    vspltisw SCRATCH1,-1
1868 ;;    vslw SCRATCH2,SCRATCH1,SCRATCH1
1869 ;;    vandc %0,%1,SCRATCH2
1870 (define_expand "altivec_absv4sf2"
1871   [(set (match_dup 2)
1872         (vec_duplicate:V4SI (const_int -1)))
1873    (set (match_dup 3)
1874         (ashift:V4SI (match_dup 2) (match_dup 2)))
1875    (set (match_operand:V4SF 0 "register_operand" "=v")
1876         (and:V4SF (not:V4SF (subreg:V4SF (match_dup 3) 0))
1877                   (match_operand:V4SF 1 "register_operand" "v")))]
1878   "TARGET_ALTIVEC"
1880   operands[2] = gen_reg_rtx (V4SImode);
1881   operands[3] = gen_reg_rtx (V4SImode);
1884 ;; Generate
1885 ;;    vspltis? SCRATCH0,0
1886 ;;    vsubs?s SCRATCH2,SCRATCH1,%1
1887 ;;    vmaxs? %0,%1,SCRATCH2"
1888 (define_expand "altivec_abss_<mode>"
1889   [(set (match_dup 2) (vec_duplicate:VI (const_int 0)))
1890    (parallel [(set (match_dup 3)
1891                    (unspec:VI [(match_dup 2)
1892                                (match_operand:VI 1 "register_operand" "v")]
1893                               UNSPEC_VSUBS))
1894               (set (reg:SI 110) (unspec:SI [(const_int 0)] UNSPEC_SET_VSCR))])
1895    (set (match_operand:VI 0 "register_operand" "=v")
1896         (smax:VI (match_dup 1) (match_dup 3)))]
1897   "TARGET_ALTIVEC"
1899   operands[2] = gen_reg_rtx (GET_MODE (operands[0]));
1900   operands[3] = gen_reg_rtx (GET_MODE (operands[0]));
1903 (define_insn "altivec_vsumsws_nomode"
1904   [(set (match_operand 0 "register_operand" "=v")
1905         (unspec:V4SI [(match_operand:V4SI 1 "register_operand" "v")
1906                       (match_operand:V4SI 2 "register_operand" "v")]
1907                      UNSPEC_VSUMSWS))
1908    (set (reg:SI 110) (unspec:SI [(const_int 0)] UNSPEC_SET_VSCR))]
1909   "TARGET_ALTIVEC"
1910   "vsumsws %0,%1,%2"
1911   [(set_attr "type" "veccomplex")])
1913 (define_expand "reduc_splus_<mode>"
1914   [(set (match_operand:VIshort 0 "register_operand" "=v")
1915         (unspec:VIshort [(match_operand:VIshort 1 "register_operand" "v")]
1916                         UNSPEC_REDUC_PLUS))]
1917   "TARGET_ALTIVEC"
1918   "
1920   rtx vzero = gen_reg_rtx (V4SImode);
1921   rtx vtmp1 = gen_reg_rtx (V4SImode);
1923   emit_insn (gen_altivec_vspltisw (vzero, const0_rtx));
1924   emit_insn (gen_altivec_vsum4s<VI_char>s (vtmp1, operands[1], vzero));
1925   emit_insn (gen_altivec_vsumsws_nomode (operands[0], vtmp1, vzero));
1926   DONE;
1929 (define_expand "reduc_uplus_v16qi"
1930   [(set (match_operand:V16QI 0 "register_operand" "=v")
1931         (unspec:V16QI [(match_operand:V16QI 1 "register_operand" "v")]
1932                       UNSPEC_REDUC_PLUS))]
1933   "TARGET_ALTIVEC"
1934   "
1936   rtx vzero = gen_reg_rtx (V4SImode);
1937   rtx vtmp1 = gen_reg_rtx (V4SImode);
1939   emit_insn (gen_altivec_vspltisw (vzero, const0_rtx));
1940   emit_insn (gen_altivec_vsum4ubs (vtmp1, operands[1], vzero));
1941   emit_insn (gen_altivec_vsumsws_nomode (operands[0], vtmp1, vzero));
1942   DONE;
1945 (define_expand "neg<mode>2"
1946   [(use (match_operand:VI 0 "register_operand" ""))
1947    (use (match_operand:VI 1 "register_operand" ""))]
1948   "TARGET_ALTIVEC"
1949   "
1951   rtx vzero;
1953   vzero = gen_reg_rtx (GET_MODE (operands[0]));
1954   emit_insn (gen_altivec_vspltis<VI_char> (vzero, const0_rtx));
1955   emit_insn (gen_sub<mode>3 (operands[0], vzero, operands[1])); 
1956   
1957   DONE;
1960 (define_expand "udot_prod<mode>"
1961   [(set (match_operand:V4SI 0 "register_operand" "=v")
1962         (plus:V4SI (match_operand:V4SI 3 "register_operand" "v")
1963                    (unspec:V4SI [(match_operand:VIshort 1 "register_operand" "v")  
1964                                  (match_operand:VIshort 2 "register_operand" "v")] 
1965                                 UNSPEC_VMSUMU)))]
1966   "TARGET_ALTIVEC"
1967   "
1968 {  
1969   emit_insn (gen_altivec_vmsumu<VI_char>m (operands[0], operands[1], operands[2], operands[3]));
1970   DONE;
1972    
1973 (define_expand "sdot_prodv8hi"
1974   [(set (match_operand:V4SI 0 "register_operand" "=v")
1975         (plus:V4SI (match_operand:V4SI 3 "register_operand" "v")
1976                    (unspec:V4SI [(match_operand:V8HI 1 "register_operand" "v")
1977                                  (match_operand:V8HI 2 "register_operand" "v")]
1978                                 UNSPEC_VMSUMSHM)))]
1979   "TARGET_ALTIVEC"
1980   "
1982   emit_insn (gen_altivec_vmsumshm (operands[0], operands[1], operands[2], operands[3]));
1983   DONE;
1986 (define_expand "widen_usum<mode>3"
1987   [(set (match_operand:V4SI 0 "register_operand" "=v")
1988         (plus:V4SI (match_operand:V4SI 2 "register_operand" "v")
1989                    (unspec:V4SI [(match_operand:VIshort 1 "register_operand" "v")]
1990                                 UNSPEC_VMSUMU)))]
1991   "TARGET_ALTIVEC"
1992   "
1994   rtx vones = gen_reg_rtx (GET_MODE (operands[1]));
1996   emit_insn (gen_altivec_vspltis<VI_char> (vones, const1_rtx));
1997   emit_insn (gen_altivec_vmsumu<VI_char>m (operands[0], operands[1], vones, operands[2]));
1998   DONE;
2001 (define_expand "widen_ssumv16qi3"
2002   [(set (match_operand:V4SI 0 "register_operand" "=v")
2003         (plus:V4SI (match_operand:V4SI 2 "register_operand" "v")
2004                    (unspec:V4SI [(match_operand:V16QI 1 "register_operand" "v")]
2005                                 UNSPEC_VMSUMM)))]
2006   "TARGET_ALTIVEC"
2007   "
2009   rtx vones = gen_reg_rtx (V16QImode);
2011   emit_insn (gen_altivec_vspltisb (vones, const1_rtx));
2012   emit_insn (gen_altivec_vmsummbm (operands[0], operands[1], vones, operands[2]));
2013   DONE;
2016 (define_expand "widen_ssumv8hi3"
2017   [(set (match_operand:V4SI 0 "register_operand" "=v")
2018         (plus:V4SI (match_operand:V4SI 2 "register_operand" "v")
2019                    (unspec:V4SI [(match_operand:V8HI 1 "register_operand" "v")]
2020                                 UNSPEC_VMSUMSHM)))]
2021   "TARGET_ALTIVEC"
2022   "
2024   rtx vones = gen_reg_rtx (V8HImode);
2026   emit_insn (gen_altivec_vspltish (vones, const1_rtx));
2027   emit_insn (gen_altivec_vmsumshm (operands[0], operands[1], vones, operands[2]));
2028   DONE;
2031 (define_expand "vec_unpacks_hi_v16qi"
2032   [(set (match_operand:V8HI 0 "register_operand" "=v")
2033         (unspec:V8HI [(match_operand:V16QI 1 "register_operand" "v")]
2034                      UNSPEC_VUPKHSB))]
2035   "TARGET_ALTIVEC"
2036   "
2038   emit_insn (gen_altivec_vupkhsb (operands[0], operands[1]));
2039   DONE;
2042 (define_expand "vec_unpacks_hi_v8hi"
2043   [(set (match_operand:V4SI 0 "register_operand" "=v")
2044         (unspec:V4SI [(match_operand:V8HI 1 "register_operand" "v")]
2045                      UNSPEC_VUPKHSH))]
2046   "TARGET_ALTIVEC"
2047   "
2049   emit_insn (gen_altivec_vupkhsh (operands[0], operands[1]));
2050   DONE;
2053 (define_expand "vec_unpacks_lo_v16qi"
2054   [(set (match_operand:V8HI 0 "register_operand" "=v")
2055         (unspec:V8HI [(match_operand:V16QI 1 "register_operand" "v")]
2056                      UNSPEC_VUPKLSB))]
2057   "TARGET_ALTIVEC"
2058   "
2060   emit_insn (gen_altivec_vupklsb (operands[0], operands[1]));
2061   DONE;
2064 (define_expand "vec_unpacks_lo_v8hi"
2065   [(set (match_operand:V4SI 0 "register_operand" "=v")
2066         (unspec:V4SI [(match_operand:V8HI 1 "register_operand" "v")]
2067                      UNSPEC_VUPKLSH))]
2068   "TARGET_ALTIVEC"
2069   "
2071   emit_insn (gen_altivec_vupklsh (operands[0], operands[1]));
2072   DONE;
2075 (define_insn "vperm_v8hiv4si"
2076   [(set (match_operand:V4SI 0 "register_operand" "=v")
2077         (unspec:V4SI [(match_operand:V8HI 1 "register_operand" "v")
2078                    (match_operand:V4SI 2 "register_operand" "v")
2079                    (match_operand:V16QI 3 "register_operand" "v")]
2080                   UNSPEC_VPERMSI))]
2081   "TARGET_ALTIVEC"
2082   "vperm %0,%1,%2,%3"
2083   [(set_attr "type" "vecperm")])
2085 (define_insn "vperm_v16qiv8hi"
2086   [(set (match_operand:V8HI 0 "register_operand" "=v")
2087         (unspec:V8HI [(match_operand:V16QI 1 "register_operand" "v")
2088                    (match_operand:V8HI 2 "register_operand" "v")
2089                    (match_operand:V16QI 3 "register_operand" "v")]
2090                   UNSPEC_VPERMHI))]
2091   "TARGET_ALTIVEC"
2092   "vperm %0,%1,%2,%3"
2093   [(set_attr "type" "vecperm")])
2096 (define_expand "vec_unpacku_hi_v16qi"
2097   [(set (match_operand:V8HI 0 "register_operand" "=v")
2098         (unspec:V8HI [(match_operand:V16QI 1 "register_operand" "v")]
2099                      UNSPEC_VUPKHUB))]
2100   "TARGET_ALTIVEC"      
2101   "
2102 {  
2103   rtx vzero = gen_reg_rtx (V8HImode);
2104   rtx mask = gen_reg_rtx (V16QImode);
2105   rtvec v = rtvec_alloc (16);
2106    
2107   emit_insn (gen_altivec_vspltish (vzero, const0_rtx));
2108    
2109   RTVEC_ELT (v, 0) = gen_rtx_CONST_INT (QImode, 16);
2110   RTVEC_ELT (v, 1) = gen_rtx_CONST_INT (QImode, 0);
2111   RTVEC_ELT (v, 2) = gen_rtx_CONST_INT (QImode, 16);
2112   RTVEC_ELT (v, 3) = gen_rtx_CONST_INT (QImode, 1);
2113   RTVEC_ELT (v, 4) = gen_rtx_CONST_INT (QImode, 16);
2114   RTVEC_ELT (v, 5) = gen_rtx_CONST_INT (QImode, 2);
2115   RTVEC_ELT (v, 6) = gen_rtx_CONST_INT (QImode, 16);
2116   RTVEC_ELT (v, 7) = gen_rtx_CONST_INT (QImode, 3);
2117   RTVEC_ELT (v, 8) = gen_rtx_CONST_INT (QImode, 16);
2118   RTVEC_ELT (v, 9) = gen_rtx_CONST_INT (QImode, 4);
2119   RTVEC_ELT (v, 10) = gen_rtx_CONST_INT (QImode, 16);
2120   RTVEC_ELT (v, 11) = gen_rtx_CONST_INT (QImode, 5);
2121   RTVEC_ELT (v, 12) = gen_rtx_CONST_INT (QImode, 16);
2122   RTVEC_ELT (v, 13) = gen_rtx_CONST_INT (QImode, 6);
2123   RTVEC_ELT (v, 14) = gen_rtx_CONST_INT (QImode, 16);
2124   RTVEC_ELT (v, 15) = gen_rtx_CONST_INT (QImode, 7);
2126   emit_insn (gen_vec_initv16qi (mask, gen_rtx_PARALLEL (V16QImode, v)));
2127   emit_insn (gen_vperm_v16qiv8hi (operands[0], operands[1], vzero, mask));
2128   DONE;
2131 (define_expand "vec_unpacku_hi_v8hi"
2132   [(set (match_operand:V4SI 0 "register_operand" "=v")
2133         (unspec:V4SI [(match_operand:V8HI 1 "register_operand" "v")]
2134                      UNSPEC_VUPKHUH))]
2135   "TARGET_ALTIVEC"
2136   "
2138   rtx vzero = gen_reg_rtx (V4SImode);
2139   rtx mask = gen_reg_rtx (V16QImode);
2140   rtvec v = rtvec_alloc (16);
2142   emit_insn (gen_altivec_vspltisw (vzero, const0_rtx));
2144   RTVEC_ELT (v, 0) = gen_rtx_CONST_INT (QImode, 16);
2145   RTVEC_ELT (v, 1) = gen_rtx_CONST_INT (QImode, 17);
2146   RTVEC_ELT (v, 2) = gen_rtx_CONST_INT (QImode, 0);
2147   RTVEC_ELT (v, 3) = gen_rtx_CONST_INT (QImode, 1);
2148   RTVEC_ELT (v, 4) = gen_rtx_CONST_INT (QImode, 16);
2149   RTVEC_ELT (v, 5) = gen_rtx_CONST_INT (QImode, 17);
2150   RTVEC_ELT (v, 6) = gen_rtx_CONST_INT (QImode, 2);
2151   RTVEC_ELT (v, 7) = gen_rtx_CONST_INT (QImode, 3);
2152   RTVEC_ELT (v, 8) = gen_rtx_CONST_INT (QImode, 16);
2153   RTVEC_ELT (v, 9) = gen_rtx_CONST_INT (QImode, 17);
2154   RTVEC_ELT (v, 10) = gen_rtx_CONST_INT (QImode, 4);
2155   RTVEC_ELT (v, 11) = gen_rtx_CONST_INT (QImode, 5);
2156   RTVEC_ELT (v, 12) = gen_rtx_CONST_INT (QImode, 16);
2157   RTVEC_ELT (v, 13) = gen_rtx_CONST_INT (QImode, 17);
2158   RTVEC_ELT (v, 14) = gen_rtx_CONST_INT (QImode, 6);
2159   RTVEC_ELT (v, 15) = gen_rtx_CONST_INT (QImode, 7);
2161   emit_insn (gen_vec_initv16qi (mask, gen_rtx_PARALLEL (V16QImode, v)));
2162   emit_insn (gen_vperm_v8hiv4si (operands[0], operands[1], vzero, mask));
2163   DONE;
2166 (define_expand "vec_unpacku_lo_v16qi"
2167   [(set (match_operand:V8HI 0 "register_operand" "=v")
2168         (unspec:V8HI [(match_operand:V16QI 1 "register_operand" "v")]
2169                      UNSPEC_VUPKLUB))]
2170   "TARGET_ALTIVEC"
2171   "
2173   rtx vzero = gen_reg_rtx (V8HImode);
2174   rtx mask = gen_reg_rtx (V16QImode);
2175   rtvec v = rtvec_alloc (16);
2177   emit_insn (gen_altivec_vspltish (vzero, const0_rtx));
2179   RTVEC_ELT (v, 0) = gen_rtx_CONST_INT (QImode, 16);
2180   RTVEC_ELT (v, 1) = gen_rtx_CONST_INT (QImode, 8);
2181   RTVEC_ELT (v, 2) = gen_rtx_CONST_INT (QImode, 16);
2182   RTVEC_ELT (v, 3) = gen_rtx_CONST_INT (QImode, 9);
2183   RTVEC_ELT (v, 4) = gen_rtx_CONST_INT (QImode, 16);
2184   RTVEC_ELT (v, 5) = gen_rtx_CONST_INT (QImode, 10);
2185   RTVEC_ELT (v, 6) = gen_rtx_CONST_INT (QImode, 16);
2186   RTVEC_ELT (v, 7) = gen_rtx_CONST_INT (QImode, 11);
2187   RTVEC_ELT (v, 8) = gen_rtx_CONST_INT (QImode, 16);
2188   RTVEC_ELT (v, 9) = gen_rtx_CONST_INT (QImode, 12);
2189   RTVEC_ELT (v, 10) = gen_rtx_CONST_INT (QImode, 16);
2190   RTVEC_ELT (v, 11) = gen_rtx_CONST_INT (QImode, 13);
2191   RTVEC_ELT (v, 12) = gen_rtx_CONST_INT (QImode, 16);
2192   RTVEC_ELT (v, 13) = gen_rtx_CONST_INT (QImode, 14);
2193   RTVEC_ELT (v, 14) = gen_rtx_CONST_INT (QImode, 16);
2194   RTVEC_ELT (v, 15) = gen_rtx_CONST_INT (QImode, 15);
2196   emit_insn (gen_vec_initv16qi (mask, gen_rtx_PARALLEL (V16QImode, v)));
2197   emit_insn (gen_vperm_v16qiv8hi (operands[0], operands[1], vzero, mask));
2198   DONE;
2201 (define_expand "vec_unpacku_lo_v8hi"
2202   [(set (match_operand:V4SI 0 "register_operand" "=v")
2203         (unspec:V4SI [(match_operand:V8HI 1 "register_operand" "v")]
2204                      UNSPEC_VUPKLUH))]
2205   "TARGET_ALTIVEC"
2206   "
2208   rtx vzero = gen_reg_rtx (V4SImode);
2209   rtx mask = gen_reg_rtx (V16QImode);
2210   rtvec v = rtvec_alloc (16);
2212   emit_insn (gen_altivec_vspltisw (vzero, const0_rtx));
2214   RTVEC_ELT (v, 0) = gen_rtx_CONST_INT (QImode, 16);
2215   RTVEC_ELT (v, 1) = gen_rtx_CONST_INT (QImode, 17);
2216   RTVEC_ELT (v, 2) = gen_rtx_CONST_INT (QImode, 8);
2217   RTVEC_ELT (v, 3) = gen_rtx_CONST_INT (QImode, 9);
2218   RTVEC_ELT (v, 4) = gen_rtx_CONST_INT (QImode, 16);
2219   RTVEC_ELT (v, 5) = gen_rtx_CONST_INT (QImode, 17);
2220   RTVEC_ELT (v, 6) = gen_rtx_CONST_INT (QImode, 10);
2221   RTVEC_ELT (v, 7) = gen_rtx_CONST_INT (QImode, 11);
2222   RTVEC_ELT (v, 8) = gen_rtx_CONST_INT (QImode, 16);
2223   RTVEC_ELT (v, 9) = gen_rtx_CONST_INT (QImode, 17);
2224   RTVEC_ELT (v, 10) = gen_rtx_CONST_INT (QImode, 12);
2225   RTVEC_ELT (v, 11) = gen_rtx_CONST_INT (QImode, 13);
2226   RTVEC_ELT (v, 12) = gen_rtx_CONST_INT (QImode, 16);
2227   RTVEC_ELT (v, 13) = gen_rtx_CONST_INT (QImode, 17);
2228   RTVEC_ELT (v, 14) = gen_rtx_CONST_INT (QImode, 14);
2229   RTVEC_ELT (v, 15) = gen_rtx_CONST_INT (QImode, 15);
2231   emit_insn (gen_vec_initv16qi (mask, gen_rtx_PARALLEL (V16QImode, v)));
2232   emit_insn (gen_vperm_v8hiv4si (operands[0], operands[1], vzero, mask));
2233   DONE;
2236 (define_expand "vec_widen_umult_hi_v16qi"
2237   [(set (match_operand:V8HI 0 "register_operand" "=v")
2238         (unspec:V8HI [(match_operand:V16QI 1 "register_operand" "v")
2239                       (match_operand:V16QI 2 "register_operand" "v")]
2240                      UNSPEC_VMULWHUB))]
2241   "TARGET_ALTIVEC"
2242   "
2244   rtx ve = gen_reg_rtx (V8HImode);
2245   rtx vo = gen_reg_rtx (V8HImode);
2246   
2247   emit_insn (gen_altivec_vmuleub (ve, operands[1], operands[2]));
2248   emit_insn (gen_altivec_vmuloub (vo, operands[1], operands[2]));
2249   emit_insn (gen_altivec_vmrghh (operands[0], ve, vo));
2250   DONE;
2253 (define_expand "vec_widen_umult_lo_v16qi"
2254   [(set (match_operand:V8HI 0 "register_operand" "=v")
2255         (unspec:V8HI [(match_operand:V16QI 1 "register_operand" "v")
2256                       (match_operand:V16QI 2 "register_operand" "v")]
2257                      UNSPEC_VMULWLUB))]
2258   "TARGET_ALTIVEC"
2259   "
2261   rtx ve = gen_reg_rtx (V8HImode);
2262   rtx vo = gen_reg_rtx (V8HImode);
2263   
2264   emit_insn (gen_altivec_vmuleub (ve, operands[1], operands[2]));
2265   emit_insn (gen_altivec_vmuloub (vo, operands[1], operands[2]));
2266   emit_insn (gen_altivec_vmrglh (operands[0], ve, vo));
2267   DONE;
2270 (define_expand "vec_widen_smult_hi_v16qi"
2271   [(set (match_operand:V8HI 0 "register_operand" "=v")
2272         (unspec:V8HI [(match_operand:V16QI 1 "register_operand" "v")
2273                       (match_operand:V16QI 2 "register_operand" "v")]
2274                      UNSPEC_VMULWHSB))]
2275   "TARGET_ALTIVEC"
2276   "
2278   rtx ve = gen_reg_rtx (V8HImode);
2279   rtx vo = gen_reg_rtx (V8HImode);
2280   
2281   emit_insn (gen_altivec_vmulesb (ve, operands[1], operands[2]));
2282   emit_insn (gen_altivec_vmulosb (vo, operands[1], operands[2]));
2283   emit_insn (gen_altivec_vmrghh (operands[0], ve, vo));
2284   DONE;
2287 (define_expand "vec_widen_smult_lo_v16qi"
2288   [(set (match_operand:V8HI 0 "register_operand" "=v")
2289         (unspec:V8HI [(match_operand:V16QI 1 "register_operand" "v")
2290                       (match_operand:V16QI 2 "register_operand" "v")]
2291                      UNSPEC_VMULWLSB))]
2292   "TARGET_ALTIVEC"
2293   "
2295   rtx ve = gen_reg_rtx (V8HImode);
2296   rtx vo = gen_reg_rtx (V8HImode);
2297   
2298   emit_insn (gen_altivec_vmulesb (ve, operands[1], operands[2]));
2299   emit_insn (gen_altivec_vmulosb (vo, operands[1], operands[2]));
2300   emit_insn (gen_altivec_vmrglh (operands[0], ve, vo));
2301   DONE;
2304 (define_expand "vec_widen_umult_hi_v8hi"
2305   [(set (match_operand:V4SI 0 "register_operand" "=v")
2306         (unspec:V4SI [(match_operand:V8HI 1 "register_operand" "v")
2307                       (match_operand:V8HI 2 "register_operand" "v")]
2308                      UNSPEC_VMULWHUH))]
2309   "TARGET_ALTIVEC"
2310   "
2312   rtx ve = gen_reg_rtx (V4SImode);
2313   rtx vo = gen_reg_rtx (V4SImode);
2314   
2315   emit_insn (gen_altivec_vmuleuh (ve, operands[1], operands[2]));
2316   emit_insn (gen_altivec_vmulouh (vo, operands[1], operands[2]));
2317   emit_insn (gen_altivec_vmrghw (operands[0], ve, vo));
2318   DONE;
2321 (define_expand "vec_widen_umult_lo_v8hi"
2322   [(set (match_operand:V4SI 0 "register_operand" "=v")
2323         (unspec:V4SI [(match_operand:V8HI 1 "register_operand" "v")
2324                       (match_operand:V8HI 2 "register_operand" "v")]
2325                      UNSPEC_VMULWLUH))]
2326   "TARGET_ALTIVEC"
2327   "
2329   rtx ve = gen_reg_rtx (V4SImode);
2330   rtx vo = gen_reg_rtx (V4SImode);
2331   
2332   emit_insn (gen_altivec_vmuleuh (ve, operands[1], operands[2]));
2333   emit_insn (gen_altivec_vmulouh (vo, operands[1], operands[2]));
2334   emit_insn (gen_altivec_vmrglw (operands[0], ve, vo));
2335   DONE;
2338 (define_expand "vec_widen_smult_hi_v8hi"
2339   [(set (match_operand:V4SI 0 "register_operand" "=v")
2340         (unspec:V4SI [(match_operand:V8HI 1 "register_operand" "v")
2341                       (match_operand:V8HI 2 "register_operand" "v")]
2342                      UNSPEC_VMULWHSH))]
2343   "TARGET_ALTIVEC"
2344   "
2346   rtx ve = gen_reg_rtx (V4SImode);
2347   rtx vo = gen_reg_rtx (V4SImode);
2348   
2349   emit_insn (gen_altivec_vmulesh (ve, operands[1], operands[2]));
2350   emit_insn (gen_altivec_vmulosh (vo, operands[1], operands[2]));
2351   emit_insn (gen_altivec_vmrghw (operands[0], ve, vo));
2352   DONE;
2355 (define_expand "vec_widen_smult_lo_v8hi"
2356   [(set (match_operand:V4SI 0 "register_operand" "=v")
2357         (unspec:V4SI [(match_operand:V8HI 1 "register_operand" "v")
2358                       (match_operand:V8HI 2 "register_operand" "v")]
2359                      UNSPEC_VMULWLSH))]
2360   "TARGET_ALTIVEC"
2361   "
2363   rtx ve = gen_reg_rtx (V4SImode);
2364   rtx vo = gen_reg_rtx (V4SImode);
2365   
2366   emit_insn (gen_altivec_vmulesh (ve, operands[1], operands[2]));
2367   emit_insn (gen_altivec_vmulosh (vo, operands[1], operands[2]));
2368   emit_insn (gen_altivec_vmrglw (operands[0], ve, vo));
2369   DONE;
2372 (define_expand "vec_pack_trunc_v8hi"
2373   [(set (match_operand:V16QI 0 "register_operand" "=v")
2374         (unspec:V16QI [(match_operand:V8HI 1 "register_operand" "v")
2375                        (match_operand:V8HI 2 "register_operand" "v")]
2376                       UNSPEC_VPKUHUM))]
2377   "TARGET_ALTIVEC"
2378   "
2380   emit_insn (gen_altivec_vpkuhum (operands[0], operands[1], operands[2]));
2381   DONE;
2383                                                                                 
2384 (define_expand "vec_pack_trunc_v4si"
2385   [(set (match_operand:V8HI 0 "register_operand" "=v")
2386         (unspec:V8HI [(match_operand:V4SI 1 "register_operand" "v")
2387                       (match_operand:V4SI 2 "register_operand" "v")]
2388                      UNSPEC_VPKUWUM))]
2389   "TARGET_ALTIVEC"
2390   "
2392   emit_insn (gen_altivec_vpkuwum (operands[0], operands[1], operands[2]));
2393   DONE;
2396 (define_expand "altivec_negv4sf2"
2397   [(use (match_operand:V4SF 0 "register_operand" ""))
2398    (use (match_operand:V4SF 1 "register_operand" ""))]
2399   "TARGET_ALTIVEC"
2400   "
2402   rtx neg0;
2404   /* Generate [-0.0, -0.0, -0.0, -0.0].  */
2405   neg0 = gen_reg_rtx (V4SImode);
2406   emit_insn (gen_altivec_vspltisw (neg0, constm1_rtx));
2407   emit_insn (gen_vashlv4si3 (neg0, neg0, neg0));
2409   /* XOR */
2410   emit_insn (gen_xorv4sf3 (operands[0],
2411                            gen_lowpart (V4SFmode, neg0), operands[1])); 
2412     
2413   DONE;
2416 ;; Vector SIMD PEM v2.06c defines LVLX, LVLXL, LVRX, LVRXL,
2417 ;; STVLX, STVLXL, STVVRX, STVRXL are available only on Cell.
2418 (define_insn "altivec_lvlx"
2419   [(set (match_operand:V16QI 0 "register_operand" "=v")
2420         (unspec:V16QI [(match_operand 1 "memory_operand" "Z")] 
2421                       UNSPEC_LVLX))]
2422   "TARGET_ALTIVEC && rs6000_cpu == PROCESSOR_CELL"
2423   "lvlx %0,%y1"
2424   [(set_attr "type" "vecload")])
2426 (define_insn "altivec_lvlxl"
2427   [(set (match_operand:V16QI 0 "register_operand" "=v")
2428         (unspec:V16QI [(match_operand 1 "memory_operand" "Z")] 
2429                       UNSPEC_LVLXL))]
2430   "TARGET_ALTIVEC && rs6000_cpu == PROCESSOR_CELL"
2431   "lvlxl %0,%y1"
2432   [(set_attr "type" "vecload")])
2434 (define_insn "altivec_lvrx"
2435   [(set (match_operand:V16QI 0 "register_operand" "=v")
2436         (unspec:V16QI [(match_operand 1 "memory_operand" "Z")] 
2437                       UNSPEC_LVRX))]
2438   "TARGET_ALTIVEC && rs6000_cpu == PROCESSOR_CELL"
2439   "lvrx %0,%y1"
2440   [(set_attr "type" "vecload")])
2442 (define_insn "altivec_lvrxl"
2443   [(set (match_operand:V16QI 0 "register_operand" "=v")
2444         (unspec:V16QI [(match_operand 1 "memory_operand" "Z")] 
2445                       UNSPEC_LVRXL))]
2446   "TARGET_ALTIVEC && rs6000_cpu == PROCESSOR_CELL"
2447   "lvrxl %0,%y1"
2448   [(set_attr "type" "vecload")])
2450 (define_insn "altivec_stvlx"
2451   [(parallel
2452     [(set (match_operand:V4SI 0 "memory_operand" "=Z")
2453           (match_operand:V4SI 1 "register_operand" "v"))
2454      (unspec [(const_int 0)] UNSPEC_STVLX)])]
2455   "TARGET_ALTIVEC && rs6000_cpu == PROCESSOR_CELL"
2456   "stvlx %1,%y0"
2457   [(set_attr "type" "vecstore")])
2459 (define_insn "altivec_stvlxl"
2460   [(parallel
2461     [(set (match_operand:V4SI 0 "memory_operand" "=Z")
2462           (match_operand:V4SI 1 "register_operand" "v"))
2463      (unspec [(const_int 0)] UNSPEC_STVLXL)])]
2464   "TARGET_ALTIVEC && rs6000_cpu == PROCESSOR_CELL"
2465   "stvlxl %1,%y0"
2466   [(set_attr "type" "vecstore")])
2468 (define_insn "altivec_stvrx"
2469   [(parallel
2470     [(set (match_operand:V4SI 0 "memory_operand" "=Z")
2471           (match_operand:V4SI 1 "register_operand" "v"))
2472      (unspec [(const_int 0)] UNSPEC_STVRX)])]
2473   "TARGET_ALTIVEC && rs6000_cpu == PROCESSOR_CELL"
2474   "stvrx %1,%y0"
2475   [(set_attr "type" "vecstore")])
2477 (define_insn "altivec_stvrxl"
2478   [(parallel
2479     [(set (match_operand:V4SI 0 "memory_operand" "=Z")
2480           (match_operand:V4SI 1 "register_operand" "v"))
2481      (unspec [(const_int 0)] UNSPEC_STVRXL)])]
2482   "TARGET_ALTIVEC && rs6000_cpu == PROCESSOR_CELL"
2483   "stvrxl %1,%y0"
2484   [(set_attr "type" "vecstore")])
2486 (define_expand "vec_extract_evenv4si"
2487  [(set (match_operand:V4SI 0 "register_operand" "")
2488         (unspec:V8HI [(match_operand:V4SI 1 "register_operand" "")
2489                       (match_operand:V4SI 2 "register_operand" "")]
2490                       UNSPEC_EXTEVEN_V4SI))]
2491   "TARGET_ALTIVEC"
2492   "
2494   rtx mask = gen_reg_rtx (V16QImode);
2495   rtvec v = rtvec_alloc (16);
2497   RTVEC_ELT (v, 0) = gen_rtx_CONST_INT (QImode, 0);
2498   RTVEC_ELT (v, 1) = gen_rtx_CONST_INT (QImode, 1);
2499   RTVEC_ELT (v, 2) = gen_rtx_CONST_INT (QImode, 2);
2500   RTVEC_ELT (v, 3) = gen_rtx_CONST_INT (QImode, 3);
2501   RTVEC_ELT (v, 4) = gen_rtx_CONST_INT (QImode, 8);
2502   RTVEC_ELT (v, 5) = gen_rtx_CONST_INT (QImode, 9);
2503   RTVEC_ELT (v, 6) = gen_rtx_CONST_INT (QImode, 10);
2504   RTVEC_ELT (v, 7) = gen_rtx_CONST_INT (QImode, 11);
2505   RTVEC_ELT (v, 8) = gen_rtx_CONST_INT (QImode, 16);
2506   RTVEC_ELT (v, 9) = gen_rtx_CONST_INT (QImode, 17);
2507   RTVEC_ELT (v, 10) = gen_rtx_CONST_INT (QImode, 18);
2508   RTVEC_ELT (v, 11) = gen_rtx_CONST_INT (QImode, 19);
2509   RTVEC_ELT (v, 12) = gen_rtx_CONST_INT (QImode, 24);
2510   RTVEC_ELT (v, 13) = gen_rtx_CONST_INT (QImode, 25);
2511   RTVEC_ELT (v, 14) = gen_rtx_CONST_INT (QImode, 26);
2512   RTVEC_ELT (v, 15) = gen_rtx_CONST_INT (QImode, 27);
2513   emit_insn (gen_vec_initv16qi (mask, gen_rtx_PARALLEL (V16QImode, v)));
2514   emit_insn (gen_altivec_vperm_v4si (operands[0], operands[1], operands[2], mask));
2515   
2516   DONE;
2519 (define_expand "vec_extract_evenv4sf"
2520  [(set (match_operand:V4SF 0 "register_operand" "")
2521         (unspec:V8HI [(match_operand:V4SF 1 "register_operand" "")
2522                       (match_operand:V4SF 2 "register_operand" "")]
2523                       UNSPEC_EXTEVEN_V4SF))]
2524   "TARGET_ALTIVEC"
2525   "
2527   rtx mask = gen_reg_rtx (V16QImode);
2528   rtvec v = rtvec_alloc (16);
2529   
2530   RTVEC_ELT (v, 0) = gen_rtx_CONST_INT (QImode, 0);
2531   RTVEC_ELT (v, 1) = gen_rtx_CONST_INT (QImode, 1);
2532   RTVEC_ELT (v, 2) = gen_rtx_CONST_INT (QImode, 2);
2533   RTVEC_ELT (v, 3) = gen_rtx_CONST_INT (QImode, 3);
2534   RTVEC_ELT (v, 4) = gen_rtx_CONST_INT (QImode, 8);
2535   RTVEC_ELT (v, 5) = gen_rtx_CONST_INT (QImode, 9);
2536   RTVEC_ELT (v, 6) = gen_rtx_CONST_INT (QImode, 10);
2537   RTVEC_ELT (v, 7) = gen_rtx_CONST_INT (QImode, 11);
2538   RTVEC_ELT (v, 8) = gen_rtx_CONST_INT (QImode, 16);
2539   RTVEC_ELT (v, 9) = gen_rtx_CONST_INT (QImode, 17);
2540   RTVEC_ELT (v, 10) = gen_rtx_CONST_INT (QImode, 18);
2541   RTVEC_ELT (v, 11) = gen_rtx_CONST_INT (QImode, 19);
2542   RTVEC_ELT (v, 12) = gen_rtx_CONST_INT (QImode, 24);
2543   RTVEC_ELT (v, 13) = gen_rtx_CONST_INT (QImode, 25);
2544   RTVEC_ELT (v, 14) = gen_rtx_CONST_INT (QImode, 26);
2545   RTVEC_ELT (v, 15) = gen_rtx_CONST_INT (QImode, 27);
2546   emit_insn (gen_vec_initv16qi (mask, gen_rtx_PARALLEL (V16QImode, v)));
2547   emit_insn (gen_altivec_vperm_v4sf (operands[0], operands[1], operands[2], mask));
2548   
2549   DONE;
2552 (define_expand "vec_extract_evenv8hi"
2553  [(set (match_operand:V4SI 0 "register_operand" "")
2554         (unspec:V8HI [(match_operand:V8HI 1 "register_operand" "")
2555                       (match_operand:V8HI 2 "register_operand" "")]
2556                       UNSPEC_EXTEVEN_V8HI))]
2557   "TARGET_ALTIVEC"
2558   "
2560   rtx mask = gen_reg_rtx (V16QImode);
2561   rtvec v = rtvec_alloc (16);
2562   
2563   RTVEC_ELT (v, 0) = gen_rtx_CONST_INT (QImode, 0);
2564   RTVEC_ELT (v, 1) = gen_rtx_CONST_INT (QImode, 1);
2565   RTVEC_ELT (v, 2) = gen_rtx_CONST_INT (QImode, 4);
2566   RTVEC_ELT (v, 3) = gen_rtx_CONST_INT (QImode, 5);
2567   RTVEC_ELT (v, 4) = gen_rtx_CONST_INT (QImode, 8);
2568   RTVEC_ELT (v, 5) = gen_rtx_CONST_INT (QImode, 9);
2569   RTVEC_ELT (v, 6) = gen_rtx_CONST_INT (QImode, 12);
2570   RTVEC_ELT (v, 7) = gen_rtx_CONST_INT (QImode, 13);
2571   RTVEC_ELT (v, 8) = gen_rtx_CONST_INT (QImode, 16);
2572   RTVEC_ELT (v, 9) = gen_rtx_CONST_INT (QImode, 17);
2573   RTVEC_ELT (v, 10) = gen_rtx_CONST_INT (QImode, 20);
2574   RTVEC_ELT (v, 11) = gen_rtx_CONST_INT (QImode, 21);
2575   RTVEC_ELT (v, 12) = gen_rtx_CONST_INT (QImode, 24);
2576   RTVEC_ELT (v, 13) = gen_rtx_CONST_INT (QImode, 25);
2577   RTVEC_ELT (v, 14) = gen_rtx_CONST_INT (QImode, 28);
2578   RTVEC_ELT (v, 15) = gen_rtx_CONST_INT (QImode, 29);
2579   emit_insn (gen_vec_initv16qi (mask, gen_rtx_PARALLEL (V16QImode, v)));
2580   emit_insn (gen_altivec_vperm_v8hi (operands[0], operands[1], operands[2], mask));
2581   
2582   DONE;
2585 (define_expand "vec_extract_evenv16qi"
2586  [(set (match_operand:V4SI 0 "register_operand" "")
2587         (unspec:V8HI [(match_operand:V16QI 1 "register_operand" "")
2588                       (match_operand:V16QI 2 "register_operand" "")]
2589                       UNSPEC_EXTEVEN_V16QI))]
2590   "TARGET_ALTIVEC"
2591   "
2593   rtx mask = gen_reg_rtx (V16QImode);
2594   rtvec v = rtvec_alloc (16);
2595   
2596   RTVEC_ELT (v, 0) = gen_rtx_CONST_INT (QImode, 0);
2597   RTVEC_ELT (v, 1) = gen_rtx_CONST_INT (QImode, 2);
2598   RTVEC_ELT (v, 2) = gen_rtx_CONST_INT (QImode, 4);
2599   RTVEC_ELT (v, 3) = gen_rtx_CONST_INT (QImode, 6);
2600   RTVEC_ELT (v, 4) = gen_rtx_CONST_INT (QImode, 8);
2601   RTVEC_ELT (v, 5) = gen_rtx_CONST_INT (QImode, 10);
2602   RTVEC_ELT (v, 6) = gen_rtx_CONST_INT (QImode, 12);
2603   RTVEC_ELT (v, 7) = gen_rtx_CONST_INT (QImode, 14);
2604   RTVEC_ELT (v, 8) = gen_rtx_CONST_INT (QImode, 16);
2605   RTVEC_ELT (v, 9) = gen_rtx_CONST_INT (QImode, 18);
2606   RTVEC_ELT (v, 10) = gen_rtx_CONST_INT (QImode, 20);
2607   RTVEC_ELT (v, 11) = gen_rtx_CONST_INT (QImode, 22);
2608   RTVEC_ELT (v, 12) = gen_rtx_CONST_INT (QImode, 24);
2609   RTVEC_ELT (v, 13) = gen_rtx_CONST_INT (QImode, 26);
2610   RTVEC_ELT (v, 14) = gen_rtx_CONST_INT (QImode, 28);
2611   RTVEC_ELT (v, 15) = gen_rtx_CONST_INT (QImode, 30);
2612   emit_insn (gen_vec_initv16qi (mask, gen_rtx_PARALLEL (V16QImode, v)));
2613   emit_insn (gen_altivec_vperm_v16qi (operands[0], operands[1], operands[2], mask));
2614   
2615   DONE;
2618 (define_expand "vec_extract_oddv4si"
2619  [(set (match_operand:V4SI 0 "register_operand" "")
2620         (unspec:V8HI [(match_operand:V4SI 1 "register_operand" "")
2621                       (match_operand:V4SI 2 "register_operand" "")]
2622                       UNSPEC_EXTODD_V4SI))]
2623   "TARGET_ALTIVEC"
2624   "
2626   rtx mask = gen_reg_rtx (V16QImode);
2627   rtvec v = rtvec_alloc (16);
2629   RTVEC_ELT (v, 0) = gen_rtx_CONST_INT (QImode, 4);
2630   RTVEC_ELT (v, 1) = gen_rtx_CONST_INT (QImode, 5);
2631   RTVEC_ELT (v, 2) = gen_rtx_CONST_INT (QImode, 6);
2632   RTVEC_ELT (v, 3) = gen_rtx_CONST_INT (QImode, 7);
2633   RTVEC_ELT (v, 4) = gen_rtx_CONST_INT (QImode, 12);
2634   RTVEC_ELT (v, 5) = gen_rtx_CONST_INT (QImode, 13);
2635   RTVEC_ELT (v, 6) = gen_rtx_CONST_INT (QImode, 14);
2636   RTVEC_ELT (v, 7) = gen_rtx_CONST_INT (QImode, 15);
2637   RTVEC_ELT (v, 8) = gen_rtx_CONST_INT (QImode, 20);
2638   RTVEC_ELT (v, 9) = gen_rtx_CONST_INT (QImode, 21);
2639   RTVEC_ELT (v, 10) = gen_rtx_CONST_INT (QImode, 22);
2640   RTVEC_ELT (v, 11) = gen_rtx_CONST_INT (QImode, 23);
2641   RTVEC_ELT (v, 12) = gen_rtx_CONST_INT (QImode, 28);
2642   RTVEC_ELT (v, 13) = gen_rtx_CONST_INT (QImode, 29);
2643   RTVEC_ELT (v, 14) = gen_rtx_CONST_INT (QImode, 30);
2644   RTVEC_ELT (v, 15) = gen_rtx_CONST_INT (QImode, 31);
2645   emit_insn (gen_vec_initv16qi (mask, gen_rtx_PARALLEL (V16QImode, v)));
2646   emit_insn (gen_altivec_vperm_v4si (operands[0], operands[1], operands[2], mask));
2647   
2648   DONE;
2651 (define_expand "vec_extract_oddv4sf"
2652  [(set (match_operand:V4SF 0 "register_operand" "")
2653         (unspec:V8HI [(match_operand:V4SF 1 "register_operand" "")
2654                       (match_operand:V4SF 2 "register_operand" "")]
2655                       UNSPEC_EXTODD_V4SF))]
2656   "TARGET_ALTIVEC"
2657   "
2659   rtx mask = gen_reg_rtx (V16QImode);
2660   rtvec v = rtvec_alloc (16);
2662   RTVEC_ELT (v, 0) = gen_rtx_CONST_INT (QImode, 4);
2663   RTVEC_ELT (v, 1) = gen_rtx_CONST_INT (QImode, 5);
2664   RTVEC_ELT (v, 2) = gen_rtx_CONST_INT (QImode, 6);
2665   RTVEC_ELT (v, 3) = gen_rtx_CONST_INT (QImode, 7);
2666   RTVEC_ELT (v, 4) = gen_rtx_CONST_INT (QImode, 12);
2667   RTVEC_ELT (v, 5) = gen_rtx_CONST_INT (QImode, 13);
2668   RTVEC_ELT (v, 6) = gen_rtx_CONST_INT (QImode, 14);
2669   RTVEC_ELT (v, 7) = gen_rtx_CONST_INT (QImode, 15);
2670   RTVEC_ELT (v, 8) = gen_rtx_CONST_INT (QImode, 20);
2671   RTVEC_ELT (v, 9) = gen_rtx_CONST_INT (QImode, 21);
2672   RTVEC_ELT (v, 10) = gen_rtx_CONST_INT (QImode, 22);
2673   RTVEC_ELT (v, 11) = gen_rtx_CONST_INT (QImode, 23);
2674   RTVEC_ELT (v, 12) = gen_rtx_CONST_INT (QImode, 28);
2675   RTVEC_ELT (v, 13) = gen_rtx_CONST_INT (QImode, 29);
2676   RTVEC_ELT (v, 14) = gen_rtx_CONST_INT (QImode, 30);
2677   RTVEC_ELT (v, 15) = gen_rtx_CONST_INT (QImode, 31);
2678   emit_insn (gen_vec_initv16qi (mask, gen_rtx_PARALLEL (V16QImode, v)));
2679   emit_insn (gen_altivec_vperm_v4sf (operands[0], operands[1], operands[2], mask));
2681   DONE;
2684 (define_insn "vpkuhum_nomode"
2685   [(set (match_operand:V16QI 0 "register_operand" "=v")
2686         (unspec:V16QI [(match_operand 1 "register_operand" "v")
2687                        (match_operand 2 "register_operand" "v")]
2688                       UNSPEC_VPKUHUM))] 
2689   "TARGET_ALTIVEC"
2690   "vpkuhum %0,%1,%2"
2691   [(set_attr "type" "vecperm")])
2693 (define_insn "vpkuwum_nomode"
2694   [(set (match_operand:V8HI 0 "register_operand" "=v")
2695         (unspec:V8HI [(match_operand 1 "register_operand" "v")
2696                       (match_operand 2 "register_operand" "v")]
2697                      UNSPEC_VPKUWUM))]
2698   "TARGET_ALTIVEC"
2699   "vpkuwum %0,%1,%2"
2700   [(set_attr "type" "vecperm")])
2702 (define_expand "vec_extract_oddv8hi"
2703  [(set (match_operand:V8HI 0 "register_operand" "")
2704         (unspec:V8HI [(match_operand:V8HI 1 "register_operand" "")
2705                       (match_operand:V8HI 2 "register_operand" "")]
2706                       UNSPEC_EXTODD_V8HI))]
2707   "TARGET_ALTIVEC"
2708   "
2710   emit_insn (gen_vpkuwum_nomode (operands[0], operands[1], operands[2]));
2711   DONE;
2714 (define_expand "vec_extract_oddv16qi"
2715  [(set (match_operand:V16QI 0 "register_operand" "")
2716         (unspec:V16QI [(match_operand:V16QI 1 "register_operand" "")
2717                       (match_operand:V16QI 2 "register_operand" "")]
2718                       UNSPEC_EXTODD_V16QI))]
2719   "TARGET_ALTIVEC"
2720   "
2722   emit_insn (gen_vpkuhum_nomode (operands[0], operands[1], operands[2]));
2723   DONE;
2726 (define_expand "vec_interleave_high<mode>"
2727  [(set (match_operand:VI 0 "register_operand" "")
2728         (unspec:VI [(match_operand:VI 1 "register_operand" "")
2729                     (match_operand:VI 2 "register_operand" "")]
2730                      UNSPEC_INTERHI))]
2731   "TARGET_ALTIVEC"
2732   "
2734   emit_insn (gen_altivec_vmrgh<VI_char> (operands[0], operands[1], operands[2]));
2735   DONE;
2738 (define_expand "vec_interleave_low<mode>"
2739  [(set (match_operand:VI 0 "register_operand" "")
2740         (unspec:VI [(match_operand:VI 1 "register_operand" "")
2741                     (match_operand:VI 2 "register_operand" "")]
2742                      UNSPEC_INTERLO))]
2743   "TARGET_ALTIVEC"
2744   "
2746   emit_insn (gen_altivec_vmrgl<VI_char> (operands[0], operands[1], operands[2]));
2747   DONE;
2750 (define_expand "vec_unpacks_float_hi_v8hi"
2751  [(set (match_operand:V4SF 0 "register_operand" "")
2752         (unspec:V4SF [(match_operand:V8HI 1 "register_operand" "")]
2753                      UNSPEC_VUPKHS_V4SF))]
2754   "TARGET_ALTIVEC"
2755   "
2757   rtx tmp = gen_reg_rtx (V4SImode);
2759   emit_insn (gen_vec_unpacks_hi_v8hi (tmp, operands[1]));
2760   emit_insn (gen_altivec_vcfsx (operands[0], tmp, const0_rtx));
2761   DONE;
2764 (define_expand "vec_unpacks_float_lo_v8hi"
2765  [(set (match_operand:V4SF 0 "register_operand" "")
2766         (unspec:V4SF [(match_operand:V8HI 1 "register_operand" "")]
2767                      UNSPEC_VUPKLS_V4SF))]
2768   "TARGET_ALTIVEC"
2769   "
2771   rtx tmp = gen_reg_rtx (V4SImode);
2773   emit_insn (gen_vec_unpacks_lo_v8hi (tmp, operands[1]));
2774   emit_insn (gen_altivec_vcfsx (operands[0], tmp, const0_rtx));
2775   DONE;
2778 (define_expand "vec_unpacku_float_hi_v8hi"
2779  [(set (match_operand:V4SF 0 "register_operand" "")
2780         (unspec:V4SF [(match_operand:V8HI 1 "register_operand" "")]
2781                      UNSPEC_VUPKHU_V4SF))]
2782   "TARGET_ALTIVEC"
2783   "
2785   rtx tmp = gen_reg_rtx (V4SImode);
2787   emit_insn (gen_vec_unpacku_hi_v8hi (tmp, operands[1]));
2788   emit_insn (gen_altivec_vcfux (operands[0], tmp, const0_rtx));
2789   DONE;
2792 (define_expand "vec_unpacku_float_lo_v8hi"
2793  [(set (match_operand:V4SF 0 "register_operand" "")
2794         (unspec:V4SF [(match_operand:V8HI 1 "register_operand" "")]
2795                      UNSPEC_VUPKLU_V4SF))]
2796   "TARGET_ALTIVEC"
2797   "
2799   rtx tmp = gen_reg_rtx (V4SImode);
2801   emit_insn (gen_vec_unpacku_lo_v8hi (tmp, operands[1]));
2802   emit_insn (gen_altivec_vcfux (operands[0], tmp, const0_rtx));
2803   DONE;