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 #include "hconfig.h"
00028 #include "system.h"
00029 #include "rtl.h"
00030 #include "errors.h"
00031 #include "gensupport.h"
00032
00033
00034 static int max_opno;
00035 static int max_dup_opno;
00036 static int max_scratch_opno;
00037 static int register_constraints;
00038 static int insn_code_number;
00039 static int insn_index_number;
00040
00041
00042
00043
00044
00045 struct clobber_pat
00046 {
00047 struct clobber_ent *insns;
00048 rtx pattern;
00049 int first_clobber;
00050 struct clobber_pat *next;
00051 int has_hard_reg;
00052 } *clobber_list;
00053
00054
00055
00056 struct clobber_ent
00057 {
00058 int code_number;
00059 struct clobber_ent *next;
00060 };
00061
00062 static void max_operand_1 PARAMS ((rtx));
00063 static int max_operand_vec PARAMS ((rtx, int));
00064 static void print_code PARAMS ((RTX_CODE));
00065 static void gen_exp PARAMS ((rtx, enum rtx_code, char *));
00066 static void gen_insn PARAMS ((rtx, int));
00067 static void gen_expand PARAMS ((rtx));
00068 static void gen_split PARAMS ((rtx));
00069 static void output_add_clobbers PARAMS ((void));
00070 static void output_added_clobbers_hard_reg_p PARAMS ((void));
00071 static void gen_rtx_scratch PARAMS ((rtx, enum rtx_code));
00072 static void output_peephole2_scratches PARAMS ((rtx));
00073
00074
00075 static void
00076 max_operand_1 (x)
00077 rtx x;
00078 {
00079 RTX_CODE code;
00080 int i;
00081 int len;
00082 const char *fmt;
00083
00084 if (x == 0)
00085 return;
00086
00087 code = GET_CODE (x);
00088
00089 if (code == MATCH_OPERAND && XSTR (x, 2) != 0 && *XSTR (x, 2) != '\0')
00090 register_constraints = 1;
00091 if (code == MATCH_SCRATCH && XSTR (x, 1) != 0 && *XSTR (x, 1) != '\0')
00092 register_constraints = 1;
00093 if (code == MATCH_OPERAND || code == MATCH_OPERATOR
00094 || code == MATCH_PARALLEL)
00095 max_opno = MAX (max_opno, XINT (x, 0));
00096 if (code == MATCH_DUP || code == MATCH_OP_DUP || code == MATCH_PAR_DUP)
00097 max_dup_opno = MAX (max_dup_opno, XINT (x, 0));
00098 if (code == MATCH_SCRATCH)
00099 max_scratch_opno = MAX (max_scratch_opno, XINT (x, 0));
00100
00101 fmt = GET_RTX_FORMAT (code);
00102 len = GET_RTX_LENGTH (code);
00103 for (i = 0; i < len; i++)
00104 {
00105 if (fmt[i] == 'e' || fmt[i] == 'u')
00106 max_operand_1 (XEXP (x, i));
00107 else if (fmt[i] == 'E')
00108 {
00109 int j;
00110 for (j = 0; j < XVECLEN (x, i); j++)
00111 max_operand_1 (XVECEXP (x, i, j));
00112 }
00113 }
00114 }
00115
00116 static int
00117 max_operand_vec (insn, arg)
00118 rtx insn;
00119 int arg;
00120 {
00121 int len = XVECLEN (insn, arg);
00122 int i;
00123
00124 max_opno = -1;
00125 max_dup_opno = -1;
00126 max_scratch_opno = -1;
00127
00128 for (i = 0; i < len; i++)
00129 max_operand_1 (XVECEXP (insn, arg, i));
00130
00131 return max_opno + 1;
00132 }
00133
00134 static void
00135 print_code (code)
00136 RTX_CODE code;
00137 {
00138 const char *p1;
00139 for (p1 = GET_RTX_NAME (code); *p1; p1++)
00140 putchar (TOUPPER(*p1));
00141 }
00142
00143 static void
00144 gen_rtx_scratch (x, subroutine_type)
00145 rtx x;
00146 enum rtx_code subroutine_type;
00147 {
00148 if (subroutine_type == DEFINE_PEEPHOLE2)
00149 {
00150 printf ("operand%d", XINT (x, 0));
00151 }
00152 else
00153 {
00154 printf ("gen_rtx_SCRATCH (%smode)", GET_MODE_NAME (GET_MODE (x)));
00155 }
00156 }
00157
00158
00159
00160
00161 static void
00162 gen_exp (x, subroutine_type, used)
00163 rtx x;
00164 enum rtx_code subroutine_type;
00165 char *used;
00166 {
00167 RTX_CODE code;
00168 int i;
00169 int len;
00170 const char *fmt;
00171
00172 if (x == 0)
00173 {
00174 printf ("NULL_RTX");
00175 return;
00176 }
00177
00178 code = GET_CODE (x);
00179
00180 switch (code)
00181 {
00182 case MATCH_OPERAND:
00183 case MATCH_DUP:
00184 if (used)
00185 {
00186 if (used[XINT (x, 0)])
00187 {
00188 printf ("copy_rtx (operand%d)", XINT (x, 0));
00189 return;
00190 }
00191 used[XINT (x, 0)] = 1;
00192 }
00193 printf ("operand%d", XINT (x, 0));
00194 return;
00195
00196 case MATCH_OP_DUP:
00197 printf ("gen_rtx (GET_CODE (operand%d), ", XINT (x, 0));
00198 if (GET_MODE (x) == VOIDmode)
00199 printf ("GET_MODE (operand%d)", XINT (x, 0));
00200 else
00201 printf ("%smode", GET_MODE_NAME (GET_MODE (x)));
00202 for (i = 0; i < XVECLEN (x, 1); i++)
00203 {
00204 printf (",\n\t\t");
00205 gen_exp (XVECEXP (x, 1, i), subroutine_type, used);
00206 }
00207 printf (")");
00208 return;
00209
00210 case MATCH_OPERATOR:
00211 printf ("gen_rtx (GET_CODE (operand%d)", XINT (x, 0));
00212 printf (", %smode", GET_MODE_NAME (GET_MODE (x)));
00213 for (i = 0; i < XVECLEN (x, 2); i++)
00214 {
00215 printf (",\n\t\t");
00216 gen_exp (XVECEXP (x, 2, i), subroutine_type, used);
00217 }
00218 printf (")");
00219 return;
00220
00221 case MATCH_PARALLEL:
00222 case MATCH_PAR_DUP:
00223 printf ("operand%d", XINT (x, 0));
00224 return;
00225
00226 case MATCH_SCRATCH:
00227 gen_rtx_scratch (x, subroutine_type);
00228 return;
00229
00230 case ADDRESS:
00231 fatal ("ADDRESS expression code used in named instruction pattern");
00232
00233 case PC:
00234 printf ("pc_rtx");
00235 return;
00236
00237 case CC0:
00238 printf ("cc0_rtx");
00239 return;
00240
00241 case CONST_INT:
00242 if (INTVAL (x) == 0)
00243 printf ("const0_rtx");
00244 else if (INTVAL (x) == 1)
00245 printf ("const1_rtx");
00246 else if (INTVAL (x) == -1)
00247 printf ("constm1_rtx");
00248 else if (INTVAL (x) == STORE_FLAG_VALUE)
00249 printf ("const_true_rtx");
00250 else
00251 {
00252 printf ("GEN_INT (");
00253 printf (HOST_WIDE_INT_PRINT_DEC_C, INTVAL (x));
00254 printf (")");
00255 }
00256 return;
00257
00258 case CONST_DOUBLE:
00259
00260
00261 abort ();
00262
00263 default:
00264 break;
00265 }
00266
00267 printf ("gen_rtx_");
00268 print_code (code);
00269 printf (" (%smode", GET_MODE_NAME (GET_MODE (x)));
00270
00271 fmt = GET_RTX_FORMAT (code);
00272 len = GET_RTX_LENGTH (code);
00273 for (i = 0; i < len; i++)
00274 {
00275 if (fmt[i] == '0')
00276 break;
00277 printf (",\n\t");
00278 if (fmt[i] == 'e' || fmt[i] == 'u')
00279 gen_exp (XEXP (x, i), subroutine_type, used);
00280 else if (fmt[i] == 'i')
00281 printf ("%u", XINT (x, i));
00282 else if (fmt[i] == 's')
00283 printf ("\"%s\"", XSTR (x, i));
00284 else if (fmt[i] == 'E')
00285 {
00286 int j;
00287 printf ("gen_rtvec (%d", XVECLEN (x, i));
00288 for (j = 0; j < XVECLEN (x, i); j++)
00289 {
00290 printf (",\n\t\t");
00291 gen_exp (XVECEXP (x, i, j), subroutine_type, used);
00292 }
00293 printf (")");
00294 }
00295 else
00296 abort ();
00297 }
00298 printf (")");
00299 }
00300
00301
00302
00303 static void
00304 gen_insn (insn, lineno)
00305 rtx insn;
00306 int lineno;
00307 {
00308 int operands;
00309 int i;
00310
00311
00312
00313
00314
00315 if (XVEC (insn, 1))
00316 {
00317 int has_hard_reg = 0;
00318
00319 for (i = XVECLEN (insn, 1) - 1; i > 0; i--)
00320 {
00321 if (GET_CODE (XVECEXP (insn, 1, i)) != CLOBBER)
00322 break;
00323
00324 if (GET_CODE (XEXP (XVECEXP (insn, 1, i), 0)) == REG)
00325 has_hard_reg = 1;
00326 else if (GET_CODE (XEXP (XVECEXP (insn, 1, i), 0)) != MATCH_SCRATCH)
00327 break;
00328 }
00329
00330 if (i != XVECLEN (insn, 1) - 1)
00331 {
00332 struct clobber_pat *p;
00333 struct clobber_ent *link
00334 = (struct clobber_ent *) xmalloc (sizeof (struct clobber_ent));
00335 int j;
00336
00337 link->code_number = insn_code_number;
00338
00339
00340
00341
00342 for (p = clobber_list; p; p = p->next)
00343 {
00344 if (p->first_clobber != i + 1
00345 || XVECLEN (p->pattern, 1) != XVECLEN (insn, 1))
00346 continue;
00347
00348 for (j = i + 1; j < XVECLEN (insn, 1); j++)
00349 {
00350 rtx old = XEXP (XVECEXP (p->pattern, 1, j), 0);
00351 rtx new = XEXP (XVECEXP (insn, 1, j), 0);
00352
00353
00354
00355
00356 if (! (GET_MODE (old) == GET_MODE (new)
00357 && ((GET_CODE (old) == MATCH_SCRATCH
00358 && GET_CODE (new) == MATCH_SCRATCH)
00359 || (GET_CODE (old) == REG && GET_CODE (new) == REG
00360 && REGNO (old) == REGNO (new)))))
00361 break;
00362 }
00363
00364 if (j == XVECLEN (insn, 1))
00365 break;
00366 }
00367
00368 if (p == 0)
00369 {
00370 p = (struct clobber_pat *) xmalloc (sizeof (struct clobber_pat));
00371
00372 p->insns = 0;
00373 p->pattern = insn;
00374 p->first_clobber = i + 1;
00375 p->next = clobber_list;
00376 p->has_hard_reg = has_hard_reg;
00377 clobber_list = p;
00378 }
00379
00380 link->next = p->insns;
00381 p->insns = link;
00382 }
00383 }
00384
00385
00386
00387
00388 if (XSTR (insn, 0)[0] == 0 || XSTR (insn, 0)[0] == '*')
00389 return;
00390
00391 printf ("/* %s:%d */\n", read_rtx_filename, lineno);
00392
00393
00394
00395 register_constraints = 0;
00396 operands = max_operand_vec (insn, 1);
00397 if (max_dup_opno >= operands)
00398 fatal ("match_dup operand number has no match_operand");
00399
00400
00401 printf ("rtx\ngen_%s (", XSTR (insn, 0));
00402 for (i = 0; i < operands; i++)
00403 if (i)
00404 printf (", operand%d", i);
00405 else
00406 printf ("operand%d", i);
00407 printf (")\n");
00408 for (i = 0; i < operands; i++)
00409 printf (" rtx operand%d;\n", i);
00410 printf ("{\n");
00411
00412
00413
00414 if (XVECLEN (insn, 1) == 1)
00415 {
00416 printf (" return ");
00417 gen_exp (XVECEXP (insn, 1, 0), DEFINE_INSN, NULL);
00418 printf (";\n}\n\n");
00419 }
00420 else
00421 {
00422 printf (" return gen_rtx_PARALLEL (VOIDmode, gen_rtvec (%d",
00423 XVECLEN (insn, 1));
00424
00425 for (i = 0; i < XVECLEN (insn, 1); i++)
00426 {
00427 printf (",\n\t\t");
00428 gen_exp (XVECEXP (insn, 1, i), DEFINE_INSN, NULL);
00429 }
00430 printf ("));\n}\n\n");
00431 }
00432 }
00433
00434
00435
00436 static void
00437 gen_expand (expand)
00438 rtx expand;
00439 {
00440 int operands;
00441 int i;
00442
00443 if (strlen (XSTR (expand, 0)) == 0)
00444 fatal ("define_expand lacks a name");
00445 if (XVEC (expand, 1) == 0)
00446 fatal ("define_expand for %s lacks a pattern", XSTR (expand, 0));
00447
00448
00449
00450 register_constraints = 0;
00451
00452 operands = max_operand_vec (expand, 1);
00453
00454
00455 printf ("rtx\ngen_%s (", XSTR (expand, 0));
00456 for (i = 0; i < operands; i++)
00457 if (i)
00458 printf (", operand%d", i);
00459 else
00460 printf ("operand%d", i);
00461 printf (")\n");
00462 for (i = 0; i < operands; i++)
00463 printf (" rtx operand%d;\n", i);
00464 printf ("{\n");
00465
00466
00467
00468
00469 if ((XSTR (expand, 3) == 0 || *XSTR (expand, 3) == '\0')
00470 && operands > max_dup_opno
00471 && XVECLEN (expand, 1) == 1)
00472 {
00473 printf (" return ");
00474 gen_exp (XVECEXP (expand, 1, 0), DEFINE_EXPAND, NULL);
00475 printf (";\n}\n\n");
00476 return;
00477 }
00478
00479
00480
00481 for (i = operands; i <= max_dup_opno; i++)
00482 printf (" rtx operand%d;\n", i);
00483 for (; i <= max_scratch_opno; i++)
00484 printf (" rtx operand%d ATTRIBUTE_UNUSED;\n", i);
00485 printf (" rtx _val = 0;\n");
00486 printf (" start_sequence ();\n");
00487
00488
00489
00490
00491
00492
00493
00494 if (XSTR (expand, 3) && *XSTR (expand, 3))
00495 {
00496 printf (" {\n");
00497 if (operands > 0 || max_dup_opno >= 0 || max_scratch_opno >= 0)
00498 printf (" rtx operands[%d];\n",
00499 MAX (operands, MAX (max_scratch_opno, max_dup_opno) + 1));
00500
00501 for (i = 0; i < operands; i++)
00502 printf (" operands[%d] = operand%d;\n", i, i);
00503
00504
00505
00506 printf ("%s\n", XSTR (expand, 3));
00507
00508
00509
00510 if (XVEC (expand, 1) != 0)
00511 {
00512 for (i = 0; i < operands; i++)
00513 printf (" operand%d = operands[%d];\n", i, i);
00514 for (; i <= max_dup_opno; i++)
00515 printf (" operand%d = operands[%d];\n", i, i);
00516 for (; i <= max_scratch_opno; i++)
00517 printf (" operand%d = operands[%d];\n", i, i);
00518 }
00519 printf (" }\n");
00520 }
00521
00522
00523
00524
00525
00526 for (i = 0; i < XVECLEN (expand, 1); i++)
00527 {
00528 rtx next = XVECEXP (expand, 1, i);
00529 if ((GET_CODE (next) == SET && GET_CODE (SET_DEST (next)) == PC)
00530 || (GET_CODE (next) == PARALLEL
00531 && ((GET_CODE (XVECEXP (next, 0, 0)) == SET
00532 && GET_CODE (SET_DEST (XVECEXP (next, 0, 0))) == PC)
00533 || GET_CODE (XVECEXP (next, 0, 0)) == RETURN))
00534 || GET_CODE (next) == RETURN)
00535 printf (" emit_jump_insn (");
00536 else if ((GET_CODE (next) == SET && GET_CODE (SET_SRC (next)) == CALL)
00537 || GET_CODE (next) == CALL
00538 || (GET_CODE (next) == PARALLEL
00539 && GET_CODE (XVECEXP (next, 0, 0)) == SET
00540 && GET_CODE (SET_SRC (XVECEXP (next, 0, 0))) == CALL)
00541 || (GET_CODE (next) == PARALLEL
00542 && GET_CODE (XVECEXP (next, 0, 0)) == CALL))
00543 printf (" emit_call_insn (");
00544 else if (GET_CODE (next) == CODE_LABEL)
00545 printf (" emit_label (");
00546 else if (GET_CODE (next) == MATCH_OPERAND
00547 || GET_CODE (next) == MATCH_DUP
00548 || GET_CODE (next) == MATCH_OPERATOR
00549 || GET_CODE (next) == MATCH_OP_DUP
00550 || GET_CODE (next) == MATCH_PARALLEL
00551 || GET_CODE (next) == MATCH_PAR_DUP
00552 || GET_CODE (next) == PARALLEL)
00553 printf (" emit (");
00554 else
00555 printf (" emit_insn (");
00556 gen_exp (next, DEFINE_EXPAND, NULL);
00557 printf (");\n");
00558 if (GET_CODE (next) == SET && GET_CODE (SET_DEST (next)) == PC
00559 && GET_CODE (SET_SRC (next)) == LABEL_REF)
00560 printf (" emit_barrier ();");
00561 }
00562
00563
00564
00565
00566 printf (" _val = get_insns ();\n");
00567 printf (" end_sequence ();\n");
00568 printf (" return _val;\n}\n\n");
00569 }
00570
00571
00572
00573 static void
00574 gen_split (split)
00575 rtx split;
00576 {
00577 int i;
00578 int operands;
00579 const char *const name =
00580 ((GET_CODE (split) == DEFINE_PEEPHOLE2) ? "peephole2" : "split");
00581 const char *unused;
00582 char *used;
00583
00584 if (XVEC (split, 0) == 0)
00585 fatal ("define_%s (definition %d) lacks a pattern", name,
00586 insn_index_number);
00587 else if (XVEC (split, 2) == 0)
00588 fatal ("define_%s (definition %d) lacks a replacement pattern", name,
00589 insn_index_number);
00590
00591
00592
00593 max_operand_vec (split, 2);
00594 operands = MAX (max_opno, MAX (max_dup_opno, max_scratch_opno)) + 1;
00595 unused = (operands == 0 ? " ATTRIBUTE_UNUSED" : "");
00596 used = xcalloc (1, operands);
00597
00598
00599 if (GET_CODE (split) == DEFINE_PEEPHOLE2)
00600 {
00601 printf ("extern rtx gen_%s_%d PARAMS ((rtx, rtx *));\n",
00602 name, insn_code_number);
00603 printf ("rtx\ngen_%s_%d (curr_insn, operands)\n",
00604 name, insn_code_number);
00605 printf (" rtx curr_insn ATTRIBUTE_UNUSED;\n");
00606 printf (" rtx *operands%s;\n", unused);
00607 }
00608 else
00609 {
00610 printf ("extern rtx gen_split_%d PARAMS ((rtx *));\n", insn_code_number);
00611 printf ("rtx\ngen_%s_%d (operands)\n", name, insn_code_number);
00612 printf (" rtx *operands%s;\n", unused);
00613 }
00614 printf ("{\n");
00615
00616
00617 for (i = 0; i < operands; i++)
00618 printf (" rtx operand%d;\n", i);
00619 printf (" rtx _val = 0;\n");
00620
00621 if (GET_CODE (split) == DEFINE_PEEPHOLE2)
00622 output_peephole2_scratches (split);
00623
00624 printf (" start_sequence ();\n");
00625
00626
00627
00628
00629 if (XSTR (split, 3))
00630 printf ("%s\n", XSTR (split, 3));
00631
00632
00633 for (i = 0; i < operands; i++)
00634 printf (" operand%d = operands[%d];\n", i, i);
00635
00636
00637
00638
00639
00640 for (i = 0; i < XVECLEN (split, 2); i++)
00641 {
00642 rtx next = XVECEXP (split, 2, i);
00643 if ((GET_CODE (next) == SET && GET_CODE (SET_DEST (next)) == PC)
00644 || (GET_CODE (next) == PARALLEL
00645 && GET_CODE (XVECEXP (next, 0, 0)) == SET
00646 && GET_CODE (SET_DEST (XVECEXP (next, 0, 0))) == PC)
00647 || GET_CODE (next) == RETURN)
00648 printf (" emit_jump_insn (");
00649 else if ((GET_CODE (next) == SET && GET_CODE (SET_SRC (next)) == CALL)
00650 || GET_CODE (next) == CALL
00651 || (GET_CODE (next) == PARALLEL
00652 && GET_CODE (XVECEXP (next, 0, 0)) == SET
00653 && GET_CODE (SET_SRC (XVECEXP (next, 0, 0))) == CALL)
00654 || (GET_CODE (next) == PARALLEL
00655 && GET_CODE (XVECEXP (next, 0, 0)) == CALL))
00656 printf (" emit_call_insn (");
00657 else if (GET_CODE (next) == CODE_LABEL)
00658 printf (" emit_label (");
00659 else if (GET_CODE (next) == MATCH_OPERAND
00660 || GET_CODE (next) == MATCH_OPERATOR
00661 || GET_CODE (next) == MATCH_PARALLEL
00662 || GET_CODE (next) == MATCH_OP_DUP
00663 || GET_CODE (next) == MATCH_DUP
00664 || GET_CODE (next) == PARALLEL)
00665 printf (" emit (");
00666 else
00667 printf (" emit_insn (");
00668 gen_exp (next, GET_CODE (split), used);
00669 printf (");\n");
00670 if (GET_CODE (next) == SET && GET_CODE (SET_DEST (next)) == PC
00671 && GET_CODE (SET_SRC (next)) == LABEL_REF)
00672 printf (" emit_barrier ();");
00673 }
00674
00675
00676
00677
00678 printf (" _val = get_insns ();\n");
00679 printf (" end_sequence ();\n");
00680 printf (" return _val;\n}\n\n");
00681
00682 free (used);
00683 }
00684
00685
00686
00687
00688
00689 static void
00690 output_add_clobbers ()
00691 {
00692 struct clobber_pat *clobber;
00693 struct clobber_ent *ent;
00694 int i;
00695
00696 printf ("\n\nvoid\nadd_clobbers (pattern, insn_code_number)\n");
00697 printf (" rtx pattern ATTRIBUTE_UNUSED;\n int insn_code_number;\n");
00698 printf ("{\n");
00699 printf (" switch (insn_code_number)\n");
00700 printf (" {\n");
00701
00702 for (clobber = clobber_list; clobber; clobber = clobber->next)
00703 {
00704 for (ent = clobber->insns; ent; ent = ent->next)
00705 printf (" case %d:\n", ent->code_number);
00706
00707 for (i = clobber->first_clobber; i < XVECLEN (clobber->pattern, 1); i++)
00708 {
00709 printf (" XVECEXP (pattern, 0, %d) = ", i);
00710 gen_exp (XVECEXP (clobber->pattern, 1, i),
00711 GET_CODE (clobber->pattern), NULL);
00712 printf (";\n");
00713 }
00714
00715 printf (" break;\n\n");
00716 }
00717
00718 printf (" default:\n");
00719 printf (" abort ();\n");
00720 printf (" }\n");
00721 printf ("}\n");
00722 }
00723
00724
00725
00726
00727
00728 static void
00729 output_added_clobbers_hard_reg_p ()
00730 {
00731 struct clobber_pat *clobber;
00732 struct clobber_ent *ent;
00733 int clobber_p, used;
00734
00735 printf ("\n\nint\nadded_clobbers_hard_reg_p (insn_code_number)\n");
00736 printf (" int insn_code_number;\n");
00737 printf ("{\n");
00738 printf (" switch (insn_code_number)\n");
00739 printf (" {\n");
00740
00741 for (clobber_p = 0; clobber_p <= 1; clobber_p++)
00742 {
00743 used = 0;
00744 for (clobber = clobber_list; clobber; clobber = clobber->next)
00745 if (clobber->has_hard_reg == clobber_p)
00746 for (ent = clobber->insns; ent; ent = ent->next)
00747 {
00748 printf (" case %d:\n", ent->code_number);
00749 used++;
00750 }
00751
00752 if (used)
00753 printf (" return %d;\n\n", clobber_p);
00754 }
00755
00756 printf (" default:\n");
00757 printf (" abort ();\n");
00758 printf (" }\n");
00759 printf ("}\n");
00760 }
00761
00762
00763
00764
00765 static void
00766 output_peephole2_scratches (split)
00767 rtx split;
00768 {
00769 int i;
00770 int insn_nr = 0;
00771
00772 printf (" HARD_REG_SET _regs_allocated;\n");
00773 printf (" CLEAR_HARD_REG_SET (_regs_allocated);\n");
00774
00775 for (i = 0; i < XVECLEN (split, 0); i++)
00776 {
00777 rtx elt = XVECEXP (split, 0, i);
00778 if (GET_CODE (elt) == MATCH_SCRATCH)
00779 {
00780 int last_insn_nr = insn_nr;
00781 int cur_insn_nr = insn_nr;
00782 int j;
00783 for (j = i + 1; j < XVECLEN (split, 0); j++)
00784 if (GET_CODE (XVECEXP (split, 0, j)) == MATCH_DUP)
00785 {
00786 if (XINT (XVECEXP (split, 0, j), 0) == XINT (elt, 0))
00787 last_insn_nr = cur_insn_nr;
00788 }
00789 else if (GET_CODE (XVECEXP (split, 0, j)) != MATCH_SCRATCH)
00790 cur_insn_nr++;
00791
00792 printf (" if ((operands[%d] = peep2_find_free_register (%d, %d, \"%s\", %smode, &_regs_allocated)) == NULL_RTX)\n\
00793 return NULL;\n",
00794 XINT (elt, 0),
00795 insn_nr, last_insn_nr,
00796 XSTR (elt, 1),
00797 GET_MODE_NAME (GET_MODE (elt)));
00798
00799 }
00800 else if (GET_CODE (elt) != MATCH_DUP)
00801 insn_nr++;
00802 }
00803 }
00804
00805 extern int main PARAMS ((int, char **));
00806
00807 int
00808 main (argc, argv)
00809 int argc;
00810 char **argv;
00811 {
00812 rtx desc;
00813
00814 progname = "genemit";
00815
00816 if (argc <= 1)
00817 fatal ("no input file name");
00818
00819 if (init_md_reader_args (argc, argv) != SUCCESS_EXIT_CODE)
00820 return (FATAL_EXIT_CODE);
00821
00822
00823
00824
00825 insn_code_number = 0;
00826 insn_index_number = 0;
00827
00828 printf ("/* Generated automatically by the program `genemit'\n\
00829 from the machine description file `md'. */\n\n");
00830
00831 printf ("#include \"config.h\"\n");
00832 printf ("#include \"system.h\"\n");
00833 printf ("#include \"rtl.h\"\n");
00834 printf ("#include \"tm_p.h\"\n");
00835 printf ("#include \"function.h\"\n");
00836 printf ("#include \"expr.h\"\n");
00837 printf ("#include \"optabs.h\"\n");
00838 printf ("#include \"real.h\"\n");
00839 printf ("#include \"flags.h\"\n");
00840 printf ("#include \"output.h\"\n");
00841 #ifdef SGI_MONGOOSE
00842 printf ("#include \"insn-flags.h\"\n");
00843 #endif
00844 printf ("#include \"insn-config.h\"\n");
00845 printf ("#include \"hard-reg-set.h\"\n");
00846 printf ("#include \"recog.h\"\n");
00847 printf ("#include \"resource.h\"\n");
00848 printf ("#include \"reload.h\"\n");
00849 printf ("#include \"toplev.h\"\n");
00850 printf ("#include \"ggc.h\"\n\n");
00851 printf ("#define FAIL return (end_sequence (), _val)\n");
00852 printf ("#define DONE return (_val = get_insns (), end_sequence (), _val)\n\n");
00853
00854
00855
00856 while (1)
00857 {
00858 int line_no;
00859
00860 desc = read_md_rtx (&line_no, &insn_code_number);
00861 if (desc == NULL)
00862 break;
00863
00864 switch (GET_CODE (desc))
00865 {
00866 case DEFINE_INSN:
00867 gen_insn (desc, line_no);
00868 break;
00869
00870 case DEFINE_EXPAND:
00871 printf ("/* %s:%d */\n", read_rtx_filename, line_no);
00872 gen_expand (desc);
00873 break;
00874
00875 case DEFINE_SPLIT:
00876 printf ("/* %s:%d */\n", read_rtx_filename, line_no);
00877 gen_split (desc);
00878 break;
00879
00880 case DEFINE_PEEPHOLE2:
00881 printf ("/* %s:%d */\n", read_rtx_filename, line_no);
00882 gen_split (desc);
00883 break;
00884
00885 default:
00886 break;
00887 }
00888 ++insn_index_number;
00889 }
00890
00891
00892
00893 output_add_clobbers ();
00894 output_added_clobbers_hard_reg_p ();
00895
00896 fflush (stdout);
00897 return (ferror (stdout) != 0 ? FATAL_EXIT_CODE : SUCCESS_EXIT_CODE);
00898 }
00899
00900
00901 const char *
00902 get_insn_name (code)
00903 int code ATTRIBUTE_UNUSED;
00904 {
00905 return NULL;
00906 }
00907
00908 #ifndef KEY // We should get it now from libiberty
00909 #ifdef SGI_MONGOOSE
00910 PTR
00911 xcalloc (nmemb, size)
00912 size_t nmemb;
00913 size_t size;
00914 {
00915 register PTR ptr;
00916 #if (GCC_VERSION >= 3000)
00917 ptr = (PTR) really_call_calloc (nmemb, size);
00918 #else
00919 ptr = (PTR) calloc (nmemb, size);
00920 #endif
00921 if (!ptr)
00922 fatal ("virtual memory exhausted");
00923 return ptr;
00924 }
00925 #endif
00926 #endif // !KEY