2 ;; Copyright (C) 2009-2016 Free Software Foundation, Inc.
3 ;; Contributed by Michael Meissner <meissner@linux.vnet.ibm.com>
5 ;; This file is part of GCC.
7 ;; GCC is free software; you can redistribute it and/or modify it
8 ;; under the terms of the GNU General Public License as published
9 ;; by the Free Software Foundation; either version 3, or (at your
10 ;; option) any later version.
12 ;; GCC is distributed in the hope that it will be useful, but WITHOUT
13 ;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
14 ;; or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
15 ;; License for more details.
17 ;; You should have received a copy of the GNU General Public License
18 ;; along with GCC; see the file COPYING3. If not see
19 ;; <http://www.gnu.org/licenses/>.
21 ;; Iterator for comparison types
22 (define_code_iterator CMP_TEST [eq lt gt unordered])
24 ;; Iterator for both scalar and vector floating point types supported by VSX
25 (define_mode_iterator VSX_B [DF V4SF V2DF])
27 ;; Iterator for the 2 64-bit vector types
28 (define_mode_iterator VSX_D [V2DF V2DI])
30 ;; Iterator for the 2 64-bit vector types + 128-bit types that are loaded with
31 ;; lxvd2x to properly handle swapping words on little endian
32 (define_mode_iterator VSX_LE [V2DF V2DI V1TI])
34 ;; Mode iterator to handle swapping words on little endian for the 128-bit
35 ;; types that goes in a single vector register.
36 (define_mode_iterator VSX_LE_128 [(KF "FLOAT128_VECTOR_P (KFmode)")
37 (TF "FLOAT128_VECTOR_P (TFmode)")
38 (TI "TARGET_VSX_TIMODE")])
40 ;; Iterator for the 2 32-bit vector types
41 (define_mode_iterator VSX_W [V4SF V4SI])
43 ;; Iterator for the DF types
44 (define_mode_iterator VSX_DF [V2DF DF])
46 ;; Iterator for vector floating point types supported by VSX
47 (define_mode_iterator VSX_F [V4SF V2DF])
49 ;; Iterator for logical types supported by VSX
50 (define_mode_iterator VSX_L [V16QI
58 (KF "FLOAT128_VECTOR_P (KFmode)")
59 (TF "FLOAT128_VECTOR_P (TFmode)")])
61 ;; Iterator for memory moves.
62 (define_mode_iterator VSX_M [V16QI
69 (KF "FLOAT128_VECTOR_P (KFmode)")
70 (TF "FLOAT128_VECTOR_P (TFmode)")
71 (TI "TARGET_VSX_TIMODE")])
73 ;; Map into the appropriate load/store name based on the type
74 (define_mode_attr VSm [(V16QI "vw4")
86 ;; Map into the appropriate suffix based on the type
87 (define_mode_attr VSs [(V16QI "sp")
100 ;; Map the register class used
101 (define_mode_attr VSr [(V16QI "v")
115 ;; Map the register class used for float<->int conversions (floating point side)
116 ;; VSr2 is the preferred register class, VSr3 is any register class that will
118 (define_mode_attr VSr2 [(V2DF "wd")
124 (define_mode_attr VSr3 [(V2DF "wa")
130 ;; Map the register class for sp<->dp float conversions, destination
131 (define_mode_attr VSr4 [(SF "ws")
136 ;; Map the register class for sp<->dp float conversions, source
137 (define_mode_attr VSr5 [(SF "ws")
142 ;; The VSX register class that a type can occupy, even if it is not the
143 ;; preferred register class (VSr is the preferred register class that will get
145 (define_mode_attr VSa [(V16QI "wa")
159 ;; Same size integer type for floating point data
160 (define_mode_attr VSi [(V4SF "v4si")
164 (define_mode_attr VSI [(V4SF "V4SI")
168 ;; Word size for same size conversion
169 (define_mode_attr VSc [(V4SF "w")
173 ;; Map into either s or v, depending on whether this is a scalar or vector
175 (define_mode_attr VSv [(V16QI "v")
185 ;; Appropriate type for add ops (and other simple FP ops)
186 (define_mode_attr VStype_simple [(V2DF "vecdouble")
190 (define_mode_attr VSfptype_simple [(V2DF "fp_addsub_d")
194 ;; Appropriate type for multiply ops
195 (define_mode_attr VStype_mul [(V2DF "vecdouble")
199 (define_mode_attr VSfptype_mul [(V2DF "fp_mul_d")
203 ;; Appropriate type for divide ops.
204 (define_mode_attr VStype_div [(V2DF "vecdiv")
208 (define_mode_attr VSfptype_div [(V2DF "fp_div_d")
212 ;; Appropriate type for sqrt ops. For now, just lump the vector sqrt with
214 (define_mode_attr VStype_sqrt [(V2DF "dsqrt")
218 (define_mode_attr VSfptype_sqrt [(V2DF "fp_sqrt_d")
222 ;; Iterator and modes for sp<->dp conversions
223 ;; Because scalar SF values are represented internally as double, use the
224 ;; V4SF type to represent this than SF.
225 (define_mode_iterator VSX_SPDP [DF V4SF V2DF])
227 (define_mode_attr VS_spdp_res [(DF "V4SF")
231 (define_mode_attr VS_spdp_insn [(DF "xscvdpsp")
235 (define_mode_attr VS_spdp_type [(DF "fp")
239 ;; Map the scalar mode for a vector type
240 (define_mode_attr VS_scalar [(V1TI "TI")
248 ;; Map to a double-sized vector mode
249 (define_mode_attr VS_double [(V4SI "V8SI")
255 ;; Map register class for 64-bit element in 128-bit vector for direct moves
257 (define_mode_attr VS_64dm [(V2DF "wk")
260 ;; Map register class for 64-bit element in 128-bit vector for normal register
262 (define_mode_attr VS_64reg [(V2DF "ws")
265 ;; Iterators for loading constants with xxspltib
266 (define_mode_iterator VSINT_84 [V4SI V2DI DI SI])
267 (define_mode_iterator VSINT_842 [V8HI V4SI V2DI])
269 ;; Iterator for ISA 3.0 vector extract/insert of small integer vectors.
270 ;; VSX_EXTRACT_I2 doesn't include V4SImode because SI extracts can be
271 ;; done on ISA 2.07 and not just ISA 3.0.
272 (define_mode_iterator VSX_EXTRACT_I [V16QI V8HI V4SI])
273 (define_mode_iterator VSX_EXTRACT_I2 [V16QI V8HI])
275 (define_mode_attr VSX_EXTRACT_WIDTH [(V16QI "b")
279 ;; Mode attribute to give the correct predicate for ISA 3.0 vector extract and
280 ;; insert to validate the operand number.
281 (define_mode_attr VSX_EXTRACT_PREDICATE [(V16QI "const_0_to_15_operand")
282 (V8HI "const_0_to_7_operand")
283 (V4SI "const_0_to_3_operand")])
285 ;; Mode attribute to give the constraint for vector extract and insert
287 (define_mode_attr VSX_EX [(V16QI "v")
291 ;; Iterator for the 2 short vector types to do a splat from an integer
292 (define_mode_iterator VSX_SPLAT_I [V16QI V8HI])
294 ;; Mode attribute to give the count for the splat instruction to splat
295 ;; the value in the 64-bit integer slot
296 (define_mode_attr VSX_SPLAT_COUNT [(V16QI "7") (V8HI "3")])
298 ;; Mode attribute to give the suffix for the splat instruction
299 (define_mode_attr VSX_SPLAT_SUFFIX [(V16QI "b") (V8HI "h")])
301 ;; Constants for creating unspecs
302 (define_c_enum "unspec"
328 UNSPEC_VSX_XVCVDPSXDS
329 UNSPEC_VSX_XVCVDPUXDS
330 UNSPEC_VSX_SIGN_EXTEND
364 ;; The patterns for LE permuted loads and stores come before the general
365 ;; VSX moves so they match first.
366 (define_insn_and_split "*vsx_le_perm_load_<mode>"
367 [(set (match_operand:VSX_LE 0 "vsx_register_operand" "=<VSa>")
368 (match_operand:VSX_LE 1 "memory_operand" "Z"))]
369 "!BYTES_BIG_ENDIAN && TARGET_VSX && !TARGET_P9_VECTOR"
371 "!BYTES_BIG_ENDIAN && TARGET_VSX && !TARGET_P9_VECTOR"
375 (parallel [(const_int 1) (const_int 0)])))
379 (parallel [(const_int 1) (const_int 0)])))]
382 operands[2] = can_create_pseudo_p () ? gen_reg_rtx_and_attrs (operands[0])
386 [(set_attr "type" "vecload")
387 (set_attr "length" "8")])
389 (define_insn_and_split "*vsx_le_perm_load_<mode>"
390 [(set (match_operand:VSX_W 0 "vsx_register_operand" "=<VSa>")
391 (match_operand:VSX_W 1 "memory_operand" "Z"))]
392 "!BYTES_BIG_ENDIAN && TARGET_VSX && !TARGET_P9_VECTOR"
394 "!BYTES_BIG_ENDIAN && TARGET_VSX && !TARGET_P9_VECTOR"
398 (parallel [(const_int 2) (const_int 3)
399 (const_int 0) (const_int 1)])))
403 (parallel [(const_int 2) (const_int 3)
404 (const_int 0) (const_int 1)])))]
407 operands[2] = can_create_pseudo_p () ? gen_reg_rtx_and_attrs (operands[0])
411 [(set_attr "type" "vecload")
412 (set_attr "length" "8")])
414 (define_insn_and_split "*vsx_le_perm_load_v8hi"
415 [(set (match_operand:V8HI 0 "vsx_register_operand" "=wa")
416 (match_operand:V8HI 1 "memory_operand" "Z"))]
417 "!BYTES_BIG_ENDIAN && TARGET_VSX && !TARGET_P9_VECTOR"
419 "!BYTES_BIG_ENDIAN && TARGET_VSX && !TARGET_P9_VECTOR"
423 (parallel [(const_int 4) (const_int 5)
424 (const_int 6) (const_int 7)
425 (const_int 0) (const_int 1)
426 (const_int 2) (const_int 3)])))
430 (parallel [(const_int 4) (const_int 5)
431 (const_int 6) (const_int 7)
432 (const_int 0) (const_int 1)
433 (const_int 2) (const_int 3)])))]
436 operands[2] = can_create_pseudo_p () ? gen_reg_rtx_and_attrs (operands[0])
440 [(set_attr "type" "vecload")
441 (set_attr "length" "8")])
443 (define_insn_and_split "*vsx_le_perm_load_v16qi"
444 [(set (match_operand:V16QI 0 "vsx_register_operand" "=wa")
445 (match_operand:V16QI 1 "memory_operand" "Z"))]
446 "!BYTES_BIG_ENDIAN && TARGET_VSX && !TARGET_P9_VECTOR"
448 "!BYTES_BIG_ENDIAN && TARGET_VSX && !TARGET_P9_VECTOR"
452 (parallel [(const_int 8) (const_int 9)
453 (const_int 10) (const_int 11)
454 (const_int 12) (const_int 13)
455 (const_int 14) (const_int 15)
456 (const_int 0) (const_int 1)
457 (const_int 2) (const_int 3)
458 (const_int 4) (const_int 5)
459 (const_int 6) (const_int 7)])))
463 (parallel [(const_int 8) (const_int 9)
464 (const_int 10) (const_int 11)
465 (const_int 12) (const_int 13)
466 (const_int 14) (const_int 15)
467 (const_int 0) (const_int 1)
468 (const_int 2) (const_int 3)
469 (const_int 4) (const_int 5)
470 (const_int 6) (const_int 7)])))]
473 operands[2] = can_create_pseudo_p () ? gen_reg_rtx_and_attrs (operands[0])
477 [(set_attr "type" "vecload")
478 (set_attr "length" "8")])
480 (define_insn "*vsx_le_perm_store_<mode>"
481 [(set (match_operand:VSX_LE 0 "memory_operand" "=Z")
482 (match_operand:VSX_LE 1 "vsx_register_operand" "+<VSa>"))]
483 "!BYTES_BIG_ENDIAN && TARGET_VSX && !TARGET_P9_VECTOR"
485 [(set_attr "type" "vecstore")
486 (set_attr "length" "12")])
489 [(set (match_operand:VSX_LE 0 "memory_operand" "")
490 (match_operand:VSX_LE 1 "vsx_register_operand" ""))]
491 "!BYTES_BIG_ENDIAN && TARGET_VSX && !TARGET_P9_VECTOR && !reload_completed"
495 (parallel [(const_int 1) (const_int 0)])))
499 (parallel [(const_int 1) (const_int 0)])))]
501 operands[2] = can_create_pseudo_p () ? gen_reg_rtx_and_attrs (operands[1])
505 ;; The post-reload split requires that we re-permute the source
506 ;; register in case it is still live.
508 [(set (match_operand:VSX_LE 0 "memory_operand" "")
509 (match_operand:VSX_LE 1 "vsx_register_operand" ""))]
510 "!BYTES_BIG_ENDIAN && TARGET_VSX && !TARGET_P9_VECTOR && reload_completed"
514 (parallel [(const_int 1) (const_int 0)])))
518 (parallel [(const_int 1) (const_int 0)])))
522 (parallel [(const_int 1) (const_int 0)])))]
525 (define_insn "*vsx_le_perm_store_<mode>"
526 [(set (match_operand:VSX_W 0 "memory_operand" "=Z")
527 (match_operand:VSX_W 1 "vsx_register_operand" "+<VSa>"))]
528 "!BYTES_BIG_ENDIAN && TARGET_VSX && !TARGET_P9_VECTOR"
530 [(set_attr "type" "vecstore")
531 (set_attr "length" "12")])
534 [(set (match_operand:VSX_W 0 "memory_operand" "")
535 (match_operand:VSX_W 1 "vsx_register_operand" ""))]
536 "!BYTES_BIG_ENDIAN && TARGET_VSX && !TARGET_P9_VECTOR && !reload_completed"
540 (parallel [(const_int 2) (const_int 3)
541 (const_int 0) (const_int 1)])))
545 (parallel [(const_int 2) (const_int 3)
546 (const_int 0) (const_int 1)])))]
548 operands[2] = can_create_pseudo_p () ? gen_reg_rtx_and_attrs (operands[1])
552 ;; The post-reload split requires that we re-permute the source
553 ;; register in case it is still live.
555 [(set (match_operand:VSX_W 0 "memory_operand" "")
556 (match_operand:VSX_W 1 "vsx_register_operand" ""))]
557 "!BYTES_BIG_ENDIAN && TARGET_VSX && !TARGET_P9_VECTOR && reload_completed"
561 (parallel [(const_int 2) (const_int 3)
562 (const_int 0) (const_int 1)])))
566 (parallel [(const_int 2) (const_int 3)
567 (const_int 0) (const_int 1)])))
571 (parallel [(const_int 2) (const_int 3)
572 (const_int 0) (const_int 1)])))]
575 (define_insn "*vsx_le_perm_store_v8hi"
576 [(set (match_operand:V8HI 0 "memory_operand" "=Z")
577 (match_operand:V8HI 1 "vsx_register_operand" "+wa"))]
578 "!BYTES_BIG_ENDIAN && TARGET_VSX && !TARGET_P9_VECTOR"
580 [(set_attr "type" "vecstore")
581 (set_attr "length" "12")])
584 [(set (match_operand:V8HI 0 "memory_operand" "")
585 (match_operand:V8HI 1 "vsx_register_operand" ""))]
586 "!BYTES_BIG_ENDIAN && TARGET_VSX && !TARGET_P9_VECTOR && !reload_completed"
590 (parallel [(const_int 4) (const_int 5)
591 (const_int 6) (const_int 7)
592 (const_int 0) (const_int 1)
593 (const_int 2) (const_int 3)])))
597 (parallel [(const_int 4) (const_int 5)
598 (const_int 6) (const_int 7)
599 (const_int 0) (const_int 1)
600 (const_int 2) (const_int 3)])))]
602 operands[2] = can_create_pseudo_p () ? gen_reg_rtx_and_attrs (operands[1])
606 ;; The post-reload split requires that we re-permute the source
607 ;; register in case it is still live.
609 [(set (match_operand:V8HI 0 "memory_operand" "")
610 (match_operand:V8HI 1 "vsx_register_operand" ""))]
611 "!BYTES_BIG_ENDIAN && TARGET_VSX && !TARGET_P9_VECTOR && reload_completed"
615 (parallel [(const_int 4) (const_int 5)
616 (const_int 6) (const_int 7)
617 (const_int 0) (const_int 1)
618 (const_int 2) (const_int 3)])))
622 (parallel [(const_int 4) (const_int 5)
623 (const_int 6) (const_int 7)
624 (const_int 0) (const_int 1)
625 (const_int 2) (const_int 3)])))
629 (parallel [(const_int 4) (const_int 5)
630 (const_int 6) (const_int 7)
631 (const_int 0) (const_int 1)
632 (const_int 2) (const_int 3)])))]
635 (define_insn "*vsx_le_perm_store_v16qi"
636 [(set (match_operand:V16QI 0 "memory_operand" "=Z")
637 (match_operand:V16QI 1 "vsx_register_operand" "+wa"))]
638 "!BYTES_BIG_ENDIAN && TARGET_VSX && !TARGET_P9_VECTOR"
640 [(set_attr "type" "vecstore")
641 (set_attr "length" "12")])
644 [(set (match_operand:V16QI 0 "memory_operand" "")
645 (match_operand:V16QI 1 "vsx_register_operand" ""))]
646 "!BYTES_BIG_ENDIAN && TARGET_VSX && !TARGET_P9_VECTOR && !reload_completed"
650 (parallel [(const_int 8) (const_int 9)
651 (const_int 10) (const_int 11)
652 (const_int 12) (const_int 13)
653 (const_int 14) (const_int 15)
654 (const_int 0) (const_int 1)
655 (const_int 2) (const_int 3)
656 (const_int 4) (const_int 5)
657 (const_int 6) (const_int 7)])))
661 (parallel [(const_int 8) (const_int 9)
662 (const_int 10) (const_int 11)
663 (const_int 12) (const_int 13)
664 (const_int 14) (const_int 15)
665 (const_int 0) (const_int 1)
666 (const_int 2) (const_int 3)
667 (const_int 4) (const_int 5)
668 (const_int 6) (const_int 7)])))]
670 operands[2] = can_create_pseudo_p () ? gen_reg_rtx_and_attrs (operands[1])
674 ;; The post-reload split requires that we re-permute the source
675 ;; register in case it is still live.
677 [(set (match_operand:V16QI 0 "memory_operand" "")
678 (match_operand:V16QI 1 "vsx_register_operand" ""))]
679 "!BYTES_BIG_ENDIAN && TARGET_VSX && !TARGET_P9_VECTOR && reload_completed"
683 (parallel [(const_int 8) (const_int 9)
684 (const_int 10) (const_int 11)
685 (const_int 12) (const_int 13)
686 (const_int 14) (const_int 15)
687 (const_int 0) (const_int 1)
688 (const_int 2) (const_int 3)
689 (const_int 4) (const_int 5)
690 (const_int 6) (const_int 7)])))
694 (parallel [(const_int 8) (const_int 9)
695 (const_int 10) (const_int 11)
696 (const_int 12) (const_int 13)
697 (const_int 14) (const_int 15)
698 (const_int 0) (const_int 1)
699 (const_int 2) (const_int 3)
700 (const_int 4) (const_int 5)
701 (const_int 6) (const_int 7)])))
705 (parallel [(const_int 8) (const_int 9)
706 (const_int 10) (const_int 11)
707 (const_int 12) (const_int 13)
708 (const_int 14) (const_int 15)
709 (const_int 0) (const_int 1)
710 (const_int 2) (const_int 3)
711 (const_int 4) (const_int 5)
712 (const_int 6) (const_int 7)])))]
715 ;; Little endian word swapping for 128-bit types that are either scalars or the
716 ;; special V1TI container class, which it is not appropriate to use vec_select
718 (define_insn "*vsx_le_permute_<mode>"
719 [(set (match_operand:VSX_LE_128 0 "nonimmediate_operand" "=<VSa>,<VSa>,Z")
721 (match_operand:VSX_LE_128 1 "input_operand" "<VSa>,Z,<VSa>")
723 "!BYTES_BIG_ENDIAN && TARGET_VSX && !TARGET_P9_VECTOR"
725 xxpermdi %x0,%x1,%x1,2
728 [(set_attr "length" "4")
729 (set_attr "type" "vecperm,vecload,vecstore")])
731 (define_insn_and_split "*vsx_le_undo_permute_<mode>"
732 [(set (match_operand:VSX_LE_128 0 "vsx_register_operand" "=<VSa>,<VSa>")
735 (match_operand:VSX_LE_128 1 "vsx_register_operand" "0,<VSa>")
738 "!BYTES_BIG_ENDIAN && TARGET_VSX"
743 [(set (match_dup 0) (match_dup 1))]
745 if (reload_completed && REGNO (operands[0]) == REGNO (operands[1]))
747 emit_note (NOTE_INSN_DELETED);
751 [(set_attr "length" "0,4")
752 (set_attr "type" "veclogical")])
754 (define_insn_and_split "*vsx_le_perm_load_<mode>"
755 [(set (match_operand:VSX_LE_128 0 "vsx_register_operand" "=<VSa>")
756 (match_operand:VSX_LE_128 1 "memory_operand" "Z"))]
757 "!BYTES_BIG_ENDIAN && TARGET_VSX && !TARGET_P9_VECTOR"
759 "!BYTES_BIG_ENDIAN && TARGET_VSX && !TARGET_P9_VECTOR"
761 (rotate:VSX_LE_128 (match_dup 1)
764 (rotate:VSX_LE_128 (match_dup 2)
768 operands[2] = can_create_pseudo_p () ? gen_reg_rtx_and_attrs (operands[0])
772 [(set_attr "type" "vecload")
773 (set_attr "length" "8")])
775 (define_insn "*vsx_le_perm_store_<mode>"
776 [(set (match_operand:VSX_LE_128 0 "memory_operand" "=Z")
777 (match_operand:VSX_LE_128 1 "vsx_register_operand" "+<VSa>"))]
778 "!BYTES_BIG_ENDIAN && TARGET_VSX && !TARGET_P9_VECTOR"
780 [(set_attr "type" "vecstore")
781 (set_attr "length" "12")])
784 [(set (match_operand:VSX_LE_128 0 "memory_operand" "")
785 (match_operand:VSX_LE_128 1 "vsx_register_operand" ""))]
786 "!BYTES_BIG_ENDIAN && TARGET_VSX && !reload_completed && !TARGET_P9_VECTOR"
788 (rotate:VSX_LE_128 (match_dup 1)
791 (rotate:VSX_LE_128 (match_dup 2)
794 operands[2] = can_create_pseudo_p () ? gen_reg_rtx_and_attrs (operands[0])
798 ;; Peephole to catch memory to memory transfers for TImode if TImode landed in
799 ;; VSX registers on a little endian system. The vector types and IEEE 128-bit
800 ;; floating point are handled by the more generic swap elimination pass.
802 [(set (match_operand:TI 0 "vsx_register_operand" "")
803 (rotate:TI (match_operand:TI 1 "vsx_register_operand" "")
805 (set (match_operand:TI 2 "vsx_register_operand" "")
806 (rotate:TI (match_dup 0)
808 "!BYTES_BIG_ENDIAN && TARGET_VSX && TARGET_VSX_TIMODE && !TARGET_P9_VECTOR
809 && (rtx_equal_p (operands[0], operands[2])
810 || peep2_reg_dead_p (2, operands[0]))"
811 [(set (match_dup 2) (match_dup 1))])
813 ;; The post-reload split requires that we re-permute the source
814 ;; register in case it is still live.
816 [(set (match_operand:VSX_LE_128 0 "memory_operand" "")
817 (match_operand:VSX_LE_128 1 "vsx_register_operand" ""))]
818 "!BYTES_BIG_ENDIAN && TARGET_VSX && reload_completed && !TARGET_P9_VECTOR"
820 (rotate:VSX_LE_128 (match_dup 1)
823 (rotate:VSX_LE_128 (match_dup 1)
826 (rotate:VSX_LE_128 (match_dup 1)
830 ;; Vector constants that can be generated with XXSPLTIB that was added in ISA
831 ;; 3.0. Both (const_vector [..]) and (vec_duplicate ...) forms are recognized.
832 (define_insn "xxspltib_v16qi"
833 [(set (match_operand:V16QI 0 "vsx_register_operand" "=wa")
834 (vec_duplicate:V16QI (match_operand:SI 1 "s8bit_cint_operand" "n")))]
837 operands[2] = GEN_INT (INTVAL (operands[1]) & 0xff);
838 return "xxspltib %x0,%2";
840 [(set_attr "type" "vecperm")])
842 (define_insn "xxspltib_<mode>_nosplit"
843 [(set (match_operand:VSINT_842 0 "vsx_register_operand" "=wa,wa")
844 (match_operand:VSINT_842 1 "xxspltib_constant_nosplit" "jwM,wE"))]
847 rtx op1 = operands[1];
851 if (!xxspltib_constant_p (op1, <MODE>mode, &num_insns, &value)
855 operands[2] = GEN_INT (value & 0xff);
856 return "xxspltib %x0,%2";
858 [(set_attr "type" "vecperm")])
860 (define_insn_and_split "*xxspltib_<mode>_split"
861 [(set (match_operand:VSINT_842 0 "altivec_register_operand" "=v")
862 (match_operand:VSINT_842 1 "xxspltib_constant_split" "wS"))]
870 rtx op0 = operands[0];
871 rtx op1 = operands[1];
872 rtx tmp = ((can_create_pseudo_p ())
873 ? gen_reg_rtx (V16QImode)
874 : gen_lowpart (V16QImode, op0));
876 if (!xxspltib_constant_p (op1, <MODE>mode, &num_insns, &value)
880 emit_insn (gen_xxspltib_v16qi (tmp, GEN_INT (value)));
882 if (<MODE>mode == V2DImode)
883 emit_insn (gen_vsx_sign_extend_qi_v2di (op0, tmp));
885 else if (<MODE>mode == V4SImode)
886 emit_insn (gen_vsx_sign_extend_qi_v4si (op0, tmp));
888 else if (<MODE>mode == V8HImode)
889 emit_insn (gen_altivec_vupkhsb (op0, tmp));
896 [(set_attr "type" "vecperm")
897 (set_attr "length" "8")])
900 ;; Prefer using vector registers over GPRs. Prefer using ISA 3.0's XXSPLTISB
901 ;; or Altivec VSPLITW 0/-1 over XXLXOR/XXLORC to set a register to all 0's or
902 ;; all 1's, since the machine does not have to wait for the previous
903 ;; instruction using the register being set (such as a store waiting on a slow
904 ;; instruction). But generate XXLXOR/XXLORC if it will avoid a register move.
906 ;; VSX store VSX load VSX move VSX->GPR GPR->VSX LQ (GPR)
907 ;; STQ (GPR) GPR load GPR store GPR move XXSPLTIB VSPLTISW
908 ;; VSX 0/-1 GPR 0/-1 VMX const GPR const LVX (VMX) STVX (VMX)
909 (define_insn "*vsx_mov<mode>_64bit"
910 [(set (match_operand:VSX_M 0 "nonimmediate_operand"
911 "=ZwO, <VSa>, <VSa>, r, we, ?wQ,
912 ?&r, ??r, ??Y, ??r, wo, v,
913 ?<VSa>, *r, v, ??r, wZ, v")
915 (match_operand:VSX_M 1 "input_operand"
916 "<VSa>, ZwO, <VSa>, we, r, r,
917 wQ, Y, r, r, wE, jwM,
918 ?jwM, jwM, W, W, v, wZ"))]
920 "TARGET_POWERPC64 && VECTOR_MEM_VSX_P (<MODE>mode)
921 && (register_operand (operands[0], <MODE>mode)
922 || register_operand (operands[1], <MODE>mode))"
924 return rs6000_output_move_128bit (operands);
927 "vecstore, vecload, vecsimple, mffgpr, mftgpr, load,
928 store, load, store, *, vecsimple, vecsimple,
929 vecsimple, *, *, *, vecstore, vecload")
934 4, 8, 20, 20, 4, 4")])
936 ;; VSX store VSX load VSX move GPR load GPR store GPR move
937 ;; XXSPLTIB VSPLTISW VSX 0/-1 GPR 0/-1 VMX const GPR const
938 ;; LVX (VMX) STVX (VMX)
939 (define_insn "*vsx_mov<mode>_32bit"
940 [(set (match_operand:VSX_M 0 "nonimmediate_operand"
941 "=ZwO, <VSa>, <VSa>, ??r, ??Y, ??r,
942 wo, v, ?<VSa>, *r, v, ??r,
945 (match_operand:VSX_M 1 "input_operand"
946 "<VSa>, ZwO, <VSa>, Y, r, r,
947 wE, jwM, ?jwM, jwM, W, W,
950 "!TARGET_POWERPC64 && VECTOR_MEM_VSX_P (<MODE>mode)
951 && (register_operand (operands[0], <MODE>mode)
952 || register_operand (operands[1], <MODE>mode))"
954 return rs6000_output_move_128bit (operands);
957 "vecstore, vecload, vecsimple, load, store, *,
958 vecsimple, vecsimple, vecsimple, *, *, *,
962 "4, 4, 4, 16, 16, 16,
966 ;; Explicit load/store expanders for the builtin functions
967 (define_expand "vsx_load_<mode>"
968 [(set (match_operand:VSX_M 0 "vsx_register_operand" "")
969 (match_operand:VSX_M 1 "memory_operand" ""))]
970 "VECTOR_MEM_VSX_P (<MODE>mode)"
972 /* Expand to swaps if needed, prior to swap optimization. */
973 if (!BYTES_BIG_ENDIAN && !TARGET_P9_VECTOR)
975 rs6000_emit_le_vsx_move (operands[0], operands[1], <MODE>mode);
980 (define_expand "vsx_store_<mode>"
981 [(set (match_operand:VSX_M 0 "memory_operand" "")
982 (match_operand:VSX_M 1 "vsx_register_operand" ""))]
983 "VECTOR_MEM_VSX_P (<MODE>mode)"
985 /* Expand to swaps if needed, prior to swap optimization. */
986 if (!BYTES_BIG_ENDIAN && !TARGET_P9_VECTOR)
988 rs6000_emit_le_vsx_move (operands[0], operands[1], <MODE>mode);
993 ;; Explicit load/store expanders for the builtin functions for lxvd2x, etc.,
994 ;; when you really want their element-reversing behavior.
995 (define_insn "vsx_ld_elemrev_v2di"
996 [(set (match_operand:V2DI 0 "vsx_register_operand" "=wa")
998 (match_operand:V2DI 1 "memory_operand" "Z")
999 (parallel [(const_int 1) (const_int 0)])))]
1000 "VECTOR_MEM_VSX_P (V2DImode) && !BYTES_BIG_ENDIAN"
1002 [(set_attr "type" "vecload")])
1004 (define_insn "vsx_ld_elemrev_v2df"
1005 [(set (match_operand:V2DF 0 "vsx_register_operand" "=wa")
1007 (match_operand:V2DF 1 "memory_operand" "Z")
1008 (parallel [(const_int 1) (const_int 0)])))]
1009 "VECTOR_MEM_VSX_P (V2DFmode) && !BYTES_BIG_ENDIAN"
1011 [(set_attr "type" "vecload")])
1013 (define_insn "vsx_ld_elemrev_v4si"
1014 [(set (match_operand:V4SI 0 "vsx_register_operand" "=wa")
1016 (match_operand:V4SI 1 "memory_operand" "Z")
1017 (parallel [(const_int 3) (const_int 2)
1018 (const_int 1) (const_int 0)])))]
1019 "VECTOR_MEM_VSX_P (V4SImode) && !BYTES_BIG_ENDIAN"
1021 [(set_attr "type" "vecload")])
1023 (define_insn "vsx_ld_elemrev_v4sf"
1024 [(set (match_operand:V4SF 0 "vsx_register_operand" "=wa")
1026 (match_operand:V4SF 1 "memory_operand" "Z")
1027 (parallel [(const_int 3) (const_int 2)
1028 (const_int 1) (const_int 0)])))]
1029 "VECTOR_MEM_VSX_P (V4SFmode) && !BYTES_BIG_ENDIAN"
1031 [(set_attr "type" "vecload")])
1033 (define_insn "vsx_ld_elemrev_v8hi"
1034 [(set (match_operand:V8HI 0 "vsx_register_operand" "=wa")
1036 (match_operand:V8HI 1 "memory_operand" "Z")
1037 (parallel [(const_int 7) (const_int 6)
1038 (const_int 5) (const_int 4)
1039 (const_int 3) (const_int 2)
1040 (const_int 1) (const_int 0)])))]
1041 "VECTOR_MEM_VSX_P (V8HImode) && !BYTES_BIG_ENDIAN && TARGET_P9_VECTOR"
1043 [(set_attr "type" "vecload")])
1045 (define_insn "vsx_ld_elemrev_v16qi"
1046 [(set (match_operand:V16QI 0 "vsx_register_operand" "=wa")
1048 (match_operand:V16QI 1 "memory_operand" "Z")
1049 (parallel [(const_int 15) (const_int 14)
1050 (const_int 13) (const_int 12)
1051 (const_int 11) (const_int 10)
1052 (const_int 9) (const_int 8)
1053 (const_int 7) (const_int 6)
1054 (const_int 5) (const_int 4)
1055 (const_int 3) (const_int 2)
1056 (const_int 1) (const_int 0)])))]
1057 "VECTOR_MEM_VSX_P (V16QImode) && !BYTES_BIG_ENDIAN && TARGET_P9_VECTOR"
1059 [(set_attr "type" "vecload")])
1061 (define_insn "vsx_st_elemrev_v2df"
1062 [(set (match_operand:V2DF 0 "memory_operand" "=Z")
1064 (match_operand:V2DF 1 "vsx_register_operand" "wa")
1065 (parallel [(const_int 1) (const_int 0)])))]
1066 "VECTOR_MEM_VSX_P (V2DFmode) && !BYTES_BIG_ENDIAN"
1068 [(set_attr "type" "vecstore")])
1070 (define_insn "vsx_st_elemrev_v2di"
1071 [(set (match_operand:V2DI 0 "memory_operand" "=Z")
1073 (match_operand:V2DI 1 "vsx_register_operand" "wa")
1074 (parallel [(const_int 1) (const_int 0)])))]
1075 "VECTOR_MEM_VSX_P (V2DImode) && !BYTES_BIG_ENDIAN"
1077 [(set_attr "type" "vecstore")])
1079 (define_insn "vsx_st_elemrev_v4sf"
1080 [(set (match_operand:V4SF 0 "memory_operand" "=Z")
1082 (match_operand:V4SF 1 "vsx_register_operand" "wa")
1083 (parallel [(const_int 3) (const_int 2)
1084 (const_int 1) (const_int 0)])))]
1085 "VECTOR_MEM_VSX_P (V4SFmode) && !BYTES_BIG_ENDIAN"
1087 [(set_attr "type" "vecstore")])
1089 (define_insn "vsx_st_elemrev_v4si"
1090 [(set (match_operand:V4SI 0 "memory_operand" "=Z")
1092 (match_operand:V4SI 1 "vsx_register_operand" "wa")
1093 (parallel [(const_int 3) (const_int 2)
1094 (const_int 1) (const_int 0)])))]
1095 "VECTOR_MEM_VSX_P (V4SImode) && !BYTES_BIG_ENDIAN"
1097 [(set_attr "type" "vecstore")])
1099 (define_insn "vsx_st_elemrev_v8hi"
1100 [(set (match_operand:V8HI 0 "memory_operand" "=Z")
1102 (match_operand:V8HI 1 "vsx_register_operand" "wa")
1103 (parallel [(const_int 7) (const_int 6)
1104 (const_int 5) (const_int 4)
1105 (const_int 3) (const_int 2)
1106 (const_int 1) (const_int 0)])))]
1107 "VECTOR_MEM_VSX_P (V8HImode) && !BYTES_BIG_ENDIAN && TARGET_P9_VECTOR"
1109 [(set_attr "type" "vecstore")])
1111 (define_insn "vsx_st_elemrev_v16qi"
1112 [(set (match_operand:V16QI 0 "memory_operand" "=Z")
1114 (match_operand:V16QI 1 "vsx_register_operand" "wa")
1115 (parallel [(const_int 15) (const_int 14)
1116 (const_int 13) (const_int 12)
1117 (const_int 11) (const_int 10)
1118 (const_int 9) (const_int 8)
1119 (const_int 7) (const_int 6)
1120 (const_int 5) (const_int 4)
1121 (const_int 3) (const_int 2)
1122 (const_int 1) (const_int 0)])))]
1123 "VECTOR_MEM_VSX_P (V16QImode) && !BYTES_BIG_ENDIAN && TARGET_P9_VECTOR"
1125 [(set_attr "type" "vecstore")])
1128 ;; VSX vector floating point arithmetic instructions. The VSX scalar
1129 ;; instructions are now combined with the insn for the traditional floating
1131 (define_insn "*vsx_add<mode>3"
1132 [(set (match_operand:VSX_F 0 "vsx_register_operand" "=<VSr>,?<VSa>")
1133 (plus:VSX_F (match_operand:VSX_F 1 "vsx_register_operand" "<VSr>,<VSa>")
1134 (match_operand:VSX_F 2 "vsx_register_operand" "<VSr>,<VSa>")))]
1135 "VECTOR_UNIT_VSX_P (<MODE>mode)"
1136 "xvadd<VSs> %x0,%x1,%x2"
1137 [(set_attr "type" "<VStype_simple>")
1138 (set_attr "fp_type" "<VSfptype_simple>")])
1140 (define_insn "*vsx_sub<mode>3"
1141 [(set (match_operand:VSX_F 0 "vsx_register_operand" "=<VSr>,?<VSa>")
1142 (minus:VSX_F (match_operand:VSX_F 1 "vsx_register_operand" "<VSr>,<VSa>")
1143 (match_operand:VSX_F 2 "vsx_register_operand" "<VSr>,<VSa>")))]
1144 "VECTOR_UNIT_VSX_P (<MODE>mode)"
1145 "xvsub<VSs> %x0,%x1,%x2"
1146 [(set_attr "type" "<VStype_simple>")
1147 (set_attr "fp_type" "<VSfptype_simple>")])
1149 (define_insn "*vsx_mul<mode>3"
1150 [(set (match_operand:VSX_F 0 "vsx_register_operand" "=<VSr>,?<VSa>")
1151 (mult:VSX_F (match_operand:VSX_F 1 "vsx_register_operand" "<VSr>,<VSa>")
1152 (match_operand:VSX_F 2 "vsx_register_operand" "<VSr>,<VSa>")))]
1153 "VECTOR_UNIT_VSX_P (<MODE>mode)"
1154 "xvmul<VSs> %x0,%x1,%x2"
1155 [(set_attr "type" "<VStype_simple>")
1156 (set_attr "fp_type" "<VSfptype_mul>")])
1158 ; Emulate vector with scalar for vec_mul in V2DImode
1159 (define_insn_and_split "vsx_mul_v2di"
1160 [(set (match_operand:V2DI 0 "vsx_register_operand" "=wa")
1161 (unspec:V2DI [(match_operand:V2DI 1 "vsx_register_operand" "wa")
1162 (match_operand:V2DI 2 "vsx_register_operand" "wa")]
1164 "VECTOR_MEM_VSX_P (V2DImode)"
1166 "VECTOR_MEM_VSX_P (V2DImode) && !reload_completed && !reload_in_progress"
1170 rtx op0 = operands[0];
1171 rtx op1 = operands[1];
1172 rtx op2 = operands[2];
1173 rtx op3 = gen_reg_rtx (DImode);
1174 rtx op4 = gen_reg_rtx (DImode);
1175 rtx op5 = gen_reg_rtx (DImode);
1176 emit_insn (gen_vsx_extract_v2di (op3, op1, GEN_INT (0)));
1177 emit_insn (gen_vsx_extract_v2di (op4, op2, GEN_INT (0)));
1178 emit_insn (gen_muldi3 (op5, op3, op4));
1179 emit_insn (gen_vsx_extract_v2di (op3, op1, GEN_INT (1)));
1180 emit_insn (gen_vsx_extract_v2di (op4, op2, GEN_INT (1)));
1181 emit_insn (gen_muldi3 (op3, op3, op4));
1182 emit_insn (gen_vsx_concat_v2di (op0, op5, op3));
1185 [(set_attr "type" "mul")])
1187 (define_insn "*vsx_div<mode>3"
1188 [(set (match_operand:VSX_F 0 "vsx_register_operand" "=<VSr>,?<VSa>")
1189 (div:VSX_F (match_operand:VSX_F 1 "vsx_register_operand" "<VSr>,<VSa>")
1190 (match_operand:VSX_F 2 "vsx_register_operand" "<VSr>,<VSa>")))]
1191 "VECTOR_UNIT_VSX_P (<MODE>mode)"
1192 "xvdiv<VSs> %x0,%x1,%x2"
1193 [(set_attr "type" "<VStype_div>")
1194 (set_attr "fp_type" "<VSfptype_div>")])
1196 ; Emulate vector with scalar for vec_div in V2DImode
1197 (define_insn_and_split "vsx_div_v2di"
1198 [(set (match_operand:V2DI 0 "vsx_register_operand" "=wa")
1199 (unspec:V2DI [(match_operand:V2DI 1 "vsx_register_operand" "wa")
1200 (match_operand:V2DI 2 "vsx_register_operand" "wa")]
1202 "VECTOR_MEM_VSX_P (V2DImode)"
1204 "VECTOR_MEM_VSX_P (V2DImode) && !reload_completed && !reload_in_progress"
1208 rtx op0 = operands[0];
1209 rtx op1 = operands[1];
1210 rtx op2 = operands[2];
1211 rtx op3 = gen_reg_rtx (DImode);
1212 rtx op4 = gen_reg_rtx (DImode);
1213 rtx op5 = gen_reg_rtx (DImode);
1214 emit_insn (gen_vsx_extract_v2di (op3, op1, GEN_INT (0)));
1215 emit_insn (gen_vsx_extract_v2di (op4, op2, GEN_INT (0)));
1216 emit_insn (gen_divdi3 (op5, op3, op4));
1217 emit_insn (gen_vsx_extract_v2di (op3, op1, GEN_INT (1)));
1218 emit_insn (gen_vsx_extract_v2di (op4, op2, GEN_INT (1)));
1219 emit_insn (gen_divdi3 (op3, op3, op4));
1220 emit_insn (gen_vsx_concat_v2di (op0, op5, op3));
1223 [(set_attr "type" "div")])
1225 (define_insn_and_split "vsx_udiv_v2di"
1226 [(set (match_operand:V2DI 0 "vsx_register_operand" "=wa")
1227 (unspec:V2DI [(match_operand:V2DI 1 "vsx_register_operand" "wa")
1228 (match_operand:V2DI 2 "vsx_register_operand" "wa")]
1230 "VECTOR_MEM_VSX_P (V2DImode)"
1232 "VECTOR_MEM_VSX_P (V2DImode) && !reload_completed && !reload_in_progress"
1236 rtx op0 = operands[0];
1237 rtx op1 = operands[1];
1238 rtx op2 = operands[2];
1239 rtx op3 = gen_reg_rtx (DImode);
1240 rtx op4 = gen_reg_rtx (DImode);
1241 rtx op5 = gen_reg_rtx (DImode);
1242 emit_insn (gen_vsx_extract_v2di (op3, op1, GEN_INT (0)));
1243 emit_insn (gen_vsx_extract_v2di (op4, op2, GEN_INT (0)));
1244 emit_insn (gen_udivdi3 (op5, op3, op4));
1245 emit_insn (gen_vsx_extract_v2di (op3, op1, GEN_INT (1)));
1246 emit_insn (gen_vsx_extract_v2di (op4, op2, GEN_INT (1)));
1247 emit_insn (gen_udivdi3 (op3, op3, op4));
1248 emit_insn (gen_vsx_concat_v2di (op0, op5, op3));
1251 [(set_attr "type" "div")])
1253 ;; *tdiv* instruction returning the FG flag
1254 (define_expand "vsx_tdiv<mode>3_fg"
1256 (unspec:CCFP [(match_operand:VSX_B 1 "vsx_register_operand" "")
1257 (match_operand:VSX_B 2 "vsx_register_operand" "")]
1259 (set (match_operand:SI 0 "gpc_reg_operand" "")
1260 (gt:SI (match_dup 3)
1262 "VECTOR_UNIT_VSX_P (<MODE>mode)"
1264 operands[3] = gen_reg_rtx (CCFPmode);
1267 ;; *tdiv* instruction returning the FE flag
1268 (define_expand "vsx_tdiv<mode>3_fe"
1270 (unspec:CCFP [(match_operand:VSX_B 1 "vsx_register_operand" "")
1271 (match_operand:VSX_B 2 "vsx_register_operand" "")]
1273 (set (match_operand:SI 0 "gpc_reg_operand" "")
1274 (eq:SI (match_dup 3)
1276 "VECTOR_UNIT_VSX_P (<MODE>mode)"
1278 operands[3] = gen_reg_rtx (CCFPmode);
1281 (define_insn "*vsx_tdiv<mode>3_internal"
1282 [(set (match_operand:CCFP 0 "cc_reg_operand" "=x,x")
1283 (unspec:CCFP [(match_operand:VSX_B 1 "vsx_register_operand" "<VSr>,<VSa>")
1284 (match_operand:VSX_B 2 "vsx_register_operand" "<VSr>,<VSa>")]
1286 "VECTOR_UNIT_VSX_P (<MODE>mode)"
1287 "x<VSv>tdiv<VSs> %0,%x1,%x2"
1288 [(set_attr "type" "<VStype_simple>")
1289 (set_attr "fp_type" "<VSfptype_simple>")])
1291 (define_insn "vsx_fre<mode>2"
1292 [(set (match_operand:VSX_F 0 "vsx_register_operand" "=<VSr>,?<VSa>")
1293 (unspec:VSX_F [(match_operand:VSX_F 1 "vsx_register_operand" "<VSr>,<VSa>")]
1295 "VECTOR_UNIT_VSX_P (<MODE>mode)"
1297 [(set_attr "type" "<VStype_simple>")
1298 (set_attr "fp_type" "<VSfptype_simple>")])
1300 (define_insn "*vsx_neg<mode>2"
1301 [(set (match_operand:VSX_F 0 "vsx_register_operand" "=<VSr>,?<VSa>")
1302 (neg:VSX_F (match_operand:VSX_F 1 "vsx_register_operand" "<VSr>,<VSa>")))]
1303 "VECTOR_UNIT_VSX_P (<MODE>mode)"
1304 "xvneg<VSs> %x0,%x1"
1305 [(set_attr "type" "<VStype_simple>")
1306 (set_attr "fp_type" "<VSfptype_simple>")])
1308 (define_insn "*vsx_abs<mode>2"
1309 [(set (match_operand:VSX_F 0 "vsx_register_operand" "=<VSr>,?<VSa>")
1310 (abs:VSX_F (match_operand:VSX_F 1 "vsx_register_operand" "<VSr>,<VSa>")))]
1311 "VECTOR_UNIT_VSX_P (<MODE>mode)"
1312 "xvabs<VSs> %x0,%x1"
1313 [(set_attr "type" "<VStype_simple>")
1314 (set_attr "fp_type" "<VSfptype_simple>")])
1316 (define_insn "vsx_nabs<mode>2"
1317 [(set (match_operand:VSX_F 0 "vsx_register_operand" "=<VSr>,?<VSa>")
1320 (match_operand:VSX_F 1 "vsx_register_operand" "<VSr>,<VSa>"))))]
1321 "VECTOR_UNIT_VSX_P (<MODE>mode)"
1322 "xvnabs<VSs> %x0,%x1"
1323 [(set_attr "type" "<VStype_simple>")
1324 (set_attr "fp_type" "<VSfptype_simple>")])
1326 (define_insn "vsx_smax<mode>3"
1327 [(set (match_operand:VSX_F 0 "vsx_register_operand" "=<VSr>,?<VSa>")
1328 (smax:VSX_F (match_operand:VSX_F 1 "vsx_register_operand" "<VSr>,<VSa>")
1329 (match_operand:VSX_F 2 "vsx_register_operand" "<VSr>,<VSa>")))]
1330 "VECTOR_UNIT_VSX_P (<MODE>mode)"
1331 "xvmax<VSs> %x0,%x1,%x2"
1332 [(set_attr "type" "<VStype_simple>")
1333 (set_attr "fp_type" "<VSfptype_simple>")])
1335 (define_insn "*vsx_smin<mode>3"
1336 [(set (match_operand:VSX_F 0 "vsx_register_operand" "=<VSr>,?<VSa>")
1337 (smin:VSX_F (match_operand:VSX_F 1 "vsx_register_operand" "<VSr>,<VSa>")
1338 (match_operand:VSX_F 2 "vsx_register_operand" "<VSr>,<VSa>")))]
1339 "VECTOR_UNIT_VSX_P (<MODE>mode)"
1340 "xvmin<VSs> %x0,%x1,%x2"
1341 [(set_attr "type" "<VStype_simple>")
1342 (set_attr "fp_type" "<VSfptype_simple>")])
1344 (define_insn "*vsx_sqrt<mode>2"
1345 [(set (match_operand:VSX_F 0 "vsx_register_operand" "=<VSr>,?<VSa>")
1346 (sqrt:VSX_F (match_operand:VSX_F 1 "vsx_register_operand" "<VSr>,<VSa>")))]
1347 "VECTOR_UNIT_VSX_P (<MODE>mode)"
1348 "xvsqrt<VSs> %x0,%x1"
1349 [(set_attr "type" "<VStype_sqrt>")
1350 (set_attr "fp_type" "<VSfptype_sqrt>")])
1352 (define_insn "*vsx_rsqrte<mode>2"
1353 [(set (match_operand:VSX_F 0 "vsx_register_operand" "=<VSr>,?<VSa>")
1354 (unspec:VSX_F [(match_operand:VSX_F 1 "vsx_register_operand" "<VSr>,<VSa>")]
1356 "VECTOR_UNIT_VSX_P (<MODE>mode)"
1357 "xvrsqrte<VSs> %x0,%x1"
1358 [(set_attr "type" "<VStype_simple>")
1359 (set_attr "fp_type" "<VSfptype_simple>")])
1361 ;; *tsqrt* returning the fg flag
1362 (define_expand "vsx_tsqrt<mode>2_fg"
1364 (unspec:CCFP [(match_operand:VSX_B 1 "vsx_register_operand" "")]
1366 (set (match_operand:SI 0 "gpc_reg_operand" "")
1367 (gt:SI (match_dup 3)
1369 "VECTOR_UNIT_VSX_P (<MODE>mode)"
1371 operands[3] = gen_reg_rtx (CCFPmode);
1374 ;; *tsqrt* returning the fe flag
1375 (define_expand "vsx_tsqrt<mode>2_fe"
1377 (unspec:CCFP [(match_operand:VSX_B 1 "vsx_register_operand" "")]
1379 (set (match_operand:SI 0 "gpc_reg_operand" "")
1380 (eq:SI (match_dup 3)
1382 "VECTOR_UNIT_VSX_P (<MODE>mode)"
1384 operands[3] = gen_reg_rtx (CCFPmode);
1387 (define_insn "*vsx_tsqrt<mode>2_internal"
1388 [(set (match_operand:CCFP 0 "cc_reg_operand" "=x,x")
1389 (unspec:CCFP [(match_operand:VSX_B 1 "vsx_register_operand" "<VSr>,<VSa>")]
1391 "VECTOR_UNIT_VSX_P (<MODE>mode)"
1392 "x<VSv>tsqrt<VSs> %0,%x1"
1393 [(set_attr "type" "<VStype_simple>")
1394 (set_attr "fp_type" "<VSfptype_simple>")])
1396 ;; Fused vector multiply/add instructions. Support the classical Altivec
1397 ;; versions of fma, which allows the target to be a separate register from the
1398 ;; 3 inputs. Under VSX, the target must be either the addend or the first
1401 (define_insn "*vsx_fmav4sf4"
1402 [(set (match_operand:V4SF 0 "vsx_register_operand" "=wf,wf,?wa,?wa,v")
1404 (match_operand:V4SF 1 "vsx_register_operand" "%wf,wf,wa,wa,v")
1405 (match_operand:V4SF 2 "vsx_register_operand" "wf,0,wa,0,v")
1406 (match_operand:V4SF 3 "vsx_register_operand" "0,wf,0,wa,v")))]
1407 "VECTOR_UNIT_VSX_P (V4SFmode)"
1409 xvmaddasp %x0,%x1,%x2
1410 xvmaddmsp %x0,%x1,%x3
1411 xvmaddasp %x0,%x1,%x2
1412 xvmaddmsp %x0,%x1,%x3
1413 vmaddfp %0,%1,%2,%3"
1414 [(set_attr "type" "vecfloat")])
1416 (define_insn "*vsx_fmav2df4"
1417 [(set (match_operand:V2DF 0 "vsx_register_operand" "=wd,wd,?wa,?wa")
1419 (match_operand:V2DF 1 "vsx_register_operand" "%wd,wd,wa,wa")
1420 (match_operand:V2DF 2 "vsx_register_operand" "wd,0,wa,0")
1421 (match_operand:V2DF 3 "vsx_register_operand" "0,wd,0,wa")))]
1422 "VECTOR_UNIT_VSX_P (V2DFmode)"
1424 xvmaddadp %x0,%x1,%x2
1425 xvmaddmdp %x0,%x1,%x3
1426 xvmaddadp %x0,%x1,%x2
1427 xvmaddmdp %x0,%x1,%x3"
1428 [(set_attr "type" "vecdouble")])
1430 (define_insn "*vsx_fms<mode>4"
1431 [(set (match_operand:VSX_F 0 "vsx_register_operand" "=<VSr>,<VSr>,?<VSa>,?<VSa>")
1433 (match_operand:VSX_F 1 "vsx_register_operand" "%<VSr>,<VSr>,<VSa>,<VSa>")
1434 (match_operand:VSX_F 2 "vsx_register_operand" "<VSr>,0,<VSa>,0")
1436 (match_operand:VSX_F 3 "vsx_register_operand" "0,<VSr>,0,<VSa>"))))]
1437 "VECTOR_UNIT_VSX_P (<MODE>mode)"
1439 xvmsuba<VSs> %x0,%x1,%x2
1440 xvmsubm<VSs> %x0,%x1,%x3
1441 xvmsuba<VSs> %x0,%x1,%x2
1442 xvmsubm<VSs> %x0,%x1,%x3"
1443 [(set_attr "type" "<VStype_mul>")])
1445 (define_insn "*vsx_nfma<mode>4"
1446 [(set (match_operand:VSX_F 0 "vsx_register_operand" "=<VSr>,<VSr>,?<VSa>,?<VSa>")
1449 (match_operand:VSX_F 1 "vsx_register_operand" "<VSr>,<VSr>,<VSa>,<VSa>")
1450 (match_operand:VSX_F 2 "vsx_register_operand" "<VSr>,0,<VSa>,0")
1451 (match_operand:VSX_F 3 "vsx_register_operand" "0,<VSr>,0,<VSa>"))))]
1452 "VECTOR_UNIT_VSX_P (<MODE>mode)"
1454 xvnmadda<VSs> %x0,%x1,%x2
1455 xvnmaddm<VSs> %x0,%x1,%x3
1456 xvnmadda<VSs> %x0,%x1,%x2
1457 xvnmaddm<VSs> %x0,%x1,%x3"
1458 [(set_attr "type" "<VStype_mul>")
1459 (set_attr "fp_type" "<VSfptype_mul>")])
1461 (define_insn "*vsx_nfmsv4sf4"
1462 [(set (match_operand:V4SF 0 "vsx_register_operand" "=wf,wf,?wa,?wa,v")
1465 (match_operand:V4SF 1 "vsx_register_operand" "%wf,wf,wa,wa,v")
1466 (match_operand:V4SF 2 "vsx_register_operand" "wf,0,wa,0,v")
1468 (match_operand:V4SF 3 "vsx_register_operand" "0,wf,0,wa,v")))))]
1469 "VECTOR_UNIT_VSX_P (V4SFmode)"
1471 xvnmsubasp %x0,%x1,%x2
1472 xvnmsubmsp %x0,%x1,%x3
1473 xvnmsubasp %x0,%x1,%x2
1474 xvnmsubmsp %x0,%x1,%x3
1475 vnmsubfp %0,%1,%2,%3"
1476 [(set_attr "type" "vecfloat")])
1478 (define_insn "*vsx_nfmsv2df4"
1479 [(set (match_operand:V2DF 0 "vsx_register_operand" "=wd,wd,?wa,?wa")
1482 (match_operand:V2DF 1 "vsx_register_operand" "%wd,wd,wa,wa")
1483 (match_operand:V2DF 2 "vsx_register_operand" "wd,0,wa,0")
1485 (match_operand:V2DF 3 "vsx_register_operand" "0,wd,0,wa")))))]
1486 "VECTOR_UNIT_VSX_P (V2DFmode)"
1488 xvnmsubadp %x0,%x1,%x2
1489 xvnmsubmdp %x0,%x1,%x3
1490 xvnmsubadp %x0,%x1,%x2
1491 xvnmsubmdp %x0,%x1,%x3"
1492 [(set_attr "type" "vecdouble")])
1494 ;; Vector conditional expressions (no scalar version for these instructions)
1495 (define_insn "vsx_eq<mode>"
1496 [(set (match_operand:VSX_F 0 "vsx_register_operand" "=<VSr>,?<VSa>")
1497 (eq:VSX_F (match_operand:VSX_F 1 "vsx_register_operand" "<VSr>,<VSa>")
1498 (match_operand:VSX_F 2 "vsx_register_operand" "<VSr>,<VSa>")))]
1499 "VECTOR_UNIT_VSX_P (<MODE>mode)"
1500 "xvcmpeq<VSs> %x0,%x1,%x2"
1501 [(set_attr "type" "<VStype_simple>")
1502 (set_attr "fp_type" "<VSfptype_simple>")])
1504 (define_insn "vsx_gt<mode>"
1505 [(set (match_operand:VSX_F 0 "vsx_register_operand" "=<VSr>,?<VSa>")
1506 (gt:VSX_F (match_operand:VSX_F 1 "vsx_register_operand" "<VSr>,<VSa>")
1507 (match_operand:VSX_F 2 "vsx_register_operand" "<VSr>,<VSa>")))]
1508 "VECTOR_UNIT_VSX_P (<MODE>mode)"
1509 "xvcmpgt<VSs> %x0,%x1,%x2"
1510 [(set_attr "type" "<VStype_simple>")
1511 (set_attr "fp_type" "<VSfptype_simple>")])
1513 (define_insn "*vsx_ge<mode>"
1514 [(set (match_operand:VSX_F 0 "vsx_register_operand" "=<VSr>,?<VSa>")
1515 (ge:VSX_F (match_operand:VSX_F 1 "vsx_register_operand" "<VSr>,<VSa>")
1516 (match_operand:VSX_F 2 "vsx_register_operand" "<VSr>,<VSa>")))]
1517 "VECTOR_UNIT_VSX_P (<MODE>mode)"
1518 "xvcmpge<VSs> %x0,%x1,%x2"
1519 [(set_attr "type" "<VStype_simple>")
1520 (set_attr "fp_type" "<VSfptype_simple>")])
1522 ;; Compare vectors producing a vector result and a predicate, setting CR6 to
1523 ;; indicate a combined status
1524 (define_insn "*vsx_eq_<mode>_p"
1525 [(set (reg:CC CR6_REGNO)
1527 [(eq:CC (match_operand:VSX_F 1 "vsx_register_operand" "<VSr>,?<VSa>")
1528 (match_operand:VSX_F 2 "vsx_register_operand" "<VSr>,?<VSa>"))]
1530 (set (match_operand:VSX_F 0 "vsx_register_operand" "=<VSr>,?<VSa>")
1531 (eq:VSX_F (match_dup 1)
1533 "VECTOR_UNIT_VSX_P (<MODE>mode)"
1534 "xvcmpeq<VSs>. %x0,%x1,%x2"
1535 [(set_attr "type" "<VStype_simple>")])
1537 (define_insn "*vsx_gt_<mode>_p"
1538 [(set (reg:CC CR6_REGNO)
1540 [(gt:CC (match_operand:VSX_F 1 "vsx_register_operand" "<VSr>,?<VSa>")
1541 (match_operand:VSX_F 2 "vsx_register_operand" "<VSr>,?<VSa>"))]
1543 (set (match_operand:VSX_F 0 "vsx_register_operand" "=<VSr>,?<VSa>")
1544 (gt:VSX_F (match_dup 1)
1546 "VECTOR_UNIT_VSX_P (<MODE>mode)"
1547 "xvcmpgt<VSs>. %x0,%x1,%x2"
1548 [(set_attr "type" "<VStype_simple>")])
1550 (define_insn "*vsx_ge_<mode>_p"
1551 [(set (reg:CC CR6_REGNO)
1553 [(ge:CC (match_operand:VSX_F 1 "vsx_register_operand" "<VSr>,?<VSa>")
1554 (match_operand:VSX_F 2 "vsx_register_operand" "<VSr>,?<VSa>"))]
1556 (set (match_operand:VSX_F 0 "vsx_register_operand" "=<VSr>,?<VSa>")
1557 (ge:VSX_F (match_dup 1)
1559 "VECTOR_UNIT_VSX_P (<MODE>mode)"
1560 "xvcmpge<VSs>. %x0,%x1,%x2"
1561 [(set_attr "type" "<VStype_simple>")])
1564 (define_insn "*vsx_xxsel<mode>"
1565 [(set (match_operand:VSX_L 0 "vsx_register_operand" "=<VSr>,?<VSa>")
1567 (ne:CC (match_operand:VSX_L 1 "vsx_register_operand" "<VSr>,<VSa>")
1568 (match_operand:VSX_L 4 "zero_constant" ""))
1569 (match_operand:VSX_L 2 "vsx_register_operand" "<VSr>,<VSa>")
1570 (match_operand:VSX_L 3 "vsx_register_operand" "<VSr>,<VSa>")))]
1571 "VECTOR_MEM_VSX_P (<MODE>mode)"
1572 "xxsel %x0,%x3,%x2,%x1"
1573 [(set_attr "type" "vecmove")])
1575 (define_insn "*vsx_xxsel<mode>_uns"
1576 [(set (match_operand:VSX_L 0 "vsx_register_operand" "=<VSr>,?<VSa>")
1578 (ne:CCUNS (match_operand:VSX_L 1 "vsx_register_operand" "<VSr>,<VSa>")
1579 (match_operand:VSX_L 4 "zero_constant" ""))
1580 (match_operand:VSX_L 2 "vsx_register_operand" "<VSr>,<VSa>")
1581 (match_operand:VSX_L 3 "vsx_register_operand" "<VSr>,<VSa>")))]
1582 "VECTOR_MEM_VSX_P (<MODE>mode)"
1583 "xxsel %x0,%x3,%x2,%x1"
1584 [(set_attr "type" "vecmove")])
1587 (define_insn "vsx_copysign<mode>3"
1588 [(set (match_operand:VSX_F 0 "vsx_register_operand" "=<VSr>,?<VSa>")
1590 [(match_operand:VSX_F 1 "vsx_register_operand" "<VSr>,<VSa>")
1591 (match_operand:VSX_F 2 "vsx_register_operand" "<VSr>,<VSa>")]
1593 "VECTOR_UNIT_VSX_P (<MODE>mode)"
1594 "xvcpsgn<VSs> %x0,%x2,%x1"
1595 [(set_attr "type" "<VStype_simple>")
1596 (set_attr "fp_type" "<VSfptype_simple>")])
1598 ;; For the conversions, limit the register class for the integer value to be
1599 ;; the fprs because we don't want to add the altivec registers to movdi/movsi.
1600 ;; For the unsigned tests, there isn't a generic double -> unsigned conversion
1601 ;; in rs6000.md so don't test VECTOR_UNIT_VSX_P, just test against VSX.
1602 ;; Don't use vsx_register_operand here, use gpc_reg_operand to match rs6000.md
1603 ;; in allowing virtual registers.
1604 (define_insn "vsx_float<VSi><mode>2"
1605 [(set (match_operand:VSX_F 0 "gpc_reg_operand" "=<VSr>,?<VSa>")
1606 (float:VSX_F (match_operand:<VSI> 1 "gpc_reg_operand" "<VSr2>,<VSr3>")))]
1607 "VECTOR_UNIT_VSX_P (<MODE>mode)"
1608 "xvcvsx<VSc><VSs> %x0,%x1"
1609 [(set_attr "type" "<VStype_simple>")
1610 (set_attr "fp_type" "<VSfptype_simple>")])
1612 (define_insn "vsx_floatuns<VSi><mode>2"
1613 [(set (match_operand:VSX_F 0 "gpc_reg_operand" "=<VSr>,?<VSa>")
1614 (unsigned_float:VSX_F (match_operand:<VSI> 1 "gpc_reg_operand" "<VSr2>,<VSr3>")))]
1615 "VECTOR_UNIT_VSX_P (<MODE>mode)"
1616 "xvcvux<VSc><VSs> %x0,%x1"
1617 [(set_attr "type" "<VStype_simple>")
1618 (set_attr "fp_type" "<VSfptype_simple>")])
1620 (define_insn "vsx_fix_trunc<mode><VSi>2"
1621 [(set (match_operand:<VSI> 0 "gpc_reg_operand" "=<VSr2>,?<VSr3>")
1622 (fix:<VSI> (match_operand:VSX_F 1 "gpc_reg_operand" "<VSr>,<VSa>")))]
1623 "VECTOR_UNIT_VSX_P (<MODE>mode)"
1624 "x<VSv>cv<VSs>sx<VSc>s %x0,%x1"
1625 [(set_attr "type" "<VStype_simple>")
1626 (set_attr "fp_type" "<VSfptype_simple>")])
1628 (define_insn "vsx_fixuns_trunc<mode><VSi>2"
1629 [(set (match_operand:<VSI> 0 "gpc_reg_operand" "=<VSr2>,?<VSr3>")
1630 (unsigned_fix:<VSI> (match_operand:VSX_F 1 "gpc_reg_operand" "<VSr>,<VSa>")))]
1631 "VECTOR_UNIT_VSX_P (<MODE>mode)"
1632 "x<VSv>cv<VSs>ux<VSc>s %x0,%x1"
1633 [(set_attr "type" "<VStype_simple>")
1634 (set_attr "fp_type" "<VSfptype_simple>")])
1636 ;; Math rounding functions
1637 (define_insn "vsx_x<VSv>r<VSs>i"
1638 [(set (match_operand:VSX_B 0 "vsx_register_operand" "=<VSr>,?<VSa>")
1639 (unspec:VSX_B [(match_operand:VSX_B 1 "vsx_register_operand" "<VSr>,<VSa>")]
1640 UNSPEC_VSX_ROUND_I))]
1641 "VECTOR_UNIT_VSX_P (<MODE>mode)"
1642 "x<VSv>r<VSs>i %x0,%x1"
1643 [(set_attr "type" "<VStype_simple>")
1644 (set_attr "fp_type" "<VSfptype_simple>")])
1646 (define_insn "vsx_x<VSv>r<VSs>ic"
1647 [(set (match_operand:VSX_B 0 "vsx_register_operand" "=<VSr>,?<VSa>")
1648 (unspec:VSX_B [(match_operand:VSX_B 1 "vsx_register_operand" "<VSr>,<VSa>")]
1649 UNSPEC_VSX_ROUND_IC))]
1650 "VECTOR_UNIT_VSX_P (<MODE>mode)"
1651 "x<VSv>r<VSs>ic %x0,%x1"
1652 [(set_attr "type" "<VStype_simple>")
1653 (set_attr "fp_type" "<VSfptype_simple>")])
1655 (define_insn "vsx_btrunc<mode>2"
1656 [(set (match_operand:VSX_F 0 "vsx_register_operand" "=<VSr>,?<VSa>")
1657 (fix:VSX_F (match_operand:VSX_F 1 "vsx_register_operand" "<VSr>,<VSa>")))]
1658 "VECTOR_UNIT_VSX_P (<MODE>mode)"
1659 "xvr<VSs>iz %x0,%x1"
1660 [(set_attr "type" "<VStype_simple>")
1661 (set_attr "fp_type" "<VSfptype_simple>")])
1663 (define_insn "*vsx_b2trunc<mode>2"
1664 [(set (match_operand:VSX_B 0 "vsx_register_operand" "=<VSr>,?<VSa>")
1665 (unspec:VSX_B [(match_operand:VSX_B 1 "vsx_register_operand" "<VSr>,<VSa>")]
1667 "VECTOR_UNIT_VSX_P (<MODE>mode)"
1668 "x<VSv>r<VSs>iz %x0,%x1"
1669 [(set_attr "type" "<VStype_simple>")
1670 (set_attr "fp_type" "<VSfptype_simple>")])
1672 (define_insn "vsx_floor<mode>2"
1673 [(set (match_operand:VSX_F 0 "vsx_register_operand" "=<VSr>,?<VSa>")
1674 (unspec:VSX_F [(match_operand:VSX_F 1 "vsx_register_operand" "<VSr>,<VSa>")]
1676 "VECTOR_UNIT_VSX_P (<MODE>mode)"
1677 "xvr<VSs>im %x0,%x1"
1678 [(set_attr "type" "<VStype_simple>")
1679 (set_attr "fp_type" "<VSfptype_simple>")])
1681 (define_insn "vsx_ceil<mode>2"
1682 [(set (match_operand:VSX_F 0 "vsx_register_operand" "=<VSr>,?<VSa>")
1683 (unspec:VSX_F [(match_operand:VSX_F 1 "vsx_register_operand" "<VSr>,<VSa>")]
1685 "VECTOR_UNIT_VSX_P (<MODE>mode)"
1686 "xvr<VSs>ip %x0,%x1"
1687 [(set_attr "type" "<VStype_simple>")
1688 (set_attr "fp_type" "<VSfptype_simple>")])
1691 ;; VSX convert to/from double vector
1693 ;; Convert between single and double precision
1694 ;; Don't use xscvspdp and xscvdpsp for scalar conversions, since the normal
1695 ;; scalar single precision instructions internally use the double format.
1696 ;; Prefer the altivec registers, since we likely will need to do a vperm
1697 (define_insn "vsx_<VS_spdp_insn>"
1698 [(set (match_operand:<VS_spdp_res> 0 "vsx_register_operand" "=<VSr4>,?<VSa>")
1699 (unspec:<VS_spdp_res> [(match_operand:VSX_SPDP 1 "vsx_register_operand" "<VSr5>,<VSa>")]
1700 UNSPEC_VSX_CVSPDP))]
1701 "VECTOR_UNIT_VSX_P (<MODE>mode)"
1702 "<VS_spdp_insn> %x0,%x1"
1703 [(set_attr "type" "<VS_spdp_type>")])
1705 ;; xscvspdp, represent the scalar SF type as V4SF
1706 (define_insn "vsx_xscvspdp"
1707 [(set (match_operand:DF 0 "vsx_register_operand" "=ws")
1708 (unspec:DF [(match_operand:V4SF 1 "vsx_register_operand" "wa")]
1709 UNSPEC_VSX_CVSPDP))]
1710 "VECTOR_UNIT_VSX_P (V4SFmode)"
1712 [(set_attr "type" "fp")])
1714 ;; xscvdpsp used for splat'ing a scalar to V4SF, knowing that the internal SF
1715 ;; format of scalars is actually DF.
1716 (define_insn "vsx_xscvdpsp_scalar"
1717 [(set (match_operand:V4SF 0 "vsx_register_operand" "=wa")
1718 (unspec:V4SF [(match_operand:SF 1 "vsx_register_operand" "f")]
1719 UNSPEC_VSX_CVSPDP))]
1720 "VECTOR_UNIT_VSX_P (V4SFmode)"
1722 [(set_attr "type" "fp")])
1724 ;; Same as vsx_xscvspdp, but use SF as the type
1725 (define_insn "vsx_xscvspdp_scalar2"
1726 [(set (match_operand:SF 0 "vsx_register_operand" "=ww")
1727 (unspec:SF [(match_operand:V4SF 1 "vsx_register_operand" "wa")]
1728 UNSPEC_VSX_CVSPDP))]
1729 "VECTOR_UNIT_VSX_P (V4SFmode)"
1731 [(set_attr "type" "fp")])
1733 ;; ISA 2.07 xscvdpspn/xscvspdpn that does not raise an error on signalling NaNs
1734 (define_insn "vsx_xscvdpspn"
1735 [(set (match_operand:V4SF 0 "vsx_register_operand" "=ww,?ww")
1736 (unspec:V4SF [(match_operand:DF 1 "vsx_register_operand" "wd,wa")]
1737 UNSPEC_VSX_CVDPSPN))]
1740 [(set_attr "type" "fp")])
1742 (define_insn "vsx_xscvspdpn"
1743 [(set (match_operand:DF 0 "vsx_register_operand" "=ws,?ws")
1744 (unspec:DF [(match_operand:V4SF 1 "vsx_register_operand" "wf,wa")]
1745 UNSPEC_VSX_CVSPDPN))]
1748 [(set_attr "type" "fp")])
1750 (define_insn "vsx_xscvdpspn_scalar"
1751 [(set (match_operand:V4SF 0 "vsx_register_operand" "=wf,?wa")
1752 (unspec:V4SF [(match_operand:SF 1 "vsx_register_operand" "ww,ww")]
1753 UNSPEC_VSX_CVDPSPN))]
1756 [(set_attr "type" "fp")])
1758 ;; Used by direct move to move a SFmode value from GPR to VSX register
1759 (define_insn "vsx_xscvspdpn_directmove"
1760 [(set (match_operand:SF 0 "vsx_register_operand" "=wa")
1761 (unspec:SF [(match_operand:SF 1 "vsx_register_operand" "wa")]
1762 UNSPEC_VSX_CVSPDPN))]
1765 [(set_attr "type" "fp")])
1767 ;; Convert and scale (used by vec_ctf, vec_cts, vec_ctu for double/long long)
1769 (define_expand "vsx_xvcvsxddp_scale"
1770 [(match_operand:V2DF 0 "vsx_register_operand" "")
1771 (match_operand:V2DI 1 "vsx_register_operand" "")
1772 (match_operand:QI 2 "immediate_operand" "")]
1773 "VECTOR_UNIT_VSX_P (V2DFmode)"
1775 rtx op0 = operands[0];
1776 rtx op1 = operands[1];
1777 int scale = INTVAL(operands[2]);
1778 emit_insn (gen_vsx_xvcvsxddp (op0, op1));
1780 rs6000_scale_v2df (op0, op0, -scale);
1784 (define_insn "vsx_xvcvsxddp"
1785 [(set (match_operand:V2DF 0 "vsx_register_operand" "=wa")
1786 (unspec:V2DF [(match_operand:V2DI 1 "vsx_register_operand" "wa")]
1787 UNSPEC_VSX_XVCVSXDDP))]
1788 "VECTOR_UNIT_VSX_P (V2DFmode)"
1790 [(set_attr "type" "vecdouble")])
1792 (define_expand "vsx_xvcvuxddp_scale"
1793 [(match_operand:V2DF 0 "vsx_register_operand" "")
1794 (match_operand:V2DI 1 "vsx_register_operand" "")
1795 (match_operand:QI 2 "immediate_operand" "")]
1796 "VECTOR_UNIT_VSX_P (V2DFmode)"
1798 rtx op0 = operands[0];
1799 rtx op1 = operands[1];
1800 int scale = INTVAL(operands[2]);
1801 emit_insn (gen_vsx_xvcvuxddp (op0, op1));
1803 rs6000_scale_v2df (op0, op0, -scale);
1807 (define_insn "vsx_xvcvuxddp"
1808 [(set (match_operand:V2DF 0 "vsx_register_operand" "=wa")
1809 (unspec:V2DF [(match_operand:V2DI 1 "vsx_register_operand" "wa")]
1810 UNSPEC_VSX_XVCVUXDDP))]
1811 "VECTOR_UNIT_VSX_P (V2DFmode)"
1813 [(set_attr "type" "vecdouble")])
1815 (define_expand "vsx_xvcvdpsxds_scale"
1816 [(match_operand:V2DI 0 "vsx_register_operand" "")
1817 (match_operand:V2DF 1 "vsx_register_operand" "")
1818 (match_operand:QI 2 "immediate_operand" "")]
1819 "VECTOR_UNIT_VSX_P (V2DFmode)"
1821 rtx op0 = operands[0];
1822 rtx op1 = operands[1];
1824 int scale = INTVAL (operands[2]);
1829 tmp = gen_reg_rtx (V2DFmode);
1830 rs6000_scale_v2df (tmp, op1, scale);
1832 emit_insn (gen_vsx_xvcvdpsxds (op0, tmp));
1836 (define_insn "vsx_xvcvdpsxds"
1837 [(set (match_operand:V2DI 0 "vsx_register_operand" "=wa")
1838 (unspec:V2DI [(match_operand:V2DF 1 "vsx_register_operand" "wa")]
1839 UNSPEC_VSX_XVCVDPSXDS))]
1840 "VECTOR_UNIT_VSX_P (V2DFmode)"
1841 "xvcvdpsxds %x0,%x1"
1842 [(set_attr "type" "vecdouble")])
1844 (define_expand "vsx_xvcvdpuxds_scale"
1845 [(match_operand:V2DI 0 "vsx_register_operand" "")
1846 (match_operand:V2DF 1 "vsx_register_operand" "")
1847 (match_operand:QI 2 "immediate_operand" "")]
1848 "VECTOR_UNIT_VSX_P (V2DFmode)"
1850 rtx op0 = operands[0];
1851 rtx op1 = operands[1];
1853 int scale = INTVAL (operands[2]);
1858 tmp = gen_reg_rtx (V2DFmode);
1859 rs6000_scale_v2df (tmp, op1, scale);
1861 emit_insn (gen_vsx_xvcvdpuxds (op0, tmp));
1865 (define_insn "vsx_xvcvdpuxds"
1866 [(set (match_operand:V2DI 0 "vsx_register_operand" "=wa")
1867 (unspec:V2DI [(match_operand:V2DF 1 "vsx_register_operand" "wa")]
1868 UNSPEC_VSX_XVCVDPUXDS))]
1869 "VECTOR_UNIT_VSX_P (V2DFmode)"
1870 "xvcvdpuxds %x0,%x1"
1871 [(set_attr "type" "vecdouble")])
1873 ;; Convert from 64-bit to 32-bit types
1874 ;; Note, favor the Altivec registers since the usual use of these instructions
1875 ;; is in vector converts and we need to use the Altivec vperm instruction.
1877 (define_insn "vsx_xvcvdpsxws"
1878 [(set (match_operand:V4SI 0 "vsx_register_operand" "=v,?wa")
1879 (unspec:V4SI [(match_operand:V2DF 1 "vsx_register_operand" "wd,wa")]
1880 UNSPEC_VSX_CVDPSXWS))]
1881 "VECTOR_UNIT_VSX_P (V2DFmode)"
1882 "xvcvdpsxws %x0,%x1"
1883 [(set_attr "type" "vecdouble")])
1885 (define_insn "vsx_xvcvdpuxws"
1886 [(set (match_operand:V4SI 0 "vsx_register_operand" "=v,?wa")
1887 (unspec:V4SI [(match_operand:V2DF 1 "vsx_register_operand" "wd,wa")]
1888 UNSPEC_VSX_CVDPUXWS))]
1889 "VECTOR_UNIT_VSX_P (V2DFmode)"
1890 "xvcvdpuxws %x0,%x1"
1891 [(set_attr "type" "vecdouble")])
1893 (define_insn "vsx_xvcvsxdsp"
1894 [(set (match_operand:V4SI 0 "vsx_register_operand" "=wd,?wa")
1895 (unspec:V4SI [(match_operand:V2DF 1 "vsx_register_operand" "wf,wa")]
1896 UNSPEC_VSX_CVSXDSP))]
1897 "VECTOR_UNIT_VSX_P (V2DFmode)"
1899 [(set_attr "type" "vecfloat")])
1901 (define_insn "vsx_xvcvuxdsp"
1902 [(set (match_operand:V4SI 0 "vsx_register_operand" "=wd,?wa")
1903 (unspec:V4SI [(match_operand:V2DF 1 "vsx_register_operand" "wf,wa")]
1904 UNSPEC_VSX_CVUXDSP))]
1905 "VECTOR_UNIT_VSX_P (V2DFmode)"
1907 [(set_attr "type" "vecdouble")])
1909 ;; Convert from 32-bit to 64-bit types
1910 (define_insn "vsx_xvcvsxwdp"
1911 [(set (match_operand:V2DF 0 "vsx_register_operand" "=wd,?wa")
1912 (unspec:V2DF [(match_operand:V4SI 1 "vsx_register_operand" "wf,wa")]
1913 UNSPEC_VSX_CVSXWDP))]
1914 "VECTOR_UNIT_VSX_P (V2DFmode)"
1916 [(set_attr "type" "vecdouble")])
1918 (define_insn "vsx_xvcvuxwdp"
1919 [(set (match_operand:V2DF 0 "vsx_register_operand" "=wd,?wa")
1920 (unspec:V2DF [(match_operand:V4SI 1 "vsx_register_operand" "wf,wa")]
1921 UNSPEC_VSX_CVUXWDP))]
1922 "VECTOR_UNIT_VSX_P (V2DFmode)"
1924 [(set_attr "type" "vecdouble")])
1926 (define_insn "vsx_xvcvspsxds"
1927 [(set (match_operand:V2DI 0 "vsx_register_operand" "=v,?wa")
1928 (unspec:V2DI [(match_operand:V4SF 1 "vsx_register_operand" "wd,wa")]
1929 UNSPEC_VSX_CVSPSXDS))]
1930 "VECTOR_UNIT_VSX_P (V2DFmode)"
1931 "xvcvspsxds %x0,%x1"
1932 [(set_attr "type" "vecdouble")])
1934 (define_insn "vsx_xvcvspuxds"
1935 [(set (match_operand:V2DI 0 "vsx_register_operand" "=v,?wa")
1936 (unspec:V2DI [(match_operand:V4SF 1 "vsx_register_operand" "wd,wa")]
1937 UNSPEC_VSX_CVSPUXDS))]
1938 "VECTOR_UNIT_VSX_P (V2DFmode)"
1939 "xvcvspuxds %x0,%x1"
1940 [(set_attr "type" "vecdouble")])
1942 ;; Only optimize (float (fix x)) -> frz if we are in fast-math mode, since
1943 ;; since the xvrdpiz instruction does not truncate the value if the floating
1944 ;; point value is < LONG_MIN or > LONG_MAX.
1945 (define_insn "*vsx_float_fix_v2df2"
1946 [(set (match_operand:V2DF 0 "vsx_register_operand" "=wd,?wa")
1949 (match_operand:V2DF 1 "vsx_register_operand" "wd,?wa"))))]
1950 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
1951 && VECTOR_UNIT_VSX_P (V2DFmode) && flag_unsafe_math_optimizations
1952 && !flag_trapping_math && TARGET_FRIZ"
1954 [(set_attr "type" "vecdouble")
1955 (set_attr "fp_type" "fp_addsub_d")])
1958 ;; Permute operations
1960 ;; Build a V2DF/V2DI vector from two scalars
1961 (define_insn "vsx_concat_<mode>"
1962 [(set (match_operand:VSX_D 0 "gpc_reg_operand" "=<VSa>,we")
1964 (match_operand:<VS_scalar> 1 "gpc_reg_operand" "<VS_64reg>,b")
1965 (match_operand:<VS_scalar> 2 "gpc_reg_operand" "<VS_64reg>,b")))]
1966 "VECTOR_MEM_VSX_P (<MODE>mode)"
1968 if (which_alternative == 0)
1969 return (BYTES_BIG_ENDIAN
1970 ? "xxpermdi %x0,%x1,%x2,0"
1971 : "xxpermdi %x0,%x2,%x1,0");
1973 else if (which_alternative == 1)
1974 return (BYTES_BIG_ENDIAN
1975 ? "mtvsrdd %x0,%1,%2"
1976 : "mtvsrdd %x0,%2,%1");
1981 [(set_attr "type" "vecperm")])
1983 ;; Special purpose concat using xxpermdi to glue two single precision values
1984 ;; together, relying on the fact that internally scalar floats are represented
1985 ;; as doubles. This is used to initialize a V4SF vector with 4 floats
1986 (define_insn "vsx_concat_v2sf"
1987 [(set (match_operand:V2DF 0 "vsx_register_operand" "=wa")
1989 [(match_operand:SF 1 "vsx_register_operand" "ww")
1990 (match_operand:SF 2 "vsx_register_operand" "ww")]
1991 UNSPEC_VSX_CONCAT))]
1992 "VECTOR_MEM_VSX_P (V2DFmode)"
1994 if (BYTES_BIG_ENDIAN)
1995 return "xxpermdi %x0,%x1,%x2,0";
1997 return "xxpermdi %x0,%x2,%x1,0";
1999 [(set_attr "type" "vecperm")])
2001 ;; V4SImode initialization splitter
2002 (define_insn_and_split "vsx_init_v4si"
2003 [(set (match_operand:V4SI 0 "gpc_reg_operand" "=&r")
2005 [(match_operand:SI 1 "reg_or_cint_operand" "rn")
2006 (match_operand:SI 2 "reg_or_cint_operand" "rn")
2007 (match_operand:SI 3 "reg_or_cint_operand" "rn")
2008 (match_operand:SI 4 "reg_or_cint_operand" "rn")]
2009 UNSPEC_VSX_VEC_INIT))
2010 (clobber (match_scratch:DI 5 "=&r"))
2011 (clobber (match_scratch:DI 6 "=&r"))]
2012 "VECTOR_MEM_VSX_P (V4SImode) && TARGET_DIRECT_MOVE_64BIT"
2014 "&& reload_completed"
2017 rs6000_split_v4si_init (operands);
2021 ;; xxpermdi for little endian loads and stores. We need several of
2022 ;; these since the form of the PARALLEL differs by mode.
2023 (define_insn "*vsx_xxpermdi2_le_<mode>"
2024 [(set (match_operand:VSX_LE 0 "vsx_register_operand" "=<VSa>")
2026 (match_operand:VSX_LE 1 "vsx_register_operand" "<VSa>")
2027 (parallel [(const_int 1) (const_int 0)])))]
2028 "!BYTES_BIG_ENDIAN && VECTOR_MEM_VSX_P (<MODE>mode)"
2029 "xxpermdi %x0,%x1,%x1,2"
2030 [(set_attr "type" "vecperm")])
2032 (define_insn "*vsx_xxpermdi4_le_<mode>"
2033 [(set (match_operand:VSX_W 0 "vsx_register_operand" "=<VSa>")
2035 (match_operand:VSX_W 1 "vsx_register_operand" "<VSa>")
2036 (parallel [(const_int 2) (const_int 3)
2037 (const_int 0) (const_int 1)])))]
2038 "!BYTES_BIG_ENDIAN && VECTOR_MEM_VSX_P (<MODE>mode)"
2039 "xxpermdi %x0,%x1,%x1,2"
2040 [(set_attr "type" "vecperm")])
2042 (define_insn "*vsx_xxpermdi8_le_V8HI"
2043 [(set (match_operand:V8HI 0 "vsx_register_operand" "=wa")
2045 (match_operand:V8HI 1 "vsx_register_operand" "wa")
2046 (parallel [(const_int 4) (const_int 5)
2047 (const_int 6) (const_int 7)
2048 (const_int 0) (const_int 1)
2049 (const_int 2) (const_int 3)])))]
2050 "!BYTES_BIG_ENDIAN && VECTOR_MEM_VSX_P (V8HImode)"
2051 "xxpermdi %x0,%x1,%x1,2"
2052 [(set_attr "type" "vecperm")])
2054 (define_insn "*vsx_xxpermdi16_le_V16QI"
2055 [(set (match_operand:V16QI 0 "vsx_register_operand" "=wa")
2057 (match_operand:V16QI 1 "vsx_register_operand" "wa")
2058 (parallel [(const_int 8) (const_int 9)
2059 (const_int 10) (const_int 11)
2060 (const_int 12) (const_int 13)
2061 (const_int 14) (const_int 15)
2062 (const_int 0) (const_int 1)
2063 (const_int 2) (const_int 3)
2064 (const_int 4) (const_int 5)
2065 (const_int 6) (const_int 7)])))]
2066 "!BYTES_BIG_ENDIAN && VECTOR_MEM_VSX_P (V16QImode)"
2067 "xxpermdi %x0,%x1,%x1,2"
2068 [(set_attr "type" "vecperm")])
2070 ;; lxvd2x for little endian loads. We need several of
2071 ;; these since the form of the PARALLEL differs by mode.
2072 (define_insn "*vsx_lxvd2x2_le_<mode>"
2073 [(set (match_operand:VSX_LE 0 "vsx_register_operand" "=<VSa>")
2075 (match_operand:VSX_LE 1 "memory_operand" "Z")
2076 (parallel [(const_int 1) (const_int 0)])))]
2077 "!BYTES_BIG_ENDIAN && VECTOR_MEM_VSX_P (<MODE>mode) && !TARGET_P9_VECTOR"
2079 [(set_attr "type" "vecload")])
2081 (define_insn "*vsx_lxvd2x4_le_<mode>"
2082 [(set (match_operand:VSX_W 0 "vsx_register_operand" "=<VSa>")
2084 (match_operand:VSX_W 1 "memory_operand" "Z")
2085 (parallel [(const_int 2) (const_int 3)
2086 (const_int 0) (const_int 1)])))]
2087 "!BYTES_BIG_ENDIAN && VECTOR_MEM_VSX_P (<MODE>mode) && !TARGET_P9_VECTOR"
2089 [(set_attr "type" "vecload")])
2091 (define_insn "*vsx_lxvd2x8_le_V8HI"
2092 [(set (match_operand:V8HI 0 "vsx_register_operand" "=wa")
2094 (match_operand:V8HI 1 "memory_operand" "Z")
2095 (parallel [(const_int 4) (const_int 5)
2096 (const_int 6) (const_int 7)
2097 (const_int 0) (const_int 1)
2098 (const_int 2) (const_int 3)])))]
2099 "!BYTES_BIG_ENDIAN && VECTOR_MEM_VSX_P (V8HImode) && !TARGET_P9_VECTOR"
2101 [(set_attr "type" "vecload")])
2103 (define_insn "*vsx_lxvd2x16_le_V16QI"
2104 [(set (match_operand:V16QI 0 "vsx_register_operand" "=wa")
2106 (match_operand:V16QI 1 "memory_operand" "Z")
2107 (parallel [(const_int 8) (const_int 9)
2108 (const_int 10) (const_int 11)
2109 (const_int 12) (const_int 13)
2110 (const_int 14) (const_int 15)
2111 (const_int 0) (const_int 1)
2112 (const_int 2) (const_int 3)
2113 (const_int 4) (const_int 5)
2114 (const_int 6) (const_int 7)])))]
2115 "!BYTES_BIG_ENDIAN && VECTOR_MEM_VSX_P (V16QImode) && !TARGET_P9_VECTOR"
2117 [(set_attr "type" "vecload")])
2119 ;; stxvd2x for little endian stores. We need several of
2120 ;; these since the form of the PARALLEL differs by mode.
2121 (define_insn "*vsx_stxvd2x2_le_<mode>"
2122 [(set (match_operand:VSX_LE 0 "memory_operand" "=Z")
2124 (match_operand:VSX_LE 1 "vsx_register_operand" "<VSa>")
2125 (parallel [(const_int 1) (const_int 0)])))]
2126 "!BYTES_BIG_ENDIAN && VECTOR_MEM_VSX_P (<MODE>mode) && !TARGET_P9_VECTOR"
2128 [(set_attr "type" "vecstore")])
2130 (define_insn "*vsx_stxvd2x4_le_<mode>"
2131 [(set (match_operand:VSX_W 0 "memory_operand" "=Z")
2133 (match_operand:VSX_W 1 "vsx_register_operand" "<VSa>")
2134 (parallel [(const_int 2) (const_int 3)
2135 (const_int 0) (const_int 1)])))]
2136 "!BYTES_BIG_ENDIAN && VECTOR_MEM_VSX_P (<MODE>mode) && !TARGET_P9_VECTOR"
2138 [(set_attr "type" "vecstore")])
2140 (define_insn "*vsx_stxvd2x8_le_V8HI"
2141 [(set (match_operand:V8HI 0 "memory_operand" "=Z")
2143 (match_operand:V8HI 1 "vsx_register_operand" "wa")
2144 (parallel [(const_int 4) (const_int 5)
2145 (const_int 6) (const_int 7)
2146 (const_int 0) (const_int 1)
2147 (const_int 2) (const_int 3)])))]
2148 "!BYTES_BIG_ENDIAN && VECTOR_MEM_VSX_P (V8HImode) && !TARGET_P9_VECTOR"
2150 [(set_attr "type" "vecstore")])
2152 (define_insn "*vsx_stxvd2x16_le_V16QI"
2153 [(set (match_operand:V16QI 0 "memory_operand" "=Z")
2155 (match_operand:V16QI 1 "vsx_register_operand" "wa")
2156 (parallel [(const_int 8) (const_int 9)
2157 (const_int 10) (const_int 11)
2158 (const_int 12) (const_int 13)
2159 (const_int 14) (const_int 15)
2160 (const_int 0) (const_int 1)
2161 (const_int 2) (const_int 3)
2162 (const_int 4) (const_int 5)
2163 (const_int 6) (const_int 7)])))]
2164 "!BYTES_BIG_ENDIAN && VECTOR_MEM_VSX_P (V16QImode) && !TARGET_P9_VECTOR"
2166 [(set_attr "type" "vecstore")])
2168 ;; Convert a TImode value into V1TImode
2169 (define_expand "vsx_set_v1ti"
2170 [(match_operand:V1TI 0 "nonimmediate_operand" "")
2171 (match_operand:V1TI 1 "nonimmediate_operand" "")
2172 (match_operand:TI 2 "input_operand" "")
2173 (match_operand:QI 3 "u5bit_cint_operand" "")]
2174 "VECTOR_MEM_VSX_P (V1TImode)"
2176 if (operands[3] != const0_rtx)
2179 emit_move_insn (operands[0], gen_lowpart (V1TImode, operands[1]));
2183 ;; Set the element of a V2DI/VD2F mode
2184 (define_insn "vsx_set_<mode>"
2185 [(set (match_operand:VSX_D 0 "vsx_register_operand" "=wd,?<VSa>")
2187 [(match_operand:VSX_D 1 "vsx_register_operand" "wd,<VSa>")
2188 (match_operand:<VS_scalar> 2 "vsx_register_operand" "<VS_64reg>,<VSa>")
2189 (match_operand:QI 3 "u5bit_cint_operand" "i,i")]
2191 "VECTOR_MEM_VSX_P (<MODE>mode)"
2193 int idx_first = BYTES_BIG_ENDIAN ? 0 : 1;
2194 if (INTVAL (operands[3]) == idx_first)
2195 return \"xxpermdi %x0,%x2,%x1,1\";
2196 else if (INTVAL (operands[3]) == 1 - idx_first)
2197 return \"xxpermdi %x0,%x1,%x2,0\";
2201 [(set_attr "type" "vecperm")])
2203 ;; Extract a DF/DI element from V2DF/V2DI
2204 ;; Optimize cases were we can do a simple or direct move.
2205 ;; Or see if we can avoid doing the move at all
2207 ;; There are some unresolved problems with reload that show up if an Altivec
2208 ;; register was picked. Limit the scalar value to FPRs for now.
2210 (define_insn "vsx_extract_<mode>"
2211 [(set (match_operand:<VS_scalar> 0 "gpc_reg_operand" "=d, d, wr, wr")
2213 (vec_select:<VS_scalar>
2214 (match_operand:VSX_D 1 "gpc_reg_operand" "<VSa>, <VSa>, wm, wo")
2217 [(match_operand:QI 2 "const_0_to_1_operand" "wD, n, wD, n")])))]
2218 "VECTOR_MEM_VSX_P (<MODE>mode)"
2220 int element = INTVAL (operands[2]);
2221 int op0_regno = REGNO (operands[0]);
2222 int op1_regno = REGNO (operands[1]);
2225 gcc_assert (IN_RANGE (element, 0, 1));
2226 gcc_assert (VSX_REGNO_P (op1_regno));
2228 if (element == VECTOR_ELEMENT_SCALAR_64BIT)
2230 if (op0_regno == op1_regno)
2231 return ASM_COMMENT_START " vec_extract to same register";
2233 else if (INT_REGNO_P (op0_regno) && TARGET_DIRECT_MOVE
2234 && TARGET_POWERPC64)
2235 return "mfvsrd %0,%x1";
2237 else if (FP_REGNO_P (op0_regno) && FP_REGNO_P (op1_regno))
2240 else if (VSX_REGNO_P (op0_regno))
2241 return "xxlor %x0,%x1,%x1";
2247 else if (element == VECTOR_ELEMENT_MFVSRLD_64BIT && INT_REGNO_P (op0_regno)
2248 && TARGET_P9_VECTOR && TARGET_POWERPC64 && TARGET_DIRECT_MOVE)
2249 return "mfvsrld %0,%x1";
2251 else if (VSX_REGNO_P (op0_regno))
2253 fldDM = element << 1;
2254 if (!BYTES_BIG_ENDIAN)
2256 operands[3] = GEN_INT (fldDM);
2257 return "xxpermdi %x0,%x1,%x1,%3";
2263 [(set_attr "type" "veclogical,mftgpr,mftgpr,vecperm")])
2265 ;; Optimize extracting a single scalar element from memory.
2266 (define_insn_and_split "*vsx_extract_<P:mode>_<VSX_D:mode>_load"
2267 [(set (match_operand:<VS_scalar> 0 "register_operand" "=<VSX_D:VS_64reg>,wr")
2268 (vec_select:<VSX_D:VS_scalar>
2269 (match_operand:VSX_D 1 "memory_operand" "m,m")
2270 (parallel [(match_operand:QI 2 "const_0_to_1_operand" "n,n")])))
2271 (clobber (match_scratch:P 3 "=&b,&b"))]
2272 "VECTOR_MEM_VSX_P (<VSX_D:MODE>mode)"
2274 "&& reload_completed"
2275 [(set (match_dup 0) (match_dup 4))]
2277 operands[4] = rs6000_adjust_vec_address (operands[0], operands[1], operands[2],
2278 operands[3], <VSX_D:VS_scalar>mode);
2280 [(set_attr "type" "fpload,load")
2281 (set_attr "length" "8")])
2283 ;; Optimize storing a single scalar element that is the right location to
2285 (define_insn "*vsx_extract_<mode>_store"
2286 [(set (match_operand:<VS_scalar> 0 "memory_operand" "=m,Z,o")
2287 (vec_select:<VS_scalar>
2288 (match_operand:VSX_D 1 "register_operand" "d,wv,wb")
2289 (parallel [(match_operand:QI 2 "vsx_scalar_64bit" "wD,wD,wD")])))]
2290 "VECTOR_MEM_VSX_P (<MODE>mode)"
2295 [(set_attr "type" "fpstore")
2296 (set_attr "length" "4")])
2298 ;; Variable V2DI/V2DF extract shift
2299 (define_insn "vsx_vslo_<mode>"
2300 [(set (match_operand:<VS_scalar> 0 "gpc_reg_operand" "=v")
2301 (unspec:<VS_scalar> [(match_operand:VSX_D 1 "gpc_reg_operand" "v")
2302 (match_operand:V2DI 2 "gpc_reg_operand" "v")]
2304 "VECTOR_MEM_VSX_P (<MODE>mode) && TARGET_DIRECT_MOVE_64BIT"
2306 [(set_attr "type" "vecperm")])
2308 ;; Variable V2DI/V2DF extract
2309 (define_insn_and_split "vsx_extract_<mode>_var"
2310 [(set (match_operand:<VS_scalar> 0 "gpc_reg_operand" "=v,<VSa>,r")
2311 (unspec:<VS_scalar> [(match_operand:VSX_D 1 "input_operand" "v,m,m")
2312 (match_operand:DI 2 "gpc_reg_operand" "r,r,r")]
2313 UNSPEC_VSX_EXTRACT))
2314 (clobber (match_scratch:DI 3 "=r,&b,&b"))
2315 (clobber (match_scratch:V2DI 4 "=&v,X,X"))]
2316 "VECTOR_MEM_VSX_P (<MODE>mode) && TARGET_DIRECT_MOVE_64BIT"
2318 "&& reload_completed"
2321 rs6000_split_vec_extract_var (operands[0], operands[1], operands[2],
2322 operands[3], operands[4]);
2326 ;; Extract a SF element from V4SF
2327 (define_insn_and_split "vsx_extract_v4sf"
2328 [(set (match_operand:SF 0 "vsx_register_operand" "=ww")
2330 (match_operand:V4SF 1 "vsx_register_operand" "wa")
2331 (parallel [(match_operand:QI 2 "u5bit_cint_operand" "n")])))
2332 (clobber (match_scratch:V4SF 3 "=0"))]
2333 "VECTOR_UNIT_VSX_P (V4SFmode)"
2338 rtx op0 = operands[0];
2339 rtx op1 = operands[1];
2340 rtx op2 = operands[2];
2341 rtx op3 = operands[3];
2343 HOST_WIDE_INT ele = BYTES_BIG_ENDIAN ? INTVAL (op2) : 3 - INTVAL (op2);
2349 if (GET_CODE (op3) == SCRATCH)
2350 op3 = gen_reg_rtx (V4SFmode);
2351 emit_insn (gen_vsx_xxsldwi_v4sf (op3, op1, op1, GEN_INT (ele)));
2354 emit_insn (gen_vsx_xscvspdp_scalar2 (op0, tmp));
2357 [(set_attr "length" "8")
2358 (set_attr "type" "fp")])
2360 (define_insn_and_split "*vsx_extract_v4sf_<mode>_load"
2361 [(set (match_operand:SF 0 "register_operand" "=f,wv,wb,?r")
2363 (match_operand:V4SF 1 "memory_operand" "m,Z,m,m")
2364 (parallel [(match_operand:QI 2 "const_0_to_3_operand" "n,n,n,n")])))
2365 (clobber (match_scratch:P 3 "=&b,&b,&b,&b"))]
2366 "VECTOR_MEM_VSX_P (V4SFmode)"
2368 "&& reload_completed"
2369 [(set (match_dup 0) (match_dup 4))]
2371 operands[4] = rs6000_adjust_vec_address (operands[0], operands[1], operands[2],
2372 operands[3], SFmode);
2374 [(set_attr "type" "fpload,fpload,fpload,load")
2375 (set_attr "length" "8")])
2377 ;; Variable V4SF extract
2378 (define_insn_and_split "vsx_extract_v4sf_var"
2379 [(set (match_operand:SF 0 "gpc_reg_operand" "=ww,ww,?r")
2380 (unspec:SF [(match_operand:V4SF 1 "input_operand" "v,m,m")
2381 (match_operand:DI 2 "gpc_reg_operand" "r,r,r")]
2382 UNSPEC_VSX_EXTRACT))
2383 (clobber (match_scratch:DI 3 "=r,&b,&b"))
2384 (clobber (match_scratch:V2DI 4 "=&v,X,X"))]
2385 "VECTOR_MEM_VSX_P (V4SFmode) && TARGET_DIRECT_MOVE_64BIT
2386 && TARGET_UPPER_REGS_SF"
2388 "&& reload_completed"
2391 rs6000_split_vec_extract_var (operands[0], operands[1], operands[2],
2392 operands[3], operands[4]);
2396 ;; Expand the builtin form of xxpermdi to canonical rtl.
2397 (define_expand "vsx_xxpermdi_<mode>"
2398 [(match_operand:VSX_L 0 "vsx_register_operand" "")
2399 (match_operand:VSX_L 1 "vsx_register_operand" "")
2400 (match_operand:VSX_L 2 "vsx_register_operand" "")
2401 (match_operand:QI 3 "u5bit_cint_operand" "")]
2402 "VECTOR_MEM_VSX_P (<MODE>mode)"
2404 rtx target = operands[0];
2405 rtx op0 = operands[1];
2406 rtx op1 = operands[2];
2407 int mask = INTVAL (operands[3]);
2408 rtx perm0 = GEN_INT ((mask >> 1) & 1);
2409 rtx perm1 = GEN_INT ((mask & 1) + 2);
2410 rtx (*gen) (rtx, rtx, rtx, rtx, rtx);
2412 if (<MODE>mode == V2DFmode)
2413 gen = gen_vsx_xxpermdi2_v2df_1;
2416 gen = gen_vsx_xxpermdi2_v2di_1;
2417 if (<MODE>mode != V2DImode)
2419 target = gen_lowpart (V2DImode, target);
2420 op0 = gen_lowpart (V2DImode, op0);
2421 op1 = gen_lowpart (V2DImode, op1);
2424 /* In little endian mode, vsx_xxpermdi2_<mode>_1 will perform a
2425 transformation we don't want; it is necessary for
2426 rs6000_expand_vec_perm_const_1 but not for this use. So we
2427 prepare for that by reversing the transformation here. */
2428 if (BYTES_BIG_ENDIAN)
2429 emit_insn (gen (target, op0, op1, perm0, perm1));
2432 rtx p0 = GEN_INT (3 - INTVAL (perm1));
2433 rtx p1 = GEN_INT (3 - INTVAL (perm0));
2434 emit_insn (gen (target, op1, op0, p0, p1));
2439 (define_insn "vsx_xxpermdi2_<mode>_1"
2440 [(set (match_operand:VSX_D 0 "vsx_register_operand" "=wd")
2442 (vec_concat:<VS_double>
2443 (match_operand:VSX_D 1 "vsx_register_operand" "wd")
2444 (match_operand:VSX_D 2 "vsx_register_operand" "wd"))
2445 (parallel [(match_operand 3 "const_0_to_1_operand" "")
2446 (match_operand 4 "const_2_to_3_operand" "")])))]
2447 "VECTOR_MEM_VSX_P (<MODE>mode)"
2451 /* For little endian, swap operands and invert/swap selectors
2452 to get the correct xxpermdi. The operand swap sets up the
2453 inputs as a little endian array. The selectors are swapped
2454 because they are defined to use big endian ordering. The
2455 selectors are inverted to get the correct doublewords for
2456 little endian ordering. */
2457 if (BYTES_BIG_ENDIAN)
2459 op3 = INTVAL (operands[3]);
2460 op4 = INTVAL (operands[4]);
2464 op3 = 3 - INTVAL (operands[4]);
2465 op4 = 3 - INTVAL (operands[3]);
2468 mask = (op3 << 1) | (op4 - 2);
2469 operands[3] = GEN_INT (mask);
2471 if (BYTES_BIG_ENDIAN)
2472 return "xxpermdi %x0,%x1,%x2,%3";
2474 return "xxpermdi %x0,%x2,%x1,%3";
2476 [(set_attr "type" "vecperm")])
2478 (define_expand "vec_perm_const<mode>"
2479 [(match_operand:VSX_D 0 "vsx_register_operand" "")
2480 (match_operand:VSX_D 1 "vsx_register_operand" "")
2481 (match_operand:VSX_D 2 "vsx_register_operand" "")
2482 (match_operand:V2DI 3 "" "")]
2483 "VECTOR_MEM_VSX_P (<MODE>mode)"
2485 if (rs6000_expand_vec_perm_const (operands))
2491 ;; Extraction of a single element in a small integer vector. None of the small
2492 ;; types are currently allowed in a vector register, so we extract to a DImode
2493 ;; and either do a direct move or store.
2494 (define_expand "vsx_extract_<mode>"
2495 [(parallel [(set (match_operand:<VS_scalar> 0 "nonimmediate_operand")
2496 (vec_select:<VS_scalar>
2497 (match_operand:VSX_EXTRACT_I 1 "gpc_reg_operand")
2498 (parallel [(match_operand:QI 2 "const_int_operand")])))
2499 (clobber (match_dup 3))])]
2500 "VECTOR_MEM_VSX_P (<MODE>mode) && TARGET_DIRECT_MOVE_64BIT"
2502 machine_mode smode = ((<MODE>mode != V4SImode && TARGET_VEXTRACTUB)
2503 ? DImode : <MODE>mode);
2504 operands[3] = gen_rtx_SCRATCH (smode);
2507 ;; Under ISA 3.0, we can use the byte/half-word/word integer stores if we are
2508 ;; extracting a vector element and storing it to memory, rather than using
2509 ;; direct move to a GPR and a GPR store.
2510 (define_insn_and_split "*vsx_extract_<mode>_p9"
2511 [(set (match_operand:<VS_scalar> 0 "nonimmediate_operand" "=r,Z")
2512 (vec_select:<VS_scalar>
2513 (match_operand:VSX_EXTRACT_I2 1 "gpc_reg_operand" "v,v")
2514 (parallel [(match_operand:QI 2 "<VSX_EXTRACT_PREDICATE>" "n,n")])))
2515 (clobber (match_scratch:DI 3 "=v,v"))]
2516 "VECTOR_MEM_VSX_P (<MODE>mode) && TARGET_VEXTRACTUB"
2518 "&& (reload_completed || MEM_P (operands[0]))"
2521 rtx dest = operands[0];
2522 rtx src = operands[1];
2523 rtx element = operands[2];
2524 rtx di_tmp = operands[3];
2526 if (GET_CODE (di_tmp) == SCRATCH)
2527 di_tmp = gen_reg_rtx (DImode);
2529 emit_insn (gen_vsx_extract_<mode>_di (di_tmp, src, element));
2532 emit_move_insn (gen_rtx_REG (DImode, REGNO (dest)), di_tmp);
2533 else if (SUBREG_P (dest))
2534 emit_move_insn (gen_rtx_REG (DImode, subreg_regno (dest)), di_tmp);
2535 else if (MEM_P (operands[0]))
2537 if (can_create_pseudo_p ())
2538 dest = rs6000_address_for_fpconvert (dest);
2540 if (<MODE>mode == V16QImode)
2541 emit_insn (gen_p9_stxsibx (dest, di_tmp));
2542 else if (<MODE>mode == V8HImode)
2543 emit_insn (gen_p9_stxsihx (dest, di_tmp));
2552 [(set_attr "type" "vecsimple,fpstore")])
2554 (define_insn "vsx_extract_<mode>_di"
2555 [(set (match_operand:DI 0 "gpc_reg_operand" "=<VSX_EX>")
2557 (vec_select:<VS_scalar>
2558 (match_operand:VSX_EXTRACT_I 1 "gpc_reg_operand" "<VSX_EX>")
2559 (parallel [(match_operand:QI 2 "<VSX_EXTRACT_PREDICATE>" "n")]))))]
2560 "VECTOR_MEM_VSX_P (<MODE>mode) && TARGET_VEXTRACTUB"
2562 int element = INTVAL (operands[2]);
2563 int unit_size = GET_MODE_UNIT_SIZE (<MODE>mode);
2564 int offset = ((VECTOR_ELT_ORDER_BIG)
2565 ? unit_size * element
2566 : unit_size * (GET_MODE_NUNITS (<MODE>mode) - 1 - element));
2568 operands[2] = GEN_INT (offset);
2570 return "xxextractuw %x0,%x1,%2";
2572 return "vextractu<wd> %0,%1,%2";
2574 [(set_attr "type" "vecsimple")])
2576 (define_insn_and_split "*vsx_extract_si"
2577 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,Z,Z,wJwK")
2579 (match_operand:V4SI 1 "gpc_reg_operand" "v,wJwK,v,v")
2580 (parallel [(match_operand:QI 2 "const_0_to_3_operand" "n,n,n,n")])))
2581 (clobber (match_scratch:V4SI 3 "=v,wJwK,v,v"))]
2582 "VECTOR_MEM_VSX_P (V4SImode) && TARGET_DIRECT_MOVE_64BIT"
2584 "&& reload_completed"
2587 rtx dest = operands[0];
2588 rtx src = operands[1];
2589 rtx element = operands[2];
2590 rtx vec_tmp = operands[3];
2593 if (!VECTOR_ELT_ORDER_BIG)
2594 element = GEN_INT (GET_MODE_NUNITS (V4SImode) - 1 - INTVAL (element));
2596 /* If the value is in the correct position, we can avoid doing the VSPLT<x>
2598 value = INTVAL (element);
2601 if (TARGET_VEXTRACTUB)
2603 rtx di_tmp = gen_rtx_REG (DImode, REGNO (vec_tmp));
2604 emit_insn (gen_vsx_extract_v4si_di (di_tmp,src, element));
2607 emit_insn (gen_altivec_vspltw_direct (vec_tmp, src, element));
2612 if (MEM_P (operands[0]))
2614 if (can_create_pseudo_p ())
2615 dest = rs6000_address_for_fpconvert (dest);
2617 if (TARGET_VSX_SMALL_INTEGER)
2618 emit_move_insn (dest, gen_rtx_REG (SImode, REGNO (vec_tmp)));
2620 emit_insn (gen_stfiwx (dest, gen_rtx_REG (DImode, REGNO (vec_tmp))));
2623 else if (TARGET_VSX_SMALL_INTEGER)
2624 emit_move_insn (dest, gen_rtx_REG (SImode, REGNO (vec_tmp)));
2626 emit_move_insn (gen_rtx_REG (DImode, REGNO (dest)),
2627 gen_rtx_REG (DImode, REGNO (vec_tmp)));
2631 [(set_attr "type" "mftgpr,fpstore,fpstore,vecsimple")
2632 (set_attr "length" "8")])
2634 (define_insn_and_split "*vsx_extract_<mode>_p8"
2635 [(set (match_operand:<VS_scalar> 0 "nonimmediate_operand" "=r")
2636 (vec_select:<VS_scalar>
2637 (match_operand:VSX_EXTRACT_I2 1 "gpc_reg_operand" "v")
2638 (parallel [(match_operand:QI 2 "<VSX_EXTRACT_PREDICATE>" "n")])))
2639 (clobber (match_scratch:VSX_EXTRACT_I2 3 "=v"))]
2640 "VECTOR_MEM_VSX_P (<MODE>mode) && TARGET_DIRECT_MOVE_64BIT"
2642 "&& reload_completed"
2645 rtx dest = operands[0];
2646 rtx src = operands[1];
2647 rtx element = operands[2];
2648 rtx vec_tmp = operands[3];
2651 if (!VECTOR_ELT_ORDER_BIG)
2652 element = GEN_INT (GET_MODE_NUNITS (<MODE>mode) - 1 - INTVAL (element));
2654 /* If the value is in the correct position, we can avoid doing the VSPLT<x>
2656 value = INTVAL (element);
2657 if (<MODE>mode == V16QImode)
2660 emit_insn (gen_altivec_vspltb_direct (vec_tmp, src, element));
2664 else if (<MODE>mode == V8HImode)
2667 emit_insn (gen_altivec_vsplth_direct (vec_tmp, src, element));
2674 emit_move_insn (gen_rtx_REG (DImode, REGNO (dest)),
2675 gen_rtx_REG (DImode, REGNO (vec_tmp)));
2678 [(set_attr "type" "mftgpr")])
2680 ;; Optimize extracting a single scalar element from memory.
2681 (define_insn_and_split "*vsx_extract_<mode>_load"
2682 [(set (match_operand:<VS_scalar> 0 "register_operand" "=r")
2683 (vec_select:<VS_scalar>
2684 (match_operand:VSX_EXTRACT_I 1 "memory_operand" "m")
2685 (parallel [(match_operand:QI 2 "<VSX_EXTRACT_PREDICATE>" "n")])))
2686 (clobber (match_scratch:DI 3 "=&b"))]
2687 "VECTOR_MEM_VSX_P (<MODE>mode) && TARGET_DIRECT_MOVE_64BIT"
2689 "&& reload_completed"
2690 [(set (match_dup 0) (match_dup 4))]
2692 operands[4] = rs6000_adjust_vec_address (operands[0], operands[1], operands[2],
2693 operands[3], <VS_scalar>mode);
2695 [(set_attr "type" "load")
2696 (set_attr "length" "8")])
2698 ;; Variable V16QI/V8HI/V4SI extract
2699 (define_insn_and_split "vsx_extract_<mode>_var"
2700 [(set (match_operand:<VS_scalar> 0 "gpc_reg_operand" "=r,r")
2702 [(match_operand:VSX_EXTRACT_I 1 "input_operand" "v,m")
2703 (match_operand:DI 2 "gpc_reg_operand" "r,r")]
2704 UNSPEC_VSX_EXTRACT))
2705 (clobber (match_scratch:DI 3 "=r,&b"))
2706 (clobber (match_scratch:V2DI 4 "=&v,X"))]
2707 "VECTOR_MEM_VSX_P (<MODE>mode) && TARGET_DIRECT_MOVE_64BIT"
2709 "&& reload_completed"
2712 rs6000_split_vec_extract_var (operands[0], operands[1], operands[2],
2713 operands[3], operands[4]);
2717 ;; Expanders for builtins
2718 (define_expand "vsx_mergel_<mode>"
2719 [(use (match_operand:VSX_D 0 "vsx_register_operand" ""))
2720 (use (match_operand:VSX_D 1 "vsx_register_operand" ""))
2721 (use (match_operand:VSX_D 2 "vsx_register_operand" ""))]
2722 "VECTOR_MEM_VSX_P (<MODE>mode)"
2727 /* Special handling for LE with -maltivec=be. */
2728 if (!BYTES_BIG_ENDIAN && VECTOR_ELT_ORDER_BIG)
2730 v = gen_rtvec (2, GEN_INT (0), GEN_INT (2));
2731 x = gen_rtx_VEC_CONCAT (<VS_double>mode, operands[2], operands[1]);
2735 v = gen_rtvec (2, GEN_INT (1), GEN_INT (3));
2736 x = gen_rtx_VEC_CONCAT (<VS_double>mode, operands[1], operands[2]);
2739 x = gen_rtx_VEC_SELECT (<MODE>mode, x, gen_rtx_PARALLEL (VOIDmode, v));
2740 emit_insn (gen_rtx_SET (operands[0], x));
2744 (define_expand "vsx_mergeh_<mode>"
2745 [(use (match_operand:VSX_D 0 "vsx_register_operand" ""))
2746 (use (match_operand:VSX_D 1 "vsx_register_operand" ""))
2747 (use (match_operand:VSX_D 2 "vsx_register_operand" ""))]
2748 "VECTOR_MEM_VSX_P (<MODE>mode)"
2753 /* Special handling for LE with -maltivec=be. */
2754 if (!BYTES_BIG_ENDIAN && VECTOR_ELT_ORDER_BIG)
2756 v = gen_rtvec (2, GEN_INT (1), GEN_INT (3));
2757 x = gen_rtx_VEC_CONCAT (<VS_double>mode, operands[2], operands[1]);
2761 v = gen_rtvec (2, GEN_INT (0), GEN_INT (2));
2762 x = gen_rtx_VEC_CONCAT (<VS_double>mode, operands[1], operands[2]);
2765 x = gen_rtx_VEC_SELECT (<MODE>mode, x, gen_rtx_PARALLEL (VOIDmode, v));
2766 emit_insn (gen_rtx_SET (operands[0], x));
2771 (define_insn "vsx_splat_<mode>"
2772 [(set (match_operand:VSX_D 0 "vsx_register_operand" "=<VSa>,<VSa>,we")
2773 (vec_duplicate:VSX_D
2774 (match_operand:<VS_scalar> 1 "splat_input_operand" "<VS_64reg>,Z,b")))]
2775 "VECTOR_MEM_VSX_P (<MODE>mode)"
2777 xxpermdi %x0,%x1,%x1,0
2780 [(set_attr "type" "vecperm,vecload,vecperm")])
2782 ;; V4SI splat support
2783 (define_insn "vsx_splat_v4si"
2784 [(set (match_operand:V4SI 0 "vsx_register_operand" "=we,we")
2786 (match_operand:SI 1 "splat_input_operand" "r,Z")))]
2791 [(set_attr "type" "vecperm,vecload")])
2793 ;; SImode is not currently allowed in vector registers. This pattern
2794 ;; allows us to use direct move to get the value in a vector register
2795 ;; so that we can use XXSPLTW
2796 (define_insn "vsx_splat_v4si_di"
2797 [(set (match_operand:V4SI 0 "vsx_register_operand" "=wa,we")
2800 (match_operand:DI 1 "gpc_reg_operand" "wj,r"))))]
2801 "VECTOR_MEM_VSX_P (V4SImode) && TARGET_DIRECT_MOVE_64BIT"
2805 [(set_attr "type" "vecperm")])
2807 ;; V4SF splat (ISA 3.0)
2808 (define_insn_and_split "vsx_splat_v4sf"
2809 [(set (match_operand:V4SF 0 "vsx_register_operand" "=wa,wa,wa")
2811 (match_operand:SF 1 "splat_input_operand" "Z,wy,r")))]
2817 "&& reload_completed && vsx_register_operand (operands[1], SFmode)"
2819 (unspec:V4SF [(match_dup 1)] UNSPEC_VSX_CVDPSPN))
2821 (unspec:V4SF [(match_dup 0)
2822 (const_int 0)] UNSPEC_VSX_XXSPLTW))]
2824 [(set_attr "type" "vecload,vecperm,mftgpr")
2825 (set_attr "length" "4,8,4")])
2827 ;; V4SF/V4SI splat from a vector element
2828 (define_insn "vsx_xxspltw_<mode>"
2829 [(set (match_operand:VSX_W 0 "vsx_register_operand" "=<VSa>")
2830 (vec_duplicate:VSX_W
2831 (vec_select:<VS_scalar>
2832 (match_operand:VSX_W 1 "vsx_register_operand" "<VSa>")
2834 [(match_operand:QI 2 "u5bit_cint_operand" "n")]))))]
2835 "VECTOR_MEM_VSX_P (<MODE>mode)"
2837 if (!BYTES_BIG_ENDIAN)
2838 operands[2] = GEN_INT (3 - INTVAL (operands[2]));
2840 return "xxspltw %x0,%x1,%2";
2842 [(set_attr "type" "vecperm")])
2844 (define_insn "vsx_xxspltw_<mode>_direct"
2845 [(set (match_operand:VSX_W 0 "vsx_register_operand" "=<VSa>")
2846 (unspec:VSX_W [(match_operand:VSX_W 1 "vsx_register_operand" "<VSa>")
2847 (match_operand:QI 2 "u5bit_cint_operand" "i")]
2848 UNSPEC_VSX_XXSPLTW))]
2849 "VECTOR_MEM_VSX_P (<MODE>mode)"
2850 "xxspltw %x0,%x1,%2"
2851 [(set_attr "type" "vecperm")])
2853 ;; V16QI/V8HI splat support on ISA 2.07
2854 (define_insn "vsx_vsplt<VSX_SPLAT_SUFFIX>_di"
2855 [(set (match_operand:VSX_SPLAT_I 0 "altivec_register_operand" "=v")
2856 (vec_duplicate:VSX_SPLAT_I
2857 (truncate:<VS_scalar>
2858 (match_operand:DI 1 "altivec_register_operand" "v"))))]
2859 "VECTOR_MEM_VSX_P (<MODE>mode) && TARGET_DIRECT_MOVE_64BIT"
2860 "vsplt<VSX_SPLAT_SUFFIX> %0,%1,<VSX_SPLAT_COUNT>"
2861 [(set_attr "type" "vecperm")])
2863 ;; V2DF/V2DI splat for use by vec_splat builtin
2864 (define_insn "vsx_xxspltd_<mode>"
2865 [(set (match_operand:VSX_D 0 "vsx_register_operand" "=wa")
2866 (unspec:VSX_D [(match_operand:VSX_D 1 "vsx_register_operand" "wa")
2867 (match_operand:QI 2 "u5bit_cint_operand" "i")]
2868 UNSPEC_VSX_XXSPLTD))]
2869 "VECTOR_MEM_VSX_P (<MODE>mode)"
2871 if ((VECTOR_ELT_ORDER_BIG && INTVAL (operands[2]) == 0)
2872 || (!VECTOR_ELT_ORDER_BIG && INTVAL (operands[2]) == 1))
2873 return "xxpermdi %x0,%x1,%x1,0";
2875 return "xxpermdi %x0,%x1,%x1,3";
2877 [(set_attr "type" "vecperm")])
2879 ;; V4SF/V4SI interleave
2880 (define_insn "vsx_xxmrghw_<mode>"
2881 [(set (match_operand:VSX_W 0 "vsx_register_operand" "=wf,?<VSa>")
2883 (vec_concat:<VS_double>
2884 (match_operand:VSX_W 1 "vsx_register_operand" "wf,<VSa>")
2885 (match_operand:VSX_W 2 "vsx_register_operand" "wf,<VSa>"))
2886 (parallel [(const_int 0) (const_int 4)
2887 (const_int 1) (const_int 5)])))]
2888 "VECTOR_MEM_VSX_P (<MODE>mode)"
2890 if (BYTES_BIG_ENDIAN)
2891 return "xxmrghw %x0,%x1,%x2";
2893 return "xxmrglw %x0,%x2,%x1";
2895 [(set_attr "type" "vecperm")])
2897 (define_insn "vsx_xxmrglw_<mode>"
2898 [(set (match_operand:VSX_W 0 "vsx_register_operand" "=wf,?<VSa>")
2900 (vec_concat:<VS_double>
2901 (match_operand:VSX_W 1 "vsx_register_operand" "wf,<VSa>")
2902 (match_operand:VSX_W 2 "vsx_register_operand" "wf,?<VSa>"))
2903 (parallel [(const_int 2) (const_int 6)
2904 (const_int 3) (const_int 7)])))]
2905 "VECTOR_MEM_VSX_P (<MODE>mode)"
2907 if (BYTES_BIG_ENDIAN)
2908 return "xxmrglw %x0,%x1,%x2";
2910 return "xxmrghw %x0,%x2,%x1";
2912 [(set_attr "type" "vecperm")])
2914 ;; Shift left double by word immediate
2915 (define_insn "vsx_xxsldwi_<mode>"
2916 [(set (match_operand:VSX_L 0 "vsx_register_operand" "=<VSa>")
2917 (unspec:VSX_L [(match_operand:VSX_L 1 "vsx_register_operand" "<VSa>")
2918 (match_operand:VSX_L 2 "vsx_register_operand" "<VSa>")
2919 (match_operand:QI 3 "u5bit_cint_operand" "i")]
2921 "VECTOR_MEM_VSX_P (<MODE>mode)"
2922 "xxsldwi %x0,%x1,%x2,%3"
2923 [(set_attr "type" "vecperm")])
2926 ;; Vector reduction insns and splitters
2928 (define_insn_and_split "vsx_reduc_<VEC_reduc_name>_v2df"
2929 [(set (match_operand:V2DF 0 "vfloat_operand" "=&wd,&?wa,wd,?wa")
2933 (match_operand:V2DF 1 "vfloat_operand" "wd,wa,wd,wa")
2934 (parallel [(const_int 1)]))
2937 (parallel [(const_int 0)])))
2939 (clobber (match_scratch:V2DF 2 "=0,0,&wd,&wa"))]
2940 "VECTOR_UNIT_VSX_P (V2DFmode)"
2946 rtx tmp = (GET_CODE (operands[2]) == SCRATCH)
2947 ? gen_reg_rtx (V2DFmode)
2949 emit_insn (gen_vsx_xxsldwi_v2df (tmp, operands[1], operands[1], const2_rtx));
2950 emit_insn (gen_<VEC_reduc_rtx>v2df3 (operands[0], tmp, operands[1]));
2953 [(set_attr "length" "8")
2954 (set_attr "type" "veccomplex")])
2956 (define_insn_and_split "vsx_reduc_<VEC_reduc_name>_v4sf"
2957 [(set (match_operand:V4SF 0 "vfloat_operand" "=wf,?wa")
2959 (unspec:V4SF [(const_int 0)] UNSPEC_REDUC)
2960 (match_operand:V4SF 1 "vfloat_operand" "wf,wa")))
2961 (clobber (match_scratch:V4SF 2 "=&wf,&wa"))
2962 (clobber (match_scratch:V4SF 3 "=&wf,&wa"))]
2963 "VECTOR_UNIT_VSX_P (V4SFmode)"
2969 rtx op0 = operands[0];
2970 rtx op1 = operands[1];
2971 rtx tmp2, tmp3, tmp4;
2973 if (can_create_pseudo_p ())
2975 tmp2 = gen_reg_rtx (V4SFmode);
2976 tmp3 = gen_reg_rtx (V4SFmode);
2977 tmp4 = gen_reg_rtx (V4SFmode);
2986 emit_insn (gen_vsx_xxsldwi_v4sf (tmp2, op1, op1, const2_rtx));
2987 emit_insn (gen_<VEC_reduc_rtx>v4sf3 (tmp3, tmp2, op1));
2988 emit_insn (gen_vsx_xxsldwi_v4sf (tmp4, tmp3, tmp3, GEN_INT (3)));
2989 emit_insn (gen_<VEC_reduc_rtx>v4sf3 (op0, tmp4, tmp3));
2992 [(set_attr "length" "16")
2993 (set_attr "type" "veccomplex")])
2995 ;; Combiner patterns with the vector reduction patterns that knows we can get
2996 ;; to the top element of the V2DF array without doing an extract.
2998 (define_insn_and_split "*vsx_reduc_<VEC_reduc_name>_v2df_scalar"
2999 [(set (match_operand:DF 0 "vfloat_operand" "=&ws,&?ws,ws,?ws")
3004 (match_operand:V2DF 1 "vfloat_operand" "wd,wa,wd,wa")
3005 (parallel [(const_int 1)]))
3008 (parallel [(const_int 0)])))
3010 (parallel [(const_int 1)])))
3011 (clobber (match_scratch:DF 2 "=0,0,&wd,&wa"))]
3012 "VECTOR_UNIT_VSX_P (V2DFmode)"
3018 rtx hi = gen_highpart (DFmode, operands[1]);
3019 rtx lo = (GET_CODE (operands[2]) == SCRATCH)
3020 ? gen_reg_rtx (DFmode)
3023 emit_insn (gen_vsx_extract_v2df (lo, operands[1], const1_rtx));
3024 emit_insn (gen_<VEC_reduc_rtx>df3 (operands[0], hi, lo));
3027 [(set_attr "length" "8")
3028 (set_attr "type" "veccomplex")])
3030 (define_insn_and_split "*vsx_reduc_<VEC_reduc_name>_v4sf_scalar"
3031 [(set (match_operand:SF 0 "vfloat_operand" "=f,?f")
3034 (unspec:V4SF [(const_int 0)] UNSPEC_REDUC)
3035 (match_operand:V4SF 1 "vfloat_operand" "wf,wa"))
3036 (parallel [(const_int 3)])))
3037 (clobber (match_scratch:V4SF 2 "=&wf,&wa"))
3038 (clobber (match_scratch:V4SF 3 "=&wf,&wa"))
3039 (clobber (match_scratch:V4SF 4 "=0,0"))]
3040 "VECTOR_UNIT_VSX_P (V4SFmode)"
3046 rtx op0 = operands[0];
3047 rtx op1 = operands[1];
3048 rtx tmp2, tmp3, tmp4, tmp5;
3050 if (can_create_pseudo_p ())
3052 tmp2 = gen_reg_rtx (V4SFmode);
3053 tmp3 = gen_reg_rtx (V4SFmode);
3054 tmp4 = gen_reg_rtx (V4SFmode);
3055 tmp5 = gen_reg_rtx (V4SFmode);
3065 emit_insn (gen_vsx_xxsldwi_v4sf (tmp2, op1, op1, const2_rtx));
3066 emit_insn (gen_<VEC_reduc_rtx>v4sf3 (tmp3, tmp2, op1));
3067 emit_insn (gen_vsx_xxsldwi_v4sf (tmp4, tmp3, tmp3, GEN_INT (3)));
3068 emit_insn (gen_<VEC_reduc_rtx>v4sf3 (tmp5, tmp4, tmp3));
3069 emit_insn (gen_vsx_xscvspdp_scalar2 (op0, tmp5));
3072 [(set_attr "length" "20")
3073 (set_attr "type" "veccomplex")])
3076 ;; Power8 Vector fusion. The fused ops must be physically adjacent.
3078 [(set (match_operand:P 0 "base_reg_operand" "")
3079 (match_operand:P 1 "short_cint_operand" ""))
3080 (set (match_operand:VSX_M 2 "vsx_register_operand" "")
3081 (mem:VSX_M (plus:P (match_dup 0)
3082 (match_operand:P 3 "int_reg_operand" ""))))]
3083 "TARGET_VSX && TARGET_P8_FUSION && !TARGET_P9_VECTOR"
3084 "li %0,%1\t\t\t# vector load fusion\;lx<VSX_M:VSm>x %x2,%0,%3"
3085 [(set_attr "length" "8")
3086 (set_attr "type" "vecload")])
3089 [(set (match_operand:P 0 "base_reg_operand" "")
3090 (match_operand:P 1 "short_cint_operand" ""))
3091 (set (match_operand:VSX_M 2 "vsx_register_operand" "")
3092 (mem:VSX_M (plus:P (match_operand:P 3 "int_reg_operand" "")
3094 "TARGET_VSX && TARGET_P8_FUSION && !TARGET_P9_VECTOR"
3095 "li %0,%1\t\t\t# vector load fusion\;lx<VSX_M:VSm>x %x2,%0,%3"
3096 [(set_attr "length" "8")
3097 (set_attr "type" "vecload")])
3100 ;; ISA 3.0 vector extend sign support
3102 (define_insn "vsx_sign_extend_qi_<mode>"
3103 [(set (match_operand:VSINT_84 0 "vsx_register_operand" "=v")
3105 [(match_operand:V16QI 1 "vsx_register_operand" "v")]
3106 UNSPEC_VSX_SIGN_EXTEND))]
3109 [(set_attr "type" "vecexts")])
3111 (define_insn "vsx_sign_extend_hi_<mode>"
3112 [(set (match_operand:VSINT_84 0 "vsx_register_operand" "=v")
3114 [(match_operand:V8HI 1 "vsx_register_operand" "v")]
3115 UNSPEC_VSX_SIGN_EXTEND))]
3118 [(set_attr "type" "vecexts")])
3120 (define_insn "*vsx_sign_extend_si_v2di"
3121 [(set (match_operand:V2DI 0 "vsx_register_operand" "=v")
3122 (unspec:V2DI [(match_operand:V4SI 1 "vsx_register_operand" "v")]
3123 UNSPEC_VSX_SIGN_EXTEND))]
3126 [(set_attr "type" "vecexts")])
3129 ;; ISA 3.0 memory operations
3130 (define_insn "p9_lxsi<wd>zx"
3131 [(set (match_operand:DI 0 "vsx_register_operand" "=wi")
3132 (unspec:DI [(zero_extend:DI
3133 (match_operand:QHI 1 "indexed_or_indirect_operand" "Z"))]
3136 "lxsi<wd>zx %x0,%y1"
3137 [(set_attr "type" "fpload")])
3139 (define_insn "p9_stxsi<wd>x"
3140 [(set (match_operand:QHI 0 "reg_or_indexed_operand" "=r,Z")
3141 (unspec:QHI [(match_operand:DI 1 "vsx_register_operand" "wi,wi")]
3147 [(set_attr "type" "mffgpr,fpstore")])
3149 ;; ISA 3.0 Binary Floating-Point Support
3151 ;; VSX Scalar Extract Exponent Double-Precision
3152 (define_insn "xsxexpdp"
3153 [(set (match_operand:DI 0 "register_operand" "=r")
3154 (unspec:DI [(match_operand:DF 1 "vsx_register_operand" "wa")]
3155 UNSPEC_VSX_SXEXPDP))]
3156 "TARGET_P9_VECTOR && TARGET_64BIT"
3158 [(set_attr "type" "integer")])
3160 ;; VSX Scalar Extract Significand Double-Precision
3161 (define_insn "xsxsigdp"
3162 [(set (match_operand:DI 0 "register_operand" "=r")
3163 (unspec:DI [(match_operand:DF 1 "vsx_register_operand" "wa")]
3164 UNSPEC_VSX_SXSIGDP))]
3165 "TARGET_P9_VECTOR && TARGET_64BIT"
3167 [(set_attr "type" "integer")])
3169 ;; VSX Scalar Insert Exponent Double-Precision
3170 (define_insn "xsiexpdp"
3171 [(set (match_operand:DF 0 "vsx_register_operand" "=wa")
3172 (unspec:DF [(match_operand:DI 1 "register_operand" "r")
3173 (match_operand:DI 2 "register_operand" "r")]
3174 UNSPEC_VSX_SIEXPDP))]
3175 "TARGET_P9_VECTOR && TARGET_64BIT"
3176 "xsiexpdp %x0,%1,%2"
3177 [(set_attr "type" "fpsimple")])
3179 ;; VSX Scalar Compare Exponents Double-Precision
3180 (define_expand "xscmpexpdp_<code>"
3184 [(match_operand:DF 1 "vsx_register_operand" "wa")
3185 (match_operand:DF 2 "vsx_register_operand" "wa")]
3186 UNSPEC_VSX_SCMPEXPDP)
3188 (set (match_operand:SI 0 "register_operand" "=r")
3189 (CMP_TEST:SI (match_dup 3)
3193 operands[3] = gen_reg_rtx (CCFPmode);
3196 (define_insn "*xscmpexpdp"
3197 [(set (match_operand:CCFP 0 "cc_reg_operand" "=y")
3199 (unspec:DF [(match_operand:DF 1 "vsx_register_operand" "wa")
3200 (match_operand:DF 2 "vsx_register_operand" "wa")]
3201 UNSPEC_VSX_SCMPEXPDP)
3202 (match_operand:SI 3 "zero_constant" "j")))]
3204 "xscmpexpdp %0,%x1,%x2"
3205 [(set_attr "type" "fpcompare")])
3207 ;; VSX Scalar Test Data Class Double- and Single-Precision
3208 ;; (The lt bit is set if operand 1 is negative. The eq bit is set
3209 ;; if any of the conditions tested by operand 2 are satisfied.
3210 ;; The gt and unordered bits are cleared to zero.)
3211 (define_expand "xststdc<Fvsx>"
3215 [(match_operand:SFDF 1 "vsx_register_operand" "wa")
3216 (match_operand:SI 2 "u7bit_cint_operand" "n")]
3219 (set (match_operand:SI 0 "register_operand" "=r")
3220 (eq:SI (match_dup 3)
3224 operands[3] = gen_reg_rtx (CCFPmode);
3225 operands[4] = CONST0_RTX (SImode);
3228 ;; The VSX Scalar Test Data Class Double- and Single-Precision
3229 ;; instruction may also be used to test for negative value.
3230 (define_expand "xststdcneg<Fvsx>"
3234 [(match_operand:SFDF 1 "vsx_register_operand" "wa")
3238 (set (match_operand:SI 0 "register_operand" "=r")
3239 (lt:SI (match_dup 2)
3243 operands[2] = gen_reg_rtx (CCFPmode);
3244 operands[3] = CONST0_RTX (SImode);
3247 (define_insn "*xststdc<Fvsx>"
3248 [(set (match_operand:CCFP 0 "" "=y")
3250 (unspec:SFDF [(match_operand:SFDF 1 "vsx_register_operand" "wa")
3251 (match_operand:SI 2 "u7bit_cint_operand" "n")]
3253 (match_operand:SI 3 "zero_constant" "j")))]
3255 "xststdc<Fvsx> %0,%x1,%2"
3256 [(set_attr "type" "fpcompare")])
3258 ;; VSX Vector Extract Exponent Double and Single Precision
3259 (define_insn "xvxexp<VSs>"
3260 [(set (match_operand:VSX_F 0 "vsx_register_operand" "=wa")
3262 [(match_operand:VSX_F 1 "vsx_register_operand" "wa")]
3265 "xvxexp<VSs> %x0,%x1"
3266 [(set_attr "type" "vecsimple")])
3268 ;; VSX Vector Extract Significand Double and Single Precision
3269 (define_insn "xvxsig<VSs>"
3270 [(set (match_operand:VSX_F 0 "vsx_register_operand" "=wa")
3272 [(match_operand:VSX_F 1 "vsx_register_operand" "wa")]
3275 "xvxsig<VSs> %x0,%x1"
3276 [(set_attr "type" "vecsimple")])
3278 ;; VSX Vector Insert Exponent Double and Single Precision
3279 (define_insn "xviexp<VSs>"
3280 [(set (match_operand:VSX_F 0 "vsx_register_operand" "=wa")
3282 [(match_operand:VSX_F 1 "vsx_register_operand" "wa")
3283 (match_operand:VSX_F 2 "vsx_register_operand" "wa")]
3286 "xviexp<VSs> %x0,%x1,%x2"
3287 [(set_attr "type" "vecsimple")])
3289 ;; VSX Vector Test Data Class Double and Single Precision
3290 ;; The corresponding elements of the result vector are all ones
3291 ;; if any of the conditions tested by operand 3 are satisfied.
3292 (define_insn "xvtstdc<VSs>"
3293 [(set (match_operand:<VSI> 0 "vsx_register_operand" "=wa")
3295 [(match_operand:VSX_F 1 "vsx_register_operand" "wa")
3296 (match_operand:SI 2 "u7bit_cint_operand" "n")]
3297 UNSPEC_VSX_VTSTDC))]
3299 "xvtstdc<VSs> %x0,%x1,%2"
3300 [(set_attr "type" "vecsimple")])
3302 ;; ISA 3.0 String Operations Support
3304 ;; Compare vectors producing a vector result and a predicate, setting CR6
3305 ;; to indicate a combined status. This pattern matches v16qi, v8hi, and
3306 ;; v4si modes. It does not match v2df, v4sf, or v2di modes. There's no
3307 ;; need to match the v2di mode because that is expanded into v4si.
3308 (define_insn "*vsx_ne_<mode>_p"
3309 [(set (reg:CC CR6_REGNO)
3311 [(ne:CC (match_operand:VSX_EXTRACT_I 1 "gpc_reg_operand" "v")
3312 (match_operand:VSX_EXTRACT_I 2 "gpc_reg_operand" "v"))]
3314 (set (match_operand:VSX_EXTRACT_I 0 "gpc_reg_operand" "=v")
3315 (ne:VSX_EXTRACT_I (match_dup 1)
3318 "xvcmpne<VSX_EXTRACT_WIDTH>. %0,%1,%2"
3319 [(set_attr "type" "vecsimple")])
3321 ;; Compare vectors producing a vector result and a predicate, setting CR6
3322 ;; to indicate a combined status, for v4sf and v2df operands.
3323 (define_insn "*vsx_ne_<mode>_p"
3324 [(set (reg:CC CR6_REGNO)
3326 (match_operand:VSX_F 1 "vsx_register_operand" "wa")
3327 (match_operand:VSX_F 2 "vsx_register_operand" "wa"))]
3329 (set (match_operand:VSX_F 0 "vsx_register_operand" "=wa")
3330 (ne:VSX_F (match_dup 1)
3333 "xvcmpne<VSs>. %x0,%x1,%x2"
3334 [(set_attr "type" "vecsimple")])
3336 (define_insn "*vector_nez_<mode>_p"
3337 [(set (reg:CC CR6_REGNO)
3338 (unspec:CC [(unspec:VI
3339 [(match_operand:VI 1 "gpc_reg_operand" "v")
3340 (match_operand:VI 2 "gpc_reg_operand" "v")]
3343 (set (match_operand:VI 0 "gpc_reg_operand" "=v")
3344 (unspec:VI [(match_dup 1)
3348 "vcmpnez<VSX_EXTRACT_WIDTH>. %0,%1,%2"
3349 [(set_attr "type" "vecsimple")])
3351 ;; Load VSX Vector with Length
3352 (define_expand "lxvl"
3354 (match_operand:DI 2 "register_operand"))
3355 (set (match_operand:V16QI 0 "vsx_register_operand")
3357 [(match_operand:DI 1 "gpc_reg_operand")
3360 "TARGET_P9_VECTOR && TARGET_64BIT"
3362 operands[3] = gen_reg_rtx (DImode);
3365 (define_insn "*lxvl"
3366 [(set (match_operand:V16QI 0 "vsx_register_operand" "=wa")
3368 [(match_operand:DI 1 "gpc_reg_operand" "b")
3369 (match_operand:DI 2 "register_operand" "+r")]
3371 "TARGET_P9_VECTOR && TARGET_64BIT"
3372 "sldi %2,%2, 56\; lxvl %x0,%1,%2"
3373 [(set_attr "length" "8")
3374 (set_attr "type" "vecload")])
3376 ;; Store VSX Vector with Length
3377 (define_expand "stxvl"
3379 (match_operand:DI 2 "register_operand"))
3380 (set (mem:V16QI (match_operand:DI 1 "gpc_reg_operand"))
3382 [(match_operand:V16QI 0 "vsx_register_operand")
3385 "TARGET_P9_VECTOR && TARGET_64BIT"
3387 operands[3] = gen_reg_rtx (DImode);
3390 (define_insn "*stxvl"
3391 [(set (mem:V16QI (match_operand:DI 1 "gpc_reg_operand" "b"))
3393 [(match_operand:V16QI 0 "vsx_register_operand" "wa")
3394 (match_operand:DI 2 "register_operand" "+r")]
3396 "TARGET_P9_VECTOR && TARGET_64BIT"
3397 "sldi %2,%2\;stxvl %x0,%1,%2"
3398 [(set_attr "length" "8")
3399 (set_attr "type" "vecstore")])
3401 ;; Vector Compare Not Equal Byte
3402 (define_insn "vcmpneb"
3403 [(set (match_operand:V16QI 0 "altivec_register_operand" "=v")
3404 (unspec:V16QI [(match_operand:V16QI 1 "altivec_register_operand" "v")
3405 (match_operand:V16QI 2 "altivec_register_operand" "v")]
3409 [(set_attr "type" "vecsimple")])
3411 ;; Vector Compare Not Equal or Zero Byte
3412 (define_insn "vcmpnezb"
3413 [(set (match_operand:V16QI 0 "altivec_register_operand" "=v")
3415 [(match_operand:V16QI 1 "altivec_register_operand" "v")
3416 (match_operand:V16QI 2 "altivec_register_operand" "v")]
3420 [(set_attr "type" "vecsimple")])
3422 ;; Vector Compare Not Equal Half Word
3423 (define_insn "vcmpneh"
3424 [(set (match_operand:V8HI 0 "altivec_register_operand" "=v")
3425 (unspec:V8HI [(match_operand:V8HI 1 "altivec_register_operand" "v")
3426 (match_operand:V8HI 2 "altivec_register_operand" "v")]
3430 [(set_attr "type" "vecsimple")])
3432 ;; Vector Compare Not Equal or Zero Half Word
3433 (define_insn "vcmpnezh"
3434 [(set (match_operand:V8HI 0 "altivec_register_operand" "=v")
3435 (unspec:V8HI [(match_operand:V8HI 1 "altivec_register_operand" "v")
3436 (match_operand:V8HI 2 "altivec_register_operand" "v")]
3440 [(set_attr "type" "vecsimple")])
3442 ;; Vector Compare Not Equal Word
3443 (define_insn "vcmpnew"
3444 [(set (match_operand:V4SI 0 "altivec_register_operand" "=v")
3446 [(match_operand:V4SI 1 "altivec_register_operand" "v")
3447 (match_operand:V4SI 2 "altivec_register_operand" "v")]
3451 [(set_attr "type" "vecsimple")])
3453 ;; Vector Compare Not Equal Float or Double
3454 (define_insn "vcmpne<VSs>"
3455 [(set (match_operand:<VSI> 0 "vsx_register_operand" "=wa")
3457 [(match_operand:VSX_F 1 "vsx_register_operand" "wa")
3458 (match_operand:VSX_F 2 "vsx_register_operand" "wa")]
3461 "xvcmpne<VSs> %x0,%x1,%x2"
3462 [(set_attr "type" "vecsimple")])
3464 ;; Vector Compare Not Equal or Zero Word
3465 (define_insn "vcmpnezw"
3466 [(set (match_operand:V4SI 0 "altivec_register_operand" "=v")
3467 (unspec:V4SI [(match_operand:V4SI 1 "altivec_register_operand" "v")
3468 (match_operand:V4SI 2 "altivec_register_operand" "v")]
3472 [(set_attr "type" "vecsimple")])
3474 ;; Vector Count Leading Zero Least-Significant Bits Byte
3475 (define_insn "vclzlsbb"
3476 [(set (match_operand:SI 0 "register_operand" "=r")
3478 [(match_operand:V16QI 1 "altivec_register_operand" "v")]
3482 [(set_attr "type" "vecsimple")])
3484 ;; Vector Count Trailing Zero Least-Significant Bits Byte
3485 (define_insn "vctzlsbb"
3486 [(set (match_operand:SI 0 "register_operand" "=r")
3488 [(match_operand:V16QI 1 "altivec_register_operand" "v")]
3492 [(set_attr "type" "vecsimple")])
3494 ;; Vector Extract Unsigned Byte Left-Indexed
3495 (define_insn "vextublx"
3496 [(set (match_operand:SI 0 "register_operand" "=r")
3498 [(match_operand:SI 1 "register_operand" "r")
3499 (match_operand:V16QI 2 "altivec_register_operand" "v")]
3503 [(set_attr "type" "vecsimple")])
3505 ;; Vector Extract Unsigned Byte Right-Indexed
3506 (define_insn "vextubrx"
3507 [(set (match_operand:SI 0 "register_operand" "=r")
3509 [(match_operand:SI 1 "register_operand" "r")
3510 (match_operand:V16QI 2 "altivec_register_operand" "v")]
3514 [(set_attr "type" "vecsimple")])
3516 ;; Vector Extract Unsigned Half Word Left-Indexed
3517 (define_insn "vextuhlx"
3518 [(set (match_operand:SI 0 "register_operand" "=r")
3520 [(match_operand:SI 1 "register_operand" "r")
3521 (match_operand:V16QI 2 "altivec_register_operand" "v")]
3525 [(set_attr "type" "vecsimple")])
3527 ;; Vector Extract Unsigned Half Word Right-Indexed
3528 (define_insn "vextuhrx"
3529 [(set (match_operand:SI 0 "register_operand" "=r")
3531 [(match_operand:SI 1 "register_operand" "r")
3532 (match_operand:V16QI 2 "altivec_register_operand" "v")]
3536 [(set_attr "type" "vecsimple")])
3538 ;; Vector Extract Unsigned Word Left-Indexed
3539 (define_insn "vextuwlx"
3540 [(set (match_operand:SI 0 "register_operand" "=r")
3542 [(match_operand:SI 1 "register_operand" "r")
3543 (match_operand:V16QI 2 "altivec_register_operand" "v")]
3547 [(set_attr "type" "vecsimple")])
3549 ;; Vector Extract Unsigned Word Right-Indexed
3550 (define_insn "vextuwrx"
3551 [(set (match_operand:SI 0 "register_operand" "=r")
3553 [(match_operand:SI 1 "register_operand" "r")
3554 (match_operand:V16QI 2 "altivec_register_operand" "v")]
3558 [(set_attr "type" "vecsimple")])