|
|
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.