diff options
author | Bill Schmidt <wschmidt@linux.vnet.ibm.com> | 2014-09-02 19:31:47 +0000 |
---|---|---|
committer | William Schmidt <wschmidt@gcc.gnu.org> | 2014-09-02 19:31:47 +0000 |
commit | 70f0f8b2b1c9bf53b9158e4264bc1e93b963c31e (patch) | |
tree | 87d4cbb1d8d6767a5af7c52d897c5a7f5bc64527 /gcc/config | |
parent | bb42f96863d48ea9a091e993c10c10f902035c9d (diff) | |
download | gcc-70f0f8b2b1c9bf53b9158e4264bc1e93b963c31e.zip gcc-70f0f8b2b1c9bf53b9158e4264bc1e93b963c31e.tar.gz gcc-70f0f8b2b1c9bf53b9158e4264bc1e93b963c31e.tar.bz2 |
rs6000-builtin.def (XVCVSXDDP_SCALE): New built-in definition.
[gcc]
2014-09-02 Bill Schmidt <wschmidt@linux.vnet.ibm.com>
* config/rs6000/rs6000-builtin.def (XVCVSXDDP_SCALE): New
built-in definition.
(XVCVUXDDP_SCALE): Likewise.
(XVCVDPSXDS_SCALE): Likewise.
(XVCVDPUXDS_SCALE): Likewise.
* config/rs6000/rs6000-c.c (altivec_overloaded_builtins): Add
entries for VSX_BUILTIN_XVCVSXDDP_SCALE,
VSX_BUILTIN_XVCVUXDDP_SCALE, VSX_BUILTIN_XVCVDPSXDS_SCALE, and
VSX_BUILTIN_XVCVDPUXDS_SCALE.
* config/rs6000/rs6000-protos.h (rs6000_scale_v2df): New
prototype.
* config/rs6000/rs6000.c (real.h): New include.
(rs6000_scale_v2df): New function.
* config/rs6000/vsx.md (UNSPEC_VSX_XVCVSXDDP): New unspec.
(UNSPEC_VSX_XVCVUXDDP): Likewise.
(UNSPEC_VSX_XVCVDPSXDS): Likewise.
(UNSPEC_VSX_XVCVDPUXDS): Likewise.
(vsx_xvcvsxddp_scale): New define_expand.
(vsx_xvcvsxddp): New define_insn.
(vsx_xvcvuxddp_scale): New define_expand.
(vsx_xvcvuxddp): New define_insn.
(vsx_xvcvdpsxds_scale): New define_expand.
(vsx_xvcvdpsxds): New define_insn.
(vsx_xvcvdpuxds_scale): New define_expand.
(vsx_xvcvdpuxds): New define_insn.
* doc/extend.texi (vec_ctf): Add new prototypes.
(vec_cts): Likewise.
(vec_ctu): Likewise.
(vec_splat): Likewise.
(vec_div): Likewise.
(vec_mul): Likewise.
[gcc/testsuite]
2014-09-02 Bill Schmidt <wschmidt@linux.vnet.ibm.com>
* gcc.target/powerpc/builtins-1.c: Add tests for vec_ctf,
vec_cts, and vec_ctu.
* gcc.target/powerpc/builtins-2.c: Likewise.
From-SVN: r214831
Diffstat (limited to 'gcc/config')
-rw-r--r-- | gcc/config/rs6000/rs6000-builtin.def | 5 | ||||
-rw-r--r-- | gcc/config/rs6000/rs6000-c.c | 8 | ||||
-rw-r--r-- | gcc/config/rs6000/rs6000-protos.h | 1 | ||||
-rw-r--r-- | gcc/config/rs6000/rs6000.c | 18 | ||||
-rw-r--r-- | gcc/config/rs6000/vsx.md | 100 |
5 files changed, 132 insertions, 0 deletions
diff --git a/gcc/config/rs6000/rs6000-builtin.def b/gcc/config/rs6000/rs6000-builtin.def index c088a1d..9bb8703 100644 --- a/gcc/config/rs6000/rs6000-builtin.def +++ b/gcc/config/rs6000/rs6000-builtin.def @@ -1264,6 +1264,11 @@ BU_VSX_2 (DIV_V2DI, "div_2di", CONST, vsx_div_v2di) BU_VSX_2 (UDIV_V2DI, "udiv_2di", CONST, vsx_udiv_v2di) BU_VSX_2 (MUL_V2DI, "mul_2di", CONST, vsx_mul_v2di) +BU_VSX_2 (XVCVSXDDP_SCALE, "xvcvsxddp_scale", CONST, vsx_xvcvsxddp_scale) +BU_VSX_2 (XVCVUXDDP_SCALE, "xvcvuxddp_scale", CONST, vsx_xvcvuxddp_scale) +BU_VSX_2 (XVCVDPSXDS_SCALE, "xvcvdpsxds_scale", CONST, vsx_xvcvdpsxds_scale) +BU_VSX_2 (XVCVDPUXDS_SCALE, "xvcvdpuxds_scale", CONST, vsx_xvcvdpuxds_scale) + /* VSX abs builtin functions. */ BU_VSX_A (XVABSDP, "xvabsdp", CONST, absv2df2) BU_VSX_A (XVNABSDP, "xvnabsdp", CONST, vsx_nabsv2df2) diff --git a/gcc/config/rs6000/rs6000-c.c b/gcc/config/rs6000/rs6000-c.c index 912e128..470efc5 100644 --- a/gcc/config/rs6000/rs6000-c.c +++ b/gcc/config/rs6000/rs6000-c.c @@ -1151,14 +1151,22 @@ const struct altivec_builtin_types altivec_overloaded_builtins[] = { RS6000_BTI_V4SF, RS6000_BTI_unsigned_V4SI, RS6000_BTI_INTSI, 0 }, { ALTIVEC_BUILTIN_VEC_CTF, ALTIVEC_BUILTIN_VCFSX, RS6000_BTI_V4SF, RS6000_BTI_V4SI, RS6000_BTI_INTSI, 0 }, + { ALTIVEC_BUILTIN_VEC_CTF, VSX_BUILTIN_XVCVSXDDP_SCALE, + RS6000_BTI_V2DF, RS6000_BTI_V2DI, RS6000_BTI_INTSI, 0}, + { ALTIVEC_BUILTIN_VEC_CTF, VSX_BUILTIN_XVCVUXDDP_SCALE, + RS6000_BTI_V2DF, RS6000_BTI_unsigned_V2DI, RS6000_BTI_INTSI, 0}, { ALTIVEC_BUILTIN_VEC_VCFSX, ALTIVEC_BUILTIN_VCFSX, RS6000_BTI_V4SF, RS6000_BTI_V4SI, RS6000_BTI_INTSI, 0 }, { ALTIVEC_BUILTIN_VEC_VCFUX, ALTIVEC_BUILTIN_VCFUX, RS6000_BTI_V4SF, RS6000_BTI_unsigned_V4SI, RS6000_BTI_INTSI, 0 }, { ALTIVEC_BUILTIN_VEC_CTS, ALTIVEC_BUILTIN_VCTSXS, RS6000_BTI_V4SI, RS6000_BTI_V4SF, RS6000_BTI_INTSI, 0 }, + { ALTIVEC_BUILTIN_VEC_CTS, VSX_BUILTIN_XVCVDPSXDS_SCALE, + RS6000_BTI_V2DI, RS6000_BTI_V2DF, RS6000_BTI_INTSI, 0 }, { ALTIVEC_BUILTIN_VEC_CTU, ALTIVEC_BUILTIN_VCTUXS, RS6000_BTI_unsigned_V4SI, RS6000_BTI_V4SF, RS6000_BTI_INTSI, 0 }, + { ALTIVEC_BUILTIN_VEC_CTU, VSX_BUILTIN_XVCVDPUXDS_SCALE, + RS6000_BTI_unsigned_V2DI, RS6000_BTI_V2DF, RS6000_BTI_INTSI, 0 }, { VSX_BUILTIN_VEC_DIV, VSX_BUILTIN_XVDIVSP, RS6000_BTI_V4SF, RS6000_BTI_V4SF, RS6000_BTI_V4SF, 0 }, { VSX_BUILTIN_VEC_DIV, VSX_BUILTIN_XVDIVDP, diff --git a/gcc/config/rs6000/rs6000-protos.h b/gcc/config/rs6000/rs6000-protos.h index 1653b92..b3a1a0a 100644 --- a/gcc/config/rs6000/rs6000-protos.h +++ b/gcc/config/rs6000/rs6000-protos.h @@ -65,6 +65,7 @@ extern void altivec_expand_stvx_be (rtx, rtx, enum machine_mode, unsigned); extern void altivec_expand_stvex_be (rtx, rtx, enum machine_mode, unsigned); extern void rs6000_expand_extract_even (rtx, rtx, rtx); extern void rs6000_expand_interleave (rtx, rtx, rtx, bool); +extern void rs6000_scale_v2df (rtx, rtx, int); extern void build_mask64_2_operands (rtx, rtx *); extern int expand_block_clear (rtx[]); extern int expand_block_move (rtx[]); diff --git a/gcc/config/rs6000/rs6000.c b/gcc/config/rs6000/rs6000.c index 5b1aa554..19b2be2 100644 --- a/gcc/config/rs6000/rs6000.c +++ b/gcc/config/rs6000/rs6000.c @@ -81,6 +81,7 @@ #include "builtins.h" #include "context.h" #include "tree-pass.h" +#include "real.h" #if TARGET_XCOFF #include "xcoffout.h" /* get declarations of xcoff_*_section_name */ #endif @@ -31250,6 +31251,23 @@ rs6000_expand_interleave (rtx target, rtx op0, rtx op1, bool highp) rs6000_do_expand_vec_perm (target, op0, op1, vmode, nelt, perm); } +/* Scale a V2DF vector SRC by two to the SCALE and place in TGT. */ +void +rs6000_scale_v2df (rtx tgt, rtx src, int scale) +{ + HOST_WIDE_INT hwi_scale (scale); + REAL_VALUE_TYPE r_pow; + rtvec v = rtvec_alloc (2); + rtx elt; + rtx scale_vec = gen_reg_rtx (V2DFmode); + (void)real_powi (&r_pow, DFmode, &dconst2, hwi_scale); + elt = CONST_DOUBLE_FROM_REAL_VALUE (r_pow, DFmode); + RTVEC_ELT (v, 0) = elt; + RTVEC_ELT (v, 1) = elt; + rs6000_expand_vector_init (scale_vec, gen_rtx_PARALLEL (V2DFmode, v)); + emit_insn (gen_mulv2df3 (tgt, src, scale_vec)); +} + /* Return an RTX representing where to find the function value of a function returning MODE. */ static rtx diff --git a/gcc/config/rs6000/vsx.md b/gcc/config/rs6000/vsx.md index 598acb3..922471f 100644 --- a/gcc/config/rs6000/vsx.md +++ b/gcc/config/rs6000/vsx.md @@ -264,6 +264,10 @@ UNSPEC_VSX_DIVSD UNSPEC_VSX_DIVUD UNSPEC_VSX_MULSD + UNSPEC_VSX_XVCVSXDDP + UNSPEC_VSX_XVCVUXDDP + UNSPEC_VSX_XVCVDPSXDS + UNSPEC_VSX_XVCVDPUXDS ]) ;; VSX moves @@ -1356,6 +1360,102 @@ "xscvspdpn %x0,%x1" [(set_attr "type" "fp")]) +;; Convert and scale (used by vec_ctf, vec_cts, vec_ctu for double/long long) + +(define_expand "vsx_xvcvsxddp_scale" + [(match_operand:V2DF 0 "vsx_register_operand" "") + (match_operand:V2DI 1 "vsx_register_operand" "") + (match_operand:QI 2 "immediate_operand" "")] + "VECTOR_UNIT_VSX_P (V2DFmode)" +{ + rtx op0 = operands[0]; + rtx op1 = operands[1]; + int scale = INTVAL(operands[2]); + emit_insn (gen_vsx_xvcvsxddp (op0, op1)); + if (scale != 0) + rs6000_scale_v2df (op0, op0, -scale); + DONE; +}) + +(define_insn "vsx_xvcvsxddp" + [(set (match_operand:V2DF 0 "vsx_register_operand" "=wa") + (unspec:V2DF [(match_operand:V2DI 1 "vsx_register_operand" "wa")] + UNSPEC_VSX_XVCVSXDDP))] + "VECTOR_UNIT_VSX_P (V2DFmode)" + "xvcvsxddp %x0,%x1" + [(set_attr "type" "vecdouble")]) + +(define_expand "vsx_xvcvuxddp_scale" + [(match_operand:V2DF 0 "vsx_register_operand" "") + (match_operand:V2DI 1 "vsx_register_operand" "") + (match_operand:QI 2 "immediate_operand" "")] + "VECTOR_UNIT_VSX_P (V2DFmode)" +{ + rtx op0 = operands[0]; + rtx op1 = operands[1]; + int scale = INTVAL(operands[2]); + emit_insn (gen_vsx_xvcvuxddp (op0, op1)); + if (scale != 0) + rs6000_scale_v2df (op0, op0, -scale); + DONE; +}) + +(define_insn "vsx_xvcvuxddp" + [(set (match_operand:V2DF 0 "vsx_register_operand" "=wa") + (unspec:V2DF [(match_operand:V2DI 1 "vsx_register_operand" "wa")] + UNSPEC_VSX_XVCVUXDDP))] + "VECTOR_UNIT_VSX_P (V2DFmode)" + "xvcvuxddp %x0,%x1" + [(set_attr "type" "vecdouble")]) + +(define_expand "vsx_xvcvdpsxds_scale" + [(match_operand:V2DI 0 "vsx_register_operand" "") + (match_operand:V2DF 1 "vsx_register_operand" "") + (match_operand:QI 2 "immediate_operand" "")] + "VECTOR_UNIT_VSX_P (V2DFmode)" +{ + rtx op0 = operands[0]; + rtx op1 = operands[1]; + rtx tmp = gen_reg_rtx (V2DFmode); + int scale = INTVAL(operands[2]); + if (scale != 0) + rs6000_scale_v2df (tmp, op1, scale); + emit_insn (gen_vsx_xvcvdpsxds (op0, tmp)); + DONE; +}) + +(define_insn "vsx_xvcvdpsxds" + [(set (match_operand:V2DI 0 "vsx_register_operand" "=wa") + (unspec:V2DI [(match_operand:V2DF 1 "vsx_register_operand" "wa")] + UNSPEC_VSX_XVCVDPSXDS))] + "VECTOR_UNIT_VSX_P (V2DFmode)" + "xvcvdpsxds %x0,%x1" + [(set_attr "type" "vecdouble")]) + +(define_expand "vsx_xvcvdpuxds_scale" + [(match_operand:V2DI 0 "vsx_register_operand" "") + (match_operand:V2DF 1 "vsx_register_operand" "") + (match_operand:QI 2 "immediate_operand" "")] + "VECTOR_UNIT_VSX_P (V2DFmode)" +{ + rtx op0 = operands[0]; + rtx op1 = operands[1]; + rtx tmp = gen_reg_rtx (V2DFmode); + int scale = INTVAL(operands[2]); + if (scale != 0) + rs6000_scale_v2df (tmp, op1, scale); + emit_insn (gen_vsx_xvcvdpuxds (op0, tmp)); + DONE; +}) + +(define_insn "vsx_xvcvdpuxds" + [(set (match_operand:V2DI 0 "vsx_register_operand" "=wa") + (unspec:V2DI [(match_operand:V2DF 1 "vsx_register_operand" "wa")] + UNSPEC_VSX_XVCVDPUXDS))] + "VECTOR_UNIT_VSX_P (V2DFmode)" + "xvcvdpuxds %x0,%x1" + [(set_attr "type" "vecdouble")]) + ;; Convert from 64-bit to 32-bit types ;; 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. |