+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.
+
2014-09-02 Kyrylo Tkachov <kyrylo.tkachov@arm.com>
PR target/62275
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)
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,
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[]);
#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
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
UNSPEC_VSX_DIVSD
UNSPEC_VSX_DIVUD
UNSPEC_VSX_MULSD
+ UNSPEC_VSX_XVCVSXDDP
+ UNSPEC_VSX_XVCVUXDDP
+ UNSPEC_VSX_XVCVDPSXDS
+ UNSPEC_VSX_XVCVDPUXDS
])
;; VSX moves
"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.
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);
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);
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 *);
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);
+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.
+
2014-09-02 Hans-Peter Nilsson <hp@axis.com>
* g++.old-deja/g++.eh/badalloc1.C [!STACK_SIZE && !__FreeBSD__]
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;
}
|| 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;
}