vx-builtins.md 68 KB

;;- Instruction patterns for the System z vector facility builtins. ;; Copyright (C) 2015 Free Software Foundation, Inc. ;; Contributed by Andreas Krebbel (Andreas.Krebbel@de.ibm.com)

;; This file is part of GCC.

;; GCC is free software; you can redistribute it and/or modify it under ;; the terms of the GNU General Public License as published by the Free ;; Software Foundation; either version 3, or (at your option) any later ;; version.

;; GCC is distributed in the hope that it will be useful, but WITHOUT ANY ;; WARRANTY; without even the implied warranty of MERCHANTABILITY or ;; FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License ;; for more details.

;; You should have received a copy of the GNU General Public License ;; along with GCC; see the file COPYING3. If not see ;; http://www.gnu.org/licenses/.

; The patterns in this file are enabled with -mzvector

(define_mode_iterator V_HW_64 [V2DI V2DF]) (define_mode_iterator V_HW_32_64 [V4SI V2DI V2DF]) (define_mode_iterator VI_HW_SD [V4SI V2DI]) (define_mode_iterator V_HW_HSD [V8HI V4SI V2DI V2DF]) (define_mode_iterator VI_HW_HSD [V8HI V4SI V2DI])

; The element type of the vector with floating point modes translated ; to int modes of the same size. (define_mode_attr non_vec_int[(V2QI "QI") (V4QI "QI") (V8QI "QI") (V16QI "QI")

              (V2HI "HI") (V4HI "HI") (V8HI "HI")
              (V2SI "SI") (V4SI "SI")
              (V2DI "DI")
              (V2SF "SI") (V4SF "SI")
              (V2DF "DI")])

; Condition code modes generated by int comparisons (define_mode_iterator VICMP [CCVEQ CCVH CCVHU])

; Comparisons supported by the vec_cmp* builtins (define_code_iterator intcmp [eq gt gtu ge geu lt ltu le leu]) (define_code_iterator fpcmp [eq gt ge lt le])

; Comparisons supported by the vec_all/any* builtins (define_code_iterator intcmpcc [eq ne gt ge lt le gtu geu ltu leu]) (define_code_iterator fpcmpcc [eq ne gt ge unle unlt lt le])

; Flags for vector string instructions (vfae all 4, vfee only ZS and CS, vstrc all 4) (define_constants [(VSTRING_FLAG_IN 8) ; invert result (VSTRING_FLAG_RT 4) ; result type (VSTRING_FLAG_ZS 2) ; zero search (VSTRING_FLAG_CS 1)]) ; condition code set

; Rounding modes as being used for e.g. VFI (define_constants [(VEC_RND_CURRENT 0) (VEC_RND_NEAREST_AWAY_FROM_ZERO 1) (VEC_RND_SHORT_PREC 3) (VEC_RND_NEAREST_TO_EVEN 4) (VEC_RND_TO_ZERO 5) (VEC_RND_TO_INF 6) (VEC_RND_TO_MINF 7)])

; Vector gather element

(define_insn "vec_gather_element" [(set (match_operand:V_HW_32_64 0 "register_operand" "=v")

(unspec:V_HW_32_64 [(match_operand:V_HW_32_64 1 "register_operand"  "0")
            (match_operand:<tointvec> 2 "register_operand"  "v")
            (match_operand:BLK        3 "memory_operand"   "QR")
            (match_operand:QI         4 "immediate_operand" "C")]
           UNSPEC_VEC_GATHER))]

"TARGET_VX" "vge\t%0,%O3(%v2,%R3),%b4" [(set_attr "op_type" "VRV")])

(define_expand "vec_genmask" [(match_operand:VI_HW 0 "register_operand" "=v") (match_operand:QI 1 "immediate_operand" "C") (match_operand:QI 2 "immediate_operand" "C")] "TARGET_VX" { int nunits = GET_MODE_NUNITS (mode); int bitlen = GET_MODE_UNIT_BITSIZE (mode); /* To bit little endian style. */ int end = bitlen - 1 - INTVAL (operands[1]); int start = bitlen - 1 - INTVAL (operands[2]); rtx const_vec[16]; int i; unsigned HOST_WIDE_INT mask; bool swapped_p = false;

if (start > end)

{
  i = start - 1; start = end + 1; end = i;
  swapped_p = true;
}

if (end == 63)

mask = HOST_WIDE_INT_M1U;

else

mask = (HOST_WIDE_INT_1U << (end + 1)) - 1;

mask &= ~((HOST_WIDE_INT_1U << start) - 1);

if (swapped_p)

mask = ~mask;

for (i = 0; i < nunits; i++)

const_vec[i] = GEN_INT (trunc_int_for_mode (mask,
              GET_MODE_INNER (<VI_HW:MODE>mode)));

emit_insn (gen_rtx_SET (VOIDmode, operands[0],

          gen_rtx_CONST_VECTOR (<VI_HW:MODE>mode,
                    gen_rtvec_v (nunits, const_vec))));

DONE; })

(define_expand "vec_genbytemaskv16qi" [(match_operand:V16QI 0 "register_operand" "") (match_operand 1 "immediate_operand" "")] "TARGET_VX && CONST_OK_FOR_CONSTRAINT_P (INTVAL (operands[1]), 'K', \"K\")" { int i; unsigned mask = 0x8000; rtx const_vec[16]; unsigned HOST_WIDE_INT byte_mask = INTVAL (operands[1]);

for (i = 0; i < 16; i++)

{
  if (mask & byte_mask)
const_vec[i] = constm1_rtx;
  else
const_vec[i] = const0_rtx;
  mask = mask >> 1;
}

emit_insn (gen_rtx_SET (VOIDmode, operands[0],

          gen_rtx_CONST_VECTOR (V16QImode,
                    gen_rtvec_v (16, const_vec))));

DONE; })

(define_expand "vec_splats" [(set (match_operand:V_HW 0 "register_operand" "")

(vec_duplicate:V_HW (match_operand:<non_vec> 1 "general_operand"  "")))]

"TARGET_VX")

(define_expand "vec_insert" [(set (match_operand:V_HW 0 "register_operand" "")

(unspec:V_HW [(match_operand:<non_vec> 2 "register_operand" "")
          (match_operand:SI        3 "shift_count_or_setmem_operand" "")
          (match_operand:V_HW      1 "register_operand" "")]
         UNSPEC_VEC_SET))]

"TARGET_VX" "")

; This is vec_set + modulo arithmetic on the element selector (op 2) (define_expand "vec_promote" [(set (match_operand:V_HW 0 "register_operand" "")

(unspec:V_HW [(match_operand:<non_vec> 1 "register_operand" "")
          (match_operand:SI        2 "shift_count_or_setmem_operand" "")
          (match_dup 0)]
         UNSPEC_VEC_SET))]

"TARGET_VX" "")

; vec_extract is also an RTL standard name -> vector.md

(define_insn "vec_insert_and_zero" [(set (match_operand:V_HW 0 "register_operand" "=v")

(unspec:V_HW [(match_operand:<non_vec> 1 "memory_operand"   "QR")]
         UNSPEC_VEC_INSERT_AND_ZERO))]

"TARGET_VX" "vllez\t%v0,%1" [(set_attr "op_type" "VRX")])

(define_insn "vlbb" [(set (match_operand:V16QI 0 "register_operand" "=v")

(unspec:V16QI [(match_operand:BLK 1 "memory_operand"    "QR")
           (match_operand:HI  2 "immediate_operand" " K")]
          UNSPEC_VEC_LOAD_BNDRY))]

"TARGET_VX" "vlbb\t%v0,%1,%2" [(set_attr "op_type" "VRX")])

