;;- 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 ;; . ; 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: 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 (mode))); emit_insn (gen_rtx_SET (VOIDmode, operands[0], gen_rtx_CONST_VECTOR (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: 1 "general_operand" "")))] "TARGET_VX") (define_expand "vec_insert" [(set (match_operand:V_HW 0 "register_operand" "") (unspec:V_HW [(match_operand: 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: 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: 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: [(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: [(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: 0 "register_operand" "") (unspec: [(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: [(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: [(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: [(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: 0 "register_operand" "") (unspec: [(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: [(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: (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: [(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: [(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_scatter_element_" [(set (mem: (plus: (unspec: [(match_operand: 1 "register_operand" "v") (match_operand:DI 3 "immediate_operand" "I")] UNSPEC_VEC_EXTRACT) (match_operand:DI 2 "address_operand" "ZQ"))) (unspec: [(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_DI (operands[0], operands[1], operands[2], operands[3])); } else { PUT_MODE (operands[2], SImode); emit_insn ( gen_vec_scatter_element_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: 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: [(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: [(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: [(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: [(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 "vec_all_" [(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], , operands[1], operands[2], true); DONE; }) (define_expand "vec_any_" [(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], , operands[1], operands[2], false); DONE; }) ; vec_all/any fp compares (define_expand "vec_all_v2df" [(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], , operands[1], operands[2], true); DONE; }) (define_expand "vec_any_v2df" [(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], , operands[1], operands[2], false); DONE; }) ; Compare without generating CC (define_expand "vec_cmp" [(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], , operands[1], operands[2]); DONE; }) (define_expand "vec_cmpv2df" [(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], , 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: [(match_operand:VI_HW_QHS 1 "register_operand" "v") (match_operand:VI_HW_QHS 2 "register_operand" "v") (match_operand: 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: [(match_operand:VI_HW_QHS 1 "register_operand" "v") (match_operand:VI_HW_QHS 2 "register_operand" "v") (match_operand: 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: [(match_operand:VI_HW_QHS 1 "register_operand" "v") (match_operand:VI_HW_QHS 2 "register_operand" "v") (match_operand: 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: [(match_operand:VI_HW_QHS 1 "register_operand" "v") (match_operand:VI_HW_QHS 2 "register_operand" "v") (match_operand: 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: [(match_operand:VI_HW_QHS 1 "register_operand" "v") (match_operand:VI_HW_QHS 2 "register_operand" "v") (match_operand: 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: 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: 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: 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: 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: 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\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 "vfaezs\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 "vfeezs\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\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 "vstrczs\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_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" "vcs\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")])