OSDN Git Service

PR target/41082
[pf3gnuchains/gcc-fork.git] / gcc / config / rs6000 / altivec.md
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)
5
6 ;; This file is part of GCC.
7
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.
12
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.
17
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/>.
21
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 ])
147
148 (define_constants
149   [(UNSPECV_SET_VRSAVE   30)
150    (UNSPECV_MTVSCR      186)
151    (UNSPECV_MFVSCR      187)
152    (UNSPECV_DSSALL      188)
153    (UNSPECV_DSS         189)
154   ])
155
156 ;; Vec int modes
157 (define_mode_iterator VI [V4SI V8HI V16QI])
158 ;; Short vec in modes
159 (define_mode_iterator VIshort [V8HI V16QI])
160 ;; Vec float modes
161 (define_mode_iterator VF [V4SF])
162 ;; Vec modes, pity mode iterators are not composable
163 (define_mode_iterator V [V4SI V8HI V16QI V4SF])
164 ;; Vec modes for move/logical/permute ops, include vector types for move not
165 ;; otherwise handled by altivec (v2df, v2di, ti)
166 (define_mode_iterator VM [V4SI V8HI V16QI V4SF V2DF V2DI TI])
167
168 ;; Like VM, except don't do TImode
169 (define_mode_iterator VM2 [V4SI V8HI V16QI V4SF V2DF V2DI])
170
171 (define_mode_attr VI_char [(V4SI "w") (V8HI "h") (V16QI "b")])
172 (define_mode_attr VI_scalar [(V4SI "SI") (V8HI "HI") (V16QI "QI")])
173
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))"
181 {
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     }
194 }
195   [(set_attr "type" "vecstore,vecload,vecsimple,store,load,*,vecsimple,*")])
196
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))"
206 {
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     }
219 }
220   [(set_attr "type" "vecstore,vecload,vecsimple,store,load,*,vecsimple,*")])
221
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)]
229 {
230   rtx dest = operands[0];
231   enum machine_mode mode = GET_MODE (operands[0]);
232   rtvec v;
233   int i, num_elements;
234
235   if (mode == V4SFmode)
236     {
237       mode = V4SImode;
238       dest = gen_lowpart (V4SImode, dest);
239     }
240
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;
245
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;
249 })
250
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))]
257 {
258   rtx dup = gen_easy_altivec_constant (operands[1]);
259   rtx const_vec;
260   enum machine_mode op_mode = <MODE>mode;
261
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);
267
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]);
278 })
279
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"
284 {
285   if (TARGET_MACHO)
286      return "mfspr %0,256";
287   else
288      return "mfvrsave %0";
289 }
290   [(set_attr "type" "*")])
291
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"
298 {
299   if (TARGET_MACHO)
300     return "mtspr 256,%1";
301   else
302     return "mtvrsave %1";
303 }
304   [(set_attr "type" "*")])
305
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")])
314
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")
323
324 ;; Simple binary operations.
325
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")])
334
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")])
342
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")])
351
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")])
361
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")])
371
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")])
380
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")])
388
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")])
397
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")])
407
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")])
417
418 ;;
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")])
427
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")])
436
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")])
445
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")])
453
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")])
461
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")])
469
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")])
477
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")])
485
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")])
493
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")])
504
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")])
515
516 ;; Fused multiply add.
517
518 (define_insn "*altivec_fmav4sf4"
519   [(set (match_operand:V4SF 0 "register_operand" "=v")
520         (fma:V4SF (match_operand:V4SF 1 "register_operand" "v")
521                   (match_operand:V4SF 2 "register_operand" "v")
522                   (match_operand:V4SF 3 "register_operand" "v")))]
523   "VECTOR_UNIT_ALTIVEC_P (V4SFmode)"
524   "vmaddfp %0,%1,%2,%3"
525   [(set_attr "type" "vecfloat")])
526
527 ;; We do multiply as a fused multiply-add with an add of a -0.0 vector.
528
529 (define_expand "altivec_mulv4sf3"
530   [(set (match_operand:V4SF 0 "register_operand" "")
531         (fma:V4SF (match_operand:V4SF 1 "register_operand" "")
532                   (match_operand:V4SF 2 "register_operand" "")
533                   (match_dup 3)))]
534   "VECTOR_UNIT_ALTIVEC_P (V4SFmode)"
535 {
536   rtx neg0;
537
538   /* Generate [-0.0, -0.0, -0.0, -0.0].  */
539   neg0 = gen_reg_rtx (V4SImode);
540   emit_insn (gen_altivec_vspltisw (neg0, constm1_rtx));
541   emit_insn (gen_vashlv4si3 (neg0, neg0, neg0));
542
543   operands[3] = gen_lowpart (V4SFmode, neg0);
544 })
545
546 ;; 32-bit integer multiplication
547 ;; A_high = Operand_0 & 0xFFFF0000 >> 16
548 ;; A_low = Operand_0 & 0xFFFF
549 ;; B_high = Operand_1 & 0xFFFF0000 >> 16
550 ;; B_low = Operand_1 & 0xFFFF
551 ;; result = A_low * B_low + (A_high * B_low + B_high * A_low) << 16
552
553 ;; (define_insn "mulv4si3"
554 ;;   [(set (match_operand:V4SI 0 "register_operand" "=v")
555 ;;         (mult:V4SI (match_operand:V4SI 1 "register_operand" "v")
556 ;;                    (match_operand:V4SI 2 "register_operand" "v")))]
557 (define_expand "mulv4si3"
558   [(use (match_operand:V4SI 0 "register_operand" ""))
559    (use (match_operand:V4SI 1 "register_operand" ""))
560    (use (match_operand:V4SI 2 "register_operand" ""))]
561    "TARGET_ALTIVEC"
562    "
563  {
564    rtx zero;
565    rtx swap;
566    rtx small_swap;
567    rtx sixteen;
568    rtx one;
569    rtx two;
570    rtx low_product;
571    rtx high_product;
572        
573    zero = gen_reg_rtx (V4SImode);
574    emit_insn (gen_altivec_vspltisw (zero, const0_rtx));
575  
576    sixteen = gen_reg_rtx (V4SImode);   
577    emit_insn (gen_altivec_vspltisw (sixteen,  gen_rtx_CONST_INT (V4SImode, -16)));
578  
579    swap = gen_reg_rtx (V4SImode);
580    emit_insn (gen_vrotlv4si3 (swap, operands[2], sixteen));
581  
582    one = gen_reg_rtx (V8HImode);
583    convert_move (one, operands[1], 0);
584  
585    two = gen_reg_rtx (V8HImode);
586    convert_move (two, operands[2], 0);
587  
588    small_swap = gen_reg_rtx (V8HImode);
589    convert_move (small_swap, swap, 0);
590  
591    low_product = gen_reg_rtx (V4SImode);
592    emit_insn (gen_altivec_vmulouh (low_product, one, two));
593  
594    high_product = gen_reg_rtx (V4SImode);
595    emit_insn (gen_altivec_vmsumuhm (high_product, one, small_swap, zero));
596  
597    emit_insn (gen_vashlv4si3 (high_product, high_product, sixteen));
598  
599    emit_insn (gen_addv4si3 (operands[0], high_product, low_product));
600    
601    DONE;
602  }")
603  
604 (define_expand "mulv8hi3"
605   [(use (match_operand:V8HI 0 "register_operand" ""))
606    (use (match_operand:V8HI 1 "register_operand" ""))
607    (use (match_operand:V8HI 2 "register_operand" ""))]
608    "TARGET_ALTIVEC"
609    "
610 {
611    rtx odd = gen_reg_rtx (V4SImode);
612    rtx even = gen_reg_rtx (V4SImode);
613    rtx high = gen_reg_rtx (V4SImode);
614    rtx low = gen_reg_rtx (V4SImode);
615
616    emit_insn (gen_altivec_vmulesh (even, operands[1], operands[2]));
617    emit_insn (gen_altivec_vmulosh (odd, operands[1], operands[2]));
618
619    emit_insn (gen_altivec_vmrghw (high, even, odd));
620    emit_insn (gen_altivec_vmrglw (low, even, odd));
621
622    emit_insn (gen_altivec_vpkuwum (operands[0], high, low));
623
624    DONE;
625 }")
626
627 ;; Fused multiply subtract 
628 (define_insn "*altivec_vnmsubfp"
629   [(set (match_operand:V4SF 0 "register_operand" "=v")
630         (neg:V4SF
631          (fma:V4SF (match_operand:V4SF 1 "register_operand" "v")
632                    (match_operand:V4SF 2 "register_operand" "v")
633                    (neg:V4SF
634                     (match_operand:V4SF 3 "register_operand" "v")))))]
635   "VECTOR_UNIT_ALTIVEC_P (V4SFmode)"
636   "vnmsubfp %0,%1,%2,%3"
637   [(set_attr "type" "vecfloat")])
638
639 (define_insn "altivec_vmsumu<VI_char>m"
640   [(set (match_operand:V4SI 0 "register_operand" "=v")
641         (unspec:V4SI [(match_operand:VIshort 1 "register_operand" "v")
642                       (match_operand:VIshort 2 "register_operand" "v")
643                       (match_operand:V4SI 3 "register_operand" "v")]
644                      UNSPEC_VMSUMU))]
645   "TARGET_ALTIVEC"
646   "vmsumu<VI_char>m %0,%1,%2,%3"
647   [(set_attr "type" "veccomplex")])
648
649 (define_insn "altivec_vmsumm<VI_char>m"
650   [(set (match_operand:V4SI 0 "register_operand" "=v")
651         (unspec:V4SI [(match_operand:VIshort 1 "register_operand" "v")
652                       (match_operand:VIshort 2 "register_operand" "v")
653                       (match_operand:V4SI 3 "register_operand" "v")]
654                      UNSPEC_VMSUMM))]
655   "TARGET_ALTIVEC"
656   "vmsumm<VI_char>m %0,%1,%2,%3"
657   [(set_attr "type" "veccomplex")])
658
659 (define_insn "altivec_vmsumshm"
660   [(set (match_operand:V4SI 0 "register_operand" "=v")
661         (unspec:V4SI [(match_operand:V8HI 1 "register_operand" "v")
662                       (match_operand:V8HI 2 "register_operand" "v")
663                       (match_operand:V4SI 3 "register_operand" "v")]
664                      UNSPEC_VMSUMSHM))]
665   "TARGET_ALTIVEC"
666   "vmsumshm %0,%1,%2,%3"
667   [(set_attr "type" "veccomplex")])
668
669 (define_insn "altivec_vmsumuhs"
670   [(set (match_operand:V4SI 0 "register_operand" "=v")
671         (unspec:V4SI [(match_operand:V8HI 1 "register_operand" "v")
672                       (match_operand:V8HI 2 "register_operand" "v")
673                       (match_operand:V4SI 3 "register_operand" "v")]
674                      UNSPEC_VMSUMUHS))
675    (set (reg:SI 110) (unspec:SI [(const_int 0)] UNSPEC_SET_VSCR))]
676   "TARGET_ALTIVEC"
677   "vmsumuhs %0,%1,%2,%3"
678   [(set_attr "type" "veccomplex")])
679
680 (define_insn "altivec_vmsumshs"
681   [(set (match_operand:V4SI 0 "register_operand" "=v")
682         (unspec:V4SI [(match_operand:V8HI 1 "register_operand" "v")
683                       (match_operand:V8HI 2 "register_operand" "v")
684                       (match_operand:V4SI 3 "register_operand" "v")]
685                      UNSPEC_VMSUMSHS))
686    (set (reg:SI 110) (unspec:SI [(const_int 0)] UNSPEC_SET_VSCR))]
687   "TARGET_ALTIVEC"
688   "vmsumshs %0,%1,%2,%3"
689   [(set_attr "type" "veccomplex")])
690
691 ;; max
692
693 (define_insn "umax<mode>3"
694   [(set (match_operand:VI 0 "register_operand" "=v")
695         (umax:VI (match_operand:VI 1 "register_operand" "v")
696                  (match_operand:VI 2 "register_operand" "v")))]
697   "TARGET_ALTIVEC"
698   "vmaxu<VI_char> %0,%1,%2"
699   [(set_attr "type" "vecsimple")])
700
701 (define_insn "smax<mode>3"
702   [(set (match_operand:VI 0 "register_operand" "=v")
703         (smax:VI (match_operand:VI 1 "register_operand" "v")
704                  (match_operand:VI 2 "register_operand" "v")))]
705   "TARGET_ALTIVEC"
706   "vmaxs<VI_char> %0,%1,%2"
707   [(set_attr "type" "vecsimple")])
708
709 (define_insn "*altivec_smaxv4sf3"
710   [(set (match_operand:V4SF 0 "register_operand" "=v")
711         (smax:V4SF (match_operand:V4SF 1 "register_operand" "v")
712                    (match_operand:V4SF 2 "register_operand" "v")))]
713   "VECTOR_UNIT_ALTIVEC_P (V4SFmode)"
714   "vmaxfp %0,%1,%2"
715   [(set_attr "type" "veccmp")])
716
717 (define_insn "umin<mode>3"
718   [(set (match_operand:VI 0 "register_operand" "=v")
719         (umin:VI (match_operand:VI 1 "register_operand" "v")
720                  (match_operand:VI 2 "register_operand" "v")))]
721   "TARGET_ALTIVEC"
722   "vminu<VI_char> %0,%1,%2"
723   [(set_attr "type" "vecsimple")])
724
725 (define_insn "smin<mode>3"
726   [(set (match_operand:VI 0 "register_operand" "=v")
727         (smin:VI (match_operand:VI 1 "register_operand" "v")
728                  (match_operand:VI 2 "register_operand" "v")))]
729   "TARGET_ALTIVEC"
730   "vmins<VI_char> %0,%1,%2"
731   [(set_attr "type" "vecsimple")])
732
733 (define_insn "*altivec_sminv4sf3"
734   [(set (match_operand:V4SF 0 "register_operand" "=v")
735         (smin:V4SF (match_operand:V4SF 1 "register_operand" "v")
736                    (match_operand:V4SF 2 "register_operand" "v")))]
737   "VECTOR_UNIT_ALTIVEC_P (V4SFmode)"
738   "vminfp %0,%1,%2"
739   [(set_attr "type" "veccmp")])
740
741 (define_insn "altivec_vmhaddshs"
742   [(set (match_operand:V8HI 0 "register_operand" "=v")
743         (unspec:V8HI [(match_operand:V8HI 1 "register_operand" "v")
744                       (match_operand:V8HI 2 "register_operand" "v")
745                       (match_operand:V8HI 3 "register_operand" "v")]
746                      UNSPEC_VMHADDSHS))
747    (set (reg:SI 110) (unspec:SI [(const_int 0)] UNSPEC_SET_VSCR))]
748   "TARGET_ALTIVEC"
749   "vmhaddshs %0,%1,%2,%3"
750   [(set_attr "type" "veccomplex")])
751
752 (define_insn "altivec_vmhraddshs"
753   [(set (match_operand:V8HI 0 "register_operand" "=v")
754         (unspec:V8HI [(match_operand:V8HI 1 "register_operand" "v")
755                       (match_operand:V8HI 2 "register_operand" "v")
756                       (match_operand:V8HI 3 "register_operand" "v")]
757                      UNSPEC_VMHRADDSHS))
758    (set (reg:SI 110) (unspec:SI [(const_int 0)] UNSPEC_SET_VSCR))]
759   "TARGET_ALTIVEC"
760   "vmhraddshs %0,%1,%2,%3"
761   [(set_attr "type" "veccomplex")])
762
763 (define_insn "altivec_vmladduhm"
764   [(set (match_operand:V8HI 0 "register_operand" "=v")
765         (unspec:V8HI [(match_operand:V8HI 1 "register_operand" "v")
766                       (match_operand:V8HI 2 "register_operand" "v")
767                       (match_operand:V8HI 3 "register_operand" "v")]
768                      UNSPEC_VMLADDUHM))]
769   "TARGET_ALTIVEC"
770   "vmladduhm %0,%1,%2,%3"
771   [(set_attr "type" "veccomplex")])
772
773 (define_insn "altivec_vmrghb"
774   [(set (match_operand:V16QI 0 "register_operand" "=v")
775         (vec_merge:V16QI (vec_select:V16QI (match_operand:V16QI 1 "register_operand" "v")
776                                            (parallel [(const_int 0)
777                                                       (const_int 8)
778                                                       (const_int 1)
779                                                       (const_int 9)
780                                                       (const_int 2)
781                                                       (const_int 10)
782                                                       (const_int 3)
783                                                       (const_int 11)
784                                                       (const_int 4)
785                                                       (const_int 12)
786                                                       (const_int 5)
787                                                       (const_int 13)
788                                                       (const_int 6)
789                                                       (const_int 14)
790                                                       (const_int 7)
791                                                       (const_int 15)]))
792                         (vec_select:V16QI (match_operand:V16QI 2 "register_operand" "v")
793                                            (parallel [(const_int 8)
794                                                       (const_int 0)
795                                                       (const_int 9)
796                                                       (const_int 1)
797                                                       (const_int 10)
798                                                       (const_int 2)
799                                                       (const_int 11)
800                                                       (const_int 3)
801                                                       (const_int 12)
802                                                       (const_int 4)
803                                                       (const_int 13)
804                                                       (const_int 5)
805                                                       (const_int 14)
806                                                       (const_int 6)
807                                                       (const_int 15)
808                                                       (const_int 7)]))
809                       (const_int 21845)))]
810   "TARGET_ALTIVEC"
811   "vmrghb %0,%1,%2"
812   [(set_attr "type" "vecperm")])
813
814 (define_insn "altivec_vmrghh"
815   [(set (match_operand:V8HI 0 "register_operand" "=v")
816         (vec_merge:V8HI (vec_select:V8HI (match_operand:V8HI 1 "register_operand" "v")
817                                            (parallel [(const_int 0)
818                                                       (const_int 4)
819                                                       (const_int 1)
820                                                       (const_int 5)
821                                                       (const_int 2)
822                                                       (const_int 6)
823                                                       (const_int 3)
824                                                       (const_int 7)]))
825                         (vec_select:V8HI (match_operand:V8HI 2 "register_operand" "v")
826                                            (parallel [(const_int 4)
827                                                       (const_int 0)
828                                                       (const_int 5)
829                                                       (const_int 1)
830                                                       (const_int 6)
831                                                       (const_int 2)
832                                                       (const_int 7)
833                                                       (const_int 3)]))
834                       (const_int 85)))]
835   "TARGET_ALTIVEC"
836   "vmrghh %0,%1,%2"
837   [(set_attr "type" "vecperm")])
838
839 (define_insn "altivec_vmrghw"
840   [(set (match_operand:V4SI 0 "register_operand" "=v")
841         (vec_merge:V4SI (vec_select:V4SI (match_operand:V4SI 1 "register_operand" "v")
842                                          (parallel [(const_int 0)
843                                                     (const_int 2)
844                                                     (const_int 1)
845                                                     (const_int 3)]))
846                         (vec_select:V4SI (match_operand:V4SI 2 "register_operand" "v")
847                                          (parallel [(const_int 2)
848                                                     (const_int 0)
849                                                     (const_int 3)
850                                                     (const_int 1)]))
851                       (const_int 5)))]
852   "VECTOR_MEM_ALTIVEC_P (V4SImode)"
853   "vmrghw %0,%1,%2"
854   [(set_attr "type" "vecperm")])
855
856 (define_insn "*altivec_vmrghsf"
857   [(set (match_operand:V4SF 0 "register_operand" "=v")
858         (vec_merge:V4SF (vec_select:V4SF (match_operand:V4SF 1 "register_operand" "v")
859                                          (parallel [(const_int 0)
860                                                     (const_int 2)
861                                                     (const_int 1)
862                                                     (const_int 3)]))
863                         (vec_select:V4SF (match_operand:V4SF 2 "register_operand" "v")
864                                          (parallel [(const_int 2)
865                                                     (const_int 0)
866                                                     (const_int 3)
867                                                     (const_int 1)]))
868                       (const_int 5)))]
869   "VECTOR_MEM_ALTIVEC_P (V4SFmode)"
870   "vmrghw %0,%1,%2"
871   [(set_attr "type" "vecperm")])
872
873 (define_insn "altivec_vmrglb"
874   [(set (match_operand:V16QI 0 "register_operand" "=v")
875         (vec_merge:V16QI (vec_select:V16QI (match_operand:V16QI 1 "register_operand" "v")
876                                            (parallel [(const_int 8)
877                                                       (const_int 0)
878                                                       (const_int 9)
879                                                       (const_int 1)
880                                                       (const_int 10)
881                                                       (const_int 2)
882                                                       (const_int 11)
883                                                       (const_int 3)
884                                                       (const_int 12)
885                                                       (const_int 4)
886                                                       (const_int 13)
887                                                       (const_int 5)
888                                                       (const_int 14)
889                                                       (const_int 6)
890                                                       (const_int 15)
891                                                       (const_int 7)]))
892                       (vec_select:V16QI (match_operand:V16QI 2 "register_operand" "v")
893                                            (parallel [(const_int 0)
894                                                       (const_int 8)
895                                                       (const_int 1)
896                                                       (const_int 9)
897                                                       (const_int 2)
898                                                       (const_int 10)
899                                                       (const_int 3)
900                                                       (const_int 11)
901                                                       (const_int 4)
902                                                       (const_int 12)
903                                                       (const_int 5)
904                                                       (const_int 13)
905                                                       (const_int 6)
906                                                       (const_int 14)
907                                                       (const_int 7)
908                                                       (const_int 15)]))
909                       (const_int 21845)))]
910   "TARGET_ALTIVEC"
911   "vmrglb %0,%1,%2"
912   [(set_attr "type" "vecperm")])
913
914 (define_insn "altivec_vmrglh"
915   [(set (match_operand:V8HI 0 "register_operand" "=v")
916         (vec_merge:V8HI (vec_select:V8HI (match_operand:V8HI 1 "register_operand" "v")
917                                            (parallel [(const_int 4)
918                                                       (const_int 0)
919                                                       (const_int 5)
920                                                       (const_int 1)
921                                                       (const_int 6)
922                                                       (const_int 2)
923                                                       (const_int 7)
924                                                       (const_int 3)]))
925                         (vec_select:V8HI (match_operand:V8HI 2 "register_operand" "v")
926                                            (parallel [(const_int 0)
927                                                       (const_int 4)
928                                                       (const_int 1)
929                                                       (const_int 5)
930                                                       (const_int 2)
931                                                       (const_int 6)
932                                                       (const_int 3)
933                                                       (const_int 7)]))
934                       (const_int 85)))]
935   "TARGET_ALTIVEC"
936   "vmrglh %0,%1,%2"
937   [(set_attr "type" "vecperm")])
938
939 (define_insn "altivec_vmrglw"
940   [(set (match_operand:V4SI 0 "register_operand" "=v")
941         (vec_merge:V4SI
942          (vec_select:V4SI (match_operand:V4SI 1 "register_operand" "v")
943                           (parallel [(const_int 2)
944                                      (const_int 0)
945                                      (const_int 3)
946                                      (const_int 1)]))
947          (vec_select:V4SI (match_operand:V4SI 2 "register_operand" "v")
948                           (parallel [(const_int 0)
949                                      (const_int 2)
950                                      (const_int 1)
951                                      (const_int 3)]))
952          (const_int 5)))]
953   "VECTOR_MEM_ALTIVEC_P (V4SImode)"
954   "vmrglw %0,%1,%2"
955   [(set_attr "type" "vecperm")])
956
957 (define_insn "*altivec_vmrglsf"
958   [(set (match_operand:V4SF 0 "register_operand" "=v")
959         (vec_merge:V4SF
960          (vec_select:V4SF (match_operand:V4SF 1 "register_operand" "v")
961                           (parallel [(const_int 2)
962                                      (const_int 0)
963                                      (const_int 3)
964                                      (const_int 1)]))
965          (vec_select:V4SF (match_operand:V4SF 2 "register_operand" "v")
966                           (parallel [(const_int 0)
967                                      (const_int 2)
968                                      (const_int 1)
969                                      (const_int 3)]))
970          (const_int 5)))]
971   "VECTOR_MEM_ALTIVEC_P (V4SFmode)"
972   "vmrglw %0,%1,%2"
973   [(set_attr "type" "vecperm")])
974
975 (define_insn "altivec_vmuleub"
976   [(set (match_operand:V8HI 0 "register_operand" "=v")
977         (unspec:V8HI [(match_operand:V16QI 1 "register_operand" "v")
978                       (match_operand:V16QI 2 "register_operand" "v")]
979                      UNSPEC_VMULEUB))]
980   "TARGET_ALTIVEC"
981   "vmuleub %0,%1,%2"
982   [(set_attr "type" "veccomplex")])
983
984 (define_insn "altivec_vmulesb"
985   [(set (match_operand:V8HI 0 "register_operand" "=v")
986         (unspec:V8HI [(match_operand:V16QI 1 "register_operand" "v")
987                       (match_operand:V16QI 2 "register_operand" "v")]
988                      UNSPEC_VMULESB))]
989   "TARGET_ALTIVEC"
990   "vmulesb %0,%1,%2"
991   [(set_attr "type" "veccomplex")])
992
993 (define_insn "altivec_vmuleuh"
994   [(set (match_operand:V4SI 0 "register_operand" "=v")
995         (unspec:V4SI [(match_operand:V8HI 1 "register_operand" "v")
996                       (match_operand:V8HI 2 "register_operand" "v")]
997                      UNSPEC_VMULEUH))]
998   "TARGET_ALTIVEC"
999   "vmuleuh %0,%1,%2"
1000   [(set_attr "type" "veccomplex")])
1001
1002 (define_insn "altivec_vmulesh"
1003   [(set (match_operand:V4SI 0 "register_operand" "=v")
1004         (unspec:V4SI [(match_operand:V8HI 1 "register_operand" "v")
1005                       (match_operand:V8HI 2 "register_operand" "v")]
1006                      UNSPEC_VMULESH))]
1007   "TARGET_ALTIVEC"
1008   "vmulesh %0,%1,%2"
1009   [(set_attr "type" "veccomplex")])
1010
1011 (define_insn "altivec_vmuloub"
1012   [(set (match_operand:V8HI 0 "register_operand" "=v")
1013         (unspec:V8HI [(match_operand:V16QI 1 "register_operand" "v")
1014                       (match_operand:V16QI 2 "register_operand" "v")]
1015                      UNSPEC_VMULOUB))]
1016   "TARGET_ALTIVEC"
1017   "vmuloub %0,%1,%2"
1018   [(set_attr "type" "veccomplex")])
1019
1020 (define_insn "altivec_vmulosb"
1021   [(set (match_operand:V8HI 0 "register_operand" "=v")
1022         (unspec:V8HI [(match_operand:V16QI 1 "register_operand" "v")
1023                       (match_operand:V16QI 2 "register_operand" "v")]
1024                      UNSPEC_VMULOSB))]
1025   "TARGET_ALTIVEC"
1026   "vmulosb %0,%1,%2"
1027   [(set_attr "type" "veccomplex")])
1028
1029 (define_insn "altivec_vmulouh"
1030   [(set (match_operand:V4SI 0 "register_operand" "=v")
1031         (unspec:V4SI [(match_operand:V8HI 1 "register_operand" "v")
1032                       (match_operand:V8HI 2 "register_operand" "v")]
1033                      UNSPEC_VMULOUH))]
1034   "TARGET_ALTIVEC"
1035   "vmulouh %0,%1,%2"
1036   [(set_attr "type" "veccomplex")])
1037
1038 (define_insn "altivec_vmulosh"
1039   [(set (match_operand:V4SI 0 "register_operand" "=v")
1040         (unspec:V4SI [(match_operand:V8HI 1 "register_operand" "v")
1041                       (match_operand:V8HI 2 "register_operand" "v")]
1042                      UNSPEC_VMULOSH))]
1043   "TARGET_ALTIVEC"
1044   "vmulosh %0,%1,%2"
1045   [(set_attr "type" "veccomplex")])
1046
1047
1048 ;; logical ops.  Have the logical ops follow the memory ops in
1049 ;; terms of whether to prefer VSX or Altivec
1050
1051 (define_insn "*altivec_and<mode>3"
1052   [(set (match_operand:VM 0 "register_operand" "=v")
1053         (and:VM (match_operand:VM 1 "register_operand" "v")
1054                 (match_operand:VM 2 "register_operand" "v")))]
1055   "VECTOR_MEM_ALTIVEC_P (<MODE>mode)"
1056   "vand %0,%1,%2"
1057   [(set_attr "type" "vecsimple")])
1058
1059 (define_insn "*altivec_ior<mode>3"
1060   [(set (match_operand:VM 0 "register_operand" "=v")
1061         (ior:VM (match_operand:VM 1 "register_operand" "v")
1062                 (match_operand:VM 2 "register_operand" "v")))]
1063   "VECTOR_MEM_ALTIVEC_P (<MODE>mode)"
1064   "vor %0,%1,%2"
1065   [(set_attr "type" "vecsimple")])
1066
1067 (define_insn "*altivec_xor<mode>3"
1068   [(set (match_operand:VM 0 "register_operand" "=v")
1069         (xor:VM (match_operand:VM 1 "register_operand" "v")
1070                 (match_operand:VM 2 "register_operand" "v")))]
1071   "VECTOR_MEM_ALTIVEC_P (<MODE>mode)"
1072   "vxor %0,%1,%2"
1073   [(set_attr "type" "vecsimple")])
1074
1075 (define_insn "*altivec_one_cmpl<mode>2"
1076   [(set (match_operand:VM 0 "register_operand" "=v")
1077         (not:VM (match_operand:VM 1 "register_operand" "v")))]
1078   "VECTOR_MEM_ALTIVEC_P (<MODE>mode)"
1079   "vnor %0,%1,%1"
1080   [(set_attr "type" "vecsimple")])
1081   
1082 (define_insn "*altivec_nor<mode>3"
1083   [(set (match_operand:VM 0 "register_operand" "=v")
1084         (not:VM (ior:VM (match_operand:VM 1 "register_operand" "v")
1085                         (match_operand:VM 2 "register_operand" "v"))))]
1086   "VECTOR_MEM_ALTIVEC_P (<MODE>mode)"
1087   "vnor %0,%1,%2"
1088   [(set_attr "type" "vecsimple")])
1089
1090 (define_insn "*altivec_andc<mode>3"
1091   [(set (match_operand:VM 0 "register_operand" "=v")
1092         (and:VM (not:VM (match_operand:VM 2 "register_operand" "v"))
1093                 (match_operand:VM 1 "register_operand" "v")))]
1094   "VECTOR_MEM_ALTIVEC_P (<MODE>mode)"
1095   "vandc %0,%1,%2"
1096   [(set_attr "type" "vecsimple")])
1097
1098 (define_insn "altivec_vpkuhum"
1099   [(set (match_operand:V16QI 0 "register_operand" "=v")
1100         (unspec:V16QI [(match_operand:V8HI 1 "register_operand" "v")
1101                        (match_operand:V8HI 2 "register_operand" "v")]
1102                       UNSPEC_VPKUHUM))]
1103   "TARGET_ALTIVEC"
1104   "vpkuhum %0,%1,%2"
1105   [(set_attr "type" "vecperm")])
1106
1107 (define_insn "altivec_vpkuwum"
1108   [(set (match_operand:V8HI 0 "register_operand" "=v")
1109         (unspec:V8HI [(match_operand:V4SI 1 "register_operand" "v")
1110                       (match_operand:V4SI 2 "register_operand" "v")]
1111                      UNSPEC_VPKUWUM))]
1112   "TARGET_ALTIVEC"
1113   "vpkuwum %0,%1,%2"
1114   [(set_attr "type" "vecperm")])
1115
1116 (define_insn "altivec_vpkpx"
1117   [(set (match_operand:V8HI 0 "register_operand" "=v")
1118         (unspec:V8HI [(match_operand:V4SI 1 "register_operand" "v")
1119                       (match_operand:V4SI 2 "register_operand" "v")]
1120                      UNSPEC_VPKPX))]
1121   "TARGET_ALTIVEC"
1122   "vpkpx %0,%1,%2"
1123   [(set_attr "type" "vecperm")])
1124
1125 (define_insn "altivec_vpkshss"
1126   [(set (match_operand:V16QI 0 "register_operand" "=v")
1127         (unspec:V16QI [(match_operand:V8HI 1 "register_operand" "v")
1128                        (match_operand:V8HI 2 "register_operand" "v")]
1129                       UNSPEC_VPKSHSS))
1130    (set (reg:SI 110) (unspec:SI [(const_int 0)] UNSPEC_SET_VSCR))]
1131   "TARGET_ALTIVEC"
1132   "vpkshss %0,%1,%2"
1133   [(set_attr "type" "vecperm")])
1134
1135 (define_insn "altivec_vpkswss"
1136   [(set (match_operand:V8HI 0 "register_operand" "=v")
1137         (unspec:V8HI [(match_operand:V4SI 1 "register_operand" "v")
1138                       (match_operand:V4SI 2 "register_operand" "v")]
1139                      UNSPEC_VPKSWSS))
1140    (set (reg:SI 110) (unspec:SI [(const_int 0)] UNSPEC_SET_VSCR))]
1141   "TARGET_ALTIVEC"
1142   "vpkswss %0,%1,%2"
1143   [(set_attr "type" "vecperm")])
1144
1145 (define_insn "altivec_vpkuhus"
1146   [(set (match_operand:V16QI 0 "register_operand" "=v")
1147         (unspec:V16QI [(match_operand:V8HI 1 "register_operand" "v")
1148                        (match_operand:V8HI 2 "register_operand" "v")]
1149                       UNSPEC_VPKUHUS))
1150    (set (reg:SI 110) (unspec:SI [(const_int 0)] UNSPEC_SET_VSCR))]
1151   "TARGET_ALTIVEC"
1152   "vpkuhus %0,%1,%2"
1153   [(set_attr "type" "vecperm")])
1154
1155 (define_insn "altivec_vpkshus"
1156   [(set (match_operand:V16QI 0 "register_operand" "=v")
1157         (unspec:V16QI [(match_operand:V8HI 1 "register_operand" "v")
1158                        (match_operand:V8HI 2 "register_operand" "v")]
1159                       UNSPEC_VPKSHUS))
1160    (set (reg:SI 110) (unspec:SI [(const_int 0)] UNSPEC_SET_VSCR))]
1161   "TARGET_ALTIVEC"
1162   "vpkshus %0,%1,%2"
1163   [(set_attr "type" "vecperm")])
1164
1165 (define_insn "altivec_vpkuwus"
1166   [(set (match_operand:V8HI 0 "register_operand" "=v")
1167         (unspec:V8HI [(match_operand:V4SI 1 "register_operand" "v")
1168                       (match_operand:V4SI 2 "register_operand" "v")]
1169                      UNSPEC_VPKUWUS))
1170    (set (reg:SI 110) (unspec:SI [(const_int 0)] UNSPEC_SET_VSCR))]
1171   "TARGET_ALTIVEC"
1172   "vpkuwus %0,%1,%2"
1173   [(set_attr "type" "vecperm")])
1174
1175 (define_insn "altivec_vpkswus"
1176   [(set (match_operand:V8HI 0 "register_operand" "=v")
1177         (unspec:V8HI [(match_operand:V4SI 1 "register_operand" "v")
1178                       (match_operand:V4SI 2 "register_operand" "v")]
1179                      UNSPEC_VPKSWUS))
1180    (set (reg:SI 110) (unspec:SI [(const_int 0)] UNSPEC_SET_VSCR))]
1181   "TARGET_ALTIVEC"
1182   "vpkswus %0,%1,%2"
1183   [(set_attr "type" "vecperm")])
1184
1185 (define_insn "*altivec_vrl<VI_char>"
1186   [(set (match_operand:VI 0 "register_operand" "=v")
1187         (rotate:VI (match_operand:VI 1 "register_operand" "v")
1188                    (match_operand:VI 2 "register_operand" "v")))]
1189   "TARGET_ALTIVEC"
1190   "vrl<VI_char> %0,%1,%2"
1191   [(set_attr "type" "vecsimple")])
1192
1193 (define_insn "altivec_vsl"
1194   [(set (match_operand:V4SI 0 "register_operand" "=v")
1195         (unspec:V4SI [(match_operand:V4SI 1 "register_operand" "v")
1196                       (match_operand:V4SI 2 "register_operand" "v")]
1197                      UNSPEC_VSLV4SI))]
1198   "TARGET_ALTIVEC"
1199   "vsl %0,%1,%2"
1200   [(set_attr "type" "vecperm")])
1201
1202 (define_insn "altivec_vslo"
1203   [(set (match_operand:V4SI 0 "register_operand" "=v")
1204         (unspec:V4SI [(match_operand:V4SI 1 "register_operand" "v")
1205                       (match_operand:V4SI 2 "register_operand" "v")]
1206                      UNSPEC_VSLO))]
1207   "TARGET_ALTIVEC"
1208   "vslo %0,%1,%2"
1209   [(set_attr "type" "vecperm")])
1210
1211 (define_insn "*altivec_vsl<VI_char>"
1212   [(set (match_operand:VI 0 "register_operand" "=v")
1213         (ashift:VI (match_operand:VI 1 "register_operand" "v")
1214                    (match_operand:VI 2 "register_operand" "v")))]
1215   "TARGET_ALTIVEC"
1216   "vsl<VI_char> %0,%1,%2"
1217   [(set_attr "type" "vecsimple")])
1218
1219 (define_insn "*altivec_vsr<VI_char>"
1220   [(set (match_operand:VI 0 "register_operand" "=v")
1221         (lshiftrt:VI (match_operand:VI 1 "register_operand" "v")
1222                      (match_operand:VI 2 "register_operand" "v")))]
1223   "TARGET_ALTIVEC"
1224   "vsr<VI_char> %0,%1,%2"
1225   [(set_attr "type" "vecsimple")])
1226
1227 (define_insn "*altivec_vsra<VI_char>"
1228   [(set (match_operand:VI 0 "register_operand" "=v")
1229         (ashiftrt:VI (match_operand:VI 1 "register_operand" "v")
1230                      (match_operand:VI 2 "register_operand" "v")))]
1231   "TARGET_ALTIVEC"
1232   "vsra<VI_char> %0,%1,%2"
1233   [(set_attr "type" "vecsimple")])
1234
1235 (define_insn "altivec_vsr"
1236   [(set (match_operand:V4SI 0 "register_operand" "=v")
1237         (unspec:V4SI [(match_operand:V4SI 1 "register_operand" "v")
1238                       (match_operand:V4SI 2 "register_operand" "v")]
1239                      UNSPEC_VSR))]
1240   "TARGET_ALTIVEC"
1241   "vsr %0,%1,%2"
1242   [(set_attr "type" "vecperm")])
1243
1244 (define_insn "altivec_vsro"
1245   [(set (match_operand:V4SI 0 "register_operand" "=v")
1246         (unspec:V4SI [(match_operand:V4SI 1 "register_operand" "v")
1247                       (match_operand:V4SI 2 "register_operand" "v")]
1248                      UNSPEC_VSRO))]
1249   "TARGET_ALTIVEC"
1250   "vsro %0,%1,%2"
1251   [(set_attr "type" "vecperm")])
1252
1253 (define_insn "altivec_vsum4ubs"
1254   [(set (match_operand:V4SI 0 "register_operand" "=v")
1255         (unspec:V4SI [(match_operand:V16QI 1 "register_operand" "v")
1256                       (match_operand:V4SI 2 "register_operand" "v")]
1257                      UNSPEC_VSUM4UBS))
1258    (set (reg:SI 110) (unspec:SI [(const_int 0)] UNSPEC_SET_VSCR))]
1259   "TARGET_ALTIVEC"
1260   "vsum4ubs %0,%1,%2"
1261   [(set_attr "type" "veccomplex")])
1262
1263 (define_insn "altivec_vsum4s<VI_char>s"
1264   [(set (match_operand:V4SI 0 "register_operand" "=v")
1265         (unspec:V4SI [(match_operand:VIshort 1 "register_operand" "v")
1266                       (match_operand:V4SI 2 "register_operand" "v")]
1267                      UNSPEC_VSUM4S))
1268    (set (reg:SI 110) (unspec:SI [(const_int 0)] UNSPEC_SET_VSCR))]
1269   "TARGET_ALTIVEC"
1270   "vsum4s<VI_char>s %0,%1,%2"
1271   [(set_attr "type" "veccomplex")])
1272
1273 (define_insn "altivec_vsum2sws"
1274   [(set (match_operand:V4SI 0 "register_operand" "=v")
1275         (unspec:V4SI [(match_operand:V4SI 1 "register_operand" "v")
1276                       (match_operand:V4SI 2 "register_operand" "v")]
1277                      UNSPEC_VSUM2SWS))
1278    (set (reg:SI 110) (unspec:SI [(const_int 0)] UNSPEC_SET_VSCR))]
1279   "TARGET_ALTIVEC"
1280   "vsum2sws %0,%1,%2"
1281   [(set_attr "type" "veccomplex")])
1282
1283 (define_insn "altivec_vsumsws"
1284   [(set (match_operand:V4SI 0 "register_operand" "=v")
1285         (unspec:V4SI [(match_operand:V4SI 1 "register_operand" "v")
1286                       (match_operand:V4SI 2 "register_operand" "v")]
1287                      UNSPEC_VSUMSWS))
1288    (set (reg:SI 110) (unspec:SI [(const_int 0)] UNSPEC_SET_VSCR))]
1289   "TARGET_ALTIVEC"
1290   "vsumsws %0,%1,%2"
1291   [(set_attr "type" "veccomplex")])
1292
1293 (define_insn "altivec_vspltb"
1294   [(set (match_operand:V16QI 0 "register_operand" "=v")
1295         (vec_duplicate:V16QI
1296          (vec_select:QI (match_operand:V16QI 1 "register_operand" "v")
1297                         (parallel
1298                          [(match_operand:QI 2 "u5bit_cint_operand" "")]))))]
1299   "TARGET_ALTIVEC"
1300   "vspltb %0,%1,%2"
1301   [(set_attr "type" "vecperm")])
1302
1303 (define_insn "altivec_vsplth"
1304   [(set (match_operand:V8HI 0 "register_operand" "=v")
1305         (vec_duplicate:V8HI
1306          (vec_select:HI (match_operand:V8HI 1 "register_operand" "v")
1307                         (parallel
1308                          [(match_operand:QI 2 "u5bit_cint_operand" "")]))))]
1309   "TARGET_ALTIVEC"
1310   "vsplth %0,%1,%2"
1311   [(set_attr "type" "vecperm")])
1312
1313 (define_insn "altivec_vspltw"
1314   [(set (match_operand:V4SI 0 "register_operand" "=v")
1315         (vec_duplicate:V4SI
1316          (vec_select:SI (match_operand:V4SI 1 "register_operand" "v")
1317                         (parallel
1318                          [(match_operand:QI 2 "u5bit_cint_operand" "i")]))))]
1319   "TARGET_ALTIVEC"
1320   "vspltw %0,%1,%2"
1321   [(set_attr "type" "vecperm")])
1322
1323 (define_insn "altivec_vspltsf"
1324   [(set (match_operand:V4SF 0 "register_operand" "=v")
1325         (vec_duplicate:V4SF
1326          (vec_select:SF (match_operand:V4SF 1 "register_operand" "v")
1327                         (parallel
1328                          [(match_operand:QI 2 "u5bit_cint_operand" "i")]))))]
1329   "VECTOR_UNIT_ALTIVEC_P (V4SFmode)"
1330   "vspltw %0,%1,%2"
1331   [(set_attr "type" "vecperm")])
1332
1333 (define_insn "altivec_vspltis<VI_char>"
1334   [(set (match_operand:VI 0 "register_operand" "=v")
1335         (vec_duplicate:VI
1336          (match_operand:QI 1 "s5bit_cint_operand" "i")))]
1337   "TARGET_ALTIVEC"
1338   "vspltis<VI_char> %0,%1"
1339   [(set_attr "type" "vecperm")])
1340
1341 (define_insn "*altivec_vrfiz"
1342   [(set (match_operand:V4SF 0 "register_operand" "=v")
1343         (fix:V4SF (match_operand:V4SF 1 "register_operand" "v")))]
1344   "VECTOR_UNIT_ALTIVEC_P (V4SFmode)"
1345   "vrfiz %0,%1"
1346   [(set_attr "type" "vecfloat")])
1347
1348 (define_insn "altivec_vperm_<mode>"
1349   [(set (match_operand:VM 0 "register_operand" "=v")
1350         (unspec:VM [(match_operand:VM 1 "register_operand" "v")
1351                     (match_operand:VM 2 "register_operand" "v")
1352                     (match_operand:V16QI 3 "register_operand" "v")]
1353                    UNSPEC_VPERM))]
1354   "TARGET_ALTIVEC"
1355   "vperm %0,%1,%2,%3"
1356   [(set_attr "type" "vecperm")])
1357
1358 (define_insn "altivec_vperm_<mode>_uns"
1359   [(set (match_operand:VM 0 "register_operand" "=v")
1360         (unspec:VM [(match_operand:VM 1 "register_operand" "v")
1361                     (match_operand:VM 2 "register_operand" "v")
1362                     (match_operand:V16QI 3 "register_operand" "v")]
1363                    UNSPEC_VPERM_UNS))]
1364   "TARGET_ALTIVEC"
1365   "vperm %0,%1,%2,%3"
1366   [(set_attr "type" "vecperm")])
1367
1368 (define_insn "altivec_vrfip"            ; ceil
1369   [(set (match_operand:V4SF 0 "register_operand" "=v")
1370         (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "v")]
1371                      UNSPEC_FRIP))]
1372   "TARGET_ALTIVEC"
1373   "vrfip %0,%1"
1374   [(set_attr "type" "vecfloat")])
1375
1376 (define_insn "altivec_vrfin"
1377   [(set (match_operand:V4SF 0 "register_operand" "=v")
1378         (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "v")]
1379                      UNSPEC_VRFIN))]
1380   "TARGET_ALTIVEC"
1381   "vrfin %0,%1"
1382   [(set_attr "type" "vecfloat")])
1383
1384 (define_insn "*altivec_vrfim"           ; floor
1385   [(set (match_operand:V4SF 0 "register_operand" "=v")
1386         (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "v")]
1387                      UNSPEC_FRIM))]
1388   "TARGET_ALTIVEC"
1389   "vrfim %0,%1"
1390   [(set_attr "type" "vecfloat")])
1391
1392 (define_insn "altivec_vcfux"
1393   [(set (match_operand:V4SF 0 "register_operand" "=v")
1394         (unspec:V4SF [(match_operand:V4SI 1 "register_operand" "v")
1395                       (match_operand:QI 2 "immediate_operand" "i")]
1396                      UNSPEC_VCFUX))]
1397   "TARGET_ALTIVEC"
1398   "vcfux %0,%1,%2"
1399   [(set_attr "type" "vecfloat")])
1400
1401 (define_insn "altivec_vcfsx"
1402   [(set (match_operand:V4SF 0 "register_operand" "=v")
1403         (unspec:V4SF [(match_operand:V4SI 1 "register_operand" "v")
1404                       (match_operand:QI 2 "immediate_operand" "i")]
1405                      UNSPEC_VCFSX))]
1406   "TARGET_ALTIVEC"
1407   "vcfsx %0,%1,%2"
1408   [(set_attr "type" "vecfloat")])
1409
1410 (define_insn "altivec_vctuxs"
1411   [(set (match_operand:V4SI 0 "register_operand" "=v")
1412         (unspec:V4SI [(match_operand:V4SF 1 "register_operand" "v")
1413                       (match_operand:QI 2 "immediate_operand" "i")]
1414                      UNSPEC_VCTUXS))
1415    (set (reg:SI 110) (unspec:SI [(const_int 0)] UNSPEC_SET_VSCR))]
1416   "TARGET_ALTIVEC"
1417   "vctuxs %0,%1,%2"
1418   [(set_attr "type" "vecfloat")])
1419
1420 (define_insn "altivec_vctsxs"
1421   [(set (match_operand:V4SI 0 "register_operand" "=v")
1422         (unspec:V4SI [(match_operand:V4SF 1 "register_operand" "v")
1423                       (match_operand:QI 2 "immediate_operand" "i")]
1424                      UNSPEC_VCTSXS))
1425    (set (reg:SI 110) (unspec:SI [(const_int 0)] UNSPEC_SET_VSCR))]
1426   "TARGET_ALTIVEC"
1427   "vctsxs %0,%1,%2"
1428   [(set_attr "type" "vecfloat")])
1429
1430 (define_insn "altivec_vlogefp"
1431   [(set (match_operand:V4SF 0 "register_operand" "=v")
1432         (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "v")]
1433                      UNSPEC_VLOGEFP))]
1434   "TARGET_ALTIVEC"
1435   "vlogefp %0,%1"
1436   [(set_attr "type" "vecfloat")])
1437
1438 (define_insn "altivec_vexptefp"
1439   [(set (match_operand:V4SF 0 "register_operand" "=v")
1440         (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "v")]
1441                      UNSPEC_VEXPTEFP))]
1442   "TARGET_ALTIVEC"
1443   "vexptefp %0,%1"
1444   [(set_attr "type" "vecfloat")])
1445
1446 (define_insn "*altivec_vrsqrtefp"
1447   [(set (match_operand:V4SF 0 "register_operand" "=v")
1448         (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "v")]
1449                      UNSPEC_RSQRT))]
1450   "VECTOR_UNIT_ALTIVEC_P (V4SFmode)"
1451   "vrsqrtefp %0,%1"
1452   [(set_attr "type" "vecfloat")])
1453
1454 (define_insn "altivec_vrefp"
1455   [(set (match_operand:V4SF 0 "register_operand" "=v")
1456         (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "v")]
1457                      UNSPEC_FRES))]
1458   "VECTOR_UNIT_ALTIVEC_P (V4SFmode)"
1459   "vrefp %0,%1"
1460   [(set_attr "type" "vecfloat")])
1461
1462 (define_expand "altivec_copysign_v4sf3"
1463   [(use (match_operand:V4SF 0 "register_operand" ""))
1464    (use (match_operand:V4SF 1 "register_operand" ""))
1465    (use (match_operand:V4SF 2 "register_operand" ""))]
1466   "VECTOR_UNIT_ALTIVEC_P (V4SFmode)"
1467   "
1468 {
1469   rtx mask = gen_reg_rtx (V4SImode);
1470   rtvec v = rtvec_alloc (4);
1471   unsigned HOST_WIDE_INT mask_val = ((unsigned HOST_WIDE_INT)1) << 31;
1472
1473   RTVEC_ELT (v, 0) = GEN_INT (mask_val);
1474   RTVEC_ELT (v, 1) = GEN_INT (mask_val);
1475   RTVEC_ELT (v, 2) = GEN_INT (mask_val);
1476   RTVEC_ELT (v, 3) = GEN_INT (mask_val);
1477
1478   emit_insn (gen_vec_initv4si (mask, gen_rtx_PARALLEL (V4SImode, v)));
1479   emit_insn (gen_vector_select_v4sf (operands[0], operands[1], operands[2],
1480                                      gen_lowpart (V4SFmode, mask)));
1481   DONE;
1482 }")
1483
1484 (define_insn "altivec_vsldoi_<mode>"
1485   [(set (match_operand:VM 0 "register_operand" "=v")
1486         (unspec:VM [(match_operand:VM 1 "register_operand" "v")
1487                     (match_operand:VM 2 "register_operand" "v")
1488                     (match_operand:QI 3 "immediate_operand" "i")]
1489                   UNSPEC_VLSDOI))]
1490   "TARGET_ALTIVEC"
1491   "vsldoi %0,%1,%2,%3"
1492   [(set_attr "type" "vecperm")])
1493
1494 (define_insn "altivec_vupkhsb"
1495   [(set (match_operand:V8HI 0 "register_operand" "=v")
1496         (unspec:V8HI [(match_operand:V16QI 1 "register_operand" "v")]
1497                      UNSPEC_VUPKHSB))]
1498   "TARGET_ALTIVEC"
1499   "vupkhsb %0,%1"
1500   [(set_attr "type" "vecperm")])
1501
1502 (define_insn "altivec_vupkhpx"
1503   [(set (match_operand:V4SI 0 "register_operand" "=v")
1504         (unspec:V4SI [(match_operand:V8HI 1 "register_operand" "v")]
1505                      UNSPEC_VUPKHPX))]
1506   "TARGET_ALTIVEC"
1507   "vupkhpx %0,%1"
1508   [(set_attr "type" "vecperm")])
1509
1510 (define_insn "altivec_vupkhsh"
1511   [(set (match_operand:V4SI 0 "register_operand" "=v")
1512         (unspec:V4SI [(match_operand:V8HI 1 "register_operand" "v")]
1513                      UNSPEC_VUPKHSH))]
1514   "TARGET_ALTIVEC"
1515   "vupkhsh %0,%1"
1516   [(set_attr "type" "vecperm")])
1517
1518 (define_insn "altivec_vupklsb"
1519   [(set (match_operand:V8HI 0 "register_operand" "=v")
1520         (unspec:V8HI [(match_operand:V16QI 1 "register_operand" "v")]
1521                      UNSPEC_VUPKLSB))]
1522   "TARGET_ALTIVEC"
1523   "vupklsb %0,%1"
1524   [(set_attr "type" "vecperm")])
1525
1526 (define_insn "altivec_vupklpx"
1527   [(set (match_operand:V4SI 0 "register_operand" "=v")
1528         (unspec:V4SI [(match_operand:V8HI 1 "register_operand" "v")]
1529                      UNSPEC_VUPKLPX))]
1530   "TARGET_ALTIVEC"
1531   "vupklpx %0,%1"
1532   [(set_attr "type" "vecperm")])
1533
1534 (define_insn "altivec_vupklsh"
1535   [(set (match_operand:V4SI 0 "register_operand" "=v")
1536         (unspec:V4SI [(match_operand:V8HI 1 "register_operand" "v")]
1537                      UNSPEC_VUPKLSH))]
1538   "TARGET_ALTIVEC"
1539   "vupklsh %0,%1"
1540   [(set_attr "type" "vecperm")])
1541
1542 ;; Compare vectors producing a vector result and a predicate, setting CR6 to
1543 ;; indicate a combined status
1544 (define_insn "*altivec_vcmpequ<VI_char>_p"
1545   [(set (reg:CC 74)
1546         (unspec:CC [(eq:CC (match_operand:VI 1 "register_operand" "v")
1547                            (match_operand:VI 2 "register_operand" "v"))]
1548                    UNSPEC_PREDICATE))
1549    (set (match_operand:VI 0 "register_operand" "=v")
1550         (eq:VI (match_dup 1)
1551                (match_dup 2)))]
1552   "VECTOR_UNIT_ALTIVEC_P (<MODE>mode)"
1553   "vcmpequ<VI_char>. %0,%1,%2"
1554   [(set_attr "type" "veccmp")])
1555
1556 (define_insn "*altivec_vcmpgts<VI_char>_p"
1557   [(set (reg:CC 74)
1558         (unspec:CC [(gt:CC (match_operand:VI 1 "register_operand" "v")
1559                            (match_operand:VI 2 "register_operand" "v"))]
1560                    UNSPEC_PREDICATE))
1561    (set (match_operand:VI 0 "register_operand" "=v")
1562         (gt:VI (match_dup 1)
1563                (match_dup 2)))]
1564   "VECTOR_UNIT_ALTIVEC_P (<MODE>mode)"
1565   "vcmpgts<VI_char>. %0,%1,%2"
1566   [(set_attr "type" "veccmp")])
1567
1568 (define_insn "*altivec_vcmpgtu<VI_char>_p"
1569   [(set (reg:CC 74)
1570         (unspec:CC [(gtu:CC (match_operand:VI 1 "register_operand" "v")
1571                             (match_operand:VI 2 "register_operand" "v"))]
1572                    UNSPEC_PREDICATE))
1573    (set (match_operand:VI 0 "register_operand" "=v")
1574         (gtu:VI (match_dup 1)
1575                 (match_dup 2)))]
1576   "VECTOR_UNIT_ALTIVEC_P (<MODE>mode)"
1577   "vcmpgtu<VI_char>. %0,%1,%2"
1578   [(set_attr "type" "veccmp")])
1579
1580 (define_insn "*altivec_vcmpeqfp_p"
1581   [(set (reg:CC 74)
1582         (unspec:CC [(eq:CC (match_operand:V4SF 1 "register_operand" "v")
1583                            (match_operand:V4SF 2 "register_operand" "v"))]
1584                    UNSPEC_PREDICATE))
1585    (set (match_operand:V4SF 0 "register_operand" "=v")
1586         (eq:V4SF (match_dup 1)
1587                  (match_dup 2)))]
1588   "VECTOR_UNIT_ALTIVEC_P (V4SFmode)"
1589   "vcmpeqfp. %0,%1,%2"
1590   [(set_attr "type" "veccmp")])
1591
1592 (define_insn "*altivec_vcmpgtfp_p"
1593   [(set (reg:CC 74)
1594         (unspec:CC [(gt:CC (match_operand:V4SF 1 "register_operand" "v")
1595                            (match_operand:V4SF 2 "register_operand" "v"))]
1596                    UNSPEC_PREDICATE))
1597    (set (match_operand:V4SF 0 "register_operand" "=v")
1598         (gt:V4SF (match_dup 1)
1599                  (match_dup 2)))]
1600   "VECTOR_UNIT_ALTIVEC_P (V4SFmode)"
1601   "vcmpgtfp. %0,%1,%2"
1602   [(set_attr "type" "veccmp")])
1603
1604 (define_insn "*altivec_vcmpgefp_p"
1605   [(set (reg:CC 74)
1606         (unspec:CC [(ge:CC (match_operand:V4SF 1 "register_operand" "v")
1607                            (match_operand:V4SF 2 "register_operand" "v"))]
1608                    UNSPEC_PREDICATE))
1609    (set (match_operand:V4SF 0 "register_operand" "=v")
1610         (ge:V4SF (match_dup 1)
1611                  (match_dup 2)))]
1612   "VECTOR_UNIT_ALTIVEC_P (V4SFmode)"
1613   "vcmpgefp. %0,%1,%2"
1614   [(set_attr "type" "veccmp")])
1615
1616 (define_insn "altivec_vcmpbfp_p"
1617   [(set (reg:CC 74)
1618         (unspec:CC [(match_operand:V4SF 1 "register_operand" "v")
1619                     (match_operand:V4SF 2 "register_operand" "v")]
1620                    UNSPEC_VCMPBFP))
1621    (set (match_operand:V4SF 0 "register_operand" "=v")
1622         (unspec:V4SF [(match_dup 1)
1623                       (match_dup 2)] 
1624                       UNSPEC_VCMPBFP))]
1625   "VECTOR_UNIT_ALTIVEC_OR_VSX_P (V4SFmode)"
1626   "vcmpbfp. %0,%1,%2"
1627   [(set_attr "type" "veccmp")])
1628
1629 (define_insn "altivec_mtvscr"
1630   [(set (reg:SI 110)
1631         (unspec_volatile:SI
1632          [(match_operand:V4SI 0 "register_operand" "v")] UNSPECV_MTVSCR))]
1633   "TARGET_ALTIVEC"
1634   "mtvscr %0"
1635   [(set_attr "type" "vecsimple")])
1636
1637 (define_insn "altivec_mfvscr"
1638   [(set (match_operand:V8HI 0 "register_operand" "=v")
1639         (unspec_volatile:V8HI [(reg:SI 110)] UNSPECV_MFVSCR))]
1640   "TARGET_ALTIVEC"
1641   "mfvscr %0"
1642   [(set_attr "type" "vecsimple")])
1643
1644 (define_insn "altivec_dssall"
1645   [(unspec_volatile [(const_int 0)] UNSPECV_DSSALL)]
1646   "TARGET_ALTIVEC"
1647   "dssall"
1648   [(set_attr "type" "vecsimple")])
1649
1650 (define_insn "altivec_dss"
1651   [(unspec_volatile [(match_operand:QI 0 "immediate_operand" "i")]
1652                     UNSPECV_DSS)]
1653   "TARGET_ALTIVEC"
1654   "dss %0"
1655   [(set_attr "type" "vecsimple")])
1656
1657 (define_insn "altivec_dst"
1658   [(unspec [(match_operand 0 "register_operand" "b")
1659             (match_operand:SI 1 "register_operand" "r")
1660             (match_operand:QI 2 "immediate_operand" "i")] UNSPEC_DST)]
1661   "TARGET_ALTIVEC && GET_MODE (operands[0]) == Pmode"
1662   "dst %0,%1,%2"
1663   [(set_attr "type" "vecsimple")])
1664
1665 (define_insn "altivec_dstt"
1666   [(unspec [(match_operand 0 "register_operand" "b")
1667             (match_operand:SI 1 "register_operand" "r")
1668             (match_operand:QI 2 "immediate_operand" "i")] UNSPEC_DSTT)]
1669   "TARGET_ALTIVEC && GET_MODE (operands[0]) == Pmode"
1670   "dstt %0,%1,%2"
1671   [(set_attr "type" "vecsimple")])
1672
1673 (define_insn "altivec_dstst"
1674   [(unspec [(match_operand 0 "register_operand" "b")
1675             (match_operand:SI 1 "register_operand" "r")
1676             (match_operand:QI 2 "immediate_operand" "i")] UNSPEC_DSTST)]
1677   "TARGET_ALTIVEC && GET_MODE (operands[0]) == Pmode"
1678   "dstst %0,%1,%2"
1679   [(set_attr "type" "vecsimple")])
1680
1681 (define_insn "altivec_dststt"
1682   [(unspec [(match_operand 0 "register_operand" "b")
1683             (match_operand:SI 1 "register_operand" "r")
1684             (match_operand:QI 2 "immediate_operand" "i")] UNSPEC_DSTSTT)]
1685   "TARGET_ALTIVEC && GET_MODE (operands[0]) == Pmode"
1686   "dststt %0,%1,%2"
1687   [(set_attr "type" "vecsimple")])
1688
1689 (define_insn "altivec_lvsl"
1690   [(set (match_operand:V16QI 0 "register_operand" "=v")
1691         (unspec:V16QI [(match_operand 1 "memory_operand" "Z")] UNSPEC_LVSL))]
1692   "TARGET_ALTIVEC"
1693   "lvsl %0,%y1"
1694   [(set_attr "type" "vecload")])
1695
1696 (define_insn "altivec_lvsr"
1697   [(set (match_operand:V16QI 0 "register_operand" "=v")
1698         (unspec:V16QI [(match_operand 1 "memory_operand" "Z")] UNSPEC_LVSR))]
1699   "TARGET_ALTIVEC"
1700   "lvsr %0,%y1"
1701   [(set_attr "type" "vecload")])
1702
1703 (define_expand "build_vector_mask_for_load"
1704   [(set (match_operand:V16QI 0 "register_operand" "")
1705         (unspec:V16QI [(match_operand 1 "memory_operand" "")] UNSPEC_LVSR))]
1706   "TARGET_ALTIVEC"
1707   "
1708
1709   rtx addr;
1710   rtx temp;
1711
1712   gcc_assert (GET_CODE (operands[1]) == MEM);
1713
1714   addr = XEXP (operands[1], 0);
1715   temp = gen_reg_rtx (GET_MODE (addr));
1716   emit_insn (gen_rtx_SET (VOIDmode, temp, 
1717                           gen_rtx_NEG (GET_MODE (addr), addr)));
1718   emit_insn (gen_altivec_lvsr (operands[0], 
1719                                replace_equiv_address (operands[1], temp)));
1720   DONE;
1721 }")
1722
1723 ;; Parallel some of the LVE* and STV*'s with unspecs because some have
1724 ;; identical rtl but different instructions-- and gcc gets confused.
1725
1726 (define_insn "altivec_lve<VI_char>x"
1727   [(parallel
1728     [(set (match_operand:VI 0 "register_operand" "=v")
1729           (match_operand:VI 1 "memory_operand" "Z"))
1730      (unspec [(const_int 0)] UNSPEC_LVE)])]
1731   "TARGET_ALTIVEC"
1732   "lve<VI_char>x %0,%y1"
1733   [(set_attr "type" "vecload")])
1734
1735 (define_insn "*altivec_lvesfx"
1736   [(parallel
1737     [(set (match_operand:V4SF 0 "register_operand" "=v")
1738           (match_operand:V4SF 1 "memory_operand" "Z"))
1739      (unspec [(const_int 0)] UNSPEC_LVE)])]
1740   "TARGET_ALTIVEC"
1741   "lvewx %0,%y1"
1742   [(set_attr "type" "vecload")])
1743
1744 (define_insn "altivec_lvxl"
1745   [(parallel
1746     [(set (match_operand:V4SI 0 "register_operand" "=v")
1747           (match_operand:V4SI 1 "memory_operand" "Z"))
1748      (unspec [(const_int 0)] UNSPEC_SET_VSCR)])]
1749   "TARGET_ALTIVEC"
1750   "lvxl %0,%y1"
1751   [(set_attr "type" "vecload")])
1752
1753 (define_insn "altivec_lvx"
1754   [(set (match_operand:V4SI 0 "register_operand" "=v")
1755         (match_operand:V4SI 1 "memory_operand" "Z"))]
1756   "TARGET_ALTIVEC"
1757   "lvx %0,%y1"
1758   [(set_attr "type" "vecload")])
1759
1760 (define_insn "altivec_stvx"
1761   [(parallel
1762     [(set (match_operand:V4SI 0 "memory_operand" "=Z")
1763           (match_operand:V4SI 1 "register_operand" "v"))
1764      (unspec [(const_int 0)] UNSPEC_STVX)])]
1765   "TARGET_ALTIVEC"
1766   "stvx %1,%y0"
1767   [(set_attr "type" "vecstore")])
1768
1769 (define_insn "altivec_stvxl"
1770   [(parallel
1771     [(set (match_operand:V4SI 0 "memory_operand" "=Z")
1772           (match_operand:V4SI 1 "register_operand" "v"))
1773      (unspec [(const_int 0)] UNSPEC_STVXL)])]
1774   "TARGET_ALTIVEC"
1775   "stvxl %1,%y0"
1776   [(set_attr "type" "vecstore")])
1777
1778 (define_insn "altivec_stve<VI_char>x"
1779   [(set (match_operand:<VI_scalar> 0 "memory_operand" "=Z")
1780         (unspec:<VI_scalar> [(match_operand:VI 1 "register_operand" "v")] UNSPEC_STVE))]
1781   "TARGET_ALTIVEC"
1782   "stve<VI_char>x %1,%y0"
1783   [(set_attr "type" "vecstore")])
1784
1785 (define_insn "*altivec_stvesfx"
1786   [(set (match_operand:SF 0 "memory_operand" "=Z")
1787         (unspec:SF [(match_operand:V4SF 1 "register_operand" "v")] UNSPEC_STVE))]
1788   "TARGET_ALTIVEC"
1789   "stvewx %1,%y0"
1790   [(set_attr "type" "vecstore")])
1791
1792 ;; Generate
1793 ;;    vspltis? SCRATCH0,0
1794 ;;    vsubu?m SCRATCH2,SCRATCH1,%1
1795 ;;    vmaxs? %0,%1,SCRATCH2"
1796 (define_expand "abs<mode>2"
1797   [(set (match_dup 2) (vec_duplicate:VI (const_int 0)))
1798    (set (match_dup 3)
1799         (minus:VI (match_dup 2)
1800                   (match_operand:VI 1 "register_operand" "v")))
1801    (set (match_operand:VI 0 "register_operand" "=v")
1802         (smax:VI (match_dup 1) (match_dup 3)))]
1803   "TARGET_ALTIVEC"
1804 {
1805   operands[2] = gen_reg_rtx (GET_MODE (operands[0]));
1806   operands[3] = gen_reg_rtx (GET_MODE (operands[0]));
1807 })
1808
1809 ;; Generate
1810 ;;    vspltisw SCRATCH1,-1
1811 ;;    vslw SCRATCH2,SCRATCH1,SCRATCH1
1812 ;;    vandc %0,%1,SCRATCH2
1813 (define_expand "altivec_absv4sf2"
1814   [(set (match_dup 2)
1815         (vec_duplicate:V4SI (const_int -1)))
1816    (set (match_dup 3)
1817         (ashift:V4SI (match_dup 2) (match_dup 2)))
1818    (set (match_operand:V4SF 0 "register_operand" "=v")
1819         (and:V4SF (not:V4SF (subreg:V4SF (match_dup 3) 0))
1820                   (match_operand:V4SF 1 "register_operand" "v")))]
1821   "TARGET_ALTIVEC"
1822 {
1823   operands[2] = gen_reg_rtx (V4SImode);
1824   operands[3] = gen_reg_rtx (V4SImode);
1825 })
1826
1827 ;; Generate
1828 ;;    vspltis? SCRATCH0,0
1829 ;;    vsubs?s SCRATCH2,SCRATCH1,%1
1830 ;;    vmaxs? %0,%1,SCRATCH2"
1831 (define_expand "altivec_abss_<mode>"
1832   [(set (match_dup 2) (vec_duplicate:VI (const_int 0)))
1833    (parallel [(set (match_dup 3)
1834                    (unspec:VI [(match_dup 2)
1835                                (match_operand:VI 1 "register_operand" "v")]
1836                               UNSPEC_VSUBS))
1837               (set (reg:SI 110) (unspec:SI [(const_int 0)] UNSPEC_SET_VSCR))])
1838    (set (match_operand:VI 0 "register_operand" "=v")
1839         (smax:VI (match_dup 1) (match_dup 3)))]
1840   "TARGET_ALTIVEC"
1841 {
1842   operands[2] = gen_reg_rtx (GET_MODE (operands[0]));
1843   operands[3] = gen_reg_rtx (GET_MODE (operands[0]));
1844 })
1845
1846 (define_insn "altivec_vsumsws_nomode"
1847   [(set (match_operand 0 "register_operand" "=v")
1848         (unspec:V4SI [(match_operand:V4SI 1 "register_operand" "v")
1849                       (match_operand:V4SI 2 "register_operand" "v")]
1850                      UNSPEC_VSUMSWS))
1851    (set (reg:SI 110) (unspec:SI [(const_int 0)] UNSPEC_SET_VSCR))]
1852   "TARGET_ALTIVEC"
1853   "vsumsws %0,%1,%2"
1854   [(set_attr "type" "veccomplex")])
1855
1856 (define_expand "reduc_splus_<mode>"
1857   [(set (match_operand:VIshort 0 "register_operand" "=v")
1858         (unspec:VIshort [(match_operand:VIshort 1 "register_operand" "v")]
1859                         UNSPEC_REDUC_PLUS))]
1860   "TARGET_ALTIVEC"
1861   "
1862
1863   rtx vzero = gen_reg_rtx (V4SImode);
1864   rtx vtmp1 = gen_reg_rtx (V4SImode);
1865
1866   emit_insn (gen_altivec_vspltisw (vzero, const0_rtx));
1867   emit_insn (gen_altivec_vsum4s<VI_char>s (vtmp1, operands[1], vzero));
1868   emit_insn (gen_altivec_vsumsws_nomode (operands[0], vtmp1, vzero));
1869   DONE;
1870 }")
1871
1872 (define_expand "reduc_uplus_v16qi"
1873   [(set (match_operand:V16QI 0 "register_operand" "=v")
1874         (unspec:V16QI [(match_operand:V16QI 1 "register_operand" "v")]
1875                       UNSPEC_REDUC_PLUS))]
1876   "TARGET_ALTIVEC"
1877   "
1878 {
1879   rtx vzero = gen_reg_rtx (V4SImode);
1880   rtx vtmp1 = gen_reg_rtx (V4SImode);
1881
1882   emit_insn (gen_altivec_vspltisw (vzero, const0_rtx));
1883   emit_insn (gen_altivec_vsum4ubs (vtmp1, operands[1], vzero));
1884   emit_insn (gen_altivec_vsumsws_nomode (operands[0], vtmp1, vzero));
1885   DONE;
1886 }")
1887
1888 (define_expand "neg<mode>2"
1889   [(use (match_operand:VI 0 "register_operand" ""))
1890    (use (match_operand:VI 1 "register_operand" ""))]
1891   "TARGET_ALTIVEC"
1892   "
1893 {
1894   rtx vzero;
1895
1896   vzero = gen_reg_rtx (GET_MODE (operands[0]));
1897   emit_insn (gen_altivec_vspltis<VI_char> (vzero, const0_rtx));
1898   emit_insn (gen_sub<mode>3 (operands[0], vzero, operands[1])); 
1899   
1900   DONE;
1901 }")
1902
1903 (define_expand "udot_prod<mode>"
1904   [(set (match_operand:V4SI 0 "register_operand" "=v")
1905         (plus:V4SI (match_operand:V4SI 3 "register_operand" "v")
1906                    (unspec:V4SI [(match_operand:VIshort 1 "register_operand" "v")  
1907                                  (match_operand:VIshort 2 "register_operand" "v")] 
1908                                 UNSPEC_VMSUMU)))]
1909   "TARGET_ALTIVEC"
1910   "
1911 {  
1912   emit_insn (gen_altivec_vmsumu<VI_char>m (operands[0], operands[1], operands[2], operands[3]));
1913   DONE;
1914 }")
1915    
1916 (define_expand "sdot_prodv8hi"
1917   [(set (match_operand:V4SI 0 "register_operand" "=v")
1918         (plus:V4SI (match_operand:V4SI 3 "register_operand" "v")
1919                    (unspec:V4SI [(match_operand:V8HI 1 "register_operand" "v")
1920                                  (match_operand:V8HI 2 "register_operand" "v")]
1921                                 UNSPEC_VMSUMSHM)))]
1922   "TARGET_ALTIVEC"
1923   "
1924 {
1925   emit_insn (gen_altivec_vmsumshm (operands[0], operands[1], operands[2], operands[3]));
1926   DONE;
1927 }")
1928
1929 (define_expand "widen_usum<mode>3"
1930   [(set (match_operand:V4SI 0 "register_operand" "=v")
1931         (plus:V4SI (match_operand:V4SI 2 "register_operand" "v")
1932                    (unspec:V4SI [(match_operand:VIshort 1 "register_operand" "v")]
1933                                 UNSPEC_VMSUMU)))]
1934   "TARGET_ALTIVEC"
1935   "
1936 {
1937   rtx vones = gen_reg_rtx (GET_MODE (operands[1]));
1938
1939   emit_insn (gen_altivec_vspltis<VI_char> (vones, const1_rtx));
1940   emit_insn (gen_altivec_vmsumu<VI_char>m (operands[0], operands[1], vones, operands[2]));
1941   DONE;
1942 }")
1943
1944 (define_expand "widen_ssumv16qi3"
1945   [(set (match_operand:V4SI 0 "register_operand" "=v")
1946         (plus:V4SI (match_operand:V4SI 2 "register_operand" "v")
1947                    (unspec:V4SI [(match_operand:V16QI 1 "register_operand" "v")]
1948                                 UNSPEC_VMSUMM)))]
1949   "TARGET_ALTIVEC"
1950   "
1951 {
1952   rtx vones = gen_reg_rtx (V16QImode);
1953
1954   emit_insn (gen_altivec_vspltisb (vones, const1_rtx));
1955   emit_insn (gen_altivec_vmsummbm (operands[0], operands[1], vones, operands[2]));
1956   DONE;
1957 }")
1958
1959 (define_expand "widen_ssumv8hi3"
1960   [(set (match_operand:V4SI 0 "register_operand" "=v")
1961         (plus:V4SI (match_operand:V4SI 2 "register_operand" "v")
1962                    (unspec:V4SI [(match_operand:V8HI 1 "register_operand" "v")]
1963                                 UNSPEC_VMSUMSHM)))]
1964   "TARGET_ALTIVEC"
1965   "
1966 {
1967   rtx vones = gen_reg_rtx (V8HImode);
1968
1969   emit_insn (gen_altivec_vspltish (vones, const1_rtx));
1970   emit_insn (gen_altivec_vmsumshm (operands[0], operands[1], vones, operands[2]));
1971   DONE;
1972 }")
1973
1974 (define_expand "vec_unpacks_hi_v16qi"
1975   [(set (match_operand:V8HI 0 "register_operand" "=v")
1976         (unspec:V8HI [(match_operand:V16QI 1 "register_operand" "v")]
1977                      UNSPEC_VUPKHSB))]
1978   "TARGET_ALTIVEC"
1979   "
1980 {
1981   emit_insn (gen_altivec_vupkhsb (operands[0], operands[1]));
1982   DONE;
1983 }")
1984
1985 (define_expand "vec_unpacks_hi_v8hi"
1986   [(set (match_operand:V4SI 0 "register_operand" "=v")
1987         (unspec:V4SI [(match_operand:V8HI 1 "register_operand" "v")]
1988                      UNSPEC_VUPKHSH))]
1989   "TARGET_ALTIVEC"
1990   "
1991 {
1992   emit_insn (gen_altivec_vupkhsh (operands[0], operands[1]));
1993   DONE;
1994 }")
1995
1996 (define_expand "vec_unpacks_lo_v16qi"
1997   [(set (match_operand:V8HI 0 "register_operand" "=v")
1998         (unspec:V8HI [(match_operand:V16QI 1 "register_operand" "v")]
1999                      UNSPEC_VUPKLSB))]
2000   "TARGET_ALTIVEC"
2001   "
2002 {
2003   emit_insn (gen_altivec_vupklsb (operands[0], operands[1]));
2004   DONE;
2005 }")
2006
2007 (define_expand "vec_unpacks_lo_v8hi"
2008   [(set (match_operand:V4SI 0 "register_operand" "=v")
2009         (unspec:V4SI [(match_operand:V8HI 1 "register_operand" "v")]
2010                      UNSPEC_VUPKLSH))]
2011   "TARGET_ALTIVEC"
2012   "
2013 {
2014   emit_insn (gen_altivec_vupklsh (operands[0], operands[1]));
2015   DONE;
2016 }")
2017
2018 (define_insn "vperm_v8hiv4si"
2019   [(set (match_operand:V4SI 0 "register_operand" "=v")
2020         (unspec:V4SI [(match_operand:V8HI 1 "register_operand" "v")
2021                    (match_operand:V4SI 2 "register_operand" "v")
2022                    (match_operand:V16QI 3 "register_operand" "v")]
2023                   UNSPEC_VPERMSI))]
2024   "TARGET_ALTIVEC"
2025   "vperm %0,%1,%2,%3"
2026   [(set_attr "type" "vecperm")])
2027
2028 (define_insn "vperm_v16qiv8hi"
2029   [(set (match_operand:V8HI 0 "register_operand" "=v")
2030         (unspec:V8HI [(match_operand:V16QI 1 "register_operand" "v")
2031                    (match_operand:V8HI 2 "register_operand" "v")
2032                    (match_operand:V16QI 3 "register_operand" "v")]
2033                   UNSPEC_VPERMHI))]
2034   "TARGET_ALTIVEC"
2035   "vperm %0,%1,%2,%3"
2036   [(set_attr "type" "vecperm")])
2037
2038
2039 (define_expand "vec_unpacku_hi_v16qi"
2040   [(set (match_operand:V8HI 0 "register_operand" "=v")
2041         (unspec:V8HI [(match_operand:V16QI 1 "register_operand" "v")]
2042                      UNSPEC_VUPKHUB))]
2043   "TARGET_ALTIVEC"      
2044   "
2045 {  
2046   rtx vzero = gen_reg_rtx (V8HImode);
2047   rtx mask = gen_reg_rtx (V16QImode);
2048   rtvec v = rtvec_alloc (16);
2049    
2050   emit_insn (gen_altivec_vspltish (vzero, const0_rtx));
2051    
2052   RTVEC_ELT (v, 0) = gen_rtx_CONST_INT (QImode, 16);
2053   RTVEC_ELT (v, 1) = gen_rtx_CONST_INT (QImode, 0);
2054   RTVEC_ELT (v, 2) = gen_rtx_CONST_INT (QImode, 16);
2055   RTVEC_ELT (v, 3) = gen_rtx_CONST_INT (QImode, 1);
2056   RTVEC_ELT (v, 4) = gen_rtx_CONST_INT (QImode, 16);
2057   RTVEC_ELT (v, 5) = gen_rtx_CONST_INT (QImode, 2);
2058   RTVEC_ELT (v, 6) = gen_rtx_CONST_INT (QImode, 16);
2059   RTVEC_ELT (v, 7) = gen_rtx_CONST_INT (QImode, 3);
2060   RTVEC_ELT (v, 8) = gen_rtx_CONST_INT (QImode, 16);
2061   RTVEC_ELT (v, 9) = gen_rtx_CONST_INT (QImode, 4);
2062   RTVEC_ELT (v, 10) = gen_rtx_CONST_INT (QImode, 16);
2063   RTVEC_ELT (v, 11) = gen_rtx_CONST_INT (QImode, 5);
2064   RTVEC_ELT (v, 12) = gen_rtx_CONST_INT (QImode, 16);
2065   RTVEC_ELT (v, 13) = gen_rtx_CONST_INT (QImode, 6);
2066   RTVEC_ELT (v, 14) = gen_rtx_CONST_INT (QImode, 16);
2067   RTVEC_ELT (v, 15) = gen_rtx_CONST_INT (QImode, 7);
2068
2069   emit_insn (gen_vec_initv16qi (mask, gen_rtx_PARALLEL (V16QImode, v)));
2070   emit_insn (gen_vperm_v16qiv8hi (operands[0], operands[1], vzero, mask));
2071   DONE;
2072 }")
2073
2074 (define_expand "vec_unpacku_hi_v8hi"
2075   [(set (match_operand:V4SI 0 "register_operand" "=v")
2076         (unspec:V4SI [(match_operand:V8HI 1 "register_operand" "v")]
2077                      UNSPEC_VUPKHUH))]
2078   "TARGET_ALTIVEC"
2079   "
2080 {
2081   rtx vzero = gen_reg_rtx (V4SImode);
2082   rtx mask = gen_reg_rtx (V16QImode);
2083   rtvec v = rtvec_alloc (16);
2084
2085   emit_insn (gen_altivec_vspltisw (vzero, const0_rtx));
2086  
2087   RTVEC_ELT (v, 0) = gen_rtx_CONST_INT (QImode, 16);
2088   RTVEC_ELT (v, 1) = gen_rtx_CONST_INT (QImode, 17);
2089   RTVEC_ELT (v, 2) = gen_rtx_CONST_INT (QImode, 0);
2090   RTVEC_ELT (v, 3) = gen_rtx_CONST_INT (QImode, 1);
2091   RTVEC_ELT (v, 4) = gen_rtx_CONST_INT (QImode, 16);
2092   RTVEC_ELT (v, 5) = gen_rtx_CONST_INT (QImode, 17);
2093   RTVEC_ELT (v, 6) = gen_rtx_CONST_INT (QImode, 2);
2094   RTVEC_ELT (v, 7) = gen_rtx_CONST_INT (QImode, 3);
2095   RTVEC_ELT (v, 8) = gen_rtx_CONST_INT (QImode, 16);
2096   RTVEC_ELT (v, 9) = gen_rtx_CONST_INT (QImode, 17);
2097   RTVEC_ELT (v, 10) = gen_rtx_CONST_INT (QImode, 4);
2098   RTVEC_ELT (v, 11) = gen_rtx_CONST_INT (QImode, 5);
2099   RTVEC_ELT (v, 12) = gen_rtx_CONST_INT (QImode, 16);
2100   RTVEC_ELT (v, 13) = gen_rtx_CONST_INT (QImode, 17);
2101   RTVEC_ELT (v, 14) = gen_rtx_CONST_INT (QImode, 6);
2102   RTVEC_ELT (v, 15) = gen_rtx_CONST_INT (QImode, 7);
2103
2104   emit_insn (gen_vec_initv16qi (mask, gen_rtx_PARALLEL (V16QImode, v)));
2105   emit_insn (gen_vperm_v8hiv4si (operands[0], operands[1], vzero, mask));
2106   DONE;
2107 }")
2108
2109 (define_expand "vec_unpacku_lo_v16qi"
2110   [(set (match_operand:V8HI 0 "register_operand" "=v")
2111         (unspec:V8HI [(match_operand:V16QI 1 "register_operand" "v")]
2112                      UNSPEC_VUPKLUB))]
2113   "TARGET_ALTIVEC"
2114   "
2115 {
2116   rtx vzero = gen_reg_rtx (V8HImode);
2117   rtx mask = gen_reg_rtx (V16QImode);
2118   rtvec v = rtvec_alloc (16);
2119
2120   emit_insn (gen_altivec_vspltish (vzero, const0_rtx));
2121
2122   RTVEC_ELT (v, 0) = gen_rtx_CONST_INT (QImode, 16);
2123   RTVEC_ELT (v, 1) = gen_rtx_CONST_INT (QImode, 8);
2124   RTVEC_ELT (v, 2) = gen_rtx_CONST_INT (QImode, 16);
2125   RTVEC_ELT (v, 3) = gen_rtx_CONST_INT (QImode, 9);
2126   RTVEC_ELT (v, 4) = gen_rtx_CONST_INT (QImode, 16);
2127   RTVEC_ELT (v, 5) = gen_rtx_CONST_INT (QImode, 10);
2128   RTVEC_ELT (v, 6) = gen_rtx_CONST_INT (QImode, 16);
2129   RTVEC_ELT (v, 7) = gen_rtx_CONST_INT (QImode, 11);
2130   RTVEC_ELT (v, 8) = gen_rtx_CONST_INT (QImode, 16);
2131   RTVEC_ELT (v, 9) = gen_rtx_CONST_INT (QImode, 12);
2132   RTVEC_ELT (v, 10) = gen_rtx_CONST_INT (QImode, 16);
2133   RTVEC_ELT (v, 11) = gen_rtx_CONST_INT (QImode, 13);
2134   RTVEC_ELT (v, 12) = gen_rtx_CONST_INT (QImode, 16);
2135   RTVEC_ELT (v, 13) = gen_rtx_CONST_INT (QImode, 14);
2136   RTVEC_ELT (v, 14) = gen_rtx_CONST_INT (QImode, 16);
2137   RTVEC_ELT (v, 15) = gen_rtx_CONST_INT (QImode, 15);
2138
2139   emit_insn (gen_vec_initv16qi (mask, gen_rtx_PARALLEL (V16QImode, v)));
2140   emit_insn (gen_vperm_v16qiv8hi (operands[0], operands[1], vzero, mask));
2141   DONE;
2142 }")
2143
2144 (define_expand "vec_unpacku_lo_v8hi"
2145   [(set (match_operand:V4SI 0 "register_operand" "=v")
2146         (unspec:V4SI [(match_operand:V8HI 1 "register_operand" "v")]
2147                      UNSPEC_VUPKLUH))]
2148   "TARGET_ALTIVEC"
2149   "
2150 {
2151   rtx vzero = gen_reg_rtx (V4SImode);
2152   rtx mask = gen_reg_rtx (V16QImode);
2153   rtvec v = rtvec_alloc (16);
2154
2155   emit_insn (gen_altivec_vspltisw (vzero, const0_rtx));
2156  
2157   RTVEC_ELT (v, 0) = gen_rtx_CONST_INT (QImode, 16);
2158   RTVEC_ELT (v, 1) = gen_rtx_CONST_INT (QImode, 17);
2159   RTVEC_ELT (v, 2) = gen_rtx_CONST_INT (QImode, 8);
2160   RTVEC_ELT (v, 3) = gen_rtx_CONST_INT (QImode, 9);
2161   RTVEC_ELT (v, 4) = gen_rtx_CONST_INT (QImode, 16);
2162   RTVEC_ELT (v, 5) = gen_rtx_CONST_INT (QImode, 17);
2163   RTVEC_ELT (v, 6) = gen_rtx_CONST_INT (QImode, 10);
2164   RTVEC_ELT (v, 7) = gen_rtx_CONST_INT (QImode, 11);
2165   RTVEC_ELT (v, 8) = gen_rtx_CONST_INT (QImode, 16);
2166   RTVEC_ELT (v, 9) = gen_rtx_CONST_INT (QImode, 17);
2167   RTVEC_ELT (v, 10) = gen_rtx_CONST_INT (QImode, 12);
2168   RTVEC_ELT (v, 11) = gen_rtx_CONST_INT (QImode, 13);
2169   RTVEC_ELT (v, 12) = gen_rtx_CONST_INT (QImode, 16);
2170   RTVEC_ELT (v, 13) = gen_rtx_CONST_INT (QImode, 17);
2171   RTVEC_ELT (v, 14) = gen_rtx_CONST_INT (QImode, 14);
2172   RTVEC_ELT (v, 15) = gen_rtx_CONST_INT (QImode, 15);
2173
2174   emit_insn (gen_vec_initv16qi (mask, gen_rtx_PARALLEL (V16QImode, v)));
2175   emit_insn (gen_vperm_v8hiv4si (operands[0], operands[1], vzero, mask));
2176   DONE;
2177 }")
2178
2179 (define_expand "vec_widen_umult_hi_v16qi"
2180   [(set (match_operand:V8HI 0 "register_operand" "=v")
2181         (unspec:V8HI [(match_operand:V16QI 1 "register_operand" "v")
2182                       (match_operand:V16QI 2 "register_operand" "v")]
2183                      UNSPEC_VMULWHUB))]
2184   "TARGET_ALTIVEC"
2185   "
2186 {
2187   rtx ve = gen_reg_rtx (V8HImode);
2188   rtx vo = gen_reg_rtx (V8HImode);
2189   
2190   emit_insn (gen_altivec_vmuleub (ve, operands[1], operands[2]));
2191   emit_insn (gen_altivec_vmuloub (vo, operands[1], operands[2]));
2192   emit_insn (gen_altivec_vmrghh (operands[0], ve, vo));
2193   DONE;
2194 }")
2195
2196 (define_expand "vec_widen_umult_lo_v16qi"
2197   [(set (match_operand:V8HI 0 "register_operand" "=v")
2198         (unspec:V8HI [(match_operand:V16QI 1 "register_operand" "v")
2199                       (match_operand:V16QI 2 "register_operand" "v")]
2200                      UNSPEC_VMULWLUB))]
2201   "TARGET_ALTIVEC"
2202   "
2203 {
2204   rtx ve = gen_reg_rtx (V8HImode);
2205   rtx vo = gen_reg_rtx (V8HImode);
2206   
2207   emit_insn (gen_altivec_vmuleub (ve, operands[1], operands[2]));
2208   emit_insn (gen_altivec_vmuloub (vo, operands[1], operands[2]));
2209   emit_insn (gen_altivec_vmrglh (operands[0], ve, vo));
2210   DONE;
2211 }")
2212
2213 (define_expand "vec_widen_smult_hi_v16qi"
2214   [(set (match_operand:V8HI 0 "register_operand" "=v")
2215         (unspec:V8HI [(match_operand:V16QI 1 "register_operand" "v")
2216                       (match_operand:V16QI 2 "register_operand" "v")]
2217                      UNSPEC_VMULWHSB))]
2218   "TARGET_ALTIVEC"
2219   "
2220 {
2221   rtx ve = gen_reg_rtx (V8HImode);
2222   rtx vo = gen_reg_rtx (V8HImode);
2223   
2224   emit_insn (gen_altivec_vmulesb (ve, operands[1], operands[2]));
2225   emit_insn (gen_altivec_vmulosb (vo, operands[1], operands[2]));
2226   emit_insn (gen_altivec_vmrghh (operands[0], ve, vo));
2227   DONE;
2228 }")
2229
2230 (define_expand "vec_widen_smult_lo_v16qi"
2231   [(set (match_operand:V8HI 0 "register_operand" "=v")
2232         (unspec:V8HI [(match_operand:V16QI 1 "register_operand" "v")
2233                       (match_operand:V16QI 2 "register_operand" "v")]
2234                      UNSPEC_VMULWLSB))]
2235   "TARGET_ALTIVEC"
2236   "
2237 {
2238   rtx ve = gen_reg_rtx (V8HImode);
2239   rtx vo = gen_reg_rtx (V8HImode);
2240   
2241   emit_insn (gen_altivec_vmulesb (ve, operands[1], operands[2]));
2242   emit_insn (gen_altivec_vmulosb (vo, operands[1], operands[2]));
2243   emit_insn (gen_altivec_vmrglh (operands[0], ve, vo));
2244   DONE;
2245 }")
2246
2247 (define_expand "vec_widen_umult_hi_v8hi"
2248   [(set (match_operand:V4SI 0 "register_operand" "=v")
2249         (unspec:V4SI [(match_operand:V8HI 1 "register_operand" "v")
2250                       (match_operand:V8HI 2 "register_operand" "v")]
2251                      UNSPEC_VMULWHUH))]
2252   "TARGET_ALTIVEC"
2253   "
2254
2255   rtx ve = gen_reg_rtx (V4SImode);
2256   rtx vo = gen_reg_rtx (V4SImode);
2257   
2258   emit_insn (gen_altivec_vmuleuh (ve, operands[1], operands[2]));
2259   emit_insn (gen_altivec_vmulouh (vo, operands[1], operands[2]));
2260   emit_insn (gen_altivec_vmrghw (operands[0], ve, vo));
2261   DONE;
2262 }")
2263
2264 (define_expand "vec_widen_umult_lo_v8hi"
2265   [(set (match_operand:V4SI 0 "register_operand" "=v")
2266         (unspec:V4SI [(match_operand:V8HI 1 "register_operand" "v")
2267                       (match_operand:V8HI 2 "register_operand" "v")]
2268                      UNSPEC_VMULWLUH))]
2269   "TARGET_ALTIVEC"
2270   "
2271
2272   rtx ve = gen_reg_rtx (V4SImode);
2273   rtx vo = gen_reg_rtx (V4SImode);
2274   
2275   emit_insn (gen_altivec_vmuleuh (ve, operands[1], operands[2]));
2276   emit_insn (gen_altivec_vmulouh (vo, operands[1], operands[2]));
2277   emit_insn (gen_altivec_vmrglw (operands[0], ve, vo));
2278   DONE;
2279 }")
2280
2281 (define_expand "vec_widen_smult_hi_v8hi"
2282   [(set (match_operand:V4SI 0 "register_operand" "=v")
2283         (unspec:V4SI [(match_operand:V8HI 1 "register_operand" "v")
2284                       (match_operand:V8HI 2 "register_operand" "v")]
2285                      UNSPEC_VMULWHSH))]
2286   "TARGET_ALTIVEC"
2287   "
2288
2289   rtx ve = gen_reg_rtx (V4SImode);
2290   rtx vo = gen_reg_rtx (V4SImode);
2291   
2292   emit_insn (gen_altivec_vmulesh (ve, operands[1], operands[2]));
2293   emit_insn (gen_altivec_vmulosh (vo, operands[1], operands[2]));
2294   emit_insn (gen_altivec_vmrghw (operands[0], ve, vo));
2295   DONE;
2296 }")
2297
2298 (define_expand "vec_widen_smult_lo_v8hi"
2299   [(set (match_operand:V4SI 0 "register_operand" "=v")
2300         (unspec:V4SI [(match_operand:V8HI 1 "register_operand" "v")
2301                       (match_operand:V8HI 2 "register_operand" "v")]
2302                      UNSPEC_VMULWLSH))]
2303   "TARGET_ALTIVEC"
2304   "
2305
2306   rtx ve = gen_reg_rtx (V4SImode);
2307   rtx vo = gen_reg_rtx (V4SImode);
2308   
2309   emit_insn (gen_altivec_vmulesh (ve, operands[1], operands[2]));
2310   emit_insn (gen_altivec_vmulosh (vo, operands[1], operands[2]));
2311   emit_insn (gen_altivec_vmrglw (operands[0], ve, vo));
2312   DONE;
2313 }")
2314
2315 (define_expand "vec_pack_trunc_v8hi"
2316   [(set (match_operand:V16QI 0 "register_operand" "=v")
2317         (unspec:V16QI [(match_operand:V8HI 1 "register_operand" "v")
2318                        (match_operand:V8HI 2 "register_operand" "v")]
2319                       UNSPEC_VPKUHUM))]
2320   "TARGET_ALTIVEC"
2321   "
2322 {
2323   emit_insn (gen_altivec_vpkuhum (operands[0], operands[1], operands[2]));
2324   DONE;
2325 }")
2326                                                                                 
2327 (define_expand "vec_pack_trunc_v4si"
2328   [(set (match_operand:V8HI 0 "register_operand" "=v")
2329         (unspec:V8HI [(match_operand:V4SI 1 "register_operand" "v")
2330                       (match_operand:V4SI 2 "register_operand" "v")]
2331                      UNSPEC_VPKUWUM))]
2332   "TARGET_ALTIVEC"
2333   "
2334 {
2335   emit_insn (gen_altivec_vpkuwum (operands[0], operands[1], operands[2]));
2336   DONE;
2337 }")
2338
2339 (define_expand "altivec_negv4sf2"
2340   [(use (match_operand:V4SF 0 "register_operand" ""))
2341    (use (match_operand:V4SF 1 "register_operand" ""))]
2342   "TARGET_ALTIVEC"
2343   "
2344 {
2345   rtx neg0;
2346
2347   /* Generate [-0.0, -0.0, -0.0, -0.0].  */
2348   neg0 = gen_reg_rtx (V4SImode);
2349   emit_insn (gen_altivec_vspltisw (neg0, constm1_rtx));
2350   emit_insn (gen_vashlv4si3 (neg0, neg0, neg0));
2351
2352   /* XOR */
2353   emit_insn (gen_xorv4sf3 (operands[0],
2354                            gen_lowpart (V4SFmode, neg0), operands[1])); 
2355     
2356   DONE;
2357 }")
2358
2359 ;; Vector SIMD PEM v2.06c defines LVLX, LVLXL, LVRX, LVRXL,
2360 ;; STVLX, STVLXL, STVVRX, STVRXL are available only on Cell.
2361 (define_insn "altivec_lvlx"
2362   [(set (match_operand:V16QI 0 "register_operand" "=v")
2363         (unspec:V16QI [(match_operand 1 "memory_operand" "Z")] 
2364                       UNSPEC_LVLX))]
2365   "TARGET_ALTIVEC && rs6000_cpu == PROCESSOR_CELL"
2366   "lvlx %0,%y1"
2367   [(set_attr "type" "vecload")])
2368
2369 (define_insn "altivec_lvlxl"
2370   [(set (match_operand:V16QI 0 "register_operand" "=v")
2371         (unspec:V16QI [(match_operand 1 "memory_operand" "Z")] 
2372                       UNSPEC_LVLXL))]
2373   "TARGET_ALTIVEC && rs6000_cpu == PROCESSOR_CELL"
2374   "lvlxl %0,%y1"
2375   [(set_attr "type" "vecload")])
2376
2377 (define_insn "altivec_lvrx"
2378   [(set (match_operand:V16QI 0 "register_operand" "=v")
2379         (unspec:V16QI [(match_operand 1 "memory_operand" "Z")] 
2380                       UNSPEC_LVRX))]
2381   "TARGET_ALTIVEC && rs6000_cpu == PROCESSOR_CELL"
2382   "lvrx %0,%y1"
2383   [(set_attr "type" "vecload")])
2384
2385 (define_insn "altivec_lvrxl"
2386   [(set (match_operand:V16QI 0 "register_operand" "=v")
2387         (unspec:V16QI [(match_operand 1 "memory_operand" "Z")] 
2388                       UNSPEC_LVRXL))]
2389   "TARGET_ALTIVEC && rs6000_cpu == PROCESSOR_CELL"
2390   "lvrxl %0,%y1"
2391   [(set_attr "type" "vecload")])
2392
2393 (define_insn "altivec_stvlx"
2394   [(parallel
2395     [(set (match_operand:V4SI 0 "memory_operand" "=Z")
2396           (match_operand:V4SI 1 "register_operand" "v"))
2397      (unspec [(const_int 0)] UNSPEC_STVLX)])]
2398   "TARGET_ALTIVEC && rs6000_cpu == PROCESSOR_CELL"
2399   "stvlx %1,%y0"
2400   [(set_attr "type" "vecstore")])
2401
2402 (define_insn "altivec_stvlxl"
2403   [(parallel
2404     [(set (match_operand:V4SI 0 "memory_operand" "=Z")
2405           (match_operand:V4SI 1 "register_operand" "v"))
2406      (unspec [(const_int 0)] UNSPEC_STVLXL)])]
2407   "TARGET_ALTIVEC && rs6000_cpu == PROCESSOR_CELL"
2408   "stvlxl %1,%y0"
2409   [(set_attr "type" "vecstore")])
2410
2411 (define_insn "altivec_stvrx"
2412   [(parallel
2413     [(set (match_operand:V4SI 0 "memory_operand" "=Z")
2414           (match_operand:V4SI 1 "register_operand" "v"))
2415      (unspec [(const_int 0)] UNSPEC_STVRX)])]
2416   "TARGET_ALTIVEC && rs6000_cpu == PROCESSOR_CELL"
2417   "stvrx %1,%y0"
2418   [(set_attr "type" "vecstore")])
2419
2420 (define_insn "altivec_stvrxl"
2421   [(parallel
2422     [(set (match_operand:V4SI 0 "memory_operand" "=Z")
2423           (match_operand:V4SI 1 "register_operand" "v"))
2424      (unspec [(const_int 0)] UNSPEC_STVRXL)])]
2425   "TARGET_ALTIVEC && rs6000_cpu == PROCESSOR_CELL"
2426   "stvrxl %1,%y0"
2427   [(set_attr "type" "vecstore")])
2428
2429 (define_expand "vec_extract_evenv4si"
2430  [(set (match_operand:V4SI 0 "register_operand" "")
2431         (unspec:V8HI [(match_operand:V4SI 1 "register_operand" "")
2432                       (match_operand:V4SI 2 "register_operand" "")]
2433                       UNSPEC_EXTEVEN_V4SI))]
2434   "TARGET_ALTIVEC"
2435   "
2436 {
2437   rtx mask = gen_reg_rtx (V16QImode);
2438   rtvec v = rtvec_alloc (16);
2439
2440   RTVEC_ELT (v, 0) = gen_rtx_CONST_INT (QImode, 0);
2441   RTVEC_ELT (v, 1) = gen_rtx_CONST_INT (QImode, 1);
2442   RTVEC_ELT (v, 2) = gen_rtx_CONST_INT (QImode, 2);
2443   RTVEC_ELT (v, 3) = gen_rtx_CONST_INT (QImode, 3);
2444   RTVEC_ELT (v, 4) = gen_rtx_CONST_INT (QImode, 8);
2445   RTVEC_ELT (v, 5) = gen_rtx_CONST_INT (QImode, 9);
2446   RTVEC_ELT (v, 6) = gen_rtx_CONST_INT (QImode, 10);
2447   RTVEC_ELT (v, 7) = gen_rtx_CONST_INT (QImode, 11);
2448   RTVEC_ELT (v, 8) = gen_rtx_CONST_INT (QImode, 16);
2449   RTVEC_ELT (v, 9) = gen_rtx_CONST_INT (QImode, 17);
2450   RTVEC_ELT (v, 10) = gen_rtx_CONST_INT (QImode, 18);
2451   RTVEC_ELT (v, 11) = gen_rtx_CONST_INT (QImode, 19);
2452   RTVEC_ELT (v, 12) = gen_rtx_CONST_INT (QImode, 24);
2453   RTVEC_ELT (v, 13) = gen_rtx_CONST_INT (QImode, 25);
2454   RTVEC_ELT (v, 14) = gen_rtx_CONST_INT (QImode, 26);
2455   RTVEC_ELT (v, 15) = gen_rtx_CONST_INT (QImode, 27);
2456   emit_insn (gen_vec_initv16qi (mask, gen_rtx_PARALLEL (V16QImode, v)));
2457   emit_insn (gen_altivec_vperm_v4si (operands[0], operands[1], operands[2], mask));
2458   
2459   DONE;
2460 }")
2461
2462 (define_expand "vec_extract_evenv4sf"
2463  [(set (match_operand:V4SF 0 "register_operand" "")
2464         (unspec:V8HI [(match_operand:V4SF 1 "register_operand" "")
2465                       (match_operand:V4SF 2 "register_operand" "")]
2466                       UNSPEC_EXTEVEN_V4SF))]
2467   "TARGET_ALTIVEC"
2468   "
2469
2470   rtx mask = gen_reg_rtx (V16QImode);
2471   rtvec v = rtvec_alloc (16);
2472   
2473   RTVEC_ELT (v, 0) = gen_rtx_CONST_INT (QImode, 0);
2474   RTVEC_ELT (v, 1) = gen_rtx_CONST_INT (QImode, 1);
2475   RTVEC_ELT (v, 2) = gen_rtx_CONST_INT (QImode, 2);
2476   RTVEC_ELT (v, 3) = gen_rtx_CONST_INT (QImode, 3);
2477   RTVEC_ELT (v, 4) = gen_rtx_CONST_INT (QImode, 8);
2478   RTVEC_ELT (v, 5) = gen_rtx_CONST_INT (QImode, 9);
2479   RTVEC_ELT (v, 6) = gen_rtx_CONST_INT (QImode, 10);
2480   RTVEC_ELT (v, 7) = gen_rtx_CONST_INT (QImode, 11);
2481   RTVEC_ELT (v, 8) = gen_rtx_CONST_INT (QImode, 16);
2482   RTVEC_ELT (v, 9) = gen_rtx_CONST_INT (QImode, 17);
2483   RTVEC_ELT (v, 10) = gen_rtx_CONST_INT (QImode, 18);
2484   RTVEC_ELT (v, 11) = gen_rtx_CONST_INT (QImode, 19);
2485   RTVEC_ELT (v, 12) = gen_rtx_CONST_INT (QImode, 24);
2486   RTVEC_ELT (v, 13) = gen_rtx_CONST_INT (QImode, 25);
2487   RTVEC_ELT (v, 14) = gen_rtx_CONST_INT (QImode, 26);
2488   RTVEC_ELT (v, 15) = gen_rtx_CONST_INT (QImode, 27);
2489   emit_insn (gen_vec_initv16qi (mask, gen_rtx_PARALLEL (V16QImode, v)));
2490   emit_insn (gen_altivec_vperm_v4sf (operands[0], operands[1], operands[2], mask));
2491   
2492   DONE;
2493 }")
2494
2495 (define_expand "vec_extract_evenv8hi"
2496  [(set (match_operand:V4SI 0 "register_operand" "")
2497         (unspec:V8HI [(match_operand:V8HI 1 "register_operand" "")
2498                       (match_operand:V8HI 2 "register_operand" "")]
2499                       UNSPEC_EXTEVEN_V8HI))]
2500   "TARGET_ALTIVEC"
2501   "
2502
2503   rtx mask = gen_reg_rtx (V16QImode);
2504   rtvec v = rtvec_alloc (16);
2505   
2506   RTVEC_ELT (v, 0) = gen_rtx_CONST_INT (QImode, 0);
2507   RTVEC_ELT (v, 1) = gen_rtx_CONST_INT (QImode, 1);
2508   RTVEC_ELT (v, 2) = gen_rtx_CONST_INT (QImode, 4);
2509   RTVEC_ELT (v, 3) = gen_rtx_CONST_INT (QImode, 5);
2510   RTVEC_ELT (v, 4) = gen_rtx_CONST_INT (QImode, 8);
2511   RTVEC_ELT (v, 5) = gen_rtx_CONST_INT (QImode, 9);
2512   RTVEC_ELT (v, 6) = gen_rtx_CONST_INT (QImode, 12);
2513   RTVEC_ELT (v, 7) = gen_rtx_CONST_INT (QImode, 13);
2514   RTVEC_ELT (v, 8) = gen_rtx_CONST_INT (QImode, 16);
2515   RTVEC_ELT (v, 9) = gen_rtx_CONST_INT (QImode, 17);
2516   RTVEC_ELT (v, 10) = gen_rtx_CONST_INT (QImode, 20);
2517   RTVEC_ELT (v, 11) = gen_rtx_CONST_INT (QImode, 21);
2518   RTVEC_ELT (v, 12) = gen_rtx_CONST_INT (QImode, 24);
2519   RTVEC_ELT (v, 13) = gen_rtx_CONST_INT (QImode, 25);
2520   RTVEC_ELT (v, 14) = gen_rtx_CONST_INT (QImode, 28);
2521   RTVEC_ELT (v, 15) = gen_rtx_CONST_INT (QImode, 29);
2522   emit_insn (gen_vec_initv16qi (mask, gen_rtx_PARALLEL (V16QImode, v)));
2523   emit_insn (gen_altivec_vperm_v8hi (operands[0], operands[1], operands[2], mask));
2524   
2525   DONE;
2526 }")
2527
2528 (define_expand "vec_extract_evenv16qi"
2529  [(set (match_operand:V4SI 0 "register_operand" "")
2530         (unspec:V8HI [(match_operand:V16QI 1 "register_operand" "")
2531                       (match_operand:V16QI 2 "register_operand" "")]
2532                       UNSPEC_EXTEVEN_V16QI))]
2533   "TARGET_ALTIVEC"
2534   "
2535
2536   rtx mask = gen_reg_rtx (V16QImode);
2537   rtvec v = rtvec_alloc (16);
2538   
2539   RTVEC_ELT (v, 0) = gen_rtx_CONST_INT (QImode, 0);
2540   RTVEC_ELT (v, 1) = gen_rtx_CONST_INT (QImode, 2);
2541   RTVEC_ELT (v, 2) = gen_rtx_CONST_INT (QImode, 4);
2542   RTVEC_ELT (v, 3) = gen_rtx_CONST_INT (QImode, 6);
2543   RTVEC_ELT (v, 4) = gen_rtx_CONST_INT (QImode, 8);
2544   RTVEC_ELT (v, 5) = gen_rtx_CONST_INT (QImode, 10);
2545   RTVEC_ELT (v, 6) = gen_rtx_CONST_INT (QImode, 12);
2546   RTVEC_ELT (v, 7) = gen_rtx_CONST_INT (QImode, 14);
2547   RTVEC_ELT (v, 8) = gen_rtx_CONST_INT (QImode, 16);
2548   RTVEC_ELT (v, 9) = gen_rtx_CONST_INT (QImode, 18);
2549   RTVEC_ELT (v, 10) = gen_rtx_CONST_INT (QImode, 20);
2550   RTVEC_ELT (v, 11) = gen_rtx_CONST_INT (QImode, 22);
2551   RTVEC_ELT (v, 12) = gen_rtx_CONST_INT (QImode, 24);
2552   RTVEC_ELT (v, 13) = gen_rtx_CONST_INT (QImode, 26);
2553   RTVEC_ELT (v, 14) = gen_rtx_CONST_INT (QImode, 28);
2554   RTVEC_ELT (v, 15) = gen_rtx_CONST_INT (QImode, 30);
2555   emit_insn (gen_vec_initv16qi (mask, gen_rtx_PARALLEL (V16QImode, v)));
2556   emit_insn (gen_altivec_vperm_v16qi (operands[0], operands[1], operands[2], mask));
2557   
2558   DONE;
2559 }")
2560
2561 (define_expand "vec_extract_oddv4si"
2562  [(set (match_operand:V4SI 0 "register_operand" "")
2563         (unspec:V8HI [(match_operand:V4SI 1 "register_operand" "")
2564                       (match_operand:V4SI 2 "register_operand" "")]
2565                       UNSPEC_EXTODD_V4SI))]
2566   "TARGET_ALTIVEC"
2567   "
2568 {
2569   rtx mask = gen_reg_rtx (V16QImode);
2570   rtvec v = rtvec_alloc (16);
2571
2572   RTVEC_ELT (v, 0) = gen_rtx_CONST_INT (QImode, 4);
2573   RTVEC_ELT (v, 1) = gen_rtx_CONST_INT (QImode, 5);
2574   RTVEC_ELT (v, 2) = gen_rtx_CONST_INT (QImode, 6);
2575   RTVEC_ELT (v, 3) = gen_rtx_CONST_INT (QImode, 7);
2576   RTVEC_ELT (v, 4) = gen_rtx_CONST_INT (QImode, 12);
2577   RTVEC_ELT (v, 5) = gen_rtx_CONST_INT (QImode, 13);
2578   RTVEC_ELT (v, 6) = gen_rtx_CONST_INT (QImode, 14);
2579   RTVEC_ELT (v, 7) = gen_rtx_CONST_INT (QImode, 15);
2580   RTVEC_ELT (v, 8) = gen_rtx_CONST_INT (QImode, 20);
2581   RTVEC_ELT (v, 9) = gen_rtx_CONST_INT (QImode, 21);
2582   RTVEC_ELT (v, 10) = gen_rtx_CONST_INT (QImode, 22);
2583   RTVEC_ELT (v, 11) = gen_rtx_CONST_INT (QImode, 23);
2584   RTVEC_ELT (v, 12) = gen_rtx_CONST_INT (QImode, 28);
2585   RTVEC_ELT (v, 13) = gen_rtx_CONST_INT (QImode, 29);
2586   RTVEC_ELT (v, 14) = gen_rtx_CONST_INT (QImode, 30);
2587   RTVEC_ELT (v, 15) = gen_rtx_CONST_INT (QImode, 31);
2588   emit_insn (gen_vec_initv16qi (mask, gen_rtx_PARALLEL (V16QImode, v)));
2589   emit_insn (gen_altivec_vperm_v4si (operands[0], operands[1], operands[2], mask));
2590   
2591   DONE;
2592 }")
2593
2594 (define_expand "vec_extract_oddv4sf"
2595  [(set (match_operand:V4SF 0 "register_operand" "")
2596         (unspec:V8HI [(match_operand:V4SF 1 "register_operand" "")
2597                       (match_operand:V4SF 2 "register_operand" "")]
2598                       UNSPEC_EXTODD_V4SF))]
2599   "TARGET_ALTIVEC"
2600   "
2601 {
2602   rtx mask = gen_reg_rtx (V16QImode);
2603   rtvec v = rtvec_alloc (16);
2604
2605   RTVEC_ELT (v, 0) = gen_rtx_CONST_INT (QImode, 4);
2606   RTVEC_ELT (v, 1) = gen_rtx_CONST_INT (QImode, 5);
2607   RTVEC_ELT (v, 2) = gen_rtx_CONST_INT (QImode, 6);
2608   RTVEC_ELT (v, 3) = gen_rtx_CONST_INT (QImode, 7);
2609   RTVEC_ELT (v, 4) = gen_rtx_CONST_INT (QImode, 12);
2610   RTVEC_ELT (v, 5) = gen_rtx_CONST_INT (QImode, 13);
2611   RTVEC_ELT (v, 6) = gen_rtx_CONST_INT (QImode, 14);
2612   RTVEC_ELT (v, 7) = gen_rtx_CONST_INT (QImode, 15);
2613   RTVEC_ELT (v, 8) = gen_rtx_CONST_INT (QImode, 20);
2614   RTVEC_ELT (v, 9) = gen_rtx_CONST_INT (QImode, 21);
2615   RTVEC_ELT (v, 10) = gen_rtx_CONST_INT (QImode, 22);
2616   RTVEC_ELT (v, 11) = gen_rtx_CONST_INT (QImode, 23);
2617   RTVEC_ELT (v, 12) = gen_rtx_CONST_INT (QImode, 28);
2618   RTVEC_ELT (v, 13) = gen_rtx_CONST_INT (QImode, 29);
2619   RTVEC_ELT (v, 14) = gen_rtx_CONST_INT (QImode, 30);
2620   RTVEC_ELT (v, 15) = gen_rtx_CONST_INT (QImode, 31);
2621   emit_insn (gen_vec_initv16qi (mask, gen_rtx_PARALLEL (V16QImode, v)));
2622   emit_insn (gen_altivec_vperm_v4sf (operands[0], operands[1], operands[2], mask));
2623
2624   DONE;
2625 }")
2626
2627 (define_insn "vpkuhum_nomode"
2628   [(set (match_operand:V16QI 0 "register_operand" "=v")
2629         (unspec:V16QI [(match_operand 1 "register_operand" "v")
2630                        (match_operand 2 "register_operand" "v")]
2631                       UNSPEC_VPKUHUM))] 
2632   "TARGET_ALTIVEC"
2633   "vpkuhum %0,%1,%2"
2634   [(set_attr "type" "vecperm")])
2635
2636 (define_insn "vpkuwum_nomode"
2637   [(set (match_operand:V8HI 0 "register_operand" "=v")
2638         (unspec:V8HI [(match_operand 1 "register_operand" "v")
2639                       (match_operand 2 "register_operand" "v")]
2640                      UNSPEC_VPKUWUM))]
2641   "TARGET_ALTIVEC"
2642   "vpkuwum %0,%1,%2"
2643   [(set_attr "type" "vecperm")])
2644
2645 (define_expand "vec_extract_oddv8hi"
2646  [(set (match_operand:V8HI 0 "register_operand" "")
2647         (unspec:V8HI [(match_operand:V8HI 1 "register_operand" "")
2648                       (match_operand:V8HI 2 "register_operand" "")]
2649                       UNSPEC_EXTODD_V8HI))]
2650   "TARGET_ALTIVEC"
2651   "
2652 {
2653   emit_insn (gen_vpkuwum_nomode (operands[0], operands[1], operands[2]));
2654   DONE;
2655 }")
2656
2657 (define_expand "vec_extract_oddv16qi"
2658  [(set (match_operand:V16QI 0 "register_operand" "")
2659         (unspec:V16QI [(match_operand:V16QI 1 "register_operand" "")
2660                       (match_operand:V16QI 2 "register_operand" "")]
2661                       UNSPEC_EXTODD_V16QI))]
2662   "TARGET_ALTIVEC"
2663   "
2664 {
2665   emit_insn (gen_vpkuhum_nomode (operands[0], operands[1], operands[2]));
2666   DONE;
2667 }")
2668
2669 (define_expand "vec_interleave_high<mode>"
2670  [(set (match_operand:VI 0 "register_operand" "")
2671         (unspec:VI [(match_operand:VI 1 "register_operand" "")
2672                     (match_operand:VI 2 "register_operand" "")]
2673                      UNSPEC_INTERHI))]
2674   "TARGET_ALTIVEC"
2675   "
2676 {
2677   emit_insn (gen_altivec_vmrgh<VI_char> (operands[0], operands[1], operands[2]));
2678   DONE;
2679 }")
2680
2681 (define_expand "vec_interleave_low<mode>"
2682  [(set (match_operand:VI 0 "register_operand" "")
2683         (unspec:VI [(match_operand:VI 1 "register_operand" "")
2684                     (match_operand:VI 2 "register_operand" "")]
2685                      UNSPEC_INTERLO))]
2686   "TARGET_ALTIVEC"
2687   "
2688 {
2689   emit_insn (gen_altivec_vmrgl<VI_char> (operands[0], operands[1], operands[2]));
2690   DONE;
2691 }")
2692
2693 (define_expand "vec_unpacks_float_hi_v8hi"
2694  [(set (match_operand:V4SF 0 "register_operand" "")
2695         (unspec:V4SF [(match_operand:V8HI 1 "register_operand" "")]
2696                      UNSPEC_VUPKHS_V4SF))]
2697   "TARGET_ALTIVEC"
2698   "
2699 {
2700   rtx tmp = gen_reg_rtx (V4SImode);
2701
2702   emit_insn (gen_vec_unpacks_hi_v8hi (tmp, operands[1]));
2703   emit_insn (gen_altivec_vcfsx (operands[0], tmp, const0_rtx));
2704   DONE;
2705 }")
2706
2707 (define_expand "vec_unpacks_float_lo_v8hi"
2708  [(set (match_operand:V4SF 0 "register_operand" "")
2709         (unspec:V4SF [(match_operand:V8HI 1 "register_operand" "")]
2710                      UNSPEC_VUPKLS_V4SF))]
2711   "TARGET_ALTIVEC"
2712   "
2713 {
2714   rtx tmp = gen_reg_rtx (V4SImode);
2715
2716   emit_insn (gen_vec_unpacks_lo_v8hi (tmp, operands[1]));
2717   emit_insn (gen_altivec_vcfsx (operands[0], tmp, const0_rtx));
2718   DONE;
2719 }")
2720
2721 (define_expand "vec_unpacku_float_hi_v8hi"
2722  [(set (match_operand:V4SF 0 "register_operand" "")
2723         (unspec:V4SF [(match_operand:V8HI 1 "register_operand" "")]
2724                      UNSPEC_VUPKHU_V4SF))]
2725   "TARGET_ALTIVEC"
2726   "
2727 {
2728   rtx tmp = gen_reg_rtx (V4SImode);
2729
2730   emit_insn (gen_vec_unpacku_hi_v8hi (tmp, operands[1]));
2731   emit_insn (gen_altivec_vcfux (operands[0], tmp, const0_rtx));
2732   DONE;
2733 }")
2734
2735 (define_expand "vec_unpacku_float_lo_v8hi"
2736  [(set (match_operand:V4SF 0 "register_operand" "")
2737         (unspec:V4SF [(match_operand:V8HI 1 "register_operand" "")]
2738                      UNSPEC_VUPKLU_V4SF))]
2739   "TARGET_ALTIVEC"
2740   "
2741 {
2742   rtx tmp = gen_reg_rtx (V4SImode);
2743
2744   emit_insn (gen_vec_unpacku_lo_v8hi (tmp, operands[1]));
2745   emit_insn (gen_altivec_vcfux (operands[0], tmp, const0_rtx));
2746   DONE;
2747 }")