; FIXME: The following two patterns might using vec_merge. But what is ; the canonical form: (vec_select (vec_merge op0 op1)) or (vec_merge ; (vec_select op0) (vec_select op1) (define_insn "vec_mergeh" [(set (match_operand:V_HW 0 "register_operand" "=v")

(unspec:V_HW [(match_operand:V_HW 1 "register_operand"  "v")
          (match_operand:V_HW 2 "register_operand"  "v")]
         UNSPEC_VEC_MERGEH))]

"TARGET_VX" "vmrh\t%v0,%1,%2" [(set_attr "op_type" "VRR")])

(define_insn "vec_mergel" [(set (match_operand:V_HW 0 "register_operand" "=v")

(unspec:V_HW [(match_operand:V_HW 1 "register_operand"  "v")
          (match_operand:V_HW 2 "register_operand"  "v")]
         UNSPEC_VEC_MERGEL))]

"TARGET_VX" "vmrl\t%v0,%1,%2" [(set_attr "op_type" "VRR")])

; Vector pack

(define_insn "vec_pack" [(set (match_operand: 0 "register_operand" "=v")

(unspec:<vec_half> [(match_operand:VI_HW_HSD 1 "register_operand"  "v")
            (match_operand:VI_HW_HSD 2 "register_operand"  "v")]
           UNSPEC_VEC_PACK))]

"TARGET_VX" "vpk\t%v0,%v1,%v2" [(set_attr "op_type" "VRR")])

; Vector pack saturate

(define_insn "vec_packs" [(set (match_operand: 0 "register_operand" "=v")

(unspec:<vec_half> [(match_operand:VI_HW_HSD 1 "register_operand"  "v")
            (match_operand:VI_HW_HSD 2 "register_operand"  "v")]
           UNSPEC_VEC_PACK_SATURATE))]

"TARGET_VX" "vpks\t%v0,%v1,%v2" [(set_attr "op_type" "VRR")])

; This is vec_packs_cc + loading cc into a caller specified memory location. (define_expand "vec_packs_cc" [(parallel

[(set (reg:CCRAW CC_REGNUM)
  (unspec:CCRAW [(match_operand:VI_HW_HSD 1 "register_operand" "")
         (match_operand:VI_HW_HSD 2 "register_operand" "")]
        UNSPEC_VEC_PACK_SATURATE_GENCC))
 (set (match_operand:<vec_half> 0 "register_operand" "")
  (unspec:<vec_half> [(match_dup 1) (match_dup 2)]
             UNSPEC_VEC_PACK_SATURATE_CC))])

(set (match_dup 4)

(unspec:SI [(reg:CCRAW CC_REGNUM)] UNSPEC_CC_TO_INT))

(set (match_operand:SI 3 "memory_operand" "")

(match_dup 4))]

"TARGET_VX" { operands[4] = gen_reg_rtx (SImode); })

(define_insn "*vec_packs_cc" [(set (reg:CCRAW CC_REGNUM)

(unspec:CCRAW [(match_operand:VI_HW_HSD 1 "register_operand" "v")
           (match_operand:VI_HW_HSD 2 "register_operand" "v")]
          UNSPEC_VEC_PACK_SATURATE_GENCC))

(set (match_operand: 0 "register_operand" "=v")

(unspec:<vec_half> [(match_dup 1) (match_dup 2)]
           UNSPEC_VEC_PACK_SATURATE_CC))]

"TARGET_VX" "vpkss\t%v0,%v1,%v2" [(set_attr "op_type" "VRR")])

; Vector pack logical saturate

(define_insn "vec_packsu" [(set (match_operand: 0 "register_operand" "=v")

(unspec:<vec_half> [(match_operand:VI_HW_HSD 1 "register_operand"  "v")
            (match_operand:VI_HW_HSD 2 "register_operand"  "v")]
           UNSPEC_VEC_PACK_UNSIGNED_SATURATE))]

"TARGET_VX" "vpkls\t%v0,%v1,%v2" [(set_attr "op_type" "VRR")])

; Emulate saturate unsigned pack on signed operands. ; Zero out negative elements and continue with the unsigned saturating pack. (define_expand "vec_packsu_u" [(set (match_operand: 0 "register_operand" "=v")

(unspec:<vec_half> [(match_operand:VI_HW_HSD 1 "register_operand"  "v")
            (match_operand:VI_HW_HSD 2 "register_operand"  "v")]
           UNSPEC_VEC_PACK_UNSIGNED_SATURATE))]

"TARGET_VX" { rtx null_vec = CONST0_RTX(mode); machine_mode half_mode; switch (mode) {

 case V8HImode: half_mode = V16QImode; break;
 case V4SImode: half_mode = V8HImode; break;
 case V2DImode: half_mode = V4SImode; break;
 default: gcc_unreachable ();

} s390_expand_vcond (operands[1], operands[1], null_vec,

          GE, operands[1], null_vec);

s390_expand_vcond (operands[2], operands[2], null_vec,

          GE, operands[2], null_vec);

emit_insn (gen_rtx_SET (VOIDmode, operands[0],

           gen_rtx_UNSPEC (half_mode,
                   gen_rtvec (2, operands[1], operands[2]),
                   UNSPEC_VEC_PACK_UNSIGNED_SATURATE)));

DONE; })

; This is vec_packsu_cc + loading cc into a caller specified memory location. ; FIXME: The reg to target mem copy should be issued by reload?! (define_expand "vec_packsu_cc" [(parallel

[(set (reg:CCRAW CC_REGNUM)
  (unspec:CCRAW [(match_operand:VI_HW_HSD 1 "register_operand" "")
         (match_operand:VI_HW_HSD 2 "register_operand" "")]
        UNSPEC_VEC_PACK_UNSIGNED_SATURATE_GENCC))
 (set (match_operand:<vec_half> 0 "register_operand" "")
  (unspec:<vec_half> [(match_dup 1) (match_dup 2)]
             UNSPEC_VEC_PACK_UNSIGNED_SATURATE_CC))])

(set (match_dup 4)

(unspec:SI [(reg:CCRAW CC_REGNUM)] UNSPEC_CC_TO_INT))

(set (match_operand:SI 3 "memory_operand" "")

(match_dup 4))]

"TARGET_VX" { operands[4] = gen_reg_rtx (SImode); })

(define_insn "*vec_packsu_cc" [(set (reg:CCRAW CC_REGNUM)

(unspec:CCRAW [(match_operand:VI_HW_HSD 1 "register_operand" "v")
           (match_operand:VI_HW_HSD 2 "register_operand" "v")]
          UNSPEC_VEC_PACK_UNSIGNED_SATURATE_GENCC))

(set (match_operand: 0 "register_operand" "=v")

(unspec:<vec_half> [(match_dup 1) (match_dup 2)]
           UNSPEC_VEC_PACK_UNSIGNED_SATURATE_CC))]

"TARGET_VX" "vpklss\t%v0,%v1,%v2" [(set_attr "op_type" "VRR")])

; Vector permute

; vec_perm is also RTL standard name, but we can only use it for V16QI

(define_insn "vec_zperm" [(set (match_operand:V_HW_HSD 0 "register_operand" "=v")

(unspec:V_HW_HSD [(match_operand:V_HW_HSD 1 "register_operand"  "v")
          (match_operand:V_HW_HSD 2 "register_operand"  "v")
          (match_operand:V16QI    3 "register_operand"  "v")]
         UNSPEC_VEC_PERM))]

"TARGET_VX" "vperm\t%v0,%v1,%v2,%v3" [(set_attr "op_type" "VRR")])

(define_expand "vec_permi" [(set (match_operand:V_HW_64 0 "register_operand" "")

(unspec:V_HW_64 [(match_operand:V_HW_64 1 "register_operand"  "")
         (match_operand:V_HW_64 2 "register_operand"  "")
         (match_operand:QI      3 "immediate_operand" "")]
        UNSPEC_VEC_PERMI))]

"TARGET_VX" { HOST_WIDE_INT val = INTVAL (operands[3]); operands[3] = GEN_INT ((val & 1) | (val & 2) << 1); })

(define_insn "*vec_permi" [(set (match_operand:V_HW_64 0 "register_operand" "=v")

(unspec:V_HW_64 [(match_operand:V_HW_64 1 "register_operand"  "v")
         (match_operand:V_HW_64 2 "register_operand"  "v")
         (match_operand:QI      3 "immediate_operand" "C")]
        UNSPEC_VEC_PERMI))]

"TARGET_VX" "vpdi\t%v0,%v1,%v2,%b3" [(set_attr "op_type" "VRR")])

; Vector replicate

; Replicate from vector element (define_expand "vec_splat" [(set (match_operand:V_HW 0 "register_operand" "")

(vec_duplicate:V_HW (vec_select:<non_vec>
             (match_operand:V_HW 1 "register_operand"  "")
             (parallel
              [(match_operand:QI 2 "immediate_operand" "")]))))]

"TARGET_VX")

; Vector scatter element

; vscef, vsceg

; A 64 bit target adress generated from 32 bit elements (define_insn "vec_scatter_elementv4si_DI" [(set (mem:SI

 (plus:DI (zero_extend:DI
       (unspec:SI [(match_operand:V4SI 1 "register_operand"  "v")
               (match_operand:DI   3 "immediate_operand" "I")]
              UNSPEC_VEC_EXTRACT))
      (match_operand:SI                2 "address_operand"  "ZQ")))
(unspec:SI [(match_operand:V4SI            0 "register_operand"  "v")
        (match_dup 3)] UNSPEC_VEC_EXTRACT))]

"TARGET_VX && TARGET_64BIT" "vscef\t%v0,%O2(%v1,%R2),%3" [(set_attr "op_type" "VRV")])

; A 31 bit target address is generated from 64 bit elements (define_insn "vec_scatter_element_SI" [(set (mem:

 (plus:SI (subreg:SI
       (unspec:<non_vec_int> [(match_operand:V_HW_64 1 "register_operand"  "v")
                  (match_operand:DI      3 "immediate_operand" "I")]
                 UNSPEC_VEC_EXTRACT) 4)
      (match_operand:SI                              2 "address_operand"  "ZQ")))
(unspec:<non_vec> [(match_operand:V_HW_64                0 "register_operand"  "v")
           (match_dup 3)] UNSPEC_VEC_EXTRACT))]

"TARGET_VX && !TARGET_64BIT" "vsce\t%v0,%O2(%v1,%R2),%3" [(set_attr "op_type" "VRV")])

; Element size and target adress size is the same (define_insn "vec_scatterelement" [(set (mem:

 (plus:<non_vec_int> (unspec:<non_vec_int>
              [(match_operand:<tointvec> 1 "register_operand"  "v")
               (match_operand:DI         3 "immediate_operand" "I")]
              UNSPEC_VEC_EXTRACT)
             (match_operand:DI           2 "address_operand"  "ZQ")))
(unspec:<non_vec> [(match_operand:V_HW_32_64     0 "register_operand"  "v")
           (match_dup 3)] UNSPEC_VEC_EXTRACT))]

"TARGET_VX" "vsce\t%v0,%O2(%v1,%R2),%3" [(set_attr "op_type" "VRV")])

; Depending on the address size we have to expand a different pattern. ; This however cannot be represented in s390-builtins.def so we do the ; multiplexing here in the expander. (define_expand "vec_scatter_element" [(match_operand:V_HW_32_64 0 "register_operand" "") (match_operand: 1 "register_operand" "") (match_operand 2 "address_operand" "") (match_operand:DI 3 "immediate_operand" "")] "TARGET_VX" { if (TARGET_64BIT)

{
  PUT_MODE (operands[2], DImode);
  emit_insn (
gen_vec_scatter_element<V_HW_32_64:mode>_DI (operands[0], operands[1],
                         operands[2], operands[3]));
}

else

{
  PUT_MODE (operands[2], SImode);
  emit_insn (
gen_vec_scatter_element<V_HW_32_64:mode>_SI (operands[0], operands[1],
                         operands[2], operands[3]));
}

DONE; })

; Vector select

; Operand 3 selects bits from either OP1 (0) or OP2 (1)

; Comparison operator should not matter as long as we always use the same ?!

; Operands 1 and 2 are swapped in order to match the altivec builtin. ; If operand 3 is a const_int bitmask this would be vec_merge (define_expand "vec_sel" [(set (match_operand:V_HW 0 "register_operand" "")

(if_then_else:V_HW
 (eq (match_operand:<tointvec> 3 "register_operand"  "")
     (match_dup 4))
 (match_operand:V_HW 2 "register_operand"  "")
 (match_operand:V_HW 1 "register_operand"  "")))]

"TARGET_VX" { operands[4] = CONST0_RTX (mode); })

; Vector sign extend to doubleword

; Sign extend of right most vector element to respective double-word (define_insn "vec_extend" [(set (match_operand:VI_HW_QHS 0 "register_operand" "=v")

(unspec:VI_HW_QHS [(match_operand:VI_HW_QHS 1 "register_operand"  "v")]
          UNSPEC_VEC_EXTEND))]

"TARGET_VX" "vseg\t%v0,%1" [(set_attr "op_type" "VRR")])

; Vector store with length

; Store bytes in OP1 from OP0 with the highest indexed byte to be ; stored from OP0 given by OP2 (define_insn "vstl" [(set (match_operand:BLK 2 "memory_operand" "=Q")

(unspec:BLK [(match_operand:V  0 "register_operand"  "v")
         (match_operand:SI 1 "register_operand"  "d")]
        UNSPEC_VEC_STORE_LEN))]

"TARGET_VX" "vstl\t%v0,%1,%2" [(set_attr "op_type" "VRS")])

; Vector unpack high

; vuphb, vuphh, vuphf (define_insn "vec_unpackh" [(set (match_operand: 0 "register_operand" "=v")

(unspec:<vec_double> [(match_operand:VI_HW_QHS 1 "register_operand"  "v")]
             UNSPEC_VEC_UNPACKH))]

"TARGET_VX" "vuph\t%v0,%v1" [(set_attr "op_type" "VRR")])

; vuplhb, vuplhh, vuplhf (define_insn "vec_unpackh_l" [(set (match_operand: 0 "register_operand" "=v")

(unspec:<vec_double> [(match_operand:VI_HW_QHS 1 "register_operand"  "v")]
             UNSPEC_VEC_UNPACKH_L))]

"TARGET_VX" "vuplh\t%v0,%v1" [(set_attr "op_type" "VRR")])

; Vector unpack low

; vuplb, vuplhw, vuplf (define_insn "vec_unpackl" [(set (match_operand: 0 "register_operand" "=v")

(unspec:<vec_double> [(match_operand:VI_HW_QHS 1 "register_operand"  "v")]
             UNSPEC_VEC_UNPACKL))]

"TARGET_VX" "vupl\t%v0,%v1" [(set_attr "op_type" "VRR")])

; vupllb, vupllh, vupllf (define_insn "vec_unpackl_l" [(set (match_operand: 0 "register_operand" "=v")

(unspec:<vec_double> [(match_operand:VI_HW_QHS 1 "register_operand"  "v")]
             UNSPEC_VEC_UNPACKL_L))]

"TARGET_VX" "vupll\t%v0,%v1" [(set_attr "op_type" "VRR")])

; Vector add

; vaq

; zvector builtins uses V16QI operands. So replace the modes in order ; to map this to a TImode add. We have to keep the V16QI mode ; operands in the expander in order to allow some operand type ; checking when expanding the builtin. (define_expand "vec_add_u128" [(match_operand:V16QI 0 "register_operand" "") (match_operand:V16QI 1 "register_operand" "") (match_operand:V16QI 2 "register_operand" "")] "TARGET_VX" { rtx op0 = gen_rtx_SUBREG (TImode, operands[0], 0); rtx op1 = gen_rtx_SUBREG (TImode, operands[1], 0); rtx op2 = gen_rtx_SUBREG (TImode, operands[2], 0);

emit_insn (gen_rtx_SET (VOIDmode, op0,

          gen_rtx_PLUS (TImode, op1, op2)));

DONE; })

; Vector add compute carry

(define_insn "vec_addc" [(set (match_operand:VI_HW 0 "register_operand" "=v")

(unspec:VI_HW [(match_operand:VI_HW 1 "register_operand"  "v")
           (match_operand:VI_HW 2 "register_operand"  "v")]
          UNSPEC_VEC_ADDC))]

"TARGET_VX" "vacc\t%v0,%v1,%v2" [(set_attr "op_type" "VRR")])

(define_insn "vec_addc_u128" [(set (match_operand:V16QI 0 "register_operand" "=v")

(unspec:V16QI [(match_operand:V16QI 1 "register_operand"  "v")
           (match_operand:V16QI 2 "register_operand"  "v")]
          UNSPEC_VEC_ADDC_U128))]

"TARGET_VX" "vaccq\t%v0,%v1,%v2" [(set_attr "op_type" "VRR")])

; Vector add with carry

(define_insn "vec_adde_u128" [(set (match_operand:V16QI 0 "register_operand" "=v")

(unspec:V16QI [(match_operand:V16QI 1 "register_operand"  "v")
           (match_operand:V16QI 2 "register_operand"  "v")
           (match_operand:V16QI 3 "register_operand"  "v")]
          UNSPEC_VEC_ADDE_U128))]

"TARGET_VX" "vacq\t%v0,%v1,%v2,%v3" [(set_attr "op_type" "VRR")])

; Vector add with carry compute carry

(define_insn "vec_addec_u128" [(set (match_operand:V16QI 0 "register_operand" "=v")

(unspec:V16QI [(match_operand:V16QI 1 "register_operand"  "v")
           (match_operand:V16QI 2 "register_operand"  "v")
           (match_operand:V16QI 3 "register_operand"  "v")]
          UNSPEC_VEC_ADDEC_U128))]

"TARGET_VX" "vacccq\t%v0,%v1,%v2,%v3" [(set_attr "op_type" "VRR")])

; Vector and

; The following two patterns allow mixed mode and's as required for the intrinsics. (define_insn "and_av2df3" [(set (match_operand:V2DF 0 "register_operand" "=v")

(and:V2DF (subreg:V2DF (match_operand:V2DI 1 "register_operand"  "v") 0)
      (match_operand:V2DF              2 "register_operand"  "v")))]

