00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #include "hconfig.h"
00025 #include "system.h"
00026 #include "rtl.h"
00027 #include "errors.h"
00028 #include "gensupport.h"
00029
00030
00031
00032 static int max_recog_operands;
00033 static int max_dup_operands;
00034 static int max_clobbers_per_insn;
00035 static int have_cc0_flag;
00036 static int have_cmove_flag;
00037 static int have_cond_exec_flag;
00038 static int have_lo_sum_flag;
00039 static int have_peephole_flag;
00040 static int have_peephole2_flag;
00041
00042
00043 static int max_insns_per_split = 1;
00044
00045
00046 static int max_insns_per_peep2;
00047
00048 static int clobbers_seen_this_insn;
00049 static int dup_operands_seen_this_insn;
00050
00051 static void walk_insn_part PARAMS ((rtx, int, int));
00052 static void gen_insn PARAMS ((rtx));
00053 static void gen_expand PARAMS ((rtx));
00054 static void gen_split PARAMS ((rtx));
00055 static void gen_peephole PARAMS ((rtx));
00056 static void gen_peephole2 PARAMS ((rtx));
00057
00058
00059
00060
00061
00062
00063
00064 static void
00065 walk_insn_part (part, recog_p, non_pc_set_src)
00066 rtx part;
00067 int recog_p;
00068 int non_pc_set_src;
00069 {
00070 int i, j;
00071 RTX_CODE code;
00072 const char *format_ptr;
00073
00074 if (part == 0)
00075 return;
00076
00077 code = GET_CODE (part);
00078 switch (code)
00079 {
00080 case CLOBBER:
00081 clobbers_seen_this_insn++;
00082 break;
00083
00084 case MATCH_OPERAND:
00085 if (XINT (part, 0) > max_recog_operands)
00086 max_recog_operands = XINT (part, 0);
00087 return;
00088
00089 case MATCH_OP_DUP:
00090 case MATCH_PAR_DUP:
00091 ++dup_operands_seen_this_insn;
00092 case MATCH_SCRATCH:
00093 case MATCH_PARALLEL:
00094 case MATCH_OPERATOR:
00095 if (XINT (part, 0) > max_recog_operands)
00096 max_recog_operands = XINT (part, 0);
00097
00098
00099 break;
00100
00101 case LABEL_REF:
00102 if (GET_CODE (XEXP (part, 0)) == MATCH_OPERAND)
00103 break;
00104 return;
00105
00106 case MATCH_DUP:
00107 ++dup_operands_seen_this_insn;
00108 if (XINT (part, 0) > max_recog_operands)
00109 max_recog_operands = XINT (part, 0);
00110 return;
00111
00112 case CC0:
00113 if (recog_p)
00114 have_cc0_flag = 1;
00115 return;
00116
00117 case LO_SUM:
00118 if (recog_p)
00119 have_lo_sum_flag = 1;
00120 return;
00121
00122 case SET:
00123 walk_insn_part (SET_DEST (part), 0, recog_p);
00124 walk_insn_part (SET_SRC (part), recog_p,
00125 GET_CODE (SET_DEST (part)) != PC);
00126 return;
00127
00128 case IF_THEN_ELSE:
00129
00130
00131
00132
00133
00134
00135 if (recog_p && non_pc_set_src
00136 && GET_CODE (XEXP (part, 1)) == MATCH_OPERAND
00137 && GET_CODE (XEXP (part, 2)) == MATCH_OPERAND)
00138 have_cmove_flag = 1;
00139 break;
00140
00141 case COND_EXEC:
00142 if (recog_p)
00143 have_cond_exec_flag = 1;
00144 break;
00145
00146 case REG: case CONST_INT: case SYMBOL_REF:
00147 case PC:
00148 return;
00149
00150 default:
00151 break;
00152 }
00153
00154 format_ptr = GET_RTX_FORMAT (GET_CODE (part));
00155
00156 for (i = 0; i < GET_RTX_LENGTH (GET_CODE (part)); i++)
00157 switch (*format_ptr++)
00158 {
00159 case 'e':
00160 case 'u':
00161 walk_insn_part (XEXP (part, i), recog_p, non_pc_set_src);
00162 break;
00163 case 'E':
00164 if (XVEC (part, i) != NULL)
00165 for (j = 0; j < XVECLEN (part, i); j++)
00166 walk_insn_part (XVECEXP (part, i, j), recog_p, non_pc_set_src);
00167 break;
00168 }
00169 }
00170
00171 static void
00172 gen_insn (insn)
00173 rtx insn;
00174 {
00175 int i;
00176
00177
00178 clobbers_seen_this_insn = 0;
00179 dup_operands_seen_this_insn = 0;
00180 if (XVEC (insn, 1) != 0)
00181 for (i = 0; i < XVECLEN (insn, 1); i++)
00182 walk_insn_part (XVECEXP (insn, 1, i), 1, 0);
00183
00184 if (clobbers_seen_this_insn > max_clobbers_per_insn)
00185 max_clobbers_per_insn = clobbers_seen_this_insn;
00186 if (dup_operands_seen_this_insn > max_dup_operands)
00187 max_dup_operands = dup_operands_seen_this_insn;
00188 }
00189
00190
00191
00192 static void
00193 gen_expand (insn)
00194 rtx insn;
00195 {
00196 int i;
00197
00198
00199
00200
00201
00202 if (XVEC (insn, 1) != 0)
00203 for (i = 0; i < XVECLEN (insn, 1); i++)
00204 {
00205
00206
00207
00208 clobbers_seen_this_insn = 0;
00209
00210 walk_insn_part (XVECEXP (insn, 1, i), 0, 0);
00211
00212 if (clobbers_seen_this_insn > max_clobbers_per_insn)
00213 max_clobbers_per_insn = clobbers_seen_this_insn;
00214 }
00215 }
00216
00217
00218
00219 static void
00220 gen_split (split)
00221 rtx split;
00222 {
00223 int i;
00224
00225
00226
00227 for (i = 0; i < XVECLEN (split, 0); i++)
00228 walk_insn_part (XVECEXP (split, 0, i), 1, 0);
00229
00230 if (XVECLEN (split, 2) > max_insns_per_split)
00231 max_insns_per_split = XVECLEN (split, 2);
00232 }
00233
00234 static void
00235 gen_peephole (peep)
00236 rtx peep;
00237 {
00238 int i;
00239
00240
00241
00242 for (i = 0; i < XVECLEN (peep, 0); i++)
00243 walk_insn_part (XVECEXP (peep, 0, i), 1, 0);
00244 }
00245
00246 static void
00247 gen_peephole2 (peep)
00248 rtx peep;
00249 {
00250 int i, n;
00251
00252
00253
00254 for (i = XVECLEN (peep, 0) - 1; i >= 0; --i)
00255 walk_insn_part (XVECEXP (peep, 0, i), 1, 0);
00256
00257
00258 for (i = XVECLEN (peep, 0) - 1, n = 0; i >= 0; --i)
00259 if (GET_CODE (XVECEXP (peep, 0, i)) != MATCH_DUP
00260 && GET_CODE (XVECEXP (peep, 0, i)) != MATCH_SCRATCH)
00261 n++;
00262 if (n > max_insns_per_peep2)
00263 max_insns_per_peep2 = n;
00264 }
00265
00266 extern int main PARAMS ((int, char **));
00267
00268 int
00269 main (argc, argv)
00270 int argc;
00271 char **argv;
00272 {
00273 rtx desc;
00274
00275 progname = "genconfig";
00276
00277 if (argc <= 1)
00278 fatal ("no input file name");
00279
00280 if (init_md_reader_args (argc, argv) != SUCCESS_EXIT_CODE)
00281 return (FATAL_EXIT_CODE);
00282
00283 puts ("/* Generated automatically by the program `genconfig'");
00284 puts (" from the machine description file `md'. */\n");
00285 puts ("#ifndef GCC_INSN_CONFIG_H");
00286 puts ("#define GCC_INSN_CONFIG_H\n");
00287
00288
00289
00290
00291 max_recog_operands = 29;
00292 max_dup_operands = 1;
00293
00294
00295
00296 while (1)
00297 {
00298 int line_no, insn_code_number = 0;
00299
00300 desc = read_md_rtx (&line_no, &insn_code_number);
00301 if (desc == NULL)
00302 break;
00303
00304 switch (GET_CODE (desc))
00305 {
00306 case DEFINE_INSN:
00307 gen_insn (desc);
00308 break;
00309
00310 case DEFINE_EXPAND:
00311 gen_expand (desc);
00312 break;
00313
00314 case DEFINE_SPLIT:
00315 gen_split (desc);
00316 break;
00317
00318 case DEFINE_PEEPHOLE2:
00319 have_peephole2_flag = 1;
00320 gen_peephole2 (desc);
00321 break;
00322
00323 case DEFINE_PEEPHOLE:
00324 have_peephole_flag = 1;
00325 gen_peephole (desc);
00326 break;
00327
00328 default:
00329 break;
00330 }
00331 }
00332
00333 printf ("#define MAX_RECOG_OPERANDS %d\n", max_recog_operands + 1);
00334 printf ("#define MAX_DUP_OPERANDS %d\n", max_dup_operands);
00335
00336
00337
00338 printf ("#ifndef MAX_INSNS_PER_SPLIT\n");
00339 printf ("#define MAX_INSNS_PER_SPLIT %d\n", max_insns_per_split);
00340 printf ("#endif\n");
00341
00342 if (have_cc0_flag)
00343 printf ("#define HAVE_cc0 1\n");
00344
00345 if (have_cmove_flag)
00346 printf ("#define HAVE_conditional_move 1\n");
00347
00348 if (have_cond_exec_flag)
00349 printf ("#define HAVE_conditional_execution 1\n");
00350
00351 if (have_lo_sum_flag)
00352 printf ("#define HAVE_lo_sum 1\n");
00353
00354 if (have_peephole_flag)
00355 printf ("#define HAVE_peephole 1\n");
00356
00357 if (have_peephole2_flag)
00358 {
00359 printf ("#define HAVE_peephole2 1\n");
00360 printf ("#define MAX_INSNS_PER_PEEP2 %d\n", max_insns_per_peep2);
00361 }
00362
00363 puts("\n#endif /* GCC_INSN_CONFIG_H */");
00364
00365 if (ferror (stdout) || fflush (stdout) || fclose (stdout))
00366 return FATAL_EXIT_CODE;
00367
00368 return SUCCESS_EXIT_CODE;
00369 }
00370
00371
00372 const char *
00373 get_insn_name (code)
00374 int code ATTRIBUTE_UNUSED;
00375 {
00376 return NULL;
00377 }