Make builtin_vectorized_function take a combined_fn
authorrsandifo <rsandifo@138bc75d-0d04-0410-961f-82ee72b054a4>
Tue, 17 Nov 2015 18:55:13 +0000 (18:55 +0000)
committerrsandifo <rsandifo@138bc75d-0d04-0410-961f-82ee72b054a4>
Tue, 17 Nov 2015 18:55:13 +0000 (18:55 +0000)
This patch replaces the fndecl argument to builtin_vectorized_function
with a combined_fn and gets the vectoriser to call it for internal
functions too.  The patch also moves vectorisation of machine-specific
built-ins to a new hook, builtin_md_vectorized_function.

Tested on x86_64-linux-gnu, aarch64-linux-gnu, arm-linux-gnu and
powerpc64-linux-gnu.

gcc/
* 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.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@230491 138bc75d-0d04-0410-961f-82ee72b054a4

13 files changed:
gcc/ChangeLog
gcc/config/aarch64/aarch64-builtins.c
gcc/config/aarch64/aarch64-protos.h
gcc/config/arm/arm-builtins.c
gcc/config/arm/arm-protos.h
gcc/config/i386/i386.c
gcc/config/rs6000/rs6000.c
gcc/doc/tm.texi
gcc/doc/tm.texi.in
gcc/target.def
gcc/targhooks.c
gcc/targhooks.h
gcc/tree-vect-stmts.c

index c6ddc5a..5c6a83d 100644 (file)
@@ -1,5 +1,49 @@
 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.
        (vect_recog_pow_pattern): Use IFN_SQRT instead of BUILT_IN_SQRT*.
 
index 6b4208f..c4cda4f 100644 (file)
@@ -38,6 +38,7 @@
 #include "expr.h"
 #include "langhooks.h"
 #include "gimple-iterator.h"
+#include "case-cfn-macros.h"
 
 #define v8qi_UP  V8QImode
 #define v4hi_UP  V4HImode
@@ -1258,7 +1259,8 @@ aarch64_expand_builtin (tree exp,
 }
 
 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;
@@ -1282,130 +1284,119 @@ aarch64_builtin_vectorized_function (tree fndecl, tree type_out, tree type_in)
        : (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;
index 9000d67..e0a050c 100644 (file)
@@ -409,10 +409,7 @@ tree aarch64_builtin_decl (unsigned, bool ATTRIBUTE_UNUSED);
 
 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);
index 612ff5c..11cd17d 100644 (file)
@@ -35,6 +35,7 @@
 #include "explow.h"
 #include "expr.h"
 #include "langhooks.h"
+#include "case-cfn-macros.h"
 
 #define SIMD_MAX_BUILTIN_ARGS 5
 
@@ -2842,7 +2843,7 @@ arm_expand_builtin (tree exp,
 }
 
 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;
@@ -2879,19 +2880,16 @@ arm_builtin_vectorized_function (tree fndecl, tree type_out, tree type_in)
       ? 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 \
@@ -2910,52 +2908,51 @@ arm_builtin_vectorized_function (tree fndecl, tree type_out, tree type_in)
    : (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;
 }
index 8e73753..e4b8fb3 100644 (file)
@@ -84,7 +84,7 @@ extern char *neon_output_shift_immediate (const char *, char, rtx *,
 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);
index 6173dae..763230a 100644 (file)
@@ -73,6 +73,7 @@ along with GCC; see the file COPYING3.  If not see
 #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"
@@ -2612,10 +2613,10 @@ static int ix86_tune_defaulted;
 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
@@ -41989,21 +41990,19 @@ ix86_store_returned_bounds (rtx slot, rtx bounds)
   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));
@@ -42013,7 +42012,7 @@ ix86_builtin_vectorized_function (tree fndecl, tree 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)
@@ -42023,17 +42022,6 @@ ix86_builtin_vectorized_function (tree fndecl, tree type_out,
          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)