"TARGET_VX" "vn\t%v0,%v1,%v2" [(set_attr "op_type" "VRR")])

(define_insn "and_cv2df3" [(set (match_operand:V2DF 0 "register_operand" "=v")

(and:V2DF (match_operand:V2DF              1 "register_operand"  "v")
      (subreg:V2DF (match_operand:V2DI 2 "register_operand"  "v") 0)))]

"TARGET_VX" "vn\t%v0,%v1,%v2" [(set_attr "op_type" "VRR")])

; Vector and with complement

; vnc (define_insn "vec_andc3" [(set (match_operand:VT_HW 0 "register_operand" "=v")

(and:VT_HW (not:VT_HW (match_operand:VT_HW 2 "register_operand"  "v"))
      (match_operand:VT_HW             1 "register_operand"  "v")))]

"TARGET_VX" "vnc\t%v0,%v1,%v2" [(set_attr "op_type" "VRR")])

; The following two patterns allow mixed mode and's as required for the intrinsics. (define_insn "vec_andc_av2df3" [(set (match_operand:V2DF 0 "register_operand" "=v")

(and:V2DF (not:V2DF (match_operand:V2DF    2 "register_operand"  "v"))
      (subreg:V2DF (match_operand:V2DI 1 "register_operand"  "v") 0)))]

"TARGET_VX" "vnc\t%v0,%v1,%v2" [(set_attr "op_type" "VRR")])

(define_insn "vec_andc_cv2df3" [(set (match_operand:V2DF 0 "register_operand" "=v")

(and:V2DF (not:V2DF (subreg:V2DF (match_operand:V2DI 2 "register_operand" "v") 0))
      (match_operand:V2DF 1 "register_operand" "v")))]

"TARGET_VX" "vnc\t%v0,%v1,%v2" [(set_attr "op_type" "VRR")])

; Vector average

(define_insn "vec_avg" [(set (match_operand:VI_HW 0 "register_operand" "=v")

(unspec:VI_HW [(match_operand:VI_HW 1 "register_operand"  "v")
           (match_operand:VI_HW 2 "register_operand"  "v")]
          UNSPEC_VEC_AVG))]

"TARGET_VX" "vavg\t%v0,%v1,%v2" [(set_attr "op_type" "VRR")])

; Vector average logical

(define_insn "vec_avgu" [(set (match_operand:VI_HW 0 "register_operand" "=v")

(unspec:VI_HW [(match_operand:VI_HW 1 "register_operand"  "v")
           (match_operand:VI_HW 2 "register_operand"  "v")]
          UNSPEC_VEC_AVGU))]

"TARGET_VX" "vavgl\t%v0,%v1,%v2" [(set_attr "op_type" "VRR")])

; Vector checksum

(define_insn "vec_checksum" [(set (match_operand:V4SI 0 "register_operand" "=v")

(unspec:V4SI [(match_operand:V4SI 1 "register_operand"  "v")
          (match_operand:V4SI 2 "register_operand"  "v")]
         UNSPEC_VEC_CHECKSUM))]

"TARGET_VX" "vcksm\t%v0,%v1,%v2" [(set_attr "op_type" "VRR")])

;; ;; Vector compare ;;

; vec_all/any int compares

(define_expand "vecallintcmpcc:code" [(match_operand:SI 0 "register_operand" "") (intcmpcc (match_operand:VI_HW 1 "register_operand" "")

     (match_operand:VI_HW 2 "register_operand" ""))]

"TARGET_VX" { s390_expand_vec_compare_cc (operands[0],

              <intcmpcc:CODE>,
              operands[1],
              operands[2],
              true);

DONE; })

(define_expand "vecanyintcmpcc:code" [(match_operand:SI 0 "register_operand" "") (intcmpcc (match_operand:VI_HW 1 "register_operand" "")

     (match_operand:VI_HW 2 "register_operand" ""))]

"TARGET_VX" { s390_expand_vec_compare_cc (operands[0],

              <intcmpcc:CODE>,
              operands[1],
              operands[2],
              false);

DONE; })

; vec_all/any fp compares

(define_expand "vecallfpcmpcc:codev2df" [(match_operand:SI 0 "register_operand" "") (fpcmpcc (match_operand:V2DF 1 "register_operand" "")

    (match_operand:V2DF 2 "register_operand" ""))]

"TARGET_VX" { s390_expand_vec_compare_cc (operands[0],

              <fpcmpcc:CODE>,
              operands[1],
              operands[2],
              true);

DONE; })

(define_expand "vecanyfpcmpcc:codev2df" [(match_operand:SI 0 "register_operand" "") (fpcmpcc (match_operand:V2DF 1 "register_operand" "")

    (match_operand:V2DF 2 "register_operand" ""))]

"TARGET_VX" { s390_expand_vec_compare_cc (operands[0],

              <fpcmpcc:CODE>,
              operands[1],
              operands[2],
              false);

DONE; })

; Compare without generating CC

(define_expand "vec_cmpintcmp:code" [(set (match_operand:VI_HW 0 "register_operand" "=v")

(intcmp:VI_HW (match_operand:VI_HW 1 "register_operand"  "v")
          (match_operand:VI_HW 2 "register_operand"  "v")))]

"TARGET_VX" { s390_expand_vec_compare (operands[0], intcmp:CODE, operands[1], operands[2]); DONE; })

(define_expand "vec_cmpfpcmp:codev2df" [(set (match_operand:V2DI 0 "register_operand" "=v")

(fpcmp:V2DI (match_operand:V2DF 1 "register_operand"  "v")
        (match_operand:V2DF 2 "register_operand"  "v")))]

"TARGET_VX" { s390_expand_vec_compare (operands[0], fpcmp:CODE, operands[1], operands[2]); DONE; })

; Vector count leading zeros

; vec_cntlz -> clz ; vec_cnttz -> ctz

; Vector xor

; vec_xor -> xor

; The following two patterns allow mixed mode xor's as required for the intrinsics. (define_insn "xor_av2df3" [(set (match_operand:V2DF 0 "register_operand" "=v")

(xor:V2DF (subreg:V2DF (match_operand:V2DI 1 "register_operand" "v") 0)
      (match_operand:V2DF 2 "register_operand" "v")))]

"TARGET_VX" "vx\t%v0,%v1,%v2" [(set_attr "op_type" "VRR")])

(define_insn "xor_cv2df3" [(set (match_operand:V2DF 0 "register_operand" "=v")

(xor:V2DF (match_operand:V2DF 1 "register_operand" "v")
      (subreg:V2DF (match_operand:V2DI 2 "register_operand" "v") 0)))]

"TARGET_VX" "vx\t%v0,%v1,%v2" [(set_attr "op_type" "VRR")])

; Vector Galois field multiply sum

(define_insn "vec_gfmsum" [(set (match_operand:VI_HW_QHS 0 "register_operand" "=v")

(unspec:VI_HW_QHS [(match_operand:VI_HW_QHS 1 "register_operand" "v")
           (match_operand:VI_HW_QHS 2 "register_operand" "v")]
          UNSPEC_VEC_GFMSUM))]

"TARGET_VX" "vgfm\t%v0,%v1,%v2" [(set_attr "op_type" "VRR")])

(define_insn "vec_gfmsum_128" [(set (match_operand:V16QI 0 "register_operand" "=v")

(unspec:V16QI [(match_operand:V2DI 1 "register_operand" "v")
           (match_operand:V2DI 2 "register_operand" "v")]
          UNSPEC_VEC_GFMSUM_128))]

"TARGET_VX" "vgfmg\t%v0,%v1,%v2" [(set_attr "op_type" "VRR")])

