From 70f0f8b2b1c9bf53b9158e4264bc1e93b963c31e Mon Sep 17 00:00:00 2001 From: Bill Schmidt Date: Tue, 2 Sep 2014 19:31:47 +0000 Subject: [PATCH] rs6000-builtin.def (XVCVSXDDP_SCALE): New built-in definition. [gcc] 2014-09-02 Bill Schmidt * 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 * 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 --- gcc/ChangeLog | 34 ++++++ gcc/config/rs6000/rs6000-builtin.def | 5 + gcc/config/rs6000/rs6000-c.c | 8 ++ gcc/config/rs6000/rs6000-protos.h | 1 + gcc/config/rs6000/rs6000.c | 18 ++++ gcc/config/rs6000/vsx.md | 100 ++++++++++++++++++ gcc/doc/extend.texi | 10 ++ gcc/testsuite/ChangeLog | 6 ++ gcc/testsuite/gcc.target/powerpc/builtins-1.c | 5 + gcc/testsuite/gcc.target/powerpc/builtins-2.c | 9 ++ 10 files changed, 196 insertions(+) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 7bfbd5a3108..b60054b18f6 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,37 @@ +2014-09-02 Bill Schmidt + + * 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. + 2014-09-02 Kyrylo Tkachov PR target/62275 diff --git a/gcc/config/rs6000/rs6000-builtin.def b/gcc/config/rs6000/rs6000-builtin.def index c088a1d8c36..9bb8703949c 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 912e1289f98..470efc5a140 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 1653b92a64d..b3a1a0a2b09 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 5b1aa5540a4..19b2be27335 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 598acb3fc50..922471fe292 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. diff --git a/gcc/doc/extend.texi b/gcc/doc/extend.texi index ba8bf02838c..4eef9001820 100644 --- a/gcc/doc/extend.texi +++ b/gcc/doc/extend.texi @@ -13882,14 +13882,18 @@ vector float vec_cpsgn (vector float, vector float); vector float vec_ctf (vector unsigned int, const int); vector float vec_ctf (vector signed int, const int); +vector double vec_ctf (vector unsigned long, const int); +vector double vec_ctf (vector signed long, const int); vector float vec_vcfsx (vector signed int, const int); vector float vec_vcfux (vector unsigned int, const int); vector signed int vec_cts (vector float, const int); +vector signed long vec_cts (vector double, const int); vector unsigned int vec_ctu (vector float, const int); +vector unsigned long vec_ctu (vector double, const int); void vec_dss (const int); @@ -14725,6 +14729,8 @@ vector float vec_splat (vector float, const int); vector signed int vec_splat (vector signed int, const int); vector unsigned int vec_splat (vector unsigned int, const int); vector bool int vec_splat (vector bool int, const int); +vector signed long vec_splat (vector signed long, const int); +vector unsigned long vec_splat (vector unsigned long, const int); vector signed char vec_splats (signed char); vector unsigned char vec_splats (unsigned char); @@ -15461,6 +15467,8 @@ vector bool long vec_cmplt (vector double, vector double); vector double vec_cpsgn (vector double, vector double); vector float vec_div (vector float, vector float); vector double vec_div (vector double, vector double); +vector long vec_div (vector long, vector long); +vector unsigned long vec_div (vector unsigned long, vector unsigned long); vector double vec_floor (vector double); vector double vec_ld (int, const vector double *); vector double vec_ld (int, const double *); @@ -15487,6 +15495,8 @@ vector float vec_msub (vector float, vector float, vector float); vector double vec_msub (vector double, vector double, vector double); vector float vec_mul (vector float, vector float); vector double vec_mul (vector double, vector double); +vector long vec_mul (vector long, vector long); +vector unsigned long vec_mul (vector unsigned long, vector unsigned long); vector float vec_nearbyint (vector float); vector double vec_nearbyint (vector double); vector float vec_nmadd (vector float, vector float, vector float); diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 0be30a7bf52..c36316ccbf7 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,9 @@ +2014-09-02 Bill Schmidt + + * gcc.target/powerpc/builtins-1.c: Add tests for vec_ctf, + vec_cts, and vec_ctu. + * gcc.target/powerpc/builtins-2.c: Likewise. + 2014-09-02 Hans-Peter Nilsson * g++.old-deja/g++.eh/badalloc1.C [!STACK_SIZE && !__FreeBSD__] diff --git a/gcc/testsuite/gcc.target/powerpc/builtins-1.c b/gcc/testsuite/gcc.target/powerpc/builtins-1.c index 0674d9732a5..3da714698d6 100644 --- a/gcc/testsuite/gcc.target/powerpc/builtins-1.c +++ b/gcc/testsuite/gcc.target/powerpc/builtins-1.c @@ -157,5 +157,10 @@ int main () vector long long l8 = vec_mul (l3, l4); vector unsigned long long u6 = vec_mul (u3, u4); + vector double dh = vec_ctf (la, -2); + vector double di = vec_ctf (ua, 2); + vector long long l9 = vec_cts (dh, -2); + vector unsigned long long u7 = vec_ctu (di, 2); + return 0; } diff --git a/gcc/testsuite/gcc.target/powerpc/builtins-2.c b/gcc/testsuite/gcc.target/powerpc/builtins-2.c index 853e2a93d2d..7f4a3924efd 100644 --- a/gcc/testsuite/gcc.target/powerpc/builtins-2.c +++ b/gcc/testsuite/gcc.target/powerpc/builtins-2.c @@ -34,5 +34,14 @@ int main () || ue[0] != 27L || ue[1] != 27L || uf[0] != 14L || uf[1] != 14L) abort (); + vector double da = vec_ctf (sa, -2); + vector double db = vec_ctf (ua, 2); + vector long long sg = vec_cts (da, -2); + vector unsigned long long ug = vec_ctu (db, 2); + + if (da[0] != 108.0 || da[1] != -56.0 || db[0] != 6.75 || db[1] != 3.5 + || sg[0] != 27L || sg[1] != -14L || ug[0] != 27L || ug[1] != 14L) + abort (); + return 0; } -- 2.30.2