comparison gcc/config/powerpcspe/altivec.md @ 111:04ced10e8804

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