(define_insn "vec_gfmsum_accum" [(set (match_operand: 0 "register_operand" "=v")

(unspec:<vec_double> [(match_operand:VI_HW_QHS 1 "register_operand" "v")
              (match_operand:VI_HW_QHS 2 "register_operand" "v")
              (match_operand:<vec_double> 3 "register_operand" "v")]
             UNSPEC_VEC_GFMSUM_ACCUM))]

"TARGET_VX" "vgfma\t%v0,%v1,%v2,%v3" [(set_attr "op_type" "VRR")])

(define_insn "vec_gfmsum_accum_128" [(set (match_operand:V16QI 0 "register_operand" "=v")

(unspec:V16QI [(match_operand:V2DI 1 "register_operand" "v")
           (match_operand:V2DI 2 "register_operand" "v")
           (match_operand:V16QI 3 "register_operand" "v")]
          UNSPEC_VEC_GFMSUM_ACCUM_128))]

"TARGET_VX" "vgfmag\t%v0,%v1,%v2,%v3" [(set_attr "op_type" "VRR")])

; FIXME: vec_neg ?

; Vector load positive: vec_abs -> abs ; Vector maximum vec_max -> smax, logical vec_max -> umax ; Vector maximum vec_min -> smin, logical vec_min -> umin

; Vector multiply and add high

; vec_mladd -> vec_vmal ; vmalb, vmalh, vmalf, vmalg (define_insn "vec_vmal" [(set (match_operand:VI_HW 0 "register_operand" "=v")

(unspec:VI_HW [(match_operand:VI_HW 1 "register_operand" "v")
           (match_operand:VI_HW 2 "register_operand" "v")
           (match_operand:VI_HW 3 "register_operand" "v")]
          UNSPEC_VEC_VMAL))]

"TARGET_VX" "vmal\t%v0,%v1,%v2,%v3" [(set_attr "op_type" "VRR")])

; vec_mhadd -> vec_vmah/vec_vmalh

; vmahb; vmahh, vmahf, vmahg (define_insn "vec_vmah" [(set (match_operand:VI_HW 0 "register_operand" "=v")

(unspec:VI_HW [(match_operand:VI_HW 1 "register_operand" "v")
           (match_operand:VI_HW 2 "register_operand" "v")
           (match_operand:VI_HW 3 "register_operand" "v")]
          UNSPEC_VEC_VMAH))]

"TARGET_VX" "vmah\t%v0,%v1,%v2,%v3" [(set_attr "op_type" "VRR")])

; vmalhb; vmalhh, vmalhf, vmalhg (define_insn "vec_vmalh" [(set (match_operand:VI_HW 0 "register_operand" "=v")

(unspec:VI_HW [(match_operand:VI_HW 1 "register_operand" "v")
           (match_operand:VI_HW 2 "register_operand" "v")
           (match_operand:VI_HW 3 "register_operand" "v")]
          UNSPEC_VEC_VMALH))]

"TARGET_VX" "vmalh\t%v0,%v1,%v2,%v3" [(set_attr "op_type" "VRR")])

; vec_meadd -> vec_vmae/vec_vmale

; vmaeb; vmaeh, vmaef, vmaeg (define_insn "vec_vmae" [(set (match_operand: 0 "register_operand" "=v")

(unspec:<vec_double> [(match_operand:VI_HW_QHS 1 "register_operand" "v")
              (match_operand:VI_HW_QHS 2 "register_operand" "v")
              (match_operand:<vec_double> 3 "register_operand" "v")]
             UNSPEC_VEC_VMAE))]

"TARGET_VX" "vmae\t%v0,%v1,%v2,%v3" [(set_attr "op_type" "VRR")])

; vmaleb; vmaleh, vmalef, vmaleg (define_insn "vec_vmale" [(set (match_operand: 0 "register_operand" "=v")

(unspec:<vec_double> [(match_operand:VI_HW_QHS 1 "register_operand" "v")
              (match_operand:VI_HW_QHS 2 "register_operand" "v")
              (match_operand:<vec_double> 3 "register_operand" "v")]
             UNSPEC_VEC_VMALE))]

"TARGET_VX" "vmale\t%v0,%v1,%v2,%v3" [(set_attr "op_type" "VRR")])

; vec_moadd -> vec_vmao/vec_vmalo

; vmaob; vmaoh, vmaof, vmaog (define_insn "vec_vmao" [(set (match_operand: 0 "register_operand" "=v")

(unspec:<vec_double> [(match_operand:VI_HW_QHS 1 "register_operand" "v")
              (match_operand:VI_HW_QHS 2 "register_operand" "v")
              (match_operand:<vec_double> 3 "register_operand" "v")]
             UNSPEC_VEC_VMAO))]

"TARGET_VX" "vmao\t%v0,%v1,%v2,%v3" [(set_attr "op_type" "VRR")])

; vmalob; vmaloh, vmalof, vmalog (define_insn "vec_vmalo" [(set (match_operand: 0 "register_operand" "=v")

(unspec:<vec_double> [(match_operand:VI_HW_QHS 1 "register_operand" "v")
              (match_operand:VI_HW_QHS 2 "register_operand" "v")
              (match_operand:<vec_double> 3 "register_operand" "v")]
             UNSPEC_VEC_VMALO))]

"TARGET_VX" "vmalo\t%v0,%v1,%v2,%v3" [(set_attr "op_type" "VRR")])

; Vector multiply high

; vec_mulh -> vec_smulh/vec_umulh

; vmhb, vmhh, vmhf (define_insn "vec_smulh" [(set (match_operand:VI_HW_QHS 0 "register_operand" "=v")

(unspec:VI_HW_QHS [(match_operand:VI_HW_QHS 1 "register_operand" "v")
           (match_operand:VI_HW_QHS 2 "register_operand" "v")]
          UNSPEC_VEC_SMULT_HI))]

"TARGET_VX" "vmh\t%v0,%v1,%v2" [(set_attr "op_type" "VRR")])

; vmlhb, vmlhh, vmlhf (define_insn "vec_umulh" [(set (match_operand:VI_HW_QHS 0 "register_operand" "=v")

(unspec:VI_HW_QHS [(match_operand:VI_HW_QHS 1 "register_operand" "v")
           (match_operand:VI_HW_QHS 2 "register_operand" "v")]
          UNSPEC_VEC_UMULT_HI))]

"TARGET_VX" "vmlh\t%v0,%v1,%v2" [(set_attr "op_type" "VRR")])

; Vector multiply low

; vec_mule -> vec_widen_umult_even/vec_widen_smult_even ; vec_mulo -> vec_widen_umult_odd/vec_widen_smult_odd

; Vector nor

(define_insn "vec_nor3" [(set (match_operand:VT_HW 0 "register_operand" "=v")

(not:VT_HW (ior:VT_HW (match_operand:VT_HW 1 "register_operand" "v")
              (match_operand:VT_HW 2 "register_operand" "v"))))]

"TARGET_VX" "vno\t%v0,%v1,%v2" [(set_attr "op_type" "VRR")])

; The following two patterns allow mixed mode and's as required for the intrinsics. (define_insn "vec_nor_av2df3" [(set (match_operand:V2DF 0 "register_operand" "=v")

(not:V2DF (ior:V2DF (subreg:V2DF (match_operand:V2DI 1 "register_operand" "v") 0)
            (match_operand:V2DF 2 "register_operand" "v"))))]

"TARGET_VX" "vno\t%v0,%v1,%v2" [(set_attr "op_type" "VRR")])

(define_insn "vec_nor_cv2df3" [(set (match_operand:V2DF 0 "register_operand" "=v")

(not:V2DF (ior:V2DF (match_operand:V2DF 1 "register_operand" "v")
            (subreg:V2DF (match_operand:V2DI 2 "register_operand" "v") 0))))]

"TARGET_VX" "vno\t%v0,%v1,%v2" [(set_attr "op_type" "VRR")])

; Vector or

; The following two patterns allow mixed mode or's as required for the intrinsics. (define_insn "ior_av2df3" [(set (match_operand:V2DF 0 "register_operand" "=v")

(ior:V2DF (subreg:V2DF (match_operand:V2DI 1 "register_operand" "v") 0)
      (match_operand:V2DF 2 "register_operand" "v")))]

"TARGET_VX" "vo\t%v0,%v1,%v2" [(set_attr "op_type" "VRR")])

(define_insn "ior_cv2df3" [(set (match_operand:V2DF 0 "register_operand" "=v")

(ior:V2DF (match_operand:V2DF 1 "register_operand" "v")
      (subreg:V2DF (match_operand:V2DI 2 "register_operand" "v") 0)))]

"TARGET_VX" "vo\t%v0,%v1,%v2" [(set_attr "op_type" "VRR")])

; Vector population count vec_popcnt -> popcount ; Vector element rotate left logical vec_rl -> vrotl, vec_rli -> rot

; Vector element rotate and insert under mask

; verimb, verimh, verimf, verimg (define_insn "verim" [(set (match_operand:VI_HW 0 "register_operand" "=v")

(unspec:VI_HW [(match_operand:VI_HW 1 "register_operand"  "0")
           (match_operand:VI_HW 2 "register_operand"  "v")
           (match_operand:VI_HW 3 "register_operand"  "v")
           (match_operand:SI    4 "immediate_operand" "I")]
          UNSPEC_VEC_RL_MASK))]

"TARGET_VX" "verim\t%v0,%v2,%v3,%b4" [(set_attr "op_type" "VRI")])

; Vector shift left

(define_insn "vec_sll" [(set (match_operand:VI_HW 0 "register_operand" "=v")

(unspec:VI_HW [(match_operand:VI_HW     1 "register_operand"  "v")
           (match_operand:VI_HW_QHS 2 "register_operand"  "v")]
          UNSPEC_VEC_SLL))]

"TARGET_VX" "vsl\t%v0,%v1,%v2" [(set_attr "op_type" "VRR")])

; Vector shift left by byte

(define_insn "vec_slb" [(set (match_operand:V_HW 0 "register_operand" "=v")

(unspec:V_HW [(match_operand:V_HW 1 "register_operand"       "v")
          (match_operand:<tointvec> 2 "register_operand" "v")]
         UNSPEC_VEC_SLB))]

"TARGET_VX" "vslb\t%v0,%v1,%v2" [(set_attr "op_type" "VRR")])

; Vector shift left double by byte

(define_insn "vec_sld" [(set (match_operand:V_HW 0 "register_operand" "=v")

(unspec:V_HW [(match_operand:V_HW 1 "register_operand" "v")
          (match_operand:V_HW 2 "register_operand" "v")
          (match_operand:DI 3 "immediate_operand" "C")]
         UNSPEC_VEC_SLDB))]

"TARGET_VX" "vsldb\t%v0,%v1,%v2,%b3" [(set_attr "op_type" "VRI")])

