OSDN Git Service

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