diff options
Diffstat (limited to 'gcc/config/rs6000/altivec.md')
-rw-r--r-- | gcc/config/rs6000/altivec.md | 222 |
1 files changed, 165 insertions, 57 deletions
diff --git a/gcc/config/rs6000/altivec.md b/gcc/config/rs6000/altivec.md index 9c3084dcb8..362fa221c1 100644 --- a/gcc/config/rs6000/altivec.md +++ b/gcc/config/rs6000/altivec.md @@ -58,6 +58,7 @@ UNSPEC_VSUM2SWS UNSPEC_VSUMSWS UNSPEC_VPERM + UNSPEC_VPERMR UNSPEC_VPERM_UNS UNSPEC_VRFIN UNSPEC_VCFUX @@ -73,6 +74,9 @@ UNSPEC_VUNPACK_LO_SIGN_DIRECT UNSPEC_VUPKHPX UNSPEC_VUPKLPX + UNSPEC_DARN + UNSPEC_DARN_32 + UNSPEC_DARN_RAW UNSPEC_DST UNSPEC_DSTT UNSPEC_DSTST @@ -110,6 +114,9 @@ UNSPEC_STVLXL UNSPEC_STVRX UNSPEC_STVRXL + UNSPEC_VSLV + UNSPEC_VSRV + UNSPEC_VADU UNSPEC_VMULWHUB UNSPEC_VMULWLUB UNSPEC_VMULWHSB @@ -189,6 +196,13 @@ (KF "FLOAT128_VECTOR_P (KFmode)") (TF "FLOAT128_VECTOR_P (TFmode)")]) +;; Specific iterator for parity which does not have a byte/half-word form, but +;; does have a quad word form +(define_mode_iterator VParity [V4SI + V2DI + V1TI + (TI "TARGET_VSX_TIMODE")]) + (define_mode_attr VI_char [(V2DI "d") (V4SI "w") (V8HI "h") (V16QI "b")]) (define_mode_attr VI_scalar [(V2DI "DI") (V4SI "SI") (V8HI "HI") (V16QI "QI")]) (define_mode_attr VI_unit [(V16QI "VECTOR_UNIT_ALTIVEC_P (V16QImode)") @@ -203,6 +217,9 @@ (define_mode_attr VP_small_lc [(V2DI "v4si") (V4SI "v8hi") (V8HI "v16qi")]) (define_mode_attr VU_char [(V2DI "w") (V4SI "h") (V8HI "b")]) +;; Vector negate +(define_mode_iterator VNEG [V4SI V2DI]) + ;; Vector move instructions. (define_insn "*altivec_mov<mode>" [(set (match_operand:VM2 0 "nonimmediate_operand" "=Z,v,v,*Y,*r,*r,v,v,*r") @@ -225,7 +242,7 @@ default: gcc_unreachable (); } } - [(set_attr "type" "vecstore,vecload,vecsimple,store,load,*,vecsimple,*,*") + [(set_attr "type" "vecstore,vecload,veclogical,store,load,*,veclogical,*,*") (set_attr "length" "4,4,4,20,20,20,4,8,32")]) ;; Unlike other altivec moves, allow the GPRs, since a normal use of TImode @@ -251,7 +268,7 @@ default: gcc_unreachable (); } } - [(set_attr "type" "vecstore,vecload,vecsimple,store,load,*,vecsimple,*")]) + [(set_attr "type" "vecstore,vecload,veclogical,store,load,*,veclogical,*")]) ;; Load up a vector with the most significant bit set by loading up -1 and ;; doing a shift left @@ -586,7 +603,7 @@ (match_operand:VI2 2 "altivec_register_operand" "v")))] "<VI_unit>" "vcmpequ<VI_char> %0,%1,%2" - [(set_attr "type" "veccmp")]) + [(set_attr "type" "veccmpfx")]) (define_insn "*altivec_gt<mode>" [(set (match_operand:VI2 0 "altivec_register_operand" "=v") @@ -594,7 +611,7 @@ (match_operand:VI2 2 "altivec_register_operand" "v")))] "<VI_unit>" "vcmpgts<VI_char> %0,%1,%2" - [(set_attr "type" "veccmp")]) + [(set_attr "type" "veccmpfx")]) (define_insn "*altivec_gtu<mode>" [(set (match_operand:VI2 0 "altivec_register_operand" "=v") @@ -602,7 +619,7 @@ (match_operand:VI2 2 "altivec_register_operand" "v")))] "<VI_unit>" "vcmpgtu<VI_char> %0,%1,%2" - [(set_attr "type" "veccmp")]) + [(set_attr "type" "veccmpfx")]) (define_insn "*altivec_eqv4sf" [(set (match_operand:V4SF 0 "altivec_register_operand" "=v") @@ -637,7 +654,7 @@ (match_operand:VM 3 "altivec_register_operand" "v")))] "VECTOR_MEM_ALTIVEC_P (<MODE>mode)" "vsel %0,%3,%2,%1" - [(set_attr "type" "vecperm")]) + [(set_attr "type" "vecmove")]) (define_insn "*altivec_vsel<mode>_uns" [(set (match_operand:VM 0 "altivec_register_operand" "=v") @@ -648,7 +665,7 @@ (match_operand:VM 3 "altivec_register_operand" "v")))] "VECTOR_MEM_ALTIVEC_P (<MODE>mode)" "vsel %0,%3,%2,%1" - [(set_attr "type" "vecperm")]) + [(set_attr "type" "vecmove")]) ;; Fused multiply add. @@ -1617,6 +1634,24 @@ "vslo %0,%1,%2" [(set_attr "type" "vecperm")]) +(define_insn "vslv" + [(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_VSLV))] + "TARGET_P9_VECTOR" + "vslv %0,%1,%2" + [(set_attr "type" "vecsimple")]) + +(define_insn "vsrv" + [(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_VSRV))] + "TARGET_P9_VECTOR" + "vsrv %0,%1,%2" + [(set_attr "type" "vecsimple")]) + (define_insn "*altivec_vsl<VI_char>" [(set (match_operand:VI2 0 "register_operand" "=v") (ashift:VI2 (match_operand:VI2 1 "register_operand" "v") @@ -1949,32 +1984,30 @@ ;; Slightly prefer vperm, since the target does not overlap the source (define_insn "*altivec_vperm_<mode>_internal" - [(set (match_operand:VM 0 "register_operand" "=v,?wo,?&wo") - (unspec:VM [(match_operand:VM 1 "register_operand" "v,0,wo") - (match_operand:VM 2 "register_operand" "v,wo,wo") - (match_operand:V16QI 3 "register_operand" "v,wo,wo")] + [(set (match_operand:VM 0 "register_operand" "=v,?wo") + (unspec:VM [(match_operand:VM 1 "register_operand" "v,wo") + (match_operand:VM 2 "register_operand" "v,0") + (match_operand:V16QI 3 "register_operand" "v,wo")] UNSPEC_VPERM))] "TARGET_ALTIVEC" "@ vperm %0,%1,%2,%3 - xxperm %x0,%x2,%x3 - xxlor %x0,%x1,%x1\t\t# xxperm fusion\;xxperm %x0,%x2,%x3" + xxperm %x0,%x1,%x3" [(set_attr "type" "vecperm") - (set_attr "length" "4,4,8")]) + (set_attr "length" "4")]) (define_insn "altivec_vperm_v8hiv16qi" - [(set (match_operand:V16QI 0 "register_operand" "=v,?wo,?&wo") - (unspec:V16QI [(match_operand:V8HI 1 "register_operand" "v,0,wo") - (match_operand:V8HI 2 "register_operand" "v,wo,wo") - (match_operand:V16QI 3 "register_operand" "v,wo,wo")] + [(set (match_operand:V16QI 0 "register_operand" "=v,?wo") + (unspec:V16QI [(match_operand:V8HI 1 "register_operand" "v,wo") + (match_operand:V8HI 2 "register_operand" "v,0") + (match_operand:V16QI 3 "register_operand" "v,wo")] UNSPEC_VPERM))] "TARGET_ALTIVEC" "@ vperm %0,%1,%2,%3 - xxperm %x0,%x2,%x3 - xxlor %x0,%x1,%x1\t\t# xxperm fusion\;xxperm %x0,%x2,%x3" + xxperm %x0,%x1,%x3" [(set_attr "type" "vecperm") - (set_attr "length" "4,4,8")]) + (set_attr "length" "4")]) (define_expand "altivec_vperm_<mode>_uns" [(set (match_operand:VM 0 "register_operand" "") @@ -1992,18 +2025,17 @@ }) (define_insn "*altivec_vperm_<mode>_uns_internal" - [(set (match_operand:VM 0 "register_operand" "=v,?wo,?&wo") - (unspec:VM [(match_operand:VM 1 "register_operand" "v,0,wo") - (match_operand:VM 2 "register_operand" "v,wo,wo") - (match_operand:V16QI 3 "register_operand" "v,wo,wo")] + [(set (match_operand:VM 0 "register_operand" "=v,?wo") + (unspec:VM [(match_operand:VM 1 "register_operand" "v,wo") + (match_operand:VM 2 "register_operand" "v,0") + (match_operand:V16QI 3 "register_operand" "v,wo")] UNSPEC_VPERM_UNS))] "TARGET_ALTIVEC" "@ vperm %0,%1,%2,%3 - xxperm %x0,%x2,%x3 - xxlor %x0,%x1,%x1\t\t# xxperm fusion\;xxperm %x0,%x2,%x3" + xxperm %x0,%x1,%x3" [(set_attr "type" "vecperm") - (set_attr "length" "4,4,8")]) + (set_attr "length" "4")]) (define_expand "vec_permv16qi" [(set (match_operand:V16QI 0 "register_operand" "") @@ -2032,6 +2064,19 @@ FAIL; }) +(define_insn "*altivec_vpermr_<mode>_internal" + [(set (match_operand:VM 0 "register_operand" "=v,?wo") + (unspec:VM [(match_operand:VM 1 "register_operand" "v,wo") + (match_operand:VM 2 "register_operand" "v,0") + (match_operand:V16QI 3 "register_operand" "v,wo")] + UNSPEC_VPERMR))] + "TARGET_P9_VECTOR" + "@ + vpermr %0,%2,%1,%3 + xxpermr %x0,%x1,%x3" + [(set_attr "type" "vecperm") + (set_attr "length" "4")]) + (define_insn "altivec_vrfip" ; ceil [(set (match_operand:V4SF 0 "register_operand" "=v") (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "v")] @@ -2238,7 +2283,7 @@ (match_dup 2)))] "<VI_unit>" "vcmpequ<VI_char>. %0,%1,%2" - [(set_attr "type" "veccmp")]) + [(set_attr "type" "veccmpfx")]) (define_insn "*altivec_vcmpgts<VI_char>_p" [(set (reg:CC 74) @@ -2250,7 +2295,7 @@ (match_dup 2)))] "<VI_unit>" "vcmpgts<VI_char>. %0,%1,%2" - [(set_attr "type" "veccmp")]) + [(set_attr "type" "veccmpfx")]) (define_insn "*altivec_vcmpgtu<VI_char>_p" [(set (reg:CC 74) @@ -2262,7 +2307,7 @@ (match_dup 2)))] "<VI_unit>" "vcmpgtu<VI_char>. %0,%1,%2" - [(set_attr "type" "veccmp")]) + [(set_attr "type" "veccmpfx")]) (define_insn "*altivec_vcmpeqfp_p" [(set (reg:CC 74) @@ -2690,20 +2735,28 @@ DONE; }) +(define_insn "*p9_neg<mode>2" + [(set (match_operand:VNEG 0 "altivec_register_operand" "=v") + (neg:VNEG (match_operand:VNEG 1 "altivec_register_operand" "v")))] + "TARGET_P9_VECTOR" + "vneg<VI_char> %0,%1" + [(set_attr "type" "vecsimple")]) + (define_expand "neg<mode>2" - [(use (match_operand:VI 0 "register_operand" "")) - (use (match_operand:VI 1 "register_operand" ""))] - "TARGET_ALTIVEC" - " + [(set (match_operand:VI2 0 "register_operand" "") + (neg:VI2 (match_operand:VI2 1 "register_operand" "")))] + "<VI_unit>" { - rtx vzero; + if (!TARGET_P9_VECTOR || (<MODE>mode != V4SImode && <MODE>mode != V2DImode)) + { + rtx vzero; - vzero = gen_reg_rtx (GET_MODE (operands[0])); - emit_insn (gen_altivec_vspltis<VI_char> (vzero, const0_rtx)); - emit_insn (gen_sub<mode>3 (operands[0], vzero, operands[1])); - - DONE; -}") + vzero = gen_reg_rtx (GET_MODE (operands[0])); + emit_move_insn (vzero, CONST0_RTX (<MODE>mode)); + emit_insn (gen_sub<mode>3 (operands[0], vzero, operands[1])); + DONE; + } +}) (define_expand "udot_prod<mode>" [(set (match_operand:V4SI 0 "register_operand" "=v") @@ -2791,32 +2844,30 @@ "") (define_insn "vperm_v8hiv4si" - [(set (match_operand:V4SI 0 "register_operand" "=v,?wo,?&wo") - (unspec:V4SI [(match_operand:V8HI 1 "register_operand" "v,0,wo") - (match_operand:V4SI 2 "register_operand" "v,wo,wo") - (match_operand:V16QI 3 "register_operand" "v,wo,wo")] + [(set (match_operand:V4SI 0 "register_operand" "=v,?wo") + (unspec:V4SI [(match_operand:V8HI 1 "register_operand" "v,wo") + (match_operand:V4SI 2 "register_operand" "v,0") + (match_operand:V16QI 3 "register_operand" "v,wo")] UNSPEC_VPERMSI))] "TARGET_ALTIVEC" "@ vperm %0,%1,%2,%3 - xxperm %x0,%x2,%x3 - xxlor %x0,%x1,%x1\t\t# xxperm fusion\;xxperm %x0,%x2,%x3" + xxperm %x0,%x1,%x3" [(set_attr "type" "vecperm") - (set_attr "length" "4,4,8")]) + (set_attr "length" "4")]) (define_insn "vperm_v16qiv8hi" - [(set (match_operand:V8HI 0 "register_operand" "=v,?wo,?&wo") - (unspec:V8HI [(match_operand:V16QI 1 "register_operand" "v,0,wo") - (match_operand:V8HI 2 "register_operand" "v,wo,wo") - (match_operand:V16QI 3 "register_operand" "v,wo,wo")] + [(set (match_operand:V8HI 0 "register_operand" "=v,?wo") + (unspec:V8HI [(match_operand:V16QI 1 "register_operand" "v,wo") + (match_operand:V8HI 2 "register_operand" "v,0") + (match_operand:V16QI 3 "register_operand" "v,wo")] UNSPEC_VPERMHI))] "TARGET_ALTIVEC" "@ vperm %0,%1,%2,%3 - xxperm %x0,%x2,%x3 - xxlor %x0,%x1,%x1\t\t# xxperm fusion\;xxperm %x0,%x2,%x3" + xxperm %x0,%x1,%x3" [(set_attr "type" "vecperm") - (set_attr "length" "4,4,8")]) + (set_attr "length" "4")]) (define_expand "vec_unpacku_hi_v16qi" @@ -3353,7 +3404,7 @@ }") -;; Power8 vector instructions encoded as Altivec instructions +;; Power8/power9 vector instructions encoded as Altivec instructions ;; Vector count leading zeros (define_insn "*p8v_clz<mode>2" @@ -3364,6 +3415,33 @@ [(set_attr "length" "4") (set_attr "type" "vecsimple")]) +;; Vector absolute difference unsigned +(define_expand "vadu<mode>3" + [(set (match_operand:VI 0 "register_operand") + (unspec:VI [(match_operand:VI 1 "register_operand") + (match_operand:VI 2 "register_operand")] + UNSPEC_VADU))] + "TARGET_P9_VECTOR") + +;; Vector absolute difference unsigned +(define_insn "*p9_vadu<mode>3" + [(set (match_operand:VI 0 "register_operand" "=v") + (unspec:VI [(match_operand:VI 1 "register_operand" "v") + (match_operand:VI 2 "register_operand" "v")] + UNSPEC_VADU))] + "TARGET_P9_VECTOR" + "vabsdu<wd> %0,%1,%2" + [(set_attr "type" "vecsimple")]) + +;; Vector count trailing zeros +(define_insn "*p9v_ctz<mode>2" + [(set (match_operand:VI2 0 "register_operand" "=v") + (ctz:VI2 (match_operand:VI2 1 "register_operand" "v")))] + "TARGET_P9_VECTOR" + "vctz<wd> %0,%1" + [(set_attr "length" "4") + (set_attr "type" "vecsimple")]) + ;; Vector population count (define_insn "*p8v_popcount<mode>2" [(set (match_operand:VI2 0 "register_operand" "=v") @@ -3373,6 +3451,15 @@ [(set_attr "length" "4") (set_attr "type" "vecsimple")]) +;; Vector parity +(define_insn "*p9v_parity<mode>2" + [(set (match_operand:VParity 0 "register_operand" "=v") + (parity:VParity (match_operand:VParity 1 "register_operand" "v")))] + "TARGET_P9_VECTOR" + "vprtyb<wd> %0,%1" + [(set_attr "length" "4") + (set_attr "type" "vecsimple")]) + ;; Vector Gather Bits by Bytes by Doubleword (define_insn "p8v_vgbbd" [(set (match_operand:V16QI 0 "register_operand" "=v") @@ -3540,6 +3627,27 @@ [(set_attr "length" "4") (set_attr "type" "vecsimple")]) +(define_insn "darn_32" + [(set (match_operand:SI 0 "register_operand" "=r") + (unspec:SI [(const_int 0)] UNSPEC_DARN_32))] + "TARGET_P9_MISC" + "darn %0,0" + [(set_attr "type" "integer")]) + +(define_insn "darn_raw" + [(set (match_operand:DI 0 "register_operand" "=r") + (unspec:DI [(const_int 0)] UNSPEC_DARN_RAW))] + "TARGET_P9_MISC && TARGET_64BIT" + "darn %0,2" + [(set_attr "type" "integer")]) + +(define_insn "darn" + [(set (match_operand:DI 0 "register_operand" "=r") + (unspec:DI [(const_int 0)] UNSPEC_DARN))] + "TARGET_P9_MISC && TARGET_64BIT" + "darn %0,1" + [(set_attr "type" "integer")]) + (define_expand "bcd<bcd_add_sub>_<code>" [(parallel [(set (reg:CCFP 74) (compare:CCFP |