(define_expand "vec_sldw" [(set (match_operand:V_HW 0 "register_operand" "")

(unspec:V_HW [(match_operand:V_HW 1 "register_operand" "")
          (match_operand:V_HW 2 "register_operand" "")
          (match_operand:DI 3 "immediate_operand"  "")]
         UNSPEC_VEC_SLDB))]

"TARGET_VX" { operands[3] = GEN_INT (INTVAL (operands[3]) << 2); })

; Vector shift right arithmetic

(define_insn "vec_sral" [(set (match_operand:VI_HW 0 "register_operand" "=v")

(unspec:VI_HW [(match_operand:VI_HW     1 "register_operand"  "v")
           (match_operand:VI_HW_QHS 2 "register_operand"  "v")]
          UNSPEC_VEC_SRAL))]

"TARGET_VX" "vsra\t%v0,%v1,%v2" [(set_attr "op_type" "VRR")])

; Vector shift right arithmetic by byte

(define_insn "vec_srab" [(set (match_operand:V_HW 0 "register_operand" "=v")

(unspec:V_HW [(match_operand:V_HW 1 "register_operand"       "v")
          (match_operand:<tointvec> 2 "register_operand" "v")]
         UNSPEC_VEC_SRAB))]

"TARGET_VX" "vsrab\t%v0,%v1,%v2" [(set_attr "op_type" "VRR")])

; Vector shift right logical

(define_insn "vec_srl" [(set (match_operand:VI_HW 0 "register_operand" "=v")

(unspec:VI_HW [(match_operand:VI_HW     1 "register_operand"  "v")
           (match_operand:VI_HW_QHS 2 "register_operand"  "v")]
          UNSPEC_VEC_SRL))]

"TARGET_VX" "vsrl\t%v0,%v1,%v2" [(set_attr "op_type" "VRR")])

; Vector shift right logical by byte

; Pattern definition in vector.md (define_expand "vec_srb" [(set (match_operand:V_HW 0 "register_operand" "")

(unspec:V_HW [(match_operand:V_HW 1 "register_operand"       "")
          (match_operand:<tointvec> 2 "register_operand" "")]
         UNSPEC_VEC_SRLB))]

"TARGET_VX")

; Vector subtract

(define_insn "vec_sub_u128" [(set (match_operand:V16QI 0 "register_operand" "=v")

(unspec:V16QI [(match_operand:V16QI 1 "register_operand" "v")
           (match_operand:V16QI 2 "register_operand" "v")]
         UNSPEC_VEC_SUB_U128))]

"TARGET_VX" "vsq\t%v0,%v1,%v2" [(set_attr "op_type" "VRR")])

; Vector subtract compute borrow indication

(define_insn "vec_subc" [(set (match_operand:VI_HW 0 "register_operand" "=v")

(unspec:VI_HW [(match_operand:VI_HW 1 "register_operand" "v")
           (match_operand:VI_HW 2 "register_operand" "v")]
          UNSPEC_VEC_SUBC))]

"TARGET_VX" "vscbi\t%v0,%v1,%v2" [(set_attr "op_type" "VRR")])

(define_insn "vec_subc_u128" [(set (match_operand:V16QI 0 "register_operand" "=v")

(unspec:V16QI [(match_operand:V16QI 1 "register_operand" "v")
           (match_operand:V16QI 2 "register_operand" "v")]
         UNSPEC_VEC_SUBC_U128))]

"TARGET_VX" "vscbiq\t%v0,%v1,%v2" [(set_attr "op_type" "VRR")])

; Vector subtract with borrow indication

(define_insn "vec_sube_u128" [(set (match_operand:V16QI 0 "register_operand" "=v")

(unspec:V16QI [(match_operand:V16QI 1 "register_operand" "v")
           (match_operand:V16QI 2 "register_operand" "v")
           (match_operand:V16QI 3 "register_operand" "v")]
          UNSPEC_VEC_SUBE_U128))]

"TARGET_VX" "vsbiq\t%v0,%v1,%v2,%v3" [(set_attr "op_type" "VRR")])

; Vector subtract with borrow compute and borrow indication

(define_insn "vec_subec_u128" [(set (match_operand:V16QI 0 "register_operand" "=v")

(unspec:V16QI [(match_operand:V16QI 1 "register_operand" "v")
           (match_operand:V16QI 2 "register_operand" "v")
           (match_operand:V16QI 3 "register_operand" "v")]
          UNSPEC_VEC_SUBEC_U128))]

"TARGET_VX" "vsbcbiq\t%v0,%v1,%v2,%v3" [(set_attr "op_type" "VRR")])

; Vector sum across

; Sum across DImode parts of the 1st operand and add the rightmost ; element of 2nd operand ; vsumgh, vsumgf (define_expand "vec_sum2" [(set (match_operand:V2DI 0 "register_operand" "")

(unspec:V2DI [(match_operand:VI_HW_HS 1 "register_operand" "")
          (match_operand:VI_HW_HS 2 "register_operand" "")]
         UNSPEC_VEC_VSUMG))]

"TARGET_VX")

; vsumqh, vsumqf (define_insn "vec_sum_u128" [(set (match_operand:V2DI 0 "register_operand" "=v")

(unspec:V2DI [(match_operand:VI_HW_SD 1 "register_operand" "v")
          (match_operand:VI_HW_SD 2 "register_operand" "v")]
         UNSPEC_VEC_VSUMQ))]

"TARGET_VX" "vsumq\t%v0,%v1,%v2" [(set_attr "op_type" "VRR")])

; vsumb, vsumh (define_expand "vec_sum4" [(set (match_operand:V4SI 0 "register_operand" "")

(unspec:V4SI [(match_operand:VI_HW_QH 1 "register_operand" "")
          (match_operand:VI_HW_QH 2 "register_operand" "")]
         UNSPEC_VEC_VSUM))]

"TARGET_VX")

; Vector test under mask

(define_expand "vec_test_mask_int" [(set (reg:CCRAW CC_REGNUM)

(unspec:CCRAW [(match_operand:V_HW 1 "register_operand" "")
           (match_operand:<tointvec> 2 "register_operand" "")]
          UNSPEC_VEC_TEST_MASK))

(set (match_operand:SI 0 "register_operand" "")

(unspec:SI [(reg:CCRAW CC_REGNUM)] UNSPEC_CC_TO_INT))]

"TARGET_VX")

(define_insn "*vec_test_mask" [(set (reg:CCRAW CC_REGNUM)

(unspec:CCRAW [(match_operand:V_HW 0 "register_operand" "v")
           (match_operand:<tointvec> 1 "register_operand" "v")]
          UNSPEC_VEC_TEST_MASK))]

"TARGET_VX" "vtm\t%v0,%v1" [(set_attr "op_type" "VRR")])

; Vector find any element equal

; vfaeb, vfaeh, vfaef ; vfaezb, vfaezh, vfaezf (define_insn "vfae" [(set (match_operand:VI_HW_QHS 0 "register_operand" "=v")

(unspec:VI_HW_QHS [(match_operand:VI_HW_QHS 1 "register_operand" "v")
           (match_operand:VI_HW_QHS 2 "register_operand" "v")
           (match_operand:SI        3 "immediate_operand" "C")]
          UNSPEC_VEC_VFAE))]

"TARGET_VX" { unsigned HOST_WIDE_INT flags = INTVAL (operands[3]);

if (flags & VSTRING_FLAG_ZS)

{
  flags &= ~VSTRING_FLAG_ZS;
  operands[3] = GEN_INT (flags);
  return "vfaez<bhfgq>\t%v0,%v1,%v2,%b3";
}

return "vfae\t%v0,%v1,%v2,%b3"; } [(set_attr "op_type" "VRR")])

; vfaebs, vfaehs, vfaefs ; vfaezbs, vfaezhs, vfaezfs (define_insn "*vfaes" [(set (match_operand:VI_HW_QHS 0 "register_operand" "=v")

(unspec:VI_HW_QHS [(match_operand:VI_HW_QHS 1 "register_operand" "v")
           (match_operand:VI_HW_QHS 2 "register_operand" "v")
           (match_operand:SI        3 "immediate_operand" "C")]
          UNSPEC_VEC_VFAE))

(set (reg:CCRAW CC_REGNUM)

(unspec:CCRAW [(match_dup 1)
           (match_dup 2)
           (match_dup 3)]
          UNSPEC_VEC_VFAECC))]

"TARGET_VX" { unsigned HOST_WIDE_INT flags = INTVAL (operands[3]);

if (flags & VSTRING_FLAG_ZS)

{
  flags &= ~VSTRING_FLAG_ZS;
  operands[3] = GEN_INT (flags);
  return "vfaez<bhfgq>s\t%v0,%v1,%v2,%b3";
}

return "vfaes\t%v0,%v1,%v2,%b3"; } [(set_attr "op_type" "VRR")])

(define_expand "vfaez" [(set (match_operand:VI_HW_QHS 0 "register_operand" "=v")

(unspec:VI_HW_QHS [(match_operand:VI_HW_QHS 1 "register_operand" "v")
           (match_operand:VI_HW_QHS 2 "register_operand" "v")
           (match_operand:SI        3 "immediate_operand" "C")]
          UNSPEC_VEC_VFAE))]

"TARGET_VX" { operands[3] = GEN_INT (INTVAL (operands[3]) | VSTRING_FLAG_ZS); })

(define_expand "vfaes" [(parallel

[(set (match_operand:VI_HW_QHS 0 "register_operand" "")
(unspec:VI_HW_QHS [(match_operand:VI_HW_QHS 1 "register_operand" "")
           (match_operand:VI_HW_QHS 2 "register_operand" "")
           (match_operand:SI        3 "immediate_operand" "C")]
          UNSPEC_VEC_VFAE))

(set (reg:CCRAW CC_REGNUM)

(unspec:CCRAW [(match_dup 1)
           (match_dup 2)
           (match_dup 3)]
          UNSPEC_VEC_VFAECC))])

(set (match_operand:SI 4 "memory_operand" "")

(unspec:SI [(reg:CCRAW CC_REGNUM)] UNSPEC_CC_TO_INT))]

"TARGET_VX" { operands[3] = GEN_INT (INTVAL (operands[3]) | VSTRING_FLAG_CS); })

(define_expand "vfaezs" [(parallel

[(set (match_operand:VI_HW_QHS 0 "register_operand" "")
(unspec:VI_HW_QHS [(match_operand:VI_HW_QHS 1 "register_operand" "")
           (match_operand:VI_HW_QHS 2 "register_operand" "")
           (match_operand:SI        3 "immediate_operand" "C")]
          UNSPEC_VEC_VFAE))

(set (reg:CCRAW CC_REGNUM)

(unspec:CCRAW [(match_dup 1)
           (match_dup 2)
           (match_dup 3)]
          UNSPEC_VEC_VFAECC))])

(set (match_operand:SI 4 "memory_operand" "")

(unspec:SI [(reg:CCRAW CC_REGNUM)] UNSPEC_CC_TO_INT))]

"TARGET_VX" { operands[3] = GEN_INT (INTVAL (operands[3]) | VSTRING_FLAG_CS | VSTRING_FLAG_ZS); })

; Vector find element equal