@@ -42045,9 +42033,17 @@ ix86_builtin_vectorized_function (tree fndecl, tree type_out,
        }
       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;
@@ -42061,15 +42057,6 @@ ix86_builtin_vectorized_function (tree fndecl, tree type_out,
          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)
@@ -42079,9 +42066,9 @@ ix86_builtin_vectorized_function (tree fndecl, tree type_out,
        }
       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;
@@ -42095,15 +42082,6 @@ ix86_builtin_vectorized_function (tree fndecl, tree type_out,
          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)
@@ -42113,9 +42091,9 @@ ix86_builtin_vectorized_function (tree fndecl, tree type_out,
        }
       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)
@@ -42123,11 +42101,6 @@ ix86_builtin_vectorized_function (tree fndecl, tree type_out,
          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)
@@ -42137,9 +42110,9 @@ ix86_builtin_vectorized_function (tree fndecl, tree type_out,
        }
       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;
@@ -42153,15 +42126,6 @@ ix86_builtin_vectorized_function (tree fndecl, tree type_out,
          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)
@@ -42171,7 +42135,7 @@ ix86_builtin_vectorized_function (tree fndecl, tree type_out,
        }
       break;
 
-    case BUILT_IN_COPYSIGN:
+    CASE_CFN_COPYSIGN:
       if (out_mode == DFmode && in_mode == DFmode)
        {
          if (out_n == 2 && in_n == 2)
@@ -42181,9 +42145,6 @@ ix86_builtin_vectorized_function (tree fndecl, tree type_out,
          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)
@@ -42195,7 +42156,7 @@ ix86_builtin_vectorized_function (tree fndecl, tree type_out,
        }
       break;
 
-    case BUILT_IN_FLOOR:
+    CASE_CFN_FLOOR:
       /* The round insn does not trap on denormals.  */
       if (flag_trapping_math || !TARGET_ROUND)
        break;
@@ -42207,13 +42168,6 @@ ix86_builtin_vectorized_function (tree fndecl, tree type_out,
          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)
@@ -42223,7 +42177,7 @@ ix86_builtin_vectorized_function (tree fndecl, tree type_out,
        }
       break;
 
-    case BUILT_IN_CEIL:
+    CASE_CFN_CEIL:
       /* The round insn does not trap on denormals.  */
       if (flag_trapping_math || !TARGET_ROUND)
        break;
@@ -42235,13 +42189,6 @@ ix86_builtin_vectorized_function (tree fndecl, tree type_out,
          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)
@@ -42251,7 +42198,7 @@ ix86_builtin_vectorized_function (tree fndecl, tree type_out,
        }
       break;
 
-    case BUILT_IN_TRUNC:
+    CASE_CFN_TRUNC:
       /* The round insn does not trap on denormals.  */
       if (flag_trapping_math || !TARGET_ROUND)
        break;
@@ -42263,13 +42210,6 @@ ix86_builtin_vectorized_function (tree fndecl, tree type_out,
          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)
@@ -42279,7 +42219,7 @@ ix86_builtin_vectorized_function (tree fndecl, tree type_out,
        }
       break;
 
-    case BUILT_IN_RINT:
+    CASE_CFN_RINT:
       /* The round insn does not trap on denormals.  */
       if (flag_trapping_math || !TARGET_ROUND)
        break;
@@ -42291,13 +42231,6 @@ ix86_builtin_vectorized_function (tree fndecl, tree type_out,
          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)
@@ -42307,7 +42240,7 @@ ix86_builtin_vectorized_function (tree fndecl, tree type_out,
        }
       break;
 
-    case BUILT_IN_ROUND:
+    CASE_CFN_ROUND:
       /* The round insn does not trap on denormals.  */
       if (flag_trapping_math || !TARGET_ROUND)
        break;
@@ -42319,13 +42252,6 @@ ix86_builtin_vectorized_function (tree fndecl, tree type_out,
          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)
@@ -42335,7 +42261,7 @@ ix86_builtin_vectorized_function (tree fndecl, tree type_out,
        }
       break;
 
-    case BUILT_IN_FMA:
+    CASE_CFN_FMA:
       if (out_mode == DFmode && in_mode == DFmode)
        {
          if (out_n == 2 && in_n == 2)
@@ -42343,9 +42269,6 @@ ix86_builtin_vectorized_function (tree fndecl, tree type_out,
          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)
@@ -42361,8 +42284,7 @@ ix86_builtin_vectorized_function (tree fndecl, tree type_out,
 
   /* 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;
 }
@@ -42371,7 +42293,7 @@ ix86_builtin_vectorized_function (tree fndecl, tree type_out,
    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;
@@ -42394,47 +42316,26 @@ ix86_veclibabi_svml (enum built_in_function fn, tree type_out, tree type_in)
 
   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;
 
@@ -42442,11 +42343,12 @@ ix86_veclibabi_svml (enum built_in_function fn, tree type_out, tree type_in)
       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)
     {
@@ -42460,9 +42362,7 @@ ix86_veclibabi_svml (enum built_in_function fn, tree type_out, tree type_in)
   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)
@@ -42485,7 +42385,7 @@ ix86_veclibabi_svml (enum built_in_function fn, tree type_out, tree type_in)
    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;
@@ -42511,30 +42411,23 @@ ix86_veclibabi_acml (enum built_in_function fn, tree type_out, tree type_in)
 
   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;
 
@@ -42542,13 +42435,12 @@ ix86_veclibabi_acml (enum built_in_function fn, tree type_out, tree type_in)
       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)
index 5d0a022..688f1db 100644 (file)
@@ -70,6 +70,7 @@
 #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"
@@ -1107,7 +1108,7 @@ static const struct rs6000_builtin_info_type rs6000_builtin_info[] =
 #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);
@@ -1117,7 +1118,7 @@ static int rs6000_ra_ever_killed (void);
 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);
@@ -1606,6 +1607,10 @@ static const struct attribute_spec rs6000_attribute_table[] =
 #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
@@ -5173,7 +5178,8 @@ rs6000_destroy_cost_data (void *data)
    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;
@@ -5198,93 +5204,57 @@ rs6000_builtin_vectorized_libmass (tree fndecl, tree type_out, tree type_in)
       || 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));
@@ -5317,7 +5287,7 @@ rs6000_builtin_vectorized_libmass (tree fndecl, tree type_out, tree type_in)
    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;
@@ -5325,7 +5295,7 @@ rs6000_builtin_vectorized_function (tree fndecl, tree type_out,
 
   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)));
 
@@ -5339,203 +5309,205 @@ rs6000_builtin_vectorized_function (tree fndecl, tree type_out,
   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
index 1a7760a..bde808b 100644 (file)
@@ -5673,11 +5673,17 @@ If this hook is defined, the autovectorizer will use the
 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
index 34105c9..0677fc1 100644 (file)
@@ -4235,6 +4235,8 @@ address;  but often a machine-dependent strategy can generate better code.
 
 @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
index 61cb14b..b0ad09e 100644 (file)
@@ -1728,18 +1728,28 @@ the argument @var{OFF} to @code{REALIGN_LOAD}, in which case the low\n\
 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.  */
index 66d983b..01d3686 100644 (file)
@@ -534,9 +534,15 @@ default_invalid_within_doloop (const rtx_insn *insn)
 /* 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;
 }
index c9d745b..f5d04e6 100644 (file)
@@ -83,7 +83,8 @@ extern bool default_has_ifunc_p (void);
 
 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);
 
index 0f64aaf..0a3cac5 100644 (file)
@@ -1648,20 +1648,20 @@ vect_finish_stmt_generation (gimple *stmt, gimple *vec_stmt,
 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;
 }