Add a VEC_SERIES rtl code
[official-gcc.git] / gcc / config / powerpcspe / altivec.md
blob81373f581d1fc35d8d3cc4cd3607357ab93870dd
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_VMULOUB
40    UNSPEC_VMULOSB
41    UNSPEC_VMULOUH
42    UNSPEC_VMULOSH
43    UNSPEC_VPKPX
44    UNSPEC_VPACK_SIGN_SIGN_SAT
45    UNSPEC_VPACK_SIGN_UNS_SAT
46    UNSPEC_VPACK_UNS_UNS_SAT
47    UNSPEC_VPACK_UNS_UNS_MOD
48    UNSPEC_VPACK_UNS_UNS_MOD_DIRECT
49    UNSPEC_VSLV4SI
50    UNSPEC_VSLO
51    UNSPEC_VSR
52    UNSPEC_VSRO
53    UNSPEC_VSUBCUW
54    UNSPEC_VSUBU
55    UNSPEC_VSUBS
56    UNSPEC_VSUM4UBS
57    UNSPEC_VSUM4S
58    UNSPEC_VSUM2SWS
59    UNSPEC_VSUMSWS
60    UNSPEC_VPERM
61    UNSPEC_VPERMR
62    UNSPEC_VPERM_UNS
63    UNSPEC_VRFIN
64    UNSPEC_VCFUX
65    UNSPEC_VCFSX
66    UNSPEC_VCTUXS
67    UNSPEC_VCTSXS
68    UNSPEC_VLOGEFP
69    UNSPEC_VEXPTEFP
70    UNSPEC_VSLDOI
71    UNSPEC_VUNPACK_HI_SIGN
72    UNSPEC_VUNPACK_LO_SIGN
73    UNSPEC_VUNPACK_HI_SIGN_DIRECT
74    UNSPEC_VUNPACK_LO_SIGN_DIRECT
75    UNSPEC_VUPKHPX
76    UNSPEC_VUPKLPX
77    UNSPEC_DARN
78    UNSPEC_DARN_32
79    UNSPEC_DARN_RAW
80    UNSPEC_DST
81    UNSPEC_DSTT
82    UNSPEC_DSTST
83    UNSPEC_DSTSTT
84    UNSPEC_LVSL
85    UNSPEC_LVSR
86    UNSPEC_LVE
87    UNSPEC_STVX
88    UNSPEC_STVXL
89    UNSPEC_STVE
90    UNSPEC_SET_VSCR
91    UNSPEC_GET_VRSAVE
92    UNSPEC_LVX
93    UNSPEC_REDUC_PLUS
94    UNSPEC_VECSH
95    UNSPEC_EXTEVEN_V4SI
96    UNSPEC_EXTEVEN_V8HI
97    UNSPEC_EXTEVEN_V16QI
98    UNSPEC_EXTEVEN_V4SF
99    UNSPEC_EXTODD_V4SI
100    UNSPEC_EXTODD_V8HI
101    UNSPEC_EXTODD_V16QI
102    UNSPEC_EXTODD_V4SF
103    UNSPEC_INTERHI_V4SI
104    UNSPEC_INTERHI_V8HI
105    UNSPEC_INTERHI_V16QI
106    UNSPEC_INTERLO_V4SI
107    UNSPEC_INTERLO_V8HI
108    UNSPEC_INTERLO_V16QI
109    UNSPEC_LVLX
110    UNSPEC_LVLXL
111    UNSPEC_LVRX
112    UNSPEC_LVRXL
113    UNSPEC_STVLX
114    UNSPEC_STVLXL
115    UNSPEC_STVRX
116    UNSPEC_STVRXL
117    UNSPEC_VADU
118    UNSPEC_VSLV
119    UNSPEC_VSRV
120    UNSPEC_VMULWHUB
121    UNSPEC_VMULWLUB
122    UNSPEC_VMULWHSB
123    UNSPEC_VMULWLSB
124    UNSPEC_VMULWHUH
125    UNSPEC_VMULWLUH
126    UNSPEC_VMULWHSH
127    UNSPEC_VMULWLSH
128    UNSPEC_VUPKHUB
129    UNSPEC_VUPKHUH
130    UNSPEC_VUPKLUB
131    UNSPEC_VUPKLUH
132    UNSPEC_VPERMSI
133    UNSPEC_VPERMHI
134    UNSPEC_INTERHI
135    UNSPEC_INTERLO
136    UNSPEC_VUPKHS_V4SF
137    UNSPEC_VUPKLS_V4SF
138    UNSPEC_VUPKHU_V4SF
139    UNSPEC_VUPKLU_V4SF
140    UNSPEC_VGBBD
141    UNSPEC_VMRGH_DIRECT
142    UNSPEC_VMRGL_DIRECT
143    UNSPEC_VSPLT_DIRECT
144    UNSPEC_VMRGEW_DIRECT
145    UNSPEC_VSUMSWS_DIRECT
146    UNSPEC_VADDCUQ
147    UNSPEC_VADDEUQM
148    UNSPEC_VADDECUQ
149    UNSPEC_VSUBCUQ
150    UNSPEC_VSUBEUQM
151    UNSPEC_VSUBECUQ
152    UNSPEC_VBPERMQ
153    UNSPEC_VBPERMD
154    UNSPEC_BCDADD
155    UNSPEC_BCDSUB
156    UNSPEC_BCD_OVERFLOW
157    UNSPEC_CMPRB
158    UNSPEC_CMPRB2
159    UNSPEC_CMPEQB
160    UNSPEC_VRLMI
161    UNSPEC_VRLNM
164 (define_c_enum "unspecv"
165   [UNSPECV_SET_VRSAVE
166    UNSPECV_MTVSCR
167    UNSPECV_MFVSCR
168    UNSPECV_DSSALL
169    UNSPECV_DSS
170   ])
172 ;; Like VI, defined in vector.md, but add ISA 2.07 integer vector ops
173 (define_mode_iterator VI2 [V4SI V8HI V16QI V2DI])
174 ;; Short vec int modes
175 (define_mode_iterator VIshort [V8HI V16QI])
176 ;; Longer vec int modes for rotate/mask ops
177 (define_mode_iterator VIlong [V2DI V4SI])
178 ;; Vec float modes
179 (define_mode_iterator VF [V4SF])
180 ;; Vec modes, pity mode iterators are not composable
181 (define_mode_iterator V [V4SI V8HI V16QI V4SF])
182 ;; Vec modes for move/logical/permute ops, include vector types for move not
183 ;; otherwise handled by altivec (v2df, v2di, ti)
184 (define_mode_iterator VM [V4SI
185                           V8HI
186                           V16QI
187                           V4SF
188                           V2DF
189                           V2DI
190                           V1TI
191                           TI
192                           (KF "FLOAT128_VECTOR_P (KFmode)")
193                           (TF "FLOAT128_VECTOR_P (TFmode)")])
195 ;; Like VM, except don't do TImode
196 (define_mode_iterator VM2 [V4SI
197                            V8HI
198                            V16QI
199                            V4SF
200                            V2DF
201                            V2DI
202                            V1TI
203                            (KF "FLOAT128_VECTOR_P (KFmode)")
204                            (TF "FLOAT128_VECTOR_P (TFmode)")])
206 ;; Specific iterator for parity which does not have a byte/half-word form, but
207 ;; does have a quad word form
208 (define_mode_iterator VParity [V4SI
209                                V2DI
210                                V1TI
211                                (TI "TARGET_VSX_TIMODE")])
213 (define_mode_attr VI_char [(V2DI "d") (V4SI "w") (V8HI "h") (V16QI "b")])
214 (define_mode_attr VI_scalar [(V2DI "DI") (V4SI "SI") (V8HI "HI") (V16QI "QI")])
215 (define_mode_attr VI_unit [(V16QI "VECTOR_UNIT_ALTIVEC_P (V16QImode)")
216                            (V8HI "VECTOR_UNIT_ALTIVEC_P (V8HImode)")
217                            (V4SI "VECTOR_UNIT_ALTIVEC_P (V4SImode)")
218                            (V2DI "VECTOR_UNIT_P8_VECTOR_P (V2DImode)")
219                            (V1TI "VECTOR_UNIT_ALTIVEC_P (V1TImode)")])
221 ;; Vector pack/unpack
222 (define_mode_iterator VP [V2DI V4SI V8HI])
223 (define_mode_attr VP_small [(V2DI "V4SI") (V4SI "V8HI") (V8HI "V16QI")])
224 (define_mode_attr VP_small_lc [(V2DI "v4si") (V4SI "v8hi") (V8HI "v16qi")])
225 (define_mode_attr VU_char [(V2DI "w") (V4SI "h") (V8HI "b")])
227 ;; Vector negate
228 (define_mode_iterator VNEG [V4SI V2DI])
230 ;; Vector move instructions.
231 (define_insn "*altivec_mov<mode>"
232   [(set (match_operand:VM2 0 "nonimmediate_operand" "=Z,v,v,?Y,?*r,?*r,v,v,?*r")
233         (match_operand:VM2 1 "input_operand" "v,Z,v,*r,Y,*r,j,W,W"))]
234   "VECTOR_MEM_ALTIVEC_P (<MODE>mode)
235    && (register_operand (operands[0], <MODE>mode) 
236        || register_operand (operands[1], <MODE>mode))"
238   switch (which_alternative)
239     {
240     case 0: return "stvx %1,%y0";
241     case 1: return "lvx %0,%y1";
242     case 2: return "vor %0,%1,%1";
243     case 3: return "#";
244     case 4: return "#";
245     case 5: return "#";
246     case 6: return "vxor %0,%0,%0";
247     case 7: return output_vec_const_move (operands);
248     case 8: return "#";
249     default: gcc_unreachable ();
250     }
252   [(set_attr "type" "vecstore,vecload,veclogical,store,load,*,veclogical,*,*")
253    (set_attr "length" "4,4,4,20,20,20,4,8,32")])
255 ;; Unlike other altivec moves, allow the GPRs, since a normal use of TImode
256 ;; is for unions.  However for plain data movement, slightly favor the vector
257 ;; loads
258 (define_insn "*altivec_movti"
259   [(set (match_operand:TI 0 "nonimmediate_operand" "=Z,v,v,?Y,?r,?r,v,v")
260         (match_operand:TI 1 "input_operand" "v,Z,v,r,Y,r,j,W"))]
261   "VECTOR_MEM_ALTIVEC_P (TImode)
262    && (register_operand (operands[0], TImode) 
263        || register_operand (operands[1], TImode))"
265   switch (which_alternative)
266     {
267     case 0: return "stvx %1,%y0";
268     case 1: return "lvx %0,%y1";
269     case 2: return "vor %0,%1,%1";
270     case 3: return "#";
271     case 4: return "#";
272     case 5: return "#";
273     case 6: return "vxor %0,%0,%0";
274     case 7: return output_vec_const_move (operands);
275     default: gcc_unreachable ();
276     }
278   [(set_attr "type" "vecstore,vecload,veclogical,store,load,*,veclogical,*")])
280 ;; Load up a vector with the most significant bit set by loading up -1 and
281 ;; doing a shift left
282 (define_split
283   [(set (match_operand:VM 0 "altivec_register_operand" "")
284         (match_operand:VM 1 "easy_vector_constant_msb" ""))]
285   "VECTOR_UNIT_ALTIVEC_OR_VSX_P (<MODE>mode) && reload_completed"
286   [(const_int 0)]
288   rtx dest = operands[0];
289   machine_mode mode = GET_MODE (operands[0]);
290   rtvec v;
291   int i, num_elements;
293   if (mode == V4SFmode)
294     {
295       mode = V4SImode;
296       dest = gen_lowpart (V4SImode, dest);
297     }
299   num_elements = GET_MODE_NUNITS (mode);
300   v = rtvec_alloc (num_elements);
301   for (i = 0; i < num_elements; i++)
302     RTVEC_ELT (v, i) = constm1_rtx;
304   emit_insn (gen_vec_initv4sisi (dest, gen_rtx_PARALLEL (mode, v)));
305   emit_insn (gen_rtx_SET (dest, gen_rtx_ASHIFT (mode, dest, dest)));
306   DONE;
309 (define_split
310   [(set (match_operand:VM 0 "altivec_register_operand" "")
311         (match_operand:VM 1 "easy_vector_constant_add_self" ""))]
312   "VECTOR_UNIT_ALTIVEC_OR_VSX_P (<MODE>mode) && reload_completed"
313   [(set (match_dup 0) (match_dup 3))
314    (set (match_dup 0) (match_dup 4))]
316   rtx dup = gen_easy_altivec_constant (operands[1]);
317   rtx const_vec;
318   machine_mode op_mode = <MODE>mode;
320   /* Divide the operand of the resulting VEC_DUPLICATE, and use
321      simplify_rtx to make a CONST_VECTOR.  */
322   XEXP (dup, 0) = simplify_const_binary_operation (ASHIFTRT, QImode,
323                                                    XEXP (dup, 0), const1_rtx);
324   const_vec = simplify_rtx (dup);
326   if (op_mode == V4SFmode)
327     {
328       op_mode = V4SImode;
329       operands[0] = gen_lowpart (op_mode, operands[0]);
330     }
331   if (GET_MODE (const_vec) == op_mode)
332     operands[3] = const_vec;
333   else
334     operands[3] = gen_lowpart (op_mode, const_vec);
335   operands[4] = gen_rtx_PLUS (op_mode, operands[0], operands[0]);
338 (define_split
339   [(set (match_operand:VM 0 "altivec_register_operand" "")
340         (match_operand:VM 1 "easy_vector_constant_vsldoi" ""))]
341   "VECTOR_UNIT_ALTIVEC_OR_VSX_P (<MODE>mode) && can_create_pseudo_p ()"
342   [(set (match_dup 2) (match_dup 3))
343    (set (match_dup 4) (match_dup 5))
344    (set (match_dup 0)
345         (unspec:VM [(match_dup 2)
346                     (match_dup 4)
347                     (match_dup 6)]
348                    UNSPEC_VSLDOI))]
350   rtx op1 = operands[1];
351   int elt = (BYTES_BIG_ENDIAN) ? 0 : GET_MODE_NUNITS (<MODE>mode) - 1;
352   HOST_WIDE_INT val = const_vector_elt_as_int (op1, elt);
353   rtx rtx_val = GEN_INT (val);
354   int shift = vspltis_shifted (op1);
356   gcc_assert (shift != 0);
357   operands[2] = gen_reg_rtx (<MODE>mode);
358   operands[3] = gen_const_vec_duplicate (<MODE>mode, rtx_val);
359   operands[4] = gen_reg_rtx (<MODE>mode);
361   if (shift < 0)
362     {
363       operands[5] = CONSTM1_RTX (<MODE>mode);
364       operands[6] = GEN_INT (-shift);
365     }
366   else
367     {
368       operands[5] = CONST0_RTX (<MODE>mode);
369       operands[6] = GEN_INT (shift);
370     }
373 (define_insn "get_vrsave_internal"
374   [(set (match_operand:SI 0 "register_operand" "=r")
375         (unspec:SI [(reg:SI VRSAVE_REGNO)] UNSPEC_GET_VRSAVE))]
376   "TARGET_ALTIVEC"
378   if (TARGET_MACHO)
379      return "mfspr %0,256";
380   else
381      return "mfvrsave %0";
383   [(set_attr "type" "*")])
385 (define_insn "*set_vrsave_internal"
386   [(match_parallel 0 "vrsave_operation"
387      [(set (reg:SI VRSAVE_REGNO)
388            (unspec_volatile:SI [(match_operand:SI 1 "register_operand" "r")
389                                 (reg:SI VRSAVE_REGNO)] UNSPECV_SET_VRSAVE))])]
390   "TARGET_ALTIVEC"
392   if (TARGET_MACHO)
393     return "mtspr 256,%1";
394   else
395     return "mtvrsave %1";
397   [(set_attr "type" "*")])
399 (define_insn "*save_world"
400  [(match_parallel 0 "save_world_operation"
401                   [(clobber (reg:SI LR_REGNO))
402                    (use (match_operand:SI 1 "call_operand" "s"))])]
403  "TARGET_MACHO && (DEFAULT_ABI == ABI_DARWIN) && TARGET_32BIT"         
404  "bl %z1"
405   [(set_attr "type" "branch")
406    (set_attr "length" "4")])
408 (define_insn "*restore_world"
409  [(match_parallel 0 "restore_world_operation"
410                   [(return)
411                    (use (reg:SI LR_REGNO))
412                    (use (match_operand:SI 1 "call_operand" "s"))
413                    (clobber (match_operand:SI 2 "gpc_reg_operand" "=r"))])]
414  "TARGET_MACHO && (DEFAULT_ABI == ABI_DARWIN) && TARGET_32BIT"
415  "b %z1")
417 ;; The save_vregs and restore_vregs patterns don't use memory_operand
418 ;; because (plus (reg) (const_int)) is not a valid vector address.
419 ;; This way is more compact than describing exactly what happens in
420 ;; the out-of-line functions, ie. loading the constant into r11/r12
421 ;; then using indexed addressing, and requires less editing of rtl
422 ;; to describe the operation to dwarf2out_frame_debug_expr.
423 (define_insn "*save_vregs_<mode>_r11"
424   [(match_parallel 0 "any_parallel_operand"
425      [(clobber (reg:P LR_REGNO))
426       (use (match_operand:P 1 "symbol_ref_operand" "s"))
427       (clobber (reg:P 11))
428       (use (reg:P 0))
429       (set (mem:V4SI (plus:P (match_operand:P 2 "gpc_reg_operand" "b")
430                              (match_operand:P 3 "short_cint_operand" "I")))
431            (match_operand:V4SI 4 "altivec_register_operand" "v"))])]
432   "TARGET_ALTIVEC"
433   "bl %1"
434   [(set_attr "type" "branch")
435    (set_attr "length" "4")])
437 (define_insn "*save_vregs_<mode>_r12"
438   [(match_parallel 0 "any_parallel_operand"
439      [(clobber (reg:P LR_REGNO))
440       (use (match_operand:P 1 "symbol_ref_operand" "s"))
441       (clobber (reg:P 12))
442       (use (reg:P 0))
443       (set (mem:V4SI (plus:P (match_operand:P 2 "gpc_reg_operand" "b")
444                              (match_operand:P 3 "short_cint_operand" "I")))
445            (match_operand:V4SI 4 "altivec_register_operand" "v"))])]
446   "TARGET_ALTIVEC"
447   "bl %1"
448   [(set_attr "type" "branch")
449    (set_attr "length" "4")])
451 (define_insn "*restore_vregs_<mode>_r11"
452   [(match_parallel 0 "any_parallel_operand"
453      [(clobber (reg:P LR_REGNO))
454       (use (match_operand:P 1 "symbol_ref_operand" "s"))
455       (clobber (reg:P 11))
456       (use (reg:P 0))
457       (set (match_operand:V4SI 2 "altivec_register_operand" "=v")
458            (mem:V4SI (plus:P (match_operand:P 3 "gpc_reg_operand" "b")
459                              (match_operand:P 4 "short_cint_operand" "I"))))])]
460   "TARGET_ALTIVEC"
461   "bl %1"
462   [(set_attr "type" "branch")
463    (set_attr "length" "4")])
465 (define_insn "*restore_vregs_<mode>_r12"
466   [(match_parallel 0 "any_parallel_operand"
467      [(clobber (reg:P LR_REGNO))
468       (use (match_operand:P 1 "symbol_ref_operand" "s"))
469       (clobber (reg:P 12))
470       (use (reg:P 0))
471       (set (match_operand:V4SI 2 "altivec_register_operand" "=v")
472            (mem:V4SI (plus:P (match_operand:P 3 "gpc_reg_operand" "b")
473                              (match_operand:P 4 "short_cint_operand" "I"))))])]
474   "TARGET_ALTIVEC"
475   "bl %1"
476   [(set_attr "type" "branch")
477    (set_attr "length" "4")])
479 ;; Simple binary operations.
481 ;; add
482 (define_insn "add<mode>3"
483   [(set (match_operand:VI2 0 "register_operand" "=v")
484         (plus:VI2 (match_operand:VI2 1 "register_operand" "v")
485                   (match_operand:VI2 2 "register_operand" "v")))]
486   "<VI_unit>"
487   "vaddu<VI_char>m %0,%1,%2"
488   [(set_attr "type" "vecsimple")])
490 (define_insn "*altivec_addv4sf3"
491   [(set (match_operand:V4SF 0 "register_operand" "=v")
492         (plus:V4SF (match_operand:V4SF 1 "register_operand" "v")
493                    (match_operand:V4SF 2 "register_operand" "v")))]
494   "VECTOR_UNIT_ALTIVEC_P (V4SFmode)"
495   "vaddfp %0,%1,%2"
496   [(set_attr "type" "vecfloat")])
498 (define_insn "altivec_vaddcuw"
499   [(set (match_operand:V4SI 0 "register_operand" "=v")
500         (unspec:V4SI [(match_operand:V4SI 1 "register_operand" "v")
501                       (match_operand:V4SI 2 "register_operand" "v")]
502                      UNSPEC_VADDCUW))]
503   "VECTOR_UNIT_ALTIVEC_P (V4SImode)"
504   "vaddcuw %0,%1,%2"
505   [(set_attr "type" "vecsimple")])
507 (define_insn "altivec_vaddu<VI_char>s"
508   [(set (match_operand:VI 0 "register_operand" "=v")
509         (unspec:VI [(match_operand:VI 1 "register_operand" "v")
510                     (match_operand:VI 2 "register_operand" "v")]
511                    UNSPEC_VADDU))
512    (set (reg:SI VSCR_REGNO) (unspec:SI [(const_int 0)] UNSPEC_SET_VSCR))]
513   "<VI_unit>"
514   "vaddu<VI_char>s %0,%1,%2"
515   [(set_attr "type" "vecsimple")])
517 (define_insn "altivec_vadds<VI_char>s"
518   [(set (match_operand:VI 0 "register_operand" "=v")
519         (unspec:VI [(match_operand:VI 1 "register_operand" "v")
520                     (match_operand:VI 2 "register_operand" "v")]
521                    UNSPEC_VADDS))
522    (set (reg:SI VSCR_REGNO) (unspec:SI [(const_int 0)] UNSPEC_SET_VSCR))]
523   "VECTOR_UNIT_ALTIVEC_P (<MODE>mode)"
524   "vadds<VI_char>s %0,%1,%2"
525   [(set_attr "type" "vecsimple")])
527 ;; sub
528 (define_insn "sub<mode>3"
529   [(set (match_operand:VI2 0 "register_operand" "=v")
530         (minus:VI2 (match_operand:VI2 1 "register_operand" "v")
531                    (match_operand:VI2 2 "register_operand" "v")))]
532   "<VI_unit>"
533   "vsubu<VI_char>m %0,%1,%2"
534   [(set_attr "type" "vecsimple")])
536 (define_insn "*altivec_subv4sf3"
537   [(set (match_operand:V4SF 0 "register_operand" "=v")
538         (minus:V4SF (match_operand:V4SF 1 "register_operand" "v")
539                     (match_operand:V4SF 2 "register_operand" "v")))]
540   "VECTOR_UNIT_ALTIVEC_P (V4SFmode)"
541   "vsubfp %0,%1,%2"
542   [(set_attr "type" "vecfloat")])
544 (define_insn "altivec_vsubcuw"
545   [(set (match_operand:V4SI 0 "register_operand" "=v")
546         (unspec:V4SI [(match_operand:V4SI 1 "register_operand" "v")
547                       (match_operand:V4SI 2 "register_operand" "v")]
548                      UNSPEC_VSUBCUW))]
549   "VECTOR_UNIT_ALTIVEC_P (V4SImode)"
550   "vsubcuw %0,%1,%2"
551   [(set_attr "type" "vecsimple")])
553 (define_insn "altivec_vsubu<VI_char>s"
554   [(set (match_operand:VI 0 "register_operand" "=v")
555         (unspec:VI [(match_operand:VI 1 "register_operand" "v")
556                     (match_operand:VI 2 "register_operand" "v")]
557                    UNSPEC_VSUBU))
558    (set (reg:SI VSCR_REGNO) (unspec:SI [(const_int 0)] UNSPEC_SET_VSCR))]
559   "VECTOR_UNIT_ALTIVEC_P (<MODE>mode)"
560   "vsubu<VI_char>s %0,%1,%2"
561   [(set_attr "type" "vecsimple")])
563 (define_insn "altivec_vsubs<VI_char>s"
564   [(set (match_operand:VI 0 "register_operand" "=v")
565         (unspec:VI [(match_operand:VI 1 "register_operand" "v")
566                     (match_operand:VI 2 "register_operand" "v")]
567                    UNSPEC_VSUBS))
568    (set (reg:SI VSCR_REGNO) (unspec:SI [(const_int 0)] UNSPEC_SET_VSCR))]
569   "VECTOR_UNIT_ALTIVEC_P (<MODE>mode)"
570   "vsubs<VI_char>s %0,%1,%2"
571   [(set_attr "type" "vecsimple")])
574 (define_insn "altivec_vavgu<VI_char>"
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_VAVGU))]
579   "TARGET_ALTIVEC"
580   "vavgu<VI_char> %0,%1,%2"
581   [(set_attr "type" "vecsimple")])
583 (define_insn "altivec_vavgs<VI_char>"
584   [(set (match_operand:VI 0 "register_operand" "=v")
585         (unspec:VI [(match_operand:VI 1 "register_operand" "v")
586                     (match_operand:VI 2 "register_operand" "v")]
587                    UNSPEC_VAVGS))]
588   "VECTOR_UNIT_ALTIVEC_P (<MODE>mode)"
589   "vavgs<VI_char> %0,%1,%2"
590   [(set_attr "type" "vecsimple")])
592 (define_insn "altivec_vcmpbfp"
593   [(set (match_operand:V4SI 0 "register_operand" "=v")
594         (unspec:V4SI [(match_operand:V4SF 1 "register_operand" "v")
595                       (match_operand:V4SF 2 "register_operand" "v")] 
596                       UNSPEC_VCMPBFP))]
597   "VECTOR_UNIT_ALTIVEC_P (V4SImode)"
598   "vcmpbfp %0,%1,%2"
599   [(set_attr "type" "veccmp")])
601 (define_insn "*altivec_eq<mode>"
602   [(set (match_operand:VI2 0 "altivec_register_operand" "=v")
603         (eq:VI2 (match_operand:VI2 1 "altivec_register_operand" "v")
604                 (match_operand:VI2 2 "altivec_register_operand" "v")))]
605   "<VI_unit>"
606   "vcmpequ<VI_char> %0,%1,%2"
607   [(set_attr "type" "veccmpfx")])
609 (define_insn "*altivec_gt<mode>"
610   [(set (match_operand:VI2 0 "altivec_register_operand" "=v")
611         (gt:VI2 (match_operand:VI2 1 "altivec_register_operand" "v")
612                 (match_operand:VI2 2 "altivec_register_operand" "v")))]
613   "<VI_unit>"
614   "vcmpgts<VI_char> %0,%1,%2"
615   [(set_attr "type" "veccmpfx")])
617 (define_insn "*altivec_gtu<mode>"
618   [(set (match_operand:VI2 0 "altivec_register_operand" "=v")
619         (gtu:VI2 (match_operand:VI2 1 "altivec_register_operand" "v")
620                  (match_operand:VI2 2 "altivec_register_operand" "v")))]
621   "<VI_unit>"
622   "vcmpgtu<VI_char> %0,%1,%2"
623   [(set_attr "type" "veccmpfx")])
625 (define_insn "*altivec_eqv4sf"
626   [(set (match_operand:V4SF 0 "altivec_register_operand" "=v")
627         (eq:V4SF (match_operand:V4SF 1 "altivec_register_operand" "v")
628                  (match_operand:V4SF 2 "altivec_register_operand" "v")))]
629   "VECTOR_UNIT_ALTIVEC_P (V4SFmode)"
630   "vcmpeqfp %0,%1,%2"
631   [(set_attr "type" "veccmp")])
633 (define_insn "*altivec_gtv4sf"
634   [(set (match_operand:V4SF 0 "altivec_register_operand" "=v")
635         (gt:V4SF (match_operand:V4SF 1 "altivec_register_operand" "v")
636                  (match_operand:V4SF 2 "altivec_register_operand" "v")))]
637   "VECTOR_UNIT_ALTIVEC_P (V4SFmode)"
638   "vcmpgtfp %0,%1,%2"
639   [(set_attr "type" "veccmp")])
641 (define_insn "*altivec_gev4sf"
642   [(set (match_operand:V4SF 0 "altivec_register_operand" "=v")
643         (ge:V4SF (match_operand:V4SF 1 "altivec_register_operand" "v")
644                  (match_operand:V4SF 2 "altivec_register_operand" "v")))]
645   "VECTOR_UNIT_ALTIVEC_P (V4SFmode)"
646   "vcmpgefp %0,%1,%2"
647   [(set_attr "type" "veccmp")])
649 (define_insn "*altivec_vsel<mode>"
650   [(set (match_operand:VM 0 "altivec_register_operand" "=v")
651         (if_then_else:VM
652          (ne:CC (match_operand:VM 1 "altivec_register_operand" "v")
653                 (match_operand:VM 4 "zero_constant" ""))
654          (match_operand:VM 2 "altivec_register_operand" "v")
655          (match_operand:VM 3 "altivec_register_operand" "v")))]
656   "VECTOR_MEM_ALTIVEC_P (<MODE>mode)"
657   "vsel %0,%3,%2,%1"
658   [(set_attr "type" "vecmove")])
660 (define_insn "*altivec_vsel<mode>_uns"
661   [(set (match_operand:VM 0 "altivec_register_operand" "=v")
662         (if_then_else:VM
663          (ne:CCUNS (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 ;; Fused multiply add.
673 (define_insn "*altivec_fmav4sf4"
674   [(set (match_operand:V4SF 0 "register_operand" "=v")
675         (fma:V4SF (match_operand:V4SF 1 "register_operand" "v")
676                   (match_operand:V4SF 2 "register_operand" "v")
677                   (match_operand:V4SF 3 "register_operand" "v")))]
678   "VECTOR_UNIT_ALTIVEC_P (V4SFmode)"
679   "vmaddfp %0,%1,%2,%3"
680   [(set_attr "type" "vecfloat")])
682 ;; We do multiply as a fused multiply-add with an add of a -0.0 vector.
684 (define_expand "altivec_mulv4sf3"
685   [(set (match_operand:V4SF 0 "register_operand" "")
686         (fma:V4SF (match_operand:V4SF 1 "register_operand" "")
687                   (match_operand:V4SF 2 "register_operand" "")
688                   (match_dup 3)))]
689   "VECTOR_UNIT_ALTIVEC_P (V4SFmode)"
691   rtx neg0;
693   /* Generate [-0.0, -0.0, -0.0, -0.0].  */
694   neg0 = gen_reg_rtx (V4SImode);
695   emit_insn (gen_altivec_vspltisw (neg0, constm1_rtx));
696   emit_insn (gen_vashlv4si3 (neg0, neg0, neg0));
698   operands[3] = gen_lowpart (V4SFmode, neg0);
701 ;; 32-bit integer multiplication
702 ;; A_high = Operand_0 & 0xFFFF0000 >> 16
703 ;; A_low = Operand_0 & 0xFFFF
704 ;; B_high = Operand_1 & 0xFFFF0000 >> 16
705 ;; B_low = Operand_1 & 0xFFFF
706 ;; result = A_low * B_low + (A_high * B_low + B_high * A_low) << 16
708 ;; (define_insn "mulv4si3"
709 ;;   [(set (match_operand:V4SI 0 "register_operand" "=v")
710 ;;         (mult:V4SI (match_operand:V4SI 1 "register_operand" "v")
711 ;;                    (match_operand:V4SI 2 "register_operand" "v")))]
712 (define_insn "mulv4si3_p8"
713   [(set (match_operand:V4SI 0 "register_operand" "=v")
714         (mult:V4SI (match_operand:V4SI 1 "register_operand" "v")
715                    (match_operand:V4SI 2 "register_operand" "v")))]
716   "TARGET_P8_VECTOR"
717   "vmuluwm %0,%1,%2"
718   [(set_attr "type" "veccomplex")])
720 (define_expand "mulv4si3"
721   [(use (match_operand:V4SI 0 "register_operand" ""))
722    (use (match_operand:V4SI 1 "register_operand" ""))
723    (use (match_operand:V4SI 2 "register_operand" ""))]
724    "TARGET_ALTIVEC"
726   rtx zero;
727   rtx swap;
728   rtx small_swap;
729   rtx sixteen;
730   rtx one;
731   rtx two;
732   rtx low_product;
733   rtx high_product;
734        
735   if (TARGET_P8_VECTOR)
736     {
737       emit_insn (gen_mulv4si3_p8 (operands[0], operands[1], operands[2]));
738       DONE;
739     }
741   zero = gen_reg_rtx (V4SImode);
742   emit_insn (gen_altivec_vspltisw (zero, const0_rtx));
744   sixteen = gen_reg_rtx (V4SImode);   
745   emit_insn (gen_altivec_vspltisw (sixteen,  gen_rtx_CONST_INT (V4SImode, -16)));
747   swap = gen_reg_rtx (V4SImode);
748   emit_insn (gen_vrotlv4si3 (swap, operands[2], sixteen));
750   one = gen_reg_rtx (V8HImode);
751   convert_move (one, operands[1], 0);
753   two = gen_reg_rtx (V8HImode);
754   convert_move (two, operands[2], 0);
756   small_swap = gen_reg_rtx (V8HImode);
757   convert_move (small_swap, swap, 0);
759   low_product = gen_reg_rtx (V4SImode);
760   emit_insn (gen_altivec_vmulouh (low_product, one, two));
762   high_product = gen_reg_rtx (V4SImode);
763   emit_insn (gen_altivec_vmsumuhm (high_product, one, small_swap, zero));
765   emit_insn (gen_vashlv4si3 (high_product, high_product, sixteen));
767   emit_insn (gen_addv4si3 (operands[0], high_product, low_product));
768    
769   DONE;
772 (define_expand "mulv8hi3"
773   [(use (match_operand:V8HI 0 "register_operand" ""))
774    (use (match_operand:V8HI 1 "register_operand" ""))
775    (use (match_operand:V8HI 2 "register_operand" ""))]
776    "TARGET_ALTIVEC"
778   rtx zero = gen_reg_rtx (V8HImode);
780   emit_insn (gen_altivec_vspltish (zero, const0_rtx));
781   emit_insn (gen_altivec_vmladduhm(operands[0], operands[1], operands[2], zero));
783   DONE;
786 ;; Fused multiply subtract 
787 (define_insn "*altivec_vnmsubfp"
788   [(set (match_operand:V4SF 0 "register_operand" "=v")
789         (neg:V4SF
790          (fma:V4SF (match_operand:V4SF 1 "register_operand" "v")
791                    (match_operand:V4SF 2 "register_operand" "v")
792                    (neg:V4SF
793                     (match_operand:V4SF 3 "register_operand" "v")))))]
794   "VECTOR_UNIT_ALTIVEC_P (V4SFmode)"
795   "vnmsubfp %0,%1,%2,%3"
796   [(set_attr "type" "vecfloat")])
798 (define_insn "altivec_vmsumu<VI_char>m"
799   [(set (match_operand:V4SI 0 "register_operand" "=v")
800         (unspec:V4SI [(match_operand:VIshort 1 "register_operand" "v")
801                       (match_operand:VIshort 2 "register_operand" "v")
802                       (match_operand:V4SI 3 "register_operand" "v")]
803                      UNSPEC_VMSUMU))]
804   "TARGET_ALTIVEC"
805   "vmsumu<VI_char>m %0,%1,%2,%3"
806   [(set_attr "type" "veccomplex")])
808 (define_insn "altivec_vmsumm<VI_char>m"
809   [(set (match_operand:V4SI 0 "register_operand" "=v")
810         (unspec:V4SI [(match_operand:VIshort 1 "register_operand" "v")
811                       (match_operand:VIshort 2 "register_operand" "v")
812                       (match_operand:V4SI 3 "register_operand" "v")]
813                      UNSPEC_VMSUMM))]
814   "TARGET_ALTIVEC"
815   "vmsumm<VI_char>m %0,%1,%2,%3"
816   [(set_attr "type" "veccomplex")])
818 (define_insn "altivec_vmsumshm"
819   [(set (match_operand:V4SI 0 "register_operand" "=v")
820         (unspec:V4SI [(match_operand:V8HI 1 "register_operand" "v")
821                       (match_operand:V8HI 2 "register_operand" "v")
822                       (match_operand:V4SI 3 "register_operand" "v")]
823                      UNSPEC_VMSUMSHM))]
824   "TARGET_ALTIVEC"
825   "vmsumshm %0,%1,%2,%3"
826   [(set_attr "type" "veccomplex")])
828 (define_insn "altivec_vmsumuhs"
829   [(set (match_operand:V4SI 0 "register_operand" "=v")
830         (unspec:V4SI [(match_operand:V8HI 1 "register_operand" "v")
831                       (match_operand:V8HI 2 "register_operand" "v")
832                       (match_operand:V4SI 3 "register_operand" "v")]
833                      UNSPEC_VMSUMUHS))
834    (set (reg:SI VSCR_REGNO) (unspec:SI [(const_int 0)] UNSPEC_SET_VSCR))]
835   "TARGET_ALTIVEC"
836   "vmsumuhs %0,%1,%2,%3"
837   [(set_attr "type" "veccomplex")])
839 (define_insn "altivec_vmsumshs"
840   [(set (match_operand:V4SI 0 "register_operand" "=v")
841         (unspec:V4SI [(match_operand:V8HI 1 "register_operand" "v")
842                       (match_operand:V8HI 2 "register_operand" "v")
843                       (match_operand:V4SI 3 "register_operand" "v")]
844                      UNSPEC_VMSUMSHS))
845    (set (reg:SI VSCR_REGNO) (unspec:SI [(const_int 0)] UNSPEC_SET_VSCR))]
846   "TARGET_ALTIVEC"
847   "vmsumshs %0,%1,%2,%3"
848   [(set_attr "type" "veccomplex")])
850 ;; max
852 (define_insn "umax<mode>3"
853   [(set (match_operand:VI2 0 "register_operand" "=v")
854         (umax:VI2 (match_operand:VI2 1 "register_operand" "v")
855                   (match_operand:VI2 2 "register_operand" "v")))]
856   "<VI_unit>"
857   "vmaxu<VI_char> %0,%1,%2"
858   [(set_attr "type" "vecsimple")])
860 (define_insn "smax<mode>3"
861   [(set (match_operand:VI2 0 "register_operand" "=v")
862         (smax:VI2 (match_operand:VI2 1 "register_operand" "v")
863                   (match_operand:VI2 2 "register_operand" "v")))]
864   "<VI_unit>"
865   "vmaxs<VI_char> %0,%1,%2"
866   [(set_attr "type" "vecsimple")])
868 (define_insn "*altivec_smaxv4sf3"
869   [(set (match_operand:V4SF 0 "register_operand" "=v")
870         (smax:V4SF (match_operand:V4SF 1 "register_operand" "v")
871                    (match_operand:V4SF 2 "register_operand" "v")))]
872   "VECTOR_UNIT_ALTIVEC_P (V4SFmode)"
873   "vmaxfp %0,%1,%2"
874   [(set_attr "type" "veccmp")])
876 (define_insn "umin<mode>3"
877   [(set (match_operand:VI2 0 "register_operand" "=v")
878         (umin:VI2 (match_operand:VI2 1 "register_operand" "v")
879                   (match_operand:VI2 2 "register_operand" "v")))]
880   "<VI_unit>"
881   "vminu<VI_char> %0,%1,%2"
882   [(set_attr "type" "vecsimple")])
884 (define_insn "smin<mode>3"
885   [(set (match_operand:VI2 0 "register_operand" "=v")
886         (smin:VI2 (match_operand:VI2 1 "register_operand" "v")
887                   (match_operand:VI2 2 "register_operand" "v")))]
888   "<VI_unit>"
889   "vmins<VI_char> %0,%1,%2"
890   [(set_attr "type" "vecsimple")])
892 (define_insn "*altivec_sminv4sf3"
893   [(set (match_operand:V4SF 0 "register_operand" "=v")
894         (smin:V4SF (match_operand:V4SF 1 "register_operand" "v")
895                    (match_operand:V4SF 2 "register_operand" "v")))]
896   "VECTOR_UNIT_ALTIVEC_P (V4SFmode)"
897   "vminfp %0,%1,%2"
898   [(set_attr "type" "veccmp")])
900 (define_insn "altivec_vmhaddshs"
901   [(set (match_operand:V8HI 0 "register_operand" "=v")
902         (unspec:V8HI [(match_operand:V8HI 1 "register_operand" "v")
903                       (match_operand:V8HI 2 "register_operand" "v")
904                       (match_operand:V8HI 3 "register_operand" "v")]
905                      UNSPEC_VMHADDSHS))
906    (set (reg:SI VSCR_REGNO) (unspec:SI [(const_int 0)] UNSPEC_SET_VSCR))]
907   "TARGET_ALTIVEC"
908   "vmhaddshs %0,%1,%2,%3"
909   [(set_attr "type" "veccomplex")])
911 (define_insn "altivec_vmhraddshs"
912   [(set (match_operand:V8HI 0 "register_operand" "=v")
913         (unspec:V8HI [(match_operand:V8HI 1 "register_operand" "v")
914                       (match_operand:V8HI 2 "register_operand" "v")
915                       (match_operand:V8HI 3 "register_operand" "v")]
916                      UNSPEC_VMHRADDSHS))
917    (set (reg:SI VSCR_REGNO) (unspec:SI [(const_int 0)] UNSPEC_SET_VSCR))]
918   "TARGET_ALTIVEC"
919   "vmhraddshs %0,%1,%2,%3"
920   [(set_attr "type" "veccomplex")])
922 (define_insn "altivec_vmladduhm"
923   [(set (match_operand:V8HI 0 "register_operand" "=v")
924         (plus:V8HI (mult:V8HI (match_operand:V8HI 1 "register_operand" "v")
925                               (match_operand:V8HI 2 "register_operand" "v"))
926                    (match_operand:V8HI 3 "register_operand" "v")))]
927   "TARGET_ALTIVEC"
928   "vmladduhm %0,%1,%2,%3"
929   [(set_attr "type" "veccomplex")])
931 (define_expand "altivec_vmrghb"
932   [(use (match_operand:V16QI 0 "register_operand" ""))
933    (use (match_operand:V16QI 1 "register_operand" ""))
934    (use (match_operand:V16QI 2 "register_operand" ""))]
935   "TARGET_ALTIVEC"
937   rtvec v;
938   rtx x;
940   /* Special handling for LE with -maltivec=be.  */
941   if (!BYTES_BIG_ENDIAN && VECTOR_ELT_ORDER_BIG)
942     {
943       v = gen_rtvec (16, GEN_INT (8), GEN_INT (24), GEN_INT (9), GEN_INT (25),
944                      GEN_INT (10), GEN_INT (26), GEN_INT (11), GEN_INT (27),
945                      GEN_INT (12), GEN_INT (28), GEN_INT (13), GEN_INT (29),
946                      GEN_INT (14), GEN_INT (30), GEN_INT (15), GEN_INT (31));
947       x = gen_rtx_VEC_CONCAT (V32QImode, operands[2], operands[1]);
948     }
949   else
950     {
951       v = gen_rtvec (16, GEN_INT (0), GEN_INT (16), GEN_INT (1), GEN_INT (17),
952                      GEN_INT (2), GEN_INT (18), GEN_INT (3), GEN_INT (19),
953                      GEN_INT (4), GEN_INT (20), GEN_INT (5), GEN_INT (21),
954                      GEN_INT (6), GEN_INT (22), GEN_INT (7), GEN_INT (23));
955       x = gen_rtx_VEC_CONCAT (V32QImode, operands[1], operands[2]);
956     }
958   x = gen_rtx_VEC_SELECT (V16QImode, x, gen_rtx_PARALLEL (VOIDmode, v));
959   emit_insn (gen_rtx_SET (operands[0], x));
960   DONE;
963 (define_insn "*altivec_vmrghb_internal"
964   [(set (match_operand:V16QI 0 "register_operand" "=v")
965         (vec_select:V16QI
966           (vec_concat:V32QI
967             (match_operand:V16QI 1 "register_operand" "v")
968             (match_operand:V16QI 2 "register_operand" "v"))
969           (parallel [(const_int 0) (const_int 16)
970                      (const_int 1) (const_int 17)
971                      (const_int 2) (const_int 18)
972                      (const_int 3) (const_int 19)
973                      (const_int 4) (const_int 20)
974                      (const_int 5) (const_int 21)
975                      (const_int 6) (const_int 22)
976                      (const_int 7) (const_int 23)])))]
977   "TARGET_ALTIVEC"
979   if (BYTES_BIG_ENDIAN)
980     return "vmrghb %0,%1,%2";
981   else
982     return "vmrglb %0,%2,%1";
984   [(set_attr "type" "vecperm")])
986 (define_insn "altivec_vmrghb_direct"
987   [(set (match_operand:V16QI 0 "register_operand" "=v")
988         (unspec:V16QI [(match_operand:V16QI 1 "register_operand" "v")
989                        (match_operand:V16QI 2 "register_operand" "v")]
990                       UNSPEC_VMRGH_DIRECT))]
991   "TARGET_ALTIVEC"
992   "vmrghb %0,%1,%2"
993   [(set_attr "type" "vecperm")])
995 (define_expand "altivec_vmrghh"
996   [(use (match_operand:V8HI 0 "register_operand" ""))
997    (use (match_operand:V8HI 1 "register_operand" ""))
998    (use (match_operand:V8HI 2 "register_operand" ""))]
999   "TARGET_ALTIVEC"
1001   rtvec v;
1002   rtx x;
1004   /* Special handling for LE with -maltivec=be.  */
1005   if (!BYTES_BIG_ENDIAN && VECTOR_ELT_ORDER_BIG)
1006     {
1007       v = gen_rtvec (8, GEN_INT (4), GEN_INT (12), GEN_INT (5), GEN_INT (13),
1008                      GEN_INT (6), GEN_INT (14), GEN_INT (7), GEN_INT (15));
1009       x = gen_rtx_VEC_CONCAT (V16HImode, operands[2], operands[1]);
1010     }
1011   else
1012     {
1013       v = gen_rtvec (8, GEN_INT (0), GEN_INT (8), GEN_INT (1), GEN_INT (9),
1014                      GEN_INT (2), GEN_INT (10), GEN_INT (3), GEN_INT (11));
1015       x = gen_rtx_VEC_CONCAT (V16HImode, operands[1], operands[2]);
1016     }
1018   x = gen_rtx_VEC_SELECT (V8HImode, x, gen_rtx_PARALLEL (VOIDmode, v));
1019   emit_insn (gen_rtx_SET (operands[0], x));
1020   DONE;
1023 (define_insn "*altivec_vmrghh_internal"
1024   [(set (match_operand:V8HI 0 "register_operand" "=v")
1025         (vec_select:V8HI
1026           (vec_concat:V16HI
1027             (match_operand:V8HI 1 "register_operand" "v")
1028             (match_operand:V8HI 2 "register_operand" "v"))
1029           (parallel [(const_int 0) (const_int 8)
1030                      (const_int 1) (const_int 9)
1031                      (const_int 2) (const_int 10)
1032                      (const_int 3) (const_int 11)])))]
1033   "TARGET_ALTIVEC"
1035   if (BYTES_BIG_ENDIAN)
1036     return "vmrghh %0,%1,%2";
1037   else
1038     return "vmrglh %0,%2,%1";
1040   [(set_attr "type" "vecperm")])
1042 (define_insn "altivec_vmrghh_direct"
1043   [(set (match_operand:V8HI 0 "register_operand" "=v")
1044         (unspec:V8HI [(match_operand:V8HI 1 "register_operand" "v")
1045                       (match_operand:V8HI 2 "register_operand" "v")]
1046                      UNSPEC_VMRGH_DIRECT))]
1047   "TARGET_ALTIVEC"
1048   "vmrghh %0,%1,%2"
1049   [(set_attr "type" "vecperm")])
1051 (define_expand "altivec_vmrghw"
1052   [(use (match_operand:V4SI 0 "register_operand" ""))
1053    (use (match_operand:V4SI 1 "register_operand" ""))
1054    (use (match_operand:V4SI 2 "register_operand" ""))]
1055   "VECTOR_MEM_ALTIVEC_P (V4SImode)"
1057   rtvec v;
1058   rtx x;
1060   /* Special handling for LE with -maltivec=be.  */
1061   if (!BYTES_BIG_ENDIAN && VECTOR_ELT_ORDER_BIG)
1062     {
1063       v = gen_rtvec (4, GEN_INT (2), GEN_INT (6), GEN_INT (3), GEN_INT (7));
1064       x = gen_rtx_VEC_CONCAT (V8SImode, operands[2], operands[1]);
1065     }
1066   else
1067     {
1068       v = gen_rtvec (4, GEN_INT (0), GEN_INT (4), GEN_INT (1), GEN_INT (5));
1069       x = gen_rtx_VEC_CONCAT (V8SImode, operands[1], operands[2]);
1070     }
1072   x = gen_rtx_VEC_SELECT (V4SImode, x, gen_rtx_PARALLEL (VOIDmode, v));
1073   emit_insn (gen_rtx_SET (operands[0], x));
1074   DONE;
1077 (define_insn "*altivec_vmrghw_internal"
1078   [(set (match_operand:V4SI 0 "register_operand" "=v")
1079         (vec_select:V4SI
1080           (vec_concat:V8SI
1081             (match_operand:V4SI 1 "register_operand" "v")
1082             (match_operand:V4SI 2 "register_operand" "v"))
1083           (parallel [(const_int 0) (const_int 4)
1084                      (const_int 1) (const_int 5)])))]
1085   "VECTOR_MEM_ALTIVEC_P (V4SImode)"
1087   if (BYTES_BIG_ENDIAN)
1088     return "vmrghw %0,%1,%2";
1089   else
1090     return "vmrglw %0,%2,%1";
1092   [(set_attr "type" "vecperm")])
1094 (define_insn "altivec_vmrghw_direct"
1095   [(set (match_operand:V4SI 0 "register_operand" "=v")
1096         (unspec:V4SI [(match_operand:V4SI 1 "register_operand" "v")
1097                       (match_operand:V4SI 2 "register_operand" "v")]
1098                      UNSPEC_VMRGH_DIRECT))]
1099   "TARGET_ALTIVEC"
1100   "vmrghw %0,%1,%2"
1101   [(set_attr "type" "vecperm")])
1103 (define_insn "*altivec_vmrghsf"
1104   [(set (match_operand:V4SF 0 "register_operand" "=v")
1105         (vec_select:V4SF
1106           (vec_concat:V8SF
1107             (match_operand:V4SF 1 "register_operand" "v")
1108             (match_operand:V4SF 2 "register_operand" "v"))
1109           (parallel [(const_int 0) (const_int 4)
1110                      (const_int 1) (const_int 5)])))]
1111   "VECTOR_MEM_ALTIVEC_P (V4SFmode)"
1113   if (BYTES_BIG_ENDIAN)
1114     return "vmrghw %0,%1,%2";
1115   else
1116     return "vmrglw %0,%2,%1";
1118   [(set_attr "type" "vecperm")])
1120 (define_expand "altivec_vmrglb"
1121   [(use (match_operand:V16QI 0 "register_operand" ""))
1122    (use (match_operand:V16QI 1 "register_operand" ""))
1123    (use (match_operand:V16QI 2 "register_operand" ""))]
1124   "TARGET_ALTIVEC"
1126   rtvec v;
1127   rtx x;
1129   /* Special handling for LE with -maltivec=be.  */
1130   if (!BYTES_BIG_ENDIAN && VECTOR_ELT_ORDER_BIG)
1131     {
1132       v = gen_rtvec (16, GEN_INT (0), GEN_INT (16), GEN_INT (1), GEN_INT (17),
1133                      GEN_INT (2), GEN_INT (18), GEN_INT (3), GEN_INT (19),
1134                      GEN_INT (4), GEN_INT (20), GEN_INT (5), GEN_INT (21),
1135                      GEN_INT (6), GEN_INT (22), GEN_INT (7), GEN_INT (23));
1136       x = gen_rtx_VEC_CONCAT (V32QImode, operands[2], operands[1]);
1137     }
1138   else
1139     {
1140       v = gen_rtvec (16, GEN_INT (8), GEN_INT (24), GEN_INT (9), GEN_INT (25),
1141                      GEN_INT (10), GEN_INT (26), GEN_INT (11), GEN_INT (27),
1142                      GEN_INT (12), GEN_INT (28), GEN_INT (13), GEN_INT (29),
1143                      GEN_INT (14), GEN_INT (30), GEN_INT (15), GEN_INT (31));
1144       x = gen_rtx_VEC_CONCAT (V32QImode, operands[1], operands[2]);
1145     }
1147   x = gen_rtx_VEC_SELECT (V16QImode, x, gen_rtx_PARALLEL (VOIDmode, v));
1148   emit_insn (gen_rtx_SET (operands[0], x));
1149   DONE;
1152 (define_insn "*altivec_vmrglb_internal"
1153   [(set (match_operand:V16QI 0 "register_operand" "=v")
1154         (vec_select:V16QI
1155           (vec_concat:V32QI
1156             (match_operand:V16QI 1 "register_operand" "v")
1157             (match_operand:V16QI 2 "register_operand" "v"))
1158           (parallel [(const_int  8) (const_int 24)
1159                      (const_int  9) (const_int 25)
1160                      (const_int 10) (const_int 26)
1161                      (const_int 11) (const_int 27)
1162                      (const_int 12) (const_int 28)
1163                      (const_int 13) (const_int 29)
1164                      (const_int 14) (const_int 30)
1165                      (const_int 15) (const_int 31)])))]
1166   "TARGET_ALTIVEC"
1168   if (BYTES_BIG_ENDIAN)
1169     return "vmrglb %0,%1,%2";
1170   else
1171     return "vmrghb %0,%2,%1";
1173   [(set_attr "type" "vecperm")])
1175 (define_insn "altivec_vmrglb_direct"
1176   [(set (match_operand:V16QI 0 "register_operand" "=v")
1177         (unspec:V16QI [(match_operand:V16QI 1 "register_operand" "v")
1178                        (match_operand:V16QI 2 "register_operand" "v")]
1179                       UNSPEC_VMRGL_DIRECT))]
1180   "TARGET_ALTIVEC"
1181   "vmrglb %0,%1,%2"
1182   [(set_attr "type" "vecperm")])
1184 (define_expand "altivec_vmrglh"
1185   [(use (match_operand:V8HI 0 "register_operand" ""))
1186    (use (match_operand:V8HI 1 "register_operand" ""))
1187    (use (match_operand:V8HI 2 "register_operand" ""))]
1188   "TARGET_ALTIVEC"
1190   rtvec v;
1191   rtx x;
1193   /* Special handling for LE with -maltivec=be.  */
1194   if (!BYTES_BIG_ENDIAN && VECTOR_ELT_ORDER_BIG)
1195     {
1196       v = gen_rtvec (8, GEN_INT (0), GEN_INT (8), GEN_INT (1), GEN_INT (9),
1197                      GEN_INT (2), GEN_INT (10), GEN_INT (3), GEN_INT (11));
1198       x = gen_rtx_VEC_CONCAT (V16HImode, operands[2], operands[1]);
1199     }
1200   else
1201     {
1202       v = gen_rtvec (8, GEN_INT (4), GEN_INT (12), GEN_INT (5), GEN_INT (13),
1203                      GEN_INT (6), GEN_INT (14), GEN_INT (7), GEN_INT (15));
1204       x = gen_rtx_VEC_CONCAT (V16HImode, operands[1], operands[2]);
1205     }
1207   x = gen_rtx_VEC_SELECT (V8HImode, x, gen_rtx_PARALLEL (VOIDmode, v));
1208   emit_insn (gen_rtx_SET (operands[0], x));
1209   DONE;
1212 (define_insn "*altivec_vmrglh_internal"
1213   [(set (match_operand:V8HI 0 "register_operand" "=v")
1214         (vec_select:V8HI
1215           (vec_concat:V16HI
1216             (match_operand:V8HI 1 "register_operand" "v")
1217             (match_operand:V8HI 2 "register_operand" "v"))
1218           (parallel [(const_int 4) (const_int 12)
1219                      (const_int 5) (const_int 13)
1220                      (const_int 6) (const_int 14)
1221                      (const_int 7) (const_int 15)])))]
1222   "TARGET_ALTIVEC"
1224   if (BYTES_BIG_ENDIAN)
1225     return "vmrglh %0,%1,%2";
1226   else
1227     return "vmrghh %0,%2,%1";
1229   [(set_attr "type" "vecperm")])
1231 (define_insn "altivec_vmrglh_direct"
1232   [(set (match_operand:V8HI 0 "register_operand" "=v")
1233         (unspec:V8HI [(match_operand:V8HI 1 "register_operand" "v")
1234                       (match_operand:V8HI 2 "register_operand" "v")]
1235                      UNSPEC_VMRGL_DIRECT))]
1236   "TARGET_ALTIVEC"
1237   "vmrglh %0,%1,%2"
1238   [(set_attr "type" "vecperm")])
1240 (define_expand "altivec_vmrglw"
1241   [(use (match_operand:V4SI 0 "register_operand" ""))
1242    (use (match_operand:V4SI 1 "register_operand" ""))
1243    (use (match_operand:V4SI 2 "register_operand" ""))]
1244   "VECTOR_MEM_ALTIVEC_P (V4SImode)"
1246   rtvec v;
1247   rtx x;
1249   /* Special handling for LE with -maltivec=be.  */
1250   if (!BYTES_BIG_ENDIAN && VECTOR_ELT_ORDER_BIG)
1251     {
1252       v = gen_rtvec (4, GEN_INT (0), GEN_INT (4), GEN_INT (1), GEN_INT (5));
1253       x = gen_rtx_VEC_CONCAT (V8SImode, operands[2], operands[1]);
1254     }
1255   else
1256     {
1257       v = gen_rtvec (4, GEN_INT (2), GEN_INT (6), GEN_INT (3), GEN_INT (7));
1258       x = gen_rtx_VEC_CONCAT (V8SImode, operands[1], operands[2]);
1259     }
1261   x = gen_rtx_VEC_SELECT (V4SImode, x, gen_rtx_PARALLEL (VOIDmode, v));
1262   emit_insn (gen_rtx_SET (operands[0], x));
1263   DONE;
1266 (define_insn "*altivec_vmrglw_internal"
1267   [(set (match_operand:V4SI 0 "register_operand" "=v")
1268         (vec_select:V4SI
1269           (vec_concat:V8SI
1270             (match_operand:V4SI 1 "register_operand" "v")
1271             (match_operand:V4SI 2 "register_operand" "v"))
1272           (parallel [(const_int 2) (const_int 6)
1273                      (const_int 3) (const_int 7)])))]
1274   "VECTOR_MEM_ALTIVEC_P (V4SImode)"
1276   if (BYTES_BIG_ENDIAN)
1277     return "vmrglw %0,%1,%2";
1278   else
1279     return "vmrghw %0,%2,%1";
1281   [(set_attr "type" "vecperm")])
1283 (define_insn "altivec_vmrglw_direct"
1284   [(set (match_operand:V4SI 0 "register_operand" "=v")
1285         (unspec:V4SI [(match_operand:V4SI 1 "register_operand" "v")
1286                       (match_operand:V4SI 2 "register_operand" "v")]
1287                      UNSPEC_VMRGL_DIRECT))]
1288   "TARGET_ALTIVEC"
1289   "vmrglw %0,%1,%2"
1290   [(set_attr "type" "vecperm")])
1292 (define_insn "*altivec_vmrglsf"
1293   [(set (match_operand:V4SF 0 "register_operand" "=v")
1294         (vec_select:V4SF
1295          (vec_concat:V8SF
1296            (match_operand:V4SF 1 "register_operand" "v")
1297            (match_operand:V4SF 2 "register_operand" "v"))
1298          (parallel [(const_int 2) (const_int 6)
1299                     (const_int 3) (const_int 7)])))]
1300   "VECTOR_MEM_ALTIVEC_P (V4SFmode)"
1302   if (BYTES_BIG_ENDIAN)
1303     return "vmrglw %0,%1,%2";
1304   else
1305     return "vmrghw %0,%2,%1";
1307   [(set_attr "type" "vecperm")])
1309 ;; Power8 vector merge even/odd
1310 (define_insn "p8_vmrgew"
1311   [(set (match_operand:V4SI 0 "register_operand" "=v")
1312         (vec_select:V4SI
1313           (vec_concat:V8SI
1314             (match_operand:V4SI 1 "register_operand" "v")
1315             (match_operand:V4SI 2 "register_operand" "v"))
1316           (parallel [(const_int 0) (const_int 4)
1317                      (const_int 2) (const_int 6)])))]
1318   "TARGET_P8_VECTOR"
1320   if (BYTES_BIG_ENDIAN)
1321     return "vmrgew %0,%1,%2";
1322   else
1323     return "vmrgow %0,%2,%1";
1325   [(set_attr "type" "vecperm")])
1327 (define_insn "p8_vmrgow"
1328   [(set (match_operand:V4SI 0 "register_operand" "=v")
1329         (vec_select:V4SI
1330           (vec_concat:V8SI
1331             (match_operand:V4SI 1 "register_operand" "v")
1332             (match_operand:V4SI 2 "register_operand" "v"))
1333           (parallel [(const_int 1) (const_int 5)
1334                      (const_int 3) (const_int 7)])))]
1335   "TARGET_P8_VECTOR"
1337   if (BYTES_BIG_ENDIAN)
1338     return "vmrgow %0,%1,%2";
1339   else
1340     return "vmrgew %0,%2,%1";
1342   [(set_attr "type" "vecperm")])
1344 (define_insn "p8_vmrgew_v4sf_direct"
1345   [(set (match_operand:V4SF 0 "register_operand" "=v")
1346         (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "v")
1347                       (match_operand:V4SF 2 "register_operand" "v")]
1348                      UNSPEC_VMRGEW_DIRECT))]
1349   "TARGET_P8_VECTOR"
1350   "vmrgew %0,%1,%2"
1351   [(set_attr "type" "vecperm")])
1353 (define_expand "vec_widen_umult_even_v16qi"
1354   [(use (match_operand:V8HI 0 "register_operand" ""))
1355    (use (match_operand:V16QI 1 "register_operand" ""))
1356    (use (match_operand:V16QI 2 "register_operand" ""))]
1357   "TARGET_ALTIVEC"
1359   if (VECTOR_ELT_ORDER_BIG)
1360     emit_insn (gen_altivec_vmuleub (operands[0], operands[1], operands[2]));
1361   else
1362     emit_insn (gen_altivec_vmuloub (operands[0], operands[1], operands[2]));
1363   DONE;
1366 (define_expand "vec_widen_smult_even_v16qi"
1367   [(use (match_operand:V8HI 0 "register_operand" ""))
1368    (use (match_operand:V16QI 1 "register_operand" ""))
1369    (use (match_operand:V16QI 2 "register_operand" ""))]
1370   "TARGET_ALTIVEC"
1372   if (VECTOR_ELT_ORDER_BIG)
1373     emit_insn (gen_altivec_vmulesb (operands[0], operands[1], operands[2]));
1374   else
1375     emit_insn (gen_altivec_vmulosb (operands[0], operands[1], operands[2]));
1376   DONE;
1379 (define_expand "vec_widen_umult_even_v8hi"
1380   [(use (match_operand:V4SI 0 "register_operand" ""))
1381    (use (match_operand:V8HI 1 "register_operand" ""))
1382    (use (match_operand:V8HI 2 "register_operand" ""))]
1383   "TARGET_ALTIVEC"
1385   if (VECTOR_ELT_ORDER_BIG)
1386     emit_insn (gen_altivec_vmuleuh (operands[0], operands[1], operands[2]));
1387   else
1388     emit_insn (gen_altivec_vmulouh (operands[0], operands[1], operands[2]));
1389   DONE;
1392 (define_expand "vec_widen_smult_even_v8hi"
1393   [(use (match_operand:V4SI 0 "register_operand" ""))
1394    (use (match_operand:V8HI 1 "register_operand" ""))
1395    (use (match_operand:V8HI 2 "register_operand" ""))]
1396   "TARGET_ALTIVEC"
1398   if (VECTOR_ELT_ORDER_BIG)
1399     emit_insn (gen_altivec_vmulesh (operands[0], operands[1], operands[2]));
1400   else
1401     emit_insn (gen_altivec_vmulosh (operands[0], operands[1], operands[2]));
1402   DONE;
1405 (define_expand "vec_widen_umult_odd_v16qi"
1406   [(use (match_operand:V8HI 0 "register_operand" ""))
1407    (use (match_operand:V16QI 1 "register_operand" ""))
1408    (use (match_operand:V16QI 2 "register_operand" ""))]
1409   "TARGET_ALTIVEC"
1411   if (VECTOR_ELT_ORDER_BIG)
1412     emit_insn (gen_altivec_vmuloub (operands[0], operands[1], operands[2]));
1413   else
1414     emit_insn (gen_altivec_vmuleub (operands[0], operands[1], operands[2]));
1415   DONE;
1418 (define_expand "vec_widen_smult_odd_v16qi"
1419   [(use (match_operand:V8HI 0 "register_operand" ""))
1420    (use (match_operand:V16QI 1 "register_operand" ""))
1421    (use (match_operand:V16QI 2 "register_operand" ""))]
1422   "TARGET_ALTIVEC"
1424   if (VECTOR_ELT_ORDER_BIG)
1425     emit_insn (gen_altivec_vmulosb (operands[0], operands[1], operands[2]));
1426   else
1427     emit_insn (gen_altivec_vmulesb (operands[0], operands[1], operands[2]));
1428   DONE;
1431 (define_expand "vec_widen_umult_odd_v8hi"
1432   [(use (match_operand:V4SI 0 "register_operand" ""))
1433    (use (match_operand:V8HI 1 "register_operand" ""))
1434    (use (match_operand:V8HI 2 "register_operand" ""))]
1435   "TARGET_ALTIVEC"
1437   if (VECTOR_ELT_ORDER_BIG)
1438     emit_insn (gen_altivec_vmulouh (operands[0], operands[1], operands[2]));
1439   else
1440     emit_insn (gen_altivec_vmuleuh (operands[0], operands[1], operands[2]));
1441   DONE;
1444 (define_expand "vec_widen_smult_odd_v8hi"
1445   [(use (match_operand:V4SI 0 "register_operand" ""))
1446    (use (match_operand:V8HI 1 "register_operand" ""))
1447    (use (match_operand:V8HI 2 "register_operand" ""))]
1448   "TARGET_ALTIVEC"
1450   if (VECTOR_ELT_ORDER_BIG)
1451     emit_insn (gen_altivec_vmulosh (operands[0], operands[1], operands[2]));
1452   else
1453     emit_insn (gen_altivec_vmulesh (operands[0], operands[1], operands[2]));
1454   DONE;
1457 (define_insn "altivec_vmuleub"
1458   [(set (match_operand:V8HI 0 "register_operand" "=v")
1459         (unspec:V8HI [(match_operand:V16QI 1 "register_operand" "v")
1460                       (match_operand:V16QI 2 "register_operand" "v")]
1461                      UNSPEC_VMULEUB))]
1462   "TARGET_ALTIVEC"
1463   "vmuleub %0,%1,%2"
1464   [(set_attr "type" "veccomplex")])
1466 (define_insn "altivec_vmuloub"
1467   [(set (match_operand:V8HI 0 "register_operand" "=v")
1468         (unspec:V8HI [(match_operand:V16QI 1 "register_operand" "v")
1469                       (match_operand:V16QI 2 "register_operand" "v")]
1470                      UNSPEC_VMULOUB))]
1471   "TARGET_ALTIVEC"
1472   "vmuloub %0,%1,%2"
1473   [(set_attr "type" "veccomplex")])
1475 (define_insn "altivec_vmulesb"
1476   [(set (match_operand:V8HI 0 "register_operand" "=v")
1477         (unspec:V8HI [(match_operand:V16QI 1 "register_operand" "v")
1478                       (match_operand:V16QI 2 "register_operand" "v")]
1479                      UNSPEC_VMULESB))]
1480   "TARGET_ALTIVEC"
1481   "vmulesb %0,%1,%2"
1482   [(set_attr "type" "veccomplex")])
1484 (define_insn "altivec_vmulosb"
1485   [(set (match_operand:V8HI 0 "register_operand" "=v")
1486         (unspec:V8HI [(match_operand:V16QI 1 "register_operand" "v")
1487                       (match_operand:V16QI 2 "register_operand" "v")]
1488                      UNSPEC_VMULOSB))]
1489   "TARGET_ALTIVEC"
1490   "vmulosb %0,%1,%2"
1491   [(set_attr "type" "veccomplex")])
1493 (define_insn "altivec_vmuleuh"
1494   [(set (match_operand:V4SI 0 "register_operand" "=v")
1495         (unspec:V4SI [(match_operand:V8HI 1 "register_operand" "v")
1496                       (match_operand:V8HI 2 "register_operand" "v")]
1497                      UNSPEC_VMULEUH))]
1498   "TARGET_ALTIVEC"
1499   "vmuleuh %0,%1,%2"
1500   [(set_attr "type" "veccomplex")])
1502 (define_insn "altivec_vmulouh"
1503   [(set (match_operand:V4SI 0 "register_operand" "=v")
1504         (unspec:V4SI [(match_operand:V8HI 1 "register_operand" "v")
1505                       (match_operand:V8HI 2 "register_operand" "v")]
1506                      UNSPEC_VMULOUH))]
1507   "TARGET_ALTIVEC"
1508   "vmulouh %0,%1,%2"
1509   [(set_attr "type" "veccomplex")])
1511 (define_insn "altivec_vmulesh"
1512   [(set (match_operand:V4SI 0 "register_operand" "=v")
1513         (unspec:V4SI [(match_operand:V8HI 1 "register_operand" "v")
1514                       (match_operand:V8HI 2 "register_operand" "v")]
1515                      UNSPEC_VMULESH))]
1516   "TARGET_ALTIVEC"
1517   "vmulesh %0,%1,%2"
1518   [(set_attr "type" "veccomplex")])
1520 (define_insn "altivec_vmulosh"
1521   [(set (match_operand:V4SI 0 "register_operand" "=v")
1522         (unspec:V4SI [(match_operand:V8HI 1 "register_operand" "v")
1523                       (match_operand:V8HI 2 "register_operand" "v")]
1524                      UNSPEC_VMULOSH))]
1525   "TARGET_ALTIVEC"
1526   "vmulosh %0,%1,%2"
1527   [(set_attr "type" "veccomplex")])
1530 ;; Vector pack/unpack
1531 (define_insn "altivec_vpkpx"
1532   [(set (match_operand:V8HI 0 "register_operand" "=v")
1533         (unspec:V8HI [(match_operand:V4SI 1 "register_operand" "v")
1534                       (match_operand:V4SI 2 "register_operand" "v")]
1535                      UNSPEC_VPKPX))]
1536   "TARGET_ALTIVEC"
1537   "*
1538   {
1539     if (VECTOR_ELT_ORDER_BIG)
1540       return \"vpkpx %0,%1,%2\";
1541     else
1542       return \"vpkpx %0,%2,%1\";
1543   }"
1544   [(set_attr "type" "vecperm")])
1546 (define_insn "altivec_vpks<VI_char>ss"
1547   [(set (match_operand:<VP_small> 0 "register_operand" "=v")
1548         (unspec:<VP_small> [(match_operand:VP 1 "register_operand" "v")
1549                             (match_operand:VP 2 "register_operand" "v")]
1550                            UNSPEC_VPACK_SIGN_SIGN_SAT))]
1551   "<VI_unit>"
1552   "*
1553   {
1554     if (VECTOR_ELT_ORDER_BIG)
1555       return \"vpks<VI_char>ss %0,%1,%2\";
1556     else
1557       return \"vpks<VI_char>ss %0,%2,%1\";
1558   }"
1559   [(set_attr "type" "vecperm")])
1561 (define_insn "altivec_vpks<VI_char>us"
1562   [(set (match_operand:<VP_small> 0 "register_operand" "=v")
1563         (unspec:<VP_small> [(match_operand:VP 1 "register_operand" "v")
1564                             (match_operand:VP 2 "register_operand" "v")]
1565                            UNSPEC_VPACK_SIGN_UNS_SAT))]
1566   "<VI_unit>"
1567   "*
1568   {
1569     if (VECTOR_ELT_ORDER_BIG)
1570       return \"vpks<VI_char>us %0,%1,%2\";
1571     else
1572       return \"vpks<VI_char>us %0,%2,%1\";
1573   }"
1574   [(set_attr "type" "vecperm")])
1576 (define_insn "altivec_vpku<VI_char>us"
1577   [(set (match_operand:<VP_small> 0 "register_operand" "=v")
1578         (unspec:<VP_small> [(match_operand:VP 1 "register_operand" "v")
1579                             (match_operand:VP 2 "register_operand" "v")]
1580                            UNSPEC_VPACK_UNS_UNS_SAT))]
1581   "<VI_unit>"
1582   "*
1583   {
1584     if (VECTOR_ELT_ORDER_BIG)
1585       return \"vpku<VI_char>us %0,%1,%2\";
1586     else
1587       return \"vpku<VI_char>us %0,%2,%1\";
1588   }"
1589   [(set_attr "type" "vecperm")])
1591 (define_insn "altivec_vpku<VI_char>um"
1592   [(set (match_operand:<VP_small> 0 "register_operand" "=v")
1593         (unspec:<VP_small> [(match_operand:VP 1 "register_operand" "v")
1594                             (match_operand:VP 2 "register_operand" "v")]
1595                            UNSPEC_VPACK_UNS_UNS_MOD))]
1596   "<VI_unit>"
1597   "*
1598   {
1599     if (VECTOR_ELT_ORDER_BIG)
1600       return \"vpku<VI_char>um %0,%1,%2\";
1601     else
1602       return \"vpku<VI_char>um %0,%2,%1\";
1603   }"
1604   [(set_attr "type" "vecperm")])
1606 (define_insn "altivec_vpku<VI_char>um_direct"
1607   [(set (match_operand:<VP_small> 0 "register_operand" "=v")
1608         (unspec:<VP_small> [(match_operand:VP 1 "register_operand" "v")
1609                             (match_operand:VP 2 "register_operand" "v")]
1610                            UNSPEC_VPACK_UNS_UNS_MOD_DIRECT))]
1611   "<VI_unit>"
1612   "*
1613   {
1614     if (BYTES_BIG_ENDIAN)
1615       return \"vpku<VI_char>um %0,%1,%2\";
1616     else
1617       return \"vpku<VI_char>um %0,%2,%1\";
1618   }"
1619   [(set_attr "type" "vecperm")])
1621 (define_insn "*altivec_vrl<VI_char>"
1622   [(set (match_operand:VI2 0 "register_operand" "=v")
1623         (rotate:VI2 (match_operand:VI2 1 "register_operand" "v")
1624                     (match_operand:VI2 2 "register_operand" "v")))]
1625   "<VI_unit>"
1626   "vrl<VI_char> %0,%1,%2"
1627   [(set_attr "type" "vecsimple")])
1629 (define_insn "altivec_vrl<VI_char>mi"
1630   [(set (match_operand:VIlong 0 "register_operand" "=v")
1631         (unspec:VIlong [(match_operand:VIlong 1 "register_operand" "0")
1632                         (match_operand:VIlong 2 "register_operand" "v")
1633                         (match_operand:VIlong 3 "register_operand" "v")]
1634                        UNSPEC_VRLMI))]
1635   "TARGET_P9_VECTOR"
1636   "vrl<VI_char>mi %0,%2,%3"
1637   [(set_attr "type" "veclogical")])
1639 (define_insn "altivec_vrl<VI_char>nm"
1640   [(set (match_operand:VIlong 0 "register_operand" "=v")
1641         (unspec:VIlong [(match_operand:VIlong 1 "register_operand" "v")
1642                         (match_operand:VIlong 2 "register_operand" "v")]
1643                        UNSPEC_VRLNM))]
1644   "TARGET_P9_VECTOR"
1645   "vrl<VI_char>nm %0,%1,%2"
1646   [(set_attr "type" "veclogical")])
1648 (define_insn "altivec_vsl"
1649   [(set (match_operand:V4SI 0 "register_operand" "=v")
1650         (unspec:V4SI [(match_operand:V4SI 1 "register_operand" "v")
1651                       (match_operand:V4SI 2 "register_operand" "v")]
1652                      UNSPEC_VSLV4SI))]
1653   "TARGET_ALTIVEC"
1654   "vsl %0,%1,%2"
1655   [(set_attr "type" "vecperm")])
1657 (define_insn "altivec_vslo"
1658   [(set (match_operand:V4SI 0 "register_operand" "=v")
1659         (unspec:V4SI [(match_operand:V4SI 1 "register_operand" "v")
1660                       (match_operand:V4SI 2 "register_operand" "v")]
1661                      UNSPEC_VSLO))]
1662   "TARGET_ALTIVEC"
1663   "vslo %0,%1,%2"
1664   [(set_attr "type" "vecperm")])
1666 (define_insn "vslv"
1667   [(set (match_operand:V16QI 0 "register_operand" "=v")
1668         (unspec:V16QI [(match_operand:V16QI 1 "register_operand" "v")
1669                        (match_operand:V16QI 2 "register_operand" "v")]
1670          UNSPEC_VSLV))]
1671   "TARGET_P9_VECTOR"
1672   "vslv %0,%1,%2"
1673   [(set_attr "type" "vecsimple")])
1675 (define_insn "vsrv"
1676   [(set (match_operand:V16QI 0 "register_operand" "=v")
1677         (unspec:V16QI [(match_operand:V16QI 1 "register_operand" "v")
1678                        (match_operand:V16QI 2 "register_operand" "v")]
1679          UNSPEC_VSRV))]
1680   "TARGET_P9_VECTOR"
1681   "vsrv %0,%1,%2"
1682   [(set_attr "type" "vecsimple")])
1684 (define_insn "*altivec_vsl<VI_char>"
1685   [(set (match_operand:VI2 0 "register_operand" "=v")
1686         (ashift:VI2 (match_operand:VI2 1 "register_operand" "v")
1687                     (match_operand:VI2 2 "register_operand" "v")))]
1688   "<VI_unit>"
1689   "vsl<VI_char> %0,%1,%2"
1690   [(set_attr "type" "vecsimple")])
1692 (define_insn "*altivec_vsr<VI_char>"
1693   [(set (match_operand:VI2 0 "register_operand" "=v")
1694         (lshiftrt:VI2 (match_operand:VI2 1 "register_operand" "v")
1695                       (match_operand:VI2 2 "register_operand" "v")))]
1696   "<VI_unit>"
1697   "vsr<VI_char> %0,%1,%2"
1698   [(set_attr "type" "vecsimple")])
1700 (define_insn "*altivec_vsra<VI_char>"
1701   [(set (match_operand:VI2 0 "register_operand" "=v")
1702         (ashiftrt:VI2 (match_operand:VI2 1 "register_operand" "v")
1703                       (match_operand:VI2 2 "register_operand" "v")))]
1704   "<VI_unit>"
1705   "vsra<VI_char> %0,%1,%2"
1706   [(set_attr "type" "vecsimple")])
1708 (define_insn "altivec_vsr"
1709   [(set (match_operand:V4SI 0 "register_operand" "=v")
1710         (unspec:V4SI [(match_operand:V4SI 1 "register_operand" "v")
1711                       (match_operand:V4SI 2 "register_operand" "v")]
1712                      UNSPEC_VSR))]
1713   "TARGET_ALTIVEC"
1714   "vsr %0,%1,%2"
1715   [(set_attr "type" "vecperm")])
1717 (define_insn "altivec_vsro"
1718   [(set (match_operand:V4SI 0 "register_operand" "=v")
1719         (unspec:V4SI [(match_operand:V4SI 1 "register_operand" "v")
1720                       (match_operand:V4SI 2 "register_operand" "v")]
1721                      UNSPEC_VSRO))]
1722   "TARGET_ALTIVEC"
1723   "vsro %0,%1,%2"
1724   [(set_attr "type" "vecperm")])
1726 (define_insn "altivec_vsum4ubs"
1727   [(set (match_operand:V4SI 0 "register_operand" "=v")
1728         (unspec:V4SI [(match_operand:V16QI 1 "register_operand" "v")
1729                       (match_operand:V4SI 2 "register_operand" "v")]
1730                      UNSPEC_VSUM4UBS))
1731    (set (reg:SI VSCR_REGNO) (unspec:SI [(const_int 0)] UNSPEC_SET_VSCR))]
1732   "TARGET_ALTIVEC"
1733   "vsum4ubs %0,%1,%2"
1734   [(set_attr "type" "veccomplex")])
1736 (define_insn "altivec_vsum4s<VI_char>s"
1737   [(set (match_operand:V4SI 0 "register_operand" "=v")
1738         (unspec:V4SI [(match_operand:VIshort 1 "register_operand" "v")
1739                       (match_operand:V4SI 2 "register_operand" "v")]
1740                      UNSPEC_VSUM4S))
1741    (set (reg:SI VSCR_REGNO) (unspec:SI [(const_int 0)] UNSPEC_SET_VSCR))]
1742   "TARGET_ALTIVEC"
1743   "vsum4s<VI_char>s %0,%1,%2"
1744   [(set_attr "type" "veccomplex")])
1746 ;; FIXME: For the following two patterns, the scratch should only be
1747 ;; allocated for !VECTOR_ELT_ORDER_BIG, and the instructions should
1748 ;; be emitted separately.
1749 (define_insn "altivec_vsum2sws"
1750   [(set (match_operand:V4SI 0 "register_operand" "=v")
1751         (unspec:V4SI [(match_operand:V4SI 1 "register_operand" "v")
1752                       (match_operand:V4SI 2 "register_operand" "v")]
1753                      UNSPEC_VSUM2SWS))
1754    (set (reg:SI VSCR_REGNO) (unspec:SI [(const_int 0)] UNSPEC_SET_VSCR))
1755    (clobber (match_scratch:V4SI 3 "=v"))]
1756   "TARGET_ALTIVEC"
1758   if (VECTOR_ELT_ORDER_BIG)
1759     return "vsum2sws %0,%1,%2";
1760   else
1761     return "vsldoi %3,%2,%2,12\n\tvsum2sws %3,%1,%3\n\tvsldoi %0,%3,%3,4";
1763   [(set_attr "type" "veccomplex")
1764    (set (attr "length")
1765      (if_then_else
1766        (match_test "VECTOR_ELT_ORDER_BIG")
1767        (const_string "4")
1768        (const_string "12")))])
1770 (define_insn "altivec_vsumsws"
1771   [(set (match_operand:V4SI 0 "register_operand" "=v")
1772         (unspec:V4SI [(match_operand:V4SI 1 "register_operand" "v")
1773                       (match_operand:V4SI 2 "register_operand" "v")]
1774                      UNSPEC_VSUMSWS))
1775    (set (reg:SI VSCR_REGNO) (unspec:SI [(const_int 0)] UNSPEC_SET_VSCR))
1776    (clobber (match_scratch:V4SI 3 "=v"))]
1777   "TARGET_ALTIVEC"
1779   if (VECTOR_ELT_ORDER_BIG)
1780     return "vsumsws %0,%1,%2";
1781   else
1782     return "vspltw %3,%2,0\n\tvsumsws %3,%1,%3\n\tvsldoi %0,%3,%3,12";
1784   [(set_attr "type" "veccomplex")
1785    (set (attr "length")
1786      (if_then_else
1787        (match_test "(VECTOR_ELT_ORDER_BIG)")
1788        (const_string "4")
1789        (const_string "12")))])
1791 (define_insn "altivec_vsumsws_direct"
1792   [(set (match_operand:V4SI 0 "register_operand" "=v")
1793         (unspec:V4SI [(match_operand:V4SI 1 "register_operand" "v")
1794                       (match_operand:V4SI 2 "register_operand" "v")]
1795                      UNSPEC_VSUMSWS_DIRECT))
1796    (set (reg:SI VSCR_REGNO) (unspec:SI [(const_int 0)] UNSPEC_SET_VSCR))]
1797   "TARGET_ALTIVEC"
1798   "vsumsws %0,%1,%2"
1799   [(set_attr "type" "veccomplex")])
1801 (define_expand "altivec_vspltb"
1802   [(use (match_operand:V16QI 0 "register_operand" ""))
1803    (use (match_operand:V16QI 1 "register_operand" ""))
1804    (use (match_operand:QI 2 "u5bit_cint_operand" ""))]
1805   "TARGET_ALTIVEC"
1807   rtvec v;
1808   rtx x;
1810   /* Special handling for LE with -maltivec=be.  We have to reflect
1811      the actual selected index for the splat in the RTL.  */
1812   if (!BYTES_BIG_ENDIAN && VECTOR_ELT_ORDER_BIG)
1813     operands[2] = GEN_INT (15 - INTVAL (operands[2]));
1815   v = gen_rtvec (1, operands[2]);
1816   x = gen_rtx_VEC_SELECT (QImode, operands[1], gen_rtx_PARALLEL (VOIDmode, v));
1817   x = gen_rtx_VEC_DUPLICATE (V16QImode, x);
1818   emit_insn (gen_rtx_SET (operands[0], x));
1819   DONE;
1822 (define_insn "*altivec_vspltb_internal"
1823   [(set (match_operand:V16QI 0 "register_operand" "=v")
1824         (vec_duplicate:V16QI
1825          (vec_select:QI (match_operand:V16QI 1 "register_operand" "v")
1826                         (parallel
1827                          [(match_operand:QI 2 "u5bit_cint_operand" "")]))))]
1828   "TARGET_ALTIVEC"
1830   /* For true LE, this adjusts the selected index.  For LE with 
1831      -maltivec=be, this reverses what was done in the define_expand
1832      because the instruction already has big-endian bias.  */
1833   if (!BYTES_BIG_ENDIAN)
1834     operands[2] = GEN_INT (15 - INTVAL (operands[2]));
1836   return "vspltb %0,%1,%2";
1838   [(set_attr "type" "vecperm")])
1840 (define_insn "altivec_vspltb_direct"
1841   [(set (match_operand:V16QI 0 "register_operand" "=v")
1842         (unspec:V16QI [(match_operand:V16QI 1 "register_operand" "v")
1843                        (match_operand:QI 2 "u5bit_cint_operand" "i")]
1844                       UNSPEC_VSPLT_DIRECT))]
1845   "TARGET_ALTIVEC"
1846   "vspltb %0,%1,%2"
1847   [(set_attr "type" "vecperm")])
1849 (define_expand "altivec_vsplth"
1850   [(use (match_operand:V8HI 0 "register_operand" ""))
1851    (use (match_operand:V8HI 1 "register_operand" ""))
1852    (use (match_operand:QI 2 "u5bit_cint_operand" ""))]
1853   "TARGET_ALTIVEC"
1855   rtvec v;
1856   rtx x;
1858   /* Special handling for LE with -maltivec=be.  We have to reflect
1859      the actual selected index for the splat in the RTL.  */
1860   if (!BYTES_BIG_ENDIAN && VECTOR_ELT_ORDER_BIG)
1861     operands[2] = GEN_INT (7 - INTVAL (operands[2]));
1863   v = gen_rtvec (1, operands[2]);
1864   x = gen_rtx_VEC_SELECT (HImode, operands[1], gen_rtx_PARALLEL (VOIDmode, v));
1865   x = gen_rtx_VEC_DUPLICATE (V8HImode, x);
1866   emit_insn (gen_rtx_SET (operands[0], x));
1867   DONE;
1870 (define_insn "*altivec_vsplth_internal"
1871   [(set (match_operand:V8HI 0 "register_operand" "=v")
1872         (vec_duplicate:V8HI
1873          (vec_select:HI (match_operand:V8HI 1 "register_operand" "v")
1874                         (parallel
1875                          [(match_operand:QI 2 "u5bit_cint_operand" "")]))))]
1876   "TARGET_ALTIVEC"
1878   /* For true LE, this adjusts the selected index.  For LE with 
1879      -maltivec=be, this reverses what was done in the define_expand
1880      because the instruction already has big-endian bias.  */
1881   if (!BYTES_BIG_ENDIAN)
1882     operands[2] = GEN_INT (7 - INTVAL (operands[2]));
1884   return "vsplth %0,%1,%2";
1886   [(set_attr "type" "vecperm")])
1888 (define_insn "altivec_vsplth_direct"
1889   [(set (match_operand:V8HI 0 "register_operand" "=v")
1890         (unspec:V8HI [(match_operand:V8HI 1 "register_operand" "v")
1891                       (match_operand:QI 2 "u5bit_cint_operand" "i")]
1892                      UNSPEC_VSPLT_DIRECT))]
1893   "TARGET_ALTIVEC"
1894   "vsplth %0,%1,%2"
1895   [(set_attr "type" "vecperm")])
1897 (define_expand "altivec_vspltw"
1898   [(use (match_operand:V4SI 0 "register_operand" ""))
1899    (use (match_operand:V4SI 1 "register_operand" ""))
1900    (use (match_operand:QI 2 "u5bit_cint_operand" ""))]
1901   "TARGET_ALTIVEC"
1903   rtvec v;
1904   rtx x;
1906   /* Special handling for LE with -maltivec=be.  We have to reflect
1907      the actual selected index for the splat in the RTL.  */
1908   if (!BYTES_BIG_ENDIAN && VECTOR_ELT_ORDER_BIG)
1909     operands[2] = GEN_INT (3 - INTVAL (operands[2]));
1911   v = gen_rtvec (1, operands[2]);
1912   x = gen_rtx_VEC_SELECT (SImode, operands[1], gen_rtx_PARALLEL (VOIDmode, v));
1913   x = gen_rtx_VEC_DUPLICATE (V4SImode, x);
1914   emit_insn (gen_rtx_SET (operands[0], x));
1915   DONE;
1918 (define_insn "*altivec_vspltw_internal"
1919   [(set (match_operand:V4SI 0 "register_operand" "=v")
1920         (vec_duplicate:V4SI
1921          (vec_select:SI (match_operand:V4SI 1 "register_operand" "v")
1922                         (parallel
1923                          [(match_operand:QI 2 "u5bit_cint_operand" "i")]))))]
1924   "TARGET_ALTIVEC"
1926   /* For true LE, this adjusts the selected index.  For LE with 
1927      -maltivec=be, this reverses what was done in the define_expand
1928      because the instruction already has big-endian bias.  */
1929   if (!BYTES_BIG_ENDIAN)
1930     operands[2] = GEN_INT (3 - INTVAL (operands[2]));
1932   return "vspltw %0,%1,%2";
1934   [(set_attr "type" "vecperm")])
1936 (define_insn "altivec_vspltw_direct"
1937   [(set (match_operand:V4SI 0 "register_operand" "=v")
1938         (unspec:V4SI [(match_operand:V4SI 1 "register_operand" "v")
1939                       (match_operand:QI 2 "u5bit_cint_operand" "i")]
1940                      UNSPEC_VSPLT_DIRECT))]
1941   "TARGET_ALTIVEC"
1942   "vspltw %0,%1,%2"
1943   [(set_attr "type" "vecperm")])
1945 (define_expand "altivec_vspltsf"
1946   [(use (match_operand:V4SF 0 "register_operand" ""))
1947    (use (match_operand:V4SF 1 "register_operand" ""))
1948    (use (match_operand:QI 2 "u5bit_cint_operand" ""))]
1949   "TARGET_ALTIVEC"
1951   rtvec v;
1952   rtx x;
1954   /* Special handling for LE with -maltivec=be.  We have to reflect
1955      the actual selected index for the splat in the RTL.  */
1956   if (!BYTES_BIG_ENDIAN && VECTOR_ELT_ORDER_BIG)
1957     operands[2] = GEN_INT (3 - INTVAL (operands[2]));
1959   v = gen_rtvec (1, operands[2]);
1960   x = gen_rtx_VEC_SELECT (SFmode, operands[1], gen_rtx_PARALLEL (VOIDmode, v));
1961   x = gen_rtx_VEC_DUPLICATE (V4SFmode, x);
1962   emit_insn (gen_rtx_SET (operands[0], x));
1963   DONE;
1966 (define_insn "*altivec_vspltsf_internal"
1967   [(set (match_operand:V4SF 0 "register_operand" "=v")
1968         (vec_duplicate:V4SF
1969          (vec_select:SF (match_operand:V4SF 1 "register_operand" "v")
1970                         (parallel
1971                          [(match_operand:QI 2 "u5bit_cint_operand" "i")]))))]
1972   "VECTOR_UNIT_ALTIVEC_P (V4SFmode)"
1974   /* For true LE, this adjusts the selected index.  For LE with 
1975      -maltivec=be, this reverses what was done in the define_expand
1976      because the instruction already has big-endian bias.  */
1977   if (!BYTES_BIG_ENDIAN)
1978     operands[2] = GEN_INT (3 - INTVAL (operands[2]));
1980   return "vspltw %0,%1,%2";
1982   [(set_attr "type" "vecperm")])
1984 (define_insn "altivec_vspltis<VI_char>"
1985   [(set (match_operand:VI 0 "register_operand" "=v")
1986         (vec_duplicate:VI
1987          (match_operand:QI 1 "s5bit_cint_operand" "i")))]
1988   "TARGET_ALTIVEC"
1989   "vspltis<VI_char> %0,%1"
1990   [(set_attr "type" "vecperm")])
1992 (define_insn "*altivec_vrfiz"
1993   [(set (match_operand:V4SF 0 "register_operand" "=v")
1994         (fix:V4SF (match_operand:V4SF 1 "register_operand" "v")))]
1995   "VECTOR_UNIT_ALTIVEC_P (V4SFmode)"
1996   "vrfiz %0,%1"
1997   [(set_attr "type" "vecfloat")])
1999 (define_expand "altivec_vperm_<mode>"
2000   [(set (match_operand:VM 0 "register_operand" "")
2001         (unspec:VM [(match_operand:VM 1 "register_operand" "")
2002                     (match_operand:VM 2 "register_operand" "")
2003                     (match_operand:V16QI 3 "register_operand" "")]
2004                    UNSPEC_VPERM))]
2005   "TARGET_ALTIVEC"
2007   if (!VECTOR_ELT_ORDER_BIG)
2008     {
2009       altivec_expand_vec_perm_le (operands);
2010       DONE;
2011     }
2014 ;; Slightly prefer vperm, since the target does not overlap the source
2015 (define_insn "*altivec_vperm_<mode>_internal"
2016   [(set (match_operand:VM 0 "register_operand" "=v,?wo")
2017         (unspec:VM [(match_operand:VM 1 "register_operand" "v,wo")
2018                     (match_operand:VM 2 "register_operand" "v,0")
2019                     (match_operand:V16QI 3 "register_operand" "v,wo")]
2020                    UNSPEC_VPERM))]
2021   "TARGET_ALTIVEC"
2022   "@
2023    vperm %0,%1,%2,%3
2024    xxperm %x0,%x1,%x3"
2025   [(set_attr "type" "vecperm")
2026    (set_attr "length" "4")])
2028 (define_insn "altivec_vperm_v8hiv16qi"
2029   [(set (match_operand:V16QI 0 "register_operand" "=v,?wo")
2030         (unspec:V16QI [(match_operand:V8HI 1 "register_operand" "v,wo")
2031                        (match_operand:V8HI 2 "register_operand" "v,0")
2032                        (match_operand:V16QI 3 "register_operand" "v,wo")]
2033                    UNSPEC_VPERM))]
2034   "TARGET_ALTIVEC"
2035   "@
2036    vperm %0,%1,%2,%3
2037    xxperm %x0,%x1,%x3"
2038   [(set_attr "type" "vecperm")
2039    (set_attr "length" "4")])
2041 (define_expand "altivec_vperm_<mode>_uns"
2042   [(set (match_operand:VM 0 "register_operand" "")
2043         (unspec:VM [(match_operand:VM 1 "register_operand" "")
2044                     (match_operand:VM 2 "register_operand" "")
2045                     (match_operand:V16QI 3 "register_operand" "")]
2046                    UNSPEC_VPERM_UNS))]
2047   "TARGET_ALTIVEC"
2049   if (!VECTOR_ELT_ORDER_BIG)
2050     {
2051       altivec_expand_vec_perm_le (operands);
2052       DONE;
2053     }
2056 (define_insn "*altivec_vperm_<mode>_uns_internal"
2057   [(set (match_operand:VM 0 "register_operand" "=v,?wo")
2058         (unspec:VM [(match_operand:VM 1 "register_operand" "v,wo")
2059                     (match_operand:VM 2 "register_operand" "v,0")
2060                     (match_operand:V16QI 3 "register_operand" "v,wo")]
2061                    UNSPEC_VPERM_UNS))]
2062   "TARGET_ALTIVEC"
2063   "@
2064    vperm %0,%1,%2,%3
2065    xxperm %x0,%x1,%x3"
2066   [(set_attr "type" "vecperm")
2067    (set_attr "length" "4")])
2069 (define_expand "vec_permv16qi"
2070   [(set (match_operand:V16QI 0 "register_operand" "")
2071         (unspec:V16QI [(match_operand:V16QI 1 "register_operand" "")
2072                        (match_operand:V16QI 2 "register_operand" "")
2073                        (match_operand:V16QI 3 "register_operand" "")]
2074                       UNSPEC_VPERM))]
2075   "TARGET_ALTIVEC"
2077   if (!BYTES_BIG_ENDIAN) {
2078     altivec_expand_vec_perm_le (operands);
2079     DONE;
2080   }
2083 (define_expand "vec_perm_constv16qi"
2084   [(match_operand:V16QI 0 "register_operand" "")
2085    (match_operand:V16QI 1 "register_operand" "")
2086    (match_operand:V16QI 2 "register_operand" "")
2087    (match_operand:V16QI 3 "" "")]
2088   "TARGET_ALTIVEC"
2090   if (altivec_expand_vec_perm_const (operands))
2091     DONE;
2092   else
2093     FAIL;
2096 (define_insn "*altivec_vpermr_<mode>_internal"
2097   [(set (match_operand:VM 0 "register_operand" "=v,?wo")
2098         (unspec:VM [(match_operand:VM 1 "register_operand" "v,wo")
2099                     (match_operand:VM 2 "register_operand" "v,0")
2100                     (match_operand:V16QI 3 "register_operand" "v,wo")]
2101                    UNSPEC_VPERMR))]
2102   "TARGET_P9_VECTOR"
2103   "@
2104    vpermr %0,%2,%1,%3
2105    xxpermr %x0,%x1,%x3"
2106   [(set_attr "type" "vecperm")
2107    (set_attr "length" "4")])
2109 (define_insn "altivec_vrfip"            ; ceil
2110   [(set (match_operand:V4SF 0 "register_operand" "=v")
2111         (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "v")]
2112                      UNSPEC_FRIP))]
2113   "TARGET_ALTIVEC"
2114   "vrfip %0,%1"
2115   [(set_attr "type" "vecfloat")])
2117 (define_insn "altivec_vrfin"
2118   [(set (match_operand:V4SF 0 "register_operand" "=v")
2119         (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "v")]
2120                      UNSPEC_VRFIN))]
2121   "TARGET_ALTIVEC"
2122   "vrfin %0,%1"
2123   [(set_attr "type" "vecfloat")])
2125 (define_insn "*altivec_vrfim"           ; floor
2126   [(set (match_operand:V4SF 0 "register_operand" "=v")
2127         (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "v")]
2128                      UNSPEC_FRIM))]
2129   "TARGET_ALTIVEC"
2130   "vrfim %0,%1"
2131   [(set_attr "type" "vecfloat")])
2133 (define_insn "altivec_vcfux"
2134   [(set (match_operand:V4SF 0 "register_operand" "=v")
2135         (unspec:V4SF [(match_operand:V4SI 1 "register_operand" "v")
2136                       (match_operand:QI 2 "immediate_operand" "i")]
2137                      UNSPEC_VCFUX))]
2138   "TARGET_ALTIVEC"
2139   "vcfux %0,%1,%2"
2140   [(set_attr "type" "vecfloat")])
2142 (define_insn "altivec_vcfsx"
2143   [(set (match_operand:V4SF 0 "register_operand" "=v")
2144         (unspec:V4SF [(match_operand:V4SI 1 "register_operand" "v")
2145                       (match_operand:QI 2 "immediate_operand" "i")]
2146                      UNSPEC_VCFSX))]
2147   "TARGET_ALTIVEC"
2148   "vcfsx %0,%1,%2"
2149   [(set_attr "type" "vecfloat")])
2151 (define_insn "altivec_vctuxs"
2152   [(set (match_operand:V4SI 0 "register_operand" "=v")
2153         (unspec:V4SI [(match_operand:V4SF 1 "register_operand" "v")
2154                       (match_operand:QI 2 "immediate_operand" "i")]
2155                      UNSPEC_VCTUXS))
2156    (set (reg:SI VSCR_REGNO) (unspec:SI [(const_int 0)] UNSPEC_SET_VSCR))]
2157   "TARGET_ALTIVEC"
2158   "vctuxs %0,%1,%2"
2159   [(set_attr "type" "vecfloat")])
2161 (define_insn "altivec_vctsxs"
2162   [(set (match_operand:V4SI 0 "register_operand" "=v")
2163         (unspec:V4SI [(match_operand:V4SF 1 "register_operand" "v")
2164                       (match_operand:QI 2 "immediate_operand" "i")]
2165                      UNSPEC_VCTSXS))
2166    (set (reg:SI VSCR_REGNO) (unspec:SI [(const_int 0)] UNSPEC_SET_VSCR))]
2167   "TARGET_ALTIVEC"
2168   "vctsxs %0,%1,%2"
2169   [(set_attr "type" "vecfloat")])
2171 (define_insn "altivec_vlogefp"
2172   [(set (match_operand:V4SF 0 "register_operand" "=v")
2173         (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "v")]
2174                      UNSPEC_VLOGEFP))]
2175   "TARGET_ALTIVEC"
2176   "vlogefp %0,%1"
2177   [(set_attr "type" "vecfloat")])
2179 (define_insn "altivec_vexptefp"
2180   [(set (match_operand:V4SF 0 "register_operand" "=v")
2181         (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "v")]
2182                      UNSPEC_VEXPTEFP))]
2183   "TARGET_ALTIVEC"
2184   "vexptefp %0,%1"
2185   [(set_attr "type" "vecfloat")])
2187 (define_insn "*altivec_vrsqrtefp"
2188   [(set (match_operand:V4SF 0 "register_operand" "=v")
2189         (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "v")]
2190                      UNSPEC_RSQRT))]
2191   "VECTOR_UNIT_ALTIVEC_P (V4SFmode)"
2192   "vrsqrtefp %0,%1"
2193   [(set_attr "type" "vecfloat")])
2195 (define_insn "altivec_vrefp"
2196   [(set (match_operand:V4SF 0 "register_operand" "=v")
2197         (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "v")]
2198                      UNSPEC_FRES))]
2199   "VECTOR_UNIT_ALTIVEC_P (V4SFmode)"
2200   "vrefp %0,%1"
2201   [(set_attr "type" "vecfloat")])
2203 (define_expand "altivec_copysign_v4sf3"
2204   [(use (match_operand:V4SF 0 "register_operand" ""))
2205    (use (match_operand:V4SF 1 "register_operand" ""))
2206    (use (match_operand:V4SF 2 "register_operand" ""))]
2207   "VECTOR_UNIT_ALTIVEC_P (V4SFmode)"
2208   "
2210   rtx mask = gen_reg_rtx (V4SImode);
2211   rtvec v = rtvec_alloc (4);
2212   unsigned HOST_WIDE_INT mask_val = ((unsigned HOST_WIDE_INT)1) << 31;
2214   RTVEC_ELT (v, 0) = GEN_INT (mask_val);
2215   RTVEC_ELT (v, 1) = GEN_INT (mask_val);
2216   RTVEC_ELT (v, 2) = GEN_INT (mask_val);
2217   RTVEC_ELT (v, 3) = GEN_INT (mask_val);
2219   emit_insn (gen_vec_initv4sisi (mask, gen_rtx_PARALLEL (V4SImode, v)));
2220   emit_insn (gen_vector_select_v4sf (operands[0], operands[1], operands[2],
2221                                      gen_lowpart (V4SFmode, mask)));
2222   DONE;
2225 (define_insn "altivec_vsldoi_<mode>"
2226   [(set (match_operand:VM 0 "register_operand" "=v")
2227         (unspec:VM [(match_operand:VM 1 "register_operand" "v")
2228                     (match_operand:VM 2 "register_operand" "v")
2229                     (match_operand:QI 3 "immediate_operand" "i")]
2230                   UNSPEC_VSLDOI))]
2231   "TARGET_ALTIVEC"
2232   "vsldoi %0,%1,%2,%3"
2233   [(set_attr "type" "vecperm")])
2235 (define_insn "altivec_vupkhs<VU_char>"
2236   [(set (match_operand:VP 0 "register_operand" "=v")
2237         (unspec:VP [(match_operand:<VP_small> 1 "register_operand" "v")]
2238                      UNSPEC_VUNPACK_HI_SIGN))]
2239   "<VI_unit>"
2241   if (VECTOR_ELT_ORDER_BIG)
2242     return "vupkhs<VU_char> %0,%1";
2243   else
2244     return "vupkls<VU_char> %0,%1";
2246   [(set_attr "type" "vecperm")])
2248 (define_insn "*altivec_vupkhs<VU_char>_direct"
2249   [(set (match_operand:VP 0 "register_operand" "=v")
2250         (unspec:VP [(match_operand:<VP_small> 1 "register_operand" "v")]
2251                      UNSPEC_VUNPACK_HI_SIGN_DIRECT))]
2252   "<VI_unit>"
2253   "vupkhs<VU_char> %0,%1"
2254   [(set_attr "type" "vecperm")])
2256 (define_insn "altivec_vupkls<VU_char>"
2257   [(set (match_operand:VP 0 "register_operand" "=v")
2258         (unspec:VP [(match_operand:<VP_small> 1 "register_operand" "v")]
2259                      UNSPEC_VUNPACK_LO_SIGN))]
2260   "<VI_unit>"
2262   if (VECTOR_ELT_ORDER_BIG)
2263     return "vupkls<VU_char> %0,%1";
2264   else
2265     return "vupkhs<VU_char> %0,%1";
2267   [(set_attr "type" "vecperm")])
2269 (define_insn "*altivec_vupkls<VU_char>_direct"
2270   [(set (match_operand:VP 0 "register_operand" "=v")
2271         (unspec:VP [(match_operand:<VP_small> 1 "register_operand" "v")]
2272                      UNSPEC_VUNPACK_LO_SIGN_DIRECT))]
2273   "<VI_unit>"
2274   "vupkls<VU_char> %0,%1"
2275   [(set_attr "type" "vecperm")])
2277 (define_insn "altivec_vupkhpx"
2278   [(set (match_operand:V4SI 0 "register_operand" "=v")
2279         (unspec:V4SI [(match_operand:V8HI 1 "register_operand" "v")]
2280                      UNSPEC_VUPKHPX))]
2281   "TARGET_ALTIVEC"
2283   if (VECTOR_ELT_ORDER_BIG)
2284     return "vupkhpx %0,%1";
2285   else
2286     return "vupklpx %0,%1";
2288   [(set_attr "type" "vecperm")])
2290 (define_insn "altivec_vupklpx"
2291   [(set (match_operand:V4SI 0 "register_operand" "=v")
2292         (unspec:V4SI [(match_operand:V8HI 1 "register_operand" "v")]
2293                      UNSPEC_VUPKLPX))]
2294   "TARGET_ALTIVEC"
2296   if (VECTOR_ELT_ORDER_BIG)
2297     return "vupklpx %0,%1";
2298   else
2299     return "vupkhpx %0,%1";
2301   [(set_attr "type" "vecperm")])
2303 ;; Compare vectors producing a vector result and a predicate, setting CR6 to
2304 ;; indicate a combined status
2305 (define_insn "*altivec_vcmpequ<VI_char>_p"
2306   [(set (reg:CC CR6_REGNO)
2307         (unspec:CC [(eq:CC (match_operand:VI2 1 "register_operand" "v")
2308                            (match_operand:VI2 2 "register_operand" "v"))]
2309                    UNSPEC_PREDICATE))
2310    (set (match_operand:VI2 0 "register_operand" "=v")
2311         (eq:VI2 (match_dup 1)
2312                 (match_dup 2)))]
2313   "<VI_unit>"
2314   "vcmpequ<VI_char>. %0,%1,%2"
2315   [(set_attr "type" "veccmpfx")])
2317 (define_insn "*altivec_vcmpgts<VI_char>_p"
2318   [(set (reg:CC CR6_REGNO)
2319         (unspec:CC [(gt:CC (match_operand:VI2 1 "register_operand" "v")
2320                            (match_operand:VI2 2 "register_operand" "v"))]
2321                    UNSPEC_PREDICATE))
2322    (set (match_operand:VI2 0 "register_operand" "=v")
2323         (gt:VI2 (match_dup 1)
2324                 (match_dup 2)))]
2325   "<VI_unit>"
2326   "vcmpgts<VI_char>. %0,%1,%2"
2327   [(set_attr "type" "veccmpfx")])
2329 (define_insn "*altivec_vcmpgtu<VI_char>_p"
2330   [(set (reg:CC CR6_REGNO)
2331         (unspec:CC [(gtu:CC (match_operand:VI2 1 "register_operand" "v")
2332                             (match_operand:VI2 2 "register_operand" "v"))]
2333                    UNSPEC_PREDICATE))
2334    (set (match_operand:VI2 0 "register_operand" "=v")
2335         (gtu:VI2 (match_dup 1)
2336                  (match_dup 2)))]
2337   "<VI_unit>"
2338   "vcmpgtu<VI_char>. %0,%1,%2"
2339   [(set_attr "type" "veccmpfx")])
2341 (define_insn "*altivec_vcmpeqfp_p"
2342   [(set (reg:CC CR6_REGNO)
2343         (unspec:CC [(eq:CC (match_operand:V4SF 1 "register_operand" "v")
2344                            (match_operand:V4SF 2 "register_operand" "v"))]
2345                    UNSPEC_PREDICATE))
2346    (set (match_operand:V4SF 0 "register_operand" "=v")
2347         (eq:V4SF (match_dup 1)
2348                  (match_dup 2)))]
2349   "VECTOR_UNIT_ALTIVEC_P (V4SFmode)"
2350   "vcmpeqfp. %0,%1,%2"
2351   [(set_attr "type" "veccmp")])
2353 (define_insn "*altivec_vcmpgtfp_p"
2354   [(set (reg:CC CR6_REGNO)
2355         (unspec:CC [(gt:CC (match_operand:V4SF 1 "register_operand" "v")
2356                            (match_operand:V4SF 2 "register_operand" "v"))]
2357                    UNSPEC_PREDICATE))
2358    (set (match_operand:V4SF 0 "register_operand" "=v")
2359         (gt:V4SF (match_dup 1)
2360                  (match_dup 2)))]
2361   "VECTOR_UNIT_ALTIVEC_P (V4SFmode)"
2362   "vcmpgtfp. %0,%1,%2"
2363   [(set_attr "type" "veccmp")])
2365 (define_insn "*altivec_vcmpgefp_p"
2366   [(set (reg:CC CR6_REGNO)
2367         (unspec:CC [(ge:CC (match_operand:V4SF 1 "register_operand" "v")
2368                            (match_operand:V4SF 2 "register_operand" "v"))]
2369                    UNSPEC_PREDICATE))
2370    (set (match_operand:V4SF 0 "register_operand" "=v")
2371         (ge:V4SF (match_dup 1)
2372                  (match_dup 2)))]
2373   "VECTOR_UNIT_ALTIVEC_P (V4SFmode)"
2374   "vcmpgefp. %0,%1,%2"
2375   [(set_attr "type" "veccmp")])
2377 (define_insn "altivec_vcmpbfp_p"
2378   [(set (reg:CC CR6_REGNO)
2379         (unspec:CC [(match_operand:V4SF 1 "register_operand" "v")
2380                     (match_operand:V4SF 2 "register_operand" "v")]
2381                    UNSPEC_VCMPBFP))
2382    (set (match_operand:V4SF 0 "register_operand" "=v")
2383         (unspec:V4SF [(match_dup 1)
2384                       (match_dup 2)] 
2385                       UNSPEC_VCMPBFP))]
2386   "VECTOR_UNIT_ALTIVEC_OR_VSX_P (V4SFmode)"
2387   "vcmpbfp. %0,%1,%2"
2388   [(set_attr "type" "veccmp")])
2390 (define_insn "altivec_mtvscr"
2391   [(set (reg:SI VSCR_REGNO)
2392         (unspec_volatile:SI
2393          [(match_operand:V4SI 0 "register_operand" "v")] UNSPECV_MTVSCR))]
2394   "TARGET_ALTIVEC"
2395   "mtvscr %0"
2396   [(set_attr "type" "vecsimple")])
2398 (define_insn "altivec_mfvscr"
2399   [(set (match_operand:V8HI 0 "register_operand" "=v")
2400         (unspec_volatile:V8HI [(reg:SI VSCR_REGNO)] UNSPECV_MFVSCR))]
2401   "TARGET_ALTIVEC"
2402   "mfvscr %0"
2403   [(set_attr "type" "vecsimple")])
2405 (define_insn "altivec_dssall"
2406   [(unspec_volatile [(const_int 0)] UNSPECV_DSSALL)]
2407   "TARGET_ALTIVEC"
2408   "dssall"
2409   [(set_attr "type" "vecsimple")])
2411 (define_insn "altivec_dss"
2412   [(unspec_volatile [(match_operand:QI 0 "immediate_operand" "i")]
2413                     UNSPECV_DSS)]
2414   "TARGET_ALTIVEC"
2415   "dss %0"
2416   [(set_attr "type" "vecsimple")])
2418 (define_insn "altivec_dst"
2419   [(unspec [(match_operand 0 "register_operand" "b")
2420             (match_operand:SI 1 "register_operand" "r")
2421             (match_operand:QI 2 "immediate_operand" "i")] UNSPEC_DST)]
2422   "TARGET_ALTIVEC && GET_MODE (operands[0]) == Pmode"
2423   "dst %0,%1,%2"
2424   [(set_attr "type" "vecsimple")])
2426 (define_insn "altivec_dstt"
2427   [(unspec [(match_operand 0 "register_operand" "b")
2428             (match_operand:SI 1 "register_operand" "r")
2429             (match_operand:QI 2 "immediate_operand" "i")] UNSPEC_DSTT)]
2430   "TARGET_ALTIVEC && GET_MODE (operands[0]) == Pmode"
2431   "dstt %0,%1,%2"
2432   [(set_attr "type" "vecsimple")])
2434 (define_insn "altivec_dstst"
2435   [(unspec [(match_operand 0 "register_operand" "b")
2436             (match_operand:SI 1 "register_operand" "r")
2437             (match_operand:QI 2 "immediate_operand" "i")] UNSPEC_DSTST)]
2438   "TARGET_ALTIVEC && GET_MODE (operands[0]) == Pmode"
2439   "dstst %0,%1,%2"
2440   [(set_attr "type" "vecsimple")])
2442 (define_insn "altivec_dststt"
2443   [(unspec [(match_operand 0 "register_operand" "b")
2444             (match_operand:SI 1 "register_operand" "r")
2445             (match_operand:QI 2 "immediate_operand" "i")] UNSPEC_DSTSTT)]
2446   "TARGET_ALTIVEC && GET_MODE (operands[0]) == Pmode"
2447   "dststt %0,%1,%2"
2448   [(set_attr "type" "vecsimple")])
2450 (define_expand "altivec_lvsl"
2451   [(use (match_operand:V16QI 0 "register_operand" ""))
2452    (use (match_operand:V16QI 1 "memory_operand" ""))]
2453   "TARGET_ALTIVEC"
2455   if (VECTOR_ELT_ORDER_BIG)
2456     emit_insn (gen_altivec_lvsl_direct (operands[0], operands[1]));
2457   else
2458     {
2459       rtx mask, constv, vperm;
2460       mask = gen_reg_rtx (V16QImode);
2461       emit_insn (gen_altivec_lvsl_direct (mask, operands[1]));
2462       constv = gen_const_vec_series (V16QImode, const0_rtx, const1_rtx);
2463       constv = force_reg (V16QImode, constv);
2464       vperm = gen_rtx_UNSPEC (V16QImode, gen_rtvec (3, mask, mask, constv),
2465                               UNSPEC_VPERM);
2466       emit_insn (gen_rtx_SET (operands[0], vperm));
2467     }
2468   DONE;
2471 (define_insn "altivec_lvsl_direct"
2472   [(set (match_operand:V16QI 0 "register_operand" "=v")
2473         (unspec:V16QI [(match_operand:V16QI 1 "memory_operand" "Z")]
2474                       UNSPEC_LVSL))]
2475   "TARGET_ALTIVEC"
2476   "lvsl %0,%y1"
2477   [(set_attr "type" "vecload")])
2479 (define_expand "altivec_lvsr"
2480   [(use (match_operand:V16QI 0 "register_operand" ""))
2481    (use (match_operand:V16QI 1 "memory_operand" ""))]
2482   "TARGET_ALTIVEC"
2484   if (VECTOR_ELT_ORDER_BIG)
2485     emit_insn (gen_altivec_lvsr_direct (operands[0], operands[1]));
2486   else
2487     {
2488       rtx mask, constv, vperm;
2489       mask = gen_reg_rtx (V16QImode);
2490       emit_insn (gen_altivec_lvsr_direct (mask, operands[1]));
2491       constv = gen_const_vec_series (V16QImode, const0_rtx, const1_rtx);
2492       constv = force_reg (V16QImode, constv);
2493       vperm = gen_rtx_UNSPEC (V16QImode, gen_rtvec (3, mask, mask, constv),
2494                               UNSPEC_VPERM);
2495       emit_insn (gen_rtx_SET (operands[0], vperm));
2496     }
2497   DONE;
2500 (define_insn "altivec_lvsr_direct"
2501   [(set (match_operand:V16QI 0 "register_operand" "=v")
2502         (unspec:V16QI [(match_operand:V16QI 1 "memory_operand" "Z")]
2503                       UNSPEC_LVSR))]
2504   "TARGET_ALTIVEC"
2505   "lvsr %0,%y1"
2506   [(set_attr "type" "vecload")])
2508 (define_expand "build_vector_mask_for_load"
2509   [(set (match_operand:V16QI 0 "register_operand" "")
2510         (unspec:V16QI [(match_operand 1 "memory_operand" "")] UNSPEC_LVSR))]
2511   "TARGET_ALTIVEC"
2512   "
2514   rtx addr;
2515   rtx temp;
2517   gcc_assert (GET_CODE (operands[1]) == MEM);
2519   addr = XEXP (operands[1], 0);
2520   temp = gen_reg_rtx (GET_MODE (addr));
2521   emit_insn (gen_rtx_SET (temp, gen_rtx_NEG (GET_MODE (addr), addr)));
2522   emit_insn (gen_altivec_lvsr (operands[0], 
2523                                replace_equiv_address (operands[1], temp)));
2524   DONE;
2527 ;; Parallel some of the LVE* and STV*'s with unspecs because some have
2528 ;; identical rtl but different instructions-- and gcc gets confused.
2530 (define_expand "altivec_lve<VI_char>x"
2531   [(parallel
2532     [(set (match_operand:VI 0 "register_operand" "=v")
2533           (match_operand:VI 1 "memory_operand" "Z"))
2534      (unspec [(const_int 0)] UNSPEC_LVE)])]
2535   "TARGET_ALTIVEC"
2537   if (!BYTES_BIG_ENDIAN && VECTOR_ELT_ORDER_BIG)
2538     {
2539       altivec_expand_lvx_be (operands[0], operands[1], <MODE>mode, UNSPEC_LVE);
2540       DONE;
2541     }
2544 (define_insn "*altivec_lve<VI_char>x_internal"
2545   [(parallel
2546     [(set (match_operand:VI 0 "register_operand" "=v")
2547           (match_operand:VI 1 "memory_operand" "Z"))
2548      (unspec [(const_int 0)] UNSPEC_LVE)])]
2549   "TARGET_ALTIVEC"
2550   "lve<VI_char>x %0,%y1"
2551   [(set_attr "type" "vecload")])
2553 (define_insn "*altivec_lvesfx"
2554   [(parallel
2555     [(set (match_operand:V4SF 0 "register_operand" "=v")
2556           (match_operand:V4SF 1 "memory_operand" "Z"))
2557      (unspec [(const_int 0)] UNSPEC_LVE)])]
2558   "TARGET_ALTIVEC"
2559   "lvewx %0,%y1"
2560   [(set_attr "type" "vecload")])
2562 (define_expand "altivec_lvxl_<mode>"
2563   [(parallel
2564     [(set (match_operand:VM2 0 "register_operand" "=v")
2565           (match_operand:VM2 1 "memory_operand" "Z"))
2566      (unspec [(const_int 0)] UNSPEC_SET_VSCR)])]
2567   "TARGET_ALTIVEC"
2569   if (!BYTES_BIG_ENDIAN && VECTOR_ELT_ORDER_BIG)
2570     {
2571       altivec_expand_lvx_be (operands[0], operands[1], <MODE>mode, UNSPEC_SET_VSCR);
2572       DONE;
2573     }
2576 (define_insn "*altivec_lvxl_<mode>_internal"
2577   [(parallel
2578     [(set (match_operand:VM2 0 "register_operand" "=v")
2579           (match_operand:VM2 1 "memory_operand" "Z"))
2580      (unspec [(const_int 0)] UNSPEC_SET_VSCR)])]
2581   "TARGET_ALTIVEC"
2582   "lvxl %0,%y1"
2583   [(set_attr "type" "vecload")])
2585 ; This version of lvx is used only in cases where we need to force an lvx
2586 ; over any other load, and we don't care about losing CSE opportunities.
2587 ; Its primary use is for prologue register saves.
2588 (define_insn "altivec_lvx_<mode>_internal"
2589   [(parallel
2590     [(set (match_operand:VM2 0 "register_operand" "=v")
2591           (match_operand:VM2 1 "memory_operand" "Z"))
2592      (unspec [(const_int 0)] UNSPEC_LVX)])]
2593   "TARGET_ALTIVEC"
2594   "lvx %0,%y1"
2595   [(set_attr "type" "vecload")])
2597 ; The next two patterns embody what lvx should usually look like.
2598 (define_insn "altivec_lvx_<mode>_2op"
2599   [(set (match_operand:VM2 0 "register_operand" "=v")
2600         (mem:VM2 (and:DI (plus:DI (match_operand:DI 1 "register_operand" "b")
2601                                   (match_operand:DI 2 "register_operand" "r"))
2602                          (const_int -16))))]
2603   "TARGET_ALTIVEC && TARGET_64BIT"
2604   "lvx %0,%1,%2"
2605   [(set_attr "type" "vecload")])
2607 (define_insn "altivec_lvx_<mode>_1op"
2608   [(set (match_operand:VM2 0 "register_operand" "=v")
2609         (mem:VM2 (and:DI (match_operand:DI 1 "register_operand" "r")
2610                          (const_int -16))))]
2611   "TARGET_ALTIVEC && TARGET_64BIT"
2612   "lvx %0,0,%1"
2613   [(set_attr "type" "vecload")])
2615 ; 32-bit versions of the above.
2616 (define_insn "altivec_lvx_<mode>_2op_si"
2617   [(set (match_operand:VM2 0 "register_operand" "=v")
2618         (mem:VM2 (and:SI (plus:SI (match_operand:SI 1 "register_operand" "b")
2619                                   (match_operand:SI 2 "register_operand" "r"))
2620                          (const_int -16))))]
2621   "TARGET_ALTIVEC && TARGET_32BIT"
2622   "lvx %0,%1,%2"
2623   [(set_attr "type" "vecload")])
2625 (define_insn "altivec_lvx_<mode>_1op_si"
2626   [(set (match_operand:VM2 0 "register_operand" "=v")
2627         (mem:VM2 (and:SI (match_operand:SI 1 "register_operand" "r")
2628                          (const_int -16))))]
2629   "TARGET_ALTIVEC && TARGET_32BIT"
2630   "lvx %0,0,%1"
2631   [(set_attr "type" "vecload")])
2633 ; This version of stvx is used only in cases where we need to force an stvx
2634 ; over any other store, and we don't care about losing CSE opportunities.
2635 ; Its primary use is for epilogue register restores.
2636 (define_insn "altivec_stvx_<mode>_internal"
2637   [(parallel
2638     [(set (match_operand:VM2 0 "memory_operand" "=Z")
2639           (match_operand:VM2 1 "register_operand" "v"))
2640      (unspec [(const_int 0)] UNSPEC_STVX)])]
2641   "TARGET_ALTIVEC"
2642   "stvx %1,%y0"
2643   [(set_attr "type" "vecstore")])
2645 ; The next two patterns embody what stvx should usually look like.
2646 (define_insn "altivec_stvx_<mode>_2op"
2647   [(set (mem:VM2 (and:DI (plus:DI (match_operand:DI 1 "register_operand" "b")
2648                                   (match_operand:DI 2 "register_operand" "r"))
2649                          (const_int -16)))
2650         (match_operand:VM2 0 "register_operand" "v"))]
2651   "TARGET_ALTIVEC && TARGET_64BIT"
2652   "stvx %0,%1,%2"
2653   [(set_attr "type" "vecstore")])
2655 (define_insn "altivec_stvx_<mode>_1op"
2656   [(set (mem:VM2 (and:DI (match_operand:DI 1 "register_operand" "r")
2657                          (const_int -16)))
2658         (match_operand:VM2 0 "register_operand" "v"))]
2659   "TARGET_ALTIVEC && TARGET_64BIT"
2660   "stvx %0,0,%1"
2661   [(set_attr "type" "vecstore")])
2663 ; 32-bit versions of the above.
2664 (define_insn "altivec_stvx_<mode>_2op_si"
2665   [(set (mem:VM2 (and:SI (plus:SI (match_operand:SI 1 "register_operand" "b")
2666                                   (match_operand:SI 2 "register_operand" "r"))
2667                          (const_int -16)))
2668         (match_operand:VM2 0 "register_operand" "v"))]
2669   "TARGET_ALTIVEC && TARGET_32BIT"
2670   "stvx %0,%1,%2"
2671   [(set_attr "type" "vecstore")])
2673 (define_insn "altivec_stvx_<mode>_1op_si"
2674   [(set (mem:VM2 (and:SI (match_operand:SI 1 "register_operand" "r")
2675                          (const_int -16)))
2676         (match_operand:VM2 0 "register_operand" "v"))]
2677   "TARGET_ALTIVEC && TARGET_32BIT"
2678   "stvx %0,0,%1"
2679   [(set_attr "type" "vecstore")])
2681 (define_expand "altivec_stvxl_<mode>"
2682   [(parallel
2683     [(set (match_operand:VM2 0 "memory_operand" "=Z")
2684           (match_operand:VM2 1 "register_operand" "v"))
2685      (unspec [(const_int 0)] UNSPEC_STVXL)])]
2686   "TARGET_ALTIVEC"
2688   if (!BYTES_BIG_ENDIAN && VECTOR_ELT_ORDER_BIG)
2689     {
2690       altivec_expand_stvx_be (operands[0], operands[1], <MODE>mode, UNSPEC_STVXL);
2691       DONE;
2692     }
2695 (define_insn "*altivec_stvxl_<mode>_internal"
2696   [(parallel
2697     [(set (match_operand:VM2 0 "memory_operand" "=Z")
2698           (match_operand:VM2 1 "register_operand" "v"))
2699      (unspec [(const_int 0)] UNSPEC_STVXL)])]
2700   "TARGET_ALTIVEC"
2701   "stvxl %1,%y0"
2702   [(set_attr "type" "vecstore")])
2704 (define_expand "altivec_stve<VI_char>x"
2705   [(set (match_operand:<VI_scalar> 0 "memory_operand" "=Z")
2706         (unspec:<VI_scalar> [(match_operand:VI 1 "register_operand" "v")] UNSPEC_STVE))]
2707   "TARGET_ALTIVEC"
2709   if (!BYTES_BIG_ENDIAN && VECTOR_ELT_ORDER_BIG)
2710     {
2711       altivec_expand_stvex_be (operands[0], operands[1], <MODE>mode, UNSPEC_STVE);
2712       DONE;
2713     }
2716 (define_insn "*altivec_stve<VI_char>x_internal"
2717   [(set (match_operand:<VI_scalar> 0 "memory_operand" "=Z")
2718         (unspec:<VI_scalar> [(match_operand:VI 1 "register_operand" "v")] UNSPEC_STVE))]
2719   "TARGET_ALTIVEC"
2720   "stve<VI_char>x %1,%y0"
2721   [(set_attr "type" "vecstore")])
2723 (define_insn "*altivec_stvesfx"
2724   [(set (match_operand:SF 0 "memory_operand" "=Z")
2725         (unspec:SF [(match_operand:V4SF 1 "register_operand" "v")] UNSPEC_STVE))]
2726   "TARGET_ALTIVEC"
2727   "stvewx %1,%y0"
2728   [(set_attr "type" "vecstore")])
2730 ;; Generate
2731 ;;    xxlxor/vxor SCRATCH0,SCRATCH0,SCRATCH0
2732 ;;    vsubu?m SCRATCH2,SCRATCH1,%1
2733 ;;    vmaxs? %0,%1,SCRATCH2"
2734 (define_expand "abs<mode>2"
2735   [(set (match_dup 2) (match_dup 3))
2736    (set (match_dup 4)
2737         (minus:VI2 (match_dup 2)
2738                    (match_operand:VI2 1 "register_operand" "v")))
2739    (set (match_operand:VI2 0 "register_operand" "=v")
2740         (smax:VI2 (match_dup 1) (match_dup 4)))]
2741   "<VI_unit>"
2743   operands[2] = gen_reg_rtx (<MODE>mode);
2744   operands[3] = CONST0_RTX (<MODE>mode);
2745   operands[4] = gen_reg_rtx (<MODE>mode);
2748 ;; Generate
2749 ;;    vspltisw SCRATCH1,0
2750 ;;    vsubu?m SCRATCH2,SCRATCH1,%1
2751 ;;    vmins? %0,%1,SCRATCH2"
2752 (define_expand "nabs<mode>2"
2753   [(set (match_dup 2) (match_dup 3))
2754    (set (match_dup 4)
2755         (minus:VI2 (match_dup 2)
2756                    (match_operand:VI2 1 "register_operand" "v")))
2757    (set (match_operand:VI2 0 "register_operand" "=v")
2758         (smin:VI2 (match_dup 1) (match_dup 4)))]
2759   "<VI_unit>"
2761   operands[2] = gen_reg_rtx (<MODE>mode);
2762   operands[3] = CONST0_RTX (<MODE>mode);
2763   operands[4] = gen_reg_rtx (<MODE>mode);
2766 ;; Generate
2767 ;;    vspltisw SCRATCH1,-1
2768 ;;    vslw SCRATCH2,SCRATCH1,SCRATCH1
2769 ;;    vandc %0,%1,SCRATCH2
2770 (define_expand "altivec_absv4sf2"
2771   [(set (match_dup 2)
2772         (vec_duplicate:V4SI (const_int -1)))
2773    (set (match_dup 3)
2774         (ashift:V4SI (match_dup 2) (match_dup 2)))
2775    (set (match_operand:V4SF 0 "register_operand" "=v")
2776         (and:V4SF (not:V4SF (subreg:V4SF (match_dup 3) 0))
2777                   (match_operand:V4SF 1 "register_operand" "v")))]
2778   "TARGET_ALTIVEC"
2780   operands[2] = gen_reg_rtx (V4SImode);
2781   operands[3] = gen_reg_rtx (V4SImode);
2784 ;; Generate
2785 ;;    vspltis? SCRATCH0,0
2786 ;;    vsubs?s SCRATCH2,SCRATCH1,%1
2787 ;;    vmaxs? %0,%1,SCRATCH2"
2788 (define_expand "altivec_abss_<mode>"
2789   [(set (match_dup 2) (vec_duplicate:VI (const_int 0)))
2790    (parallel [(set (match_dup 3)
2791                    (unspec:VI [(match_dup 2)
2792                                (match_operand:VI 1 "register_operand" "v")]
2793                               UNSPEC_VSUBS))
2794               (set (reg:SI VSCR_REGNO)
2795                    (unspec:SI [(const_int 0)] UNSPEC_SET_VSCR))])
2796    (set (match_operand:VI 0 "register_operand" "=v")
2797         (smax:VI (match_dup 1) (match_dup 3)))]
2798   "TARGET_ALTIVEC"
2800   operands[2] = gen_reg_rtx (GET_MODE (operands[0]));
2801   operands[3] = gen_reg_rtx (GET_MODE (operands[0]));
2804 (define_expand "reduc_plus_scal_<mode>"
2805   [(set (match_operand:<VI_scalar> 0 "register_operand" "=v")
2806         (unspec:VIshort [(match_operand:VIshort 1 "register_operand" "v")]
2807                         UNSPEC_REDUC_PLUS))]
2808   "TARGET_ALTIVEC"
2810   rtx vzero = gen_reg_rtx (V4SImode);
2811   rtx vtmp1 = gen_reg_rtx (V4SImode);
2812   rtx vtmp2 = gen_reg_rtx (<MODE>mode);
2813   rtx dest = gen_lowpart (V4SImode, vtmp2);
2814   int elt = VECTOR_ELT_ORDER_BIG ? GET_MODE_NUNITS (<MODE>mode) - 1 : 0;
2816   emit_insn (gen_altivec_vspltisw (vzero, const0_rtx));
2817   emit_insn (gen_altivec_vsum4s<VI_char>s (vtmp1, operands[1], vzero));
2818   emit_insn (gen_altivec_vsumsws_direct (dest, vtmp1, vzero));
2819   rs6000_expand_vector_extract (operands[0], vtmp2, GEN_INT (elt));
2820   DONE;
2823 (define_insn "*p9_neg<mode>2"
2824   [(set (match_operand:VNEG 0 "altivec_register_operand" "=v")
2825         (neg:VNEG (match_operand:VNEG 1 "altivec_register_operand" "v")))]
2826   "TARGET_P9_VECTOR"
2827   "vneg<VI_char> %0,%1"
2828   [(set_attr "type" "vecsimple")])
2830 (define_expand "neg<mode>2"
2831   [(set (match_operand:VI2 0 "register_operand" "")
2832         (neg:VI2 (match_operand:VI2 1 "register_operand" "")))]
2833   "<VI_unit>"
2835   if (!TARGET_P9_VECTOR || (<MODE>mode != V4SImode && <MODE>mode != V2DImode))
2836     {
2837       rtx vzero;
2839       vzero = gen_reg_rtx (GET_MODE (operands[0]));
2840       emit_move_insn (vzero, CONST0_RTX (<MODE>mode));
2841       emit_insn (gen_sub<mode>3 (operands[0], vzero, operands[1]));
2842       DONE;
2843     }
2846 (define_expand "udot_prod<mode>"
2847   [(set (match_operand:V4SI 0 "register_operand" "=v")
2848         (plus:V4SI (match_operand:V4SI 3 "register_operand" "v")
2849                    (unspec:V4SI [(match_operand:VIshort 1 "register_operand" "v")  
2850                                  (match_operand:VIshort 2 "register_operand" "v")] 
2851                                 UNSPEC_VMSUMU)))]
2852   "TARGET_ALTIVEC"
2853   "
2854 {  
2855   emit_insn (gen_altivec_vmsumu<VI_char>m (operands[0], operands[1], operands[2], operands[3]));
2856   DONE;
2858    
2859 (define_expand "sdot_prodv8hi"
2860   [(set (match_operand:V4SI 0 "register_operand" "=v")
2861         (plus:V4SI (match_operand:V4SI 3 "register_operand" "v")
2862                    (unspec:V4SI [(match_operand:V8HI 1 "register_operand" "v")
2863                                  (match_operand:V8HI 2 "register_operand" "v")]
2864                                 UNSPEC_VMSUMSHM)))]
2865   "TARGET_ALTIVEC"
2866   "
2868   emit_insn (gen_altivec_vmsumshm (operands[0], operands[1], operands[2], operands[3]));
2869   DONE;
2872 (define_expand "widen_usum<mode>3"
2873   [(set (match_operand:V4SI 0 "register_operand" "=v")
2874         (plus:V4SI (match_operand:V4SI 2 "register_operand" "v")
2875                    (unspec:V4SI [(match_operand:VIshort 1 "register_operand" "v")]
2876                                 UNSPEC_VMSUMU)))]
2877   "TARGET_ALTIVEC"
2878   "
2880   rtx vones = gen_reg_rtx (GET_MODE (operands[1]));
2882   emit_insn (gen_altivec_vspltis<VI_char> (vones, const1_rtx));
2883   emit_insn (gen_altivec_vmsumu<VI_char>m (operands[0], operands[1], vones, operands[2]));
2884   DONE;
2887 (define_expand "widen_ssumv16qi3"
2888   [(set (match_operand:V4SI 0 "register_operand" "=v")
2889         (plus:V4SI (match_operand:V4SI 2 "register_operand" "v")
2890                    (unspec:V4SI [(match_operand:V16QI 1 "register_operand" "v")]
2891                                 UNSPEC_VMSUMM)))]
2892   "TARGET_ALTIVEC"
2893   "
2895   rtx vones = gen_reg_rtx (V16QImode);
2897   emit_insn (gen_altivec_vspltisb (vones, const1_rtx));
2898   emit_insn (gen_altivec_vmsummbm (operands[0], operands[1], vones, operands[2]));
2899   DONE;
2902 (define_expand "widen_ssumv8hi3"
2903   [(set (match_operand:V4SI 0 "register_operand" "=v")
2904         (plus:V4SI (match_operand:V4SI 2 "register_operand" "v")
2905                    (unspec:V4SI [(match_operand:V8HI 1 "register_operand" "v")]
2906                                 UNSPEC_VMSUMSHM)))]
2907   "TARGET_ALTIVEC"
2908   "
2910   rtx vones = gen_reg_rtx (V8HImode);
2912   emit_insn (gen_altivec_vspltish (vones, const1_rtx));
2913   emit_insn (gen_altivec_vmsumshm (operands[0], operands[1], vones, operands[2]));
2914   DONE;
2917 (define_expand "vec_unpacks_hi_<VP_small_lc>"
2918   [(set (match_operand:VP 0 "register_operand" "=v")
2919         (unspec:VP [(match_operand:<VP_small> 1 "register_operand" "v")]
2920                    UNSPEC_VUNPACK_HI_SIGN_DIRECT))]
2921   "<VI_unit>"
2922   "")
2924 (define_expand "vec_unpacks_lo_<VP_small_lc>"
2925   [(set (match_operand:VP 0 "register_operand" "=v")
2926         (unspec:VP [(match_operand:<VP_small> 1 "register_operand" "v")]
2927                    UNSPEC_VUNPACK_LO_SIGN_DIRECT))]
2928   "<VI_unit>"
2929   "")
2931 (define_insn "vperm_v8hiv4si"
2932   [(set (match_operand:V4SI 0 "register_operand" "=v,?wo")
2933         (unspec:V4SI [(match_operand:V8HI 1 "register_operand" "v,wo")
2934                       (match_operand:V4SI 2 "register_operand" "v,0")
2935                       (match_operand:V16QI 3 "register_operand" "v,wo")]
2936                   UNSPEC_VPERMSI))]
2937   "TARGET_ALTIVEC"
2938   "@
2939    vperm %0,%1,%2,%3
2940    xxperm %x0,%x1,%x3"
2941   [(set_attr "type" "vecperm")
2942    (set_attr "length" "4")])
2944 (define_insn "vperm_v16qiv8hi"
2945   [(set (match_operand:V8HI 0 "register_operand" "=v,?wo")
2946         (unspec:V8HI [(match_operand:V16QI 1 "register_operand" "v,wo")
2947                       (match_operand:V8HI 2 "register_operand" "v,0")
2948                       (match_operand:V16QI 3 "register_operand" "v,wo")]
2949                   UNSPEC_VPERMHI))]
2950   "TARGET_ALTIVEC"
2951   "@
2952    vperm %0,%1,%2,%3
2953    xxperm %x0,%x1,%x3"
2954   [(set_attr "type" "vecperm")
2955    (set_attr "length" "4")])
2958 (define_expand "vec_unpacku_hi_v16qi"
2959   [(set (match_operand:V8HI 0 "register_operand" "=v")
2960         (unspec:V8HI [(match_operand:V16QI 1 "register_operand" "v")]
2961                      UNSPEC_VUPKHUB))]
2962   "TARGET_ALTIVEC"      
2963   "
2964 {  
2965   rtx vzero = gen_reg_rtx (V8HImode);
2966   rtx mask = gen_reg_rtx (V16QImode);
2967   rtvec v = rtvec_alloc (16);
2968   bool be = BYTES_BIG_ENDIAN;
2969    
2970   emit_insn (gen_altivec_vspltish (vzero, const0_rtx));
2971    
2972   RTVEC_ELT (v,  0) = gen_rtx_CONST_INT (QImode, be ? 16 :  7);
2973   RTVEC_ELT (v,  1) = gen_rtx_CONST_INT (QImode, be ?  0 : 16);
2974   RTVEC_ELT (v,  2) = gen_rtx_CONST_INT (QImode, be ? 16 :  6);
2975   RTVEC_ELT (v,  3) = gen_rtx_CONST_INT (QImode, be ?  1 : 16);
2976   RTVEC_ELT (v,  4) = gen_rtx_CONST_INT (QImode, be ? 16 :  5);
2977   RTVEC_ELT (v,  5) = gen_rtx_CONST_INT (QImode, be ?  2 : 16);
2978   RTVEC_ELT (v,  6) = gen_rtx_CONST_INT (QImode, be ? 16 :  4);
2979   RTVEC_ELT (v,  7) = gen_rtx_CONST_INT (QImode, be ?  3 : 16);
2980   RTVEC_ELT (v,  8) = gen_rtx_CONST_INT (QImode, be ? 16 :  3);
2981   RTVEC_ELT (v,  9) = gen_rtx_CONST_INT (QImode, be ?  4 : 16);
2982   RTVEC_ELT (v, 10) = gen_rtx_CONST_INT (QImode, be ? 16 :  2);
2983   RTVEC_ELT (v, 11) = gen_rtx_CONST_INT (QImode, be ?  5 : 16);
2984   RTVEC_ELT (v, 12) = gen_rtx_CONST_INT (QImode, be ? 16 :  1);
2985   RTVEC_ELT (v, 13) = gen_rtx_CONST_INT (QImode, be ?  6 : 16);
2986   RTVEC_ELT (v, 14) = gen_rtx_CONST_INT (QImode, be ? 16 :  0);
2987   RTVEC_ELT (v, 15) = gen_rtx_CONST_INT (QImode, be ?  7 : 16);
2989   emit_insn (gen_vec_initv16qiqi (mask, gen_rtx_PARALLEL (V16QImode, v)));
2990   emit_insn (gen_vperm_v16qiv8hi (operands[0], operands[1], vzero, mask));
2991   DONE;
2994 (define_expand "vec_unpacku_hi_v8hi"
2995   [(set (match_operand:V4SI 0 "register_operand" "=v")
2996         (unspec:V4SI [(match_operand:V8HI 1 "register_operand" "v")]
2997                      UNSPEC_VUPKHUH))]
2998   "TARGET_ALTIVEC"
2999   "
3001   rtx vzero = gen_reg_rtx (V4SImode);
3002   rtx mask = gen_reg_rtx (V16QImode);
3003   rtvec v = rtvec_alloc (16);
3004   bool be = BYTES_BIG_ENDIAN;
3006   emit_insn (gen_altivec_vspltisw (vzero, const0_rtx));
3008   RTVEC_ELT (v,  0) = gen_rtx_CONST_INT (QImode, be ? 16 :  7);
3009   RTVEC_ELT (v,  1) = gen_rtx_CONST_INT (QImode, be ? 17 :  6);
3010   RTVEC_ELT (v,  2) = gen_rtx_CONST_INT (QImode, be ?  0 : 17);
3011   RTVEC_ELT (v,  3) = gen_rtx_CONST_INT (QImode, be ?  1 : 16);
3012   RTVEC_ELT (v,  4) = gen_rtx_CONST_INT (QImode, be ? 16 :  5);
3013   RTVEC_ELT (v,  5) = gen_rtx_CONST_INT (QImode, be ? 17 :  4);
3014   RTVEC_ELT (v,  6) = gen_rtx_CONST_INT (QImode, be ?  2 : 17);
3015   RTVEC_ELT (v,  7) = gen_rtx_CONST_INT (QImode, be ?  3 : 16);
3016   RTVEC_ELT (v,  8) = gen_rtx_CONST_INT (QImode, be ? 16 :  3);
3017   RTVEC_ELT (v,  9) = gen_rtx_CONST_INT (QImode, be ? 17 :  2);
3018   RTVEC_ELT (v, 10) = gen_rtx_CONST_INT (QImode, be ?  4 : 17);
3019   RTVEC_ELT (v, 11) = gen_rtx_CONST_INT (QImode, be ?  5 : 16);
3020   RTVEC_ELT (v, 12) = gen_rtx_CONST_INT (QImode, be ? 16 :  1);
3021   RTVEC_ELT (v, 13) = gen_rtx_CONST_INT (QImode, be ? 17 :  0);
3022   RTVEC_ELT (v, 14) = gen_rtx_CONST_INT (QImode, be ?  6 : 17);
3023   RTVEC_ELT (v, 15) = gen_rtx_CONST_INT (QImode, be ?  7 : 16);
3025   emit_insn (gen_vec_initv16qiqi (mask, gen_rtx_PARALLEL (V16QImode, v)));
3026   emit_insn (gen_vperm_v8hiv4si (operands[0], operands[1], vzero, mask));
3027   DONE;
3030 (define_expand "vec_unpacku_lo_v16qi"
3031   [(set (match_operand:V8HI 0 "register_operand" "=v")
3032         (unspec:V8HI [(match_operand:V16QI 1 "register_operand" "v")]
3033                      UNSPEC_VUPKLUB))]
3034   "TARGET_ALTIVEC"
3035   "
3037   rtx vzero = gen_reg_rtx (V8HImode);
3038   rtx mask = gen_reg_rtx (V16QImode);
3039   rtvec v = rtvec_alloc (16);
3040   bool be = BYTES_BIG_ENDIAN;
3042   emit_insn (gen_altivec_vspltish (vzero, const0_rtx));
3044   RTVEC_ELT (v,  0) = gen_rtx_CONST_INT (QImode, be ? 16 : 15);
3045   RTVEC_ELT (v,  1) = gen_rtx_CONST_INT (QImode, be ?  8 : 16);
3046   RTVEC_ELT (v,  2) = gen_rtx_CONST_INT (QImode, be ? 16 : 14);
3047   RTVEC_ELT (v,  3) = gen_rtx_CONST_INT (QImode, be ?  9 : 16);
3048   RTVEC_ELT (v,  4) = gen_rtx_CONST_INT (QImode, be ? 16 : 13);
3049   RTVEC_ELT (v,  5) = gen_rtx_CONST_INT (QImode, be ? 10 : 16);
3050   RTVEC_ELT (v,  6) = gen_rtx_CONST_INT (QImode, be ? 16 : 12);
3051   RTVEC_ELT (v,  7) = gen_rtx_CONST_INT (QImode, be ? 11 : 16);
3052   RTVEC_ELT (v,  8) = gen_rtx_CONST_INT (QImode, be ? 16 : 11);
3053   RTVEC_ELT (v,  9) = gen_rtx_CONST_INT (QImode, be ? 12 : 16);
3054   RTVEC_ELT (v, 10) = gen_rtx_CONST_INT (QImode, be ? 16 : 10);
3055   RTVEC_ELT (v, 11) = gen_rtx_CONST_INT (QImode, be ? 13 : 16);
3056   RTVEC_ELT (v, 12) = gen_rtx_CONST_INT (QImode, be ? 16 :  9);
3057   RTVEC_ELT (v, 13) = gen_rtx_CONST_INT (QImode, be ? 14 : 16);
3058   RTVEC_ELT (v, 14) = gen_rtx_CONST_INT (QImode, be ? 16 :  8);
3059   RTVEC_ELT (v, 15) = gen_rtx_CONST_INT (QImode, be ? 15 : 16);
3061   emit_insn (gen_vec_initv16qiqi (mask, gen_rtx_PARALLEL (V16QImode, v)));
3062   emit_insn (gen_vperm_v16qiv8hi (operands[0], operands[1], vzero, mask));
3063   DONE;
3066 (define_expand "vec_unpacku_lo_v8hi"
3067   [(set (match_operand:V4SI 0 "register_operand" "=v")
3068         (unspec:V4SI [(match_operand:V8HI 1 "register_operand" "v")]
3069                      UNSPEC_VUPKLUH))]
3070   "TARGET_ALTIVEC"
3071   "
3073   rtx vzero = gen_reg_rtx (V4SImode);
3074   rtx mask = gen_reg_rtx (V16QImode);
3075   rtvec v = rtvec_alloc (16);
3076   bool be = BYTES_BIG_ENDIAN;
3078   emit_insn (gen_altivec_vspltisw (vzero, const0_rtx));
3080   RTVEC_ELT (v,  0) = gen_rtx_CONST_INT (QImode, be ? 16 : 15);
3081   RTVEC_ELT (v,  1) = gen_rtx_CONST_INT (QImode, be ? 17 : 14);
3082   RTVEC_ELT (v,  2) = gen_rtx_CONST_INT (QImode, be ?  8 : 17);
3083   RTVEC_ELT (v,  3) = gen_rtx_CONST_INT (QImode, be ?  9 : 16);
3084   RTVEC_ELT (v,  4) = gen_rtx_CONST_INT (QImode, be ? 16 : 13);
3085   RTVEC_ELT (v,  5) = gen_rtx_CONST_INT (QImode, be ? 17 : 12);
3086   RTVEC_ELT (v,  6) = gen_rtx_CONST_INT (QImode, be ? 10 : 17);
3087   RTVEC_ELT (v,  7) = gen_rtx_CONST_INT (QImode, be ? 11 : 16);
3088   RTVEC_ELT (v,  8) = gen_rtx_CONST_INT (QImode, be ? 16 : 11);
3089   RTVEC_ELT (v,  9) = gen_rtx_CONST_INT (QImode, be ? 17 : 10);
3090   RTVEC_ELT (v, 10) = gen_rtx_CONST_INT (QImode, be ? 12 : 17);
3091   RTVEC_ELT (v, 11) = gen_rtx_CONST_INT (QImode, be ? 13 : 16);
3092   RTVEC_ELT (v, 12) = gen_rtx_CONST_INT (QImode, be ? 16 :  9);
3093   RTVEC_ELT (v, 13) = gen_rtx_CONST_INT (QImode, be ? 17 :  8);
3094   RTVEC_ELT (v, 14) = gen_rtx_CONST_INT (QImode, be ? 14 : 17);
3095   RTVEC_ELT (v, 15) = gen_rtx_CONST_INT (QImode, be ? 15 : 16);
3097   emit_insn (gen_vec_initv16qiqi (mask, gen_rtx_PARALLEL (V16QImode, v)));
3098   emit_insn (gen_vperm_v8hiv4si (operands[0], operands[1], vzero, mask));
3099   DONE;
3102 (define_expand "vec_widen_umult_hi_v16qi"
3103   [(set (match_operand:V8HI 0 "register_operand" "=v")
3104         (unspec:V8HI [(match_operand:V16QI 1 "register_operand" "v")
3105                       (match_operand:V16QI 2 "register_operand" "v")]
3106                      UNSPEC_VMULWHUB))]
3107   "TARGET_ALTIVEC"
3108   "
3110   rtx ve = gen_reg_rtx (V8HImode);
3111   rtx vo = gen_reg_rtx (V8HImode);
3112   
3113   if (BYTES_BIG_ENDIAN)
3114     {
3115       emit_insn (gen_altivec_vmuleub (ve, operands[1], operands[2]));
3116       emit_insn (gen_altivec_vmuloub (vo, operands[1], operands[2]));
3117       emit_insn (gen_altivec_vmrghh_direct (operands[0], ve, vo));
3118     }
3119   else
3120     {
3121       emit_insn (gen_altivec_vmuloub (ve, operands[1], operands[2]));
3122       emit_insn (gen_altivec_vmuleub (vo, operands[1], operands[2]));
3123       emit_insn (gen_altivec_vmrghh_direct (operands[0], vo, ve));
3124     }
3125   DONE;
3128 (define_expand "vec_widen_umult_lo_v16qi"
3129   [(set (match_operand:V8HI 0 "register_operand" "=v")
3130         (unspec:V8HI [(match_operand:V16QI 1 "register_operand" "v")
3131                       (match_operand:V16QI 2 "register_operand" "v")]
3132                      UNSPEC_VMULWLUB))]
3133   "TARGET_ALTIVEC"
3134   "
3136   rtx ve = gen_reg_rtx (V8HImode);
3137   rtx vo = gen_reg_rtx (V8HImode);
3138   
3139   if (BYTES_BIG_ENDIAN)
3140     {
3141       emit_insn (gen_altivec_vmuleub (ve, operands[1], operands[2]));
3142       emit_insn (gen_altivec_vmuloub (vo, operands[1], operands[2]));
3143       emit_insn (gen_altivec_vmrglh_direct (operands[0], ve, vo));
3144     }
3145   else
3146     {
3147       emit_insn (gen_altivec_vmuloub (ve, operands[1], operands[2]));
3148       emit_insn (gen_altivec_vmuleub (vo, operands[1], operands[2]));
3149       emit_insn (gen_altivec_vmrglh_direct (operands[0], vo, ve));
3150     }
3151   DONE;
3154 (define_expand "vec_widen_smult_hi_v16qi"
3155   [(set (match_operand:V8HI 0 "register_operand" "=v")
3156         (unspec:V8HI [(match_operand:V16QI 1 "register_operand" "v")
3157                       (match_operand:V16QI 2 "register_operand" "v")]
3158                      UNSPEC_VMULWHSB))]
3159   "TARGET_ALTIVEC"
3160   "
3162   rtx ve = gen_reg_rtx (V8HImode);
3163   rtx vo = gen_reg_rtx (V8HImode);
3164   
3165   if (BYTES_BIG_ENDIAN)
3166     {
3167       emit_insn (gen_altivec_vmulesb (ve, operands[1], operands[2]));
3168       emit_insn (gen_altivec_vmulosb (vo, operands[1], operands[2]));
3169       emit_insn (gen_altivec_vmrghh_direct (operands[0], ve, vo));
3170     }
3171   else
3172     {
3173       emit_insn (gen_altivec_vmulosb (ve, operands[1], operands[2]));
3174       emit_insn (gen_altivec_vmulesb (vo, operands[1], operands[2]));
3175       emit_insn (gen_altivec_vmrghh_direct (operands[0], vo, ve));
3176     }
3177   DONE;
3180 (define_expand "vec_widen_smult_lo_v16qi"
3181   [(set (match_operand:V8HI 0 "register_operand" "=v")
3182         (unspec:V8HI [(match_operand:V16QI 1 "register_operand" "v")
3183                       (match_operand:V16QI 2 "register_operand" "v")]
3184                      UNSPEC_VMULWLSB))]
3185   "TARGET_ALTIVEC"
3186   "
3188   rtx ve = gen_reg_rtx (V8HImode);
3189   rtx vo = gen_reg_rtx (V8HImode);
3190   
3191   if (BYTES_BIG_ENDIAN)
3192     {
3193       emit_insn (gen_altivec_vmulesb (ve, operands[1], operands[2]));
3194       emit_insn (gen_altivec_vmulosb (vo, operands[1], operands[2]));
3195       emit_insn (gen_altivec_vmrglh_direct (operands[0], ve, vo));
3196     }
3197   else
3198     {
3199       emit_insn (gen_altivec_vmulosb (ve, operands[1], operands[2]));
3200       emit_insn (gen_altivec_vmulesb (vo, operands[1], operands[2]));
3201       emit_insn (gen_altivec_vmrglh_direct (operands[0], vo, ve));
3202     }
3203   DONE;
3206 (define_expand "vec_widen_umult_hi_v8hi"
3207   [(set (match_operand:V4SI 0 "register_operand" "=v")
3208         (unspec:V4SI [(match_operand:V8HI 1 "register_operand" "v")
3209                       (match_operand:V8HI 2 "register_operand" "v")]
3210                      UNSPEC_VMULWHUH))]
3211   "TARGET_ALTIVEC"
3212   "
3214   rtx ve = gen_reg_rtx (V4SImode);
3215   rtx vo = gen_reg_rtx (V4SImode);
3216   
3217   if (BYTES_BIG_ENDIAN)
3218     {
3219       emit_insn (gen_altivec_vmuleuh (ve, operands[1], operands[2]));
3220       emit_insn (gen_altivec_vmulouh (vo, operands[1], operands[2]));
3221       emit_insn (gen_altivec_vmrghw_direct (operands[0], ve, vo));
3222     }
3223   else
3224     {
3225       emit_insn (gen_altivec_vmulouh (ve, operands[1], operands[2]));
3226       emit_insn (gen_altivec_vmuleuh (vo, operands[1], operands[2]));
3227       emit_insn (gen_altivec_vmrghw_direct (operands[0], vo, ve));
3228     }
3229   DONE;
3232 (define_expand "vec_widen_umult_lo_v8hi"
3233   [(set (match_operand:V4SI 0 "register_operand" "=v")
3234         (unspec:V4SI [(match_operand:V8HI 1 "register_operand" "v")
3235                       (match_operand:V8HI 2 "register_operand" "v")]
3236                      UNSPEC_VMULWLUH))]
3237   "TARGET_ALTIVEC"
3238   "
3240   rtx ve = gen_reg_rtx (V4SImode);
3241   rtx vo = gen_reg_rtx (V4SImode);
3242   
3243   if (BYTES_BIG_ENDIAN)
3244     {
3245       emit_insn (gen_altivec_vmuleuh (ve, operands[1], operands[2]));
3246       emit_insn (gen_altivec_vmulouh (vo, operands[1], operands[2]));
3247       emit_insn (gen_altivec_vmrglw_direct (operands[0], ve, vo));
3248     }
3249   else
3250     {
3251       emit_insn (gen_altivec_vmulouh (ve, operands[1], operands[2]));
3252       emit_insn (gen_altivec_vmuleuh (vo, operands[1], operands[2]));
3253       emit_insn (gen_altivec_vmrglw_direct (operands[0], vo, ve));
3254     }
3255   DONE;
3258 (define_expand "vec_widen_smult_hi_v8hi"
3259   [(set (match_operand:V4SI 0 "register_operand" "=v")
3260         (unspec:V4SI [(match_operand:V8HI 1 "register_operand" "v")
3261                       (match_operand:V8HI 2 "register_operand" "v")]
3262                      UNSPEC_VMULWHSH))]
3263   "TARGET_ALTIVEC"
3264   "
3266   rtx ve = gen_reg_rtx (V4SImode);
3267   rtx vo = gen_reg_rtx (V4SImode);
3268   
3269   if (BYTES_BIG_ENDIAN)
3270     {
3271       emit_insn (gen_altivec_vmulesh (ve, operands[1], operands[2]));
3272       emit_insn (gen_altivec_vmulosh (vo, operands[1], operands[2]));
3273       emit_insn (gen_altivec_vmrghw_direct (operands[0], ve, vo));
3274     }
3275   else
3276     {
3277       emit_insn (gen_altivec_vmulosh (ve, operands[1], operands[2]));
3278       emit_insn (gen_altivec_vmulesh (vo, operands[1], operands[2]));
3279       emit_insn (gen_altivec_vmrghw_direct (operands[0], vo, ve));
3280     }
3281   DONE;
3284 (define_expand "vec_widen_smult_lo_v8hi"
3285   [(set (match_operand:V4SI 0 "register_operand" "=v")
3286         (unspec:V4SI [(match_operand:V8HI 1 "register_operand" "v")
3287                       (match_operand:V8HI 2 "register_operand" "v")]
3288                      UNSPEC_VMULWLSH))]
3289   "TARGET_ALTIVEC"
3290   "
3292   rtx ve = gen_reg_rtx (V4SImode);
3293   rtx vo = gen_reg_rtx (V4SImode);
3294   
3295   if (BYTES_BIG_ENDIAN)
3296     {
3297       emit_insn (gen_altivec_vmulesh (ve, operands[1], operands[2]));
3298       emit_insn (gen_altivec_vmulosh (vo, operands[1], operands[2]));
3299       emit_insn (gen_altivec_vmrglw_direct (operands[0], ve, vo));
3300     }
3301   else
3302     {
3303       emit_insn (gen_altivec_vmulosh (ve, operands[1], operands[2]));
3304       emit_insn (gen_altivec_vmulesh (vo, operands[1], operands[2]));
3305       emit_insn (gen_altivec_vmrglw_direct (operands[0], vo, ve));
3306     }
3307   DONE;
3310 (define_expand "vec_pack_trunc_<mode>"
3311   [(set (match_operand:<VP_small> 0 "register_operand" "=v")
3312         (unspec:<VP_small> [(match_operand:VP 1 "register_operand" "v")
3313                             (match_operand:VP 2 "register_operand" "v")]
3314                       UNSPEC_VPACK_UNS_UNS_MOD))]
3315   "<VI_unit>"
3316   "")
3318 (define_expand "mulv16qi3"
3319   [(set (match_operand:V16QI 0 "register_operand" "=v")
3320         (mult:V16QI (match_operand:V16QI 1 "register_operand" "v")
3321                     (match_operand:V16QI 2 "register_operand" "v")))]
3322   "TARGET_ALTIVEC"
3323   "
3325   rtx even = gen_reg_rtx (V8HImode);
3326   rtx odd = gen_reg_rtx (V8HImode);
3327   rtx mask = gen_reg_rtx (V16QImode);
3328   rtvec v = rtvec_alloc (16);
3329   int i;
3331   for (i = 0; i < 8; ++i) {
3332     RTVEC_ELT (v, 2 * i)
3333      = gen_rtx_CONST_INT (QImode, BYTES_BIG_ENDIAN ? 2 * i + 1 : 31 - 2 * i);
3334     RTVEC_ELT (v, 2 * i + 1)
3335      = gen_rtx_CONST_INT (QImode, BYTES_BIG_ENDIAN ? 2 * i + 17 : 15 - 2 * i);
3336   }
3338   emit_insn (gen_vec_initv16qiqi (mask, gen_rtx_PARALLEL (V16QImode, v)));
3339   emit_insn (gen_altivec_vmulesb (even, operands[1], operands[2]));
3340   emit_insn (gen_altivec_vmulosb (odd, operands[1], operands[2]));
3341   emit_insn (gen_altivec_vperm_v8hiv16qi (operands[0], even, odd, mask));
3342   DONE;
3345 (define_expand "altivec_negv4sf2"
3346   [(use (match_operand:V4SF 0 "register_operand" ""))
3347    (use (match_operand:V4SF 1 "register_operand" ""))]
3348   "TARGET_ALTIVEC"
3349   "
3351   rtx neg0;
3353   /* Generate [-0.0, -0.0, -0.0, -0.0].  */
3354   neg0 = gen_reg_rtx (V4SImode);
3355   emit_insn (gen_altivec_vspltisw (neg0, constm1_rtx));
3356   emit_insn (gen_vashlv4si3 (neg0, neg0, neg0));
3358   /* XOR */
3359   emit_insn (gen_xorv4sf3 (operands[0],
3360                            gen_lowpart (V4SFmode, neg0), operands[1])); 
3361     
3362   DONE;
3365 ;; Vector SIMD PEM v2.06c defines LVLX, LVLXL, LVRX, LVRXL,
3366 ;; STVLX, STVLXL, STVVRX, STVRXL are available only on Cell.
3367 (define_insn "altivec_lvlx"
3368   [(set (match_operand:V16QI 0 "register_operand" "=v")
3369         (unspec:V16QI [(match_operand:BLK 1 "memory_operand" "Z")]
3370                       UNSPEC_LVLX))]
3371   "TARGET_ALTIVEC && rs6000_cpu == PROCESSOR_CELL"
3372   "lvlx %0,%y1"
3373   [(set_attr "type" "vecload")])
3375 (define_insn "altivec_lvlxl"
3376   [(set (match_operand:V16QI 0 "register_operand" "=v")
3377         (unspec:V16QI [(match_operand:BLK 1 "memory_operand" "Z")]
3378                       UNSPEC_LVLXL))]
3379   "TARGET_ALTIVEC && rs6000_cpu == PROCESSOR_CELL"
3380   "lvlxl %0,%y1"
3381   [(set_attr "type" "vecload")])
3383 (define_insn "altivec_lvrx"
3384   [(set (match_operand:V16QI 0 "register_operand" "=v")
3385         (unspec:V16QI [(match_operand:BLK 1 "memory_operand" "Z")]
3386                       UNSPEC_LVRX))]
3387   "TARGET_ALTIVEC && rs6000_cpu == PROCESSOR_CELL"
3388   "lvrx %0,%y1"
3389   [(set_attr "type" "vecload")])
3391 (define_insn "altivec_lvrxl"
3392   [(set (match_operand:V16QI 0 "register_operand" "=v")
3393         (unspec:V16QI [(match_operand:BLK 1 "memory_operand" "Z")]
3394                       UNSPEC_LVRXL))]
3395   "TARGET_ALTIVEC && rs6000_cpu == PROCESSOR_CELL"
3396   "lvrxl %0,%y1"
3397   [(set_attr "type" "vecload")])
3399 (define_insn "altivec_stvlx"
3400   [(parallel
3401     [(set (match_operand:V16QI 0 "memory_operand" "=Z")
3402           (match_operand:V16QI 1 "register_operand" "v"))
3403      (unspec [(const_int 0)] UNSPEC_STVLX)])]
3404   "TARGET_ALTIVEC && rs6000_cpu == PROCESSOR_CELL"
3405   "stvlx %1,%y0"
3406   [(set_attr "type" "vecstore")])
3408 (define_insn "altivec_stvlxl"
3409   [(parallel
3410     [(set (match_operand:V16QI 0 "memory_operand" "=Z")
3411           (match_operand:V16QI 1 "register_operand" "v"))
3412      (unspec [(const_int 0)] UNSPEC_STVLXL)])]
3413   "TARGET_ALTIVEC && rs6000_cpu == PROCESSOR_CELL"
3414   "stvlxl %1,%y0"
3415   [(set_attr "type" "vecstore")])
3417 (define_insn "altivec_stvrx"
3418   [(parallel
3419     [(set (match_operand:V16QI 0 "memory_operand" "=Z")
3420           (match_operand:V16QI 1 "register_operand" "v"))
3421      (unspec [(const_int 0)] UNSPEC_STVRX)])]
3422   "TARGET_ALTIVEC && rs6000_cpu == PROCESSOR_CELL"
3423   "stvrx %1,%y0"
3424   [(set_attr "type" "vecstore")])
3426 (define_insn "altivec_stvrxl"
3427   [(parallel
3428     [(set (match_operand:V16QI 0 "memory_operand" "=Z")
3429           (match_operand:V16QI 1 "register_operand" "v"))
3430      (unspec [(const_int 0)] UNSPEC_STVRXL)])]
3431   "TARGET_ALTIVEC && rs6000_cpu == PROCESSOR_CELL"
3432   "stvrxl %1,%y0"
3433   [(set_attr "type" "vecstore")])
3435 (define_expand "vec_unpacks_float_hi_v8hi"
3436  [(set (match_operand:V4SF 0 "register_operand" "")
3437         (unspec:V4SF [(match_operand:V8HI 1 "register_operand" "")]
3438                      UNSPEC_VUPKHS_V4SF))]
3439   "TARGET_ALTIVEC"
3440   "
3442   rtx tmp = gen_reg_rtx (V4SImode);
3444   emit_insn (gen_vec_unpacks_hi_v8hi (tmp, operands[1]));
3445   emit_insn (gen_altivec_vcfsx (operands[0], tmp, const0_rtx));
3446   DONE;
3449 (define_expand "vec_unpacks_float_lo_v8hi"
3450  [(set (match_operand:V4SF 0 "register_operand" "")
3451         (unspec:V4SF [(match_operand:V8HI 1 "register_operand" "")]
3452                      UNSPEC_VUPKLS_V4SF))]
3453   "TARGET_ALTIVEC"
3454   "
3456   rtx tmp = gen_reg_rtx (V4SImode);
3458   emit_insn (gen_vec_unpacks_lo_v8hi (tmp, operands[1]));
3459   emit_insn (gen_altivec_vcfsx (operands[0], tmp, const0_rtx));
3460   DONE;
3463 (define_expand "vec_unpacku_float_hi_v8hi"
3464  [(set (match_operand:V4SF 0 "register_operand" "")
3465         (unspec:V4SF [(match_operand:V8HI 1 "register_operand" "")]
3466                      UNSPEC_VUPKHU_V4SF))]
3467   "TARGET_ALTIVEC"
3468   "
3470   rtx tmp = gen_reg_rtx (V4SImode);
3472   emit_insn (gen_vec_unpacku_hi_v8hi (tmp, operands[1]));
3473   emit_insn (gen_altivec_vcfux (operands[0], tmp, const0_rtx));
3474   DONE;
3477 (define_expand "vec_unpacku_float_lo_v8hi"
3478  [(set (match_operand:V4SF 0 "register_operand" "")
3479         (unspec:V4SF [(match_operand:V8HI 1 "register_operand" "")]
3480                      UNSPEC_VUPKLU_V4SF))]
3481   "TARGET_ALTIVEC"
3482   "
3484   rtx tmp = gen_reg_rtx (V4SImode);
3486   emit_insn (gen_vec_unpacku_lo_v8hi (tmp, operands[1]));
3487   emit_insn (gen_altivec_vcfux (operands[0], tmp, const0_rtx));
3488   DONE;
3492 ;; Power8/power9 vector instructions encoded as Altivec instructions
3494 ;; Vector count leading zeros
3495 (define_insn "*p8v_clz<mode>2"
3496   [(set (match_operand:VI2 0 "register_operand" "=v")
3497         (clz:VI2 (match_operand:VI2 1 "register_operand" "v")))]
3498   "TARGET_P8_VECTOR"
3499   "vclz<wd> %0,%1"
3500   [(set_attr "length" "4")
3501    (set_attr "type" "vecsimple")])
3503 ;; Vector absolute difference unsigned
3504 (define_expand "vadu<mode>3"
3505   [(set (match_operand:VI 0 "register_operand")
3506         (unspec:VI [(match_operand:VI 1 "register_operand")
3507                     (match_operand:VI 2 "register_operand")]
3508          UNSPEC_VADU))]
3509   "TARGET_P9_VECTOR")
3511 ;; Vector absolute difference unsigned
3512 (define_insn "*p9_vadu<mode>3"
3513   [(set (match_operand:VI 0 "register_operand" "=v")
3514         (unspec:VI [(match_operand:VI 1 "register_operand" "v")
3515                     (match_operand:VI 2 "register_operand" "v")]
3516          UNSPEC_VADU))]
3517   "TARGET_P9_VECTOR"
3518   "vabsdu<wd> %0,%1,%2"
3519   [(set_attr "type" "vecsimple")])
3521 ;; Vector count trailing zeros
3522 (define_insn "*p9v_ctz<mode>2"
3523   [(set (match_operand:VI2 0 "register_operand" "=v")
3524         (ctz:VI2 (match_operand:VI2 1 "register_operand" "v")))]
3525   "TARGET_P9_VECTOR"
3526   "vctz<wd> %0,%1"
3527   [(set_attr "length" "4")
3528    (set_attr "type" "vecsimple")])
3530 ;; Vector population count
3531 (define_insn "*p8v_popcount<mode>2"
3532   [(set (match_operand:VI2 0 "register_operand" "=v")
3533         (popcount:VI2 (match_operand:VI2 1 "register_operand" "v")))]
3534   "TARGET_P8_VECTOR"
3535   "vpopcnt<wd> %0,%1"
3536   [(set_attr "length" "4")
3537    (set_attr "type" "vecsimple")])
3539 ;; Vector parity
3540 (define_insn "*p9v_parity<mode>2"
3541   [(set (match_operand:VParity 0 "register_operand" "=v")
3542         (parity:VParity (match_operand:VParity 1 "register_operand" "v")))]
3543   "TARGET_P9_VECTOR"
3544   "vprtyb<wd> %0,%1"
3545   [(set_attr "length" "4")
3546    (set_attr "type" "vecsimple")])
3548 ;; Vector Gather Bits by Bytes by Doubleword
3549 (define_insn "p8v_vgbbd"
3550   [(set (match_operand:V16QI 0 "register_operand" "=v")
3551         (unspec:V16QI [(match_operand:V16QI 1 "register_operand" "v")]
3552                       UNSPEC_VGBBD))]
3553   "TARGET_P8_VECTOR"
3554   "vgbbd %0,%1"
3555   [(set_attr "length" "4")
3556    (set_attr "type" "vecsimple")])
3559 ;; 128-bit binary integer arithmetic
3560 ;; We have a special container type (V1TImode) to allow operations using the
3561 ;; ISA 2.07 128-bit binary support to target the VMX/altivec registers without
3562 ;; having to worry about the register allocator deciding GPRs are better.
3564 (define_insn "altivec_vadduqm"
3565   [(set (match_operand:V1TI 0 "register_operand" "=v")
3566         (plus:V1TI (match_operand:V1TI 1 "register_operand" "v")
3567                    (match_operand:V1TI 2 "register_operand" "v")))]
3568   "TARGET_VADDUQM"
3569   "vadduqm %0,%1,%2"
3570   [(set_attr "length" "4")
3571    (set_attr "type" "vecsimple")])
3573 (define_insn "altivec_vaddcuq"
3574   [(set (match_operand:V1TI 0 "register_operand" "=v")
3575         (unspec:V1TI [(match_operand:V1TI 1 "register_operand" "v")
3576                       (match_operand:V1TI 2 "register_operand" "v")]
3577                      UNSPEC_VADDCUQ))]
3578   "TARGET_VADDUQM"
3579   "vaddcuq %0,%1,%2"
3580   [(set_attr "length" "4")
3581    (set_attr "type" "vecsimple")])
3583 (define_insn "altivec_vsubuqm"
3584   [(set (match_operand:V1TI 0 "register_operand" "=v")
3585         (minus:V1TI (match_operand:V1TI 1 "register_operand" "v")
3586                     (match_operand:V1TI 2 "register_operand" "v")))]
3587   "TARGET_VADDUQM"
3588   "vsubuqm %0,%1,%2"
3589   [(set_attr "length" "4")
3590    (set_attr "type" "vecsimple")])
3592 (define_insn "altivec_vsubcuq"
3593   [(set (match_operand:V1TI 0 "register_operand" "=v")
3594         (unspec:V1TI [(match_operand:V1TI 1 "register_operand" "v")
3595                       (match_operand:V1TI 2 "register_operand" "v")]
3596                      UNSPEC_VSUBCUQ))]
3597   "TARGET_VADDUQM"
3598   "vsubcuq %0,%1,%2"
3599   [(set_attr "length" "4")
3600    (set_attr "type" "vecsimple")])
3602 (define_insn "altivec_vaddeuqm"
3603   [(set (match_operand:V1TI 0 "register_operand" "=v")
3604         (unspec:V1TI [(match_operand:V1TI 1 "register_operand" "v")
3605                       (match_operand:V1TI 2 "register_operand" "v")
3606                       (match_operand:V1TI 3 "register_operand" "v")]
3607                      UNSPEC_VADDEUQM))]
3608   "TARGET_VADDUQM"
3609   "vaddeuqm %0,%1,%2,%3"
3610   [(set_attr "length" "4")
3611    (set_attr "type" "vecsimple")])
3613 (define_insn "altivec_vaddecuq"
3614   [(set (match_operand:V1TI 0 "register_operand" "=v")
3615         (unspec:V1TI [(match_operand:V1TI 1 "register_operand" "v")
3616                       (match_operand:V1TI 2 "register_operand" "v")
3617                       (match_operand:V1TI 3 "register_operand" "v")]
3618                      UNSPEC_VADDECUQ))]
3619   "TARGET_VADDUQM"
3620   "vaddecuq %0,%1,%2,%3"
3621   [(set_attr "length" "4")
3622    (set_attr "type" "vecsimple")])
3624 (define_insn "altivec_vsubeuqm"
3625   [(set (match_operand:V1TI 0 "register_operand" "=v")
3626         (unspec:V1TI [(match_operand:V1TI 1 "register_operand" "v")
3627                       (match_operand:V1TI 2 "register_operand" "v")
3628                       (match_operand:V1TI 3 "register_operand" "v")]
3629                    UNSPEC_VSUBEUQM))]
3630   "TARGET_VADDUQM"
3631   "vsubeuqm %0,%1,%2,%3"
3632   [(set_attr "length" "4")
3633    (set_attr "type" "vecsimple")])
3635 (define_insn "altivec_vsubecuq"
3636   [(set (match_operand:V1TI 0 "register_operand" "=v")
3637         (unspec:V1TI [(match_operand:V1TI 1 "register_operand" "v")
3638                       (match_operand:V1TI 2 "register_operand" "v")
3639                       (match_operand:V1TI 3 "register_operand" "v")]
3640                      UNSPEC_VSUBECUQ))]
3641   "TARGET_VADDUQM"
3642   "vsubecuq %0,%1,%2,%3"
3643   [(set_attr "length" "4")
3644    (set_attr "type" "vecsimple")])
3646 ;; We use V2DI as the output type to simplify converting the permute
3647 ;; bits into an integer
3648 (define_insn "altivec_vbpermq"
3649   [(set (match_operand:V2DI 0 "register_operand" "=v")
3650         (unspec:V2DI [(match_operand:V16QI 1 "register_operand" "v")
3651                       (match_operand:V16QI 2 "register_operand" "v")]
3652                      UNSPEC_VBPERMQ))]
3653   "TARGET_P8_VECTOR"
3654   "vbpermq %0,%1,%2"
3655   [(set_attr "type" "vecperm")])
3657 ; One of the vector API interfaces requires returning vector unsigned char.
3658 (define_insn "altivec_vbpermq2"
3659   [(set (match_operand:V16QI 0 "register_operand" "=v")
3660         (unspec:V16QI [(match_operand:V16QI 1 "register_operand" "v")
3661                        (match_operand:V16QI 2 "register_operand" "v")]
3662                       UNSPEC_VBPERMQ))]
3663   "TARGET_P8_VECTOR"
3664   "vbpermq %0,%1,%2"
3665   [(set_attr "type" "vecperm")])
3667 (define_insn "altivec_vbpermd"
3668   [(set (match_operand:V2DI 0 "register_operand" "=v")
3669         (unspec:V2DI [(match_operand:V2DI 1 "register_operand" "v")
3670                       (match_operand:V16QI 2 "register_operand" "v")]
3671                      UNSPEC_VBPERMD))]
3672   "TARGET_P9_VECTOR"
3673   "vbpermd %0,%1,%2"
3674   [(set_attr "type" "vecsimple")])
3676 ;; Decimal Integer operations
3677 (define_int_iterator UNSPEC_BCD_ADD_SUB [UNSPEC_BCDADD UNSPEC_BCDSUB])
3679 (define_int_attr bcd_add_sub [(UNSPEC_BCDADD "add")
3680                               (UNSPEC_BCDSUB "sub")])
3682 (define_code_iterator BCD_TEST [eq lt gt unordered])
3684 (define_insn "bcd<bcd_add_sub>"
3685   [(set (match_operand:V1TI 0 "gpc_reg_operand" "=v")
3686         (unspec:V1TI [(match_operand:V1TI 1 "gpc_reg_operand" "v")
3687                       (match_operand:V1TI 2 "gpc_reg_operand" "v")
3688                       (match_operand:QI 3 "const_0_to_1_operand" "n")]
3689                      UNSPEC_BCD_ADD_SUB))
3690    (clobber (reg:CCFP CR6_REGNO))]
3691   "TARGET_P8_VECTOR"
3692   "bcd<bcd_add_sub>. %0,%1,%2,%3"
3693   [(set_attr "length" "4")
3694    (set_attr "type" "vecsimple")])
3696 ;; Use a floating point type (V2DFmode) for the compare to set CR6 so that we
3697 ;; can use the unordered test for BCD nans and add/subtracts that overflow.  An
3698 ;; UNORDERED test on an integer type (like V1TImode) is not defined.  The type
3699 ;; probably should be one that can go in the VMX (Altivec) registers, so we
3700 ;; can't use DDmode or DFmode.
3701 (define_insn "*bcd<bcd_add_sub>_test"
3702   [(set (reg:CCFP CR6_REGNO)
3703         (compare:CCFP
3704          (unspec:V2DF [(match_operand:V1TI 1 "register_operand" "v")
3705                        (match_operand:V1TI 2 "register_operand" "v")
3706                        (match_operand:QI 3 "const_0_to_1_operand" "i")]
3707                       UNSPEC_BCD_ADD_SUB)
3708          (match_operand:V2DF 4 "zero_constant" "j")))
3709    (clobber (match_scratch:V1TI 0 "=v"))]
3710   "TARGET_P8_VECTOR"
3711   "bcd<bcd_add_sub>. %0,%1,%2,%3"
3712   [(set_attr "length" "4")
3713    (set_attr "type" "vecsimple")])
3715 (define_insn "*bcd<bcd_add_sub>_test2"
3716   [(set (match_operand:V1TI 0 "register_operand" "=v")
3717         (unspec:V1TI [(match_operand:V1TI 1 "register_operand" "v")
3718                       (match_operand:V1TI 2 "register_operand" "v")
3719                       (match_operand:QI 3 "const_0_to_1_operand" "i")]
3720                      UNSPEC_BCD_ADD_SUB))
3721    (set (reg:CCFP CR6_REGNO)
3722         (compare:CCFP
3723          (unspec:V2DF [(match_dup 1)
3724                        (match_dup 2)
3725                        (match_dup 3)]
3726                       UNSPEC_BCD_ADD_SUB)
3727          (match_operand:V2DF 4 "zero_constant" "j")))]
3728   "TARGET_P8_VECTOR"
3729   "bcd<bcd_add_sub>. %0,%1,%2,%3"
3730   [(set_attr "length" "4")
3731    (set_attr "type" "vecsimple")])
3733 (define_insn "darn_32"
3734   [(set (match_operand:SI 0 "register_operand" "=r")
3735         (unspec:SI [(const_int 0)] UNSPEC_DARN_32))]
3736   "TARGET_P9_MISC"
3737   "darn %0,0"
3738   [(set_attr "type" "integer")])
3740 (define_insn "darn_raw"
3741   [(set (match_operand:DI 0 "register_operand" "=r")
3742         (unspec:DI [(const_int 0)] UNSPEC_DARN_RAW))]
3743   "TARGET_P9_MISC && TARGET_64BIT"
3744   "darn %0,2"
3745   [(set_attr "type" "integer")])
3747 (define_insn "darn"
3748   [(set (match_operand:DI 0 "register_operand" "=r")
3749         (unspec:DI [(const_int 0)] UNSPEC_DARN))]
3750   "TARGET_P9_MISC && TARGET_64BIT"
3751   "darn %0,1"
3752   [(set_attr "type" "integer")])
3754 ;; Test byte within range.
3756 ;; The bytes of operand 1 are organized as xx:xx:xx:vv, where xx
3757 ;; represents a byte whose value is ignored in this context and
3758 ;; vv, the least significant byte, holds the byte value that is to
3759 ;; be tested for membership within the range specified by operand 2.
3760 ;; The bytes of operand 2 are organized as xx:xx:hi:lo.
3762 ;; Return in target register operand 0 a value of 1 if lo <= vv and
3763 ;; vv <= hi.  Otherwise, set register operand 0 to 0.
3765 ;; Though the instructions to which this expansion maps operate on
3766 ;; 64-bit registers, the current implementation only operates on
3767 ;; SI-mode operands as the high-order bits provide no information
3768 ;; that is not already available in the low-order bits.  To avoid the
3769 ;; costs of data widening operations, future enhancements might allow
3770 ;; DI mode for operand 0 and/or might allow operand 1 to be QI mode.
3771 (define_expand "cmprb"
3772   [(set (match_dup 3)
3773         (unspec:CC [(match_operand:SI 1 "gpc_reg_operand" "r")
3774                     (match_operand:SI 2 "gpc_reg_operand" "r")]
3775          UNSPEC_CMPRB))
3776    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
3777         (if_then_else:SI (lt (match_dup 3)
3778                              (const_int 0))
3779                          (const_int -1)
3780                          (if_then_else (gt (match_dup 3)
3781                                            (const_int 0))
3782                                        (const_int 1)
3783                                        (const_int 0))))]
3784   "TARGET_P9_MISC"
3786   operands[3] = gen_reg_rtx (CCmode);
3789 ;; The bytes of operand 1 are organized as xx:xx:xx:vv, where xx
3790 ;; represents a byte whose value is ignored in this context and
3791 ;; vv, the least significant byte, holds the byte value that is to
3792 ;; be tested for membership within the range specified by operand 2.
3793 ;; The bytes of operand 2 are organized as xx:xx:hi:lo.
3795 ;; Set bit 1 (the GT bit, 0x4) of CR register operand 0 to 1 if
3796 ;; lo <= vv and vv <= hi.  Otherwise, set the GT bit to 0.  The other
3797 ;; 3 bits of the target CR register are all set to 0.
3798 (define_insn "*cmprb_internal"
3799   [(set (match_operand:CC 0 "cc_reg_operand" "=y")
3800         (unspec:CC [(match_operand:SI 1 "gpc_reg_operand" "r")
3801                     (match_operand:SI 2 "gpc_reg_operand" "r")]
3802          UNSPEC_CMPRB))]
3803   "TARGET_P9_MISC"
3804   "cmprb %0,0,%1,%2"
3805   [(set_attr "type" "logical")])
3807 ;; Set operand 0 register to -1 if the LT bit (0x8) of condition
3808 ;; register operand 1 is on.  Otherwise, set operand 0 register to 1
3809 ;; if the GT bit (0x4) of condition register operand 1 is on.
3810 ;; Otherwise, set operand 0 to 0.  Note that the result stored into
3811 ;; register operand 0 is non-zero iff either the LT or GT bits are on
3812 ;; within condition register operand 1.
3813 (define_insn "setb_signed"
3814    [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
3815          (if_then_else:SI (lt (match_operand:CC 1 "cc_reg_operand" "y")
3816                               (const_int 0))
3817                           (const_int -1)
3818                           (if_then_else (gt (match_dup 1)
3819                                             (const_int 0))
3820                                         (const_int 1)
3821                                         (const_int 0))))]
3822   "TARGET_P9_MISC"
3823   "setb %0,%1"
3824   [(set_attr "type" "logical")])
3826 (define_insn "setb_unsigned"
3827    [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
3828          (if_then_else:SI (ltu (match_operand:CCUNS 1 "cc_reg_operand" "y")
3829                               (const_int 0))
3830                           (const_int -1)
3831                           (if_then_else (gtu (match_dup 1)
3832                                             (const_int 0))
3833                                         (const_int 1)
3834                                         (const_int 0))))]
3835   "TARGET_P9_MISC"
3836   "setb %0,%1"
3837   [(set_attr "type" "logical")])
3839 ;; Test byte within two ranges.
3841 ;; The bytes of operand 1 are organized as xx:xx:xx:vv, where xx
3842 ;; represents a byte whose value is ignored in this context and
3843 ;; vv, the least significant byte, holds the byte value that is to
3844 ;; be tested for membership within the range specified by operand 2.
3845 ;; The bytes of operand 2 are organized as hi_1:lo_1:hi_2:lo_2.
3847 ;; Return in target register operand 0 a value of 1 if (lo_1 <= vv and
3848 ;; vv <= hi_1) or if (lo_2 <= vv and vv <= hi_2).  Otherwise, set register
3849 ;; operand 0 to 0.
3851 ;; Though the instructions to which this expansion maps operate on
3852 ;; 64-bit registers, the current implementation only operates on
3853 ;; SI-mode operands as the high-order bits provide no information
3854 ;; that is not already available in the low-order bits.  To avoid the
3855 ;; costs of data widening operations, future enhancements might allow
3856 ;; DI mode for operand 0 and/or might allow operand 1 to be QI mode.
3857 (define_expand "cmprb2"
3858   [(set (match_dup 3)
3859         (unspec:CC [(match_operand:SI 1 "gpc_reg_operand" "r")
3860                     (match_operand:SI 2 "gpc_reg_operand" "r")]
3861          UNSPEC_CMPRB2))
3862    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
3863         (if_then_else:SI (lt (match_dup 3)
3864                              (const_int 0))
3865                          (const_int -1)
3866                          (if_then_else (gt (match_dup 3)
3867                                            (const_int 0))
3868                                        (const_int 1)
3869                                        (const_int 0))))]
3870   "TARGET_P9_MISC"
3872   operands[3] = gen_reg_rtx (CCmode);
3875 ;; The bytes of operand 1 are organized as xx:xx:xx:vv, where xx
3876 ;; represents a byte whose value is ignored in this context and
3877 ;; vv, the least significant byte, holds the byte value that is to
3878 ;; be tested for membership within the ranges specified by operand 2.
3879 ;; The bytes of operand 2 are organized as hi_1:lo_1:hi_2:lo_2.
3881 ;; Set bit 1 (the GT bit, 0x4) of CR register operand 0 to 1 if
3882 ;; (lo_1 <= vv and vv <= hi_1) or if (lo_2 <= vv and vv <= hi_2).
3883 ;; Otherwise, set the GT bit to 0.  The other 3 bits of the target
3884 ;; CR register are all set to 0.
3885 (define_insn "*cmprb2_internal"
3886   [(set (match_operand:CC 0 "cc_reg_operand" "=y")
3887         (unspec:CC [(match_operand:SI 1 "gpc_reg_operand" "r")
3888                     (match_operand:SI 2 "gpc_reg_operand" "r")]
3889          UNSPEC_CMPRB2))]
3890   "TARGET_P9_MISC"
3891   "cmprb %0,1,%1,%2"
3892   [(set_attr "type" "logical")])
3894 ;; Test byte membership within set of 8 bytes.
3896 ;; The bytes of operand 1 are organized as xx:xx:xx:vv, where xx
3897 ;; represents a byte whose value is ignored in this context and
3898 ;; vv, the least significant byte, holds the byte value that is to
3899 ;; be tested for membership within the set specified by operand 2.
3900 ;; The bytes of operand 2 are organized as e0:e1:e2:e3:e4:e5:e6:e7.
3902 ;; Return in target register operand 0 a value of 1 if vv equals one
3903 ;; of the values e0, e1, e2, e3, e4, e5, e6, or e7.  Otherwise, set
3904 ;; register operand 0 to 0.  Note that the 8 byte values held within
3905 ;; operand 2 need not be unique.
3907 ;; Though the instructions to which this expansion maps operate on
3908 ;; 64-bit registers, the current implementation requires that operands
3909 ;; 0 and 1 have mode SI as the high-order bits provide no information
3910 ;; that is not already available in the low-order bits.  To avoid the
3911 ;; costs of data widening operations, future enhancements might allow
3912 ;; DI mode for operand 0 and/or might allow operand 1 to be QI mode.
3913 (define_expand "cmpeqb"
3914   [(set (match_dup 3)
3915         (unspec:CC [(match_operand:SI 1 "gpc_reg_operand" "r")
3916                     (match_operand:DI 2 "gpc_reg_operand" "r")]
3917          UNSPEC_CMPEQB))
3918    (set (match_operand:SI 0 "gpc_reg_operand" "=r")
3919         (if_then_else:SI (lt (match_dup 3)
3920                              (const_int 0))
3921                          (const_int -1)
3922                          (if_then_else (gt (match_dup 3)
3923                                            (const_int 0))
3924                                        (const_int 1)
3925                                        (const_int 0))))]
3926   "TARGET_P9_MISC && TARGET_64BIT"
3928   operands[3] = gen_reg_rtx (CCmode);
3931 ;; The bytes of operand 1 are organized as xx:xx:xx:vv, where xx
3932 ;; represents a byte whose value is ignored in this context and
3933 ;; vv, the least significant byte, holds the byte value that is to
3934 ;; be tested for membership within the set specified by operand 2.
3935 ;; The bytes of operand 2 are organized as e0:e1:e2:e3:e4:e5:e6:e7.
3937 ;; Set bit 1 (the GT bit, 0x4) of CR register operand 0 to 1 if vv
3938 ;; equals one of the values e0, e1, e2, e3, e4, e5, e6, or e7.  Otherwise,
3939 ;; set the GT bit to zero.  The other 3 bits of the target CR register
3940 ;; are all set to 0.
3941 (define_insn "*cmpeqb_internal"
3942   [(set (match_operand:CC 0 "cc_reg_operand" "=y")
3943          (unspec:CC [(match_operand:SI 1 "gpc_reg_operand" "r")
3944                      (match_operand:DI 2 "gpc_reg_operand" "r")]
3945           UNSPEC_CMPEQB))]
3946   "TARGET_P9_MISC && TARGET_64BIT"
3947   "cmpeqb %0,%1,%2"
3948   [(set_attr "type" "logical")])
3950 (define_expand "bcd<bcd_add_sub>_<code>"
3951   [(parallel [(set (reg:CCFP CR6_REGNO)
3952                    (compare:CCFP
3953                     (unspec:V2DF [(match_operand:V1TI 1 "register_operand" "")
3954                                   (match_operand:V1TI 2 "register_operand" "")
3955                                   (match_operand:QI 3 "const_0_to_1_operand" "")]
3956                                  UNSPEC_BCD_ADD_SUB)
3957                     (match_dup 4)))
3958               (clobber (match_scratch:V1TI 5 ""))])
3959    (set (match_operand:SI 0 "register_operand" "")
3960         (BCD_TEST:SI (reg:CCFP CR6_REGNO)
3961                      (const_int 0)))]
3962   "TARGET_P8_VECTOR"
3964   operands[4] = CONST0_RTX (V2DFmode);
3967 ;; Peephole2 pattern to combine a bcdadd/bcdsub that calculates the value and
3968 ;; the bcdadd/bcdsub that tests the value.  The combiner won't work since
3969 ;; CR6 is a hard coded register.  Unfortunately, all of the Altivec predicate
3970 ;; support is hard coded to use the fixed register CR6 instead of creating
3971 ;; a register class for CR6.
3973 (define_peephole2
3974   [(parallel [(set (match_operand:V1TI 0 "register_operand" "")
3975                    (unspec:V1TI [(match_operand:V1TI 1 "register_operand" "")
3976                                  (match_operand:V1TI 2 "register_operand" "")
3977                                  (match_operand:QI 3 "const_0_to_1_operand" "")]
3978                                 UNSPEC_BCD_ADD_SUB))
3979               (clobber (reg:CCFP CR6_REGNO))])
3980    (parallel [(set (reg:CCFP CR6_REGNO)
3981                    (compare:CCFP
3982                     (unspec:V2DF [(match_dup 1)
3983                                   (match_dup 2)
3984                                   (match_dup 3)]
3985                                  UNSPEC_BCD_ADD_SUB)
3986                     (match_operand:V2DF 4 "zero_constant" "")))
3987               (clobber (match_operand:V1TI 5 "register_operand" ""))])]
3988   "TARGET_P8_VECTOR"
3989   [(parallel [(set (match_dup 0)
3990                    (unspec:V1TI [(match_dup 1)
3991                                  (match_dup 2)
3992                                  (match_dup 3)]
3993                                 UNSPEC_BCD_ADD_SUB))
3994               (set (reg:CCFP CR6_REGNO)
3995                    (compare:CCFP
3996                     (unspec:V2DF [(match_dup 1)
3997                                   (match_dup 2)
3998                                   (match_dup 3)]
3999                                  UNSPEC_BCD_ADD_SUB)
4000                     (match_dup 4)))])])