; vfeebs, vfeehs, vfeefs ; vfeezbs, vfeezhs, vfeezfs (define_insn "*vfees" [(set (match_operand:VI_HW_QHS 0 "register_operand" "=v")

(unspec:VI_HW_QHS [(match_operand:VI_HW_QHS 1 "register_operand" "v")
           (match_operand:VI_HW_QHS 2 "register_operand" "v")
           (match_operand:QI 3 "immediate_operand" "C")]
          UNSPEC_VEC_VFEE))

(set (reg:CCRAW CC_REGNUM)

(unspec:CCRAW [(match_dup 1)
           (match_dup 2)
           (match_dup 3)]
          UNSPEC_VEC_VFEECC))]

"TARGET_VX" { unsigned HOST_WIDE_INT flags = INTVAL (operands[3]);

gcc_assert (!(flags & ~(VSTRING_FLAG_ZS | VSTRING_FLAG_CS))); flags &= ~VSTRING_FLAG_CS;

if (flags == VSTRING_FLAG_ZS)

return "vfeez<bhfgq>s\t%v0,%v1,%v2";

return "vfees\t%v0,%v1,%v2,%b3"; } [(set_attr "op_type" "VRR")])

; vfeeb, vfeeh, vfeef (define_insn "vfee" [(set (match_operand:VI_HW_QHS 0 "register_operand" "")

(unspec:VI_HW_QHS [(match_operand:VI_HW_QHS 1 "register_operand" "")
           (match_operand:VI_HW_QHS 2 "register_operand" "")
           (const_int 0)]
          UNSPEC_VEC_VFEE))]

"TARGET_VX" "vfee\t%v0,%v1,%v2,0" [(set_attr "op_type" "VRR")])

; vfeezb, vfeezh, vfeezf (define_insn "vfeez" [(set (match_operand:VI_HW_QHS 0 "register_operand" "")

(unspec:VI_HW_QHS [(match_operand:VI_HW_QHS 1 "register_operand" "")
           (match_operand:VI_HW_QHS 2 "register_operand" "")
           (const_int VSTRING_FLAG_ZS)]
          UNSPEC_VEC_VFEE))]

"TARGET_VX" "vfeezs\t%v0,%v1,%v2,2" [(set_attr "op_type" "VRR")])

(define_expand "vfees" [(parallel

[(set (match_operand:VI_HW_QHS                    0 "register_operand" "")
  (unspec:VI_HW_QHS [(match_operand:VI_HW_QHS 1 "register_operand" "")
             (match_operand:VI_HW_QHS 2 "register_operand" "")
             (const_int VSTRING_FLAG_CS)]
            UNSPEC_VEC_VFEE))

(set (reg:CCRAW CC_REGNUM)

(unspec:CCRAW [(match_dup 1)
           (match_dup 2)
           (const_int VSTRING_FLAG_CS)]
          UNSPEC_VEC_VFEECC))])

(set (match_operand:SI 3 "memory_operand" "")

(unspec:SI [(reg:CCRAW CC_REGNUM)] UNSPEC_CC_TO_INT))]

"TARGET_VX")

(define_expand "vfeezs" [(parallel

[(set (match_operand:VI_HW_QHS                    0 "register_operand" "")
  (unspec:VI_HW_QHS [(match_operand:VI_HW_QHS 1 "register_operand" "")
             (match_operand:VI_HW_QHS 2 "register_operand" "")
             (match_dup 4)]
            UNSPEC_VEC_VFEE))

(set (reg:CCRAW CC_REGNUM)

(unspec:CCRAW [(match_dup 1)
           (match_dup 2)
           (match_dup 4)]
          UNSPEC_VEC_VFEECC))])

(set (match_operand:SI 3 "memory_operand" "")

(unspec:SI [(reg:CCRAW CC_REGNUM)] UNSPEC_CC_TO_INT))]

"TARGET_VX" { operands[4] = GEN_INT (VSTRING_FLAG_ZS | VSTRING_FLAG_CS); })

; Vector find element not equal

; vfeneb, vfeneh, vfenef (define_insn "vfene" [(set (match_operand:VI_HW_QHS 0 "register_operand" "=v")

(unspec:VI_HW_QHS [(match_operand:VI_HW_QHS 1 "register_operand"  "v")
           (match_operand:VI_HW_QHS 2 "register_operand"  "v")
           (const_int 0)]
          UNSPEC_VEC_VFENE))]

"TARGET_VX" "vfene\t%v0,%v1,%v2,0" [(set_attr "op_type" "VRR")])

; vec_vfenes can be found in vector.md since it is used for strlen

; vfenezb, vfenezh, vfenezf (define_insn "vfenez" [(set (match_operand:VI_HW_QHS 0 "register_operand" "")

(unspec:VI_HW_QHS [(match_operand:VI_HW_QHS 1 "register_operand" "")
           (match_operand:VI_HW_QHS 2 "register_operand" "")
           (const_int VSTRING_FLAG_ZS)]
          UNSPEC_VEC_VFENE))]

"TARGET_VX" "vfenez\t%v0,%v1,%v2" [(set_attr "op_type" "VRR")])

(define_expand "vfenes" [(parallel

[(set (match_operand:VI_HW_QHS                    0 "register_operand" "")
  (unspec:VI_HW_QHS [(match_operand:VI_HW_QHS 1 "register_operand" "")
             (match_operand:VI_HW_QHS 2 "register_operand" "")
             (const_int VSTRING_FLAG_CS)]
            UNSPEC_VEC_VFENE))

(set (reg:CCRAW CC_REGNUM)

(unspec:CCRAW [(match_dup 1)
           (match_dup 2)
           (const_int VSTRING_FLAG_CS)]
          UNSPEC_VEC_VFENECC))])

(set (match_operand:SI 3 "memory_operand" "")

(unspec:SI [(reg:CCRAW CC_REGNUM)] UNSPEC_CC_TO_INT))]

"TARGET_VX")

(define_expand "vfenezs" [(parallel

[(set (match_operand:VI_HW_QHS                    0 "register_operand" "")
  (unspec:VI_HW_QHS [(match_operand:VI_HW_QHS 1 "register_operand" "")
             (match_operand:VI_HW_QHS 2 "register_operand" "")
             (match_dup 4)]
            UNSPEC_VEC_VFENE))
 (set (reg:CCRAW CC_REGNUM)
  (unspec:CCRAW [(match_dup 1)
         (match_dup 2)
         (match_dup 4)]
        UNSPEC_VEC_VFENECC))])

(set (match_operand:SI 3 "memory_operand" "")

(unspec:SI [(reg:CCRAW CC_REGNUM)] UNSPEC_CC_TO_INT))]

"TARGET_VX" { operands[4] = GEN_INT (VSTRING_FLAG_ZS | VSTRING_FLAG_CS); })

; Vector isolate string

; vistrb, vistrh, vistrf (define_insn "vistr" [(set (match_operand:VI_HW_QHS 0 "register_operand" "=v")

(unspec:VI_HW_QHS [(match_operand:VI_HW_QHS 1 "register_operand" "v")]
          UNSPEC_VEC_VISTR))]

"TARGET_VX" "vistr\t%v0,%v1" [(set_attr "op_type" "VRR")])

; vistrbs, vistrhs, vistrfs (define_insn "*vistrs" [(set (match_operand:VI_HW_QHS 0 "register_operand" "=v")

(unspec:VI_HW_QHS [(match_operand:VI_HW_QHS 1 "register_operand" "v")]
          UNSPEC_VEC_VISTR))

(set (reg:CCRAW CC_REGNUM)

(unspec:CCRAW [(match_dup 1)] UNSPEC_VEC_VISTRCC))]

"TARGET_VX" "vistrs\t%v0,%v1" [(set_attr "op_type" "VRR")])

(define_expand "vistrs" [(parallel

[(set (match_operand:VI_HW_QHS                    0 "register_operand" "")
  (unspec:VI_HW_QHS [(match_operand:VI_HW_QHS 1 "register_operand" "")]
            UNSPEC_VEC_VISTR))
 (set (reg:CCRAW CC_REGNUM)
  (unspec:CCRAW [(match_dup 1)]
        UNSPEC_VEC_VISTRCC))])

(set (match_operand:SI 2 "memory_operand" "")

(unspec:SI [(reg:CCRAW CC_REGNUM)] UNSPEC_CC_TO_INT))]

"TARGET_VX")

; Vector compare range

; vstrcb, vstrch, vstrcf ; vstrczb, vstrczh, vstrczf (define_insn "vstrc" [(set (match_operand:VI_HW_QHS 0 "register_operand" "=v")

(unspec:VI_HW_QHS [(match_operand:VI_HW_QHS 1 "register_operand"  "v")
           (match_operand:VI_HW_QHS 2 "register_operand"  "v")
           (match_operand:VI_HW_QHS 3 "register_operand"  "v")
           (match_operand:SI        4 "immediate_operand" "C")]
          UNSPEC_VEC_VSTRC))]

"TARGET_VX" { unsigned HOST_WIDE_INT flags = INTVAL (operands[4]);

if (flags & VSTRING_FLAG_ZS)

{
  flags &= ~VSTRING_FLAG_ZS;
  operands[4] = GEN_INT (flags);
  return "vstrcz<bhfgq>\t%v0,%v1,%v2,%v3,%b4";
}

return "vstrc\t%v0,%v1,%v2,%v3,%b4"; } [(set_attr "op_type" "VRR")])

; vstrcbs, vstrchs, vstrcfs ; vstrczbs, vstrczhs, vstrczfs (define_insn "*vstrcs" [(set (match_operand:VI_HW_QHS 0 "register_operand" "=v")

(unspec:VI_HW_QHS [(match_operand:VI_HW_QHS 1 "register_operand"  "v")
           (match_operand:VI_HW_QHS 2 "register_operand"  "v")
           (match_operand:VI_HW_QHS 3 "register_operand"  "v")
           (match_operand:SI        4 "immediate_operand" "C")]
          UNSPEC_VEC_VSTRC))

(set (reg:CCRAW CC_REGNUM)

(unspec:CCRAW [(match_dup 1)
           (match_dup 2)
           (match_dup 3)
           (match_dup 4)]
          UNSPEC_VEC_VSTRCCC))]

"TARGET_VX" { unsigned HOST_WIDE_INT flags = INTVAL (operands[4]);

if (flags & VSTRING_FLAG_ZS)

{
  flags &= ~VSTRING_FLAG_ZS;
  operands[4] = GEN_INT (flags);
  return "vstrcz<bhfgq>s\t%v0,%v1,%v2,%v3,%b4";
}

return "vstrcs\t%v0,%v1,%v2,%v3,%b4"; } [(set_attr "op_type" "VRR")])

(define_expand "vstrcz" [(set (match_operand:VI_HW_QHS 0 "register_operand" "=v")

(unspec:VI_HW_QHS [(match_operand:VI_HW_QHS 1 "register_operand" "v")
           (match_operand:VI_HW_QHS 2 "register_operand" "v")
           (match_operand:VI_HW_QHS 3 "register_operand" "v")
           (match_operand:SI        4 "immediate_operand" "C")]
          UNSPEC_VEC_VSTRC))]

"TARGET_VX" { operands[4] = GEN_INT (INTVAL (operands[4]) | VSTRING_FLAG_ZS); })

