Add a VEC_SERIES rtl code
[official-gcc.git] / gcc / config / rs6000 / altivec.md
blobd0fcd1c3d8a9cb4533301dad61268829559fbedf
1 ;; AltiVec patterns.
2 ;; Copyright (C) 2002-2017 Free Software Foundation, Inc.
3 ;; Contributed by Aldy Hernandez (aldy@quesejoda.com)
5 ;; This file is part of GCC.
7 ;; GCC is free software; you can redistribute it and/or modify it
8 ;; under the terms of the GNU General Public License as published
9 ;; by the Free Software Foundation; either version 3, or (at your
10 ;; option) any later version.
12 ;; GCC is distributed in the hope that it will be useful, but WITHOUT
13 ;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
14 ;; or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
15 ;; License for more details.
17 ;; You should have received a copy of the GNU General Public License
18 ;; along with GCC; see the file COPYING3.  If not see
19 ;; <http://www.gnu.org/licenses/>.
21 (define_c_enum "unspec"
22   [UNSPEC_VCMPBFP
23    UNSPEC_VMSUMU
24    UNSPEC_VMSUMM
25    UNSPEC_VMSUMSHM
26    UNSPEC_VMSUMUHS
27    UNSPEC_VMSUMSHS
28    UNSPEC_VMHADDSHS
29    UNSPEC_VMHRADDSHS
30    UNSPEC_VADDCUW
31    UNSPEC_VADDU
32    UNSPEC_VADDS
33    UNSPEC_VAVGU
34    UNSPEC_VAVGS
35    UNSPEC_VMULEUB
36    UNSPEC_VMULESB
37    UNSPEC_VMULEUH
38    UNSPEC_VMULESH
39    UNSPEC_VMULEUW
40    UNSPEC_VMULESW
41    UNSPEC_VMULOUB
42    UNSPEC_VMULOSB
43    UNSPEC_VMULOUH
44    UNSPEC_VMULOSH
45    UNSPEC_VMULOUW
46    UNSPEC_VMULOSW
47    UNSPEC_VPKPX
48    UNSPEC_VPACK_SIGN_SIGN_SAT
49    UNSPEC_VPACK_SIGN_UNS_SAT
50    UNSPEC_VPACK_UNS_UNS_SAT
51    UNSPEC_VPACK_UNS_UNS_MOD
52    UNSPEC_VPACK_UNS_UNS_MOD_DIRECT
53    UNSPEC_VREVEV
54    UNSPEC_VSLV4SI
55    UNSPEC_VSLO
56    UNSPEC_VSR
57    UNSPEC_VSRO
58    UNSPEC_VSUBCUW
59    UNSPEC_VSUBU
60    UNSPEC_VSUBS
61    UNSPEC_VSUM4UBS
62    UNSPEC_VSUM4S
63    UNSPEC_VSUM2SWS
64    UNSPEC_VSUMSWS
65    UNSPEC_VPERM
66    UNSPEC_VPERMR
67    UNSPEC_VPERM_UNS
68    UNSPEC_VRFIN
69    UNSPEC_VCFUX
70    UNSPEC_VCFSX
71    UNSPEC_VCTUXS
72    UNSPEC_VCTSXS
73    UNSPEC_VLOGEFP
74    UNSPEC_VEXPTEFP
75    UNSPEC_VSLDOI
76    UNSPEC_VUNPACK_HI_SIGN
77    UNSPEC_VUNPACK_LO_SIGN
78    UNSPEC_VUNPACK_HI_SIGN_DIRECT
79    UNSPEC_VUNPACK_LO_SIGN_DIRECT
80    UNSPEC_VUPKHPX
81    UNSPEC_VUPKLPX
82    UNSPEC_CONVERT_4F32_8I16
83    UNSPEC_DARN
84    UNSPEC_DARN_32
85    UNSPEC_DARN_RAW
86    UNSPEC_DST
87    UNSPEC_DSTT
88    UNSPEC_DSTST
89    UNSPEC_DSTSTT
90    UNSPEC_LVSL
91    UNSPEC_LVSR
92    UNSPEC_LVE
93    UNSPEC_STVX
94    UNSPEC_STVXL
95    UNSPEC_STVE
96    UNSPEC_SET_VSCR
97    UNSPEC_GET_VRSAVE
98    UNSPEC_LVX
99    UNSPEC_REDUC_PLUS
100    UNSPEC_VECSH
101    UNSPEC_EXTEVEN_V4SI
102    UNSPEC_EXTEVEN_V8HI
103    UNSPEC_EXTEVEN_V16QI
104    UNSPEC_EXTEVEN_V4SF
105    UNSPEC_EXTODD_V4SI
106    UNSPEC_EXTODD_V8HI
107    UNSPEC_EXTODD_V16QI
108    UNSPEC_EXTODD_V4SF
109    UNSPEC_INTERHI_V4SI
110    UNSPEC_INTERHI_V8HI
111    UNSPEC_INTERHI_V16QI
112    UNSPEC_INTERLO_V4SI
113    UNSPEC_INTERLO_V8HI
114    UNSPEC_INTERLO_V16QI
115    UNSPEC_LVLX
116    UNSPEC_LVLXL
117    UNSPEC_LVRX
118    UNSPEC_LVRXL
119    UNSPEC_STVLX
120    UNSPEC_STVLXL
121    UNSPEC_STVRX
122    UNSPEC_STVRXL
123    UNSPEC_VADU
124    UNSPEC_VSLV
125    UNSPEC_VSRV
126    UNSPEC_VMULWHUB
127    UNSPEC_VMULWLUB
128    UNSPEC_VMULWHSB
129    UNSPEC_VMULWLSB
130    UNSPEC_VMULWHUH
131    UNSPEC_VMULWLUH
132    UNSPEC_VMULWHSH
133    UNSPEC_VMULWLSH
134    UNSPEC_VUPKHUB
135    UNSPEC_VUPKHUH
136    UNSPEC_VUPKLUB
137    UNSPEC_VUPKLUH
138    UNSPEC_VPERMSI
139    UNSPEC_VPERMHI
140    UNSPEC_INTERHI
141    UNSPEC_INTERLO
142    UNSPEC_VUPKHS_V4SF
143    UNSPEC_VUPKLS_V4SF
144    UNSPEC_VUPKHU_V4SF
145    UNSPEC_VUPKLU_V4SF
146    UNSPEC_VGBBD
147    UNSPEC_VMRGH_DIRECT
148    UNSPEC_VMRGL_DIRECT
149    UNSPEC_VSPLT_DIRECT
150    UNSPEC_VMRGEW_DIRECT
151    UNSPEC_VMRGOW_DIRECT
152    UNSPEC_VSUMSWS_DIRECT
153    UNSPEC_VADDCUQ
154    UNSPEC_VADDEUQM
155    UNSPEC_VADDECUQ
156    UNSPEC_VSUBCUQ
157    UNSPEC_VSUBEUQM
158    UNSPEC_VSUBECUQ
159    UNSPEC_VBPERMQ
160    UNSPEC_VBPERMD
161    UNSPEC_BCDADD
162    UNSPEC_BCDSUB
163    UNSPEC_BCD_OVERFLOW
164    UNSPEC_CMPRB
165    UNSPEC_CMPRB2
166    UNSPEC_CMPEQB
167    UNSPEC_VRLMI
168    UNSPEC_VRLNM
171 (define_c_enum "unspecv"
172   [UNSPECV_SET_VRSAVE
173    UNSPECV_MTVSCR
174    UNSPECV_MFVSCR
175    UNSPECV_DSSALL
176    UNSPECV_DSS
177   ])
179 ;; Like VI, defined in vector.md, but add ISA 2.07 integer vector ops
180 (define_mode_iterator VI2 [V4SI V8HI V16QI V2DI])
181 ;; Short vec int modes
182 (define_mode_iterator VIshort [V8HI V16QI])
183 ;; Longer vec int modes for rotate/mask ops
184 (define_mode_iterator VIlong [V2DI V4SI])
185 ;; Vec float modes
186 (define_mode_iterator VF [V4SF])
187 ;; Vec modes, pity mode iterators are not composable
188 (define_mode_iterator V [V4SI V8HI V16QI V4SF])
189 ;; Vec modes for move/logical/permute ops, include vector types for move not
190 ;; otherwise handled by altivec (v2df, v2di, ti)
191 (define_mode_iterator VM [V4SI
192                           V8HI
193                           V16QI
194                           V4SF
195                           V2DF
196                           V2DI
197                           V1TI
198                           TI
199                           (KF "FLOAT128_VECTOR_P (KFmode)")
200                           (TF "FLOAT128_VECTOR_P (TFmode)")])
202 ;; Like VM, except don't do TImode
203 (define_mode_iterator VM2 [V4SI
204                            V8HI
205                            V16QI
206                            V4SF
207                            V2DF
208                            V2DI
209                            V1TI
210                            (KF "FLOAT128_VECTOR_P (KFmode)")
211                            (TF "FLOAT128_VECTOR_P (TFmode)")])
213 ;; Map the Vector convert single precision to double precision for integer
214 ;; versus floating point
215 (define_mode_attr VS_sxwsp [(V4SI "sxw") (V4SF "sp")])
217 ;; Specific iterator for parity which does not have a byte/half-word form, but
218 ;; does have a quad word form
219 (define_mode_iterator VParity [V4SI
220                                V2DI
221                                V1TI
222                                TI])
224 (define_mode_attr VI_char [(V2DI "d") (V4SI "w") (V8HI "h") (V16QI "b")])
225 (define_mode_attr VI_scalar [(V2DI "DI") (V4SI "SI") (V8HI "HI") (V16QI "QI")])
226 (define_mode_attr VI_unit [(V16QI "VECTOR_UNIT_ALTIVEC_P (V16QImode)")
227                            (V8HI "VECTOR_UNIT_ALTIVEC_P (V8HImode)")
228                            (V4SI "VECTOR_UNIT_ALTIVEC_P (V4SImode)")
229                            (V2DI "VECTOR_UNIT_P8_VECTOR_P (V2DImode)")
230                            (V1TI "VECTOR_UNIT_ALTIVEC_P (V1TImode)")])
232 ;; Vector pack/unpack
233 (define_mode_iterator VP [V2DI V4SI V8HI])
234 (define_mode_attr VP_small [(V2DI "V4SI") (V4SI "V8HI") (V8HI "V16QI")])
235 (define_mode_attr VP_small_lc [(V2DI "v4si") (V4SI "v8hi") (V8HI "v16qi")])
236 (define_mode_attr VU_char [(V2DI "w") (V4SI "h") (V8HI "b")])
238 ;; Vector negate
239 (define_mode_iterator VNEG [V4SI V2DI])
241 ;; Vector move instructions.
242 (define_insn "*altivec_mov<mode>"
243   [(set (match_operand:VM2 0 "nonimmediate_operand" "=Z,v,v,?Y,?*r,?*r,v,v,?*r")
244         (match_operand:VM2 1 "input_operand" "v,Z,v,*r,Y,*r,j,W,W"))]
245   "VECTOR_MEM_ALTIVEC_P (<MODE>mode)
246    && (register_operand (operands[0], <MODE>mode) 
247        || register_operand (operands[1], <MODE>mode))"
249   switch (which_alternative)
250     {
251     case 0: return "stvx %1,%y0";
252     case 1: return "lvx %0,%y1";
253     case 2: return "vor %0,%1,%1";
254     case 3: return "#";
255     case 4: return "#";
256     case 5: return "#";
257     case 6: return "vxor %0,%0,%0";
258     case 7: return output_vec_const_move (operands);
259     case 8: return "#";
260     default: gcc_unreachable ();
261     }
263   [(set_attr "type" "vecstore,vecload,veclogical,store,load,*,veclogical,*,*")
264    (set_attr "length" "4,4,4,20,20,20,4,8,32")])
266 ;; Unlike other altivec moves, allow the GPRs, since a normal use of TImode
267 ;; is for unions.  However for plain data movement, slightly favor the vector
268 ;; loads
269 (define_insn "*altivec_movti"
270   [(set (match_operand:TI 0 "nonimmediate_operand" "=Z,v,v,?Y,?r,?r,v,v")
271         (match_operand:TI 1 "input_operand" "v,Z,v,r,Y,r,j,W"))]
272   "VECTOR_MEM_ALTIVEC_P (TImode)
273    && (register_operand (operands[0], TImode) 
274        || register_operand (operands[1], TImode))"
276   switch (which_alternative)
277     {
278     case 0: return "stvx %1,%y0";
279     case 1: return "lvx %0,%y1";
280     case 2: return "vor %0,%1,%1";
281     case 3: return "#";
282     case 4: return "#";
283     case 5: return "#";
284     case 6: return "vxor %0,%0,%0";
285     case 7: return output_vec_const_move (operands);
286     default: gcc_unreachable ();
287     }
289   [(set_attr "type" "vecstore,vecload,veclogical,store,load,*,veclogical,*")])
291 ;; Load up a vector with the most significant bit set by loading up -1 and
292 ;; doing a shift left
293 (define_split
294   [(set (match_operand:VM 0 "altivec_register_operand" "")
295         (match_operand:VM 1 "easy_vector_constant_msb" ""))]
296   "VECTOR_UNIT_ALTIVEC_OR_VSX_P (<MODE>mode) && reload_completed"
297   [(const_int 0)]
299   rtx dest = operands[0];
300   machine_mode mode = GET_MODE (operands[0]);
301   rtvec v;
302   int i, num_elements;
304   if (mode == V4SFmode)
305     {
306       mode = V4SImode;
307       dest = gen_lowpart (V4SImode, dest);
308     }
310   num_elements = GET_MODE_NUNITS (mode);
311   v = rtvec_alloc (num_elements);
312   for (i = 0; i < num_elements; i++)
313     RTVEC_ELT (v, i) = constm1_rtx;
315   emit_insn (gen_vec_initv4sisi (dest, gen_rtx_PARALLEL (mode, v)));
316   emit_insn (gen_rtx_SET (dest, gen_rtx_ASHIFT (mode, dest, dest)));
317   DONE;
320 (define_split
321   [(set (match_operand:VM 0 "altivec_register_operand" "")
322         (match_operand:VM 1 "easy_vector_constant_add_self" ""))]
323   "VECTOR_UNIT_ALTIVEC_OR_VSX_P (<MODE>mode) && reload_completed"
324   [(set (match_dup 0) (match_dup 3))
325    (set (match_dup 0) (match_dup 4))]
327   rtx dup = gen_easy_altivec_constant (operands[1]);
328   rtx const_vec;
329   machine_mode op_mode = <MODE>mode;
331   /* Divide the operand of the resulting VEC_DUPLICATE, and use
332      simplify_rtx to make a CONST_VECTOR.  */
333   XEXP (dup, 0) = simplify_const_binary_operation (ASHIFTRT, QImode,
334                                                    XEXP (dup, 0), const1_rtx);
335   const_vec = simplify_rtx (dup);
337   if (op_mode == V4SFmode)
338     {
339       op_mode = V4SImode;
340       operands[0] = gen_lowpart (op_mode, operands[0]);
341     }
342   if (GET_MODE (const_vec) == op_mode)
343     operands[3] = const_vec;
344   else
345     operands[3] = gen_lowpart (op_mode, const_vec);
346   operands[4] = gen_rtx_PLUS (op_mode, operands[0], operands[0]);
349 (define_split
350   [(set (match_operand:VM 0 "altivec_register_operand" "")
351         (match_operand:VM 1 "easy_vector_constant_vsldoi" ""))]
352   "VECTOR_UNIT_ALTIVEC_OR_VSX_P (<MODE>mode) && can_create_pseudo_p ()"
353   [(set (match_dup 2) (match_dup 3))
354    (set (match_dup 4) (match_dup 5))
355    (set (match_dup 0)
356         (unspec:VM [(match_dup 2)
357                     (match_dup 4)
358                     (match_dup 6)]
359                    UNSPEC_VSLDOI))]
361   rtx op1 = operands[1];
362   int elt = (BYTES_BIG_ENDIAN) ? 0 : GET_MODE_NUNITS (<MODE>mode) - 1;
363   HOST_WIDE_INT val = const_vector_elt_as_int (op1, elt);
364   rtx rtx_val = GEN_INT (val);
365   int shift = vspltis_shifted (op1);
367   gcc_assert (shift != 0);
368   operands[2] = gen_reg_rtx (<MODE>mode);
369   operands[3] = gen_const_vec_duplicate (<MODE>mode, rtx_val);
370   operands[4] = gen_reg_rtx (<MODE>mode);
372   if (shift < 0)
373     {
374       operands[5] = CONSTM1_RTX (<MODE>mode);
375       operands[6] = GEN_INT (-shift);
376     }
377   else
378     {
379       operands[5] = CONST0_RTX (<MODE>mode);
380       operands[6] = GEN_INT (shift);
381     }
384 (define_insn "get_vrsave_internal"
385   [(set (match_operand:SI 0 "register_operand" "=r")
386         (unspec:SI [(reg:SI VRSAVE_REGNO)] UNSPEC_GET_VRSAVE))]
387   "TARGET_ALTIVEC"
389   if (TARGET_MACHO)
390      return "mfspr %0,256";
391   else
392      return "mfvrsave %0";
394   [(set_attr "type" "*")])
396 (define_insn "*set_vrsave_internal"
397   [(match_parallel 0 "vrsave_operation"
398      [(set (reg:SI VRSAVE_REGNO)
399            (unspec_volatile:SI [(match_operand:SI 1 "register_operand" "r")
400                                 (reg:SI VRSAVE_REGNO)] UNSPECV_SET_VRSAVE))])]
401   "TARGET_ALTIVEC"
403   if (TARGET_MACHO)
404     return "mtspr 256,%1";
405   else
406     return "mtvrsave %1";
408   [(set_attr "type" "*")])
410 (define_insn "*save_world"
411  [(match_parallel 0 "save_world_operation"
412                   [(clobber (reg:SI LR_REGNO))
413                    (use (match_operand:SI 1 "call_operand" "s"))])]
414  "TARGET_MACHO && (DEFAULT_ABI == ABI_DARWIN) && TARGET_32BIT"         
415  "bl %z1"
416   [(set_attr "type" "branch")
417    (set_attr "length" "4")])
419 (define_insn "*restore_world"
420  [(match_parallel 0 "restore_world_operation"
421                   [(return)
422                    (use (reg:SI LR_REGNO))
423                    (use (match_operand:SI 1 "call_operand" "s"))
424                    (clobber (match_operand:SI 2 "gpc_reg_operand" "=r"))])]
425  "TARGET_MACHO && (DEFAULT_ABI == ABI_DARWIN) && TARGET_32BIT"
426  "b %z1")
428 ;; The save_vregs and restore_vregs patterns don't use memory_operand
429 ;; because (plus (reg) (const_int)) is not a valid vector address.
430 ;; This way is more compact than describing exactly what happens in
431 ;; the out-of-line functions, ie. loading the constant into r11/r12
432 ;; then using indexed addressing, and requires less editing of rtl
433 ;; to describe the operation to dwarf2out_frame_debug_expr.
434 (define_insn "*save_vregs_<mode>_r11"
435   [(match_parallel 0 "any_parallel_operand"
436      [(clobber (reg:P LR_REGNO))
437       (use (match_operand:P 1 "symbol_ref_operand" "s"))
438       (clobber (reg:P 11))
439       (use (reg:P 0))
440       (set (mem:V4SI (plus:P (match_operand:P 2 "gpc_reg_operand" "b")
441                              (match_operand:P 3 "short_cint_operand" "I")))
442            (match_operand:V4SI 4 "altivec_register_operand" "v"))])]
443   "TARGET_ALTIVEC"
444   "bl %1"
445   [(set_attr "type" "branch")
446    (set_attr "length" "4")])
448 (define_insn "*save_vregs_<mode>_r12"
449   [(match_parallel 0 "any_parallel_operand"
450      [(clobber (reg:P LR_REGNO))
451       (use (match_operand:P 1 "symbol_ref_operand" "s"))
452       (clobber (reg:P 12))
453       (use (reg:P 0))
454       (set (mem:V4SI (plus:P (match_operand:P 2 "gpc_reg_operand" "b")
455                              (match_operand:P 3 "short_cint_operand" "I")))
456            (match_operand:V4SI 4 "altivec_register_operand" "v"))])]
457   "TARGET_ALTIVEC"
458   "bl %1"
459   [(set_attr "type" "branch")
460    (set_attr "length" "4")])
462 (define_insn "*restore_vregs_<mode>_r11"
463   [(match_parallel 0 "any_parallel_operand"
464      [(clobber (reg:P LR_REGNO))
465       (use (match_operand:P 1 "symbol_ref_operand" "s"))
466       (clobber (reg:P 11))
467       (use (reg:P 0))
468       (set (match_operand:V4SI 2 "altivec_register_operand" "=v")
469            (mem:V4SI (plus:P (match_operand:P 3 "gpc_reg_operand" "b")
470                              (match_operand:P 4 "short_cint_operand" "I"))))])]
471   "TARGET_ALTIVEC"
472   "bl %1"
473   [(set_attr "type" "branch")
474    (set_attr "length" "4")])
476 (define_insn "*restore_vregs_<mode>_r12"
477   [(match_parallel 0 "any_parallel_operand"
478      [(clobber (reg:P LR_REGNO))
479       (use (match_operand:P 1 "symbol_ref_operand" "s"))
480       (clobber (reg:P 12))
481       (use (reg:P 0))
482       (set (match_operand:V4SI 2 "altivec_register_operand" "=v")
483            (mem:V4SI (plus:P (match_operand:P 3 "gpc_reg_operand" "b")
484                              (match_operand:P 4 "short_cint_operand" "I"))))])]
485   "TARGET_ALTIVEC"
486   "bl %1"
487   [(set_attr "type" "branch")
488    (set_attr "length" "4")])
490 ;; Simple binary operations.
492 ;; add
493 (define_insn "add<mode>3"
494   [(set (match_operand:VI2 0 "register_operand" "=v")
495         (plus:VI2 (match_operand:VI2 1 "register_operand" "v")
496                   (match_operand:VI2 2 "register_operand" "v")))]
497   "<VI_unit>"
498   "vaddu<VI_char>m %0,%1,%2"
499   [(set_attr "type" "vecsimple")])
501 (define_insn "*altivec_addv4sf3"
502   [(set (match_operand:V4SF 0 "register_operand" "=v")
503         (plus:V4SF (match_operand:V4SF 1 "register_operand" "v")
504                    (match_operand:V4SF 2 "register_operand" "v")))]
505   "VECTOR_UNIT_ALTIVEC_P (V4SFmode)"
506   "vaddfp %0,%1,%2"
507   [(set_attr "type" "vecfloat")])
509 (define_insn "altivec_vaddcuw"
510   [(set (match_operand:V4SI 0 "register_operand" "=v")
511         (unspec:V4SI [(match_operand:V4SI 1 "register_operand" "v")
512                       (match_operand:V4SI 2 "register_operand" "v")]
513                      UNSPEC_VADDCUW))]
514   "VECTOR_UNIT_ALTIVEC_P (V4SImode)"
515   "vaddcuw %0,%1,%2"
516   [(set_attr "type" "vecsimple")])
518 (define_insn "altivec_vaddu<VI_char>s"
519   [(set (match_operand:VI 0 "register_operand" "=v")
520         (unspec:VI [(match_operand:VI 1 "register_operand" "v")
521                     (match_operand:VI 2 "register_operand" "v")]
522                    UNSPEC_VADDU))
523    (set (reg:SI VSCR_REGNO) (unspec:SI [(const_int 0)] UNSPEC_SET_VSCR))]
524   "<VI_unit>"
525   "vaddu<VI_char>s %0,%1,%2"
526   [(set_attr "type" "vecsimple")])
528 (define_insn "altivec_vadds<VI_char>s"
529   [(set (match_operand:VI 0 "register_operand" "=v")
530         (unspec:VI [(match_operand:VI 1 "register_operand" "v")
531                     (match_operand:VI 2 "register_operand" "v")]
532                    UNSPEC_VADDS))
533    (set (reg:SI VSCR_REGNO) (unspec:SI [(const_int 0)] UNSPEC_SET_VSCR))]
534   "VECTOR_UNIT_ALTIVEC_P (<MODE>mode)"
535   "vadds<VI_char>s %0,%1,%2"
536   [(set_attr "type" "vecsimple")])
538 ;; sub
539 (define_insn "sub<mode>3"
540   [(set (match_operand:VI2 0 "register_operand" "=v")
541         (minus:VI2 (match_operand:VI2 1 "register_operand" "v")
542                    (match_operand:VI2 2 "register_operand" "v")))]
543   "<VI_unit>"
544   "vsubu<VI_char>m %0,%1,%2"
545   [(set_attr "type" "vecsimple")])
547 (define_insn "*altivec_subv4sf3"
548   [(set (match_operand:V4SF 0 "register_operand" "=v")
549         (minus:V4SF (match_operand:V4SF 1 "register_operand" "v")
550                     (match_operand:V4SF 2 "register_operand" "v")))]
551   "VECTOR_UNIT_ALTIVEC_P (V4SFmode)"
552   "vsubfp %0,%1,%2"
553   [(set_attr "type" "vecfloat")])
555 (define_insn "altivec_vsubcuw"
556   [(set (match_operand:V4SI 0 "register_operand" "=v")
557         (unspec:V4SI [(match_operand:V4SI 1 "register_operand" "v")
558                       (match_operand:V4SI 2 "register_operand" "v")]
559                      UNSPEC_VSUBCUW))]
560   "VECTOR_UNIT_ALTIVEC_P (V4SImode)"
561   "vsubcuw %0,%1,%2"
562   [(set_attr "type" "vecsimple")])
564 (define_insn "altivec_vsubu<VI_char>s"
565   [(set (match_operand:VI 0 "register_operand" "=v")
566         (unspec:VI [(match_operand:VI 1 "register_operand" "v")
567                     (match_operand:VI 2 "register_operand" "v")]
568                    UNSPEC_VSUBU))
569    (set (reg:SI VSCR_REGNO) (unspec:SI [(const_int 0)] UNSPEC_SET_VSCR))]
570   "VECTOR_UNIT_ALTIVEC_P (<MODE>mode)"
571   "vsubu<VI_char>s %0,%1,%2"
572   [(set_attr "type" "vecsimple")])
574 (define_insn "altivec_vsubs<VI_char>s"
575   [(set (match_operand:VI 0 "register_operand" "=v")
576         (unspec:VI [(match_operand:VI 1 "register_operand" "v")
577                     (match_operand:VI 2 "register_operand" "v")]
578                    UNSPEC_VSUBS))
579    (set (reg:SI VSCR_REGNO) (unspec:SI [(const_int 0)] UNSPEC_SET_VSCR))]
580   "VECTOR_UNIT_ALTIVEC_P (<MODE>mode)"
581   "vsubs<VI_char>s %0,%1,%2"
582   [(set_attr "type" "vecsimple")])
585 (define_insn "altivec_vavgu<VI_char>"
586   [(set (match_operand:VI 0 "register_operand" "=v")
587         (unspec:VI [(match_operand:VI 1 "register_operand" "v")
588                     (match_operand:VI 2 "register_operand" "v")]
589                    UNSPEC_VAVGU))]
590   "TARGET_ALTIVEC"
591   "vavgu<VI_char> %0,%1,%2"
592   [(set_attr "type" "vecsimple")])
594 (define_insn "altivec_vavgs<VI_char>"
595   [(set (match_operand:VI 0 "register_operand" "=v")
596         (unspec:VI [(match_operand:VI 1 "register_operand" "v")
597                     (match_operand:VI 2 "register_operand" "v")]
598                    UNSPEC_VAVGS))]
599   "VECTOR_UNIT_ALTIVEC_P (<MODE>mode)"
600   "vavgs<VI_char> %0,%1,%2"
601   [(set_attr "type" "vecsimple")])
603 (define_insn "altivec_vcmpbfp"
604   [(set (match_operand:V4SI 0 "register_operand" "=v")
605         (unspec:V4SI [(match_operand:V4SF 1 "register_operand" "v")
606                       (match_operand:V4SF 2 "register_operand" "v")] 
607                       UNSPEC_VCMPBFP))]
608   "VECTOR_UNIT_ALTIVEC_P (V4SImode)"
609   "vcmpbfp %0,%1,%2"
610   [(set_attr "type" "veccmp")])
612 (define_insn "*altivec_eq<mode>"
613   [(set (match_operand:VI2 0 "altivec_register_operand" "=v")
614         (eq:VI2 (match_operand:VI2 1 "altivec_register_operand" "v")
615                 (match_operand:VI2 2 "altivec_register_operand" "v")))]
616   "<VI_unit>"
617   "vcmpequ<VI_char> %0,%1,%2"
618   [(set_attr "type" "veccmpfx")])
620 (define_insn "*altivec_gt<mode>"
621   [(set (match_operand:VI2 0 "altivec_register_operand" "=v")
622         (gt:VI2 (match_operand:VI2 1 "altivec_register_operand" "v")
623                 (match_operand:VI2 2 "altivec_register_operand" "v")))]
624   "<VI_unit>"
625   "vcmpgts<VI_char> %0,%1,%2"
626   [(set_attr "type" "veccmpfx")])
628 (define_insn "*altivec_gtu<mode>"
629   [(set (match_operand:VI2 0 "altivec_register_operand" "=v")
630         (gtu:VI2 (match_operand:VI2 1 "altivec_register_operand" "v")
631                  (match_operand:VI2 2 "altivec_register_operand" "v")))]
632   "<VI_unit>"
633   "vcmpgtu<VI_char> %0,%1,%2"
634   [(set_attr "type" "veccmpfx")])
636 (define_insn "*altivec_eqv4sf"
637   [(set (match_operand:V4SF 0 "altivec_register_operand" "=v")
638         (eq:V4SF (match_operand:V4SF 1 "altivec_register_operand" "v")
639                  (match_operand:V4SF 2 "altivec_register_operand" "v")))]
640   "VECTOR_UNIT_ALTIVEC_P (V4SFmode)"
641   "vcmpeqfp %0,%1,%2"
642   [(set_attr "type" "veccmp")])
644 (define_insn "*altivec_gtv4sf"
645   [(set (match_operand:V4SF 0 "altivec_register_operand" "=v")
646         (gt:V4SF (match_operand:V4SF 1 "altivec_register_operand" "v")
647                  (match_operand:V4SF 2 "altivec_register_operand" "v")))]
648   "VECTOR_UNIT_ALTIVEC_P (V4SFmode)"
649   "vcmpgtfp %0,%1,%2"
650   [(set_attr "type" "veccmp")])
652 (define_insn "*altivec_gev4sf"
653   [(set (match_operand:V4SF 0 "altivec_register_operand" "=v")
654         (ge:V4SF (match_operand:V4SF 1 "altivec_register_operand" "v")
655                  (match_operand:V4SF 2 "altivec_register_operand" "v")))]
656   "VECTOR_UNIT_ALTIVEC_P (V4SFmode)"
657   "vcmpgefp %0,%1,%2"
658   [(set_attr "type" "veccmp")])
660 (define_insn "*altivec_vsel<mode>"
661   [(set (match_operand:VM 0 "altivec_register_operand" "=v")
662         (if_then_else:VM
663          (ne:CC (match_operand:VM 1 "altivec_register_operand" "v")
664                 (match_operand:VM 4 "zero_constant" ""))
665          (match_operand:VM 2 "altivec_register_operand" "v")
666          (match_operand:VM 3 "altivec_register_operand" "v")))]
667   "VECTOR_MEM_ALTIVEC_P (<MODE>mode)"
668   "vsel %0,%3,%2,%1"
669   [(set_attr "type" "vecmove")])
671 (define_insn "*altivec_vsel<mode>_uns"
672   [(set (match_operand:VM 0 "altivec_register_operand" "=v")
673         (if_then_else:VM
674          (ne:CCUNS (match_operand:VM 1 "altivec_register_operand" "v")
675                    (match_operand:VM 4 "zero_constant" ""))
676          (match_operand:VM 2 "altivec_register_operand" "v")
677          (match_operand:VM 3 "altivec_register_operand" "v")))]
678   "VECTOR_MEM_ALTIVEC_P (<MODE>mode)"
679   "vsel %0,%3,%2,%1"
680   [(set_attr "type" "vecmove")])
682 ;; Fused multiply add.
684 (define_insn "*altivec_fmav4sf4"
685   [(set (match_operand:V4SF 0 "register_operand" "=v")
686         (fma:V4SF (match_operand:V4SF 1 "register_operand" "v")
687                   (match_operand:V4SF 2 "register_operand" "v")
688                   (match_operand:V4SF 3 "register_operand" "v")))]
689   "VECTOR_UNIT_ALTIVEC_P (V4SFmode)"
690   "vmaddfp %0,%1,%2,%3"
691   [(set_attr "type" "vecfloat")])
693 ;; We do multiply as a fused multiply-add with an add of a -0.0 vector.
695 (define_expand "altivec_mulv4sf3"
696   [(set (match_operand:V4SF 0 "register_operand" "")
697         (fma:V4SF (match_operand:V4SF 1 "register_operand" "")
698                   (match_operand:V4SF 2 "register_operand" "")
699                   (match_dup 3)))]
700   "VECTOR_UNIT_ALTIVEC_P (V4SFmode)"
702   rtx neg0;
704   /* Generate [-0.0, -0.0, -0.0, -0.0].  */
705   neg0 = gen_reg_rtx (V4SImode);
706   emit_insn (gen_altivec_vspltisw (neg0, constm1_rtx));
707   emit_insn (gen_vashlv4si3 (neg0, neg0, neg0));
709   operands[3] = gen_lowpart (V4SFmode, neg0);
712 ;; 32-bit integer multiplication
713 ;; A_high = Operand_0 & 0xFFFF0000 >> 16
714 ;; A_low = Operand_0 & 0xFFFF
715 ;; B_high = Operand_1 & 0xFFFF0000 >> 16
716 ;; B_low = Operand_1 & 0xFFFF
717 ;; result = A_low * B_low + (A_high * B_low + B_high * A_low) << 16
719 ;; (define_insn "mulv4si3"
720 ;;   [(set (match_operand:V4SI 0 "register_operand" "=v")
721 ;;         (mult:V4SI (match_operand:V4SI 1 "register_operand" "v")
722 ;;                    (match_operand:V4SI 2 "register_operand" "v")))]
723 (define_insn "mulv4si3_p8"
724   [(set (match_operand:V4SI 0 "register_operand" "=v")
725         (mult:V4SI (match_operand:V4SI 1 "register_operand" "v")
726                    (match_operand:V4SI 2 "register_operand" "v")))]
727   "TARGET_P8_VECTOR"
728   "vmuluwm %0,%1,%2"
729   [(set_attr "type" "veccomplex")])
731 (define_expand "mulv4si3"
732   [(use (match_operand:V4SI 0 "register_operand" ""))
733    (use (match_operand:V4SI 1 "register_operand" ""))
734    (use (match_operand:V4SI 2 "register_operand" ""))]
735    "TARGET_ALTIVEC"
737   rtx zero;
738   rtx swap;
739   rtx small_swap;
740   rtx sixteen;
741   rtx one;
742   rtx two;
743   rtx low_product;
744   rtx high_product;
745        
746   if (TARGET_P8_VECTOR)
747     {
748       emit_insn (gen_mulv4si3_p8 (operands[0], operands[1], operands[2]));
749       DONE;
750     }
752   zero = gen_reg_rtx (V4SImode);
753   emit_insn (gen_altivec_vspltisw (zero, const0_rtx));
755   sixteen = gen_reg_rtx (V4SImode);   
756   emit_insn (gen_altivec_vspltisw (sixteen,  gen_rtx_CONST_INT (V4SImode, -16)));
758   swap = gen_reg_rtx (V4SImode);
759   emit_insn (gen_vrotlv4si3 (swap, operands[2], sixteen));
761   one = gen_reg_rtx (V8HImode);
762   convert_move (one, operands[1], 0);
764   two = gen_reg_rtx (V8HImode);
765   convert_move (two, operands[2], 0);
767   small_swap = gen_reg_rtx (V8HImode);
768   convert_move (small_swap, swap, 0);
770   low_product = gen_reg_rtx (V4SImode);
771   emit_insn (gen_altivec_vmulouh (low_product, one, two));
773   high_product = gen_reg_rtx (V4SImode);
774   emit_insn (gen_altivec_vmsumuhm (high_product, one, small_swap, zero));
776   emit_insn (gen_vashlv4si3 (high_product, high_product, sixteen));
778   emit_insn (gen_addv4si3 (operands[0], high_product, low_product));
779    
780   DONE;
783 (define_expand "mulv8hi3"
784   [(use (match_operand:V8HI 0 "register_operand" ""))
785    (use (match_operand:V8HI 1 "register_operand" ""))
786    (use (match_operand:V8HI 2 "register_operand" ""))]
787    "TARGET_ALTIVEC"
789   rtx zero = gen_reg_rtx (V8HImode);
791   emit_insn (gen_altivec_vspltish (zero, const0_rtx));
792   emit_insn (gen_fmav8hi4 (operands[0], operands[1], operands[2], zero));
794   DONE;
798 ;; Fused multiply subtract 
799 (define_insn "*altivec_vnmsubfp"
800   [(set (match_operand:V4SF 0 "register_operand" "=v")
801         (neg:V4SF
802          (fma:V4SF (match_operand:V4SF 1 "register_operand" "v")
803                    (match_operand:V4SF 2 "register_operand" "v")
804                    (neg:V4SF
805                     (match_operand:V4SF 3 "register_operand" "v")))))]
806   "VECTOR_UNIT_ALTIVEC_P (V4SFmode)"
807   "vnmsubfp %0,%1,%2,%3"
808   [(set_attr "type" "vecfloat")])
810 (define_insn "altivec_vmsumu<VI_char>m"
811   [(set (match_operand:V4SI 0 "register_operand" "=v")
812         (unspec:V4SI [(match_operand:VIshort 1 "register_operand" "v")
813                       (match_operand:VIshort 2 "register_operand" "v")
814                       (match_operand:V4SI 3 "register_operand" "v")]
815                      UNSPEC_VMSUMU))]
816   "TARGET_ALTIVEC"
817   "vmsumu<VI_char>m %0,%1,%2,%3"
818   [(set_attr "type" "veccomplex")])
820 (define_insn "altivec_vmsumm<VI_char>m"
821   [(set (match_operand:V4SI 0 "register_operand" "=v")
822         (unspec:V4SI [(match_operand:VIshort 1 "register_operand" "v")
823                       (match_operand:VIshort 2 "register_operand" "v")
824                       (match_operand:V4SI 3 "register_operand" "v")]
825                      UNSPEC_VMSUMM))]
826   "TARGET_ALTIVEC"
827   "vmsumm<VI_char>m %0,%1,%2,%3"
828   [(set_attr "type" "veccomplex")])
830 (define_insn "altivec_vmsumshm"
831   [(set (match_operand:V4SI 0 "register_operand" "=v")
832         (unspec:V4SI [(match_operand:V8HI 1 "register_operand" "v")
833                       (match_operand:V8HI 2 "register_operand" "v")
834                       (match_operand:V4SI 3 "register_operand" "v")]
835                      UNSPEC_VMSUMSHM))]
836   "TARGET_ALTIVEC"
837   "vmsumshm %0,%1,%2,%3"
838   [(set_attr "type" "veccomplex")])
840 (define_insn "altivec_vmsumuhs"
841   [(set (match_operand:V4SI 0 "register_operand" "=v")
842         (unspec:V4SI [(match_operand:V8HI 1 "register_operand" "v")
843                       (match_operand:V8HI 2 "register_operand" "v")
844                       (match_operand:V4SI 3 "register_operand" "v")]
845                      UNSPEC_VMSUMUHS))
846    (set (reg:SI VSCR_REGNO) (unspec:SI [(const_int 0)] UNSPEC_SET_VSCR))]
847   "TARGET_ALTIVEC"
848   "vmsumuhs %0,%1,%2,%3"
849   [(set_attr "type" "veccomplex")])
851 (define_insn "altivec_vmsumshs"
852   [(set (match_operand:V4SI 0 "register_operand" "=v")
853         (unspec:V4SI [(match_operand:V8HI 1 "register_operand" "v")
854                       (match_operand:V8HI 2 "register_operand" "v")
855                       (match_operand:V4SI 3 "register_operand" "v")]
856                      UNSPEC_VMSUMSHS))
857    (set (reg:SI VSCR_REGNO) (unspec:SI [(const_int 0)] UNSPEC_SET_VSCR))]
858   "TARGET_ALTIVEC"
859   "vmsumshs %0,%1,%2,%3"
860   [(set_attr "type" "veccomplex")])
862 ;; max
864 (define_insn "umax<mode>3"
865   [(set (match_operand:VI2 0 "register_operand" "=v")
866         (umax:VI2 (match_operand:VI2 1 "register_operand" "v")
867                   (match_operand:VI2 2 "register_operand" "v")))]
868   "<VI_unit>"
869   "vmaxu<VI_char> %0,%1,%2"
870   [(set_attr "type" "vecsimple")])
872 (define_insn "smax<mode>3"
873   [(set (match_operand:VI2 0 "register_operand" "=v")
874         (smax:VI2 (match_operand:VI2 1 "register_operand" "v")
875                   (match_operand:VI2 2 "register_operand" "v")))]
876   "<VI_unit>"
877   "vmaxs<VI_char> %0,%1,%2"
878   [(set_attr "type" "vecsimple")])
880 (define_insn "*altivec_smaxv4sf3"
881   [(set (match_operand:V4SF 0 "register_operand" "=v")
882         (smax:V4SF (match_operand:V4SF 1 "register_operand" "v")
883                    (match_operand:V4SF 2 "register_operand" "v")))]
884   "VECTOR_UNIT_ALTIVEC_P (V4SFmode)"
885   "vmaxfp %0,%1,%2"
886   [(set_attr "type" "veccmp")])
888 (define_insn "umin<mode>3"
889   [(set (match_operand:VI2 0 "register_operand" "=v")
890         (umin:VI2 (match_operand:VI2 1 "register_operand" "v")
891                   (match_operand:VI2 2 "register_operand" "v")))]
892   "<VI_unit>"
893   "vminu<VI_char> %0,%1,%2"
894   [(set_attr "type" "vecsimple")])
896 (define_insn "smin<mode>3"
897   [(set (match_operand:VI2 0 "register_operand" "=v")
898         (smin:VI2 (match_operand:VI2 1 "register_operand" "v")
899                   (match_operand:VI2 2 "register_operand" "v")))]
900   "<VI_unit>"
901   "vmins<VI_char> %0,%1,%2"
902   [(set_attr "type" "vecsimple")])
904 (define_insn "*altivec_sminv4sf3"
905   [(set (match_operand:V4SF 0 "register_operand" "=v")
906         (smin:V4SF (match_operand:V4SF 1 "register_operand" "v")
907                    (match_operand:V4SF 2 "register_operand" "v")))]
908   "VECTOR_UNIT_ALTIVEC_P (V4SFmode)"
909   "vminfp %0,%1,%2"
910   [(set_attr "type" "veccmp")])
912 (define_insn "altivec_vmhaddshs"
913   [(set (match_operand:V8HI 0 "register_operand" "=v")
914         (unspec:V8HI [(match_operand:V8HI 1 "register_operand" "v")
915                       (match_operand:V8HI 2 "register_operand" "v")
916                       (match_operand:V8HI 3 "register_operand" "v")]
917                      UNSPEC_VMHADDSHS))
918    (set (reg:SI VSCR_REGNO) (unspec:SI [(const_int 0)] UNSPEC_SET_VSCR))]
919   "TARGET_ALTIVEC"
920   "vmhaddshs %0,%1,%2,%3"
921   [(set_attr "type" "veccomplex")])
923 (define_insn "altivec_vmhraddshs"
924   [(set (match_operand:V8HI 0 "register_operand" "=v")
925         (unspec:V8HI [(match_operand:V8HI 1 "register_operand" "v")
926                       (match_operand:V8HI 2 "register_operand" "v")
927                       (match_operand:V8HI 3 "register_operand" "v")]
928                      UNSPEC_VMHRADDSHS))
929    (set (reg:SI VSCR_REGNO) (unspec:SI [(const_int 0)] UNSPEC_SET_VSCR))]
930   "TARGET_ALTIVEC"
931   "vmhraddshs %0,%1,%2,%3"
932   [(set_attr "type" "veccomplex")])
934 (define_insn "fmav8hi4"
935   [(set (match_operand:V8HI 0 "register_operand" "=v")
936         (plus:V8HI (mult:V8HI (match_operand:V8HI 1 "register_operand" "v")
937                               (match_operand:V8HI 2 "register_operand" "v"))
938                    (match_operand:V8HI 3 "register_operand" "v")))]
939   "TARGET_ALTIVEC"
940   "vmladduhm %0,%1,%2,%3"
941   [(set_attr "type" "veccomplex")])
943 (define_expand "altivec_vmrghb"
944   [(use (match_operand:V16QI 0 "register_operand" ""))
945    (use (match_operand:V16QI 1 "register_operand" ""))
946    (use (match_operand:V16QI 2 "register_operand" ""))]
947   "TARGET_ALTIVEC"
949   rtvec v;
950   rtx x;
952   /* Special handling for LE with -maltivec=be.  */
953   if (!BYTES_BIG_ENDIAN && VECTOR_ELT_ORDER_BIG)
954     {
955       v = gen_rtvec (16, GEN_INT (8), GEN_INT (24), GEN_INT (9), GEN_INT (25),
956                      GEN_INT (10), GEN_INT (26), GEN_INT (11), GEN_INT (27),
957                      GEN_INT (12), GEN_INT (28), GEN_INT (13), GEN_INT (29),
958                      GEN_INT (14), GEN_INT (30), GEN_INT (15), GEN_INT (31));
959       x = gen_rtx_VEC_CONCAT (V32QImode, operands[2], operands[1]);
960     }
961   else
962     {
963       v = gen_rtvec (16, GEN_INT (0), GEN_INT (16), GEN_INT (1), GEN_INT (17),
964                      GEN_INT (2), GEN_INT (18), GEN_INT (3), GEN_INT (19),
965                      GEN_INT (4), GEN_INT (20), GEN_INT (5), GEN_INT (21),
966                      GEN_INT (6), GEN_INT (22), GEN_INT (7), GEN_INT (23));
967       x = gen_rtx_VEC_CONCAT (V32QImode, operands[1], operands[2]);
968     }
970   x = gen_rtx_VEC_SELECT (V16QImode, x, gen_rtx_PARALLEL (VOIDmode, v));
971   emit_insn (gen_rtx_SET (operands[0], x));
972   DONE;
975 (define_insn "*altivec_vmrghb_internal"
976   [(set (match_operand:V16QI 0 "register_operand" "=v")
977         (vec_select:V16QI
978           (vec_concat:V32QI
979             (match_operand:V16QI 1 "register_operand" "v")
980             (match_operand:V16QI 2 "register_operand" "v"))
981           (parallel [(const_int 0) (const_int 16)
982                      (const_int 1) (const_int 17)
983                      (const_int 2) (const_int 18)
984                      (const_int 3) (const_int 19)
985                      (const_int 4) (const_int 20)
986                      (const_int 5) (const_int 21)
987                      (const_int 6) (const_int 22)
988                      (const_int 7) (const_int 23)])))]
989   "TARGET_ALTIVEC"
991   if (BYTES_BIG_ENDIAN)
992     return "vmrghb %0,%1,%2";
993   else
994     return "vmrglb %0,%2,%1";
996   [(set_attr "type" "vecperm")])
998 (define_insn "altivec_vmrghb_direct"
999   [(set (match_operand:V16QI 0 "register_operand" "=v")
1000         (unspec:V16QI [(match_operand:V16QI 1 "register_operand" "v")
1001                        (match_operand:V16QI 2 "register_operand" "v")]
1002                       UNSPEC_VMRGH_DIRECT))]
1003   "TARGET_ALTIVEC"
1004   "vmrghb %0,%1,%2"
1005   [(set_attr "type" "vecperm")])
1007 (define_expand "altivec_vmrghh"
1008   [(use (match_operand:V8HI 0 "register_operand" ""))
1009    (use (match_operand:V8HI 1 "register_operand" ""))
1010    (use (match_operand:V8HI 2 "register_operand" ""))]
1011   "TARGET_ALTIVEC"
1013   rtvec v;
1014   rtx x;
1016   /* Special handling for LE with -maltivec=be.  */
1017   if (!BYTES_BIG_ENDIAN && VECTOR_ELT_ORDER_BIG)
1018     {
1019       v = gen_rtvec (8, GEN_INT (4), GEN_INT (12), GEN_INT (5), GEN_INT (13),
1020                      GEN_INT (6), GEN_INT (14), GEN_INT (7), GEN_INT (15));
1021       x = gen_rtx_VEC_CONCAT (V16HImode, operands[2], operands[1]);
1022     }
1023   else
1024     {
1025       v = gen_rtvec (8, GEN_INT (0), GEN_INT (8), GEN_INT (1), GEN_INT (9),
1026                      GEN_INT (2), GEN_INT (10), GEN_INT (3), GEN_INT (11));
1027       x = gen_rtx_VEC_CONCAT (V16HImode, operands[1], operands[2]);
1028     }
1030   x = gen_rtx_VEC_SELECT (V8HImode, x, gen_rtx_PARALLEL (VOIDmode, v));
1031   emit_insn (gen_rtx_SET (operands[0], x));
1032   DONE;
1035 (define_insn "*altivec_vmrghh_internal"
1036   [(set (match_operand:V8HI 0 "register_operand" "=v")
1037         (vec_select:V8HI
1038           (vec_concat:V16HI
1039             (match_operand:V8HI 1 "register_operand" "v")
1040             (match_operand:V8HI 2 "register_operand" "v"))
1041           (parallel [(const_int 0) (const_int 8)
1042                      (const_int 1) (const_int 9)
1043                      (const_int 2) (const_int 10)
1044                      (const_int 3) (const_int 11)])))]
1045   "TARGET_ALTIVEC"
1047   if (BYTES_BIG_ENDIAN)
1048     return "vmrghh %0,%1,%2";
1049   else
1050     return "vmrglh %0,%2,%1";
1052   [(set_attr "type" "vecperm")])
1054 (define_insn "altivec_vmrghh_direct"
1055   [(set (match_operand:V8HI 0 "register_operand" "=v")
1056         (unspec:V8HI [(match_operand:V8HI 1 "register_operand" "v")
1057                       (match_operand:V8HI 2 "register_operand" "v")]
1058                      UNSPEC_VMRGH_DIRECT))]
1059   "TARGET_ALTIVEC"
1060   "vmrghh %0,%1,%2"
1061   [(set_attr "type" "vecperm")])
1063 (define_expand "altivec_vmrghw"
1064   [(use (match_operand:V4SI 0 "register_operand" ""))
1065    (use (match_operand:V4SI 1 "register_operand" ""))
1066    (use (match_operand:V4SI 2 "register_operand" ""))]
1067   "VECTOR_MEM_ALTIVEC_P (V4SImode)"
1069   rtvec v;
1070   rtx x;
1072   /* Special handling for LE with -maltivec=be.  */
1073   if (!BYTES_BIG_ENDIAN && VECTOR_ELT_ORDER_BIG)
1074     {
1075       v = gen_rtvec (4, GEN_INT (2), GEN_INT (6), GEN_INT (3), GEN_INT (7));
1076       x = gen_rtx_VEC_CONCAT (V8SImode, operands[2], operands[1]);
1077     }
1078   else
1079     {
1080       v = gen_rtvec (4, GEN_INT (0), GEN_INT (4), GEN_INT (1), GEN_INT (5));
1081       x = gen_rtx_VEC_CONCAT (V8SImode, operands[1], operands[2]);
1082     }
1084   x = gen_rtx_VEC_SELECT (V4SImode, x, gen_rtx_PARALLEL (VOIDmode, v));
1085   emit_insn (gen_rtx_SET (operands[0], x));
1086   DONE;
1089 (define_insn "*altivec_vmrghw_internal"
1090   [(set (match_operand:V4SI 0 "register_operand" "=v")
1091         (vec_select:V4SI
1092           (vec_concat:V8SI
1093             (match_operand:V4SI 1 "register_operand" "v")
1094             (match_operand:V4SI 2 "register_operand" "v"))
1095           (parallel [(const_int 0) (const_int 4)
1096                      (const_int 1) (const_int 5)])))]
1097   "VECTOR_MEM_ALTIVEC_P (V4SImode)"
1099   if (BYTES_BIG_ENDIAN)
1100     return "vmrghw %0,%1,%2";
1101   else
1102     return "vmrglw %0,%2,%1";
1104   [(set_attr "type" "vecperm")])
1106 (define_insn "altivec_vmrghw_direct"
1107   [(set (match_operand:V4SI 0 "register_operand" "=v")
1108         (unspec:V4SI [(match_operand:V4SI 1 "register_operand" "v")
1109                       (match_operand:V4SI 2 "register_operand" "v")]
1110                      UNSPEC_VMRGH_DIRECT))]
1111   "TARGET_ALTIVEC"
1112   "vmrghw %0,%1,%2"
1113   [(set_attr "type" "vecperm")])
1115 (define_insn "*altivec_vmrghsf"
1116   [(set (match_operand:V4SF 0 "register_operand" "=v")
1117         (vec_select:V4SF
1118           (vec_concat:V8SF
1119             (match_operand:V4SF 1 "register_operand" "v")
1120             (match_operand:V4SF 2 "register_operand" "v"))
1121           (parallel [(const_int 0) (const_int 4)
1122                      (const_int 1) (const_int 5)])))]
1123   "VECTOR_MEM_ALTIVEC_P (V4SFmode)"
1125   if (BYTES_BIG_ENDIAN)
1126     return "vmrghw %0,%1,%2";
1127   else
1128     return "vmrglw %0,%2,%1";
1130   [(set_attr "type" "vecperm")])
1132 (define_expand "altivec_vmrglb"
1133   [(use (match_operand:V16QI 0 "register_operand" ""))
1134    (use (match_operand:V16QI 1 "register_operand" ""))
1135    (use (match_operand:V16QI 2 "register_operand" ""))]
1136   "TARGET_ALTIVEC"
1138   rtvec v;
1139   rtx x;
1141   /* Special handling for LE with -maltivec=be.  */
1142   if (!BYTES_BIG_ENDIAN && VECTOR_ELT_ORDER_BIG)
1143     {
1144       v = gen_rtvec (16, GEN_INT (0), GEN_INT (16), GEN_INT (1), GEN_INT (17),
1145                      GEN_INT (2), GEN_INT (18), GEN_INT (3), GEN_INT (19),
1146                      GEN_INT (4), GEN_INT (20), GEN_INT (5), GEN_INT (21),
1147                      GEN_INT (6), GEN_INT (22), GEN_INT (7), GEN_INT (23));
1148       x = gen_rtx_VEC_CONCAT (V32QImode, operands[2], operands[1]);
1149     }
1150   else
1151     {
1152       v = gen_rtvec (16, GEN_INT (8), GEN_INT (24), GEN_INT (9), GEN_INT (25),
1153                      GEN_INT (10), GEN_INT (26), GEN_INT (11), GEN_INT (27),
1154                      GEN_INT (12), GEN_INT (28), GEN_INT (13), GEN_INT (29),
1155                      GEN_INT (14), GEN_INT (30), GEN_INT (15), GEN_INT (31));
1156       x = gen_rtx_VEC_CONCAT (V32QImode, operands[1], operands[2]);
1157     }
1159   x = gen_rtx_VEC_SELECT (V16QImode, x, gen_rtx_PARALLEL (VOIDmode, v));
1160   emit_insn (gen_rtx_SET (operands[0], x));
1161   DONE;
1164 (define_insn "*altivec_vmrglb_internal"
1165   [(set (match_operand:V16QI 0 "register_operand" "=v")
1166         (vec_select:V16QI
1167           (vec_concat:V32QI
1168             (match_operand:V16QI 1 "register_operand" "v")
1169             (match_operand:V16QI 2 "register_operand" "v"))
1170           (parallel [(const_int  8) (const_int 24)
1171                      (const_int  9) (const_int 25)
1172                      (const_int 10) (const_int 26)
1173                      (const_int 11) (const_int 27)
1174                      (const_int 12) (const_int 28)
1175                      (const_int 13) (const_int 29)
1176                      (const_int 14) (const_int 30)
1177                      (const_int 15) (const_int 31)])))]
1178   "TARGET_ALTIVEC"
1180   if (BYTES_BIG_ENDIAN)
1181     return "vmrglb %0,%1,%2";
1182   else
1183     return "vmrghb %0,%2,%1";
1185   [(set_attr "type" "vecperm")])
1187 (define_insn "altivec_vmrglb_direct"
1188   [(set (match_operand:V16QI 0 "register_operand" "=v")
1189         (unspec:V16QI [(match_operand:V16QI 1 "register_operand" "v")
1190                        (match_operand:V16QI 2 "register_operand" "v")]
1191                       UNSPEC_VMRGL_DIRECT))]
1192   "TARGET_ALTIVEC"
1193   "vmrglb %0,%1,%2"
1194   [(set_attr "type" "vecperm")])
1196 (define_expand "altivec_vmrglh"
1197   [(use (match_operand:V8HI 0 "register_operand" ""))
1198    (use (match_operand:V8HI 1 "register_operand" ""))
1199    (use (match_operand:V8HI 2 "register_operand" ""))]
1200   "TARGET_ALTIVEC"
1202   rtvec v;
1203   rtx x;
1205   /* Special handling for LE with -maltivec=be.  */
1206   if (!BYTES_BIG_ENDIAN && VECTOR_ELT_ORDER_BIG)
1207     {
1208       v = gen_rtvec (8, GEN_INT (0), GEN_INT (8), GEN_INT (1), GEN_INT (9),
1209                      GEN_INT (2), GEN_INT (10), GEN_INT (3), GEN_INT (11));
1210       x = gen_rtx_VEC_CONCAT (V16HImode, operands[2], operands[1]);
1211     }
1212   else
1213     {
1214       v = gen_rtvec (8, GEN_INT (4), GEN_INT (12), GEN_INT (5), GEN_INT (13),
1215                      GEN_INT (6), GEN_INT (14), GEN_INT (7), GEN_INT (15));
1216       x = gen_rtx_VEC_CONCAT (V16HImode, operands[1], operands[2]);
1217     }
1219   x = gen_rtx_VEC_SELECT (V8HImode, x, gen_rtx_PARALLEL (VOIDmode, v));
1220   emit_insn (gen_rtx_SET (operands[0], x));
1221   DONE;
1224 (define_insn "*altivec_vmrglh_internal"
1225   [(set (match_operand:V8HI 0 "register_operand" "=v")
1226         (vec_select:V8HI
1227           (vec_concat:V16HI
1228             (match_operand:V8HI 1 "register_operand" "v")
1229             (match_operand:V8HI 2 "register_operand" "v"))
1230           (parallel [(const_int 4) (const_int 12)
1231                      (const_int 5) (const_int 13)
1232                      (const_int 6) (const_int 14)
1233                      (const_int 7) (const_int 15)])))]
1234   "TARGET_ALTIVEC"
1236   if (BYTES_BIG_ENDIAN)
1237     return "vmrglh %0,%1,%2";
1238   else
1239     return "vmrghh %0,%2,%1";
1241   [(set_attr "type" "vecperm")])
1243 (define_insn "altivec_vmrglh_direct"
1244   [(set (match_operand:V8HI 0 "register_operand" "=v")
1245         (unspec:V8HI [(match_operand:V8HI 1 "register_operand" "v")
1246                       (match_operand:V8HI 2 "register_operand" "v")]
1247                      UNSPEC_VMRGL_DIRECT))]
1248   "TARGET_ALTIVEC"
1249   "vmrglh %0,%1,%2"
1250   [(set_attr "type" "vecperm")])
1252 (define_expand "altivec_vmrglw"
1253   [(use (match_operand:V4SI 0 "register_operand" ""))
1254    (use (match_operand:V4SI 1 "register_operand" ""))
1255    (use (match_operand:V4SI 2 "register_operand" ""))]
1256   "VECTOR_MEM_ALTIVEC_P (V4SImode)"
1258   rtvec v;
1259   rtx x;
1261   /* Special handling for LE with -maltivec=be.  */
1262   if (!BYTES_BIG_ENDIAN && VECTOR_ELT_ORDER_BIG)
1263     {
1264       v = gen_rtvec (4, GEN_INT (0), GEN_INT (4), GEN_INT (1), GEN_INT (5));
1265       x = gen_rtx_VEC_CONCAT (V8SImode, operands[2], operands[1]);
1266     }
1267   else
1268     {
1269       v = gen_rtvec (4, GEN_INT (2), GEN_INT (6), GEN_INT (3), GEN_INT (7));
1270       x = gen_rtx_VEC_CONCAT (V8SImode, operands[1], operands[2]);
1271     }
1273   x = gen_rtx_VEC_SELECT (V4SImode, x, gen_rtx_PARALLEL (VOIDmode, v));
1274   emit_insn (gen_rtx_SET (operands[0], x));
1275   DONE;
1278 (define_insn "*altivec_vmrglw_internal"
1279   [(set (match_operand:V4SI 0 "register_operand" "=v")
1280         (vec_select:V4SI
1281           (vec_concat:V8SI
1282             (match_operand:V4SI 1 "register_operand" "v")
1283             (match_operand:V4SI 2 "register_operand" "v"))
1284           (parallel [(const_int 2) (const_int 6)
1285                      (const_int 3) (const_int 7)])))]
1286   "VECTOR_MEM_ALTIVEC_P (V4SImode)"
1288   if (BYTES_BIG_ENDIAN)
1289     return "vmrglw %0,%1,%2";
1290   else
1291     return "vmrghw %0,%2,%1";
1293   [(set_attr "type" "vecperm")])
1295 (define_insn "altivec_vmrglw_direct"
1296   [(set (match_operand:V4SI 0 "register_operand" "=v")
1297         (unspec:V4SI [(match_operand:V4SI 1 "register_operand" "v")
1298                       (match_operand:V4SI 2 "register_operand" "v")]
1299                      UNSPEC_VMRGL_DIRECT))]
1300   "TARGET_ALTIVEC"
1301   "vmrglw %0,%1,%2"
1302   [(set_attr "type" "vecperm")])
1304 (define_insn "*altivec_vmrglsf"
1305   [(set (match_operand:V4SF 0 "register_operand" "=v")
1306         (vec_select:V4SF
1307          (vec_concat:V8SF
1308            (match_operand:V4SF 1 "register_operand" "v")
1309            (match_operand:V4SF 2 "register_operand" "v"))
1310          (parallel [(const_int 2) (const_int 6)
1311                     (const_int 3) (const_int 7)])))]
1312   "VECTOR_MEM_ALTIVEC_P (V4SFmode)"
1314   if (BYTES_BIG_ENDIAN)
1315     return "vmrglw %0,%1,%2";
1316   else
1317     return "vmrghw %0,%2,%1";
1319   [(set_attr "type" "vecperm")])
1321 ;; Power8 vector merge two V4SF/V4SI even words to V4SF
1322 (define_insn "p8_vmrgew_<mode>"
1323   [(set (match_operand:VSX_W 0 "register_operand" "=v")
1324         (vec_select:VSX_W
1325           (vec_concat:<VS_double>
1326             (match_operand:VSX_W 1 "register_operand" "v")
1327             (match_operand:VSX_W 2 "register_operand" "v"))
1328           (parallel [(const_int 0) (const_int 4)
1329                      (const_int 2) (const_int 6)])))]
1330   "TARGET_P8_VECTOR"
1332   if (BYTES_BIG_ENDIAN)
1333     return "vmrgew %0,%1,%2";
1334   else
1335     return "vmrgow %0,%2,%1";
1337   [(set_attr "type" "vecperm")])
1339 (define_insn "p8_vmrgow"
1340   [(set (match_operand:V4SI 0 "register_operand" "=v")
1341         (vec_select:V4SI
1342           (vec_concat:V8SI
1343             (match_operand:V4SI 1 "register_operand" "v")
1344             (match_operand:V4SI 2 "register_operand" "v"))
1345           (parallel [(const_int 1) (const_int 5)
1346                      (const_int 3) (const_int 7)])))]
1347   "TARGET_P8_VECTOR"
1349   if (BYTES_BIG_ENDIAN)
1350     return "vmrgow %0,%1,%2";
1351   else
1352     return "vmrgew %0,%2,%1";
1354   [(set_attr "type" "vecperm")])
1356 (define_insn "p8_vmrgew_<mode>_direct"
1357   [(set (match_operand:VSX_W 0 "register_operand" "=v")
1358         (unspec:VSX_W [(match_operand:VSX_W 1 "register_operand" "v")
1359                        (match_operand:VSX_W 2 "register_operand" "v")]
1360                      UNSPEC_VMRGEW_DIRECT))]
1361   "TARGET_P8_VECTOR"
1362   "vmrgew %0,%1,%2"
1363   [(set_attr "type" "vecperm")])
1365 (define_insn "p8_vmrgow_<mode>_direct"
1366   [(set (match_operand:VSX_W 0 "register_operand" "=v")
1367         (unspec:VSX_W [(match_operand:VSX_W 1 "register_operand" "v")
1368                        (match_operand:VSX_W 2 "register_operand" "v")]
1369                      UNSPEC_VMRGOW_DIRECT))]
1370   "TARGET_P8_VECTOR"
1371   "vmrgow %0,%1,%2"
1372   [(set_attr "type" "vecperm")])
1374 (define_expand "vec_widen_umult_even_v16qi"
1375   [(use (match_operand:V8HI 0 "register_operand" ""))
1376    (use (match_operand:V16QI 1 "register_operand" ""))
1377    (use (match_operand:V16QI 2 "register_operand" ""))]
1378   "TARGET_ALTIVEC"
1380   if (VECTOR_ELT_ORDER_BIG)
1381     emit_insn (gen_altivec_vmuleub (operands[0], operands[1], operands[2]));
1382   else
1383     emit_insn (gen_altivec_vmuloub (operands[0], operands[1], operands[2]));
1384   DONE;
1387 (define_expand "vec_widen_smult_even_v16qi"
1388   [(use (match_operand:V8HI 0 "register_operand" ""))
1389    (use (match_operand:V16QI 1 "register_operand" ""))
1390    (use (match_operand:V16QI 2 "register_operand" ""))]
1391   "TARGET_ALTIVEC"
1393   if (VECTOR_ELT_ORDER_BIG)
1394     emit_insn (gen_altivec_vmulesb (operands[0], operands[1], operands[2]));
1395   else
1396     emit_insn (gen_altivec_vmulosb (operands[0], operands[1], operands[2]));
1397   DONE;
1400 (define_expand "vec_widen_umult_even_v8hi"
1401   [(use (match_operand:V4SI 0 "register_operand" ""))
1402    (use (match_operand:V8HI 1 "register_operand" ""))
1403    (use (match_operand:V8HI 2 "register_operand" ""))]
1404   "TARGET_ALTIVEC"
1406   if (VECTOR_ELT_ORDER_BIG)
1407     emit_insn (gen_altivec_vmuleuh (operands[0], operands[1], operands[2]));
1408   else
1409     emit_insn (gen_altivec_vmulouh (operands[0], operands[1], operands[2]));
1410   DONE;
1413 (define_expand "vec_widen_smult_even_v8hi"
1414   [(use (match_operand:V4SI 0 "register_operand" ""))
1415    (use (match_operand:V8HI 1 "register_operand" ""))
1416    (use (match_operand:V8HI 2 "register_operand" ""))]
1417   "TARGET_ALTIVEC"
1419   if (VECTOR_ELT_ORDER_BIG)
1420     emit_insn (gen_altivec_vmulesh (operands[0], operands[1], operands[2]));
1421   else
1422     emit_insn (gen_altivec_vmulosh (operands[0], operands[1], operands[2]));
1423   DONE;
1426 (define_expand "vec_widen_umult_even_v4si"
1427   [(use (match_operand:V2DI 0 "register_operand"))
1428    (use (match_operand:V4SI 1 "register_operand"))
1429    (use (match_operand:V4SI 2 "register_operand"))]
1430   "TARGET_P8_VECTOR"
1432  if (VECTOR_ELT_ORDER_BIG)
1433     emit_insn (gen_altivec_vmuleuw (operands[0], operands[1], operands[2]));
1434   else
1435     emit_insn (gen_altivec_vmulouw (operands[0], operands[1], operands[2]));
1436  DONE;
1439 (define_expand "vec_widen_smult_even_v4si"
1440   [(use (match_operand:V2DI 0 "register_operand"))
1441    (use (match_operand:V4SI 1 "register_operand"))
1442    (use (match_operand:V4SI 2 "register_operand"))]
1443   "TARGET_P8_VECTOR"
1445   if (VECTOR_ELT_ORDER_BIG)
1446     emit_insn (gen_altivec_vmulesw (operands[0], operands[1], operands[2]));
1447  else
1448     emit_insn (gen_altivec_vmulosw (operands[0], operands[1], operands[2]));
1449   DONE;
1452 (define_expand "vec_widen_umult_odd_v16qi"
1453   [(use (match_operand:V8HI 0 "register_operand" ""))
1454    (use (match_operand:V16QI 1 "register_operand" ""))
1455    (use (match_operand:V16QI 2 "register_operand" ""))]
1456   "TARGET_ALTIVEC"
1458   if (VECTOR_ELT_ORDER_BIG)
1459     emit_insn (gen_altivec_vmuloub (operands[0], operands[1], operands[2]));
1460   else
1461     emit_insn (gen_altivec_vmuleub (operands[0], operands[1], operands[2]));
1462   DONE;
1465 (define_expand "vec_widen_smult_odd_v16qi"
1466   [(use (match_operand:V8HI 0 "register_operand" ""))
1467    (use (match_operand:V16QI 1 "register_operand" ""))
1468    (use (match_operand:V16QI 2 "register_operand" ""))]
1469   "TARGET_ALTIVEC"
1471   if (VECTOR_ELT_ORDER_BIG)
1472     emit_insn (gen_altivec_vmulosb (operands[0], operands[1], operands[2]));
1473   else
1474     emit_insn (gen_altivec_vmulesb (operands[0], operands[1], operands[2]));
1475   DONE;
1478 (define_expand "vec_widen_umult_odd_v8hi"
1479   [(use (match_operand:V4SI 0 "register_operand" ""))
1480    (use (match_operand:V8HI 1 "register_operand" ""))
1481    (use (match_operand:V8HI 2 "register_operand" ""))]
1482   "TARGET_ALTIVEC"
1484   if (VECTOR_ELT_ORDER_BIG)
1485     emit_insn (gen_altivec_vmulouh (operands[0], operands[1], operands[2]));
1486   else
1487     emit_insn (gen_altivec_vmuleuh (operands[0], operands[1], operands[2]));
1488   DONE;
1491 (define_expand "vec_widen_smult_odd_v8hi"
1492   [(use (match_operand:V4SI 0 "register_operand" ""))
1493    (use (match_operand:V8HI 1 "register_operand" ""))
1494    (use (match_operand:V8HI 2 "register_operand" ""))]
1495   "TARGET_ALTIVEC"
1497   if (VECTOR_ELT_ORDER_BIG)
1498     emit_insn (gen_altivec_vmulosh (operands[0], operands[1], operands[2]));
1499   else
1500     emit_insn (gen_altivec_vmulesh (operands[0], operands[1], operands[2]));
1501   DONE;
1504 (define_expand "vec_widen_umult_odd_v4si"
1505   [(use (match_operand:V2DI 0 "register_operand"))
1506    (use (match_operand:V4SI 1 "register_operand"))
1507    (use (match_operand:V4SI 2 "register_operand"))]
1508   "TARGET_P8_VECTOR"
1510   if (VECTOR_ELT_ORDER_BIG)
1511     emit_insn (gen_altivec_vmulouw (operands[0], operands[1], operands[2]));
1512   else
1513     emit_insn (gen_altivec_vmuleuw (operands[0], operands[1], operands[2]));
1514   DONE;
1517 (define_expand "vec_widen_smult_odd_v4si"
1518   [(use (match_operand:V2DI 0 "register_operand"))
1519    (use (match_operand:V4SI 1 "register_operand"))
1520    (use (match_operand:V4SI 2 "register_operand"))]
1521   "TARGET_P8_VECTOR"
1523   if (VECTOR_ELT_ORDER_BIG)
1524     emit_insn (gen_altivec_vmulosw (operands[0], operands[1], operands[2]));
1525   else
1526     emit_insn (gen_altivec_vmulesw (operands[0], operands[1], operands[2]));
1527   DONE;
1530 (define_insn "altivec_vmuleub"
1531   [(set (match_operand:V8HI 0 "register_operand" "=v")
1532         (unspec:V8HI [(match_operand:V16QI 1 "register_operand" "v")
1533                       (match_operand:V16QI 2 "register_operand" "v")]
1534                      UNSPEC_VMULEUB))]
1535   "TARGET_ALTIVEC"
1536   "vmuleub %0,%1,%2"
1537   [(set_attr "type" "veccomplex")])
1539 (define_insn "altivec_vmuloub"
1540   [(set (match_operand:V8HI 0 "register_operand" "=v")
1541         (unspec:V8HI [(match_operand:V16QI 1 "register_operand" "v")
1542                       (match_operand:V16QI 2 "register_operand" "v")]
1543                      UNSPEC_VMULOUB))]
1544   "TARGET_ALTIVEC"
1545   "vmuloub %0,%1,%2"
1546   [(set_attr "type" "veccomplex")])
1548 (define_insn "altivec_vmulesb"
1549   [(set (match_operand:V8HI 0 "register_operand" "=v")
1550         (unspec:V8HI [(match_operand:V16QI 1 "register_operand" "v")
1551                       (match_operand:V16QI 2 "register_operand" "v")]
1552                      UNSPEC_VMULESB))]
1553   "TARGET_ALTIVEC"
1554   "vmulesb %0,%1,%2"
1555   [(set_attr "type" "veccomplex")])
1557 (define_insn "altivec_vmulosb"
1558   [(set (match_operand:V8HI 0 "register_operand" "=v")
1559         (unspec:V8HI [(match_operand:V16QI 1 "register_operand" "v")
1560                       (match_operand:V16QI 2 "register_operand" "v")]
1561                      UNSPEC_VMULOSB))]
1562   "TARGET_ALTIVEC"
1563   "vmulosb %0,%1,%2"
1564   [(set_attr "type" "veccomplex")])
1566 (define_insn "altivec_vmuleuh"
1567   [(set (match_operand:V4SI 0 "register_operand" "=v")
1568         (unspec:V4SI [(match_operand:V8HI 1 "register_operand" "v")
1569                       (match_operand:V8HI 2 "register_operand" "v")]
1570                      UNSPEC_VMULEUH))]
1571   "TARGET_ALTIVEC"
1572   "vmuleuh %0,%1,%2"
1573   [(set_attr "type" "veccomplex")])
1575 (define_insn "altivec_vmulouh"
1576   [(set (match_operand:V4SI 0 "register_operand" "=v")
1577         (unspec:V4SI [(match_operand:V8HI 1 "register_operand" "v")
1578                       (match_operand:V8HI 2 "register_operand" "v")]
1579                      UNSPEC_VMULOUH))]
1580   "TARGET_ALTIVEC"
1581   "vmulouh %0,%1,%2"
1582   [(set_attr "type" "veccomplex")])
1584 (define_insn "altivec_vmulesh"
1585   [(set (match_operand:V4SI 0 "register_operand" "=v")
1586         (unspec:V4SI [(match_operand:V8HI 1 "register_operand" "v")
1587                       (match_operand:V8HI 2 "register_operand" "v")]
1588                      UNSPEC_VMULESH))]
1589   "TARGET_ALTIVEC"
1590   "vmulesh %0,%1,%2"
1591   [(set_attr "type" "veccomplex")])
1593 (define_insn "altivec_vmulosh"
1594   [(set (match_operand:V4SI 0 "register_operand" "=v")
1595         (unspec:V4SI [(match_operand:V8HI 1 "register_operand" "v")
1596                       (match_operand:V8HI 2 "register_operand" "v")]
1597                      UNSPEC_VMULOSH))]
1598   "TARGET_ALTIVEC"
1599   "vmulosh %0,%1,%2"
1600   [(set_attr "type" "veccomplex")])
1602 (define_insn "altivec_vmuleuw"
1603   [(set (match_operand:V2DI 0 "register_operand" "=v")
1604        (unspec:V2DI [(match_operand:V4SI 1 "register_operand" "v")
1605                      (match_operand:V4SI 2 "register_operand" "v")]
1606                     UNSPEC_VMULEUW))]
1607   "TARGET_P8_VECTOR"
1608   "vmuleuw %0,%1,%2"
1609   [(set_attr "type" "veccomplex")])
1611 (define_insn "altivec_vmulouw"
1612   [(set (match_operand:V2DI 0 "register_operand" "=v")
1613        (unspec:V2DI [(match_operand:V4SI 1 "register_operand" "v")
1614                      (match_operand:V4SI 2 "register_operand" "v")]
1615                     UNSPEC_VMULOUW))]
1616   "TARGET_P8_VECTOR"
1617   "vmulouw %0,%1,%2"
1618   [(set_attr "type" "veccomplex")])
1620 (define_insn "altivec_vmulesw"
1621   [(set (match_operand:V2DI 0 "register_operand" "=v")
1622        (unspec:V2DI [(match_operand:V4SI 1 "register_operand" "v")
1623                      (match_operand:V4SI 2 "register_operand" "v")]
1624                     UNSPEC_VMULESW))]
1625   "TARGET_P8_VECTOR"
1626   "vmulesw %0,%1,%2"
1627   [(set_attr "type" "veccomplex")])
1629 (define_insn "altivec_vmulosw"
1630   [(set (match_operand:V2DI 0 "register_operand" "=v")
1631        (unspec:V2DI [(match_operand:V4SI 1 "register_operand" "v")
1632                      (match_operand:V4SI 2 "register_operand" "v")]
1633                     UNSPEC_VMULOSW))]
1634   "TARGET_P8_VECTOR"
1635   "vmulosw %0,%1,%2"
1636   [(set_attr "type" "veccomplex")])
1638 ;; Vector pack/unpack
1639 (define_insn "altivec_vpkpx"
1640   [(set (match_operand:V8HI 0 "register_operand" "=v")
1641         (unspec:V8HI [(match_operand:V4SI 1 "register_operand" "v")
1642                       (match_operand:V4SI 2 "register_operand" "v")]
1643                      UNSPEC_VPKPX))]
1644   "TARGET_ALTIVEC"
1645   "*
1646   {
1647     if (VECTOR_ELT_ORDER_BIG)
1648       return \"vpkpx %0,%1,%2\";
1649     else
1650       return \"vpkpx %0,%2,%1\";
1651   }"
1652   [(set_attr "type" "vecperm")])
1654 (define_insn "altivec_vpks<VI_char>ss"
1655   [(set (match_operand:<VP_small> 0 "register_operand" "=v")
1656         (unspec:<VP_small> [(match_operand:VP 1 "register_operand" "v")
1657                             (match_operand:VP 2 "register_operand" "v")]
1658                            UNSPEC_VPACK_SIGN_SIGN_SAT))]
1659   "<VI_unit>"
1660   "*
1661   {
1662     if (VECTOR_ELT_ORDER_BIG)
1663       return \"vpks<VI_char>ss %0,%1,%2\";
1664     else
1665       return \"vpks<VI_char>ss %0,%2,%1\";
1666   }"
1667   [(set_attr "type" "vecperm")])
1669 (define_insn "altivec_vpks<VI_char>us"
1670   [(set (match_operand:<VP_small> 0 "register_operand" "=v")
1671         (unspec:<VP_small> [(match_operand:VP 1 "register_operand" "v")
1672                             (match_operand:VP 2 "register_operand" "v")]
1673                            UNSPEC_VPACK_SIGN_UNS_SAT))]
1674   "<VI_unit>"
1675   "*
1676   {
1677     if (VECTOR_ELT_ORDER_BIG)
1678       return \"vpks<VI_char>us %0,%1,%2\";
1679     else
1680       return \"vpks<VI_char>us %0,%2,%1\";
1681   }"
1682   [(set_attr "type" "vecperm")])
1684 (define_insn "altivec_vpku<VI_char>us"
1685   [(set (match_operand:<VP_small> 0 "register_operand" "=v")
1686         (unspec:<VP_small> [(match_operand:VP 1 "register_operand" "v")
1687                             (match_operand:VP 2 "register_operand" "v")]
1688                            UNSPEC_VPACK_UNS_UNS_SAT))]
1689   "<VI_unit>"
1690   "*
1691   {
1692     if (VECTOR_ELT_ORDER_BIG)
1693       return \"vpku<VI_char>us %0,%1,%2\";
1694     else
1695       return \"vpku<VI_char>us %0,%2,%1\";
1696   }"
1697   [(set_attr "type" "vecperm")])
1699 (define_insn "altivec_vpku<VI_char>um"
1700   [(set (match_operand:<VP_small> 0 "register_operand" "=v")
1701         (unspec:<VP_small> [(match_operand:VP 1 "register_operand" "v")
1702                             (match_operand:VP 2 "register_operand" "v")]
1703                            UNSPEC_VPACK_UNS_UNS_MOD))]
1704   "<VI_unit>"
1705   "*
1706   {
1707     if (VECTOR_ELT_ORDER_BIG)
1708       return \"vpku<VI_char>um %0,%1,%2\";
1709     else
1710       return \"vpku<VI_char>um %0,%2,%1\";
1711   }"
1712   [(set_attr "type" "vecperm")])
1714 (define_insn "altivec_vpku<VI_char>um_direct"
1715   [(set (match_operand:<VP_small> 0 "register_operand" "=v")
1716         (unspec:<VP_small> [(match_operand:VP 1 "register_operand" "v")
1717                             (match_operand:VP 2 "register_operand" "v")]
1718                            UNSPEC_VPACK_UNS_UNS_MOD_DIRECT))]
1719   "<VI_unit>"
1720   "*
1721   {
1722     if (BYTES_BIG_ENDIAN)
1723       return \"vpku<VI_char>um %0,%1,%2\";
1724     else
1725       return \"vpku<VI_char>um %0,%2,%1\";
1726   }"
1727   [(set_attr "type" "vecperm")])
1729 (define_insn "*altivec_vrl<VI_char>"
1730   [(set (match_operand:VI2 0 "register_operand" "=v")
1731         (rotate:VI2 (match_operand:VI2 1 "register_operand" "v")
1732                     (match_operand:VI2 2 "register_operand" "v")))]
1733   "<VI_unit>"
1734   "vrl<VI_char> %0,%1,%2"
1735   [(set_attr "type" "vecsimple")])
1737 (define_insn "altivec_vrl<VI_char>mi"
1738   [(set (match_operand:VIlong 0 "register_operand" "=v")
1739         (unspec:VIlong [(match_operand:VIlong 1 "register_operand" "0")
1740                         (match_operand:VIlong 2 "register_operand" "v")
1741                         (match_operand:VIlong 3 "register_operand" "v")]
1742                        UNSPEC_VRLMI))]
1743   "TARGET_P9_VECTOR"
1744   "vrl<VI_char>mi %0,%2,%3"
1745   [(set_attr "type" "veclogical")])
1747 (define_insn "altivec_vrl<VI_char>nm"
1748   [(set (match_operand:VIlong 0 "register_operand" "=v")
1749         (unspec:VIlong [(match_operand:VIlong 1 "register_operand" "v")
1750                         (match_operand:VIlong 2 "register_operand" "v")]
1751                        UNSPEC_VRLNM))]
1752   "TARGET_P9_VECTOR"
1753   "vrl<VI_char>nm %0,%1,%2"
1754   [(set_attr "type" "veclogical")])
1756 (define_insn "altivec_vsl"
1757   [(set (match_operand:V4SI 0 "register_operand" "=v")
1758         (unspec:V4SI [(match_operand:V4SI 1 "register_operand" "v")
1759                       (match_operand:V4SI 2 "register_operand" "v")]
1760                      UNSPEC_VSLV4SI))]
1761   "TARGET_ALTIVEC"
1762   "vsl %0,%1,%2"
1763   [(set_attr "type" "vecperm")])
1765 (define_insn "altivec_vslo"
1766   [(set (match_operand:V4SI 0 "register_operand" "=v")
1767         (unspec:V4SI [(match_operand:V4SI 1 "register_operand" "v")
1768                       (match_operand:V4SI 2 "register_operand" "v")]
1769                      UNSPEC_VSLO))]
1770   "TARGET_ALTIVEC"
1771   "vslo %0,%1,%2"
1772   [(set_attr "type" "vecperm")])
1774 (define_insn "vslv"
1775   [(set (match_operand:V16QI 0 "register_operand" "=v")
1776         (unspec:V16QI [(match_operand:V16QI 1 "register_operand" "v")
1777                        (match_operand:V16QI 2 "register_operand" "v")]
1778          UNSPEC_VSLV))]
1779   "TARGET_P9_VECTOR"
1780   "vslv %0,%1,%2"
1781   [(set_attr "type" "vecsimple")])
1783 (define_insn "vsrv"
1784   [(set (match_operand:V16QI 0 "register_operand" "=v")
1785         (unspec:V16QI [(match_operand:V16QI 1 "register_operand" "v")
1786                        (match_operand:V16QI 2 "register_operand" "v")]
1787          UNSPEC_VSRV))]
1788   "TARGET_P9_VECTOR"
1789   "vsrv %0,%1,%2"
1790   [(set_attr "type" "vecsimple")])
1792 (define_insn "*altivec_vsl<VI_char>"
1793   [(set (match_operand:VI2 0 "register_operand" "=v")
1794         (ashift:VI2 (match_operand:VI2 1 "register_operand" "v")
1795                     (match_operand:VI2 2 "register_operand" "v")))]
1796   "<VI_unit>"
1797   "vsl<VI_char> %0,%1,%2"
1798   [(set_attr "type" "vecsimple")])
1800 (define_insn "*altivec_vsr<VI_char>"
1801   [(set (match_operand:VI2 0 "register_operand" "=v")
1802         (lshiftrt:VI2 (match_operand:VI2 1 "register_operand" "v")
1803                       (match_operand:VI2 2 "register_operand" "v")))]
1804   "<VI_unit>"
1805   "vsr<VI_char> %0,%1,%2"
1806   [(set_attr "type" "vecsimple")])
1808 (define_insn "*altivec_vsra<VI_char>"
1809   [(set (match_operand:VI2 0 "register_operand" "=v")
1810         (ashiftrt:VI2 (match_operand:VI2 1 "register_operand" "v")
1811                       (match_operand:VI2 2 "register_operand" "v")))]
1812   "<VI_unit>"
1813   "vsra<VI_char> %0,%1,%2"
1814   [(set_attr "type" "vecsimple")])
1816 (define_insn "altivec_vsr"
1817   [(set (match_operand:V4SI 0 "register_operand" "=v")
1818         (unspec:V4SI [(match_operand:V4SI 1 "register_operand" "v")
1819                       (match_operand:V4SI 2 "register_operand" "v")]
1820                      UNSPEC_VSR))]
1821   "TARGET_ALTIVEC"
1822   "vsr %0,%1,%2"
1823   [(set_attr "type" "vecperm")])
1825 (define_insn "altivec_vsro"
1826   [(set (match_operand:V4SI 0 "register_operand" "=v")
1827         (unspec:V4SI [(match_operand:V4SI 1 "register_operand" "v")
1828                       (match_operand:V4SI 2 "register_operand" "v")]
1829                      UNSPEC_VSRO))]
1830   "TARGET_ALTIVEC"
1831   "vsro %0,%1,%2"
1832   [(set_attr "type" "vecperm")])
1834 (define_insn "altivec_vsum4ubs"
1835   [(set (match_operand:V4SI 0 "register_operand" "=v")
1836         (unspec:V4SI [(match_operand:V16QI 1 "register_operand" "v")
1837                       (match_operand:V4SI 2 "register_operand" "v")]
1838                      UNSPEC_VSUM4UBS))
1839    (set (reg:SI VSCR_REGNO) (unspec:SI [(const_int 0)] UNSPEC_SET_VSCR))]
1840   "TARGET_ALTIVEC"
1841   "vsum4ubs %0,%1,%2"
1842   [(set_attr "type" "veccomplex")])
1844 (define_insn "altivec_vsum4s<VI_char>s"
1845   [(set (match_operand:V4SI 0 "register_operand" "=v")
1846         (unspec:V4SI [(match_operand:VIshort 1 "register_operand" "v")
1847                       (match_operand:V4SI 2 "register_operand" "v")]
1848                      UNSPEC_VSUM4S))
1849    (set (reg:SI VSCR_REGNO) (unspec:SI [(const_int 0)] UNSPEC_SET_VSCR))]
1850   "TARGET_ALTIVEC"
1851   "vsum4s<VI_char>s %0,%1,%2"
1852   [(set_attr "type" "veccomplex")])
1854 (define_expand "altivec_vsum2sws"
1855   [(use (match_operand:V4SI 0 "register_operand"))
1856    (use (match_operand:V4SI 1 "register_operand"))
1857    (use (match_operand:V4SI 2 "register_operand"))]
1858   "TARGET_ALTIVEC"
1860   if (VECTOR_ELT_ORDER_BIG)
1861     emit_insn (gen_altivec_vsum2sws_direct (operands[0], operands[1],
1862                                             operands[2]));
1863   else
1864     {
1865       rtx tmp1 = gen_reg_rtx (V4SImode);
1866       rtx tmp2 = gen_reg_rtx (V4SImode);
1867       emit_insn (gen_altivec_vsldoi_v4si (tmp1, operands[2],
1868                                           operands[2], GEN_INT (12)));
1869       emit_insn (gen_altivec_vsum2sws_direct (tmp2, operands[1], tmp1));
1870       emit_insn (gen_altivec_vsldoi_v4si (operands[0], tmp2, tmp2,
1871                                           GEN_INT (4)));
1872     }
1873   DONE;
1876 ; FIXME: This can probably be expressed without an UNSPEC.
1877 (define_insn "altivec_vsum2sws_direct"
1878   [(set (match_operand:V4SI 0 "register_operand" "=v")
1879         (unspec:V4SI [(match_operand:V4SI 1 "register_operand" "v")
1880                       (match_operand:V4SI 2 "register_operand" "v")]
1881                      UNSPEC_VSUM2SWS))
1882    (set (reg:SI VSCR_REGNO) (unspec:SI [(const_int 0)] UNSPEC_SET_VSCR))]
1883   "TARGET_ALTIVEC"
1884   "vsum2sws %0,%1,%2"
1885   [(set_attr "type" "veccomplex")])
1887 (define_expand "altivec_vsumsws"
1888   [(use (match_operand:V4SI 0 "register_operand"))
1889    (use (match_operand:V4SI 1 "register_operand"))
1890    (use (match_operand:V4SI 2 "register_operand"))]
1891   "TARGET_ALTIVEC"
1893   if (VECTOR_ELT_ORDER_BIG)
1894     emit_insn (gen_altivec_vsumsws_direct (operands[0], operands[1],
1895                                            operands[2]));
1896   else
1897     {
1898       rtx tmp1 = gen_reg_rtx (V4SImode);
1899       rtx tmp2 = gen_reg_rtx (V4SImode);
1900       emit_insn (gen_altivec_vspltw_direct (tmp1, operands[2], const0_rtx));
1901       emit_insn (gen_altivec_vsumsws_direct (tmp2, operands[1], tmp1));
1902       emit_insn (gen_altivec_vsldoi_v4si (operands[0], tmp2, tmp2,
1903                                           GEN_INT (12)));
1904     }
1905   DONE;
1908 ; FIXME: This can probably be expressed without an UNSPEC.
1909 (define_insn "altivec_vsumsws_direct"
1910   [(set (match_operand:V4SI 0 "register_operand" "=v")
1911         (unspec:V4SI [(match_operand:V4SI 1 "register_operand" "v")
1912                       (match_operand:V4SI 2 "register_operand" "v")]
1913                      UNSPEC_VSUMSWS_DIRECT))
1914    (set (reg:SI VSCR_REGNO) (unspec:SI [(const_int 0)] UNSPEC_SET_VSCR))]
1915   "TARGET_ALTIVEC"
1916   "vsumsws %0,%1,%2"
1917   [(set_attr "type" "veccomplex")])
1919 (define_expand "altivec_vspltb"
1920   [(use (match_operand:V16QI 0 "register_operand" ""))
1921    (use (match_operand:V16QI 1 "register_operand" ""))
1922    (use (match_operand:QI 2 "u5bit_cint_operand" ""))]
1923   "TARGET_ALTIVEC"
1925   rtvec v;
1926   rtx x;
1928   /* Special handling for LE with -maltivec=be.  We have to reflect
1929      the actual selected index for the splat in the RTL.  */
1930   if (!BYTES_BIG_ENDIAN && VECTOR_ELT_ORDER_BIG)
1931     operands[2] = GEN_INT (15 - INTVAL (operands[2]));
1933   v = gen_rtvec (1, operands[2]);
1934   x = gen_rtx_VEC_SELECT (QImode, operands[1], gen_rtx_PARALLEL (VOIDmode, v));
1935   x = gen_rtx_VEC_DUPLICATE (V16QImode, x);
1936   emit_insn (gen_rtx_SET (operands[0], x));
1937   DONE;
1940 (define_insn "*altivec_vspltb_internal"
1941   [(set (match_operand:V16QI 0 "register_operand" "=v")
1942         (vec_duplicate:V16QI
1943          (vec_select:QI (match_operand:V16QI 1 "register_operand" "v")
1944                         (parallel
1945                          [(match_operand:QI 2 "u5bit_cint_operand" "")]))))]
1946   "TARGET_ALTIVEC"
1948   /* For true LE, this adjusts the selected index.  For LE with 
1949      -maltivec=be, this reverses what was done in the define_expand
1950      because the instruction already has big-endian bias.  */
1951   if (!BYTES_BIG_ENDIAN)
1952     operands[2] = GEN_INT (15 - INTVAL (operands[2]));
1954   return "vspltb %0,%1,%2";
1956   [(set_attr "type" "vecperm")])
1958 (define_insn "altivec_vspltb_direct"
1959   [(set (match_operand:V16QI 0 "register_operand" "=v")
1960         (unspec:V16QI [(match_operand:V16QI 1 "register_operand" "v")
1961                        (match_operand:QI 2 "u5bit_cint_operand" "i")]
1962                       UNSPEC_VSPLT_DIRECT))]
1963   "TARGET_ALTIVEC"
1964   "vspltb %0,%1,%2"
1965   [(set_attr "type" "vecperm")])
1967 (define_expand "altivec_vsplth"
1968   [(use (match_operand:V8HI 0 "register_operand" ""))
1969    (use (match_operand:V8HI 1 "register_operand" ""))
1970    (use (match_operand:QI 2 "u5bit_cint_operand" ""))]
1971   "TARGET_ALTIVEC"
1973   rtvec v;
1974   rtx x;
1976   /* Special handling for LE with -maltivec=be.  We have to reflect
1977      the actual selected index for the splat in the RTL.  */
1978   if (!BYTES_BIG_ENDIAN && VECTOR_ELT_ORDER_BIG)
1979     operands[2] = GEN_INT (7 - INTVAL (operands[2]));
1981   v = gen_rtvec (1, operands[2]);
1982   x = gen_rtx_VEC_SELECT (HImode, operands[1], gen_rtx_PARALLEL (VOIDmode, v));
1983   x = gen_rtx_VEC_DUPLICATE (V8HImode, x);
1984   emit_insn (gen_rtx_SET (operands[0], x));
1985   DONE;
1988 (define_insn "*altivec_vsplth_internal"
1989   [(set (match_operand:V8HI 0 "register_operand" "=v")
1990         (vec_duplicate:V8HI
1991          (vec_select:HI (match_operand:V8HI 1 "register_operand" "v")
1992                         (parallel
1993                          [(match_operand:QI 2 "u5bit_cint_operand" "")]))))]
1994   "TARGET_ALTIVEC"
1996   /* For true LE, this adjusts the selected index.  For LE with 
1997      -maltivec=be, this reverses what was done in the define_expand
1998      because the instruction already has big-endian bias.  */
1999   if (!BYTES_BIG_ENDIAN)
2000     operands[2] = GEN_INT (7 - INTVAL (operands[2]));
2002   return "vsplth %0,%1,%2";
2004   [(set_attr "type" "vecperm")])
2006 (define_insn "altivec_vsplth_direct"
2007   [(set (match_operand:V8HI 0 "register_operand" "=v")
2008         (unspec:V8HI [(match_operand:V8HI 1 "register_operand" "v")
2009                       (match_operand:QI 2 "u5bit_cint_operand" "i")]
2010                      UNSPEC_VSPLT_DIRECT))]
2011   "TARGET_ALTIVEC"
2012   "vsplth %0,%1,%2"
2013   [(set_attr "type" "vecperm")])
2015 (define_expand "altivec_vspltw"
2016   [(use (match_operand:V4SI 0 "register_operand" ""))
2017    (use (match_operand:V4SI 1 "register_operand" ""))
2018    (use (match_operand:QI 2 "u5bit_cint_operand" ""))]
2019   "TARGET_ALTIVEC"
2021   rtvec v;
2022   rtx x;
2024   /* Special handling for LE with -maltivec=be.  We have to reflect
2025      the actual selected index for the splat in the RTL.  */
2026   if (!BYTES_BIG_ENDIAN && VECTOR_ELT_ORDER_BIG)
2027     operands[2] = GEN_INT (3 - INTVAL (operands[2]));
2029   v = gen_rtvec (1, operands[2]);
2030   x = gen_rtx_VEC_SELECT (SImode, operands[1], gen_rtx_PARALLEL (VOIDmode, v));
2031   x = gen_rtx_VEC_DUPLICATE (V4SImode, x);
2032   emit_insn (gen_rtx_SET (operands[0], x));
2033   DONE;
2036 (define_insn "*altivec_vspltw_internal"
2037   [(set (match_operand:V4SI 0 "register_operand" "=v")
2038         (vec_duplicate:V4SI
2039          (vec_select:SI (match_operand:V4SI 1 "register_operand" "v")
2040                         (parallel
2041                          [(match_operand:QI 2 "u5bit_cint_operand" "i")]))))]
2042   "TARGET_ALTIVEC"
2044   /* For true LE, this adjusts the selected index.  For LE with 
2045      -maltivec=be, this reverses what was done in the define_expand
2046      because the instruction already has big-endian bias.  */
2047   if (!BYTES_BIG_ENDIAN)
2048     operands[2] = GEN_INT (3 - INTVAL (operands[2]));
2050   return "vspltw %0,%1,%2";
2052   [(set_attr "type" "vecperm")])
2054 (define_insn "altivec_vspltw_direct"
2055   [(set (match_operand:V4SI 0 "register_operand" "=v")
2056         (unspec:V4SI [(match_operand:V4SI 1 "register_operand" "v")
2057                       (match_operand:QI 2 "u5bit_cint_operand" "i")]
2058                      UNSPEC_VSPLT_DIRECT))]
2059   "TARGET_ALTIVEC"
2060   "vspltw %0,%1,%2"
2061   [(set_attr "type" "vecperm")])
2063 (define_expand "altivec_vspltsf"
2064   [(use (match_operand:V4SF 0 "register_operand" ""))
2065    (use (match_operand:V4SF 1 "register_operand" ""))
2066    (use (match_operand:QI 2 "u5bit_cint_operand" ""))]
2067   "TARGET_ALTIVEC"
2069   rtvec v;
2070   rtx x;
2072   /* Special handling for LE with -maltivec=be.  We have to reflect
2073      the actual selected index for the splat in the RTL.  */
2074   if (!BYTES_BIG_ENDIAN && VECTOR_ELT_ORDER_BIG)
2075     operands[2] = GEN_INT (3 - INTVAL (operands[2]));
2077   v = gen_rtvec (1, operands[2]);
2078   x = gen_rtx_VEC_SELECT (SFmode, operands[1], gen_rtx_PARALLEL (VOIDmode, v));
2079   x = gen_rtx_VEC_DUPLICATE (V4SFmode, x);
2080   emit_insn (gen_rtx_SET (operands[0], x));
2081   DONE;
2084 (define_insn "*altivec_vspltsf_internal"
2085   [(set (match_operand:V4SF 0 "register_operand" "=v")
2086         (vec_duplicate:V4SF
2087          (vec_select:SF (match_operand:V4SF 1 "register_operand" "v")
2088                         (parallel
2089                          [(match_operand:QI 2 "u5bit_cint_operand" "i")]))))]
2090   "VECTOR_UNIT_ALTIVEC_P (V4SFmode)"
2092   /* For true LE, this adjusts the selected index.  For LE with 
2093      -maltivec=be, this reverses what was done in the define_expand
2094      because the instruction already has big-endian bias.  */
2095   if (!BYTES_BIG_ENDIAN)
2096     operands[2] = GEN_INT (3 - INTVAL (operands[2]));
2098   return "vspltw %0,%1,%2";
2100   [(set_attr "type" "vecperm")])
2102 (define_insn "altivec_vspltis<VI_char>"
2103   [(set (match_operand:VI 0 "register_operand" "=v")
2104         (vec_duplicate:VI
2105          (match_operand:QI 1 "s5bit_cint_operand" "i")))]
2106   "TARGET_ALTIVEC"
2107   "vspltis<VI_char> %0,%1"
2108   [(set_attr "type" "vecperm")])
2110 (define_insn "*altivec_vrfiz"
2111   [(set (match_operand:V4SF 0 "register_operand" "=v")
2112         (fix:V4SF (match_operand:V4SF 1 "register_operand" "v")))]
2113   "VECTOR_UNIT_ALTIVEC_P (V4SFmode)"
2114   "vrfiz %0,%1"
2115   [(set_attr "type" "vecfloat")])
2117 (define_expand "altivec_vperm_<mode>"
2118   [(set (match_operand:VM 0 "register_operand" "")
2119         (unspec:VM [(match_operand:VM 1 "register_operand" "")
2120                     (match_operand:VM 2 "register_operand" "")
2121                     (match_operand:V16QI 3 "register_operand" "")]
2122                    UNSPEC_VPERM))]
2123   "TARGET_ALTIVEC"
2125   if (!VECTOR_ELT_ORDER_BIG)
2126     {
2127       altivec_expand_vec_perm_le (operands);
2128       DONE;
2129     }
2132 ;; Slightly prefer vperm, since the target does not overlap the source
2133 (define_insn "*altivec_vperm_<mode>_internal"
2134   [(set (match_operand:VM 0 "register_operand" "=v,?wo")
2135         (unspec:VM [(match_operand:VM 1 "register_operand" "v,wo")
2136                     (match_operand:VM 2 "register_operand" "v,0")
2137                     (match_operand:V16QI 3 "register_operand" "v,wo")]
2138                    UNSPEC_VPERM))]
2139   "TARGET_ALTIVEC"
2140   "@
2141    vperm %0,%1,%2,%3
2142    xxperm %x0,%x1,%x3"
2143   [(set_attr "type" "vecperm")
2144    (set_attr "length" "4")])
2146 (define_insn "altivec_vperm_v8hiv16qi"
2147   [(set (match_operand:V16QI 0 "register_operand" "=v,?wo")
2148         (unspec:V16QI [(match_operand:V8HI 1 "register_operand" "v,wo")
2149                        (match_operand:V8HI 2 "register_operand" "v,0")
2150                        (match_operand:V16QI 3 "register_operand" "v,wo")]
2151                    UNSPEC_VPERM))]
2152   "TARGET_ALTIVEC"
2153   "@
2154    vperm %0,%1,%2,%3
2155    xxperm %x0,%x1,%x3"
2156   [(set_attr "type" "vecperm")
2157    (set_attr "length" "4")])
2159 (define_expand "altivec_vperm_<mode>_uns"
2160   [(set (match_operand:VM 0 "register_operand" "")
2161         (unspec:VM [(match_operand:VM 1 "register_operand" "")
2162                     (match_operand:VM 2 "register_operand" "")
2163                     (match_operand:V16QI 3 "register_operand" "")]
2164                    UNSPEC_VPERM_UNS))]
2165   "TARGET_ALTIVEC"
2167   if (!VECTOR_ELT_ORDER_BIG)
2168     {
2169       altivec_expand_vec_perm_le (operands);
2170       DONE;
2171     }
2174 (define_insn "*altivec_vperm_<mode>_uns_internal"
2175   [(set (match_operand:VM 0 "register_operand" "=v,?wo")
2176         (unspec:VM [(match_operand:VM 1 "register_operand" "v,wo")
2177                     (match_operand:VM 2 "register_operand" "v,0")
2178                     (match_operand:V16QI 3 "register_operand" "v,wo")]
2179                    UNSPEC_VPERM_UNS))]
2180   "TARGET_ALTIVEC"
2181   "@
2182    vperm %0,%1,%2,%3
2183    xxperm %x0,%x1,%x3"
2184   [(set_attr "type" "vecperm")
2185    (set_attr "length" "4")])
2187 (define_expand "vec_permv16qi"
2188   [(set (match_operand:V16QI 0 "register_operand" "")
2189         (unspec:V16QI [(match_operand:V16QI 1 "register_operand" "")
2190                        (match_operand:V16QI 2 "register_operand" "")
2191                        (match_operand:V16QI 3 "register_operand" "")]
2192                       UNSPEC_VPERM))]
2193   "TARGET_ALTIVEC"
2195   if (!BYTES_BIG_ENDIAN) {
2196     altivec_expand_vec_perm_le (operands);
2197     DONE;
2198   }
2201 (define_expand "vec_perm_constv16qi"
2202   [(match_operand:V16QI 0 "register_operand" "")
2203    (match_operand:V16QI 1 "register_operand" "")
2204    (match_operand:V16QI 2 "register_operand" "")
2205    (match_operand:V16QI 3 "" "")]
2206   "TARGET_ALTIVEC"
2208   if (altivec_expand_vec_perm_const (operands))
2209     DONE;
2210   else
2211     FAIL;
2214 (define_insn "*altivec_vpermr_<mode>_internal"
2215   [(set (match_operand:VM 0 "register_operand" "=v,?wo")
2216         (unspec:VM [(match_operand:VM 1 "register_operand" "v,wo")
2217                     (match_operand:VM 2 "register_operand" "v,0")
2218                     (match_operand:V16QI 3 "register_operand" "v,wo")]
2219                    UNSPEC_VPERMR))]
2220   "TARGET_P9_VECTOR"
2221   "@
2222    vpermr %0,%2,%1,%3
2223    xxpermr %x0,%x1,%x3"
2224   [(set_attr "type" "vecperm")
2225    (set_attr "length" "4")])
2227 (define_insn "altivec_vrfip"            ; ceil
2228   [(set (match_operand:V4SF 0 "register_operand" "=v")
2229         (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "v")]
2230                      UNSPEC_FRIP))]
2231   "TARGET_ALTIVEC"
2232   "vrfip %0,%1"
2233   [(set_attr "type" "vecfloat")])
2235 (define_insn "altivec_vrfin"
2236   [(set (match_operand:V4SF 0 "register_operand" "=v")
2237         (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "v")]
2238                      UNSPEC_VRFIN))]
2239   "TARGET_ALTIVEC"
2240   "vrfin %0,%1"
2241   [(set_attr "type" "vecfloat")])
2243 (define_insn "*altivec_vrfim"           ; floor
2244   [(set (match_operand:V4SF 0 "register_operand" "=v")
2245         (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "v")]
2246                      UNSPEC_FRIM))]
2247   "TARGET_ALTIVEC"
2248   "vrfim %0,%1"
2249   [(set_attr "type" "vecfloat")])
2251 (define_insn "altivec_vcfux"
2252   [(set (match_operand:V4SF 0 "register_operand" "=v")
2253         (unspec:V4SF [(match_operand:V4SI 1 "register_operand" "v")
2254                       (match_operand:QI 2 "immediate_operand" "i")]
2255                      UNSPEC_VCFUX))]
2256   "TARGET_ALTIVEC"
2257   "vcfux %0,%1,%2"
2258   [(set_attr "type" "vecfloat")])
2260 (define_insn "altivec_vcfsx"
2261   [(set (match_operand:V4SF 0 "register_operand" "=v")
2262         (unspec:V4SF [(match_operand:V4SI 1 "register_operand" "v")
2263                       (match_operand:QI 2 "immediate_operand" "i")]
2264                      UNSPEC_VCFSX))]
2265   "TARGET_ALTIVEC"
2266   "vcfsx %0,%1,%2"
2267   [(set_attr "type" "vecfloat")])
2269 (define_insn "altivec_vctuxs"
2270   [(set (match_operand:V4SI 0 "register_operand" "=v")
2271         (unspec:V4SI [(match_operand:V4SF 1 "register_operand" "v")
2272                       (match_operand:QI 2 "immediate_operand" "i")]
2273                      UNSPEC_VCTUXS))
2274    (set (reg:SI VSCR_REGNO) (unspec:SI [(const_int 0)] UNSPEC_SET_VSCR))]
2275   "TARGET_ALTIVEC"
2276   "vctuxs %0,%1,%2"
2277   [(set_attr "type" "vecfloat")])
2279 (define_insn "altivec_vctsxs"
2280   [(set (match_operand:V4SI 0 "register_operand" "=v")
2281         (unspec:V4SI [(match_operand:V4SF 1 "register_operand" "v")
2282                       (match_operand:QI 2 "immediate_operand" "i")]
2283                      UNSPEC_VCTSXS))
2284    (set (reg:SI VSCR_REGNO) (unspec:SI [(const_int 0)] UNSPEC_SET_VSCR))]
2285   "TARGET_ALTIVEC"
2286   "vctsxs %0,%1,%2"
2287   [(set_attr "type" "vecfloat")])
2289 (define_insn "altivec_vlogefp"
2290   [(set (match_operand:V4SF 0 "register_operand" "=v")
2291         (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "v")]
2292                      UNSPEC_VLOGEFP))]
2293   "TARGET_ALTIVEC"
2294   "vlogefp %0,%1"
2295   [(set_attr "type" "vecfloat")])
2297 (define_insn "altivec_vexptefp"
2298   [(set (match_operand:V4SF 0 "register_operand" "=v")
2299         (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "v")]
2300                      UNSPEC_VEXPTEFP))]
2301   "TARGET_ALTIVEC"
2302   "vexptefp %0,%1"
2303   [(set_attr "type" "vecfloat")])
2305 (define_insn "*altivec_vrsqrtefp"
2306   [(set (match_operand:V4SF 0 "register_operand" "=v")
2307         (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "v")]
2308                      UNSPEC_RSQRT))]
2309   "VECTOR_UNIT_ALTIVEC_P (V4SFmode)"
2310   "vrsqrtefp %0,%1"
2311   [(set_attr "type" "vecfloat")])
2313 (define_insn "altivec_vrefp"
2314   [(set (match_operand:V4SF 0 "register_operand" "=v")
2315         (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "v")]
2316                      UNSPEC_FRES))]
2317   "VECTOR_UNIT_ALTIVEC_P (V4SFmode)"
2318   "vrefp %0,%1"
2319   [(set_attr "type" "vecfloat")])
2321 (define_expand "altivec_copysign_v4sf3"
2322   [(use (match_operand:V4SF 0 "register_operand" ""))
2323    (use (match_operand:V4SF 1 "register_operand" ""))
2324    (use (match_operand:V4SF 2 "register_operand" ""))]
2325   "VECTOR_UNIT_ALTIVEC_P (V4SFmode)"
2326   "
2328   rtx mask = gen_reg_rtx (V4SImode);
2329   rtvec v = rtvec_alloc (4);
2330   unsigned HOST_WIDE_INT mask_val = ((unsigned HOST_WIDE_INT)1) << 31;
2332   RTVEC_ELT (v, 0) = GEN_INT (mask_val);
2333   RTVEC_ELT (v, 1) = GEN_INT (mask_val);
2334   RTVEC_ELT (v, 2) = GEN_INT (mask_val);
2335   RTVEC_ELT (v, 3) = GEN_INT (mask_val);
2337   emit_insn (gen_vec_initv4sisi (mask, gen_rtx_PARALLEL (V4SImode, v)));
2338   emit_insn (gen_vector_select_v4sf (operands[0], operands[1], operands[2],
2339                                      gen_lowpart (V4SFmode, mask)));
2340   DONE;
2343 (define_insn "altivec_vsldoi_<mode>"
2344   [(set (match_operand:VM 0 "register_operand" "=v")
2345         (unspec:VM [(match_operand:VM 1 "register_operand" "v")
2346                     (match_operand:VM 2 "register_operand" "v")
2347                     (match_operand:QI 3 "immediate_operand" "i")]
2348                   UNSPEC_VSLDOI))]
2349   "TARGET_ALTIVEC"
2350   "vsldoi %0,%1,%2,%3"
2351   [(set_attr "type" "vecperm")])
2353 (define_insn "altivec_vupkhs<VU_char>"
2354   [(set (match_operand:VP 0 "register_operand" "=v")
2355         (unspec:VP [(match_operand:<VP_small> 1 "register_operand" "v")]
2356                      UNSPEC_VUNPACK_HI_SIGN))]
2357   "<VI_unit>"
2359   if (VECTOR_ELT_ORDER_BIG)
2360     return "vupkhs<VU_char> %0,%1";
2361   else
2362     return "vupkls<VU_char> %0,%1";
2364   [(set_attr "type" "vecperm")])
2366 (define_insn "*altivec_vupkhs<VU_char>_direct"
2367   [(set (match_operand:VP 0 "register_operand" "=v")
2368         (unspec:VP [(match_operand:<VP_small> 1 "register_operand" "v")]
2369                      UNSPEC_VUNPACK_HI_SIGN_DIRECT))]
2370   "<VI_unit>"
2371   "vupkhs<VU_char> %0,%1"
2372   [(set_attr "type" "vecperm")])
2374 (define_insn "altivec_vupkls<VU_char>"
2375   [(set (match_operand:VP 0 "register_operand" "=v")
2376         (unspec:VP [(match_operand:<VP_small> 1 "register_operand" "v")]
2377                      UNSPEC_VUNPACK_LO_SIGN))]
2378   "<VI_unit>"
2380   if (VECTOR_ELT_ORDER_BIG)
2381     return "vupkls<VU_char> %0,%1";
2382   else
2383     return "vupkhs<VU_char> %0,%1";
2385   [(set_attr "type" "vecperm")])
2387 (define_insn "*altivec_vupkls<VU_char>_direct"
2388   [(set (match_operand:VP 0 "register_operand" "=v")
2389         (unspec:VP [(match_operand:<VP_small> 1 "register_operand" "v")]
2390                      UNSPEC_VUNPACK_LO_SIGN_DIRECT))]
2391   "<VI_unit>"
2392   "vupkls<VU_char> %0,%1"
2393   [(set_attr "type" "vecperm")])
2395 (define_insn "altivec_vupkhpx"
2396   [(set (match_operand:V4SI 0 "register_operand" "=v")
2397         (unspec:V4SI [(match_operand:V8HI 1 "register_operand" "v")]
2398                      UNSPEC_VUPKHPX))]
2399   "TARGET_ALTIVEC"
2401   if (VECTOR_ELT_ORDER_BIG)
2402     return "vupkhpx %0,%1";
2403   else
2404     return "vupklpx %0,%1";
2406   [(set_attr "type" "vecperm")])
2408 (define_insn "altivec_vupklpx"
2409   [(set (match_operand:V4SI 0 "register_operand" "=v")
2410         (unspec:V4SI [(match_operand:V8HI 1 "register_operand" "v")]
2411                      UNSPEC_VUPKLPX))]
2412   "TARGET_ALTIVEC"
2414   if (VECTOR_ELT_ORDER_BIG)
2415     return "vupklpx %0,%1";
2416   else
2417     return "vupkhpx %0,%1";
2419   [(set_attr "type" "vecperm")])
2421 ;; Compare vectors producing a vector result and a predicate, setting CR6 to
2422 ;; indicate a combined status
2423 (define_insn "*altivec_vcmpequ<VI_char>_p"
2424   [(set (reg:CC CR6_REGNO)
2425         (unspec:CC [(eq:CC (match_operand:VI2 1 "register_operand" "v")
2426                            (match_operand:VI2 2 "register_operand" "v"))]
2427                    UNSPEC_PREDICATE))
2428    (set (match_operand:VI2 0 "register_operand" "=v")
2429         (eq:VI2 (match_dup 1)
2430                 (match_dup 2)))]
2431   "<VI_unit>"
2432   "vcmpequ<VI_char>. %0,%1,%2"
2433   [(set_attr "type" "veccmpfx")])
2435 (define_insn "*altivec_vcmpgts<VI_char>_p"
2436   [(set (reg:CC CR6_REGNO)
2437         (unspec:CC [(gt:CC (match_operand:VI2 1 "register_operand" "v")
2438                            (match_operand:VI2 2 "register_operand" "v"))]
2439                    UNSPEC_PREDICATE))
2440    (set (match_operand:VI2 0 "register_operand" "=v")
2441         (gt:VI2 (match_dup 1)
2442                 (match_dup 2)))]
2443   "<VI_unit>"
2444   "vcmpgts<VI_char>. %0,%1,%2"
2445   [(set_attr "type" "veccmpfx")])
2447 (define_insn "*altivec_vcmpgtu<VI_char>_p"
2448   [(set (reg:CC CR6_REGNO)
2449         (unspec:CC [(gtu:CC (match_operand:VI2 1 "register_operand" "v")
2450                             (match_operand:VI2 2 "register_operand" "v"))]
2451                    UNSPEC_PREDICATE))
2452    (set (match_operand:VI2 0 "register_operand" "=v")
2453         (gtu:VI2 (match_dup 1)
2454                  (match_dup 2)))]
2455   "<VI_unit>"
2456   "vcmpgtu<VI_char>. %0,%1,%2"
2457   [(set_attr "type" "veccmpfx")])
2459 (define_insn "*altivec_vcmpeqfp_p"
2460   [(set (reg:CC CR6_REGNO)
2461         (unspec:CC [(eq:CC (match_operand:V4SF 1 "register_operand" "v")
2462                            (match_operand:V4SF 2 "register_operand" "v"))]
2463                    UNSPEC_PREDICATE))
2464    (set (match_operand:V4SF 0 "register_operand" "=v")
2465         (eq:V4SF (match_dup 1)
2466                  (match_dup 2)))]
2467   "VECTOR_UNIT_ALTIVEC_P (V4SFmode)"
2468   "vcmpeqfp. %0,%1,%2"
2469   [(set_attr "type" "veccmp")])
2471 (define_insn "*altivec_vcmpgtfp_p"
2472   [(set (reg:CC CR6_REGNO)
2473         (unspec:CC [(gt:CC (match_operand:V4SF 1 "register_operand" "v")
2474                            (match_operand:V4SF 2 "register_operand" "v"))]
2475                    UNSPEC_PREDICATE))
2476    (set (match_operand:V4SF 0 "register_operand" "=v")
2477         (gt:V4SF (match_dup 1)
2478                  (match_dup 2)))]
2479   "VECTOR_UNIT_ALTIVEC_P (V4SFmode)"
2480   "vcmpgtfp. %0,%1,%2"
2481   [(set_attr "type" "veccmp")])
2483 (define_insn "*altivec_vcmpgefp_p"
2484   [(set (reg:CC CR6_REGNO)
2485         (unspec:CC [(ge:CC (match_operand:V4SF 1 "register_operand" "v")
2486                            (match_operand:V4SF 2 "register_operand" "v"))]
2487                    UNSPEC_PREDICATE))
2488    (set (match_operand:V4SF 0 "register_operand" "=v")
2489         (ge:V4SF (match_dup 1)
2490                  (match_dup 2)))]
2491   "VECTOR_UNIT_ALTIVEC_P (V4SFmode)"
2492   "vcmpgefp. %0,%1,%2"
2493   [(set_attr "type" "veccmp")])
2495 (define_insn "altivec_vcmpbfp_p"
2496   [(set (reg:CC CR6_REGNO)
2497         (unspec:CC [(match_operand:V4SF 1 "register_operand" "v")
2498                     (match_operand:V4SF 2 "register_operand" "v")]
2499                    UNSPEC_VCMPBFP))
2500    (set (match_operand:V4SF 0 "register_operand" "=v")
2501         (unspec:V4SF [(match_dup 1)
2502                       (match_dup 2)] 
2503                       UNSPEC_VCMPBFP))]
2504   "VECTOR_UNIT_ALTIVEC_OR_VSX_P (V4SFmode)"
2505   "vcmpbfp. %0,%1,%2"
2506   [(set_attr "type" "veccmp")])
2508 (define_insn "altivec_mtvscr"
2509   [(set (reg:SI VSCR_REGNO)
2510         (unspec_volatile:SI
2511          [(match_operand:V4SI 0 "register_operand" "v")] UNSPECV_MTVSCR))]
2512   "TARGET_ALTIVEC"
2513   "mtvscr %0"
2514   [(set_attr "type" "vecsimple")])
2516 (define_insn "altivec_mfvscr"
2517   [(set (match_operand:V8HI 0 "register_operand" "=v")
2518         (unspec_volatile:V8HI [(reg:SI VSCR_REGNO)] UNSPECV_MFVSCR))]
2519   "TARGET_ALTIVEC"
2520   "mfvscr %0"
2521   [(set_attr "type" "vecsimple")])
2523 (define_insn "altivec_dssall"
2524   [(unspec_volatile [(const_int 0)] UNSPECV_DSSALL)]
2525   "TARGET_ALTIVEC"
2526   "dssall"
2527   [(set_attr "type" "vecsimple")])
2529 (define_insn "altivec_dss"
2530   [(unspec_volatile [(match_operand:QI 0 "immediate_operand" "i")]
2531                     UNSPECV_DSS)]
2532   "TARGET_ALTIVEC"
2533   "dss %0"
2534   [(set_attr "type" "vecsimple")])
2536 (define_insn "altivec_dst"
2537   [(unspec [(match_operand 0 "register_operand" "b")
2538             (match_operand:SI 1 "register_operand" "r")
2539             (match_operand:QI 2 "immediate_operand" "i")] UNSPEC_DST)]
2540   "TARGET_ALTIVEC && GET_MODE (operands[0]) == Pmode"
2541   "dst %0,%1,%2"
2542   [(set_attr "type" "vecsimple")])
2544 (define_insn "altivec_dstt"
2545   [(unspec [(match_operand 0 "register_operand" "b")
2546             (match_operand:SI 1 "register_operand" "r")
2547             (match_operand:QI 2 "immediate_operand" "i")] UNSPEC_DSTT)]
2548   "TARGET_ALTIVEC && GET_MODE (operands[0]) == Pmode"
2549   "dstt %0,%1,%2"
2550   [(set_attr "type" "vecsimple")])
2552 (define_insn "altivec_dstst"
2553   [(unspec [(match_operand 0 "register_operand" "b")
2554             (match_operand:SI 1 "register_operand" "r")
2555             (match_operand:QI 2 "immediate_operand" "i")] UNSPEC_DSTST)]
2556   "TARGET_ALTIVEC && GET_MODE (operands[0]) == Pmode"
2557   "dstst %0,%1,%2"
2558   [(set_attr "type" "vecsimple")])
2560 (define_insn "altivec_dststt"
2561   [(unspec [(match_operand 0 "register_operand" "b")
2562             (match_operand:SI 1 "register_operand" "r")
2563             (match_operand:QI 2 "immediate_operand" "i")] UNSPEC_DSTSTT)]
2564   "TARGET_ALTIVEC && GET_MODE (operands[0]) == Pmode"
2565   "dststt %0,%1,%2"
2566   [(set_attr "type" "vecsimple")])
2568 (define_expand "altivec_lvsl"
2569   [(use (match_operand:V16QI 0 "register_operand" ""))
2570    (use (match_operand:V16QI 1 "memory_operand" ""))]
2571   "TARGET_ALTIVEC"
2573   if (VECTOR_ELT_ORDER_BIG)
2574     emit_insn (gen_altivec_lvsl_direct (operands[0], operands[1]));
2575   else
2576     {
2577       rtx mask, constv, vperm;
2578       mask = gen_reg_rtx (V16QImode);
2579       emit_insn (gen_altivec_lvsl_direct (mask, operands[1]));
2580       constv = gen_const_vec_series (V16QImode, const0_rtx, const1_rtx);
2581       constv = force_reg (V16QImode, constv);
2582       vperm = gen_rtx_UNSPEC (V16QImode, gen_rtvec (3, mask, mask, constv),
2583                               UNSPEC_VPERM);
2584       emit_insn (gen_rtx_SET (operands[0], vperm));
2585     }
2586   DONE;
2589 (define_insn "altivec_lvsl_reg"
2590   [(set (match_operand:V16QI 0 "altivec_register_operand" "=v")
2591         (unspec:V16QI
2592         [(match_operand:DI 1 "gpc_reg_operand" "b")]
2593         UNSPEC_LVSL_REG))]
2594   "TARGET_ALTIVEC"
2595   "lvsl %0,0,%1"
2596   [(set_attr "type" "vecload")])
2598 (define_insn "altivec_lvsl_direct"
2599   [(set (match_operand:V16QI 0 "register_operand" "=v")
2600         (unspec:V16QI [(match_operand:V16QI 1 "memory_operand" "Z")]
2601                       UNSPEC_LVSL))]
2602   "TARGET_ALTIVEC"
2603   "lvsl %0,%y1"
2604   [(set_attr "type" "vecload")])
2606 (define_expand "altivec_lvsr"
2607   [(use (match_operand:V16QI 0 "altivec_register_operand"))
2608    (use (match_operand:V16QI 1 "memory_operand"))]
2609   "TARGET_ALTIVEC"
2611   if (VECTOR_ELT_ORDER_BIG)
2612     emit_insn (gen_altivec_lvsr_direct (operands[0], operands[1]));
2613   else
2614     {
2615       rtx mask, constv, vperm;
2616       mask = gen_reg_rtx (V16QImode);
2617       emit_insn (gen_altivec_lvsr_direct (mask, operands[1]));
2618       constv = gen_const_vec_series (V16QImode, const0_rtx, const1_rtx);
2619       constv = force_reg (V16QImode, constv);
2620       vperm = gen_rtx_UNSPEC (V16QImode, gen_rtvec (3, mask, mask, constv),
2621                               UNSPEC_VPERM);
2622       emit_insn (gen_rtx_SET (operands[0], vperm));
2623     }
2624   DONE;
2627 (define_insn "altivec_lvsr_reg"
2628   [(set (match_operand:V16QI 0 "altivec_register_operand" "=v")
2629        (unspec:V16QI
2630        [(match_operand:DI 1 "gpc_reg_operand" "b")]
2631        UNSPEC_LVSR_REG))]
2632   "TARGET_ALTIVEC"
2633   "lvsr %0,0,%1"
2634   [(set_attr "type" "vecload")])
2636 (define_insn "altivec_lvsr_direct"
2637   [(set (match_operand:V16QI 0 "register_operand" "=v")
2638         (unspec:V16QI [(match_operand:V16QI 1 "memory_operand" "Z")]
2639                       UNSPEC_LVSR))]
2640   "TARGET_ALTIVEC"
2641   "lvsr %0,%y1"
2642   [(set_attr "type" "vecload")])
2644 (define_expand "build_vector_mask_for_load"
2645   [(set (match_operand:V16QI 0 "register_operand" "")
2646         (unspec:V16QI [(match_operand 1 "memory_operand" "")] UNSPEC_LVSR))]
2647   "TARGET_ALTIVEC"
2648   "
2650   rtx addr;
2651   rtx temp;
2653   gcc_assert (GET_CODE (operands[1]) == MEM);
2655   addr = XEXP (operands[1], 0);
2656   temp = gen_reg_rtx (GET_MODE (addr));
2657   emit_insn (gen_rtx_SET (temp, gen_rtx_NEG (GET_MODE (addr), addr)));
2658   emit_insn (gen_altivec_lvsr (operands[0], 
2659                                replace_equiv_address (operands[1], temp)));
2660   DONE;
2663 ;; Parallel some of the LVE* and STV*'s with unspecs because some have
2664 ;; identical rtl but different instructions-- and gcc gets confused.
2666 (define_expand "altivec_lve<VI_char>x"
2667   [(parallel
2668     [(set (match_operand:VI 0 "register_operand" "=v")
2669           (match_operand:VI 1 "memory_operand" "Z"))
2670      (unspec [(const_int 0)] UNSPEC_LVE)])]
2671   "TARGET_ALTIVEC"
2673   if (!BYTES_BIG_ENDIAN && VECTOR_ELT_ORDER_BIG)
2674     {
2675       altivec_expand_lvx_be (operands[0], operands[1], <MODE>mode, UNSPEC_LVE);
2676       DONE;
2677     }
2680 (define_insn "*altivec_lve<VI_char>x_internal"
2681   [(parallel
2682     [(set (match_operand:VI 0 "register_operand" "=v")
2683           (match_operand:VI 1 "memory_operand" "Z"))
2684      (unspec [(const_int 0)] UNSPEC_LVE)])]
2685   "TARGET_ALTIVEC"
2686   "lve<VI_char>x %0,%y1"
2687   [(set_attr "type" "vecload")])
2689 (define_insn "*altivec_lvesfx"
2690   [(parallel
2691     [(set (match_operand:V4SF 0 "register_operand" "=v")
2692           (match_operand:V4SF 1 "memory_operand" "Z"))
2693      (unspec [(const_int 0)] UNSPEC_LVE)])]
2694   "TARGET_ALTIVEC"
2695   "lvewx %0,%y1"
2696   [(set_attr "type" "vecload")])
2698 (define_expand "altivec_lvxl_<mode>"
2699   [(parallel
2700     [(set (match_operand:VM2 0 "register_operand" "=v")
2701           (match_operand:VM2 1 "memory_operand" "Z"))
2702      (unspec [(const_int 0)] UNSPEC_SET_VSCR)])]
2703   "TARGET_ALTIVEC"
2705   if (!BYTES_BIG_ENDIAN && VECTOR_ELT_ORDER_BIG)
2706     {
2707       altivec_expand_lvx_be (operands[0], operands[1], <MODE>mode, UNSPEC_SET_VSCR);
2708       DONE;
2709     }
2712 (define_insn "*altivec_lvxl_<mode>_internal"
2713   [(parallel
2714     [(set (match_operand:VM2 0 "register_operand" "=v")
2715           (match_operand:VM2 1 "memory_operand" "Z"))
2716      (unspec [(const_int 0)] UNSPEC_SET_VSCR)])]
2717   "TARGET_ALTIVEC"
2718   "lvxl %0,%y1"
2719   [(set_attr "type" "vecload")])
2721 ; This version of lvx is used only in cases where we need to force an lvx
2722 ; over any other load, and we don't care about losing CSE opportunities.
2723 ; Its primary use is for prologue register saves.
2724 (define_insn "altivec_lvx_<mode>_internal"
2725   [(parallel
2726     [(set (match_operand:VM2 0 "register_operand" "=v")
2727           (match_operand:VM2 1 "memory_operand" "Z"))
2728      (unspec [(const_int 0)] UNSPEC_LVX)])]
2729   "TARGET_ALTIVEC"
2730   "lvx %0,%y1"
2731   [(set_attr "type" "vecload")])
2733 ; The next two patterns embody what lvx should usually look like.
2734 (define_insn "altivec_lvx_<mode>_2op"
2735   [(set (match_operand:VM2 0 "register_operand" "=v")
2736         (mem:VM2 (and:DI (plus:DI (match_operand:DI 1 "register_operand" "b")
2737                                   (match_operand:DI 2 "register_operand" "r"))
2738                          (const_int -16))))]
2739   "TARGET_ALTIVEC && TARGET_64BIT"
2740   "lvx %0,%1,%2"
2741   [(set_attr "type" "vecload")])
2743 (define_insn "altivec_lvx_<mode>_1op"
2744   [(set (match_operand:VM2 0 "register_operand" "=v")
2745         (mem:VM2 (and:DI (match_operand:DI 1 "register_operand" "r")
2746                          (const_int -16))))]
2747   "TARGET_ALTIVEC && TARGET_64BIT"
2748   "lvx %0,0,%1"
2749   [(set_attr "type" "vecload")])
2751 ; 32-bit versions of the above.
2752 (define_insn "altivec_lvx_<mode>_2op_si"
2753   [(set (match_operand:VM2 0 "register_operand" "=v")
2754         (mem:VM2 (and:SI (plus:SI (match_operand:SI 1 "register_operand" "b")
2755                                   (match_operand:SI 2 "register_operand" "r"))
2756                          (const_int -16))))]
2757   "TARGET_ALTIVEC && TARGET_32BIT"
2758   "lvx %0,%1,%2"
2759   [(set_attr "type" "vecload")])
2761 (define_insn "altivec_lvx_<mode>_1op_si"
2762   [(set (match_operand:VM2 0 "register_operand" "=v")
2763         (mem:VM2 (and:SI (match_operand:SI 1 "register_operand" "r")
2764                          (const_int -16))))]
2765   "TARGET_ALTIVEC && TARGET_32BIT"
2766   "lvx %0,0,%1"
2767   [(set_attr "type" "vecload")])
2769 ; This version of stvx is used only in cases where we need to force an stvx
2770 ; over any other store, and we don't care about losing CSE opportunities.
2771 ; Its primary use is for epilogue register restores.
2772 (define_insn "altivec_stvx_<mode>_internal"
2773   [(parallel
2774     [(set (match_operand:VM2 0 "memory_operand" "=Z")
2775           (match_operand:VM2 1 "register_operand" "v"))
2776      (unspec [(const_int 0)] UNSPEC_STVX)])]
2777   "TARGET_ALTIVEC"
2778   "stvx %1,%y0"
2779   [(set_attr "type" "vecstore")])
2781 ; The next two patterns embody what stvx should usually look like.
2782 (define_insn "altivec_stvx_<mode>_2op"
2783   [(set (mem:VM2 (and:DI (plus:DI (match_operand:DI 1 "register_operand" "b")
2784                                   (match_operand:DI 2 "register_operand" "r"))
2785                          (const_int -16)))
2786         (match_operand:VM2 0 "register_operand" "v"))]
2787   "TARGET_ALTIVEC && TARGET_64BIT"
2788   "stvx %0,%1,%2"
2789   [(set_attr "type" "vecstore")])
2791 (define_insn "altivec_stvx_<mode>_1op"
2792   [(set (mem:VM2 (and:DI (match_operand:DI 1 "register_operand" "r")
2793                          (const_int -16)))
2794         (match_operand:VM2 0 "register_operand" "v"))]
2795   "TARGET_ALTIVEC && TARGET_64BIT"
2796   "stvx %0,0,%1"
2797   [(set_attr "type" "vecstore")])
2799 ; 32-bit versions of the above.
2800 (define_insn "altivec_stvx_<mode>_2op_si"
2801   [(set (mem:VM2 (and:SI (plus:SI (match_operand:SI 1 "register_operand" "b")
2802                                   (match_operand:SI 2 "register_operand" "r"))
2803                          (const_int -16)))
2804         (match_operand:VM2 0 "register_operand" "v"))]
2805   "TARGET_ALTIVEC && TARGET_32BIT"
2806   "stvx %0,%1,%2"
2807   [(set_attr "type" "vecstore")])
2809 (define_insn "altivec_stvx_<mode>_1op_si"
2810   [(set (mem:VM2 (and:SI (match_operand:SI 1 "register_operand" "r")
2811                          (const_int -16)))
2812         (match_operand:VM2 0 "register_operand" "v"))]
2813   "TARGET_ALTIVEC && TARGET_32BIT"
2814   "stvx %0,0,%1"
2815   [(set_attr "type" "vecstore")])
2817 (define_expand "altivec_stvxl_<mode>"
2818   [(parallel
2819     [(set (match_operand:VM2 0 "memory_operand" "=Z")
2820           (match_operand:VM2 1 "register_operand" "v"))
2821      (unspec [(const_int 0)] UNSPEC_STVXL)])]
2822   "TARGET_ALTIVEC"
2824   if (!BYTES_BIG_ENDIAN && VECTOR_ELT_ORDER_BIG)
2825     {
2826       altivec_expand_stvx_be (operands[0], operands[1], <MODE>mode, UNSPEC_STVXL);
2827       DONE;
2828     }
2831 (define_insn "*altivec_stvxl_<mode>_internal"
2832   [(parallel
2833     [(set (match_operand:VM2 0 "memory_operand" "=Z")
2834           (match_operand:VM2 1 "register_operand" "v"))
2835      (unspec [(const_int 0)] UNSPEC_STVXL)])]
2836   "TARGET_ALTIVEC"
2837   "stvxl %1,%y0"
2838   [(set_attr "type" "vecstore")])
2840 (define_expand "altivec_stve<VI_char>x"
2841   [(set (match_operand:<VI_scalar> 0 "memory_operand" "=Z")
2842         (unspec:<VI_scalar> [(match_operand:VI 1 "register_operand" "v")] UNSPEC_STVE))]
2843   "TARGET_ALTIVEC"
2845   if (!BYTES_BIG_ENDIAN && VECTOR_ELT_ORDER_BIG)
2846     {
2847       altivec_expand_stvex_be (operands[0], operands[1], <MODE>mode, UNSPEC_STVE);
2848       DONE;
2849     }
2852 (define_insn "*altivec_stve<VI_char>x_internal"
2853   [(set (match_operand:<VI_scalar> 0 "memory_operand" "=Z")
2854         (unspec:<VI_scalar> [(match_operand:VI 1 "register_operand" "v")] UNSPEC_STVE))]
2855   "TARGET_ALTIVEC"
2856   "stve<VI_char>x %1,%y0"
2857   [(set_attr "type" "vecstore")])
2859 (define_insn "*altivec_stvesfx"
2860   [(set (match_operand:SF 0 "memory_operand" "=Z")
2861         (unspec:SF [(match_operand:V4SF 1 "register_operand" "v")] UNSPEC_STVE))]
2862   "TARGET_ALTIVEC"
2863   "stvewx %1,%y0"
2864   [(set_attr "type" "vecstore")])
2866 ;; Generate doublee
2867 ;; signed int/float to double convert words 0 and 2
2868 (define_expand "doublee<mode>2"
2869   [(set (match_operand:V2DF 0 "register_operand" "=v")
2870         (match_operand:VSX_W 1 "register_operand" "v"))]
2871   "TARGET_VSX"
2873   machine_mode op_mode = GET_MODE (operands[1]);
2875   if (VECTOR_ELT_ORDER_BIG)
2876     {
2877       /* Big endian word numbering for words in operand is 0 1 2 3.
2878          Input words 0 and 2 are where they need to be.  */
2879       emit_insn (gen_vsx_xvcv<VS_sxwsp>dp (operands[0], operands[1]));
2880     }
2881   else
2882     {
2883       /* Little endian word numbering for operand is 3 2 1 0.
2884          take (operand[1] operand[1]) and shift left one word
2885          3 2 1 0    3 2 1 0  =>  2 1 0 3
2886          Input words 2 and 0 are now where they need to be for the
2887          conversion.  */
2888       rtx rtx_tmp;
2889       rtx rtx_val = GEN_INT (1);
2891       rtx_tmp = gen_reg_rtx (op_mode);
2892       emit_insn (gen_vsx_xxsldwi_<mode> (rtx_tmp, operands[1],
2893                                          operands[1], rtx_val));
2894       emit_insn (gen_vsx_xvcv<VS_sxwsp>dp (operands[0], rtx_tmp));
2895     }
2896   DONE;
2898   [(set_attr "type" "veccomplex")])
2900 ;; Generate unsdoublee
2901 ;; unsigned int to double convert words 0 and 2
2902 (define_expand "unsdoubleev4si2"
2903   [(set (match_operand:V2DF 0 "register_operand" "=v")
2904         (match_operand:V4SI 1 "register_operand" "v"))]
2905   "TARGET_VSX"
2907   if (VECTOR_ELT_ORDER_BIG)
2908     {
2909       /* Big endian word numbering for words in operand is 0 1 2 3.
2910          Input words 0 and 2 are where they need to be.  */
2911       emit_insn (gen_vsx_xvcvuxwdp (operands[0], operands[1]));
2912     }
2913   else
2914     {
2915       /* Little endian word numbering for operand is 3 2 1 0.
2916          take (operand[1] operand[1]) and shift left one word
2917          3 2 1 0    3 2 1 0  =>   2 1 0 3
2918          Input words 2 and 0 are now where they need to be for the
2919          conversion.  */
2920       rtx rtx_tmp;
2921       rtx rtx_val = GEN_INT (1);
2923       rtx_tmp = gen_reg_rtx (V4SImode);
2924       emit_insn (gen_vsx_xxsldwi_v4si (rtx_tmp, operands[1],
2925                                        operands[1], rtx_val));
2926       emit_insn (gen_vsx_xvcvuxwdp (operands[0], rtx_tmp));
2927     }
2928   DONE;
2930   [(set_attr "type" "veccomplex")])
2932 ;; Generate doubleov
2933 ;; signed int/float to double convert words 1 and 3
2934 (define_expand "doubleo<mode>2"
2935   [(set (match_operand:V2DF 0 "register_operand" "=v")
2936         (match_operand:VSX_W 1 "register_operand" "v"))]
2937   "TARGET_VSX"
2939   machine_mode op_mode = GET_MODE (operands[1]);
2941   if (VECTOR_ELT_ORDER_BIG)
2942     {
2943       /* Big endian word numbering for words in operand is 0 1 2 3.
2944          take (operand[1] operand[1]) and shift left one word
2945          0 1 2 3    0 1 2 3  =>  1 2 3 0
2946          Input words 1 and 3 are now where they need to be for the
2947          conversion.  */
2948       rtx rtx_tmp;
2949       rtx rtx_val = GEN_INT (1);
2951       rtx_tmp = gen_reg_rtx (op_mode);
2952       emit_insn (gen_vsx_xxsldwi_<mode> (rtx_tmp, operands[1],
2953                                          operands[1], rtx_val));
2954       emit_insn (gen_vsx_xvcv<VS_sxwsp>dp (operands[0], rtx_tmp));
2955     }
2956   else
2957     {
2958       /* Little endian word numbering for operand is 3 2 1 0.
2959          Input words 3 and 1 are where they need to be.  */
2960       emit_insn (gen_vsx_xvcv<VS_sxwsp>dp (operands[0], operands[1]));
2961     }
2962   DONE;
2964   [(set_attr "type" "veccomplex")])
2966 ;; Generate unsdoubleov
2967 ;; unsigned int to double convert words 1 and 3
2968 (define_expand "unsdoubleov4si2"
2969   [(set (match_operand:V2DF 0 "register_operand" "=v")
2970         (match_operand:V4SI 1 "register_operand" "v"))]
2971   "TARGET_VSX"
2973   if (VECTOR_ELT_ORDER_BIG)
2974     {
2975       /* Big endian word numbering for words in operand is 0 1 2 3.
2976          take (operand[1] operand[1]) and shift left one word
2977          0 1 2 3    0 1 2 3  =>  1 2 3 0
2978          Input words 1 and 3 are now where they need to be for the
2979          conversion.  */
2980       rtx rtx_tmp;
2981       rtx rtx_val = GEN_INT (1);
2983       rtx_tmp = gen_reg_rtx (V4SImode);
2984       emit_insn (gen_vsx_xxsldwi_v4si (rtx_tmp, operands[1],
2985                                        operands[1], rtx_val));
2986       emit_insn (gen_vsx_xvcvuxwdp (operands[0], rtx_tmp));
2987     }
2988   else
2989     {
2990       /* Want to convert the words 1 and 3.
2991          Little endian word numbering for operand is 3 2 1 0.
2992          Input words 3 and 1 are where they need to be.  */
2993       emit_insn (gen_vsx_xvcvuxwdp (operands[0], operands[1]));
2994     }
2995   DONE;
2997   [(set_attr "type" "veccomplex")])
2999 ;; Generate doublehv
3000 ;; signed int/float to double convert words 0 and 1
3001 (define_expand "doubleh<mode>2"
3002   [(set (match_operand:V2DF 0 "register_operand" "=v")
3003         (match_operand:VSX_W 1 "register_operand" "v"))]
3004   "TARGET_VSX"
3006   rtx rtx_tmp;
3007   rtx rtx_val;
3009   machine_mode op_mode = GET_MODE (operands[1]);
3010   rtx_tmp = gen_reg_rtx (op_mode);
3012   if (VECTOR_ELT_ORDER_BIG)
3013     {
3014       /* Big endian word numbering for words in operand is 0 1 2 3.
3015          Shift operand left one word, rtx_tmp word order is now 1 2 3 0.
3016          take (rts_tmp operand[1]) and shift left three words
3017          1 2 3 0  0 1 2 3 => 0 0 1 2
3018          Input words 0 and 1 are now where they need to be for the
3019          conversion.  */
3020       rtx_val = GEN_INT (1);
3021       emit_insn (gen_vsx_xxsldwi_<mode> (rtx_tmp, operands[1],
3022                                          operands[1], rtx_val));
3024       rtx_val = GEN_INT (3);
3025       emit_insn (gen_vsx_xxsldwi_<mode> (rtx_tmp, rtx_tmp,
3026                                          operands[1], rtx_val));
3027       emit_insn (gen_vsx_xvcv<VS_sxwsp>dp (operands[0], rtx_tmp));
3028     }
3029   else
3030     {
3031       /* Little endian word numbering for operand is 3 2 1 0.
3032          Shift operand left three words, rtx_tmp word order is now 0 3 2 1.
3033          take (operand[1] rts_tmp) and shift left two words
3034          3 2 1 0  0 3 2 1   =>  1 0 0 3
3035          Input words 0 and 1 are now where they need to be for the
3036          conversion.  */
3037       rtx_val = GEN_INT (3);
3038       emit_insn (gen_vsx_xxsldwi_<mode> (rtx_tmp, operands[1],
3039                                          operands[1], rtx_val));
3041       rtx_val = GEN_INT (2);
3042       emit_insn (gen_vsx_xxsldwi_<mode> (rtx_tmp, operands[1],
3043                                          rtx_tmp, rtx_val));
3044       emit_insn (gen_vsx_xvcv<VS_sxwsp>dp (operands[0], rtx_tmp));
3045     }
3046   DONE;
3048   [(set_attr "type" "veccomplex")])
3050 ;; Generate unsdoublehv
3051 ;; unsigned int to double convert words 0 and 1
3052 (define_expand "unsdoublehv4si2"
3053   [(set (match_operand:V2DF 0 "register_operand" "=v")
3054         (match_operand:V4SI 1 "register_operand" "v"))]
3055   "TARGET_VSX"
3057   rtx rtx_tmp = gen_reg_rtx (V4SImode);
3058   rtx rtx_val = GEN_INT (12);
3060   if (VECTOR_ELT_ORDER_BIG)
3061     {
3062       /* Big endian word numbering for words in operand is 0 1 2 3.
3063          Shift operand left one word, rtx_tmp word order is now 1 2 3 0.
3064          take (rts_tmp operand[1]) and shift left three words
3065          1 2 3 0  0 1 2 3 => 0 0 1 2
3066          Input words 0 and 1 are now where they need to be for the
3067          conversion.  */
3068       rtx_val = GEN_INT (1);
3069       emit_insn (gen_vsx_xxsldwi_v4si (rtx_tmp, operands[1],
3070                                        operands[1], rtx_val));
3072       rtx_val = GEN_INT (3);
3073       emit_insn (gen_vsx_xxsldwi_v4si (rtx_tmp, rtx_tmp,
3074                                        operands[1], rtx_val));
3075       emit_insn (gen_vsx_xvcvuxwdp (operands[0], rtx_tmp));
3076     }
3077   else
3078     {
3079       /* Little endian word numbering for operand is 3 2 1 0.
3080          Shift operand left three words, rtx_tmp word order is now 0 3 2 1.
3081          take (operand[1] rts_tmp) and shift left two words
3082          3 2 1 0   0 3 2 1  =>   1 0 0 3
3083          Input words 1 and 0 are now where they need to be for the
3084          conversion.  */
3085       rtx_val = GEN_INT (3);
3087       rtx_tmp = gen_reg_rtx (V4SImode);
3088       emit_insn (gen_vsx_xxsldwi_v4si (rtx_tmp, operands[1],
3089                                        operands[1], rtx_val));
3091       rtx_val = GEN_INT (2);
3092       emit_insn (gen_vsx_xxsldwi_v4si (rtx_tmp, operands[1],
3093                                        rtx_tmp, rtx_val));
3094       emit_insn (gen_vsx_xvcvuxwdp (operands[0], rtx_tmp));
3095     }
3096   DONE;
3098   [(set_attr "type" "veccomplex")])
3100 ;; Generate doublelv
3101 ;; signed int/float to double convert words 2 and 3
3102 (define_expand "doublel<mode>2"
3103   [(set (match_operand:V2DF 0 "register_operand" "=v")
3104         (match_operand:VSX_W 1 "register_operand" "v"))]
3105   "TARGET_VSX"
3107   rtx rtx_tmp;
3108   rtx rtx_val = GEN_INT (3);
3110   machine_mode op_mode = GET_MODE (operands[1]);
3111   rtx_tmp = gen_reg_rtx (op_mode);
3113   if (VECTOR_ELT_ORDER_BIG)
3114     {
3115       /* Big endian word numbering for operand is 0 1 2 3.
3116          Shift operand left three words, rtx_tmp word order is now 3 0 1 2.
3117          take (operand[1] rtx_tmp) and shift left two words
3118          0 1 2 3   3 0 1 2  =>  2 3 3 0
3119          now use convert instruction to convert word 2 and 3 in the
3120          input vector.  */
3121       rtx_val = GEN_INT (3);
3122       emit_insn (gen_vsx_xxsldwi_<mode> (rtx_tmp, operands[1],
3123                                          operands[1], rtx_val));
3125       rtx_val = GEN_INT (2);
3126       emit_insn (gen_vsx_xxsldwi_<mode> (rtx_tmp, operands[1],
3127                                          rtx_tmp, rtx_val));
3128       emit_insn (gen_vsx_xvcv<VS_sxwsp>dp (operands[0], rtx_tmp));
3129     }
3130   else
3131     {
3132       /* Little endian word numbering for operand is 3 2 1 0.
3133          Shift operand left one word, rtx_tmp word order is now  2 1 0 3.
3134          take (rtx_tmp operand[1]) and shift left three words
3135          2 1 0 3  3 2 1 0  =>  3 3 2 1
3136          now use convert instruction to convert word 3 and 2 in the
3137          input vector.  */
3138       rtx_val = GEN_INT (1);
3139       emit_insn (gen_vsx_xxsldwi_<mode> (rtx_tmp, operands[1],
3140                                          operands[1], rtx_val));
3142       rtx_val = GEN_INT (3);
3143       emit_insn (gen_vsx_xxsldwi_<mode> (rtx_tmp, rtx_tmp,
3144                                          operands[1], rtx_val));
3145       emit_insn (gen_vsx_xvcv<VS_sxwsp>dp (operands[0], rtx_tmp));
3146     }
3147   DONE;
3149   [(set_attr "type" "veccomplex")])
3151 ;; Generate unsdoublelv
3152 ;; unsigned int to double convert convert 2 and 3
3153 (define_expand "unsdoublelv4si2"
3154   [(set (match_operand:V2DF 0 "register_operand" "=v")
3155         (match_operand:V4SI 1 "register_operand" "v"))]
3156   "TARGET_VSX"
3158   rtx rtx_tmp = gen_reg_rtx (V4SImode);
3159   rtx rtx_val = GEN_INT (12);
3161   if (VECTOR_ELT_ORDER_BIG)
3162     {
3163       /* Big endian word numbering for operand is 0 1 2 3.
3164          Shift operand left three words, rtx_tmp word order is now 3 0 1 2.
3165          take (operand[1] rtx_tmp) and shift left two words
3166          0 1 2 3   3 0 1 2  =>  2 3 3 0
3167          now use convert instruction to convert word 2 and 3 in the
3168          input vector.  */
3169       rtx_val = GEN_INT (3);
3170       emit_insn (gen_vsx_xxsldwi_v4si (rtx_tmp, operands[1],
3171                                        operands[1], rtx_val));
3173       rtx_val = GEN_INT (2);
3174       emit_insn (gen_vsx_xxsldwi_v4si (rtx_tmp, operands[1],
3175                                        rtx_tmp, rtx_val));
3176       emit_insn (gen_vsx_xvcvuxwdp (operands[0], rtx_tmp));
3177     }
3178   else
3179     {
3180       /* Little endian word numbering for operand is 3 2 1 0.
3181          Shift operand left one word, rtx_tmp word order is now 2 1 0 3.
3182          take (rtx_tmp operand[1]) and shift left three words
3183          2 1 0 3  3 2 1 0  =>   3 3 2 1
3184          now use convert instruction to convert word 3 and 2 in the
3185          input vector.  */
3186       rtx_val = GEN_INT (1);
3187       emit_insn (gen_vsx_xxsldwi_v4si (rtx_tmp,
3188       operands[1], operands[1], rtx_val));
3190       rtx_val = GEN_INT (3);
3191       emit_insn (gen_vsx_xxsldwi_v4si (rtx_tmp, rtx_tmp,
3192                                        operands[1], rtx_val));
3193       emit_insn (gen_vsx_xvcvuxwdp (operands[0], rtx_tmp));
3194     }
3195   DONE;
3197   [(set_attr "type" "veccomplex")])
3199 ;; Generate two vector F32 converted to packed vector I16 vector
3200 (define_expand "convert_4f32_8i16"
3201   [(set (match_operand:V8HI 0 "register_operand" "=v")
3202         (unspec:V8HI [(match_operand:V4SF 1 "register_operand" "v")
3203                       (match_operand:V4SF 2 "register_operand" "v")]
3204                      UNSPEC_CONVERT_4F32_8I16))]
3205   "TARGET_P9_VECTOR"
3207   rtx rtx_tmp_hi = gen_reg_rtx (V4SImode);
3208   rtx rtx_tmp_lo = gen_reg_rtx (V4SImode);
3210   emit_insn (gen_altivec_vctuxs (rtx_tmp_hi, operands[1], const0_rtx));
3211   emit_insn (gen_altivec_vctuxs (rtx_tmp_lo, operands[2], const0_rtx));
3212   emit_insn (gen_altivec_vpkswss (operands[0], rtx_tmp_hi, rtx_tmp_lo));
3213   DONE;
3216 ;; Generate
3217 ;;    xxlxor/vxor SCRATCH0,SCRATCH0,SCRATCH0
3218 ;;    vsubu?m SCRATCH2,SCRATCH1,%1
3219 ;;    vmaxs? %0,%1,SCRATCH2"
3220 (define_expand "abs<mode>2"
3221   [(set (match_dup 2) (match_dup 3))
3222    (set (match_dup 4)
3223         (minus:VI2 (match_dup 2)
3224                    (match_operand:VI2 1 "register_operand" "v")))
3225    (set (match_operand:VI2 0 "register_operand" "=v")
3226         (smax:VI2 (match_dup 1) (match_dup 4)))]
3227   "<VI_unit>"
3229   operands[2] = gen_reg_rtx (<MODE>mode);
3230   operands[3] = CONST0_RTX (<MODE>mode);
3231   operands[4] = gen_reg_rtx (<MODE>mode);
3234 ;; Generate
3235 ;;    vspltisw SCRATCH1,0
3236 ;;    vsubu?m SCRATCH2,SCRATCH1,%1
3237 ;;    vmins? %0,%1,SCRATCH2"
3238 (define_expand "nabs<mode>2"
3239   [(set (match_dup 2) (match_dup 3))
3240    (set (match_dup 4)
3241         (minus:VI2 (match_dup 2)
3242                    (match_operand:VI2 1 "register_operand" "v")))
3243    (set (match_operand:VI2 0 "register_operand" "=v")
3244         (smin:VI2 (match_dup 1) (match_dup 4)))]
3245   "<VI_unit>"
3247   operands[2] = gen_reg_rtx (<MODE>mode);
3248   operands[3] = CONST0_RTX (<MODE>mode);
3249   operands[4] = gen_reg_rtx (<MODE>mode);
3252 ;; Generate
3253 ;;    vspltisw SCRATCH1,-1
3254 ;;    vslw SCRATCH2,SCRATCH1,SCRATCH1
3255 ;;    vandc %0,%1,SCRATCH2
3256 (define_expand "altivec_absv4sf2"
3257   [(set (match_dup 2)
3258         (vec_duplicate:V4SI (const_int -1)))
3259    (set (match_dup 3)
3260         (ashift:V4SI (match_dup 2) (match_dup 2)))
3261    (set (match_operand:V4SF 0 "register_operand" "=v")
3262         (and:V4SF (not:V4SF (subreg:V4SF (match_dup 3) 0))
3263                   (match_operand:V4SF 1 "register_operand" "v")))]
3264   "TARGET_ALTIVEC"
3266   operands[2] = gen_reg_rtx (V4SImode);
3267   operands[3] = gen_reg_rtx (V4SImode);
3270 ;; Generate
3271 ;;    vspltis? SCRATCH0,0
3272 ;;    vsubs?s SCRATCH2,SCRATCH1,%1
3273 ;;    vmaxs? %0,%1,SCRATCH2"
3274 (define_expand "altivec_abss_<mode>"
3275   [(set (match_dup 2) (vec_duplicate:VI (const_int 0)))
3276    (parallel [(set (match_dup 3)
3277                    (unspec:VI [(match_dup 2)
3278                                (match_operand:VI 1 "register_operand" "v")]
3279                               UNSPEC_VSUBS))
3280               (set (reg:SI VSCR_REGNO)
3281                    (unspec:SI [(const_int 0)] UNSPEC_SET_VSCR))])
3282    (set (match_operand:VI 0 "register_operand" "=v")
3283         (smax:VI (match_dup 1) (match_dup 3)))]
3284   "TARGET_ALTIVEC"
3286   operands[2] = gen_reg_rtx (GET_MODE (operands[0]));
3287   operands[3] = gen_reg_rtx (GET_MODE (operands[0]));
3290 (define_expand "reduc_plus_scal_<mode>"
3291   [(set (match_operand:<VI_scalar> 0 "register_operand" "=v")
3292         (unspec:VIshort [(match_operand:VIshort 1 "register_operand" "v")]
3293                         UNSPEC_REDUC_PLUS))]
3294   "TARGET_ALTIVEC"
3296   rtx vzero = gen_reg_rtx (V4SImode);
3297   rtx vtmp1 = gen_reg_rtx (V4SImode);
3298   rtx vtmp2 = gen_reg_rtx (<MODE>mode);
3299   rtx dest = gen_lowpart (V4SImode, vtmp2);
3300   int elt = VECTOR_ELT_ORDER_BIG ? GET_MODE_NUNITS (<MODE>mode) - 1 : 0;
3302   emit_insn (gen_altivec_vspltisw (vzero, const0_rtx));
3303   emit_insn (gen_altivec_vsum4s<VI_char>s (vtmp1, operands[1], vzero));
3304   emit_insn (gen_altivec_vsumsws_direct (dest, vtmp1, vzero));
3305   rs6000_expand_vector_extract (operands[0], vtmp2, GEN_INT (elt));
3306   DONE;
3309 (define_insn "*p9_neg<mode>2"
3310   [(set (match_operand:VNEG 0 "altivec_register_operand" "=v")
3311         (neg:VNEG (match_operand:VNEG 1 "altivec_register_operand" "v")))]
3312   "TARGET_P9_VECTOR"
3313   "vneg<VI_char> %0,%1"
3314   [(set_attr "type" "vecsimple")])
3316 (define_expand "neg<mode>2"
3317   [(set (match_operand:VI2 0 "register_operand" "")
3318         (neg:VI2 (match_operand:VI2 1 "register_operand" "")))]
3319   "<VI_unit>"
3321   if (!TARGET_P9_VECTOR || (<MODE>mode != V4SImode && <MODE>mode != V2DImode))
3322     {
3323       rtx vzero;
3325       vzero = gen_reg_rtx (GET_MODE (operands[0]));
3326       emit_move_insn (vzero, CONST0_RTX (<MODE>mode));
3327       emit_insn (gen_sub<mode>3 (operands[0], vzero, operands[1]));
3328       DONE;
3329     }
3332 (define_expand "udot_prod<mode>"
3333   [(set (match_operand:V4SI 0 "register_operand" "=v")
3334         (plus:V4SI (match_operand:V4SI 3 "register_operand" "v")
3335                    (unspec:V4SI [(match_operand:VIshort 1 "register_operand" "v")  
3336                                  (match_operand:VIshort 2 "register_operand" "v")] 
3337                                 UNSPEC_VMSUMU)))]
3338   "TARGET_ALTIVEC"
3339   "
3340 {  
3341   emit_insn (gen_altivec_vmsumu<VI_char>m (operands[0], operands[1], operands[2], operands[3]));
3342   DONE;
3344    
3345 (define_expand "sdot_prodv8hi"
3346   [(set (match_operand:V4SI 0 "register_operand" "=v")
3347         (plus:V4SI (match_operand:V4SI 3 "register_operand" "v")
3348                    (unspec:V4SI [(match_operand:V8HI 1 "register_operand" "v")
3349                                  (match_operand:V8HI 2 "register_operand" "v")]
3350                                 UNSPEC_VMSUMSHM)))]
3351   "TARGET_ALTIVEC"
3352   "
3354   emit_insn (gen_altivec_vmsumshm (operands[0], operands[1], operands[2], operands[3]));
3355   DONE;
3358 (define_expand "widen_usum<mode>3"
3359   [(set (match_operand:V4SI 0 "register_operand" "=v")
3360         (plus:V4SI (match_operand:V4SI 2 "register_operand" "v")
3361                    (unspec:V4SI [(match_operand:VIshort 1 "register_operand" "v")]
3362                                 UNSPEC_VMSUMU)))]
3363   "TARGET_ALTIVEC"
3364   "
3366   rtx vones = gen_reg_rtx (GET_MODE (operands[1]));
3368   emit_insn (gen_altivec_vspltis<VI_char> (vones, const1_rtx));
3369   emit_insn (gen_altivec_vmsumu<VI_char>m (operands[0], operands[1], vones, operands[2]));
3370   DONE;
3373 (define_expand "widen_ssumv16qi3"
3374   [(set (match_operand:V4SI 0 "register_operand" "=v")
3375         (plus:V4SI (match_operand:V4SI 2 "register_operand" "v")
3376                    (unspec:V4SI [(match_operand:V16QI 1 "register_operand" "v")]
3377                                 UNSPEC_VMSUMM)))]
3378   "TARGET_ALTIVEC"
3379   "
3381   rtx vones = gen_reg_rtx (V16QImode);
3383   emit_insn (gen_altivec_vspltisb (vones, const1_rtx));
3384   emit_insn (gen_altivec_vmsummbm (operands[0], operands[1], vones, operands[2]));
3385   DONE;
3388 (define_expand "widen_ssumv8hi3"
3389   [(set (match_operand:V4SI 0 "register_operand" "=v")
3390         (plus:V4SI (match_operand:V4SI 2 "register_operand" "v")
3391                    (unspec:V4SI [(match_operand:V8HI 1 "register_operand" "v")]
3392                                 UNSPEC_VMSUMSHM)))]
3393   "TARGET_ALTIVEC"
3394   "
3396   rtx vones = gen_reg_rtx (V8HImode);
3398   emit_insn (gen_altivec_vspltish (vones, const1_rtx));
3399   emit_insn (gen_altivec_vmsumshm (operands[0], operands[1], vones, operands[2]));
3400   DONE;
3403 (define_expand "vec_unpacks_hi_<VP_small_lc>"
3404   [(set (match_operand:VP 0 "register_operand" "=v")
3405         (unspec:VP [(match_operand:<VP_small> 1 "register_operand" "v")]
3406                    UNSPEC_VUNPACK_HI_SIGN_DIRECT))]
3407   "<VI_unit>"
3408   "")
3410 (define_expand "vec_unpacks_lo_<VP_small_lc>"
3411   [(set (match_operand:VP 0 "register_operand" "=v")
3412         (unspec:VP [(match_operand:<VP_small> 1 "register_operand" "v")]
3413                    UNSPEC_VUNPACK_LO_SIGN_DIRECT))]
3414   "<VI_unit>"
3415   "")
3417 (define_insn "vperm_v8hiv4si"
3418   [(set (match_operand:V4SI 0 "register_operand" "=v,?wo")
3419         (unspec:V4SI [(match_operand:V8HI 1 "register_operand" "v,wo")
3420                       (match_operand:V4SI 2 "register_operand" "v,0")
3421                       (match_operand:V16QI 3 "register_operand" "v,wo")]
3422                   UNSPEC_VPERMSI))]
3423   "TARGET_ALTIVEC"
3424   "@
3425    vperm %0,%1,%2,%3
3426    xxperm %x0,%x1,%x3"
3427   [(set_attr "type" "vecperm")
3428    (set_attr "length" "4")])
3430 (define_insn "vperm_v16qiv8hi"
3431   [(set (match_operand:V8HI 0 "register_operand" "=v,?wo")
3432         (unspec:V8HI [(match_operand:V16QI 1 "register_operand" "v,wo")
3433                       (match_operand:V8HI 2 "register_operand" "v,0")
3434                       (match_operand:V16QI 3 "register_operand" "v,wo")]
3435                   UNSPEC_VPERMHI))]
3436   "TARGET_ALTIVEC"
3437   "@
3438    vperm %0,%1,%2,%3
3439    xxperm %x0,%x1,%x3"
3440   [(set_attr "type" "vecperm")
3441    (set_attr "length" "4")])
3444 (define_expand "vec_unpacku_hi_v16qi"
3445   [(set (match_operand:V8HI 0 "register_operand" "=v")
3446         (unspec:V8HI [(match_operand:V16QI 1 "register_operand" "v")]
3447                      UNSPEC_VUPKHUB))]
3448   "TARGET_ALTIVEC"      
3449   "
3450 {  
3451   rtx vzero = gen_reg_rtx (V8HImode);
3452   rtx mask = gen_reg_rtx (V16QImode);
3453   rtvec v = rtvec_alloc (16);
3454   bool be = BYTES_BIG_ENDIAN;
3455    
3456   emit_insn (gen_altivec_vspltish (vzero, const0_rtx));
3457    
3458   RTVEC_ELT (v,  0) = gen_rtx_CONST_INT (QImode, be ? 16 :  7);
3459   RTVEC_ELT (v,  1) = gen_rtx_CONST_INT (QImode, be ?  0 : 16);
3460   RTVEC_ELT (v,  2) = gen_rtx_CONST_INT (QImode, be ? 16 :  6);
3461   RTVEC_ELT (v,  3) = gen_rtx_CONST_INT (QImode, be ?  1 : 16);
3462   RTVEC_ELT (v,  4) = gen_rtx_CONST_INT (QImode, be ? 16 :  5);
3463   RTVEC_ELT (v,  5) = gen_rtx_CONST_INT (QImode, be ?  2 : 16);
3464   RTVEC_ELT (v,  6) = gen_rtx_CONST_INT (QImode, be ? 16 :  4);
3465   RTVEC_ELT (v,  7) = gen_rtx_CONST_INT (QImode, be ?  3 : 16);
3466   RTVEC_ELT (v,  8) = gen_rtx_CONST_INT (QImode, be ? 16 :  3);
3467   RTVEC_ELT (v,  9) = gen_rtx_CONST_INT (QImode, be ?  4 : 16);
3468   RTVEC_ELT (v, 10) = gen_rtx_CONST_INT (QImode, be ? 16 :  2);
3469   RTVEC_ELT (v, 11) = gen_rtx_CONST_INT (QImode, be ?  5 : 16);
3470   RTVEC_ELT (v, 12) = gen_rtx_CONST_INT (QImode, be ? 16 :  1);
3471   RTVEC_ELT (v, 13) = gen_rtx_CONST_INT (QImode, be ?  6 : 16);
3472   RTVEC_ELT (v, 14) = gen_rtx_CONST_INT (QImode, be ? 16 :  0);
3473   RTVEC_ELT (v, 15) = gen_rtx_CONST_INT (QImode, be ?  7 : 16);
3475   emit_insn (gen_vec_initv16qiqi (mask, gen_rtx_PARALLEL (V16QImode, v)));
3476   emit_insn (gen_vperm_v16qiv8hi (operands[0], operands[1], vzero, mask));
3477   DONE;
3480 (define_expand "vec_unpacku_hi_v8hi"
3481   [(set (match_operand:V4SI 0 "register_operand" "=v")
3482         (unspec:V4SI [(match_operand:V8HI 1 "register_operand" "v")]
3483                      UNSPEC_VUPKHUH))]
3484   "TARGET_ALTIVEC"
3485   "
3487   rtx vzero = gen_reg_rtx (V4SImode);
3488   rtx mask = gen_reg_rtx (V16QImode);
3489   rtvec v = rtvec_alloc (16);
3490   bool be = BYTES_BIG_ENDIAN;
3492   emit_insn (gen_altivec_vspltisw (vzero, const0_rtx));
3494   RTVEC_ELT (v,  0) = gen_rtx_CONST_INT (QImode, be ? 16 :  7);
3495   RTVEC_ELT (v,  1) = gen_rtx_CONST_INT (QImode, be ? 17 :  6);
3496   RTVEC_ELT (v,  2) = gen_rtx_CONST_INT (QImode, be ?  0 : 17);
3497   RTVEC_ELT (v,  3) = gen_rtx_CONST_INT (QImode, be ?  1 : 16);
3498   RTVEC_ELT (v,  4) = gen_rtx_CONST_INT (QImode, be ? 16 :  5);
3499   RTVEC_ELT (v,  5) = gen_rtx_CONST_INT (QImode, be ? 17 :  4);
3500   RTVEC_ELT (v,  6) = gen_rtx_CONST_INT (QImode, be ?  2 : 17);
3501   RTVEC_ELT (v,  7) = gen_rtx_CONST_INT (QImode, be ?  3 : 16);
3502   RTVEC_ELT (v,  8) = gen_rtx_CONST_INT (QImode, be ? 16 :  3);
3503   RTVEC_ELT (v,  9) = gen_rtx_CONST_INT (QImode, be ? 17 :  2);
3504   RTVEC_ELT (v, 10) = gen_rtx_CONST_INT (QImode, be ?  4 : 17);
3505   RTVEC_ELT (v, 11) = gen_rtx_CONST_INT (QImode, be ?  5 : 16);
3506   RTVEC_ELT (v, 12) = gen_rtx_CONST_INT (QImode, be ? 16 :  1);
3507   RTVEC_ELT (v, 13) = gen_rtx_CONST_INT (QImode, be ? 17 :  0);
3508   RTVEC_ELT (v, 14) = gen_rtx_CONST_INT (QImode, be ?  6 : 17);
3509   RTVEC_ELT (v, 15) = gen_rtx_CONST_INT (QImode, be ?  7 : 16);
3511   emit_insn (gen_vec_initv16qiqi (mask, gen_rtx_PARALLEL (V16QImode, v)));
3512   emit_insn (gen_vperm_v8hiv4si (operands[0], operands[1], vzero, mask));
3513   DONE;
3516 (define_expand "vec_unpacku_lo_v16qi"
3517   [(set (match_operand:V8HI 0 "register_operand" "=v")
3518         (unspec:V8HI [(match_operand:V16QI 1 "register_operand" "v")]
3519                      UNSPEC_VUPKLUB))]
3520   "TARGET_ALTIVEC"
3521   "
3523   rtx vzero = gen_reg_rtx (V8HImode);
3524   rtx mask = gen_reg_rtx (V16QImode);
3525   rtvec v = rtvec_alloc (16);
3526   bool be = BYTES_BIG_ENDIAN;
3528   emit_insn (gen_altivec_vspltish (vzero, const0_rtx));
3530   RTVEC_ELT (v,  0) = gen_rtx_CONST_INT (QImode, be ? 16 : 15);
3531   RTVEC_ELT (v,  1) = gen_rtx_CONST_INT (QImode, be ?  8 : 16);
3532   RTVEC_ELT (v,  2) = gen_rtx_CONST_INT (QImode, be ? 16 : 14);
3533   RTVEC_ELT (v,  3) = gen_rtx_CONST_INT (QImode, be ?  9 : 16);
3534   RTVEC_ELT (v,  4) = gen_rtx_CONST_INT (QImode, be ? 16 : 13);
3535   RTVEC_ELT (v,  5) = gen_rtx_CONST_INT (QImode, be ? 10 : 16);
3536   RTVEC_ELT (v,  6) = gen_rtx_CONST_INT (QImode, be ? 16 : 12);
3537   RTVEC_ELT (v,  7) = gen_rtx_CONST_INT (QImode, be ? 11 : 16);
3538   RTVEC_ELT (v,  8) = gen_rtx_CONST_INT (QImode, be ? 16 : 11);
3539   RTVEC_ELT (v,  9) = gen_rtx_CONST_INT (QImode, be ? 12 : 16);
3540   RTVEC_ELT (v, 10) = gen_rtx_CONST_INT (QImode, be ? 16 : 10);
3541   RTVEC_ELT (v, 11) = gen_rtx_CONST_INT (QImode, be ? 13 : 16);
3542   RTVEC_ELT (v, 12) = gen_rtx_CONST_INT (QImode, be ? 16 :  9);
3543   RTVEC_ELT (v, 13) = gen_rtx_CONST_INT (QImode, be ? 14 : 16);
3544   RTVEC_ELT (v, 14) = gen_rtx_CONST_INT (QImode, be ? 16 :  8);
3545   RTVEC_ELT (v, 15) = gen_rtx_CONST_INT (QImode, be ? 15 : 16);
3547   emit_insn (gen_vec_initv16qiqi (mask, gen_rtx_PARALLEL (V16QImode, v)));
3548   emit_insn (gen_vperm_v16qiv8hi (operands[0], operands[1], vzero, mask));
3549   DONE;
3552 (define_expand "vec_unpacku_lo_v8hi"
3553   [(set (match_operand:V4SI 0 "register_operand" "=v")
3554         (unspec:V4SI [(match_operand:V8HI 1 "register_operand" "v")]
3555                      UNSPEC_VUPKLUH))]
3556   "TARGET_ALTIVEC"
3557   "
3559   rtx vzero = gen_reg_rtx (V4SImode);
3560   rtx mask = gen_reg_rtx (V16QImode);
3561   rtvec v = rtvec_alloc (16);
3562   bool be = BYTES_BIG_ENDIAN;
3564   emit_insn (gen_altivec_vspltisw (vzero, const0_rtx));
3566   RTVEC_ELT (v,  0) = gen_rtx_CONST_INT (QImode, be ? 16 : 15);
3567   RTVEC_ELT (v,  1) = gen_rtx_CONST_INT (QImode, be ? 17 : 14);
3568   RTVEC_ELT (v,  2) = gen_rtx_CONST_INT (QImode, be ?  8 : 17);
3569   RTVEC_ELT (v,  3) = gen_rtx_CONST_INT (QImode, be ?  9 : 16);
3570   RTVEC_ELT (v,  4) = gen_rtx_CONST_INT (QImode, be ? 16 : 13);
3571   RTVEC_ELT (v,  5) = gen_rtx_CONST_INT (QImode, be ? 17 : 12);
3572   RTVEC_ELT (v,  6) = gen_rtx_CONST_INT (QImode, be ? 10 : 17);
3573   RTVEC_ELT (v,  7) = gen_rtx_CONST_INT (QImode, be ? 11 : 16);
3574   RTVEC_ELT (v,  8) = gen_rtx_CONST_INT (QImode, be ? 16 : 11);
3575   RTVEC_ELT (v,  9) = gen_rtx_CONST_INT (QImode, be ? 17 : 10);
3576   RTVEC_ELT (v, 10) = gen_rtx_CONST_INT (QImode, be ? 12 : 17);
3577   RTVEC_ELT (v, 11) = gen_rtx_CONST_INT (QImode, be ? 13 : 16);
3578   RTVEC_ELT (v, 12) = gen_rtx_CONST_INT (QImode, be ? 16 :  9);
3579   RTVEC_ELT (v, 13) = gen_rtx_CONST_INT (QImode, be ? 17 :  8);
3580   RTVEC_ELT (v, 14) = gen_rtx_CONST_INT (QImode, be ? 14 : 17);
3581   RTVEC_ELT (v, 15) = gen_rtx_CONST_INT (QImode, be ? 15 : 16);
3583   emit_insn (gen_vec_initv16qiqi (mask, gen_rtx_PARALLEL (V16QImode, v)));
3584   emit_insn (gen_vperm_v8hiv4si (operands[0], operands[1], vzero, mask));
3585   DONE;
3588 (define_expand "vec_widen_umult_hi_v16qi"
3589   [(set (match_operand:V8HI 0 "register_operand" "=v")
3590         (unspec:V8HI [(match_operand:V16QI 1 "register_operand" "v")
3591                       (match_operand:V16QI 2 "register_operand" "v")]
3592                      UNSPEC_VMULWHUB))]
3593   "TARGET_ALTIVEC"
3594   "
3596   rtx ve = gen_reg_rtx (V8HImode);
3597   rtx vo = gen_reg_rtx (V8HImode);
3598   
3599   if (BYTES_BIG_ENDIAN)
3600     {
3601       emit_insn (gen_altivec_vmuleub (ve, operands[1], operands[2]));
3602       emit_insn (gen_altivec_vmuloub (vo, operands[1], operands[2]));
3603       emit_insn (gen_altivec_vmrghh_direct (operands[0], ve, vo));
3604     }
3605   else
3606     {
3607       emit_insn (gen_altivec_vmuloub (ve, operands[1], operands[2]));
3608       emit_insn (gen_altivec_vmuleub (vo, operands[1], operands[2]));
3609       emit_insn (gen_altivec_vmrghh_direct (operands[0], vo, ve));
3610     }
3611   DONE;
3614 (define_expand "vec_widen_umult_lo_v16qi"
3615   [(set (match_operand:V8HI 0 "register_operand" "=v")
3616         (unspec:V8HI [(match_operand:V16QI 1 "register_operand" "v")
3617                       (match_operand:V16QI 2 "register_operand" "v")]
3618                      UNSPEC_VMULWLUB))]
3619   "TARGET_ALTIVEC"
3620   "
3622   rtx ve = gen_reg_rtx (V8HImode);
3623   rtx vo = gen_reg_rtx (V8HImode);
3624   
3625   if (BYTES_BIG_ENDIAN)
3626     {
3627       emit_insn (gen_altivec_vmuleub (ve, operands[1], operands[2]));
3628       emit_insn (gen_altivec_vmuloub (vo, operands[1], operands[2]));
3629       emit_insn (gen_altivec_vmrglh_direct (operands[0], ve, vo));
3630     }
3631   else
3632     {
3633       emit_insn (gen_altivec_vmuloub (ve, operands[1], operands[2]));
3634       emit_insn (gen_altivec_vmuleub (vo, operands[1], operands[2]));
3635       emit_insn (gen_altivec_vmrglh_direct (operands[0], vo, ve));
3636     }
3637   DONE;
3640 (define_expand "vec_widen_smult_hi_v16qi"
3641   [(set (match_operand:V8HI 0 "register_operand" "=v")
3642         (unspec:V8HI [(match_operand:V16QI 1 "register_operand" "v")
3643                       (match_operand:V16QI 2 "register_operand" "v")]
3644                      UNSPEC_VMULWHSB))]
3645   "TARGET_ALTIVEC"
3646   "
3648   rtx ve = gen_reg_rtx (V8HImode);
3649   rtx vo = gen_reg_rtx (V8HImode);
3650   
3651   if (BYTES_BIG_ENDIAN)
3652     {
3653       emit_insn (gen_altivec_vmulesb (ve, operands[1], operands[2]));
3654       emit_insn (gen_altivec_vmulosb (vo, operands[1], operands[2]));
3655       emit_insn (gen_altivec_vmrghh_direct (operands[0], ve, vo));
3656     }
3657   else
3658     {
3659       emit_insn (gen_altivec_vmulosb (ve, operands[1], operands[2]));
3660       emit_insn (gen_altivec_vmulesb (vo, operands[1], operands[2]));
3661       emit_insn (gen_altivec_vmrghh_direct (operands[0], vo, ve));
3662     }
3663   DONE;
3666 (define_expand "vec_widen_smult_lo_v16qi"
3667   [(set (match_operand:V8HI 0 "register_operand" "=v")
3668         (unspec:V8HI [(match_operand:V16QI 1 "register_operand" "v")
3669                       (match_operand:V16QI 2 "register_operand" "v")]
3670                      UNSPEC_VMULWLSB))]
3671   "TARGET_ALTIVEC"
3672   "
3674   rtx ve = gen_reg_rtx (V8HImode);
3675   rtx vo = gen_reg_rtx (V8HImode);
3676   
3677   if (BYTES_BIG_ENDIAN)
3678     {
3679       emit_insn (gen_altivec_vmulesb (ve, operands[1], operands[2]));
3680       emit_insn (gen_altivec_vmulosb (vo, operands[1], operands[2]));
3681       emit_insn (gen_altivec_vmrglh_direct (operands[0], ve, vo));
3682     }
3683   else
3684     {
3685       emit_insn (gen_altivec_vmulosb (ve, operands[1], operands[2]));
3686       emit_insn (gen_altivec_vmulesb (vo, operands[1], operands[2]));
3687       emit_insn (gen_altivec_vmrglh_direct (operands[0], vo, ve));
3688     }
3689   DONE;
3692 (define_expand "vec_widen_umult_hi_v8hi"
3693   [(set (match_operand:V4SI 0 "register_operand" "=v")
3694         (unspec:V4SI [(match_operand:V8HI 1 "register_operand" "v")
3695                       (match_operand:V8HI 2 "register_operand" "v")]
3696                      UNSPEC_VMULWHUH))]
3697   "TARGET_ALTIVEC"
3698   "
3700   rtx ve = gen_reg_rtx (V4SImode);
3701   rtx vo = gen_reg_rtx (V4SImode);
3702   
3703   if (BYTES_BIG_ENDIAN)
3704     {
3705       emit_insn (gen_altivec_vmuleuh (ve, operands[1], operands[2]));
3706       emit_insn (gen_altivec_vmulouh (vo, operands[1], operands[2]));
3707       emit_insn (gen_altivec_vmrghw_direct (operands[0], ve, vo));
3708     }
3709   else
3710     {
3711       emit_insn (gen_altivec_vmulouh (ve, operands[1], operands[2]));
3712       emit_insn (gen_altivec_vmuleuh (vo, operands[1], operands[2]));
3713       emit_insn (gen_altivec_vmrghw_direct (operands[0], vo, ve));
3714     }
3715   DONE;
3718 (define_expand "vec_widen_umult_lo_v8hi"
3719   [(set (match_operand:V4SI 0 "register_operand" "=v")
3720         (unspec:V4SI [(match_operand:V8HI 1 "register_operand" "v")
3721                       (match_operand:V8HI 2 "register_operand" "v")]
3722                      UNSPEC_VMULWLUH))]
3723   "TARGET_ALTIVEC"
3724   "
3726   rtx ve = gen_reg_rtx (V4SImode);
3727   rtx vo = gen_reg_rtx (V4SImode);
3728   
3729   if (BYTES_BIG_ENDIAN)
3730     {
3731       emit_insn (gen_altivec_vmuleuh (ve, operands[1], operands[2]));
3732       emit_insn (gen_altivec_vmulouh (vo, operands[1], operands[2]));
3733       emit_insn (gen_altivec_vmrglw_direct (operands[0], ve, vo));
3734     }
3735   else
3736     {
3737       emit_insn (gen_altivec_vmulouh (ve, operands[1], operands[2]));
3738       emit_insn (gen_altivec_vmuleuh (vo, operands[1], operands[2]));
3739       emit_insn (gen_altivec_vmrglw_direct (operands[0], vo, ve));
3740     }
3741   DONE;
3744 (define_expand "vec_widen_smult_hi_v8hi"
3745   [(set (match_operand:V4SI 0 "register_operand" "=v")
3746         (unspec:V4SI [(match_operand:V8HI 1 "register_operand" "v")
3747                       (match_operand:V8HI 2 "register_operand" "v")]
3748                      UNSPEC_VMULWHSH))]
3749   "TARGET_ALTIVEC"
3750   "
3752   rtx ve = gen_reg_rtx (V4SImode);
3753   rtx vo = gen_reg_rtx (V4SImode);
3754   
3755   if (BYTES_BIG_ENDIAN)
3756     {
3757       emit_insn (gen_altivec_vmulesh (ve, operands[1], operands[2]));
3758       emit_insn (gen_altivec_vmulosh (vo, operands[1], operands[2]));
3759       emit_insn (gen_altivec_vmrghw_direct (operands[0], ve, vo));
3760     }
3761   else
3762     {
3763       emit_insn (gen_altivec_vmulosh (ve, operands[1], operands[2]));
3764       emit_insn (gen_altivec_vmulesh (vo, operands[1], operands[2]));
3765       emit_insn (gen_altivec_vmrghw_direct (operands[0], vo, ve));
3766     }
3767   DONE;
3770 (define_expand "vec_widen_smult_lo_v8hi"
3771   [(set (match_operand:V4SI 0 "register_operand" "=v")
3772         (unspec:V4SI [(match_operand:V8HI 1 "register_operand" "v")
3773                       (match_operand:V8HI 2 "register_operand" "v")]
3774                      UNSPEC_VMULWLSH))]
3775   "TARGET_ALTIVEC"
3776   "
3778   rtx ve = gen_reg_rtx (V4SImode);
3779   rtx vo = gen_reg_rtx (V4SImode);
3780   
3781   if (BYTES_BIG_ENDIAN)
3782     {
3783       emit_insn (gen_altivec_vmulesh (ve, operands[1], operands[2]));
3784       emit_insn (gen_altivec_vmulosh (vo, operands[1], operands[2]));
3785       emit_insn (gen_altivec_vmrglw_direct (operands[0], ve, vo));
3786     }
3787   else
3788     {
3789       emit_insn (gen_altivec_vmulosh (ve, operands[1], operands[2]));
3790       emit_insn (gen_altivec_vmulesh (vo, operands[1], operands[2]));
3791       emit_insn (gen_altivec_vmrglw_direct (operands[0], vo, ve));
3792     }
3793   DONE;
3796 (define_expand "vec_pack_trunc_<mode>"
3797   [(set (match_operand:<VP_small> 0 "register_operand" "=v")
3798         (unspec:<VP_small> [(match_operand:VP 1 "register_operand" "v")
3799                             (match_operand:VP 2 "register_operand" "v")]
3800                       UNSPEC_VPACK_UNS_UNS_MOD))]
3801   "<VI_unit>"
3802   "")
3804 (define_expand "mulv16qi3"
3805   [(set (match_operand:V16QI 0 "register_operand" "=v")
3806         (mult:V16QI (match_operand:V16QI 1 "register_operand" "v")
3807                     (match_operand:V16QI 2 "register_operand" "v")))]
3808   "TARGET_ALTIVEC"
3809   "
3811   rtx even = gen_reg_rtx (V8HImode);
3812   rtx odd = gen_reg_rtx (V8HImode);
3813   rtx mask = gen_reg_rtx (V16QImode);
3814   rtvec v = rtvec_alloc (16);
3815   int i;
3817   for (i = 0; i < 8; ++i) {
3818     RTVEC_ELT (v, 2 * i)
3819      = gen_rtx_CONST_INT (QImode, BYTES_BIG_ENDIAN ? 2 * i + 1 : 31 - 2 * i);
3820     RTVEC_ELT (v, 2 * i + 1)
3821      = gen_rtx_CONST_INT (QImode, BYTES_BIG_ENDIAN ? 2 * i + 17 : 15 - 2 * i);
3822   }
3824   emit_insn (gen_vec_initv16qiqi (mask, gen_rtx_PARALLEL (V16QImode, v)));
3825   emit_insn (gen_altivec_vmulesb (even, operands[1], operands[2]));
3826   emit_insn (gen_altivec_vmulosb (odd, operands[1], operands[2]));
3827   emit_insn (gen_altivec_vperm_v8hiv16qi (operands[0], even, odd, mask));
3828   DONE;
3831 (define_expand "altivec_negv4sf2"
3832   [(use (match_operand:V4SF 0 "register_operand" ""))
3833    (use (match_operand:V4SF 1 "register_operand" ""))]
3834   "TARGET_ALTIVEC"
3835   "
3837   rtx neg0;
3839   /* Generate [-0.0, -0.0, -0.0, -0.0].  */
3840   neg0 = gen_reg_rtx (V4SImode);
3841   emit_insn (gen_altivec_vspltisw (neg0, constm1_rtx));
3842   emit_insn (gen_vashlv4si3 (neg0, neg0, neg0));
3844   /* XOR */
3845   emit_insn (gen_xorv4sf3 (operands[0],
3846                            gen_lowpart (V4SFmode, neg0), operands[1])); 
3847     
3848   DONE;
3851 ;; Vector reverse elements
3852 (define_expand "altivec_vreve<mode>2"
3853   [(set (match_operand:VEC_A 0 "register_operand" "=v")
3854         (unspec:VEC_A [(match_operand:VEC_A 1 "register_operand" "v")]
3855                       UNSPEC_VREVEV))]
3856   "TARGET_ALTIVEC"
3858   int i, j, size, num_elements;
3859   rtvec v = rtvec_alloc (16);
3860   rtx mask = gen_reg_rtx (V16QImode);
3862   size = GET_MODE_UNIT_SIZE (<MODE>mode);
3863   num_elements = GET_MODE_NUNITS (<MODE>mode);
3865   for (j = 0; j < num_elements; j++)
3866     for (i = 0; i < size; i++)
3867       RTVEC_ELT (v, i + j * size)
3868         = GEN_INT (i + (num_elements - 1 - j) * size);
3870   emit_insn (gen_vec_initv16qiqi (mask, gen_rtx_PARALLEL (V16QImode, v)));
3871   emit_insn (gen_altivec_vperm_<mode> (operands[0], operands[1],
3872              operands[1], mask));
3873   DONE;
3876 ;; Vector SIMD PEM v2.06c defines LVLX, LVLXL, LVRX, LVRXL,
3877 ;; STVLX, STVLXL, STVVRX, STVRXL are available only on Cell.
3878 (define_insn "altivec_lvlx"
3879   [(set (match_operand:V16QI 0 "register_operand" "=v")
3880         (unspec:V16QI [(match_operand:BLK 1 "memory_operand" "Z")]
3881                       UNSPEC_LVLX))]
3882   "TARGET_ALTIVEC && rs6000_cpu == PROCESSOR_CELL"
3883   "lvlx %0,%y1"
3884   [(set_attr "type" "vecload")])
3886 (define_insn "altivec_lvlxl"
3887   [(set (match_operand:V16QI 0 "register_operand" "=v")
3888         (unspec:V16QI [(match_operand:BLK 1 "memory_operand" "Z")]
3889                       UNSPEC_LVLXL))]
3890   "TARGET_ALTIVEC && rs6000_cpu == PROCESSOR_CELL"
3891   "lvlxl %0,%y1"
3892   [(set_attr "type" "vecload")])
3894 (define_insn "altivec_lvrx"
3895   [(set (match_operand:V16QI 0 "register_operand" "=v")
3896         (unspec:V16QI [(match_operand:BLK 1 "memory_operand" "Z")]
3897                       UNSPEC_LVRX))]
3898   "TARGET_ALTIVEC && rs6000_cpu == PROCESSOR_CELL"
3899   "lvrx %0,%y1"
3900   [(set_attr "type" "vecload")])
3902 (define_insn "altivec_lvrxl"
3903   [(set (match_operand:V16QI 0 "register_operand" "=v")
3904         (unspec:V16QI [(match_operand:BLK 1 "memory_operand" "Z")]
3905                       UNSPEC_LVRXL))]
3906   "TARGET_ALTIVEC && rs6000_cpu == PROCESSOR_CELL"
3907   "lvrxl %0,%y1"
3908   [(set_attr "type" "vecload")])
3910 (define_insn "altivec_stvlx"
3911   [(parallel
3912     [(set (match_operand:V16QI 0 "memory_operand" "=Z")
3913           (match_operand:V16QI 1 "register_operand" "v"))
3914      (unspec [(const_int 0)] UNSPEC_STVLX)])]
3915   "TARGET_ALTIVEC && rs6000_cpu == PROCESSOR_CELL"
3916   "stvlx %1,%y0"
3917   [(set_attr "type" "vecstore")])
3919 (define_insn "altivec_stvlxl"
3920   [(parallel
3921     [(set (match_operand:V16QI 0 "memory_operand" "=Z")
3922           (match_operand:V16QI 1 "register_operand" "v"))
3923      (unspec [(const_int 0)] UNSPEC_STVLXL)])]
3924   "TARGET_ALTIVEC && rs6000_cpu == PROCESSOR_CELL"
3925   "stvlxl %1,%y0"
3926   [(set_attr "type" "vecstore")])
3928 (define_insn "altivec_stvrx"
3929   [(parallel
3930     [(set (match_operand:V16QI 0 "memory_operand" "=Z")
3931           (match_operand:V16QI 1 "register_operand" "v"))
3932      (unspec [(const_int 0)] UNSPEC_STVRX)])]
3933   "TARGET_ALTIVEC && rs6000_cpu == PROCESSOR_CELL"
3934   "stvrx %1,%y0"
3935   [(set_attr "type" "vecstore")])
3937 (define_insn "altivec_stvrxl"
3938   [(parallel
3939     [(set (match_operand:V16QI 0 "memory_operand" "=Z")
3940           (match_operand:V16QI 1 "register_operand" "v"))
3941      (unspec [(const_int 0)] UNSPEC_STVRXL)])]
3942   "TARGET_ALTIVEC && rs6000_cpu == PROCESSOR_CELL"
3943   "stvrxl %1,%y0"
3944   [(set_attr "type" "vecstore")])
3946 (define_expand "vec_unpacks_float_hi_v8hi"
3947  [(set (match_operand:V4SF 0 "register_operand" "")
3948         (unspec:V4SF [(match_operand:V8HI 1 "register_operand" "")]
3949                      UNSPEC_VUPKHS_V4SF))]
3950   "TARGET_ALTIVEC"
3951   "
3953   rtx tmp = gen_reg_rtx (V4SImode);
3955   emit_insn (gen_vec_unpacks_hi_v8hi (tmp, operands[1]));
3956   emit_insn (gen_altivec_vcfsx (operands[0], tmp, const0_rtx));
3957   DONE;
3960 (define_expand "vec_unpacks_float_lo_v8hi"
3961  [(set (match_operand:V4SF 0 "register_operand" "")
3962         (unspec:V4SF [(match_operand:V8HI 1 "register_operand" "")]
3963                      UNSPEC_VUPKLS_V4SF))]
3964   "TARGET_ALTIVEC"
3965   "
3967   rtx tmp = gen_reg_rtx (V4SImode);
3969   emit_insn (gen_vec_unpacks_lo_v8hi (tmp, operands[1]));
3970   emit_insn (gen_altivec_vcfsx (operands[0], tmp, const0_rtx));
3971   DONE;
3974 (define_expand "vec_unpacku_float_hi_v8hi"
3975  [(set (match_operand:V4SF 0 "register_operand" "")
3976         (unspec:V4SF [(match_operand:V8HI 1 "register_operand" "")]
3977                      UNSPEC_VUPKHU_V4SF))]
3978   "TARGET_ALTIVEC"
3979   "
3981   rtx tmp = gen_reg_rtx (V4SImode);
3983   emit_insn (gen_vec_unpacku_hi_v8hi (tmp, operands[1]));
3984   emit_insn (gen_altivec_vcfux (operands[0], tmp, const0_rtx));
3985   DONE;
3988 (define_expand "vec_unpacku_float_lo_v8hi"
3989  [(set (match_operand:V4SF 0 "register_operand" "")
3990         (unspec:V4SF [(match_operand:V8HI 1 "register_operand" "")]
3991                      UNSPEC_VUPKLU_V4SF))]
3992   "TARGET_ALTIVEC"
3993   "
3995   rtx tmp = gen_reg_rtx (V4SImode);
3997   emit_insn (gen_vec_unpacku_lo_v8hi (tmp, operands[1]));
3998   emit_insn (gen_altivec_vcfux (operands[0], tmp, const0_rtx));
3999   DONE;
4003 ;; Power8/power9 vector instructions encoded as Altivec instructions
4005 ;; Vector count leading zeros
4006 (define_insn "*p8v_clz<mode>2"
4007   [(set (match_operand:VI2 0 "register_operand" "=v")
4008         (clz:VI2 (match_operand:VI2 1 "register_operand" "v")))]
4009   "TARGET_P8_VECTOR"
4010   "vclz<wd> %0,%1"
4011   [(set_attr "length" "4")
4012    (set_attr "type" "vecsimple")])
4014 ;; Vector absolute difference unsigned
4015 (define_expand "vadu<mode>3"
4016   [(set (match_operand:VI 0 "register_operand")
4017         (unspec:VI [(match_operand:VI 1 "register_operand")
4018                     (match_operand:VI 2 "register_operand")]
4019          UNSPEC_VADU))]
4020   "TARGET_P9_VECTOR")
4022 ;; Vector absolute difference unsigned
4023 (define_insn "*p9_vadu<mode>3"
4024   [(set (match_operand:VI 0 "register_operand" "=v")
4025         (unspec:VI [(match_operand:VI 1 "register_operand" "v")
4026                     (match_operand:VI 2 "register_operand" "v")]
4027          UNSPEC_VADU))]
4028   "TARGET_P9_VECTOR"
4029   "vabsdu<wd> %0,%1,%2"
4030   [(set_attr "type" "vecsimple")])
4032 ;; Vector count trailing zeros
4033 (define_insn "*p9v_ctz<mode>2"
4034   [(set (match_operand:VI2 0 "register_operand" "=v")
4035         (ctz:VI2 (match_operand:VI2 1 "register_operand" "v")))]
4036   "TARGET_P9_VECTOR"
4037   "vctz<wd> %0,%1"
4038   [(set_attr "length" "4")
4039    (set_attr "type" "vecsimple")])
4041 ;; Vector population count
4042 (define_insn "*p8v_popcount<mode>2"
4043   [(set (match_operand:VI2 0 "register_operand" "=v")
4044         (popcount:VI2 (match_operand:VI2 1 "register_operand" "v")))]
4045   "TARGET_P8_VECTOR"
4046   "vpopcnt<wd> %0,%1"
4047   [(set_attr "length" "4")
4048    (set_attr "type" "vecsimple")])
4050 ;; Vector parity
4051 (define_insn "*p9v_parity<mode>2"
4052   [(set (match_operand:VParity 0 "register_operand" "=v")
4053         (parity:VParity (match_operand:VParity 1 "register_operand" "v")))]
4054   "TARGET_P9_VECTOR"
4055   "vprtyb<wd> %0,%1"
4056   [(set_attr "length" "4")
4057    (set_attr "type" "vecsimple")])
4059 ;; Vector Gather Bits by Bytes by Doubleword
4060 (define_insn "p8v_vgbbd"
4061   [(set (match_operand:V16QI 0 "register_operand" "=v")
4062         (unspec:V16QI [(match_operand:V16QI 1 "register_operand" "v")]
4063                       UNSPEC_VGBBD))]
4064   "TARGET_P8_VECTOR"
4065   "vgbbd %0,%1"
4066   [(set_attr "length" "4")
4067    (set_attr "type" "vecsimple")])
4070 ;; 128-bit binary integer arithmetic
4071 ;; We have a special container type (V1TImode) to allow operations using the
4072 ;; ISA 2.07 128-bit binary support to target the VMX/altivec registers without
4073 ;; having to worry about the register allocator deciding GPRs are better.
4075 (define_insn "altivec_vadduqm"
4076   [(set (match_operand:V1TI 0 "register_operand" "=v")
4077         (plus:V1TI (match_operand:V1TI 1 "register_operand" "v")
4078                    (match_operand:V1TI 2 "register_operand" "v")))]
4079   "TARGET_VADDUQM"
4080   "vadduqm %0,%1,%2"
4081   [(set_attr "length" "4")
4082    (set_attr "type" "vecsimple")])
4084 (define_insn "altivec_vaddcuq"
4085   [(set (match_operand:V1TI 0 "register_operand" "=v")
4086         (unspec:V1TI [(match_operand:V1TI 1 "register_operand" "v")
4087                       (match_operand:V1TI 2 "register_operand" "v")]
4088                      UNSPEC_VADDCUQ))]
4089   "TARGET_VADDUQM"
4090   "vaddcuq %0,%1,%2"
4091   [(set_attr "length" "4")
4092    (set_attr "type" "vecsimple")])
4094 (define_insn "altivec_vsubuqm"
4095   [(set (match_operand:V1TI 0 "register_operand" "=v")
4096         (minus:V1TI (match_operand:V1TI 1 "register_operand" "v")
4097                     (match_operand:V1TI 2 "register_operand" "v")))]
4098   "TARGET_VADDUQM"
4099   "vsubuqm %0,%1,%2"
4100   [(set_attr "length" "4")
4101    (set_attr "type" "vecsimple")])
4103 (define_insn "altivec_vsubcuq"
4104   [(set (match_operand:V1TI 0 "register_operand" "=v")
4105         (unspec:V1TI [(match_operand:V1TI 1 "register_operand" "v")
4106                       (match_operand:V1TI 2 "register_operand" "v")]
4107                      UNSPEC_VSUBCUQ))]
4108   "TARGET_VADDUQM"
4109   "vsubcuq %0,%1,%2"
4110   [(set_attr "length" "4")
4111    (set_attr "type" "vecsimple")])
4113 (define_insn "altivec_vaddeuqm"
4114   [(set (match_operand:V1TI 0 "register_operand" "=v")
4115         (unspec:V1TI [(match_operand:V1TI 1 "register_operand" "v")
4116                       (match_operand:V1TI 2 "register_operand" "v")
4117                       (match_operand:V1TI 3 "register_operand" "v")]
4118                      UNSPEC_VADDEUQM))]
4119   "TARGET_VADDUQM"
4120   "vaddeuqm %0,%1,%2,%3"
4121   [(set_attr "length" "4")
4122    (set_attr "type" "vecsimple")])
4124 (define_insn "altivec_vaddecuq"
4125   [(set (match_operand:V1TI 0 "register_operand" "=v")
4126         (unspec:V1TI [(match_operand:V1TI 1 "register_operand" "v")
4127                       (match_operand:V1TI 2 "register_operand" "v")
4128                       (match_operand:V1TI 3 "register_operand" "v")]
4129                      UNSPEC_VADDECUQ))]
4130   "TARGET_VADDUQM"
4131   "vaddecuq %0,%1,%2,%3"
4132   [(set_attr "length" "4")
4133    (set_attr "type" "vecsimple")])
4135 (define_insn "altivec_vsubeuqm"
4136   [(set (match_operand:V1TI 0 "register_operand" "=v")
4137         (unspec:V1TI [(match_operand:V1TI 1 "register_operand" "v")
4138                       (match_operand:V1TI 2 "register_operand" "v")
4139                       (match_operand:V1TI 3 "register_operand" "v")]
4140                    UNSPEC_VSUBEUQM))]
4141   "TARGET_VADDUQM"
4142   "vsubeuqm %0,%1,%2,%3"
4143   [(set_attr "length" "4")
4144    (set_attr "type" "vecsimple")])
4146 (define_insn "altivec_vsubecuq"
4147   [(set (match_operand:V1TI 0 "register_operand" "=v")
4148         (unspec:V1TI [(match_operand:V1TI 1 "register_operand" "v")
4149                       (match_operand:V1TI 2 "register_operand" "v")
4150                       (match_operand:V1TI 3 "register_operand" "v")]
4151                      UNSPEC_VSUBECUQ))]
4152   "TARGET_VADDUQM"
4153   "vsubecuq %0,%1,%2,%3"
4154   [(set_attr "length" "4")
4155    (set_attr "type" "vecsimple")])
4157 ;; We use V2DI as the output type to simplify converting the permute
4158 ;; bits into an integer
4159 (define_insn "altivec_vbpermq"
4160   [(set (match_operand:V2DI 0 "register_operand" "=v")
4161         (unspec:V2DI [(match_operand:V16QI 1 "register_operand" "v")
4162                       (match_operand:V16QI 2 "register_operand" "v")]
4163                      UNSPEC_VBPERMQ))]
4164   "TARGET_P8_VECTOR"
4165   "vbpermq %0,%1,%2"
4166   [(set_attr "type" "vecperm")])
4168 ; One of the vector API interfaces requires returning vector unsigned char.
4169 (define_insn "altivec_vbpermq2"
4170   [(set (match_operand:V16QI 0 "register_operand" "=v")
4171         (unspec:V16QI [(match_operand:V16QI 1 "register_operand" "v")
4172                        (match_operand:V16QI 2 "register_operand" "v")]
4173                       UNSPEC_VBPERMQ))]
4174   "TARGET_P8_VECTOR"
4175   "vbpermq %0,%1,%2"
4176   [(set_attr "type" "vecperm")])
4178 (define_insn "altivec_vbpermd"
4179   [(set (match_operand:V2DI 0 "register_operand" "=v")
4180         (unspec:V2DI [(match_operand:V2DI 1 "register_operand" "v")
4181                       (match_operand:V16QI 2 "register_operand" "v")]
4182                      UNSPEC_VBPERMD))]
4183   "TARGET_P9_VECTOR"
4184   "vbpermd %0,%1,%2"
4185   [(set_attr "type" "vecsimple")])
4187 ;; Decimal Integer operations
4188 (define_int_iterator UNSPEC_BCD_ADD_SUB [UNSPEC_BCDADD UNSPEC_BCDSUB])
4190 (define_int_attr bcd_add_sub [(UNSPEC_BCDADD "add")
4191                               (UNSPEC_BCDSUB "sub")])
4193 (define_code_iterator BCD_TEST [eq lt gt unordered])
4195 (define_insn "bcd<bcd_add_sub>"
4196   [(set (match_operand:V1TI 0 "gpc_reg_operand" "=v")
4197         (unspec:V1TI [(match_operand:V1TI 1 "gpc_reg_operand" "v")
4198                       (match_operand:V1TI 2 "gpc_reg_operand" "v")
4199                       (match_operand:QI 3 "const_0_to_1_operand" "n")]
4200                      UNSPEC_BCD_ADD_SUB))
4201    (clobber (reg:CCFP CR6_REGNO))]
4202   "TARGET_P8_VECTOR"
4203   "bcd<bcd_add_sub>. %0,%1,%2,%3"
4204   [(set_attr "length" "4")
4205    (set_attr "type" "vecsimple")])
4207 ;; Use a floating point type (V2DFmode) for the compare to set CR6 so that we
4208 ;; can use the unordered test for BCD nans and add/subtracts that overflow.  An
4209 ;; UNORDERED test on an integer type (like V1TImode) is not defined.  The type
4210 ;; probably should be one that can go in the VMX (Altivec) registers, so we
4211 ;; can't use DDmode or DFmode.
4212 (define_insn "*bcd<bcd_add_sub>_test"
4213   [(set (reg:CCFP CR6_REGNO)
4214         (compare:CCFP
4215          (unspec:V2DF [(match_operand:V1TI 1 "register_operand" "v")
4216                        (match_operand:V1TI 2 "register_operand" "v")
4217                        (match_operand:QI 3 "const_0_to_1_operand" "i")]
4218                       UNSPEC_BCD_ADD_SUB)
4219          (match_operand:V2DF 4 "zero_constant" "j")))
4220    (clobber (match_scratch:V1TI 0 "=v"))]
4221   "TARGET_P8_VECTOR"
4222   "bcd<bcd_add_sub>. %0,%1,%2,%3"
4223   [(set_attr "length" "4")
4224    (set_attr "type" "vecsimple")])
4226 (define_insn "*bcd<bcd_add_sub>_test2"
4227   [(set (match_operand:V1TI 0 "register_operand" "=v")
4228         (unspec:V1TI [(match_operand:V1TI 1 "register_operand" "v")
4229                       (match_operand:V1TI 2 "register_operand" "v")
4230                       (match_operand:QI 3 "const_0_to_1_operand" "i")]
4231                      UNSPEC_BCD_ADD_SUB))
4232    (set (reg:CCFP CR6_REGNO)
4233         (compare:CCFP
4234          (unspec:V2DF [(match_dup 1)
4235                        (match_dup 2)
4236                        (match_dup 3)]
4237                       UNSPEC_BCD_ADD_SUB)
4238          (match_operand:V2DF 4 "zero_constant" "j")))]
4239   "TARGET_P8_VECTOR"
4240   "bcd<bcd_add_sub>. %0,%1,%2,%3"
4241   [(set_attr "length" "4")
4242    (set_attr "type" "vecsimple")])
4244 (define_insn "darn_32"
4245   [(set (match_operand:SI 0 "register_operand" "=r")
4246         (unspec:SI [(const_int 0)] UNSPEC_DARN_32))]
4247   "TARGET_P9_MISC"
4248   "darn %0,0"
4249   [(set_attr "type" "integer")])
4251 (define_insn "darn_raw"
4252   [(set (match_operand:DI 0 "register_operand" "=r")
4253         (unspec:DI [(const_int 0)] UNSPEC_DARN_RAW))]
4254   "TARGET_P9_MISC && TARGET_64BIT"
4255   "darn %0,2"
4256   [(set_attr "type" "integer")])
4258 (define_insn "darn"
4259   [(set (match_operand:DI 0 "register_operand" "=r")
4260         (unspec:DI [(const_int 0)] UNSPEC_DARN))]
4261   "TARGET_P9_MISC && TARGET_64BIT"
4262   "darn %0,1"
4263   [(set_attr "type" "integer")])
4265 ;; Test byte within range.
4267 ;; The bytes of operand 1 are organized as xx:xx:xx:vv, where xx
4268 ;; represents a byte whose value is ignored in this context and
4269 ;; vv, the least significant byte, holds the byte value that is to
4270 ;; be tested for membership within the range specified by operand 2.
4271 ;; The bytes of operand 2 are organized as xx:xx:hi:lo.
4273 ;; Return in target register operand 0 a value of 1 if lo <= vv and
4274 ;; vv <= hi.  Otherwise, set register operand 0 to 0.
4276 ;; Though the instructions to which this expansion maps operate on
4277 ;; 64-bit registers, the current implementation only operates on
4278 ;; SI-mode operands as the high-order bits provide no information
4279 ;; that is not already available in the low-order bits.  To avoid the
4280 ;; costs of data widening operations, future enhancements might allow
4281 ;; DI mode for operand 0 and/or might allow operand 1 to be QI mode.
4282 (define_expand "cmprb"
4283   [(set (match_dup 3)
4284         (unspec:CC [(match_operand:SI 1 "gpc_reg_operand" "r")
4285                     (match_operand:SI 2 "gpc_reg_operand" "r")]
4286          UNSPEC_CMPRB))
4287    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
4288         (if_then_else:SI (lt (match_dup 3)
4289                              (const_int 0))
4290                          (const_int -1)
4291                          (if_then_else (gt (match_dup 3)
4292                                            (const_int 0))
4293                                        (const_int 1)
4294                                        (const_int 0))))]
4295   "TARGET_P9_MISC"
4297   operands[3] = gen_reg_rtx (CCmode);
4300 ;; The bytes of operand 1 are organized as xx:xx:xx:vv, where xx
4301 ;; represents a byte whose value is ignored in this context and
4302 ;; vv, the least significant byte, holds the byte value that is to
4303 ;; be tested for membership within the range specified by operand 2.
4304 ;; The bytes of operand 2 are organized as xx:xx:hi:lo.
4306 ;; Set bit 1 (the GT bit, 0x4) of CR register operand 0 to 1 if
4307 ;; lo <= vv and vv <= hi.  Otherwise, set the GT bit to 0.  The other
4308 ;; 3 bits of the target CR register are all set to 0.
4309 (define_insn "*cmprb_internal"
4310   [(set (match_operand:CC 0 "cc_reg_operand" "=y")
4311         (unspec:CC [(match_operand:SI 1 "gpc_reg_operand" "r")
4312                     (match_operand:SI 2 "gpc_reg_operand" "r")]
4313          UNSPEC_CMPRB))]
4314   "TARGET_P9_MISC"
4315   "cmprb %0,0,%1,%2"
4316   [(set_attr "type" "logical")])
4318 ;; Set operand 0 register to -1 if the LT bit (0x8) of condition
4319 ;; register operand 1 is on.  Otherwise, set operand 0 register to 1
4320 ;; if the GT bit (0x4) of condition register operand 1 is on.
4321 ;; Otherwise, set operand 0 to 0.  Note that the result stored into
4322 ;; register operand 0 is non-zero iff either the LT or GT bits are on
4323 ;; within condition register operand 1.
4324 (define_insn "setb_signed"
4325    [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
4326          (if_then_else:SI (lt (match_operand:CC 1 "cc_reg_operand" "y")
4327                               (const_int 0))
4328                           (const_int -1)
4329                           (if_then_else (gt (match_dup 1)
4330                                             (const_int 0))
4331                                         (const_int 1)
4332                                         (const_int 0))))]
4333   "TARGET_P9_MISC"
4334   "setb %0,%1"
4335   [(set_attr "type" "logical")])
4337 (define_insn "setb_unsigned"
4338    [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
4339          (if_then_else:SI (ltu (match_operand:CCUNS 1 "cc_reg_operand" "y")
4340                               (const_int 0))
4341                           (const_int -1)
4342                           (if_then_else (gtu (match_dup 1)
4343                                             (const_int 0))
4344                                         (const_int 1)
4345                                         (const_int 0))))]
4346   "TARGET_P9_MISC"
4347   "setb %0,%1"
4348   [(set_attr "type" "logical")])
4350 ;; Test byte within two ranges.
4352 ;; The bytes of operand 1 are organized as xx:xx:xx:vv, where xx
4353 ;; represents a byte whose value is ignored in this context and
4354 ;; vv, the least significant byte, holds the byte value that is to
4355 ;; be tested for membership within the range specified by operand 2.
4356 ;; The bytes of operand 2 are organized as hi_1:lo_1:hi_2:lo_2.
4358 ;; Return in target register operand 0 a value of 1 if (lo_1 <= vv and
4359 ;; vv <= hi_1) or if (lo_2 <= vv and vv <= hi_2).  Otherwise, set register
4360 ;; operand 0 to 0.
4362 ;; Though the instructions to which this expansion maps operate on
4363 ;; 64-bit registers, the current implementation only operates on
4364 ;; SI-mode operands as the high-order bits provide no information
4365 ;; that is not already available in the low-order bits.  To avoid the
4366 ;; costs of data widening operations, future enhancements might allow
4367 ;; DI mode for operand 0 and/or might allow operand 1 to be QI mode.
4368 (define_expand "cmprb2"
4369   [(set (match_dup 3)
4370         (unspec:CC [(match_operand:SI 1 "gpc_reg_operand" "r")
4371                     (match_operand:SI 2 "gpc_reg_operand" "r")]
4372          UNSPEC_CMPRB2))
4373    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
4374         (if_then_else:SI (lt (match_dup 3)
4375                              (const_int 0))
4376                          (const_int -1)
4377                          (if_then_else (gt (match_dup 3)
4378                                            (const_int 0))
4379                                        (const_int 1)
4380                                        (const_int 0))))]
4381   "TARGET_P9_MISC"
4383   operands[3] = gen_reg_rtx (CCmode);
4386 ;; The bytes of operand 1 are organized as xx:xx:xx:vv, where xx
4387 ;; represents a byte whose value is ignored in this context and
4388 ;; vv, the least significant byte, holds the byte value that is to
4389 ;; be tested for membership within the ranges specified by operand 2.
4390 ;; The bytes of operand 2 are organized as hi_1:lo_1:hi_2:lo_2.
4392 ;; Set bit 1 (the GT bit, 0x4) of CR register operand 0 to 1 if
4393 ;; (lo_1 <= vv and vv <= hi_1) or if (lo_2 <= vv and vv <= hi_2).
4394 ;; Otherwise, set the GT bit to 0.  The other 3 bits of the target
4395 ;; CR register are all set to 0.
4396 (define_insn "*cmprb2_internal"
4397   [(set (match_operand:CC 0 "cc_reg_operand" "=y")
4398         (unspec:CC [(match_operand:SI 1 "gpc_reg_operand" "r")
4399                     (match_operand:SI 2 "gpc_reg_operand" "r")]
4400          UNSPEC_CMPRB2))]
4401   "TARGET_P9_MISC"
4402   "cmprb %0,1,%1,%2"
4403   [(set_attr "type" "logical")])
4405 ;; Test byte membership within set of 8 bytes.
4407 ;; The bytes of operand 1 are organized as xx:xx:xx:vv, where xx
4408 ;; represents a byte whose value is ignored in this context and
4409 ;; vv, the least significant byte, holds the byte value that is to
4410 ;; be tested for membership within the set specified by operand 2.
4411 ;; The bytes of operand 2 are organized as e0:e1:e2:e3:e4:e5:e6:e7.
4413 ;; Return in target register operand 0 a value of 1 if vv equals one
4414 ;; of the values e0, e1, e2, e3, e4, e5, e6, or e7.  Otherwise, set
4415 ;; register operand 0 to 0.  Note that the 8 byte values held within
4416 ;; operand 2 need not be unique.
4418 ;; Though the instructions to which this expansion maps operate on
4419 ;; 64-bit registers, the current implementation requires that operands
4420 ;; 0 and 1 have mode SI as the high-order bits provide no information
4421 ;; that is not already available in the low-order bits.  To avoid the
4422 ;; costs of data widening operations, future enhancements might allow
4423 ;; DI mode for operand 0 and/or might allow operand 1 to be QI mode.
4424 (define_expand "cmpeqb"
4425   [(set (match_dup 3)
4426         (unspec:CC [(match_operand:SI 1 "gpc_reg_operand" "r")
4427                     (match_operand:DI 2 "gpc_reg_operand" "r")]
4428          UNSPEC_CMPEQB))
4429    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
4430         (if_then_else:SI (lt (match_dup 3)
4431                              (const_int 0))
4432                          (const_int -1)
4433                          (if_then_else (gt (match_dup 3)
4434                                            (const_int 0))
4435                                        (const_int 1)
4436                                        (const_int 0))))]
4437   "TARGET_P9_MISC && TARGET_64BIT"
4439   operands[3] = gen_reg_rtx (CCmode);
4442 ;; The bytes of operand 1 are organized as xx:xx:xx:vv, where xx
4443 ;; represents a byte whose value is ignored in this context and
4444 ;; vv, the least significant byte, holds the byte value that is to
4445 ;; be tested for membership within the set specified by operand 2.
4446 ;; The bytes of operand 2 are organized as e0:e1:e2:e3:e4:e5:e6:e7.
4448 ;; Set bit 1 (the GT bit, 0x4) of CR register operand 0 to 1 if vv
4449 ;; equals one of the values e0, e1, e2, e3, e4, e5, e6, or e7.  Otherwise,
4450 ;; set the GT bit to zero.  The other 3 bits of the target CR register
4451 ;; are all set to 0.
4452 (define_insn "*cmpeqb_internal"
4453   [(set (match_operand:CC 0 "cc_reg_operand" "=y")
4454          (unspec:CC [(match_operand:SI 1 "gpc_reg_operand" "r")
4455                      (match_operand:DI 2 "gpc_reg_operand" "r")]
4456           UNSPEC_CMPEQB))]
4457   "TARGET_P9_MISC && TARGET_64BIT"
4458   "cmpeqb %0,%1,%2"
4459   [(set_attr "type" "logical")])
4461 (define_expand "bcd<bcd_add_sub>_<code>"
4462   [(parallel [(set (reg:CCFP CR6_REGNO)
4463                    (compare:CCFP
4464                     (unspec:V2DF [(match_operand:V1TI 1 "register_operand" "")
4465                                   (match_operand:V1TI 2 "register_operand" "")
4466                                   (match_operand:QI 3 "const_0_to_1_operand" "")]
4467                                  UNSPEC_BCD_ADD_SUB)
4468                     (match_dup 4)))
4469               (clobber (match_scratch:V1TI 5 ""))])
4470    (set (match_operand:SI 0 "register_operand" "")
4471         (BCD_TEST:SI (reg:CCFP CR6_REGNO)
4472                      (const_int 0)))]
4473   "TARGET_P8_VECTOR"
4475   operands[4] = CONST0_RTX (V2DFmode);
4478 ;; Peephole2 pattern to combine a bcdadd/bcdsub that calculates the value and
4479 ;; the bcdadd/bcdsub that tests the value.  The combiner won't work since
4480 ;; CR6 is a hard coded register.  Unfortunately, all of the Altivec predicate
4481 ;; support is hard coded to use the fixed register CR6 instead of creating
4482 ;; a register class for CR6.
4484 (define_peephole2
4485   [(parallel [(set (match_operand:V1TI 0 "register_operand" "")
4486                    (unspec:V1TI [(match_operand:V1TI 1 "register_operand" "")
4487                                  (match_operand:V1TI 2 "register_operand" "")
4488                                  (match_operand:QI 3 "const_0_to_1_operand" "")]
4489                                 UNSPEC_BCD_ADD_SUB))
4490               (clobber (reg:CCFP CR6_REGNO))])
4491    (parallel [(set (reg:CCFP CR6_REGNO)
4492                    (compare:CCFP
4493                     (unspec:V2DF [(match_dup 1)
4494                                   (match_dup 2)
4495                                   (match_dup 3)]
4496                                  UNSPEC_BCD_ADD_SUB)
4497                     (match_operand:V2DF 4 "zero_constant" "")))
4498               (clobber (match_operand:V1TI 5 "register_operand" ""))])]
4499   "TARGET_P8_VECTOR"
4500   [(parallel [(set (match_dup 0)
4501                    (unspec:V1TI [(match_dup 1)
4502                                  (match_dup 2)
4503                                  (match_dup 3)]
4504                                 UNSPEC_BCD_ADD_SUB))
4505               (set (reg:CCFP CR6_REGNO)
4506                    (compare:CCFP
4507                     (unspec:V2DF [(match_dup 1)
4508                                   (match_dup 2)
4509                                   (match_dup 3)]
4510                                  UNSPEC_BCD_ADD_SUB)
4511                     (match_dup 4)))])])