+2015-11-17 Richard Sandiford <richard.sandiford@arm.com>
+
+ * target.def (builtin_vectorized_function): Take a combined_fn (in
+ the form of an unsigned int) rather than a function decl.
+ (builtin_md_vectorized_function): New.
+ * targhooks.h (default_builtin_vectorized_function): Replace the
+ fndecl argument with an unsigned int.
+ (default_builtin_md_vectorized_function): Declare.
+ * targhooks.c (default_builtin_vectorized_function): Replace the
+ fndecl argument with an unsigned int.
+ (default_builtin_md_vectorized_function): New function.
+ * doc/tm.texi.in (TARGET_VECTORIZE_BUILTIN_MD_VECTORIZED_FUNCTION):
+ New hook.
+ * doc/tm.texi: Regenerate.
+ * tree-vect-stmts.c (vectorizable_function): Update call to
+ builtin_vectorized_function, also passing internal functions.
+ Call builtin_md_vectorized_function for target-specific builtins.
+ * config/aarch64/aarch64-protos.h
+ (aarch64_builtin_vectorized_function): Replace fndecl argument
+ with an unsigned int.
+ * config/aarch64/aarch64-builtins.c: Include case-cfn-macros.h.
+ (aarch64_builtin_vectorized_function): Update after above changes.
+ Use CASE_CFN_*.
+ * config/arm/arm-protos.h (arm_builtin_vectorized_function): Replace
+ fndecl argument with an unsigned int.
+ * config/arm/arm-builtins.c: Include case-cfn-macros.h
+ (arm_builtin_vectorized_function): Update after above changes.
+ Use CASE_CFN_*.
+ * config/i386/i386.c: Include case-cfn-macros.h
+ (ix86_veclib_handler): Take a combined_fn rather than a
+ built_in_function.
+ (ix86_veclibabi_svml, ix86_veclibabi_acml): Likewise. Use
+ mathfn_built_in rather than calling builtin_decl_implicit directly.
+ (ix86_builtin_vectorized_function) Update after above changes.
+ Use CASE_CFN_*.
+ * config/rs6000/rs6000.c: Include case-cfn-macros.h
+ (rs6000_builtin_vectorized_libmass): Replace fndecl argument
+ with a combined_fn. Use CASE_CFN_*. Use mathfn_built_in rather
+ than calling builtin_decl_implicit directly.
+ (rs6000_builtin_vectorized_function): Update after above changes.
+ Use CASE_CFN_*. Move BUILT_IN_MD to...
+ (rs6000_builtin_md_vectorized_function): ...this new function.
+ (TARGET_VECTORIZE_BUILTIN_MD_VECTORIZED_FUNCTION): Define.
+
2015-11-17 Richard Sandiford <richard.sandiford@arm.com>
* tree-vect-patterns.c: Include internal-fn.h.
#include "expr.h"
#include "langhooks.h"
#include "gimple-iterator.h"
+#include "case-cfn-macros.h"
#define v8qi_UP V8QImode
#define v4hi_UP V4HImode
}
tree
-aarch64_builtin_vectorized_function (tree fndecl, tree type_out, tree type_in)
+aarch64_builtin_vectorized_function (unsigned int fn, tree type_out,
+ tree type_in)
{
machine_mode in_mode, out_mode;
int in_n, out_n;
: (AARCH64_CHECK_BUILTIN_MODE (2, S) \
? aarch64_builtin_decls[AARCH64_SIMD_BUILTIN_UNOP_##N##v2sf] \
: NULL_TREE)))
- if (DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_NORMAL)
+ switch (fn)
{
- enum built_in_function fn = DECL_FUNCTION_CODE (fndecl);
- switch (fn)
- {
#undef AARCH64_CHECK_BUILTIN_MODE
#define AARCH64_CHECK_BUILTIN_MODE(C, N) \
(out_mode == N##Fmode && out_n == C \
&& in_mode == N##Fmode && in_n == C)
- case BUILT_IN_FLOOR:
- case BUILT_IN_FLOORF:
- return AARCH64_FIND_FRINT_VARIANT (floor);
- case BUILT_IN_CEIL:
- case BUILT_IN_CEILF:
- return AARCH64_FIND_FRINT_VARIANT (ceil);
- case BUILT_IN_TRUNC:
- case BUILT_IN_TRUNCF:
- return AARCH64_FIND_FRINT_VARIANT (btrunc);
- case BUILT_IN_ROUND:
- case BUILT_IN_ROUNDF:
- return AARCH64_FIND_FRINT_VARIANT (round);
- case BUILT_IN_NEARBYINT:
- case BUILT_IN_NEARBYINTF:
- return AARCH64_FIND_FRINT_VARIANT (nearbyint);
- case BUILT_IN_SQRT:
- case BUILT_IN_SQRTF:
- return AARCH64_FIND_FRINT_VARIANT (sqrt);
+ CASE_CFN_FLOOR:
+ return AARCH64_FIND_FRINT_VARIANT (floor);
+ CASE_CFN_CEIL:
+ return AARCH64_FIND_FRINT_VARIANT (ceil);
+ CASE_CFN_TRUNC:
+ return AARCH64_FIND_FRINT_VARIANT (btrunc);
+ CASE_CFN_ROUND:
+ return AARCH64_FIND_FRINT_VARIANT (round);
+ CASE_CFN_NEARBYINT:
+ return AARCH64_FIND_FRINT_VARIANT (nearbyint);
+ CASE_CFN_SQRT:
+ return AARCH64_FIND_FRINT_VARIANT (sqrt);
#undef AARCH64_CHECK_BUILTIN_MODE
#define AARCH64_CHECK_BUILTIN_MODE(C, N) \
(out_mode == SImode && out_n == C \
&& in_mode == N##Imode && in_n == C)
- case BUILT_IN_CLZ:
- {
- if (AARCH64_CHECK_BUILTIN_MODE (4, S))
- return aarch64_builtin_decls[AARCH64_SIMD_BUILTIN_UNOP_clzv4si];
- return NULL_TREE;
- }
- case BUILT_IN_CTZ:
- {
- if (AARCH64_CHECK_BUILTIN_MODE (2, S))
- return aarch64_builtin_decls[AARCH64_SIMD_BUILTIN_UNOP_ctzv2si];
- else if (AARCH64_CHECK_BUILTIN_MODE (4, S))
- return aarch64_builtin_decls[AARCH64_SIMD_BUILTIN_UNOP_ctzv4si];
- return NULL_TREE;
- }
+ CASE_CFN_CLZ:
+ {
+ if (AARCH64_CHECK_BUILTIN_MODE (4, S))
+ return aarch64_builtin_decls[AARCH64_SIMD_BUILTIN_UNOP_clzv4si];
+ return NULL_TREE;
+ }
+ CASE_CFN_CTZ:
+ {
+ if (AARCH64_CHECK_BUILTIN_MODE (2, S))
+ return aarch64_builtin_decls[AARCH64_SIMD_BUILTIN_UNOP_ctzv2si];
+ else if (AARCH64_CHECK_BUILTIN_MODE (4, S))
+ return aarch64_builtin_decls[AARCH64_SIMD_BUILTIN_UNOP_ctzv4si];
+ return NULL_TREE;
+ }
#undef AARCH64_CHECK_BUILTIN_MODE
#define AARCH64_CHECK_BUILTIN_MODE(C, N) \
(out_mode == N##Imode && out_n == C \
&& in_mode == N##Fmode && in_n == C)
- case BUILT_IN_LFLOOR:
- case BUILT_IN_LFLOORF:
- case BUILT_IN_LLFLOOR:
- case BUILT_IN_IFLOORF:
- {
- enum aarch64_builtins builtin;
- if (AARCH64_CHECK_BUILTIN_MODE (2, D))
- builtin = AARCH64_SIMD_BUILTIN_UNOP_lfloorv2dfv2di;
- else if (AARCH64_CHECK_BUILTIN_MODE (4, S))
- builtin = AARCH64_SIMD_BUILTIN_UNOP_lfloorv4sfv4si;
- else if (AARCH64_CHECK_BUILTIN_MODE (2, S))
- builtin = AARCH64_SIMD_BUILTIN_UNOP_lfloorv2sfv2si;
- else
- return NULL_TREE;
-
- return aarch64_builtin_decls[builtin];
- }
- case BUILT_IN_LCEIL:
- case BUILT_IN_LCEILF:
- case BUILT_IN_LLCEIL:
- case BUILT_IN_ICEILF:
- {
- enum aarch64_builtins builtin;
- if (AARCH64_CHECK_BUILTIN_MODE (2, D))
- builtin = AARCH64_SIMD_BUILTIN_UNOP_lceilv2dfv2di;
- else if (AARCH64_CHECK_BUILTIN_MODE (4, S))
- builtin = AARCH64_SIMD_BUILTIN_UNOP_lceilv4sfv4si;
- else if (AARCH64_CHECK_BUILTIN_MODE (2, S))
- builtin = AARCH64_SIMD_BUILTIN_UNOP_lceilv2sfv2si;
- else
- return NULL_TREE;
-
- return aarch64_builtin_decls[builtin];
- }
- case BUILT_IN_LROUND:
- case BUILT_IN_IROUNDF:
- {
- enum aarch64_builtins builtin;
- if (AARCH64_CHECK_BUILTIN_MODE (2, D))
- builtin = AARCH64_SIMD_BUILTIN_UNOP_lroundv2dfv2di;
- else if (AARCH64_CHECK_BUILTIN_MODE (4, S))
- builtin = AARCH64_SIMD_BUILTIN_UNOP_lroundv4sfv4si;
- else if (AARCH64_CHECK_BUILTIN_MODE (2, S))
- builtin = AARCH64_SIMD_BUILTIN_UNOP_lroundv2sfv2si;
- else
- return NULL_TREE;
-
- return aarch64_builtin_decls[builtin];
- }
- case BUILT_IN_BSWAP16:
+ CASE_CFN_IFLOOR:
+ CASE_CFN_LFLOOR:
+ CASE_CFN_LLFLOOR:
+ {
+ enum aarch64_builtins builtin;
+ if (AARCH64_CHECK_BUILTIN_MODE (2, D))
+ builtin = AARCH64_SIMD_BUILTIN_UNOP_lfloorv2dfv2di;
+ else if (AARCH64_CHECK_BUILTIN_MODE (4, S))
+ builtin = AARCH64_SIMD_BUILTIN_UNOP_lfloorv4sfv4si;
+ else if (AARCH64_CHECK_BUILTIN_MODE (2, S))
+ builtin = AARCH64_SIMD_BUILTIN_UNOP_lfloorv2sfv2si;
+ else
+ return NULL_TREE;
+
+ return aarch64_builtin_decls[builtin];
+ }
+ CASE_CFN_ICEIL:
+ CASE_CFN_LCEIL:
+ CASE_CFN_LLCEIL:
+ {
+ enum aarch64_builtins builtin;
+ if (AARCH64_CHECK_BUILTIN_MODE (2, D))
+ builtin = AARCH64_SIMD_BUILTIN_UNOP_lceilv2dfv2di;
+ else if (AARCH64_CHECK_BUILTIN_MODE (4, S))
+ builtin = AARCH64_SIMD_BUILTIN_UNOP_lceilv4sfv4si;
+ else if (AARCH64_CHECK_BUILTIN_MODE (2, S))
+ builtin = AARCH64_SIMD_BUILTIN_UNOP_lceilv2sfv2si;
+ else
+ return NULL_TREE;
+
+ return aarch64_builtin_decls[builtin];
+ }
+ CASE_CFN_IROUND:
+ CASE_CFN_LROUND:
+ CASE_CFN_LLROUND:
+ {
+ enum aarch64_builtins builtin;
+ if (AARCH64_CHECK_BUILTIN_MODE (2, D))
+ builtin = AARCH64_SIMD_BUILTIN_UNOP_lroundv2dfv2di;
+ else if (AARCH64_CHECK_BUILTIN_MODE (4, S))
+ builtin = AARCH64_SIMD_BUILTIN_UNOP_lroundv4sfv4si;
+ else if (AARCH64_CHECK_BUILTIN_MODE (2, S))
+ builtin = AARCH64_SIMD_BUILTIN_UNOP_lroundv2sfv2si;
+ else
+ return NULL_TREE;
+
+ return aarch64_builtin_decls[builtin];
+ }
+ case CFN_BUILT_IN_BSWAP16:
#undef AARCH64_CHECK_BUILTIN_MODE
#define AARCH64_CHECK_BUILTIN_MODE(C, N) \
(out_mode == N##Imode && out_n == C \
&& in_mode == N##Imode && in_n == C)
- if (AARCH64_CHECK_BUILTIN_MODE (4, H))
- return aarch64_builtin_decls[AARCH64_SIMD_BUILTIN_UNOPU_bswapv4hi];
- else if (AARCH64_CHECK_BUILTIN_MODE (8, H))
- return aarch64_builtin_decls[AARCH64_SIMD_BUILTIN_UNOPU_bswapv8hi];
- else
- return NULL_TREE;
- case BUILT_IN_BSWAP32:
- if (AARCH64_CHECK_BUILTIN_MODE (2, S))
- return aarch64_builtin_decls[AARCH64_SIMD_BUILTIN_UNOPU_bswapv2si];
- else if (AARCH64_CHECK_BUILTIN_MODE (4, S))
- return aarch64_builtin_decls[AARCH64_SIMD_BUILTIN_UNOPU_bswapv4si];
- else
- return NULL_TREE;
- case BUILT_IN_BSWAP64:
- if (AARCH64_CHECK_BUILTIN_MODE (2, D))
- return aarch64_builtin_decls[AARCH64_SIMD_BUILTIN_UNOPU_bswapv2di];
- else
- return NULL_TREE;
- default:
- return NULL_TREE;
- }
+ if (AARCH64_CHECK_BUILTIN_MODE (4, H))
+ return aarch64_builtin_decls[AARCH64_SIMD_BUILTIN_UNOPU_bswapv4hi];
+ else if (AARCH64_CHECK_BUILTIN_MODE (8, H))
+ return aarch64_builtin_decls[AARCH64_SIMD_BUILTIN_UNOPU_bswapv8hi];
+ else
+ return NULL_TREE;
+ case CFN_BUILT_IN_BSWAP32:
+ if (AARCH64_CHECK_BUILTIN_MODE (2, S))
+ return aarch64_builtin_decls[AARCH64_SIMD_BUILTIN_UNOPU_bswapv2si];
+ else if (AARCH64_CHECK_BUILTIN_MODE (4, S))
+ return aarch64_builtin_decls[AARCH64_SIMD_BUILTIN_UNOPU_bswapv4si];
+ else
+ return NULL_TREE;
+ case CFN_BUILT_IN_BSWAP64:
+ if (AARCH64_CHECK_BUILTIN_MODE (2, D))
+ return aarch64_builtin_decls[AARCH64_SIMD_BUILTIN_UNOPU_bswapv2di];
+ else
+ return NULL_TREE;
+ default:
+ return NULL_TREE;
}
return NULL_TREE;
tree aarch64_builtin_rsqrt (unsigned int, bool);
-tree
-aarch64_builtin_vectorized_function (tree fndecl,
- tree type_out,
- tree type_in);
+tree aarch64_builtin_vectorized_function (unsigned int, tree, tree);
extern void aarch64_split_combinev16qi (rtx operands[3]);
extern void aarch64_expand_vec_perm (rtx target, rtx op0, rtx op1, rtx sel);
#include "explow.h"
#include "expr.h"
#include "langhooks.h"
+#include "case-cfn-macros.h"
#define SIMD_MAX_BUILTIN_ARGS 5
}
tree
-arm_builtin_vectorized_function (tree fndecl, tree type_out, tree type_in)
+arm_builtin_vectorized_function (unsigned int fn, tree type_out, tree type_in)
{
machine_mode in_mode, out_mode;
int in_n, out_n;
? arm_builtin_decl(ARM_BUILTIN_NEON_##N##v4sf, false) \
: NULL_TREE))
- if (DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_NORMAL)
+ switch (fn)
{
- enum built_in_function fn = DECL_FUNCTION_CODE (fndecl);
- switch (fn)
- {
- case BUILT_IN_FLOORF:
- return ARM_FIND_VRINT_VARIANT (vrintm);
- case BUILT_IN_CEILF:
- return ARM_FIND_VRINT_VARIANT (vrintp);
- case BUILT_IN_TRUNCF:
- return ARM_FIND_VRINT_VARIANT (vrintz);
- case BUILT_IN_ROUNDF:
- return ARM_FIND_VRINT_VARIANT (vrinta);
+ CASE_CFN_FLOOR:
+ return ARM_FIND_VRINT_VARIANT (vrintm);
+ CASE_CFN_CEIL:
+ return ARM_FIND_VRINT_VARIANT (vrintp);
+ CASE_CFN_TRUNC:
+ return ARM_FIND_VRINT_VARIANT (vrintz);
+ CASE_CFN_ROUND:
+ return ARM_FIND_VRINT_VARIANT (vrinta);
#undef ARM_CHECK_BUILTIN_MODE_1
#define ARM_CHECK_BUILTIN_MODE_1(C) \
(out_mode == SImode && out_n == C \
: (ARM_CHECK_BUILTIN_MODE (4) \
? arm_builtin_decl(ARM_BUILTIN_NEON_##N##uv4sfv4si, false) \
: NULL_TREE))
- case BUILT_IN_LROUNDF:
- return out_unsigned_p
- ? ARM_FIND_VCVTU_VARIANT (vcvta)
- : ARM_FIND_VCVT_VARIANT (vcvta);
- case BUILT_IN_LCEILF:
- return out_unsigned_p
- ? ARM_FIND_VCVTU_VARIANT (vcvtp)
- : ARM_FIND_VCVT_VARIANT (vcvtp);
- case BUILT_IN_LFLOORF:
- return out_unsigned_p
- ? ARM_FIND_VCVTU_VARIANT (vcvtm)
- : ARM_FIND_VCVT_VARIANT (vcvtm);
+ CASE_CFN_LROUND:
+ return (out_unsigned_p
+ ? ARM_FIND_VCVTU_VARIANT (vcvta)
+ : ARM_FIND_VCVT_VARIANT (vcvta));
+ CASE_CFN_LCEIL:
+ return (out_unsigned_p
+ ? ARM_FIND_VCVTU_VARIANT (vcvtp)
+ : ARM_FIND_VCVT_VARIANT (vcvtp));
+ CASE_CFN_LFLOOR:
+ return (out_unsigned_p
+ ? ARM_FIND_VCVTU_VARIANT (vcvtm)
+ : ARM_FIND_VCVT_VARIANT (vcvtm));
#undef ARM_CHECK_BUILTIN_MODE
#define ARM_CHECK_BUILTIN_MODE(C, N) \
(out_mode == N##mode && out_n == C \
&& in_mode == N##mode && in_n == C)
- case BUILT_IN_BSWAP16:
- if (ARM_CHECK_BUILTIN_MODE (4, HI))
- return arm_builtin_decl (ARM_BUILTIN_NEON_bswapv4hi, false);
- else if (ARM_CHECK_BUILTIN_MODE (8, HI))
- return arm_builtin_decl (ARM_BUILTIN_NEON_bswapv8hi, false);
- else
- return NULL_TREE;
- case BUILT_IN_BSWAP32:
- if (ARM_CHECK_BUILTIN_MODE (2, SI))
- return arm_builtin_decl (ARM_BUILTIN_NEON_bswapv2si, false);
- else if (ARM_CHECK_BUILTIN_MODE (4, SI))
- return arm_builtin_decl (ARM_BUILTIN_NEON_bswapv4si, false);
- else
- return NULL_TREE;
- case BUILT_IN_BSWAP64:
- if (ARM_CHECK_BUILTIN_MODE (2, DI))
- return arm_builtin_decl (ARM_BUILTIN_NEON_bswapv2di, false);
- else
- return NULL_TREE;
- case BUILT_IN_COPYSIGNF:
- if (ARM_CHECK_BUILTIN_MODE (2, SF))
- return arm_builtin_decl (ARM_BUILTIN_NEON_copysignfv2sf, false);
- else if (ARM_CHECK_BUILTIN_MODE (4, SF))
- return arm_builtin_decl (ARM_BUILTIN_NEON_copysignfv4sf, false);
- else
- return NULL_TREE;
-
- default:
- return NULL_TREE;
- }
+ case CFN_BUILT_IN_BSWAP16:
+ if (ARM_CHECK_BUILTIN_MODE (4, HI))
+ return arm_builtin_decl (ARM_BUILTIN_NEON_bswapv4hi, false);
+ else if (ARM_CHECK_BUILTIN_MODE (8, HI))
+ return arm_builtin_decl (ARM_BUILTIN_NEON_bswapv8hi, false);
+ else
+ return NULL_TREE;
+ case CFN_BUILT_IN_BSWAP32:
+ if (ARM_CHECK_BUILTIN_MODE (2, SI))
+ return arm_builtin_decl (ARM_BUILTIN_NEON_bswapv2si, false);
+ else if (ARM_CHECK_BUILTIN_MODE (4, SI))
+ return arm_builtin_decl (ARM_BUILTIN_NEON_bswapv4si, false);
+ else
+ return NULL_TREE;
+ case CFN_BUILT_IN_BSWAP64:
+ if (ARM_CHECK_BUILTIN_MODE (2, DI))
+ return arm_builtin_decl (ARM_BUILTIN_NEON_bswapv2di, false);
+ else
+ return NULL_TREE;
+ CASE_CFN_COPYSIGN:
+ if (ARM_CHECK_BUILTIN_MODE (2, SF))
+ return arm_builtin_decl (ARM_BUILTIN_NEON_copysignfv2sf, false);
+ else if (ARM_CHECK_BUILTIN_MODE (4, SF))
+ return arm_builtin_decl (ARM_BUILTIN_NEON_copysignfv4sf, false);
+ else
+ return NULL_TREE;
+
+ default:
+ return NULL_TREE;
}
return NULL_TREE;
}
extern void neon_pairwise_reduce (rtx, rtx, machine_mode,
rtx (*) (rtx, rtx, rtx));
extern rtx neon_make_constant (rtx);
-extern tree arm_builtin_vectorized_function (tree, tree, tree);
+extern tree arm_builtin_vectorized_function (unsigned int, tree, tree);
extern void neon_expand_vector_init (rtx, rtx);
extern void neon_lane_bounds (rtx, HOST_WIDE_INT, HOST_WIDE_INT, const_tree);
extern void neon_const_bounds (rtx, HOST_WIDE_INT, HOST_WIDE_INT);
#include "tree-chkp.h"
#include "rtl-chkp.h"
#include "dbgcnt.h"
+#include "case-cfn-macros.h"
/* This file should be included last. */
#include "target-def.h"
static int ix86_arch_specified;
/* Vectorization library interface and handlers. */
-static tree (*ix86_veclib_handler) (enum built_in_function, tree, tree);
+static tree (*ix86_veclib_handler) (combined_fn, tree, tree);
-static tree ix86_veclibabi_svml (enum built_in_function, tree, tree);
-static tree ix86_veclibabi_acml (enum built_in_function, tree, tree);
+static tree ix86_veclibabi_svml (combined_fn, tree, tree);
+static tree ix86_veclibabi_acml (combined_fn, tree, tree);
/* Processor target table, indexed by processor number */
struct ptt
emit_move_insn (slot, bounds);
}
-/* Returns a function decl for a vectorized version of the builtin function
- with builtin function code FN and the result vector type TYPE, or NULL_TREE
+/* Returns a function decl for a vectorized version of the combined function
+ with combined_fn code FN and the result vector type TYPE, or NULL_TREE
if it is not available. */
static tree
-ix86_builtin_vectorized_function (tree fndecl, tree type_out,
+ix86_builtin_vectorized_function (unsigned int fn, tree type_out,
tree type_in)
{
machine_mode in_mode, out_mode;
int in_n, out_n;
- enum built_in_function fn = DECL_FUNCTION_CODE (fndecl);
if (TREE_CODE (type_out) != VECTOR_TYPE
- || TREE_CODE (type_in) != VECTOR_TYPE
- || DECL_BUILT_IN_CLASS (fndecl) != BUILT_IN_NORMAL)
+ || TREE_CODE (type_in) != VECTOR_TYPE)
return NULL_TREE;
out_mode = TYPE_MODE (TREE_TYPE (type_out));
switch (fn)
{
- case BUILT_IN_SQRT:
+ CASE_CFN_SQRT:
if (out_mode == DFmode && in_mode == DFmode)
{
if (out_n == 2 && in_n == 2)
else if (out_n == 8 && in_n == 8)
return ix86_get_builtin (IX86_BUILTIN_SQRTPD512);
}
- break;
-
- case BUILT_IN_EXP2F:
- if (out_mode == SFmode && in_mode == SFmode)
- {
- if (out_n == 16 && in_n == 16)
- return ix86_get_builtin (IX86_BUILTIN_EXP2PS);
- }
- break;
-
- case BUILT_IN_SQRTF:
if (out_mode == SFmode && in_mode == SFmode)
{
if (out_n == 4 && in_n == 4)
}
break;
- case BUILT_IN_IFLOOR:
- case BUILT_IN_LFLOOR:
- case BUILT_IN_LLFLOOR:
+ CASE_CFN_EXP2:
+ if (out_mode == SFmode && in_mode == SFmode)
+ {
+ if (out_n == 16 && in_n == 16)
+ return ix86_get_builtin (IX86_BUILTIN_EXP2PS);
+ }
+ break;
+
+ CASE_CFN_IFLOOR:
+ CASE_CFN_LFLOOR:
+ CASE_CFN_LLFLOOR:
/* The round insn does not trap on denormals. */
if (flag_trapping_math || !TARGET_ROUND)
break;
else if (out_n == 16 && in_n == 8)
return ix86_get_builtin (IX86_BUILTIN_FLOORPD_VEC_PACK_SFIX512);
}
- break;
-
- case BUILT_IN_IFLOORF:
- case BUILT_IN_LFLOORF:
- case BUILT_IN_LLFLOORF:
- /* The round insn does not trap on denormals. */
- if (flag_trapping_math || !TARGET_ROUND)
- break;
-
if (out_mode == SImode && in_mode == SFmode)
{
if (out_n == 4 && in_n == 4)
}
break;
- case BUILT_IN_ICEIL:
- case BUILT_IN_LCEIL:
- case BUILT_IN_LLCEIL:
+ CASE_CFN_ICEIL:
+ CASE_CFN_LCEIL:
+ CASE_CFN_LLCEIL:
/* The round insn does not trap on denormals. */
if (flag_trapping_math || !TARGET_ROUND)
break;
else if (out_n == 16 && in_n == 8)
return ix86_get_builtin (IX86_BUILTIN_CEILPD_VEC_PACK_SFIX512);
}
- break;
-
- case BUILT_IN_ICEILF:
- case BUILT_IN_LCEILF:
- case BUILT_IN_LLCEILF:
- /* The round insn does not trap on denormals. */
- if (flag_trapping_math || !TARGET_ROUND)
- break;
-
if (out_mode == SImode && in_mode == SFmode)
{
if (out_n == 4 && in_n == 4)
}
break;
- case BUILT_IN_IRINT:
- case BUILT_IN_LRINT:
- case BUILT_IN_LLRINT:
+ CASE_CFN_IRINT:
+ CASE_CFN_LRINT:
+ CASE_CFN_LLRINT:
if (out_mode == SImode && in_mode == DFmode)
{
if (out_n == 4 && in_n == 2)
else if (out_n == 8 && in_n == 4)
return ix86_get_builtin (IX86_BUILTIN_VEC_PACK_SFIX256);
}
- break;
-
- case BUILT_IN_IRINTF:
- case BUILT_IN_LRINTF:
- case BUILT_IN_LLRINTF:
if (out_mode == SImode && in_mode == SFmode)
{
if (out_n == 4 && in_n == 4)
}
break;
- case BUILT_IN_IROUND:
- case BUILT_IN_LROUND:
- case BUILT_IN_LLROUND:
+ CASE_CFN_IROUND:
+ CASE_CFN_LROUND:
+ CASE_CFN_LLROUND:
/* The round insn does not trap on denormals. */
if (flag_trapping_math || !TARGET_ROUND)
break;
else if (out_n == 16 && in_n == 8)
return ix86_get_builtin (IX86_BUILTIN_ROUNDPD_AZ_VEC_PACK_SFIX512);
}
- break;
-
- case BUILT_IN_IROUNDF:
- case BUILT_IN_LROUNDF:
- case BUILT_IN_LLROUNDF:
- /* The round insn does not trap on denormals. */
- if (flag_trapping_math || !TARGET_ROUND)
- break;
-
if (out_mode == SImode && in_mode == SFmode)
{
if (out_n == 4 && in_n == 4)
}
break;
- case BUILT_IN_COPYSIGN:
+ CASE_CFN_COPYSIGN:
if (out_mode == DFmode && in_mode == DFmode)
{
if (out_n == 2 && in_n == 2)
else if (out_n == 8 && in_n == 8)
return ix86_get_builtin (IX86_BUILTIN_CPYSGNPD512);
}
- break;
-
- case BUILT_IN_COPYSIGNF:
if (out_mode == SFmode && in_mode == SFmode)
{
if (out_n == 4 && in_n == 4)
}
break;
- case BUILT_IN_FLOOR:
+ CASE_CFN_FLOOR:
/* The round insn does not trap on denormals. */
if (flag_trapping_math || !TARGET_ROUND)
break;
else if (out_n == 4 && in_n == 4)
return ix86_get_builtin (IX86_BUILTIN_FLOORPD256);
}
- break;
-
- case BUILT_IN_FLOORF:
- /* The round insn does not trap on denormals. */
- if (flag_trapping_math || !TARGET_ROUND)
- break;
-
if (out_mode == SFmode && in_mode == SFmode)
{
if (out_n == 4 && in_n == 4)
}
break;
- case BUILT_IN_CEIL:
+ CASE_CFN_CEIL:
/* The round insn does not trap on denormals. */
if (flag_trapping_math || !TARGET_ROUND)
break;
else if (out_n == 4 && in_n == 4)
return ix86_get_builtin (IX86_BUILTIN_CEILPD256);
}
- break;
-
- case BUILT_IN_CEILF:
- /* The round insn does not trap on denormals. */
- if (flag_trapping_math || !TARGET_ROUND)
- break;
-
if (out_mode == SFmode && in_mode == SFmode)
{
if (out_n == 4 && in_n == 4)
}
break;
- case BUILT_IN_TRUNC:
+ CASE_CFN_TRUNC:
/* The round insn does not trap on denormals. */
if (flag_trapping_math || !TARGET_ROUND)
break;
else if (out_n == 4 && in_n == 4)
return ix86_get_builtin (IX86_BUILTIN_TRUNCPD256);
}
- break;
-
- case BUILT_IN_TRUNCF:
- /* The round insn does not trap on denormals. */
- if (flag_trapping_math || !TARGET_ROUND)
- break;
-
if (out_mode == SFmode && in_mode == SFmode)
{
if (out_n == 4 && in_n == 4)
}
break;
- case BUILT_IN_RINT:
+ CASE_CFN_RINT:
/* The round insn does not trap on denormals. */
if (flag_trapping_math || !TARGET_ROUND)
break;
else if (out_n == 4 && in_n == 4)
return ix86_get_builtin (IX86_BUILTIN_RINTPD256);
}
- break;
-
- case BUILT_IN_RINTF:
- /* The round insn does not trap on denormals. */
- if (flag_trapping_math || !TARGET_ROUND)
- break;
-
if (out_mode == SFmode && in_mode == SFmode)
{
if (out_n == 4 && in_n == 4)
}
break;
- case BUILT_IN_ROUND:
+ CASE_CFN_ROUND:
/* The round insn does not trap on denormals. */
if (flag_trapping_math || !TARGET_ROUND)
break;
else if (out_n == 4 && in_n == 4)
return ix86_get_builtin (IX86_BUILTIN_ROUNDPD_AZ256);
}
- break;
-
- case BUILT_IN_ROUNDF:
- /* The round insn does not trap on denormals. */
- if (flag_trapping_math || !TARGET_ROUND)
- break;
-
if (out_mode == SFmode && in_mode == SFmode)
{
if (out_n == 4 && in_n == 4)
}
break;
- case BUILT_IN_FMA:
+ CASE_CFN_FMA:
if (out_mode == DFmode && in_mode == DFmode)
{
if (out_n == 2 && in_n == 2)
if (out_n == 4 && in_n == 4)
return ix86_get_builtin (IX86_BUILTIN_VFMADDPD256);
}
- break;
-
- case BUILT_IN_FMAF:
if (out_mode == SFmode && in_mode == SFmode)
{
if (out_n == 4 && in_n == 4)
/* Dispatch to a handler for a vectorization library. */
if (ix86_veclib_handler)
- return ix86_veclib_handler ((enum built_in_function) fn, type_out,
- type_in);
+ return ix86_veclib_handler (combined_fn (fn), type_out, type_in);
return NULL_TREE;
}
a library with vectorized intrinsics. */
static tree
-ix86_veclibabi_svml (enum built_in_function fn, tree type_out, tree type_in)
+ix86_veclibabi_svml (combined_fn fn, tree type_out, tree type_in)
{
char name[20];
tree fntype, new_fndecl, args;
switch (fn)
{
- case BUILT_IN_EXP:
- case BUILT_IN_LOG:
- case BUILT_IN_LOG10:
- case BUILT_IN_POW:
- case BUILT_IN_TANH:
- case BUILT_IN_TAN:
- case BUILT_IN_ATAN:
- case BUILT_IN_ATAN2:
- case BUILT_IN_ATANH:
- case BUILT_IN_CBRT:
- case BUILT_IN_SINH:
- case BUILT_IN_SIN:
- case BUILT_IN_ASINH:
- case BUILT_IN_ASIN:
- case BUILT_IN_COSH:
- case BUILT_IN_COS:
- case BUILT_IN_ACOSH:
- case BUILT_IN_ACOS:
- if (el_mode != DFmode || n != 2)
- return NULL_TREE;
- break;
-
- case BUILT_IN_EXPF:
- case BUILT_IN_LOGF:
- case BUILT_IN_LOG10F:
- case BUILT_IN_POWF:
- case BUILT_IN_TANHF:
- case BUILT_IN_TANF:
- case BUILT_IN_ATANF:
- case BUILT_IN_ATAN2F:
- case BUILT_IN_ATANHF:
- case BUILT_IN_CBRTF:
- case BUILT_IN_SINHF:
- case BUILT_IN_SINF:
- case BUILT_IN_ASINHF:
- case BUILT_IN_ASINF:
- case BUILT_IN_COSHF:
- case BUILT_IN_COSF:
- case BUILT_IN_ACOSHF:
- case BUILT_IN_ACOSF:
- if (el_mode != SFmode || n != 4)
+ CASE_CFN_EXP:
+ CASE_CFN_LOG:
+ CASE_CFN_LOG10:
+ CASE_CFN_POW:
+ CASE_CFN_TANH:
+ CASE_CFN_TAN:
+ CASE_CFN_ATAN:
+ CASE_CFN_ATAN2:
+ CASE_CFN_ATANH:
+ CASE_CFN_CBRT:
+ CASE_CFN_SINH:
+ CASE_CFN_SIN:
+ CASE_CFN_ASINH:
+ CASE_CFN_ASIN:
+ CASE_CFN_COSH:
+ CASE_CFN_COS:
+ CASE_CFN_ACOSH:
+ CASE_CFN_ACOS:
+ if ((el_mode != DFmode || n != 2)
+ && (el_mode != SFmode || n != 4))
return NULL_TREE;
break;
return NULL_TREE;
}
- bname = IDENTIFIER_POINTER (DECL_NAME (builtin_decl_implicit (fn)));
+ tree fndecl = mathfn_built_in (TREE_TYPE (type_in), fn);
+ bname = IDENTIFIER_POINTER (DECL_NAME (fndecl));
- if (fn == BUILT_IN_LOGF)
+ if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_LOGF)
strcpy (name, "vmlsLn4");
- else if (fn == BUILT_IN_LOG)
+ else if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_LOG)
strcpy (name, "vmldLn2");
else if (n == 4)
{
name[4] &= ~0x20;
arity = 0;
- for (args = DECL_ARGUMENTS (builtin_decl_implicit (fn));
- args;
- args = TREE_CHAIN (args))
+ for (args = DECL_ARGUMENTS (fndecl); args; args = TREE_CHAIN (args))
arity++;
if (arity == 1)
a library with vectorized intrinsics. */
static tree
-ix86_veclibabi_acml (enum built_in_function fn, tree type_out, tree type_in)
+ix86_veclibabi_acml (combined_fn fn, tree type_out, tree type_in)
{
char name[20] = "__vr.._";
tree fntype, new_fndecl, args;
switch (fn)
{
- case BUILT_IN_SIN:
- case BUILT_IN_COS:
- case BUILT_IN_EXP:
- case BUILT_IN_LOG:
- case BUILT_IN_LOG2:
- case BUILT_IN_LOG10:
- name[4] = 'd';
- name[5] = '2';
- if (el_mode != DFmode
- || n != 2)
- return NULL_TREE;
- break;
-
- case BUILT_IN_SINF:
- case BUILT_IN_COSF:
- case BUILT_IN_EXPF:
- case BUILT_IN_POWF:
- case BUILT_IN_LOGF:
- case BUILT_IN_LOG2F:
- case BUILT_IN_LOG10F:
- name[4] = 's';
- name[5] = '4';
- if (el_mode != SFmode
- || n != 4)
+ CASE_CFN_SIN:
+ CASE_CFN_COS:
+ CASE_CFN_EXP:
+ CASE_CFN_LOG:
+ CASE_CFN_LOG2:
+ CASE_CFN_LOG10:
+ if (el_mode == DFmode && n == 2)
+ {
+ name[4] = 'd';
+ name[5] = '2';
+ }
+ else if (el_mode == SFmode && n == 4)
+ {
+ name[4] = 's';
+ name[5] = '4';
+ }
+ else
return NULL_TREE;
break;
return NULL_TREE;
}
- bname = IDENTIFIER_POINTER (DECL_NAME (builtin_decl_implicit (fn)));
+ tree fndecl = mathfn_built_in (TREE_TYPE (type_in), fn);
+ bname = IDENTIFIER_POINTER (DECL_NAME (fndecl));
sprintf (name + 7, "%s", bname+10);
arity = 0;
- for (args = DECL_ARGUMENTS (builtin_decl_implicit (fn));
- args;
- args = TREE_CHAIN (args))
+ for (args = DECL_ARGUMENTS (fndecl); args; args = TREE_CHAIN (args))
arity++;
if (arity == 1)
#if TARGET_MACHO
#include "gstab.h" /* for N_SLINE */
#endif
+#include "case-cfn-macros.h"
/* This file should be included last. */
#include "target-def.h"
#undef RS6000_BUILTIN_X
/* Support for -mveclibabi=<xxx> to control which vector library to use. */
-static tree (*rs6000_veclib_handler) (tree, tree, tree);
+static tree (*rs6000_veclib_handler) (combined_fn, tree, tree);
\f
static bool rs6000_debug_legitimate_address_p (machine_mode, rtx, bool);
static tree rs6000_handle_longcall_attribute (tree *, tree, tree, int, bool *);
static tree rs6000_handle_altivec_attribute (tree *, tree, tree, int, bool *);
static tree rs6000_handle_struct_attribute (tree *, tree, tree, int, bool *);
-static tree rs6000_builtin_vectorized_libmass (tree, tree, tree);
+static tree rs6000_builtin_vectorized_libmass (combined_fn, tree, tree);
static void rs6000_emit_set_long_const (rtx, HOST_WIDE_INT);
static int rs6000_memory_move_cost (machine_mode, reg_class_t, bool);
static bool rs6000_debug_rtx_costs (rtx, machine_mode, int, int, int *, bool);
#define TARGET_VECTORIZE_BUILTIN_VECTORIZED_FUNCTION \
rs6000_builtin_vectorized_function
+#undef TARGET_VECTORIZE_BUILTIN_MD_VECTORIZED_FUNCTION
+#define TARGET_VECTORIZE_BUILTIN_MD_VECTORIZED_FUNCTION \
+ rs6000_builtin_md_vectorized_function
+
#if !TARGET_MACHO
#undef TARGET_STACK_PROTECT_FAIL
#define TARGET_STACK_PROTECT_FAIL rs6000_stack_protect_fail
library with vectorized intrinsics. */
static tree
-rs6000_builtin_vectorized_libmass (tree fndecl, tree type_out, tree type_in)
+rs6000_builtin_vectorized_libmass (combined_fn fn, tree type_out,
+ tree type_in)
{
char name[32];
const char *suffix = NULL;
|| n != in_n)
return NULL_TREE;
- if (DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_NORMAL)
- {
- enum built_in_function fn = DECL_FUNCTION_CODE (fndecl);
- switch (fn)
- {
- case BUILT_IN_ATAN2:
- case BUILT_IN_HYPOT:
- case BUILT_IN_POW:
- n_args = 2;
- /* fall through */
-
- case BUILT_IN_ACOS:
- case BUILT_IN_ACOSH:
- case BUILT_IN_ASIN:
- case BUILT_IN_ASINH:
- case BUILT_IN_ATAN:
- case BUILT_IN_ATANH:
- case BUILT_IN_CBRT:
- case BUILT_IN_COS:
- case BUILT_IN_COSH:
- case BUILT_IN_ERF:
- case BUILT_IN_ERFC:
- case BUILT_IN_EXP2:
- case BUILT_IN_EXP:
- case BUILT_IN_EXPM1:
- case BUILT_IN_LGAMMA:
- case BUILT_IN_LOG10:
- case BUILT_IN_LOG1P:
- case BUILT_IN_LOG2:
- case BUILT_IN_LOG:
- case BUILT_IN_SIN:
- case BUILT_IN_SINH:
- case BUILT_IN_SQRT:
- case BUILT_IN_TAN:
- case BUILT_IN_TANH:
- bdecl = builtin_decl_implicit (fn);
- suffix = "d2"; /* pow -> powd2 */
- if (el_mode != DFmode
- || n != 2
- || !bdecl)
- return NULL_TREE;
- break;
+ switch (fn)
+ {
+ CASE_CFN_ATAN2:
+ CASE_CFN_HYPOT:
+ CASE_CFN_POW:
+ n_args = 2;
+ /* fall through */
- case BUILT_IN_ATAN2F:
- case BUILT_IN_HYPOTF:
- case BUILT_IN_POWF:
- n_args = 2;
- /* fall through */
-
- case BUILT_IN_ACOSF:
- case BUILT_IN_ACOSHF:
- case BUILT_IN_ASINF:
- case BUILT_IN_ASINHF:
- case BUILT_IN_ATANF:
- case BUILT_IN_ATANHF:
- case BUILT_IN_CBRTF:
- case BUILT_IN_COSF:
- case BUILT_IN_COSHF:
- case BUILT_IN_ERFF:
- case BUILT_IN_ERFCF:
- case BUILT_IN_EXP2F:
- case BUILT_IN_EXPF:
- case BUILT_IN_EXPM1F:
- case BUILT_IN_LGAMMAF:
- case BUILT_IN_LOG10F:
- case BUILT_IN_LOG1PF:
- case BUILT_IN_LOG2F:
- case BUILT_IN_LOGF:
- case BUILT_IN_SINF:
- case BUILT_IN_SINHF:
- case BUILT_IN_SQRTF:
- case BUILT_IN_TANF:
- case BUILT_IN_TANHF:
- bdecl = builtin_decl_implicit (fn);
+ CASE_CFN_ACOS:
+ CASE_CFN_ACOSH:
+ CASE_CFN_ASIN:
+ CASE_CFN_ASINH:
+ CASE_CFN_ATAN:
+ CASE_CFN_ATANH:
+ CASE_CFN_CBRT:
+ CASE_CFN_COS:
+ CASE_CFN_COSH:
+ CASE_CFN_ERF:
+ CASE_CFN_ERFC:
+ CASE_CFN_EXP2:
+ CASE_CFN_EXP:
+ CASE_CFN_EXPM1:
+ CASE_CFN_LGAMMA:
+ CASE_CFN_LOG10:
+ CASE_CFN_LOG1P:
+ CASE_CFN_LOG2:
+ CASE_CFN_LOG:
+ CASE_CFN_SIN:
+ CASE_CFN_SINH:
+ CASE_CFN_SQRT:
+ CASE_CFN_TAN:
+ CASE_CFN_TANH:
+ if (el_mode == DFmode && n == 2)
+ {
+ bdecl = mathfn_built_in (double_type_node, fn);
+ suffix = "d2"; /* pow -> powd2 */
+ }
+ else if (el_mode == SFmode && n == 4)
+ {
+ bdecl = mathfn_built_in (float_type_node, fn);
suffix = "4"; /* powf -> powf4 */
- if (el_mode != SFmode
- || n != 4
- || !bdecl)
- return NULL_TREE;
- break;
-
- default:
- return NULL_TREE;
}
+ else
+ return NULL_TREE;
+ if (!bdecl)
+ return NULL_TREE;
+ break;
+
+ default:
+ return NULL_TREE;
}
- else
- return NULL_TREE;
gcc_assert (suffix != NULL);
bname = IDENTIFIER_POINTER (DECL_NAME (bdecl));
if it is not available. */
static tree
-rs6000_builtin_vectorized_function (tree fndecl, tree type_out,
+rs6000_builtin_vectorized_function (unsigned int fn, tree type_out,
tree type_in)
{
machine_mode in_mode, out_mode;
if (TARGET_DEBUG_BUILTIN)
fprintf (stderr, "rs6000_builtin_vectorized_function (%s, %s, %s)\n",
- IDENTIFIER_POINTER (DECL_NAME (fndecl)),
+ combined_fn_name (combined_fn (fn)),
GET_MODE_NAME (TYPE_MODE (type_out)),
GET_MODE_NAME (TYPE_MODE (type_in)));
in_mode = TYPE_MODE (TREE_TYPE (type_in));
in_n = TYPE_VECTOR_SUBPARTS (type_in);
- if (DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_NORMAL)
+ switch (fn)
{
- enum built_in_function fn = DECL_FUNCTION_CODE (fndecl);
- switch (fn)
+ CASE_CFN_CLZ:
+ if (TARGET_P8_VECTOR && in_mode == out_mode && out_n == in_n)
{
- case BUILT_IN_CLZIMAX:
- case BUILT_IN_CLZLL:
- case BUILT_IN_CLZL:
- case BUILT_IN_CLZ:
- if (TARGET_P8_VECTOR && in_mode == out_mode && out_n == in_n)
- {
- if (out_mode == QImode && out_n == 16)
- return rs6000_builtin_decls[P8V_BUILTIN_VCLZB];
- else if (out_mode == HImode && out_n == 8)
- return rs6000_builtin_decls[P8V_BUILTIN_VCLZH];
- else if (out_mode == SImode && out_n == 4)
- return rs6000_builtin_decls[P8V_BUILTIN_VCLZW];
- else if (out_mode == DImode && out_n == 2)
- return rs6000_builtin_decls[P8V_BUILTIN_VCLZD];
- }
- break;
- case BUILT_IN_COPYSIGN:
- if (VECTOR_UNIT_VSX_P (V2DFmode)
- && out_mode == DFmode && out_n == 2
- && in_mode == DFmode && in_n == 2)
- return rs6000_builtin_decls[VSX_BUILTIN_CPSGNDP];
- break;
- case BUILT_IN_COPYSIGNF:
- if (out_mode != SFmode || out_n != 4
- || in_mode != SFmode || in_n != 4)
- break;
- if (VECTOR_UNIT_VSX_P (V4SFmode))
- return rs6000_builtin_decls[VSX_BUILTIN_CPSGNSP];
- if (VECTOR_UNIT_ALTIVEC_P (V4SFmode))
- return rs6000_builtin_decls[ALTIVEC_BUILTIN_COPYSIGN_V4SF];
- break;
- case BUILT_IN_POPCOUNTIMAX:
- case BUILT_IN_POPCOUNTLL:
- case BUILT_IN_POPCOUNTL:
- case BUILT_IN_POPCOUNT:
- if (TARGET_P8_VECTOR && in_mode == out_mode && out_n == in_n)
- {
- if (out_mode == QImode && out_n == 16)
- return rs6000_builtin_decls[P8V_BUILTIN_VPOPCNTB];
- else if (out_mode == HImode && out_n == 8)
- return rs6000_builtin_decls[P8V_BUILTIN_VPOPCNTH];
- else if (out_mode == SImode && out_n == 4)
- return rs6000_builtin_decls[P8V_BUILTIN_VPOPCNTW];
- else if (out_mode == DImode && out_n == 2)
- return rs6000_builtin_decls[P8V_BUILTIN_VPOPCNTD];
- }
- break;
- case BUILT_IN_SQRT:
- if (VECTOR_UNIT_VSX_P (V2DFmode)
- && out_mode == DFmode && out_n == 2
- && in_mode == DFmode && in_n == 2)
- return rs6000_builtin_decls[VSX_BUILTIN_XVSQRTDP];
- break;
- case BUILT_IN_SQRTF:
- if (VECTOR_UNIT_VSX_P (V4SFmode)
- && out_mode == SFmode && out_n == 4
- && in_mode == SFmode && in_n == 4)
- return rs6000_builtin_decls[VSX_BUILTIN_XVSQRTSP];
- break;
- case BUILT_IN_CEIL:
- if (VECTOR_UNIT_VSX_P (V2DFmode)
- && out_mode == DFmode && out_n == 2
- && in_mode == DFmode && in_n == 2)
- return rs6000_builtin_decls[VSX_BUILTIN_XVRDPIP];
- break;
- case BUILT_IN_CEILF:
- if (out_mode != SFmode || out_n != 4
- || in_mode != SFmode || in_n != 4)
- break;
- if (VECTOR_UNIT_VSX_P (V4SFmode))
- return rs6000_builtin_decls[VSX_BUILTIN_XVRSPIP];
- if (VECTOR_UNIT_ALTIVEC_P (V4SFmode))
- return rs6000_builtin_decls[ALTIVEC_BUILTIN_VRFIP];
- break;
- case BUILT_IN_FLOOR:
- if (VECTOR_UNIT_VSX_P (V2DFmode)
- && out_mode == DFmode && out_n == 2
- && in_mode == DFmode && in_n == 2)
- return rs6000_builtin_decls[VSX_BUILTIN_XVRDPIM];
- break;
- case BUILT_IN_FLOORF:
- if (out_mode != SFmode || out_n != 4
- || in_mode != SFmode || in_n != 4)
- break;
- if (VECTOR_UNIT_VSX_P (V4SFmode))
- return rs6000_builtin_decls[VSX_BUILTIN_XVRSPIM];
- if (VECTOR_UNIT_ALTIVEC_P (V4SFmode))
- return rs6000_builtin_decls[ALTIVEC_BUILTIN_VRFIM];
- break;
- case BUILT_IN_FMA:
- if (VECTOR_UNIT_VSX_P (V2DFmode)
- && out_mode == DFmode && out_n == 2
- && in_mode == DFmode && in_n == 2)
- return rs6000_builtin_decls[VSX_BUILTIN_XVMADDDP];
- break;
- case BUILT_IN_FMAF:
- if (VECTOR_UNIT_VSX_P (V4SFmode)
- && out_mode == SFmode && out_n == 4
- && in_mode == SFmode && in_n == 4)
- return rs6000_builtin_decls[VSX_BUILTIN_XVMADDSP];
- else if (VECTOR_UNIT_ALTIVEC_P (V4SFmode)
- && out_mode == SFmode && out_n == 4
- && in_mode == SFmode && in_n == 4)
- return rs6000_builtin_decls[ALTIVEC_BUILTIN_VMADDFP];
- break;
- case BUILT_IN_TRUNC:
- if (VECTOR_UNIT_VSX_P (V2DFmode)
- && out_mode == DFmode && out_n == 2
- && in_mode == DFmode && in_n == 2)
- return rs6000_builtin_decls[VSX_BUILTIN_XVRDPIZ];
- break;
- case BUILT_IN_TRUNCF:
- if (out_mode != SFmode || out_n != 4
- || in_mode != SFmode || in_n != 4)
- break;
- if (VECTOR_UNIT_VSX_P (V4SFmode))
- return rs6000_builtin_decls[VSX_BUILTIN_XVRSPIZ];
- if (VECTOR_UNIT_ALTIVEC_P (V4SFmode))
- return rs6000_builtin_decls[ALTIVEC_BUILTIN_VRFIZ];
- break;
- case BUILT_IN_NEARBYINT:
- if (VECTOR_UNIT_VSX_P (V2DFmode)
- && flag_unsafe_math_optimizations
- && out_mode == DFmode && out_n == 2
- && in_mode == DFmode && in_n == 2)
- return rs6000_builtin_decls[VSX_BUILTIN_XVRDPI];
- break;
- case BUILT_IN_NEARBYINTF:
- if (VECTOR_UNIT_VSX_P (V4SFmode)
- && flag_unsafe_math_optimizations
- && out_mode == SFmode && out_n == 4
- && in_mode == SFmode && in_n == 4)
- return rs6000_builtin_decls[VSX_BUILTIN_XVRSPI];
- break;
- case BUILT_IN_RINT:
- if (VECTOR_UNIT_VSX_P (V2DFmode)
- && !flag_trapping_math
- && out_mode == DFmode && out_n == 2
- && in_mode == DFmode && in_n == 2)
- return rs6000_builtin_decls[VSX_BUILTIN_XVRDPIC];
- break;
- case BUILT_IN_RINTF:
- if (VECTOR_UNIT_VSX_P (V4SFmode)
- && !flag_trapping_math
- && out_mode == SFmode && out_n == 4
- && in_mode == SFmode && in_n == 4)
- return rs6000_builtin_decls[VSX_BUILTIN_XVRSPIC];
- break;
- default:
- break;
+ if (out_mode == QImode && out_n == 16)
+ return rs6000_builtin_decls[P8V_BUILTIN_VCLZB];
+ else if (out_mode == HImode && out_n == 8)
+ return rs6000_builtin_decls[P8V_BUILTIN_VCLZH];
+ else if (out_mode == SImode && out_n == 4)
+ return rs6000_builtin_decls[P8V_BUILTIN_VCLZW];
+ else if (out_mode == DImode && out_n == 2)
+ return rs6000_builtin_decls[P8V_BUILTIN_VCLZD];
}
- }
-
- else if (DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_MD)
- {
- enum rs6000_builtins fn
- = (enum rs6000_builtins)DECL_FUNCTION_CODE (fndecl);
- switch (fn)
- {
- case RS6000_BUILTIN_RSQRTF:
- if (VECTOR_UNIT_ALTIVEC_OR_VSX_P (V4SFmode)
- && out_mode == SFmode && out_n == 4
- && in_mode == SFmode && in_n == 4)
- return rs6000_builtin_decls[ALTIVEC_BUILTIN_VRSQRTFP];
- break;
- case RS6000_BUILTIN_RSQRT:
- if (VECTOR_UNIT_VSX_P (V2DFmode)
- && out_mode == DFmode && out_n == 2
- && in_mode == DFmode && in_n == 2)
- return rs6000_builtin_decls[VSX_BUILTIN_RSQRT_2DF];
- break;
- case RS6000_BUILTIN_RECIPF:
- if (VECTOR_UNIT_ALTIVEC_OR_VSX_P (V4SFmode)
- && out_mode == SFmode && out_n == 4
- && in_mode == SFmode && in_n == 4)
- return rs6000_builtin_decls[ALTIVEC_BUILTIN_VRECIPFP];
- break;
- case RS6000_BUILTIN_RECIP:
- if (VECTOR_UNIT_VSX_P (V2DFmode)
- && out_mode == DFmode && out_n == 2
- && in_mode == DFmode && in_n == 2)
- return rs6000_builtin_decls[VSX_BUILTIN_RECIP_V2DF];
- break;
- default:
- break;
+ break;
+ CASE_CFN_COPYSIGN:
+ if (VECTOR_UNIT_VSX_P (V2DFmode)
+ && out_mode == DFmode && out_n == 2
+ && in_mode == DFmode && in_n == 2)
+ return rs6000_builtin_decls[VSX_BUILTIN_CPSGNDP];
+ if (VECTOR_UNIT_VSX_P (V4SFmode)
+ && out_mode == SFmode && out_n == 4
+ && in_mode == SFmode && in_n == 4)
+ return rs6000_builtin_decls[VSX_BUILTIN_CPSGNSP];
+ if (VECTOR_UNIT_ALTIVEC_P (V4SFmode)
+ && out_mode == SFmode && out_n == 4
+ && in_mode == SFmode && in_n == 4)
+ return rs6000_builtin_decls[ALTIVEC_BUILTIN_COPYSIGN_V4SF];
+ break;
+ CASE_CFN_POPCOUNT:
+ if (TARGET_P8_VECTOR && in_mode == out_mode && out_n == in_n)
+ {
+ if (out_mode == QImode && out_n == 16)
+ return rs6000_builtin_decls[P8V_BUILTIN_VPOPCNTB];
+ else if (out_mode == HImode && out_n == 8)
+ return rs6000_builtin_decls[P8V_BUILTIN_VPOPCNTH];
+ else if (out_mode == SImode && out_n == 4)
+ return rs6000_builtin_decls[P8V_BUILTIN_VPOPCNTW];
+ else if (out_mode == DImode && out_n == 2)
+ return rs6000_builtin_decls[P8V_BUILTIN_VPOPCNTD];
}
+ break;
+ CASE_CFN_SQRT:
+ if (VECTOR_UNIT_VSX_P (V2DFmode)
+ && out_mode == DFmode && out_n == 2
+ && in_mode == DFmode && in_n == 2)
+ return rs6000_builtin_decls[VSX_BUILTIN_XVSQRTDP];
+ if (VECTOR_UNIT_VSX_P (V4SFmode)
+ && out_mode == SFmode && out_n == 4
+ && in_mode == SFmode && in_n == 4)
+ return rs6000_builtin_decls[VSX_BUILTIN_XVSQRTSP];
+ break;
+ CASE_CFN_CEIL:
+ if (VECTOR_UNIT_VSX_P (V2DFmode)
+ && out_mode == DFmode && out_n == 2
+ && in_mode == DFmode && in_n == 2)
+ return rs6000_builtin_decls[VSX_BUILTIN_XVRDPIP];
+ if (VECTOR_UNIT_VSX_P (V4SFmode)
+ && out_mode == SFmode && out_n == 4
+ && in_mode == SFmode && in_n == 4)
+ return rs6000_builtin_decls[VSX_BUILTIN_XVRSPIP];
+ if (VECTOR_UNIT_ALTIVEC_P (V4SFmode)
+ && out_mode == SFmode && out_n == 4
+ && in_mode == SFmode && in_n == 4)
+ return rs6000_builtin_decls[ALTIVEC_BUILTIN_VRFIP];
+ break;
+ CASE_CFN_FLOOR:
+ if (VECTOR_UNIT_VSX_P (V2DFmode)
+ && out_mode == DFmode && out_n == 2
+ && in_mode == DFmode && in_n == 2)
+ return rs6000_builtin_decls[VSX_BUILTIN_XVRDPIM];
+ if (VECTOR_UNIT_VSX_P (V4SFmode)
+ && out_mode == SFmode && out_n == 4
+ && in_mode == SFmode && in_n == 4)
+ return rs6000_builtin_decls[VSX_BUILTIN_XVRSPIM];
+ if (VECTOR_UNIT_ALTIVEC_P (V4SFmode)
+ && out_mode == SFmode && out_n == 4
+ && in_mode == SFmode && in_n == 4)
+ return rs6000_builtin_decls[ALTIVEC_BUILTIN_VRFIM];
+ break;
+ CASE_CFN_FMA:
+ if (VECTOR_UNIT_VSX_P (V2DFmode)
+ && out_mode == DFmode && out_n == 2
+ && in_mode == DFmode && in_n == 2)
+ return rs6000_builtin_decls[VSX_BUILTIN_XVMADDDP];
+ if (VECTOR_UNIT_VSX_P (V4SFmode)
+ && out_mode == SFmode && out_n == 4
+ && in_mode == SFmode && in_n == 4)
+ return rs6000_builtin_decls[VSX_BUILTIN_XVMADDSP];
+ if (VECTOR_UNIT_ALTIVEC_P (V4SFmode)
+ && out_mode == SFmode && out_n == 4
+ && in_mode == SFmode && in_n == 4)
+ return rs6000_builtin_decls[ALTIVEC_BUILTIN_VMADDFP];
+ break;
+ CASE_CFN_TRUNC:
+ if (VECTOR_UNIT_VSX_P (V2DFmode)
+ && out_mode == DFmode && out_n == 2
+ && in_mode == DFmode && in_n == 2)
+ return rs6000_builtin_decls[VSX_BUILTIN_XVRDPIZ];
+ if (VECTOR_UNIT_VSX_P (V4SFmode)
+ && out_mode == SFmode && out_n == 4
+ && in_mode == SFmode && in_n == 4)
+ return rs6000_builtin_decls[VSX_BUILTIN_XVRSPIZ];
+ if (VECTOR_UNIT_ALTIVEC_P (V4SFmode)
+ && out_mode == SFmode && out_n == 4
+ && in_mode == SFmode && in_n == 4)
+ return rs6000_builtin_decls[ALTIVEC_BUILTIN_VRFIZ];
+ break;
+ CASE_CFN_NEARBYINT:
+ if (VECTOR_UNIT_VSX_P (V2DFmode)
+ && flag_unsafe_math_optimizations
+ && out_mode == DFmode && out_n == 2
+ && in_mode == DFmode && in_n == 2)
+ return rs6000_builtin_decls[VSX_BUILTIN_XVRDPI];
+ if (VECTOR_UNIT_VSX_P (V4SFmode)
+ && flag_unsafe_math_optimizations
+ && out_mode == SFmode && out_n == 4
+ && in_mode == SFmode && in_n == 4)
+ return rs6000_builtin_decls[VSX_BUILTIN_XVRSPI];
+ break;
+ CASE_CFN_RINT:
+ if (VECTOR_UNIT_VSX_P (V2DFmode)
+ && !flag_trapping_math
+ && out_mode == DFmode && out_n == 2
+ && in_mode == DFmode && in_n == 2)
+ return rs6000_builtin_decls[VSX_BUILTIN_XVRDPIC];
+ if (VECTOR_UNIT_VSX_P (V4SFmode)
+ && !flag_trapping_math
+ && out_mode == SFmode && out_n == 4
+ && in_mode == SFmode && in_n == 4)
+ return rs6000_builtin_decls[VSX_BUILTIN_XVRSPIC];
+ break;
+ default:
+ break;
}
/* Generate calls to libmass if appropriate. */
if (rs6000_veclib_handler)
- return rs6000_veclib_handler (fndecl, type_out, type_in);
+ return rs6000_veclib_handler (combined_fn (fn), type_out, type_in);
+
+ return NULL_TREE;
+}
+
+/* Implement TARGET_VECTORIZE_BUILTIN_MD_VECTORIZED_FUNCTION. */
+static tree
+rs6000_builtin_md_vectorized_function (tree fndecl, tree type_out,
+ tree type_in)
+{
+ machine_mode in_mode, out_mode;
+ int in_n, out_n;
+
+ if (TARGET_DEBUG_BUILTIN)
+ fprintf (stderr, "rs6000_builtin_md_vectorized_function (%s, %s, %s)\n",
+ IDENTIFIER_POINTER (DECL_NAME (fndecl)),
+ GET_MODE_NAME (TYPE_MODE (type_out)),
+ GET_MODE_NAME (TYPE_MODE (type_in)));
+
+ if (TREE_CODE (type_out) != VECTOR_TYPE
+ || TREE_CODE (type_in) != VECTOR_TYPE
+ || !TARGET_VECTORIZE_BUILTINS)
+ return NULL_TREE;
+
+ out_mode = TYPE_MODE (TREE_TYPE (type_out));
+ out_n = TYPE_VECTOR_SUBPARTS (type_out);
+ in_mode = TYPE_MODE (TREE_TYPE (type_in));
+ in_n = TYPE_VECTOR_SUBPARTS (type_in);
+
+ enum rs6000_builtins fn
+ = (enum rs6000_builtins) DECL_FUNCTION_CODE (fndecl);
+ switch (fn)
+ {
+ case RS6000_BUILTIN_RSQRTF:
+ if (VECTOR_UNIT_ALTIVEC_OR_VSX_P (V4SFmode)
+ && out_mode == SFmode && out_n == 4
+ && in_mode == SFmode && in_n == 4)
+ return rs6000_builtin_decls[ALTIVEC_BUILTIN_VRSQRTFP];
+ break;
+ case RS6000_BUILTIN_RSQRT:
+ if (VECTOR_UNIT_VSX_P (V2DFmode)
+ && out_mode == DFmode && out_n == 2
+ && in_mode == DFmode && in_n == 2)
+ return rs6000_builtin_decls[VSX_BUILTIN_RSQRT_2DF];
+ break;
+ case RS6000_BUILTIN_RECIPF:
+ if (VECTOR_UNIT_ALTIVEC_OR_VSX_P (V4SFmode)
+ && out_mode == SFmode && out_n == 4
+ && in_mode == SFmode && in_n == 4)
+ return rs6000_builtin_decls[ALTIVEC_BUILTIN_VRECIPFP];
+ break;
+ case RS6000_BUILTIN_RECIP:
+ if (VECTOR_UNIT_VSX_P (V2DFmode)
+ && out_mode == DFmode && out_n == 2
+ && in_mode == DFmode && in_n == 2)
+ return rs6000_builtin_decls[VSX_BUILTIN_RECIP_V2DF];
+ break;
+ default:
+ break;
+ }
return NULL_TREE;
}
\f
conversion. Otherwise, it will return @code{NULL_TREE}.
@end deftypefn
-@deftypefn {Target Hook} tree TARGET_VECTORIZE_BUILTIN_VECTORIZED_FUNCTION (tree @var{fndecl}, tree @var{vec_type_out}, tree @var{vec_type_in})
+@deftypefn {Target Hook} tree TARGET_VECTORIZE_BUILTIN_VECTORIZED_FUNCTION (unsigned @var{code}, tree @var{vec_type_out}, tree @var{vec_type_in})
This hook should return the decl of a function that implements the
-vectorized variant of the builtin function with builtin function code
+vectorized variant of the function with the @code{combined_fn} code
@var{code} or @code{NULL_TREE} if such a function is not available.
-The value of @var{fndecl} is the builtin function declaration. The
+The return type of the vectorized function shall be of vector type
+@var{vec_type_out} and the argument types should be @var{vec_type_in}.
+@end deftypefn
+
+@deftypefn {Target Hook} tree TARGET_VECTORIZE_BUILTIN_MD_VECTORIZED_FUNCTION (tree @var{fndecl}, tree @var{vec_type_out}, tree @var{vec_type_in})
+This hook should return the decl of a function that implements the
+vectorized variant of target built-in function @code{fndecl}. The
return type of the vectorized function shall be of vector type
@var{vec_type_out} and the argument types should be @var{vec_type_in}.
@end deftypefn
@hook TARGET_VECTORIZE_BUILTIN_VECTORIZED_FUNCTION
+@hook TARGET_VECTORIZE_BUILTIN_MD_VECTORIZED_FUNCTION
+
@hook TARGET_VECTORIZE_SUPPORT_VECTOR_MISALIGNMENT
@hook TARGET_VECTORIZE_PREFERRED_SIMD_MODE
log2(@var{VS}) @minus{} 1 bits of @var{addr} will be considered.",
tree, (void), NULL)
-/* Returns a code for builtin that realizes vectorized version of
- function, or NULL_TREE if not available. */
+/* Returns a built-in function that realizes the vectorized version of
+ a target-independent function, or NULL_TREE if not available. */
DEFHOOK
(builtin_vectorized_function,
"This hook should return the decl of a function that implements the\n\
-vectorized variant of the builtin function with builtin function code\n\
+vectorized variant of the function with the @code{combined_fn} code\n\
@var{code} or @code{NULL_TREE} if such a function is not available.\n\
-The value of @var{fndecl} is the builtin function declaration. The\n\
+The return type of the vectorized function shall be of vector type\n\
+@var{vec_type_out} and the argument types should be @var{vec_type_in}.",
+ tree, (unsigned code, tree vec_type_out, tree vec_type_in),
+ default_builtin_vectorized_function)
+
+/* Returns a built-in function that realizes the vectorized version of
+ a target-specific function, or NULL_TREE if not available. */
+DEFHOOK
+(builtin_md_vectorized_function,
+ "This hook should return the decl of a function that implements the\n\
+vectorized variant of target built-in function @code{fndecl}. The\n\
return type of the vectorized function shall be of vector type\n\
@var{vec_type_out} and the argument types should be @var{vec_type_in}.",
tree, (tree fndecl, tree vec_type_out, tree vec_type_in),
- default_builtin_vectorized_function)
+ default_builtin_md_vectorized_function)
/* Returns a function declaration for a builtin that realizes the
vector conversion, or NULL_TREE if not available. */
/* Mapping of builtin functions to vectorized variants. */
tree
-default_builtin_vectorized_function (tree fndecl ATTRIBUTE_UNUSED,
- tree type_out ATTRIBUTE_UNUSED,
- tree type_in ATTRIBUTE_UNUSED)
+default_builtin_vectorized_function (unsigned int, tree, tree)
+{
+ return NULL_TREE;
+}
+
+/* Mapping of target builtin functions to vectorized variants. */
+
+tree
+default_builtin_md_vectorized_function (tree, tree, tree)
{
return NULL_TREE;
}
extern const char * default_invalid_within_doloop (const rtx_insn *);
-extern tree default_builtin_vectorized_function (tree, tree, tree);
+extern tree default_builtin_vectorized_function (unsigned int, tree, tree);
+extern tree default_builtin_md_vectorized_function (tree, tree, tree);
extern tree default_builtin_vectorized_conversion (unsigned int, tree, tree);
tree
vectorizable_function (gcall *call, tree vectype_out, tree vectype_in)
{
- tree fndecl = gimple_call_fndecl (call);
-
- /* We only handle functions that do not read or clobber memory -- i.e.
- const or novops ones. */
- if (!(gimple_call_flags (call) & (ECF_CONST | ECF_NOVOPS)))
+ /* We only handle functions that do not read or clobber memory. */
+ if (gimple_vuse (call))
return NULL_TREE;
- if (!fndecl
- || TREE_CODE (fndecl) != FUNCTION_DECL
- || !DECL_BUILT_IN (fndecl))
- return NULL_TREE;
+ combined_fn fn = gimple_call_combined_fn (call);
+ if (fn != CFN_LAST)
+ return targetm.vectorize.builtin_vectorized_function
+ (fn, vectype_out, vectype_in);
+
+ if (gimple_call_builtin_p (call, BUILT_IN_MD))
+ return targetm.vectorize.builtin_md_vectorized_function
+ (gimple_call_fndecl (call), vectype_out, vectype_in);
- return targetm.vectorize.builtin_vectorized_function (fndecl, vectype_out,
- vectype_in);
+ return NULL_TREE;
}