(define_expand "vstrcs" [(parallel

[(set (match_operand:VI_HW_QHS 0 "register_operand" "")
(unspec:VI_HW_QHS [(match_operand:VI_HW_QHS 1 "register_operand" "")
           (match_operand:VI_HW_QHS 2 "register_operand" "")
           (match_operand:VI_HW_QHS 3 "register_operand" "")
           (match_operand:SI        4 "immediate_operand" "C")]
          UNSPEC_VEC_VSTRC))

(set (reg:CCRAW CC_REGNUM)

(unspec:CCRAW [(match_dup 1)
           (match_dup 2)
           (match_dup 3)
           (match_dup 4)]
          UNSPEC_VEC_VSTRCCC))])

(set (match_operand:SI 5 "memory_operand" "")

(unspec:SI [(reg:CCRAW CC_REGNUM)] UNSPEC_CC_TO_INT))]

"TARGET_VX" { operands[4] = GEN_INT (INTVAL (operands[4]) | VSTRING_FLAG_CS); })

(define_expand "vstrczs" [(parallel

[(set (match_operand:VI_HW_QHS 0 "register_operand" "")
(unspec:VI_HW_QHS [(match_operand:VI_HW_QHS 1 "register_operand" "")
           (match_operand:VI_HW_QHS 2 "register_operand" "")
           (match_operand:VI_HW_QHS 3 "register_operand" "")
           (match_operand:SI        4 "immediate_operand" "C")]
          UNSPEC_VEC_VSTRC))

(set (reg:CCRAW CC_REGNUM)

(unspec:CCRAW [(match_dup 1)
           (match_dup 2)
           (match_dup 3)
           (match_dup 4)]
          UNSPEC_VEC_VSTRCCC))])

(set (match_operand:SI 5 "memory_operand" "")

(unspec:SI [(reg:CCRAW CC_REGNUM)] UNSPEC_CC_TO_INT))]

"TARGET_VX" { operands[4] = GEN_INT (INTVAL (operands[4]) | VSTRING_FLAG_CS | VSTRING_FLAG_ZS); })

; Signed V2DI -> V2DF conversion - inexact exception disabled (define_insn "vec_di_to_df_s64" [(set (match_operand:V2DF 0 "register_operand" "=v")

(unspec:V2DF [(match_operand:V2DI 1 "register_operand"  "v")
          (match_operand:QI   2 "immediate_operand" "C")]
         UNSPEC_VEC_VCDGB))]

"TARGET_VX" "vcdgb\t%v0,%v1,4,%b2" [(set_attr "op_type" "VRR")])

; The result needs to be multiplied with 2**-op2 (define_expand "vec_ctd_s64" [(set (match_operand:V2DF 0 "register_operand" "")

(unspec:V2DF [(match_operand:V2DI 1 "register_operand" "")
          (const_int 0)] ; According to current BFP rounding mode
         UNSPEC_VEC_VCDGB))

(use (match_operand:QI 2 "immediate_operand" "")) (set (match_dup 0) (mult:V2DF (match_dup 0) (match_dup 3)))] "TARGET_VX" { REAL_VALUE_TYPE f; rtx c;

real_2expN (&f, -INTVAL (operands[2]), DFmode); c = CONST_DOUBLE_FROM_REAL_VALUE (f, DFmode);

operands[3] = gen_rtx_CONST_VECTOR (V2DFmode, gen_rtvec (2, c, c)); operands[3] = force_reg (V2DFmode, operands[3]); })

; Unsigned V2DI -> V2DF conversion - inexact exception disabled (define_insn "vec_di_to_df_u64" [(set (match_operand:V2DF 0 "register_operand" "=v")

(unspec:V2DF [(match_operand:V2DI 1 "register_operand"  "v")
          (match_operand:QI   2 "immediate_operand" "C")]
         UNSPEC_VEC_VCDLGB))]

"TARGET_VX" "vcdlgb\t%v0,%v1,4,%b2" [(set_attr "op_type" "VRR")])

; The result needs to be multiplied with 2**-op2 (define_expand "vec_ctd_u64" [(set (match_operand:V2DF 0 "register_operand" "")

(unspec:V2DF [(match_operand:V2DI 1 "register_operand" "")
          (const_int 0)] ; According to current BFP rounding mode
         UNSPEC_VEC_VCDLGB))

(use (match_operand:QI 2 "immediate_operand" "")) (set (match_dup 0) (mult:V2DF (match_dup 0) (match_dup 3)))] "TARGET_VX" { REAL_VALUE_TYPE f; rtx c;

real_2expN (&f, -INTVAL (operands[2]), DFmode); c = CONST_DOUBLE_FROM_REAL_VALUE (f, DFmode);

operands[3] = gen_rtx_CONST_VECTOR (V2DFmode, gen_rtvec (2, c, c)); operands[3] = force_reg (V2DFmode, operands[3]); })

; Signed V2DF -> V2DI conversion - inexact exception disabled (define_insn "vec_df_to_di_s64" [(set (match_operand:V2DI 0 "register_operand" "=v")

(unspec:V2DI [(match_operand:V2DF 1 "register_operand"  "v")
          (match_operand:QI   2 "immediate_operand" "C")]
         UNSPEC_VEC_VCGDB))]

"TARGET_VX" "vcgdb\t%v0,%v1,4,%b2" [(set_attr "op_type" "VRR")])

; The input needs to be multiplied with 2**op2 (define_expand "vec_ctsl" [(use (match_operand:QI 2 "immediate_operand" "")) (set (match_dup 4) (mult:V2DF (match_operand:V2DF 1 "register_operand" "")

             (match_dup 3)))

(set (match_operand:V2DI 0 "register_operand" "")

(unspec:V2DI [(match_dup 4) (const_int 0)] ; According to current BFP rounding mode
         UNSPEC_VEC_VCGDB))]

"TARGET_VX" { REAL_VALUE_TYPE f; rtx c;

real_2expN (&f, INTVAL (operands[2]), DFmode); c = CONST_DOUBLE_FROM_REAL_VALUE (f, DFmode);

operands[3] = gen_rtx_CONST_VECTOR (V2DFmode, gen_rtvec (2, c, c)); operands[3] = force_reg (V2DFmode, operands[3]); operands[4] = gen_reg_rtx (V2DFmode); })

; Unsigned V2DF -> V2DI conversion - inexact exception disabled (define_insn "vec_df_to_di_u64" [(set (match_operand:V2DI 0 "register_operand" "=v")

(unspec:V2DI [(match_operand:V2DF 1 "register_operand"  "v")
          (match_operand:QI   2 "immediate_operand" "C")]
         UNSPEC_VEC_VCLGDB))]

"TARGET_VX" "vclgdb\t%v0,%v1,4,%b2" [(set_attr "op_type" "VRR")])

; The input needs to be multiplied with 2**op2 (define_expand "vec_ctul" [(use (match_operand:QI 2 "immediate_operand" "")) (set (match_dup 4) (mult:V2DF (match_operand:V2DF 1 "register_operand" "")

             (match_dup 3)))

(set (match_operand:V2DI 0 "register_operand" "")

(unspec:V2DI [(match_dup 4) (const_int 0)] ; According to current BFP rounding mode
         UNSPEC_VEC_VCLGDB))]

"TARGET_VX" { REAL_VALUE_TYPE f; rtx c;

real_2expN (&f, INTVAL (operands[2]), DFmode); c = CONST_DOUBLE_FROM_REAL_VALUE (f, DFmode);

operands[3] = gen_rtx_CONST_VECTOR (V2DFmode, gen_rtvec (2, c, c)); operands[3] = force_reg (V2DFmode, operands[3]); operands[4] = gen_reg_rtx (V2DFmode); })

; Vector load fp integer - IEEE inexact exception is suppressed (define_insn "vfidb" [(set (match_operand:V2DI 0 "register_operand" "=v")

(unspec:V2DI [(match_operand:V2DF 1 "register_operand"  "v")
          (match_operand:QI   2 "immediate_operand" "C")
          (match_operand:QI   3 "immediate_operand" "C")]
         UNSPEC_VEC_VFIDB))]

"TARGET_VX" "vfidb\t%v0,%v1,%b2,%b3" [(set_attr "op_type" "VRR")])

(define_expand "vec_ceil" [(set (match_operand:V2DI 0 "register_operand" "")

(unspec:V2DI [(match_operand:V2DF 1 "register_operand" "")
          (const_int VEC_RND_TO_INF)]
         UNSPEC_VEC_VFIDB))]

"TARGET_VX")

(define_expand "vec_floor" [(set (match_operand:V2DI 0 "register_operand" "")

(unspec:V2DI [(match_operand:V2DF 1 "register_operand" "")
          (const_int VEC_RND_TO_MINF)]
         UNSPEC_VEC_VFIDB))]

"TARGET_VX")

(define_expand "vec_trunc" [(set (match_operand:V2DI 0 "register_operand" "")

(unspec:V2DI [(match_operand:V2DF 1 "register_operand" "")
          (const_int VEC_RND_TO_ZERO)]
         UNSPEC_VEC_VFIDB))]

"TARGET_VX")

(define_expand "vec_roundc" [(set (match_operand:V2DI 0 "register_operand" "")

(unspec:V2DI [(match_operand:V2DF 1 "register_operand" "")
          (const_int VEC_RND_CURRENT)]
         UNSPEC_VEC_VFIDB))]

"TARGET_VX")

(define_expand "vec_round" [(set (match_operand:V2DI 0 "register_operand" "")

(unspec:V2DI [(match_operand:V2DF 1 "register_operand" "")
          (const_int VEC_RND_NEAREST_TO_EVEN)]
         UNSPEC_VEC_VFIDB))]

"TARGET_VX")

; Vector load lengthened - V4SF -> V2DF

(define_insn "*vldeb" [(set (match_operand:V2DF 0 "register_operand" "=v")

(unspec:V2DF [(match_operand:V4SF 1 "register_operand"  "v")]
         UNSPEC_VEC_VLDEB))]

"TARGET_VX" "vldeb\t%v0,%v1" [(set_attr "op_type" "VRR")])

(define_expand "vec_ld2f" [; Initialize a vector to all zeroes. FIXME: This should not be ; necessary since all elements of the vector will be set anyway. ; This is just to make it explicit to the data flow framework. (set (match_dup 2) (match_dup 3)) (set (match_dup 2) (unspec:V4SF [(match_operand:SF 1 "memory_operand" "")

                (const_int 0)
                (match_dup 2)]
                UNSPEC_VEC_SET))

(set (match_dup 2) (unspec:V4SF [(match_dup 4)

                (const_int 2)
                (match_dup 2)]
                UNSPEC_VEC_SET))

(set (match_operand:V2DF 0 "register_operand" "")

(unspec:V2DF [(match_dup 2)] UNSPEC_VEC_VLDEB))]

"TARGET_VX" { operands[2] = gen_reg_rtx (V4SFmode); operands[3] = CONST0_RTX (V4SFmode); operands[4] = adjust_address (operands[1], SFmode, 4); })

