diff gcc/gencfn-macros.c @ 16:04ced10e8804

gcc 7
author kono
date Fri, 27 Oct 2017 22:46:09 +0900
parents
children 84e7813d76e9
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/gcc/gencfn-macros.c	Fri Oct 27 22:46:09 2017 +0900
@@ -0,0 +1,218 @@
+/* Generate macros based on the combined_fn enum.
+   Copyright (C) 2015-2017 Free Software Foundation, Inc.
+
+This file is part of GCC.
+
+GCC is free software; you can redistribute it and/or modify it under
+the terms of the GNU General Public License as published by the Free
+Software Foundation; either version 3, or (at your option) any later
+version.
+
+GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with GCC; see the file COPYING3.  If not see
+<http://www.gnu.org/licenses/>.  */
+
+/* Automatically generate code fragments related to combined_fn.
+
+   The program looks for math built-in functions that have float, double
+   and long double variants, such as {sqrtf, sqrt, sqrtl}, and that may
+   or may not have an associated internal function as well.  It also looks
+   for integer built-in functions that have int, long, long long and
+   intmax_t variants, such as {clz, clzl, clzll, clzimax}, and that
+   again may or may not have an associated internal function as well.
+
+   When run with -c, the generator prints a list of macros such as:
+
+      CASE_CFN_SQRT
+
+   for each group of functions described above, with 'case CFN_*'
+   statements for each built-in and internal function in the group.
+   For example, there are both built-in and internal implementations
+   of SQRT, so "CASE_CFN_SQRT:" is equivalent to:
+
+      case CFN_BUILT_IN_SQRTF:
+      case CFN_BUILT_IN_SQRT:
+      case CFN_BUILT_IN_SQRTL:
+      case CFN_SQRT:
+
+   The macros for groups with no internal function drop the last line.
+
+   When run with -o, the generator prints a similar list of
+   define_operator_list directives, for use by match.pd.  Each operator
+   list starts with the built-in functions, in order of ascending type width.
+   This is followed by an entry for the internal function, or "null" if there
+   is no internal function for the group.  For example:
+
+     (define_operator_list SQRT
+	 BUILT_IN_SQRTF
+	 BUILT_IN_SQRT
+	 BUILT_IN_SQRTL
+	 IFN_SQRT)
+
+   and:
+
+     (define_operator_list CABS
+	 BUILT_IN_CABSF
+	 BUILT_IN_CABS
+	 BUILT_IN_CABSL
+	 null)  */
+
+#include "bconfig.h"
+#include "system.h"
+#include "coretypes.h"
+#include "hash-table.h"
+#include "hash-set.h"
+#include "errors.h"
+
+typedef hash_set <nofree_string_hash> string_set;
+
+/* Add all names in null-terminated list NAMES to SET.  */
+
+static void
+add_to_set (string_set *set, const char *const *names)
+{
+  for (unsigned int i = 0; names[i]; ++i)
+    set->add (names[i]);
+}
+
+/* Return true if *BUILTINS contains BUILT_IN_<NAME><SUFFIX> for all
+   suffixes in null-terminated list SUFFIXES.  */
+
+static bool
+is_group (string_set *builtins, const char *name, const char *const *suffixes)
+{
+  for (unsigned int i = 0; suffixes[i]; ++i)
+    if (!builtins->contains (ACONCAT (("BUILT_IN_", name, suffixes[i], NULL))))
+      return false;
+  return true;
+}
+
+/* Print a macro for all combined functions related to NAME, with the
+   null-terminated list of suffixes in SUFFIXES.  INTERNAL_P says whether
+   CFN_<NAME> also exists.  */
+
+static void
+print_case_cfn (const char *name, bool internal_p,
+		const char *const *suffixes)
+{
+  printf ("#define CASE_CFN_%s", name);
+  if (internal_p)
+    printf (" \\\n  case CFN_%s", name);
+  for (unsigned int i = 0; suffixes[i]; ++i)
+    printf ("%s \\\n  case CFN_BUILT_IN_%s%s",
+	    internal_p || i > 0 ? ":" : "", name, suffixes[i]);
+  printf ("\n");
+}
+
+/* Print an operator list for all combined functions related to NAME,
+   with the null-terminated list of suffixes in SUFFIXES.  INTERNAL_P
+   says whether CFN_<NAME> also exists.  */
+
+static void
+print_define_operator_list (const char *name, bool internal_p,
+			    const char *const *suffixes)
+{
+  printf ("(define_operator_list %s\n", name);
+  for (unsigned int i = 0; suffixes[i]; ++i)
+    printf ("    BUILT_IN_%s%s\n", name, suffixes[i]);
+  if (internal_p)
+    printf ("    IFN_%s)\n", name);
+  else
+    printf ("    null)\n");
+}
+
+const char *const builtin_names[] = {
+#define DEF_BUILTIN(ENUM, N, C, T, LT, B, F, NA, AT, IM, COND) \
+  #ENUM,
+#include "builtins.def"
+  NULL
+};
+
+const char *const internal_fn_flt_names[] = {
+#define DEF_INTERNAL_FLT_FN(NAME, FLAGS, OPTAB, TYPE) \
+  #NAME,
+#include "internal-fn.def"
+  NULL
+};
+
+const char *const internal_fn_int_names[] = {
+#define DEF_INTERNAL_INT_FN(NAME, FLAGS, OPTAB, TYPE) \
+  #NAME,
+#include "internal-fn.def"
+  NULL
+};
+
+static const char *const flt_suffixes[] = { "F", "", "L", NULL };
+static const char *const int_suffixes[] = { "", "L", "LL", "IMAX", NULL };
+
+static const char *const *const suffix_lists[] = {
+  flt_suffixes,
+  int_suffixes,
+  NULL
+};
+
+int
+main (int argc, char **argv)
+{
+  /* Check arguments.  */
+  progname = argv[0];
+  if (argc != 2
+      || argv[1][0] != '-'
+      || !strchr ("co", argv[1][1])
+      || argv[1][2])
+    fatal ("usage: %s [-c|-o] > file", progname);
+  int type = argv[1][1];
+
+  /* Collect the set of built-in and internal functions.  */
+  string_set builtins;
+  string_set internal_fns;
+  add_to_set (&builtins, builtin_names);
+  add_to_set (&internal_fns, internal_fn_flt_names);
+  add_to_set (&internal_fns, internal_fn_int_names);
+
+  /* Check the functions.  */
+  for (unsigned int i = 0; internal_fn_flt_names[i]; ++i)
+    {
+      const char *name = internal_fn_flt_names[i];
+      if (!is_group (&builtins, name, flt_suffixes))
+	error ("DEF_INTERNAL_FLT_FN (%s) has no associated built-in"
+	       " functions", name);
+    }
+  for (unsigned int i = 0; internal_fn_int_names[i]; ++i)
+    {
+      const char *name = internal_fn_int_names[i];
+      if (!is_group (&builtins, name, int_suffixes))
+	error ("DEF_INTERNAL_INT_FN (%s) has no associated built-in"
+	       " functions", name);
+    }
+
+  /* Go through the built-in functions in declaration order, outputting
+     definitions as appropriate.  */
+  for (unsigned int i = 0; builtin_names[i]; ++i)
+    {
+      const char *name = builtin_names[i];
+      if (strncmp (name, "BUILT_IN_", 9) == 0)
+	{
+	  const char *root = name + 9;
+	  for (unsigned int j = 0; suffix_lists[j]; ++j)
+	    if (is_group (&builtins, root, suffix_lists[j]))
+	      {
+		bool internal_p = internal_fns.contains (root);
+		if (type == 'c')
+		  print_case_cfn (root, internal_p, suffix_lists[j]);
+		else
+		  print_define_operator_list (root, internal_p,
+					      suffix_lists[j]);
+	      }
+	}
+    }
+
+  if (fflush (stdout) || fclose (stdout) || have_error)
+    return FATAL_EXIT_CODE;
+  return SUCCESS_EXIT_CODE;
+}