aboutsummaryrefslogtreecommitdiff
path: root/gcc/internal-fn.c
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/internal-fn.c')
-rw-r--r--gcc/internal-fn.c45
1 files changed, 45 insertions, 0 deletions
diff --git a/gcc/internal-fn.c b/gcc/internal-fn.c
index 139dcff..119fa1a 100644
--- a/gcc/internal-fn.c
+++ b/gcc/internal-fn.c
@@ -90,6 +90,8 @@ init_internal_fns ()
const direct_internal_fn_info direct_internal_fn_array[IFN_LAST + 1] = {
#define DEF_INTERNAL_FN(CODE, FLAGS, FNSPEC) not_direct,
#define DEF_INTERNAL_OPTAB_FN(CODE, FLAGS, OPTAB, TYPE) TYPE##_direct,
+#define DEF_INTERNAL_SIGNED_OPTAB_FN(CODE, FLAGS, SELECTOR, SIGNED_OPTAB, \
+ UNSIGNED_OPTAB, TYPE) TYPE##_direct,
#include "internal-fn.def"
not_direct
};
@@ -2818,6 +2820,30 @@ multi_vector_optab_supported_p (convert_optab optab, tree_pair types,
#define direct_mask_store_optab_supported_p direct_optab_supported_p
#define direct_store_lanes_optab_supported_p multi_vector_optab_supported_p
+/* Return the optab used by internal function FN. */
+
+static optab
+direct_internal_fn_optab (internal_fn fn, tree_pair types)
+{
+ switch (fn)
+ {
+#define DEF_INTERNAL_FN(CODE, FLAGS, FNSPEC) \
+ case IFN_##CODE: break;
+#define DEF_INTERNAL_OPTAB_FN(CODE, FLAGS, OPTAB, TYPE) \
+ case IFN_##CODE: return OPTAB##_optab;
+#define DEF_INTERNAL_SIGNED_OPTAB_FN(CODE, FLAGS, SELECTOR, SIGNED_OPTAB, \
+ UNSIGNED_OPTAB, TYPE) \
+ case IFN_##CODE: return (TYPE_UNSIGNED (types.SELECTOR) \
+ ? UNSIGNED_OPTAB ## _optab \
+ : SIGNED_OPTAB ## _optab);
+#include "internal-fn.def"
+
+ case IFN_LAST:
+ break;
+ }
+ gcc_unreachable ();
+}
+
/* Return true if FN is supported for the types in TYPES when the
optimization type is OPT_TYPE. The types are those associated with
the "type0" and "type1" fields of FN's direct_internal_fn_info
@@ -2835,6 +2861,16 @@ direct_internal_fn_supported_p (internal_fn fn, tree_pair types,
case IFN_##CODE: \
return direct_##TYPE##_optab_supported_p (OPTAB##_optab, types, \
opt_type);
+#define DEF_INTERNAL_SIGNED_OPTAB_FN(CODE, FLAGS, SELECTOR, SIGNED_OPTAB, \
+ UNSIGNED_OPTAB, TYPE) \
+ case IFN_##CODE: \
+ { \
+ optab which_optab = (TYPE_UNSIGNED (types.SELECTOR) \
+ ? UNSIGNED_OPTAB ## _optab \
+ : SIGNED_OPTAB ## _optab); \
+ return direct_##TYPE##_optab_supported_p (which_optab, types, \
+ opt_type); \
+ }
#include "internal-fn.def"
case IFN_LAST:
@@ -2874,6 +2910,15 @@ set_edom_supported_p (void)
{ \
expand_##TYPE##_optab_fn (fn, stmt, OPTAB##_optab); \
}
+#define DEF_INTERNAL_SIGNED_OPTAB_FN(CODE, FLAGS, SELECTOR, SIGNED_OPTAB, \
+ UNSIGNED_OPTAB, TYPE) \
+ static void \
+ expand_##CODE (internal_fn fn, gcall *stmt) \
+ { \
+ tree_pair types = direct_internal_fn_types (fn, stmt); \
+ optab which_optab = direct_internal_fn_optab (fn, types); \
+ expand_##TYPE##_optab_fn (fn, stmt, which_optab); \
+ }
#include "internal-fn.def"
/* Routines to expand each internal function, indexed by function number.