; Vector load rounded - V2DF -> V4SF

(define_insn "*vledb" [(set (match_operand:V4SF 0 "register_operand" "=v")

(unspec:V4SF [(match_operand:V2DF 1 "register_operand"  "v")]
         UNSPEC_VEC_VLEDB))]

"TARGET_VX" "vledb\t%v0,%v1,0,0" [(set_attr "op_type" "VRR")])

(define_expand "vec_st2f" [(set (match_dup 2)

(unspec:V4SF [(match_operand:V2DF 0 "register_operand" "")]
         UNSPEC_VEC_VLEDB))

(set (match_operand:SF 1 "memory_operand" "")

(unspec:SF [(match_dup 2) (const_int 0)] UNSPEC_VEC_EXTRACT))

(set (match_dup 3)

(unspec:SF [(match_dup 2) (const_int 2)] UNSPEC_VEC_EXTRACT))]

"TARGET_VX" { operands[2] = gen_reg_rtx (V4SFmode); operands[3] = adjust_address (operands[1], SFmode, 4); })

; Vector load negated fp

(define_expand "vec_nabs" [(set (match_operand:V2DF 0 "register_operand" "")

(neg:V2DF (abs:V2DF (match_operand:V2DF 1 "register_operand" ""))))]

"TARGET_VX")

; Vector square root fp vec_sqrt -> sqrt rtx standard name

; Vector FP test data class immediate

(define_insn "*vftcidb" [(set (match_operand:V2DF 0 "register_operand" "=v")

(unspec:V2DF [(match_operand:V2DF 1 "register_operand"  "v")
          (match_operand:SI   2 "immediate_operand" "J")]
         UNSPEC_VEC_VFTCIDB))

(set (reg:CCRAW CC_REGNUM)

(unspec:CCRAW [(match_dup 1) (match_dup 2)] UNSPEC_VEC_VFTCIDBCC))]

"TARGET_VX" "vftcidb\t%v0,%v1,%x2" [(set_attr "op_type" "VRR")])

(define_insn "*vftcidb_cconly" [(set (reg:CCRAW CC_REGNUM)

(unspec:CCRAW [(match_operand:V2DF 1 "register_operand"  "v")
           (match_operand:SI   2 "immediate_operand" "J")]
          UNSPEC_VEC_VFTCIDBCC))

(clobber (match_scratch:V2DI 0 "=v"))] "TARGET_VX" "vftcidb\t%v0,%v1,%x2" [(set_attr "op_type" "VRR")])

(define_expand "vftcidb" [(parallel

[(set (match_operand:V2DF               0 "register_operand"  "")
  (unspec:V2DF [(match_operand:V2DF 1 "register_operand"  "")
        (match_operand:SI   2 "immediate_operand" "")]
           UNSPEC_VEC_VFTCIDB))
 (set (reg:CCRAW CC_REGNUM)
  (unspec:CCRAW [(match_dup 1) (match_dup 2)] UNSPEC_VEC_VFTCIDBCC))])

(set (match_operand:SI 3 "memory_operand" "")

(unspec:SI [(reg:CCRAW CC_REGNUM)] UNSPEC_CC_TO_INT))]

"TARGET_VX")

;; ;; Integer compares ;;

; All comparisons which produce a CC need fully populated (VI_HW) ; vector arguments. Otherwise the any/all CCs would be just bogus.

(define_insn "*vec_cmpVICMP:insn_cmp_cconly" [(set (reg:VICMP CC_REGNUM)

(compare:VICMP (match_operand:VI_HW 0 "register_operand" "v")
           (match_operand:VI_HW 1 "register_operand" "v")))

(clobber (match_scratch:VI_HW 2 "=v"))] "TARGET_VX" "vcVICMP:insn_cmps\t%v2,%v0,%v1" [(set_attr "op_type" "VRR")])

; FIXME: The following 2x3 definitions should be merged into 2 with ; VICMP like above but I could not find a way to set the comparison ; operator (eq) depending on the mode CCVEQ (mode_iterator). Or the ; other way around - setting the mode depending on the code ; (code_iterator). (define_expand "vec_cmpeq_cc" [(parallel

[(set (reg:CCVEQ CC_REGNUM)
(compare:CCVEQ (match_operand:VI_HW 1 "register_operand" "v")
           (match_operand:VI_HW 2 "register_operand" "v")))
 (set (match_operand:VI_HW 0 "register_operand" "=v")
  (eq:VI_HW (match_dup 1) (match_dup 2)))])

(set (match_operand:SI 3 "memory_operand" "")

(unspec:SI [(reg:CCVEQ CC_REGNUM)] UNSPEC_CC_TO_INT))]

"TARGET_VX")

(define_expand "vec_cmph_cc" [(parallel

[(set (reg:CCVH CC_REGNUM)
  (compare:CCVH (match_operand:VI_HW 1 "register_operand" "v")
        (match_operand:VI_HW 2 "register_operand" "v")))
 (set (match_operand:VI_HW 0 "register_operand" "=v")
  (gt:VI_HW (match_dup 1) (match_dup 2)))])

(set (match_operand:SI 3 "memory_operand" "")

(unspec:SI [(reg:CCVH CC_REGNUM)] UNSPEC_CC_TO_INT))]

"TARGET_VX")

(define_expand "vec_cmphl_cc" [(parallel

[(set (reg:CCVHU CC_REGNUM)
  (compare:CCVHU (match_operand:VI_HW 1 "register_operand" "v")
         (match_operand:VI_HW 2 "register_operand" "v")))
 (set (match_operand:VI_HW 0 "register_operand" "=v")
  (gtu:VI_HW (match_dup 1) (match_dup 2)))])

(set (match_operand:SI 3 "memory_operand" "")

(unspec:SI [(reg:CCVHU CC_REGNUM)] UNSPEC_CC_TO_INT))]

"TARGET_VX")

(define_insn "*vec_cmpeq_cc" [(set (reg:CCVEQ CC_REGNUM)

(compare:CCVEQ (match_operand:VI_HW 0 "register_operand"  "v")
           (match_operand:VI_HW 1 "register_operand"  "v")))

(set (match_operand:VI_HW 2 "register_operand" "=v")

(eq:VI_HW (match_dup 0) (match_dup 1)))]

"TARGET_VX" "vceqs\t%v2,%v0,%v1" [(set_attr "op_type" "VRR")])

(define_insn "*vec_cmph_cc" [(set (reg:CCVH CC_REGNUM)

(compare:CCVH (match_operand:VI_HW 0 "register_operand"  "v")
          (match_operand:VI_HW 1 "register_operand"  "v")))

(set (match_operand:VI_HW 2 "register_operand" "=v")

(gt:VI_HW (match_dup 0) (match_dup 1)))]

"TARGET_VX" "vchs\t%v2,%v0,%v1" [(set_attr "op_type" "VRR")])

(define_insn "*vec_cmphl_cc" [(set (reg:CCVHU CC_REGNUM)

(compare:CCVHU (match_operand:VI_HW 0 "register_operand"  "v")
           (match_operand:VI_HW 1 "register_operand"  "v")))

(set (match_operand:VI_HW 2 "register_operand" "=v")

(gtu:VI_HW (match_dup 0) (match_dup 1)))]

"TARGET_VX" "vchls\t%v2,%v0,%v1" [(set_attr "op_type" "VRR")])

;; ;; Floating point comparesg ;;

(define_insn "*vec_cmpv2df_cconly" [(set (reg:VFCMP CC_REGNUM)

(compare:VFCMP (match_operand:V2DF 0 "register_operand" "v")
           (match_operand:V2DF 1 "register_operand" "v")))

(clobber (match_scratch:V2DI 2 "=v"))] "TARGET_VX" "vfcdbs\t%v2,%v0,%v1" [(set_attr "op_type" "VRR")])

; FIXME: Merge the following 2x3 patterns with VFCMP (define_expand "vec_cmpeqv2df_cc" [(parallel

[(set (reg:CCVEQ CC_REGNUM)
  (compare:CCVEQ (match_operand:V2DF 1 "register_operand"  "v")
         (match_operand:V2DF 2 "register_operand"  "v")))
 (set (match_operand:V2DI 0 "register_operand" "=v")
  (eq:V2DI (match_dup 1) (match_dup 2)))])

(set (match_operand:SI 3 "memory_operand" "")

(unspec:SI [(reg:CCVEQ CC_REGNUM)] UNSPEC_CC_TO_INT))]

"TARGET_VX")

(define_expand "vec_cmphv2df_cc" [(parallel

[(set (reg:CCVH CC_REGNUM)
  (compare:CCVH (match_operand:V2DF 1 "register_operand"  "v")
        (match_operand:V2DF 2 "register_operand"  "v")))
 (set (match_operand:V2DI 0 "register_operand" "=v")
  (gt:V2DI (match_dup 1) (match_dup 2)))])

(set (match_operand:SI 3 "memory_operand" "")

(unspec:SI [(reg:CCVH CC_REGNUM)] UNSPEC_CC_TO_INT))]

"TARGET_VX")

(define_expand "vec_cmphev2df_cc" [(parallel

[(set (reg:CCVFHE CC_REGNUM)
  (compare:CCVFHE (match_operand:V2DF 1 "register_operand"  "v")
          (match_operand:V2DF 2 "register_operand"  "v")))
 (set (match_operand:V2DI 0 "register_operand" "=v")
  (ge:V2DI (match_dup 1) (match_dup 2)))])

(set (match_operand:SI 3 "memory_operand" "")

(unspec:SI [(reg:CCVFHE CC_REGNUM)] UNSPEC_CC_TO_INT))]

"TARGET_VX")

(define_insn "*vec_cmpeqv2df_cc" [(set (reg:CCVEQ CC_REGNUM)

(compare:CCVEQ (match_operand:V2DF 0 "register_operand"  "v")
           (match_operand:V2DF 1 "register_operand"  "v")))

(set (match_operand:V2DI 2 "register_operand" "=v")

(eq:V2DI (match_dup 0) (match_dup 1)))]

"TARGET_VX" "vfcedbs\t%v2,%v0,%v1" [(set_attr "op_type" "VRR")])

(define_insn "*vec_cmphv2df_cc" [(set (reg:CCVH CC_REGNUM)

(compare:CCVH (match_operand:V2DF 0 "register_operand"  "v")
          (match_operand:V2DF 1 "register_operand"  "v")))

(set (match_operand:V2DI 2 "register_operand" "=v")

(gt:V2DI (match_dup 0) (match_dup 1)))]

"TARGET_VX" "vfchdbs\t%v2,%v0,%v1" [(set_attr "op_type" "VRR")])

(define_insn "*vec_cmphev2df_cc" [(set (reg:CCVFHE CC_REGNUM)

(compare:CCVFHE (match_operand:V2DF 0 "register_operand"  "v")
        (match_operand:V2DF 1 "register_operand"  "v")))

(set (match_operand:V2DI 2 "register_operand" "=v")

(ge:V2DI (match_dup 0) (match_dup 1)))]

"TARGET_VX" "vfchedbs\t%v2,%v0,%v1" [(set_attr "op_type" "VRR")])