00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029 #include "bconfig.h"
00030 #include "system.h"
00031 #include "coretypes.h"
00032 #include "tm.h"
00033 #include "rtl.h"
00034 #include "errors.h"
00035 #include "hashtab.h"
00036 #include "gensupport.h"
00037
00038
00039 static int saw_eh_return;
00040
00041 static void write_header (void);
00042 static void write_conditions (void);
00043 static int write_one_condition (void **, void *);
00044
00045
00046
00047 static void
00048 write_header (void)
00049 {
00050 puts ("\
00051 /* Generated automatically by the program `genconditions' from the target\n\
00052 machine description file. */\n\
00053 \n\
00054 #include \"bconfig.h\"\n\
00055 #include \"system.h\"\n\
00056 \n\
00057 /* It is necessary, but not entirely safe, to include the headers below\n\
00058 in a generator program. As a defensive measure, don't do so when the\n\
00059 table isn't going to have anything in it. */\n\
00060 #if GCC_VERSION >= 3001\n\
00061 \n\
00062 /* Do not allow checking to confuse the issue. */\n\
00063 #undef ENABLE_CHECKING\n\
00064 #undef ENABLE_TREE_CHECKING\n\
00065 #undef ENABLE_RTL_CHECKING\n\
00066 #undef ENABLE_RTL_FLAG_CHECKING\n\
00067 #undef ENABLE_GC_CHECKING\n\
00068 #undef ENABLE_GC_ALWAYS_COLLECT\n\
00069 \n\
00070 #include \"coretypes.h\"\n\
00071 #include \"tm.h\"\n\
00072 #include \"insn-constants.h\"\n\
00073 #include \"rtl.h\"\n\
00074 #include \"tm_p.h\"\n\
00075 #include \"function.h\"\n\
00076 \n\
00077 /* Fake - insn-config.h doesn't exist yet. */\n\
00078 #define MAX_RECOG_OPERANDS 10\n\
00079 #define MAX_DUP_OPERANDS 10\n\
00080 #define MAX_INSNS_PER_SPLIT 5\n\
00081 \n\
00082 #include \"regs.h\"\n\
00083 #include \"recog.h\"\n\
00084 #include \"real.h\"\n\
00085 #include \"output.h\"\n\
00086 #include \"flags.h\"\n\
00087 #include \"hard-reg-set.h\"\n\
00088 #include \"resource.h\"\n\
00089 #include \"toplev.h\"\n\
00090 #include \"reload.h\"\n\
00091 #include \"tm-constrs.h\"\n");
00092
00093 if (saw_eh_return)
00094 puts ("#define HAVE_eh_return 1");
00095 puts ("#include \"except.h\"\n");
00096
00097 puts ("\
00098 /* Dummy external declarations. */\n\
00099 extern rtx insn;\n\
00100 extern rtx ins1;\n\
00101 extern rtx operands[];\n\
00102 \n\
00103 #endif /* gcc >= 3.0.1 */\n");
00104 }
00105
00106
00107
00108
00109
00110
00111
00112
00113
00114 static int
00115 write_one_condition (void **slot, void * ARG_UNUSED (dummy))
00116 {
00117 const struct c_test *test = * (const struct c_test **) slot;
00118 const char *p;
00119
00120 print_rtx_ptr_loc (test->expr);
00121 fputs (" { \"", stdout);
00122 for (p = test->expr; *p; p++)
00123 {
00124 switch (*p)
00125 {
00126 case '\n': fputs ("\\n\\", stdout); break;
00127 case '\\':
00128 case '\"': putchar ('\\'); break;
00129 default: break;
00130 }
00131 putchar (*p);
00132 }
00133
00134 fputs ("\",\n __builtin_constant_p ", stdout);
00135 print_c_condition (test->expr);
00136 fputs ("\n ? (int) ", stdout);
00137 print_c_condition (test->expr);
00138 fputs ("\n : -1 },\n", stdout);
00139 return 1;
00140 }
00141
00142
00143
00144 static void
00145 write_conditions (void)
00146 {
00147 puts ("\
00148 /* Structure definition duplicated from gensupport.h rather than\n\
00149 drag in that file and its dependencies. */\n\
00150 struct c_test\n\
00151 {\n\
00152 const char *expr;\n\
00153 int value;\n\
00154 };\n\
00155 \n\
00156 /* This table lists each condition found in the machine description.\n\
00157 Each condition is mapped to its truth value (0 or 1), or -1 if that\n\
00158 cannot be calculated at compile time.\n\
00159 If we don't have __builtin_constant_p, or it's not acceptable in array\n\
00160 initializers, fall back to assuming that all conditions potentially\n\
00161 vary at run time. It works in 3.0.1 and later; 3.0 only when not\n\
00162 optimizing. */\n\
00163 \n\
00164 #if GCC_VERSION >= 3001\n\
00165 static const struct c_test insn_conditions[] = {\n");
00166
00167 traverse_c_tests (write_one_condition, 0);
00168
00169 puts ("\n};\n#endif /* gcc >= 3.0.1 */\n");
00170 }
00171
00172
00173
00174
00175
00176 static void
00177 write_writer (void)
00178 {
00179 puts ("int\n"
00180 "main(void)\n"
00181 "{\n"
00182 " unsigned int i;\n"
00183 " const char *p;\n"
00184 " puts (\"(define_conditions [\");\n"
00185 "#if GCC_VERSION >= 3001\n"
00186 " for (i = 0; i < ARRAY_SIZE (insn_conditions); i++)\n"
00187 " {\n"
00188 " printf (\" (%d \\\"\", insn_conditions[i].value);\n"
00189 " for (p = insn_conditions[i].expr; *p; p++)\n"
00190 " {\n"
00191 " switch (*p)\n"
00192 " {\n"
00193 " case '\\\\':\n"
00194 " case '\\\"': putchar ('\\\\'); break;\n"
00195 " default: break;\n"
00196 " }\n"
00197 " putchar (*p);\n"
00198 " }\n"
00199 " puts (\"\\\")\");\n"
00200 " }\n"
00201 "#endif /* gcc >= 3.0.1 */\n"
00202 " puts (\"])\");\n"
00203 " fflush (stdout);\n"
00204 "return ferror (stdout) != 0 ? FATAL_EXIT_CODE : SUCCESS_EXIT_CODE;\n"
00205 "}");
00206 }
00207
00208 int
00209 main (int argc, char **argv)
00210 {
00211 rtx desc;
00212 int pattern_lineno;
00213 int code;
00214
00215 progname = "genconditions";
00216
00217 if (init_md_reader_args (argc, argv) != SUCCESS_EXIT_CODE)
00218 return (FATAL_EXIT_CODE);
00219
00220
00221 while (1)
00222 {
00223 desc = read_md_rtx (&pattern_lineno, &code);
00224 if (desc == NULL)
00225 break;
00226
00227
00228
00229 switch (GET_CODE (desc))
00230 {
00231 default:
00232 break;
00233
00234 case DEFINE_INSN:
00235 case DEFINE_EXPAND:
00236 add_c_test (XSTR (desc, 2), -1);
00237
00238
00239 if (!strcmp (XSTR (desc, 0), "eh_return"))
00240 saw_eh_return = 1;
00241 break;
00242
00243 case DEFINE_SPLIT:
00244 case DEFINE_PEEPHOLE:
00245 case DEFINE_PEEPHOLE2:
00246 add_c_test (XSTR (desc, 1), -1);
00247 break;
00248 }
00249 }
00250
00251 write_header ();
00252 write_conditions ();
00253 write_writer ();
00254
00255 fflush (stdout);
00256 return (ferror (stdout) != 0 ? FATAL_EXIT_CODE : SUCCESS_EXIT_CODE);
00257 }