|
|
1.1 ! root 1: /* Print RTL for GNU C Compiler. ! 2: Copyright (C) 1987, 1988, 1992 Free Software Foundation, Inc. ! 3: ! 4: This file is part of GNU CC. ! 5: ! 6: GNU CC is free software; you can redistribute it and/or modify ! 7: it under the terms of the GNU General Public License as published by ! 8: the Free Software Foundation; either version 2, or (at your option) ! 9: any later version. ! 10: ! 11: GNU CC is distributed in the hope that it will be useful, ! 12: but WITHOUT ANY WARRANTY; without even the implied warranty of ! 13: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ! 14: GNU General Public License for more details. ! 15: ! 16: You should have received a copy of the GNU General Public License ! 17: along with GNU CC; see the file COPYING. If not, write to ! 18: the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ ! 19: ! 20: ! 21: #include "config.h" ! 22: #include <ctype.h> ! 23: #include <stdio.h> ! 24: #include "rtl.h" ! 25: ! 26: ! 27: /* How to print out a register name. ! 28: We don't use PRINT_REG because some definitions of PRINT_REG ! 29: don't work here. */ ! 30: #ifndef DEBUG_PRINT_REG ! 31: #define DEBUG_PRINT_REG(RTX, CODE, FILE) \ ! 32: fprintf ((FILE), "%d %s", REGNO (RTX), reg_names[REGNO (RTX)]) ! 33: #endif ! 34: ! 35: /* Array containing all of the register names */ ! 36: ! 37: #ifdef DEBUG_REGISTER_NAMES ! 38: static char *reg_names[] = DEBUG_REGISTER_NAMES; ! 39: #else ! 40: static char *reg_names[] = REGISTER_NAMES; ! 41: #endif ! 42: ! 43: static FILE *outfile; ! 44: ! 45: char spaces[] = " "; ! 46: ! 47: static int sawclose = 0; ! 48: ! 49: /* Names for patterns. Non-zero only when linked with insn-output.c. */ ! 50: ! 51: extern char **insn_name_ptr; ! 52: ! 53: /* Print IN_RTX onto OUTFILE. This is the recursive part of printing. */ ! 54: ! 55: static void ! 56: print_rtx (in_rtx) ! 57: register rtx in_rtx; ! 58: { ! 59: static int indent; ! 60: register int i, j; ! 61: register char *format_ptr; ! 62: register int is_insn; ! 63: ! 64: if (sawclose) ! 65: { ! 66: fprintf (outfile, "\n%s", ! 67: (spaces + (sizeof spaces - 1 - indent * 2))); ! 68: sawclose = 0; ! 69: } ! 70: ! 71: if (in_rtx == 0) ! 72: { ! 73: fprintf (outfile, "(nil)"); ! 74: sawclose = 1; ! 75: return; ! 76: } ! 77: ! 78: /* print name of expression code */ ! 79: fprintf (outfile, "(%s", GET_RTX_NAME (GET_CODE (in_rtx))); ! 80: ! 81: if (in_rtx->in_struct) ! 82: fprintf (outfile, "/s"); ! 83: ! 84: if (in_rtx->volatil) ! 85: fprintf (outfile, "/v"); ! 86: ! 87: if (in_rtx->unchanging) ! 88: fprintf (outfile, "/u"); ! 89: ! 90: if (in_rtx->integrated) ! 91: fprintf (outfile, "/i"); ! 92: ! 93: if (GET_MODE (in_rtx) != VOIDmode) ! 94: { ! 95: /* Print REG_NOTE names for EXPR_LIST and INSN_LIST. */ ! 96: if (GET_CODE (in_rtx) == EXPR_LIST || GET_CODE (in_rtx) == INSN_LIST) ! 97: fprintf (outfile, ":%s", GET_REG_NOTE_NAME (GET_MODE (in_rtx))); ! 98: else ! 99: fprintf (outfile, ":%s", GET_MODE_NAME (GET_MODE (in_rtx))); ! 100: } ! 101: ! 102: is_insn = (GET_RTX_CLASS (GET_CODE (in_rtx)) == 'i'); ! 103: format_ptr = GET_RTX_FORMAT (GET_CODE (in_rtx)); ! 104: ! 105: for (i = 0; i < GET_RTX_LENGTH (GET_CODE (in_rtx)); i++) ! 106: switch (*format_ptr++) ! 107: { ! 108: case 'S': ! 109: case 's': ! 110: if (XSTR (in_rtx, i) == 0) ! 111: fprintf (outfile, " \"\""); ! 112: else ! 113: fprintf (outfile, " (\"%s\")", XSTR (in_rtx, i)); ! 114: sawclose = 1; ! 115: break; ! 116: ! 117: /* 0 indicates a field for internal use that should not be printed. */ ! 118: case '0': ! 119: break; ! 120: ! 121: case 'e': ! 122: indent += 2; ! 123: if (!sawclose) ! 124: fprintf (outfile, " "); ! 125: print_rtx (XEXP (in_rtx, i)); ! 126: indent -= 2; ! 127: break; ! 128: ! 129: case 'E': ! 130: case 'V': ! 131: indent += 2; ! 132: if (sawclose) ! 133: { ! 134: fprintf (outfile, "\n%s", ! 135: (spaces + (sizeof spaces - 1 - indent * 2))); ! 136: sawclose = 0; ! 137: } ! 138: fprintf (outfile, "[ "); ! 139: if (NULL != XVEC (in_rtx, i)) ! 140: { ! 141: indent += 2; ! 142: if (XVECLEN (in_rtx, i)) ! 143: sawclose = 1; ! 144: ! 145: for (j = 0; j < XVECLEN (in_rtx, i); j++) ! 146: print_rtx (XVECEXP (in_rtx, i, j)); ! 147: ! 148: indent -= 2; ! 149: } ! 150: if (sawclose) ! 151: fprintf (outfile, "\n%s", ! 152: (spaces + (sizeof spaces - 1 - indent * 2))); ! 153: ! 154: fprintf (outfile, "] "); ! 155: sawclose = 1; ! 156: indent -= 2; ! 157: break; ! 158: ! 159: case 'w': ! 160: fprintf (outfile, ! 161: #if HOST_BITS_PER_WIDE_INT == HOST_BITS_PER_INT ! 162: " %d", ! 163: #else ! 164: " %ld", ! 165: #endif ! 166: XWINT (in_rtx, i)); ! 167: break; ! 168: ! 169: case 'i': ! 170: { ! 171: register int value = XINT (in_rtx, i); ! 172: ! 173: if (GET_CODE (in_rtx) == REG && value < FIRST_PSEUDO_REGISTER) ! 174: { ! 175: fputc (' ', outfile); ! 176: DEBUG_PRINT_REG (in_rtx, 0, outfile); ! 177: } ! 178: else ! 179: fprintf (outfile, " %d", value); ! 180: } ! 181: if (is_insn && &INSN_CODE (in_rtx) == &XINT (in_rtx, i) ! 182: && insn_name_ptr ! 183: && XINT (in_rtx, i) >= 0) ! 184: fprintf (outfile, " {%s}", insn_name_ptr[XINT (in_rtx, i)]); ! 185: sawclose = 0; ! 186: break; ! 187: ! 188: /* Print NOTE_INSN names rather than integer codes. */ ! 189: ! 190: case 'n': ! 191: if (XINT (in_rtx, i) <= 0) ! 192: fprintf (outfile, " %s", GET_NOTE_INSN_NAME (XINT (in_rtx, i))); ! 193: else ! 194: fprintf (outfile, " %d", XINT (in_rtx, i)); ! 195: sawclose = 0; ! 196: break; ! 197: ! 198: case 'u': ! 199: if (XEXP (in_rtx, i) != NULL) ! 200: fprintf (outfile, " %d", INSN_UID (XEXP (in_rtx, i))); ! 201: else ! 202: fprintf (outfile, " 0"); ! 203: sawclose = 0; ! 204: break; ! 205: ! 206: case '*': ! 207: fprintf (outfile, " Unknown"); ! 208: sawclose = 0; ! 209: break; ! 210: ! 211: default: ! 212: fprintf (stderr, ! 213: "switch format wrong in rtl.print_rtx(). format was: %c.\n", ! 214: format_ptr[-1]); ! 215: abort (); ! 216: } ! 217: ! 218: fprintf (outfile, ")"); ! 219: sawclose = 1; ! 220: } ! 221: ! 222: /* Call this function from the debugger to see what X looks like. */ ! 223: ! 224: void ! 225: debug_rtx (x) ! 226: rtx x; ! 227: { ! 228: outfile = stderr; ! 229: print_rtx (x); ! 230: fprintf (stderr, "\n"); ! 231: } ! 232: ! 233: /* Count of rtx's to print with debug_rtx_list. ! 234: This global exists because gdb user defined commands have no arguments. */ ! 235: ! 236: int debug_rtx_count = 0; /* 0 is treated as equivalent to 1 */ ! 237: ! 238: /* Call this function to print list from X on. ! 239: ! 240: N is a count of the rtx's to print. Positive values print from the specified ! 241: rtx on. Negative values print a window around the rtx. ! 242: EG: -5 prints 2 rtx's on either side (in addition to the specified rtx). */ ! 243: ! 244: void ! 245: debug_rtx_list (x, n) ! 246: rtx x; ! 247: int n; ! 248: { ! 249: int i,count; ! 250: rtx insn; ! 251: ! 252: count = n == 0 ? 1 : n < 0 ? -n : n; ! 253: ! 254: /* If we are printing a window, back up to the start. */ ! 255: ! 256: if (n < 0) ! 257: for (i = count / 2; i > 0; i--) ! 258: { ! 259: if (PREV_INSN (x) == 0) ! 260: break; ! 261: x = PREV_INSN (x); ! 262: } ! 263: ! 264: for (i = count, insn = x; i > 0 && insn != 0; i--, insn = NEXT_INSN (insn)) ! 265: debug_rtx (insn); ! 266: } ! 267: ! 268: /* Call this function to search an rtx list to find one with insn uid UID, ! 269: and then call debug_rtx_list to print it, using DEBUG_RTX_COUNT. ! 270: The found insn is returned to enable further debugging analysis. */ ! 271: ! 272: rtx ! 273: debug_rtx_find(x, uid) ! 274: rtx x; ! 275: int uid; ! 276: { ! 277: while (x != 0 && INSN_UID (x) != uid) ! 278: x = NEXT_INSN (x); ! 279: if (x != 0) ! 280: { ! 281: debug_rtx_list (x, debug_rtx_count); ! 282: return x; ! 283: } ! 284: else ! 285: { ! 286: fprintf (stderr, "insn uid %d not found\n", uid); ! 287: return 0; ! 288: } ! 289: } ! 290: ! 291: /* External entry point for printing a chain of insns ! 292: starting with RTX_FIRST onto file OUTF. ! 293: A blank line separates insns. ! 294: ! 295: If RTX_FIRST is not an insn, then it alone is printed, with no newline. */ ! 296: ! 297: void ! 298: print_rtl (outf, rtx_first) ! 299: FILE *outf; ! 300: rtx rtx_first; ! 301: { ! 302: register rtx tmp_rtx; ! 303: ! 304: outfile = outf; ! 305: sawclose = 0; ! 306: ! 307: if (rtx_first == 0) ! 308: fprintf (outf, "(nil)\n"); ! 309: else ! 310: switch (GET_CODE (rtx_first)) ! 311: { ! 312: case INSN: ! 313: case JUMP_INSN: ! 314: case CALL_INSN: ! 315: case NOTE: ! 316: case CODE_LABEL: ! 317: case BARRIER: ! 318: for (tmp_rtx = rtx_first; NULL != tmp_rtx; tmp_rtx = NEXT_INSN (tmp_rtx)) ! 319: { ! 320: print_rtx (tmp_rtx); ! 321: fprintf (outfile, "\n"); ! 322: } ! 323: break; ! 324: ! 325: default: ! 326: print_rtx (rtx_first); ! 327: } ! 328: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.