From 5315810c391b75661de9027ea2848d31390e1d8b Mon Sep 17 00:00:00 2001 From: Kewen Lin Date: Wed, 23 Oct 2019 04:02:00 -0500 Subject: [PATCH 3/3] Update RTL pattern on vector fp/int 32bit <-> 64bit conversion --- gcc/config/rs6000/rs6000-modes.def | 4 + gcc/config/rs6000/vsx.md | 240 +++++++++++++++++++++++++++---------- 2 files changed, 181 insertions(+), 63 deletions(-) diff --git a/gcc/config/rs6000/rs6000-modes.def b/gcc/config/rs6000/rs6000-modes.def index 677062c..449e176 100644 --- a/gcc/config/rs6000/rs6000-modes.def +++ b/gcc/config/rs6000/rs6000-modes.def @@ -74,6 +74,10 @@ VECTOR_MODES (FLOAT, 16); /* V8HF V4SF V2DF */ VECTOR_MODES (INT, 32); /* V32QI V16HI V8SI V4DI */ VECTOR_MODES (FLOAT, 32); /* V16HF V8SF V4DF */ +/* Half VMX/VSX vector (for select) */ +VECTOR_MODE (FLOAT, SF, 2); /* V2SF */ +VECTOR_MODE (INT, SI, 2); /* V2SI */ + /* Replacement for TImode that only is allowed in GPRs. We also use PTImode for quad memory atomic operations to force getting an even/odd register combination. */ diff --git a/gcc/config/rs6000/vsx.md b/gcc/config/rs6000/vsx.md index 83e4071..44025f6 100644 --- a/gcc/config/rs6000/vsx.md +++ b/gcc/config/rs6000/vsx.md @@ -265,7 +265,6 @@ ;; Constants for creating unspecs (define_c_enum "unspec" [UNSPEC_VSX_CONCAT - UNSPEC_VSX_CVDPSXWS UNSPEC_VSX_CVDPUXWS UNSPEC_VSX_CVSPDP UNSPEC_VSX_CVHPSP @@ -273,10 +272,6 @@ UNSPEC_VSX_CVDPSPN UNSPEC_VSX_CVSXWDP UNSPEC_VSX_CVUXWDP - UNSPEC_VSX_CVSXDSP - UNSPEC_VSX_CVUXDSP - UNSPEC_VSX_CVSPSXDS - UNSPEC_VSX_CVSPUXDS UNSPEC_VSX_FLOAT2 UNSPEC_VSX_UNS_FLOAT2 UNSPEC_VSX_FLOATE @@ -2106,22 +2101,69 @@ "xscvdpsp %x0,%x1" [(set_attr "type" "fp")]) -(define_insn "vsx_xvcvspdp" +(define_insn "vsx_xvcvspdp_be" [(set (match_operand:V2DF 0 "vsx_register_operand" "=v,?wa") - (unspec:V2DF [(match_operand:V4SF 1 "vsx_register_operand" "wa,wa")] - UNSPEC_VSX_CVSPDP))] - "VECTOR_UNIT_VSX_P (V4SFmode)" + (float_extend:V2DF + (vec_select:V2SF (match_operand:V4SF 1 "vsx_register_operand" "wa,wa") + (parallel [(const_int 0) (const_int 2)]))))] + "VECTOR_UNIT_VSX_P (V4SFmode) && BYTES_BIG_ENDIAN" + "xvcvspdp %x0,%x1" + [(set_attr "type" "vecdouble")]) + +(define_insn "vsx_xvcvspdp_le" + [(set (match_operand:V2DF 0 "vsx_register_operand" "=v,?wa") + (float_extend:V2DF + (vec_select:V2SF (match_operand:V4SF 1 "vsx_register_operand" "wa,wa") + (parallel [(const_int 1) (const_int 3)]))))] + "VECTOR_UNIT_VSX_P (V4SFmode) && !BYTES_BIG_ENDIAN" "xvcvspdp %x0,%x1" [(set_attr "type" "vecdouble")]) -(define_insn "vsx_xvcvdpsp" +(define_expand "vsx_xvcvspdp" + [(match_operand:V2DF 0 "vsx_register_operand") + (match_operand:V4SF 1 "vsx_register_operand")] + "VECTOR_UNIT_VSX_P (V4SFmode)" +{ + if (BYTES_BIG_ENDIAN) + emit_insn (gen_vsx_xvcvspdp_be (operands[0], operands[1])); + else + emit_insn (gen_vsx_xvcvspdp_le (operands[0], operands[1])); + DONE; +}) + +(define_insn "vsx_xvcvdpsp_be" [(set (match_operand:V4SF 0 "vsx_register_operand" "=wa,?wa") - (unspec:V4SF [(match_operand:V2DF 1 "vsx_register_operand" "v,wa")] - UNSPEC_VSX_CVSPDP))] - "VECTOR_UNIT_VSX_P (V2DFmode)" + (float_truncate:V4SF + (vec_concat:V4DF (match_operand:V2DF 1 "vsx_register_operand" "v,wa") + (vec_select:V2DF (match_dup 1) + (parallel [(const_int 1) (const_int 0)])))))] + "VECTOR_UNIT_VSX_P (V2DFmode) && BYTES_BIG_ENDIAN" "xvcvdpsp %x0,%x1" [(set_attr "type" "vecdouble")]) +(define_insn "vsx_xvcvdpsp_le" + [(set (match_operand:V4SF 0 "vsx_register_operand" "=wa,?wa") + (float_truncate:V4SF + (vec_concat:V4DF + (vec_select:V2DF (match_operand:V2DF 1 "vsx_register_operand" "v,wa") + (parallel [(const_int 1) (const_int 0)])) + (match_dup 1))))] + "VECTOR_UNIT_VSX_P (V2DFmode) && !BYTES_BIG_ENDIAN" + "xvcvdpsp %x0,%x1" + [(set_attr "type" "vecdouble")]) + +(define_expand "vsx_xvcvdpsp" + [(match_operand:V4SF 0 "vsx_register_operand") + (match_operand:V2DF 1 "vsx_register_operand")] + "VECTOR_UNIT_VSX_P (V2DFmode)" +{ + if (BYTES_BIG_ENDIAN) + emit_insn (gen_vsx_xvcvdpsp_be (operands[0], operands[1])); + else + emit_insn (gen_vsx_xvcvdpsp_le (operands[0], operands[1])); + DONE; +}) + ;; xscvspdp, represent the scalar SF type as V4SF (define_insn "vsx_xscvspdp" [(set (match_operand:DF 0 "vsx_register_operand" "=wa") @@ -2301,48 +2343,144 @@ ;; Note, favor the Altivec registers since the usual use of these instructions ;; is in vector converts and we need to use the Altivec vperm instruction. -(define_insn "vsx_xvcvdpsxws" +;; Convert vector of 64-bit floating point numbers to vector of +;; 32-bit signed/unsigned integers. +(define_insn "vsx_xvcvdpxws_be" [(set (match_operand:V4SI 0 "vsx_register_operand" "=v,?wa") - (unspec:V4SI [(match_operand:V2DF 1 "vsx_register_operand" "wa,wa")] - UNSPEC_VSX_CVDPSXWS))] - "VECTOR_UNIT_VSX_P (V2DFmode)" - "xvcvdpsxws %x0,%x1" + (any_fix:V4SI + (vec_concat:V4DF (match_operand:V2DF 1 "vsx_register_operand" "wa,wa") + (vec_select:V2DF (match_dup 1) + (parallel [(const_int 1) (const_int 0)])))))] + "VECTOR_UNIT_VSX_P (V2DFmode) && BYTES_BIG_ENDIAN" + "xvcvdpxws %x0,%x1" [(set_attr "type" "vecdouble")]) -(define_insn "vsx_xvcvdpuxws" +(define_insn "vsx_xvcvdpxws_le" [(set (match_operand:V4SI 0 "vsx_register_operand" "=v,?wa") - (unspec:V4SI [(match_operand:V2DF 1 "vsx_register_operand" "wa,wa")] - UNSPEC_VSX_CVDPUXWS))] - "VECTOR_UNIT_VSX_P (V2DFmode)" - "xvcvdpuxws %x0,%x1" + (any_fix:V4SI + (vec_concat:V4DF + (vec_select:V2DF (match_operand:V2DF 1 "vsx_register_operand" "wa,wa") + (parallel [(const_int 1) (const_int 0)])) + (match_dup 1))))] + "VECTOR_UNIT_VSX_P (V2DFmode) && !BYTES_BIG_ENDIAN" + "xvcvdpxws %x0,%x1" [(set_attr "type" "vecdouble")]) -(define_insn "vsx_xvcvsxdsp" - [(set (match_operand:V4SF 0 "vsx_register_operand" "=wa") - (unspec:V4SF [(match_operand:V2DI 1 "vsx_register_operand" "wa")] - UNSPEC_VSX_CVSXDSP))] +(define_expand "vsx_xvcvdpxws" + [(match_operand:V4SI 0 "vsx_register_operand") + (match_operand:V2DF 1 "vsx_register_operand") + (any_fix (pc))] "VECTOR_UNIT_VSX_P (V2DFmode)" - "xvcvsxdsp %x0,%x1" +{ + if (BYTES_BIG_ENDIAN) + emit_insn (gen_vsx_xvcvdpxws_be (operands[0], operands[1])); + else + emit_insn (gen_vsx_xvcvdpxws_le (operands[0], operands[1])); + DONE; +}) + +;; Convert vector of 64-bit signed/unsigned integers to vector of +;; 32-bit floating point numbers. +(define_insn "vsx_xvcvxdsp_be" + [(set (match_operand:V4SF 0 "vsx_register_operand" "=wa") + (any_float:V4SF + (vec_concat:V4DI (match_operand:V2DI 1 "vsx_register_operand" "wa") + (vec_select:V2DI (match_dup 1) + (parallel [(const_int 1) (const_int 0)])))))] + "VECTOR_UNIT_VSX_P (V4SFmode) && BYTES_BIG_ENDIAN" + "xvcvxdsp %x0,%x1" [(set_attr "type" "vecfloat")]) -(define_insn "vsx_xvcvuxdsp" +(define_insn "vsx_xvcvxdsp_le" [(set (match_operand:V4SF 0 "vsx_register_operand" "=wa") - (unspec:V4SF [(match_operand:V2DI 1 "vsx_register_operand" "wa")] - UNSPEC_VSX_CVUXDSP))] - "VECTOR_UNIT_VSX_P (V2DFmode)" - "xvcvuxdsp %x0,%x1" + (any_float:V4SF + (vec_concat:V4DI + (vec_select:V2DI (match_operand:V2DI 1 "vsx_register_operand" "wa") + (parallel [(const_int 1) (const_int 0)])) + (match_dup 1))))] + "VECTOR_UNIT_VSX_P (V4SFmode) && !BYTES_BIG_ENDIAN" + "xvcvxdsp %x0,%x1" + [(set_attr "type" "vecfloat")]) + +(define_expand "vsx_xvcvxdsp" + [(match_operand:V4SF 0 "vsx_register_operand") + (match_operand:V2DI 1 "vsx_register_operand") + (any_float (pc))] + "VECTOR_UNIT_VSX_P (V4SFmode)" +{ + if (BYTES_BIG_ENDIAN) + emit_insn (gen_vsx_xvcvxdsp_be (operands[0], operands[1])); + else + emit_insn (gen_vsx_xvcvxdsp_le (operands[0], operands[1])); + DONE; +}) + +;; Convert vector of 32-bit signed/unsigned integers to vector of +;; 64-bit floating point numbers. +(define_insn "vsx_xvcvxwdp_be" + [(set (match_operand:V2DF 0 "vsx_register_operand" "=wa") + (any_float:V2DF + (vec_select:V2SI (match_operand:V4SI 1 "vsx_register_operand" "wa") + (parallel [(const_int 0) (const_int 2)]))))] + "VECTOR_UNIT_VSX_P (V2DFmode) && BYTES_BIG_ENDIAN" + "xvcvxwdp %x0,%x1" [(set_attr "type" "vecdouble")]) -;; Convert from 32-bit to 64-bit types -;; Provide both vector and scalar targets -(define_insn "vsx_xvcvsxwdp" +(define_insn "vsx_xvcvxwdp_le" [(set (match_operand:V2DF 0 "vsx_register_operand" "=wa") - (unspec:V2DF [(match_operand:V4SI 1 "vsx_register_operand" "wa")] - UNSPEC_VSX_CVSXWDP))] + (any_float:V2DF + (vec_select:V2SI (match_operand:V4SI 1 "vsx_register_operand" "wa") + (parallel [(const_int 1) (const_int 3)]))))] + "VECTOR_UNIT_VSX_P (V2DFmode) && !BYTES_BIG_ENDIAN" + "xvcvxwdp %x0,%x1" + [(set_attr "type" "vecdouble")]) + +(define_expand "vsx_xvcvxwdp" + [(match_operand:V2DF 0 "vsx_register_operand") + (match_operand:V4SI 1 "vsx_register_operand") + (any_float (pc))] "VECTOR_UNIT_VSX_P (V2DFmode)" - "xvcvsxwdp %x0,%x1" +{ + if (BYTES_BIG_ENDIAN) + emit_insn (gen_vsx_xvcvxwdp_be (operands[0], operands[1])); + else + emit_insn (gen_vsx_xvcvxwdp_le (operands[0], operands[1])); + DONE; +}) + +;; Convert vector of 32-bit floating point numbers to vector of +;; 64-bit signed/unsigned integers. +(define_insn "vsx_xvcvspxds_be" + [(set (match_operand:V2DI 0 "vsx_register_operand" "=v,?wa") + (any_fix:V2DI + (vec_select:V2SF (match_operand:V4SF 1 "vsx_register_operand" "wa,wa") + (parallel [(const_int 0) (const_int 2)]))))] + "VECTOR_UNIT_VSX_P (V2DFmode) && BYTES_BIG_ENDIAN" + "xvcvspxds %x0,%x1" + [(set_attr "type" "vecdouble")]) + +(define_insn "vsx_xvcvspxds_le" + [(set (match_operand:V2DI 0 "vsx_register_operand" "=v,?wa") + (any_fix:V2DI + (vec_select:V2SF (match_operand:V4SF 1 "vsx_register_operand" "wa,wa") + (parallel [(const_int 1) (const_int 3)]))))] + "VECTOR_UNIT_VSX_P (V2DFmode) && !BYTES_BIG_ENDIAN" + "xvcvspxds %x0,%x1" [(set_attr "type" "vecdouble")]) +(define_expand "vsx_xvcvspxds" + [(match_operand:V2DI 0 "vsx_register_operand") + (match_operand:V4SF 1 "vsx_register_operand") + (any_fix (pc))] + "VECTOR_UNIT_VSX_P (V2DFmode)" +{ + if (BYTES_BIG_ENDIAN) + emit_insn (gen_vsx_xvcvspxds_be (operands[0], operands[1])); + else + emit_insn (gen_vsx_xvcvspxds_le (operands[0], operands[1])); + DONE; +}) + (define_insn "vsx_xvcvsxwdp_df" [(set (match_operand:DF 0 "vsx_register_operand" "=wa") (unspec:DF [(match_operand:V4SI 1 "vsx_register_operand" "wa")] @@ -2351,14 +2489,6 @@ "xvcvsxwdp %x0,%x1" [(set_attr "type" "vecdouble")]) -(define_insn "vsx_xvcvuxwdp" - [(set (match_operand:V2DF 0 "vsx_register_operand" "=wa") - (unspec:V2DF [(match_operand:V4SI 1 "vsx_register_operand" "wa")] - UNSPEC_VSX_CVUXWDP))] - "VECTOR_UNIT_VSX_P (V2DFmode)" - "xvcvuxwdp %x0,%x1" - [(set_attr "type" "vecdouble")]) - (define_insn "vsx_xvcvuxwdp_df" [(set (match_operand:DF 0 "vsx_register_operand" "=wa") (unspec:DF [(match_operand:V4SI 1 "vsx_register_operand" "wa")] @@ -2367,22 +2497,6 @@ "xvcvuxwdp %x0,%x1" [(set_attr "type" "vecdouble")]) -(define_insn "vsx_xvcvspsxds" - [(set (match_operand:V2DI 0 "vsx_register_operand" "=v,?wa") - (unspec:V2DI [(match_operand:V4SF 1 "vsx_register_operand" "wa,wa")] - UNSPEC_VSX_CVSPSXDS))] - "VECTOR_UNIT_VSX_P (V2DFmode)" - "xvcvspsxds %x0,%x1" - [(set_attr "type" "vecdouble")]) - -(define_insn "vsx_xvcvspuxds" - [(set (match_operand:V2DI 0 "vsx_register_operand" "=v,?wa") - (unspec:V2DI [(match_operand:V4SF 1 "vsx_register_operand" "wa,wa")] - UNSPEC_VSX_CVSPUXDS))] - "VECTOR_UNIT_VSX_P (V2DFmode)" - "xvcvspuxds %x0,%x1" - [(set_attr "type" "vecdouble")]) - ;; Generate float2 double ;; convert two double to float (define_expand "float2_v2df" -- 2.7.4