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 "config.h"
00025 #include "system.h"
00026 #include "coretypes.h"
00027 #include "tm.h"
00028 #include "rtl.h"
00029 #include "obstack.h"
00030 #include "hard-reg-set.h"
00031 #include "basic-block.h"
00032 #include "real.h"
00033 #include "sched-int.h"
00034 #include "tree-pass.h"
00035
00036 static char *safe_concat (char *, char *, const char *);
00037 static void print_exp (char *, rtx, int);
00038 static void print_value (char *, rtx, int);
00039 static void print_pattern (char *, rtx, int);
00040
00041 #define BUF_LEN 2048
00042
00043 static char *
00044 safe_concat (char *buf, char *cur, const char *str)
00045 {
00046 char *end = buf + BUF_LEN - 2;
00047 int c;
00048
00049 if (cur > end)
00050 {
00051 *end = '\0';
00052 return end;
00053 }
00054
00055 while (cur < end && (c = *str++) != '\0')
00056 *cur++ = c;
00057
00058 *cur = '\0';
00059 return cur;
00060 }
00061
00062
00063
00064
00065
00066 static void
00067 print_exp (char *buf, rtx x, int verbose)
00068 {
00069 char tmp[BUF_LEN];
00070 const char *st[4];
00071 char *cur = buf;
00072 const char *fun = (char *) 0;
00073 const char *sep;
00074 rtx op[4];
00075 int i;
00076
00077 for (i = 0; i < 4; i++)
00078 {
00079 st[i] = (char *) 0;
00080 op[i] = NULL_RTX;
00081 }
00082
00083 switch (GET_CODE (x))
00084 {
00085 case PLUS:
00086 op[0] = XEXP (x, 0);
00087 if (GET_CODE (XEXP (x, 1)) == CONST_INT
00088 && INTVAL (XEXP (x, 1)) < 0)
00089 {
00090 st[1] = "-";
00091 op[1] = GEN_INT (-INTVAL (XEXP (x, 1)));
00092 }
00093 else
00094 {
00095 st[1] = "+";
00096 op[1] = XEXP (x, 1);
00097 }
00098 break;
00099 case LO_SUM:
00100 op[0] = XEXP (x, 0);
00101 st[1] = "+low(";
00102 op[1] = XEXP (x, 1);
00103 st[2] = ")";
00104 break;
00105 case MINUS:
00106 op[0] = XEXP (x, 0);
00107 st[1] = "-";
00108 op[1] = XEXP (x, 1);
00109 break;
00110 case COMPARE:
00111 fun = "cmp";
00112 op[0] = XEXP (x, 0);
00113 op[1] = XEXP (x, 1);
00114 break;
00115 case NEG:
00116 st[0] = "-";
00117 op[0] = XEXP (x, 0);
00118 break;
00119 case MULT:
00120 op[0] = XEXP (x, 0);
00121 st[1] = "*";
00122 op[1] = XEXP (x, 1);
00123 break;
00124 case DIV:
00125 op[0] = XEXP (x, 0);
00126 st[1] = "/";
00127 op[1] = XEXP (x, 1);
00128 break;
00129 case UDIV:
00130 fun = "udiv";
00131 op[0] = XEXP (x, 0);
00132 op[1] = XEXP (x, 1);
00133 break;
00134 case MOD:
00135 op[0] = XEXP (x, 0);
00136 st[1] = "%";
00137 op[1] = XEXP (x, 1);
00138 break;
00139 case UMOD:
00140 fun = "umod";
00141 op[0] = XEXP (x, 0);
00142 op[1] = XEXP (x, 1);
00143 break;
00144 case SMIN:
00145 fun = "smin";
00146 op[0] = XEXP (x, 0);
00147 op[1] = XEXP (x, 1);
00148 break;
00149 case SMAX:
00150 fun = "smax";
00151 op[0] = XEXP (x, 0);
00152 op[1] = XEXP (x, 1);
00153 break;
00154 case UMIN:
00155 fun = "umin";
00156 op[0] = XEXP (x, 0);
00157 op[1] = XEXP (x, 1);
00158 break;
00159 case UMAX:
00160 fun = "umax";
00161 op[0] = XEXP (x, 0);
00162 op[1] = XEXP (x, 1);
00163 break;
00164 case NOT:
00165 st[0] = "!";
00166 op[0] = XEXP (x, 0);
00167 break;
00168 case AND:
00169 op[0] = XEXP (x, 0);
00170 st[1] = "&";
00171 op[1] = XEXP (x, 1);
00172 break;
00173 case IOR:
00174 op[0] = XEXP (x, 0);
00175 st[1] = "|";
00176 op[1] = XEXP (x, 1);
00177 break;
00178 case XOR:
00179 op[0] = XEXP (x, 0);
00180 st[1] = "^";
00181 op[1] = XEXP (x, 1);
00182 break;
00183 case ASHIFT:
00184 op[0] = XEXP (x, 0);
00185 st[1] = "<<";
00186 op[1] = XEXP (x, 1);
00187 break;
00188 case LSHIFTRT:
00189 op[0] = XEXP (x, 0);
00190 st[1] = " 0>>";
00191 op[1] = XEXP (x, 1);
00192 break;
00193 case ASHIFTRT:
00194 op[0] = XEXP (x, 0);
00195 st[1] = ">>";
00196 op[1] = XEXP (x, 1);
00197 break;
00198 case ROTATE:
00199 op[0] = XEXP (x, 0);
00200 st[1] = "<-<";
00201 op[1] = XEXP (x, 1);
00202 break;
00203 case ROTATERT:
00204 op[0] = XEXP (x, 0);
00205 st[1] = ">->";
00206 op[1] = XEXP (x, 1);
00207 break;
00208 case ABS:
00209 fun = "abs";
00210 op[0] = XEXP (x, 0);
00211 break;
00212 case SQRT:
00213 fun = "sqrt";
00214 op[0] = XEXP (x, 0);
00215 break;
00216 case FFS:
00217 fun = "ffs";
00218 op[0] = XEXP (x, 0);
00219 break;
00220 case EQ:
00221 op[0] = XEXP (x, 0);
00222 st[1] = "==";
00223 op[1] = XEXP (x, 1);
00224 break;
00225 case NE:
00226 op[0] = XEXP (x, 0);
00227 st[1] = "!=";
00228 op[1] = XEXP (x, 1);
00229 break;
00230 case GT:
00231 op[0] = XEXP (x, 0);
00232 st[1] = ">";
00233 op[1] = XEXP (x, 1);
00234 break;
00235 case GTU:
00236 fun = "gtu";
00237 op[0] = XEXP (x, 0);
00238 op[1] = XEXP (x, 1);
00239 break;
00240 case LT:
00241 op[0] = XEXP (x, 0);
00242 st[1] = "<";
00243 op[1] = XEXP (x, 1);
00244 break;
00245 case LTU:
00246 fun = "ltu";
00247 op[0] = XEXP (x, 0);
00248 op[1] = XEXP (x, 1);
00249 break;
00250 case GE:
00251 op[0] = XEXP (x, 0);
00252 st[1] = ">=";
00253 op[1] = XEXP (x, 1);
00254 break;
00255 case GEU:
00256 fun = "geu";
00257 op[0] = XEXP (x, 0);
00258 op[1] = XEXP (x, 1);
00259 break;
00260 case LE:
00261 op[0] = XEXP (x, 0);
00262 st[1] = "<=";
00263 op[1] = XEXP (x, 1);
00264 break;
00265 case LEU:
00266 fun = "leu";
00267 op[0] = XEXP (x, 0);
00268 op[1] = XEXP (x, 1);
00269 break;
00270 case SIGN_EXTRACT:
00271 fun = (verbose) ? "sign_extract" : "sxt";
00272 op[0] = XEXP (x, 0);
00273 op[1] = XEXP (x, 1);
00274 op[2] = XEXP (x, 2);
00275 break;
00276 case ZERO_EXTRACT:
00277 fun = (verbose) ? "zero_extract" : "zxt";
00278 op[0] = XEXP (x, 0);
00279 op[1] = XEXP (x, 1);
00280 op[2] = XEXP (x, 2);
00281 break;
00282 case SIGN_EXTEND:
00283 fun = (verbose) ? "sign_extend" : "sxn";
00284 op[0] = XEXP (x, 0);
00285 break;
00286 case ZERO_EXTEND:
00287 fun = (verbose) ? "zero_extend" : "zxn";
00288 op[0] = XEXP (x, 0);
00289 break;
00290 case FLOAT_EXTEND:
00291 fun = (verbose) ? "float_extend" : "fxn";
00292 op[0] = XEXP (x, 0);
00293 break;
00294 case TRUNCATE:
00295 fun = (verbose) ? "trunc" : "trn";
00296 op[0] = XEXP (x, 0);
00297 break;
00298 case FLOAT_TRUNCATE:
00299 fun = (verbose) ? "float_trunc" : "ftr";
00300 op[0] = XEXP (x, 0);
00301 break;
00302 case FLOAT:
00303 fun = (verbose) ? "float" : "flt";
00304 op[0] = XEXP (x, 0);
00305 break;
00306 case UNSIGNED_FLOAT:
00307 fun = (verbose) ? "uns_float" : "ufl";
00308 op[0] = XEXP (x, 0);
00309 break;
00310 case FIX:
00311 fun = "fix";
00312 op[0] = XEXP (x, 0);
00313 break;
00314 case UNSIGNED_FIX:
00315 fun = (verbose) ? "uns_fix" : "ufx";
00316 op[0] = XEXP (x, 0);
00317 break;
00318 case PRE_DEC:
00319 st[0] = "--";
00320 op[0] = XEXP (x, 0);
00321 break;
00322 case PRE_INC:
00323 st[0] = "++";
00324 op[0] = XEXP (x, 0);
00325 break;
00326 case POST_DEC:
00327 op[0] = XEXP (x, 0);
00328 st[1] = "--";
00329 break;
00330 case POST_INC:
00331 op[0] = XEXP (x, 0);
00332 st[1] = "++";
00333 break;
00334 case CALL:
00335 st[0] = "call ";
00336 op[0] = XEXP (x, 0);
00337 if (verbose)
00338 {
00339 st[1] = " argc:";
00340 op[1] = XEXP (x, 1);
00341 }
00342 break;
00343 case IF_THEN_ELSE:
00344 st[0] = "{(";
00345 op[0] = XEXP (x, 0);
00346 st[1] = ")?";
00347 op[1] = XEXP (x, 1);
00348 st[2] = ":";
00349 op[2] = XEXP (x, 2);
00350 st[3] = "}";
00351 break;
00352 case TRAP_IF:
00353 fun = "trap_if";
00354 op[0] = TRAP_CONDITION (x);
00355 break;
00356 case PREFETCH:
00357 fun = "prefetch";
00358 op[0] = XEXP (x, 0);
00359 op[1] = XEXP (x, 1);
00360 op[2] = XEXP (x, 2);
00361 break;
00362 case UNSPEC:
00363 case UNSPEC_VOLATILE:
00364 {
00365 cur = safe_concat (buf, cur, "unspec");
00366 if (GET_CODE (x) == UNSPEC_VOLATILE)
00367 cur = safe_concat (buf, cur, "/v");
00368 cur = safe_concat (buf, cur, "[");
00369 sep = "";
00370 for (i = 0; i < XVECLEN (x, 0); i++)
00371 {
00372 print_pattern (tmp, XVECEXP (x, 0, i), verbose);
00373 cur = safe_concat (buf, cur, sep);
00374 cur = safe_concat (buf, cur, tmp);
00375 sep = ",";
00376 }
00377 cur = safe_concat (buf, cur, "] ");
00378 sprintf (tmp, "%d", XINT (x, 1));
00379 cur = safe_concat (buf, cur, tmp);
00380 }
00381 break;
00382 default:
00383
00384 st[0] = GET_RTX_NAME (GET_CODE (x));
00385 break;
00386 }
00387
00388
00389 if (fun)
00390 {
00391 cur = safe_concat (buf, cur, fun);
00392 cur = safe_concat (buf, cur, "(");
00393 }
00394
00395 for (i = 0; i < 4; i++)
00396 {
00397 if (st[i])
00398 cur = safe_concat (buf, cur, st[i]);
00399
00400 if (op[i])
00401 {
00402 if (fun && i != 0)
00403 cur = safe_concat (buf, cur, ",");
00404
00405 print_value (tmp, op[i], verbose);
00406 cur = safe_concat (buf, cur, tmp);
00407 }
00408 }
00409
00410 if (fun)
00411 cur = safe_concat (buf, cur, ")");
00412 }
00413
00414
00415
00416
00417 static void
00418 print_value (char *buf, rtx x, int verbose)
00419 {
00420 char t[BUF_LEN];
00421 char *cur = buf;
00422
00423 switch (GET_CODE (x))
00424 {
00425 case CONST_INT:
00426 sprintf (t, HOST_WIDE_INT_PRINT_HEX, INTVAL (x));
00427 cur = safe_concat (buf, cur, t);
00428 break;
00429 case CONST_DOUBLE:
00430 if (FLOAT_MODE_P (GET_MODE (x)))
00431 real_to_decimal (t, CONST_DOUBLE_REAL_VALUE (x), sizeof (t), 0, 1);
00432 else
00433 sprintf (t, "<0x%lx,0x%lx>", (long) CONST_DOUBLE_LOW (x), (long) CONST_DOUBLE_HIGH (x));
00434 cur = safe_concat (buf, cur, t);
00435 break;
00436 case CONST_STRING:
00437 cur = safe_concat (buf, cur, "\"");
00438 cur = safe_concat (buf, cur, XSTR (x, 0));
00439 cur = safe_concat (buf, cur, "\"");
00440 break;
00441 case SYMBOL_REF:
00442 cur = safe_concat (buf, cur, "`");
00443 cur = safe_concat (buf, cur, XSTR (x, 0));
00444 cur = safe_concat (buf, cur, "'");
00445 break;
00446 case LABEL_REF:
00447 sprintf (t, "L%d", INSN_UID (XEXP (x, 0)));
00448 cur = safe_concat (buf, cur, t);
00449 break;
00450 case CONST:
00451 print_value (t, XEXP (x, 0), verbose);
00452 cur = safe_concat (buf, cur, "const(");
00453 cur = safe_concat (buf, cur, t);
00454 cur = safe_concat (buf, cur, ")");
00455 break;
00456 case HIGH:
00457 print_value (t, XEXP (x, 0), verbose);
00458 cur = safe_concat (buf, cur, "high(");
00459 cur = safe_concat (buf, cur, t);
00460 cur = safe_concat (buf, cur, ")");
00461 break;
00462 case REG:
00463 if (REGNO (x) < FIRST_PSEUDO_REGISTER)
00464 {
00465 int c = reg_names[REGNO (x)][0];
00466 if (ISDIGIT (c))
00467 cur = safe_concat (buf, cur, "%");
00468
00469 cur = safe_concat (buf, cur, reg_names[REGNO (x)]);
00470 }
00471 else
00472 {
00473 sprintf (t, "r%d", REGNO (x));
00474 cur = safe_concat (buf, cur, t);
00475 }
00476 if (verbose
00477 #ifdef INSN_SCHEDULING
00478 && !current_sched_info
00479 #endif
00480 )
00481 {
00482 sprintf (t, ":%s", GET_MODE_NAME (GET_MODE (x)));
00483 cur = safe_concat (buf, cur, t);
00484 }
00485 break;
00486 case SUBREG:
00487 print_value (t, SUBREG_REG (x), verbose);
00488 cur = safe_concat (buf, cur, t);
00489 sprintf (t, "#%d", SUBREG_BYTE (x));
00490 cur = safe_concat (buf, cur, t);
00491 break;
00492 case SCRATCH:
00493 cur = safe_concat (buf, cur, "scratch");
00494 break;
00495 case CC0:
00496 cur = safe_concat (buf, cur, "cc0");
00497 break;
00498 case PC:
00499 cur = safe_concat (buf, cur, "pc");
00500 break;
00501 case MEM:
00502 print_value (t, XEXP (x, 0), verbose);
00503 cur = safe_concat (buf, cur, "[");
00504 cur = safe_concat (buf, cur, t);
00505 cur = safe_concat (buf, cur, "]");
00506 break;
00507 default:
00508 print_exp (t, x, verbose);
00509 cur = safe_concat (buf, cur, t);
00510 break;
00511 }
00512 }
00513
00514
00515
00516 static void
00517 print_pattern (char *buf, rtx x, int verbose)
00518 {
00519 char t1[BUF_LEN], t2[BUF_LEN], t3[BUF_LEN];
00520
00521 switch (GET_CODE (x))
00522 {
00523 case SET:
00524 print_value (t1, SET_DEST (x), verbose);
00525 print_value (t2, SET_SRC (x), verbose);
00526 sprintf (buf, "%s=%s", t1, t2);
00527 break;
00528 case RETURN:
00529 sprintf (buf, "return");
00530 break;
00531 case CALL:
00532 print_exp (buf, x, verbose);
00533 break;
00534 case CLOBBER:
00535 print_value (t1, XEXP (x, 0), verbose);
00536 sprintf (buf, "clobber %s", t1);
00537 break;
00538 case USE:
00539 print_value (t1, XEXP (x, 0), verbose);
00540 sprintf (buf, "use %s", t1);
00541 break;
00542 case COND_EXEC:
00543 if (GET_CODE (COND_EXEC_TEST (x)) == NE
00544 && XEXP (COND_EXEC_TEST (x), 1) == const0_rtx)
00545 print_value (t1, XEXP (COND_EXEC_TEST (x), 0), verbose);
00546 else if (GET_CODE (COND_EXEC_TEST (x)) == EQ
00547 && XEXP (COND_EXEC_TEST (x), 1) == const0_rtx)
00548 {
00549 t1[0] = '!';
00550 print_value (t1 + 1, XEXP (COND_EXEC_TEST (x), 0), verbose);
00551 }
00552 else
00553 print_value (t1, COND_EXEC_TEST (x), verbose);
00554 print_pattern (t2, COND_EXEC_CODE (x), verbose);
00555 sprintf (buf, "(%s) %s", t1, t2);
00556 break;
00557 case PARALLEL:
00558 {
00559 int i;
00560
00561 sprintf (t1, "{");
00562 for (i = 0; i < XVECLEN (x, 0); i++)
00563 {
00564 print_pattern (t2, XVECEXP (x, 0, i), verbose);
00565 sprintf (t3, "%s%s;", t1, t2);
00566 strcpy (t1, t3);
00567 }
00568 sprintf (buf, "%s}", t1);
00569 }
00570 break;
00571 case SEQUENCE:
00572
00573 gcc_unreachable ();
00574 case ASM_INPUT:
00575 sprintf (buf, "asm {%s}", XSTR (x, 0));
00576 break;
00577 case ADDR_VEC:
00578 break;
00579 case ADDR_DIFF_VEC:
00580 print_value (buf, XEXP (x, 0), verbose);
00581 break;
00582 case TRAP_IF:
00583 print_value (t1, TRAP_CONDITION (x), verbose);
00584 sprintf (buf, "trap_if %s", t1);
00585 break;
00586 case UNSPEC:
00587 {
00588 int i;
00589
00590 sprintf (t1, "unspec{");
00591 for (i = 0; i < XVECLEN (x, 0); i++)
00592 {
00593 print_pattern (t2, XVECEXP (x, 0, i), verbose);
00594 sprintf (t3, "%s%s;", t1, t2);
00595 strcpy (t1, t3);
00596 }
00597 sprintf (buf, "%s}", t1);
00598 }
00599 break;
00600 case UNSPEC_VOLATILE:
00601 {
00602 int i;
00603
00604 sprintf (t1, "unspec/v{");
00605 for (i = 0; i < XVECLEN (x, 0); i++)
00606 {
00607 print_pattern (t2, XVECEXP (x, 0, i), verbose);
00608 sprintf (t3, "%s%s;", t1, t2);
00609 strcpy (t1, t3);
00610 }
00611 sprintf (buf, "%s}", t1);
00612 }
00613 break;
00614 default:
00615 print_value (buf, x, verbose);
00616 }
00617 }
00618
00619
00620
00621
00622
00623
00624
00625
00626 void
00627 print_insn (char *buf, rtx x, int verbose)
00628 {
00629 char t[BUF_LEN];
00630 rtx insn = x;
00631
00632 switch (GET_CODE (x))
00633 {
00634 case INSN:
00635 print_pattern (t, PATTERN (x), verbose);
00636 #ifdef INSN_SCHEDULING
00637 if (verbose && current_sched_info)
00638 sprintf (buf, "%s: %s", (*current_sched_info->print_insn) (x, 1),
00639 t);
00640 else
00641 #endif
00642 sprintf (buf, " %4d %s", INSN_UID (x), t);
00643 break;
00644 case JUMP_INSN:
00645 print_pattern (t, PATTERN (x), verbose);
00646 #ifdef INSN_SCHEDULING
00647 if (verbose && current_sched_info)
00648 sprintf (buf, "%s: jump %s", (*current_sched_info->print_insn) (x, 1),
00649 t);
00650 else
00651 #endif
00652 sprintf (buf, " %4d %s", INSN_UID (x), t);
00653 break;
00654 case CALL_INSN:
00655 x = PATTERN (insn);
00656 if (GET_CODE (x) == PARALLEL)
00657 {
00658 x = XVECEXP (x, 0, 0);
00659 print_pattern (t, x, verbose);
00660 }
00661 else
00662 strcpy (t, "call <...>");
00663 #ifdef INSN_SCHEDULING
00664 if (verbose && current_sched_info)
00665 sprintf (buf, "%s: %s", (*current_sched_info->print_insn) (x, 1), t);
00666 else
00667 #endif
00668 sprintf (buf, " %4d %s", INSN_UID (insn), t);
00669 break;
00670 case CODE_LABEL:
00671 sprintf (buf, "L%d:", INSN_UID (x));
00672 break;
00673 case BARRIER:
00674 sprintf (buf, "i%4d: barrier", INSN_UID (x));
00675 break;
00676 case NOTE:
00677 if (NOTE_LINE_NUMBER (x) > 0)
00678 {
00679 expanded_location xloc;
00680 NOTE_EXPANDED_LOCATION (xloc, x);
00681 sprintf (buf, " %4d note \"%s\" %d", INSN_UID (x),
00682 xloc.file, xloc.line);
00683 }
00684 else
00685 sprintf (buf, " %4d %s", INSN_UID (x),
00686 GET_NOTE_INSN_NAME (NOTE_LINE_NUMBER (x)));
00687 break;
00688 default:
00689 sprintf (buf, "i%4d <What %s?>", INSN_UID (x),
00690 GET_RTX_NAME (GET_CODE (x)));
00691 }
00692 }
00693
00694
00695
00696
00697 void
00698 dump_insn_slim (FILE *f, rtx x)
00699 {
00700 char t[BUF_LEN + 32];
00701 rtx note;
00702
00703 print_insn (t, x, 1);
00704 fputs (t, f);
00705 putc ('\n', f);
00706 if (INSN_P (x) && REG_NOTES (x))
00707 for (note = REG_NOTES (x); note; note = XEXP (note, 1))
00708 {
00709 print_value (t, XEXP (note, 0), 1);
00710 fprintf (f, " %s: %s\n",
00711 GET_REG_NOTE_NAME (REG_NOTE_KIND (note)), t);
00712 }
00713 }
00714
00715
00716 void
00717 debug_insn_slim (rtx x)
00718 {
00719 dump_insn_slim (stderr, x);
00720 }
00721
00722
00723
00724
00725 void
00726 print_rtl_slim_with_bb (FILE *f, rtx first, int flags)
00727 {
00728 basic_block current_bb = NULL;
00729 rtx insn;
00730
00731 for (insn = first; NULL != insn; insn = NEXT_INSN (insn))
00732 {
00733 if ((flags & TDF_BLOCKS)
00734 && (INSN_P (insn) || GET_CODE (insn) == NOTE)
00735 && BLOCK_FOR_INSN (insn)
00736 && !current_bb)
00737 {
00738 current_bb = BLOCK_FOR_INSN (insn);
00739 dump_bb_info (current_bb, true, false, flags, ";; ", f);
00740 }
00741
00742 dump_insn_slim (f, insn);
00743
00744 if ((flags & TDF_BLOCKS)
00745 && current_bb
00746 && insn == BB_END (current_bb))
00747 {
00748 dump_bb_info (current_bb, false, true, flags, ";; ", f);
00749 current_bb = NULL;
00750 }
00751 }
00752 }
00753