00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #include "hconfig.h"
00024 #include "system.h"
00025 #include "rtl.h"
00026 #include "errors.h"
00027 #include "gensupport.h"
00028
00029
00030
00031
00032
00033
00034
00035
00036 struct link
00037 {
00038 struct link *next;
00039 int pos;
00040 int vecelt;
00041 };
00042
00043 static int max_opno;
00044
00045
00046
00047 static int n_operands;
00048
00049
00050
00051
00052 static int insn_code_number = 0;
00053
00054 static void gen_peephole PARAMS ((rtx));
00055 static void match_rtx PARAMS ((rtx, struct link *, int));
00056 static void print_path PARAMS ((struct link *));
00057 static void print_code PARAMS ((RTX_CODE));
00058
00059 static void
00060 gen_peephole (peep)
00061 rtx peep;
00062 {
00063 int ninsns = XVECLEN (peep, 0);
00064 int i;
00065
00066 n_operands = 0;
00067
00068 printf (" insn = ins1;\n");
00069 #if 0
00070 printf (" want_jump = 0;\n");
00071 #endif
00072
00073 for (i = 0; i < ninsns; i++)
00074 {
00075 if (i > 0)
00076 {
00077 printf (" do { insn = NEXT_INSN (insn);\n");
00078 printf (" if (insn == 0) goto L%d; }\n",
00079 insn_code_number);
00080 printf (" while (GET_CODE (insn) == NOTE\n");
00081 printf ("\t || (GET_CODE (insn) == INSN\n");
00082 printf ("\t && (GET_CODE (PATTERN (insn)) == USE\n");
00083 printf ("\t\t || GET_CODE (PATTERN (insn)) == CLOBBER)));\n");
00084
00085 printf (" if (GET_CODE (insn) == CODE_LABEL\n\
00086 || GET_CODE (insn) == BARRIER)\n goto L%d;\n",
00087 insn_code_number);
00088 }
00089
00090 #if 0
00091 printf (" if (GET_CODE (insn) == JUMP_INSN)\n");
00092 printf (" want_jump = JUMP_LABEL (insn);\n");
00093 #endif
00094
00095 printf (" pat = PATTERN (insn);\n");
00096
00097
00098
00099
00100 match_rtx (XVECEXP (peep, 0, i), NULL, insn_code_number);
00101 }
00102
00103
00104
00105
00106 if (XSTR (peep, 1) && XSTR (peep, 1)[0])
00107 printf (" if (! (%s)) goto L%d;\n",
00108 XSTR (peep, 1), insn_code_number);
00109
00110
00111
00112
00113
00114
00115
00116 printf (" PATTERN (ins1) = gen_rtx_PARALLEL (VOIDmode, gen_rtvec_v (%d, operands));\n", n_operands);
00117
00118 #if 0
00119 printf (" if (want_jump && GET_CODE (ins1) != JUMP_INSN)\n");
00120 printf (" {\n");
00121 printf (" rtx insn2 = emit_jump_insn_before (PATTERN (ins1), ins1);\n");
00122 printf (" delete_related_insns (ins1);\n");
00123 printf (" ins1 = ins2;\n");
00124 printf (" }\n");
00125 #endif
00126
00127
00128
00129 printf (" INSN_CODE (ins1) = %d;\n",
00130 insn_code_number);
00131
00132
00133 if (ninsns > 1)
00134 printf (" delete_for_peephole (NEXT_INSN (ins1), insn);\n");
00135
00136
00137
00138 printf (" return NEXT_INSN (insn);\n");
00139
00140 printf (" L%d:\n\n", insn_code_number);
00141 }
00142
00143 static void
00144 match_rtx (x, path, fail_label)
00145 rtx x;
00146 struct link *path;
00147 int fail_label;
00148 {
00149 RTX_CODE code;
00150 int i;
00151 int len;
00152 const char *fmt;
00153 struct link link;
00154
00155 if (x == 0)
00156 return;
00157
00158
00159 code = GET_CODE (x);
00160
00161 switch (code)
00162 {
00163 case MATCH_OPERAND:
00164 if (XINT (x, 0) > max_opno)
00165 max_opno = XINT (x, 0);
00166 if (XINT (x, 0) >= n_operands)
00167 n_operands = 1 + XINT (x, 0);
00168
00169 printf (" x = ");
00170 print_path (path);
00171 printf (";\n");
00172
00173 printf (" operands[%d] = x;\n", XINT (x, 0));
00174 if (XSTR (x, 1) && XSTR (x, 1)[0])
00175 printf (" if (! %s (x, %smode)) goto L%d;\n",
00176 XSTR (x, 1), GET_MODE_NAME (GET_MODE (x)), fail_label);
00177 return;
00178
00179 case MATCH_DUP:
00180 case MATCH_PAR_DUP:
00181 printf (" x = ");
00182 print_path (path);
00183 printf (";\n");
00184
00185 printf (" if (!rtx_equal_p (operands[%d], x)) goto L%d;\n",
00186 XINT (x, 0), fail_label);
00187 return;
00188
00189 case MATCH_OP_DUP:
00190 printf (" x = ");
00191 print_path (path);
00192 printf (";\n");
00193
00194 printf (" if (GET_CODE (operands[%d]) != GET_CODE (x)\n", XINT (x, 0));
00195 printf (" || GET_MODE (operands[%d]) != GET_MODE (x)) goto L%d;\n",
00196 XINT (x, 0), fail_label);
00197 printf (" operands[%d] = x;\n", XINT (x, 0));
00198 link.next = path;
00199 link.vecelt = -1;
00200 for (i = 0; i < XVECLEN (x, 1); i++)
00201 {
00202 link.pos = i;
00203 match_rtx (XVECEXP (x, 1, i), &link, fail_label);
00204 }
00205 return;
00206
00207 case MATCH_OPERATOR:
00208 if (XINT (x, 0) > max_opno)
00209 max_opno = XINT (x, 0);
00210 if (XINT (x, 0) >= n_operands)
00211 n_operands = 1 + XINT (x, 0);
00212
00213 printf (" x = ");
00214 print_path (path);
00215 printf (";\n");
00216
00217 printf (" operands[%d] = x;\n", XINT (x, 0));
00218 if (XSTR (x, 1) && XSTR (x, 1)[0])
00219 printf (" if (! %s (x, %smode)) goto L%d;\n",
00220 XSTR (x, 1), GET_MODE_NAME (GET_MODE (x)), fail_label);
00221 link.next = path;
00222 link.vecelt = -1;
00223 for (i = 0; i < XVECLEN (x, 2); i++)
00224 {
00225 link.pos = i;
00226 match_rtx (XVECEXP (x, 2, i), &link, fail_label);
00227 }
00228 return;
00229
00230 case MATCH_PARALLEL:
00231 if (XINT (x, 0) > max_opno)
00232 max_opno = XINT (x, 0);
00233 if (XINT (x, 0) >= n_operands)
00234 n_operands = 1 + XINT (x, 0);
00235
00236 printf (" x = ");
00237 print_path (path);
00238 printf (";\n");
00239
00240 printf (" if (GET_CODE (x) != PARALLEL) goto L%d;\n", fail_label);
00241 printf (" operands[%d] = x;\n", XINT (x, 0));
00242 if (XSTR (x, 1) && XSTR (x, 1)[0])
00243 printf (" if (! %s (x, %smode)) goto L%d;\n",
00244 XSTR (x, 1), GET_MODE_NAME (GET_MODE (x)), fail_label);
00245 link.next = path;
00246 link.pos = 0;
00247 for (i = 0; i < XVECLEN (x, 2); i++)
00248 {
00249 link.vecelt = i;
00250 match_rtx (XVECEXP (x, 2, i), &link, fail_label);
00251 }
00252 return;
00253
00254 case ADDRESS:
00255 match_rtx (XEXP (x, 0), path, fail_label);
00256 return;
00257
00258 default:
00259 break;
00260 }
00261
00262 printf (" x = ");
00263 print_path (path);
00264 printf (";\n");
00265
00266 printf (" if (GET_CODE (x) != ");
00267 print_code (code);
00268 printf (") goto L%d;\n", fail_label);
00269
00270 if (GET_MODE (x) != VOIDmode)
00271 {
00272 printf (" if (GET_MODE (x) != %smode) goto L%d;\n",
00273 GET_MODE_NAME (GET_MODE (x)), fail_label);
00274 }
00275
00276 link.next = path;
00277 link.vecelt = -1;
00278 fmt = GET_RTX_FORMAT (code);
00279 len = GET_RTX_LENGTH (code);
00280 for (i = 0; i < len; i++)
00281 {
00282 link.pos = i;
00283 if (fmt[i] == 'e' || fmt[i] == 'u')
00284 match_rtx (XEXP (x, i), &link, fail_label);
00285 else if (fmt[i] == 'E')
00286 {
00287 int j;
00288 printf (" if (XVECLEN (x, %d) != %d) goto L%d;\n",
00289 i, XVECLEN (x, i), fail_label);
00290 for (j = 0; j < XVECLEN (x, i); j++)
00291 {
00292 link.vecelt = j;
00293 match_rtx (XVECEXP (x, i, j), &link, fail_label);
00294 }
00295 }
00296 else if (fmt[i] == 'i')
00297 {
00298
00299 if (i != 0)
00300 {
00301 printf (" x = ");
00302 print_path (path);
00303 printf (";\n");
00304 }
00305
00306 printf (" if (XINT (x, %d) != %d) goto L%d;\n",
00307 i, XINT (x, i), fail_label);
00308 }
00309 else if (fmt[i] == 'w')
00310 {
00311
00312 if (i != 0)
00313 {
00314 printf (" x = ");
00315 print_path (path);
00316 printf (";\n");
00317 }
00318
00319 printf (" if (XWINT (x, %d) != ", i);
00320 printf (HOST_WIDE_INT_PRINT_DEC, XWINT (x, i));
00321 printf (") goto L%d;\n", fail_label);
00322 }
00323 else if (fmt[i] == 's')
00324 {
00325
00326 if (i != 0)
00327 {
00328 printf (" x = ");
00329 print_path (path);
00330 printf (";\n");
00331 }
00332
00333 printf (" if (strcmp (XSTR (x, %d), \"%s\")) goto L%d;\n",
00334 i, XSTR (x, i), fail_label);
00335 }
00336 }
00337 }
00338
00339
00340
00341
00342
00343 static void
00344 print_path (path)
00345 struct link *path;
00346 {
00347 if (path == 0)
00348 printf ("pat");
00349 else if (path->vecelt >= 0)
00350 {
00351 printf ("XVECEXP (");
00352 print_path (path->next);
00353 printf (", %d, %d)", path->pos, path->vecelt);
00354 }
00355 else
00356 {
00357 printf ("XEXP (");
00358 print_path (path->next);
00359 printf (", %d)", path->pos);
00360 }
00361 }
00362
00363 static void
00364 print_code (code)
00365 RTX_CODE code;
00366 {
00367 const char *p1;
00368 for (p1 = GET_RTX_NAME (code); *p1; p1++)
00369 putchar (TOUPPER(*p1));
00370 }
00371
00372 extern int main PARAMS ((int, char **));
00373
00374 int
00375 main (argc, argv)
00376 int argc;
00377 char **argv;
00378 {
00379 rtx desc;
00380
00381 max_opno = -1;
00382
00383 progname = "genpeep";
00384
00385 if (argc <= 1)
00386 fatal ("no input file name");
00387
00388 if (init_md_reader_args (argc, argv) != SUCCESS_EXIT_CODE)
00389 return (FATAL_EXIT_CODE);
00390
00391 printf ("/* Generated automatically by the program `genpeep'\n\
00392 from the machine description file `md'. */\n\n");
00393
00394 printf ("#include \"config.h\"\n");
00395 printf ("#include \"system.h\"\n");
00396 printf ("#include \"insn-config.h\"\n");
00397 printf ("#include \"rtl.h\"\n");
00398 printf ("#include \"tm_p.h\"\n");
00399 printf ("#include \"regs.h\"\n");
00400 printf ("#include \"output.h\"\n");
00401 printf ("#include \"real.h\"\n");
00402 printf ("#include \"recog.h\"\n");
00403 printf ("#include \"except.h\"\n\n");
00404 printf ("#include \"function.h\"\n\n");
00405
00406 printf ("#ifdef HAVE_peephole\n");
00407 printf ("extern rtx peep_operand[];\n\n");
00408 printf ("#define operands peep_operand\n\n");
00409
00410 printf ("rtx\npeephole (ins1)\n rtx ins1;\n{\n");
00411 printf (" rtx insn ATTRIBUTE_UNUSED, x ATTRIBUTE_UNUSED, pat ATTRIBUTE_UNUSED;\n\n");
00412
00413
00414 printf (" if (NEXT_INSN (ins1)\n");
00415 printf (" && GET_CODE (NEXT_INSN (ins1)) == BARRIER)\n");
00416 printf (" return 0;\n\n");
00417
00418
00419
00420 while (1)
00421 {
00422 int line_no, rtx_number = 0;
00423
00424 desc = read_md_rtx (&line_no, &rtx_number);
00425 if (desc == NULL)
00426 break;
00427
00428 if (GET_CODE (desc) == DEFINE_PEEPHOLE)
00429 {
00430 gen_peephole (desc);
00431 insn_code_number++;
00432 }
00433 if (GET_CODE (desc) == DEFINE_INSN
00434 || GET_CODE (desc) == DEFINE_EXPAND
00435 || GET_CODE (desc) == DEFINE_SPLIT
00436 || GET_CODE (desc) == DEFINE_PEEPHOLE2)
00437 {
00438 insn_code_number++;
00439 }
00440 }
00441
00442 printf (" return 0;\n}\n\n");
00443
00444 if (max_opno == -1)
00445 max_opno = 1;
00446
00447 printf ("rtx peep_operand[%d];\n", max_opno + 1);
00448 printf ("#endif\n");
00449
00450 fflush (stdout);
00451 return (ferror (stdout) != 0 ? FATAL_EXIT_CODE : SUCCESS_EXIT_CODE);
00452 }
00453
00454
00455 const char *
00456 get_insn_name (code)
00457 int code ATTRIBUTE_UNUSED;
00458 {
00459 return NULL;
00460 }