X-Git-Url: http://git.sourceforge.jp/view?a=blobdiff_plain;f=gcc%2Fgenconditions.c;h=65f64c085ce9383f31dc951bd099d5a552b0fd4b;hb=d7ee9e9b2c64ba18bed14efcf05bec2ff8b2c824;hp=3f05706f46c9520f26c7cd6099a14b6a107e076c;hpb=ba08da2c50d6a9089afa00750d0c676c740582a8;p=pf3gnuchains%2Fgcc-fork.git diff --git a/gcc/genconditions.c b/gcc/genconditions.c index 3f05706f46c..65f64c085ce 100644 --- a/gcc/genconditions.c +++ b/gcc/genconditions.c @@ -1,11 +1,12 @@ /* Process machine description and calculate constant conditions. - Copyright (C) 2001, 2002, 2003, 2004 Free Software Foundation, Inc. + Copyright (C) 2001, 2002, 2003, 2004, 2005, 2007 + 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 2, or (at your option) + 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, @@ -14,9 +15,8 @@ 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 COPYING. If not, write to - the Free Software Foundation, 59 Temple Place - Suite 330, - Boston, MA 02111-1307, USA. */ + along with GCC; see the file COPYING3. If not see + . */ /* In a machine description, all of the insn patterns - define_insn, define_expand, define_split, define_peephole, define_peephole2 - @@ -38,31 +38,10 @@ /* so we can include except.h in the generated file. */ static int saw_eh_return; -static htab_t condition_table; - -static void add_condition (const char *); static void write_header (void); static void write_conditions (void); static int write_one_condition (void **, void *); -/* Record the C test expression EXPR in the condition_table. - Duplicates clobber previous entries, which leaks memory, but - we don't care for this application. */ - -static void -add_condition (const char *expr) -{ - struct c_test *test; - - if (expr[0] == 0) - return; - - test = XNEW (struct c_test); - test->expr = expr; - - *(htab_find_slot (condition_table, test, INSERT)) = test; -} - /* Generate the header for insn-conditions.c. */ static void @@ -73,32 +52,33 @@ write_header (void) machine description file. */\n\ \n\ #include \"bconfig.h\"\n\ -#include \"insn-constants.h\"\n"); - - puts ("\ +#include \"system.h\"\n\ +\n\ +/* It is necessary, but not entirely safe, to include the headers below\n\ + in a generator program. As a defensive measure, don't do so when the\n\ + table isn't going to have anything in it. */\n\ +#if GCC_VERSION >= 3001\n\ +\n\ /* Do not allow checking to confuse the issue. */\n\ #undef ENABLE_CHECKING\n\ #undef ENABLE_TREE_CHECKING\n\ #undef ENABLE_RTL_CHECKING\n\ #undef ENABLE_RTL_FLAG_CHECKING\n\ #undef ENABLE_GC_CHECKING\n\ -#undef ENABLE_GC_ALWAYS_COLLECT\n"); - - puts ("\ -#include \"system.h\"\n\ +#undef ENABLE_GC_ALWAYS_COLLECT\n\ +\n\ #include \"coretypes.h\"\n\ #include \"tm.h\"\n\ +#include \"insn-constants.h\"\n\ #include \"rtl.h\"\n\ #include \"tm_p.h\"\n\ -#include \"function.h\"\n"); - - puts ("\ +#include \"function.h\"\n\ +\n\ /* Fake - insn-config.h doesn't exist yet. */\n\ #define MAX_RECOG_OPERANDS 10\n\ #define MAX_DUP_OPERANDS 10\n\ -#define MAX_INSNS_PER_SPLIT 5\n"); - - puts ("\ +#define MAX_INSNS_PER_SPLIT 5\n\ +\n\ #include \"regs.h\"\n\ #include \"recog.h\"\n\ #include \"real.h\"\n\ @@ -108,7 +88,7 @@ write_header (void) #include \"resource.h\"\n\ #include \"toplev.h\"\n\ #include \"reload.h\"\n\ -#include \"gensupport.h\"\n"); +#include \"tm-constrs.h\"\n"); if (saw_eh_return) puts ("#define HAVE_eh_return 1"); @@ -118,24 +98,18 @@ write_header (void) /* Dummy external declarations. */\n\ extern rtx insn;\n\ extern rtx ins1;\n\ -extern rtx operands[];\n"); - - puts ("\ -/* If we don't have __builtin_constant_p, or it's not acceptable in\n\ - array initializers, fall back to assuming that all conditions\n\ - potentially vary at run time. It works in 3.0.1 and later; 3.0\n\ - only when not optimizing. */\n\ -#if (GCC_VERSION >= 3001) || ((GCC_VERSION == 3000) && !__OPTIMIZE__)\n\ -# define MAYBE_EVAL(expr) (__builtin_constant_p(expr) ? (int) (expr) : -1)\n\ -#else\n\ -# define MAYBE_EVAL(expr) -1\n\ -#endif\n"); +extern rtx operands[];\n\ +\n\ +#endif /* gcc >= 3.0.1 */\n"); } /* Write out one entry in the conditions table, using the data pointed to by SLOT. Each entry looks like this: - { "! optimize_size && ! TARGET_READ_MODIFY_WRITE", - MAYBE_EVAL (! optimize_size && ! TARGET_READ_MODIFY_WRITE) }, */ + + { "! optimize_size && ! TARGET_READ_MODIFY_WRITE", + __builtin_constant_p (! optimize_size && ! TARGET_READ_MODIFY_WRITE) + ? (int) (! optimize_size && ! TARGET_READ_MODIFY_WRITE) + : -1) }, */ static int write_one_condition (void **slot, void * ARG_UNUSED (dummy)) @@ -143,18 +117,25 @@ write_one_condition (void **slot, void * ARG_UNUSED (dummy)) const struct c_test *test = * (const struct c_test **) slot; const char *p; + print_rtx_ptr_loc (test->expr); fputs (" { \"", stdout); for (p = test->expr; *p; p++) { - if (*p == '\n') - fputs ("\\n\\\n", stdout); - else if (*p == '"') - fputs ("\\\"", stdout); - else - putchar (*p); + switch (*p) + { + case '\n': fputs ("\\n\\", stdout); break; + case '\\': + case '\"': putchar ('\\'); break; + default: break; + } + putchar (*p); } - printf ("\",\n MAYBE_EVAL (%s) },\n", test->expr); + fputs ("\",\n __builtin_constant_p ", stdout); + print_c_condition (test->expr); + fputs ("\n ? (int) ", stdout); + print_c_condition (test->expr); + fputs ("\n : -1 },\n", stdout); return 1; } @@ -164,19 +145,64 @@ static void write_conditions (void) { puts ("\ +/* Structure definition duplicated from gensupport.h rather than\n\ + drag in that file and its dependencies. */\n\ +struct c_test\n\ +{\n\ + const char *expr;\n\ + int value;\n\ +};\n\ +\n\ /* This table lists each condition found in the machine description.\n\ Each condition is mapped to its truth value (0 or 1), or -1 if that\n\ - cannot be calculated at compile time. */\n\ + cannot be calculated at compile time.\n\ + If we don't have __builtin_constant_p, or it's not acceptable in array\n\ + initializers, fall back to assuming that all conditions potentially\n\ + vary at run time. It works in 3.0.1 and later; 3.0 only when not\n\ + optimizing. */\n\ \n\ -const struct c_test insn_conditions[] = {"); +#if GCC_VERSION >= 3001\n\ +static const struct c_test insn_conditions[] = {\n"); - htab_traverse (condition_table, write_one_condition, 0); + traverse_c_tests (write_one_condition, 0); - puts ("};\n"); + puts ("\n};\n#endif /* gcc >= 3.0.1 */\n"); +} - printf ("const size_t n_insn_conditions = %lu;\n", - (unsigned long) htab_elements (condition_table)); - puts ("const int insn_elision_unavailable = 0;"); +/* Emit code which will convert the C-format table to a + (define_conditions) form, which the MD reader can understand. + The result will be added to the set of files scanned by + 'downstream' generators. */ +static void +write_writer (void) +{ + puts ("int\n" + "main(void)\n" + "{\n" + " unsigned int i;\n" + " const char *p;\n" + " puts (\"(define_conditions [\");\n" + "#if GCC_VERSION >= 3001\n" + " for (i = 0; i < ARRAY_SIZE (insn_conditions); i++)\n" + " {\n" + " printf (\" (%d \\\"\", insn_conditions[i].value);\n" + " for (p = insn_conditions[i].expr; *p; p++)\n" + " {\n" + " switch (*p)\n" + " {\n" + " case '\\\\':\n" + " case '\\\"': putchar ('\\\\'); break;\n" + " default: break;\n" + " }\n" + " putchar (*p);\n" + " }\n" + " puts (\"\\\")\");\n" + " }\n" + "#endif /* gcc >= 3.0.1 */\n" + " puts (\"])\");\n" + " fflush (stdout);\n" + "return ferror (stdout) != 0 ? FATAL_EXIT_CODE : SUCCESS_EXIT_CODE;\n" + "}"); } int @@ -191,10 +217,7 @@ main (int argc, char **argv) if (init_md_reader_args (argc, argv) != SUCCESS_EXIT_CODE) return (FATAL_EXIT_CODE); - condition_table = htab_create (1000, hash_c_test, cmp_c_test, NULL); - /* Read the machine description. */ - while (1) { desc = read_md_rtx (&pattern_lineno, &code); @@ -210,7 +233,7 @@ main (int argc, char **argv) case DEFINE_INSN: case DEFINE_EXPAND: - add_condition (XSTR (desc, 2)); + add_c_test (XSTR (desc, 2), -1); /* except.h needs to know whether there is an eh_return pattern in the machine description. */ if (!strcmp (XSTR (desc, 0), "eh_return")) @@ -220,13 +243,14 @@ main (int argc, char **argv) case DEFINE_SPLIT: case DEFINE_PEEPHOLE: case DEFINE_PEEPHOLE2: - add_condition (XSTR (desc, 1)); + add_c_test (XSTR (desc, 1), -1); break; } } write_header (); write_conditions (); + write_writer (); fflush (stdout); return (ferror (stdout) != 0 ? FATAL_EXIT_CODE : SUCCESS_EXIT_CODE);